mchung@1472: /* mchung@1472: * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. mchung@1472: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. mchung@1472: * mchung@1472: * This code is free software; you can redistribute it and/or modify it mchung@1472: * under the terms of the GNU General Public License version 2 only, as mchung@1472: * published by the Free Software Foundation. mchung@1472: * mchung@1472: * This code is distributed in the hope that it will be useful, but WITHOUT mchung@1472: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or mchung@1472: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License mchung@1472: * version 2 for more details (a copy is included in the LICENSE file that mchung@1472: * accompanied this code). mchung@1472: * mchung@1472: * You should have received a copy of the GNU General Public License version mchung@1472: * 2 along with this work; if not, write to the Free Software Foundation, mchung@1472: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. mchung@1472: * mchung@1472: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA mchung@1472: * or visit www.oracle.com if you need additional information or have any mchung@1472: * questions. mchung@1472: */ mchung@1472: mchung@1472: /* mchung@1472: * @test mchung@2139: * @bug 8003562 8005428 8015912 mchung@1472: * @summary Basic tests for jdeps tool mchung@1472: * @build Test p.Foo mchung@1472: * @run main Basic mchung@1472: */ mchung@1472: mchung@1472: import java.io.File; mchung@1472: import java.io.IOException; mchung@1472: import java.io.PrintWriter; mchung@1472: import java.io.StringWriter; mchung@1638: import java.nio.file.Path; mchung@1638: import java.nio.file.Paths; mchung@1472: import java.util.*; mchung@1472: import java.util.regex.*; mchung@1472: mchung@1472: public class Basic { mchung@1638: private static boolean symbolFileExist = initProfiles(); mchung@1638: private static boolean initProfiles() { mchung@1638: // check if ct.sym exists; if not use the profiles.properties file mchung@1638: Path home = Paths.get(System.getProperty("java.home")); mchung@1638: if (home.endsWith("jre")) { mchung@1638: home = home.getParent(); mchung@1638: } mchung@1638: Path ctsym = home.resolve("lib").resolve("ct.sym"); mchung@1638: boolean symbolExists = ctsym.toFile().exists(); mchung@1638: if (!symbolExists) { mchung@1638: Path testSrcProfiles = mchung@1638: Paths.get(System.getProperty("test.src", "."), "profiles.properties"); mchung@1638: if (!testSrcProfiles.toFile().exists()) mchung@1638: throw new Error(testSrcProfiles + " does not exist"); mchung@1638: System.out.format("%s doesn't exist.%nUse %s to initialize profiles info%n", mchung@1638: ctsym, testSrcProfiles); mchung@1638: System.setProperty("jdeps.profiles", testSrcProfiles.toString()); mchung@1638: } mchung@1638: return symbolExists; mchung@1638: } mchung@1638: mchung@1472: public static void main(String... args) throws Exception { mchung@1472: int errors = 0; mchung@1472: errors += new Basic().run(); mchung@1472: if (errors > 0) mchung@1472: throw new Exception(errors + " errors found"); mchung@1472: } mchung@1472: mchung@1472: int run() throws IOException { mchung@1472: File testDir = new File(System.getProperty("test.classes", ".")); mchung@1472: // test a .class file mchung@1472: test(new File(testDir, "Test.class"), mchung@1638: new String[] {"java.lang", "p"}, mchung@1638: new String[] {"compact1", "not found"}); mchung@1472: // test a directory mchung@1472: test(new File(testDir, "p"), mchung@1638: new String[] {"java.lang", "java.util", "java.lang.management"}, mchung@1638: new String[] {"compact1", "compact1", "compact3"}); mchung@1472: // test class-level dependency output mchung@1472: test(new File(testDir, "Test.class"), mchung@2139: new String[] {"java.lang.Object", "java.lang.String", "p.Foo"}, mchung@2139: new String[] {"compact1", "compact1", "not found"}, mchung@2139: new String[] {"-verbose:class"}); mchung@1472: // test -p option mchung@1472: test(new File(testDir, "Test.class"), mchung@1472: new String[] {"p.Foo"}, mchung@1638: new String[] {"not found"}, mchung@2139: new String[] {"-verbose:class", "-p", "p"}); mchung@1472: // test -e option mchung@1472: test(new File(testDir, "Test.class"), mchung@1472: new String[] {"p.Foo"}, mchung@1638: new String[] {"not found"}, mchung@2139: new String[] {"-verbose:class", "-e", "p\\..*"}); mchung@1472: test(new File(testDir, "Test.class"), mchung@1472: new String[] {"java.lang"}, mchung@1638: new String[] {"compact1"}, mchung@2139: new String[] {"-verbose:package", "-e", "java\\.lang\\..*"}); mchung@2139: // test -classpath and -include options mchung@1472: test(null, mchung@2139: new String[] {"java.lang", "java.util", mchung@1638: "java.lang.management"}, mchung@2139: new String[] {"compact1", "compact1", "compact3"}, mchung@2139: new String[] {"-classpath", testDir.getPath(), "-include", "p.+|Test.class"}); mchung@2139: test(new File(testDir, "Test.class"), mchung@2139: new String[] {"java.lang.Object", "java.lang.String", "p.Foo"}, mchung@2139: new String[] {"compact1", "compact1", testDir.getName()}, mchung@2139: new String[] {"-v", "-classpath", testDir.getPath(), "Test.class"}); mchung@1472: return errors; mchung@1472: } mchung@1472: mchung@1638: void test(File file, String[] expect, String[] profiles) { mchung@1638: test(file, expect, profiles, new String[0]); mchung@1472: } mchung@1472: mchung@1638: void test(File file, String[] expect, String[] profiles, String[] options) { mchung@1638: List args = new ArrayList<>(Arrays.asList(options)); mchung@1472: if (file != null) { mchung@1638: args.add(file.getPath()); mchung@1472: } mchung@1638: List argsWithDashP = new ArrayList<>(); mchung@1638: argsWithDashP.add("-P"); mchung@1638: argsWithDashP.addAll(args); mchung@1638: // test without -P mchung@1638: checkResult("dependencies", expect, jdeps(args.toArray(new String[0])).keySet()); mchung@1638: // test with -P mchung@1638: checkResult("profiles", expect, profiles, jdeps(argsWithDashP.toArray(new String[0]))); mchung@1472: } mchung@1472: mchung@1638: Map jdeps(String... args) { mchung@1472: StringWriter sw = new StringWriter(); mchung@1472: PrintWriter pw = new PrintWriter(sw); mchung@1472: System.err.println("jdeps " + Arrays.toString(args)); mchung@1472: int rc = com.sun.tools.jdeps.Main.run(args, pw); mchung@1472: pw.close(); mchung@1472: String out = sw.toString(); mchung@1472: if (!out.isEmpty()) mchung@1472: System.err.println(out); mchung@1472: if (rc != 0) mchung@1472: throw new Error("jdeps failed: rc=" + rc); mchung@1472: return findDeps(out); mchung@1472: } mchung@1472: mchung@1472: // Pattern used to parse lines mchung@1472: private static Pattern linePattern = Pattern.compile(".*\r?\n"); mchung@1638: private static Pattern pattern = Pattern.compile("\\s+ -> (\\S+) +(.*)"); mchung@1472: mchung@1472: // Use the linePattern to break the given String into lines, applying mchung@1472: // the pattern to each line to see if we have a match mchung@1638: private static Map findDeps(String out) { mchung@1638: Map result = new HashMap<>(); mchung@1472: Matcher lm = linePattern.matcher(out); // Line matcher mchung@1472: Matcher pm = null; // Pattern matcher mchung@1472: int lines = 0; mchung@1472: while (lm.find()) { mchung@1472: lines++; mchung@1472: CharSequence cs = lm.group(); // The current line mchung@1472: if (pm == null) mchung@1472: pm = pattern.matcher(cs); mchung@1472: else mchung@1472: pm.reset(cs); mchung@1472: if (pm.find()) mchung@1638: result.put(pm.group(1), pm.group(2).trim()); mchung@1472: if (lm.end() == out.length()) mchung@1472: break; mchung@1472: } mchung@1638: return result; mchung@1472: } mchung@1472: mchung@1638: void checkResult(String label, String[] expect, Collection found) { mchung@1638: List list = Arrays.asList(expect); mchung@1638: if (!isEqual(list, found)) mchung@1638: error("Unexpected " + label + " found: '" + found + "', expected: '" + list + "'"); mchung@1638: } mchung@1472: mchung@1638: void checkResult(String label, String[] expect, String[] profiles, Map result) { mchung@1638: if (expect.length != profiles.length) mchung@1638: error("Invalid expected names and profiles"); mchung@1638: mchung@1638: // check the dependencies mchung@1638: checkResult(label, expect, result.keySet()); mchung@1638: // check profile information mchung@1638: checkResult(label, profiles, result.values()); mchung@1638: for (int i=0; i < expect.length; i++) { mchung@1638: String profile = result.get(expect[i]); mchung@1638: if (!profile.equals(profiles[i])) mchung@1638: error("Unexpected profile: '" + profile + "', expected: '" + profiles[i] + "'"); mchung@1638: } mchung@1638: } mchung@1638: mchung@1638: boolean isEqual(List expected, Collection found) { mchung@1638: if (expected.size() != found.size()) mchung@1638: return false; mchung@1638: mchung@1638: List list = new ArrayList<>(found); mchung@1638: list.removeAll(expected); mchung@1638: return list.isEmpty(); mchung@1472: } mchung@1472: mchung@1472: void error(String msg) { mchung@1472: System.err.println("Error: " + msg); mchung@1472: errors++; mchung@1472: } mchung@1472: mchung@1472: int errors; mchung@1472: }