/* * 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 rtm; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; import java.util.LinkedList; import java.util.Arrays; import java.util.Collections; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.oracle.java.testlibrary.OutputAnalyzer; import com.oracle.java.testlibrary.ProcessTools; import com.oracle.java.testlibrary.Utils; import com.oracle.java.testlibrary.cli.CommandLineOptionTest; /** * Auxiliary methods used for RTM testing. */ public class RTMTestBase { private static final String RTM_STATE_CHANGE_REASON = "rtm_state_change"; /** * We don't parse compilation log as XML-document and use regular * expressions instead, because in some cases it could be * malformed. */ private static final String FIRED_UNCOMMON_TRAP_PATTERN_TEMPLATE = "rtm_state_change * installed during compilation. * * @param compilationLogFile a path to file with LogCompilation output. * @return count of installed uncommon traps with reason * rtm_state_change. * @throws IOException */ public static int installedRTMStateChangeTraps(String compilationLogFile) throws IOException { return RTMTestBase.installedUncommonTraps(compilationLogFile, RTMTestBase.RTM_STATE_CHANGE_REASON); } /** * Finds count of fired uncommon traps with reason {@code reason}. * * @param compilationLogFile a path to file with LogCompilation output. * @param reason a reason of fired uncommon traps. * @return count of fired uncommon traps with reason {@code reason}. * @throws IOException */ public static int firedUncommonTraps(String compilationLogFile, String reason) throws IOException { String pattern = String.format( RTMTestBase.FIRED_UNCOMMON_TRAP_PATTERN_TEMPLATE, reason); return RTMTestBase.findTraps(compilationLogFile, pattern); } /** * Finds count of fired uncommon traps with reason rtm_state_change. * * @param compilationLogFile a path to file with LogCompilation output. * @return count of fired uncommon traps with reason * rtm_state_change. * @throws IOException */ public static int firedRTMStateChangeTraps(String compilationLogFile) throws IOException { return RTMTestBase.firedUncommonTraps(compilationLogFile, RTMTestBase.RTM_STATE_CHANGE_REASON); } /** * Finds count of uncommon traps that matches regular * expression in {@code re}. * * @param compilationLogFile a path to file with LogCompilation output. * @param re regular expression to match uncommon traps. * @throws IOException */ private static int findTraps(String compilationLogFile, String re) throws IOException { String compilationLog = RTMTestBase.fileAsString(compilationLogFile); Pattern pattern = Pattern.compile(re); Matcher matcher = pattern.matcher(compilationLog); int traps = 0; while (matcher.find()) { traps++; } return traps; } /** * Returns file's content as a string. * * @param path a path to file to operate on. * @return string with content of file. * @throws IOException */ private static String fileAsString(String path) throws IOException { byte[] fileAsBytes = Files.readAllBytes(Paths.get(path)); return new String(fileAsBytes); } /** * Prepares VM options for test execution. * This method get test java options, filter out all RTM-related options, * adds CompileCommand=compileonly,method_name options for each method * from {@code methodToCompile} and finally appends all {@code vmOpts}. * * @param test test case whose methods that should be compiled. * If {@code null} then no additional compileonly * commands will be added to VM options. * @param vmOpts additional options to pass to VM. * @return Array with VM options. */ private static String[] prepareTestOptions(CompilableTest test, String... vmOpts) { return RTMTestBase.prepareFilteredTestOptions(test, null, vmOpts); } /** * Prepares VM options for test execution. * This method get test java options, filter out all RTM-related options * and all options that matches regexps in {@code additionalFilters}, * adds CompileCommand=compileonly,method_name options for each method * from {@code methodToCompile} and finally appends all {@code vmOpts}. * * @param test test case whose methods that should be compiled. * If {@code null} then no additional compileonly * commands will be added to VM options. * @param additionalFilters array with regular expression that will be * used to filter out test java options. * If {@code null} then no additional filters * will be used. * @param vmOpts additional options to pass to VM. * @return array with VM options. */ private static String[] prepareFilteredTestOptions(CompilableTest test, String[] additionalFilters, String... vmOpts) { List finalVMOpts = new LinkedList<>(); String[] filters; if (additionalFilters != null) { filters = Arrays.copyOf(additionalFilters, additionalFilters.length + 1); } else { filters = new String[1]; } filters[filters.length - 1] = "RTM"; String[] filteredVMOpts = Utils.getFilteredTestJavaOpts(filters); Collections.addAll(finalVMOpts, filteredVMOpts); Collections.addAll(finalVMOpts, "-Xcomp", "-server", "-XX:-TieredCompilation", "-XX:+UseRTMLocking", CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-Xbootclasspath/a:.", "-XX:+WhiteBoxAPI"); if (test != null) { for (String method : test.getMethodsToCompileNames()) { finalVMOpts.add("-XX:CompileCommand=compileonly," + method); } } Collections.addAll(finalVMOpts, vmOpts); return finalVMOpts.toArray(new String[finalVMOpts.size()]); } /** * Adds additional options for VM required for successful execution of test. * * @param logFileName a name of compilation log file * @param test a test case to execute * @param options additional options to VM * @return an array with VM options */ private static String[] prepareTestOptions(String logFileName, CompilableTest test, String... options) { String[] preparedOptions = RTMTestBase.prepareFilteredTestOptions( test, new String[] { "LogCompilation", "LogFile" }); List updatedOptions = new LinkedList<>(); Collections.addAll(updatedOptions, preparedOptions); Collections.addAll(updatedOptions, "-XX:+LogCompilation", "-XX:LogFile=" + logFileName); Collections.addAll(updatedOptions, options); return updatedOptions.toArray(new String[updatedOptions.size()]); } }