001: /*
002:
003: Derby - Class org.apache.derbyTesting.unitTests.harness.BasicUnitTestManager
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyTesting.unitTests.harness;
023:
024: import org.apache.derby.iapi.services.context.ContextManager;
025: import org.apache.derby.iapi.services.context.ContextService;
026: import org.apache.derby.iapi.services.monitor.ModuleControl;
027: import org.apache.derby.iapi.error.StandardException;
028: import org.apache.derby.iapi.services.monitor.Monitor;
029: import org.apache.derby.iapi.services.sanity.SanityManager;
030: import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
031: import org.apache.derbyTesting.unitTests.harness.UnitTest;
032: import org.apache.derbyTesting.unitTests.harness.UnitTestConstants;
033: import org.apache.derbyTesting.unitTests.harness.UnitTestManager;
034: import org.apache.derbyTesting.unitTests.harness.T_Bomb;
035: import java.util.Date;
036: import java.util.Enumeration;
037: import java.util.Properties;
038: import java.util.Vector;
039: import java.util.Hashtable;
040:
041: public class BasicUnitTestManager implements UnitTestManager,
042: ModuleControl {
043: private Vector vectorOfTests;
044: private Hashtable namesOfTests;
045:
046: private static boolean alreadyRun = false;
047: private HeaderPrintWriter output;
048: private HeaderPrintWriter currentOutput;
049: private int testType = UnitTestConstants.TYPE_COMPLETE;
050: private int testDuration = UnitTestConstants.DURATION_FOREVER;
051: private boolean reportOutputOn = true;
052: private boolean performanceReportOn = false;
053: private ContextService contextService;
054: private boolean runForever = false;
055:
056: /*
057: ** Constructor
058: */
059:
060: public BasicUnitTestManager() {
061: }
062:
063: /*
064: ** Methods of ModuleControl
065: */
066: public void boot(boolean create, Properties startParams)
067: throws StandardException {
068: boolean testStatus = true;
069:
070: // startParams should define output, for now
071: // use the sytem trace stream. If that doesn't exist
072: // then use a null stream.
073:
074: output = Monitor.getStream();
075:
076: contextService = ContextService.getFactory();
077:
078: this .currentOutput = output;
079:
080: vectorOfTests = new Vector();
081: namesOfTests = new Hashtable();
082:
083: findTests(startParams, startParams);
084: try {
085: findTests(System.getProperties(), startParams);
086: } catch (SecurityException se) {
087: }
088: findTests(Monitor.getMonitor().getApplicationProperties(),
089: startParams);
090:
091: if (!alreadyRun) {
092: testStatus = runTests();
093: alreadyRun = true;
094: }
095:
096: if (!testStatus) {
097:
098: // try to print out that the shutdown is occurring.
099: System.out
100: .println("Shutting down due to unit test failure.");
101: output
102: .printlnWithHeader("Shutting down due to unit test failure, see log for more information.");
103:
104: Monitor.getMonitor().shutdown();
105: }
106: }
107:
108: public void stop() {
109: return;
110: }
111:
112: public synchronized void registerTest(UnitTest objectToTest,
113: String testName) {
114:
115: // only add the new test if it isn't already there.
116: // otherwise you will upset me.
117: if (!namesOfTests.containsKey(testName)) {
118: vectorOfTests.addElement(objectToTest);
119: namesOfTests.put(testName, testName);
120: }
121: }
122:
123: private void findTests(Properties testList, Properties startParams) {
124:
125: if (testList == null)
126: return;
127:
128: for (Enumeration e = testList.propertyNames(); e
129: .hasMoreElements();) {
130:
131: String key = (String) e.nextElement();
132: if (key.startsWith("derby.module.test.")) {
133: String unitTestClass = testList.getProperty(key);
134:
135: try {
136: Object unitTest = Monitor.bootServiceModule(false,
137: this , unitTestClass, startParams);
138: if (unitTest instanceof UnitTest) {
139: registerTest((UnitTest) unitTest, unitTestClass);
140: } else if (unitTest != null) {
141: System.out
142: .println("class does not implement UnitTest "
143: + unitTestClass);
144: }
145: } catch (StandardException se) {
146: System.out.println("exception booting "
147: + unitTestClass);
148: System.out.println(se.toString());
149: se.printStackTrace(System.out);
150: }
151: }
152: }
153: }
154:
155: /**
156: * emitAMessage
157: *
158: * Convenience routine to emit messages. This routine only works
159: * for messages provided by this package.
160: *
161: * @see UnitTestConstants for supported durations.
162: **/
163: private void emitAMessage(String message) {
164:
165: currentOutput.printlnWithHeader(message);
166: }
167:
168: private boolean runATest(UnitTest aTest) {
169:
170: boolean result;
171:
172: String this TestName = aTest.getClass().getName();
173: Date startTime = null, endTime;
174:
175: // push a new context manager
176: ContextManager cm = null;
177: if (contextService != null) {
178: cm = contextService.newContextManager();
179: contextService.setCurrentContextManager(cm);
180: }
181:
182: if (performanceReportOn)
183: startTime = new Date();
184:
185: try {
186: emitAMessage("Starting test '" + this TestName + "'.");
187: result = aTest.Execute(currentOutput);
188: if (result == true)
189: emitAMessage("Test '" + this TestName + "' passed");
190: else
191: emitAMessage("Test '" + this TestName + "' failed");
192:
193: } catch (Throwable t) {
194: if (t instanceof ThreadDeath) {
195: t.printStackTrace(output.getPrintWriter());
196: Runtime.getRuntime().exit(1);
197: }
198:
199: result = false;
200: String msg = t.getMessage();
201: if (msg == null)
202: msg = t.getClass().getName();
203: emitAMessage("Test '" + this TestName
204: + "' failed with exception '" + msg + "'.");
205: t.printStackTrace(output.getPrintWriter());
206: } finally {
207:
208: if (contextService != null) {
209: //
210: //Assure the completed test does not stick around
211: //cm.cleanupOnError
212: // (BasicUnitTestDatabaseException.cleanUp());
213: contextService.resetCurrentContextManager(cm);
214: }
215: }
216:
217: if (performanceReportOn) {
218: endTime = new Date();
219: emitAMessage("Test '" + this TestName + "' took "
220: + new Long(endTime.getTime() - startTime.getTime())
221: + " milliseconds.");
222: }
223:
224: return result;
225: }
226:
227: // STUB: Verify its ok this is synchronized.
228: public synchronized boolean runTests() {
229:
230: boolean result = true;
231: int passCount = 0;
232: int failCount = 0;
233: int skipCount = 0;
234: boolean runTests = true;
235:
236: if (SanityManager.DEBUG) {
237: runTests = !SanityManager
238: .DEBUG_ON(UnitTestManager.SKIP_UNIT_TESTS);
239: runForever = SanityManager
240: .DEBUG_ON(UnitTestManager.RUN_FOREVER);
241: }
242: if (runTests) {
243:
244: if (!runForever)
245: T_Bomb.makeBomb();
246: for (int ix = vectorOfTests.size() - 1; ix >= 0; ix--) {
247:
248: UnitTest this Test = ((UnitTest) vectorOfTests
249: .elementAt(ix));
250: if (this Test.UnitTestDuration() <= this .testDuration
251: && this Test.UnitTestType() <= this .testType) {
252: if (runATest(this Test))
253: passCount++;
254: else
255: failCount++;
256: vectorOfTests.removeElementAt(ix);
257: } else {
258: skipCount++;
259: }
260: }
261: emitAMessage("Test Summary - Run "
262: + (passCount + failCount) + ", Passed " + passCount
263: + ", Failed " + failCount + ", Skipped "
264: + skipCount + ".");
265: } else {
266: emitAMessage("Tests not run.");
267: }
268: return (failCount == 0);
269: }
270:
271: public boolean runTests(int testType, int testDuration) {
272: //STUB: Sanity check for type/duration
273: this .testType = testType;
274: this .testDuration = testDuration;
275: return runTests();
276: }
277:
278: public void setTestDuration(int testDuration) {
279: //STUB: Sanity check for type/duration
280: this .testDuration = testDuration;
281: return;
282: }
283:
284: public void setTestType(int testType) {
285: //STUB: Sanity check for type/duration
286: this .testType = testType;
287: return;
288: }
289:
290: public void setPerformanceReportOn(boolean performanceReportOn) {
291: this.performanceReportOn = performanceReportOn;
292: return;
293: }
294: }
|