View Javadoc
1   package org.apache.maven.surefire.booter.spi;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.surefire.api.booter.Command;
23  import org.apache.maven.surefire.api.booter.Shutdown;
24  import org.junit.Test;
25  
26  import java.io.ByteArrayInputStream;
27  import java.io.EOFException;
28  import java.io.IOException;
29  import java.io.InputStream;
30  
31  import static java.nio.channels.Channels.newChannel;
32  import static org.apache.maven.surefire.api.booter.MasterProcessCommand.BYE_ACK;
33  import static org.apache.maven.surefire.api.booter.MasterProcessCommand.NOOP;
34  import static org.apache.maven.surefire.api.booter.MasterProcessCommand.RUN_CLASS;
35  import static org.apache.maven.surefire.api.booter.MasterProcessCommand.SHUTDOWN;
36  import static org.apache.maven.surefire.api.booter.MasterProcessCommand.SKIP_SINCE_NEXT_TEST;
37  import static org.apache.maven.surefire.api.booter.MasterProcessCommand.TEST_SET_FINISHED;
38  import static org.apache.maven.surefire.api.booter.Shutdown.DEFAULT;
39  import static org.apache.maven.surefire.api.booter.Shutdown.EXIT;
40  import static org.apache.maven.surefire.api.booter.Shutdown.KILL;
41  import static org.fest.assertions.Assertions.assertThat;
42  import static org.junit.Assert.assertEquals;
43  import static org.junit.Assert.assertNull;
44  import static org.junit.Assert.fail;
45  
46  /**
47   * Tests for {@link LegacyMasterProcessChannelDecoder}.
48   */
49  public class LegacyMasterProcessChannelDecoderTest
50  {
51      @Test
52      public void testDecoderRunClass() throws IOException
53      {
54          assertEquals( String.class, RUN_CLASS.getDataType() );
55          byte[] encoded = ":maven-surefire-command:run-testclass:pkg.Test:\n".getBytes();
56          InputStream is = new ByteArrayInputStream( encoded );
57          LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
58          Command command = decoder.decode();
59          assertThat( command.getCommandType() ).isSameAs( RUN_CLASS );
60          assertThat( command.getData() ).isEqualTo( "pkg.Test" );
61      }
62  
63      @Test
64      public void testDecoderTestsetFinished() throws IOException
65      {
66          Command command = Command.TEST_SET_FINISHED;
67          assertThat( command.getCommandType() ).isSameAs( TEST_SET_FINISHED );
68          assertEquals( Void.class, TEST_SET_FINISHED.getDataType() );
69          byte[] encoded = ":maven-surefire-command:testset-finished:".getBytes();
70          ByteArrayInputStream is = new ByteArrayInputStream( encoded );
71          LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
72          command = decoder.decode();
73          assertThat( command.getCommandType() ).isSameAs( TEST_SET_FINISHED );
74          assertNull( command.getData() );
75      }
76  
77      @Test
78      public void testDecoderSkipSinceNextTest() throws IOException
79      {
80          Command command = Command.SKIP_SINCE_NEXT_TEST;
81          assertThat( command.getCommandType() ).isSameAs( SKIP_SINCE_NEXT_TEST );
82          assertEquals( Void.class, SKIP_SINCE_NEXT_TEST.getDataType() );
83          byte[] encoded = ":maven-surefire-command:skip-since-next-test:".getBytes();
84          ByteArrayInputStream is = new ByteArrayInputStream( encoded );
85          LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
86          command = decoder.decode();
87          assertThat( command.getCommandType() ).isSameAs( SKIP_SINCE_NEXT_TEST );
88          assertNull( command.getData() );
89      }
90  
91      @Test
92      public void testDecoderShutdownWithExit() throws IOException
93      {
94          Shutdown shutdownType = EXIT;
95          assertEquals( String.class, SHUTDOWN.getDataType() );
96          byte[] encoded = ( ":maven-surefire-command:shutdown:" + shutdownType + ":" ).getBytes();
97          ByteArrayInputStream is = new ByteArrayInputStream( encoded );
98          LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
99          Command command = decoder.decode();
100         assertThat( command.getCommandType() ).isSameAs( SHUTDOWN );
101         assertThat( command.getData() ).isEqualTo( shutdownType.name() );
102     }
103 
104     @Test
105     public void testDecoderShutdownWithKill() throws IOException
106     {
107         Shutdown shutdownType = KILL;
108         assertEquals( String.class, SHUTDOWN.getDataType() );
109         byte[] encoded = ( ":maven-surefire-command:shutdown:" + shutdownType + ":" ).getBytes();
110         ByteArrayInputStream is = new ByteArrayInputStream( encoded );
111         LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
112         Command command = decoder.decode();
113         assertThat( command.getCommandType() ).isSameAs( SHUTDOWN );
114         assertThat( command.getData() ).isEqualTo( shutdownType.name() );
115     }
116 
117     @Test
118     public void testDecoderShutdownWithDefault() throws IOException
119     {
120         Shutdown shutdownType = DEFAULT;
121         assertEquals( String.class, SHUTDOWN.getDataType() );
122         byte[] encoded = ( ":maven-surefire-command:shutdown:" + shutdownType + ":" ).getBytes();
123         ByteArrayInputStream is = new ByteArrayInputStream( encoded );
124         LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
125         Command command = decoder.decode();
126         assertThat( command.getCommandType() ).isSameAs( SHUTDOWN );
127         assertThat( command.getData() ).isEqualTo( shutdownType.name() );
128     }
129 
130     @Test
131     public void testDecoderNoop() throws IOException
132     {
133         assertThat( NOOP ).isSameAs( Command.NOOP.getCommandType() );
134         assertEquals( Void.class, NOOP.getDataType() );
135         byte[] encoded = ":maven-surefire-command:noop:".getBytes();
136         ByteArrayInputStream is = new ByteArrayInputStream( encoded );
137         LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
138         Command command = decoder.decode();
139         assertThat( command.getCommandType() ).isSameAs( NOOP );
140         assertNull( command.getData() );
141     }
142 
143     @Test
144     public void shouldIgnoreDamagedStream() throws IOException
145     {
146         assertThat( BYE_ACK ).isSameAs( Command.BYE_ACK.getCommandType() );
147         assertEquals( Void.class, BYE_ACK.getDataType() );
148         byte[] encoded = ":maven-surefire-command:bye-ack:".getBytes();
149         byte[] streamContent = ( "<something>" + new String( encoded ) + "<damaged>" ).getBytes();
150         ByteArrayInputStream is = new ByteArrayInputStream( streamContent );
151         LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
152         Command command = decoder.decode();
153         assertThat( command.getCommandType() ).isSameAs( BYE_ACK );
154         assertNull( command.getData() );
155     }
156 
157     @Test
158     public void shouldIgnoreDamagedHeader() throws IOException
159     {
160         assertThat( BYE_ACK ).isSameAs( Command.BYE_ACK.getCommandType() );
161         assertEquals( Void.class, BYE_ACK.getDataType() );
162         byte[] encoded = ":maven-surefire-command:bye-ack:".getBytes();
163         byte[] streamContent = ( ":<damaged>:" + new String( encoded ) ).getBytes();
164         ByteArrayInputStream is = new ByteArrayInputStream( streamContent );
165         LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
166         Command command = decoder.decode();
167         assertThat( command.getCommandType() ).isSameAs( BYE_ACK );
168         assertNull( command.getData() );
169     }
170 
171     @Test
172     public void testDecoderByeAck() throws IOException
173     {
174         assertThat( BYE_ACK ).isSameAs( Command.BYE_ACK.getCommandType() );
175         assertEquals( Void.class, BYE_ACK.getDataType() );
176         byte[] encoded = ":maven-surefire-command:bye-ack:".getBytes();
177         ByteArrayInputStream is = new ByteArrayInputStream( encoded );
178         LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
179         Command command = decoder.decode();
180         assertThat( command.getCommandType() ).isSameAs( BYE_ACK );
181         assertNull( command.getData() );
182     }
183 
184     @Test
185     public void shouldDecodeTwoCommands() throws IOException
186     {
187         String cmd = ":maven-surefire-command:bye-ack:\r\n:maven-surefire-command:bye-ack:";
188         InputStream is = new ByteArrayInputStream( cmd.getBytes() );
189         LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
190 
191         Command command = decoder.decode();
192         assertThat( command.getCommandType() ).isEqualTo( BYE_ACK );
193         assertThat( command.getData() ).isNull();
194 
195         command = decoder.decode();
196         assertThat( command.getCommandType() ).isEqualTo( BYE_ACK );
197         assertThat( command.getData() ).isNull();
198 
199         decoder.close();
200     }
201 
202     @Test( expected = EOFException.class )
203     public void testIncompleteCommand() throws IOException
204     {
205 
206         ByteArrayInputStream is = new ByteArrayInputStream( ":maven-surefire-command:".getBytes() );
207         LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
208         decoder.decode();
209         fail();
210     }
211 
212     @Test( expected = EOFException.class )
213     public void testIncompleteCommandStart() throws IOException
214     {
215 
216         ByteArrayInputStream is = new ByteArrayInputStream( new byte[] {':', '\r'} );
217         LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
218         decoder.decode();
219         fail();
220     }
221 
222     @Test( expected = EOFException.class )
223     public void shouldNotDecodeCorruptedCommand() throws IOException
224     {
225         String cmd = ":maven-surefire-command:bye-ack ::maven-surefire-command:";
226         InputStream is = new ByteArrayInputStream( cmd.getBytes() );
227         LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
228 
229         decoder.decode();
230     }
231 
232     @Test
233     public void shouldSkipCorruptedCommand() throws IOException
234     {
235         String cmd = ":maven-surefire-command:bye-ack\r\n::maven-surefire-command:noop:";
236         InputStream is = new ByteArrayInputStream( cmd.getBytes() );
237         LegacyMasterProcessChannelDecoder decoder = new LegacyMasterProcessChannelDecoder( newChannel( is ) );
238 
239         Command command = decoder.decode();
240         assertThat( command.getCommandType() ).isSameAs( NOOP );
241         assertNull( command.getData() );
242     }
243 }