KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derbyTesting > unitTests > harness > T_MultiThreadedIterations


1 /*
2
3    Derby - Class org.apache.derbyTesting.unitTests.harness.T_MultiThreadedIterations
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derbyTesting.unitTests.harness;
23
24 import org.apache.derby.iapi.services.monitor.Monitor;
25 import org.apache.derby.iapi.services.property.PropertyUtil;
26
27 import java.util.Properties JavaDoc;
28
29 /**
30     Abstract class which executes T_MultiIterations. This allows multiple
31     threads running T_MultiIterations.
32
33     This allows the setup to be performed once, and then the
34     test itself to be run with multiple threads for a number of iterations.
35     The number of threads and iterations are set by the property
36     derby.unittests.numThreads and derby.unittests.iterations
37     and default to 1.
38     <P>
39     Statistics are provided about each iteration in the error log. The statistics
40     are time for each iteration, used and total memory changes per iteration.
41
42     @see T_Generic
43 */

44 public abstract class T_MultiThreadedIterations extends T_MultiIterations implements Runnable JavaDoc
45 {
46     protected int threadNumber = 0;
47
48     static volatile boolean inError = false;
49
50     static int numThreads = 1;
51     static int iterations = 1;
52
53     Throwable JavaDoc error = null;
54     static Thread JavaDoc[] TestThreads;
55     static T_MultiThreadedIterations[] TestObjects;
56
57     protected T_MultiThreadedIterations()
58     {
59         super();
60     }
61
62     /**
63       Run the test. The test should raise an exception if it
64       fails. runTests should return if the tests pass.
65
66       @exception T_Fail Test code throws these
67       */

68     protected void runTests() throws T_Fail
69     {
70         /*
71         ** The property name for the number of iterations is
72         ** derby.className.numThreads. For example, if the test
73         ** class is derby.com.package.to.test.T_Tester,
74         ** the property name is derby.T_Tester.numThreads.
75         */

76         String JavaDoc myClass = this.getClass().getName();
77         String JavaDoc noPackage = myClass.substring(myClass.lastIndexOf('.') + 1);
78         String JavaDoc propertyName = "derby." + noPackage + ".numThreads";
79
80         String JavaDoc nthread = PropertyUtil.getSystemProperty(propertyName);
81         if (nthread != null) {
82             try {
83                     numThreads = Integer.parseInt(nthread);
84             } catch (NumberFormatException JavaDoc nfe) {
85                 numThreads = 1;
86             }
87             if (numThreads <= 0)
88                 numThreads = 1;
89         }
90
91         if (numThreads == 1) // just use this thread
92
super.runTests(); // use T_MultiIterations runtest
93
else
94         {
95             // start numThreads new threads, each with its own test object
96
TestThreads = new Thread JavaDoc[numThreads];
97             TestObjects = new T_MultiThreadedIterations[numThreads];
98
99             inError = false;
100
101             for (int i = 0; i < numThreads; i++)
102             {
103                 TestObjects[i] = newTestObject();
104                 TestObjects[i].out = this.out;
105
106                 TestThreads[i] = new Thread JavaDoc(TestObjects[i], "Thread_" + i);
107             }
108
109             // use the first test object to setup the test
110
TestObjects[0].setupTest();
111             TestObjects[0].threadNumber = 0;
112
113             // make the other test objects to join in the setup
114
for (int i = 1; i < numThreads; i++)
115             {
116                 TestObjects[i].threadNumber = i;
117                 TestObjects[i].joinSetupTest();
118             }
119
120             // now run them
121
propertyName = "derby." + noPackage + ".iterations";
122
123             String JavaDoc iter = PropertyUtil.getSystemProperty(propertyName);
124             if (iter != null) {
125                 try {
126                     iterations = Integer.parseInt(iter);
127                 } catch (NumberFormatException JavaDoc nfe) {
128                     // leave at one
129
}
130                 if (iterations <= 0)
131                     iterations = 1;
132             }
133
134             for (int i = 0; i < numThreads; i++)
135             {
136                 TestThreads[i].start();
137             }
138
139             // wait for the threads to end
140
try
141             {
142                 for (int i = 0; i < numThreads; i++)
143                 {
144                     TestThreads[i].join();
145                 }
146             }
147             catch (InterruptedException JavaDoc ie) {
148                 throw T_Fail.exceptionFail(ie);
149             }
150
151             // report error
152
for (int i = 0; i < numThreads; i++)
153             {
154                 if (TestObjects[i].error != null)
155                     throw T_Fail.exceptionFail(TestObjects[i].error);
156             }
157         }
158     }
159
160     /*
161      * run each worker test thread
162      */

163     public void run()
164     {
165         String JavaDoc threadName = "[" + Thread.currentThread().getName() + "] ";
166
167         out.println(threadName + "started");
168
169         try
170         {
171
172             for (int i = 0; i < iterations; i++)
173             {
174                 Runtime.getRuntime().gc();
175                 long btm = Runtime.getRuntime().totalMemory();
176                 long bfm = Runtime.getRuntime().freeMemory();
177                 long bum = btm - bfm;
178
179                 long start = System. currentTimeMillis();
180
181                 runTestSet();
182                 long end = System. currentTimeMillis();
183
184                 Runtime.getRuntime().gc();
185                 long atm = Runtime.getRuntime().totalMemory();
186                 long afm = Runtime.getRuntime().freeMemory();
187                 long aum = atm - afm;
188
189                 out.println(threadName + "Iteration " + i + " took " + (end - start) + "ms");
190                 out.println(threadName + "Total memory increased by " + (atm - btm) + " is " + atm);
191                 out.println(threadName + "Used memory increased by " + (aum - bum) + " is " + aum);
192             }
193         }
194         catch (ThreadDeath JavaDoc death) // some other thread has died and want to see my stack
195
{
196             out.println(threadName + "caught thread death, printing stack");
197             death.printStackTrace(out.getPrintWriter());
198             Thread.dumpStack();
199
200             throw death;
201         }
202         catch (Throwable JavaDoc t)
203         {
204             error = t;
205         }
206
207         if (error == null)
208             out.println(threadName + "finished with no error");
209         else if (!inError)
210         {
211             inError = true;
212
213             error.printStackTrace(out.getPrintWriter());
214             for (int i = 0; i < numThreads; i++)
215             {
216                 if (this != TestObjects[i]) // don't kill myself again
217
TestThreads[i].interrupt();
218             }
219         }
220     }
221
222     /*
223      * multi threaded test abstract methods
224      */

225
226     /*
227      * joins an existing setup - do whatever remaining setup the test may need
228      * to do given that setupTest has already been run by another test object
229      *
230      * This call will be executed in the main (parent) thread
231      */

232     protected abstract void joinSetupTest() throws T_Fail;
233
234     /*
235      * make a new test object instance
236      */

237     protected abstract T_MultiThreadedIterations newTestObject();
238
239
240     /*
241      * class specific method
242      */

243     protected int getNumThreads()
244     {
245         return numThreads;
246     }
247 }
248
Popular Tags