/* * Copyright (c) 2014, 2019, 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.
*/
/** * Base class for command line option tests.
*/ publicabstractclass CommandLineOptionTest { publicstaticfinal String UNLOCK_DIAGNOSTIC_VM_OPTIONS
= "-XX:+UnlockDiagnosticVMOptions"; publicstaticfinal String UNLOCK_EXPERIMENTAL_VM_OPTIONS
= "-XX:+UnlockExperimentalVMOptions"; protectedstaticfinal String UNRECOGNIZED_OPTION_ERROR_FORMAT
= "Unrecognized VM option '[+-]?%s(=.*)?'"; protectedstaticfinal String EXPERIMENTAL_OPTION_ERROR_FORMAT
= "VM option '%s' is experimental and must be enabled via "
+ "-XX:\\+UnlockExperimentalVMOptions."; protectedstaticfinal String DIAGNOSTIC_OPTION_ERROR_FORMAT
= " VM option '%s' is diagnostic and must be enabled via "
+ "-XX:\\+UnlockDiagnosticVMOptions."; privatestaticfinal 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.
*/ publicstaticvoid 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.
*/ publicstaticvoid 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, InputArguments.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); thrownew AssertionError(errorMessage, e);
}
/** * 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.
*/ publicstaticvoid 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); thrownew 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.
*/ publicstaticvoid verifySameJVMStartup(String expectedMessages[],
String unexpectedMessages[], String exitErrorMessage,
String wrongWarningMessage, ExitCode exitCode, String... options) throws Throwable {
List<String> finalOptions = new ArrayList<>();
finalOptions.add(CommandLineOptionTest.getVMTypeOption());
String extraFlagForEmulated = CommandLineOptionTest.getVMTypeOptionForEmulated(); if (extraFlagForEmulated != null) {
finalOptions.add(extraFlagForEmulated);
}
Collections.addAll(finalOptions, options);
/** * 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.
*/ publicstaticvoid 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.
*/ publicstaticvoid verifyOptionValue(String optionName,
String expectedValue, String optionErrorString, boolean addTestVmOptions, String... additionalVMOpts) throws Throwable {
List<String> vmOpts = new ArrayList<>();
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); thrownew 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
*/ publicstaticvoid 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); thrownew 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
*/ publicstatic OutputAnalyzer startVMWithOptions(String[] optionNames,
String[] optionValues,
String... additionalVMOpts) throws Throwable {
List<String> vmOpts = new ArrayList<>(); if (optionNames == null || optionValues == null || optionNames.length != optionValues.length) { thrownew 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");
/** * 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.
*/ publicstaticvoid 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.
*/ publicstaticvoid 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.
*/ publicstaticvoid verifyOptionValueForSameVM(String optionName,
String expectedValue, String optionErrorString,
String... additionalVMOpts) throws Throwable {
List<String> finalOptions = new ArrayList<>();
finalOptions.add(CommandLineOptionTest.getVMTypeOption());
String extraFlagForEmulated = CommandLineOptionTest.getVMTypeOptionForEmulated(); if (extraFlagForEmulated != null) {
finalOptions.add(extraFlagForEmulated);
}
Collections.addAll(finalOptions, additionalVMOpts);
/** * 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
*/ publicstatic 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
*/ publicstatic 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
*/ publicstatic String prepareFlag(String name, String value) { if (value.equals("+") || value.equalsIgnoreCase("true")) { return"-XX:+" + name;
} elseif (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
*/ publicstatic 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
*/ publicstatic 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
*/ publicstatic 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.
*/ privatestatic String getVMTypeOption() { if (Platform.isServer()) { return"-server";
} elseif (Platform.isClient()) { return"-client";
} elseif (Platform.isMinimal()) { return"-minimal";
} elseif (Platform.isZero()) { return"-zero";
} thrownew RuntimeException("Unknown VM mode.");
}
/** * @return addtional VMoptions(Emulated related) required to start a new VM with the same type as current.
*/ privatestatic String getVMTypeOptionForEmulated() { if (Platform.isServer() && !Platform.isEmulatedClient()) { return"-XX:-NeverActAsServerClassMachine";
} elseif (Platform.isEmulatedClient()) { return"-XX:+NeverActAsServerClassMachine";
} returnnull;
}
privatefinal 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.
*/ publicfinalvoid test() throws Throwable { if (predicate.getAsBoolean()) {
runTestCases();
}
}
/** * @throws Throwable if some issue happened during test cases execution.
*/ protectedabstractvoid runTestCases() throws Throwable;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.