langtools/test/tools/javac/MethodParameters/MethodParametersTester.java
changeset 40316 20b50a99fe8d
parent 21482 21e66f272f98
equal deleted inserted replaced
40315:9e994c77db6a 40316:20b50a99fe8d
       
     1 /*
       
     2  * Copyright (c) 2013, 2016, 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 import java.io.*;
       
    25 import java.lang.reflect.Constructor;
       
    26 import java.nio.charset.StandardCharsets;
       
    27 import java.nio.file.Files;
       
    28 import java.util.ArrayList;
       
    29 import java.util.Arrays;
       
    30 import java.util.List;
       
    31 
       
    32 /**
       
    33  * Test driver for MethodParameters testing.
       
    34  * <p>
       
    35  * The intended use of this driver is to run it, giving the name of
       
    36  * a single class compiled with -parameters as argument. The driver
       
    37  * will test the specified class, and any nested classes it finds.
       
    38  * <p>
       
    39  * Each class is tested in two way. By refelction, and by directly
       
    40  * checking MethodParameters attributes in the classfile. The checking
       
    41  * is done using two visitor classes {@link ClassFileVisitor} and
       
    42  * {@link ReflectionVisitor}.
       
    43  * <p>
       
    44  * The {@code ReflectionVisitor} test logically belongs with library tests.
       
    45  * we wish to reuse the same test-cases, so both test are committed together,
       
    46  * under langtools. The tests, may be duplicated in the jdk repository.
       
    47  */
       
    48 public class MethodParametersTester {
       
    49 
       
    50     final static File classesdir = new File(System.getProperty("test.classes", "."));
       
    51 
       
    52     private String classname;
       
    53     private File[] files;
       
    54     private File refFile;
       
    55     private int errors;
       
    56     private int warnings;
       
    57     private int diffGolden;
       
    58 
       
    59     /**
       
    60      * The visitor classes that does the actual checking are referenced
       
    61      * statically, to force compilations, without having to reference
       
    62      * them in individual test cases.
       
    63      * <p>
       
    64      * This makes it easy to change the set of visitors, without
       
    65      * complicating the design with dynamic discovery and compilation
       
    66      * of visitor classes.
       
    67      */
       
    68     static final Class visitors[] = {
       
    69         ClassFileVisitor.class,
       
    70         ReflectionVisitor.class
       
    71     };
       
    72 
       
    73     /**
       
    74      * Test-driver expect a single classname as argument.
       
    75      */
       
    76     public static void main(String... args) throws Exception {
       
    77         if (args.length != 2) {
       
    78             throw new Error("A single class name and a golden file are expected as argument");
       
    79         }
       
    80         String testSrc = System.getProperty("test.src");
       
    81         String testName = args[0];
       
    82         String testGoldenFile = args[1];
       
    83         final String pattern = testName + ".*\\.class";
       
    84         File refFile = new File(testSrc, testGoldenFile);
       
    85         File[] files = classesdir.listFiles(new FileFilter() {
       
    86                 public boolean accept(File f) {
       
    87                     return f.getName().matches(pattern);
       
    88                 }
       
    89             });
       
    90         if (files.length == 0) {
       
    91             File file = new File(classesdir, testName + ".class");
       
    92             throw new Error(file.getPath() + " not found");
       
    93         }
       
    94 
       
    95         new MethodParametersTester(testName, files, refFile).run();
       
    96     }
       
    97 
       
    98     public MethodParametersTester(String name, File[] files, File refFile) {
       
    99         this.classname = name;
       
   100         this.files = files;
       
   101         this.refFile = refFile;
       
   102     }
       
   103 
       
   104     void run() throws Exception {
       
   105 
       
   106         // Test with each visitor
       
   107         for (Class<Visitor> vclass : visitors) {
       
   108             boolean compResult = false;
       
   109             try {
       
   110                 String vname = vclass.getName();
       
   111                 Constructor c = vclass.getConstructor(MethodParametersTester.class);
       
   112 
       
   113                 info("\nRun " + vname + " for " + classname + "\n");
       
   114                 StringBuilder sb = new StringBuilder();
       
   115                 for (File f : files) {
       
   116                     String fname = f.getName();
       
   117                     fname = fname.substring(0, fname.length() - 6);
       
   118                     Visitor v = (Visitor) c.newInstance(this);
       
   119                     try {
       
   120                         v.visitClass(fname, f,  sb);
       
   121                     } catch(Exception e) {
       
   122                         error("Uncaught exception in visitClass()");
       
   123                         e.printStackTrace();
       
   124                     }
       
   125                 }
       
   126                 String output = sb.toString();
       
   127                 info(output);
       
   128                 compResult = compareOutput(refFile, output);
       
   129             } catch(ReflectiveOperationException e) {
       
   130                 warn("Class " + vclass.getName() + " ignored, not a Visitor");
       
   131                 continue;
       
   132             }
       
   133             if (!compResult) {
       
   134                 diffGolden++;
       
   135                 error("The output from " + vclass.getName() + " did not match golden file.");
       
   136         }
       
   137         }
       
   138 
       
   139         if (0 != diffGolden)
       
   140             throw new Exception("Test output is not equal with golden file.");
       
   141 
       
   142         if(0 != warnings)
       
   143                 System.err.println("Test generated " + warnings + " warnings");
       
   144 
       
   145         if(0 != errors)
       
   146             throw new Exception("Tester test failed with " +
       
   147                                 errors + " errors");
       
   148     }
       
   149     // Check if test output matches the golden file.
       
   150     boolean compareOutput(File refFile, String sb)
       
   151             throws FileNotFoundException, IOException {
       
   152 
       
   153         List<String> refFileList = Files.readAllLines(refFile.toPath(), StandardCharsets.UTF_8);
       
   154         List<String> sbList = Arrays.asList(sb.split("[\r\n]+"));
       
   155         // Check if test output contains unexpected lines or is missing expected lines.
       
   156         List<String> sbOnly = new ArrayList<>(sbList);
       
   157         sbOnly.removeAll(refFileList);
       
   158         for (String line: sbOnly)
       
   159             error("unexpected line found: " + line);
       
   160 
       
   161         List<String> refOnly = new ArrayList<>(refFileList);
       
   162         refOnly.removeAll(sbList);
       
   163         for (String line: refOnly)
       
   164             error("expected line not found: " + line);
       
   165 
       
   166         return sbOnly.isEmpty() && refOnly.isEmpty();
       
   167     }
       
   168 
       
   169     abstract static  class Visitor {
       
   170         MethodParametersTester tester;
       
   171         File classesdir;
       
   172 
       
   173         public Visitor(MethodParametersTester tester) {
       
   174             this.tester = tester;
       
   175         }
       
   176 
       
   177         abstract void visitClass(final String classname, final File  cfile,
       
   178                 final StringBuilder sb) throws Exception;
       
   179 
       
   180         public void error(String msg) {
       
   181             tester.error(msg);
       
   182         }
       
   183 
       
   184         public void warn(String msg) {
       
   185             tester.warn(msg);
       
   186         }
       
   187     }
       
   188 
       
   189     void error(String msg) {
       
   190         System.err.println("Error: " + msg);
       
   191         errors++;
       
   192     }
       
   193 
       
   194     void warn(String msg) {
       
   195         System.err.println("Warning: " + msg);
       
   196         warnings++;
       
   197     }
       
   198 
       
   199     void info(String msg) {
       
   200         System.out.println(msg);
       
   201     }
       
   202 }