001 package com.mockrunner.base; 002 003 import java.lang.reflect.Constructor; 004 import java.util.ArrayList; 005 import java.util.Enumeration; 006 import java.util.List; 007 008 import junit.framework.Test; 009 import junit.framework.TestCase; 010 import junit.framework.TestResult; 011 import junit.framework.TestSuite; 012 013 import org.apache.commons.logging.Log; 014 import org.apache.commons.logging.LogFactory; 015 016 /** 017 * This TestSuite starts all test methods in 018 * a number of seperate threads. <b>Doesn't 019 * work properly yet. Do not use it :-)</b> 020 */ 021 public class MultiThreadTestSuite extends TestSuite 022 { 023 private final static Log log = LogFactory.getLog(MultiThreadTestSuite.class); 024 private int numberThreads; 025 private boolean doClone; 026 027 public MultiThreadTestSuite(Class theClass, String name) 028 { 029 this(theClass, name, 5, true); 030 } 031 032 public MultiThreadTestSuite(Class theClass) 033 { 034 this(theClass, 5, true); 035 } 036 037 public MultiThreadTestSuite(Class theClass, String name, int numberThreads, boolean doClone) 038 { 039 super(theClass, name); 040 this.numberThreads = numberThreads; 041 this.doClone = doClone; 042 } 043 044 public MultiThreadTestSuite(Class theClass, int numberThreads, boolean doClone) 045 { 046 super(theClass); 047 this.numberThreads = numberThreads; 048 this.doClone = doClone; 049 } 050 051 public void run(TestResult result) 052 { 053 Enumeration tests = tests(); 054 while(tests.hasMoreElements()) 055 { 056 if(result.shouldStop()) return; 057 TestCase currentTest = (TestCase)tests.nextElement(); 058 List threads = createThreadListForTest(currentTest, result); 059 runAllThreadsForTest(threads); 060 } 061 } 062 063 private Test createNewTestInstanceBasedOn(TestCase test) 064 { 065 TestCase newTest = null; 066 try 067 { 068 Constructor constructor = getTestConstructor(test.getClass()); 069 if (constructor.getParameterTypes().length == 0) 070 { 071 newTest = (TestCase)constructor.newInstance(new Object[0]); 072 newTest.setName(test.getName()); 073 074 } 075 else 076 { 077 newTest = (TestCase)constructor.newInstance(new Object[]{test.getName()}); 078 } 079 } 080 catch(Exception exc) 081 { 082 log.error(exc.getMessage(), exc); 083 } 084 return newTest; 085 } 086 087 private List createThreadListForTest(TestCase currentTest, TestResult result) 088 { 089 ArrayList threads = new ArrayList(numberThreads); 090 for(int ii = 0; ii < numberThreads; ii++) 091 { 092 Test newTest = currentTest; 093 if(doClone) newTest = createNewTestInstanceBasedOn(currentTest); 094 TestThread thread = new TestThread("TestThread " + ii, newTest, result); 095 threads.add(thread); 096 } 097 return threads; 098 } 099 100 private void runAllThreadsForTest(List threads) 101 { 102 for(int ii = 0; ii < threads.size(); ii++) 103 { 104 Thread thread = (Thread)threads.get(ii); 105 thread.start(); 106 } 107 for(int ii = 0; ii < threads.size(); ii++) 108 { 109 Thread thread = (Thread)threads.get(ii); 110 try 111 { 112 thread.join(); 113 } 114 catch(InterruptedException exc) 115 { 116 log.error("Interrupted", exc); 117 } 118 } 119 } 120 121 private static class TestThread extends Thread 122 { 123 private Test test; 124 private TestResult result; 125 126 public TestThread(String name, Test test, TestResult result) 127 { 128 super(name); 129 this.test = test; 130 this.result = result; 131 } 132 133 public void run() 134 { 135 test.run(result); 136 } 137 } 138 }