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