# HG changeset patch # User ksrini # Date 1300293690 25200 # Node ID 3c7365401a9700f9261803f07a0f0b268afa05a4 # Parent 4189ac38ddc9293d5f1cd0dd7f1aea934ab0cd42 7026359: (langtools) fix big jar test Reviewed-by: jjg diff -r 4189ac38ddc9 -r 3c7365401a97 langtools/test/tools/javac/file/zip/T6836682.java --- a/langtools/test/tools/javac/file/zip/T6836682.java Wed Mar 16 11:12:26 2011 +0000 +++ b/langtools/test/tools/javac/file/zip/T6836682.java Wed Mar 16 09:41:30 2011 -0700 @@ -23,58 +23,122 @@ /* * @test - * @ignore * @bug 6836682 7025988 - * @summary JavacFileManager handles zip64 archives (64K+ entries and large file support) + * @summary JavacFileManager handling of zip64 archives (Scenario A and B) * @compile -XDignore.symbol.file T6836682.java Utils.java * @run main T6836682 */ +/* + * This test consists of two scenarios: + * + * Scenario A: create a jar with entries exceeding 64K, and see if the javac + * can handle this large jar on the classpath. Generally this test completes + * within a minute + * + * Scenario B: create a jar with a large enough file exceeding 4GB, and + * similarly test javac. This test is known to be slow and problematic on + * certain operating systems, thus this test can be selected by passing a + * property through jtreg as follows: + * -javaoptions=-DT6836682.testScenarioB=true. + * Note this test will only run iff all the disk requirements are met at runtime. + */ +import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; -import java.util.jar.JarOutputStream; +import java.util.zip.CRC32; import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; public class T6836682 { private static final long GIGA = 1024 * 1024 * 1024; + private static final int BUFFER_LEN = Short.MAX_VALUE * 2; - static void createLargeFile(File outFile, long minlength) throws IOException { - FileOutputStream fos = null; - BufferedOutputStream bos = null; - byte[] buffer = new byte[Short.MAX_VALUE * 2]; + static long getCount(long minlength) { + return (minlength / BUFFER_LEN) + 1; + } + + static long computeCRC(long minlength) { + CRC32 crc = new CRC32(); + byte[] buffer = new byte[BUFFER_LEN]; + long count = getCount(minlength); + for (long i = 0; i < count; i++) { + crc.update(buffer); + } + return crc.getValue(); + } + + static long computeCRC(File inFile) throws IOException { + byte[] buffer = new byte[8192]; + CRC32 crc = new CRC32(); + FileInputStream fis = null; + BufferedInputStream bis = null; try { - fos = new FileOutputStream(outFile); - bos = new BufferedOutputStream(fos); - long count = minlength / ( Short.MAX_VALUE * 2) + 1; - for (long i = 0 ; i < count ; i++) { - bos.write(buffer); + fis = new FileInputStream(inFile); + bis = new BufferedInputStream(fis); + int n = bis.read(buffer); + while (n > 0) { + crc.update(buffer, 0, n); + n = bis.read(buffer); } } finally { - Utils.close(bos); - Utils.close(fos); + Utils.close(bis); + Utils.close(fis); } - if (outFile.length() < minlength) { - throw new RuntimeException("could not create large file " + outFile.getAbsolutePath()); + return crc.getValue(); + } + + static void createLargeFile(OutputStream os, long minlength) throws IOException { + byte[] buffer = new byte[BUFFER_LEN]; + long count = getCount(minlength); + for (long i = 0; i < count; i++) { + os.write(buffer); } + os.flush(); } static void createJarWithLargeFile(File jarFile, File javaFile, long minlength) throws IOException { Utils.createClassFile(javaFile, null, true); - File largeFile = new File("large.data"); - createLargeFile(largeFile, minlength); - String[] jarArgs = { - "0cvf", - jarFile.getAbsolutePath(), - largeFile.getName(), - Utils.getClassFileName(javaFile) - }; - Utils.jarTool.run(jarArgs); + File classFile = new File(Utils.getClassFileName(javaFile)); + ZipOutputStream zos = null; + BufferedOutputStream bos = null; + FileInputStream fis = null; + try { + zos = new ZipOutputStream(new FileOutputStream(jarFile)); + zos.setLevel(ZipOutputStream.STORED); + zos.setMethod(0); + bos = new BufferedOutputStream(zos); + + ZipEntry ze = new ZipEntry("large.data"); + ze.setCompressedSize(getCount(minlength) * BUFFER_LEN); + ze.setSize(getCount(minlength) * BUFFER_LEN); + ze.setCrc(computeCRC(minlength)); + ze.setMethod(ZipEntry.STORED); + zos.putNextEntry(ze); + createLargeFile(bos, minlength); + + ze = new ZipEntry(classFile.getName()); + ze.setCompressedSize(classFile.length()); + ze.setSize(classFile.length()); + ze.setCrc(computeCRC(classFile)); + ze.setMethod(ZipEntry.STORED); + zos.putNextEntry(ze); + fis = new FileInputStream(classFile); + Utils.copyStream(fis, bos); + bos.flush(); + zos.closeEntry(); + } finally { + Utils.close(bos); + Utils.close(zos); + Utils.close(fis); + } // deleted to prevent accidental linkage new File(Utils.getClassFileName(javaFile)).delete(); } @@ -82,27 +146,40 @@ static void createLargeJar(File jarFile, File javaFile) throws IOException { File classFile = new File(Utils.getClassFileName(javaFile)); Utils.createClassFile(javaFile, null, true); - JarOutputStream jos = null; + ZipOutputStream zos = null; FileInputStream fis = null; + final int MAX = Short.MAX_VALUE * 2 + 10; + ZipEntry ze = null; try { - jos = new JarOutputStream(new FileOutputStream(jarFile)); - - for (int i = 0; i < Short.MAX_VALUE * 2 + 10; i++) { - jos.putNextEntry(new ZipEntry("X" + i + ".txt")); + zos = new ZipOutputStream(new FileOutputStream(jarFile)); + zos.setLevel(ZipOutputStream.STORED); + zos.setMethod(ZipOutputStream.STORED); + for (int i = 0; i < MAX ; i++) { + ze = new ZipEntry("X" + i + ".txt"); + ze.setSize(0); + ze.setCompressedSize(0); + ze.setCrc(0); + zos.putNextEntry(ze); } - jos.putNextEntry(new ZipEntry(classFile.getName())); + + // add a class file + ze = new ZipEntry(classFile.getName()); + ze.setCompressedSize(classFile.length()); + ze.setSize(classFile.length()); + ze.setCrc(computeCRC(classFile)); + zos.putNextEntry(ze); fis = new FileInputStream(classFile); - Utils.copyStream(fis, jos); + Utils.copyStream(fis, zos); } finally { - Utils.close(jos); + Utils.close(zos); Utils.close(fis); - } // deleted to prevent accidental linkage new File(Utils.getClassFileName(javaFile)).delete(); } + } // a jar with entries exceeding 64k + a class file for the existential test - public static void testLargeJar(String... args) throws IOException { + public static void testScenarioA(String... args) throws IOException { File largeJar = new File("large.jar"); File javaFile = new File("Foo.java"); createLargeJar(largeJar, javaFile); @@ -120,7 +197,7 @@ } // a jar with an enormous file + a class file for the existential test - public static void testHugeJar(String... args) throws IOException { + public static void testScenarioB(String... args) throws IOException { final File largeJar = new File("huge.jar"); final File javaFile = new File("Foo.java"); @@ -131,7 +208,7 @@ final long absolute = MAX_VALUE + 1L; final long required = (long)(absolute * 1.1); // pad for sundries System.out.println("\tavailable: " + available / GIGA + " GB"); - System.out.println("\required: " + required / GIGA + " GB"); + System.out.println("\trequired: " + required / GIGA + " GB"); if (available > required) { createJarWithLargeFile(largeJar, javaFile, absolute); @@ -146,12 +223,19 @@ Utils.deleteFile(largeJar); } } else { - System.out.println("Warning: test passes vacuously, requirements exceeds available space"); + System.out.println("Warning: testScenarioB passes vacuously," + + " requirements exceeds available space"); } } public static void main(String... args) throws IOException { - testLargeJar(); - testHugeJar(); + testScenarioA(); + System.out.println("testScenarioA: PASS"); + if (Boolean.getBoolean("T6836682.testScenarioB")) { + testScenarioB(); + System.out.println("testScenarioB: PASS"); + } else { + System.out.println("Warning: testScenarioB, large file test skipped"); + } } }