jdk8/jdk8/langtools: 5125b9854d07 (original) (raw)
--- a/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java Wed Feb 06 23:10:35 2013 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java Thu Feb 07 20:47:06 2013 -0800 @@ -40,14 +40,17 @@ IMPORTINHERITED("import java.lang.annotation.Inherited;\n"), IMPORTRETENTION("import java.lang.annotation.Retention;\n" + "\nimport java.lang.annotation.RetentionPolicy;\n"),
IMPORTSTMTS("import java.lang.annotation.*;\n"),[](#l1.7) REPEATABLE("\n@Repeatable(FooContainer.class)\n"),[](#l1.8) CONTAINER("@interface FooContainer {\n" +" Foo[] value();\n}\n"),[](#l1.9) BASE("@interface Foo {}\n"),[](#l1.10)
BASEANNO("@Foo"),[](#l1.11) REPEATABLEANNO("\n@Foo() @Foo()"),[](#l1.12) DEPRECATED("\n@Deprecated"),[](#l1.13) DOCUMENTED("\n@Documented"),[](#l1.14) INHERITED("\n@Inherited"),[](#l1.15)
RETENTION("@Retention(RetentionPolicy.#VAL)\n");[](#l1.16)
RETENTION("@Retention(RetentionPolicy.#VAL)\n"),[](#l1.17)
TARGET("\n@Target(#VAL)\n");[](#l1.18)
private String val; @@ -69,6 +72,7 @@ public static final String template = "/PACKAGE/\n" + "//pkg test;\n\n" +
"/*ANNODATA*/\n" + // import statements, declaration of Foo/FooContainer[](#l1.26) "/*TYPE*/ //class\n" +[](#l1.27) "class #ClassName {\n" +[](#l1.28) " /*FIELD*/ //instance var\n" +[](#l1.29)
@@ -97,7 +101,11 @@ "interface TestInterface {}\n\n" + "/TYPE/\n" + "/ANNOTATION_TYPE/\n" +
"@interface TestAnnotationType{}\n";[](#l1.34)
"@interface TestAnnotationType{}\n" +[](#l1.35)
"class TestPkg {}\n" +[](#l1.36)
"class TestTypeAnno </*TYPE_PARAMETER*/ T extends Object> {\n" +[](#l1.37)
" String /*TYPE_USE*/[] arr;\n" +[](#l1.38)
"}";[](#l1.39)
// Create and compile FileObject using values for className and contents public static boolean compileCode(String className, String contents, @@ -150,3 +158,4 @@ } } } +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/combo/TargetAnnoCombo.java Thu Feb 07 20:47:06 2013 -0800 @@ -0,0 +1,469 @@ +/*
- *
- *
- *
- *
- or visit www.oracle.com if you need additional information or have any
- */ + +/**
- / + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticCollector; +import javax.tools.JavaFileObject; + +/
- *
- *
- *
- *
base=["ElementType.PARAMETER", "ElementType.TYPE_USE", "ElementType.METHOD", "ElementType.FIELD", "ElementType.PACKAGE", "ElementType.TYPE_PARAMETER"],[](#l2.76)
container=["ElementType.TYPE", "ElementType.METHOD", "ElementType.ANNOTATION_TYPE", "ElementType.CONSTRUCTOR", "ElementType.FIELD"][](#l2.77)
- *
- *
base = null,[](#l2.88)
container = ["ElementType.ANNOTATION_TYPE","ElementType.CONSTRUCTOR","ElementType.LOCAL_VARIABLE"][](#l2.89)
- *
- *
base = ["ElementType.FIELD", "ElementType.LOCAL_VARIABLE", "ElementType.TYPE", "ElementType.PARAMETER"],[](#l2.99)
container = null[](#l2.100)
- *
- *
- *
- *
- *
- */ + +public class TargetAnnoCombo {
- int errors = 0;
- static final String TESTPKG = "testpkg";
- /*
* Set it to true to get more debug information including base and[](#l2.127)
* container target sets for a given test case number[](#l2.128)
*/[](#l2.129)
- static final boolean DEBUG = false;
- // JDK 5/6/7/8 Targets
- static final String[] targetVals = {"ElementType.ANNOTATION_TYPE",
"ElementType.CONSTRUCTOR", "ElementType.FIELD",[](#l2.134)
"ElementType.LOCAL_VARIABLE", "ElementType.METHOD",[](#l2.135)
"ElementType.TYPE", "ElementType.PARAMETER",[](#l2.136)
"ElementType.PACKAGE", "ElementType.TYPE_USE",[](#l2.137)
"ElementType.TYPE_PARAMETER"};[](#l2.138)
- // TYPE_USE and TYPE_PARAMETER (added in JDK8) are not part of default Target set
- static final int DEFAULT_TARGET_CNT = 8;
/* maxTestNum = (base and container combinations of targetVals elems [0 - 1048575 combos])[](#l2.145)
* + (combinations where base or container has no Target [1024 combos])[](#l2.146)
* + (no -1 even though 1st test is number 0 as last test is where both[](#l2.147)
* base and container have no target)[](#l2.148)
*/[](#l2.149)
int maxTestNum = (int)Math.pow(2, 2*targetVals.length) + 2*(int)Math.pow(2, targetVals.length);[](#l2.151)
TestCaseGenerator tcg = new TestCaseGenerator(maxTestNum);[](#l2.152)
TargetAnnoCombo tac = new TargetAnnoCombo();[](#l2.153)
int testCtr = 0;[](#l2.155)
int testCase = -1;[](#l2.156)
while ( (testCase=tcg.getNextTestCase()) != -1 ) {[](#l2.157)
tac.executeTestCase(testCase, maxTestNum);[](#l2.158)
testCtr++;[](#l2.159)
}[](#l2.160)
System.out.println("Total tests run: " + testCtr);[](#l2.162)
if (tac.errors > 0)[](#l2.163)
throw new Exception(tac.errors + " errors found");[](#l2.164)
- }
- /*
* For given testCase, determine the base and container annotation Target sets,[](#l2.168)
* get if testCase should compile, get test source file(s), get compilation result and verify.[](#l2.169)
*[](#l2.170)
*/[](#l2.171)
- private void executeTestCase(int testCase, int maxTestNum) {
// Determine base and container annotation Target sets for the testCase[](#l2.174)
Set<String> baseAnnoTarget = null;[](#l2.175)
Set<String> conAnnoTarget = null;[](#l2.176)
//Number of base and container combinations [0 - 1048575 combos][](#l2.178)
int baseContCombos = (int)Math.pow(2, 2*targetVals.length);[](#l2.179)
//Number of either base or container combinations when one of them has no @Target [1024 combos][](#l2.180)
int targetValsCombos = (int)Math.pow(2, targetVals.length);[](#l2.181)
if (testCase >= baseContCombos) {[](#l2.183)
//Base annotation do not have @Target[](#l2.184)
if (testCase < baseContCombos + targetValsCombos) {[](#l2.185)
baseAnnoTarget = null;[](#l2.186)
conAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos));[](#l2.187)
} else if (testCase < baseContCombos + 2*targetValsCombos) {[](#l2.188)
//Container annotation do not have @Target[](#l2.189)
baseAnnoTarget = getSetFromBitVec(Integer.toBinaryString(testCase - baseContCombos - targetValsCombos));[](#l2.190)
conAnnoTarget = null;[](#l2.191)
} else {[](#l2.192)
//Both Base and Container annotation do not have @Target[](#l2.193)
baseAnnoTarget = null;[](#l2.194)
conAnnoTarget = null;[](#l2.195)
}[](#l2.196)
} else {[](#l2.197)
//TestCase number is represented as 10-bits for base followed by container bits[](#l2.198)
String bin = Integer.toBinaryString(testCase);[](#l2.199)
String base="", cont=bin;[](#l2.200)
if (bin.length() > targetVals.length){[](#l2.201)
base = bin.substring(0, bin.length() - targetVals.length);[](#l2.202)
cont = bin.substring(bin.length() - targetVals.length,bin.length());[](#l2.203)
}[](#l2.204)
baseAnnoTarget = getSetFromBitVec(base);[](#l2.205)
conAnnoTarget = getSetFromBitVec(cont);[](#l2.206)
}[](#l2.207)
debugPrint("Test case number = " + testCase + " => binary = " + Integer.toBinaryString(testCase));[](#l2.209)
debugPrint(" => baseAnnoTarget = " + baseAnnoTarget);[](#l2.210)
debugPrint(" => containerAnnoTarget = " + conAnnoTarget);[](#l2.211)
// Determine if a testCase should compile or not[](#l2.213)
String className = "TC" + testCase;[](#l2.214)
boolean shouldCompile = isValidSubSet(baseAnnoTarget, conAnnoTarget);[](#l2.215)
// Get test source file(s)[](#l2.217)
Iterable<? extends JavaFileObject> files = getFileList(className, baseAnnoTarget,[](#l2.218)
conAnnoTarget, shouldCompile);[](#l2.219)
// Get result of compiling test src file(s)[](#l2.221)
boolean result = getCompileResult(className, shouldCompile, files);[](#l2.222)
// List test src code if test fails[](#l2.224)
if(!result) {[](#l2.225)
System.out.println("FAIL: Test " + testCase);[](#l2.226)
try {[](#l2.227)
for (JavaFileObject f: files) {[](#l2.228)
System.out.println("File: " + f.getName() + "\n" + f.getCharContent(true));[](#l2.229)
}[](#l2.230)
} catch (IOException ioe) {[](#l2.231)
System.out.println("Exception: " + ioe);[](#l2.232)
}[](#l2.233)
} else {[](#l2.234)
debugPrint("PASS: Test " + testCase);[](#l2.235)
}[](#l2.236)
- }
- // Get a Set based on bits that are set to 1
- public Set getSetFromBitVec(String bitVec) {
Set<String> ret = new HashSet<>();[](#l2.241)
char[] bit = bitVec.toCharArray();[](#l2.242)
for (int i=bit.length-1, j=0; i>=0; i--, j++){[](#l2.243)
if (bit[i] == '1') {[](#l2.244)
ret.add(targetVals[j]);[](#l2.245)
}[](#l2.246)
}[](#l2.247)
return ret;[](#l2.248)
- }
- // Compile the test source file(s) and return test result
- private boolean getCompileResult(String className, boolean shouldCompile,
Iterable<? extends JavaFileObject> files) {[](#l2.253)
DiagnosticCollector<JavaFileObject> diagnostics =[](#l2.255)
new DiagnosticCollector<JavaFileObject>();[](#l2.256)
Helper.compileCode(diagnostics, files);[](#l2.257)
// Test case pass or fail[](#l2.259)
boolean ok = false;[](#l2.260)
String errMesg = "";[](#l2.262)
int numDiags = diagnostics.getDiagnostics().size();[](#l2.263)
if (numDiags == 0) {[](#l2.265)
if (shouldCompile) {[](#l2.266)
debugPrint("Test passed, compiled as expected.");[](#l2.267)
ok = true;[](#l2.268)
} else {[](#l2.269)
errMesg = "Test failed, compiled unexpectedly.";[](#l2.270)
ok = false;[](#l2.271)
}[](#l2.272)
} else {[](#l2.273)
if (shouldCompile) {[](#l2.274)
// did not compile[](#l2.275)
errMesg = "Test failed, did not compile.";[](#l2.276)
ok = false;[](#l2.277)
} else {[](#l2.278)
// Error in compilation as expected[](#l2.279)
String expectedErrKey = "compiler.err.invalid.repeatable." +[](#l2.280)
"annotation.incompatible.target";[](#l2.281)
for (Diagnostic<?> d : diagnostics.getDiagnostics()) {[](#l2.282)
if((d.getKind() == Diagnostic.Kind.ERROR) &&[](#l2.283)
d.getCode().contains(expectedErrKey)) {[](#l2.284)
// Error message as expected[](#l2.285)
debugPrint("Error message as expected.");[](#l2.286)
ok = true;[](#l2.287)
break;[](#l2.288)
} else {[](#l2.289)
// error message is incorrect[](#l2.290)
ok = false;[](#l2.291)
}[](#l2.292)
}[](#l2.293)
if (!ok) {[](#l2.294)
errMesg = "Incorrect error received when compiling " +[](#l2.295)
className + ", expected: " + expectedErrKey;[](#l2.296)
}[](#l2.297)
}[](#l2.298)
}[](#l2.299)
if(!ok) {[](#l2.301)
error(errMesg);[](#l2.302)
for (Diagnostic<?> d : diagnostics.getDiagnostics())[](#l2.303)
System.out.println(" Diags: " + d);[](#l2.304)
}[](#l2.305)
return ok;[](#l2.306)
- }
- private void debugPrint(String string) {
if(DEBUG)[](#l2.310)
System.out.println(string);[](#l2.311)
- }
- // Create src code and corresponding JavaFileObjects
- private Iterable<? extends JavaFileObject> getFileList(String className,
Set<String> baseAnnoTarget, Set<String> conAnnoTarget,[](#l2.316)
boolean shouldCompile) {[](#l2.317)
String srcContent = "";[](#l2.319)
String pkgInfoContent = "";[](#l2.320)
String template = Helper.template;[](#l2.321)
String baseTarget = "", conTarget = "";[](#l2.322)
String target = Helper.ContentVars.TARGET.getVal();[](#l2.324)
if(baseAnnoTarget != null) {[](#l2.325)
baseTarget = target.replace("#VAL", baseAnnoTarget.toString())[](#l2.326)
.replace("[", "{").replace("]", "}");[](#l2.327)
}[](#l2.328)
if(conAnnoTarget != null) {[](#l2.329)
conTarget = target.replace("#VAL", conAnnoTarget.toString())[](#l2.330)
.replace("[", "{").replace("]", "}");[](#l2.331)
}[](#l2.332)
String annoData = Helper.ContentVars.IMPORTSTMTS.getVal() +[](#l2.334)
conTarget +[](#l2.335)
Helper.ContentVars.CONTAINER.getVal() +[](#l2.336)
baseTarget +[](#l2.337)
Helper.ContentVars.REPEATABLE.getVal() +[](#l2.338)
Helper.ContentVars.BASE.getVal();[](#l2.339)
JavaFileObject pkgInfoFile = null;[](#l2.341)
/*[](#l2.343)
* If shouldCompile = true and no @Target is specified for container annotation,[](#l2.344)
* then all 8 ElementType enum constants are applicable as targets for[](#l2.345)
* container annotation.[](#l2.346)
*/[](#l2.347)
if(shouldCompile && conAnnoTarget == null) {[](#l2.348)
//conAnnoTarget = new HashSet<String>(Arrays.asList(targetVals));[](#l2.349)
conAnnoTarget = getDefaultTargetSet();[](#l2.350)
}[](#l2.351)
if(shouldCompile) {[](#l2.353)
boolean isPkgCasePresent = new ArrayList<String>(conAnnoTarget).contains("ElementType.PACKAGE");[](#l2.354)
String repeatableAnno = Helper.ContentVars.BASEANNO.getVal() + " " + Helper.ContentVars.BASEANNO.getVal();[](#l2.355)
for(String s: conAnnoTarget) {[](#l2.356)
s = s.replace("ElementType.","");[](#l2.357)
String replaceStr = "/*"+s+"*/";[](#l2.358)
if(s.equalsIgnoreCase("PACKAGE")) {[](#l2.359)
//Create packageInfo file[](#l2.360)
String pkgInfoName = TESTPKG + "." + "package-info";[](#l2.361)
pkgInfoContent = repeatableAnno + "\npackage " + TESTPKG + ";" + annoData;[](#l2.362)
pkgInfoFile = Helper.getFile(pkgInfoName, pkgInfoContent);[](#l2.363)
} else {[](#l2.364)
template = template.replace(replaceStr, repeatableAnno);[](#l2.365)
//srcContent = template.replace("#ClassName",className);[](#l2.366)
if(!isPkgCasePresent) {[](#l2.367)
srcContent = template.replace("/*ANNODATA*/", annoData).replace("#ClassName",className);[](#l2.368)
} else {[](#l2.369)
replaceStr = "/*PACKAGE*/";[](#l2.370)
srcContent = template.replace(replaceStr, "package " + TESTPKG + ";")[](#l2.371)
.replace("#ClassName", className);[](#l2.372)
}[](#l2.373)
}[](#l2.374)
}[](#l2.375)
} else {[](#l2.376)
// For invalid cases, compilation should fail at declaration site[](#l2.377)
template = "class #ClassName {}";[](#l2.378)
srcContent = annoData + template.replace("#ClassName",className);[](#l2.379)
}[](#l2.380)
JavaFileObject srcFile = Helper.getFile(className, srcContent);[](#l2.381)
Iterable<? extends JavaFileObject> files = null;[](#l2.382)
if(pkgInfoFile != null)[](#l2.383)
files = Arrays.asList(pkgInfoFile,srcFile);[](#l2.384)
else[](#l2.385)
files = Arrays.asList(srcFile);[](#l2.386)
return files;[](#l2.387)
- }
- private Set getDefaultTargetSet() {
Set<String> defaultSet = new HashSet<>();[](#l2.391)
int ctr = 0;[](#l2.392)
for(String s : targetVals) {[](#l2.393)
if(ctr++ < DEFAULT_TARGET_CNT) {[](#l2.394)
defaultSet.add(s);[](#l2.395)
}[](#l2.396)
}[](#l2.397)
return defaultSet;[](#l2.398)
- }
- private boolean isValidSubSet(Set baseAnnoTarget, Set conAnnoTarget) {
/*[](#l2.402)
* RULE 1: conAnnoTarget should be a subset of baseAnnoTarget[](#l2.403)
* RULE 2: For empty @Target ({}) - annotation cannot be applied anywhere[](#l2.404)
* - Empty sets for both is valid[](#l2.405)
* - Empty baseTarget set is invalid with non-empty conTarget set[](#l2.406)
* - Non-empty baseTarget set is valid with empty conTarget set[](#l2.407)
* RULE 3: For no @Target specified - annotation can be applied to any JDK 7 targets[](#l2.408)
* - No @Target for both is valid[](#l2.409)
* - No @Target for baseTarget set with @Target conTarget set is valid[](#l2.410)
* - @Target for baseTarget set with no @Target for conTarget is invalid[](#l2.411)
*/[](#l2.412)
/* If baseAnno has no @Target, Foo can be either applied to @Target specified for container annotation[](#l2.415)
* else will be applicable for all default targets if no @Target is present for container annotation.[](#l2.416)
* In both cases, the set will be a valid set with no @Target for base annotation[](#l2.417)
*/[](#l2.418)
if(baseAnnoTarget == null) {[](#l2.419)
if(conAnnoTarget == null) return true;[](#l2.420)
return !(conAnnoTarget.contains("ElementType.TYPE_USE") || conAnnoTarget.contains("ElementType.TYPE_PARAMETER"));[](#l2.421)
}[](#l2.422)
Set<String> tempBaseSet = new HashSet<>(baseAnnoTarget);[](#l2.424)
// If BaseAnno has TYPE, then ANNOTATION_TYPE is allowed by default[](#l2.425)
if(baseAnnoTarget.contains("ElementType.TYPE")) {[](#l2.426)
tempBaseSet.add("ElementType.ANNOTATION_TYPE");[](#l2.427)
}[](#l2.428)
/*[](#l2.430)
* If containerAnno has no @Target, only valid case if baseAnnoTarget has all targets defined[](#l2.431)
* else invalid set[](#l2.432)
*/[](#l2.433)
if(conAnnoTarget == null) {[](#l2.434)
return (tempBaseSet.containsAll(getDefaultTargetSet()));[](#l2.435)
}[](#l2.436)
// At this point, neither conAnnoTarget or baseAnnoTarget are null[](#l2.438)
if(conAnnoTarget.size() == 0) return true;[](#l2.439)
// At this point, conAnnoTarget is non-empty[](#l2.441)
if (baseAnnoTarget.size() == 0) return false;[](#l2.442)
// At this point, neither conAnnoTarget or baseAnnoTarget are empty[](#l2.444)
return tempBaseSet.containsAll(conAnnoTarget);[](#l2.445)
- }
- // Lists the start and end range for the given set of target vals
- void showGroups() {
//Group 1: All target set combinations ( 0 to 1048575 ) including empty @Target sets => @Target({})[](#l2.455)
int grpEnd1 = (int)Math.pow(2, 2*targetVals.length) - 1;[](#l2.456)
System.out.println("[Group 1]: 0 - " + grpEnd1);[](#l2.457)
//Group 2: @Target not defined for base annotation ( 1048576 - 1049599 ).[](#l2.459)
System.out.print("[Group 2]: " + (grpEnd1 + 1) + " - ");[](#l2.460)
int grpEnd2 = grpEnd1 + 1 + (int)Math.pow(2, targetVals.length) - 1;[](#l2.461)
System.out.println(grpEnd2);[](#l2.462)
//Group 3: @Target not defined for container annotation ( 1049600 - 1050623 ).[](#l2.464)
System.out.print("[Group 3]: " + (grpEnd2 + 1) + " - ");[](#l2.465)
int grpEnd3 = grpEnd2 + 1 + (int)Math.pow(2, targetVals.length) - 1;[](#l2.466)
System.out.println(grpEnd3);[](#l2.467)
//Group 4: @Target not defined for both base and container annotations ( 1050624 ).[](#l2.469)
System.out.println("[Group 4]: " + (grpEnd3 + 1));[](#l2.470)
- }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/annotations/repeatingAnnotations/combo/TestCaseGenerator.java Thu Feb 07 20:47:06 2013 -0800 @@ -0,0 +1,191 @@ +/*
- *
- *
- *
- *
- or visit www.oracle.com if you need additional information or have any
- / + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Random; + +/ System properties:
- */ +public class TestCaseGenerator {
- // Total number of tests to be run
- int numberOfTests = -1;
- //Single test case
- int testCaseNum = -1;
- //Seed used to generate test cases
- int testSeed;
- /*
* Get parameter values from command line to set numberOfTests, testCaseNum,[](#l3.59)
* and testSeed[](#l3.60)
*/[](#l3.61)
- public TestCaseGenerator(int maxTestNum) {
this.maxTestNum = maxTestNum;[](#l3.63)
// Set values for variables based on input from command line[](#l3.65)
// TestMode system property[](#l3.67)
String testModeVal = System.getProperty("TestMode");[](#l3.68)
if(testModeVal != null && !testModeVal.isEmpty()) {[](#l3.69)
switch (testModeVal.toUpperCase()) {[](#l3.70)
case "FULL":[](#l3.71)
numberOfTests = maxTestNum;[](#l3.72)
break;[](#l3.73)
case "DEFAULT":[](#l3.74)
numberOfTests = DEFAULT_TEST_COUNT;[](#l3.75)
break;[](#l3.76)
default:[](#l3.77)
System.out.println("Invalid property value " + testModeVal +[](#l3.78)
" for numberOfTests. Possible range: 0 to " +[](#l3.79)
maxTestNum + ". Ignoring property");[](#l3.80)
numberOfTests = -1;[](#l3.81)
}[](#l3.82)
}[](#l3.83)
// NumberOfTests system property[](#l3.85)
String numTestsStr = System.getProperty("NumberOfTests");[](#l3.86)
if(numTestsStr != null && !numTestsStr.isEmpty()) {[](#l3.87)
int numTests = -1;[](#l3.88)
try {[](#l3.89)
numTests = Integer.parseInt(numTestsStr);[](#l3.90)
if (numTests < 0 || numTests > maxTestNum) {[](#l3.91)
throw new NumberFormatException();[](#l3.92)
}[](#l3.93)
} catch(NumberFormatException nfe) {[](#l3.94)
System.out.println("Invalid NumberOfTests property value " +[](#l3.95)
numTestsStr + ". Possible range: 0 to " + maxTestNum +[](#l3.96)
"Reset to default: " + DEFAULT_TEST_COUNT);[](#l3.97)
numTests = DEFAULT_TEST_COUNT;[](#l3.98)
}[](#l3.99)
if (numberOfTests != -1 && numTests != -1) {[](#l3.101)
System.out.println("TestMode and NumberOfTests cannot be set together. Ignoring TestMode.");[](#l3.102)
}[](#l3.103)
numberOfTests = numTests;[](#l3.104)
}[](#l3.105)
// TestSeed system property[](#l3.107)
String seedVal = System.getProperty("TestSeed");[](#l3.108)
if(seedVal != null && !seedVal.isEmpty()) {[](#l3.109)
try {[](#l3.110)
testSeed = Integer.parseInt(seedVal);[](#l3.111)
} catch(NumberFormatException nfe) {[](#l3.112)
Random srand = new Random();[](#l3.113)
testSeed = srand.nextInt();[](#l3.114)
}[](#l3.115)
} else {[](#l3.116)
Random srand = new Random();[](#l3.117)
testSeed = srand.nextInt();[](#l3.118)
}[](#l3.119)
// TestCaseNum system property[](#l3.121)
String testNumStr = System.getProperty("TestCaseNum");[](#l3.122)
if(testNumStr != null && !testNumStr.isEmpty()) {[](#l3.123)
try {[](#l3.124)
testCaseNum = Integer.parseInt(testNumStr);[](#l3.125)
if (testCaseNum < 0 || testCaseNum > maxTestNum) {[](#l3.126)
throw new NumberFormatException();[](#l3.127)
}[](#l3.128)
} catch(NumberFormatException nfe) {[](#l3.129)
System.out.println("Invalid TestCaseNumber property value " +[](#l3.130)
testNumStr + ". Possible value in range: 0 to " +[](#l3.131)
maxTestNum + ". Defaulting to last test case.");[](#l3.132)
testCaseNum = maxTestNum;[](#l3.133)
}[](#l3.134)
if ( numberOfTests != -1) {[](#l3.136)
System.out.println("TestMode or NumberOfTests cannot be set along with TestCaseNum. Ignoring TestCaseNumber.");[](#l3.137)
testCaseNum = -1;[](#l3.138)
}[](#l3.139)
}[](#l3.140)
if (numberOfTests == -1 && testCaseNum == -1) {[](#l3.142)
numberOfTests = DEFAULT_TEST_COUNT;[](#l3.143)
System.out.println("Setting TestMode to default, will run " + numberOfTests + "tests.");[](#l3.144)
}[](#l3.145)
/*[](#l3.147)
* By this point in code, we will have:[](#l3.148)
* - testSeed: as per TestSeed or a Random one[](#l3.149)
* - numberOfTests to run or -1 to denote not set[](#l3.150)
* - testCaseNum to run or -1 to denote not set[](#l3.151)
*/[](#l3.152)
/*[](#l3.154)
* If numberOfTests = maxTestNum, all tests are to be run,[](#l3.155)
* so no randNum will be required[](#l3.156)
*/[](#l3.157)
if (numberOfTests != -1 && numberOfTests < maxTestNum) {[](#l3.158)
System.out.println("Seed = " + testSeed);[](#l3.159)
randNum = new Random(testSeed);[](#l3.160)
uniqueTestSet = new HashSet<>();[](#l3.161)
}[](#l3.162)
testCompletedCount = 0;[](#l3.164)
// to be used to keep sequential count when running all tests[](#l3.165)
curTestNum = 0;[](#l3.166)
- }
- /*
* returns next test case number to run[](#l3.170)
* returns -1 when there are no more tests to run[](#l3.171)
*/[](#l3.172)
- public int getNextTestCase() {
if (testCaseNum != -1) {[](#l3.174)
int nextTC = testCaseNum;[](#l3.175)
testCaseNum = -1;[](#l3.176)
return nextTC;[](#l3.177)
}[](#l3.178)
if (++testCompletedCount <= numberOfTests) {[](#l3.179)
if (numberOfTests == maxTestNum) {[](#l3.180)
//all the tests need to be run, so just return[](#l3.181)
//next test case sequentially[](#l3.182)
return curTestNum++;[](#l3.183)
} else {[](#l3.184)
int nextTC = -1;[](#l3.185)
// Ensuring unique test are run[](#l3.186)
while(!uniqueTestSet.add(nextTC = randNum.nextInt(maxTestNum))) {[](#l3.187)
}[](#l3.188)
return nextTC;[](#l3.189)
}[](#l3.190)
}[](#l3.191)
return -1;[](#l3.192)
- }