strarup@1594: /* strarup@1594: * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. strarup@1594: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. strarup@1594: * strarup@1594: * This code is free software; you can redistribute it and/or modify it strarup@1594: * under the terms of the GNU General Public License version 2 only, as strarup@1594: * published by the Free Software Foundation. strarup@1594: * strarup@1594: * This code is distributed in the hope that it will be useful, but WITHOUT strarup@1594: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or strarup@1594: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License strarup@1594: * version 2 for more details (a copy is included in the LICENSE file that strarup@1594: * accompanied this code). strarup@1594: * strarup@1594: * You should have received a copy of the GNU General Public License version strarup@1594: * 2 along with this work; if not, write to the Free Software Foundation, strarup@1594: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. strarup@1594: * strarup@1594: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA strarup@1594: * or visit www.oracle.com if you need additional information or have any strarup@1594: * questions. strarup@1594: */ strarup@1594: strarup@1594: import java.io.*; strarup@1594: import java.lang.reflect.Constructor; mnunez@2137: import java.nio.charset.StandardCharsets; mnunez@2137: import java.nio.file.Files; mnunez@2137: import java.util.ArrayList; mnunez@2137: import java.util.Arrays; mnunez@2137: import java.util.List; strarup@1594: strarup@1594: /** strarup@1594: * Test driver for MethodParameters testing. strarup@1594: *

strarup@1594: * The intended use of this driver is to run it, giving the name of strarup@1594: * a single class compiled with -parameters as argument. The driver strarup@1594: * will test the specified class, and any nested classes it finds. strarup@1594: *

strarup@1594: * Each class is tested in two way. By refelction, and by directly strarup@1594: * checking MethodParameters attributes in the classfile. The checking strarup@1594: * is done using two visitor classes {@link ClassFileVisitor} and strarup@1594: * {@link ReflectionVisitor}. strarup@1594: *

strarup@1594: * The {@code ReflectionVisitor} test logically belongs with library tests. strarup@1594: * we wish to reuse the same test-cases, so both test are committed together, strarup@1594: * under langtools. The tests, may be duplicated in the jdk repository. strarup@1594: */ strarup@1594: public class Tester { strarup@1594: strarup@1594: final static File classesdir = new File(System.getProperty("test.classes", ".")); strarup@1594: mnunez@2137: private String classname; mnunez@2137: private File[] files; mnunez@2137: private File refFile; mnunez@2137: private int errors; mnunez@2137: private int warnings; mnunez@2137: private int diffGolden; mnunez@2137: strarup@1594: /** strarup@1594: * The visitor classes that does the actual checking are referenced strarup@1594: * statically, to force compilations, without having to reference strarup@1594: * them in individual test cases. strarup@1594: *

strarup@1594: * This makes it easy to change the set of visitors, without strarup@1594: * complicating the design with dynamic discovery and compilation strarup@1594: * of visitor classes. strarup@1594: */ strarup@1594: static final Class visitors[] = { strarup@1594: ClassFileVisitor.class, strarup@1594: ReflectionVisitor.class strarup@1594: }; strarup@1594: strarup@1594: /** strarup@1594: * Test-driver expect a single classname as argument. strarup@1594: */ strarup@1594: public static void main(String... args) throws Exception { mnunez@2137: if (args.length != 2) { mnunez@2137: throw new Error("A single class name and a golden file are expected as argument"); strarup@1594: } mnunez@2137: String testSrc = System.getProperty("test.src"); mnunez@2137: String testName = args[0]; mnunez@2137: String testGoldenFile = args[1]; mnunez@2137: final String pattern = testName + ".*\\.class"; mnunez@2137: File refFile = new File(testSrc, testGoldenFile); mnunez@2137: File[] files = classesdir.listFiles(new FileFilter() { strarup@1594: public boolean accept(File f) { strarup@1594: return f.getName().matches(pattern); strarup@1594: } strarup@1594: }); strarup@1594: if (files.length == 0) { mnunez@2137: File file = new File(classesdir, testName + ".class"); strarup@1594: throw new Error(file.getPath() + " not found"); strarup@1594: } strarup@1594: mnunez@2137: new Tester(testName, files, refFile).run(); strarup@1594: } strarup@1594: mnunez@2137: public Tester(String name, File[] files, File refFile) { strarup@1594: this.classname = name; strarup@1594: this.files = files; mnunez@2137: this.refFile = refFile; strarup@1594: } strarup@1594: strarup@1594: void run() throws Exception { strarup@1594: strarup@1594: // Test with each visitor strarup@1594: for (Class vclass : visitors) { mnunez@2137: boolean compResult = false; strarup@1594: try { strarup@1594: String vname = vclass.getName(); strarup@1594: Constructor c = vclass.getConstructor(Tester.class); strarup@1594: strarup@1594: info("\nRun " + vname + " for " + classname + "\n"); strarup@1594: StringBuilder sb = new StringBuilder(); strarup@1594: for (File f : files) { strarup@1594: String fname = f.getName(); strarup@1594: fname = fname.substring(0, fname.length() - 6); strarup@1594: Visitor v = (Visitor) c.newInstance(this); strarup@1594: try { strarup@1594: v.visitClass(fname, f, sb); strarup@1594: } catch(Exception e) { strarup@1594: error("Uncaught exception in visitClass()"); strarup@1594: e.printStackTrace(); strarup@1594: } strarup@1594: } mnunez@2137: String output = sb.toString(); mnunez@2137: info(output); mnunez@2137: compResult = compareOutput(refFile, output); strarup@1594: } catch(ReflectiveOperationException e) { strarup@1594: warn("Class " + vclass.getName() + " ignored, not a Visitor"); strarup@1594: continue; strarup@1594: } mnunez@2137: if (!compResult) { mnunez@2137: diffGolden++; mnunez@2137: error("The output from " + vclass.getName() + " did not match golden file."); strarup@1594: } mnunez@2137: } mnunez@2137: mnunez@2137: if (0 != diffGolden) mnunez@2137: throw new Exception("Test output is not equal with golden file."); strarup@1594: strarup@1594: if(0 != warnings) strarup@1594: System.err.println("Test generated " + warnings + " warnings"); strarup@1594: strarup@1594: if(0 != errors) strarup@1594: throw new Exception("Tester test failed with " + strarup@1594: errors + " errors"); strarup@1594: } mnunez@2137: // Check if test output matches the golden file. mnunez@2137: boolean compareOutput(File refFile, String sb) mnunez@2137: throws FileNotFoundException, IOException { mnunez@2137: mnunez@2137: List refFileList = Files.readAllLines(refFile.toPath(), StandardCharsets.UTF_8); ksrini@2151: List sbList = Arrays.asList(sb.split("[\r\n]+")); mnunez@2137: // Check if test output contains unexpected lines or is missing expected lines. ksrini@2151: List sbOnly = new ArrayList<>(sbList); mnunez@2137: sbOnly.removeAll(refFileList); mnunez@2137: for (String line: sbOnly) mnunez@2137: error("unexpected line found: " + line); mnunez@2137: ksrini@2151: List refOnly = new ArrayList<>(refFileList); mnunez@2137: refOnly.removeAll(sbList); mnunez@2137: for (String line: refOnly) mnunez@2137: error("expected line not found: " + line); mnunez@2137: mnunez@2137: return sbOnly.isEmpty() && refOnly.isEmpty(); mnunez@2137: } strarup@1594: strarup@1594: abstract static class Visitor { strarup@1594: Tester tester; strarup@1594: File classesdir; strarup@1594: strarup@1594: public Visitor(Tester tester) { strarup@1594: this.tester = tester; strarup@1594: } strarup@1594: strarup@1594: abstract void visitClass(final String classname, final File cfile, strarup@1594: final StringBuilder sb) throws Exception; strarup@1594: strarup@1594: public void error(String msg) { strarup@1594: tester.error(msg); strarup@1594: } strarup@1594: strarup@1594: public void warn(String msg) { strarup@1594: tester.warn(msg); strarup@1594: } strarup@1594: } strarup@1594: strarup@1594: void error(String msg) { strarup@1594: System.err.println("Error: " + msg); strarup@1594: errors++; strarup@1594: } strarup@1594: strarup@1594: void warn(String msg) { strarup@1594: System.err.println("Warning: " + msg); strarup@1594: warnings++; strarup@1594: } strarup@1594: strarup@1594: void info(String msg) { strarup@1594: System.out.println(msg); strarup@1594: } strarup@1594: }