8059623: JEP-JDK-8043304: Test task: command line options tests

Reviewed-by: twisti, thartmann, goetz, iignatyev
This commit is contained in:
Filipp Zhinkin 2014-12-26 14:33:23 +03:00
parent 80613b8656
commit f70b5b2e9c
11 changed files with 1123 additions and 0 deletions

View file

@ -0,0 +1,182 @@
/*
* Copyright (c) 2014, 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 com.oracle.java.testlibrary.ExitCode;
import com.oracle.java.testlibrary.Platform;
import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
import common.CodeCacheOptions;
import sun.hotspot.code.BlobType;
/**
* @test
* @bug 8015774
* @summary Verify SegmentedCodeCache option's processing
* @library /testlibrary /../../test/lib
* @build TestSegmentedCodeCacheOption com.oracle.java.testlibrary.*
* @run main TestSegmentedCodeCacheOption
*/
public class TestSegmentedCodeCacheOption {
private static final String INT_MODE = "-Xint";
private static final String TIERED_COMPILATION = "TieredCompilation";
private static final String SEGMENTED_CODE_CACHE = "SegmentedCodeCache";
private static final String USE_SEGMENTED_CODE_CACHE
= CommandLineOptionTest.prepareBooleanFlag(SEGMENTED_CODE_CACHE,
true);
private static final long THRESHOLD_CC_SIZE_VALUE
= CodeCacheOptions.mB(240);
private static final long BELOW_THRESHOLD_CC_SIZE
= THRESHOLD_CC_SIZE_VALUE - CodeCacheOptions.mB(1);
private static final String[] UNEXPECTED_MESSAGES = new String[] {
".*" + SEGMENTED_CODE_CACHE + ".*"
};
private static enum TestCase {
JVM_STARTUP {
@Override
public void run() throws Throwable {
// There should be no errors when we're trying to enable SCC ...
String testCaseWarningMessage = "JVM output should not contain "
+ "any warnings related to " + SEGMENTED_CODE_CACHE;
String testCaseExitCodeMessage = "JVM should start without any "
+ "issues with " + USE_SEGMENTED_CODE_CACHE;
CommandLineOptionTest.verifySameJVMStartup(
/* expectedMessages */ null, UNEXPECTED_MESSAGES,
testCaseExitCodeMessage, testCaseWarningMessage,
ExitCode.OK, USE_SEGMENTED_CODE_CACHE);
// ... and when we're trying to enable it w/o TieredCompilation
testCaseExitCodeMessage = "Disabled tiered compilation should "
+ "not cause startup failure w/ "
+ USE_SEGMENTED_CODE_CACHE;
CommandLineOptionTest.verifySameJVMStartup(
/* expectedMessages */ null, UNEXPECTED_MESSAGES,
testCaseExitCodeMessage, testCaseWarningMessage,
ExitCode.OK, USE_SEGMENTED_CODE_CACHE,
CommandLineOptionTest.prepareBooleanFlag(
TIERED_COMPILATION, false));
// ... and even w/ Xint.
testCaseExitCodeMessage = "It should be possible to use "
+ USE_SEGMENTED_CODE_CACHE + " in interpreted mode "
+ "without any errors.";
CommandLineOptionTest.verifyJVMStartup(
/* expected messages */ null, UNEXPECTED_MESSAGES,
testCaseExitCodeMessage, testCaseWarningMessage,
ExitCode.OK, false, INT_MODE, USE_SEGMENTED_CODE_CACHE);
}
},
OPTION_VALUES_GENERIC {
@Override
public void run() throws Throwable {
// SCC is disabled w/o TieredCompilation by default
String errorMessage = SEGMENTED_CODE_CACHE
+ " should be disabled by default when tiered "
+ "compilation is disabled";
CommandLineOptionTest.verifyOptionValueForSameVM(
SEGMENTED_CODE_CACHE, "false", errorMessage,
CommandLineOptionTest.prepareBooleanFlag(
TIERED_COMPILATION, false));
// SCC is disabled by default when ReservedCodeCacheSize is too
// small
errorMessage = String.format("%s should be disabled bu default "
+ "when %s value is too small.", SEGMENTED_CODE_CACHE,
BlobType.All.sizeOptionName);
CommandLineOptionTest.verifyOptionValueForSameVM(
SEGMENTED_CODE_CACHE, "false", errorMessage,
CommandLineOptionTest.prepareNumericFlag(
BlobType.All.sizeOptionName,
BELOW_THRESHOLD_CC_SIZE));
// SCC could be explicitly enabled w/ Xint
errorMessage = String.format("It should be possible to "
+ "explicitly enable %s in interpreted mode.",
SEGMENTED_CODE_CACHE);
CommandLineOptionTest.verifyOptionValue(SEGMENTED_CODE_CACHE,
"true", errorMessage, false, INT_MODE,
USE_SEGMENTED_CODE_CACHE);
// SCC could be explicitly enabled w/o TieredCompilation and w/
// small ReservedCodeCacheSize value
errorMessage = String.format("It should be possible to "
+ "explicitly enable %s with small %s and "
+ "disabled tiered comp.", SEGMENTED_CODE_CACHE,
BlobType.All.sizeOptionName);
CommandLineOptionTest.verifyOptionValueForSameVM(
SEGMENTED_CODE_CACHE, "true", errorMessage,
CommandLineOptionTest.prepareBooleanFlag(
TIERED_COMPILATION, false),
CommandLineOptionTest.prepareNumericFlag(
BlobType.All.sizeOptionName,
BELOW_THRESHOLD_CC_SIZE),
USE_SEGMENTED_CODE_CACHE);
}
},
OPTION_VALUES_SERVER_SPECIFIC {
@Override
public boolean isApplicable() {
return Platform.isServer() && Platform.isTieredSupported();
}
@Override
public void run() throws Throwable {
// SCC is enabled by default when TieredCompilation is on and
// ReservedCodeCacheSize is large enough
String errorMessage = String.format("Large enough %s and "
+ "enabled tiered compilation should enable %s "
+ "by default.", BlobType.All.sizeOptionName,
SEGMENTED_CODE_CACHE);
CommandLineOptionTest.verifyOptionValueForSameVM(
SEGMENTED_CODE_CACHE, "true", errorMessage,
CommandLineOptionTest.prepareNumericFlag(
BlobType.All.sizeOptionName,
THRESHOLD_CC_SIZE_VALUE),
CommandLineOptionTest.prepareBooleanFlag(
TIERED_COMPILATION, true));
}
};
TestCase() {
}
public boolean isApplicable() {
return true;
}
public abstract void run() throws Throwable;
}
public static void main(String args[]) throws Throwable {
for (TestCase testCase : TestCase.values()) {
if (testCase.isApplicable()) {
System.out.println("Running test case: " + testCase.name());
testCase.run();
} else {
System.out.println("Test case skipped: " + testCase.name());
}
}
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2014, 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 codeheapsize;
import com.oracle.java.testlibrary.ExitCode;
import com.oracle.java.testlibrary.Platform;
import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
import common.CodeCacheCLITestCase;
import common.CodeCacheOptions;
import sun.hotspot.code.BlobType;
/**
* Test case runner aimed to verify that NonNMethodCodeHeapSize smaller than
* CodeCacheMinimumUseSpace cause JVM startup failure.
*/
public class CodeCacheFreeSpaceRunner implements CodeCacheCLITestCase.Runner {
private static final String CC_MIN_USE_SPACE = "CodeCacheMinimumUseSpace";
private static final String TOO_SMALL_NMETHOD_CH_ERROR
= "Invalid NonNMethodCodeHeapSize.*";
private static final long MULTIPLIER = Platform.isDebugBuild() ? 3L : 1L;
@Override
public void run(CodeCacheCLITestCase.Description testCaseDescription,
CodeCacheOptions options) throws Throwable {
long ccMinUseSpace = ((options.nonNmethods - 1) / MULTIPLIER + 1);
String exitCodeErrorMessage = String.format("JVM startup should fail "
+ "if %s's value lower then %s.",
BlobType.NonNMethod.sizeOptionName, CC_MIN_USE_SPACE);
String vmOutputErrorMessage = String.format("JVM's output should "
+ "contain appropriate error message when %s lower "
+ "then %s.", BlobType.NonNMethod.sizeOptionName,
CC_MIN_USE_SPACE);
CommandLineOptionTest.verifySameJVMStartup(
new String[]{ TOO_SMALL_NMETHOD_CH_ERROR },
/* unexpected messages */ null,
exitCodeErrorMessage, vmOutputErrorMessage, ExitCode.FAIL,
testCaseDescription.getTestOptions(options,
CommandLineOptionTest.prepareNumericFlag(
CC_MIN_USE_SPACE, ccMinUseSpace + 1)));
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2014, 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 codeheapsize;
import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
import common.CodeCacheCLITestCase;
import common.CodeCacheOptions;
import sun.hotspot.code.BlobType;
/**
* Test case runner aimed to verify that all four options related to code cache
* sizing have correct values.
*/
public class GenericCodeHeapSizeRunner implements CodeCacheCLITestCase.Runner {
@Override
public void run(CodeCacheCLITestCase.Description testCaseDescription,
CodeCacheOptions options) throws Throwable {
CodeCacheOptions expectedValues
= options.mapOptions(testCaseDescription.involvedCodeHeaps);
CommandLineOptionTest.verifyOptionValueForSameVM(
BlobType.All.sizeOptionName,
Long.toString(expectedValues.reserved),
String.format("%s should have value %d.",
BlobType.All.sizeOptionName, expectedValues.reserved),
testCaseDescription.getTestOptions(options));
CommandLineOptionTest.verifyOptionValueForSameVM(
BlobType.NonNMethod.sizeOptionName,
Long.toString(expectedValues.nonNmethods),
String.format("%s should have value %d.",
BlobType.NonNMethod.sizeOptionName,
expectedValues.nonNmethods),
testCaseDescription.getTestOptions(options));
CommandLineOptionTest.verifyOptionValueForSameVM(
BlobType.MethodNonProfiled.sizeOptionName,
Long.toString(expectedValues.nonProfiled),
String.format("%s should have value %d.",
BlobType.MethodNonProfiled.sizeOptionName,
expectedValues.nonProfiled),
testCaseDescription.getTestOptions(options));
CommandLineOptionTest.verifyOptionValueForSameVM(
BlobType.MethodProfiled.sizeOptionName,
Long.toString(expectedValues.profiled),
String.format("%s should have value %d.",
BlobType.MethodProfiled.sizeOptionName,
expectedValues.profiled),
testCaseDescription.getTestOptions(options));
}
}

View file

@ -0,0 +1,133 @@
/*
* Copyright (c) 2014, 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 codeheapsize;
import common.CodeCacheCLITestCase;
import common.CodeCacheOptions;
import com.oracle.java.testlibrary.ExitCode;
import com.oracle.java.testlibrary.Utils;
import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
import sun.hotspot.code.BlobType;
import java.util.Random;
/**
* Test case runner aimed to verify option's consistency.
*/
public class JVMStartupRunner implements CodeCacheCLITestCase.Runner {
private static final String INCONSISTENT_CH_SIZES_ERROR
= "Invalid code heap sizes.*";
@Override
public void run(CodeCacheCLITestCase.Description testCaseDescription,
CodeCacheOptions options) throws Throwable {
// Everything should be fine when
// sum(all code heap sizes) == reserved CC size
CommandLineOptionTest.verifySameJVMStartup(/* expected messages */ null,
new String[]{ INCONSISTENT_CH_SIZES_ERROR },
"JVM startup should not fail with consistent code heap sizes",
"JVM output should not contain warning about inconsistent code "
+ "heap sizes", ExitCode.OK, options.prepareOptions());
verifySingleInconsistentValue(options);
verifyAllInconsistentValues(options);
}
/**
* Verifies that if at least one of three options will have value, such
* that sum of all three values will be inconsistent, then JVM startup will
* fail.
*/
private static void verifySingleInconsistentValue(CodeCacheOptions options)
throws Throwable {
verifyHeapSizesSum(options.reserved,
scaleCodeHeapSize(options.profiled), options.nonProfiled,
options.nonNmethods);
verifyHeapSizesSum(options.reserved, options.profiled,
scaleCodeHeapSize(options.nonProfiled), options.nonNmethods);
verifyHeapSizesSum(options.reserved, options.profiled,
options.nonProfiled, scaleCodeHeapSize(options.nonNmethods));
}
/**
* Verifies that if all three options will have values such that their sum
* is inconsistent with ReservedCodeCacheSize value, then JVM startup will
* fail.
*/
private static void verifyAllInconsistentValues(CodeCacheOptions options)
throws Throwable {
long profiled = options.profiled;
long nonProfiled = options.nonProfiled;
long nonNMethods = options.nonNmethods;
while (options.reserved == profiled + nonProfiled + nonNMethods) {
profiled = scaleCodeHeapSize(profiled);
nonProfiled = scaleCodeHeapSize(nonProfiled);
nonNMethods = scaleCodeHeapSize(nonNMethods);
}
verifyHeapSizesSum(options.reserved, profiled, nonProfiled,
nonNMethods);
}
private static void verifyHeapSizesSum(long reserved, long profiled,
long nonProfiled, long nonNmethods) throws Throwable {
// JVM startup expected to fail when
// sum(all code heap sizes) != reserved CC size
CommandLineOptionTest.verifySameJVMStartup(
new String[]{ INCONSISTENT_CH_SIZES_ERROR },
/* unexpected messages */ null,
"JVM startup should fail with inconsistent code heap size.",
"JVM output should contain appropriate error message of code "
+ "heap sizes are inconsistent",
ExitCode.FAIL,
CommandLineOptionTest.prepareBooleanFlag(
CodeCacheOptions.SEGMENTED_CODE_CACHE, true),
CommandLineOptionTest.prepareNumericFlag(
BlobType.All.sizeOptionName, reserved),
CommandLineOptionTest.prepareNumericFlag(
BlobType.MethodProfiled.sizeOptionName, profiled),
CommandLineOptionTest.prepareNumericFlag(
BlobType.MethodNonProfiled.sizeOptionName, nonProfiled),
CommandLineOptionTest.prepareNumericFlag(
BlobType.NonNMethod.sizeOptionName, nonNmethods));
}
/**
* Returns {@code unscaledSize} value scaled by a random factor from
* range (1, 2). If {@code unscaledSize} is not 0, then this
* method will return value that won't be equal to {@code unscaledSize}.
*
* @param unscaledSize The value to be scaled.
* @return {@code unscaledSize} value scaled by a factor from range (1, 2).
*/
private static long scaleCodeHeapSize(long unscaledSize) {
Random random = Utils.getRandomInstance();
long scaledSize = unscaledSize;
while (scaledSize == unscaledSize && unscaledSize != 0) {
float scale = 1.0f + random.nextFloat();
scaledSize = (long) Math.ceil(scale * unscaledSize);
}
return scaledSize;
}
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2014, 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 codeheapsize;
import com.oracle.java.testlibrary.Platform;
import common.CodeCacheCLITestBase;
import common.CodeCacheCLITestCase;
import sun.hotspot.code.BlobType;
import java.util.EnumSet;
/**
* @test
* @bug 8015774
* @summary Verify processing of options related to code heaps sizing.
* @library /testlibrary .. /../../test/lib
* @build TestCodeHeapSizeOptions com.oracle.java.testlibrary.* codeheapsize.*
* common.*
* @run main/timeout=240 codeheapsize.TestCodeHeapSizeOptions
*/
public class TestCodeHeapSizeOptions extends CodeCacheCLITestBase {
private static final CodeCacheCLITestCase JVM_STARTUP
= new CodeCacheCLITestCase(new CodeCacheCLITestCase.Description(
options -> options.segmented,
EnumSet.noneOf(BlobType.class)),
new JVMStartupRunner());
private static final CodeCacheCLITestCase CODE_CACHE_FREE_SPACE
= new CodeCacheCLITestCase(new CodeCacheCLITestCase.Description(
options -> options.segmented
&& Platform.isDebugBuild(),
EnumSet.noneOf(BlobType.class)),
new CodeCacheFreeSpaceRunner());
private static final GenericCodeHeapSizeRunner GENERIC_RUNNER
= new GenericCodeHeapSizeRunner();
private TestCodeHeapSizeOptions() {
super(CodeCacheCLITestBase.OPTIONS_SET,
new CodeCacheCLITestCase(CodeCacheCLITestCase
.CommonDescriptions.INT_MODE.description,
GENERIC_RUNNER),
new CodeCacheCLITestCase(CodeCacheCLITestCase
.CommonDescriptions.NON_TIERED.description,
GENERIC_RUNNER),
new CodeCacheCLITestCase(CodeCacheCLITestCase
.CommonDescriptions.TIERED_LEVEL_0.description,
GENERIC_RUNNER),
new CodeCacheCLITestCase(CodeCacheCLITestCase
.CommonDescriptions.TIERED_LEVEL_1.description,
GENERIC_RUNNER),
new CodeCacheCLITestCase(CodeCacheCLITestCase
.CommonDescriptions.TIERED_LEVEL_4.description,
GENERIC_RUNNER),
JVM_STARTUP,
CODE_CACHE_FREE_SPACE);
}
public static void main(String args[]) throws Throwable {
new TestCodeHeapSizeOptions().runTestCases();
}
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2014, 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 common;
/**
* Base for code cache related command line options tests.
*/
public class CodeCacheCLITestBase {
public static final CodeCacheOptions[] OPTIONS_SET
= new CodeCacheOptions[] {
new CodeCacheOptions(CodeCacheOptions.mB(60),
CodeCacheOptions.mB(20), CodeCacheOptions.mB(20),
CodeCacheOptions.mB(20)),
new CodeCacheOptions(CodeCacheOptions.mB(200),
CodeCacheOptions.mB(75), CodeCacheOptions.mB(75),
CodeCacheOptions.mB(50)),
new CodeCacheOptions(CodeCacheOptions.mB(300),
CodeCacheOptions.mB(100), CodeCacheOptions.mB(100),
CodeCacheOptions.mB(100)),
new CodeCacheOptions(CodeCacheOptions.mB(60)),
new CodeCacheOptions(CodeCacheOptions.mB(200)),
new CodeCacheOptions(CodeCacheOptions.mB(300))
};
private final CodeCacheCLITestCase[] testCases;
private final CodeCacheOptions[] options;
public CodeCacheCLITestBase(CodeCacheOptions[] options,
CodeCacheCLITestCase... testCases) {
this.testCases = testCases;
this.options = options;
}
protected void runTestCases() throws Throwable {
for (CodeCacheCLITestCase testCase : testCases) {
for (CodeCacheOptions opts : options) {
testCase.run(opts);
}
}
}
}

View file

@ -0,0 +1,165 @@
/*
* Copyright (c) 2014, 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 common;
import com.oracle.java.testlibrary.Platform;
import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
import sun.hotspot.code.BlobType;
import java.util.Collections;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Function;
/**
* Code cache related command line option test case consisting of description
* of code heaps used during test case run and additional options that should
* be passed to JVM and runner aimed to perform actual testing based on the
* description.
*/
public class CodeCacheCLITestCase {
private static final Function<CodeCacheOptions, Boolean> ONLY_SEGMENTED
= options -> options.segmented;
private static final Function<CodeCacheOptions, Boolean> SEGMENTED_SERVER
= ONLY_SEGMENTED.andThen(isSegmented -> isSegmented
&& Platform.isServer() && Platform.isTieredSupported());
private static final String USE_INT_MODE = "-Xint";
private static final String SEGMENTED_CODE_CACHE = "SegmentedCodeCache";
private static final String TIERED_COMPILATION = "TieredCompilation";
private static final String TIERED_STOP_AT = "TieredStopAtLevel";
private final Description description;
private final Runner runner;
public CodeCacheCLITestCase(Description description, Runner runner) {
this.description = description;
this.runner = runner;
}
public final void run(CodeCacheOptions options) throws Throwable {
if (description.isApplicable(options)) {
runner.run(description, options);
}
}
public enum CommonDescriptions {
/**
* Verifies that in interpreted mode PrintCodeCache output contains
* only NonNMethod code heap.
*/
INT_MODE(ONLY_SEGMENTED, EnumSet.of(BlobType.NonNMethod), USE_INT_MODE),
/**
* Verifies that with disabled SegmentedCodeCache PrintCodeCache output
* contains only CodeCache's entry.
*/
NON_SEGMENTED(options -> !options.segmented, EnumSet.of(BlobType.All),
CommandLineOptionTest.prepareBooleanFlag(SEGMENTED_CODE_CACHE,
false)),
/**
* Verifies that with disabled tiered compilation and enabled segmented
* code cache PrintCodeCache output does not contain information about
* profiled-nmethods heap and non-segmented CodeCache.
*/
NON_TIERED(ONLY_SEGMENTED,
EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled),
CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION,
false)),
/**
* Verifies that with TieredStopAtLevel=0 PrintCodeCache output will
* contain information about non-nmethods and non-profiled nmethods
* heaps only.
*/
TIERED_LEVEL_0(SEGMENTED_SERVER,
EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled),
CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION,
true),
CommandLineOptionTest.prepareNumericFlag(TIERED_STOP_AT, 0)),
/**
* Verifies that with TieredStopAtLevel=1 PrintCodeCache output will
* contain information about non-nmethods and non-profiled nmethods
* heaps only.
*/
TIERED_LEVEL_1(SEGMENTED_SERVER,
EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled),
CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION,
true),
CommandLineOptionTest.prepareNumericFlag(TIERED_STOP_AT, 1)),
/**
* Verifies that with TieredStopAtLevel=4 PrintCodeCache output will
* contain information about all three code heaps.
*/
TIERED_LEVEL_4(SEGMENTED_SERVER,
EnumSet.complementOf(EnumSet.of(BlobType.All)),
CommandLineOptionTest.prepareBooleanFlag(TIERED_COMPILATION,
true),
CommandLineOptionTest.prepareNumericFlag(TIERED_STOP_AT, 4));
CommonDescriptions(Function<CodeCacheOptions, Boolean> predicate,
EnumSet<BlobType> involvedCodeHeaps,
String... additionalOptions) {
this.description = new Description(predicate,
involvedCodeHeaps, additionalOptions);
}
public final Description description;
}
public static class Description {
public final EnumSet<BlobType> involvedCodeHeaps;
private final String[] testCaseSpecificOptions;
private final Function<CodeCacheOptions, Boolean> predicate;
public Description(Function<CodeCacheOptions, Boolean> predicate,
EnumSet<BlobType> involvedCodeHeaps,
String... testCaseSpecificOptions) {
this.involvedCodeHeaps = involvedCodeHeaps;
this.testCaseSpecificOptions = testCaseSpecificOptions;
this.predicate = predicate;
}
public boolean isApplicable(CodeCacheOptions options) {
return predicate.apply(options);
}
public CodeCacheOptions expectedValues(CodeCacheOptions options) {
return options.mapOptions(involvedCodeHeaps);
}
public String[] getTestOptions(CodeCacheOptions codeCacheOptions,
String... additionalOptions) {
List<String> options = new LinkedList<>();
Collections.addAll(options, testCaseSpecificOptions);
Collections.addAll(options, additionalOptions);
return codeCacheOptions.prepareOptions(
options.toArray(new String[options.size()]));
}
}
public static interface Runner {
public void run(Description testCaseDescription,
CodeCacheOptions options) throws Throwable;
}
}

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2014, 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 common;
import sun.hotspot.code.BlobType;
import java.util.Arrays;
public class CodeCacheInfoFormatter {
private static final String DEFAULT_SIZE_FORMAT = "[0-9]+Kb";
private BlobType heap = null;
private String size = DEFAULT_SIZE_FORMAT;
private String used = DEFAULT_SIZE_FORMAT;
private String maxUsed = DEFAULT_SIZE_FORMAT;
private String free = DEFAULT_SIZE_FORMAT;
public static CodeCacheInfoFormatter forHeap(BlobType heap) {
return new CodeCacheInfoFormatter(heap);
}
public static String[] forHeaps(BlobType... heaps) {
return Arrays.stream(heaps)
.map(CodeCacheInfoFormatter::forHeap)
.map(CodeCacheInfoFormatter::getInfoString)
.toArray(String[]::new);
}
private static String formatSize(long suffix) {
return String.format("%dKb", suffix / 1024);
}
private CodeCacheInfoFormatter(BlobType heap) {
this.heap = heap;
}
public CodeCacheInfoFormatter withSize(long size) {
this.size = CodeCacheInfoFormatter.formatSize(size);
return this;
}
public CodeCacheInfoFormatter withUsed(long used) {
this.used = CodeCacheInfoFormatter.formatSize(used);
return this;
}
public CodeCacheInfoFormatter withMaxUsed(long maxUsed) {
this.maxUsed = CodeCacheInfoFormatter.formatSize(maxUsed);
return this;
}
public CodeCacheInfoFormatter withFree(long free) {
this.free = CodeCacheInfoFormatter.formatSize(free);
return this;
}
public String getInfoString() {
return String.format("%s: size=%s used=%s max_used=%s free=%s",
heap.beanName, size, used, maxUsed, free);
}
}

