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