View Javadoc

1   // Copyright (C) 2000 - 2009 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 junit.framework.TestCase;
25  
26  import net.grinder.common.Test;
27  import net.grinder.common.StubTest;
28  import net.grinder.engine.common.EngineException;
29  import net.grinder.engine.process.DispatchContext.DispatchStateException;
30  import net.grinder.script.InvalidContextException;
31  import net.grinder.script.Statistics.StatisticsForTest;
32  import net.grinder.scriptengine.Instrumenter;
33  import net.grinder.statistics.StatisticsIndexMap;
34  import net.grinder.statistics.StatisticsServicesImplementation;
35  import net.grinder.statistics.StatisticsSet;
36  import net.grinder.statistics.StatisticsSetFactory;
37  import net.grinder.testutility.AssertUtilities;
38  import net.grinder.testutility.RandomStubFactory;
39  import net.grinder.testutility.Time;
40  import net.grinder.util.StandardTimeAuthority;
41  
42  
43  /**
44   * Unit test case for <code>TestData</code>.
45   *
46   * @author Philip Aston
47   */
48  public class TestTestData extends TestCase {
49  
50    private static final StatisticsIndexMap.LongSampleIndex s_timedTestsIndex;
51    private static final StatisticsIndexMap.LongIndex s_untimedTestsIndex;
52  
53    static {
54      final StatisticsIndexMap indexMap =
55        StatisticsServicesImplementation.getInstance().getStatisticsIndexMap();
56  
57      s_timedTestsIndex= indexMap.getLongSampleIndex("timedTests");
58      s_untimedTestsIndex= indexMap.getLongIndex("untimedTests");
59    }
60  
61  
62    private final StatisticsSetFactory m_statisticsSetFactory =
63      StatisticsServicesImplementation.getInstance().getStatisticsSetFactory();
64  
65    private final RandomStubFactory<Instrumenter> m_instrumenterStubFactory =
66      RandomStubFactory.create(Instrumenter.class);
67    private final Instrumenter m_instrumenter =
68      m_instrumenterStubFactory.getStub();
69  
70    private final RandomStubFactory<TestStatisticsHelper>
71      m_testStatisticsHelperStubFactory =
72        RandomStubFactory.create(TestStatisticsHelper.class);
73    private final TestStatisticsHelper m_testStatisticsHelper =
74      m_testStatisticsHelperStubFactory.getStub();
75  
76    private final StubThreadContextLocator m_threadContextLocator =
77      new StubThreadContextLocator();
78    private final RandomStubFactory<ThreadContext> m_threadContextStubFactory =
79      RandomStubFactory.create(ThreadContext.class);
80    private final ThreadContext m_threadContext =
81      m_threadContextStubFactory.getStub();
82  
83    private final StandardTimeAuthority m_timeAuthority =
84      new StandardTimeAuthority();
85  
86    public void testCreateProxy() throws Exception {
87      final Test test1 = new StubTest(1, "test1");
88  
89      final TestData testData =
90        new TestData(null, m_statisticsSetFactory, null,
91                     m_timeAuthority, m_instrumenter, test1);
92  
93      final Object original = new Object();
94  
95      testData.createProxy(original);
96  
97      m_instrumenterStubFactory.assertSuccess(
98        "createInstrumentedProxy", test1, testData, original);
99      m_instrumenterStubFactory.assertNoMoreCalls();
100   }
101 
102   public void testDispatch() throws Exception {
103     final Test test1 = new StubTest(1, "test1");
104 
105     final TestData testData =
106       new TestData(m_threadContextLocator,
107                    m_statisticsSetFactory,
108                    m_testStatisticsHelper,
109                    m_timeAuthority,
110                    m_instrumenter,
111                    test1);
112 
113     assertSame(test1, testData.getTest());
114     final StatisticsSet statistics = testData.getTestStatistics();
115     assertNotNull(statistics);
116 
117     // 1. Happy case.
118     try {
119       testData.start();
120       fail("Expected EngineException");
121     }
122     catch (EngineException e) {
123       AssertUtilities.assertContains(e.getMessage(), "Only Worker Threads");
124     }
125 
126     m_threadContextLocator.set(m_threadContext);
127 
128     testData.start();
129 
130     m_threadContextStubFactory.assertSuccess("getDispatchResultReporter");
131     final DispatchContext dispatchContext =
132       (DispatchContext) m_threadContextStubFactory.assertSuccess(
133       "pushDispatchContext", DispatchContext.class).getParameters()[0];
134     m_threadContextStubFactory.assertNoMoreCalls();
135 
136     testData.end(true);
137 
138     m_threadContextStubFactory.assertSuccess("popDispatchContext");
139     m_threadContextStubFactory.assertNoMoreCalls();
140 
141     // Test statistics not updated until we report.
142     m_testStatisticsHelperStubFactory.assertNoMoreCalls();
143     m_testStatisticsHelperStubFactory.setResult("getSuccess", Boolean.TRUE);
144 
145     // Calling report() is the only way to reset the dispatcher.
146     dispatchContext.report();
147 
148     m_testStatisticsHelperStubFactory.assertSuccess(
149       "recordTest", StatisticsSet.class, Long.class);
150 
151     m_testStatisticsHelperStubFactory.assertSuccess(
152       "getSuccess", StatisticsSet.class);
153 
154     m_testStatisticsHelperStubFactory.assertNoMoreCalls();
155 
156     // 2. Nested case.
157     testData.start();
158 
159     m_threadContextStubFactory.assertSuccess(
160       "pushDispatchContext", DispatchContext.class);
161     m_threadContextStubFactory.assertNoMoreCalls();
162 
163     testData.start();
164     m_threadContextStubFactory.assertNoMoreCalls();
165 
166     testData.end(true);
167     m_threadContextStubFactory.assertNoMoreCalls();
168 
169     testData.end(true);
170 
171     m_threadContextStubFactory.assertSuccess("popDispatchContext");
172     m_threadContextStubFactory.assertNoMoreCalls();
173 
174     // Test statistics not updated until we report.
175     m_testStatisticsHelperStubFactory.assertNoMoreCalls();
176 
177     dispatchContext.report();
178 
179     m_testStatisticsHelperStubFactory.assertSuccess(
180       "recordTest", StatisticsSet.class, Long.class);
181 
182     m_testStatisticsHelperStubFactory.assertSuccess(
183       "getSuccess", StatisticsSet.class);
184 
185     m_testStatisticsHelperStubFactory.assertNoMoreCalls();
186 
187     // 3. Unhappy case.
188     testData.start();
189     testData.end(false);
190 
191     // The dispatcher's statistics (not the test statistics) are
192     // marked bad.
193     final StatisticsSet dispatcherStatistics =
194       (StatisticsSet)
195       m_testStatisticsHelperStubFactory.assertSuccess(
196         "setSuccess", StatisticsSet.class, Boolean.class).getParameters()[0];
197     assertNotSame(statistics, dispatcherStatistics);
198     m_testStatisticsHelperStubFactory.assertNoMoreCalls();
199 
200     // 3b. Unhappy case with pause timer left running.
201     dispatchContext.report();
202     m_testStatisticsHelperStubFactory.resetCallHistory();
203 
204     testData.start();
205     dispatchContext.getPauseTimer().start();
206 
207     testData.end(false);
208 
209     // The dispatcher's statistics (not the test statistics) are
210     // marked bad.
211     final StatisticsSet dispatcherStatistics2 =
212       (StatisticsSet)
213       m_testStatisticsHelperStubFactory.assertSuccess(
214         "setSuccess", StatisticsSet.class, Boolean.class).getParameters()[0];
215     assertNotSame(statistics, dispatcherStatistics2);
216     m_testStatisticsHelperStubFactory.assertNoMoreCalls();
217 
218     // 4. Assertion failures.
219     try {
220       testData.start();
221       fail("Expected DispatchStateException");
222     }
223     catch (DispatchStateException e) {
224     }
225 
226     // 5. Lets test the reporting with an error.
227     m_testStatisticsHelperStubFactory.setResult("getSuccess", Boolean.FALSE);
228 
229     dispatchContext.report();
230 
231     m_testStatisticsHelperStubFactory.assertSuccess(
232       "recordTest", StatisticsSet.class, Long.class);
233 
234     m_testStatisticsHelperStubFactory.assertSuccess(
235       "getSuccess", dispatcherStatistics);
236 
237     m_testStatisticsHelperStubFactory.assertSuccess(
238       "incrementErrors", statistics);
239 
240     m_testStatisticsHelperStubFactory.assertNoMoreCalls();
241   }
242 
243   public void testDispatchContext() throws Exception {
244     final Test test1 = new StubTest(1, "test1");
245 
246     // We need a real helper here, not a stub.
247     final TestStatisticsHelper testStatisticsHelper =
248       new TestStatisticsHelperImplementation(
249         StatisticsServicesImplementation.getInstance().getStatisticsIndexMap());
250 
251     final TestData testData =
252       new TestData(m_threadContextLocator,
253                    m_statisticsSetFactory,
254                    testStatisticsHelper,
255                    m_timeAuthority,
256                    m_instrumenter,
257                    test1);
258 
259     assertSame(test1, testData.getTest());
260     final StatisticsSet statistics = testData.getTestStatistics();
261     assertNotNull(statistics);
262 
263     m_threadContextLocator.set(m_threadContext);
264 
265     final long beforeTime = System.currentTimeMillis();
266 
267     testData.start();
268 
269     m_threadContextStubFactory.assertSuccess("getDispatchResultReporter");
270     final DispatchContext dispatchContext =
271       (DispatchContext)
272       m_threadContextStubFactory.assertSuccess(
273         "pushDispatchContext", DispatchContext.class).getParameters()[0];
274     m_threadContextStubFactory.assertNoMoreCalls();
275 
276     testData.end(true);
277 
278     m_threadContextStubFactory.assertSuccess("popDispatchContext");
279     m_threadContextStubFactory.assertNoMoreCalls();
280 
281     // Test statistics not updated until we report.
282     assertEquals(0, statistics.getCount(s_timedTestsIndex));
283 
284     assertSame(test1, dispatchContext.getTest());
285 
286     final StatisticsForTest dispatchStatisticsForTest =
287       dispatchContext.getStatisticsForTest();
288     assertSame(dispatchStatisticsForTest,
289       dispatchContext.getStatisticsForTest());
290     assertEquals(test1, dispatchStatisticsForTest.getTest());
291     assertNotNull(dispatchStatisticsForTest);
292 
293     assertNotNull(dispatchContext.getPauseTimer());
294 
295     final long elapsedTime = dispatchContext.getElapsedTime();
296     assertTrue(elapsedTime >= 0);
297     assertTrue(elapsedTime <= System.currentTimeMillis() - beforeTime);
298 
299     dispatchContext.getPauseTimer().add(new StopWatch(){
300 
301       public void start() { }
302       public void stop() { }
303       public void reset() { }
304       public void add(StopWatch watch) { }
305 
306       public long getTime() throws StopWatchRunningException {
307         return 1000;
308       }
309       public boolean isRunning() {
310         return false;
311       }
312     });
313 
314     // Call will take much less than a second, so we get 0.
315     assertEquals(0, dispatchContext.getElapsedTime());
316 
317     assertEquals(0, dispatchStatisticsForTest.getLong("untimedTests"));
318 
319     // Its easier for the test to update the statistics by hand.
320     dispatchStatisticsForTest.setLong("untimedTests", 2);
321 
322     dispatchContext.report();
323 
324     try {
325       dispatchContext.report();
326       fail("Expected DispatchStateException");
327     }
328     catch (DispatchStateException e) {
329     }
330 
331     // report() will have updated the statistics with a single,
332     // successful, timed test.
333     assertEquals(1, statistics.getCount(s_timedTestsIndex));
334     assertEquals(0, statistics.getValue(s_untimedTestsIndex));
335 
336     assertEquals(-1, dispatchContext.getElapsedTime());
337     assertNull(dispatchContext.getStatisticsForTest());
338 
339     try {
340       dispatchStatisticsForTest.setLong("untimedTests", 2);
341       fail("Expected InvalidContextException");
342     }
343     catch (InvalidContextException e) {
344     }
345 
346     testData.start();
347 
348     assertTrue(dispatchContext.getElapsedTime() < 20);
349     try {
350       Thread.sleep(50);
351     }
352     catch (InterruptedException e) {
353       fail(e.getMessage());
354     }
355 
356     assertTrue(dispatchContext.getElapsedTime() >=
357                50 - Time.J2SE_TIME_ACCURACY_MILLIS);
358 
359     testData.end(true);
360 
361     final long elapsedTime2 = dispatchContext.getElapsedTime();
362     assertTrue(elapsedTime2 >= 50 - Time.J2SE_TIME_ACCURACY_MILLIS);
363     assertTrue(elapsedTime2 <= 200); // Pause timer was reset after last call.
364 
365     assertFalse(statistics.isComposite());
366     dispatchContext.setHasNestedContexts();
367     assertTrue(statistics.isComposite());
368   }
369 
370   public void testDispatchForBug1593169() throws Exception {
371     final TestData testData =
372       new TestData(m_threadContextLocator,
373                    m_statisticsSetFactory,
374                    m_testStatisticsHelper,
375                    m_timeAuthority,
376                    m_instrumenter,
377                    new StubTest(1, "test1"));
378 
379 
380     m_threadContextLocator.set(m_threadContext);
381 
382     final ShutdownException se = new ShutdownException("Bang");
383     m_threadContextStubFactory.setThrows("pushDispatchContext", se);
384 
385     try {
386       testData.start();
387       fail("Expected ShutdownException");
388     }
389     catch (ShutdownException e) {
390     }
391 
392     m_threadContextStubFactory.assertSuccess("getDispatchResultReporter");
393     m_threadContextStubFactory.assertException("pushDispatchContext",
394                                                se,
395                                                DispatchContext.class);
396     m_threadContextStubFactory.assertNoMoreCalls();
397   }
398 }