8324641: [IR Framework] Add Setup method to provide custom arguments and set fields

Reviewed-by: chagedorn, thartmann
This commit is contained in:
Emanuel Peter 2024-02-09 05:30:20 +00:00
parent b797652209
commit 8d9ad97c29
28 changed files with 1115 additions and 268 deletions

View File

@ -78,7 +78,7 @@ public class TestIterativeEA {
}
@Test
@Arguments({ Argument.RANDOM_EACH })
@Arguments(values = { Argument.RANDOM_EACH })
@IR(failOn = { IRNode.ALLOC })
public static int testSlow(int val) {
MyClass obj = new MyClass(val);
@ -88,7 +88,7 @@ public class TestIterativeEA {
}
@Test
@Arguments({ Argument.RANDOM_EACH })
@Arguments(values = { Argument.RANDOM_EACH })
@IR(failOn = { IRNode.ALLOC })
public static int testFast(int val) {
MyClass obj = new MyClass(val);
@ -119,7 +119,7 @@ public class TestIterativeEA {
}
@Test
@Arguments({ Argument.RANDOM_EACH })
@Arguments(values = { Argument.RANDOM_EACH })
@IR(failOn = { IRNode.ALLOC })
static int testNested(int i) {
C c = new C(new B(new A(i)));

View File

@ -41,7 +41,7 @@ public class TestOptimizeUnstableIf {
}
@Test
@Arguments({Argument.MAX}) // the argument needs to be big enough to fall out of cache.
@Arguments(values = {Argument.MAX}) // the argument needs to be big enough to fall out of cache.
@IR(failOn = {IRNode.ALLOC_OF, "Integer"})
public static int boxing_object(int value) {
Integer ii = Integer.valueOf(value);

View File

@ -40,7 +40,7 @@ public class TestRemixAddressExpressions {
@Test
@IR(counts = { IRNode.ADD_I, "1", IRNode.LSHIFT_I, "2" })
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
public static float invPlusVarLshiftInt(int inv, int scale) {
float res = 0;
for (int i = 1; i < 100; i *= 11) {
@ -51,7 +51,7 @@ public class TestRemixAddressExpressions {
@Test
@IR(counts = { IRNode.ADD_L, "1", IRNode.LSHIFT_L, "2" })
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
public static float invPlusVarLshiftLong(long inv, int scale) {
float res = 0;
for (long i = 1; i < 100; i *= 11) {
@ -62,7 +62,7 @@ public class TestRemixAddressExpressions {
@Test
@IR(counts = { IRNode.ADD_I, "1", IRNode.SUB_I, "1", IRNode.LSHIFT_I, "2" })
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
public static float invMinusVarLshiftInt(int inv, int scale) {
float res = 0;
for (int i = 1; i < 100; i *= 11) {
@ -73,7 +73,7 @@ public class TestRemixAddressExpressions {
@Test
@IR(counts = { IRNode.ADD_L, "1", IRNode.SUB_L, "1", IRNode.LSHIFT_L, "2" })
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
public static float invMinusVarLshiftLong(long inv, int scale) {
float res = 0;
for (long i = 1; i < 100; i *= 11) {
@ -84,7 +84,7 @@ public class TestRemixAddressExpressions {
@Test
@IR(counts = { IRNode.ADD_I, "1", IRNode.SUB_I, "1", IRNode.LSHIFT_I, "2" })
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
public static float varMinusInvLshiftInt(int inv, int scale) {
float res = 0;
for (int i = 1; i < 100; i *= 11) {
@ -95,7 +95,7 @@ public class TestRemixAddressExpressions {
@Test
@IR(counts = { IRNode.ADD_L, "1", IRNode.SUB_L, "1", IRNode.LSHIFT_L, "2" })
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
public static float varMinusInvLshiftLong(long inv, int scale) {
float res = 0;
for (long i = 1; i < 100; i *= 11) {

View File

@ -44,7 +44,7 @@ public class TestShiftAndMask {
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
@IR(failOn = { IRNode.AND_I, IRNode.LSHIFT_I })
public static int shiftMaskInt(int i) {
return (i << 2) & 3; // transformed to: return 0;
@ -58,7 +58,7 @@ public class TestShiftAndMask {
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
@IR(failOn = { IRNode.AND_L, IRNode.LSHIFT_L })
public static long shiftMaskLong(long i) {
return (i << 2) & 3; // transformed to: return 0;
@ -75,7 +75,7 @@ public class TestShiftAndMask {
static volatile int barrier;
@Test
@Arguments({Argument.RANDOM_EACH, Argument.BOOLEAN_TOGGLE_FIRST_TRUE})
@Arguments(values = {Argument.RANDOM_EACH, Argument.BOOLEAN_TOGGLE_FIRST_TRUE})
@IR(failOn = { IRNode.AND_I, IRNode.LSHIFT_I })
public static int shiftNonConstMaskInt(int i, boolean flag) {
int mask;
@ -96,7 +96,7 @@ public class TestShiftAndMask {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.BOOLEAN_TOGGLE_FIRST_TRUE})
@Arguments(values = {Argument.RANDOM_EACH, Argument.BOOLEAN_TOGGLE_FIRST_TRUE})
@IR(failOn = { IRNode.AND_L, IRNode.LSHIFT_L })
public static long shiftNonConstMaskLong(long i, boolean flag) {
long mask;
@ -207,7 +207,7 @@ public class TestShiftAndMask {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = { IRNode.AND_I, IRNode.ADD_I, IRNode.LSHIFT_I })
public static int addShiftMaskInt2(int i, int j) {
return ((j << 2) + (i << 2)) & 3; // transformed to: return 0;
@ -221,7 +221,7 @@ public class TestShiftAndMask {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = { IRNode.AND_L, IRNode.ADD_L, IRNode.LSHIFT_L })
public static long addShiftMaskLong2(long i, long j) {
return ((j << 2) + (i << 2)) & 3; // transformed to: return 0;
@ -274,7 +274,7 @@ public class TestShiftAndMask {
}
@Test
@Arguments({Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH})
@IR(failOn = { IRNode.AND_L, IRNode.LSHIFT_I, IRNode.CONV_I2L })
public static long shiftConvMask(int i) {
return ((long)(i << 2)) & 3; // transformed to: return 0;
@ -288,7 +288,7 @@ public class TestShiftAndMask {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.BOOLEAN_TOGGLE_FIRST_TRUE})
@Arguments(values = {Argument.RANDOM_EACH, Argument.BOOLEAN_TOGGLE_FIRST_TRUE})
@IR(failOn = { IRNode.AND_L, IRNode.LSHIFT_I, IRNode.CONV_I2L })
public static long shiftNotConstConvMask(int i, boolean flag) {
long mask;
@ -326,7 +326,7 @@ public class TestShiftAndMask {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = { IRNode.AND_L, IRNode.ADD_L, IRNode.LSHIFT_I, IRNode.CONV_I2L })
public static long addShiftConvMask2(int i, int j) {
return (((long)(j << 2)) + ((long)(i << 2))) & 3; // transformed to: return 0;

View File

@ -43,7 +43,7 @@ public class TestSpecialCasesOf_AMinusB_Plus_CMinusD_InAddIdeal {
}
@Test
@Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE})
@Arguments(values = {Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE})
@IR(failOn = {IRNode.ADD_I})
@IR(counts = {IRNode.SUB_I, "1"})
public int test1Int(int a, int b, int c) {
@ -51,7 +51,7 @@ public class TestSpecialCasesOf_AMinusB_Plus_CMinusD_InAddIdeal {
}
@Test
@Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE})
@Arguments(values = {Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE})
@IR(failOn = {IRNode.ADD_L})
@IR(counts = {IRNode.SUB_L, "1"})
public long test1Long(long a, long b, long c) {
@ -59,7 +59,7 @@ public class TestSpecialCasesOf_AMinusB_Plus_CMinusD_InAddIdeal {
}
@Test
@Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE})
@Arguments(values = {Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE})
@IR(failOn = {IRNode.ADD_I})
@IR(counts = {IRNode.SUB_I, "1"})
public int test2Int(int b, int a, int c) { // make sure inputs sorted
@ -67,7 +67,7 @@ public class TestSpecialCasesOf_AMinusB_Plus_CMinusD_InAddIdeal {
}
@Test
@Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE})
@Arguments(values = {Argument.RANDOM_ONCE, Argument.RANDOM_ONCE, Argument.RANDOM_ONCE})
@IR(failOn = {IRNode.ADD_L})
@IR(counts = {IRNode.SUB_L, "1"})
public long test2Long(long b, long a, long c) { // make sure inputs sorted

View File

@ -44,7 +44,7 @@ public class TestTestRemovalPeephole {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = {IRNode.X86_TESTI_REG, IRNode.X86_TESTL_REG}, phase = CompilePhase.FINAL_CODE)
public boolean testIntAddtionEquals0(int x, int y) {
int result = x + y;
@ -56,7 +56,7 @@ public class TestTestRemovalPeephole {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = {IRNode.X86_TESTI_REG, IRNode.X86_TESTL_REG}, phase = CompilePhase.FINAL_CODE)
public boolean testIntAddtionNotEquals0(int x, int y) {
int result = x + y;
@ -68,7 +68,7 @@ public class TestTestRemovalPeephole {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = {IRNode.X86_TESTI_REG, IRNode.X86_TESTL_REG}, phase = CompilePhase.FINAL_CODE)
public boolean testLongAddtionEquals0(long x, long y) {
long result = x + y;
@ -80,7 +80,7 @@ public class TestTestRemovalPeephole {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = {IRNode.X86_TESTI_REG, IRNode.X86_TESTL_REG}, phase = CompilePhase.FINAL_CODE)
public boolean testLongAddtionNotEquals0(long x, long y) {
long result = x + y;
@ -92,7 +92,7 @@ public class TestTestRemovalPeephole {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = {IRNode.X86_TESTI_REG, IRNode.X86_TESTL_REG}, phase = CompilePhase.FINAL_CODE)
public boolean testIntOrEquals0(int x, int y) {
int result = x | y;
@ -104,7 +104,7 @@ public class TestTestRemovalPeephole {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = {IRNode.X86_TESTI_REG, IRNode.X86_TESTL_REG}, phase = CompilePhase.FINAL_CODE)
public boolean testIntOrNotEquals0(int x, int y) {
int result = x | y;
@ -116,7 +116,7 @@ public class TestTestRemovalPeephole {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = {IRNode.X86_TESTI_REG, IRNode.X86_TESTL_REG}, phase = CompilePhase.FINAL_CODE)
public boolean testLongOrEquals0(long x, long y) {
long result = x | y;
@ -128,7 +128,7 @@ public class TestTestRemovalPeephole {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = {IRNode.X86_TESTI_REG, IRNode.X86_TESTL_REG}, phase = CompilePhase.FINAL_CODE)
public boolean testLongOrNotEquals0(long x, long y) {
long result = x | y;
@ -140,7 +140,7 @@ public class TestTestRemovalPeephole {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = {IRNode.X86_TESTI_REG, IRNode.X86_TESTL_REG}, phase = CompilePhase.FINAL_CODE)
public boolean testIntOrGreater0(int x, int y) {
int result = x | y;
@ -152,7 +152,7 @@ public class TestTestRemovalPeephole {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = {IRNode.X86_TESTI_REG, IRNode.X86_TESTL_REG}, phase = CompilePhase.FINAL_CODE)
public boolean testLongOrGreater0(long x, long y) {
long result = x | y;
@ -180,4 +180,4 @@ public class TestTestRemovalPeephole {
Asserts.assertEQ((x | y) != 0, testLongOrNotEquals0(x, y));
Asserts.assertEQ((x | y) > 0, testLongOrGreater0(x, y));
}
}
}

View File

@ -114,7 +114,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_L, "1"})
public static void testLongMinValueMinus1(boolean flag, boolean flag2) {
long l = flag ? -1 : Long.MIN_VALUE;
@ -129,7 +129,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = {IRNode.MUL_L, IRNode.STORE_L}, counts = {IRNode.STORE_I, "1"})
public static void testLongMinValuePlus1(boolean flag, boolean flag2) {
long l = flag ? -1 : Long.MIN_VALUE;
@ -144,7 +144,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = {IRNode.MUL_L, IRNode.STORE_L, IRNode.LSHIFT}, counts = {IRNode.STORE_I, "1"})
public static void testLongMinValueUnderflowOnce(boolean flag, boolean flag2) {
long l = flag ? Long.MIN_VALUE/2 : Long.MIN_VALUE/2 + 1;
@ -159,7 +159,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_I, "1", IRNode.STORE_L, "1", IRNode.MUL_L, "1"})
public static void testLongMinValueUnderflowOnceTwice(boolean flag, boolean flag2) {
long l = flag ? Long.MIN_VALUE/2 : Long.MIN_VALUE/2 + 1;
@ -174,7 +174,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = {IRNode.MUL_L, IRNode.STORE_L, IRNode.LSHIFT}, counts = {IRNode.STORE_I, "1"})
public static void testLongMinValueUnderflowTwice(boolean flag, boolean flag2) {
long l = flag ? Long.MIN_VALUE/2 : Long.MIN_VALUE/2 + 1;
@ -189,7 +189,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = {IRNode.MUL_L, IRNode.STORE_L, IRNode.LSHIFT}, counts = {IRNode.STORE_I, "1"})
public static void testLongMaxValueOverflowOnce(boolean flag, boolean flag2) {
long l = flag2 ? Long.MAX_VALUE/2 - 1 : Long.MAX_VALUE/2;
@ -204,7 +204,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_I, "1", IRNode.STORE_L, "1", IRNode.MUL_L, "1"})
public static void testLongMaxValueOverflowOnceTwice(boolean flag, boolean flag2) {
long l = flag2 ? Long.MAX_VALUE/2 - 1 : Long.MAX_VALUE/2;
@ -219,7 +219,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = {IRNode.MUL_L, IRNode.STORE_L, IRNode.LSHIFT}, counts = {IRNode.STORE_I, "1"})
public static void testLongMaxValueOverflowTwice(boolean flag, boolean flag2) {
long l = flag2 ? Long.MAX_VALUE/2 - 1 : Long.MAX_VALUE/2;
@ -234,7 +234,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = IRNode.MUL_L, counts = {IRNode.STORE_L, "1"})
public static void testLongProductsOverflowOnceAtMin(boolean flag, boolean flag2) {
long l = flag ? Long.MAX_VALUE/2 + 1 : Long.MAX_VALUE/2 + 2;
@ -251,7 +251,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = IRNode.MUL_L, counts = {IRNode.STORE_L, "1"})
public static void testLongProductsOverflowOnceAtMax(boolean flag, boolean flag2) {
// 88971434439113593 * 311 = Long.MAX_VALUE*3 + 2 --cast to long--> Long.MAX_VALUE
@ -269,7 +269,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = IRNode.MUL_L, counts = {IRNode.STORE_L, "1"})
public static void testLongProductsUnderflowOnceAtMin(boolean flag, boolean flag2) {
long l = flag ? Long.MIN_VALUE/3 - 1 : Long.MIN_VALUE/3 - 2;
@ -286,7 +286,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = IRNode.MUL_L, counts = {IRNode.STORE_L, "1"})
public static void testLongProductsUnderflowOnceAtMax(boolean flag, boolean flag2) {
// -6917529027641081856 * 4 = Long.MIN_VALUE*3 --cast to long--> Long.MIN_VALUE
@ -304,7 +304,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_L, "1"})
public static void testLongProductsDifferentNumberOfOverflow(boolean flag, boolean flag2) {
// 88971434439113593 * 311 = Long.MAX_VALUE*3 + 2 --cast to long--> Long.MAX_VALUE // Overflown once
@ -322,7 +322,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_L, "1"})
public static void testLongProductsDifferentNumberOfUnderflows(boolean flag, boolean flag2) {
// -6917529027641081856 * 4 = Long.MIN_VALUE*3 --cast to long--> Long.MIN_VALUE // Underflown once
@ -340,7 +340,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_L, "1"})
public static void testLongNotSameOverflow1(boolean flag, boolean flag2) {
long l = flag ? 1 : Long.MAX_VALUE;
@ -355,7 +355,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_L, "1"})
public static void testLongNotSameOverflow2(boolean flag, boolean flag2) {
long l = flag ? 1 : Long.MIN_VALUE;
@ -370,7 +370,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_L, "1"})
public static void testLongNotSameOverflow3(boolean flag, boolean flag2) {
long l = flag ? -1 : Long.MIN_VALUE;
@ -385,7 +385,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_L, "1"})
public static void testLongNotSameOverflow4(boolean flag, boolean flag2) {
long l = flag ? -1 : Long.MAX_VALUE;
@ -400,7 +400,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_L, "1"})
public static void testLongNotSameOverflow5(boolean flag, boolean flag2) {
long l = flag ? Long.MIN_VALUE : Long.MAX_VALUE;
@ -492,7 +492,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_I, "1"})
public static void testIntMinValueMinus1(boolean flag, boolean flag2) {
int l = flag ? -1 : Integer.MIN_VALUE;
@ -508,7 +508,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = {IRNode.MUL_I, IRNode.STORE_L}, counts = {IRNode.STORE_I, "1"})
public static void testIntMinValuePlus1(boolean flag, boolean flag2) {
int l = flag ? -1 : Integer.MIN_VALUE;
@ -523,7 +523,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = {IRNode.MUL_I, IRNode.STORE_L, IRNode.LSHIFT}, counts = {IRNode.STORE_I, "1"})
public static void testIntMinValueUnderflowOnce(boolean flag, boolean flag2) {
int l = flag ? Integer.MIN_VALUE/2 : Integer.MIN_VALUE/2 + 1;
@ -538,7 +538,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_I, "1", IRNode.STORE_L, "1", IRNode.MUL_I, "1"})
public static void testIntMinValueUnderflowOnceTwice(boolean flag, boolean flag2) {
int l = flag ? Integer.MIN_VALUE/2 : Integer.MIN_VALUE/2 + 1;
@ -553,7 +553,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = {IRNode.MUL_I, IRNode.STORE_L, IRNode.LSHIFT}, counts = {IRNode.STORE_I, "1"})
public static void testIntMinValueUnderflowTwice(boolean flag, boolean flag2) {
int l = flag ? Integer.MIN_VALUE/2 : Integer.MIN_VALUE/2 + 1;
@ -568,7 +568,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = {IRNode.MUL_I, IRNode.STORE_L, IRNode.LSHIFT}, counts = {IRNode.STORE_I, "1"})
public static void testIntMaxValueOverflowOnce(boolean flag, boolean flag2) {
int l = flag2 ? Integer.MAX_VALUE/2 - 1 : Integer.MAX_VALUE/2;
@ -583,7 +583,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_I, "1", IRNode.STORE_L, "1", IRNode.MUL_I, "1"})
public static void testIntMaxValueOverflowOnceTwice(boolean flag, boolean flag2) {
int l = flag2 ? Integer.MAX_VALUE/2 - 1 : Integer.MAX_VALUE/2;
@ -598,7 +598,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = {IRNode.MUL_I, IRNode.STORE_L, IRNode.LSHIFT}, counts = {IRNode.STORE_I, "1"})
public static void testIntMaxValueOverflowTwice(boolean flag, boolean flag2) {
int l = flag2 ? Integer.MAX_VALUE/2 - 1 : Integer.MAX_VALUE/2;
@ -613,7 +613,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = IRNode.MUL_I, counts = {IRNode.STORE_L, "1"})
public static void testIntProductsOverflowOnceAtMin(boolean flag, boolean flag2) {
int l = flag ? Integer.MAX_VALUE/2 + 1 : Integer.MAX_VALUE/2 + 2;
@ -630,7 +630,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = IRNode.MUL_I, counts = {IRNode.STORE_L, "1"})
public static void testIntProductsOverflowOnceAtMax(boolean flag, boolean flag2) {
// 63786643 * 101 = Integer.MAX_VALUE*3 + 2 --cast to int--> Integer.MAX_VALUE
@ -648,7 +648,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = IRNode.MUL_I, counts = {IRNode.STORE_L, "1"})
public static void testIntProductsUnderflowOnceAtMin(boolean flag, boolean flag2) {
int l = flag ? Integer.MIN_VALUE/3 - 1 : Integer.MIN_VALUE/3 - 2;
@ -665,7 +665,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(failOn = IRNode.MUL_I, counts = {IRNode.STORE_L, "1"})
public static void testIntProductsUnderflowOnceAtMax(boolean flag, boolean flag2) {
// -1610612736 * 4 = Integer.MIN_VALUE*3 --cast to int--> Integer.MIN_VALUE
@ -683,7 +683,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_I, "1"})
public static void testIntProductsDifferentNumberOfOverflow(boolean flag, boolean flag2) {
// 63786643 * 101 = Integer.MAX_VALUE*3 + 2 --cast to int--> Integer.MAX_VALUE // Overflown once
@ -701,7 +701,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_I, "1"})
public static void testIntProductsDifferentNumberOfUnderflows(boolean flag, boolean flag2) {
// -1610612736 * 4 = Integer.MIN_VALUE*3 --cast to int--> Integer.MIN_VALUE // Underflown once
@ -719,7 +719,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_I, "1"})
public static void testIntNotSameOverflow1(boolean flag, boolean flag2) {
int l = flag ? 1 : Integer.MAX_VALUE;
@ -734,7 +734,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_I, "1"})
public static void testIntNotSameOverflow2(boolean flag, boolean flag2) {
int l = flag ? 1 : Integer.MIN_VALUE;
@ -749,7 +749,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_I, "1"})
public static void testIntNotSameOverflow3(boolean flag, boolean flag2) {
int l = flag ? -1 : Integer.MIN_VALUE;
@ -764,7 +764,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_I, "1"})
public static void testIntNotSameOverflow4(boolean flag, boolean flag2) {
int l = flag ? -1 : Integer.MAX_VALUE;
@ -779,7 +779,7 @@ public class TestIntegerMulRing {
@Test
@Warmup(0)
@Arguments({Argument.TRUE, Argument.FALSE})
@Arguments(values = {Argument.TRUE, Argument.FALSE})
@IR(counts = {IRNode.STORE_L, "2", IRNode.MUL_I, "1"})
public static void testIntNotSameOverflow5(boolean flag, boolean flag2) {
int l = flag ? Integer.MIN_VALUE : Integer.MAX_VALUE;

View File

@ -55,7 +55,7 @@ public class ScalarReplacementTests {
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
@IR(failOn = {IRNode.CALL, IRNode.LOAD, IRNode.STORE, IRNode.FIELD_ACCESS, IRNode.ALLOC})
public String stringConstant(int age) {
Person p = new Person("Java", age);
@ -63,7 +63,7 @@ public class ScalarReplacementTests {
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
@IR(failOn = {IRNode.CALL, IRNode.LOAD, IRNode.STORE, IRNode.FIELD_ACCESS, IRNode.ALLOC})
public int intConstant(int age) {
Person p = new Person("Java", age);
@ -71,7 +71,7 @@ public class ScalarReplacementTests {
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
@IR(failOn = {IRNode.CALL, IRNode.LOAD, IRNode.STORE, IRNode.FIELD_ACCESS, IRNode.ALLOC})
public String nestedStringConstant(int age) {
Person p1 = new Person("Java", age);
@ -80,7 +80,7 @@ public class ScalarReplacementTests {
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
@IR(failOn = {IRNode.CALL, IRNode.LOAD, IRNode.STORE, IRNode.FIELD_ACCESS, IRNode.ALLOC})
public int nestedIntConstant(int age) {
Person p1 = new Person("Java", age);
@ -89,7 +89,7 @@ public class ScalarReplacementTests {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@IR(failOn = {IRNode.CALL, IRNode.LOAD, IRNode.STORE, IRNode.FIELD_ACCESS, IRNode.ALLOC})
public int nestedConstants(int age1, int age2) {
Person p = new Person(

View File

@ -27,8 +27,10 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* This annotation is used to specify well-defined {@link Argument} values for test methods (specifying {@link Test}) when
* used as part of a <b>base test</b> or <b>checked test</b>.
* This annotation is used for test methods (see {@link Test}) to specify what values should be passed as arguments.
* One can either specify the individual arguments with values (see {@link Argument}), or use
* a setup method (see {@link Setup}) to define more complex arguments and/or even set fields values.
* This annotation can only be applied to a <b>normal test</b>.
*
* @see Argument
* @see Test
@ -37,7 +39,11 @@ import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Arguments {
/**
* Get the argument value.
* Get the argument values.
*/
Argument[] value();
Argument[] values() default {};
/**
* Get the setup method name.
*/
String setup() default "";
}

View File

@ -34,19 +34,29 @@ There are various ways how to set up and run a test within the `main()` method o
The framework offers various annotations and flags to control how your test code should be invoked and being checked. This section gives an overview over all these features.
### 2.1 Different Tests
There are three kinds of tests depending on how much control is needed over the test invocation.
#### Base Tests
The simplest form of testing provides a single `@Test` annotated method which the framework will invoke as part of the testing. The test method has no or well-defined arguments that the framework can automatically provide.
There are two ways a test can be written, depending on how much control is needed over the test invocation.
More information on base tests with a precise definition can be found in the Javadocs of [Test](./Test.java). Concrete examples on how to specify a base test can be found in [BaseTestsExample](../../../testlibrary_tests/ir_framework/examples/BaseTestExample.java).
#### Normal Test
The normal and simplest form of testing provides a single `@Test` annotated method which the framework invokes directly as part of the testing. The test method either has no arguments, or they must be specified with an `@Arguments` annotation.
#### Checked Tests
The base tests do not provide any way of verification by user code. A checked test enables this by allowing the user to define an additional `@Check` annotated method which is invoked directly after the `@Test` annotated method. This allows the user to perform various checks about the test method including return value verification.
Arguments can be provided with `@Arguments(values = {...})` by providing well-specified inputs for each individual argument. Alternatively, a setup method can be chosen with `@Arguments(setup = "setupMethodName")`, which computes arguments and can also set fields.
More information on checked tests with a precise definition can be found in the Javadocs of [Check](./Check.java). Concrete examples on how to specify a checked test can be found in [CheckedTestsExample](../../../testlibrary_tests/ir_framework/examples/CheckedTestExample.java).
More information on normal test methods with a precise definition can be found in the Javadocs of [Test](./Test.java). Concrete examples on how to specify a normal test can be found in [NormalTestExample](../../../testlibrary_tests/ir_framework/examples/NormalTestExample.java).
##### Setup Method
A `@Setup` annotated method can provide custom arguments and set fields before a normal test is run. A `@Test` annotated method can additionally be annotated with `@Arguments(setup = "setupMethodName")` to define the dedicated `@Setup` method.
More information on normal tests with `@Setup` methods together with a precise definition can be found in the Javadocs of [Setup](./Setup.java). Concrete examples on how to specify a setup method can be found in [SetupExample](../../../testlibrary_tests/ir_framework/examples/SetupExample.java).
##### Check Method
A `@Check(test = "checkMethodName")` annotated method is invoked directly after the `@Test` annotated method `checkMethodName()` is executed. The user can perform various checks, such as test method return value and field value verification.
More information on check methods with a precise definition can be found in the Javadocs of [Check](./Check.java). Concrete examples on how to specify check methods can be found in [CheckedTestExample](../../../testlibrary_tests/ir_framework/examples/CheckedTestExample.java).
Note: `@Setup` and `@Check` methods can only be specified for normal but not for custom run tests (see next section).
#### Custom Run Tests
Neither the base nor the checked tests provide any control over how a `@Test` annotated method is invoked in terms of customized argument values and/or conditions for the invocation itself. A custom run test gives full control over the invocation of the `@Test` annotated method to the user. The framework calls a dedicated `@Run` annotated method from which the user can invoke the `@Test` method according to his/her needs.
A custom run test gives full control over the invocation of the `@Test` annotated method to the user which includes argument and field setup as well as result and field value verification. The framework calls a dedicated `@Run` annotated method from which the user can invoke the `@Test` method according to their needs.
More information on checked tests with a precise definition can be found in the Javadocs of [Run](./Run.java). Concrete examples on how to specify a custom run test can be found in [CustomRunTestsExample](../../../testlibrary_tests/ir_framework/examples/CustomRunTestExample.java).

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2024, 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 compiler.lib.ir_framework;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* This annotation is used to identify Setup methods. These can be used to compute arbitrary arguments for a test
* method (see {@link Test}), as well as to set field values. A test method can use a setup method, by specifying
* it in a {@link Arguments} annotation. A setup method can optionally take a {@link SetupInfo} as an argument. The
* arguments for the test methods are returned as a new object array.
*
* Examples on how to use test methods can be found in {@link ir_framework.examples.SetupExample} and also as part of the
* internal testing in the package {@link ir_framework.tests}.
*
* @see Arguments
* @see Setup
* @see SetupInfo
* @see Test
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Setup {
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2024, 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 compiler.lib.ir_framework;
/**
* Info optionally passed to {@link Setup} annotated methods.
*
* @see Setup
*/
public record SetupInfo(int invocationCounter) {
/**
* Get the invocation counter, which increments with every invocation of the setup method. It allows the creation
* of deterministically different inputs to the test method for every invocation.
*/
@Override
public int invocationCounter() {
return invocationCounter;
}
}

View File

@ -71,7 +71,7 @@ import java.lang.annotation.RetentionPolicy;
* </ul>
*
* <p>
* Examples on how to write base tests can be found in {@link ir_framework.examples.BaseTestExample}
* Examples on how to write base tests can be found in {@link ir_framework.examples.NormalTestExample}
* and also as part of the internal testing in the package {@link ir_framework.tests}.
*
* @see Arguments

View File

@ -94,7 +94,6 @@ abstract class AbstractTest {
if (skip) {
return;
}
onStart();
for (int i = 0; i < warmupIterations; i++) {
invokeTest();
}
@ -104,10 +103,6 @@ abstract class AbstractTest {
invokeTest();
}
protected void onStart() {
// Do nothing by default.
}
abstract protected void invokeTest();
abstract protected void onWarmupFinished();

View File

@ -68,18 +68,14 @@ class ArgumentValue {
}
/**
* Return all arguments for the @Arguments annotation.
* From the @Arguments(value = {...}) annotation, determine the list of ArgumentValues for a specific test method m.
*
* @param m The @Test method.
* @param values The argument values specified in the annotation.
* @return Returns an array with Argument objects for each specified argument in the @Arguments annotation of m.
* Returns null if method has no @Arguments annotation.
*/
public static ArgumentValue[] getArguments(Method m) {
Arguments argumentsAnno = m.getAnnotation(Arguments.class);
if (argumentsAnno == null) {
return null;
}
Argument[] values = argumentsAnno.value();
public static ArgumentValue[] getArgumentValues(Method m, Argument[] values) {
ArgumentValue[] arguments = new ArgumentValue[values.length];
Class<?>[] declaredParameters = m.getParameterTypes();
Parameter[] declaredParameterObjects = m.getParameters();
@ -250,7 +246,7 @@ class ArgumentValue {
return isFixedRandom;
}
public Object getArgument() {
public Object getValue() {
if (isRandomEach) {
return getRandom(randomClass);
} else {
@ -322,7 +318,7 @@ class BooleanToggleValue extends ArgumentValue {
}
@Override
public Object getArgument() {
public Object getValue() {
previousBoolean = !previousBoolean;
return previousBoolean;
}

View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2024, 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 compiler.lib.ir_framework.test;
import compiler.lib.ir_framework.shared.TestFormat;
import compiler.lib.ir_framework.shared.TestRunException;
import compiler.lib.ir_framework.Argument;
import compiler.lib.ir_framework.Arguments;
import compiler.lib.ir_framework.SetupInfo;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Arrays;
/**
* This interface provides arguments (and can set fields) for a test method. Different implementations are chosen
* based on the @Arguments annotation for the @Test method.
*/
interface ArgumentsProvider {
/**
* Compute arguments (and possibly set fields) for a test method.
*
* @param invocationTarget object on which the test method is called, or null if the test method is static.
* @param invocationCounter is incremented for every set of arguments to be provided for the test method.
* It can be used to create deterministic inputs, that vary between different
* invocations of the test method.
* @return Returns the arguments to be passed into the test method.
*/
Object[] getArguments(Object invocationTarget, int invocationCounter);
}
/**
* For a test method, determine what ArgumentsProvider is to be constructed, given its @Arguments annotation,
* and the available setup methods.
*/
class ArgumentsProviderBuilder {
public static ArgumentsProvider build(Method method,
HashMap<String, Method> setupMethodMap) {
Arguments argumentsAnnotation = method.getAnnotation(Arguments.class);
if (argumentsAnnotation == null) {
return new DefaultArgumentsProvider();
}
Argument[] values = argumentsAnnotation.values();
String setupMethodName = argumentsAnnotation.setup();
if (!setupMethodName.isEmpty()) {
TestFormat.check(values.length == 0,
"@Arguments: Can only specify \"setup\" or \"values\" but not both in " + method);
TestFormat.check(setupMethodMap.containsKey(setupMethodName),
"@Arguments setup: did not find " + setupMethodName +
" for " + method);
Method setupMethod = setupMethodMap.get(setupMethodName);
return new SetupArgumentsProvider(setupMethod);
} else {
TestFormat.check(values.length > 0,
"@Arguments: Empty annotation not allowed. Either specify \"values\" or \"setup\" in " + method);
ArgumentValue[] argumentValues = ArgumentValue.getArgumentValues(method, values);
return new ValueArgumentsProvider(argumentValues);
}
}
}
/**
* Default: when no @Arguments annotation is provided (including for custom run tests).
*/
final class DefaultArgumentsProvider implements ArgumentsProvider {
@Override
public Object[] getArguments(Object invocationTarget, int invocationCounter) {
return new Object[]{};
}
}
/**
* Used for @Arguments(values = {...}) to specify individual arguments directly.
*/
final class ValueArgumentsProvider implements ArgumentsProvider {
ArgumentValue[] argumentValues;
ValueArgumentsProvider(ArgumentValue[] argumentValues) {
this.argumentValues = argumentValues;
}
@Override
public Object[] getArguments(Object invocationTarget, int invocationCounter) {
return Arrays.stream(argumentValues).map(v -> v.getValue()).toArray();
}
}
/**
* Used for @Arguments(setup = "setupMethodName") to specify a setup method to provide arguments
* and possibly set fields.
*/
final class SetupArgumentsProvider implements ArgumentsProvider {
Method setupMethod;
SetupArgumentsProvider(Method setupMethod) {
this.setupMethod = setupMethod;
}
@Override
public Object[] getArguments(Object invocationTarget, int invocationCounter) {
Object target = Modifier.isStatic(setupMethod.getModifiers()) ? null
: invocationTarget;
try {
if (setupMethod.getParameterCount() == 1) {
return (Object[]) setupMethod.invoke(target, new SetupInfo(invocationCounter));
} else {
return (Object[]) setupMethod.invoke(target);
}
} catch (Exception e) {
throw new TestRunException("There was an error while invoking setup method " +
setupMethod + " on " + target, e);
}
}
}

View File

@ -38,6 +38,7 @@ class BaseTest extends AbstractTest {
protected final Object invocationTarget;
private final boolean shouldCompile;
private final boolean waitForCompilation;
private int invocationCounter;
public BaseTest(DeclaredTest test, boolean skip) {
super(test.getWarmupIterations(), skip);
@ -47,6 +48,7 @@ class BaseTest extends AbstractTest {
this.invocationTarget = createInvocationTarget(testMethod);
this.shouldCompile = shouldCompile(test);
this.waitForCompilation = isWaitForCompilation(test);
this.invocationCounter = 0;
}
@Override
@ -59,11 +61,6 @@ class BaseTest extends AbstractTest {
return testMethod.getName();
}
@Override
protected void onStart() {
test.printFixedRandomArguments();
}
@Override
public void onWarmupFinished() {
testInfo.setWarmUpFinished();
@ -74,16 +71,18 @@ class BaseTest extends AbstractTest {
verify(invokeTestMethod());
}
/**
* Compute arguments (and possibly set fields), and invoke the test method.
*/
private Object invokeTestMethod() {
Object[] arguments = test.getArguments(invocationTarget, invocationCounter++);
try {
if (test.hasArguments()) {
return testMethod.invoke(invocationTarget, test.getArguments());
} else {
return testMethod.invoke(invocationTarget);
}
return testMethod.invoke(invocationTarget, arguments);
} catch (Exception e) {
throw new TestRunException("There was an error while invoking @Test method " + testMethod
+ ". Used arguments: " + test.getArgumentsString(), e);
throw new TestRunException("There was an error while invoking @Test method " + testMethod +
". Target: " + invocationTarget +
". Arguments: " + test.formatArguments(arguments),
e);
}
}

View File

@ -27,24 +27,23 @@ import compiler.lib.ir_framework.CompLevel;
import compiler.lib.ir_framework.shared.TestRunException;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* This class represents a @Test method.
*/
public class DeclaredTest {
private final Method testMethod;
private final ArgumentValue[] arguments;
private final ArgumentsProvider argumentsProvider;
private final int warmupIterations;
private final CompLevel compLevel;
private Method attachedMethod;
public DeclaredTest(Method testMethod, ArgumentValue[] arguments, CompLevel compLevel, int warmupIterations) {
public DeclaredTest(Method testMethod, ArgumentsProvider argumentsProvider, CompLevel compLevel, int warmupIterations) {
// Make sure we can also call non-public or public methods in package private classes
testMethod.setAccessible(true);
this.testMethod = testMethod;
this.compLevel = compLevel;
this.arguments = arguments;
this.argumentsProvider = argumentsProvider;
this.warmupIterations = warmupIterations;
this.attachedMethod = null;
}
@ -61,12 +60,8 @@ public class DeclaredTest {
return warmupIterations;
}
public boolean hasArguments() {
return arguments != null;
}
public Object[] getArguments() {
return Arrays.stream(arguments).map(ArgumentValue::getArgument).toArray();
public Object[] getArguments(Object invocationTarget, int invocationCounter) {
return argumentsProvider.getArguments(invocationTarget, invocationCounter);
}
public void setAttachedMethod(Method m) {
@ -77,41 +72,22 @@ public class DeclaredTest {
return attachedMethod;
}
public void printFixedRandomArguments() {
if (hasArguments()) {
boolean hasRandomArgs = false;
StringBuilder builder = new StringBuilder("Fixed random arguments for method ").append(testMethod).append(": ");
for (int i = 0; i < arguments.length; i++) {
ArgumentValue argument = arguments[i];
if (argument.isFixedRandom()) {
hasRandomArgs = true;
Object argumentVal = argument.getArgument();
builder.append("arg ").append(i).append(": ").append(argumentVal.toString());
if (argumentVal instanceof Character) {
builder.append(" (").append((int)(Character)argumentVal).append(")");
}
builder.append(", ");
}
}
if (hasRandomArgs) {
// Drop the last comma and space.
builder.setLength(builder.length() - 2);
System.out.println(builder.toString());
}
/**
* Format an array of arguments to string for error reporting.
*/
public String formatArguments(Object[] arguments) {
if (arguments == null) {
return "<null>";
}
}
public String getArgumentsString() {
if (hasArguments()) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < arguments.length; i++) {
builder.append("arg ").append(i).append(": ").append(arguments[i].getArgument()).append(", ");
}
builder.setLength(builder.length() - 2);
return builder.toString();
} else {
if (arguments.length == 0) {
return "<void>";
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < arguments.length; i++) {
builder.append("arg ").append(i).append(": ").append(arguments[i]).append(", ");
}
builder.setLength(builder.length() - 2);
return builder.toString();
}
public Object invoke(Object obj, Object... args) {

View File

@ -107,6 +107,7 @@ public class TestVM {
private final HashMap<Method, DeclaredTest> declaredTests = new HashMap<>();
private final List<AbstractTest> allTests = new ArrayList<>();
private final HashMap<String, Method> testMethodMap = new HashMap<>();
private final HashMap<String, Method> setupMethodMap = new HashMap<>();
private final List<String> excludeList;
private final List<String> testList;
private Set<Class<?>> helperClasses = null; // Helper classes that contain framework annotations to be processed.
@ -225,6 +226,8 @@ public class TestVM {
"Cannot use @Run annotation in " + clazzType + " " + c + " at " + m);
TestFormat.checkNoThrow(getAnnotation(m, Check.class) == null,
"Cannot use @Check annotation in " + clazzType + " " + c + " at " + m);
TestFormat.checkNoThrow(getAnnotation(m, Setup.class) == null,
"Cannot use @Setup annotation in " + clazzType + " " + c + " at " + m);
}
}
@ -256,6 +259,11 @@ public class TestVM {
if (DUMP_REPLAY) {
addReplay();
}
// Collect the @Setup methods so we can reference them
// from the test methods
collectSetupMethods();
// Make sure to first setup test methods and make them non-inlineable and only then process compile commands.
setupDeclaredTests();
processControlAnnotations(testClass);
@ -495,6 +503,35 @@ public class TestVM {
}
}
/**
* Collect all @Setup annotated methods and add them to setupMethodMap, for convenience to reference later from
* tests with @Arguments(setup = "setupMethodName").
*/
private void collectSetupMethods() {
for (Method m : testClass.getDeclaredMethods()) {
Setup setupAnnotation = getAnnotation(m, Setup.class);
if (setupAnnotation != null) {
addSetupMethod(m);
}
}
}
private void addSetupMethod(Method m) {
TestFormat.checkNoThrow(getAnnotation(m, Test.class) == null,
"@Setup method cannot have @Test annotation: " + m);
TestFormat.checkNoThrow(getAnnotation(m, Check.class) == null,
"@Setup method cannot have @Check annotation: " + m);
TestFormat.checkNoThrow(getAnnotation(m, Arguments.class) == null,
"@Setup method cannot have @Arguments annotation: " + m);
TestFormat.checkNoThrow(getAnnotation(m, Run.class) == null,
"@Setup method cannot have @Run annotation: " + m);
Method mOverloaded = setupMethodMap.put(m.getName(), m);
TestFormat.checkNoThrow(mOverloaded == null,
"@Setup method cannot be overloaded: " + mOverloaded + " with " + m);
m.setAccessible(true);
}
/**
* Setup @Test annotated method an add them to the declaredTests map to have a convenient way of accessing them
* once setting up a framework test (base checked, or custom run test).
@ -540,7 +577,8 @@ public class TestVM {
if (EXCLUDE_RANDOM) {
compLevel = compLevel.excludeCompilationRandomly(m);
}
DeclaredTest test = new DeclaredTest(m, ArgumentValue.getArguments(m), compLevel, warmupIterations);
ArgumentsProvider argumentsProvider = ArgumentsProviderBuilder.build(m, setupMethodMap);
DeclaredTest test = new DeclaredTest(m, argumentsProvider, compLevel, warmupIterations);
declaredTests.put(m, test);
testMethodMap.put(m.getName(), m);
}
@ -729,7 +767,8 @@ public class TestVM {
TestFormat.check(attachedMethod == null,
"Cannot use @Test " + testMethod + " for more than one @Run/@Check method. Found: "
+ m + ", " + attachedMethod);
TestFormat.check(!test.hasArguments(),
Arguments argumentsAnno = getAnnotation(testMethod, Arguments.class);
TestFormat.check(argumentsAnno == null,
"Cannot use @Arguments at test method " + testMethod + " in combination with @Run method " + m);
Warmup warmupAnno = getAnnotation(testMethod, Warmup.class);
TestFormat.checkNoThrow(warmupAnno == null,

View File

@ -74,7 +74,7 @@ public class CheckedTestExample {
}
@Test
@Arguments(Argument.DEFAULT) // As with normal tests, you need to tell the framework what the argument is.
@Arguments(values = Argument.DEFAULT) // As with normal tests, you need to tell the framework what the argument is.
@Warmup(100) // As with normal tests, you can specify the warmup iterations.
public int test(int x) {
return 42;

View File

@ -30,7 +30,7 @@ import compiler.lib.ir_framework.test.TestVM; // Only used for Javadocs
* @test
* @summary Example test to use the new test framework.
* @library /test/lib /
* @run driver ir_framework.examples.BaseTestExample
* @run driver ir_framework.examples.NormalTestExample
*/
/**
@ -58,11 +58,11 @@ import compiler.lib.ir_framework.test.TestVM; // Only used for Javadocs
* @see Warmup
* @see TestFramework
*/
public class BaseTestExample {
public class NormalTestExample {
int iFld;
public static void main(String[] args) {
TestFramework.run(); // equivalent to TestFramework.run(BaseTestExample.class)
TestFramework.run(); // equivalent to TestFramework.run(NormalTestExample.class)
}
// Test without arguments.
@ -74,14 +74,14 @@ public class BaseTestExample {
// Test with arguments. Use Argument class to choose a value.
// Object arguments need to have an associated default constructor in its class.
@Test
@Arguments({Argument.DEFAULT, Argument.MAX})
@Arguments(values = {Argument.DEFAULT, Argument.MAX})
public void basicTestWithArguments(int x, long y) {
iFld = x;
}
// @Warmup needs to be positive or zero. In case of zero, the method is directly compiled (simulated -Xcomp).
@Test
@Arguments({Argument.DEFAULT, Argument.MAX})
@Arguments(values = {Argument.DEFAULT, Argument.MAX})
@Warmup(100)
public void basicTestWithDifferentWarmup(int x, long y) {
iFld = x;

View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2024, 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 ir_framework.examples;
import compiler.lib.ir_framework.*;
import compiler.lib.ir_framework.SetupInfo;
import jdk.test.lib.Utils;
import java.util.Random;
/*
* @test
* @summary Example test to use setup method (provide arguments and set fields).
* @library /test/lib /
* @run driver ir_framework.examples.SetupExample
*/
/**
* This file shows some examples of how to use a setup method, annotated with {@link Setup}, and referenced by
* a test method with @Arguments(setup = "setupMethodName").
*
* @see Setup
* @see Arguments
* @see Test
*/
public class SetupExample {
private static final Random RANDOM = Utils.getRandomInstance();
int iFld1, iFld2;
public static void main(String[] args) {
TestFramework.run();
}
// ----------------- Random but Linked --------------
@Setup
static Object[] setupLinkedII() {
int r = RANDOM.nextInt();
return new Object[]{ r, r + 42 };
}
@Test
@Arguments(setup = "setupLinkedII")
static int testSetupLinkedII(int a, int b) {
return b - a;
}
@Check(test = "testSetupLinkedII")
static void checkSetupLinkedII(int res) {
if (res != 42) {
throw new RuntimeException("wrong result " + res);
}
}
// ----------------- Random Arrays --------------
static int[] generateI(int len) {
int[] a = new int[len];
for (int i = 0; i < len; i++) {
a[i] = RANDOM.nextInt();
}
return a;
}
@Setup
static Object[] setupRandomArrayII() {
// Random length, so that AutoVectorization pre/main/post and drain loops are tested
int len = RANDOM.nextInt(20_000);
int[] a = generateI(len);
int[] b = generateI(len);
return new Object[] { a, b };
}
@Test
@Arguments(setup = "setupRandomArrayII")
static Object[] testAdd(int[] a, int[] b) {
int[] c = new int[a.length];
for (int i = 0; i < a.length; i++) {
c[i] = a[i] + b[i];
}
return new Object[] { a, b, c };
}
@Check(test = "testAdd")
static void checkAdd(Object[] res) {
int[] a = (int[])res[0];
int[] b = (int[])res[1];
int[] c = (int[])res[2];
for (int i = 0; i < a.length; i++) {
if (c[i] != a[i] + b[i]) {
throw new RuntimeException("wrong values: " + a[i] + " " + b[i] + " " + c[i]);
}
}
}
// ----------------- Setup Fields ---------------
@Setup
void setupFields() {
int r = RANDOM.nextInt();
iFld1 = r;
iFld2 = r + 42;
}
@Test
@Arguments(setup = "setupFields")
int testSetupFields() {
return iFld2 - iFld1;
}
@Check(test = "testSetupFields")
static void checkSetupFields(int res) {
if (res != 42) {
throw new RuntimeException("wrong result " + res);
}
}
// ----------------- Deterministic Values -------
@Setup
Object[] setupDeterministic(SetupInfo info) {
// This value increments with every invocation of the setup method: 0, 1, 2, ...
int cnt = info.invocationCounter();
// Return true with low frequency. If we did this randomly, we can get unlucky
// and never return true. So doing it deterministically can be helpful when we
// want "low frequency" but a guaranteed "true" at some point.
return new Object[]{ cnt % 1_000 };
}
@Test
@Arguments(setup = "setupDeterministic")
@IR(counts = {IRNode.STORE_OF_FIELD, "iFld1", "1",
IRNode.STORE_OF_FIELD, "iFld2", "1"})
void testLowProbabilityBranchDeterministic(int x) {
if (x == 7) {
// unlikely branch -> guaranteed taken -> in profile -> not trapped -> in IR
iFld1 = 42;
} else {
// likely branch
iFld2 = 77;
}
}
}

View File

@ -45,7 +45,7 @@ class PackagePrivate {
}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void test2(int x) {
}

View File

@ -56,6 +56,7 @@ public class TestBadFormat {
expectTestFormatException(BadWarmup.class);
expectTestFormatException(BadBaseTests.class);
expectTestFormatException(BadRunTests.class);
expectTestFormatException(BadSetupTest.class);
expectTestFormatException(BadCheckTest.class);
expectTestFormatException(BadIRAnnotationBeforeFlagVM.class);
expectTestFormatException(BadIRAnnotations.class);
@ -205,57 +206,57 @@ class BadArgumentsAnnotation {
public void checkNoArgAnnotation2() {}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void argNumberMismatch(int a, int b) {}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void argNumberMismatch2() {}
@Test
@Arguments(Argument.NUMBER_42)
@Arguments(values = Argument.NUMBER_42)
public void notBoolean(boolean a) {}
@Test
@Arguments(Argument.NUMBER_MINUS_42)
@Arguments(values = Argument.NUMBER_MINUS_42)
public void notBoolean2(boolean a) {}
@Test
@Arguments(Argument.TRUE)
@Arguments(values = Argument.TRUE)
public void notNumber(int a) {}
@Test
@Arguments(Argument.FALSE)
@Arguments(values = Argument.FALSE)
public void notNumber2(int a) {}
@Test
@Arguments(Argument.BOOLEAN_TOGGLE_FIRST_TRUE)
@Arguments(values = Argument.BOOLEAN_TOGGLE_FIRST_TRUE)
public void notNumber3(int a) {}
@Test
@Arguments(Argument.BOOLEAN_TOGGLE_FIRST_FALSE)
@Arguments(values = Argument.BOOLEAN_TOGGLE_FIRST_FALSE)
public void notNumber4(int a) {}
@Test
@Arguments({Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.TRUE})
@Arguments(values = {Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.TRUE})
public void notNumber5(boolean a, int b) {}
@FailCount(2)
@Test
@Arguments({Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.NUMBER_42})
@Arguments(values = {Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.NUMBER_42})
public void notNumber6(int a, boolean b) {}
@FailCount(2)
@Test
@Arguments({Argument.MIN, Argument.MAX})
@Arguments(values = {Argument.MIN, Argument.MAX})
public void notNumber7(boolean a, boolean b) {}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void missingDefaultConstructor(ClassNoDefaultConstructor a) {}
@Test
@Arguments(Argument.TRUE)
@Arguments(values = Argument.TRUE)
public void wrongArgumentNumberWithRun(Object o1, Object o2) {
}
@ -265,7 +266,7 @@ class BadArgumentsAnnotation {
}
@Test
@Arguments(Argument.TRUE)
@Arguments(values = Argument.TRUE)
public void wrongArgumentNumberWithCheck(Object o1, Object o2) {
}
@ -282,11 +283,11 @@ class BadOverloadedMethod {
public void sameName() {}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void sameName(boolean a) {}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void sameName(double a) {}
}
@ -488,21 +489,21 @@ class BadWarmup {
class BadBaseTests {
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
@FailCount(3) // No default constructor + parameter + return
public TestInfo cannotUseTestInfoAsParameterOrReturn(TestInfo info) {
return null;
}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
@FailCount(3) // No default constructor + parameter + return
public RunInfo cannotUseRunInfoAsParameterOrReturn(RunInfo info) {
return null;
}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
@FailCount(3) // No default constructor + parameter + return
public AbstractInfo cannotUseAbstractInfoAsParameterOrReturn(AbstractInfo info) {
return null;
@ -531,7 +532,7 @@ class BadRunTests {
public void noTestExists() {}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void argTest(int x) {}
@FailCount(0) // Combined with argTest()
@ -578,7 +579,7 @@ class BadRunTests {
@Test
public void testInvalidRunWithArgAnnotation() {}
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
@Run(test = "testInvalidRunWithArgAnnotation")
public void invalidRunWithArgAnnotation(RunInfo info) {}
@ -623,6 +624,74 @@ class BadRunTests {
public void runInvalidReuse2() {}
}
class BadSetupTest {
// ----------- Bad Combinations of Annotations -----------------
@Setup
@Test
public Object[] badSetupTestAnnotation() {
return new Object[]{1, 2, 3};
}
@NoFail
@Test
public void testForBadSetupCheckAnnotation() {}
@Setup
@Check(test = "testForBadSetupCheckAnnotation")
public void badSetupCheckAnnotation() {}
@Setup
@Arguments(values = {Argument.NUMBER_42, Argument.NUMBER_42})
public void badSetupArgumentsAnnotation(int a, int b) {}
@NoFail
@Test
public void testForBadSetupRunAnnotation() {}
@Setup
@Run(test = "testForBadSetupRunAnnotation")
public void badSetupRunAnnotation() {}
// ----------- Useless but ok: Setup Without Test Method -----
@NoFail
@Setup
public void setupWithNoTest() {}
// ----------- Bad: Test where Setup Method does not exist ---
@Test
@Arguments(setup = "nonExistingMethod")
public void testWithNonExistingMethod() {}
// ----------- Bad Arguments Annotation ----------------------
@NoFail
@Setup
public Object[] setupForTestSetupAndValues() {
return new Object[]{1, 2};
}
@Test
@Arguments(setup = "setupForTestSetupAndValues",
values = {Argument.NUMBER_42, Argument.NUMBER_42})
public void testSetupAndValues(int a, int b) {}
// ----------- Overloaded Setup Method ----------------------
@NoFail
@Setup
Object[] setupOverloaded() {
return new Object[]{3, 2, 1};
}
@Setup
Object[] setupOverloaded(SetupInfo info) {
return new Object[]{1, 2, 3};
}
@NoFail
@Test
@Arguments(setup = "setupOverloaded")
void testOverloaded(int a, int b, int c) {}
}
class BadCheckTest {
@Check(test = "checkForCheck2")
public void checkForCheck() {}
@ -702,7 +771,7 @@ class BadCheckTest {
@Test
public void testInvalidRunWithArgAnnotation() {}
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
@Check(test = "testInvalidRunWithArgAnnotation")
public void invalidRunWithArgAnnotation(TestInfo info) {}
}

View File

@ -133,7 +133,7 @@ public class TestBasics {
// Base test, with arguments, directly invoked.
// Specify the argument values with @Arguments
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void byteDefaultArgument(byte x) {
executed[4]++;
if (x != 0) {
@ -142,7 +142,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void shortDefaultArgument(short x) {
executed[5]++;
if (x != 0) {
@ -151,7 +151,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void intDefaultArgument(int x) {
executed[6]++;
if (x != 0) {
@ -160,7 +160,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void longDefaultArgument(long x) {
executed[7]++;
if (x != 0L) {
@ -169,7 +169,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void floatDefaultArgument(float x) {
executed[8]++;
if (x != 0.0f) {
@ -178,7 +178,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void doubleDefaultArgument(double x) {
executed[9]++;
if (x != 0.0f) {
@ -187,7 +187,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void charDefaultArgument(char x) {
executed[10]++;
if (x != '\u0000') {
@ -196,7 +196,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void booleanDefaultArgument(boolean x) {
executed[11]++;
if (x) {
@ -205,7 +205,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void stringObjectDefaultArgument(String x) {
executed[12]++;
if (x == null || x.length() != 0) {
@ -214,7 +214,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
public void defaultObjectDefaultArgument(DefaultObject x) {
executed[13]++;
if (x == null || x.i != 4) {
@ -223,7 +223,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.NUMBER_42)
@Arguments(values = Argument.NUMBER_42)
public void byte42(byte x) {
executed[14]++;
if (x != 42) {
@ -232,7 +232,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.NUMBER_42)
@Arguments(values = Argument.NUMBER_42)
public void short42(short x) {
executed[15]++;
if (x != 42) {
@ -241,7 +241,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.NUMBER_42)
@Arguments(values = Argument.NUMBER_42)
public void int42(int x) {
executed[16]++;
if (x != 42) {
@ -250,7 +250,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.NUMBER_42)
@Arguments(values = Argument.NUMBER_42)
public void long42(long x) {
executed[17]++;
if (x != 42) {
@ -259,7 +259,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.NUMBER_42)
@Arguments(values = Argument.NUMBER_42)
public void float42(float x) {
executed[18]++;
if (x != 42.0) {
@ -268,7 +268,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.NUMBER_42)
@Arguments(values = Argument.NUMBER_42)
public void double42(double x) {
executed[19]++;
if (x != 42.0) {
@ -277,7 +277,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.FALSE)
@Arguments(values = Argument.FALSE)
public void booleanFalse(boolean x) {
executed[20]++;
if (x) {
@ -286,7 +286,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.TRUE)
@Arguments(values = Argument.TRUE)
public void booleanTrue(boolean x) {
executed[21]++;
if (!x) {
@ -295,37 +295,37 @@ public class TestBasics {
}
@Test
@Arguments(Argument.RANDOM_ONCE)
@Arguments(values = Argument.RANDOM_ONCE)
public void randomByte(byte x) {
executed[22]++;
}
@Test
@Arguments(Argument.RANDOM_ONCE)
@Arguments(values = Argument.RANDOM_ONCE)
public void randomShort(short x) {
executed[23]++;
}
@Test
@Arguments(Argument.RANDOM_ONCE)
@Arguments(values = Argument.RANDOM_ONCE)
public void randomInt(int x) {
executed[24]++;
}
@Test
@Arguments(Argument.RANDOM_ONCE)
@Arguments(values = Argument.RANDOM_ONCE)
public void randomLong(long x) {
executed[25]++;
}
@Test
@Arguments(Argument.RANDOM_ONCE)
@Arguments(values = Argument.RANDOM_ONCE)
public void randomFloat(float x) {
executed[26]++;
}
@Test
@Arguments(Argument.RANDOM_ONCE)
@Arguments(values = Argument.RANDOM_ONCE)
public void randomDouble(double x) {
executed[27]++;
}
@ -336,13 +336,13 @@ public class TestBasics {
}
@Test
@Arguments(Argument.RANDOM_ONCE)
@Arguments(values = Argument.RANDOM_ONCE)
public void randomBoolean(boolean x) {
executed[28]++;
}
@Test
@Arguments(Argument.BOOLEAN_TOGGLE_FIRST_FALSE)
@Arguments(values = Argument.BOOLEAN_TOGGLE_FIRST_FALSE)
public void booleanToggleFirstFalse(boolean x) {
if (executed[29] == 0) {
// First invocation
@ -357,56 +357,56 @@ public class TestBasics {
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
public void randomEachByte(byte x) {
checkNonFloatingRandomNumber(x, executed[30]);
executed[30]++;
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
public void randomEachShort(short x) {
checkNonFloatingRandomNumber(x, executed[31]);
executed[31]++;
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
public void randomEachInt(int x) {
checkNonFloatingRandomNumber(x, executed[32]);
executed[32]++;
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
public void randomEachLong(long x) {
checkNonFloatingRandomNumber(x, executed[33]);
executed[33]++;
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
public void randomEachChar(char x) {
checkNonFloatingRandomNumber(x, executed[34]);
executed[34]++;
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
public void randomEachFloat(float x) {
checkFloatingRandomNumber(x, executed[35]);
executed[35]++;
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
public void randomEachDouble(double x) {
checkFloatingRandomNumber(x, executed[36]);
executed[36]++;
}
@Test
@Arguments(Argument.RANDOM_EACH)
@Arguments(values = Argument.RANDOM_EACH)
public void randomEachBoolean(boolean x) {
checkRandomBoolean(x, executed[37]);
executed[37]++;
@ -459,7 +459,7 @@ public class TestBasics {
@Test
@Arguments(Argument.NUMBER_MINUS_42)
@Arguments(values = Argument.NUMBER_MINUS_42)
public void byteMinus42(byte x) {
executed[38]++;
if (x != -42) {
@ -468,7 +468,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.NUMBER_MINUS_42)
@Arguments(values = Argument.NUMBER_MINUS_42)
public void shortMinus42(short x) {
executed[39]++;
if (x != -42) {
@ -477,7 +477,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.NUMBER_MINUS_42)
@Arguments(values = Argument.NUMBER_MINUS_42)
public void intMinus42(int x) {
executed[40]++;
if (x != -42) {
@ -486,7 +486,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.NUMBER_MINUS_42)
@Arguments(values = Argument.NUMBER_MINUS_42)
public void longMinus42(long x) {
executed[41]++;
if (x != -42) {
@ -495,7 +495,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.NUMBER_MINUS_42)
@Arguments(values = Argument.NUMBER_MINUS_42)
public void floatMinus42(float x) {
executed[42]++;
if (x != -42.0) {
@ -504,7 +504,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.NUMBER_MINUS_42)
@Arguments(values = Argument.NUMBER_MINUS_42)
public void doubleMinus42(double x) {
executed[43]++;
if (x != -42.0) {
@ -513,7 +513,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MIN)
@Arguments(values = Argument.MIN)
public void byteMin(byte x) {
executed[79]++;
if (x != Byte.MIN_VALUE) {
@ -522,7 +522,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MIN)
@Arguments(values = Argument.MIN)
public void charMin(char x) {
executed[80]++;
if (x != Character.MIN_VALUE) {
@ -531,7 +531,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MIN)
@Arguments(values = Argument.MIN)
public void shortMin(short x) {
executed[81]++;
if (x != Short.MIN_VALUE) {
@ -540,7 +540,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MIN)
@Arguments(values = Argument.MIN)
public void intMin(int x) {
executed[82]++;
if (x != Integer.MIN_VALUE) {
@ -549,7 +549,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MIN)
@Arguments(values = Argument.MIN)
public void longMin(long x) {
executed[83]++;
if (x != Long.MIN_VALUE) {
@ -558,7 +558,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MIN)
@Arguments(values = Argument.MIN)
public void floatMin(float x) {
executed[84]++;
if (x != Float.MIN_VALUE) {
@ -567,7 +567,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MIN)
@Arguments(values = Argument.MIN)
public void doubleMin(double x) {
executed[85]++;
if (x != Double.MIN_VALUE) {
@ -576,7 +576,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MAX)
@Arguments(values = Argument.MAX)
public void byteMax(byte x) {
executed[86]++;
if (x != Byte.MAX_VALUE) {
@ -585,7 +585,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MAX)
@Arguments(values = Argument.MAX)
public void charMax(char x) {
executed[87]++;
if (x != Character.MAX_VALUE) {
@ -594,7 +594,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MAX)
@Arguments(values = Argument.MAX)
public void shortMax(short x) {
executed[88]++;
if (x != Short.MAX_VALUE) {
@ -603,7 +603,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MAX)
@Arguments(values = Argument.MAX)
public void intMax(int x) {
executed[89]++;
if (x != Integer.MAX_VALUE) {
@ -612,7 +612,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MAX)
@Arguments(values = Argument.MAX)
public void longMax(long x) {
executed[90]++;
if (x != Long.MAX_VALUE) {
@ -621,7 +621,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MAX)
@Arguments(values = Argument.MAX)
public void floatMax(float x) {
executed[91]++;
if (x != Float.MAX_VALUE) {
@ -630,7 +630,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.MAX)
@Arguments(values = Argument.MAX)
public void doubleMax(double x) {
executed[78]++;
if (x != Double.MAX_VALUE) {
@ -639,7 +639,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.DEFAULT, Argument.DEFAULT})
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
public void twoArgsDefault1(byte x, short y) {
executed[44]++;
if (x != 0 || y != 0) {
@ -648,7 +648,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.DEFAULT, Argument.DEFAULT})
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
public void twoArgsDefault2(int x, short y) {
executed[45]++;
if (x != 0 || y != 0) {
@ -657,7 +657,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.DEFAULT, Argument.DEFAULT})
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
public void twoArgsDefault3(short x, long y) {
executed[46]++;
if (x != 0 || y != 0) {
@ -666,7 +666,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.DEFAULT, Argument.DEFAULT})
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
public void twoArgsDefault4(float x, boolean y) {
executed[47]++;
if (x != 0.0 || y) {
@ -675,7 +675,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.DEFAULT, Argument.DEFAULT})
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
public void twoArgsDefault5(boolean x, char y) {
executed[48]++;
if (x || y != '\u0000') {
@ -684,7 +684,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.DEFAULT, Argument.DEFAULT})
@Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
public void twoArgsDefault6(char x, byte y) {
executed[49]++;
if (x != '\u0000' || y != 0) {
@ -693,13 +693,13 @@ public class TestBasics {
}
@Test
@Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE})
@Arguments(values = {Argument.RANDOM_ONCE, Argument.RANDOM_ONCE})
public void twoArgsRandomOnce(char x, byte y) {
executed[50]++;
}
@Test
@Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE,
@Arguments(values = {Argument.RANDOM_ONCE, Argument.RANDOM_ONCE,
Argument.RANDOM_ONCE, Argument.RANDOM_ONCE,
Argument.RANDOM_ONCE, Argument.RANDOM_ONCE,
Argument.RANDOM_ONCE, Argument.RANDOM_ONCE})
@ -711,7 +711,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE,
@Arguments(values = {Argument.RANDOM_ONCE, Argument.RANDOM_ONCE,
Argument.RANDOM_ONCE, Argument.RANDOM_ONCE,
Argument.RANDOM_ONCE, Argument.RANDOM_ONCE,
Argument.RANDOM_ONCE, Argument.RANDOM_ONCE})
@ -720,7 +720,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.RANDOM_EACH, Argument.RANDOM_EACH,
@Arguments(values = {Argument.RANDOM_EACH, Argument.RANDOM_EACH,
Argument.RANDOM_EACH, Argument.RANDOM_EACH,
Argument.RANDOM_EACH, Argument.RANDOM_EACH,
Argument.RANDOM_EACH, Argument.RANDOM_EACH})
@ -729,7 +729,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.RANDOM_ONCE, Argument.RANDOM_ONCE,
@Arguments(values = {Argument.RANDOM_ONCE, Argument.RANDOM_ONCE,
Argument.RANDOM_EACH, Argument.RANDOM_EACH,
Argument.RANDOM_ONCE, Argument.RANDOM_EACH,
Argument.RANDOM_EACH, Argument.RANDOM_ONCE})
@ -738,7 +738,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.NUMBER_42, Argument.NUMBER_42,
@Arguments(values = {Argument.NUMBER_42, Argument.NUMBER_42,
Argument.NUMBER_42, Argument.NUMBER_42,
Argument.NUMBER_42, Argument.NUMBER_42})
public void check42Mix1(byte a, short b, int c, long d, float e, double f) {
@ -749,7 +749,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.NUMBER_MINUS_42, Argument.NUMBER_MINUS_42,
@Arguments(values = {Argument.NUMBER_MINUS_42, Argument.NUMBER_MINUS_42,
Argument.NUMBER_MINUS_42, Argument.NUMBER_MINUS_42,
Argument.NUMBER_MINUS_42, Argument.NUMBER_MINUS_42})
public void check42Mix2(byte a, short b, int c, long d, float e, double f) {
@ -760,7 +760,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.NUMBER_MINUS_42, Argument.NUMBER_42,
@Arguments(values = {Argument.NUMBER_MINUS_42, Argument.NUMBER_42,
Argument.NUMBER_MINUS_42, Argument.NUMBER_MINUS_42,
Argument.NUMBER_42, Argument.NUMBER_MINUS_42})
public void check42Mix3(byte a, short b, int c, long d, float e, double f) {
@ -772,7 +772,7 @@ public class TestBasics {
@Test
@Arguments(Argument.BOOLEAN_TOGGLE_FIRST_TRUE)
@Arguments(values = Argument.BOOLEAN_TOGGLE_FIRST_TRUE)
public void booleanToggleFirstTrue(boolean x) {
if (executed[58] == 0) {
// First invocation
@ -787,7 +787,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.BOOLEAN_TOGGLE_FIRST_TRUE})
@Arguments(values = {Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.BOOLEAN_TOGGLE_FIRST_TRUE})
public void checkTwoToggles(boolean b1, boolean b2) {
if (executed[59] == 0) {
// First invocation
@ -804,7 +804,7 @@ public class TestBasics {
}
@Test
@Arguments({Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.FALSE,
@Arguments(values = {Argument.BOOLEAN_TOGGLE_FIRST_FALSE, Argument.FALSE,
Argument.TRUE, Argument.BOOLEAN_TOGGLE_FIRST_TRUE})
public void booleanMix(boolean b1, boolean b2, boolean b3, boolean b4) {
if (executed[60] == 0) {
@ -853,7 +853,7 @@ public class TestBasics {
}
@Test
@Arguments(Argument.NUMBER_42)
@Arguments(values = Argument.NUMBER_42)
public short testCheckWithArgs(short x) {
executed[94]++;
return x;

View File

@ -96,7 +96,7 @@ public class TestCheckedTests {
}
@Test
@Arguments(Argument.NUMBER_42)
@Arguments(values = Argument.NUMBER_42)
@IR(failOn = IRNode.LOAD)
@IR(counts = {IRNode.STORE_I, "0"})
public int testGood3(int x) {
@ -139,7 +139,7 @@ class BadIRAndRuntimeCheckedTests {
}
@Test
@Arguments(Argument.NUMBER_42)
@Arguments(values = Argument.NUMBER_42)
public int testBad3(int x) {
return x;
}
@ -153,7 +153,7 @@ class BadIRAndRuntimeCheckedTests {
}
@Test
@Arguments(Argument.NUMBER_42)
@Arguments(values = Argument.NUMBER_42)
@IR(failOn = IRNode.LOAD)
@IR(counts = {IRNode.STORE_I, "1"})
public int testBad4(int x) {
@ -168,7 +168,7 @@ class BadIRAndRuntimeCheckedTests {
}
@Test
@Arguments(Argument.NUMBER_42)
@Arguments(values = Argument.NUMBER_42)
public int testBad5(int x) {
return x;
}
@ -210,7 +210,7 @@ class BadIRCheckedTests {
}
@Test
@Arguments(Argument.NUMBER_42)
@Arguments(values = Argument.NUMBER_42)
@IR(failOn = IRNode.LOAD)
@IR(counts = {IRNode.STORE_I, "1"})
public int testBad4(int x) {

View File

@ -413,7 +413,7 @@ public class TestIRMatching {
class AndOr1 {
@Test
@Arguments(Argument.DEFAULT)
@Arguments(values = Argument.DEFAULT)
@IR(applyIfAnd = {"UsePerfData", "true", "TLABRefillWasteFraction", "50", "UseTLAB", "true"}, failOn = {IRNode.CALL})
public void test1(int i) {
dontInline();
@ -1110,7 +1110,7 @@ class Traps {
}
@Test
@Arguments(Argument.TRUE)
@Arguments(values = Argument.TRUE)
@IR(failOn = IRNode.TRAP) // fails
@IR(failOn = IRNode.UNSTABLE_IF_TRAP) // fails
@IR(failOn = {IRNode.PREDICATE_TRAP,

View File

@ -0,0 +1,369 @@
/*
* Copyright (c) 2024, 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 ir_framework.tests;
import compiler.lib.ir_framework.*;
import compiler.lib.ir_framework.driver.TestVMException;
import compiler.lib.ir_framework.shared.TestRunException;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import jdk.test.lib.Asserts;
import jdk.test.lib.Utils;
import java.util.Random;
/*
* @test
* @bug 8324641
* @requires vm.debug == true & vm.compMode != "Xint" & vm.compiler2.enabled & vm.flagless
* @summary Test different custom run tests.
* @library /test/lib /testlibrary_tests /
* @run driver ir_framework.tests.TestSetupTests
*/
public class TestSetupTests {
private static final Random RANDOM = Utils.getRandomInstance();
public static void main(String[] args) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
PrintStream oldOut = System.out;
System.setOut(ps);
// Positive tests in TestSetupTests class
TestFramework.run();
// Positive tests in TestSetupTestsWithFields class
TestFramework.run(TestSetupTestsWithFields.class);
// Positive tests in TestSetupTestsSetupInfo class
TestFramework.run(TestSetupTestsSetupInfo.class);
// Positive tests with expected exceptions
try {
TestFramework.run(TestSetupTestsWithExpectedExceptions.class);
Asserts.fail("Should have thrown exception");
} catch (TestVMException e) {
System.setOut(oldOut);
Asserts.assertTrue(e.getExceptionInfo().contains("testTooManyArgs"));
Asserts.assertTrue(e.getExceptionInfo().contains("IllegalArgumentException: wrong number of arguments: 3 expected: 1"));
Asserts.assertTrue(e.getExceptionInfo().contains("testTooFewArgs"));
Asserts.assertTrue(e.getExceptionInfo().contains("IllegalArgumentException: wrong number of arguments: 2 expected: 3"));
Asserts.assertTrue(e.getExceptionInfo().contains("testTooManyArgs2"));
Asserts.assertTrue(e.getExceptionInfo().contains("IllegalArgumentException: wrong number of arguments: 3 expected: 0"));
Asserts.assertTrue(e.getExceptionInfo().contains("testTooFewArgs2"));
Asserts.assertTrue(e.getExceptionInfo().contains("IllegalArgumentException: wrong number of arguments: 0 expected: 3"));
Asserts.assertTrue(e.getExceptionInfo().contains("setupTestBadSetupArgsTooMany"));
Asserts.assertTrue(e.getExceptionInfo().contains("wrong number of arguments: 0 expected: 2"));
Asserts.assertTrue(e.getExceptionInfo().contains("setupTestBadSetupArgsWrongType"));
Asserts.assertTrue(e.getExceptionInfo().contains("argument type mismatch"));
Asserts.assertTrue(e.getExceptionInfo().contains("setupReturnIntArray"));
Asserts.assertTrue(e.getExceptionInfo().contains("class [I cannot be cast to class [Ljava.lang.Object;"));
Asserts.assertTrue(e.getExceptionInfo().contains("setupReturnInt"));
Asserts.assertTrue(e.getExceptionInfo().contains("class java.lang.Integer cannot be cast to class [Ljava.lang.Object;"));
Asserts.assertTrue(e.getExceptionInfo().contains("testSetupWrongArgumentType"));
Asserts.assertTrue(e.getExceptionInfo().contains("argument type mismatch"));
Asserts.assertTrue(e.getExceptionInfo().contains("testSetupNull"));
Asserts.assertTrue(e.getExceptionInfo().contains("wrong number of arguments: 0 expected: 1"));
Asserts.assertTrue(e.getExceptionInfo().contains("Arguments: <null>"));
Asserts.assertTrue(e.getExceptionInfo().contains("setupThrowInSetup"));
Asserts.assertTrue(e.getExceptionInfo().contains("BadCheckedTestException: expected setup"));
Asserts.assertTrue(e.getExceptionInfo().contains("testThrowInTest"));
Asserts.assertTrue(e.getExceptionInfo().contains("BadCheckedTestException: expected test"));
Asserts.assertTrue(e.getExceptionInfo().contains("checkThrowInCheck"));
Asserts.assertTrue(e.getExceptionInfo().contains("BadCheckedTestException: expected check"));
// Check number of total failures:
Asserts.assertEQ(e.getExceptionInfo().split("argument type mismatch").length - 1, 2);
Asserts.assertEQ(e.getExceptionInfo().split("There was an error while invoking setup").length - 1, 5);
Asserts.assertEQ(e.getExceptionInfo().split("There was an error while invoking @Test").length - 1, 7);
Asserts.assertEQ(e.getExceptionInfo().split("There was an error while invoking @Check").length - 1, 1);
Asserts.assertEQ(e.getExceptionInfo().split("BadCheckedTestException").length - 1, 3);
Asserts.assertTrue(e.getExceptionInfo().contains("Test Failures (13)"));
}
}
// ---------- Setup Nothing ---------------
@Setup
public void setupVoid() {}
@Test
@Arguments(setup = "setupVoid")
public void testSetupVoid() {}
@Setup
public Object[] setupEmpty() {
return new Object[]{};
}
@Test
@Arguments(setup = "setupEmpty")
public void testSetupEmpty() {}
// ---------- Setup Arrays ---------------
@Setup
static Object[] setupArrayII(SetupInfo info) {
int[] a = new int[1_000];
int[] b = new int[1_000];
int x = info.invocationCounter();
for (int i = 0; i < a.length; i++) { a[i] = x + i; }
for (int i = 0; i < a.length; i++) { b[i] = x - i; }
return new Object[]{a, b};
}
@Test
@Arguments(setup = "setupArrayII")
static void testSetupArrayII(int[] a, int[] b) {
for (int i = 0; i < a.length; i++) {
int y = a[i] - b[i];
if (y != 2 * i) {
throw new RuntimeException("bad values for i=" + i + " a[i]=" + a[i] + " b[i]=" + b[i]);
}
}
}
// ---------- Setup "linked" random values ---------------
@Setup
static Object[] setupLinkedII() {
int r = RANDOM.nextInt();
return new Object[]{ r, r + 42};
}
@Test
@Arguments(setup = "setupLinkedII")
static int testSetupLinkedII(int a, int b) {
return b - a;
}
@Check(test = "testSetupLinkedII")
static void checkSetupLinkedII(int res) {
if (res != 42) { throw new RuntimeException("wrong result " + res); }
}
}
class TestSetupTestsWithFields {
int iFld1, iFld2, iFld3;
@Setup
Object[] setupTest1(SetupInfo info) {
iFld1 = info.invocationCounter() + 1;
iFld2 = info.invocationCounter() + 2;
iFld3 = info.invocationCounter() + 3;
return new Object[]{info.invocationCounter()}; // -> argument x in test
}
@Test
@Arguments(setup = "setupTest1")
int test1(int x) {
if (iFld1 != x + 1) { throw new RuntimeException("iFld1 wrong value: " + iFld1 + " != " + (x + 1)); }
if (iFld2 != x + 2) { throw new RuntimeException("iFld2 wrong value: " + iFld2 + " != " + (x + 2)); }
if (iFld3 != x + 3) { throw new RuntimeException("iFld3 wrong value: " + iFld3 + " != " + (x + 3)); }
iFld1++;
iFld2++;
iFld3++;
return x + 5; // -> argument y in check
}
@Check(test = "test1")
void checkTest1(int y) {
if (iFld1 != y - 3) { throw new RuntimeException("iFld1 wrong value: " + iFld1 + " != " + (y - 3)); }
if (iFld2 != y - 2) { throw new RuntimeException("iFld2 wrong value: " + iFld2 + " != " + (y - 2)); }
if (iFld3 != y - 1) { throw new RuntimeException("iFld3 wrong value: " + iFld3 + " != " + (y - 1)); }
}
}
class TestSetupTestsSetupInfo {
static int lastCnt = -1;
@Setup
Object[] setupTest1(SetupInfo info) {
int cnt = info.invocationCounter();
// Check that we increment every time
if (cnt - 1 != lastCnt) {
throw new RuntimeException("SetupInfo invocationCounter does not increment correctly: " +
cnt + ", vs last: " + lastCnt);
}
lastCnt = cnt;
return new Object[]{1, 2};
}
@Test
@Arguments(setup = "setupTest1")
void test1(int a, int b) {}
}
class TestSetupTestsWithExpectedExceptions {
// ----------------- wrong number of arguments ------------------
@Setup
public Object[] setupTooManyArgs() {
return new Object[]{1, 2, 3};
}
@Test
@Arguments(setup = "setupTooManyArgs")
public void testTooManyArgs(int a) {}
@Setup
public Object[] setupTooFewArgs() {
return new Object[]{1, 2};
}
@Test
@Arguments(setup = "setupTooFewArgs")
public void testTooFewArgs(int a, int b, int c) {}
@Setup
public Object[] setupTooManyArgs2() {
return new Object[]{1, 2, 3};
}
@Test
@Arguments(setup = "setupTooManyArgs2")
public void testTooManyArgs2() {}
@Setup
public Object[] setupTooFewArgs2() {
return new Object[]{};
}
@Test
@Arguments(setup = "setupTooFewArgs2")
public void testTooFewArgs2(int a, int b, int c) {}
// ----------------- wrong arguments for setup ------------------
@Setup
public Object[] setupTestBadSetupArgsTooMany(SetupInfo setupInfo, int bad) {
return new Object[]{1, 2};
}
@Test
@Arguments(setup = "setupTestBadSetupArgsTooMany")
public void testBadSetupArgsTooMany(int a, int b) {}
@Setup
public Object[] setupTestBadSetupArgsWrongType(int bad) {
return new Object[]{1, 2};
}
@Test
@Arguments(setup = "setupTestBadSetupArgsWrongType")
public void testBadSetupArgsWrongType(int a, int b) {}
// ----------------- setup wrong return type ------------------
@Setup
public int[] setupReturnIntArray() {
return new int[]{1, 2, 3};
}
@Test
@Arguments(setup = "setupReturnIntArray")
public void testSetupReturnIntArray(int a, int b, int c) {}
@Setup
public int setupReturnInt(SetupInfo setupInfo) {
return setupInfo.invocationCounter();
}
@Test
@Arguments(setup = "setupReturnInt")
public void testSetupReturnInt(int a) {}
// ----------------- setup provides wrong argument types ------
@Setup
public Object[] setupWrongArgumentType(SetupInfo setupInfo) {
return new Object[]{(int)1, (long)2};
}
@Test
@Arguments(setup = "setupWrongArgumentType")
public void testSetupWrongArgumentType(long a, int b) {}
// ----------------- setup returns null ------
@Setup
public Object[] setupNull() {
return null;
}
@Test
@Arguments(setup = "setupNull")
public void testSetupNull(Object x) {}
// ----------------- Throw in Setup -----------
@Setup
public Object[] setupThrowInSetup() {
throw new BadCheckedTestException("expected setup");
}
@Test
@Arguments(setup = "setupThrowInSetup")
public void testThrowInSetup() {
throw new RuntimeException("should have thrown in setup");
}
// ----------------- Throw in Test -----------
@Setup
public Object[] setupThrowInTest(SetupInfo info) {
return new Object[]{ info.invocationCounter() };
}
@Test
@Arguments(setup = "setupThrowInTest")
public int testThrowInTest(int x) {
throw new BadCheckedTestException("expected test");
}
@Check(test = "testThrowInTest")
public void checkThrowInTest(int x) {
throw new RuntimeException("should have thrown in test");
}
// ----------------- Throw in Check -----------
@Setup
public Object[] setupThrowInCheck(SetupInfo info) {
return new Object[]{ info.invocationCounter() };
}
@Test
@Arguments(setup = "setupThrowInCheck")
public int testThrowInCheck(int x) {
return x + 1;
}
@Check(test = "testThrowInCheck")
public void checkThrowInCheck(int x) {
throw new BadCheckedTestException("expected check");
}
}
class BadCheckedTestException extends RuntimeException {
BadCheckedTestException(String s) {
super(s);
}
}