8179249: Improve process output analysis in CDS tests
Summary: Added new API TestCommon.run(...).assertNormalExit(...), etc
Reviewed-by: mseledtsov
--- a/test/hotspot/jtreg/runtime/appcds/AppendClasspath.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/AppendClasspath.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -48,39 +48,33 @@
TestCommon.testDump(appJar, TestCommon.list("Hello"));
// PASS: 1) runtime with classpath containing the one used in dump time
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar + File.pathSeparator + appJar2,
- "HelloMore");
- TestCommon.checkExec(output);
+ "HelloMore")
+ .assertNormalExit();
final String errorMessage1 = "Unable to use shared archive";
final String errorMessage2 = "shared class paths mismatch";
// FAIL: 2) runtime with classpath different from the one used in dump time
// (runtime has an extra jar file prepended to the class path)
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar2 + File.pathSeparator + appJar,
- "HelloMore");
- output.shouldContain(errorMessage1);
- output.shouldContain(errorMessage2);
- output.shouldHaveExitValue(1);
+ "HelloMore")
+ .assertAbnormalExit(errorMessage1, errorMessage2);
// FAIL: 3) runtime with classpath part of the one used in dump time
TestCommon.testDump(appJar + File.pathSeparator + appJar2,
TestCommon.list("Hello"));
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar2,
- "Hello");
- output.shouldContain(errorMessage1);
- output.shouldContain(errorMessage2);
- output.shouldHaveExitValue(1);
+ "Hello")
+ .assertAbnormalExit(errorMessage1, errorMessage2);
// FAIL: 4) runtime with same set of jar files in the classpath but
// with different order
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar2 + File.pathSeparator + appJar,
- "HelloMore");
- output.shouldContain(errorMessage1);
- output.shouldContain(errorMessage2);
- output.shouldHaveExitValue(1);
+ "HelloMore")
+ .assertAbnormalExit(errorMessage1, errorMessage2);
}
}
--- a/test/hotspot/jtreg/runtime/appcds/BootClassPathMismatch.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/BootClassPathMismatch.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -62,20 +62,13 @@
public void testBootClassPathMismatch() throws Exception {
String appJar = JarBuilder.getOrCreateHelloJar();
String appClasses[] = {"Hello"};
- OutputAnalyzer dumpOutput = TestCommon.dump(
+ TestCommon.dump(
appJar, appClasses, "-Xbootclasspath/a:" + appJar);
String testDir = TestCommon.getTestDir("newdir");
String otherJar = testDir + File.separator + "hello.jar";
- OutputAnalyzer execOutput = TestCommon.exec(
- appJar, "-verbose:class", "-Xbootclasspath/a:" + otherJar, "Hello");
- try {
- TestCommon.checkExec(execOutput, mismatchMessage);
- } catch (java.lang.RuntimeException re) {
- String cause = re.getMessage();
- if (!mismatchMessage.equals(cause)) {
- throw re;
- }
- }
+ TestCommon.run(
+ "-cp", appJar, "-verbose:class", "-Xbootclasspath/a:" + otherJar, "Hello")
+ .assertAbnormalExit(mismatchMessage);
}
/* Error should be detected if:
@@ -85,17 +78,10 @@
public void testBootClassPathMismatch2() throws Exception {
String appJar = JarBuilder.getOrCreateHelloJar();
String appClasses[] = {"Hello"};
- OutputAnalyzer dumpOutput = TestCommon.dump(appJar, appClasses);
- OutputAnalyzer execOutput = TestCommon.exec(
- appJar, "-verbose:class", "-Xbootclasspath/a:" + appJar, "Hello");
- try {
- TestCommon.checkExec(execOutput, mismatchMessage);
- } catch (java.lang.RuntimeException re) {
- String cause = re.getMessage();
- if (!mismatchMessage.equals(cause)) {
- throw re;
- }
- }
+ TestCommon.dump(appJar, appClasses);
+ TestCommon.run(
+ "-cp", appJar, "-verbose:class", "-Xbootclasspath/a:" + appJar, "Hello")
+ .assertAbnormalExit(mismatchMessage);
}
/* No error if:
@@ -105,13 +91,12 @@
public void testBootClassPathMatch() throws Exception {
String appJar = TestCommon.getTestJar("hello.jar");
String appClasses[] = {"Hello"};
- OutputAnalyzer dumpOutput = TestCommon.dump(
+ TestCommon.dump(
appJar, appClasses, "-Xbootclasspath/a:" + appJar);
- OutputAnalyzer execOutput = TestCommon.exec(
- appJar, "-verbose:class",
- "-Xbootclasspath/a:" + appJar, "Hello");
- TestCommon.checkExec(execOutput,
- "[class,load] Hello source: shared objects file");
+ TestCommon.run(
+ "-cp", appJar, "-verbose:class",
+ "-Xbootclasspath/a:" + appJar, "Hello")
+ .assertNormalExit("[class,load] Hello source: shared objects file");
}
private static void copyHelloToNewDir() throws Exception {
--- a/test/hotspot/jtreg/runtime/appcds/CaseSensitiveClassPath.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/CaseSensitiveClassPath.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, 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
@@ -76,17 +76,17 @@
} else {
jarPathUpper = Paths.get(appJarUpper);
}
-
- out = TestCommon.exec(appJarUpper, "Hello", "-Xlog:class+path=info",
- "-Xlog:cds");
- if (TestCommon.isUnableToMap(out))
- return;
+ boolean isSameFile = Files.isSameFile(jarPath, jarPathUpper);
- if (Files.isSameFile(jarPath, jarPathUpper)) {
- TestCommon.checkExec(out, "Hello World");
- } else {
- out.shouldContain("shared class paths mismatch")
- .shouldHaveExitValue(1);
- }
- }
+ TestCommon.run("-cp", appJarUpper, "Hello", "-Xlog:class+path=info",
+ "-Xlog:cds")
+ .ifNoMappingFailure(output -> {
+ if (isSameFile) {
+ output.shouldContain("Hello World");
+ } else {
+ output.shouldContain("shared class paths mismatch");
+ output.shouldHaveExitValue(1);
+ }
+ });
+ }
}
--- a/test/hotspot/jtreg/runtime/appcds/ClassPathAttr.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/ClassPathAttr.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -68,29 +68,30 @@
"CpAttr4",
"CpAttr5"));
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
- "CpAttr1");
- TestCommon.checkExec(output);
+ "CpAttr1")
+ .assertNormalExit();
// Logging test for class+path.
- output = TestCommon.execCommon(
+ TestCommon.run(
"-Xlog:class+path",
"-cp", cp,
- "CpAttr1");
- if (!TestCommon.isUnableToMap(output)){
- output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
- output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
- }
+ "CpAttr1")
+ .assertNormalExit(output -> {
+ output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
+ output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
+ });
+
// Make sure aliased TraceClassPaths still works
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+TraceClassPaths",
"-cp", cp,
- "CpAttr1");
- if (!TestCommon.isUnableToMap(output)){
- output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
- output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
- }
+ "CpAttr1")
+ .assertNormalExit(output -> {
+ output.shouldMatch("checking shared classpath entry: .*cpattr2.jar");
+ output.shouldMatch("checking shared classpath entry: .*cpattr3.jar");
+ });
}
}
--- a/test/hotspot/jtreg/runtime/appcds/HelloExtTest.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/HelloExtTest.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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
@@ -24,7 +24,8 @@
/*
* @test
- * @summary a simple test for loading a class using the ext class loader in AppCDS
+ * @summary a simple test for loading a class using the platform class loader
+ * (which used to be called the "extension loader) in AppCDS
* @requires vm.cds
* @library /test/lib
* @modules java.base/jdk.internal.misc
@@ -53,19 +54,20 @@
TestCommon.list("org/omg/CORBA/ORB", "[Ljava/lang/Comparable;"),
bootClassPath, "-verbose:class", "--add-modules", "java.corba");
- OutputAnalyzer output = TestCommon.execCommon("-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
- "-cp", appJar, bootClassPath, "-verbose:class", "--add-modules", "java.corba", "HelloExt");
-
String prefix = ".class.load. ";
String class_pattern = ".*LambdaForm[$]MH[/][0123456789].*";
String suffix = ".*source: shared objects file.*";
String pattern = prefix + class_pattern + suffix;
- output.shouldNotMatch(pattern);
+
+ TestCommon.run("-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+ "-cp", appJar, bootClassPath, "-verbose:class", "--add-modules", "java.corba", "HelloExt")
+ .assertNormalExit(output -> output.shouldNotMatch(pattern));
+
- output = TestCommon.execCommon("-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
- "-cp", appJar, bootClassPath, "-verbose:class",
- "-XX:+PrintSharedArchiveAndExit", "-XX:+PrintSharedDictionary",
- "--add-modules", "java.corba", "HelloExt");
- output.shouldNotMatch(class_pattern);
+ TestCommon.run("-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
+ "-cp", appJar, bootClassPath, "-verbose:class",
+ "-XX:+PrintSharedArchiveAndExit", "-XX:+PrintSharedDictionary",
+ "--add-modules", "java.corba", "HelloExt")
+ .assertNormalExit(output -> output.shouldNotMatch(class_pattern));
}
}
--- a/test/hotspot/jtreg/runtime/appcds/IgnoreEmptyClassPaths.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/IgnoreEmptyClassPaths.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -51,12 +51,12 @@
TestCommon.testDump(cp_dump, TestCommon.list("Hello", "HelloMore"),
"-XX:+TraceClassPaths", "-XX:+IgnoreEmptyClassPaths");
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
"-verbose:class",
"-cp", cp_exec,
"-XX:+IgnoreEmptyClassPaths", // should affect classpath even if placed after the "-cp" argument
"-XX:+TraceClassPaths",
- "HelloMore");
- TestCommon.checkExec(output);
+ "HelloMore")
+ .assertNormalExit();
}
}
--- a/test/hotspot/jtreg/runtime/appcds/JvmtiAddPath.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/JvmtiAddPath.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -59,8 +59,7 @@
static void run(String[] extra_matches, String cp, String... args) throws Exception {
String[] opts = {"-cp", cp, "-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI", use_whitebox_jar};
opts = TestCommon.concat(opts, args);
- OutputAnalyzer output = TestCommon.execCommon(opts);
- TestCommon.checkExec(output, extra_matches);
+ TestCommon.run(opts).assertNormalExit(extra_matches);
}
public static void main(String[] args) throws Exception {
--- a/test/hotspot/jtreg/runtime/appcds/OldClassTest.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/OldClassTest.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -65,11 +65,11 @@
OutputAnalyzer output = TestCommon.dump(jar, appClasses);
TestCommon.checkExecReturn(output, 0, true, "Pre JDK 1.5 class not supported by CDS");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", jar,
"-verbose:class",
- "Hello");
- TestCommon.checkExecReturn(output, 0, true, "Hello Unicode world (Old)");
+ "Hello")
+ .assertNormalExit("Hello Unicode world (Old)");
// CASE 2: if we exlcude old version of this class, we should not pick up
// the newer version of this class in a subsequent classpath element.
@@ -77,11 +77,11 @@
output = TestCommon.dump(classpath, appClasses);
TestCommon.checkExecReturn(output, 0, true, "Pre JDK 1.5 class not supported by CDS");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", classpath,
"-verbose:class",
- "Hello");
- TestCommon.checkExecReturn(output, 0, true, "Hello Unicode world (Old)");
+ "Hello")
+ .assertNormalExit("Hello Unicode world (Old)");
}
static void createTestJarFile(File jarSrcFile, File jarFile) throws Exception {
--- a/test/hotspot/jtreg/runtime/appcds/PrintSharedArchiveAndExit.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/PrintSharedArchiveAndExit.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -67,81 +67,79 @@
TestCommon.testDump(cp, TestCommon.list("Hello"));
- OutputAnalyzer output;
-
log("Normal execution -- all the JAR paths should be checked");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
- "-XX:+PrintSharedArchiveAndExit");
- check(output, 0, true, lastCheckMsg);
+ "-XX:+PrintSharedArchiveAndExit")
+ .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg));
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
"-XX:+PrintSharedArchiveAndExit",
- "-XX:+PrintSharedDictionary"); // Test PrintSharedDictionary as well.
- check(output, 0, true, lastCheckMsg, "java.lang.Object");
+ "-XX:+PrintSharedDictionary") // Test PrintSharedDictionary as well.
+ .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg, "java.lang.Object"));
log("Normal execution -- Make sure -version, help message and app main()\n" +
"class are not invoked. These are checked inside check().");
- output = TestCommon.execCommon("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "-version");
- check(output, 0, true, lastCheckMsg);
+ TestCommon.run("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "-version")
+ .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg));
- output = TestCommon.execCommon("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "-help");
- check(output, 0, true, lastCheckMsg);
+ TestCommon.run("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "-help")
+ .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg));
- output = TestCommon.execCommon("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "Hello");
- check(output, 0, true, lastCheckMsg);
+ TestCommon.run("-cp", cp, "-XX:+PrintSharedArchiveAndExit", "Hello")
+ .ifNoMappingFailure(output -> check(output, 0, true, lastCheckMsg));
log("Execution with simple errors -- with 'simple' errors like missing or modified\n" +
"JAR files, the VM should try to continue to print the remaining information.\n" +
"Use an invalid Boot CP -- all the JAR paths should be checked");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
"-Xbootclasspath/a:foo.jar",
- "-XX:+PrintSharedArchiveAndExit");
- check(output, 1, true, lastCheckMsg, "[BOOT classpath mismatch, ");
+ "-XX:+PrintSharedArchiveAndExit")
+ .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "[BOOT classpath mismatch, "));
log("Use an App CP shorter than the one at dump time -- all the JAR paths should be checked");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", ".",
- "-XX:+PrintSharedArchiveAndExit");
- check(output, 1, true, lastCheckMsg, "Run time APP classpath is shorter than the one at dump time: .");
+ "-XX:+PrintSharedArchiveAndExit")
+ .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "Run time APP classpath is shorter than the one at dump time: ."));
log("Use an invalid App CP -- all the JAR paths should be checked");
String invalidCP = "non-existing-dir" + File.pathSeparator + cp;
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", invalidCP,
- "-XX:+PrintSharedArchiveAndExit");
- check(output, 1, true, lastCheckMsg, "APP classpath mismatch, actual: -Djava.class.path=" + invalidCP);
+ "-XX:+PrintSharedArchiveAndExit")
+ .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "APP classpath mismatch, actual: -Djava.class.path=" + invalidCP));
log("Changed modification time of hello.jar -- all the JAR paths should be checked");
(new File(appJar)).setLastModified(System.currentTimeMillis() + 2000);
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
- "-XX:+PrintSharedArchiveAndExit");
- check(output, 1, true, lastCheckMsg, "[Timestamp mismatch]");
+ "-XX:+PrintSharedArchiveAndExit")
+ .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "[Timestamp mismatch]"));
log("Even if hello.jar is out of date, we should still be able to print the dictionary.");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
"-XX:+PrintSharedArchiveAndExit",
- "-XX:+PrintSharedDictionary"); // Test PrintSharedDictionary as well.
- check(output, 1, true, lastCheckMsg, "java.lang.Object");
+ "-XX:+PrintSharedDictionary") // Test PrintSharedDictionary as well.
+ .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "java.lang.Object"));
log("Remove hello.jar -- all the JAR paths should be checked");
(new File(appJar)).delete();
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
- "-XX:+PrintSharedArchiveAndExit");
- check(output, 1, true, lastCheckMsg, "[Required classpath entry does not exist: " + appJar + "]");
+ "-XX:+PrintSharedArchiveAndExit")
+ .ifNoMappingFailure(output -> check(output, 1, true, lastCheckMsg, "[Required classpath entry does not exist: " + appJar + "]"));
log("Execution with major errors -- with 'major' errors like the JSA file\n" +
"is missing, we should stop immediately to avoid crashing the JVM.");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", cp,
"-XX:+PrintSharedArchiveAndExit",
- "-XX:SharedArchiveFile=./no-such-fileappcds.jsa");
- check(output, 1, false, lastCheckMsg);
+ "-XX:SharedArchiveFile=./no-such-fileappcds.jsa")
+ .ifNoMappingFailure(output -> check(output, 1, false, lastCheckMsg));
}
}
--- a/test/hotspot/jtreg/runtime/appcds/ProhibitedPackage.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/ProhibitedPackage.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -77,10 +77,10 @@
OutputAnalyzer output;
// -Xshare:on
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
- "-cp", appJar, "-Xlog:class+load=info", "ProhibitedHelper");
- TestCommon.checkExec(output, "Prohibited package name: java.lang");
+ "-cp", appJar, "-Xlog:class+load=info", "ProhibitedHelper")
+ .assertNormalExit("Prohibited package name: java.lang");
// -Xshare:auto
output = TestCommon.execAuto(
--- a/test/hotspot/jtreg/runtime/appcds/SpecifySysLoaderProp.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/SpecifySysLoaderProp.java Wed Feb 14 07:08:25 2018 -0800
@@ -51,56 +51,49 @@
// (0) Baseline. Do not specify -Djava.system.class.loader
// The test class should be loaded from archive
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
"-verbose:class",
"-cp", appJar,
- "ReportMyLoader");
- TestCommon.checkExec(output,
- "[class,load] ReportMyLoader source: shared objects file",
- "ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@");
+ "ReportMyLoader")
+ .assertNormalExit("[class,load] ReportMyLoader source: shared objects file",
+ "ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@");
// (1) Try to execute the archive with -Djava.system.class.loader=no.such.Klass,
// it should fail
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar,
"-Djava.system.class.loader=no.such.Klass",
- "ReportMyLoader");
- try {
- output.shouldContain(warning);
- output.shouldContain("ClassNotFoundException: no.such.Klass");
- } catch (Exception e) {
- TestCommon.checkCommonExecExceptions(output, e);
- }
+ "ReportMyLoader")
+ .assertAbnormalExit(output -> {
+ output.shouldContain(warning);
+ output.shouldContain("ClassNotFoundException: no.such.Klass");
+ });
// (2) Try to execute the archive with -Djava.system.class.loader=TestClassLoader,
// it should run, but AppCDS should be disabled
- output = TestCommon.execCommon(
+ TestCommon.run(
"-verbose:class",
"-cp", appJar,
"-Djava.system.class.loader=TestClassLoader",
- "ReportMyLoader");
- TestCommon.checkExec(output,
- "ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@", //<-this is still printed because TestClassLoader simply delegates to Launcher$AppLoader, but ...
- "TestClassLoader.called = true", //<-but this proves that TestClassLoader was indeed called.
- "TestClassLoader: loadClass(\"ReportMyLoader\","); //<- this also proves that TestClassLoader was indeed called.
- try {
+ "ReportMyLoader")
+ .assertNormalExit("ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@", //<-this is still printed because TestClassLoader simply delegates to Launcher$AppLoader, but ...
+ "TestClassLoader.called = true", //<-but this proves that TestClassLoader was indeed called.
+ "TestClassLoader: loadClass(\"ReportMyLoader\",") //<- this also proves that TestClassLoader was indeed called.
+ .assertNormalExit(output -> {
output.shouldMatch(".class,load. TestClassLoader source: file:");
output.shouldMatch(".class,load. ReportMyLoader source: file:.*" + jarFileName);
- } catch (Exception e) {
- TestCommon.checkCommonExecExceptions(output, e);
- }
+ });
// (3) Try to change the java.system.class.loader programmatically after
// the app's main method is executed. This should have no effect in terms of
// changing or switching the actual system class loader that's already in use.
- output = TestCommon.execCommon(
+ TestCommon.run(
"-verbose:class",
"-cp", appJar,
- "TrySwitchMyLoader");
- TestCommon.checkExec(output,
- "[class,load] ReportMyLoader source: shared objects file",
- "TrySwitchMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@",
- "ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@",
- "TestClassLoader.called = false");
+ "TrySwitchMyLoader")
+ .assertNormalExit("[class,load] ReportMyLoader source: shared objects file",
+ "TrySwitchMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@",
+ "ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@",
+ "TestClassLoader.called = false");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/TestCommon.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/TestCommon.java Wed Feb 14 07:08:25 2018 -0800
@@ -28,6 +28,7 @@
import jdk.test.lib.Platform;
import jdk.test.lib.cds.CDSOptions;
import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.cds.CDSTestUtils.Result;
import jdk.test.lib.process.ProcessTools;
import jdk.test.lib.process.OutputAnalyzer;
import java.io.File;
@@ -191,6 +192,14 @@
return runWithArchive(opts);
}
+ // This is the new API for running a Java process with CDS enabled.
+ // See comments in the CDSTestUtils.Result class for how to use this method.
+ public static Result run(String... suffix) throws Exception {
+ AppCDSOptions opts = (new AppCDSOptions());
+ opts.addSuffix(suffix);
+ return new Result(opts, runWithArchive(opts));
+ }
+
public static OutputAnalyzer exec(String appJar, String... suffix) throws Exception {
AppCDSOptions opts = (new AppCDSOptions()).setAppJar(appJar);
--- a/test/hotspot/jtreg/runtime/appcds/TraceLongClasspath.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/TraceLongClasspath.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -84,21 +84,22 @@
"/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/jdk/lib/tools.jar" + ps +
"/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/modules/foobar.ooo_12.1.3/ooo-manifest.jar";
- longClassPath += ps + appJar;
+ String myCP = longClassPath + ps + appJar;
// Dump an archive with a specified JAR file in -classpath
- TestCommon.testDump(longClassPath, TestCommon.list("Hello"));
+ TestCommon.testDump(myCP, TestCommon.list("Hello"));
// Then try to execute the archive with a different classpath and with -XX:+TraceClassPaths.
// The diagnosis "expecting" app classpath trace should show the entire classpath.
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+TraceClassPaths",
"-cp", appJar,
- "Hello");
- output.shouldContain("Unable to use shared archive");
- output.shouldContain("shared class paths mismatch");
- // the "expecting" app classpath from -XX:+TraceClassPaths should not
- // be truncated
- output.shouldContain(longClassPath);
- output.shouldHaveExitValue(1);
+ "Hello")
+ .assertAbnormalExit(output -> {
+ output.shouldContain("Unable to use shared archive");
+ output.shouldContain("shared class paths mismatch");
+ // the "expecting" app classpath from -XX:+TraceClassPaths should not
+ // be truncated
+ output.shouldContain(myCP);
+ });
}
}
--- a/test/hotspot/jtreg/runtime/appcds/VerifierTest.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/VerifierTest.java Wed Feb 14 07:08:25 2018 -0800
@@ -45,6 +45,7 @@
static final String MAP_FAIL =
"shared archive file was created with less restrictive verification setting";
static final String VFY_ERR = "java.lang.VerifyError";
+ static final String PASS_RESULT = "Hi, how are you?";
enum Testset1Part {
A, B
@@ -110,12 +111,22 @@
TestCommon.testDump(jar, appClasses);
}
+ static void checkRuntimeOutput(OutputAnalyzer output, String expected) throws Exception {
+ output.shouldContain(expected);
+ if (expected.equals(PASS_RESULT) ||
+ expected.equals(VFY_ERR)) {
+ output.shouldHaveExitValue(0);
+ } else {
+ output.shouldNotHaveExitValue(0);
+ }
+ }
+
static void testset_1(String jar, String[] noAppClasses, String[] appClasses, Testset1Part part)
throws Exception
{
String config[][] = {
// {dump_list, dumptime_verification_setting,
- // runtime_verification_setting, runtime_output},
+ // runtime_verification_setting, expected_output_str},
// Dump app/ext with -Xverify:remote
{"app", VFY_REMOTE, VFY_REMOTE, VFY_ERR},
@@ -166,7 +177,7 @@
noAppClasses;
String dump_setting = config[i][1];
String runtime_setting = config[i][2];
- String runtime_output = config[i][3];
+ String expected_output_str = config[i][3];
System.out.println("Test case [" + i + "]: dumping " + config[i][0] +
" with " + dump_setting +
", run with " + runtime_setting);
@@ -178,17 +189,10 @@
"-Xms256m",
"-Xmx256m");
}
- OutputAnalyzer runtimeOutput = TestCommon.execCommon(
- "-cp", jar,
- runtime_setting,
- "VerifierTest0");
- try {
- runtimeOutput.shouldContain(runtime_output);
- } catch (RuntimeException re) {
- // Check if the failure is due to archive mapping failure.
- // If not, a RuntimeException will be thrown.
- runtimeOutput.shouldContain("Unable to use shared archive");
- }
+ TestCommon.run("-cp", jar,
+ runtime_setting,
+ "VerifierTest0")
+ .ifNoMappingFailure(output -> checkRuntimeOutput(output, expected_output_str));
prev_dump_setting = dump_setting;
}
}
@@ -204,10 +208,9 @@
"Hi$MyClass");
jar = TestCommon.getTestJar(jarName_hi + ".jar") + File.pathSeparator +
TestCommon.getTestJar(jarName_greet + ".jar");
- final String PASS_RESULT = "Hi, how are you?";
String config2[][] = {
// {dump_list, dumptime_verification_setting,
- // runtime_verification_setting, runtime_output},
+ // runtime_verification_setting, expected_output_str},
// Dump app/ext with -Xverify:remote
{"app", VFY_REMOTE, VFY_REMOTE, PASS_RESULT},
@@ -226,7 +229,7 @@
// config2[i][0] is always set to "app" in this test
String dump_setting = config2[i][1];
String runtime_setting = config2[i][2];
- String runtime_output = config2[i][3];
+ String expected_output_str = config2[i][3];
System.out.println("Test case [" + i + "]: dumping " + config2[i][0] +
" with " + dump_setting +
", run with " + runtime_setting);
@@ -237,19 +240,11 @@
// issue - assert failure when dumping archive with the -Xverify:all
"-Xms256m",
"-Xmx256m");
- OutputAnalyzer runtimeOutput = TestCommon.execCommon(
- "-cp", jar,
- runtime_setting,
- "Hi");
- try {
- runtimeOutput.shouldContain(runtime_output);
- } catch (RuntimeException re) {
- // Check if the failure is due to archive mapping failure.
- // If not, a RuntimeException will be thrown.
- runtimeOutput.shouldContain("Unable to use shared archive");
- }
+ TestCommon.run("-cp", jar,
+ runtime_setting,
+ "Hi")
+ .ifNoMappingFailure(output -> checkRuntimeOutput(output, expected_output_str));
}
-
}
static void createTestJarFile(File jarSrcFile, File jarFile) throws Exception {
--- a/test/hotspot/jtreg/runtime/appcds/WrongClasspath.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/WrongClasspath.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, 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
@@ -45,11 +45,10 @@
TestCommon.testDump(appJar, TestCommon.list("Hello"));
// Then try to execute the archive without -classpath -- it should fail
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
/* "-cp", appJar, */ // <- uncomment this and the execution should succeed
- "Hello");
- output.shouldContain("Unable to use shared archive");
- output.shouldContain("shared class paths mismatch");
- output.shouldHaveExitValue(1);
+ "Hello")
+ .assertAbnormalExit("Unable to use shared archive",
+ "shared class paths mismatch");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/javaldr/ArrayTest.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/ArrayTest.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -79,7 +79,6 @@
}
String[] opts = new String[argsList.size()];
opts = argsList.toArray(opts);
- output = TestCommon.execCommon(opts);
- TestCommon.checkExec(output);
+ TestCommon.run(opts).assertNormalExit();
}
}
--- a/test/hotspot/jtreg/runtime/appcds/javaldr/CheckAnonymousClass.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/CheckAnonymousClass.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -44,9 +44,6 @@
TestCommon.dump(appJar, TestCommon.list("Hello", "org/omg/CORBA/ORB"),
"--add-modules", "java.corba", "-Xlog:class+load=info");
- OutputAnalyzer output = TestCommon.execCommon("-XX:+UnlockDiagnosticVMOptions",
- "-cp", appJar, "-Xlog:class+load=info", "--add-modules", "java.corba", "Hello");
-
String prefix = ".class.load. ";
// class name pattern like the following:
// jdk.internal.loader.BuiltinClassLoader$$Lambda$1/1816757085
@@ -55,20 +52,14 @@
String suffix = ".*source: shared objects file.*";
String pattern = prefix + class_pattern + suffix;
// during run time, anonymous classes shouldn't be loaded from the archive
- try {
- output.shouldNotMatch(pattern);
- } catch (Exception e) {
- TestCommon.checkCommonExecExceptions(output, e);
- }
+ TestCommon.run("-XX:+UnlockDiagnosticVMOptions",
+ "-cp", appJar, "-Xlog:class+load=info", "--add-modules", "java.corba", "Hello")
+ .assertNormalExit(output -> output.shouldNotMatch(pattern));
// inspect the archive and make sure no anonymous class is in there
- output = TestCommon.execCommon("-XX:+UnlockDiagnosticVMOptions",
+ TestCommon.run("-XX:+UnlockDiagnosticVMOptions",
"-cp", appJar, "-Xlog:class+load=info", "-XX:+PrintSharedArchiveAndExit",
- "-XX:+PrintSharedDictionary", "--add-modules", "java.corba", "Hello");
- try {
- output.shouldNotMatch(class_pattern);
- } catch (Exception e) {
- TestCommon.checkCommonExecExceptions(output, e);
- }
+ "-XX:+PrintSharedDictionary", "--add-modules", "java.corba", "Hello")
+ .assertNormalExit(output -> output.shouldNotMatch(class_pattern));
}
}
--- a/test/hotspot/jtreg/runtime/appcds/javaldr/GCDuringDump.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/GCDuringDump.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -67,13 +67,13 @@
TestCommon.testDump(appJar, TestCommon.list("Hello"),
extraArg, "-Xmx32m", gcLog);
- OutputAnalyzer output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar,
"-Xmx32m",
"-XX:+PrintSharedSpaces",
gcLog,
- "Hello");
- TestCommon.checkExec(output);
+ "Hello")
+ .assertNormalExit();
}
}
}
--- a/test/hotspot/jtreg/runtime/appcds/javaldr/GCSharedStringsDuringDump.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/javaldr/GCSharedStringsDuringDump.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -113,7 +113,7 @@
"-XX:SharedArchiveConfigFile=" + sharedArchiveCfgFile);
}
- output = TestCommon.execCommon(
+ TestCommon.run(
"-cp", appJar,
bootClassPath,
"-Xmx32m",
@@ -124,8 +124,8 @@
"-XX:+WhiteBoxAPI",
"-XX:SharedReadOnlySize=30m",
gcLog,
- "GCSharedStringsDuringDumpWb");
- TestCommon.checkExec(output);
+ "GCSharedStringsDuringDumpWb")
+ .assertNormalExit();
}
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/AppClassInCP.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/AppClassInCP.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, 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
@@ -90,13 +90,13 @@
String classPath = appJar + File.pathSeparator + classDir;
System.out.println("classPath: " + classPath);
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"-cp", classPath,
"--patch-module=java.naming=" + moduleJar,
"-Xlog:class+load",
- "PatchMain", "javax.naming.spi.NamingManager", "mypackage.Hello");
- TestCommon.checkExec(output,
+ "PatchMain", "javax.naming.spi.NamingManager", "mypackage.Hello")
+ .assertNormalExit(
"I pass!",
"Hello!",
"Hello source: shared objects file");
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/CustomPackage.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/CustomPackage.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, 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
@@ -72,12 +72,12 @@
"PatchMain", "javax.naming.myspi.NamingManager");
TestCommon.checkDump(output, "Preload Warning: Cannot find javax/naming/myspi/NamingManager");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.naming=" + moduleJar,
"-Xlog:class+load",
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.myspi.NamingManager");
- TestCommon.checkExec(output, "I pass!");
+ "PatchMain", "javax.naming.myspi.NamingManager")
+ .assertNormalExit("I pass!");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/MismatchedPatchModule.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/MismatchedPatchModule.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, 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
@@ -72,12 +72,12 @@
TestCommon.checkDump(output, "Loading classes to share");
// javax.naming.spi.NamingManager is not patched at runtime
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.naming2=" + moduleJar,
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.spi.NamingManager");
- output.shouldNotContain("I pass!");
+ "PatchMain", "javax.naming.spi.NamingManager")
+ .assertNormalExit(o -> o.shouldNotContain("I pass!"));
// Case 2: --patch-module specified for dump time but not for run time
System.out.println("Case 2: --patch-module specified for dump time but not for run time");
@@ -89,11 +89,11 @@
TestCommon.checkDump(output, "Loading classes to share");
// javax.naming.spi.NamingManager is not patched at runtime
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.spi.NamingManager");
- output.shouldNotContain("I pass!");
+ "PatchMain", "javax.naming.spi.NamingManager")
+ .assertNormalExit(o -> o.shouldNotContain("I pass!"));
// Case 3: --patch-module specified for run time but not for dump time
System.out.println("Case 3: --patch-module specified for run time but not for dump time");
@@ -104,12 +104,12 @@
TestCommon.checkDump(output, "Loading classes to share");
// javax.naming.spi.NamingManager is patched at runtime
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.naming=" + moduleJar,
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.spi.NamingManager");
- TestCommon.checkExec(output, "I pass!");
+ "PatchMain", "javax.naming.spi.NamingManager")
+ .assertNormalExit("I pass!");
// Case 4: mismatched --patch-module entry counts between dump time and run time
System.out.println("Case 4: mismatched --patch-module entry counts between dump time and run time");
@@ -121,12 +121,12 @@
TestCommon.checkDump(output, "Loading classes to share");
// javax.naming.spi.NamingManager is patched at runtime
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.naming=" + moduleJar,
"--patch-module=java.naming2=" + moduleJar,
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.spi.NamingManager");
- TestCommon.checkExec(output, "I pass!");
+ "PatchMain", "javax.naming.spi.NamingManager")
+ .assertNormalExit("I pass!");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/PatchJavaBase.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/PatchJavaBase.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, 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
@@ -64,10 +64,11 @@
"PatchMain", "java.lang.NewClass");
TestCommon.checkDump(output, "Loading classes to share");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.base=" + moduleJar,
- "PatchMain", "java.lang.NewClass");
- output.shouldContain("CDS is disabled when java.base module is patched");
+ "PatchMain", "java.lang.NewClass")
+ .assertAbnormalExit("Unable to use shared archive",
+ "CDS is disabled when java.base module is patched");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/Simple.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/Simple.java Wed Feb 14 07:08:25 2018 -0800
@@ -70,12 +70,12 @@
"PatchMain", "javax.naming.spi.NamingManager");
TestCommon.checkDump(output, "Loading classes to share");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.naming=" + moduleJar,
"-Xlog:class+load",
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.spi.NamingManager");
- TestCommon.checkExec(output, "I pass!");
+ "PatchMain", "javax.naming.spi.NamingManager")
+ .assertNormalExit("I pass!");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/SubClassOfPatchedClass.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/SubClassOfPatchedClass.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, 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
@@ -92,13 +92,13 @@
String classPath = appJar + File.pathSeparator + classDir;
System.out.println("classPath: " + classPath);
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"-cp", classPath,
"--patch-module=java.naming=" + moduleJar,
"-Xlog:class+load",
- "PatchMain", "javax.naming.Reference", "mypackage.MyReference");
- TestCommon.checkExec(output,
+ "PatchMain", "javax.naming.Reference", "mypackage.MyReference")
+ .assertNormalExit(
"I pass!",
"MyReference source: file:");
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/TwoJars.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/PatchModule/TwoJars.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, 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
@@ -89,12 +89,12 @@
"PatchMain", "javax.naming.spi.NamingManager");
TestCommon.checkDump(output, "Loading classes to share");
- output = TestCommon.execCommon(
+ TestCommon.run(
"-XX:+UnlockDiagnosticVMOptions",
"--patch-module=java.naming=" + moduleJar2 + File.pathSeparator + moduleJar,
"-Xlog:class+load",
"-Xlog:class+path=info",
- "PatchMain", "javax.naming.spi.NamingManager");
- TestCommon.checkExec(output, "I pass");
+ "PatchMain", "javax.naming.spi.NamingManager")
+ .assertNormalExit("I pass");
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/DummyClassesInBootClassPath.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/DummyClassesInBootClassPath.java Wed Feb 14 07:08:25 2018 -0800
@@ -70,10 +70,10 @@
}
String[] arguments = new String[argsList.size()];
arguments = argsList.toArray(arguments);
- OutputAnalyzer execOutput = TestCommon.execCommon(
+ Testcommon.run(
"--add-modules", "java.activation", "-Xbootclasspath/a:" + appJar,
- "DummyClassHelper", arguments[0], arguments[1]);
- checkOutput(execOutput, classNames);
+ "DummyClassHelper", arguments[0], arguments[1])
+ .assertNormalExit(output -> checkOutput(output, classNames));
JarBuilder.build(true, "WhiteBox", "sun/hotspot/WhiteBox");
String whiteBoxJar = TestCommon.getTestJar("WhiteBox.jar");
@@ -87,8 +87,8 @@
String[] opts = {"-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI",
"--add-modules", "java.activation", bootClassPath, "-Xlog:class+path=trace",
"DummyClassHelper", arguments[0], arguments[1], arguments[2]};
- execOutput = TestCommon.execCommon(opts);
- checkOutput(execOutput, classNames);
+ Testcommon.run(opts)
+ .assertNormalExit(output -> checkOutput(output, classNames));
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/EmptyClassInBootClassPath.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/jigsaw/classpathtests/EmptyClassInBootClassPath.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, 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
@@ -73,16 +73,14 @@
argsList.add("useAppLoader");
String[] opts = new String[argsList.size()];
opts = argsList.toArray(opts);
- OutputAnalyzer runOutput = TestCommon.execCommon(opts);
- TestCommon.checkExec(runOutput, "appLoader found method main");
+ TestCommon.run(opts).assertNormalExit("appLoader found method main");
// case 2: load class in bootclasspath using boot loader
argsList.remove(argsList.size() - 1);
argsList.add("useBootLoader");
opts = new String[argsList.size()];
opts = argsList.toArray(opts);
- runOutput = TestCommon.execCommon(opts);
- TestCommon.checkExec(runOutput, EXPECTED_EXCEPTION);
+ TestCommon.run(opts).assertNormalExit(EXPECTED_EXCEPTION);
// case 3: load class in bootclasspath using app loader with '--limit-modules java.base'
argsList.add(0, "--limit-modules");
@@ -91,16 +89,13 @@
argsList.add("useAppLoader");
opts = new String[argsList.size()];
opts = argsList.toArray(opts);
- runOutput = TestCommon.execCommon(opts);
- TestCommon.checkExec(runOutput, EXPECTED_EXCEPTION);
+ TestCommon.run(opts).assertNormalExit(EXPECTED_EXCEPTION);
// case 4: load class in bootclasspath using boot loader with '--limit-modules java.base'
argsList.remove(argsList.size() - 1);
argsList.add("useBootLoader");
opts = new String[argsList.size()];
opts = argsList.toArray(opts);
- runOutput = TestCommon.execCommon(opts);
- TestCommon.checkExec(runOutput, EXPECTED_EXCEPTION);
-
+ TestCommon.run(opts).assertNormalExit(EXPECTED_EXCEPTION);
}
}
--- a/test/hotspot/jtreg/runtime/appcds/jvmti/transformRelatedClasses/TransformRelatedClassesAppCDS.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/hotspot/jtreg/runtime/appcds/jvmti/transformRelatedClasses/TransformRelatedClassesAppCDS.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2018, 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
@@ -113,10 +113,9 @@
log("runTestWithAppLoader(): testCaseId = %d", entry.testCaseId);
String params = TransformTestCommon.getAgentParams(entry, parent, child);
String agentParam = String.format("-javaagent:%s=%s", agentJar, params);
- out = TestCommon.execCommon("-Xlog:class+load=info", "-cp", appJar,
- agentParam, child);
-
- TransformTestCommon.checkResults(entry, out, parent, child);
+ TestCommon.run("-Xlog:class+load=info", "-cp", appJar,
+ agentParam, child)
+ .assertNormalExit(output -> TransformTestCommon.checkResults(entry, output, parent, child));
}
}
@@ -187,13 +186,13 @@
String agentParam = "-javaagent:" + agentJar + "=" +
TransformTestCommon.getAgentParams(entry, parent, child);
- out = TestCommon.execCommon("-Xlog:class+load=info",
- "-cp", appJar,
- "--add-opens=java.base/java.security=ALL-UNNAMED",
- agentParam,
- "CustomLoaderApp",
- customJar, loaderType, child);
- TransformTestCommon.checkResults(entry, out, parent, child);
+ TestCommon.run("-Xlog:class+load=info",
+ "-cp", appJar,
+ "--add-opens=java.base/java.security=ALL-UNNAMED",
+ agentParam,
+ "CustomLoaderApp",
+ customJar, loaderType, child)
+ .assertNormalExit(output -> TransformTestCommon.checkResults(entry, output, parent, child));
}
--- a/test/lib/jdk/test/lib/cds/CDSTestUtils.java Thu Feb 15 09:22:25 2018 -0800
+++ b/test/lib/jdk/test/lib/cds/CDSTestUtils.java Wed Feb 14 07:08:25 2018 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, 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
@@ -36,6 +36,160 @@
// This class contains common test utilities for testing CDS
public class CDSTestUtils {
+ public interface Checker {
+ public void check(OutputAnalyzer output) throws Exception;
+ }
+
+ /*
+ * INTRODUCTION
+ *
+ * When testing various CDS functionalities, we need to launch JVM processes
+ * using a "launch method" (such as TestCommon.run), and analyze the results of these
+ * processes.
+ *
+ * While typical jtreg tests would use OutputAnalyzer in such cases, due to the
+ * complexity of CDS failure modes, we have added the CDSTestUtils.Result class
+ * to make the analysis more convenient and less error prone.
+ *
+ * A Java process can end in one of the following 4 states:
+ *
+ * 1: Unexpected error - such as JVM crashing. In this case, the "launch method"
+ * will throw a RuntimeException.
+ * 2: Mapping Failure - this happens when the OS (intermittently) fails to map the
+ * CDS archive, normally caused by Address Space Layout Randomization.
+ * We usually treat this as "pass".
+ * 3: Normal Exit - the JVM process has finished without crashing, and the exit code is 0.
+ * 4: Abnormal Exit - the JVM process has finished without crashing, and the exit code is not 0.
+ *
+ * In most test cases, we need to check the JVM process's output in cases 3 and 4. However, we need
+ * to make sure that our test code is not confused by case 2.
+ *
+ * For example, a JVM process is expected to print the string "Hi" and exit with 0. With the old
+ * CDSTestUtils.runWithArchive API, the test may be written as this:
+ *
+ * OutputAnalyzer out = CDSTestUtils.runWithArchive(args);
+ * out.shouldContain("Hi");
+ *
+ * However, if the JVM process fails with mapping failure, the string "Hi" will not be in the output,
+ * and your test case will fail intermittently.
+ *
+ * Instead, the test case should be written as
+ *
+ * CCDSTestUtils.run(args).assertNormalExit("Hi");
+ *
+ * EXAMPLES/HOWTO
+ *
+ * 1. For simple substring matching:
+ *
+ * CCDSTestUtils.run(args).assertNormalExit("Hi");
+ * CCDSTestUtils.run(args).assertNormalExit("a", "b", "x");
+ * CCDSTestUtils.run(args).assertAbnormalExit("failure 1", "failure2");
+ *
+ * 2. For more complex output matching: using Lambda expressions
+ *
+ * CCDSTestUtils.run(args)
+ * .assertNormalExit(output -> output.shouldNotContain("this should not be printed");
+ * CCDSTestUtils.run(args)
+ * .assertAbnormalExit(output -> {
+ * output.shouldNotContain("this should not be printed");
+ * output.shouldHaveExitValue(123);
+ * });
+ *
+ * 3. Chaining several checks:
+ *
+ * CCDSTestUtils.run(args)
+ * .assertNormalExit(output -> output.shouldNotContain("this should not be printed")
+ * .assertNormalExit("should have this", "should have that");
+ *
+ * 4. [Rare use case] if a test sometimes exit normally, and sometimes abnormally:
+ *
+ * CCDSTestUtils.run(args)
+ * .ifNormalExit("ths string is printed when exiting with 0")
+ * .ifAbNormalExit("ths string is printed when exiting with 1");
+ *
+ * NOTE: you usually don't want to write your test case like this -- it should always
+ * exit with the same exit code. (But I kept this API because some existing test cases
+ * behave this way -- need to revisit).
+ */
+ public static class Result {
+ private final OutputAnalyzer output;
+ private final CDSOptions options;
+ private final boolean hasMappingFailure;
+ private final boolean hasAbnormalExit;
+ private final boolean hasNormalExit;
+
+ public Result(CDSOptions opts, OutputAnalyzer out) throws Exception {
+ options = opts;
+ output = out;
+ hasMappingFailure = CDSTestUtils.checkCommonExecExceptions(output);
+ hasAbnormalExit = (!hasMappingFailure) && (output.getExitValue() != 0);
+ hasNormalExit = (!hasMappingFailure) && (output.getExitValue() == 0);
+
+ if (hasNormalExit) {
+ if ("on".equals(options.xShareMode) && output.getStderr().contains("java version")) {
+ // "-showversion" is always passed in the command-line by the execXXX methods.
+ // During normal exit, we require that the VM to show that sharing was enabled.
+ output.shouldContain("sharing");
+ }
+ }
+ }
+
+ public Result assertNormalExit(Checker checker) throws Exception {
+ if (!hasMappingFailure) {
+ checker.check(output);
+ output.shouldHaveExitValue(0);
+ }
+ return this;
+ }
+
+ public Result assertAbnormalExit(Checker checker) throws Exception {
+ if (!hasMappingFailure) {
+ checker.check(output);
+ output.shouldNotHaveExitValue(0);
+ }
+ return this;
+ }
+
+ public Result ifNormalExit(Checker checker) throws Exception {
+ if (hasNormalExit) {
+ checker.check(output);
+ }
+ return this;
+ }
+
+ public Result ifAbnormalExit(Checker checker) throws Exception {
+ if (hasAbnormalExit) {
+ checker.check(output);
+ }
+ return this;
+ }
+
+ public Result ifNoMappingFailure(Checker checker) throws Exception {
+ if (!hasMappingFailure) {
+ checker.check(output);
+ }
+ return this;
+ }
+
+
+ public Result assertNormalExit(String... matches) throws Exception {
+ if (!hasMappingFailure) {
+ checkMatches(output, matches);
+ output.shouldHaveExitValue(0);
+ }
+ return this;
+ }
+
+ public Result assertAbnormalExit(String... matches) throws Exception {
+ if (!hasMappingFailure) {
+ checkMatches(output, matches);
+ output.shouldNotHaveExitValue(0);
+ }
+
+ return this;
+ }
+ }
+
// Specify this property to copy sdandard output of the child test process to
// the parent/main stdout of the test.
// By default such output is logged into a file, and is copied into the main stdout.
@@ -119,7 +273,7 @@
// of exceptions and common errors.
// Exception e argument - an exception to be re-thrown if none of the common
// exceptions match. Pass null if you wish not to re-throw any exception.
- public static void checkCommonExecExceptions(OutputAnalyzer output, Exception e)
+ public static boolean checkCommonExecExceptions(OutputAnalyzer output, Exception e)
throws Exception {
if (output.getStdout().contains("http://bugreport.java.com/bugreport/crash.jsp")) {
throw new RuntimeException("Hotspot crashed");
@@ -128,7 +282,7 @@
throw new RuntimeException("Test Failed");
}
if (output.getOutput().contains("shared class paths mismatch")) {
- throw new RuntimeException("shared class paths mismatch");
+// throw new RuntimeException("shared class paths mismatch");
}
if (output.getOutput().contains("Unable to unmap shared space")) {
throw new RuntimeException("Unable to unmap shared space");
@@ -139,11 +293,17 @@
// and can be random (see ASLR).
if (isUnableToMap(output)) {
System.out.println(UnableToMapMsg);
- return;
+ return true;
}
- if (e != null)
+ if (e != null) {
throw e;
+ }
+ return false;
+ }
+
+ public static boolean checkCommonExecExceptions(OutputAnalyzer output) throws Exception {
+ return checkCommonExecExceptions(output, null);
}
@@ -176,6 +336,12 @@
return false;
}
+ public static Result run(String... cliPrefix) throws Exception {
+ CDSOptions opts = new CDSOptions();
+ opts.setArchiveName(getDefaultArchiveName());
+ opts.addPrefix(cliPrefix);
+ return new Result(opts, runWithArchive(opts));
+ }
// Execute JVM with CDS archive, specify command line args suffix
public static OutputAnalyzer runWithArchive(String... cliPrefix)
@@ -246,7 +412,7 @@
return output;
}
- checkExtraMatches(output, extraMatches);
+ checkMatches(output, extraMatches);
return output;
}
@@ -260,13 +426,13 @@
}
output.shouldHaveExitValue(expectedExitValue);
- checkExtraMatches(output, extraMatches);
+ checkMatches(output, extraMatches);
return output;
}
- public static OutputAnalyzer checkExtraMatches(OutputAnalyzer output,
- String... extraMatches) throws Exception {
- for (String match : extraMatches) {
+ public static OutputAnalyzer checkMatches(OutputAnalyzer output,
+ String... matches) throws Exception {
+ for (String match : matches) {
output.shouldContain(match);
}
return output;