1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.surefire.booterclient.lazytestprovider;
20
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.util.Iterator;
24 import java.util.NoSuchElementException;
25
26 import org.apache.maven.surefire.api.booter.Command;
27 import org.apache.maven.surefire.api.booter.MasterProcessChannelDecoder;
28 import org.apache.maven.surefire.booter.ForkedNodeArg;
29 import org.apache.maven.surefire.booter.spi.CommandChannelDecoder;
30 import org.junit.Rule;
31 import org.junit.Test;
32 import org.junit.rules.ExpectedException;
33
34 import static java.nio.channels.Channels.newChannel;
35 import static java.nio.charset.StandardCharsets.UTF_8;
36 import static org.apache.maven.plugin.surefire.booterclient.lazytestprovider.TestLessInputStream.TestLessInputStreamBuilder;
37 import static org.apache.maven.surefire.api.booter.Command.SKIP_SINCE_NEXT_TEST;
38 import static org.apache.maven.surefire.api.booter.MasterProcessCommand.NOOP;
39 import static org.apache.maven.surefire.api.booter.MasterProcessCommand.SHUTDOWN;
40 import static org.apache.maven.surefire.api.booter.Shutdown.EXIT;
41 import static org.apache.maven.surefire.api.booter.Shutdown.KILL;
42 import static org.hamcrest.MatcherAssert.assertThat;
43 import static org.hamcrest.Matchers.is;
44 import static org.hamcrest.Matchers.notNullValue;
45 import static org.junit.Assert.assertFalse;
46 import static org.junit.Assert.assertTrue;
47 import static org.junit.Assert.fail;
48
49
50
51
52
53
54
55 public class TestLessInputStreamBuilderTest {
56 @Rule
57 public final ExpectedException e = ExpectedException.none();
58
59 @Test
60 public void cachableCommandsShouldBeIterableWithStillOpenIterator() {
61 TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
62 TestLessInputStream is = builder.build();
63 Iterator<Command> iterator = builder.getIterableCachable().iterator();
64
65 assertFalse(iterator.hasNext());
66
67 builder.getCachableCommands().skipSinceNextTest();
68 assertTrue(iterator.hasNext());
69 assertThat(iterator.next(), is(SKIP_SINCE_NEXT_TEST));
70
71 assertFalse(iterator.hasNext());
72
73 builder.getCachableCommands().shutdown(KILL);
74 assertTrue(iterator.hasNext());
75 assertThat(iterator.next(), is(new Command(SHUTDOWN, "KILL")));
76
77 builder.removeStream(is);
78 }
79
80 @Test
81 public void immediateCommands() throws IOException {
82 TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
83 TestLessInputStream is = builder.build();
84 assertThat(is.availablePermits(), is(0));
85 is.noop();
86 assertThat(is.availablePermits(), is(1));
87 is.beforeNextCommand();
88 assertThat(is.availablePermits(), is(0));
89 assertThat(is.nextCommand(), is(Command.NOOP));
90 assertThat(is.availablePermits(), is(0));
91 e.expect(NoSuchElementException.class);
92 is.nextCommand();
93 }
94
95 @Test
96 public void combinedCommands() throws IOException {
97 TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
98 TestLessInputStream is = builder.build();
99 assertThat(is.availablePermits(), is(0));
100 builder.getCachableCommands().skipSinceNextTest();
101 is.noop();
102 assertThat(is.availablePermits(), is(2));
103 is.beforeNextCommand();
104 assertThat(is.availablePermits(), is(1));
105 assertThat(is.nextCommand(), is(Command.NOOP));
106 assertThat(is.availablePermits(), is(1));
107 builder.getCachableCommands().skipSinceNextTest();
108 assertThat(is.availablePermits(), is(1));
109 builder.getImmediateCommands().shutdown(EXIT);
110 assertThat(is.availablePermits(), is(2));
111 is.beforeNextCommand();
112 assertThat(is.nextCommand().getCommandType(), is(SHUTDOWN));
113 assertThat(is.availablePermits(), is(1));
114 is.beforeNextCommand();
115 assertThat(is.nextCommand(), is(SKIP_SINCE_NEXT_TEST));
116 assertThat(is.availablePermits(), is(0));
117 builder.getImmediateCommands().noop();
118 assertThat(is.availablePermits(), is(1));
119 builder.getCachableCommands().shutdown(EXIT);
120 builder.getCachableCommands().shutdown(EXIT);
121 assertThat(is.availablePermits(), is(2));
122 is.beforeNextCommand();
123 assertThat(is.nextCommand(), is(Command.NOOP));
124 assertThat(is.availablePermits(), is(1));
125 is.beforeNextCommand();
126 assertThat(is.nextCommand().getCommandType(), is(SHUTDOWN));
127 assertThat(is.availablePermits(), is(0));
128 e.expect(NoSuchElementException.class);
129 is.nextCommand();
130 }
131
132 @Test
133 public void shouldDecodeTwoCommands() throws IOException {
134 TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
135 final TestLessInputStream pluginIs = builder.build();
136 InputStream is = new InputStream() {
137 private byte[] buffer;
138 private int idx;
139 private boolean isLastBuffer;
140
141 @Override
142 public int read() throws IOException {
143 if (buffer == null) {
144 idx = 0;
145 Command cmd = pluginIs.readNextCommand();
146 if (cmd != null) {
147 if (cmd.getCommandType() == SHUTDOWN) {
148 buffer = (":maven-surefire-command:\u0008:shutdown:\u0005:UTF-8:\u0000\u0000\u0000\u0004:"
149 + cmd.toShutdownData().getParam() + ":")
150 .getBytes(UTF_8);
151 } else if (cmd.getCommandType() == NOOP) {
152 buffer = ":maven-surefire-command:\u0004:noop:".getBytes(UTF_8);
153 isLastBuffer = true;
154 } else {
155 fail();
156 }
157 }
158 }
159
160 if (buffer != null) {
161 byte b = buffer[idx++];
162 if (idx == buffer.length) {
163 buffer = null;
164 idx = 0;
165 }
166 return b;
167 }
168
169 if (isLastBuffer) {
170 return -1;
171 }
172 throw new IOException();
173 }
174 };
175 MasterProcessChannelDecoder decoder = new CommandChannelDecoder(newChannel(is), new ForkedNodeArg(1, false));
176 builder.getImmediateCommands().shutdown(KILL);
177 builder.getImmediateCommands().noop();
178 Command bye = decoder.decode();
179 assertThat(bye, is(notNullValue()));
180 assertThat(bye.getCommandType(), is(SHUTDOWN));
181 assertThat(bye.getData(), is(KILL.name()));
182 Command noop = decoder.decode();
183 assertThat(noop, is(notNullValue()));
184 assertThat(noop.getCommandType(), is(NOOP));
185 }
186
187 @Test(expected = UnsupportedOperationException.class)
188 public void shouldThrowUnsupportedException1() {
189 TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
190 builder.getImmediateCommands().provideNewTest();
191 }
192
193 @Test(expected = UnsupportedOperationException.class)
194 public void shouldThrowUnsupportedException2() {
195 TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
196 builder.getImmediateCommands().skipSinceNextTest();
197 }
198
199 @Test(expected = UnsupportedOperationException.class)
200 public void shouldThrowUnsupportedException3() {
201 TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
202 builder.getImmediateCommands().acknowledgeByeEventReceived();
203 }
204
205 @Test(expected = UnsupportedOperationException.class)
206 public void shouldThrowUnsupportedException4() {
207 TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
208 builder.getCachableCommands().acknowledgeByeEventReceived();
209 }
210
211 @Test(expected = UnsupportedOperationException.class)
212 public void shouldThrowUnsupportedException5() {
213 TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
214 builder.getCachableCommands().provideNewTest();
215 }
216
217 @Test(expected = UnsupportedOperationException.class)
218 public void shouldThrowUnsupportedException6() {
219 TestLessInputStreamBuilder builder = new TestLessInputStreamBuilder();
220 builder.getCachableCommands().noop();
221 }
222 }