View Javadoc

1   // Copyright (C) 2004 - 2011 Philip Aston
2   // All rights reserved.
3   //
4   // This file is part of The Grinder software distribution. Refer to
5   // the file LICENSE which is part of The Grinder distribution for
6   // licensing details. The Grinder distribution is available on the
7   // Internet at http://grinder.sourceforge.net/
8   //
9   // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
12  // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
13  // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
14  // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16  // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17  // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
18  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
20  // OF THE POSSIBILITY OF SUCH DAMAGE.
21  
22  package net.grinder.engine.agent;
23  
24  import static org.junit.Assert.assertEquals;
25  import static org.junit.Assert.assertTrue;
26  import static org.junit.Assert.fail;
27  
28  import java.io.ByteArrayOutputStream;
29  import java.io.OutputStream;
30  import java.io.PrintWriter;
31  import java.util.List;
32  
33  import net.grinder.common.GrinderException;
34  import net.grinder.common.UncheckedInterruptedException;
35  
36  import org.junit.Test;
37  
38  
39  /**
40   * Unit tests for {@link ProcessWorker}.
41   *
42   * @author Philip Aston
43   */
44  public class TestProcessWorker {
45  
46    private static final String s_testClasspath =
47      System.getProperty("java.class.path");
48  
49    private ByteArrayOutputStream m_outputStream = new ByteArrayOutputStream();
50    private ByteArrayOutputStream m_errorStream = new ByteArrayOutputStream();
51    private final StubAgentIdentity m_agentIdentity =
52      new StubAgentIdentity("test");
53  
54    @Test public void testWithInvalidProcess() throws Exception {
55  
56      final CommandLine commandLine =
57        new MyCommandLine("No such process blah blah blah",
58                          "some argument");
59  
60      try {
61        new ProcessWorker(m_agentIdentity.createWorkerIdentity(),
62                          commandLine,
63                          m_outputStream,
64                          m_errorStream);
65        fail("Expected GrinderException");
66      }
67      catch (GrinderException e) {
68      }
69  
70      assertEquals(0, m_outputStream.toByteArray().length);
71      assertEquals(0, m_errorStream.toByteArray().length);
72    }
73  
74    @Test public void testWithInvalidJavaClass() throws Exception {
75  
76      final CommandLine commandLine =
77        new MyCommandLine("java",
78                          "some nonsense class");
79  
80      final ProcessWorker childProcess =
81        new ProcessWorker(m_agentIdentity.createWorkerIdentity(),
82                          commandLine,
83                          m_outputStream,
84                          m_errorStream);
85  
86      childProcess.waitFor();
87  
88      assertEquals("test-0", childProcess.getIdentity().getName());
89      assertEquals(0, m_outputStream.toByteArray().length);
90      assertTrue(m_errorStream.toByteArray().length > 0);
91    }
92  
93    @Test public void testArguments() throws Exception {
94  
95      final CommandLine commandLine =
96        new MyCommandLine("java",
97                          "-classpath",
98                          s_testClasspath,
99                          EchoClass.class.getName(),
100                         "some stuff",
101                         "blah",
102                         "3810 32190 130100''''");
103 
104     final ProcessWorker childProcess =
105       new ProcessWorker(m_agentIdentity.createWorkerIdentity(),
106                         commandLine,
107                         m_outputStream,
108                         m_errorStream);
109 
110     final PrintWriter out =
111       new PrintWriter(childProcess.getCommunicationStream());
112     out.print(EchoClass.ECHO_ARGUMENTS);
113     out.print('\n');
114     out.flush();
115     out.close();
116 
117     childProcess.waitFor();
118 
119     final StringBuffer expected = new StringBuffer();
120 
121     final List<String> command = commandLine.getCommandList();
122 
123     for (String argument : command.subList(4, command.size())) {
124       expected.append(argument);
125     }
126 
127     assertEquals("", new String(m_errorStream.toByteArray()));
128 
129     assertEquals(expected.toString(),
130                  new String(m_outputStream.toByteArray()));
131 
132     assertEquals("test-0", childProcess.getIdentity().getName());
133   }
134 
135   @Test public void testConcurrentProcessing() throws Exception {
136     final CommandLine commandLine =
137       new MyCommandLine("java",
138                         "-classpath",
139                         s_testClasspath,
140                         EchoClass.class.getName());
141 
142     final ProcessWorker childProcess =
143       new ProcessWorker(m_agentIdentity.createWorkerIdentity(),
144                         commandLine,
145                         m_outputStream,
146                         m_errorStream);
147 
148     final PrintWriter out =
149       new PrintWriter(childProcess.getCommunicationStream());
150     out.print(EchoClass.ECHO_STREAMS);
151     out.print('\n');
152     out.flush();
153 
154     final Thread t =
155       new Thread(new WriteData(childProcess.getCommunicationStream()));
156     t.start();
157 
158     childProcess.waitFor();
159 
160     t.join(1000);
161 
162     assertTrue(!t.isAlive());
163 
164     final byte[] outputBytes = m_outputStream.toByteArray();
165     final byte[] errorBytes = m_errorStream.toByteArray();
166 
167     assertEquals(256, outputBytes.length);
168     assertEquals(256, errorBytes.length);
169 
170     for (int i=0; i<256; ++i) {
171       assertEquals(i, outputBytes[i] & 0xFF);
172       assertEquals(i, errorBytes[i] & 0xFF);
173     }
174 
175     out.close();
176   }
177 
178   @Test public void testDestroy() throws Exception {
179     final CommandLine commandLine =
180       new MyCommandLine("java",
181                         "-classpath",
182                         s_testClasspath,
183                         EchoClass.class.getName());
184 
185     final ProcessWorker childProcess =
186       new ProcessWorker(m_agentIdentity.createWorkerIdentity(),
187                         commandLine,
188                         m_outputStream,
189                         m_errorStream);
190 
191     childProcess.destroy();
192 
193     // Won't return if process is running. Actual exit value is
194     // platform specific, and sometimes 0 on win32!
195     childProcess.waitFor();
196   }
197 
198   @Test public void testDestroyInterrupted() throws Exception {
199     final CommandLine commandLine =
200       new MyCommandLine("java",
201                         "-classpath",
202                         s_testClasspath,
203                         EchoClass.class.getName());
204 
205     final ProcessWorker childProcess =
206       new ProcessWorker(m_agentIdentity.createWorkerIdentity(),
207                         commandLine,
208                         m_outputStream,
209                         m_errorStream);
210 
211     Thread.currentThread().interrupt();
212 
213     try {
214       childProcess.destroy();
215       fail("Expected UncheckedInterruptedException");
216     }
217     catch (UncheckedInterruptedException e) {
218     }
219 
220     childProcess.destroy();
221 
222     // Won't return if process is running. Actual exit value is
223     // platform specific, and sometimes 0 on win32!
224     childProcess.waitFor();
225   }
226 
227   @Test public void testWaitForInterrupted() throws Exception {
228     final CommandLine commandLine =
229       new MyCommandLine("java",
230                         "-classpath",
231                         s_testClasspath,
232                         EchoClass.class.getName());
233 
234     final ProcessWorker childProcess =
235       new ProcessWorker(m_agentIdentity.createWorkerIdentity(),
236                         commandLine,
237                         m_outputStream,
238                         m_errorStream);
239 
240     childProcess.destroy();
241 
242     Thread.currentThread().interrupt();
243 
244     try {
245       childProcess.waitFor();
246       fail("Expected UncheckedInterruptedException");
247     }
248     catch (UncheckedInterruptedException e) {
249     }
250 
251     // Won't return if process is running. Actual exit value is
252     // platform specific, and sometimes 0 on win32!
253     childProcess.waitFor();
254   }
255 
256   private static final class WriteData implements Runnable {
257     private final OutputStream m_outputStream;
258 
259     public WriteData(OutputStream outputStream) {
260       m_outputStream = outputStream;
261     }
262 
263     public void run() {
264       try {
265         for (int i=0; i<256; ++i) {
266           m_outputStream.write(i);
267           Thread.sleep(1);
268         }
269         m_outputStream.close();
270       }
271       catch (Exception e) {
272         e.printStackTrace();
273       }
274     }
275   }
276 }