SJavacTester.java revision 2958:27da0c3ac83a
1235274Sgabor/* 2235274Sgabor * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. 3235274Sgabor * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4235274Sgabor * 5235274Sgabor * This code is free software; you can redistribute it and/or modify it 6235274Sgabor * under the terms of the GNU General Public License version 2 only, as 7235274Sgabor * published by the Free Software Foundation. 8235274Sgabor * 9235274Sgabor * This code is distributed in the hope that it will be useful, but WITHOUT 10235274Sgabor * 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 static final String SERVER_ARG = "--server:" 34 + "portfile=testportfile," 35 + "background=false"; 36 37 final Path TEST_ROOT = Paths.get(getClass().getSimpleName()); 38 39 // Generated sources that will test aspects of sjavac 40 final Path GENSRC = TEST_ROOT.resolve("gensrc"); 41 // Gensrc dirs used to test merging of serveral source roots. 42 final Path GENSRC2 = TEST_ROOT.resolve("gensrc2"); 43 final Path GENSRC3 = TEST_ROOT.resolve("gensrc3"); 44 45 // Dir for compiled classes. 46 final Path BIN = TEST_ROOT.resolve("bin"); 47 // Dir for c-header files. 48 final Path HEADERS = TEST_ROOT.resolve("headers"); 49 50 // Remember the previous bin and headers state here. 51 Map<String,Long> previous_bin_state; 52 Map<String,Long> previous_headers_state; 53 54 void initialCompile() throws Exception { 55 System.out.println("\nInitial compile of gensrc."); 56 ToolBox tb = new ToolBox(); 57 tb.writeFile(GENSRC.resolve("alfa/omega/AINT.java"), 58 "package alfa.omega; public interface AINT { void aint(); }"); 59 tb.writeFile(GENSRC.resolve("alfa/omega/A.java"), 60 "package alfa.omega; public class A implements AINT { "+ 61 "public final static int DEFINITION = 17; public void aint() { } }"); 62 tb.writeFile(GENSRC.resolve("alfa/omega/AA.java"), 63 "package alfa.omega;"+ 64 "// A package private class, not contributing to the public api.\n"+ 65 "class AA {"+ 66 " // A properly nested static inner class.\n"+ 67 " static class AAA { }\n"+ 68 " // A properly nested inner class.\n"+ 69 " class AAAA { }\n"+ 70 " Runnable foo() {\n"+ 71 " // A proper anonymous class.\n"+ 72 " return new Runnable() { public void run() { } };\n"+ 73 " }\n"+ 74 " AAA aaa;\n"+ 75 " AAAA aaaa;\n"+ 76 " AAAAA aaaaa;\n"+ 77 "}\n"+ 78 "class AAAAA {\n"+ 79 " // A bad auxiliary class, but no one is referencing it\n"+ 80 " // from outside of this source file, therefore it is ok.\n"+ 81 "}\n"); 82 tb.writeFile(GENSRC.resolve("beta/BINT.java"), 83 "package beta;public interface BINT { void foo(); }"); 84 tb.writeFile(GENSRC.resolve("beta/B.java"), 85 "package beta; import alfa.omega.A; public class B {"+ 86 "private int b() { return A.DEFINITION; } native void foo(); }"); 87 88 compile(GENSRC.toString(), 89 "-d", BIN.toString(), 90 "-h", HEADERS.toString(), 91 "-j", "1", 92 SERVER_ARG, 93 "--log=debug"); 94 } 95 96 void removeFrom(Path dir, String... args) throws IOException { 97 for (String filename : args) { 98 Path p = dir.resolve(filename); 99 Files.delete(p); 100 } 101 } 102 103 void delete(final Path root) throws IOException { 104 if (!Files.exists(root)) return; 105 Files.walkFileTree(root, new SimpleFileVisitor<Path>() { 106 @Override 107 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException 108 { 109 Files.delete(file); 110 return FileVisitResult.CONTINUE; 111 } 112 113 @Override 114 public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException 115 { 116 if (e == null) { 117 if (!dir.equals(root)) Files.delete(dir); 118 return FileVisitResult.CONTINUE; 119 } else { 120 // directory iteration failed 121 throw e; 122 } 123 } 124 }); 125 } 126 127 void compile(String... args) throws Exception { 128 int rc = Main.go(args); 129 if (rc != 0) throw new Exception("Error during compile!"); 130 131 // Wait a second, to get around the (temporary) problem with 132 // second resolution in the Java file api. But do not do this 133 // on windows where the timestamps work. 134 long in_a_sec = System.currentTimeMillis()+1000; 135 while (in_a_sec > System.currentTimeMillis()) { 136 try { 137 Thread.sleep(1000); 138 } catch (InterruptedException e) { 139 } 140 } 141 } 142 143 void compileExpectFailure(String... args) throws Exception { 144 int rc = Main.go(args); 145 if (rc == 0) throw new Exception("Expected error during compile! Did not fail!"); 146 } 147 148 Map<String,Long> collectState(Path dir) throws IOException { 149 final Map<String,Long> files = new HashMap<>(); 150 Files.walkFileTree(dir, new SimpleFileVisitor<Path>() { 151 @Override 152 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) 153 throws IOException 154 { 155 files.put(file.toString(),new Long(Files.getLastModifiedTime(file).toMillis())); 156 return FileVisitResult.CONTINUE; 157 } 158 }); 159 return files; 160 } 161 162 void verifyThatFilesHaveBeenRemoved(Map<String,Long> from, 163 Map<String,Long> to, 164 String... args) throws Exception { 165 166 Set<String> froms = from.keySet(); 167 Set<String> tos = to.keySet(); 168 169 if (froms.equals(tos)) { 170 throw new Exception("Expected new state to have fewer files than previous state!"); 171 } 172 173 for (String t : tos) { 174 if (!froms.contains(t)) { 175 throw new Exception("Expected "+t+" to exist in previous state!"); 176 } 177 } 178 179 for (String f : args) { 180 f = f.replace("/", File.separator); 181 if (!froms.contains(f)) { 182 throw new Exception("Expected "+f+" to exist in previous state!"); 183 } 184 if (tos.contains(f)) { 185 throw new Exception("Expected "+f+" to have been removed from the new state!"); 186 } 187 } 188 189 if (froms.size() - args.length != tos.size()) { 190 throw new Exception("There are more removed files than the expected list!"); 191 } 192 } 193 194 void verifyThatFilesHaveBeenAdded(Map<String,Long> from, 195 Map<String,Long> to, 196 String... args) throws Exception { 197 198 Set<String> froms = from.keySet(); 199 Set<String> tos = to.keySet(); 200 201 if (froms.equals(tos)) { 202 throw new Exception("Expected new state to have more files than previous state!"); 203 } 204 205 for (String t : froms) { 206 if (!tos.contains(t)) { 207 throw new Exception("Expected "+t+" to exist in new state!"); 208 } 209 } 210 211 for (String f : args) { 212 f = f.replace("/", File.separator); 213 if (!tos.contains(f)) { 214 throw new Exception("Expected "+f+" to have been added to new state!"); 215 } 216 if (froms.contains(f)) { 217 throw new Exception("Expected "+f+" to not exist in previous state!"); 218 } 219 } 220 221 if (froms.size() + args.length != tos.size()) { 222 throw new Exception("There are more added files than the expected list!"); 223 } 224 } 225 226 void verifyNewerFiles(Map<String,Long> from, 227 Map<String,Long> to, 228 String... args) throws Exception { 229 if (!from.keySet().equals(to.keySet())) { 230 throw new Exception("Expected the set of files to be identical!"); 231 } 232 Set<String> files = new HashSet<String>(); 233 for (String s : args) { 234 files.add(s.replace("/", File.separator)); 235 } 236 for (String fn : from.keySet()) { 237 long f = from.get(fn); 238 long t = to.get(fn); 239 if (files.contains(fn)) { 240 if (t <= f) { 241 throw new Exception("Expected "+fn+" to have a more recent timestamp!"); 242 } 243 } else { 244 if (t != f) { 245 throw new Exception("Expected "+fn+" to have the same timestamp!"); 246 } 247 } 248 } 249 } 250 251 String print(Map<String,Long> m) { 252 StringBuilder b = new StringBuilder(); 253 Set<String> keys = m.keySet(); 254 for (String k : keys) { 255 b.append(k+" "+m.get(k)+"\n"); 256 } 257 return b.toString(); 258 } 259 260 void verifyEqual(Map<String,Long> from, Map<String,Long> to) throws Exception { 261 if (!from.equals(to)) { 262 System.out.println("FROM---"+print(from)); 263 System.out.println("TO-----"+print(to)); 264 throw new Exception("The dir should not differ! But it does!"); 265 } 266 } 267 268 void clean(Path... listOfDirs) throws Exception { 269 for (Path dir : listOfDirs) { 270 delete(dir); 271 } 272 } 273} 274