test/tools/javac/file/zip/T6836682.java

changeset 936
f2f04935ef3f
parent 924
4fd20d5b7295
child 2525
2eb010b6cb22
equal deleted inserted replaced
935:5b29f2a85085 936:f2f04935ef3f
21 * questions. 21 * questions.
22 */ 22 */
23 23
24 /* 24 /*
25 * @test 25 * @test
26 * @ignore
27 * @bug 6836682 7025988 26 * @bug 6836682 7025988
28 * @summary JavacFileManager handles zip64 archives (64K+ entries and large file support) 27 * @summary JavacFileManager handling of zip64 archives (Scenario A and B)
29 * @compile -XDignore.symbol.file T6836682.java Utils.java 28 * @compile -XDignore.symbol.file T6836682.java Utils.java
30 * @run main T6836682 29 * @run main T6836682
31 */ 30 */
31 /*
32 * This test consists of two scenarios:
33 *
34 * Scenario A: create a jar with entries exceeding 64K, and see if the javac
35 * can handle this large jar on the classpath. Generally this test completes
36 * within a minute
37 *
38 * Scenario B: create a jar with a large enough file exceeding 4GB, and
39 * similarly test javac. This test is known to be slow and problematic on
40 * certain operating systems, thus this test can be selected by passing a
41 * property through jtreg as follows:
42 * -javaoptions=-DT6836682.testScenarioB=true.
43 * Note this test will only run iff all the disk requirements are met at runtime.
44 */
45 import java.io.BufferedInputStream;
32 import java.io.BufferedOutputStream; 46 import java.io.BufferedOutputStream;
33 import java.io.File; 47 import java.io.File;
34 import java.io.FileInputStream; 48 import java.io.FileInputStream;
35 import java.io.FileOutputStream; 49 import java.io.FileOutputStream;
36 import java.io.IOException; 50 import java.io.IOException;
51 import java.io.OutputStream;
37 import java.nio.file.Files; 52 import java.nio.file.Files;
38 import java.nio.file.Path; 53 import java.nio.file.Path;
39 import java.util.jar.JarOutputStream; 54 import java.util.zip.CRC32;
40 import java.util.zip.ZipEntry; 55 import java.util.zip.ZipEntry;
56 import java.util.zip.ZipOutputStream;
41 57
42 public class T6836682 { 58 public class T6836682 {
43 59
44 private static final long GIGA = 1024 * 1024 * 1024; 60 private static final long GIGA = 1024 * 1024 * 1024;
45 61 private static final int BUFFER_LEN = Short.MAX_VALUE * 2;
46 static void createLargeFile(File outFile, long minlength) throws IOException { 62
47 FileOutputStream fos = null; 63 static long getCount(long minlength) {
48 BufferedOutputStream bos = null; 64 return (minlength / BUFFER_LEN) + 1;
49 byte[] buffer = new byte[Short.MAX_VALUE * 2]; 65 }
50 try { 66
51 fos = new FileOutputStream(outFile); 67 static long computeCRC(long minlength) {
52 bos = new BufferedOutputStream(fos); 68 CRC32 crc = new CRC32();
53 long count = minlength / ( Short.MAX_VALUE * 2) + 1; 69 byte[] buffer = new byte[BUFFER_LEN];
54 for (long i = 0 ; i < count ; i++) { 70 long count = getCount(minlength);
55 bos.write(buffer); 71 for (long i = 0; i < count; i++) {
56 } 72 crc.update(buffer);
57 } finally { 73 }
58 Utils.close(bos); 74 return crc.getValue();
59 Utils.close(fos); 75 }
60 } 76
61 if (outFile.length() < minlength) { 77 static long computeCRC(File inFile) throws IOException {
62 throw new RuntimeException("could not create large file " + outFile.getAbsolutePath()); 78 byte[] buffer = new byte[8192];
63 } 79 CRC32 crc = new CRC32();
80 FileInputStream fis = null;
81 BufferedInputStream bis = null;
82 try {
83 fis = new FileInputStream(inFile);
84 bis = new BufferedInputStream(fis);
85 int n = bis.read(buffer);
86 while (n > 0) {
87 crc.update(buffer, 0, n);
88 n = bis.read(buffer);
89 }
90 } finally {
91 Utils.close(bis);
92 Utils.close(fis);
93 }
94 return crc.getValue();
95 }
96
97 static void createLargeFile(OutputStream os, long minlength) throws IOException {
98 byte[] buffer = new byte[BUFFER_LEN];
99 long count = getCount(minlength);
100 for (long i = 0; i < count; i++) {
101 os.write(buffer);
102 }
103 os.flush();
64 } 104 }
65 105
66 static void createJarWithLargeFile(File jarFile, File javaFile, 106 static void createJarWithLargeFile(File jarFile, File javaFile,
67 long minlength) throws IOException { 107 long minlength) throws IOException {
68 Utils.createClassFile(javaFile, null, true); 108 Utils.createClassFile(javaFile, null, true);
69 File largeFile = new File("large.data"); 109 File classFile = new File(Utils.getClassFileName(javaFile));
70 createLargeFile(largeFile, minlength); 110 ZipOutputStream zos = null;
71 String[] jarArgs = { 111 BufferedOutputStream bos = null;
72 "0cvf", 112 FileInputStream fis = null;
73 jarFile.getAbsolutePath(), 113 try {
74 largeFile.getName(), 114 zos = new ZipOutputStream(new FileOutputStream(jarFile));
75 Utils.getClassFileName(javaFile) 115 zos.setLevel(ZipOutputStream.STORED);
76 }; 116 zos.setMethod(0);
77 Utils.jarTool.run(jarArgs); 117 bos = new BufferedOutputStream(zos);
118
119 ZipEntry ze = new ZipEntry("large.data");
120 ze.setCompressedSize(getCount(minlength) * BUFFER_LEN);
121 ze.setSize(getCount(minlength) * BUFFER_LEN);
122 ze.setCrc(computeCRC(minlength));
123 ze.setMethod(ZipEntry.STORED);
124 zos.putNextEntry(ze);
125 createLargeFile(bos, minlength);
126
127 ze = new ZipEntry(classFile.getName());
128 ze.setCompressedSize(classFile.length());
129 ze.setSize(classFile.length());
130 ze.setCrc(computeCRC(classFile));
131 ze.setMethod(ZipEntry.STORED);
132 zos.putNextEntry(ze);
133 fis = new FileInputStream(classFile);
134 Utils.copyStream(fis, bos);
135 bos.flush();
136 zos.closeEntry();
137 } finally {
138 Utils.close(bos);
139 Utils.close(zos);
140 Utils.close(fis);
141 }
78 // deleted to prevent accidental linkage 142 // deleted to prevent accidental linkage
79 new File(Utils.getClassFileName(javaFile)).delete(); 143 new File(Utils.getClassFileName(javaFile)).delete();
80 } 144 }
81 145
82 static void createLargeJar(File jarFile, File javaFile) throws IOException { 146 static void createLargeJar(File jarFile, File javaFile) throws IOException {
83 File classFile = new File(Utils.getClassFileName(javaFile)); 147 File classFile = new File(Utils.getClassFileName(javaFile));
84 Utils.createClassFile(javaFile, null, true); 148 Utils.createClassFile(javaFile, null, true);
85 JarOutputStream jos = null; 149 ZipOutputStream zos = null;
86 FileInputStream fis = null; 150 FileInputStream fis = null;
87 try { 151 final int MAX = Short.MAX_VALUE * 2 + 10;
88 jos = new JarOutputStream(new FileOutputStream(jarFile)); 152 ZipEntry ze = null;
89 153 try {
90 for (int i = 0; i < Short.MAX_VALUE * 2 + 10; i++) { 154 zos = new ZipOutputStream(new FileOutputStream(jarFile));
91 jos.putNextEntry(new ZipEntry("X" + i + ".txt")); 155 zos.setLevel(ZipOutputStream.STORED);
92 } 156 zos.setMethod(ZipOutputStream.STORED);
93 jos.putNextEntry(new ZipEntry(classFile.getName())); 157 for (int i = 0; i < MAX ; i++) {
158 ze = new ZipEntry("X" + i + ".txt");
159 ze.setSize(0);
160 ze.setCompressedSize(0);
161 ze.setCrc(0);
162 zos.putNextEntry(ze);
163 }
164
165 // add a class file
166 ze = new ZipEntry(classFile.getName());
167 ze.setCompressedSize(classFile.length());
168 ze.setSize(classFile.length());
169 ze.setCrc(computeCRC(classFile));
170 zos.putNextEntry(ze);
94 fis = new FileInputStream(classFile); 171 fis = new FileInputStream(classFile);
95 Utils.copyStream(fis, jos); 172 Utils.copyStream(fis, zos);
96 } finally { 173 } finally {
97 Utils.close(jos); 174 Utils.close(zos);
98 Utils.close(fis); 175 Utils.close(fis);
99 }
100 // deleted to prevent accidental linkage 176 // deleted to prevent accidental linkage
101 new File(Utils.getClassFileName(javaFile)).delete(); 177 new File(Utils.getClassFileName(javaFile)).delete();
102 } 178 }
179 }
103 180
104 // a jar with entries exceeding 64k + a class file for the existential test 181 // a jar with entries exceeding 64k + a class file for the existential test
105 public static void testLargeJar(String... args) throws IOException { 182 public static void testScenarioA(String... args) throws IOException {
106 File largeJar = new File("large.jar"); 183 File largeJar = new File("large.jar");
107 File javaFile = new File("Foo.java"); 184 File javaFile = new File("Foo.java");
108 createLargeJar(largeJar, javaFile); 185 createLargeJar(largeJar, javaFile);
109 186
110 File testFile = new File("Bar.java"); 187 File testFile = new File("Bar.java");
118 Utils.deleteFile(largeJar); 195 Utils.deleteFile(largeJar);
119 } 196 }
120 } 197 }
121 198
122 // a jar with an enormous file + a class file for the existential test 199 // a jar with an enormous file + a class file for the existential test
123 public static void testHugeJar(String... args) throws IOException { 200 public static void testScenarioB(String... args) throws IOException {
124 final File largeJar = new File("huge.jar"); 201 final File largeJar = new File("huge.jar");
125 final File javaFile = new File("Foo.java"); 202 final File javaFile = new File("Foo.java");
126 203
127 final Path path = largeJar.getAbsoluteFile().getParentFile().toPath(); 204 final Path path = largeJar.getAbsoluteFile().getParentFile().toPath();
128 final long available = Files.getFileStore(path).getUsableSpace(); 205 final long available = Files.getFileStore(path).getUsableSpace();
129 final long MAX_VALUE = 0xFFFF_FFFFL; 206 final long MAX_VALUE = 0xFFFF_FFFFL;
130 207
131 final long absolute = MAX_VALUE + 1L; 208 final long absolute = MAX_VALUE + 1L;
132 final long required = (long)(absolute * 1.1); // pad for sundries 209 final long required = (long)(absolute * 1.1); // pad for sundries
133 System.out.println("\tavailable: " + available / GIGA + " GB"); 210 System.out.println("\tavailable: " + available / GIGA + " GB");
134 System.out.println("\required: " + required / GIGA + " GB"); 211 System.out.println("\trequired: " + required / GIGA + " GB");
135 212
136 if (available > required) { 213 if (available > required) {
137 createJarWithLargeFile(largeJar, javaFile, absolute); 214 createJarWithLargeFile(largeJar, javaFile, absolute);
138 File testFile = new File("Bar.java"); 215 File testFile = new File("Bar.java");
139 Utils.createJavaFile(testFile, javaFile); 216 Utils.createJavaFile(testFile, javaFile);
144 } 221 }
145 } finally { 222 } finally {
146 Utils.deleteFile(largeJar); 223 Utils.deleteFile(largeJar);
147 } 224 }
148 } else { 225 } else {
149 System.out.println("Warning: test passes vacuously, requirements exceeds available space"); 226 System.out.println("Warning: testScenarioB passes vacuously," +
227 " requirements exceeds available space");
150 } 228 }
151 } 229 }
152 230
153 public static void main(String... args) throws IOException { 231 public static void main(String... args) throws IOException {
154 testLargeJar(); 232 testScenarioA();
155 testHugeJar(); 233 System.out.println("testScenarioA: PASS");
234 if (Boolean.getBoolean("T6836682.testScenarioB")) {
235 testScenarioB();
236 System.out.println("testScenarioB: PASS");
237 } else {
238 System.out.println("Warning: testScenarioB, large file test skipped");
239 }
156 } 240 }
157 } 241 }

mercurial