Mon, 13 Dec 2010 14:56:50 +0000
7006109: Add test library to simplify the task of writing automated type-system tests
Summary: Types.java needs to be more stress-tested
Reviewed-by: jjg
1 /*
2 * Copyright (c) 2009, 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 */
24 /*
25 * @test
26 * @bug 6877206
27 * @summary JavaFileObject.toUri returns bogus URI (win)
28 */
30 import java.io.*;
31 import java.net.*;
32 import java.util.*;
33 import java.util.jar.*;
34 import java.util.zip.*;
35 import javax.tools.*;
37 import com.sun.tools.javac.file.JavacFileManager;
38 import com.sun.tools.javac.util.Context;
39 import com.sun.tools.javac.util.Options;
41 // Test URIs returned from JavacFileManager and its support classes.
42 // For a variety of file objects, verify the validity of FileObject.toUri()
43 // by verifying the URI exists and points to the same contents as the file
44 // object itself
46 public class T6877206 {
47 public static void main(String... args) throws Exception {
48 new T6877206().run();
49 }
51 Set<String> foundClasses = new TreeSet<String>();
52 Set<String> foundJars = new TreeSet<String>();
54 void run() throws Exception {
55 File rt_jar = findRtJar();
57 // names for entries to be created in directories and jar files
58 String[] entries = { "p/A.class", "p/resources/A-1.jpg" };
60 // test various combinations of directories and jar files, intended to
61 // cover all sources of URIs within JavacFileManager's support classes
63 test(createFileManager(), createDir("dir", entries), "p", entries.length);
64 test(createFileManager(), createDir("a b/dir", entries), "p", entries.length);
66 for (boolean useJavaUtilZip: new boolean[] { false, true }) {
67 test(createFileManager(useJavaUtilZip), createJar("jar", entries), "p", entries.length);
68 test(createFileManager(useJavaUtilZip), createJar("jar jar", entries), "p", entries.length);
70 for (boolean useSymbolFile: new boolean[] { false, true }) {
71 test(createFileManager(useJavaUtilZip, useSymbolFile), rt_jar, "java.lang.ref", -1);
72 }
73 }
75 // Verify that we hit all the impl classes we intended
76 checkCoverage("classes", foundClasses,
77 "RegularFileObject", "SymbolFileObject", "ZipFileIndexFileObject", "ZipFileObject");
79 // Verify that we hit the jar files we intended, specifically ct.sym as well as rt.jar
80 checkCoverage("jar files", foundJars,
81 "ct.sym", "jar", "jar jar", "rt.jar");
82 }
84 // use a new file manager for each test
85 void test(StandardJavaFileManager fm, File f, String pkg, int expect) throws Exception {
86 JarURLConnection c;
87 System.err.println("Test " + f);
88 try {
89 fm.setLocation(StandardLocation.CLASS_PATH, Collections.singleton(f));
91 int count = 0;
92 for (JavaFileObject fo: fm.list(StandardLocation.CLASS_PATH,
93 pkg, EnumSet.allOf(JavaFileObject.Kind.class), true)) {
94 System.err.println("checking " + fo);
95 // record the file object class name for coverage checks later
96 foundClasses.add(fo.getClass().getSimpleName());
97 testFileObject(fo);
98 count++;
99 }
101 if (expect > 0 && count != expect)
102 throw new Exception("wrong number of entries found: "
103 + count + ", expected " + expect);
104 } finally {
105 fm.close();
106 }
107 }
109 void testFileObject(JavaFileObject fo) throws Exception {
110 // test the validity of the result of toUri() by using URLConnection
111 // and comparing the results of reading from the connection with the
112 // result of reading from the file object directly.
113 URI uri = fo.toUri();
114 System.err.println("uri: " + uri);
116 URLConnection urlconn = uri.toURL().openConnection();
117 if (urlconn instanceof JarURLConnection) {
118 JarURLConnection jarconn = (JarURLConnection) urlconn;
119 File f = new File(jarconn.getJarFile().getName());
120 // record access to the jar file for coverage checks later
121 foundJars.add(f.getName());
122 }
124 try {
125 byte[] uriData = read(urlconn.getInputStream());
126 byte[] foData = read(fo.openInputStream());
127 if (!Arrays.equals(uriData, foData)) {
128 if (uriData.length != foData.length)
129 throw new Exception("data size differs: uri data "
130 + uriData.length + " bytes, fo data " + foData.length+ " bytes");
131 for (int i = 0; i < uriData.length; i++) {
132 if (uriData[i] != foData[i])
133 throw new Exception("unexpected data returned at offset " + i
134 + ", uri data " + uriData[i] + ", fo data " + foData[i]);
135 }
136 throw new AssertionError("cannot find difference");
137 }
138 } finally {
139 // In principle, simply closing the result of urlconn.getInputStream()
140 // should have been sufficient. But the internal JarURLConnection
141 // does not close the JarFile in an expeditious manner, thus preventing
142 // jtreg from deleting the jar file before starting the next test.
143 // Therefore we force access to the JarURLConnection to close the
144 // JarFile when necessary.
145 if (urlconn instanceof JarURLConnection) {
146 JarURLConnection jarconn = (JarURLConnection) urlconn;
147 jarconn.getJarFile().close();
148 }
149 }
150 }
152 void checkCoverage(String label, Set<String> found, String... expect) throws Exception {
153 Set<String> e = new TreeSet<String>(Arrays.asList(expect));
154 if (!found.equals(e)) {
155 e.removeAll(found);
156 throw new Exception("expected " + label + " not used: " + e);
157 }
158 }
160 JavacFileManager createFileManager() {
161 return createFileManager(false, false);
162 }
164 JavacFileManager createFileManager(boolean useJavaUtilZip) {
165 return createFileManager(useJavaUtilZip, false);
166 }
168 JavacFileManager createFileManager(boolean useJavaUtilZip, boolean useSymbolFile) {
169 // javac should really not be using system properties like this
170 // -- it should really be using (hidden) options -- but until then
171 // take care to leave system properties as we find them, so as not
172 // to adversely affect other tests that might follow.
173 String prev = System.getProperty("useJavaUtilZip");
174 boolean resetProperties = false;
175 try {
176 if (useJavaUtilZip) {
177 System.setProperty("useJavaUtilZip", "true");
178 resetProperties = true;
179 } else if (System.getProperty("useJavaUtilZip") != null) {
180 System.getProperties().remove("useJavaUtilZip");
181 resetProperties = true;
182 }
184 Context c = new Context();
185 if (!useSymbolFile) {
186 Options options = Options.instance(c);
187 options.put("ignore.symbol.file", "true");
188 }
190 return new JavacFileManager(c, false, null);
191 } finally {
192 if (resetProperties) {
193 if (prev == null) {
194 System.getProperties().remove("useJavaUtilZip");
195 } else {
196 System.setProperty("useJavaUtilZip", prev);
197 }
198 }
199 }
200 }
202 File createDir(String name, String... entries) throws Exception {
203 File dir = new File(name);
204 if (!dir.mkdirs())
205 throw new Exception("cannot create directories " + dir);
206 for (String e: entries) {
207 writeFile(new File(dir, e), e);
208 }
209 return dir;
210 }
212 File createJar(String name, String... entries) throws IOException {
213 File jar = new File(name);
214 OutputStream out = new FileOutputStream(jar);
215 try {
216 JarOutputStream jos = new JarOutputStream(out);
217 for (String e: entries) {
218 jos.putNextEntry(new ZipEntry(e));
219 jos.write(e.getBytes());
220 }
221 jos.close();
222 } finally {
223 out.close();
224 }
225 return jar;
226 }
228 File findRtJar() throws Exception {
229 File java_home = new File(System.getProperty("java.home"));
230 if (java_home.getName().equals("jre"))
231 java_home = java_home.getParentFile();
232 File rt_jar = new File(new File(new File(java_home, "jre"), "lib"), "rt.jar");
233 if (!rt_jar.exists())
234 throw new Exception("can't find rt.jar");
235 return rt_jar;
236 }
238 byte[] read(InputStream in) throws IOException {
239 byte[] data = new byte[1024];
240 int offset = 0;
241 try {
242 int n;
243 while ((n = in.read(data, offset, data.length - offset)) != -1) {
244 offset += n;
245 if (offset == data.length)
246 data = Arrays.copyOf(data, 2 * data.length);
247 }
248 } finally {
249 in.close();
250 }
251 return Arrays.copyOf(data, offset);
252 }
254 void writeFile(File f, String s) throws IOException {
255 f.getParentFile().mkdirs();
256 FileWriter out = new FileWriter(f);
257 try {
258 out.write(s);
259 } finally {
260 out.close();
261 }
262 }
263 }