001: /*
002: * @(#)MultiThreadedTestRunnerUTest.java
003: *
004: * Copyright (C) 2002-2003 Matt Albrecht
005: * groboclown@users.sourceforge.net
006: * http://groboutils.sourceforge.net
007: *
008: * Permission is hereby granted, free of charge, to any person obtaining a
009: * copy of this software and associated documentation files (the "Software"),
010: * to deal in the Software without restriction, including without limitation
011: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
012: * and/or sell copies of the Software, and to permit persons to whom the
013: * Software is furnished to do so, subject to the following conditions:
014: *
015: * The above copyright notice and this permission notice shall be included in
016: * all copies or substantial portions of the Software.
017: *
018: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
019: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
020: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
021: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
022: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
023: * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
024: * DEALINGS IN THE SOFTWARE.
025: */
026:
027: package net.sourceforge.groboutils.junit.v1;
028:
029: import net.sourceforge.groboutils.autodoc.v1.AutoDoc;
030: import junit.framework.Test;
031: import junit.framework.TestCase;
032: import junit.framework.TestSuite;
033:
034: import java.io.IOException;
035:
036: /**
037: * Tests the MultiThreadedTestRunner class.
038: *
039: * @author Matt Albrecht <a href="mailto:groboclown@users.sourceforge.net">groboclown@users.sourceforge.net</a>
040: * @since March 1, 2002
041: * @version $Date: 2004/04/09 19:26:52 $
042: */
043: public class MultiThreadedTestRunnerUTest extends TestCase {
044: //-------------------------------------------------------------------------
045: // Standard JUnit Class-specific declarations
046:
047: private static final Class THIS_CLASS = MultiThreadedTestRunnerUTest.class;
048: private static final AutoDoc DOC = new AutoDoc(THIS_CLASS);
049:
050: public MultiThreadedTestRunnerUTest(String name) {
051: super (name);
052: }
053:
054: //-------------------------------------------------------------------------
055: // Tests
056:
057: public void testConstructor1() {
058: DOC.getLog().debug("testConstructor1");
059: try {
060: new MultiThreadedTestRunner(null);
061: fail("did not throw an IllegalArgumentException.");
062: } catch (IllegalArgumentException e) {
063: // check exception text?
064: }
065: }
066:
067: public void testConstructor2() {
068: DOC.getLog().debug("testConstructor2");
069: try {
070: new MultiThreadedTestRunner(new TestRunnable[0]);
071: fail("did not throw an IllegalArgumentException.");
072: } catch (IllegalArgumentException e) {
073: // check exception text?
074: }
075: }
076:
077: static class RunValue1 {
078: public int value;
079: }
080:
081: public synchronized void testRun1() throws Throwable {
082: DOC.getIT().testsIssue(526710);
083: DOC.getLog().debug("testRun1");
084:
085: final RunValue1 runCount = new RunValue1();
086: TestRunnable tr1 = new TestRunnable() {
087: public void runTest() throws Throwable {
088: DOC.getLog().debug("Running test testRun1");
089: ++runCount.value;
090: }
091: };
092: MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(
093: new TestRunnable[] { tr1 });
094: mttr.runTestRunnables();
095:
096: assertEquals("Did not run the runTest method enough times.", 1,
097: runCount.value);
098: }
099:
100: public synchronized void testRun2() throws Throwable {
101: DOC.getIT().testsIssue(526710);
102: DOC.getLog().debug("testRun2");
103:
104: final RunValue1 runCount = new RunValue1();
105: TestRunnable tr1 = new TestRunnable() {
106: public void runTest() throws Throwable {
107: ++runCount.value;
108: }
109: };
110: MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(
111: new TestRunnable[] { tr1 });
112: mttr.runTestRunnables(1000);
113:
114: assertEquals("Did not run the runTest method enough times.", 1,
115: runCount.value);
116: }
117:
118: public synchronized void testRun3a() throws Throwable {
119: DOC.getIT().testsIssue(526710);
120: DOC.getLog().debug("testRun3a");
121: DOC
122: .getLog()
123: .warn(
124: "****************\n"
125: + "This test may expose timing issues, where only one test is run.\n"
126: + "I've only seen this with JDK 1.1, but that may expose an underlying\n"
127: + "problem. This will require further investigation.\n"
128: + "****************");
129:
130: final RunValue1 runCount = new RunValue1();
131: TestRunnable tr1 = new TestRunnable() {
132: public synchronized void runTest() throws Throwable {
133: ++runCount.value;
134: }
135: };
136: MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(
137: new TestRunnable[] { tr1, tr1 });
138: mttr.runTestRunnables();
139:
140: assertEquals("Did not run the runTest method enough times.", 2,
141: runCount.value);
142: }
143:
144: public synchronized void testRun3b() throws Throwable {
145: DOC.getLog().debug("testRun3b");
146: final RunValue1 runCount = new RunValue1();
147: TestRunnable tr1 = new TestRunnable() {
148: public void runTest() throws Throwable {
149: ++runCount.value;
150: }
151: };
152: int totalCount = 15;
153: TestRunnable trList[] = new TestRunnable[totalCount];
154: for (int i = 0; i < totalCount; ++i) {
155: trList[i] = tr1;
156: }
157: MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(
158: trList);
159: mttr.runTestRunnables();
160:
161: assertEquals("Did not run the runTest method enough times.",
162: totalCount, runCount.value);
163: }
164:
165: public void testRun4() throws Throwable {
166: DOC.getLog().debug("testRun4");
167: TestRunnable tr1 = new TestRunnable() {
168: public void runTest() throws Throwable {
169: throw new IOException("My exception");
170: }
171: };
172: MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(
173: new TestRunnable[] { tr1 });
174: try {
175: mttr.runTestRunnables();
176: fail("did not throw IOException.");
177: } catch (IOException ioe) {
178: // check message
179: assertEquals("IOException not the one we threw.",
180: "My exception", ioe.getMessage());
181: }
182: }
183:
184: public void testRun5() throws Throwable {
185: DOC.getLog().debug("testRun5");
186: TestRunnable tr1 = new TestRunnable() {
187: public void runTest() throws Throwable {
188: Object o = new Object();
189: synchronized (o) {
190: o.wait();
191: }
192: }
193: };
194: MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(
195: new TestRunnable[] { tr1 });
196: boolean fail = false;
197: try {
198: // wait for 10 ms to ensure the join loop is not entered
199: mttr.runTestRunnables(10);
200: fail = true;
201: } catch (junit.framework.AssertionFailedError e) {
202: // test failure?
203: }
204: if (fail) {
205: fail("Did not throw an assertion failed error.");
206: }
207: }
208:
209: public void testRun5a() throws Throwable {
210: DOC.getLog().debug("testRun5a");
211: TestRunnable tr1 = new TestRunnable() {
212: public void runTest() throws Throwable {
213: Object o = new Object();
214: synchronized (o) {
215: o.wait();
216: }
217: }
218: };
219: MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(
220: new TestRunnable[] { tr1 });
221: boolean fail = false;
222: try {
223: // wait for 1 second to ensure the join section is entered
224: mttr.runTestRunnables(1000);
225: fail = true;
226: } catch (junit.framework.AssertionFailedError e) {
227: // test failure?
228: }
229: if (fail) {
230: fail("Did not throw an assertion failed error.");
231: }
232: }
233:
234: private static final int MAX_LOOP_COUNT = 20000;
235:
236: static abstract class TestRunnable6 extends TestRunnable {
237: public Thread runningThread = null;
238: public boolean wasInterrupted = false;
239:
240: public void runTest() throws Throwable {
241: this .runningThread = Thread.currentThread();
242: runMyTest();
243: }
244:
245: public abstract void runMyTest() throws Throwable;
246: }
247:
248: public void testRun6() throws Throwable {
249: DOC.getIT().testsIssue(771000);
250: DOC.getLog().debug("testRun6");
251: TestRunnable6 tr1 = new TestRunnable6() {
252: public void runMyTest() throws Throwable {
253: DOC.getLog().warn("runMyTest 6 running forever");
254: // never exit!
255: for (int i = 0; i < MAX_LOOP_COUNT; ++i) {
256: //Thread.yield();
257: try {
258: delay(100);
259: } catch (InterruptedException ie) {
260: this .wasInterrupted = true;
261: DOC.getLog().warn("runMyTest 6: interrupted!");
262: }
263: DOC.getLog().warn("runMyTest 6: Loop!");
264: if (Thread.interrupted()) {
265: this .wasInterrupted = true;
266: DOC.getLog().warn("runMyTest 6: inerrupted!");
267: }
268: }
269: fail("This line should NEVER be reached!");
270: }
271: };
272: MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(
273: new TestRunnable[] { tr1 });
274: boolean fail = false;
275: try {
276: mttr.runTestRunnables(10);
277: fail = true;
278: } catch (junit.framework.AssertionFailedError e) {
279: // test failure
280: if (e.getMessage() != null
281: && e.getMessage().indexOf(
282: "This line should NEVER be reached!") >= 0) {
283: fail("Did not kill the runnable.");
284: }
285: }
286: if (fail) {
287: fail("Did not throw an assertion failed error.");
288: }
289:
290: assertTrue("Test was not interrupted.", tr1.wasInterrupted);
291: assertFalse("Did not stop the test runnable.",
292: tr1.runningThread.isAlive());
293: }
294:
295: public void testRun7() throws Throwable {
296: DOC.getIT().testsIssue(771001);
297: DOC.getLog().debug("testRun7");
298: TestRunnable6 tr1 = new TestRunnable6() {
299: public void runMyTest() throws Throwable {
300: assertTrue("Did not create the thread as daemon.",
301: this .runningThread.isDaemon());
302: }
303: };
304: MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(
305: new TestRunnable[] { tr1 });
306: mttr.runTestRunnables();
307: }
308:
309: static class TesterClass {
310: public int value;
311: }
312:
313: public void testRun8() throws Throwable {
314: DOC.getIT().testsIssue(771008);
315:
316: // ensure the monitors catch an error
317:
318: DOC.getLog().debug("testRun8");
319: final TesterClass tc = new TesterClass();
320: TestRunnable tr1 = new TestRunnable() {
321: public void runTest() throws Throwable {
322: for (int i = 0; i < 30; ++i) {
323: tc.value = i;
324: delay(100);
325: }
326: tc.value = -1;
327: }
328: };
329: TestMonitorRunnable tm1 = new TestMonitorRunnable() {
330: public void runMonitor() throws Throwable {
331: assertTrue("Value is < 0.", tc.value >= 0);
332: }
333: };
334: MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(
335: new TestRunnable[] { tr1 }, new TestRunnable[] { tm1 });
336: boolean fail = false;
337: try {
338: mttr.runTestRunnables();
339: fail = true;
340: } catch (junit.framework.AssertionFailedError e) {
341: assertTrue("Did not throw correct exception from monitor.",
342: e.getMessage().indexOf("Value is < 0.") >= 0);
343: }
344: if (fail) {
345: fail("Did not throw an assertion failed error.");
346: }
347: }
348:
349: static abstract class TestMonitorRunnable9 extends
350: TestMonitorRunnable {
351: public Thread runningThread = null;
352:
353: public void runTest() throws Throwable {
354: this .runningThread = Thread.currentThread();
355: super .runTest();
356: }
357: }
358:
359: public void testRun9() throws Throwable {
360: DOC.getIT().testsIssue(771008);
361:
362: // ensure the monitors quit
363:
364: DOC.getLog().debug("testRun9");
365: TestRunnable tr1 = new TestRunnable() {
366: public void runTest() throws Throwable {
367: delay(100);
368: }
369: };
370: TestMonitorRunnable9 tm1 = new TestMonitorRunnable9() {
371: public void runMonitor() throws Throwable {
372: // do nothing
373: }
374: };
375: MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(
376: new TestRunnable[] { tr1 }, new TestRunnable[] { tm1 });
377: mttr.runTestRunnables();
378: assertFalse("Did not stop the test monitor.", tm1.runningThread
379: .isAlive());
380: }
381:
382: public void testRun10() throws Throwable {
383: DOC.getIT().testsIssue(771008);
384:
385: // ensure the monitors quit
386:
387: DOC.getLog().debug("testRun10");
388: TestRunnable tr1 = new TestRunnable() {
389: public void runTest() throws Throwable {
390: delay(100);
391: }
392: };
393: TestRunnable6 tm1 = new TestRunnable6() {
394: public void runMyTest() throws Throwable {
395: DOC.getLog().warn("runMyTest 10 running forever");
396: for (int i = 0; i < MAX_LOOP_COUNT; ++i) {
397: //Thread.yield();
398: try {
399: delay(100);
400: } catch (InterruptedException ie) {
401: this .wasInterrupted = true;
402: DOC.getLog().warn("runMyTest 10: interrupted!");
403: }
404: DOC.getLog().warn("runMyTest 10: Loop!");
405: if (Thread.interrupted()) {
406: this .wasInterrupted = true;
407: DOC.getLog().warn("runMyTest 10: interrupted!");
408: }
409: }
410: fail("This line should NEVER be reached!");
411: }
412: };
413: MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(
414: new TestRunnable[] { tr1 }, new TestRunnable[] { tm1 });
415:
416: // monitor timeout should never cause an error.
417: mttr.runTestRunnables();
418:
419: assertTrue("monitor was not interrupted.", tm1.wasInterrupted);
420: Thread.sleep(100);
421: assertFalse("Did not stop the test monitor.", tm1.runningThread
422: .isAlive());
423: }
424:
425: public void testRun11() throws Throwable {
426: DOC.getIT().testsIssue(771008);
427:
428: // ensure the monitors catch an error (generated right away)
429:
430: DOC.getLog().debug("testRun11");
431: final TesterClass tc = new TesterClass();
432: TestRunnable tr1 = new TestRunnable() {
433: public void runTest() throws Throwable {
434: tc.value = -1;
435: for (int i = 0; i < 30; ++i) {
436: delay(100);
437: tc.value = i;
438: }
439: }
440: };
441: TestMonitorRunnable tm1 = new TestMonitorRunnable() {
442: public void runMonitor() throws Throwable {
443: assertTrue("Value is < 0.", tc.value >= 0);
444: }
445: };
446: MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(
447: new TestRunnable[] { tr1 }, new TestRunnable[] { tm1 });
448: boolean fail = false;
449: try {
450: mttr.runTestRunnables();
451: fail = true;
452: } catch (junit.framework.AssertionFailedError e) {
453: assertTrue("Did not throw correct exception from monitor.",
454: e.getMessage().indexOf("Value is < 0.") >= 0);
455: }
456: if (fail) {
457: fail("Did not throw an assertion failed error.");
458: }
459: }
460:
461: //-------------------------------------------------------------------------
462: // Standard JUnit declarations
463:
464: public static Test suite() {
465: TestSuite suite = new TestSuite(THIS_CLASS);
466:
467: return suite;
468: }
469:
470: public static void main(String[] args) {
471: String[] name = { THIS_CLASS.getName() };
472:
473: // junit.textui.TestRunner.main( name );
474: // junit.swingui.TestRunner.main( name );
475:
476: junit.textui.TestRunner.main(name);
477: }
478:
479: /**
480: *
481: * @exception Exception thrown under any exceptional condition.
482: */
483: protected void setUp() throws Exception {
484: super .setUp();
485:
486: // set ourself up
487: }
488:
489: /**
490: *
491: * @exception Exception thrown under any exceptional condition.
492: */
493: protected void tearDown() throws Exception {
494: // tear ourself down
495:
496: super.tearDown();
497: }
498: }
|