1 /* 2 * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 package compiler.rtm.cli; 26 27 import jdk.test.lib.ExitCode; 28 import jdk.test.lib.Platform; 29 import jdk.test.lib.cli.CommandLineOptionTest; 30 31 import java.util.function.BooleanSupplier; 32 33 /** 34 * Base for all RTM-related CLI tests. 35 */ 36 public abstract class RTMGenericCommandLineOptionTest 37 extends CommandLineOptionTest { 38 protected static final String RTM_INSTR_ERROR 39 = "RTM instructions are not available on this CPU"; 40 protected static final String RTM_UNSUPPORTED_VM_ERROR 41 = "RTM locking optimization is not supported in this VM"; 42 protected static final String RTM_ABORT_RATIO_WARNING 43 = "RTMAbortRatio must be in the range 0 to 100, resetting it to 50"; 44 protected static final String RTM_FOR_STACK_LOCKS_WARNING 45 = "UseRTMForStackLocks flag should be off when UseRTMLocking " 46 + "flag is off"; 47 protected static final String RTM_COUNT_INCR_WARNING 48 = "RTMTotalCountIncrRate must be a power of 2, resetting it to 64"; 49 protected static final String RTM_BIASED_LOCKING_WARNING 50 = "Biased locking is not supported with RTM locking; " 51 + "ignoring UseBiasedLocking flag"; 52 53 protected final String optionName; 54 protected final String errorMessage; 55 protected final String experimentalOptionError; 56 protected final boolean isExperimental; 57 protected final boolean isBoolean; 58 protected final String defaultValue; 59 protected final String[] optionValues; 60 61 /** 62 * Constructs new genetic RTM CLI test, for option {@code optionName} which 63 * has default value {@code defaultValue}. Test cases will use option's 64 * values passed via {@code optionValues} for verification of correct 65 * option processing. 66 * 67 * Test constructed using this ctor will be started on any cpu regardless 68 * it's architecture and supported/unsupported features. 69 * 70 * @param predicate predicate responsible for test's preconditions check 71 * @param optionName name of option to be tested 72 * @param isBoolean {@code true} if option is binary 73 * @param isExperimental {@code true} if option is experimental 74 * @param defaultValue default value of tested option 75 * @param optionValues different option values 76 */ 77 public RTMGenericCommandLineOptionTest(BooleanSupplier predicate, 78 String optionName, boolean isBoolean, boolean isExperimental, 79 String defaultValue, String... optionValues) { 80 super(predicate); 81 this.optionName = optionName; 82 this.isExperimental = isExperimental; 83 this.isBoolean = isBoolean; 84 this.defaultValue = defaultValue; 85 this.optionValues = optionValues; 86 this.errorMessage = CommandLineOptionTest. 87 getUnrecognizedOptionErrorMessage(optionName); 88 this.experimentalOptionError = CommandLineOptionTest. 89 getExperimentalOptionErrorMessage(optionName); 90 } 91 92 @Override 93 public void runTestCases() throws Throwable { 94 if (Platform.isX86() || Platform.isX64() || Platform.isPPC()) { 95 if (Platform.isServer()) { 96 runX86SupportedVMTestCases(); 97 } else { 98 runX86UnsupportedVMTestCases(); 99 } 100 } else { 101 runNonX86TestCases(); 102 } 103 } 104 105 /** 106 * Runs test cases on X86 CPU if VM supports RTM locking. 107 * @throws Throwable 108 */ 109 protected void runX86SupportedVMTestCases() throws Throwable { 110 runGenericX86TestCases(); 111 } 112 113 /** 114 * Runs test cases on X86 CPU if VM does not support RTM locking. 115 * @throws Throwable 116 */ 117 protected void runX86UnsupportedVMTestCases() throws Throwable { 118 runGenericX86TestCases(); 119 } 120 121 /** 122 * Runs test cases on non-X86 CPU. 123 * @throws Throwable 124 */ 125 protected void runNonX86TestCases() throws Throwable { 126 CommandLineOptionTest.verifySameJVMStartup( 127 new String[] { errorMessage }, null, 128 String.format("Option '%s' should be unknown on non-X86CPUs.%n" 129 + "JVM startup should fail", optionName), "", ExitCode.FAIL, 130 prepareOptionValue(defaultValue)); 131 } 132 133 /** 134 * Runs generic X86 test cases. 135 * @throws Throwable 136 */ 137 protected void runGenericX86TestCases() throws Throwable { 138 verifyJVMStartup(); 139 verifyOptionValues(); 140 } 141 142 protected void verifyJVMStartup() throws Throwable { 143 String optionValue = prepareOptionValue(defaultValue); 144 String shouldFailMessage = String.format("VM option '%s' is " 145 + "experimental.%nVM startup expected to fail without " 146 + "-XX:+UnlockExperimentalVMOptions option", optionName); 147 String shouldPassMessage = String.format("VM option '%s' is " 148 + "experimental%nVM startup should pass with " 149 + "-XX:+UnlockExperimentalVMOptions option", optionName); 150 if (isExperimental) { 151 // verify that option is experimental 152 CommandLineOptionTest.verifySameJVMStartup( 153 new String[] { experimentalOptionError }, 154 new String[] { errorMessage }, shouldFailMessage, 155 shouldFailMessage, ExitCode.FAIL, optionValue); 156 // verify that it could be passed if experimental options 157 // are unlocked 158 CommandLineOptionTest.verifySameJVMStartup(null, 159 new String[] { 160 experimentalOptionError, 161 errorMessage 162 }, 163 shouldPassMessage, 164 "JVM should start without any warnings or errors", 165 ExitCode.OK, 166 CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, 167 optionValue); 168 } else { 169 // verify that option could be passed 170 CommandLineOptionTest.verifySameJVMStartup(null, 171 new String[]{errorMessage}, 172 String.format("VM startup shuld pass with '%s' option", 173 optionName), 174 "JVM should start without any warnings or errors", 175 ExitCode.OK, optionValue); 176 } 177 } 178 179 protected void verifyOptionValues() throws Throwable { 180 // verify default value 181 if (isExperimental) { 182 CommandLineOptionTest.verifyOptionValueForSameVM(optionName, 183 defaultValue, 184 String.format("Option '%s' is expected to have '%s' " 185 + "default value", optionName, defaultValue), 186 CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); 187 } else { 188 CommandLineOptionTest.verifyOptionValueForSameVM(optionName, 189 defaultValue, 190 String.format("Option '%s' is expected to have '%s' " 191 + "default value", optionName, defaultValue)); 192 } 193 // verify other specified option values 194 if (optionValues == null) { 195 return; 196 } 197 198 for (String value : optionValues) { 199 if (isExperimental) { 200 CommandLineOptionTest.verifyOptionValueForSameVM(optionName, 201 value, 202 String.format("Option '%s' is set to have '%s' value", 203 optionName, value), 204 CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, 205 prepareOptionValue(value)); 206 } else { 207 CommandLineOptionTest.verifyOptionValueForSameVM(optionName, 208 value, 209 String.format("Option '%s' is set to have '%s' value", 210 optionName, value), prepareOptionValue(value)); 211 } 212 } 213 } 214 215 protected String prepareOptionValue(String value) { 216 if (isBoolean) { 217 return CommandLineOptionTest.prepareBooleanFlag(optionName, 218 Boolean.valueOf(value)); 219 } else { 220 return String.format("-XX:%s=%s", optionName, value); 221 } 222 } 223 }