# HG changeset patch # User ppunegov # Date 1448373500 -10800 # Node ID 41286f2487951c4f9ab34bb8ed0ce0a40fe59a0c # Parent 3f99eccd6ea3b5a3b23e1847207d9296b0960928 8066154: JEP-JDK-8046155: Test task: huge directive file Summary: Stress tests for directive parser Reviewed-by: iignatyev, neliasso diff -r 3f99eccd6ea3 -r 41286f248795 hotspot/test/compiler/compilercontrol/parser/DirectiveParser.java --- a/hotspot/test/compiler/compilercontrol/parser/DirectiveParser.java Tue Nov 24 15:50:27 2015 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ - -/* - * @test - * @bug 8137167 - * @summary Tests directive json parser - * @library /testlibrary /../../test/lib ../share / - * @run driver compiler.compilercontrol.parser.DirectiveParser - */ - -package compiler.compilercontrol.parser; - -import compiler.compilercontrol.share.JSONFile; -import jdk.test.lib.Asserts; -import jdk.test.lib.OutputAnalyzer; -import jdk.test.lib.ProcessTools; -import jdk.test.lib.Utils; - -public class DirectiveParser { - private static final String ERROR_MSG = "VM should exit with error " - + "on incorrect JSON file: "; - private static final String EXPECTED_ERROR_STRING = "Parsing of compiler" - + " directives failed"; - - public static void main(String[] args) { - simpleTest(); - nonMatchingBrackets(); - arrayTest(); - emptyObjectTest(); - emptyFile(); - noFile(); - directory(); - } - - private static void simpleTest() { - String fileName = "simple.json"; - try (JSONFile file = new JSONFile(fileName)) { - file.write(JSONFile.Element.ARRAY) - .write(JSONFile.Element.OBJECT) - .write(JSONFile.Element.PAIR, "match") - .write(JSONFile.Element.VALUE, "\"java/lang/String.*\"") - .write(JSONFile.Element.PAIR, "c2") - .write(JSONFile.Element.OBJECT) - .write(JSONFile.Element.PAIR, "inline") - .write(JSONFile.Element.ARRAY) - .write(JSONFile.Element.VALUE, "\"+*.indexOf\"") - .write(JSONFile.Element.VALUE, "\"-a.b\"") - .end() - .end() - .end() // end object - .write(JSONFile.Element.OBJECT) - .write(JSONFile.Element.PAIR, "match") - .write(JSONFile.Element.VALUE, "\"*.indexOf\"") - .write(JSONFile.Element.PAIR, "c1") - .write(JSONFile.Element.OBJECT) - .write(JSONFile.Element.PAIR, "enable") - .write(JSONFile.Element.VALUE, "false") - .end() - .end(); // end object - file.end(); - } - OutputAnalyzer output = execute(fileName); - output.shouldHaveExitValue(0); - output.shouldNotContain(EXPECTED_ERROR_STRING); - } - - private static void nonMatchingBrackets() { - String fileName = "non-matching.json"; - try (JSONFile file = new JSONFile(fileName)) { - file.write(JSONFile.Element.ARRAY) - .write(JSONFile.Element.OBJECT) - .write(JSONFile.Element.PAIR, "match") - .write(JSONFile.Element.VALUE, "\"java/lang/String.*\"") - .end(); - // don't write matching } - } - OutputAnalyzer output = execute(fileName); - Asserts.assertNE(output.getExitValue(), 0, ERROR_MSG + "non matching " - + "brackets"); - output.shouldContain(EXPECTED_ERROR_STRING); - } - - private static void arrayTest() { - String fileName = "array.json"; - try (JSONFile file = new JSONFile(fileName)) { - file.write(JSONFile.Element.ARRAY); - file.end(); - } - OutputAnalyzer output = execute(fileName); - Asserts.assertNE(output.getExitValue(), 0, ERROR_MSG + "empty array"); - } - - private static void emptyObjectTest() { - String fileName = "emptyObject.json"; - try (JSONFile file = new JSONFile(fileName)) { - file.write(JSONFile.Element.OBJECT); - file.end(); - } - OutputAnalyzer output = execute(fileName); - Asserts.assertNE(output.getExitValue(), 0, ERROR_MSG + "empty object " - + "without any match"); - output.shouldContain(EXPECTED_ERROR_STRING); - } - - private static void emptyFile() { - String fileName = "empty.json"; - try (JSONFile file = new JSONFile(fileName)) { - // empty - } - OutputAnalyzer output = execute(fileName); - Asserts.assertNE(output.getExitValue(), 0, ERROR_MSG + "empty file"); - output.shouldContain(EXPECTED_ERROR_STRING); - } - - private static void noFile() { - OutputAnalyzer output = execute("nonexistent.json"); - Asserts.assertNE(output.getExitValue(), 0, ERROR_MSG + "non existing " - + "file"); - } - - private static void directory() { - OutputAnalyzer output = execute(Utils.TEST_SRC); - Asserts.assertNE(output.getExitValue(), 0, ERROR_MSG + "directory as " - + "a name"); - } - - private static OutputAnalyzer execute(String fileName) { - OutputAnalyzer output; - try { - output = ProcessTools.executeTestJvm( - "-XX:+UnlockDiagnosticVMOptions", - "-XX:CompilerDirectivesFile=" + fileName, - "-version"); - } catch (Throwable thr) { - throw new Error("Execution failed", thr); - } - return output; - } -} diff -r 3f99eccd6ea3 -r 41286f248795 hotspot/test/compiler/compilercontrol/parser/DirectiveParserTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/compilercontrol/parser/DirectiveParserTest.java Tue Nov 24 16:58:20 2015 +0300 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2015, 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. + */ + +/* + * @test + * @bug 8137167 + * @summary Tests directive json parser + * @library /testlibrary /test/lib ../share / + * @run driver compiler.compilercontrol.parser.DirectiveParserTest + */ + +package compiler.compilercontrol.parser; + +import compiler.compilercontrol.share.JSONFile; +import jdk.test.lib.Asserts; +import jdk.test.lib.OutputAnalyzer; +import jdk.test.lib.ProcessTools; +import jdk.test.lib.Utils; + +public class DirectiveParserTest { + private static final String ERROR_MSG = "VM should exit with error " + + "on incorrect JSON file: "; + private static final String EXPECTED_ERROR_STRING = "Parsing of compiler" + + " directives failed"; + + public static void main(String[] args) { + simpleTest(); + nonMatchingBrackets(); + arrayTest(); + emptyObjectTest(); + emptyFile(); + noFile(); + directory(); + } + + private static void simpleTest() { + String fileName = "simple.json"; + try (JSONFile file = new JSONFile(fileName)) { + file.write(JSONFile.Element.ARRAY) + .write(JSONFile.Element.OBJECT) + .write(JSONFile.Element.PAIR, "match") + .write(JSONFile.Element.VALUE, "\"java/lang/String.*\"") + .write(JSONFile.Element.PAIR, "c2") + .write(JSONFile.Element.OBJECT) + .write(JSONFile.Element.PAIR, "inline") + .write(JSONFile.Element.ARRAY) + .write(JSONFile.Element.VALUE, "\"+*.indexOf\"") + .write(JSONFile.Element.VALUE, "\"-a.b\"") + .end() + .end() + .end() // end object + .write(JSONFile.Element.OBJECT) + .write(JSONFile.Element.PAIR, "match") + .write(JSONFile.Element.VALUE, "\"*.indexOf\"") + .write(JSONFile.Element.PAIR, "c1") + .write(JSONFile.Element.OBJECT) + .write(JSONFile.Element.PAIR, "enable") + .write(JSONFile.Element.VALUE, "false") + .end() + .end(); // end object + file.end(); + } + OutputAnalyzer output = HugeDirectiveUtil.execute(fileName); + output.shouldHaveExitValue(0); + output.shouldNotContain(EXPECTED_ERROR_STRING); + } + + private static void nonMatchingBrackets() { + String fileName = "non-matching.json"; + try (JSONFile file = new JSONFile(fileName)) { + file.write(JSONFile.Element.ARRAY) + .write(JSONFile.Element.OBJECT) + .write(JSONFile.Element.PAIR, "match") + .write(JSONFile.Element.VALUE, "\"java/lang/String.*\"") + .end(); + // don't write matching } + } + OutputAnalyzer output = HugeDirectiveUtil.execute(fileName); + Asserts.assertNE(output.getExitValue(), 0, ERROR_MSG + "non matching " + + "brackets"); + output.shouldContain(EXPECTED_ERROR_STRING); + } + + private static void arrayTest() { + String fileName = "array.json"; + try (JSONFile file = new JSONFile(fileName)) { + file.write(JSONFile.Element.ARRAY); + file.end(); + } + OutputAnalyzer output = HugeDirectiveUtil.execute(fileName); + Asserts.assertNE(output.getExitValue(), 0, ERROR_MSG + "empty array"); + } + + private static void emptyObjectTest() { + String fileName = "emptyObject.json"; + try (JSONFile file = new JSONFile(fileName)) { + file.write(JSONFile.Element.OBJECT); + file.end(); + } + OutputAnalyzer output = HugeDirectiveUtil.execute(fileName); + Asserts.assertNE(output.getExitValue(), 0, ERROR_MSG + "empty object " + + "without any match"); + output.shouldContain(EXPECTED_ERROR_STRING); + } + + private static void emptyFile() { + String fileName = "empty.json"; + try (JSONFile file = new JSONFile(fileName)) { + // empty + } + OutputAnalyzer output = HugeDirectiveUtil.execute(fileName); + Asserts.assertNE(output.getExitValue(), 0, ERROR_MSG + "empty file"); + output.shouldContain(EXPECTED_ERROR_STRING); + } + + private static void noFile() { + OutputAnalyzer output = HugeDirectiveUtil.execute("nonexistent.json"); + Asserts.assertNE(output.getExitValue(), 0, ERROR_MSG + "non existing " + + "file"); + } + + private static void directory() { + OutputAnalyzer output = HugeDirectiveUtil.execute(Utils.TEST_SRC); + Asserts.assertNE(output.getExitValue(), 0, ERROR_MSG + "directory as " + + "a name"); + } +} diff -r 3f99eccd6ea3 -r 41286f248795 hotspot/test/compiler/compilercontrol/parser/DirectiveStressTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/compilercontrol/parser/DirectiveStressTest.java Tue Nov 24 16:58:20 2015 +0300 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2015, 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. + */ + +/* + * @test + * @bug 8137167 + * @summary Stress directive json parser + * @library /testlibrary /test/lib ../share / + * @run driver compiler.compilercontrol.parser.DirectiveStressTest + */ + +package compiler.compilercontrol.parser; + +import compiler.compilercontrol.share.AbstractTestBase; +import compiler.compilercontrol.share.JSONFile; +import compiler.compilercontrol.share.method.MethodDescriptor; +import compiler.compilercontrol.share.scenario.DirectiveWriter; +import jdk.test.lib.OutputAnalyzer; +import pool.PoolHelper; + +import java.util.List; +import java.util.stream.Collectors; + +public class DirectiveStressTest { + private static final int AMOUNT = Integer.getInteger( + "compiler.compilercontrol.parser.DirectiveStressTest.amount", + Short.MAX_VALUE * 2 + 2); + private static final List DESCRIPTORS + = new PoolHelper().getAllMethods().stream() + .map(pair -> AbstractTestBase.getValidMethodDescriptor( + pair.first)) + .collect(Collectors.toList()); + private static final String EXPECTED_MESSAGE = " compiler directives added"; + + public static void main(String[] args) { + hugeFileTest(); + hugeObjectTest(); + } + + /* + * Creates file with AMOUNT of options in match block + */ + private static void hugeObjectTest() { + String fileName = "hugeObject.json"; + try (DirectiveWriter file = new DirectiveWriter(fileName)) { + file.write(JSONFile.Element.ARRAY); + HugeDirectiveUtil.createMatchObject(DESCRIPTORS, file, AMOUNT); + file.end(); // end array block + } + OutputAnalyzer output = HugeDirectiveUtil.execute(fileName); + output.shouldHaveExitValue(0); + output.shouldContain(1 + EXPECTED_MESSAGE); + output.shouldNotContain(HugeDirectiveUtil.EXPECTED_ERROR_STRING); + } + + /* + * Creates huge valid file with AMOUNT of match directives + */ + private static void hugeFileTest() { + String fileName = "hugeFile.json"; + HugeDirectiveUtil.createHugeFile(DESCRIPTORS, fileName, AMOUNT); + OutputAnalyzer output = HugeDirectiveUtil.execute(fileName); + output.shouldHaveExitValue(0); + output.shouldContain(AMOUNT + EXPECTED_MESSAGE); + output.shouldNotContain(HugeDirectiveUtil.EXPECTED_ERROR_STRING); + } +} diff -r 3f99eccd6ea3 -r 41286f248795 hotspot/test/compiler/compilercontrol/parser/HugeDirectiveUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/compilercontrol/parser/HugeDirectiveUtil.java Tue Nov 24 16:58:20 2015 +0300 @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.compilercontrol.parser; + +import compiler.compilercontrol.share.JSONFile; +import compiler.compilercontrol.share.method.MethodDescriptor; +import compiler.compilercontrol.share.scenario.DirectiveWriter; +import compiler.compilercontrol.share.scenario.Scenario; +import jdk.test.lib.OutputAnalyzer; +import jdk.test.lib.ProcessTools; +import jdk.test.lib.Utils; + +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; + +/** + * Creates a huge directive file + */ +public final class HugeDirectiveUtil { + private static final Random RANDOM = Utils.getRandomInstance(); + protected static final String EXPECTED_ERROR_STRING = "Parsing of compiler " + + "directives failed"; + + private HugeDirectiveUtil() { } + + /** + * Creates huge file with specified amount of directives + * + * @param descriptors a list of descriptors to be randomly used + * in match and inline blocks + * @param fileName a directives file name to be created + * @param amount an amount of match objects + */ + public static void createHugeFile(List descriptors, + String fileName, int amount) { + try (DirectiveWriter file = new DirectiveWriter(fileName)) { + file.write(JSONFile.Element.ARRAY); + for (int i = 0; i < amount; i++) { + createMatchObject(descriptors, file, 1); + } + file.end(); + } + } + + /** + * Creates match object in the given file with specified size + * + * @param descriptors a list of method descriptors to be used + * @param file a directive file to write at + * @param objectSize a size of the match object + */ + public static void createMatchObject(List descriptors, + DirectiveWriter file, int objectSize) { + // get random amount of methods for the match + List methods = getRandomDescriptors(descriptors); + file.match(methods.toArray(new String[methods.size()])); + for (int i = 0; i < objectSize; i++) { + // emit compiler block + file.emitCompiler(Utils.getRandomElement( + Scenario.Compiler.values())); + file.option(Utils.getRandomElement(DirectiveWriter.Option.values()), + RANDOM.nextBoolean()); + file.end(); // ends compiler block + + // add standalone option + file.option(Utils.getRandomElement(DirectiveWriter.Option.values()), + RANDOM.nextBoolean()); + } + // add inline block with random inlinees + methods = getRandomDescriptors(descriptors).stream() + .map(s -> (RANDOM.nextBoolean() ? "+" : "-") + s) + .collect(Collectors.toList()); + file.inline(methods.toArray(new String[methods.size()])); + + // end match block + file.end(); + } + + private static List getRandomDescriptors( + List descriptors) { + int amount = 1 + RANDOM.nextInt(descriptors.size() - 1); + int skipAmount = RANDOM.nextInt(descriptors.size() - amount); + return descriptors.stream() + .skip(skipAmount) + .limit(amount) + .map(MethodDescriptor::getString) + .collect(Collectors.toList()); + } + + protected static OutputAnalyzer execute(String fileName) { + OutputAnalyzer output; + try { + output = ProcessTools.executeTestJvm( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:CompilerDirectivesFile=" + fileName, + "-version"); + } catch (Throwable thr) { + throw new Error("Execution failed with: " + thr, thr); + } + return output; + } +}