This commit is contained in:
Dmitrij Pochepko 2016-05-31 13:58:28 +00:00
commit fafec2b66c
9 changed files with 365 additions and 218 deletions

View File

@ -44,6 +44,10 @@ ifneq "x$(SEED)" "x"
APPLICATION_ARGS += --seed $(SEED)
endif
ifneq "x$(EXTRA_SRC_DIR)" "x"
EXTRA_SRC_FILES := $(shell find $(EXTRA_SRC_DIR) -name '*.java')
endif
JAVA = $(JDK_HOME)/bin/java
JAVAC = $(JDK_HOME)/bin/javac
JAR = $(JDK_HOME)/bin/jar
@ -99,6 +103,7 @@ COMPILE: INIT filelist compile_testlib
filelist: $(SRC_FILES)
@rm -f $@
@echo $(SRC_FILES) > $@
@echo $(EXTRA_SRC_FILES) >> $@
INIT: $(DIST_DIR)
$(shell if [ ! -d $(CLASSES_DIR) ]; then mkdir -p $(CLASSES_DIR); fi)

View File

@ -9,3 +9,5 @@ exclude-methods-file=conf/exclude.methods.lst
print-complexity=true
print-hierarchy=true
disable-static=true
generatorsFactories=jdk.test.lib.jittester.TestGeneratorsFactory
generators=JavaCode,ByteCode

View File

