DotFileTest.java revision 2571:10fc81ac75b4
1/* 2 * Copyright (c) 2014, 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 -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 private static boolean symbolFileExist = initProfiles(); 45 private static boolean initProfiles() { 46 // check if ct.sym exists; if not use the profiles.properties file 47 Path home = Paths.get(System.getProperty("java.home")); 48 if (home.endsWith("jre")) { 49 home = home.getParent(); 50 } 51 Path ctsym = home.resolve("lib").resolve("ct.sym"); 52 boolean symbolExists = ctsym.toFile().exists(); 53 if (!symbolExists) { 54 Path testSrcProfiles = 55 Paths.get(System.getProperty("test.src", "."), "profiles.properties"); 56 if (!testSrcProfiles.toFile().exists()) 57 throw new Error(testSrcProfiles + " does not exist"); 58 System.out.format("%s doesn't exist.%nUse %s to initialize profiles info%n", 59 ctsym, testSrcProfiles); 60 System.setProperty("jdeps.profiles", testSrcProfiles.toString()); 61 } 62 return symbolExists; 63 } 64 65 public static void main(String... args) throws Exception { 66 int errors = 0; 67 errors += new DotFileTest().run(); 68 if (errors > 0) 69 throw new Exception(errors + " errors found"); 70 } 71 72 final Path dir; 73 final Path dotoutput; 74 DotFileTest() { 75 this.dir = Paths.get(System.getProperty("test.classes", ".")); 76 this.dotoutput = dir.resolve("dots"); 77 } 78 79 int run() throws IOException { 80 File testDir = dir.toFile(); 81 // test a .class file 82 test(new File(testDir, "Test.class"), 83 new String[] {"java.lang", "p"}, 84 new String[] {"compact1", "not found"}); 85 // test a directory 86 // also test non-SE javax.activity class dependency 87 test(new File(testDir, "p"), 88 new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto"}, 89 new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"}, 90 new String[] {"-classpath", testDir.getPath()}); 91 // test class-level dependency output 92 test(new File(testDir, "Test.class"), 93 new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"}, 94 new String[] {"compact1", "compact1", "not found", "not found"}, 95 new String[] {"-verbose:class"}); 96 // test -filter:none option 97 test(new File(testDir, "p"), 98 new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto", "p"}, 99 new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1", "p"}, 100 new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:none"}); 101 // test -filter:archive option 102 test(new File(testDir, "p"), 103 new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto"}, 104 new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"}, 105 new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:archive"}); 106 // test -p option 107 test(new File(testDir, "Test.class"), 108 new String[] {"p.Foo", "p.Bar"}, 109 new String[] {"not found", "not found"}, 110 new String[] {"-verbose:class", "-p", "p"}); 111 // test -e option 112 test(new File(testDir, "Test.class"), 113 new String[] {"p.Foo", "p.Bar"}, 114 new String[] {"not found", "not found"}, 115 new String[] {"-verbose:class", "-e", "p\\..*"}); 116 test(new File(testDir, "Test.class"), 117 new String[] {"java.lang"}, 118 new String[] {"compact1"}, 119 new String[] {"-verbose:package", "-e", "java\\.lang\\..*"}); 120 // test -classpath options 121 test(new File(testDir, "Test.class"), 122 new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"}, 123 new String[] {"compact1", "compact1", testDir.getName(), testDir.getName()}, 124 new String[] {"-v", "-classpath", testDir.getPath()}); 125 126 testSummary(new File(testDir, "Test.class"), 127 new String[] {"java.base", testDir.getName()}, 128 new String[] {"compact1", ""}, 129 new String[] {"-classpath", testDir.getPath()}); 130 testSummary(new File(testDir, "Test.class"), 131 new String[] {"java.lang", "p"}, 132 new String[] {"compact1", testDir.getName()}, 133 new String[] {"-v", "-classpath", testDir.getPath()}); 134 return errors; 135 } 136 137 void test(File file, String[] expect, String[] profiles) throws IOException { 138 test(file, expect, profiles, new String[0]); 139 } 140 141 void test(File file, String[] expect, String[] profiles, String[] options) 142 throws IOException 143 { 144 Path dotfile = dotoutput.resolve(file.toPath().getFileName().toString() + ".dot"); 145 146 List<String> args = new ArrayList<>(Arrays.asList(options)); 147 args.add("-dotoutput"); 148 args.add(dotoutput.toString()); 149 if (file != null) { 150 args.add(file.getPath()); 151 } 152 153 Map<String,String> result = jdeps(args, dotfile); 154 checkResult("dependencies", expect, result.keySet()); 155 156 // with -P option 157 List<String> argsWithDashP = new ArrayList<>(); 158 argsWithDashP.add("-dotoutput"); 159 argsWithDashP.add(dotoutput.toString()); 160 argsWithDashP.add("-P"); 161 argsWithDashP.addAll(args); 162 163 result = jdeps(argsWithDashP, dotfile); 164 checkResult("profiles", expect, profiles, result); 165 } 166 167 void testSummary(File file, String[] expect, String[] profiles, String[] options) 168 throws IOException 169 { 170 Path dotfile = dotoutput.resolve("summary.dot"); 171 172 List<String> args = new ArrayList<>(Arrays.asList(options)); 173 args.add("-dotoutput"); 174 args.add(dotoutput.toString()); 175 if (file != null) { 176 args.add(file.getPath()); 177 } 178 179 Map<String,String> result = jdeps(args, dotfile); 180 checkResult("dependencies", expect, result.keySet()); 181 182 // with -P option 183 List<String> argsWithDashP = new ArrayList<>(); 184 argsWithDashP.add("-dotoutput"); 185 argsWithDashP.add(dotoutput.toString()); 186 argsWithDashP.add("-P"); 187 argsWithDashP.addAll(args); 188 189 result = jdeps(argsWithDashP, dotfile); 190 checkResult("profiles", expect, profiles, result); 191 } 192 193 Map<String,String> jdeps(List<String> args, Path dotfile) throws IOException { 194 if (Files.exists(dotoutput)) { 195 try (DirectoryStream<Path> stream = Files.newDirectoryStream(dotoutput)) { 196 for (Path p : stream) { 197 Files.delete(p); 198 } 199 } 200 Files.delete(dotoutput); 201 } 202 // invoke jdeps 203 StringWriter sw = new StringWriter(); 204 PrintWriter pw = new PrintWriter(sw); 205 System.err.println("jdeps " + args); 206 int rc = com.sun.tools.jdeps.Main.run(args.toArray(new String[0]), pw); 207 pw.close(); 208 String out = sw.toString(); 209 if (!out.isEmpty()) 210 System.err.println(out); 211 if (rc != 0) 212 throw new Error("jdeps failed: rc=" + rc); 213 214 // check output files 215 if (Files.notExists(dotfile)) { 216 throw new RuntimeException(dotfile + " doesn't exist"); 217 } 218 return parse(dotfile); 219 } 220 private static Pattern pattern = Pattern.compile("(.*) -> +([^ ]*) (.*)"); 221 private Map<String,String> parse(Path outfile) throws IOException { 222 Map<String,String> result = new LinkedHashMap<>(); 223 for (String line : Files.readAllLines(outfile)) { 224 line = line.replace('"', ' ').replace(';', ' '); 225 Matcher pm = pattern.matcher(line); 226 if (pm.find()) { 227 String origin = pm.group(1).trim(); 228 String target = pm.group(2).trim(); 229 String module = pm.group(3).replace('(', ' ').replace(')', ' ').trim(); 230 result.put(target, module); 231 } 232 } 233 return result; 234 } 235 236 void checkResult(String label, String[] expect, Collection<String> found) { 237 List<String> list = Arrays.asList(expect); 238 if (!isEqual(list, found)) 239 error("Unexpected " + label + " found: '" + found + "', expected: '" + list + "'"); 240 } 241 242 void checkResult(String label, String[] expect, String[] profiles, Map<String,String> result) { 243 if (expect.length != profiles.length) 244 error("Invalid expected names and profiles"); 245 246 // check the dependencies 247 checkResult(label, expect, result.keySet()); 248 // check profile information 249 checkResult(label, profiles, result.values()); 250 for (int i=0; i < expect.length; i++) { 251 String profile = result.get(expect[i]); 252 if (!profile.equals(profiles[i])) 253 error("Unexpected profile: '" + profile + "', expected: '" + profiles[i] + "'"); 254 } 255 } 256 257 boolean isEqual(List<String> expected, Collection<String> found) { 258 if (expected.size() != found.size()) 259 return false; 260 261 List<String> list = new ArrayList<>(found); 262 list.removeAll(expected); 263 return list.isEmpty(); 264 } 265 266 void error(String msg) { 267 System.err.println("Error: " + msg); 268 errors++; 269 } 270 271 int errors; 272} 273