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