7026359: (langtools) fix big jar test
authorksrini
Wed, 16 Mar 2011 09:41:30 -0700
changeset 8850 3c7365401a97
parent 8849 4189ac38ddc9
child 8851 e630c590eb10
7026359: (langtools) fix big jar test Reviewed-by: jjg
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");
+        }
     }
 }