RTMTestBase.java revision 12158:0fe2815ffa74
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 24package compiler.testlibrary.rtm; 25 26import jdk.test.lib.process.OutputAnalyzer; 27import jdk.test.lib.process.ProcessTools; 28import jdk.test.lib.Utils; 29import jdk.test.lib.cli.CommandLineOptionTest; 30 31import java.io.IOException; 32import java.nio.file.Files; 33import java.nio.file.Paths; 34import java.util.Arrays; 35import java.util.Collections; 36import java.util.LinkedList; 37import java.util.List; 38import java.util.regex.Matcher; 39import java.util.regex.Pattern; 40 41/** 42 * Auxiliary methods used for RTM testing. 43 */ 44public class RTMTestBase { 45 private static final String RTM_STATE_CHANGE_REASON = "rtm_state_change"; 46 /** 47 * We don't parse compilation log as XML-document and use regular 48 * expressions instead, because in some cases it could be 49 * malformed. 50 */ 51 private static final String FIRED_UNCOMMON_TRAP_PATTERN_TEMPLATE 52 = "<uncommon_trap thread='[0-9]+' reason='%s'"; 53 private static final String INSTALLED_UNCOMMON_TRAP_PATTERN_TEMPLATE 54 = "<uncommon_trap bci='[0-9]+' reason='%s'"; 55 56 /** 57 * Executes RTM test in a new JVM started with {@code options} cli options. 58 * 59 * @param test test case to execute. 60 * @param options additional options for VM 61 * @throws Exception when something went wrong. 62 */ 63 public static OutputAnalyzer executeRTMTest(CompilableTest test, 64 String... options) throws Exception { 65 ProcessBuilder processBuilder 66 = ProcessTools.createJavaProcessBuilder( 67 RTMTestBase.prepareTestOptions(test, options)); 68 OutputAnalyzer outputAnalyzer 69 = new OutputAnalyzer(processBuilder.start()); 70 System.out.println(outputAnalyzer.getOutput()); 71 return outputAnalyzer; 72 } 73 74 /** 75 * Executes test case and save compilation log to {@code logFileName}. 76 * 77 * @param logFileName a name of compilation log file 78 * @param test a test case to execute case to execute 79 * @param options additional options to VM 80 * @return OutputAnalyzer for started test case 81 * @throws Exception when something went wrong 82 */ 83 public static OutputAnalyzer executeRTMTest(String logFileName, 84 CompilableTest test, String... options) throws Exception { 85 ProcessBuilder processBuilder 86 = ProcessTools.createJavaProcessBuilder( 87 RTMTestBase.prepareTestOptions(logFileName, test, options)); 88 OutputAnalyzer outputAnalyzer 89 = new OutputAnalyzer(processBuilder.start()); 90 91 System.out.println(outputAnalyzer.getOutput()); 92 93 return outputAnalyzer; 94 } 95 96 /** 97 * Finds count of uncommon traps with reason {@code reason} installed 98 * during compilation. 99 * 100 * @param compilationLogFile a path to file with LogCompilation output. 101 * @param reason reason of installed uncommon traps. 102 * @return count of installed uncommon traps with reason {@code reason}. 103 * @throws IOException 104 */ 105 public static int installedUncommonTraps(String compilationLogFile, 106 String reason)throws IOException { 107 String pattern = String.format( 108 RTMTestBase.INSTALLED_UNCOMMON_TRAP_PATTERN_TEMPLATE, 109 reason); 110 return RTMTestBase.findTraps(compilationLogFile, pattern); 111 } 112 113 /** 114 * Finds count of uncommon traps with reason <i>rtm_state_change</i> 115 * installed during compilation. 116 * 117 * @param compilationLogFile a path to file with LogCompilation output. 118 * @return count of installed uncommon traps with reason 119 * <i>rtm_state_change</i>. 120 * @throws IOException 121 */ 122 public static int installedRTMStateChangeTraps(String compilationLogFile) 123 throws IOException { 124 return RTMTestBase.installedUncommonTraps(compilationLogFile, 125 RTMTestBase.RTM_STATE_CHANGE_REASON); 126 } 127 128 /** 129 * Finds count of fired uncommon traps with reason {@code reason}. 130 * 131 * @param compilationLogFile a path to file with LogCompilation output. 132 * @param reason a reason of fired uncommon traps. 133 * @return count of fired uncommon traps with reason {@code reason}. 134 * @throws IOException 135 */ 136 public static int firedUncommonTraps(String compilationLogFile, 137 String reason) throws IOException { 138 String pattern = String.format( 139 RTMTestBase.FIRED_UNCOMMON_TRAP_PATTERN_TEMPLATE, 140 reason); 141 return RTMTestBase.findTraps(compilationLogFile, pattern); 142 } 143 144 /** 145 * Finds count of fired uncommon traps with reason <i>rtm_state_change</i>. 146 * 147 * @param compilationLogFile a path to file with LogCompilation output. 148 * @return count of fired uncommon traps with reason 149 * <i>rtm_state_change</i>. 150 * @throws IOException 151 */ 152 public static int firedRTMStateChangeTraps(String compilationLogFile) 153 throws IOException { 154 return RTMTestBase.firedUncommonTraps(compilationLogFile, 155 RTMTestBase.RTM_STATE_CHANGE_REASON); 156 } 157 158 /** 159 * Finds count of uncommon traps that matches regular 160 * expression in {@code re}. 161 * 162 * @param compilationLogFile a path to file with LogCompilation output. 163 * @param re regular expression to match uncommon traps. 164 * @throws IOException 165 */ 166 private static int findTraps(String compilationLogFile, String re) 167 throws IOException { 168 String compilationLog = RTMTestBase.fileAsString(compilationLogFile); 169 Pattern pattern = Pattern.compile(re); 170 Matcher matcher = pattern.matcher(compilationLog); 171 int traps = 0; 172 while (matcher.find()) { 173 traps++; 174 } 175 return traps; 176 } 177 178 /** 179 * Returns file's content as a string. 180 * 181 * @param path a path to file to operate on. 182 * @return string with content of file. 183 * @throws IOException 184 */ 185 private static String fileAsString(String path) throws IOException { 186 byte[] fileAsBytes = Files.readAllBytes(Paths.get(path)); 187 return new String(fileAsBytes); 188 } 189 190 /** 191 * Prepares VM options for test execution. 192 * This method get test java options, filter out all RTM-related options, 193 * adds CompileCommand=compileonly,method_name options for each method 194 * from {@code methodToCompile} and finally appends all {@code vmOpts}. 195 * 196 * @param test test case whose methods that should be compiled. 197 * If {@code null} then no additional <i>compileonly</i> 198 * commands will be added to VM options. 199 * @param vmOpts additional options to pass to VM. 200 * @return Array with VM options. 201 */ 202 private static String[] prepareTestOptions(CompilableTest test, 203 String... vmOpts) { 204 return RTMTestBase.prepareFilteredTestOptions(test, null, vmOpts); 205 } 206 207 /** 208 * Prepares VM options for test execution. 209 * This method get test java options, filter out all RTM-related options 210 * and all options that matches regexps in {@code additionalFilters}, 211 * adds CompileCommand=compileonly,method_name options for each method 212 * from {@code methodToCompile} and finally appends all {@code vmOpts}. 213 * 214 * @param test test case whose methods that should be compiled. 215 * If {@code null} then no additional <i>compileonly</i> 216 * commands will be added to VM options. 217 * @param additionalFilters array with regular expression that will be 218 * used to filter out test java options. 219 * If {@code null} then no additional filters 220 * will be used. 221 * @param vmOpts additional options to pass to VM. 222 * @return array with VM options. 223 */ 224 private static String[] prepareFilteredTestOptions(CompilableTest test, 225 String[] additionalFilters, String... vmOpts) { 226 List<String> finalVMOpts = new LinkedList<>(); 227 String[] filters; 228 229 if (additionalFilters != null) { 230 filters = Arrays.copyOf(additionalFilters, 231 additionalFilters.length + 1); 232 } else { 233 filters = new String[1]; 234 } 235 236 filters[filters.length - 1] = "RTM"; 237 String[] filteredVMOpts = Utils.getFilteredTestJavaOpts(filters); 238 Collections.addAll(finalVMOpts, filteredVMOpts); 239 Collections.addAll(finalVMOpts, "-Xcomp", "-server", 240 "-XX:-TieredCompilation", "-XX:+UseRTMLocking", 241 CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, 242 CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, 243 "-Xbootclasspath/a:.", "-XX:+WhiteBoxAPI", 244 "-XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED"); 245 246 if (test != null) { 247 for (String method : test.getMethodsToCompileNames()) { 248 finalVMOpts.add("-XX:CompileCommand=compileonly," + method); 249 } 250 } 251 Collections.addAll(finalVMOpts, vmOpts); 252 return finalVMOpts.toArray(new String[finalVMOpts.size()]); 253 } 254 255 /** 256 * Adds additional options for VM required for successful execution of test. 257 * 258 * @param logFileName a name of compilation log file 259 * @param test a test case to execute 260 * @param options additional options to VM 261 * @return an array with VM options 262 */ 263 private static String[] prepareTestOptions(String logFileName, 264 CompilableTest test, String... options) { 265 String[] preparedOptions = RTMTestBase.prepareFilteredTestOptions( 266 test, 267 new String[] { 268 "LogCompilation", 269 "LogFile" 270 }); 271 List<String> updatedOptions = new LinkedList<>(); 272 Collections.addAll(updatedOptions, preparedOptions); 273 Collections.addAll(updatedOptions, 274 "-XX:+LogCompilation", 275 "-XX:LogFile=" + logFileName); 276 Collections.addAll(updatedOptions, options); 277 278 return updatedOptions.toArray(new String[updatedOptions.size()]); 279 } 280} 281