diff options
author | Dani Megert | 2013-01-22 10:45:23 +0000 |
---|---|---|
committer | Dani Megert | 2013-01-22 10:45:23 +0000 |
commit | b20395d8a6bf58ada6e7efd2b277641ae6c4aaac (patch) | |
tree | f474888c81d8f4e41e169120df91756649f40ac2 /bundles/org.eclipse.test.performance/src/org/eclipse/test | |
parent | a4b794f557dbd0cca7a45885de1b977987b90670 (diff) | |
download | eclipse.platform.releng-b20395d8a6bf58ada6e7efd2b277641ae6c4aaac.tar.gz eclipse.platform.releng-b20395d8a6bf58ada6e7efd2b277641ae6c4aaac.tar.xz eclipse.platform.releng-b20395d8a6bf58ada6e7efd2b277641ae6c4aaac.zip |
Fixed bug 388413: Move BytecodeOrderedTestSuite to
org.eclipse.test.performance
Diffstat (limited to 'bundles/org.eclipse.test.performance/src/org/eclipse/test')
-rw-r--r-- | bundles/org.eclipse.test.performance/src/org/eclipse/test/OrderedTestSuite.java | 176 |
1 files changed, 175 insertions, 1 deletions
diff --git a/bundles/org.eclipse.test.performance/src/org/eclipse/test/OrderedTestSuite.java b/bundles/org.eclipse.test.performance/src/org/eclipse/test/OrderedTestSuite.java index 93c0e82b..ed6eb2f2 100644 --- a/bundles/org.eclipse.test.performance/src/org/eclipse/test/OrderedTestSuite.java +++ b/bundles/org.eclipse.test.performance/src/org/eclipse/test/OrderedTestSuite.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2012 IBM Corporation and others. + * Copyright (c) 2007, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,7 +10,13 @@ *******************************************************************************/ package org.eclipse.test; +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.IOException; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; import java.util.Set; @@ -71,6 +77,174 @@ public class OrderedTestSuite extends TestSuite { } + /** + * Creates a new test suite that runs tests in bytecode declaration order. + * + * @param testClass the JUnit-3-style test class + * @since 3.9 + */ + public OrderedTestSuite(Class testClass) { + this(testClass, testClass.getName()); + } + + /** + * Creates a new test suite that runs tests in bytecode declaration order. + * + * @param testClass the JUnit-3-style test class + * @param name the name of the suite + * @since 3.9 + */ + public OrderedTestSuite(Class testClass, String name) { + super(name); + + TestSuite randomOrderSuite= new TestSuite(testClass); + ArrayList tests= Collections.list(randomOrderSuite.tests()); + + class SortingException extends RuntimeException { + private static final long serialVersionUID= 1L; + + public SortingException(String message) { + super(message); + } + } + final ArrayList orderedMethodNames= new ArrayList(); + Class c= testClass; + try { + while (Test.class.isAssignableFrom(c)) { + addDeclaredTestMethodNames(c, orderedMethodNames); + c= c.getSuperclass(); + } + Collections.sort(tests, new Comparator() { + public int compare(Object o1, Object o2) { + if (o1 instanceof TestCase && o2 instanceof TestCase) { + TestCase t1= (TestCase)o1; + TestCase t2= (TestCase)o2; + int i1= orderedMethodNames.indexOf(t1.getName()); + int i2= orderedMethodNames.indexOf(t2.getName()); + if (i1 != -1 && i2 != -1) + return i1 - i2; + } + throw new SortingException("suite failed to detect test order: " + o1 + ", " + o2); //$NON-NLS-1$ //$NON-NLS-2$ + } + }); + } catch (SortingException e) { + addTest(error(testClass, "suite failed to detect test order", e)); //$NON-NLS-1$ + } catch (IOException e) { + addTest(error(testClass, "suite failed to detect test order", e)); //$NON-NLS-1$ + } + + for (Iterator iter= tests.iterator(); iter.hasNext();) { + Test test= (Test)iter.next(); + addTest(test); + } + } + + private void addDeclaredTestMethodNames(Class c, ArrayList methodNames) throws IOException { + /* + * XXX: This method needs to be updated if new constant pool tags are specified. Current + * supported major class file version: 51 (Java 1.7). + * + * See JVMS 7, 4.4 The Constant Pool. + */ + String className= c.getName(); + int lastDot= className.lastIndexOf("."); //$NON-NLS-1$ + if (lastDot != -1) + className= className.substring(lastDot + 1); + DataInputStream is= new DataInputStream(new BufferedInputStream(c.getResourceAsStream(className + ".class"))); //$NON-NLS-1$ + int magic= is.readInt(); + if (magic != 0xcafebabe) + throw new IOException("bad magic bytes: 0x" + Integer.toHexString(magic)); //$NON-NLS-1$ + int minor= is.readUnsignedShort(); + int major= is.readUnsignedShort(); + int cpCount= is.readUnsignedShort(); + String[] constantPoolStrings= new String[cpCount]; + for (int i= 1; i < cpCount; i++) { + + byte tag= is.readByte(); + switch (tag) { + case 7: // CONSTANT_Class + skip(is, 2); + break; + case 9: // CONSTANT_Fieldref + case 10: // CONSTANT_Methodref + case 11: // CONSTANT_InterfaceMethodref + skip(is, 4); + break; + case 8: // CONSTANT_String + skip(is, 2); + break; + case 3: // CONSTANT_Integer + case 4: // CONSTANT_Float + skip(is, 4); + break; + case 5: // CONSTANT_Long + case 6: // CONSTANT_Double + skip(is, 8); + i++; // weird spec wants this + break; + case 12: // CONSTANT_NameAndType + skip(is, 4); + break; + case 1: // CONSTANT_Utf8 + constantPoolStrings[i]= is.readUTF(); + break; + case 15: // CONSTANT_MethodHandle + skip(is, 3); + break; + case 16: // CONSTANT_MethodType + skip(is, 2); + break; + case 18: // CONSTANT_InvokeDynamic + skip(is, 4); + break; + default: + throw new IOException("unknown constant pool tag " + tag + " at index " + i + ". Class file version: " + major + "." + minor); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + } + } + skip(is, 2 * 3); // access_flags, this_class, super_class + int interfacesCount= is.readUnsignedShort(); + skip(is, 2 * interfacesCount); + int fieldsCount= is.readUnsignedShort(); + for (int i= 0; i < fieldsCount; i++) { + skip(is, 2 * 3); // access_flags, name_index, descriptor_index + int attributesCount= is.readUnsignedShort(); + for (int j= 0; j < attributesCount; j++) { + skip(is, 2); // attribute_name_index + long attInfoCount= readUnsignedInt(is); + skip(is, attInfoCount); + } + } + + int methodsCount= is.readUnsignedShort(); + for (int i= 0; i < methodsCount; i++) { + skip(is, 2); // access_flags + int nameIndex= is.readUnsignedShort(); + int descIndex= is.readUnsignedShort(); + if ("()V".equals(constantPoolStrings[descIndex])) { //$NON-NLS-1$ + String name= constantPoolStrings[nameIndex]; + if (name.startsWith("test")) //$NON-NLS-1$ + methodNames.add(name); + } + int attributesCount= is.readUnsignedShort(); + for (int j= 0; j < attributesCount; j++) { + skip(is, 2); // attribute_name_index + long attInfoCount= readUnsignedInt(is); + skip(is, attInfoCount); + } + } + } + + private static void skip(DataInputStream is, long bytes) throws IOException { + while (bytes > 0) + bytes-= is.skip(bytes); + if (bytes != 0) + throw new IOException("error in skipping bytes: " + bytes); //$NON-NLS-1$ + } + + private static long readUnsignedInt(DataInputStream is) throws IOException { + return is.readInt() & 0xFFFFffffL; + } + private static Test error(Class testClass, String testMethod, Exception exception) { final Throwable e2= exception.fillInStackTrace(); return new TestCase(testMethod + "(" + testClass.getName() + ")") { //$NON-NLS-1$ //$NON-NLS-2$ |