1 /*
   2  * Copyright (c) 2012, 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 /*
  25  * @test
  26  * @bug 8003562
  27  * @summary Basic tests for jdeps tool
  28  * @build Test p.Foo
  29  * @run main Basic
  30  */
  31 
  32 import java.io.File;
  33 import java.io.IOException;
  34 import java.io.PrintWriter;
  35 import java.io.StringWriter;
  36 import java.util.*;
  37 import java.util.regex.*;
  38 
  39 public class Basic {
  40     public static void main(String... args) throws Exception {
  41         int errors = 0;
  42 
  43         errors += new Basic().run();
  44         if (errors > 0)
  45             throw new Exception(errors + " errors found");
  46     }
  47 
  48     int run() throws IOException {
  49         File testDir = new File(System.getProperty("test.classes", "."));
  50         // test a .class file
  51         test(new File(testDir, "Test.class"),
  52              new String[] {"java.lang", "p"});
  53         // test a directory
  54         test(new File(testDir, "p"),
  55              new String[] {"java.lang", "java.util"});
  56         // test class-level dependency output
  57         test(new File(testDir, "Test.class"),
  58              new String[] {"java.lang.Object", "p.Foo"},
  59              new String[] {"-v:class"});
  60         // test -p option
  61         test(new File(testDir, "Test.class"),
  62              new String[] {"p.Foo"},
  63              new String[] {"-v:class", "-p", "p"});
  64         // test -e option
  65         test(new File(testDir, "Test.class"),
  66              new String[] {"p.Foo"},
  67              new String[] {"-v:class", "-e", "p\\..*"});
  68         test(new File(testDir, "Test.class"),
  69              new String[] {"java.lang"},
  70              new String[] {"-v:package", "-e", "java\\.lang\\..*"});
  71         // test -classpath and -all options
  72         test(null,
  73              new String[] {"com.sun.tools.jdeps", "java.lang", "java.util",
  74                            "java.util.regex", "java.io", "p"},
  75              new String[] {"-classpath", testDir.getPath(), "*"});
  76         return errors;
  77     }
  78 
  79     void test(File file, String[] expect) {
  80         test(file, expect, new String[0]);
  81     }
  82 
  83     void test(File file, String[] expect, String[] options) {
  84         String[] args;
  85         if (file != null) {
  86             args = Arrays.copyOf(options, options.length+1);
  87             args[options.length] = file.getPath();
  88         } else {
  89             args = options;
  90         }
  91         String[] deps = jdeps(args);
  92         checkEqual("dependencies", expect, deps);
  93     }
  94 
  95     String[] jdeps(String... args) {
  96         StringWriter sw = new StringWriter();
  97         PrintWriter pw = new PrintWriter(sw);
  98         System.err.println("jdeps " + Arrays.toString(args));
  99         int rc = com.sun.tools.jdeps.Main.run(args, pw);
 100         pw.close();
 101         String out = sw.toString();
 102         if (!out.isEmpty())
 103             System.err.println(out);
 104         if (rc != 0)
 105             throw new Error("jdeps failed: rc=" + rc);
 106         return findDeps(out);
 107     }
 108 
 109     // Pattern used to parse lines
 110     private static Pattern linePattern
 111         = Pattern.compile(".*\r?\n");
 112     private static Pattern pattern
 113         = Pattern.compile("\\s+ -> (\\S+) +.*");
 114 
 115     // Use the linePattern to break the given String into lines, applying
 116     // the pattern to each line to see if we have a match
 117     private static String[] findDeps(String out) {
 118         List<String> result = new ArrayList<>();
 119         Matcher lm = linePattern.matcher(out);  // Line matcher
 120         Matcher pm = null;                      // Pattern matcher
 121         int lines = 0;
 122         while (lm.find()) {
 123             lines++;
 124             CharSequence cs = lm.group();       // The current line
 125             if (pm == null)
 126                 pm = pattern.matcher(cs);
 127             else
 128                 pm.reset(cs);
 129             if (pm.find())
 130                 result.add(pm.group(1));
 131             if (lm.end() == out.length())
 132                 break;
 133         }
 134         return result.toArray(new String[0]);
 135     }
 136 
 137     void checkEqual(String label, String[] expect, String[] found) {
 138         Set<String> s1 = new HashSet<>(Arrays.asList(expect));
 139         Set<String> s2 = new HashSet<>(Arrays.asList(found));
 140 
 141         if (!s1.equals(s2))
 142             error("Unexpected " + label + " found: '" + s2 + "', expected: '" + s1 + "'");
 143     }
 144 
 145     void error(String msg) {
 146         System.err.println("Error: " + msg);
 147         errors++;
 148     }
 149 
 150     int errors;
 151 }