View Javadoc

1   // Copyright (C) 2006 - 2012 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.process;
23  
24  import static org.junit.Assert.assertEquals;
25  import static org.junit.Assert.assertFalse;
26  import static org.junit.Assert.assertNotNull;
27  import static org.junit.Assert.assertNull;
28  import static org.junit.Assert.assertSame;
29  import static org.junit.Assert.assertTrue;
30  import static org.junit.Assert.fail;
31  import static org.mockito.AdditionalMatchers.and;
32  import static org.mockito.Matchers.contains;
33  import static org.mockito.Matchers.isA;
34  import static org.mockito.Mockito.doThrow;
35  import static org.mockito.Mockito.mock;
36  import static org.mockito.Mockito.times;
37  import static org.mockito.Mockito.verify;
38  import static org.mockito.Mockito.verifyNoMoreInteractions;
39  import static org.mockito.Mockito.when;
40  import net.grinder.common.GrinderProperties;
41  import net.grinder.common.SSLContextFactory;
42  import net.grinder.common.StubTest;
43  import net.grinder.common.ThreadLifeCycleListener;
44  import net.grinder.script.Statistics.StatisticsForTest;
45  import net.grinder.statistics.StatisticsServices;
46  import net.grinder.statistics.StatisticsServicesImplementation;
47  import net.grinder.statistics.StatisticsSet;
48  
49  import org.junit.Before;
50  import org.junit.Test;
51  import org.mockito.Mock;
52  import org.mockito.MockitoAnnotations;
53  import org.slf4j.Logger;
54  import org.slf4j.Marker;
55  import org.slf4j.MarkerFactory;
56  
57  
58  /**
59   * Unit tests for {@link ThreadContextImplementation}.
60   *
61   * @author Philip Aston
62   */
63  public class TestThreadContextImplementation {
64  
65    @Mock private GrinderProperties m_properties;
66    @Mock private SSLContextFactory m_sslContextFactory;
67    @Mock private DispatchContext m_dispatchContext;
68    @Mock private StatisticsForTest m_statisticsForTest;
69    @Mock private Logger m_dataLogger;
70  
71    private final StatisticsServices m_statisticsServices =
72      StatisticsServicesImplementation.getInstance();
73  
74    @Before public void setUp() {
75      MockitoAnnotations.initMocks(this);
76    }
77  
78    @Test public void testBasics() throws Exception {
79      final ThreadContext threadContext =
80        new ThreadContextImplementation(m_properties,
81                                        m_statisticsServices,
82                                        13,
83                                        null);
84  
85      assertEquals(13, threadContext.getThreadNumber());
86      assertEquals(-1, threadContext.getRunNumber());
87  
88      assertNull(threadContext.getThreadSSLContextFactory());
89      threadContext.setThreadSSLContextFactory(m_sslContextFactory);
90      assertSame(m_sslContextFactory, threadContext.getThreadSSLContextFactory());
91    }
92  
93    @Test public void testDispatchResultReporter() throws Exception {
94  
95      final ThreadContext threadContext =
96        new ThreadContextImplementation(m_properties,
97                                        m_statisticsServices,
98                                        1,
99                                        m_dataLogger);
100 
101     final DispatchResultReporter dispatchResultReporter =
102       threadContext.getDispatchResultReporter();
103 
104     final net.grinder.common.Test test = new StubTest(22, "test");
105 
106     final StatisticsSet statistics =
107       m_statisticsServices.getStatisticsSetFactory().create();
108 
109     dispatchResultReporter.report(test, 123456, statistics);
110 
111     verify(m_dataLogger).info(and(contains("22"),
112                                   contains("123456")),
113                               isA(DataLogArguments.class));
114   }
115 
116   @Test public void testNullDispatchResultReporter() throws Exception {
117 
118     when(m_properties.getProperty("grinder.logData")).thenReturn("false");
119 
120     final ThreadContext threadContext =
121       new ThreadContextImplementation(m_properties,
122                                       m_statisticsServices,
123                                       1,
124                                       m_dataLogger);
125 
126     final DispatchResultReporter dispatchResultReporter =
127       threadContext.getDispatchResultReporter();
128 
129     final net.grinder.common.Test test = new StubTest(22, "test");
130 
131     final StatisticsSet statistics =
132       m_statisticsServices.getStatisticsSetFactory().create();
133 
134     dispatchResultReporter.report(test, 123456, statistics);
135 
136     verifyNoMoreInteractions(m_dataLogger);
137   }
138 
139   @Test public void testDispatchContext() throws Exception {
140     final ThreadContext threadContext =
141       new ThreadContextImplementation(m_properties,
142                                       m_statisticsServices,
143                                       1,
144                                       null);
145 
146     assertNull(threadContext.getStatisticsForCurrentTest());
147     assertNull(threadContext.getStatisticsForLastTest());
148 
149     try {
150       threadContext.popDispatchContext();
151       fail("Expected AssertionError");
152     }
153     catch (AssertionError e) {
154     }
155 
156     when(m_dispatchContext.getTest()).thenReturn(new StubTest(14, "test"));
157 
158     when(m_dispatchContext.getStatisticsForTest())
159       .thenReturn(m_statisticsForTest);
160 
161     threadContext.pushDispatchContext(m_dispatchContext);
162 
163     verify(m_dispatchContext).getLogMarker();
164 
165     assertSame(m_statisticsForTest,
166                threadContext.getStatisticsForCurrentTest());
167     assertNull(threadContext.getStatisticsForLastTest());
168 
169     verify(m_dispatchContext).getStatisticsForTest();
170     verifyNoMoreInteractions(m_dispatchContext);
171 
172     threadContext.popDispatchContext();
173 
174     verify(m_dispatchContext, times(2)).getStatisticsForTest();
175     verify(m_dispatchContext).report();
176     verifyNoMoreInteractions(m_dispatchContext);
177 
178     assertSame(m_statisticsForTest, threadContext.getStatisticsForLastTest());
179     assertNull(threadContext.getStatisticsForCurrentTest());
180 
181     final DispatchContext anotherDispatchContext = mock(DispatchContext.class);
182     when(anotherDispatchContext.getTest())
183       .thenReturn(new StubTest(3, "another test"));
184 
185     final StopWatch stopWatch2 = mock(StopWatch.class);
186     when(m_dispatchContext.getPauseTimer()).thenReturn(stopWatch2);
187 
188     final StopWatch stopWatch = mock(StopWatch.class);
189     when(anotherDispatchContext.getPauseTimer()).thenReturn(stopWatch);
190 
191     threadContext.pushDispatchContext(anotherDispatchContext);
192     threadContext.pushDispatchContext(m_dispatchContext);
193 
194     threadContext.popDispatchContext();
195 
196     verify(m_dispatchContext).getPauseTimer();
197     verify(m_dispatchContext, times(3)).getStatisticsForTest();
198     verify(m_dispatchContext, times(2)).report();
199 
200     verify(anotherDispatchContext).getPauseTimer();
201 
202     verify(stopWatch).add(stopWatch2);
203 
204     verifyNoMoreInteractions(stopWatch, stopWatch2);
205 
206     threadContext.pauseClock();
207     verify(anotherDispatchContext, times(2)).getPauseTimer();
208     verify(stopWatch).start();
209 
210     threadContext.resumeClock();
211     verify(anotherDispatchContext, times(3)).getPauseTimer();
212     verify(stopWatch).stop();
213 
214     threadContext.popDispatchContext();
215 
216     verify(anotherDispatchContext).getStatisticsForTest();
217     verify(anotherDispatchContext).report();
218 
219     threadContext.pauseClock();
220     threadContext.resumeClock();
221 
222     threadContext.fireBeginThreadEvent();
223     threadContext.fireBeginRunEvent();
224     threadContext.fireEndRunEvent();
225     threadContext.fireBeginShutdownEvent();
226     threadContext.fireEndThreadEvent();
227 
228     try {
229       threadContext.popDispatchContext();
230       fail("Expected AssertionError");
231     }
232     catch (AssertionError e) {
233     }
234   }
235 
236   @Test public void testEvents() throws Exception {
237     final ThreadLifeCycleListener threadLifeCycleListener =
238       mock(ThreadLifeCycleListener.class);
239 
240     final ThreadContext threadContext =
241       new ThreadContextImplementation(m_properties,
242                                       m_statisticsServices,
243                                       1,
244                                       null);
245 
246     threadContext.registerThreadLifeCycleListener(threadLifeCycleListener);
247 
248     threadContext.fireBeginThreadEvent();
249     verify(threadLifeCycleListener).beginThread();
250 
251     threadContext.fireBeginRunEvent();
252     verify(threadLifeCycleListener).beginRun();
253 
254     threadContext.fireEndRunEvent();
255     verify(threadLifeCycleListener).endRun();
256 
257     threadContext.fireBeginShutdownEvent();
258     verify(threadLifeCycleListener).beginShutdown();
259 
260     threadContext.fireEndThreadEvent();
261     verify(threadLifeCycleListener).endThread();
262 
263     verifyNoMoreInteractions(threadLifeCycleListener);
264 
265     threadContext.fireEndThreadEvent();
266     verify(threadLifeCycleListener, times(2)).endThread();
267     verifyNoMoreInteractions(threadLifeCycleListener);
268 
269     threadContext.removeThreadLifeCycleListener(threadLifeCycleListener);
270 
271     threadContext.fireEndThreadEvent();
272     verifyNoMoreInteractions(threadLifeCycleListener);
273   }
274 
275   @Test public void testDelayReports() throws Exception {
276     final ThreadContext threadContext =
277       new ThreadContextImplementation(m_properties,
278                                       m_statisticsServices,
279                                       1,
280                                       null);
281 
282     when(m_dispatchContext.getTest()).thenReturn(new StubTest(14, "test"));
283     when(m_dispatchContext.getStatisticsForTest())
284     .thenReturn(m_statisticsForTest);
285 
286     threadContext.pushDispatchContext(m_dispatchContext);
287     verify(m_dispatchContext).getLogMarker();
288 
289     threadContext.setDelayReports(false);
290     threadContext.setDelayReports(true);
291     verifyNoMoreInteractions(m_dispatchContext);
292 
293     assertSame(m_statisticsForTest,
294                threadContext.getStatisticsForCurrentTest());
295     assertNull(threadContext.getStatisticsForLastTest());
296 
297     verify(m_dispatchContext).getStatisticsForTest();
298 
299     threadContext.popDispatchContext();
300     verify(m_dispatchContext, times(2)).getStatisticsForTest();
301 
302     assertNotNull(threadContext.getStatisticsForLastTest());
303     assertNull(threadContext.getStatisticsForCurrentTest());
304 
305     // Now have a pending context.
306 
307     threadContext.reportPendingDispatchContext();
308     verify(m_dispatchContext).report();
309     threadContext.reportPendingDispatchContext();
310     verifyNoMoreInteractions(m_dispatchContext);
311 
312     // Test flush at beginning of next test (same test)
313     threadContext.pushDispatchContext(m_dispatchContext);
314     verify(m_dispatchContext, times(2)).getLogMarker();
315     threadContext.popDispatchContext();
316     verify(m_dispatchContext, times(3)).getStatisticsForTest();
317     threadContext.pushDispatchContext(m_dispatchContext);
318     verify(m_dispatchContext, times(2)).report();
319     verify(m_dispatchContext, times(3)).getLogMarker();
320     threadContext.popDispatchContext();
321     verify(m_dispatchContext, times(4)).getStatisticsForTest();
322     threadContext.reportPendingDispatchContext();
323     verify(m_dispatchContext, times(3)).report();
324 
325     // Test flush at beginning of next test (different test).
326     threadContext.pushDispatchContext(m_dispatchContext);
327     verify(m_dispatchContext, times(4)).getLogMarker();
328     threadContext.popDispatchContext();
329 
330     when(m_dispatchContext.getTest()).thenReturn(new StubTest(16, "abc"));
331 
332     verify(m_dispatchContext, times(5)).getStatisticsForTest();
333     threadContext.pushDispatchContext(m_dispatchContext);
334     verify(m_dispatchContext, times(4)).report();
335     verify(m_dispatchContext, times(5)).getLogMarker();
336     threadContext.popDispatchContext();
337     verify(m_dispatchContext, times(6)).getStatisticsForTest();
338     threadContext.reportPendingDispatchContext();
339     verify(m_dispatchContext, times(5)).report();
340 
341     // Test flushed at end of run.
342     threadContext.pushDispatchContext(m_dispatchContext);
343     verify(m_dispatchContext, times(6)).getLogMarker();
344     threadContext.popDispatchContext();
345     verify(m_dispatchContext, times(7)).getStatisticsForTest();
346     threadContext.fireBeginRunEvent();
347     verifyNoMoreInteractions(m_dispatchContext);
348     threadContext.fireEndRunEvent();
349     verify(m_dispatchContext, times(6)).report();
350 
351     // Test flushed if delay reports is turned off.
352     threadContext.pushDispatchContext(m_dispatchContext);
353     verify(m_dispatchContext, times(7)).getLogMarker();
354     threadContext.popDispatchContext();
355     verify(m_dispatchContext, times(8)).getStatisticsForTest();
356     verifyNoMoreInteractions(m_dispatchContext);
357     threadContext.setDelayReports(false);
358     verify(m_dispatchContext, times(7)).report();
359     verifyNoMoreInteractions(m_dispatchContext);
360   }
361 
362   @Test public void testDispatchContextWhenShuttingDown() throws Exception {
363     final ThreadContext threadContext =
364       new ThreadContextImplementation(m_properties,
365                                       m_statisticsServices,
366                                       1,
367                                       null);
368     threadContext.shutdown();
369 
370     for (int i=0; i<2; ++i) {
371       try {
372         threadContext.pushDispatchContext(m_dispatchContext);
373         fail("Expected ShutdownException");
374       }
375       catch (ShutdownException e) {
376       }
377 
378       threadContext.popDispatchContext(); // No-op.
379 
380       verifyNoMoreInteractions(m_dispatchContext);
381     }
382   }
383 
384   @Test public void testWithBadDispatchContext() throws Exception {
385     final ThreadContext threadContext =
386       new ThreadContextImplementation(m_properties,
387                                       m_statisticsServices,
388                                       1,
389                                       null);
390 
391     when(m_dispatchContext.getTest()).thenReturn(new StubTest(14, "test"));
392 
393     final Throwable t = new DispatchContext.DispatchStateException("foo");
394     doThrow(t).when(m_dispatchContext).report();
395 
396     threadContext.pushDispatchContext(m_dispatchContext);
397 
398     try {
399       threadContext.popDispatchContext();
400       fail("Expected AssertionError");
401     }
402     catch (AssertionError e) {
403       assertSame(t, e.getCause());
404     }
405   }
406 
407   @Test public void testWithBadPendingDispatchContext() throws Exception {
408     final ThreadContext threadContext =
409       new ThreadContextImplementation(m_properties,
410                                       m_statisticsServices,
411                                       1,
412                                       null);
413 
414     when(m_dispatchContext.getTest()).thenReturn(new StubTest(14, "test"));
415 
416     threadContext.setDelayReports(true);
417 
418     final Throwable t = new DispatchContext.DispatchStateException("foo");
419     doThrow(t).when(m_dispatchContext).report();
420 
421     threadContext.pushDispatchContext(m_dispatchContext);
422     threadContext.popDispatchContext();
423 
424     try {
425       threadContext.reportPendingDispatchContext();
426       fail("Expected AssertionError");
427     }
428     catch (AssertionError e) {
429       assertSame(t, e.getCause());
430     }
431   }
432 
433   @Test public void testGetLogMarker() throws Exception {
434     final ThreadContext threadContext =
435       new ThreadContextImplementation(m_properties,
436                                       m_statisticsServices,
437                                       2,
438                                       null);
439 
440     final Marker marker = threadContext.getLogMarker();
441     assertEquals("thread-2", marker.getName());
442     assertFalse(marker.hasReferences());
443   }
444 
445   @Test public void testGetLogMarkerWithRun() throws Exception {
446     final ThreadContext threadContext =
447       new ThreadContextImplementation(m_properties,
448                                       m_statisticsServices,
449                                       2,
450                                       null);
451 
452     threadContext.setCurrentRunNumber(3);
453 
454     final Marker marker = threadContext.getLogMarker();
455     assertEquals("thread-2", marker.getName());
456     assertTrue(marker.contains("run-3"));
457 
458     threadContext.setCurrentRunNumber(4);
459     assertTrue(marker.contains("run-4"));
460 
461     threadContext.setCurrentRunNumber(-1);
462     assertFalse(marker.hasReferences());
463   }
464 
465   @Test public void testGetLogMarkerWithTest() throws Exception {
466     final ThreadContextImplementation threadContext =
467       new ThreadContextImplementation(m_properties,
468                                       m_statisticsServices,
469                                       2,
470                                       null);
471 
472     threadContext.setTestLogMarker(MarkerFactory.getMarker("test-3"));
473 
474     final Marker marker = threadContext.getLogMarker();
475     assertEquals("thread-2", marker.getName());
476     assertTrue(marker.contains("test-3"));
477 
478     threadContext.setTestLogMarker(MarkerFactory.getMarker("test-4"));
479     assertTrue(marker.contains("test-4"));
480 
481     threadContext.setTestLogMarker(null);
482     assertFalse(marker.hasReferences());
483   }
484 }