SJavacTester.java revision 3219:aacc4ceb35c9
1/* 2 * Copyright (c) 2014, 2016, 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 24import java.util.*; 25import java.io.*; 26import java.nio.file.*; 27import java.nio.file.attribute.*; 28 29import com.sun.tools.sjavac.Main; 30 31public class SJavacTester { 32 33 final ToolBox tb = new ToolBox(); 34 final Path TEST_ROOT = Paths.get(getClass().getSimpleName()); 35 36 // Generated sources that will test aspects of sjavac 37 final Path GENSRC = TEST_ROOT.resolve("gensrc"); 38 // Gensrc dirs used to test merging of serveral source roots. 39 final Path GENSRC2 = TEST_ROOT.resolve("gensrc2"); 40 final Path GENSRC3 = TEST_ROOT.resolve("gensrc3"); 41 42 // Dir for compiled classes. 43 final Path BIN = TEST_ROOT.resolve("bin"); 44 // Dir for c-header files. 45 final Path HEADERS = TEST_ROOT.resolve("headers"); 46 47 // Remember the previous bin and headers state here. 48 Map<String,Long> previous_bin_state; 49 Map<String,Long> previous_headers_state; 50 51 void initialCompile() throws Exception { 52 System.out.println("\nInitial compile of gensrc."); 53 tb.writeFile(GENSRC.resolve("alfa/omega/AINT.java"), 54 "package alfa.omega; public interface AINT { void aint(); }"); 55 tb.writeFile(GENSRC.resolve("alfa/omega/A.java"), 56 "package alfa.omega; public class A implements AINT { "+ 57 "public final static int DEFINITION = 17; public void aint() { } }"); 58 tb.writeFile(GENSRC.resolve("alfa/omega/AA.java"), 59 "package alfa.omega;"+ 60 "// A package private class, not contributing to the public api.\n"+ 61 "class AA {"+ 62 " // A properly nested static inner class.\n"+ 63 " static class AAA { }\n"+ 64 " // A properly nested inner class.\n"+ 65 " class AAAA { }\n"+ 66 " Runnable foo() {\n"+ 67 " // A proper anonymous class.\n"+ 68 " return new Runnable() { public void run() { } };\n"+ 69 " }\n"+ 70 " AAA aaa;\n"+ 71 " AAAA aaaa;\n"+ 72 " AAAAA aaaaa;\n"+ 73 "}\n"+ 74 "class AAAAA {\n"+ 75 " // A bad auxiliary class, but no one is referencing it\n"+ 76 " // from outside of this source file, therefore it is ok.\n"+ 77 "}\n"); 78 tb.writeFile(GENSRC.resolve("beta/BINT.java"), 79 "package beta;public interface BINT { void foo(); }"); 80 tb.writeFile(GENSRC.resolve("beta/B.java"), 81 "package beta; import alfa.omega.A; public class B {"+ 82 "private int b() { return A.DEFINITION; } native void foo(); }"); 83 84 compile(GENSRC.toString(), 85 "-d", BIN.toString(), 86 "--state-dir=" + BIN, 87 "-h", HEADERS.toString(), 88 "-j", "1", 89 "--log=debug"); 90 } 91 92 void removeFrom(Path dir, String... args) throws IOException { 93 for (String filename : args) { 94 Path p = dir.resolve(filename); 95 Files.delete(p); 96 } 97 } 98 99 void compile(String... args) throws Exception { 100 int rc = Main.go(args); 101 if (rc != 0) throw new Exception("Error during compile!"); 102 103 // Wait a second, to get around the (temporary) problem with 104 // second resolution in the Java file api. But do not do this 105 // on windows where the timestamps work. 106 long in_a_sec = System.currentTimeMillis()+1000; 107 while (in_a_sec > System.currentTimeMillis()) { 108 try { 109 Thread.sleep(1000); 110 } catch (InterruptedException e) { 111 } 112 } 113 } 114 115 void compileExpectFailure(String... args) throws Exception { 116 int rc = Main.go(args); 117 if (rc == 0) throw new Exception("Expected error during compile! Did not fail!"); 118 } 119 120 Map<String,Long> collectState(Path dir) throws IOException { 121 final Map<String,Long> files = new HashMap<>(); 122 Files.walkFileTree(dir, new SimpleFileVisitor<Path>() { 123 @Override 124 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 125 throws IOException 126 { 127 files.put(file.toString(),new Long(Files.getLastModifiedTime(file).toMillis())); 128 return FileVisitResult.CONTINUE; 129 } 130 }); 131 return files; 132 } 133 134 void verifyThatFilesHaveBeenRemoved(Map<String,Long> from, 135 Map<String,Long> to, 136 String... args) throws Exception { 137 138 Set<String> froms = from.keySet(); 139 Set<String> tos = to.keySet(); 140 141 if (froms.equals(tos)) { 142 throw new Exception("Expected new state to have fewer files than previous state!"); 143 } 144 145 for (String t : tos) { 146 if (!froms.contains(t)) { 147 throw new Exception("Expected "+t+" to exist in previous state!"); 148 } 149 } 150 151 for (String f : args) { 152 f = f.replace("/", File.separator); 153 if (!froms.contains(f)) { 154 throw new Exception("Expected "+f+" to exist in previous state!"); 155 } 156 if (tos.contains(f)) { 157 throw new Exception("Expected "+f+" to have been removed from the new state!"); 158 } 159 } 160 161 if (froms.size() - args.length != tos.size()) { 162 throw new Exception("There are more removed files than the expected list!"); 163 } 164 } 165 166 void verifyThatFilesHaveBeenAdded(Map<String,Long> from, 167 Map<String,Long> to, 168 String... args) throws Exception { 169 170 Set<String> froms = from.keySet(); 171 Set<String> tos = to.keySet(); 172 173 if (froms.equals(tos)) { 174 throw new Exception("Expected new state to have more files than previous state!"); 175 } 176 177 for (String t : froms) { 178 if (!tos.contains(t)) { 179 throw new Exception("Expected "+t+" to exist in new state!"); 180 } 181 } 182 183 for (String f : args) { 184 f = f.replace("/", File.separator); 185 if (!tos.contains(f)) { 186 throw new Exception("Expected "+f+" to have been added to new state!"); 187 } 188 if (froms.contains(f)) { 189 throw new Exception("Expected "+f+" to not exist in previous state!"); 190 } 191 } 192 193 if (froms.size() + args.length != tos.size()) { 194 throw new Exception("There are more added files than the expected list!"); 195 } 196 } 197 198 void verifyNewerFiles(Map<String,Long> from, 199 Map<String,Long> to, 200 String... args) throws Exception { 201 if (!from.keySet().equals(to.keySet())) { 202 throw new Exception("Expected the set of files to be identical!"); 203 } 204 Set<String> files = new HashSet<String>(); 205 for (String s : args) { 206 files.add(s.replace("/", File.separator)); 207 } 208 for (String fn : from.keySet()) { 209 long f = from.get(fn); 210 long t = to.get(fn); 211 if (files.contains(fn)) { 212 if (t <= f) { 213 throw new Exception("Expected "+fn+" to have a more recent timestamp!"); 214 } 215 } else { 216 if (t != f) { 217 throw new Exception("Expected "+fn+" to have the same timestamp!"); 218 } 219 } 220 } 221 } 222 223 String print(Map<String,Long> m) { 224 StringBuilder b = new StringBuilder(); 225 Set<String> keys = m.keySet(); 226 for (String k : keys) { 227 b.append(k+" "+m.get(k)+"\n"); 228 } 229 return b.toString(); 230 } 231 232 void verifyEqual(Map<String,Long> from, Map<String,Long> to) throws Exception { 233 if (!from.equals(to)) { 234 System.out.println("FROM---"+print(from)); 235 System.out.println("TO-----"+print(to)); 236 throw new Exception("The dir should not differ! But it does!"); 237 } 238 } 239} 240