1/* 2 * Copyright (c) 2014, 2017, 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 24package compiler.rtm.cli; 25 26import jdk.test.lib.process.ExitCode; 27import jdk.test.lib.Platform; 28import jdk.test.lib.cli.CommandLineOptionTest; 29 30import java.util.function.BooleanSupplier; 31 32/** 33 * Base for all RTM-related CLI tests. 34 */ 35public abstract class RTMGenericCommandLineOptionTest { 36 37 protected static final String RTM_INSTR_ERROR 38 = "RTM instructions are not available on this CPU"; 39 protected static final String RTM_UNSUPPORTED_VM_ERROR 40 = "RTM locking optimization is not supported in this VM"; 41 protected static final String RTM_FOR_STACK_LOCKS_WARNING 42 = "UseRTMForStackLocks flag should be off when UseRTMLocking " 43 + "flag is off"; 44 protected static final String RTM_COUNT_INCR_WARNING 45 = "must be a power of 2, resetting it to 64"; 46 protected static final String RTM_BIASED_LOCKING_WARNING 47 = "Biased locking is not supported with RTM locking; " 48 + "ignoring UseBiasedLocking flag"; 49 50 protected final String optionName; 51 protected final String errorMessage; 52 protected final String experimentalOptionError; 53 protected final boolean isExperimental; 54 protected final boolean isBoolean; 55 protected final String defaultValue; 56 protected final String[] optionValues; 57 58 /** 59 * Constructs new genetic RTM CLI test, for option {@code optionName} which 60 * has default value {@code defaultValue}. Test cases will use option's 61 * values passed via {@code optionValues} for verification of correct 62 * option processing. 63 * 64 * Test constructed using this ctor will be started on any cpu regardless 65 * it's architecture and supported/unsupported features. 66 * 67 * @param optionName name of option to be tested 68 * @param isBoolean {@code true} if option is binary 69 * @param isExperimental {@code true} if option is experimental 70 * @param defaultValue default value of tested option 71 * @param optionValues different option values 72 */ 73 public RTMGenericCommandLineOptionTest( 74 String optionName, boolean isBoolean, boolean isExperimental, 75 String defaultValue, String... optionValues) { 76 this.optionName = optionName; 77 this.isExperimental = isExperimental; 78 this.isBoolean = isBoolean; 79 this.defaultValue = defaultValue; 80 this.optionValues = optionValues; 81 this.errorMessage = CommandLineOptionTest. 82 getUnrecognizedOptionErrorMessage(optionName); 83 this.experimentalOptionError = CommandLineOptionTest. 84 getExperimentalOptionErrorMessage(optionName); 85 } 86 87 public void runTestCases() throws Throwable { 88 if (Platform.isX86() || Platform.isX64() || Platform.isPPC()) { 89 if (Platform.isServer()) { 90 runX86SupportedVMTestCases(); 91 } else { 92 runX86UnsupportedVMTestCases(); 93 } 94 } else { 95 runNonX86TestCases(); 96 } 97 } 98 99 /** 100 * Runs test cases on X86 CPU if VM supports RTM locking. 101 * @throws Throwable 102 */ 103 protected void runX86SupportedVMTestCases() throws Throwable { 104 runGenericX86TestCases(); 105 } 106 107 /** 108 * Runs test cases on X86 CPU if VM does not support RTM locking. 109 * @throws Throwable 110 */ 111 protected void runX86UnsupportedVMTestCases() throws Throwable { 112 runGenericX86TestCases(); 113 } 114 115 /** 116 * Runs test cases on non-X86 CPU. 117 * @throws Throwable 118 */ 119 protected void runNonX86TestCases() throws Throwable { 120 CommandLineOptionTest.verifySameJVMStartup( 121 new String[] { errorMessage }, null, 122 String.format("Option '%s' should be unknown on non-X86CPUs.%n" 123 + "JVM startup should fail", optionName), "", ExitCode.FAIL, 124 prepareOptionValue(defaultValue)); 125 } 126 127 /** 128 * Runs generic X86 test cases. 129 * @throws Throwable 130 */ 131 protected void runGenericX86TestCases() throws Throwable { 132 verifyJVMStartup(); 133 verifyOptionValues(); 134 } 135 136 protected void verifyJVMStartup() throws Throwable { 137 String optionValue = prepareOptionValue(defaultValue); 138 String shouldFailMessage = String.format("VM option '%s' is " 139 + "experimental.%nVM startup expected to fail without " 140 + "-XX:+UnlockExperimentalVMOptions option", optionName); 141 String shouldPassMessage = String.format("VM option '%s' is " 142 + "experimental%nVM startup should pass with " 143 + "-XX:+UnlockExperimentalVMOptions option", optionName); 144 if (isExperimental) { 145 // verify that option is experimental 146 CommandLineOptionTest.verifySameJVMStartup( 147 new String[] { experimentalOptionError }, 148 new String[] { errorMessage }, shouldFailMessage, 149 shouldFailMessage, ExitCode.FAIL, optionValue); 150 // verify that it could be passed if experimental options 151 // are unlocked 152 CommandLineOptionTest.verifySameJVMStartup(null, 153 new String[] { 154 experimentalOptionError, 155 errorMessage 156 }, 157 shouldPassMessage, 158 "JVM should start without any warnings or errors", 159 ExitCode.OK, 160 CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, 161 optionValue); 162 } else { 163 // verify that option could be passed 164 CommandLineOptionTest.verifySameJVMStartup(null, 165 new String[]{errorMessage}, 166 String.format("VM startup shuld pass with '%s' option", 167 optionName), 168 "JVM should start without any warnings or errors", 169 ExitCode.OK, optionValue); 170 } 171 } 172 173 protected void verifyOptionValues() throws Throwable { 174 // verify default value 175 if (isExperimental) { 176 CommandLineOptionTest.verifyOptionValueForSameVM(optionName, 177 defaultValue, 178 String.format("Option '%s' is expected to have '%s' " 179 + "default value", optionName, defaultValue), 180 CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); 181 } else { 182 CommandLineOptionTest.verifyOptionValueForSameVM(optionName, 183 defaultValue, 184 String.format("Option '%s' is expected to have '%s' " 185 + "default value", optionName, defaultValue)); 186 } 187 // verify other specified option values 188 if (optionValues == null) { 189 return; 190 } 191 192 for (String value : optionValues) { 193 if (isExperimental) { 194 CommandLineOptionTest.verifyOptionValueForSameVM(optionName, 195 value, 196 String.format("Option '%s' is set to have '%s' value", 197 optionName, value), 198 CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, 199 prepareOptionValue(value)); 200 } else { 201 CommandLineOptionTest.verifyOptionValueForSameVM(optionName, 202 value, 203 String.format("Option '%s' is set to have '%s' value", 204 optionName, value), prepareOptionValue(value)); 205 } 206 } 207 } 208 209 protected String prepareOptionValue(String value) { 210 if (isBoolean) { 211 return CommandLineOptionTest.prepareBooleanFlag(optionName, 212 Boolean.valueOf(value)); 213 } else { 214 return String.format("-XX:%s=%s", optionName, value); 215 } 216 } 217} 218