001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.junit;
043:
044: import java.util.*;
045: import junit.framework.TestSuite;
046: import junit.framework.Test;
047:
048: /**
049: * NetBeans extension to JUnit's TestSuite class.
050: */
051: public class NbTestSuite extends TestSuite implements NbTest {
052:
053: private Filter fFilter;
054:
055: /**
056: * Constructs an empty TestSuite.
057: */
058: public NbTestSuite() {
059: super ();
060: }
061:
062: /**
063: * Constructs a TestSuite from the given class. Adds all the methods
064: * starting with "test" as test cases to the suite.
065: *
066: */
067: public NbTestSuite(Class theClass) {
068: super (theClass);
069: }
070:
071: /**
072: * Constructs an empty TestSuite.
073: */
074: public NbTestSuite(String name) {
075: super (name);
076: }
077:
078: /**
079: * Adds a test to the suite.
080: */
081: public void addTest(Test test) {
082: if (test instanceof NbTest) {
083: //System.out.println("NbTestSuite.addTest(): Adding test with filter, test:"+test);
084: ((NbTest) test).setFilter(fFilter);
085: } else {
086: //System.out.println("NbTestSuite.addTest(): Adding test, test:"+test);
087: }
088: super .addTest(test);
089: }
090:
091: /**
092: * adds a test suite to this test suite
093: */
094: public void addTestSuite(Class testClass) {
095: NbTest t = new NbTestSuite(testClass);
096: t.setFilter(fFilter);
097: addTest(t);
098: }
099:
100: /**
101: * Sets active filter.
102: * @param filter Filter to be set as active for current test, null will reset filtering.
103: */
104: public void setFilter(Filter filter) {
105: Enumeration e;
106:
107: this .fFilter = filter;
108: e = this .tests();
109: while (e.hasMoreElements()) {
110: Object test = e.nextElement();
111: if (test instanceof NbTest) {
112: //System.out.println("NbTestSuite.setFilter(): Setting filter:"+filter);
113: ((NbTest) test).setFilter(filter);
114: }
115:
116: }
117: }
118:
119: /**
120: * Checks if a test isn't filtered out by the active filter.
121: */
122: public boolean canRun() {
123: return true; // suite can always run
124: }
125:
126: public String getExpectedFail() {
127: return null;
128: }
129:
130: /** Factory method to create a special execution suite that not only
131: * executes the tests but also measures the times each execution took.
132: * It then compares the times and fails if the difference is too big.
133: * Test tests can be executed more times to eliminate the effect
134: * of GC and hotspot compiler.
135: *
136: * @param clazz the class to create tests for (from methods starting with test)
137: * @param slowness this must be true: slowness * min < max
138: * @param repeat number of times to repeat the test
139: */
140: public static NbTestSuite speedSuite(Class clazz, int slowness,
141: int repeat) {
142: return new SpeedSuite(clazz, repeat, slowness,
143: SpeedSuite.CONSTANT);
144: }
145:
146: /** Factory method to create a special execution suite that not only
147: * executes the tests but also measures the times each execution took.
148: * It then compares the times devided by the size of query
149: * and fails if the difference is too big.
150: * Test tests can be executed more times to eliminate the effect
151: * of GC and hotspot compiler.
152: *
153: * @param clazz the class to create tests for (from methods starting with test)
154: * @param slowness this must be true: slowness * min < max
155: * @param repeat number of times to repeat the test
156: */
157: public static NbTestSuite linearSpeedSuite(Class clazz,
158: int slowness, int repeat) {
159: return new SpeedSuite(clazz, repeat, slowness,
160: SpeedSuite.LINEAR);
161: }
162:
163: /** Allows enhanced execution and comparition of speed of a set of
164: * tests.
165: */
166: private static final class SpeedSuite extends NbTestSuite {
167: public static final int CONSTANT = 0;
168: public static final int LINEAR = 1;
169:
170: /** number of repeats to try, if there is a failure */
171: private int repeat;
172: /** the maximum difference between the slowest and fastest test */
173: private int slowness;
174: /** type of query CONSTANT, LINEAR, etc. */
175: private int type;
176:
177: public SpeedSuite(Class clazz, int repeat, int slowness,
178: int type) {
179: super (clazz);
180: this .repeat = repeat;
181: this .slowness = slowness;
182: this .type = type;
183: }
184:
185: public void run(junit.framework.TestResult result) {
186: StringBuffer error = new StringBuffer();
187: for (int i = 0; i < repeat; i++) {
188: super .run(result);
189:
190: error.setLength(0);
191:
192: if (!result.wasSuccessful()) {
193: // if there was a failure, end the test
194: return;
195: }
196:
197: {
198: Enumeration en = tests();
199: while (en.hasMoreElements()) {
200: Object t = en.nextElement();
201: if (t instanceof NbTestCase) {
202: NbTestCase test = (NbTestCase) t;
203: error.append("Test ");
204: error.append(test.getName());
205: error.append(" took ");
206: error
207: .append(test.getExecutionTime() / 1000000);
208: error.append(" ms\n");
209: } else {
210: error.append("Test ");
211: error.append(t);
212: error.append(" is not NbTestCase");
213: }
214:
215: }
216: }
217:
218: double min = Long.MAX_VALUE;
219: double max = Long.MIN_VALUE;
220:
221: {
222: Enumeration en = tests();
223: while (en.hasMoreElements()) {
224: Object t = en.nextElement();
225: if (t instanceof NbTestCase) {
226: double l = ((NbTestCase) t)
227: .getExecutionTime();
228:
229: if (type == LINEAR) {
230: l = l
231: / ((NbTestCase) t)
232: .getTestNumber();
233: }
234:
235: if (l > max)
236: max = l;
237: if (l < min)
238: min = l;
239: }
240: }
241: }
242:
243: System.err.println(error.toString());
244:
245: if (max <= min * slowness) {
246: // ok
247: return;
248: }
249: }
250:
251: result.addFailure(this ,
252: new junit.framework.AssertionFailedError(
253: "Execution times of tests differ too much;\n"
254: + "the results are supposed to be "
255: + typeName() + ":\n"
256: + error.toString()));
257: }
258:
259: private String typeName() {
260: switch (type) {
261: case CONSTANT:
262: return "constant";
263: case LINEAR:
264: return "linear";
265: default:
266: NbTestCase.fail("This is not supported type: " + type);
267: }
268: return null;
269: }
270: }
271: }
|