1 /* 2 * Copyright (c) 2015, 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 package compiler.compilercontrol.share.processors; 25 26 import compiler.compilercontrol.share.method.MethodDescriptor; 27 import compiler.compilercontrol.share.method.MethodGenerator; 28 import compiler.compilercontrol.share.pool.PoolHelper; 29 import compiler.compilercontrol.share.scenario.State; 30 import jdk.test.lib.Asserts; 31 import jdk.test.lib.process.OutputAnalyzer; 32 33 import java.io.File; 34 import java.io.FileNotFoundException; 35 import java.lang.reflect.Executable; 36 import java.util.List; 37 import java.util.Map; 38 import java.util.Scanner; 39 import java.util.function.Consumer; 40 import java.util.regex.Matcher; 41 import java.util.regex.Pattern; 42 import java.util.stream.Collectors; 43 44 /** 45 * Log compilation file processor 46 */ 47 public class LogProcessor implements Consumer<OutputAnalyzer> { 48 public static final String LOG_FILE = "compilation.log"; 49 private static final String TASK_ELEMENT = "<task [^>]*>"; 50 private static final String TASK_DONE_ELEMENT = "<task_done [^>]*>"; 51 private static final String TASK_END_ELEMENT = "</task>"; 52 private static final String ANY_ELEMENT = "<[^>]*>"; 53 private static final Pattern METHOD_PATTERN = Pattern.compile( 54 "method='([^']+)'"); 55 private final List<String> loggedMethods; 56 private final List<String> testMethods; 57 58 public LogProcessor(Map<Executable, State> states) { 59 loggedMethods = states.keySet().stream() 60 .filter(x -> states.get(x).isLog()) 61 .map(MethodGenerator::commandDescriptor) 62 .map(MethodDescriptor::getString) 63 .collect(Collectors.toList()); 64 testMethods = new PoolHelper().getAllMethods() 65 .stream() 66 .map(pair -> pair.first) 67 .map(MethodGenerator::commandDescriptor) 68 .map(MethodDescriptor::getString) 69 .collect(Collectors.toList()); 70 } 71 72 @Override 73 public void accept(OutputAnalyzer outputAnalyzer) { 74 if (loggedMethods.isEmpty()) { 75 return; 76 } 77 matchTasks(getScanner()); 78 } 79 80 /* 81 * Gets scanner for log file of the test case 82 */ 83 private Scanner getScanner() { 84 File logFile = new File(LOG_FILE); 85 Scanner scanner; 86 try { 87 scanner = new Scanner(logFile); 88 } catch (FileNotFoundException e) { 89 throw new Error("TESTBUG: file not found: " + logFile, e); 90 } 91 return scanner; 92 } 93 94 /* 95 * Parses for <task method='java.lang.String indexOf (I)I' > 96 * and finds if there is a compilation log for this task 97 */ 98 private void matchTasks(Scanner scanner) { 99 String task = scanner.findWithinHorizon(TASK_ELEMENT, 0); 100 while (task != null) { 101 String element = scanner.findWithinHorizon(ANY_ELEMENT, 0); 102 if (Pattern.matches(TASK_DONE_ELEMENT, element) 103 || Pattern.matches(TASK_END_ELEMENT, element)) { 104 /* If there is nothing between <task> and </task> 105 except <task done /> then compilation log is empty. 106 Check the method in this task should not be logged */ 107 Asserts.assertFalse(matchMethod(task), "Compilation log " 108 + "expected. Met: " + element); 109 } 110 task = scanner.findWithinHorizon(TASK_ELEMENT, 0); 111 } 112 } 113 114 // Check that input method should be logged 115 private boolean matchMethod(String input) { 116 Matcher matcher = METHOD_PATTERN.matcher(input); 117 Asserts.assertTrue(matcher.find(), "Wrong matcher or input"); 118 // Get method and normalize it 119 String method = normalize(matcher.group(1)); 120 if (loggedMethods.contains(method)) { 121 return true; 122 } 123 if (!testMethods.contains(method)) { 124 return false; 125 } 126 return false; 127 } 128 129 // Normalize given signature to conform regular expression used in tests 130 private String normalize(String method) { 131 return method.replaceAll("\\.", "/") // replace dots in a class string 132 .replaceFirst(" ", ".") // replace space between class and method 133 .replaceFirst(" ", "") // remove space between method and signature 134 .replace("<", "<") 135 .replace(">", ">"); 136 } 137 }