1 /*
   2  * Copyright (c) 2014, 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.testlibrary.uncommontrap;
  25 
  26 import java.io.FileReader;
  27 import java.io.IOException;
  28 import java.nio.file.Files;
  29 import java.nio.file.Path;
  30 import java.nio.file.Paths;
  31 import java.util.Iterator;
  32 import java.util.List;
  33 import java.util.Properties;
  34 import java.util.regex.Pattern;
  35 
  36 import jdk.test.lib.Asserts;
  37 
  38 /**
  39  * Utility tool aimed to verify presence or absence of specified uncommon trap
  40  * in compilation log.
  41  */
  42 public class Verifier {
  43     public static final String PROPERTIES_FILE_SUFFIX = ".verify.properties";
  44     public static final String VERIFICATION_SHOULD_BE_SKIPPED
  45             = "uncommon.trap.verification.skipped";
  46     public static final String UNCOMMON_TRAP_NAME = "uncommon.trap.name";
  47     public static final String UNCOMMON_TRAP_BCI = "uncommon.trap.bci";
  48     public static final String UNCOMMON_TRAP_COMMENT = "uncommon.trap.comment";
  49     public static final String UNCOMMON_TRAP_ACTION = "uncommon.trap.action";
  50     public static final String UNCOMMON_TRAP_SHOULD_EMITTED
  51             = "uncommon.trap.emitted";
  52     public static final String UNCOMMON_TRAP_SHOULD_FIRED
  53             = "uncommon.trap.fired";
  54 
  55     private static final String EMITTED_TRAP_PATTERN
  56             = "<uncommon_trap bci='%s' reason='%s' action='%s' "
  57                     + "comment='%s'";
  58     private static final String FIRED_TRAP_PATTERN
  59             = "<uncommon_trap thread='[0-9]*' reason='%s' action='%s'";
  60     private static final String JVMS_PATTERN = "<jvms bci='%s'";
  61 
  62     public static void main(String args[]) {
  63         if (args.length == 0) {
  64             throw new Error("At least one argument containing name of "
  65                     + "compilation log file is expected");
  66         }
  67 
  68         for (String compLogFile : args) {
  69             try {
  70                 verify(Paths.get(compLogFile));
  71             } catch (IOException e) {
  72                 throw new Error("Unable to process compilation log.", e);
  73             }
  74         }
  75     }
  76 
  77     private static void verify(Path compLogFile) throws IOException {
  78         Path propertiesFile = Paths.get(compLogFile.toString() +
  79                 PROPERTIES_FILE_SUFFIX);
  80 
  81         Properties properties = new Properties();
  82         try (FileReader reader = new FileReader(propertiesFile.toFile())) {
  83             properties.load(reader);
  84         }
  85 
  86         if (Boolean.valueOf(properties.getProperty(
  87                 VERIFICATION_SHOULD_BE_SKIPPED, "false"))) {
  88             System.out.println("Skipping verification for log file: "
  89                     + compLogFile.toString());
  90             return;
  91         }
  92 
  93         System.out.println("Verifying log file: " + compLogFile.toString());
  94 
  95         List<String> compLogContent = Files.readAllLines(compLogFile);
  96         verifyUncommonTrapEmitted(properties, compLogContent);
  97         verifyUncommonTrapFired(properties, compLogContent);
  98     }
  99 
 100     private static void verifyUncommonTrapEmitted(Properties properties,
 101             List<String> compLogContent)  {
 102         String emittedTrapRE = String.format(EMITTED_TRAP_PATTERN,
 103                 properties.getProperty(UNCOMMON_TRAP_BCI, ".*"),
 104                 properties.getProperty(UNCOMMON_TRAP_NAME, ".*"),
 105                 properties.getProperty(UNCOMMON_TRAP_ACTION, ".*"),
 106                 properties.getProperty(UNCOMMON_TRAP_COMMENT, ".*"));
 107         Pattern pattern = Pattern.compile(emittedTrapRE);
 108 
 109         long trapsCount = compLogContent.stream()
 110                 .filter(line -> pattern.matcher(line).find())
 111                 .count();
 112 
 113         boolean shouldBeEmitted = Boolean.valueOf(
 114                 properties.getProperty(UNCOMMON_TRAP_SHOULD_EMITTED));
 115 
 116         Asserts.assertEQ(shouldBeEmitted, trapsCount > 0, String.format(
 117                 "Uncommon trap that matches following string in compilation log"
 118                         + " should %sbe emitted: %s.",
 119                 (shouldBeEmitted ? " " : "not "), emittedTrapRE));
 120     }
 121 
 122     private static void verifyUncommonTrapFired(Properties properties,
 123             List<String> compLogContent) {
 124         String firedTrapRE = String.format(FIRED_TRAP_PATTERN,
 125                 properties.getProperty(UNCOMMON_TRAP_NAME, ".*"),
 126                 properties.getProperty(UNCOMMON_TRAP_ACTION, ".*"));
 127         String jvmsRE = String.format(JVMS_PATTERN,
 128                 properties.getProperty(UNCOMMON_TRAP_BCI, ".*"));
 129 
 130         boolean trapFired = false;
 131         Pattern firedTrapPattern = Pattern.compile(firedTrapRE);
 132         Pattern jvmsPattern = Pattern.compile(jvmsRE);
 133 
 134         Iterator<String> iterator = compLogContent.iterator();
 135         while (iterator.hasNext() && !trapFired) {
 136             trapFired = firedTrapPattern.matcher(iterator.next()).find()
 137                     && jvmsPattern.matcher(iterator.next()).find();
 138         }
 139 
 140         boolean shouldBeFired = Boolean.valueOf(
 141                 properties.getProperty(UNCOMMON_TRAP_SHOULD_FIRED));
 142         Asserts.assertEQ(shouldBeFired, trapFired, String.format(
 143                 "Uncommon trap that matches following string in compilation log"
 144                         + " should %sbe fired: %s.",
 145                 (shouldBeFired ? "" : "not "), firedTrapRE));
 146     }
 147 }
 148