8157957: ClassNotFoundException: jdk.test.lib.JDKToolFinder
Reviewed-by: coleenp, gtriantafill, mseledtsov, iignatyev, dholmes, dsamersoff
This commit is contained in:
parent
a39d9629dd
commit
830cf57fbd
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2015, 2016, 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,7 +48,7 @@ TARGETS += $(BUILD_WB_JAR)
|
||||
# test-lib.jar will contain only hprof classes until JDK-8081381 is resolved
|
||||
$(eval $(call SetupJavaCompilation, BUILD_TEST_LIB_JAR, \
|
||||
SETUP := GENERATE_USINGJDKBYTECODE, \
|
||||
SRC := $(TEST_LIB_SOURCE_DIR)/share/classes/jdk/test/lib/hprof, \
|
||||
SRC := $(TEST_LIB_SOURCE_DIR)/jdk/test/lib/hprof, \
|
||||
BIN := $(TEST_LIB_SUPPORT)/test-lib_classes, \
|
||||
JAR := $(TEST_LIB_SUPPORT)/test-lib.jar, \
|
||||
))
|
||||
|
257
test/lib/ClassFileInstaller.java
Normal file
257
test/lib/ClassFileInstaller.java
Normal file
@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* Dump a class file for a class on the class path in the current directory, or
|
||||
* in the specified JAR file. This class is usually used when you build a class
|
||||
* from a test library, but want to use this class in a sub-process.
|
||||
*
|
||||
* For example, to build the following library class:
|
||||
* test/lib/sun/hotspot/WhiteBox.java
|
||||
*
|
||||
* You would use the following tags:
|
||||
*
|
||||
* @library /test/lib
|
||||
* @build sun.hotspot.WhiteBox
|
||||
*
|
||||
* JTREG would build the class file under
|
||||
* ${JTWork}/classes/test/lib/sun/hotspot/WhiteBox.class
|
||||
*
|
||||
* With you run your main test class using "@run main MyMainClass", JTREG would setup the
|
||||
* -classpath to include "${JTWork}/classes/test/lib/", so MyMainClass would be able to
|
||||
* load the WhiteBox class.
|
||||
*
|
||||
* However, if you run a sub process, and do not wish to use the exact same -classpath,
|
||||
* You can use ClassFileInstaller to ensure that WhiteBox is available in the current
|
||||
* directory of your test:
|
||||
*
|
||||
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||
*
|
||||
* Or, you can use the -jar option to store the class in the specified JAR file. If a relative
|
||||
* path name is given, the JAR file would be relative to the current directory of
|
||||
*
|
||||
* @run main ClassFileInstaller -jar myjar.jar sun.hotspot.WhiteBox
|
||||
*/
|
||||
public class ClassFileInstaller {
|
||||
/**
|
||||
* You can enable debug tracing of ClassFileInstaller by running JTREG with
|
||||
* jtreg -DClassFileInstaller.debug=true ... <names of tests>
|
||||
*/
|
||||
public static boolean DEBUG = Boolean.getBoolean("ClassFileInstaller.debug");
|
||||
|
||||
/**
|
||||
* @param args The names of the classes to dump
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void main(String... args) throws Exception {
|
||||
if (args.length > 1 && args[0].equals("-jar")) {
|
||||
if (args.length < 2) {
|
||||
throw new RuntimeException("Usage: ClassFileInstaller <options> <classes>\n" +
|
||||
"where possible options include:\n" +
|
||||
" -jar <path> Write to the JAR file <path>");
|
||||
}
|
||||
writeJar(args[1], null, args, 2, args.length);
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
System.out.println("ClassFileInstaller: Writing to " + System.getProperty("user.dir"));
|
||||
}
|
||||
for (String arg : args) {
|
||||
writeClassToDisk(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Manifest {
|
||||
private InputStream in;
|
||||
|
||||
private Manifest(InputStream in) {
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
static Manifest fromSourceFile(String fileName) throws Exception {
|
||||
String pathName = System.getProperty("test.src") + File.separator + fileName;
|
||||
return new Manifest(new FileInputStream(pathName));
|
||||
}
|
||||
|
||||
// Example:
|
||||
// String manifest = "Premain-Class: RedefineClassHelper\n" +
|
||||
// "Can-Redefine-Classes: true\n";
|
||||
// ClassFileInstaller.writeJar("redefineagent.jar",
|
||||
// ClassFileInstaller.Manifest.fromString(manifest),
|
||||
// "RedefineClassHelper");
|
||||
static Manifest fromString(String manifest) throws Exception {
|
||||
return new Manifest(new ByteArrayInputStream(manifest.getBytes()));
|
||||
}
|
||||
|
||||
public InputStream getInputStream() {
|
||||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeJar(String jarFile, Manifest manifest, String classes[], int from, int to) throws Exception {
|
||||
if (DEBUG) {
|
||||
System.out.println("ClassFileInstaller: Writing to " + getJarPath(jarFile));
|
||||
}
|
||||
|
||||
(new File(jarFile)).delete();
|
||||
FileOutputStream fos = new FileOutputStream(jarFile);
|
||||
ZipOutputStream zos = new ZipOutputStream(fos);
|
||||
|
||||
// The manifest must be the first or second entry. See comments in JarInputStream
|
||||
// constructor and JDK-5046178.
|
||||
if (manifest != null) {
|
||||
writeToDisk(zos, "META-INF/MANIFEST.MF", manifest.getInputStream());
|
||||
}
|
||||
|
||||
for (int i=from; i<to; i++) {
|
||||
writeClassToDisk(zos, classes[i]);
|
||||
}
|
||||
|
||||
zos.close();
|
||||
fos.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* You can call ClassFileInstaller.writeJar() from your main test class instead of
|
||||
* using "@run ClassFileInstaller -jar ...". E.g.,
|
||||
*
|
||||
* String jarPath = ClassFileInstaller.getJarPath("myjar.jar", "sun.hotspot.WhiteBox")
|
||||
*
|
||||
* If you call this API, make sure you build ClassFileInstaller with the following tags:
|
||||
*
|
||||
* @library testlibrary
|
||||
* @build ClassFileInstaller
|
||||
*/
|
||||
public static String writeJar(String jarFile, String... classes) throws Exception {
|
||||
writeJar(jarFile, null, classes, 0, classes.length);
|
||||
return getJarPath(jarFile);
|
||||
}
|
||||
|
||||
public static String writeJar(String jarFile, Manifest manifest, String... classes) throws Exception {
|
||||
writeJar(jarFile, manifest, classes, 0, classes.length);
|
||||
return getJarPath(jarFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the absolute path to the file specified in "@ClassFileInstaller -jar myjar.jar",
|
||||
* In your test program, instead of using the JAR file name directly:
|
||||
*
|
||||
* String jarPath = "myjar.jar";
|
||||
*
|
||||
* you should call this function, like:
|
||||
*
|
||||
* String jarPath = ClassFileInstaller.getJarPath("myjar.jar")
|
||||
*
|
||||
* The reasons are:
|
||||
* (1) Using absolute path makes it easy to cut-and-paste from the JTR file and rerun your
|
||||
* test in any directory.
|
||||
* (2) In the future, we may make the JAR file name unique to avoid clobbering
|
||||
* during parallel JTREG execution.
|
||||
*
|
||||
*/
|
||||
public static String getJarPath(String jarFileName) {
|
||||
return new File(jarFileName).getAbsolutePath();
|
||||
}
|
||||
|
||||
public static void writeClassToDisk(String className) throws Exception {
|
||||
writeClassToDisk((ZipOutputStream)null, className);
|
||||
}
|
||||
private static void writeClassToDisk(ZipOutputStream zos, String className) throws Exception {
|
||||
writeClassToDisk(zos, className, "");
|
||||
}
|
||||
|
||||
public static void writeClassToDisk(String className, String prependPath) throws Exception {
|
||||
writeClassToDisk(null, className, prependPath);
|
||||
}
|
||||
private static void writeClassToDisk(ZipOutputStream zos, String className, String prependPath) throws Exception {
|
||||
ClassLoader cl = ClassFileInstaller.class.getClassLoader();
|
||||
|
||||
// Convert dotted class name to a path to a class file
|
||||
String pathName = className.replace('.', '/').concat(".class");
|
||||
InputStream is = cl.getResourceAsStream(pathName);
|
||||
if (is == null) {
|
||||
throw new RuntimeException("Failed to find " + pathName);
|
||||
}
|
||||
if (prependPath.length() > 0) {
|
||||
pathName = prependPath + "/" + pathName;
|
||||
}
|
||||
writeToDisk(zos, pathName, is);
|
||||
}
|
||||
|
||||
public static void writeClassToDisk(String className, byte[] bytecode) throws Exception {
|
||||
writeClassToDisk(null, className, bytecode);
|
||||
}
|
||||
private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode) throws Exception {
|
||||
writeClassToDisk(zos, className, bytecode, "");
|
||||
}
|
||||
|
||||
public static void writeClassToDisk(String className, byte[] bytecode, String prependPath) throws Exception {
|
||||
writeClassToDisk(null, className, bytecode, prependPath);
|
||||
}
|
||||
private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode, String prependPath) throws Exception {
|
||||
// Convert dotted class name to a path to a class file
|
||||
String pathName = className.replace('.', '/').concat(".class");
|
||||
if (prependPath.length() > 0) {
|
||||
pathName = prependPath + "/" + pathName;
|
||||
}
|
||||
writeToDisk(zos, pathName, new ByteArrayInputStream(bytecode));
|
||||
}
|
||||
|
||||
private static void writeToDisk(ZipOutputStream zos, String pathName, InputStream is) throws Exception {
|
||||
if (DEBUG) {
|
||||
System.out.println("ClassFileInstaller: Writing " + pathName);
|
||||
}
|
||||
if (zos != null) {
|
||||
ZipEntry ze = new ZipEntry(pathName);
|
||||
zos.putNextEntry(ze);
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = is.read(buf))>0){
|
||||
zos.write(buf, 0, len);
|
||||
}
|
||||
} else {
|
||||
// Create the class file's package directory
|
||||
Path p = Paths.get(pathName);
|
||||
if (pathName.contains("/")) {
|
||||
Files.createDirectories(p.getParent());
|
||||
}
|
||||
// Create the class file
|
||||
Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
is.close();
|
||||
}
|
||||
}
|
79
test/lib/RedefineClassHelper.java
Normal file
79
test/lib/RedefineClassHelper.java
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, 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.
|
||||
*/
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.instrument.*;
|
||||
import jdk.test.lib.InMemoryJavaCompiler;
|
||||
|
||||
/*
|
||||
* Helper class to write tests that redefine classes.
|
||||
* When main method is run, it will create a redefineagent.jar that can be used
|
||||
* with the -javaagent option to support redefining classes in jtreg tests.
|
||||
*
|
||||
* See sample test in test/testlibrary_tests/RedefineClassTest.java
|
||||
*/
|
||||
public class RedefineClassHelper {
|
||||
|
||||
public static Instrumentation instrumentation;
|
||||
public static void premain(String agentArgs, Instrumentation inst) {
|
||||
instrumentation = inst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redefine a class
|
||||
*
|
||||
* @param clazz Class to redefine
|
||||
* @param javacode String with the new java code for the class to be redefined
|
||||
*/
|
||||
public static void redefineClass(Class clazz, String javacode) throws Exception {
|
||||
byte[] bytecode = InMemoryJavaCompiler.compile(clazz.getName(), javacode);
|
||||
redefineClass(clazz, bytecode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redefine a class
|
||||
*
|
||||
* @param clazz Class to redefine
|
||||
* @param bytecode byte[] with the new class
|
||||
*/
|
||||
public static void redefineClass(Class clazz, byte[] bytecode) throws Exception {
|
||||
instrumentation.redefineClasses(new ClassDefinition(clazz, bytecode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method to be invoked before test to create the redefineagent.jar
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
ClassFileInstaller.main("RedefineClassHelper");
|
||||
|
||||
PrintWriter pw = new PrintWriter("MANIFEST.MF");
|
||||
pw.println("Premain-Class: RedefineClassHelper");
|
||||
pw.println("Can-Redefine-Classes: true");
|
||||
pw.close();
|
||||
|
||||
sun.tools.jar.Main jarTool = new sun.tools.jar.Main(System.out, System.err, "jar");
|
||||
if (!jarTool.run(new String[] { "-cmf", "MANIFEST.MF", "redefineagent.jar", "RedefineClassHelper.class" })) {
|
||||
throw new Exception("jar operation failed");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2016, 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
|
106
test/lib/jdk/test/lib/BuildHelper.java
Normal file
106
test/lib/jdk/test/lib/BuildHelper.java
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, 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 jdk.test.lib;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.util.Properties;
|
||||
|
||||
public class BuildHelper {
|
||||
|
||||
/**
|
||||
* Commercial builds should have the BUILD_TYPE set to commercial
|
||||
* within the release file, found at the root of the JDK.
|
||||
*/
|
||||
public static boolean isCommercialBuild() throws Exception {
|
||||
String buildType = getReleaseProperty("BUILD_TYPE","notFound");
|
||||
return buildType.equals("commercial");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the value for property key, or defaultValue if no property not found.
|
||||
* If present, double quotes are trimmed.
|
||||
*/
|
||||
public static String getReleaseProperty(String key, String defaultValue) throws Exception {
|
||||
Properties properties = getReleaseProperties();
|
||||
String value = properties.getProperty(key, defaultValue);
|
||||
return trimDoubleQuotes(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value for property key, or null if no property not found.
|
||||
* If present, double quotes are trimmed.
|
||||
*/
|
||||
public static String getReleaseProperty(String key) throws Exception {
|
||||
return getReleaseProperty(key, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get properties from the release file
|
||||
*/
|
||||
public static Properties getReleaseProperties() throws Exception {
|
||||
Properties properties = new Properties();
|
||||
properties.load(new FileReader(getReleaseFile()));
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Every JDK has a release file in its root.
|
||||
* @return A handler to the release file.
|
||||
*/
|
||||
public static File getReleaseFile() throws Exception {
|
||||
String jdkPath = getJDKRoot();
|
||||
File releaseFile = new File(jdkPath,"release");
|
||||
if ( ! releaseFile.canRead() ) {
|
||||
throw new Exception("Release file is not readable, or it is absent: " +
|
||||
releaseFile.getCanonicalPath());
|
||||
}
|
||||
return releaseFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns path to the JDK under test.
|
||||
* This path is obtained through the test.jdk property, usually set by JTREG.
|
||||
*/
|
||||
public static String getJDKRoot() {
|
||||
String jdkPath = System.getProperty("test.jdk");
|
||||
if (jdkPath == null) {
|
||||
throw new RuntimeException("System property 'test.jdk' not set. This property is normally set by jtreg. "
|
||||
+ "When running test separately, set this property using '-Dtest.jdk=/path/to/jdk'.");
|
||||
}
|
||||
return jdkPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim double quotes from the beginning and the end of the given string.
|
||||
* @param original string to trim.
|
||||
* @return a new trimmed string.
|
||||
*/
|
||||
public static String trimDoubleQuotes(String original) {
|
||||
if (original == null) { return null; }
|
||||
String trimmed = original.replaceAll("^\"+|\"+$", "");
|
||||
return trimmed;
|
||||
}
|
||||
}
|
90
test/lib/jdk/test/lib/ByteCodeLoader.java
Normal file
90
test/lib/jdk/test/lib/ByteCodeLoader.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2016, 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 jdk.test.lib;
|
||||
|
||||
import java.security.SecureClassLoader;
|
||||
|
||||
/**
|
||||
* {@code ByteCodeLoader} can be used for easy loading of byte code already
|
||||
* present in memory.
|
||||
*
|
||||
* {@code InMemoryCompiler} can be used for compiling source code in a string
|
||||
* into byte code, which then can be loaded with {@code ByteCodeLoader}.
|
||||
*
|
||||
* @see InMemoryCompiler
|
||||
*/
|
||||
public class ByteCodeLoader extends SecureClassLoader {
|
||||
private final String className;
|
||||
private final byte[] byteCode;
|
||||
private volatile Class<?> holder;
|
||||
|
||||
/**
|
||||
* Creates a new {@code ByteCodeLoader} ready to load a class with the
|
||||
* given name and the given byte code.
|
||||
*
|
||||
* @param className The name of the class
|
||||
* @param byteCode The byte code of the class
|
||||
*/
|
||||
public ByteCodeLoader(String className, byte[] byteCode) {
|
||||
this.className = className;
|
||||
this.byteCode = byteCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> loadClass(String name) throws ClassNotFoundException {
|
||||
if (!name.equals(className)) {
|
||||
return super.loadClass(name);
|
||||
}
|
||||
if (holder == null) {
|
||||
synchronized(this) {
|
||||
if (holder == null) {
|
||||
holder = findClass(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
if (!name.equals(className)) {
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
|
||||
return defineClass(name, byteCode, 0, byteCode.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for creating a new {@code ByteCodeLoader} and then
|
||||
* directly load the given byte code.
|
||||
*
|
||||
* @param className The name of the class
|
||||
* @param byteCode The byte code for the class
|
||||
* @throws ClassNotFoundException if the class can't be loaded
|
||||
* @return A {@see Class} object representing the class
|
||||
*/
|
||||
public static Class<?> load(String className, byte[] byteCode) throws ClassNotFoundException {
|
||||
return new ByteCodeLoader(className, byteCode).loadClass(className);
|
||||
}
|
||||
}
|
165
test/lib/jdk/test/lib/DynamicVMOption.java
Normal file
165
test/lib/jdk/test/lib/DynamicVMOption.java
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, 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 jdk.test.lib;
|
||||
|
||||
import com.sun.management.HotSpotDiagnosticMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
|
||||
/**
|
||||
* A utility class to work with VM options which could be altered during
|
||||
* execution.
|
||||
*
|
||||
* This class is a wrapper around {@code com.sun.management.VMOption}.
|
||||
* It provides more convenient interface to read/write the values.
|
||||
*
|
||||
*/
|
||||
public class DynamicVMOption {
|
||||
|
||||
private final HotSpotDiagnosticMXBean mxBean;
|
||||
|
||||
/**
|
||||
* VM option name, like "MinHeapFreeRatio".
|
||||
*/
|
||||
public final String name;
|
||||
|
||||
/**
|
||||
* Creates an instance of DynamicVMOption.
|
||||
*
|
||||
* @param name the VM option name
|
||||
*/
|
||||
public DynamicVMOption(String name) {
|
||||
this.name = name;
|
||||
mxBean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new value for the option.
|
||||
* Trying to set not applicable value will cause IllegalArgumentException.
|
||||
* Behavior with null is undefined, most likely NPE will be thrown.
|
||||
*
|
||||
* @param newValue the value to be set
|
||||
* @see #getValue()
|
||||
* @throws IllegalArgumentException if newValue is not applicable to the option
|
||||
*/
|
||||
public final void setValue(String newValue) {
|
||||
mxBean.setVMOption(name, newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of option.
|
||||
*
|
||||
* @return the current option value
|
||||
* @see #setValue(java.lang.String)
|
||||
*/
|
||||
public final String getValue() {
|
||||
return mxBean.getVMOption(name).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if option is writable, false otherwise.
|
||||
*
|
||||
* @return true, if option is writable, false otherwise
|
||||
*/
|
||||
public final boolean isWriteable() {
|
||||
return mxBean.getVMOption(name).isWriteable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given value is applicable for the option.
|
||||
*
|
||||
* This method tries to set the option to the new value. If no exception
|
||||
* has been thrown the value is treated as valid.
|
||||
*
|
||||
* Calling this method will not change the option value. After an attempt
|
||||
* to set a new value, the option will be restored to its previous value.
|
||||
*
|
||||
* @param value the value to verify
|
||||
* @return true if option could be set to the given value
|
||||
*/
|
||||
public boolean isValidValue(String value) {
|
||||
boolean isValid = true;
|
||||
String oldValue = getValue();
|
||||
try {
|
||||
setValue(value);
|
||||
} catch (NullPointerException e) {
|
||||
if (value == null) {
|
||||
isValid = false;
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
isValid = false;
|
||||
} finally {
|
||||
setValue(oldValue);
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the given VM option as String.
|
||||
*
|
||||
* This is a simple shortcut for {@code new DynamicVMOption(name).getValue()}
|
||||
*
|
||||
* @param name the name of VM option
|
||||
* @return value as a string
|
||||
* @see #getValue()
|
||||
*/
|
||||
public static String getString(String name) {
|
||||
return new DynamicVMOption(name).getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the given option as int.
|
||||
*
|
||||
* @param name the name of VM option
|
||||
* @return value parsed as integer
|
||||
* @see #getString(java.lang.String)
|
||||
*
|
||||
*/
|
||||
public static int getInt(String name) {
|
||||
return Integer.parseInt(getString(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the VM option to a new value.
|
||||
*
|
||||
* This is a simple shortcut for {@code new DynamicVMOption(name).setValue(value)}
|
||||
*
|
||||
* @param name the name of VM option
|
||||
* @param value the value to be set
|
||||
* @see #setValue(java.lang.String)
|
||||
*/
|
||||
public static void setString(String name, String value) {
|
||||
new DynamicVMOption(name).setValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the VM option value to a new integer value.
|
||||
*
|
||||
* @param name the name of VM option
|
||||
* @param value the integer value to be set
|
||||
* @see #setString(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public static void setInt(String name, int value) {
|
||||
new DynamicVMOption(name).setValue(Integer.toString(value));
|
||||
}
|
||||
|
||||
}
|
97
test/lib/jdk/test/lib/FileInstaller.java
Normal file
97
test/lib/jdk/test/lib/FileInstaller.java
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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 jdk.test.lib;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
|
||||
/**
|
||||
* Copy a resource: file or directory recursively, using relative path(src and dst)
|
||||
* which are applied to test source directory(src) and current directory(dst)
|
||||
*/
|
||||
public class FileInstaller {
|
||||
/**
|
||||
* @param args source and destination
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
if (args.length != 2) {
|
||||
throw new IllegalArgumentException("Unexpected number of arguments for file copy");
|
||||
}
|
||||
Path src = Paths.get(Utils.TEST_SRC, args[0]).toAbsolutePath();
|
||||
Path dst = Paths.get(args[1]).toAbsolutePath();
|
||||
if (src.toFile().exists()) {
|
||||
if (src.toFile().isDirectory()) {
|
||||
Files.walkFileTree(src, new CopyFileVisitor(src, dst));
|
||||
} else {
|
||||
Path dstDir = dst.getParent();
|
||||
if (!dstDir.toFile().exists()) {
|
||||
Files.createDirectories(dstDir);
|
||||
}
|
||||
Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
} else {
|
||||
throw new IOException("Can't find source " + src);
|
||||
}
|
||||
}
|
||||
|
||||
private static class CopyFileVisitor extends SimpleFileVisitor<Path> {
|
||||
private final Path copyFrom;
|
||||
private final Path copyTo;
|
||||
|
||||
public CopyFileVisitor(Path copyFrom, Path copyTo) {
|
||||
this.copyFrom = copyFrom;
|
||||
this.copyTo = copyTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path file,
|
||||
BasicFileAttributes attrs) throws IOException {
|
||||
Path relativePath = file.relativize(copyFrom);
|
||||
Path destination = copyTo.resolve(relativePath);
|
||||
if (!destination.toFile().exists()) {
|
||||
Files.createDirectories(destination);
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file,
|
||||
BasicFileAttributes attrs) throws IOException {
|
||||
if (!file.toFile().isFile()) {
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
Path relativePath = copyFrom.relativize(file);
|
||||
Path destination = copyTo.resolve(relativePath);
|
||||
Files.copy(file, destination, StandardCopyOption.COPY_ATTRIBUTES);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
}
|
||||
}
|
153
test/lib/jdk/test/lib/InMemoryJavaCompiler.java
Normal file
153
test/lib/jdk/test/lib/InMemoryJavaCompiler.java
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2016, 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 jdk.test.lib;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.tools.ForwardingJavaFileManager;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaCompiler.CompilationTask;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.JavaFileObject.Kind;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
/**
|
||||
* {@code InMemoryJavaCompiler} can be used for compiling a {@link
|
||||
* CharSequence} to a {@code byte[]}.
|
||||
*
|
||||
* The compiler will not use the file system at all, instead using a {@link
|
||||
* ByteArrayOutputStream} for storing the byte code. For the source code, any
|
||||
* kind of {@link CharSequence} can be used, e.g. {@link String}, {@link
|
||||
* StringBuffer} or {@link StringBuilder}.
|
||||
*
|
||||
* The {@code InMemoryCompiler} can easily be used together with a {@code
|
||||
* ByteClassLoader} to easily compile and load source code in a {@link String}:
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* import jdk.test.lib.InMemoryJavaCompiler;
|
||||
* import jdk.test.lib.ByteClassLoader;
|
||||
*
|
||||
* class Example {
|
||||
* public static void main(String[] args) {
|
||||
* String className = "Foo";
|
||||
* String sourceCode = "public class " + className + " {" +
|
||||
* " public void bar() {" +
|
||||
* " System.out.println("Hello from bar!");" +
|
||||
* " }" +
|
||||
* "}";
|
||||
* byte[] byteCode = InMemoryJavaCompiler.compile(className, sourceCode);
|
||||
* Class fooClass = ByteClassLoader.load(className, byteCode);
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public class InMemoryJavaCompiler {
|
||||
private static class MemoryJavaFileObject extends SimpleJavaFileObject {
|
||||
private final String className;
|
||||
private final CharSequence sourceCode;
|
||||
private final ByteArrayOutputStream byteCode;
|
||||
|
||||
public MemoryJavaFileObject(String className, CharSequence sourceCode) {
|
||||
super(URI.create("string:///" + className.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE);
|
||||
this.className = className;
|
||||
this.sourceCode = sourceCode;
|
||||
this.byteCode = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
||||
return sourceCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream openOutputStream() throws IOException {
|
||||
return byteCode;
|
||||
}
|
||||
|
||||
public byte[] getByteCode() {
|
||||
return byteCode.toByteArray();
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
}
|
||||
}
|
||||
|
||||
private static class FileManagerWrapper extends ForwardingJavaFileManager {
|
||||
private MemoryJavaFileObject file;
|
||||
|
||||
public FileManagerWrapper(MemoryJavaFileObject file) {
|
||||
super(getCompiler().getStandardFileManager(null, null, null));
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaFileObject getJavaFileForOutput(Location location, String className,
|
||||
Kind kind, FileObject sibling)
|
||||
throws IOException {
|
||||
if (!file.getClassName().equals(className)) {
|
||||
throw new IOException("Expected class with name " + file.getClassName() +
|
||||
", but got " + className);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the class with the given name and source code.
|
||||
*
|
||||
* @param className The name of the class
|
||||
* @param sourceCode The source code for the class with name {@code className}
|
||||
* @param options additional command line options
|
||||
* @throws RuntimeException if the compilation did not succeed
|
||||
* @return The resulting byte code from the compilation
|
||||
*/
|
||||
public static byte[] compile(String className, CharSequence sourceCode, String... options) {
|
||||
MemoryJavaFileObject file = new MemoryJavaFileObject(className, sourceCode);
|
||||
CompilationTask task = getCompilationTask(file, options);
|
||||
|
||||
if(!task.call()) {
|
||||
throw new RuntimeException("Could not compile " + className + " with source code " + sourceCode);
|
||||
}
|
||||
|
||||
return file.getByteCode();
|
||||
}
|
||||
|
||||
private static JavaCompiler getCompiler() {
|
||||
return ToolProvider.getSystemJavaCompiler();
|
||||
}
|
||||
|
||||
private static CompilationTask getCompilationTask(MemoryJavaFileObject file, String... options) {
|
||||
return getCompiler().getTask(null, new FileManagerWrapper(file), null, Arrays.asList(options), null, Arrays.asList(file));
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2016, 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
|
||||
@ -26,7 +26,7 @@ package jdk.test.lib;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import jdk.test.lib.process.*;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
/**
|
||||
* A utility for constructing command lines for starting JDK tool processes.
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2016, 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
|
||||
@ -31,7 +31,7 @@ public class Platform {
|
||||
private static final String osName = System.getProperty("os.name");
|
||||
private static final String dataModel = System.getProperty("sun.arch.data.model");
|
||||
private static final String vmVersion = System.getProperty("java.vm.version");
|
||||
private static final String javaVersion = System.getProperty("java.version");
|
||||
private static final String jdkDebug = System.getProperty("jdk.debug");
|
||||
private static final String osArch = System.getProperty("os.arch");
|
||||
private static final String userName = System.getProperty("user.name");
|
||||
private static final String compiler = System.getProperty("sun.management.compiler");
|
||||
@ -113,8 +113,7 @@ public class Platform {
|
||||
}
|
||||
|
||||
public static boolean isDebugBuild() {
|
||||
return (vmVersion.toLowerCase().contains("debug") ||
|
||||
javaVersion.toLowerCase().contains("debug"));
|
||||
return (jdkDebug.toLowerCase().contains("debug"));
|
||||
}
|
||||
|
||||
public static String getVMVersion() {
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2016, 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
|
||||
@ -40,7 +40,10 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -50,8 +53,9 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
|
||||
import jdk.test.lib.process.*;
|
||||
import static jdk.test.lib.Asserts.assertTrue;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
/**
|
||||
* Common library for various test helper functions.
|
||||
@ -446,6 +450,23 @@ public final class Utils {
|
||||
return iterator.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns random element of non empty array
|
||||
*
|
||||
* @param <T> a type of array element
|
||||
* @param array array of elements
|
||||
* @return random element of array
|
||||
* @throws IllegalArgumentException if array is empty
|
||||
*/
|
||||
public static <T> T getRandomElement(T[] array)
|
||||
throws IllegalArgumentException {
|
||||
if (array == null || array.length == 0) {
|
||||
throw new IllegalArgumentException("Empty or null array");
|
||||
}
|
||||
Random random = getRandomInstance();
|
||||
return array[random.nextInt(array.length)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for condition to be true
|
||||
*
|
||||
@ -636,5 +657,38 @@ public final class Utils {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Object[] getNullValues(Class<?>... types) {
|
||||
Object[] result = new Object[types.length];
|
||||
int i = 0;
|
||||
for (Class<?> type : types) {
|
||||
result[i++] = NULL_VALUES.get(type);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private static Map<Class<?>, Object> NULL_VALUES = new HashMap<>();
|
||||
static {
|
||||
NULL_VALUES.put(boolean.class, false);
|
||||
NULL_VALUES.put(byte.class, (byte) 0);
|
||||
NULL_VALUES.put(short.class, (short) 0);
|
||||
NULL_VALUES.put(char.class, '\0');
|
||||
NULL_VALUES.put(int.class, 0);
|
||||
NULL_VALUES.put(long.class, 0L);
|
||||
NULL_VALUES.put(float.class, 0.0f);
|
||||
NULL_VALUES.put(double.class, 0.0d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns mandatory property value
|
||||
* @param propName is a name of property to request
|
||||
* @return a String with requested property value
|
||||
*/
|
||||
public static String getMandatoryProperty(String propName) {
|
||||
Objects.requireNonNull(propName, "Requested null property");
|
||||
String prop = System.getProperty(propName);
|
||||
Objects.requireNonNull(prop,
|
||||
String.format("A mandatory property '%s' isn't set", propName));
|
||||
return prop;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2016, 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
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, 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 jdk.test.lib.cli;
|
||||
|
||||
import jdk.test.lib.cli.predicate.CPUSpecificPredicate;
|
||||
|
||||
/**
|
||||
* Base class for command line options tests that
|
||||
* requires specific CPU arch or specific CPU features.
|
||||
*/
|
||||
public abstract class CPUSpecificCommandLineOptionTest
|
||||
extends CommandLineOptionTest {
|
||||
/**
|
||||
* Creates new CPU specific test instance that does not
|
||||
* require any CPU features.
|
||||
*
|
||||
* @param cpuArchPattern Regular expression that should
|
||||
* match os.arch.
|
||||
*/
|
||||
public CPUSpecificCommandLineOptionTest(String cpuArchPattern) {
|
||||
this(cpuArchPattern, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new CPU specific test instance that does not
|
||||
* require from CPU support of {@code supportedCPUFeatures} features
|
||||
* and no support of {@code unsupportedCPUFeatures}.
|
||||
*
|
||||
* @param cpuArchPattern Regular expression that should
|
||||
* match os.arch.
|
||||
* @param supportedCPUFeatures Array with names of features that
|
||||
* should be supported by CPU. If {@code null},
|
||||
* then no features have to be supported.
|
||||
* @param unsupportedCPUFeatures Array with names of features that
|
||||
* should not be supported by CPU.
|
||||
* If {@code null}, then CPU may support any
|
||||
* features.
|
||||
*/
|
||||
public CPUSpecificCommandLineOptionTest(String cpuArchPattern,
|
||||
String supportedCPUFeatures[], String unsupportedCPUFeatures[]) {
|
||||
super(new CPUSpecificPredicate(cpuArchPattern, supportedCPUFeatures,
|
||||
unsupportedCPUFeatures));
|
||||
}
|
||||
}
|
524
test/lib/jdk/test/lib/cli/CommandLineOptionTest.java
Normal file
524
test/lib/jdk/test/lib/cli/CommandLineOptionTest.java
Normal file
@ -0,0 +1,524 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, 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 jdk.test.lib.cli;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
import jdk.test.lib.process.ExitCode;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.Platform;
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
/**
|
||||
* Base class for command line option tests.
|
||||
*/
|
||||
public abstract class CommandLineOptionTest {
|
||||
public static final String UNLOCK_DIAGNOSTIC_VM_OPTIONS
|
||||
= "-XX:+UnlockDiagnosticVMOptions";
|
||||
public static final String UNLOCK_EXPERIMENTAL_VM_OPTIONS
|
||||
= "-XX:+UnlockExperimentalVMOptions";
|
||||
protected static final String UNRECOGNIZED_OPTION_ERROR_FORMAT
|
||||
= "Unrecognized VM option '[+-]?%s(=.*)?'";
|
||||
protected static final String EXPERIMENTAL_OPTION_ERROR_FORMAT
|
||||
= "VM option '%s' is experimental and must be enabled via "
|
||||
+ "-XX:\\+UnlockExperimentalVMOptions.";
|
||||
protected static final String DIAGNOSTIC_OPTION_ERROR_FORMAT
|
||||
= " VM option '%s' is diagnostic and must be enabled via "
|
||||
+ "-XX:\\+UnlockDiagnosticVMOptions.";
|
||||
private static final String PRINT_FLAGS_FINAL_FORMAT = "%s\\s*:?=\\s*%s";
|
||||
|
||||
/**
|
||||
* Verifies that JVM startup behavior matches our expectations.
|
||||
*
|
||||
* @param option an option that should be passed to JVM
|
||||
* @param expectedMessages an array of patterns that should occur
|
||||
* in JVM output. If {@code null} then
|
||||
* JVM output could be empty.
|
||||
* @param unexpectedMessages an array of patterns that should not
|
||||
* occur in JVM output. If {@code null} then
|
||||
* JVM output could be empty.
|
||||
* @param exitErrorMessage message that will be shown if exit code is not
|
||||
* as expected.
|
||||
* @param wrongWarningMessage message that will be shown if warning
|
||||
* messages are not as expected.
|
||||
* @param exitCode expected exit code.
|
||||
* @throws Throwable if verification fails or some other issues occur.
|
||||
*/
|
||||
public static void verifyJVMStartup(String option,
|
||||
String expectedMessages[], String unexpectedMessages[],
|
||||
String exitErrorMessage, String wrongWarningMessage,
|
||||
ExitCode exitCode) throws Throwable {
|
||||
CommandLineOptionTest.verifyJVMStartup(expectedMessages,
|
||||
unexpectedMessages, exitErrorMessage,
|
||||
wrongWarningMessage, exitCode, false, option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that JVM startup behavior matches our expectations.
|
||||
*
|
||||
* @param expectedMessages an array of patterns that should occur
|
||||
* in JVM output. If {@code null} then
|
||||
* JVM output could be empty.
|
||||
* @param unexpectedMessages an array of patterns that should not
|
||||
* occur in JVM output. If {@code null} then
|
||||
* JVM output could be empty.
|
||||
* @param exitErrorMessage message that will be shown if exit code is not
|
||||
* as expected.
|
||||
* @param wrongWarningMessage message that will be shown if warning
|
||||
* messages are not as expected.
|
||||
* @param exitCode expected exit code.
|
||||
* @param addTestVMOptions if {@code true} then test VM options will be
|
||||
* passed to VM.
|
||||
* @param options options that should be passed to VM in addition to mode
|
||||
* flag.
|
||||
* @throws Throwable if verification fails or some other issues occur.
|
||||
*/
|
||||
public static void verifyJVMStartup(String expectedMessages[],
|
||||
String unexpectedMessages[], String exitErrorMessage,
|
||||
String wrongWarningMessage, ExitCode exitCode,
|
||||
boolean addTestVMOptions, String... options)
|
||||
throws Throwable {
|
||||
List<String> finalOptions = new ArrayList<>();
|
||||
if (addTestVMOptions) {
|
||||
Collections.addAll(finalOptions, ProcessTools.getVmInputArgs());
|
||||
Collections.addAll(finalOptions, Utils.getTestJavaOpts());
|
||||
}
|
||||
Collections.addAll(finalOptions, options);
|
||||
finalOptions.add("-version");
|
||||
|
||||
ProcessBuilder processBuilder
|
||||
= ProcessTools.createJavaProcessBuilder(finalOptions.toArray(
|
||||
new String[finalOptions.size()]));
|
||||
OutputAnalyzer outputAnalyzer
|
||||
= new OutputAnalyzer(processBuilder.start());
|
||||
|
||||
try {
|
||||
outputAnalyzer.shouldHaveExitValue(exitCode.value);
|
||||
} catch (RuntimeException e) {
|
||||
String errorMessage = String.format(
|
||||
"JVM process should have exit value '%d'.%n%s",
|
||||
exitCode.value, exitErrorMessage);
|
||||
throw new AssertionError(errorMessage, e);
|
||||
}
|
||||
|
||||
verifyOutput(expectedMessages, unexpectedMessages,
|
||||
wrongWarningMessage, outputAnalyzer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that JVM startup behavior matches our expectations.
|
||||
*
|
||||
* @param expectedMessages an array of patterns that should occur in JVM
|
||||
* output. If {@code null} then
|
||||
* JVM output could be empty.
|
||||
* @param unexpectedMessages an array of patterns that should not occur
|
||||
* in JVM output. If {@code null} then
|
||||
* JVM output could be empty.
|
||||
* @param wrongWarningMessage message that will be shown if messages are
|
||||
* not as expected.
|
||||
* @param outputAnalyzer OutputAnalyzer instance
|
||||
* @throws AssertionError if verification fails.
|
||||
*/
|
||||
public static void verifyOutput(String[] expectedMessages,
|
||||
String[] unexpectedMessages, String wrongWarningMessage,
|
||||
OutputAnalyzer outputAnalyzer) {
|
||||
if (expectedMessages != null) {
|
||||
for (String expectedMessage : expectedMessages) {
|
||||
try {
|
||||
outputAnalyzer.shouldMatch(expectedMessage);
|
||||
} catch (RuntimeException e) {
|
||||
String errorMessage = String.format(
|
||||
"Expected message not found: '%s'.%n%s",
|
||||
expectedMessage, wrongWarningMessage);
|
||||
throw new AssertionError(errorMessage, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (unexpectedMessages != null) {
|
||||
for (String unexpectedMessage : unexpectedMessages) {
|
||||
try {
|
||||
outputAnalyzer.shouldNotMatch(unexpectedMessage);
|
||||
} catch (RuntimeException e) {
|
||||
String errorMessage = String.format(
|
||||
"Unexpected message found: '%s'.%n%s",
|
||||
unexpectedMessage, wrongWarningMessage);
|
||||
throw new AssertionError(errorMessage, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that JVM startup behavior matches our expectations when type
|
||||
* of newly started VM is the same as the type of current.
|
||||
*
|
||||
* @param expectedMessages an array of patterns that should occur
|
||||
* in JVM output. If {@code null} then
|
||||
* JVM output could be empty.
|
||||
* @param unexpectedMessages an array of patterns that should not
|
||||
* occur in JVM output. If {@code null} then
|
||||
* JVM output could be empty.
|
||||
* @param exitErrorMessage Message that will be shown if exit value is not
|
||||
* as expected.
|
||||
* @param wrongWarningMessage message that will be shown if warning
|
||||
* messages are not as expected.
|
||||
* @param exitCode expected exit code.
|
||||
* @param options options that should be passed to VM in addition to mode
|
||||
* flag.
|
||||
* @throws Throwable if verification fails or some other issues occur.
|
||||
*/
|
||||
public static void verifySameJVMStartup(String expectedMessages[],
|
||||
String unexpectedMessages[], String exitErrorMessage,
|
||||
String wrongWarningMessage, ExitCode exitCode, String... options)
|
||||
throws Throwable {
|
||||
List<String> finalOptions = new ArrayList<>();
|
||||
finalOptions.add(CommandLineOptionTest.getVMTypeOption());
|
||||
Collections.addAll(finalOptions, options);
|
||||
|
||||
CommandLineOptionTest.verifyJVMStartup(expectedMessages,
|
||||
unexpectedMessages, exitErrorMessage,
|
||||
wrongWarningMessage, exitCode, false,
|
||||
finalOptions.toArray(new String[finalOptions.size()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that value of specified JVM option is the same as
|
||||
* expected value.
|
||||
* This method filter out option with {@code optionName}
|
||||
* name from test java options.
|
||||
*
|
||||
* @param optionName a name of tested option.
|
||||
* @param expectedValue expected value of tested option.
|
||||
* @param optionErrorString message will be shown if option value is not as
|
||||
* expected.
|
||||
* @param additionalVMOpts additional options that should be
|
||||
* passed to JVM.
|
||||
* @throws Throwable if verification fails or some other issues occur.
|
||||
*/
|
||||
public static void verifyOptionValue(String optionName,
|
||||
String expectedValue, String optionErrorString,
|
||||
String... additionalVMOpts) throws Throwable {
|
||||
verifyOptionValue(optionName, expectedValue, optionErrorString,
|
||||
true, additionalVMOpts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that value of specified JVM option is the same as
|
||||
* expected value.
|
||||
* This method filter out option with {@code optionName}
|
||||
* name from test java options.
|
||||
*
|
||||
* @param optionName a name of tested option.
|
||||
* @param expectedValue expected value of tested option.
|
||||
* @param addTestVmOptions if {@code true}, then test VM options
|
||||
* will be used.
|
||||
* @param optionErrorString message will be shown if option value is not as
|
||||
* expected.
|
||||
* @param additionalVMOpts additional options that should be
|
||||
* passed to JVM.
|
||||
* @throws Throwable if verification fails or some other issues
|
||||
* occur.
|
||||
*/
|
||||
public static void verifyOptionValue(String optionName,
|
||||
String expectedValue, String optionErrorString,
|
||||
boolean addTestVmOptions, String... additionalVMOpts)
|
||||
throws Throwable {
|
||||
List<String> vmOpts = new ArrayList<>();
|
||||
|
||||
if (addTestVmOptions) {
|
||||
Collections.addAll(vmOpts,
|
||||
Utils.getFilteredTestJavaOpts(optionName));
|
||||
}
|
||||
Collections.addAll(vmOpts, additionalVMOpts);
|
||||
Collections.addAll(vmOpts, "-XX:+PrintFlagsFinal", "-version");
|
||||
|
||||
ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
|
||||
vmOpts.toArray(new String[vmOpts.size()]));
|
||||
|
||||
OutputAnalyzer outputAnalyzer
|
||||
= new OutputAnalyzer(processBuilder.start());
|
||||
|
||||
try {
|
||||
outputAnalyzer.shouldHaveExitValue(0);
|
||||
} catch (RuntimeException e) {
|
||||
String errorMessage = String.format(
|
||||
"JVM should start with option '%s' without errors.",
|
||||
optionName);
|
||||
throw new AssertionError(errorMessage, e);
|
||||
}
|
||||
verifyOptionValue(optionName, expectedValue, optionErrorString,
|
||||
outputAnalyzer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that value of specified JVM option is the same as
|
||||
* expected value.
|
||||
*
|
||||
* @param optionName a name of tested option.
|
||||
* @param expectedValue expected value of tested option.
|
||||
* @param optionErrorString message will be shown if option value is not
|
||||
* as expected.
|
||||
* @param outputAnalyzer OutputAnalyzer instance
|
||||
* @throws AssertionError if verification fails
|
||||
*/
|
||||
public static void verifyOptionValue(String optionName,
|
||||
String expectedValue, String optionErrorString,
|
||||
OutputAnalyzer outputAnalyzer) {
|
||||
try {
|
||||
outputAnalyzer.shouldMatch(String.format(
|
||||
CommandLineOptionTest.PRINT_FLAGS_FINAL_FORMAT,
|
||||
optionName, expectedValue));
|
||||
} catch (RuntimeException e) {
|
||||
String errorMessage = String.format(
|
||||
"Option '%s' is expected to have '%s' value%n%s",
|
||||
optionName, expectedValue,
|
||||
optionErrorString);
|
||||
throw new AssertionError(errorMessage, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start VM with given options and values.
|
||||
* Generates command line option flags from
|
||||
* {@code optionNames} and {@code optionValues}.
|
||||
*
|
||||
* @param optionNames names of options to pass in
|
||||
* @param optionValues values of option
|
||||
* @param additionalVMOpts additional options that should be
|
||||
* passed to JVM.
|
||||
* @return output from vm process
|
||||
*/
|
||||
public static OutputAnalyzer startVMWithOptions(String[] optionNames,
|
||||
String[] optionValues,
|
||||
String... additionalVMOpts) throws Throwable {
|
||||
List<String> vmOpts = new ArrayList<>();
|
||||
if (optionNames == null || optionValues == null || optionNames.length != optionValues.length) {
|
||||
throw new IllegalArgumentException("optionNames and/or optionValues");
|
||||
}
|
||||
|
||||
for (int i = 0; i < optionNames.length; i++) {
|
||||
vmOpts.add(prepareFlag(optionNames[i], optionValues[i]));
|
||||
}
|
||||
Collections.addAll(vmOpts, additionalVMOpts);
|
||||
Collections.addAll(vmOpts, "-version");
|
||||
|
||||
ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
|
||||
vmOpts.toArray(new String[vmOpts.size()]));
|
||||
|
||||
return new OutputAnalyzer(processBuilder.start());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies from the output that values of specified JVM options were the same as
|
||||
* expected values.
|
||||
*
|
||||
* @param outputAnalyzer search output for expect options and values.
|
||||
* @param optionNames names of tested options.
|
||||
* @param expectedValues expected values of tested options.
|
||||
* @throws Throwable if verification fails or some other issues occur.
|
||||
*/
|
||||
public static void verifyOptionValuesFromOutput(OutputAnalyzer outputAnalyzer,
|
||||
String[] optionNames,
|
||||
String[] expectedValues) throws Throwable {
|
||||
outputAnalyzer.shouldHaveExitValue(0);
|
||||
for (int i = 0; i < optionNames.length; i++) {
|
||||
outputAnalyzer.shouldMatch(String.format(
|
||||
CommandLineOptionTest.PRINT_FLAGS_FINAL_FORMAT,
|
||||
optionNames[i], expectedValues[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that value of specified JVM options are the same as
|
||||
* expected values.
|
||||
* Generates command line option flags from
|
||||
* {@code optionNames} and {@code expectedValues}.
|
||||
*
|
||||
* @param optionNames names of tested options.
|
||||
* @param expectedValues expected values of tested options.
|
||||
* @throws Throwable if verification fails or some other issues occur.
|
||||
*/
|
||||
public static void verifyOptionValues(String[] optionNames,
|
||||
String[] expectedValues) throws Throwable {
|
||||
OutputAnalyzer outputAnalyzer = startVMWithOptions(optionNames, expectedValues, "-XX:+PrintFlagsFinal");
|
||||
verifyOptionValuesFromOutput(outputAnalyzer, optionNames, expectedValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that value of specified JVM when type of newly started VM
|
||||
* is the same as the type of current.
|
||||
* This method filter out option with {@code optionName}
|
||||
* name from test java options.
|
||||
* Only mode flag will be passed to VM in addition to
|
||||
* {@code additionalVMOpts}
|
||||
*
|
||||
* @param optionName name of tested option.
|
||||
* @param expectedValue expected value of tested option.
|
||||
* @param optionErrorString message to show if option has another value
|
||||
* @param additionalVMOpts additional options that should be
|
||||
* passed to JVM.
|
||||
* @throws Throwable if verification fails or some other issues occur.
|
||||
*/
|
||||
public static void verifyOptionValueForSameVM(String optionName,
|
||||
String expectedValue, String optionErrorString,
|
||||
String... additionalVMOpts) throws Throwable {
|
||||
List<String> finalOptions = new ArrayList<>();
|
||||
finalOptions.add(CommandLineOptionTest.getVMTypeOption());
|
||||
Collections.addAll(finalOptions, additionalVMOpts);
|
||||
|
||||
CommandLineOptionTest.verifyOptionValue(optionName, expectedValue,
|
||||
optionErrorString, false,
|
||||
finalOptions.toArray(new String[finalOptions.size()]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares boolean command line flag with name {@code name} according
|
||||
* to it's {@code value}.
|
||||
*
|
||||
* @param name the name of option to be prepared
|
||||
* @param value the value of option
|
||||
* @return prepared command line flag
|
||||
*/
|
||||
public static String prepareBooleanFlag(String name, boolean value) {
|
||||
return String.format("-XX:%c%s", (value ? '+' : '-'), name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares numeric command line flag with name {@code name} by setting
|
||||
* it's value to {@code value}.
|
||||
*
|
||||
* @param name the name of option to be prepared
|
||||
* @param value the value of option
|
||||
* @return prepared command line flag
|
||||
*/
|
||||
public static String prepareNumericFlag(String name, Number value) {
|
||||
return String.format("-XX:%s=%s", name, value.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares generic command line flag with name {@code name} by setting
|
||||
* it's value to {@code value}.
|
||||
*
|
||||
* @param name the name of option to be prepared
|
||||
* @param value the value of option ("+" or "-" can be used instead of "true" or "false")
|
||||
* @return prepared command line flag
|
||||
*/
|
||||
public static String prepareFlag(String name, String value) {
|
||||
if (value.equals("+") || value.equalsIgnoreCase("true")) {
|
||||
return "-XX:+" + name;
|
||||
} else if (value.equals("-") || value.equalsIgnoreCase("false")) {
|
||||
return "-XX:-" + name;
|
||||
} else {
|
||||
return "-XX:" + name + "=" + value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns message that should occur in VM output if option
|
||||
* {@code optionName} if unrecognized.
|
||||
*
|
||||
* @param optionName the name of option for which message should be returned
|
||||
* @return message saying that option {@code optionName} is unrecognized
|
||||
*/
|
||||
public static String getUnrecognizedOptionErrorMessage(String optionName) {
|
||||
return String.format(
|
||||
CommandLineOptionTest.UNRECOGNIZED_OPTION_ERROR_FORMAT,
|
||||
optionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns message that should occur in VM output if option
|
||||
* {@code optionName} is experimental and
|
||||
* -XX:+UnlockExperimentalVMOptions was not passed to VM.
|
||||
*
|
||||
* @param optionName the name of option for which message should be returned
|
||||
* @return message saying that option {@code optionName} is experimental
|
||||
*/
|
||||
public static String getExperimentalOptionErrorMessage(String optionName) {
|
||||
return String.format(
|
||||
CommandLineOptionTest.EXPERIMENTAL_OPTION_ERROR_FORMAT,
|
||||
optionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns message that should occur in VM output if option
|
||||
* {@code optionName} is diagnostic and -XX:+UnlockDiagnosticVMOptions
|
||||
* was not passed to VM.
|
||||
*
|
||||
* @param optionName the name of option for which message should be returned
|
||||
* @return message saying that option {@code optionName} is diganostic
|
||||
*/
|
||||
public static String getDiagnosticOptionErrorMessage(String optionName) {
|
||||
return String.format(
|
||||
CommandLineOptionTest.DIAGNOSTIC_OPTION_ERROR_FORMAT,
|
||||
optionName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return option required to start a new VM with the same type as current.
|
||||
* @throws RuntimeException when VM type is unknown.
|
||||
*/
|
||||
private static String getVMTypeOption() {
|
||||
if (Platform.isServer()) {
|
||||
return "-server";
|
||||
} else if (Platform.isClient()) {
|
||||
return "-client";
|
||||
} else if (Platform.isMinimal()) {
|
||||
return "-minimal";
|
||||
} else if (Platform.isGraal()) {
|
||||
return "-graal";
|
||||
}
|
||||
throw new RuntimeException("Unknown VM mode.");
|
||||
}
|
||||
|
||||
private final BooleanSupplier predicate;
|
||||
|
||||
/**
|
||||
* Constructs new CommandLineOptionTest that will be executed only if
|
||||
* predicate {@code predicate} return {@code true}.
|
||||
* @param predicate a predicate responsible for test's preconditions check.
|
||||
*/
|
||||
public CommandLineOptionTest(BooleanSupplier predicate) {
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs command line option test.
|
||||
*/
|
||||
public final void test() throws Throwable {
|
||||
if (predicate.getAsBoolean()) {
|
||||
runTestCases();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Throwable if some issue happened during test cases execution.
|
||||
*/
|
||||
protected abstract void runTestCases() throws Throwable;
|
||||
}
|
41
test/lib/jdk/test/lib/cli/predicate/AndPredicate.java
Normal file
41
test/lib/jdk/test/lib/cli/predicate/AndPredicate.java
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, 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 jdk.test.lib.cli.predicate;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
public class AndPredicate implements BooleanSupplier {
|
||||
private final BooleanSupplier a;
|
||||
private final BooleanSupplier b;
|
||||
|
||||
public AndPredicate(BooleanSupplier a, BooleanSupplier b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAsBoolean() {
|
||||
return a.getAsBoolean() && b.getAsBoolean();
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, 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 jdk.test.lib.cli.predicate;
|
||||
|
||||
import jdk.test.lib.Platform;
|
||||
import sun.hotspot.cpuinfo.CPUInfo;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
public class CPUSpecificPredicate implements BooleanSupplier {
|
||||
private final String cpuArchPattern;
|
||||
private final String supportedCPUFeatures[];
|
||||
private final String unsupportedCPUFeatures[];
|
||||
|
||||
public CPUSpecificPredicate(String cpuArchPattern,
|
||||
String supportedCPUFeatures[],
|
||||
String unsupportedCPUFeatures[]) {
|
||||
this.cpuArchPattern = cpuArchPattern;
|
||||
this.supportedCPUFeatures = supportedCPUFeatures;
|
||||
this.unsupportedCPUFeatures = unsupportedCPUFeatures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAsBoolean() {
|
||||
if (!Platform.getOsArch().matches(cpuArchPattern)) {
|
||||
System.out.println("CPU arch " + Platform.getOsArch() + " does not match " + cpuArchPattern);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (supportedCPUFeatures != null) {
|
||||
for (String feature : supportedCPUFeatures) {
|
||||
if (!CPUInfo.hasFeature(feature)) {
|
||||
System.out.println("CPU does not support " + feature
|
||||
+ " feature");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (unsupportedCPUFeatures != null) {
|
||||
for (String feature : unsupportedCPUFeatures) {
|
||||
if (CPUInfo.hasFeature(feature)) {
|
||||
System.out.println("CPU support " + feature + " feature");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
40
test/lib/jdk/test/lib/cli/predicate/NotPredicate.java
Normal file
40
test/lib/jdk/test/lib/cli/predicate/NotPredicate.java
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, 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 jdk.test.lib.cli.predicate;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
public class NotPredicate implements BooleanSupplier {
|
||||
private final BooleanSupplier s;
|
||||
|
||||
public NotPredicate(BooleanSupplier s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAsBoolean() {
|
||||
return !s.getAsBoolean();
|
||||
}
|
||||
}
|
42
test/lib/jdk/test/lib/cli/predicate/OrPredicate.java
Normal file
42
test/lib/jdk/test/lib/cli/predicate/OrPredicate.java
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, 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 jdk.test.lib.cli.predicate;
|
||||
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
public class OrPredicate implements BooleanSupplier {
|
||||
private final BooleanSupplier a;
|
||||
private final BooleanSupplier b;
|
||||
|
||||
public OrPredicate(BooleanSupplier a, BooleanSupplier b) {
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getAsBoolean() {
|
||||
return a.getAsBoolean() || b.getAsBoolean();
|
||||
}
|
||||
}
|
75
test/lib/jdk/test/lib/dcmd/CommandExecutor.java
Normal file
75
test/lib/jdk/test/lib/dcmd/CommandExecutor.java
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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 jdk.test.lib.dcmd;
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
/**
|
||||
* Abstract base class for Diagnostic Command executors
|
||||
*/
|
||||
public abstract class CommandExecutor {
|
||||
|
||||
/**
|
||||
* Execute a diagnostic command
|
||||
*
|
||||
* @param cmd The diagnostic command to execute
|
||||
* @return an {@link jdk.testlibrary.OutputAnalyzer} encapsulating the output of the command
|
||||
* @throws CommandExecutorException if there is an exception on the "calling side" while trying to execute the
|
||||
* Diagnostic Command. Exceptions thrown on the remote side are available as textual representations in
|
||||
* stderr, regardless of the specific executor used.
|
||||
*/
|
||||
public final OutputAnalyzer execute(String cmd) throws CommandExecutorException {
|
||||
return execute(cmd, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a diagnostic command
|
||||
*
|
||||
* @param cmd The diagnostic command to execute
|
||||
* @param silent Do not print the command output
|
||||
* @return an {@link jdk.testlibrary.OutputAnalyzer} encapsulating the output of the command
|
||||
* @throws CommandExecutorException if there is an exception on the "calling side" while trying to execute the
|
||||
* Diagnostic Command. Exceptions thrown on the remote side are available as textual representations in
|
||||
* stderr, regardless of the specific executor used.
|
||||
*/
|
||||
public final OutputAnalyzer execute(String cmd, boolean silent) throws CommandExecutorException {
|
||||
if (!silent) {
|
||||
System.out.printf("Running DCMD '%s' through '%s'%n", cmd, this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
OutputAnalyzer oa = executeImpl(cmd);
|
||||
|
||||
if (!silent) {
|
||||
System.out.println("---------------- stdout ----------------");
|
||||
System.out.println(oa.getStdout());
|
||||
System.out.println("---------------- stderr ----------------");
|
||||
System.out.println(oa.getStderr());
|
||||
System.out.println("----------------------------------------");
|
||||
System.out.println();
|
||||
}
|
||||
return oa;
|
||||
}
|
||||
|
||||
protected abstract OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException;
|
||||
}
|
36
test/lib/jdk/test/lib/dcmd/CommandExecutorException.java
Normal file
36
test/lib/jdk/test/lib/dcmd/CommandExecutorException.java
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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 jdk.test.lib.dcmd;
|
||||
|
||||
/**
|
||||
* CommandExecutorException encapsulates exceptions thrown (on the "calling side") from the execution of Diagnostic
|
||||
* Commands
|
||||
*/
|
||||
public class CommandExecutorException extends RuntimeException {
|
||||
private static final long serialVersionUID = -7039597746579144280L;
|
||||
|
||||
public CommandExecutorException(String message, Throwable e) {
|
||||
super(message, e);
|
||||
}
|
||||
}
|
81
test/lib/jdk/test/lib/dcmd/FileJcmdExecutor.java
Normal file
81
test/lib/jdk/test/lib/dcmd/FileJcmdExecutor.java
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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 jdk.test.lib.dcmd;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Executes Diagnostic Commands on the target VM (specified by pid) using the jcmd tool and its ability to read
|
||||
* Diagnostic Commands from a file.
|
||||
*/
|
||||
public class FileJcmdExecutor extends PidJcmdExecutor {
|
||||
|
||||
/**
|
||||
* Instantiates a new FileJcmdExecutor targeting the current VM
|
||||
*/
|
||||
public FileJcmdExecutor() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new FileJcmdExecutor targeting the VM indicated by the given pid
|
||||
*
|
||||
* @param target Pid of the target VM
|
||||
*/
|
||||
public FileJcmdExecutor(String target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
protected List<String> createCommandLine(String cmd) throws CommandExecutorException {
|
||||
File cmdFile = createTempFile();
|
||||
writeCommandToTemporaryFile(cmd, cmdFile);
|
||||
|
||||
return Arrays.asList(jcmdBinary, Long.toString(pid),
|
||||
"-f", cmdFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
private void writeCommandToTemporaryFile(String cmd, File cmdFile) {
|
||||
try (PrintWriter pw = new PrintWriter(cmdFile)) {
|
||||
pw.println(cmd);
|
||||
} catch (IOException e) {
|
||||
String message = "Could not write to file: " + cmdFile.getAbsolutePath();
|
||||
throw new CommandExecutorException(message, e);
|
||||
}
|
||||
}
|
||||
|
||||
private File createTempFile() {
|
||||
try {
|
||||
File cmdFile = File.createTempFile("input", "jcmd");
|
||||
cmdFile.deleteOnExit();
|
||||
return cmdFile;
|
||||
} catch (IOException e) {
|
||||
throw new CommandExecutorException("Could not create temporary file", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
187
test/lib/jdk/test/lib/dcmd/JMXExecutor.java
Normal file
187
test/lib/jdk/test/lib/dcmd/JMXExecutor.java
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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 jdk.test.lib.dcmd;
|
||||
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
import javax.management.*;
|
||||
import javax.management.remote.JMXConnector;
|
||||
import javax.management.remote.JMXConnectorFactory;
|
||||
import javax.management.remote.JMXServiceURL;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Executes Diagnostic Commands on the target VM (specified by a host/port combination or a full JMX Service URL) using
|
||||
* the JMX interface. If the target is not the current VM, the JMX Remote interface must be enabled beforehand.
|
||||
*/
|
||||
public class JMXExecutor extends CommandExecutor {
|
||||
|
||||
private final MBeanServerConnection mbs;
|
||||
|
||||
/**
|
||||
* Instantiates a new JMXExecutor targeting the current VM
|
||||
*/
|
||||
public JMXExecutor() {
|
||||
super();
|
||||
mbs = ManagementFactory.getPlatformMBeanServer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new JMXExecutor targeting the VM indicated by the given host/port combination or a full JMX
|
||||
* Service URL
|
||||
*
|
||||
* @param target a host/port combination on the format "host:port" or a full JMX Service URL of the target VM
|
||||
*/
|
||||
public JMXExecutor(String target) {
|
||||
String urlStr;
|
||||
|
||||
if (target.matches("^\\w[\\w\\-]*(\\.[\\w\\-]+)*:\\d+$")) {
|
||||
/* Matches "hostname:port" */
|
||||
urlStr = String.format("service:jmx:rmi:///jndi/rmi://%s/jmxrmi", target);
|
||||
} else if (target.startsWith("service:")) {
|
||||
urlStr = target;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Could not recognize target string: " + target);
|
||||
}
|
||||
|
||||
try {
|
||||
JMXServiceURL url = new JMXServiceURL(urlStr);
|
||||
JMXConnector c = JMXConnectorFactory.connect(url, new HashMap<>());
|
||||
mbs = c.getMBeanServerConnection();
|
||||
} catch (IOException e) {
|
||||
throw new CommandExecutorException("Could not initiate connection to target: " + target, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException {
|
||||
String stdout = "";
|
||||
String stderr = "";
|
||||
|
||||
String[] cmdParts = cmd.split(" ", 2);
|
||||
String operation = commandToMethodName(cmdParts[0]);
|
||||
Object[] dcmdArgs = produceArguments(cmdParts);
|
||||
String[] signature = {String[].class.getName()};
|
||||
|
||||
ObjectName beanName = getMBeanName();
|
||||
|
||||
try {
|
||||
stdout = (String) mbs.invoke(beanName, operation, dcmdArgs, signature);
|
||||
}
|
||||
|
||||
/* Failures on the "local" side, the one invoking the command. */
|
||||
catch (ReflectionException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof NoSuchMethodException) {
|
||||
/* We want JMXExecutor to match the behavior of the other CommandExecutors */
|
||||
String message = "Unknown diagnostic command: " + operation;
|
||||
stderr = exceptionTraceAsString(new IllegalArgumentException(message, e));
|
||||
} else {
|
||||
rethrowExecutorException(operation, dcmdArgs, e);
|
||||
}
|
||||
}
|
||||
|
||||
/* Failures on the "local" side, the one invoking the command. */
|
||||
catch (InstanceNotFoundException | IOException e) {
|
||||
rethrowExecutorException(operation, dcmdArgs, e);
|
||||
}
|
||||
|
||||
/* Failures on the remote side, the one executing the invoked command. */
|
||||
catch (MBeanException e) {
|
||||
stdout = exceptionTraceAsString(e);
|
||||
}
|
||||
|
||||
return new OutputAnalyzer(stdout, stderr);
|
||||
}
|
||||
|
||||
private void rethrowExecutorException(String operation, Object[] dcmdArgs,
|
||||
Exception e) throws CommandExecutorException {
|
||||
String message = String.format("Could not invoke: %s %s", operation,
|
||||
String.join(" ", (String[]) dcmdArgs[0]));
|
||||
throw new CommandExecutorException(message, e);
|
||||
}
|
||||
|
||||
private ObjectName getMBeanName() throws CommandExecutorException {
|
||||
String MBeanName = "com.sun.management:type=DiagnosticCommand";
|
||||
|
||||
try {
|
||||
return new ObjectName(MBeanName);
|
||||
} catch (MalformedObjectNameException e) {
|
||||
String message = "MBean not found: " + MBeanName;
|
||||
throw new CommandExecutorException(message, e);
|
||||
}
|
||||
}
|
||||
|
||||
private Object[] produceArguments(String[] cmdParts) {
|
||||
Object[] dcmdArgs = {new String[0]}; /* Default: No arguments */
|
||||
|
||||
if (cmdParts.length == 2) {
|
||||
dcmdArgs[0] = cmdParts[1].split(" ");
|
||||
}
|
||||
return dcmdArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from diagnostic command to MBean method name
|
||||
*
|
||||
* Examples:
|
||||
* help --> help
|
||||
* VM.version --> vmVersion
|
||||
* VM.command_line --> vmCommandLine
|
||||
*/
|
||||
private static String commandToMethodName(String cmd) {
|
||||
String operation = "";
|
||||
boolean up = false; /* First letter is to be lower case */
|
||||
|
||||
/*
|
||||
* If a '.' or '_' is encountered it is not copied,
|
||||
* instead the next character will be converted to upper case
|
||||
*/
|
||||
for (char c : cmd.toCharArray()) {
|
||||
if (('.' == c) || ('_' == c)) {
|
||||
up = true;
|
||||
} else if (up) {
|
||||
operation = operation.concat(Character.toString(c).toUpperCase());
|
||||
up = false;
|
||||
} else {
|
||||
operation = operation.concat(Character.toString(c).toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
private static String exceptionTraceAsString(Throwable cause) {
|
||||
StringWriter sw = new StringWriter();
|
||||
cause.printStackTrace(new PrintWriter(sw));
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
}
|
58
test/lib/jdk/test/lib/dcmd/JcmdExecutor.java
Normal file
58
test/lib/jdk/test/lib/dcmd/JcmdExecutor.java
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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 jdk.test.lib.dcmd;
|
||||
|
||||
import jdk.test.lib.JDKToolFinder;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Base class for Diagnostic Command Executors using the jcmd tool
|
||||
*/
|
||||
public abstract class JcmdExecutor extends CommandExecutor {
|
||||
protected String jcmdBinary;
|
||||
|
||||
protected abstract List<String> createCommandLine(String cmd) throws CommandExecutorException;
|
||||
|
||||
protected JcmdExecutor() {
|
||||
jcmdBinary = JDKToolFinder.getJDKTool("jcmd");
|
||||
}
|
||||
|
||||
protected OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException {
|
||||
List<String> commandLine = createCommandLine(cmd);
|
||||
|
||||
try {
|
||||
System.out.printf("Executing command '%s'%n", commandLine);
|
||||
OutputAnalyzer output = ProcessTools.executeProcess(new ProcessBuilder(commandLine));
|
||||
System.out.printf("Command returned with exit code %d%n", output.getExitValue());
|
||||
|
||||
return output;
|
||||
} catch (Exception e) {
|
||||
String message = String.format("Caught exception while executing '%s'", commandLine);
|
||||
throw new CommandExecutorException(message, e);
|
||||
}
|
||||
}
|
||||
}
|
57
test/lib/jdk/test/lib/dcmd/MainClassJcmdExecutor.java
Normal file
57
test/lib/jdk/test/lib/dcmd/MainClassJcmdExecutor.java
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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 jdk.test.lib.dcmd;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Executes Diagnostic Commands on the target VM (specified by main class) using the jcmd tool
|
||||
*/
|
||||
public class MainClassJcmdExecutor extends JcmdExecutor {
|
||||
private final String mainClass;
|
||||
|
||||
/**
|
||||
* Instantiates a new MainClassJcmdExecutor targeting the current VM
|
||||
*/
|
||||
public MainClassJcmdExecutor() {
|
||||
super();
|
||||
mainClass = System.getProperty("sun.java.command").split(" ")[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new MainClassJcmdExecutor targeting the VM indicated by the given main class
|
||||
*
|
||||
* @param target Main class of the target VM
|
||||
*/
|
||||
public MainClassJcmdExecutor(String target) {
|
||||
super();
|
||||
mainClass = target;
|
||||
}
|
||||
|
||||
protected List<String> createCommandLine(String cmd) throws CommandExecutorException {
|
||||
return Arrays.asList(jcmdBinary, mainClass, cmd);
|
||||
}
|
||||
|
||||
}
|
63
test/lib/jdk/test/lib/dcmd/PidJcmdExecutor.java
Normal file
63
test/lib/jdk/test/lib/dcmd/PidJcmdExecutor.java
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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 jdk.test.lib.dcmd;
|
||||
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Executes Diagnostic Commands on the target VM (specified by pid) using the jcmd tool
|
||||
*/
|
||||
public class PidJcmdExecutor extends JcmdExecutor {
|
||||
protected final long pid;
|
||||
|
||||
/**
|
||||
* Instantiates a new PidJcmdExecutor targeting the current VM
|
||||
*/
|
||||
public PidJcmdExecutor() {
|
||||
super();
|
||||
try {
|
||||
pid = ProcessTools.getProcessId();
|
||||
} catch (Exception e) {
|
||||
throw new CommandExecutorException("Could not determine own pid", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new PidJcmdExecutor targeting the VM indicated by the given pid
|
||||
*
|
||||
* @param target Pid of the target VM
|
||||
*/
|
||||
public PidJcmdExecutor(String target) {
|
||||
super();
|
||||
pid = Long.valueOf(target);
|
||||
}
|
||||
|
||||
protected List<String> createCommandLine(String cmd) throws CommandExecutorException {
|
||||
return Arrays.asList(jcmdBinary, Long.toString(pid), cmd);
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2016, 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
|
40
test/lib/jdk/test/lib/process/ExitCode.java
Normal file
40
test/lib/jdk/test/lib/process/ExitCode.java
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, 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 jdk.test.lib.process;
|
||||
|
||||
/**
|
||||
* Exit code values that could be returned by the JVM.
|
||||
*/
|
||||
public enum ExitCode {
|
||||
OK(0),
|
||||
FAIL(1),
|
||||
CRASH(134);
|
||||
|
||||
public final int value;
|
||||
|
||||
ExitCode(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2016, 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
|
||||
@ -374,14 +374,14 @@ public final class OutputAnalyzer {
|
||||
* - exit code
|
||||
* Note: the command line is printed by the ProcessTools
|
||||
*/
|
||||
private void reportDiagnosticSummary() {
|
||||
String msg =
|
||||
" stdout: [" + stdout + "];\n" +
|
||||
" stderr: [" + stderr + "]\n" +
|
||||
" exitValue = " + getExitValue() + "\n";
|
||||
public void reportDiagnosticSummary() {
|
||||
String msg =
|
||||
" stdout: [" + stdout + "];\n" +
|
||||
" stderr: [" + stderr + "]\n" +
|
||||
" exitValue = " + getExitValue() + "\n";
|
||||
|
||||
System.err.println(msg);
|
||||
}
|
||||
System.err.println(msg);
|
||||
}
|
||||
|
||||
|
||||
/**
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2016, 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
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2016, 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
|
||||
@ -28,10 +28,13 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
@ -301,6 +304,16 @@ public final class ProcessTools {
|
||||
public static long getProcessId() throws Exception {
|
||||
return ProcessHandle.current().getPid();
|
||||
}
|
||||
/**
|
||||
* Gets the array of strings containing input arguments passed to the VM
|
||||
*
|
||||
* @return arguments
|
||||
*/
|
||||
public static String[] getVmInputArgs() {
|
||||
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
|
||||
List<String> args = runtime.getInputArguments();
|
||||
return args.toArray(new String[args.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get platform specific VM arguments (e.g. -d64 on 64bit Solaris)
|
||||
@ -342,16 +355,10 @@ public final class ProcessTools {
|
||||
args.add(javapath);
|
||||
Collections.addAll(args, getPlatformSpecificVMArgs());
|
||||
|
||||
args.add("-cp");
|
||||
args.add(System.getProperty("java.class.path"));
|
||||
|
||||
if (addTestVmAndJavaOptions) {
|
||||
// -cp is needed to make sure the same classpath is used whether the test is
|
||||
// run in AgentVM mode or OtherVM mode. It was added to the hotspot version
|
||||
// of this API as part of 8077608. However, for the jdk version it is only
|
||||
// added when addTestVmAndJavaOptions is true in order to minimize
|
||||
// disruption to existing JDK tests, which have yet to be tested with -cp
|
||||
// being added. At some point -cp should always be added to be consistent
|
||||
// with what the hotspot version does.
|
||||
args.add("-cp");
|
||||
args.add(System.getProperty("java.class.path"));
|
||||
Collections.addAll(args, Utils.getTestJavaOpts());
|
||||
}
|
||||
|
||||
@ -377,6 +384,26 @@ public final class ProcessTools {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a test jvm process, waits for it to finish and returns the process output.
|
||||
* The default jvm options from the test's run command, jtreg, test.vm.opts and test.java.opts, are added.
|
||||
* The java from the test.jdk is used to execute the command.
|
||||
*
|
||||
* The command line will be like:
|
||||
* {test.jdk}/bin/java {test.fromRun.opts} {test.vm.opts} {test.java.opts} cmds
|
||||
*
|
||||
* @param cmds User specifed arguments.
|
||||
* @return The output from the process.
|
||||
*/
|
||||
public static OutputAnalyzer executeTestJvmAllArgs(String... cmds) throws Throwable {
|
||||
List<String> argsList = new ArrayList<>();
|
||||
String[] testArgs = getVmInputArgs();
|
||||
Collections.addAll(argsList, testArgs);
|
||||
Collections.addAll(argsList, Utils.addTestJavaOpts(cmds));
|
||||
ProcessBuilder pb = createJavaProcessBuilder(argsList.toArray(new String[argsList.size()]));
|
||||
return executeProcess(pb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a test jvm process, waits for it to finish and returns the process output.
|
||||
* The default jvm options from jtreg, test.vm.opts and test.java.opts, are added.
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2016, 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
test/lib/jdk/test/lib/util/Pair.java
Normal file
68
test/lib/jdk/test/lib/util/Pair.java
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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 jdk.test.lib.util;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Pair - a two element tuple
|
||||
*
|
||||
* @param <F> first type
|
||||
* @param <S> second type
|
||||
*/
|
||||
public class Pair<F, S> {
|
||||
public final F first;
|
||||
public final S second;
|
||||
|
||||
public Pair(F first, S second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + first + ":" + second + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other instanceof Pair<?, ?>) {
|
||||
Pair<?, ?> otherPair = (Pair<?, ?>) other;
|
||||
return Objects.equals(first, otherPair.first) &&
|
||||
Objects.equals(second, otherPair.second);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (first == null) {
|
||||
return (second == null) ? 0 : second.hashCode();
|
||||
} else if (second == null) {
|
||||
return first.hashCode();
|
||||
} else {
|
||||
return first.hashCode() * 17 + second.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
90
test/lib/jdk/test/lib/util/Triple.java
Normal file
90
test/lib/jdk/test/lib/util/Triple.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 2016, 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 jdk.test.lib.util;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Triple - a three element tuple
|
||||
*
|
||||
* @param <F> first element type
|
||||
* @param <S> second element type
|
||||
* @param <T> third element type
|
||||
*/
|
||||
public class Triple<F, S, T> {
|
||||
private final Pair<F, Pair<S, T>> container;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param first first element of the triple
|
||||
* @param second second element of the triple
|
||||
* @param third third element of the triple
|
||||
*/
|
||||
public Triple(F first, S second, T third) {
|
||||
container = new Pair<>(first, new Pair<>(second, third));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets first element of the triple
|
||||
*/
|
||||
public F getFirst() {
|
||||
return container.first;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets second element of the triple
|
||||
*/
|
||||
public S getSecond() {
|
||||
return container.second.first;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets third element of the triple
|
||||
*/
|
||||
public T getThird() {
|
||||
return container.second.second;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return container.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Triple<?, ?, ?>) {
|
||||
Triple<?, ?, ?> objTriple = (Triple<?, ?, ?>) obj;
|
||||
return Objects.equals(container.first, objTriple.container.first)
|
||||
&& Objects.equals(container.second,
|
||||
objTriple.container.second);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + getFirst() + " : " + getSecond() + " : " + getThird() + ")";
|
||||
}
|
||||
}
|
66
test/lib/jdk/test/lib/wrappers/InfiniteLoop.java
Normal file
66
test/lib/jdk/test/lib/wrappers/InfiniteLoop.java
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, 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 jdk.test.lib.wrappers;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Class which runs another Runnable in infinite loop with certain pauses
|
||||
* between cycles.
|
||||
*/
|
||||
public class InfiniteLoop implements Runnable {
|
||||
private final Runnable target;
|
||||
private final long mills;
|
||||
|
||||
|
||||
/**
|
||||
* @param target a target to run in a loop
|
||||
* @param mills the length of pause time in milliseconds
|
||||
* @throws NullPointerException if target is null
|
||||
* @throws IllegalArgumentException if the value of millis is negative
|
||||
*/
|
||||
public InfiniteLoop(Runnable target, long mills) {
|
||||
Objects.requireNonNull(target);
|
||||
if (mills < 0) {
|
||||
throw new IllegalArgumentException("mills < 0");
|
||||
}
|
||||
this.target = target;
|
||||
this.mills = mills;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (true) {
|
||||
target.run();
|
||||
if (mills > 0) {
|
||||
Thread.sleep(mills);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
86
test/lib/jdk/test/lib/wrappers/TimeLimitedRunner.java
Normal file
86
test/lib/jdk/test/lib/wrappers/TimeLimitedRunner.java
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2016, 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 jdk.test.lib.wrappers;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Auxiliary class to run target w/ given timeout.
|
||||
*/
|
||||
public class TimeLimitedRunner implements Callable<Void> {
|
||||
private final long stoptime;
|
||||
private final long timeout;
|
||||
private final double factor;
|
||||
private final Callable<Boolean> target;
|
||||
|
||||
/**
|
||||
* @param timeout a timeout. zero means no time limitation
|
||||
* @param factor a multiplier used to estimate next iteration time
|
||||
* @param target a target to run
|
||||
* @throws NullPointerException if target is null
|
||||
* @throws IllegalArgumentException if timeout is negative or
|
||||
factor isn't positive
|
||||
*/
|
||||
public TimeLimitedRunner(long timeout, double factor,
|
||||
Callable<Boolean> target) {
|
||||
Objects.requireNonNull(target, "target must not be null");
|
||||
if (timeout < 0) {
|
||||
throw new IllegalArgumentException("timeout[" + timeout + "] < 0");
|
||||
}
|
||||
if (factor <= 0d) {
|
||||
throw new IllegalArgumentException("factor[" + factor + "] <= 0");
|
||||
}
|
||||
this.stoptime = System.currentTimeMillis() + timeout;
|
||||
this.timeout = timeout;
|
||||
this.factor = factor;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs @{linkplan target} while it returns true and timeout isn't exceeded
|
||||
*/
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
long maxDuration = 0L;
|
||||
long iterStart = System.currentTimeMillis();
|
||||
if (timeout != 0 && iterStart > stoptime) {
|
||||
return null;
|
||||
}
|
||||
while (target.call()) {
|
||||
if (timeout != 0) {
|
||||
long iterDuration = System.currentTimeMillis() - iterStart;
|
||||
maxDuration = Math.max(maxDuration, iterDuration);
|
||||
iterStart = System.currentTimeMillis();
|
||||
if (iterStart + (maxDuration * factor) > stoptime) {
|
||||
System.out.println("Not enough time to continue execution. "
|
||||
+ "Interrupted.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user