@ -25,50 +25,19 @@ package jdk.test.lib.jittester;
import jdk.test.lib.Pair;
import jdk.test.lib.jittester.factories.IRNodeBuilder;
import jdk.test.lib.jittester.jtreg.Printer;
import jdk.test.lib.jittester.types.TypeKlass;
import jdk.test.lib.jittester.utils.FixedTrees;
import jdk.test.lib.jittester.utils.OptionResolver;
import jdk.test.lib.jittester.utils.OptionResolver.Option;
import jdk.test.lib.jittester.utils.PseudoRandom;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.function.Function;
public class Automatic {
private static final int MINUTES_TO_WAIT = Integer.getInteger("jdk.test.lib.jittester", 3);
static String getJtregHeader(String mainClass, boolean addCompile) {
String synopsis = "seed = '" + ProductionParams.seed.value() + "'"
+ ", specificSeed = '" + PseudoRandom.getCurrentSeed() + "'";
StringBuilder header = new StringBuilder();
header.append("/*\n * @test\n * @summary ")
.append(synopsis)
.append(" \n* @library / ../\n");
if (addCompile) {
header.append("\n * @compile ")
.append(mainClass)
.append(".java\n");
}
header.append(" * @run build jdk.test.lib.jittester.jtreg.JitTesterDriver "
+ "jdk.test.lib.jittester.jtreg.Printer\n")
.append(" * @run driver jdk.test.lib.jittester.jtreg.JitTesterDriver ")
.append(mainClass)
.append("\n */\n\n");
if (ProductionParams.printHierarchy.value()) {
header.append("/*\n")
.append(Automatic.printHierarchy())
.append("*/\n");
}
return header.toString();
}
public static final int MINUTES_TO_WAIT = Integer.getInteger("jdk.test.lib.jittester", 3);
private static Pair<IRNode, IRNode> generateIRTree(String name) {
SymbolTable.removeAll();
@ -120,123 +89,48 @@ public class Automatic {
}
}
private static List<TestsGenerator> getTestGenerators() {
List<TestsGenerator> result = new ArrayList<>();
Class<?> factoryClass;
Function<String[], List<TestsGenerator>> factory;
String[] factoryClassNames = ProductionParams.generatorsFactories.value().split(",");
String[] generatorNames = ProductionParams.generators.value().split(",");
for (String factoryClassName : factoryClassNames) {
try {
factoryClass = Class.forName(factoryClassName);
factory = (Function<String[], List<TestsGenerator>>) factoryClass.newInstance();
} catch (ReflectiveOperationException roe) {
throw new Error("Can't instantiate generators factory", roe);
}
result.addAll(factory.apply(generatorNames));
}
return result;
}
public static void main(String[] args) {
initializeTestGenerator(args);
int counter = 0;
try {
Path testbaseDir = Paths.get(ProductionParams.testbaseDir.value());
System.out.printf(" %13s | %8s | %8s | %8s |%n", "start time", "count", "generat",
"running");
System.out.printf(" %13s | %8s | %8s | %8s |%n", "---", "---", "---","---");
String path = getJavaPath();
String javacPath = Paths.get(path, "javac").toString();
String javaPath = Paths.get(path, "java").toString();
// compile Printer class first. A common one for all tests
ensureExisting(testbaseDir);
ProcessBuilder pbPrinter = new ProcessBuilder(javacPath,
Paths.get(testbaseDir.toString(), "jdk", "test", "lib", "jittester",
"jtreg", "Printer.java").toString());
runProcess(pbPrinter, testbaseDir.resolve("Printer").toString());
do {
double start = System.currentTimeMillis();
System.out.print("[" + LocalTime.now() + "] |");
String name = "Test_" + counter;
Pair<IRNode, IRNode> irTree = generateIRTree(name);
System.out.printf(" %8d |", counter);
double generationTime = System.currentTimeMillis() - start;
System.out.printf(" %8.0f |", generationTime);
if (!ProductionParams.disableJavacodeGeneration.value()) {
JavaCodeGenerator generator = new JavaCodeGenerator();
String javaFile = generator.apply(irTree.first, irTree.second);
ProcessBuilder pb = new ProcessBuilder(javacPath, "-cp", testbaseDir.toString()
+ ":" + generator.getTestbase().toString(), javaFile);
runProcess(pb, generator.getTestbase().resolve(name).toString());
start = System.currentTimeMillis();
// Run compiled class files
pb = new ProcessBuilder(javaPath, "-Xint", "-cp", testbaseDir.toString()
+ ":" + generator.getTestbase().toString(), name);
String goldFile = name + ".gold";
runProcess(pb, generator.getTestbase().resolve(goldFile).toString());
}
if (!ProductionParams.disableBytecodeGeneration.value()) {
ByteCodeGenerator generator = new ByteCodeGenerator();
generator.apply(irTree.first, irTree.second);
generator.writeJtregBytecodeRunner(name);
// Run generated bytecode
ProcessBuilder pb = new ProcessBuilder(javaPath, "-Xint", "-Xverify", "-cp",
testbaseDir.toString() + ":" + generator.getTestbase().toString(),
name);
String goldFile = name + ".gold";
start = System.currentTimeMillis();
runProcess(pb, generator.getTestbase().resolve(goldFile).toString());
}
double runningTime = System.currentTimeMillis() - start;
System.out.printf(" %8.0f |%n", runningTime);
if (runningTime < TimeUnit.MINUTES.toMillis(MINUTES_TO_WAIT)) {
++counter;
}
} while (counter < ProductionParams.numberOfTests.value());
} catch (IOException | InterruptedException ex) {
ex.printStackTrace();
}
}
private static String getJavaPath() {
String[] env = { "JDK_HOME", "JAVA_HOME", "BOOTDIR" };
for (String name : env) {
String path = System.getenv(name);
if (path != null) {
return path + "/bin/";
System.out.printf(" %13s | %8s | %8s | %8s |%n", "start time", "count", "generat",
"running");
System.out.printf(" %13s | %8s | %8s | %8s |%n", "---", "---", "---", "---");
List<TestsGenerator> generators = getTestGenerators();
do {
double start = System.currentTimeMillis();
System.out.print("[" + LocalTime.now() + "] |");
String name = "Test_" + counter;
Pair<IRNode, IRNode> irTree = generateIRTree(name);
System.out.printf(" %8d |", counter);
double generationTime = System.currentTimeMillis() - start;
System.out.printf(" %8.0f |", generationTime);
start = System.currentTimeMillis();
for (TestsGenerator generator : generators) {
generator.accept(irTree.first, irTree.second);
}
}
return "";
}
private static int runProcess(ProcessBuilder pb, String name)
throws IOException, InterruptedException {
pb.redirectError(new File(name + ".err"));
pb.redirectOutput(new File(name + ".out"));
Process process = pb.start();
if (process.waitFor(MINUTES_TO_WAIT, TimeUnit.MINUTES)) {
try (FileWriter file = new FileWriter(name + ".exit")) {
file.write(Integer.toString(process.exitValue()));
double runningTime = System.currentTimeMillis() - start;
System.out.printf(" %8.0f |%n", runningTime);
if (runningTime < TimeUnit.MINUTES.toMillis(MINUTES_TO_WAIT)) {
++counter;
}
return process.exitValue();
} else {
process.destroyForcibly();
return -1;
}
}
private static String printHierarchy() {
return TypeList.getAll().stream()
.filter(t -> t instanceof TypeKlass)
.map(t -> typeDescription((TypeKlass) t))
.collect(Collectors.joining("\n","CLASS HIERARCHY:\n", "\n"));
}
private static String typeDescription(TypeKlass type) {
StringBuilder result = new StringBuilder();
String parents = type.getParentsNames().stream().collect(Collectors.joining(","));
result.append(type.isAbstract() ? "abstract " : "")
.append(type.isFinal() ? "final " : "")
.append(type.isInterface() ? "interface " : "class ")
.append(type.getName())
.append(parents.isEmpty() ? "" : ": " + parents);
return result.toString();
}
static void ensureExisting(Path path) {
if (Files.notExists(path)) {
try {
Files.createDirectories(path);
} catch (IOException ex) {
ex.printStackTrace();
}
}
} while (counter < ProductionParams.numberOfTests.value());
}
}

View File

@ -23,54 +23,60 @@
package jdk.test.lib.jittester;
import jdk.test.lib.jittester.visitors.ByteCodeVisitor;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.function.BiFunction;
import java.util.function.Function;
import jdk.test.lib.jittester.visitors.ByteCodeVisitor;
/**
* Generates class files from bytecode
* Generates class files from IRTree
*/
class ByteCodeGenerator implements BiFunction<IRNode, IRNode, String> {
private final Path testbase = Paths.get(ProductionParams.testbaseDir.value(),
"bytecode_tests");
class ByteCodeGenerator extends TestsGenerator {
private static final String DEFAULT_SUFFIX = "bytecode_tests";
public void writeJtregBytecodeRunner(String name) {
try (FileWriter file = new FileWriter(testbase.resolve(name + ".java").toFile())) {
file.write(Automatic.getJtregHeader(name, false));
} catch (IOException e) {
e.printStackTrace();
}
ByteCodeGenerator() {
super(DEFAULT_SUFFIX);
}
public String apply(IRNode mainClass, IRNode privateClasses) {
Automatic.ensureExisting(testbase);
ByteCodeGenerator(String suffix, Function<String, String[]> preRunActions, String jtDriverOptions) {
super(suffix, preRunActions, jtDriverOptions);
}
@Override
public void accept(IRNode mainClass, IRNode privateClasses) {
generateClassFiles(mainClass, privateClasses);
generateSeparateJtregHeader(mainClass);
compilePrinter();
generateGoldenOut(mainClass.getName());
}
private void generateSeparateJtregHeader(IRNode mainClass) {
String mainClassName = mainClass.getName();
writeFile(generatorDir, mainClassName + ".java", getJtregHeader(mainClassName));
}
private void generateClassFiles(IRNode mainClass, IRNode privateClasses) {
String mainClassName = mainClass.getName();
ensureExisting(generatorDir);
try {
ByteCodeVisitor vis = new ByteCodeVisitor();
if (privateClasses != null) {
privateClasses.accept(vis);
}
mainClass.accept(vis);
Path mainClassPath = testbase.resolve(mainClass.getName() + ".class");
writeToClassFile(mainClassPath, vis.getByteCode(mainClass.getName()));
writeFile(mainClassName + ".class", vis.getByteCode(mainClassName));
if (privateClasses != null) {
privateClasses.getChildren().forEach(c -> {
String name = c.getName();
Path classPath = testbase.resolve(name + ".class");
writeToClassFile(classPath, vis.getByteCode(name));
writeFile(name + ".class", vis.getByteCode(name));
});
}
return mainClassPath.toString();
} catch (Throwable t) {
Path errFile = testbase.resolve(mainClass.getName() + ".err");
Path errFile = generatorDir.resolve(mainClassName + ".err");
try (PrintWriter pw = new PrintWriter(Files.newOutputStream(errFile,
StandardOpenOption.CREATE_NEW))) {
t.printStackTrace(pw);
@ -78,16 +84,11 @@ class ByteCodeGenerator implements BiFunction<IRNode, IRNode, String> {
t.printStackTrace();
throw new Error("can't write error to error file " + errFile, e);
}
return null;
}
}
public Path getTestbase() {
return testbase;
}
private void writeToClassFile(Path path, byte[] bytecode) {
try (FileOutputStream file = new FileOutputStream(path.toString())) {
private void writeFile(String fileName, byte[] bytecode) {
try (FileOutputStream file = new FileOutputStream(generatorDir.resolve(fileName).toFile())) {
file.write(bytecode);
} catch (IOException ex) {
ex.printStackTrace();

View File

@ -23,48 +23,59 @@
package jdk.test.lib.jittester;
import java.io.File;
import java.io.IOException;
import java.util.function.Function;
import jdk.test.lib.jittester.visitors.JavaCodeVisitor;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.function.BiFunction;
/**
* Generates class files from java source code
* Generates java source code from IRTree
*/
class JavaCodeGenerator implements BiFunction<IRNode, IRNode, String> {
private final Path testbase = Paths.get(ProductionParams.testbaseDir.value(), "java_tests");
public class JavaCodeGenerator extends TestsGenerator {
private static final String DEFAULT_SUFFIX = "java_tests";
private String generateJavaCode(IRNode mainClass, IRNode privateClasses) {
JavaCodeGenerator() {
this(DEFAULT_SUFFIX, JavaCodeGenerator::generatePrerunAction, "");
}
JavaCodeGenerator(String prefix, Function<String, String[]> preRunActions, String jtDriverOptions) {
super(prefix, preRunActions, jtDriverOptions);
}
@Override
public void accept(IRNode mainClass, IRNode privateClasses) {
String mainClassName = mainClass.getName();
generateSources(mainClass, privateClasses);
compilePrinter();
compileJavaFile(mainClassName);
generateGoldenOut(mainClassName);
}
private void generateSources(IRNode mainClass, IRNode privateClasses) {
String mainClassName = mainClass.getName();
StringBuilder code = new StringBuilder();
JavaCodeVisitor vis = new JavaCodeVisitor();
code.append(Automatic.getJtregHeader(mainClass.getName(), true));
code.append(getJtregHeader(mainClassName));
if (privateClasses != null) {
code.append(privateClasses.accept(vis));
}
code.append(mainClass.accept(vis));
return code.toString();
ensureExisting(generatorDir);
writeFile(generatorDir, mainClassName + ".java", code.toString());
}
public Path getTestbase() {
return testbase;
}
@Override
public String apply(IRNode mainClass, IRNode privateClasses) {
String code = generateJavaCode(mainClass, privateClasses);
Automatic.ensureExisting(testbase);
Path fileName = testbase.resolve(mainClass.getName() + ".java");
try (FileWriter file = new FileWriter(fileName.toFile())) {
file.write(code);
return fileName.toString();
} catch (IOException ex) {
ex.printStackTrace();
private void compileJavaFile(String mainClassName) {
String classPath = getRoot() + File.pathSeparator + generatorDir;
ProcessBuilder pb = new ProcessBuilder(JAVAC, "-cp", classPath,
generatorDir.resolve(mainClassName + ".java").toString());
try {
runProcess(pb, generatorDir.resolve(mainClassName).toString());
} catch (IOException | InterruptedException e) {
throw new Error("Can't compile sources ", e);
}
return "";
}
private static String[] generatePrerunAction(String mainClassName) {
return new String[] {"@compile " + mainClassName + ".java"};
}
}

View File

@ -68,8 +68,6 @@ public class ProductionParams {
public static Option<Boolean> disableNestedBlocks = null;
public static Option<Boolean> disableArrays = null;
public static Option<Boolean> enableFinalizers = null;
public static Option<Boolean> disableBytecodeGeneration = null;
public static Option<Boolean> disableJavacodeGeneration = null;
// workaraound: to reduce chance throwing ArrayIndexOutOfBoundsException
public static Option<Integer> chanceExpressionIndex = null;
public static Option<String> testbaseDir = null;
@ -78,6 +76,8 @@ public class ProductionParams {
public static Option<Long> specificSeed = null;
public static Option<String> classesFile = null;
public static Option<String> excludeMethodsFile = null;
public static Option<String> generators = null;
public static Option<String> generatorsFactories = null;
public static void register(OptionResolver optionResolver) {
productionLimit = optionResolver.addIntegerOption('l', "production-limit", 100, "Limit on steps in the production of an expression");
@ -120,8 +120,6 @@ public class ProductionParams {
disableNestedBlocks = optionResolver.addBooleanOption("disable-nested-blocks", "Disable generation of nested blocks");
disableArrays = optionResolver.addBooleanOption("disable-arrays", "Disable generation of arrays");
enableFinalizers = optionResolver.addBooleanOption("enable-finalizers", "Enable finalizers (for stress testing)");
disableBytecodeGeneration = optionResolver.addBooleanOption("disable-bytecode-generation", "Disable generation of bytecode output");
disableJavacodeGeneration = optionResolver.addBooleanOption("disable-javacode-generation", "Disable generation of java source code output");
chanceExpressionIndex = optionResolver.addIntegerOption("chance-expression-index", 0, "A non negative decimal integer used to restrict chane of generating expression in array index while creating or accessing by index");
testbaseDir = optionResolver.addStringOption("testbase-dir", ".", "Testbase dir");
numberOfTests = optionResolver.addIntegerOption('n', "number-of-tests", 0, "Number of test classes to generate");
@ -129,5 +127,7 @@ public class ProductionParams {
specificSeed = optionResolver.addLongOption('z', "specificSeed", 0L, "A seed to be set for specific test generation(regular seed still needed for initialization)");
classesFile = optionResolver.addStringOption('f', "classes-file", "conf/classes.lst", "File to read classes from");
excludeMethodsFile = optionResolver.addStringOption('r', "exclude-methods-file", "conf/exclude.methods.lst", "File to read excluded methods from");
generators = optionResolver.addStringOption("generators", "", "Comma-separated list of generator names");
generatorsFactories = optionResolver.addStringOption("generatorsFactories", "", "Comma-separated list of generators factories class names");
}
}

View File

@ -0,0 +1,49 @@
/*
* 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.
*/
package jdk.test.lib.jittester;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class TestGeneratorsFactory implements Function<String[], List<TestsGenerator>> {
@Override
public List<TestsGenerator> apply(String[] input) {
List<TestsGenerator> result = new ArrayList<>();
for (String generatorName : input) {
switch (generatorName) {
case "JavaCode":
result.add(new JavaCodeGenerator());
break;
case "ByteCode":
result.add(new ByteCodeGenerator());
break;
default:
throw new IllegalArgumentException("Unknown generator: " + generatorName);
}
}
return result;
}
}

View File

@ -0,0 +1,184 @@
/*
* 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.
*/
package jdk.test.lib.jittester;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import jdk.test.lib.jittester.types.TypeKlass;
import jdk.test.lib.jittester.utils.PseudoRandom;
public abstract class TestsGenerator implements BiConsumer<IRNode, IRNode> {
protected static final String JAVA_BIN = getJavaPath();
protected static final String JAVAC = Paths.get(JAVA_BIN, "javac").toString();
protected static final String JAVA = Paths.get(JAVA_BIN, "java").toString();
protected final Path generatorDir;
protected final Function<String, String[]> preRunActions;
protected final String jtDriverOptions;
protected TestsGenerator(String suffix) {
this(suffix, s -> new String[0], "");
}
protected TestsGenerator(String suffix, Function<String, String[]> preRunActions,
String jtDriverOptions) {
generatorDir = getRoot().resolve(suffix);
this.preRunActions = preRunActions;
this.jtDriverOptions = jtDriverOptions;
}
protected void generateGoldenOut(String mainClassName) {
String classPath = getRoot() + File.pathSeparator + generatorDir;
ProcessBuilder pb = new ProcessBuilder(JAVA, "-Xint", "-Xverify", "-cp", classPath,
mainClassName);
String goldFile = mainClassName + ".gold";
try {
runProcess(pb, generatorDir.resolve(goldFile).toString());
} catch (IOException | InterruptedException e) {
throw new Error("Can't run generated test ", e);
}
}
protected static int runProcess(ProcessBuilder pb, String name)
throws IOException, InterruptedException {
pb.redirectError(new File(name + ".err"));
pb.redirectOutput(new File(name + ".out"));
Process process = pb.start();
if (process.waitFor(Automatic.MINUTES_TO_WAIT, TimeUnit.MINUTES)) {
try (FileWriter file = new FileWriter(name + ".exit")) {
file.write(Integer.toString(process.exitValue()));
}
return process.exitValue();
} else {
process.destroyForcibly();
return -1;
}
}
protected static void compilePrinter() {
Path root = getRoot();
ProcessBuilder pbPrinter = new ProcessBuilder(JAVAC,
root.resolve("jdk")
.resolve("test")
.resolve("lib")
.resolve("jittester")
.resolve("jtreg")
.resolve("Printer.java")
.toString());
try {
int exitCode = runProcess(pbPrinter, root.resolve("Printer").toString());
if (exitCode != 0) {
throw new Error("Printer compilation returned exit code " + exitCode);
}
} catch (IOException | InterruptedException e) {
throw new Error("Can't compile printer", e);
}
}
protected static void ensureExisting(Path path) {
if (Files.notExists(path)) {
try {
Files.createDirectories(path);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
protected String getJtregHeader(String mainClassName) {
String synopsis = "seed = '" + ProductionParams.seed.value() + "'"
+ ", specificSeed = '" + PseudoRandom.getCurrentSeed() + "'";
StringBuilder header = new StringBuilder();
header.append("/*\n * @test\n * @summary ")
.append(synopsis)
.append(" \n * @library / ../\n");
header.append(" * @run build jdk.test.lib.jittester.jtreg.JitTesterDriver "
+ "jdk.test.lib.jittester.jtreg.Printer\n");
for (String action : preRunActions.apply(mainClassName)) {
header.append(" * ")
.append(action)
.append("\n");
}
header.append(" * @run driver jdk.test.lib.jittester.jtreg.JitTesterDriver ")
.append(jtDriverOptions)
.append(" ")
.append(mainClassName)
.append("\n */\n\n");
if (ProductionParams.printHierarchy.value()) {
header.append("/*\n")
.append(printHierarchy())
.append("*/\n");
}
return header.toString();
}
protected static Path getRoot() {
return Paths.get(ProductionParams.testbaseDir.value());
}
protected static void writeFile(Path targetDir, String fileName, String content) {
try (FileWriter file = new FileWriter(targetDir.resolve(fileName).toFile())) {
file.write(content);
} catch (IOException e) {
e.printStackTrace();
}
}
private static String printHierarchy() {
return TypeList.getAll()
.stream()
.filter(t -> t instanceof TypeKlass)
.map(t -> typeDescription((TypeKlass) t))
.collect(Collectors.joining("\n","CLASS HIERARCHY:\n", "\n"));
}
private static String typeDescription(TypeKlass type) {
StringBuilder result = new StringBuilder();
String parents = type.getParentsNames().stream().collect(Collectors.joining(","));
result.append(type.isAbstract() ? "abstract " : "")
.append(type.isFinal() ? "final " : "")
.append(type.isInterface() ? "interface " : "class ")
.append(type.getName())
.append(parents.isEmpty() ? "" : ": " + parents);
return result.toString();
}
private static String getJavaPath() {
String[] env = { "JDK_HOME", "JAVA_HOME", "BOOTDIR" };
for (String name : env) {
String path = System.getenv(name);
if (path != null) {
return path + "/bin/";
}
}
return "";
}
}

View File

@ -40,30 +40,31 @@ import java.util.stream.Stream;
public class JitTesterDriver {
public static void main(String[] args) {
if (args.length != 1) {
if (args.length < 1) {
throw new IllegalArgumentException(
"[TESTBUG]: wrong number of argument : " + args.length
+ ". Expected 1 argument -- jit-tester test name.");
+ ". Expected at least 1 argument -- jit-tester test name.");
}
OutputAnalyzer oa;
try {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, args[0]);
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, args);
oa = new OutputAnalyzer(pb.start());
} catch (Exception e) {
throw new Error("Unexpected exception on test jvm start :" + e, e);
}
String name = args[args.length - 1];
Pattern splitOut = Pattern.compile("\\n"); // tests use \n only in stdout
Pattern splitErr = Pattern.compile("\\r?\\n"); // can handle both \r\n and \n
Path testDir = Paths.get(Utils.TEST_SRC);
String goldOut = formatOutput(streamGoldFile(testDir, args[0], "out"));
String goldOut = formatOutput(streamGoldFile(testDir, name, "out"));
String anlzOut = formatOutput(Arrays.stream(splitOut.split(oa.getStdout())));
Asserts.assertEQ(anlzOut, goldOut, "Actual stdout isn't equal to golden one");
String goldErr = formatOutput(streamGoldFile(testDir, args[0], "err"));
String goldErr = formatOutput(streamGoldFile(testDir, name, "err"));
String anlzErr = formatOutput(Arrays.stream(splitErr.split(oa.getStderr())));
Asserts.assertEQ(anlzErr, goldErr, "Actual stderr isn't equal to golden one");
int exitValue = Integer.parseInt(streamGoldFile(testDir, args[0], "exit").findFirst().get());
int exitValue = Integer.parseInt(streamGoldFile(testDir, name, "exit").findFirst().get());
oa.shouldHaveExitValue(exitValue);
}