DotFileTest.java revision 2721:f7ce2cfa4cdb
1263646Sbapt/* 2263646Sbapt * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3263646Sbapt * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4263646Sbapt * 5263646Sbapt * This code is free software; you can redistribute it and/or modify it 6263646Sbapt * under the terms of the GNU General Public License version 2 only, as 7263646Sbapt * published by the Free Software Foundation. 8263646Sbapt * 9263646Sbapt * This code is distributed in the hope that it will be useful, but WITHOUT 10263646Sbapt * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11263646Sbapt * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12263646Sbapt * version 2 for more details (a copy is included in the LICENSE file that 13263646Sbapt * accompanied this code). 14290071Sbapt * 15290071Sbapt * You should have received a copy of the GNU General Public License version 16290071Sbapt * 2 along with this work; if not, write to the Free Software Foundation, 17290071Sbapt * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18263646Sbapt * 19290071Sbapt * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20263646Sbapt * or visit www.oracle.com if you need additional information or have any 21263646Sbapt * questions. 22263646Sbapt */ 23264400Simp 24/* 25 * @test 26 * @bug 8003562 27 * @summary Basic tests for jdeps -dotoutput option 28 * @build Test p.Foo p.Bar javax.activity.NotCompactProfile 29 * @run main DotFileTest 30 */ 31 32import java.io.File; 33import java.io.IOException; 34import java.io.PrintWriter; 35import java.io.StringWriter; 36import java.nio.file.DirectoryStream; 37import java.nio.file.Files; 38import java.nio.file.Path; 39import java.nio.file.Paths; 40import java.util.*; 41import java.util.regex.*; 42 43public class DotFileTest { 44 public static void main(String... args) throws Exception { 45 int errors = 0; 46 errors += new DotFileTest().run(); 47 if (errors > 0) 48 throw new Exception(errors + " errors found"); 49 } 50 51 final Path dir; 52 final Path dotoutput; 53 DotFileTest() { 54 this.dir = Paths.get(System.getProperty("test.classes", ".")); 55 this.dotoutput = dir.resolve("dots"); 56 } 57 58 int run() throws IOException { 59 File testDir = dir.toFile(); 60 // test a .class file 61 test(new File(testDir, "Test.class"), 62 new String[] {"java.lang", "p"}, 63 new String[] {"compact1", "not found"}); 64 // test a directory 65 // also test non-SE javax.activity class dependency 66 test(new File(testDir, "p"), 67 new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto"}, 68 new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"}, 69 new String[] {"-classpath", testDir.getPath()}); 70 // test class-level dependency output 71 test(new File(testDir, "Test.class"), 72 new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"}, 73 new String[] {"compact1", "compact1", "not found", "not found"}, 74 new String[] {"-verbose:class"}); 75 // test -filter:none option 76 test(new File(testDir, "p"), 77 new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto", "p"}, 78 new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1", "p"}, 79 new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:none"}); 80 // test -filter:archive option 81 test(new File(testDir, "p"), 82 new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto"}, 83 new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"}, 84 new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:archive"}); 85 // test -p option 86 test(new File(testDir, "Test.class"), 87 new String[] {"p.Foo", "p.Bar"}, 88 new String[] {"not found", "not found"}, 89 new String[] {"-verbose:class", "-p", "p"}); 90 // test -e option 91 test(new File(testDir, "Test.class"), 92 new String[] {"p.Foo", "p.Bar"}, 93 new String[] {"not found", "not found"}, 94 new String[] {"-verbose:class", "-e", "p\\..*"}); 95 test(new File(testDir, "Test.class"), 96 new String[] {"java.lang"}, 97 new String[] {"compact1"}, 98 new String[] {"-verbose:package", "-e", "java\\.lang\\..*"}); 99 // test -classpath options 100 test(new File(testDir, "Test.class"), 101 new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"}, 102 new String[] {"compact1", "compact1", testDir.getName(), testDir.getName()}, 103 new String[] {"-v", "-classpath", testDir.getPath()}); 104 105 testSummary(new File(testDir, "Test.class"), 106 new String[] {"java.base", testDir.getName()}, 107 new String[] {"compact1", ""}, 108 new String[] {"-classpath", testDir.getPath()}); 109 testSummary(new File(testDir, "Test.class"), 110 new String[] {"java.lang", "p"}, 111 new String[] {"compact1", testDir.getName()}, 112 new String[] {"-v", "-classpath", testDir.getPath()}); 113 return errors; 114 } 115 116 void test(File file, String[] expect, String[] profiles) throws IOException { 117 test(file, expect, profiles, new String[0]); 118 } 119 120 void test(File file, String[] expect, String[] profiles, String[] options) 121 throws IOException 122 { 123 Path dotfile = dotoutput.resolve(file.toPath().getFileName().toString() + ".dot"); 124 125 List<String> args = new ArrayList<>(Arrays.asList(options)); 126 args.add("-dotoutput"); 127 args.add(dotoutput.toString()); 128 if (file != null) { 129 args.add(file.getPath()); 130 } 131 132 Map<String,String> result = jdeps(args, dotfile); 133 checkResult("dependencies", expect, result.keySet()); 134 135 // with -P option 136 List<String> argsWithDashP = new ArrayList<>(); 137 argsWithDashP.add("-dotoutput"); 138 argsWithDashP.add(dotoutput.toString()); 139 argsWithDashP.add("-P"); 140 argsWithDashP.addAll(args); 141 142 result = jdeps(argsWithDashP, dotfile); 143 checkResult("profiles", expect, profiles, result); 144 } 145 146 void testSummary(File file, String[] expect, String[] profiles, String[] options) 147 throws IOException 148 { 149 Path dotfile = dotoutput.resolve("summary.dot"); 150 151 List<String> args = new ArrayList<>(Arrays.asList(options)); 152 args.add("-dotoutput"); 153 args.add(dotoutput.toString()); 154 if (file != null) { 155 args.add(file.getPath()); 156 } 157 158 Map<String,String> result = jdeps(args, dotfile); 159 checkResult("dependencies", expect, result.keySet()); 160 161 // with -P option 162 List<String> argsWithDashP = new ArrayList<>(); 163 argsWithDashP.add("-dotoutput"); 164 argsWithDashP.add(dotoutput.toString()); 165 argsWithDashP.add("-P"); 166 argsWithDashP.addAll(args); 167 168 result = jdeps(argsWithDashP, dotfile); 169 checkResult("profiles", expect, profiles, result); 170 } 171 172 Map<String,String> jdeps(List<String> args, Path dotfile) throws IOException { 173 if (Files.exists(dotoutput)) { 174 try (DirectoryStream<Path> stream = Files.newDirectoryStream(dotoutput)) { 175 for (Path p : stream) { 176 Files.delete(p); 177 } 178 } 179 Files.delete(dotoutput); 180 } 181 // invoke jdeps 182 StringWriter sw = new StringWriter(); 183 PrintWriter pw = new PrintWriter(sw); 184 System.err.println("jdeps " + args); 185 int rc = com.sun.tools.jdeps.Main.run(args.toArray(new String[0]), pw); 186 pw.close(); 187 String out = sw.toString(); 188 if (!out.isEmpty()) 189 System.err.println(out); 190 if (rc != 0) 191 throw new Error("jdeps failed: rc=" + rc); 192 193 // check output files 194 if (Files.notExists(dotfile)) { 195 throw new RuntimeException(dotfile + " doesn't exist"); 196 } 197 return parse(dotfile); 198 } 199 private static Pattern pattern = Pattern.compile("(.*) -> +([^ ]*) (.*)"); 200 private Map<String,String> parse(Path outfile) throws IOException { 201 Map<String,String> result = new LinkedHashMap<>(); 202 for (String line : Files.readAllLines(outfile)) { 203 line = line.replace('"', ' ').replace(';', ' '); 204 Matcher pm = pattern.matcher(line); 205 if (pm.find()) { 206 String origin = pm.group(1).trim(); 207 String target = pm.group(2).trim(); 208 String module = pm.group(3).replace('(', ' ').replace(')', ' ').trim(); 209 result.put(target, module); 210 } 211 } 212 return result; 213 } 214 215 void checkResult(String label, String[] expect, Collection<String> found) { 216 List<String> list = Arrays.asList(expect); 217 if (!isEqual(list, found)) 218 error("Unexpected " + label + " found: '" + found + "', expected: '" + list + "'"); 219 } 220 221 void checkResult(String label, String[] expect, String[] profiles, Map<String,String> result) { 222 if (expect.length != profiles.length) 223 error("Invalid expected names and profiles"); 224 225 // check the dependencies 226 checkResult(label, expect, result.keySet()); 227 // check profile information 228 checkResult(label, profiles, result.values()); 229 for (int i=0; i < expect.length; i++) { 230 String profile = result.get(expect[i]); 231 if (!profile.equals(profiles[i])) 232 error("Unexpected profile: '" + profile + "', expected: '" + profiles[i] + "'"); 233 } 234 } 235 236 boolean isEqual(List<String> expected, Collection<String> found) { 237 if (expected.size() != found.size()) 238 return false; 239 240 List<String> list = new ArrayList<>(found); 241 list.removeAll(expected); 242 return list.isEmpty(); 243 } 244 245 void error(String msg) { 246 System.err.println("Error: " + msg); 247 errors++; 248 } 249 250 int errors; 251} 252