* Killing test suites (you can run tests by package) * Introduced categories to run certain tests only on 'light'/'full'tags/light-jdk8u5+36
@@ -3,3 +3,5 @@ | |||
/hotspot | |||
build | |||
*.iml | |||
hs_err* | |||
core |
@@ -148,6 +148,8 @@ project('dcevm') { | |||
test { | |||
executable new File(targetJreFile, 'bin/java') | |||
systemProperty 'dcevm.test.light', (flavor == 'light') | |||
if (kind == 'fastdebug') { | |||
jvmArgs '-XX:LogFile=build/hotspot.log' | |||
} | |||
@@ -160,7 +162,9 @@ project('dcevm') { | |||
ignoreFailures = true | |||
outputs.upToDateWhen { false } | |||
exclude '**/*Suite.class' | |||
useJUnit { | |||
excludeCategories ('com.github.dcevm.test.category.' + (flavor == 'light' ? 'Full' : 'Light')) | |||
} | |||
} | |||
test.dependsOn project(':hotspot').tasks[kind == 'fastdebug' ? 'installFastdebug' : 'installProduct'] |
@@ -21,22 +21,17 @@ | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm; | |||
package com.github.dcevm.test.eval; | |||
import org.junit.runner.RunWith; | |||
import org.junit.runners.Suite; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
/** | |||
* Tests used for evaluation purposes (especially performance measurements). | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@RunWith(Suite.class) | |||
@Suite.SuiteClasses({ | |||
FractionTest.class, | |||
GeometryScenario.class, | |||
AddingInterfaceTest.class | |||
}) | |||
public class EvalTestSuite { | |||
@Retention(RetentionPolicy.CLASS) | |||
public @interface FieldRedefinitionPolicy { | |||
RedefinitionPolicy value(); | |||
} |
@@ -22,24 +22,17 @@ | |||
* | |||
*/ | |||
package com.github.dcevm.test.structural; | |||
package com.github.dcevm; | |||
import org.junit.runner.RunWith; | |||
import org.junit.runners.Suite; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
/** | |||
* Class redefinition tests that do arbitrary structural changes. | |||
* <p/> | |||
* TODO: Add a test where redefinition triggers classloading (e.g. because a super type is not yet loaded). | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@RunWith(Suite.class) | |||
@Suite.SuiteClasses({ | |||
RedefineClassClassTest.class, | |||
RedefineObjectClassTest.class, | |||
InterfaceTest.class, | |||
ThisTypeChange.class | |||
}) | |||
public class StructuralTestSuite { | |||
@Retention(RetentionPolicy.CLASS) | |||
public @interface MethodRedefinitionPolicy { | |||
RedefinitionPolicy value(); | |||
} |
@@ -22,28 +22,15 @@ | |||
* | |||
*/ | |||
package com.github.dcevm.test.fields; | |||
import org.junit.runner.RunWith; | |||
import org.junit.runners.Suite; | |||
package com.github.dcevm; | |||
/** | |||
* Class redefinition tests that may change the methods and fields of class, but do not change the superklass or the implemented | |||
* interface. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@RunWith(Suite.class) | |||
@Suite.SuiteClasses({ | |||
FieldChangedOrderTest.class, | |||
FieldModificationTest.class, | |||
ObjectStressTest.class, | |||
YieldTest.class, | |||
ComplexFieldTest.class, | |||
FieldAlignmentTest.class, | |||
StringFieldTest.class, | |||
RedefinePrivateFieldTest.class, | |||
EnumTest.class | |||
}) | |||
public class FieldsTestSuite { | |||
public enum RedefinitionPolicy { | |||
StaticCheck, | |||
DynamicCheck, | |||
AccessDeletedMembers, | |||
AccessOldMembers | |||
} |
@@ -23,9 +23,9 @@ | |||
*/ | |||
package com.github.dcevm; | |||
import org.objectweb.asm.ClassVisitor; | |||
import org.objectweb.asm.MethodVisitor; | |||
import org.objectweb.asm.*; | |||
import org.objectweb.asm.commons.Remapper; | |||
import org.objectweb.asm.commons.RemappingAnnotationAdapter; | |||
import org.objectweb.asm.commons.RemappingClassAdapter; | |||
import org.objectweb.asm.commons.RemappingMethodAdapter; | |||
@@ -79,8 +79,7 @@ public class TestClassAdapter extends RemappingClassAdapter { | |||
protected MethodVisitor createRemappingMethodAdapter( | |||
int access, | |||
String newDesc, | |||
MethodVisitor mv) | |||
{ | |||
MethodVisitor mv) { | |||
return new RemappingMethodAdapter(access, newDesc, mv, remapper) { | |||
@Override | |||
public void visitMethodInsn(int opcode, String owner, String name, String desc) { | |||
@@ -97,5 +96,40 @@ public class TestClassAdapter extends RemappingClassAdapter { | |||
int pos = name.indexOf(METHOD_SUFFIX); | |||
return (pos != -1) ? name.substring(0, pos) : name; | |||
} | |||
@Override | |||
public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { | |||
AnnotationVisitor av = super.visitAnnotation(remapper.mapDesc(desc), visible); | |||
return av == null ? null : new RemappingAnnotationAdapter(av, remapper) { | |||
@Override | |||
public void visitEnum(String name, String enumDesc, String value) { | |||
if (Type.getType(enumDesc).getClassName().equals(RedefinitionPolicy.class.getName())) { | |||
RedefinitionPolicy valueAsEnum = RedefinitionPolicy.valueOf(value); | |||
if (Type.getType(desc).getClassName().equals(FieldRedefinitionPolicy.class.getName())) { | |||
cv.visitAttribute(new SingleByteAttribute(FieldRedefinitionPolicy.class.getSimpleName(), (byte) valueAsEnum.ordinal())); | |||
} | |||
if (Type.getType(desc).getClassName().equals(MethodRedefinitionPolicy.class.getName())) { | |||
cv.visitAttribute(new SingleByteAttribute(MethodRedefinitionPolicy.class.getSimpleName(), (byte) valueAsEnum.ordinal())); | |||
} | |||
} | |||
super.visitEnum(name, desc, value); | |||
} | |||
}; | |||
} | |||
private static class SingleByteAttribute extends Attribute { | |||
private byte value; | |||
public SingleByteAttribute(String name, byte value) { | |||
super(name); | |||
this.value = value; | |||
} | |||
@Override | |||
protected ByteVector write(ClassWriter writer, byte[] code, int len, int maxStack, int maxLocals) { | |||
return new ByteVector().putByte(value); | |||
} | |||
} | |||
} | |||
@@ -1,49 +0,0 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test; | |||
import com.github.dcevm.test.body.BodyTestSuite; | |||
import com.github.dcevm.test.eval.EvalTestSuite; | |||
import com.github.dcevm.test.fields.FieldsTestSuite; | |||
import com.github.dcevm.test.methods.MethodsTestSuite; | |||
import com.github.dcevm.test.structural.StructuralTestSuite; | |||
import org.junit.runner.RunWith; | |||
import org.junit.runners.Suite; | |||
/** | |||
* Summarizes all available test suites. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@RunWith(Suite.class) | |||
@Suite.SuiteClasses({ | |||
BodyTestSuite.class, | |||
EvalTestSuite.class, | |||
MethodsTestSuite.class, | |||
FieldsTestSuite.class, | |||
StructuralTestSuite.class | |||
}) | |||
public class LightTestSuite { | |||
} |
@@ -33,8 +33,7 @@ import com.github.dcevm.HotSwapTool; | |||
* @author Thomas Wuerthinger | |||
*/ | |||
public class TestUtil { | |||
public static final boolean LIGHT = true; | |||
public static final boolean LIGHT = Boolean.getBoolean("dcevm.test.light"); | |||
public static int assertException(Class exceptionClass, Runnable run) { | |||
@@ -63,15 +62,6 @@ public class TestUtil { | |||
return assertException(UnsupportedOperationException.class, run); | |||
} | |||
public static void assertUnsupportedToVersion(final Class clazz, final int version) { | |||
TestUtil.assertUnsupported(new Runnable() { | |||
@Override | |||
public void run() { | |||
HotSwapTool.toVersion(clazz, version); | |||
} | |||
}); | |||
} | |||
public static void assertUnsupportedToVersionWithLight(final Class clazz, final int version) { | |||
TestUtil.assertUnsupportedWithLight(new Runnable() { | |||
@Override |
@@ -1,53 +0,0 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.body; | |||
import org.junit.runner.RunWith; | |||
import org.junit.runners.Suite; | |||
/** | |||
* Class redefinition tests that swap only method bodies and change nothing else. This test cases should also | |||
* run with the current version of HotSpot. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@RunWith(Suite.class) | |||
@Suite.SuiteClasses( | |||
{ | |||
StaticTest.class, | |||
SimpleStaticTest.class, | |||
MultipleThreadsTest.class, | |||
OldActivationTest.class, | |||
RefactorActiveMethodTest.class, | |||
StressTest.class, | |||
FacTest.class, | |||
FibTest.class, | |||
RedefinePrivateMethodTest.class, | |||
ClassRenamingTestCase.class, | |||
EMCPTest.class, | |||
ArrayTest.class | |||
}) | |||
public class BodyTestSuite { | |||
} |
@@ -30,9 +30,9 @@ import org.junit.Test; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import static junit.framework.Assert.assertNull; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static junit.framework.Assert.assertNull; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertTrue; | |||
@@ -0,0 +1,7 @@ | |||
package com.github.dcevm.test.category; | |||
/** | |||
* Tests which are only supported by full flavor of DCEVM. | |||
*/ | |||
public interface Full { | |||
} |
@@ -0,0 +1,8 @@ | |||
package com.github.dcevm.test.category; | |||
/** | |||
* Tests which are only supported by light flavor of DCEVM (for example, tests verifying certain | |||
* operation is prohibited on light flavor). | |||
*/ | |||
public interface Light { | |||
} |
@@ -0,0 +1,193 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.fields; | |||
import com.github.dcevm.test.TestUtil; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static org.junit.Assert.assertEquals; | |||
/** | |||
* Tests for accessing a deleted field. In the first scenario, the field is deleted from the class. | |||
* In the second scenario, it is deleted because of a changed subtype relationship. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
public class AccessDeletedFieldTest { | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
// Version 0 | |||
public static class A { | |||
public int x; | |||
int getFieldInOldCode() { | |||
__toVersion__(1); | |||
// This field does no longer exist | |||
return x; | |||
} | |||
} | |||
public static class B extends A { | |||
} | |||
// Version 1 | |||
public static class A___1 { | |||
} | |||
// Version 2 | |||
public static class B___2 { | |||
} | |||
// Method to enforce cast (otherwise bytecodes become invalid in version 2) | |||
public static A convertBtoA(Object b) { | |||
return (A) b; | |||
} | |||
@Test | |||
public void testOldCodeAccessesDeletedField() { | |||
assert __version__() == 0; | |||
final A a = new A(); | |||
a.x = 1; | |||
TestUtil.assertException(NoSuchFieldError.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
assertEquals(0, a.getFieldInOldCode()); | |||
} | |||
}); | |||
assert __version__() == 1; | |||
__toVersion__(0); | |||
assertEquals(0, a.x); | |||
} | |||
@Test | |||
public void testAccessDeletedField() { | |||
assert __version__() == 0; | |||
final A a = new A(); | |||
a.x = 1; | |||
assertEquals(1, a.x); | |||
__toVersion__(1); | |||
TestUtil.assertException(NoSuchFieldError.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
System.out.println(a.x); | |||
} | |||
}); | |||
__toVersion__(0); | |||
assertEquals(0, a.x); | |||
} | |||
@Test | |||
public void testAccessDeleteBaseClassFieldNormal() { | |||
__toVersion__(0); | |||
assert __version__() == 0; | |||
final B b = new B(); | |||
b.x = 1; | |||
final A a = new A(); | |||
a.x = 2; | |||
assertEquals(1, b.x); | |||
assertEquals(2, a.x); | |||
__toVersion__(2); | |||
TestUtil.assertException(NoSuchFieldError.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
System.out.println(b.x); | |||
} | |||
}); | |||
assertEquals(2, a.x); | |||
__toVersion__(0); | |||
assertEquals(0, b.x); | |||
} | |||
@Test | |||
public void testAccessDeleteBaseClassFieldInvalid() { | |||
__toVersion__(0); | |||
assert __version__() == 0; | |||
final B b = new B(); | |||
final A a1 = new A(); | |||
a1.x = 1; | |||
b.x = 1; | |||
__toVersion__(2); | |||
TestUtil.assertException(NoSuchFieldError.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
System.out.println(b.x); | |||
} | |||
}); | |||
assertEquals(1, a1.x); | |||
__toVersion__(0); | |||
assertEquals(0, b.x); | |||
assertEquals(1, a1.x); | |||
A a = convertBtoA(b); | |||
assertEquals(0, b.x); | |||
// Must fail, because now an instance of B is in a local variable of type A! | |||
TestUtil.assertException(UnsupportedOperationException.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
__toVersion__(2); | |||
} | |||
}); | |||
assertEquals(0, a.x); | |||
// Still at version 0 | |||
assert __version__() == 0; | |||
} | |||
} |
@@ -0,0 +1,123 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.fields; | |||
import com.github.dcevm.test.TestUtil; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static org.junit.Assert.assertEquals; | |||
/** | |||
* Tests for accessing a deleted static field. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
public class AccessDeletedStaticFieldTest { | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
// Version 0 | |||
public static class A { | |||
public static int x; | |||
static int getFieldInOldCode() { | |||
__toVersion__(1); | |||
newMethodFromOldCode(); | |||
// This field does no longer exist | |||
return x; | |||
} | |||
static int getFieldEMCPMethod() { | |||
__toVersion__(2); | |||
return A.x; | |||
} | |||
} | |||
// Version 1 | |||
public static class A___1 { | |||
} | |||
// Version 2 | |||
public static class A___2 { | |||
// EMCP to method in version 0 | |||
static int getFieldEMCPMethod() { | |||
__toVersion__(2); | |||
return A.x; | |||
} | |||
} | |||
private static void newMethodFromOldCode() { | |||
TestUtil.assertException(NoSuchFieldError.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
System.out.println(A.x); | |||
} | |||
}); | |||
} | |||
@Test | |||
public void testAccessDeletedStaticField() { | |||
assert __version__() == 0; | |||
A.x = 1; | |||
assertEquals(1, A.getFieldInOldCode()); | |||
assert __version__() == 1; | |||
__toVersion__(0); | |||
assertEquals(0, A.x); | |||
assert __version__() == 0; | |||
} | |||
@Test | |||
public void testAccessDeletedStaticFieldFromEMCPMethod() { | |||
assert __version__() == 0; | |||
TestUtil.assertException(NoSuchFieldError.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
System.out.println(A.getFieldEMCPMethod()); | |||
} | |||
}); | |||
__toVersion__(0); | |||
assertEquals(0, A.x); | |||
assert __version__() == 0; | |||
} | |||
} |
@@ -26,7 +26,11 @@ package com.github.dcevm.test.methods; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import java.lang.annotation.*; | |||
import java.lang.annotation.Annotation; | |||
import java.lang.annotation.ElementType; | |||
import java.lang.annotation.Retention; | |||
import java.lang.annotation.RetentionPolicy; | |||
import java.lang.annotation.Target; | |||
import java.lang.reflect.Field; | |||
import java.lang.reflect.Method; | |||
@@ -0,0 +1,94 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.methods; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static org.junit.Assert.assertEquals; | |||
/** | |||
* Test case that calls an interface method that was deleted through class redefinition. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
public class CallDeletedInterfaceMethodTest { | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
// Version 0 | |||
public static interface I { | |||
public int foo(); | |||
} | |||
public static class A implements I { | |||
@Override | |||
public int foo() { | |||
return 1; | |||
} | |||
} | |||
public static class Helper { | |||
public static int process(I i) { | |||
__toVersion__(1); | |||
return i.foo(); | |||
} | |||
} | |||
// Version 1 | |||
public static interface I___1 { | |||
} | |||
public static class Helper___1 { | |||
public static int process(I i) { | |||
return 2; | |||
} | |||
} | |||
@Test | |||
public void testOldCodeCallsDeletedInterfaceMethod() { | |||
assert __version__() == 0; | |||
A a = new A(); | |||
assertEquals(1, Helper.process(a)); | |||
assert __version__() == 1; | |||
assertEquals(2, Helper.process(a)); | |||
__toVersion__(0); | |||
assertEquals(1, Helper.process(a)); | |||
assert __version__() == 1; | |||
assertEquals(2, Helper.process(a)); | |||
__toVersion__(0); | |||
} | |||
} |
@@ -0,0 +1,114 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.methods; | |||
import com.github.dcevm.MethodRedefinitionPolicy; | |||
import com.github.dcevm.RedefinitionPolicy; | |||
import junit.framework.Assert; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static org.junit.Assert.assertEquals; | |||
/** | |||
* Test case that calls a virtual method that was deleted through class redefinition. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
public class CallDeletedMethodTest { | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
// Version 0 | |||
public static class A { | |||
public int value() { | |||
return 5; | |||
} | |||
public int oldMethod() { | |||
__toVersion__(1); | |||
return deletedMethod(); | |||
} | |||
public int deletedMethod() { | |||
return 1; | |||
} | |||
} | |||
// Version 1 | |||
@MethodRedefinitionPolicy(RedefinitionPolicy.AccessDeletedMembers) | |||
public static class A___1 { | |||
public int oldMethod() { | |||
return 2; | |||
} | |||
} | |||
@Test | |||
public void testOldCodeCallsDeletedMethod() { | |||
assert __version__() == 0; | |||
A a = new A(); | |||
assertEquals(1, a.oldMethod()); | |||
assert __version__() == 1; | |||
assertEquals(2, a.oldMethod()); | |||
__toVersion__(0); | |||
assertEquals(1, a.oldMethod()); | |||
assert __version__() == 1; | |||
assertEquals(2, a.oldMethod()); | |||
__toVersion__(0); | |||
} | |||
@Test | |||
public void testNewCodeCallsDeletedMethod() { | |||
assert __version__() == 0; | |||
A a = new A(); | |||
assertEquals(5, a.value()); | |||
__toVersion__(1); | |||
try { | |||
a.value(); | |||
Assert.fail("NoSuchMethodError exception must be thrown!"); | |||
} catch (NoSuchMethodError e) { | |||
// Expected exception | |||
} | |||
__toVersion__(0); | |||
assertEquals(5, a.value()); | |||
} | |||
} |
@@ -24,8 +24,8 @@ | |||
package com.github.dcevm.test.methods; | |||
import junit.framework.Assert; | |||
import com.github.dcevm.test.TestUtil; | |||
import junit.framework.Assert; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
@@ -1,159 +1,169 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.methods; | |||
import junit.framework.Assert; | |||
import com.github.dcevm.test.TestUtil; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static org.junit.Assert.assertEquals; | |||
/** | |||
* Test cases that delete a method that is currently active on the stack. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
public class DeleteActiveMethodTest { | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
// Version 0 | |||
public static class A { | |||
boolean firstCall; | |||
public int value() { | |||
firstCall = true; | |||
return helperValue(); | |||
} | |||
public int helperValue() { | |||
if (!firstCall) { | |||
return -1; | |||
} | |||
firstCall = false; | |||
Thread t = new Thread(new Runnable() { | |||
@Override | |||
public void run() { | |||
__toVersion__(1); | |||
} | |||
}); | |||
t.start(); | |||
try { | |||
do { | |||
this.helperValue(); | |||
} while (t.isAlive()); | |||
this.helperValue(); | |||
Assert.fail("Exception expected!"); | |||
} catch (NoSuchMethodError e) { | |||
} | |||
try { | |||
t.join(); | |||
} catch (InterruptedException e) { | |||
} | |||
return 1; | |||
} | |||
} | |||
public static class B { | |||
public int fac(int x) { | |||
if (x == 0) { | |||
__toVersion__(1); | |||
} | |||
return x * fac(x - 1); | |||
} | |||
} | |||
// Version 1 | |||
public static class A___1 { | |||
boolean firstCall; | |||
public int value() { | |||
__toVersion__(0); | |||
return 2; | |||
} | |||
} | |||
public static class B___1 { | |||
} | |||
@Test | |||
public void testDeleteActiveMethodSimple() { | |||
assert __version__() == 0; | |||
final B b = new B(); | |||
TestUtil.assertException(NoSuchMethodError.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
b.fac(5); | |||
} | |||
}); | |||
assert __version__() == 1; | |||
__toVersion__(0); | |||
assert __version__() == 0; | |||
} | |||
@Test | |||
public void testDeleteActiveMethod() { | |||
assert __version__() == 0; | |||
A a = new A(); | |||
assertEquals(1, a.value()); | |||
assert __version__() == 1; | |||
assertEquals(2, a.value()); | |||
assert __version__() == 0; | |||
assertEquals(1, a.value()); | |||
assert __version__() == 1; | |||
assertEquals(2, a.value()); | |||
assert __version__() == 0; | |||
assertEquals(1, a.value()); | |||
assert __version__() == 1; | |||
assertEquals(2, a.value()); | |||
assert __version__() == 0; | |||
} | |||
} | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.methods; | |||
import static org.junit.Assert.assertEquals; | |||
import com.github.dcevm.MethodRedefinitionPolicy; | |||
import com.github.dcevm.RedefinitionPolicy; | |||
import com.github.dcevm.test.TestUtil; | |||
import junit.framework.Assert; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
/** | |||
* Test cases that delete a method that is currently active on the stack. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
public class DeleteActiveMethodTest { | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
// Version 0 | |||
public static class A { | |||
boolean firstCall; | |||
public int value() { | |||
firstCall = true; | |||
return helperValue(); | |||
} | |||
public int helperValue() { | |||
if (!firstCall) { | |||
return -1; | |||
} | |||
firstCall = false; | |||
Thread t = new Thread(new Runnable() { | |||
@Override | |||
public void run() { | |||
__toVersion__(1); | |||
} | |||
}); | |||
t.start(); | |||
try { | |||
while (t.isAlive()) { | |||
try { | |||
this.helperValue(); | |||
Thread.sleep(500); | |||
} catch (InterruptedException e) { | |||
} | |||
helperValue(); | |||
} | |||
Assert.fail("Exception expected!"); | |||
} catch (NoSuchMethodError e) { | |||
} | |||
try { | |||
t.join(); | |||
} catch (InterruptedException e) { | |||
} | |||
return 1; | |||
} | |||
} | |||
public static class B { | |||
public int fac(int x) { | |||
if (x == 0) { | |||
__toVersion__(1); | |||
} | |||
return x * fac(x - 1); | |||
} | |||
} | |||
// Version 1 | |||
@MethodRedefinitionPolicy(RedefinitionPolicy.DynamicCheck) | |||
public static class A___1 { | |||
boolean firstCall; | |||
public int value() { | |||
__toVersion__(0); | |||
return 2; | |||
} | |||
} | |||
@MethodRedefinitionPolicy(RedefinitionPolicy.DynamicCheck) | |||
public static class B___1 { | |||
} | |||
@Test | |||
public void testDeleteActiveMethodSimple() { | |||
assert __version__() == 0; | |||
final B b = new B(); | |||
TestUtil.assertException(NoSuchMethodError.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
b.fac(5); | |||
} | |||
}); | |||
assert __version__() == 1; | |||
__toVersion__(0); | |||
assert __version__() == 0; | |||
} | |||
@Test | |||
public void testDeleteActiveMethod() { | |||
assert __version__() == 0; | |||
A a = new A(); | |||
assertEquals(1, a.value()); | |||
assert __version__() == 1; | |||
assertEquals(2, a.value()); | |||
assert __version__() == 0; | |||
assertEquals(1, a.value()); | |||
assert __version__() == 1; | |||
assertEquals(2, a.value()); | |||
assert __version__() == 0; | |||
assertEquals(1, a.value()); | |||
assert __version__() == 1; | |||
assertEquals(2, a.value()); | |||
assert __version__() == 0; | |||
} | |||
} |
@@ -1,49 +0,0 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.methods; | |||
import org.junit.runner.RunWith; | |||
import org.junit.runners.Suite; | |||
/** | |||
* Class redefinition tests that perform adding/removing/changing the methods of a class. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@RunWith(Suite.class) | |||
@Suite.SuiteClasses({ | |||
AddMethodTest.class, | |||
DeleteActiveMethodTest.class, | |||
ClassReflectionTest.class, | |||
MethodReflectionTest.class, | |||
ClassObjectSynchronizationTest.class, | |||
ClassObjectHashcodeTest.class, | |||
OverrideMethodTest.class, | |||
SingleClassTest.class, | |||
SingleClassReflectionTest.class, | |||
AnnotationTest.class | |||
}) | |||
public class MethodsTestSuite { | |||
} |
@@ -0,0 +1,123 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.methods; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static org.junit.Assert.assertEquals; | |||
/** | |||
* Test case that makes sure that old code does not get on-stack-replaced. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
public class OldCodeNonOSRTest { | |||
// Chose high enough to make sure method could get OSR (usually the OSR flag in the VM is set to about 15000) | |||
private static final int N = 100000; | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
// Version 0 | |||
public static class A { | |||
public int value() { | |||
return 5; | |||
} | |||
public int oldMethod() { | |||
__toVersion__(1); | |||
int sum = 0; | |||
for (int i=0; i<N; i++) { | |||
sum += i; | |||
} | |||
return (sum & deletedMethod()) | 1; | |||
} | |||
public int oldMethod2() { | |||
int sum = 0; | |||
for (int i=0; i<N; i++) { | |||
sum += i; | |||
} | |||
__toVersion__(1); | |||
return (sum & deletedMethod()) | 1; | |||
} | |||
public int oldMethod3() { | |||
int sum = 0; | |||
for (int i=0; i<N; i++) { | |||
sum += i; | |||
} | |||
__toVersion__(1); | |||
for (int i=0; i<N; i++) { | |||
sum += i; | |||
} | |||
return (sum & deletedMethod()) | 1; | |||
} | |||
public int deletedMethod() { | |||
return 1; | |||
} | |||
} | |||
// Version 1 | |||
public static class A___1 { | |||
public int oldMethod() { | |||
return 2; | |||
} | |||
} | |||
@Test | |||
public void testOldCodeNonOSR() { | |||
assert __version__() == 0; | |||
A a = new A(); | |||
assertEquals(1, a.oldMethod()); | |||
assert __version__() == 1; | |||
assertEquals(2, a.oldMethod()); | |||
__toVersion__(0); | |||
assertEquals(1, a.oldMethod2()); | |||
assert __version__() == 1; | |||
assertEquals(2, a.oldMethod()); | |||
__toVersion__(0); | |||
assertEquals(1, a.oldMethod3()); | |||
assert __version__() == 1; | |||
assertEquals(2, a.oldMethod()); | |||
__toVersion__(0); | |||
} | |||
} |
@@ -0,0 +1,88 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.natives; | |||
import org.junit.Before; | |||
import org.junit.Ignore; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static org.junit.Assert.assertEquals; | |||
/** | |||
* Testing correct resolving of a native method after class redefinition. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@Ignore | |||
public class SimpleNativeTest { | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
// Version 0 | |||
public static class A { | |||
public static int get() { | |||
return value(); | |||
} | |||
public static native int value(); | |||
} | |||
// Version 1 | |||
public static class A___1 { | |||
public static int get() { | |||
return value() + value2(); | |||
} | |||
public static native int value(); | |||
public static native int value2(); | |||
} | |||
@Test | |||
public void testSimpleNativeCalls() { | |||
assert __version__() == 0; | |||
assertEquals(1, A.get()); | |||
__toVersion__(1); | |||
assertEquals(3, A.get()); | |||
__toVersion__(0); | |||
assertEquals(1, A.get()); | |||
} | |||
} |
@@ -0,0 +1,397 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.structural; | |||
import org.junit.Before; | |||
import org.junit.Ignore; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static org.junit.Assert.*; | |||
/** | |||
* Smallest test case for a hierarchy swap. A<B is changed to B<A. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@Ignore | |||
public class HierarchySwapTest { | |||
// Version 0 | |||
public static class A { | |||
public int value() { | |||
return 1; | |||
} | |||
} | |||
public static class B extends A { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
public static class C { | |||
public boolean doInstanceCheckA(Object o) { | |||
return o instanceof A; | |||
} | |||
public boolean doInstanceCheckB(Object o) { | |||
return o instanceof B; | |||
} | |||
} | |||
public static class Base { | |||
public String className() { | |||
return "Base"; | |||
} | |||
} | |||
public static class D extends Base { | |||
@Override | |||
public String className() { | |||
return "D"; | |||
} | |||
public String superClassName() { | |||
return super.className(); | |||
} | |||
} | |||
public static class E extends Base { | |||
@Override | |||
public String className() { | |||
return "E"; | |||
} | |||
public String superClassName() { | |||
return super.className(); | |||
} | |||
} | |||
public static class F extends Base { | |||
@Override | |||
public String className() { | |||
return "F"; | |||
} | |||
public String superClassName() { | |||
return super.className(); | |||
} | |||
} | |||
// Version 1 | |||
public static class A___1 extends B___1 { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
public static class B___1 { | |||
public int value() { | |||
return 4; | |||
} | |||
} | |||
public static class C___1 { | |||
public boolean doInstanceCheckA(Object o) { | |||
return o instanceof A; | |||
} | |||
public boolean doInstanceCheckB(Object o) { | |||
return o instanceof B; | |||
} | |||
} | |||
// Version 2 | |||
public static class D___2 extends Base { | |||
@Override | |||
public String className() { | |||
return "D"; | |||
} | |||
public String superClassName() { | |||
return super.className(); | |||
} | |||
} | |||
public static class E___2 extends D { | |||
@Override | |||
public String className() { | |||
return "E"; | |||
} | |||
@Override | |||
public String superClassName() { | |||
return super.className(); | |||
} | |||
} | |||
public static class F___2 extends E { | |||
@Override | |||
public String className() { | |||
return "F"; | |||
} | |||
@Override | |||
public String superClassName() { | |||
return super.className(); | |||
} | |||
} | |||
// Version 3 | |||
public static class D___3 extends E { | |||
@Override | |||
public String className() { | |||
return "D"; | |||
} | |||
@Override | |||
public String superClassName() { | |||
return super.className(); | |||
} | |||
} | |||
public static class E___3 extends F { | |||
@Override | |||
public String className() { | |||
return "E"; | |||
} | |||
@Override | |||
public String superClassName() { | |||
return super.className(); | |||
} | |||
} | |||
public static class F___3 extends Base { | |||
@Override | |||
public String className() { | |||
return "F"; | |||
} | |||
public String superClassName() { | |||
return super.className(); | |||
} | |||
} | |||
// Version 4 | |||
public static class D___4 extends E { | |||
@Override | |||
public String className() { | |||
return "D"; | |||
} | |||
@Override | |||
public String superClassName() { | |||
return super.className(); | |||
} | |||
} | |||
public static class E___4 extends Base { | |||
@Override | |||
public String className() { | |||
return "E"; | |||
} | |||
public String superClassName() { | |||
return super.className(); | |||
} | |||
} | |||
public static class F___4 extends E { | |||
@Override | |||
public String className() { | |||
return "F"; | |||
} | |||
@Override | |||
public String superClassName() { | |||
return super.className(); | |||
} | |||
} | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
@Test | |||
public void testHierarchySwap() { | |||
assert __version__() == 0; | |||
A a = new A(); | |||
B b = new B(); | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertTrue(b.getClass().getSuperclass().equals(A.class)); | |||
assertFalse(a.getClass().getSuperclass().equals(B.class)); | |||
__toVersion__(1); | |||
assertEquals(8, a.value()); | |||
assertEquals(4, b.value()); | |||
assertFalse(b.getClass().getSuperclass().equals(A.class)); | |||
assertTrue(a.getClass().getSuperclass().equals(B.class)); | |||
__toVersion__(0); | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertTrue(b.getClass().getSuperclass().equals(A.class)); | |||
assertFalse(a.getClass().getSuperclass().equals(B.class)); | |||
} | |||
@Test | |||
public void testHierarchySwapWithInstanceOfTest() { | |||
assert __version__() == 0; | |||
A a = new A(); | |||
B b = new B(); | |||
C c = new C(); | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertTrue(c.doInstanceCheckA(b)); | |||
assertFalse(c.doInstanceCheckB(a)); | |||
__toVersion__(1); | |||
assertEquals(8, a.value()); | |||
assertEquals(4, b.value()); | |||
assertFalse(c.doInstanceCheckA(b)); | |||
assertTrue(c.doInstanceCheckB(a)); | |||
__toVersion__(0); | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertTrue(c.doInstanceCheckA(b)); | |||
assertFalse(c.doInstanceCheckB(a)); | |||
} | |||
@Test | |||
public void testHierarchySwapWithInstanceOf() { | |||
assert __version__() == 0; | |||
A a = new A(); | |||
B b = new B(); | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertTrue(b instanceof A); | |||
assertFalse(a instanceof B); | |||
__toVersion__(1); | |||
assertEquals(8, a.value()); | |||
assertEquals(4, b.value()); | |||
assertFalse(b instanceof A); | |||
assertTrue(a instanceof B); | |||
__toVersion__(0); | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertTrue(b instanceof A); | |||
assertFalse(a instanceof B); | |||
} | |||
@Test | |||
public void testTripleSwap() { | |||
assert __version__() == 0; | |||
D d = new D(); | |||
E e = new E(); | |||
F f = new F(); | |||
assertEquals(d.superClassName(), "Base"); | |||
assertEquals(e.superClassName(), "Base"); | |||
assertEquals(f.superClassName(), "Base"); | |||
__toVersion__(2); | |||
assertEquals(d.superClassName(), "Base"); | |||
assertEquals(e.superClassName(), "D"); | |||
assertEquals(f.superClassName(), "E"); | |||
__toVersion__(3); | |||
assertEquals(d.superClassName(), "E"); | |||
assertEquals(e.superClassName(), "F"); | |||
assertEquals(f.superClassName(), "Base"); | |||
__toVersion__(4); | |||
assertEquals(d.superClassName(), "E"); | |||
assertEquals(e.superClassName(), "Base"); | |||
assertEquals(f.superClassName(), "E"); | |||
__toVersion__(3); | |||
assertEquals(d.superClassName(), "E"); | |||
assertEquals(e.superClassName(), "F"); | |||
assertEquals(f.superClassName(), "Base"); | |||
__toVersion__(2); | |||
assertEquals(d.superClassName(), "Base"); | |||
assertEquals(e.superClassName(), "D"); | |||
assertEquals(f.superClassName(), "E"); | |||
__toVersion__(0); | |||
assertEquals(d.superClassName(), "Base"); | |||
assertEquals(e.superClassName(), "Base"); | |||
assertEquals(f.superClassName(), "Base"); | |||
} | |||
} |
@@ -25,7 +25,11 @@ | |||
package com.github.dcevm.test.structural; | |||
import com.github.dcevm.test.TestUtil; | |||
import org.junit.*; | |||
import org.junit.After; | |||
import org.junit.AfterClass; | |||
import org.junit.Before; | |||
import org.junit.BeforeClass; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; |
@@ -0,0 +1,293 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.structural; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static org.junit.Assert.assertEquals; | |||
/** | |||
* Tests that modify a large class hierarchy with the classes A, B, C, D, E, and F. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
public class LargeHierarchyTest { | |||
private A a = new A(); | |||
private B b = new B(); | |||
private C c = new C(); | |||
private D d = new D(); | |||
private E e = new E(); | |||
private F f = new F(); | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
// Version 0 | |||
public static class A { | |||
public int value() { | |||
return 1; | |||
} | |||
} | |||
public static class B extends A { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
public static class C extends B { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
public static class D extends C { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
public static class E extends D { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
public static class F extends E { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
// Version 1 | |||
public static class A___1 { | |||
public int value() { | |||
return 2; | |||
} | |||
} | |||
// Version 2 | |||
// D - E - F | |||
// / | |||
// A - B - C | |||
public static class D___2 extends A { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
// Version 3 | |||
// D | |||
// / | |||
// A - B - C - E - F | |||
public static class D___3 extends A { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
public static class E___3 extends A { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
// Version 4 | |||
// Completely flat | |||
public static class C___4 extends A { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
public static class D___4 extends A { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
public static class E___4 extends A { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
public static class F___4 extends A { | |||
@Override | |||
public int value() { | |||
return super.value() * 2; | |||
} | |||
} | |||
// Version 5 | |||
public static class F___5 extends E { | |||
@Override | |||
public int value() { | |||
return 0; | |||
} | |||
} | |||
@Test | |||
public void testChangeBaseClass() { | |||
assert __version__() == 0; | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertEquals(4, c.value()); | |||
assertEquals(8, d.value()); | |||
assertEquals(16, e.value()); | |||
assertEquals(32, f.value()); | |||
__toVersion__(1); | |||
assertEquals(2, a.value()); | |||
assertEquals(4, b.value()); | |||
assertEquals(8, c.value()); | |||
assertEquals(16, d.value()); | |||
assertEquals(32, e.value()); | |||
assertEquals(64, f.value()); | |||
__toVersion__(0); | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertEquals(4, c.value()); | |||
assertEquals(8, d.value()); | |||
assertEquals(16, e.value()); | |||
assertEquals(32, f.value()); | |||
} | |||
@Test | |||
public void testChangeSubClass() { | |||
assert __version__() == 0; | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertEquals(4, c.value()); | |||
assertEquals(8, d.value()); | |||
assertEquals(16, e.value()); | |||
assertEquals(32, f.value()); | |||
__toVersion__(5); | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertEquals(4, c.value()); | |||
assertEquals(8, d.value()); | |||
assertEquals(16, e.value()); | |||
assertEquals(0, f.value()); | |||
__toVersion__(0); | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertEquals(4, c.value()); | |||
assertEquals(8, d.value()); | |||
assertEquals(16, e.value()); | |||
assertEquals(32, f.value()); | |||
} | |||
@Test | |||
public void testChangeHierarchy() { | |||
assert __version__() == 0; | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertEquals(4, c.value()); | |||
assertEquals(8, d.value()); | |||
assertEquals(16, e.value()); | |||
assertEquals(32, f.value()); | |||
__toVersion__(2); | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertEquals(4, c.value()); | |||
assertEquals(2, d.value()); | |||
assertEquals(4, e.value()); | |||
assertEquals(8, f.value()); | |||
__toVersion__(3); | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertEquals(4, c.value()); | |||
assertEquals(2, d.value()); | |||
assertEquals(2, e.value()); | |||
assertEquals(4, f.value()); | |||
__toVersion__(4); | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertEquals(2, c.value()); | |||
assertEquals(2, d.value()); | |||
assertEquals(2, e.value()); | |||
assertEquals(2, f.value()); | |||
__toVersion__(0); | |||
assertEquals(1, a.value()); | |||
assertEquals(2, b.value()); | |||
assertEquals(4, c.value()); | |||
assertEquals(8, d.value()); | |||
assertEquals(16, e.value()); | |||
assertEquals(32, f.value()); | |||
} | |||
} |
@@ -24,9 +24,11 @@ | |||
package com.github.dcevm.test.structural; | |||
import com.github.dcevm.ClassRedefinitionPolicy; | |||
import com.github.dcevm.test.category.Full; | |||
import org.junit.Before; | |||
import org.junit.Ignore; | |||
import org.junit.Test; | |||
import org.junit.experimental.categories.Category; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
@@ -36,6 +38,7 @@ import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@Category(Full.class) | |||
@Ignore | |||
public class RedefineClassClassTest { | |||
@@ -24,9 +24,11 @@ | |||
package com.github.dcevm.test.structural; | |||
import com.github.dcevm.ClassRedefinitionPolicy; | |||
import com.github.dcevm.test.category.Full; | |||
import org.junit.Before; | |||
import org.junit.Ignore; | |||
import org.junit.Test; | |||
import org.junit.experimental.categories.Category; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
@@ -37,113 +39,109 @@ import static org.junit.Assert.assertEquals; | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@Category(Full.class) | |||
@Ignore | |||
public class RedefineObjectClassTest { | |||
// Version 0 | |||
public static class Helper { | |||
public static String access(Object o) { | |||
return ""; | |||
} | |||
// Version 0 | |||
public static class Helper { | |||
public static String access(Object o) { | |||
return ""; | |||
} | |||
} | |||
// Version 1 | |||
// Version 1 | |||
public static class Helper___1 { | |||
public static String access(Object o) { | |||
return ((A___1) o).myTestFunction___(); | |||
} | |||
public static class Helper___1 { | |||
public static String access(Object o) { | |||
return ((A___1) o).myTestFunction___(); | |||
} | |||
} | |||
@ClassRedefinitionPolicy(alias = java.lang.Object.class) | |||
public static class A___1 { | |||
@ClassRedefinitionPolicy(alias = java.lang.Object.class) | |||
public static class A___1 { | |||
public final native Class<? extends Object> getClass___(); | |||
public final native Class<? extends Object> getClass___(); | |||
@Override | |||
public native int hashCode(); | |||
public native int hashCode(); | |||
@Override | |||
public boolean equals(Object obj) { | |||
return (this == obj); | |||
} | |||
public static int x; | |||
public static int x1; | |||
public static int x2; | |||
public static int x3; | |||
public static int x4; | |||
public static int x5; | |||
public boolean equals(Object obj) { | |||
return (this == obj); | |||
} | |||
@Override | |||
protected native Object clone() throws CloneNotSupportedException; | |||
public static int x; | |||
public static int x1; | |||
public static int x2; | |||
public static int x3; | |||
public static int x4; | |||
public static int x5; | |||
@Override | |||
public String toString() { | |||
System.out.println("x=" + (x++)); | |||
return getClass().getName() + "@" + Integer.toHexString(hashCode());// myTestFunction___(); | |||
} | |||
protected native Object clone() throws CloneNotSupportedException; | |||
public final String myTestFunction___() { | |||
return "com/github/dcevm/test"; | |||
} | |||
public String toString() { | |||
System.out.println("x=" + (x++)); | |||
return getClass().getName() + "@" + Integer.toHexString(hashCode());// myTestFunction___(); | |||
} | |||
public final native void notify___(); | |||
public final String myTestFunction___() { | |||
return "test"; | |||
} | |||
public final native void notifyAll___(); | |||
public final native void notify___(); | |||
public final native void wait___(long timeout) throws InterruptedException; | |||
public final native void notifyAll___(); | |||
public final void wait___(long timeout, int nanos) throws InterruptedException { | |||
public final native void wait___(long timeout) throws InterruptedException; | |||
public final void wait___(long timeout, int nanos) throws InterruptedException { | |||
if (timeout < 0) { | |||
throw new IllegalArgumentException("timeout value is negative"); | |||
} | |||
if (nanos < 0 || nanos > 999999) { | |||
throw new IllegalArgumentException( | |||
"nanosecond timeout value out of range"); | |||
} | |||
if (timeout < 0) { | |||
throw new IllegalArgumentException("timeout value is negative"); | |||
} | |||
if (nanos >= 500000 || (nanos != 0 && timeout == 0)) { | |||
timeout++; | |||
} | |||
if (nanos < 0 || nanos > 999999) { | |||
throw new IllegalArgumentException( | |||
"nanosecond timeout value out of range"); | |||
} | |||
wait(timeout); | |||
} | |||
if (nanos >= 500000 || (nanos != 0 && timeout == 0)) { | |||
timeout++; | |||
} | |||
public final void wait___() throws InterruptedException { | |||
wait(0); | |||
} | |||
wait(timeout); | |||
} | |||
@Override | |||
protected void finalize() throws Throwable { | |||
} | |||
public final void wait___() throws InterruptedException { | |||
wait(0); | |||
} | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
protected void finalize() throws Throwable { | |||
} | |||
} | |||
@Test | |||
public void testRedefineObject() { | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
assert __version__() == 0; | |||
@Test | |||
public void testRedefineObject() { | |||
Object o = new Object(); | |||
__toVersion__(1); | |||
assert __version__() == 0; | |||
System.out.println(this.toString()); | |||
System.out.println(o.toString()); | |||
System.out.println(this.toString()); | |||
Object o = new Object(); | |||
__toVersion__(1); | |||
System.out.println(this.toString()); | |||
System.out.println(o.toString()); | |||
System.out.println(this.toString()); | |||
//assertEquals("test", o.toString()); | |||
assertEquals("com/github/dcevm/test", Helper.access(o)); | |||
__toVersion__(0); | |||
__toVersion__(1); | |||
__toVersion__(0); | |||
} | |||
//assertEquals("test", o.toString()); | |||
assertEquals("test", Helper.access(o)); | |||
__toVersion__(0); | |||
__toVersion__(1); | |||
__toVersion__(0); | |||
} | |||
} |
@@ -25,8 +25,10 @@ | |||
package com.github.dcevm.test.structural; | |||
import com.github.dcevm.test.TestUtil; | |||
import com.github.dcevm.test.category.Light; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.junit.experimental.categories.Category; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
@@ -36,6 +38,7 @@ import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@Category(Light.class) | |||
public class ThisTypeChange { | |||
@Before |
@@ -0,0 +1,180 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.structural; | |||
import com.github.dcevm.test.TestUtil; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static org.junit.Assert.assertEquals; | |||
/** | |||
* Test case for type narrowing. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
public class TypeNarrowingHeapTest { | |||
// Version 0 | |||
public static class A { | |||
int x = 1; | |||
int y = 2; | |||
int z = 3; | |||
public int value() { | |||
return x; | |||
} | |||
} | |||
public static class C { | |||
private A a; | |||
public C(A a) { | |||
this.a = a; | |||
} | |||
} | |||
public static class B extends A { | |||
} | |||
// Version 1 | |||
public static class B___1 { | |||
} | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
A a = new A(); | |||
B b = new B(); | |||
} | |||
@Test | |||
public void testSimpleTypeNarrowing() { | |||
assert __version__() == 0; | |||
A a = convertBtoA(new B()); | |||
assertEquals(1, a.value()); | |||
// Cannot do conversion if A object is on the stack! | |||
a = null; | |||
__toVersion__(1); | |||
TestUtil.assertException(NoSuchMethodError.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
B b = new B(); | |||
b.value(); | |||
} | |||
}); | |||
__toVersion__(0); | |||
assert __version__() == 0; | |||
} | |||
@Test | |||
public void testTypeNarrowingWithField() { | |||
C c = new C(new A()); | |||
__toVersion__(1); | |||
__toVersion__(0); | |||
c = new C(convertBtoA(new B())); | |||
TestUtil.assertException(UnsupportedOperationException.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
__toVersion__(1); | |||
} | |||
}); | |||
assert __version__() == 0; | |||
c.a = null; | |||
__toVersion__(1); | |||
__toVersion__(0); | |||
} | |||
// Method to enforce cast (otherwise bytecodes become invalid in version 2) | |||
public static A convertBtoA(Object b) { | |||
return (A)b; | |||
} | |||
@Test | |||
public void testTypeNarrowingWithArray() { | |||
final B b = new B(); | |||
final A[] arr = new A[3]; | |||
arr[0] = new A(); | |||
assert b instanceof A; | |||
__toVersion__(1); | |||
assert !(b instanceof A); | |||
TestUtil.assertException(ArrayStoreException.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
arr[1] = b; | |||
} | |||
}); | |||
__toVersion__(0); | |||
arr[1] = new B(); | |||
TestUtil.assertException(UnsupportedOperationException.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
__toVersion__(1); | |||
} | |||
}); | |||
assert __version__() == 0; | |||
assert b instanceof A; | |||
arr[1] = new A(); | |||
__toVersion__(1); | |||
assert !(b instanceof A); | |||
__toVersion__(0); | |||
assert b instanceof A; | |||
} | |||
} |
@@ -0,0 +1,113 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.structural; | |||
import com.github.dcevm.test.TestUtil; | |||
import org.junit.Before; | |||
import org.junit.Ignore; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
/** | |||
* Test case for type narrowing where a non-active method fails verification because of the new hierarchy. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@Ignore | |||
public class TypeNarrowingMethodTest { | |||
// Version 0 | |||
public static class A { | |||
int x = 1; | |||
int y = 2; | |||
int z = 3; | |||
public int value() { | |||
return x; | |||
} | |||
public static int badMethod(B b) { | |||
A a = b; | |||
return a.y; | |||
} | |||
} | |||
public static class B extends A { | |||
} | |||
// Version 1 | |||
public static class B___1 { | |||
} | |||
// Version 2 | |||
public static class A___2 { | |||
int x = 1; | |||
int y = 2; | |||
int z = 3; | |||
public int value() { | |||
return x; | |||
} | |||
public static int badMethod(B b) { | |||
return 5; | |||
} | |||
} | |||
public static class B___2 { | |||
} | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
A a = new A(); | |||
B b = new B(); | |||
} | |||
@Test | |||
public void testTypeNarrowingWithViolatingMethod() { | |||
TestUtil.assertException(UnsupportedOperationException.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
__toVersion__(1); | |||
} | |||
}); | |||
assert __version__() == 0; | |||
__toVersion__(2); | |||
__toVersion__(0); | |||
} | |||
} |
@@ -0,0 +1,118 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.structural; | |||
import com.github.dcevm.test.TestUtil; | |||
import org.junit.Before; | |||
import org.junit.Ignore; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
/** | |||
* Test case for type narrowing where a non-active method fails verification because of the new hierarchy. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@Ignore | |||
public class TypeNarrowingMethodTest2 { | |||
// Version 0 | |||
public static class A { | |||
int x = 1; | |||
int y = 2; | |||
int z = 3; | |||
public int value() { | |||
return x; | |||
} | |||
public static int badMethod() { | |||
A a = indirectionMethod(); | |||
return a.y; | |||
} | |||
} | |||
public static class B extends A { | |||
} | |||
// Version 1 | |||
public static class B___1 { | |||
} | |||
// Version 2 | |||
public static class A___2 { | |||
int x = 1; | |||
int y = 2; | |||
int z = 3; | |||
public int value() { | |||
return x; | |||
} | |||
public static int badMethod(B b) { | |||
return 5; | |||
} | |||
} | |||
public static class B___2 { | |||
} | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
A a = new A(); | |||
B b = new B(); | |||
} | |||
public static B indirectionMethod() { | |||
return new B(); | |||
} | |||
@Test | |||
public void testTypeNarrowingWithViolatingMethod() { | |||
final A a = new A(); | |||
TestUtil.assertException(UnsupportedOperationException.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
__toVersion__(1); | |||
System.out.println(a.badMethod()); | |||
} | |||
}); | |||
assert __version__() == 0; | |||
__toVersion__(2); | |||
__toVersion__(0); | |||
} | |||
} |
@@ -0,0 +1,117 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.structural; | |||
import com.github.dcevm.test.TestUtil; | |||
import org.junit.Before; | |||
import org.junit.Ignore; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
/** | |||
* Test case for type narrowing where a non-active method fails verification because of the new hierarchy. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
@Ignore | |||
public class TypeNarrowingMethodTest3 { | |||
// Version 0 | |||
public static class A { | |||
int x = 1; | |||
int y = 2; | |||
int z = 3; | |||
public int value() { | |||
return x; | |||
} | |||
public static int badMethod() { | |||
A a = indirectionMethod()[0]; | |||
return a.y; | |||
} | |||
} | |||
public static class B extends A { | |||
} | |||
// Version 1 | |||
public static class B___1 { | |||
} | |||
// Version 2 | |||
public static class A___2 { | |||
int x = 1; | |||
int y = 2; | |||
int z = 3; | |||
public int value() { | |||
return x; | |||
} | |||
public static int badMethod(B b) { | |||
return 5; | |||
} | |||
} | |||
public static class B___2 { | |||
} | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
A a = new A(); | |||
B b = new B(); | |||
} | |||
public static B[] indirectionMethod() { | |||
return new B[]{ new B() }; | |||
} | |||
@Test | |||
public void testTypeNarrowingWithViolatingMethod() { | |||
final A a = new A(); | |||
TestUtil.assertException(UnsupportedOperationException.class, new Runnable() { | |||
@Override | |||
public void run() { | |||
__toVersion__(1); | |||
System.out.println(a.badMethod()); | |||
} | |||
}); | |||
assert __version__() == 0; | |||
__toVersion__(2); | |||
__toVersion__(0); | |||
} | |||
} |
@@ -0,0 +1,100 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.transformer; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static org.junit.Assert.assertEquals; | |||
class BaseClass { | |||
public void $transformer() { | |||
transformerExecuted(); | |||
} | |||
public void transformerExecuted() { | |||
} | |||
} | |||
/** | |||
* Tests for executing the transformer of a base class. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
public class BaseClassTransformerTest { | |||
// Version 0 | |||
public static class A { | |||
public int x = 2; | |||
} | |||
// Version 3 | |||
public static class A___1 extends BaseClass { | |||
public int x; | |||
@Override | |||
public void transformerExecuted() { | |||
System.out.println("Transformer of A executing..."); | |||
x = x * 2; | |||
} | |||
} | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
@Test | |||
public void testSimpleTransformer() { | |||
assert __version__() == 0; | |||
A a = new A(); | |||
assertEquals(2, a.x); | |||
__toVersion__(1); | |||
assertEquals(4, a.x); | |||
__toVersion__(0); | |||
assertEquals(4, a.x); | |||
__toVersion__(1); | |||
assertEquals(8, a.x); | |||
__toVersion__(0); | |||
assertEquals(8, a.x); | |||
} | |||
} |
@@ -0,0 +1,89 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.transformer; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static org.junit.Assert.assertEquals; | |||
/** | |||
* Tests for executing the transformer of a class. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
public class SimpleTransformerTest { | |||
// Version 0 | |||
public static class A { | |||
public int x = 2; | |||
} | |||
// Version 3 | |||
public static class A___1 { | |||
public int x; | |||
public void $transformer() { | |||
System.out.println("Transformer of A executing..."); | |||
x = x * 2; | |||
} | |||
} | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
@Test | |||
public void testSimpleTransformer() { | |||
assert __version__() == 0; | |||
A a = new A(); | |||
assertEquals(2, a.x); | |||
__toVersion__(1); | |||
assertEquals(4, a.x); | |||
__toVersion__(0); | |||
assertEquals(4, a.x); | |||
__toVersion__(1); | |||
assertEquals(8, a.x); | |||
__toVersion__(0); | |||
assertEquals(8, a.x); | |||
} | |||
} |
@@ -0,0 +1,88 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.transformer; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
/** | |||
* @author Kerstin Breiteneder | |||
* @author Christoph Wimberger | |||
*/ | |||
public class StaticConstructorTransformerTest { | |||
//Version 0 | |||
public static class Static_TestClass { | |||
// remove static --> no fatal error occurs | |||
public static int x = 0; | |||
//public int x = 0; | |||
static { | |||
System.out.println("Start Static_TestClass Version 0"); | |||
try { | |||
Thread.sleep(1000); | |||
} catch (InterruptedException ex) { | |||
} | |||
System.out.println("End Static_TestClass Version 0"); | |||
} | |||
} | |||
//Version 1 | |||
public static class Static_TestClass___1 { | |||
public int version = 1; | |||
static { | |||
System.out.println("Static_TestClass Version 1"); | |||
} | |||
public void $transformer() { | |||
System.out.println(":::::::::transformerExecuted:::::::::::"); | |||
} | |||
} | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
@Test | |||
public void testStaticConstructorTransformerTest() { | |||
assert __version__() == 0; | |||
try { | |||
Class.forName("at.ssw.hotswap.test.transformer.StaticConstructorTransformerTest$Static_TestClass"); | |||
} catch (ClassNotFoundException ex) { | |||
ex.printStackTrace(); | |||
} | |||
Static_TestClass clazz = new Static_TestClass(); | |||
__toVersion__(1); | |||
} | |||
} |
@@ -0,0 +1,87 @@ | |||
/* | |||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | |||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |||
* | |||
* This code is free software; you can redistribute it and/or modify it | |||
* under the terms of the GNU General Public License version 2 only, as | |||
* published by the Free Software Foundation. | |||
* | |||
* This code is distributed in the hope that it will be useful, but WITHOUT | |||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
* version 2 for more details (a copy is included in the LICENSE file that | |||
* accompanied this code). | |||
* | |||
* You should have received a copy of the GNU General Public License version | |||
* 2 along with this work; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |||
* | |||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |||
* or visit www.oracle.com if you need additional information or have any | |||
* questions. | |||
* | |||
*/ | |||
package com.github.dcevm.test.transformer; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__; | |||
import static com.github.dcevm.test.util.HotSwapTestHelper.__version__; | |||
import static org.junit.Assert.assertEquals; | |||
/** | |||
* Tests for executing the transformer of a class. | |||
* | |||
* @author Thomas Wuerthinger | |||
*/ | |||
public class StaticTransformerTest { | |||
// Version 0 | |||
public static class A { | |||
public static int x = 2; | |||
} | |||
// Version 3 | |||
public static class A___1 { | |||
public static int x; | |||
public static void $staticTransformer() { | |||
System.out.println("Static transformer of A executing..."); | |||
x = x * 2; | |||
} | |||
} | |||
@Before | |||
public void setUp() throws Exception { | |||
__toVersion__(0); | |||
} | |||
@Test | |||
public void testStaticTransformer() { | |||
assert __version__() == 0; | |||
assertEquals(2, A.x); | |||
__toVersion__(1); | |||
assertEquals(4, A.x); | |||
__toVersion__(0); | |||
assertEquals(4, A.x); | |||
__toVersion__(1); | |||
assertEquals(8, A.x); | |||
__toVersion__(0); | |||
assertEquals(8, A.x); | |||
} | |||
} |
@@ -24,6 +24,7 @@ | |||
package com.github.dcevm.test.util; | |||
import com.github.dcevm.HotSwapTool; | |||
import sun.reflect.CallerSensitive; | |||
/** | |||
* Shortcut methods for testing. Methods are named this way to make them more visible in the test code. |