View file

@ -0,0 +1,129 @@
/*
* Copyright (c) 2014, 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 common;
import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
import sun.hotspot.code.BlobType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
public class CodeCacheOptions {
public static final String SEGMENTED_CODE_CACHE = "SegmentedCodeCache";
private static final EnumSet<BlobType> NON_SEGMENTED_HEAPS
= EnumSet.of(BlobType.All);
private static final EnumSet<BlobType> ALL_SEGMENTED_HEAPS
= EnumSet.complementOf(NON_SEGMENTED_HEAPS);
private static final EnumSet<BlobType> SEGMENTED_HEAPS_WO_PROFILED
= EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled);
private static final EnumSet<BlobType> ONLY_NON_METHODS_HEAP
= EnumSet.of(BlobType.NonNMethod);
public final long reserved;
public final long nonNmethods;
public final long nonProfiled;
public final long profiled;
public final boolean segmented;
public static long mB(long val) {
return CodeCacheOptions.kB(val) * 1024L;
}
public static long kB(long val) {
return val * 1024L;
}
public CodeCacheOptions(long reserved) {
this.reserved = reserved;
this.nonNmethods = 0;
this.nonProfiled = 0;
this.profiled = 0;
this.segmented = false;
}
public CodeCacheOptions(long reserved, long nonNmethods, long nonProfiled,
long profiled) {
this.reserved = reserved;
this.nonNmethods = nonNmethods;
this.nonProfiled = nonProfiled;
this.profiled = profiled;
this.segmented = true;
}
public long sizeForHeap(BlobType heap) {
switch (heap) {
case All:
return this.reserved;
case NonNMethod:
return this.nonNmethods;
case MethodNonProfiled:
return this.nonProfiled;
case MethodProfiled:
return this.profiled;
default:
throw new Error("Unknown heap: " + heap.name());
}
}
public String[] prepareOptions(String... additionalOptions) {
List<String> options = new ArrayList<>();
Collections.addAll(options, additionalOptions);
Collections.addAll(options,
CommandLineOptionTest.prepareBooleanFlag(
SEGMENTED_CODE_CACHE, segmented),
CommandLineOptionTest.prepareNumericFlag(
BlobType.All.sizeOptionName, reserved));
if (segmented) {
Collections.addAll(options,
CommandLineOptionTest.prepareNumericFlag(
BlobType.NonNMethod.sizeOptionName, nonNmethods),
CommandLineOptionTest.prepareNumericFlag(
BlobType.MethodNonProfiled.sizeOptionName,
nonProfiled),
CommandLineOptionTest.prepareNumericFlag(
BlobType.MethodProfiled.sizeOptionName, profiled));
}
return options.toArray(new String[options.size()]);
}
public CodeCacheOptions mapOptions(EnumSet<BlobType> involvedCodeHeaps) {
if (involvedCodeHeaps.isEmpty()
|| involvedCodeHeaps.equals(NON_SEGMENTED_HEAPS)
|| involvedCodeHeaps.equals(ALL_SEGMENTED_HEAPS)) {
return this;
} else if (involvedCodeHeaps.equals(SEGMENTED_HEAPS_WO_PROFILED)) {
return new CodeCacheOptions(reserved, nonNmethods,
profiled + nonProfiled, 0L);
} else if (involvedCodeHeaps.equals(ONLY_NON_METHODS_HEAP)) {
return new CodeCacheOptions(reserved, nonNmethods + profiled
+ nonProfiled, 0L, 0L);
} else {
throw new Error("Test bug: unexpected set of code heaps involved "
+ "into test.");
}
}
}

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2014, 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 printcodecache;
import com.oracle.java.testlibrary.ExitCode;
import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
import common.CodeCacheCLITestCase;
import common.CodeCacheInfoFormatter;
import common.CodeCacheOptions;
import sun.hotspot.code.BlobType;
import java.util.EnumSet;
import java.util.stream.Collectors;
/**
* Runner implementation aimed to verify PrintCodeCache output.
*/
public class PrintCodeCacheRunner implements CodeCacheCLITestCase.Runner {
private final boolean printCodeCache;
public PrintCodeCacheRunner(boolean printCodeCache) {
this.printCodeCache = printCodeCache;
}
public PrintCodeCacheRunner() {
this(true);
}
@Override
public void run(CodeCacheCLITestCase.Description testCaseDescription,
CodeCacheOptions options) throws Throwable {
CodeCacheOptions expectedValues
= testCaseDescription.expectedValues(options);
String[] expectedMessages
= testCaseDescription.involvedCodeHeaps.stream()
.map(heap -> CodeCacheInfoFormatter.forHeap(heap)
.withSize(expectedValues.sizeForHeap(heap)))
.map(CodeCacheInfoFormatter::getInfoString)
.toArray(String[]::new);
EnumSet<BlobType> unexpectedHeapsSet
= EnumSet.complementOf(testCaseDescription.involvedCodeHeaps);
String[] unexpectedMessages = CodeCacheInfoFormatter.forHeaps(
unexpectedHeapsSet.toArray(
new BlobType[unexpectedHeapsSet.size()]));
String description = String.format("JVM output should contain entries "
+ "for following code heaps: [%s] and should not contain "
+ "entries for following code heaps: [%s].",
testCaseDescription.involvedCodeHeaps.stream()
.map(BlobType::name)
.collect(Collectors.joining(", ")),
unexpectedHeapsSet.stream()
.map(BlobType::name)
.collect(Collectors.joining(", ")));
CommandLineOptionTest.verifySameJVMStartup(expectedMessages,
unexpectedMessages, "JVM startup failure is not expected, "
+ "since all options have allowed values", description,
ExitCode.OK,
testCaseDescription.getTestOptions(options,
CommandLineOptionTest.prepareBooleanFlag(
"PrintCodeCache", printCodeCache)));
}
}

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2014, 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 printcodecache;
import common.CodeCacheCLITestBase;
import common.CodeCacheCLITestCase;
import sun.hotspot.code.BlobType;
import java.util.EnumSet;
/**
* @test
* @bug 8015774
* @summary Verify that PrintCodeCache option print correct information.
* @library /testlibrary .. /../../test/lib
* @build TestPrintCodeCacheOption com.oracle.java.testlibrary.*
* printcodecache.* common.*
* @run main/timeout=240 printcodecache.TestPrintCodeCacheOption
*/
public class TestPrintCodeCacheOption extends CodeCacheCLITestBase {
private static final CodeCacheCLITestCase DISABLED_PRINT_CODE_CACHE
= new CodeCacheCLITestCase(new CodeCacheCLITestCase.Description(
options -> true, EnumSet.noneOf(BlobType.class)),
new PrintCodeCacheRunner(false));
private static final CodeCacheCLITestCase.Runner DEFAULT_RUNNER
= new PrintCodeCacheRunner();
private TestPrintCodeCacheOption() {
super(CodeCacheCLITestBase.OPTIONS_SET,
new CodeCacheCLITestCase(CodeCacheCLITestCase
.CommonDescriptions.INT_MODE.description,
DEFAULT_RUNNER),
new CodeCacheCLITestCase(CodeCacheCLITestCase
.CommonDescriptions.NON_SEGMENTED.description,
DEFAULT_RUNNER),
new CodeCacheCLITestCase(CodeCacheCLITestCase
.CommonDescriptions.NON_TIERED.description,
DEFAULT_RUNNER),
new CodeCacheCLITestCase(CodeCacheCLITestCase
.CommonDescriptions.TIERED_LEVEL_0.description,
DEFAULT_RUNNER),
new CodeCacheCLITestCase(CodeCacheCLITestCase
.CommonDescriptions.TIERED_LEVEL_1.description,
DEFAULT_RUNNER),
new CodeCacheCLITestCase(CodeCacheCLITestCase
.CommonDescriptions.TIERED_LEVEL_4.description,
DEFAULT_RUNNER),
DISABLED_PRINT_CODE_CACHE);
}
public static void main(String args[]) throws Throwable {
new TestPrintCodeCacheOption().runTestCases();
}
}