1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sourceforge.quexec.proc;
20
21
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26
27 import java.io.IOException;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.List;
31 import java.util.TreeMap;
32 import java.util.Map;
33 import java.util.concurrent.TimeoutException;
34
35 import net.sourceforge.quexec.packet.chars.consumer.StoreCharPacketConsumer;
36 import net.sourceforge.quexec.packet.chars.consumer.StreamCharPacketConsumer;
37 import net.sourceforge.quexec.packet.chars.producer.AbstractReaderCharPacketProducer;
38 import net.sourceforge.quexec.packet.chars.producer.LinewiseCharPacketProducer;
39 import net.sourceforge.quexec.packet.chars.stream.QueueCharPacketStream;
40 import net.sourceforge.quexec.packet.chars.stream.StreamTestUtils;
41 import net.sourceforge.quexec.packet.chars.stream.WriterCharPacketOutputStream;
42
43 import org.junit.After;
44 import org.junit.AfterClass;
45 import org.junit.Before;
46 import org.junit.BeforeClass;
47 import org.junit.Test;
48
49 public class ProcessExecutorTest {
50
51 private static final String[] output = {
52 "bla",
53 "foo",
54 "bar",
55 };
56
57 private ProcessExecutor pexec;
58
59 private StoreCharPacketConsumer storeConsumer;
60
61 private QueueCharPacketStream procOutStream;
62
63 private WriterCharPacketOutputStream procInStream;
64
65 @BeforeClass
66 public static void setUpBeforeClass() throws Exception {
67 }
68
69 @AfterClass
70 public static void tearDownAfterClass() throws Exception {
71 }
72
73 @Before
74 public void setUp() throws Exception {
75 this.pexec = new ProcessExecutor();
76
77 }
78
79 private void connectStoreConsumer() {
80 this.storeConsumer = new StoreCharPacketConsumer();
81
82 AbstractReaderCharPacketProducer producer =
83 new LinewiseCharPacketProducer();
84 producer.setConsumer(this.storeConsumer);
85
86 ReaderProcessOutputConnector connector =
87 new ReaderProcessOutputConnector();
88 connector.setConnectReader(producer);
89
90 this.pexec.setConnector(connector);
91 }
92
93 private void connectInputOutputStreams() {
94 List<ProcessConnector> connList = new ArrayList<ProcessConnector>(2);
95
96 ReaderProcessOutputConnector outConn =
97 new ReaderProcessOutputConnector();
98 AbstractReaderCharPacketProducer producer =
99 new LinewiseCharPacketProducer();
100 StreamCharPacketConsumer consumer =
101 new StreamCharPacketConsumer();
102 this.procOutStream = QueueCharPacketStream.newInstance();
103 consumer.setOutputStream(this.procOutStream);
104 producer.setConsumer(consumer);
105 outConn.setConnectReader(producer);
106 connList.add(outConn);
107
108 WriterProcessInputConnector inpConn = new WriterProcessInputConnector();
109 this.procInStream = new WriterCharPacketOutputStream();
110 inpConn.setConnectWriter(this.procInStream);
111 connList.add(inpConn);
112
113 this.pexec.setConnectors(connList);
114 }
115
116 @After
117 public void tearDown() throws Exception {
118 }
119
120 @Test(timeout=1000)
121 public void runSuccessfulCommandAndCheckReturnCode()
122 throws IOException, InterruptedException, TimeoutException {
123 final int rcVal = 10;
124 this.pexec.execJava(Arrays.asList(
125 ArgToReturnCodeMain.class.getName(),
126 String.valueOf(rcVal)));
127 assertEquals(rcVal, this.pexec.waitFor());
128 }
129
130 @Test(expected=TimeoutException.class)
131 public void runNonTerminatingCommandWithTimeout()
132 throws IOException, InterruptedException, TimeoutException {
133 this.pexec.execJava(NonTerminatingMain.class.getName());
134 this.pexec.waitFor(100);
135 }
136
137 @Test(timeout=10000)
138 public void checkOutputAfterSuccessfulRun()
139 throws IOException, InterruptedException, TimeoutException {
140 final String[] output = {
141 "bla",
142 "foo",
143 "bar",
144 };
145 connectStoreConsumer();
146 List<String> args = new ArrayList<String>(output.length + 1);
147 args.add(EchoArgsMain.class.getName());
148 args.addAll(Arrays.asList(output));
149 this.pexec.execJava(args);
150 assertEquals(0, this.pexec.waitFor());
151 assertEquals(concatenate(output), this.storeConsumer.retrieveData());
152 }
153
154 @Test(timeout=10000)
155 public void checkOutputAfterTimeout()
156 throws IOException, InterruptedException, TimeoutException {
157 connectStoreConsumer();
158 List<String> args = new ArrayList<String>(output.length + 1);
159 args.add(EchoArgsNonTerminatingMain.class.getName());
160 args.addAll(Arrays.asList(output));
161 this.pexec.execJava(args);
162 try {
163 this.pexec.waitFor(1000);
164 fail("timeout should occur");
165 }
166 catch (TimeoutException ignored) {
167
168 }
169 assertEquals(concatenate(output), this.storeConsumer.retrieveData());
170
171 }
172
173 @Test(timeout=1000)
174 public void checkReceiveThroughPacketStream()
175 throws IOException, InterruptedException {
176 connectInputOutputStreams();
177 List<String> args = new ArrayList<String>(output.length + 1);
178 args.add(EchoArgsMain.class.getName());
179 args.addAll(Arrays.asList(output));
180 this.pexec.execJava(args);
181
182 for (int pos = 0; pos < output.length; pos++) {
183 assertFalse(this.procOutStream.isFinished());
184 assertEquals(output[pos] + "\n", this.procOutStream.readPacket());
185 }
186
187 Thread.sleep(100);
188 assertFalse(this.procOutStream.isFinished());
189 assertEquals(0, this.pexec.waitFor());
190 StreamTestUtils.checkStreamFinished(this.procOutStream);
191 }
192
193 @Test(timeout=4000)
194 public void interactiveInputAndOutput()
195 throws IOException, InterruptedException {
196 connectInputOutputStreams();
197 this.pexec.execJava(CatMain.class.getName());
198
199
200 for (int pos = 0; pos < output.length; pos++) {
201 assertFalse(this.procOutStream.isFinished());
202 this.procInStream.sendPacket(output[pos] + "X\n");
203 assertEquals(output[pos] + "X\n", this.procOutStream.readPacket());
204 }
205
206
207 for (int pos = 0; pos < output.length; pos++) {
208 this.procInStream.sendPacket(output[pos] + "Y\n");
209 }
210 this.procInStream.finish();
211
212
213 assertEquals(0, this.pexec.waitFor());
214 for (int pos = 0; pos < output.length; pos++) {
215 assertFalse(this.procOutStream.isFinished());
216 assertEquals(output[pos] + "Y\n", this.procOutStream.readPacket());
217 }
218 assertTrue(this.procOutStream.isFinished());
219 }
220
221 @Test(timeout=5000)
222 public void manipulateProcessEnvironment()
223 throws IOException, InterruptedException {
224 connectInputOutputStreams();
225
226 this.pexec.setClearEnvironment(true);
227 Map<String, String> env = new TreeMap<String, String>();
228 for (int pos = 0; pos < output.length; pos++) {
229 env.put(String.valueOf(pos), output[pos]);
230 }
231 this.pexec.setEnvSettings(env);
232
233 this.pexec.execJava(PrintEnvMain.class.getName());
234 for (int pos = 0; pos < output.length; pos++) {
235 assertFalse(this.procOutStream.isFinished());
236 assertEquals(output[pos] + "\n", this.procOutStream.readPacket());
237 }
238 assertFalse(this.procOutStream.isFinished());
239 this.pexec.waitFor();
240 StreamTestUtils.checkStreamFinished(this.procOutStream);
241 }
242
243 private static String concatenate(String[] l) {
244 StringBuffer buffer = new StringBuffer();
245 for (String s : l) {
246 buffer.append(s);
247 buffer.append("\n");
248 }
249 return buffer.toString();
250 }
251 }