Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Java/Openjdk/test/jdk/java/util/zip/ZipFile/   (Sun/Oracle ©)  Datei vom 13.11.2022 mit Größe 14 kB image not shown  

Quelle  TestZipFile.java   Sprache: JAVA

 
/*
 * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */


/*
 * @test
 * @bug 8142508 8146431
 * @modules java.base/java.util.zip:open
 * @summary Tests various ZipFile apis
 * @run main/manual TestZipFile
 */


import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class TestZipFile {

    private static final Random r = new Random();
    private static final int    N = 50;
    private static final int    NN = 10;
    private static final int    ENUM = 10000;
    private static final int    ESZ = 10000;
    private static ExecutorService executor = Executors.newFixedThreadPool(20);
    private static final Set<Path> paths = new HashSet<>();
    private static final boolean isWindows = System.getProperty("os.name")
            .startsWith("Windows");

    static void realMain (String[] args) throws Throwable {
        try {
            for (int i = 0; i < N; i++) {
                test(r.nextInt(ENUM), r.nextInt(ESZ), falsetrue);
                test(r.nextInt(ENUM), r.nextInt(ESZ), truetrue);
            }
            executor.shutdown();
            executor.awaitTermination(10, TimeUnit.MINUTES);
            executor = Executors.newFixedThreadPool(20);
            for (int i = 0; i < NN; i++) {
                test(r.nextInt(ENUM), 100000 + r.nextInt(ESZ), falsetrue);
                test(r.nextInt(ENUM), 100000 + r.nextInt(ESZ), truetrue);
                if(!isWindows) {
                    testCachedDelete();
                    testCachedOverwrite();
                }
            }
            test(70000, 1000, falsetrue);   // > 65536 entry number;
            testDelete();                     // OPEN_DELETE

            executor.shutdown();
            executor.awaitTermination(10, TimeUnit.MINUTES);
        } finally {
            for (Path path : paths) {
                Files.deleteIfExists(path);
            }
        }
    }

    static void test(int numEntry, int szMax, boolean addPrefix, boolean cleanOld) {
        String name = "test-" + r.nextInt() + ".zip";
        Zip zip = new Zip(name, numEntry, szMax, addPrefix, cleanOld);
        for (int i = 0; i < NN; i++) {
            executor.submit(() -> doTest(zip));
        }
     }

    // test scenario:
    // (1) open the ZipFile(zip) with OPEN_READ | OPEN_DELETE
    // (2) test the ZipFile works correctly
    // (3) check the zip is deleted after ZipFile gets closed
    static void testDelete() throws Throwable {
        String name = "testDelete-" + r.nextInt() + ".zip";
        Zip zip = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), falsetrue);
        try (ZipFile zf = new ZipFile(new File(zip.name),
                                      ZipFile.OPEN_READ | ZipFile.OPEN_DELETE ))
        {
            doTest0(zip, zf);
        }
        Path p = Paths.get(name);
        if (Files.exists(p)) {
            fail("Failed to delete " + name + " with OPEN_DELETE");
        }
    }

    // test scenario:
    // (1) keep a ZipFile(zip1) alive (in ZipFile's cache), dont close it
    // (2) delete zip1 and create zip2 with the same name the zip1 with zip2
    // (3) zip1 tests should fail, but no crash
    // (4) zip2 tasks should all get zip2, then pass normal testing.
    static void testCachedDelete() throws Throwable {
        String name = "testCachedDelete-" + r.nextInt() + ".zip";
        Zip zip1 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), falsetrue);

        try (ZipFile zf = new ZipFile(zip1.name)) {
            for (int i = 0; i < NN; i++) {
                executor.submit(() -> verifyNoCrash(zip1));
            }
            // delete the "zip1"  and create a new one to test
            Zip zip2 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), falsetrue);
            /*
                System.out.println("========================================");
                System.out.printf("    zip1=%s, mt=%d, enum=%d%n    ->attrs=[key=%s, sz=%d, mt=%d]%n",
                    zip1.name, zip1.lastModified, zip1.entries.size(),
                    zip1.attrs.fileKey(), zip1.attrs.size(), zip1.attrs.lastModifiedTime().toMillis());
                System.out.printf("    zip2=%s, mt=%d, enum=%d%n    ->attrs=[key=%s, sz=%d, mt=%d]%n",
                    zip2.name, zip2.lastModified, zip2.entries.size(),
                    zip2.attrs.fileKey(), zip2.attrs.size(), zip2.attrs.lastModifiedTime().toMillis());
            */

            for (int i = 0; i < NN; i++) {
                executor.submit(() -> doTest(zip2));
            }
        }
    }

   // overwrite the "zip1"  and create a new one to test. So the two zip files
   // have the same fileKey, but probably different lastModified()
    static void testCachedOverwrite() throws Throwable {
        String name = "testCachedOverWrite-" + r.nextInt() + ".zip";
        Zip zip1 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), falsetrue);
        try (ZipFile zf = new ZipFile(zip1.name)) {
            for (int i = 0; i < NN; i++) {
                executor.submit(() -> verifyNoCrash(zip1));
            }
            // overwrite the "zip1"  with new contents
            Zip zip2 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), falsefalse);
            for (int i = 0; i < NN; i++) {
                executor.submit(() -> doTest(zip2));
            }
        }
    }

    // just check the entries and contents. since the file has been either overwritten
    // or deleted/rewritten, we only care if it crahes or not.
    static void verifyNoCrash(Zip zip) throws RuntimeException {
        try (ZipFile zf = new ZipFile(zip.name)) {
            List<ZipEntry> zlist = new ArrayList<>(zip.entries.keySet());
            String[] elist = zf.stream().map(e -> e.getName()).toArray(String[]::new);
            if (!Arrays.equals(elist,
                               zlist.stream().map( e -> e.getName()).toArray(String[]::new)))
            {
                //System.out.printf("++++++ LIST NG [%s] entries.len=%d, expected=%d+++++++%n",
                //                  zf.getName(), elist.length, zlist.size());
                return;
            }
            for (ZipEntry ze : zlist) {
                byte[] zdata = zip.entries.get(ze);
                ZipEntry e = zf.getEntry(ze.getName());
                if (e != null) {
                    checkEqual(e, ze);
                    if (!e.isDirectory()) {
                        // check with readAllBytes
                        try (InputStream is = zf.getInputStream(e)) {
                            if (!Arrays.equals(zdata, is.readAllBytes())) {
                                //System.out.printf("++++++ BYTES NG  [%s]/[%s] ++++++++%n",
                                //                  zf.getName(), ze.getName());
                            }
                        }
                    }
                }
            }
        } catch (Throwable t) {
            // t.printStackTrace();
            // fail(t.toString());
        }
    }

    static void checkEqual(ZipEntry x, ZipEntry y) {
        if (x.getName().equals(y.getName()) &&
            x.isDirectory() == y.isDirectory() &&
            x.getMethod() == y.getMethod() &&
            (x.getTime() / 2000) == y.getTime() / 2000 &&
            x.getSize() == y.getSize() &&
            x.getCompressedSize() == y.getCompressedSize() &&
            x.getCrc() == y.getCrc() &&
            x.getComment().equals(y.getComment())
        ) {
            pass();
        } else {
            fail(x + " not equal to " + y);
            System.out.printf(" %s %s%n", x.getName(), y.getName());
            System.out.printf(" %d %d%n", x.getMethod(), y.getMethod());
            System.out.printf(" %d %d%n", x.getTime(), y.getTime());
            System.out.printf(" %d %d%n", x.getSize(), y.getSize());
            System.out.printf(" %d %d%n", x.getCompressedSize(), y.getCompressedSize());
            System.out.printf(" %d %d%n", x.getCrc(), y.getCrc());
            System.out.println("-----------------");
        }
    }

    static void doTest(Zip zip) throws RuntimeException {
        //Thread me = Thread.currentThread();
        try (ZipFile zf = new ZipFile(zip.name)) {
            doTest0(zip, zf);
        } catch (Throwable t) {
            throw new RuntimeException(t);
        }
    }

    static void doTest0(Zip zip, ZipFile zf) throws Throwable {
        // (0) check zero-length entry name, no AIOOBE
        try {
            check(zf.getEntry("") == null);
        } catch (Throwable t) {
            unexpected(t);
        }

        List<ZipEntry> list = new ArrayList<>(zip.entries.keySet());
        // (1) check entry list, in expected order
        if (!check(Arrays.equals(
                list.stream().map( e -> e.getName()).toArray(String[]::new),
                zf.stream().map( e -> e.getName()).toArray(String[]::new)))) {
            return;
        }
        // (2) shuffle, and check each entry and its bytes
        Collections.shuffle(list);
        for (ZipEntry ze : list) {
            byte[] data = zip.entries.get(ze);
            ZipEntry e = zf.getEntry(ze.getName());
            checkEqual(e, ze);
            if (!e.isDirectory()) {
                // check with readAllBytes
                try (InputStream is = zf.getInputStream(e)) {
                    check(Arrays.equals(data, is.readAllBytes()));
                }
                // check with smaller sized buf
                try (InputStream is = zf.getInputStream(e)) {
                    byte[] buf = new byte[(int)e.getSize()];
                    int sz = r.nextInt((int)e.getSize()/4 + 1) + 1;
                    int off = 0;
                    int n;
                    while ((n = is.read(buf, off, buf.length - off)) > 0) {
                        off += n;
                    }
                    check(is.read() == -1);
                    check(Arrays.equals(data, buf));
                }
            }
        }
    }

    private static class Zip {
        final String name;
        final Map<ZipEntry, byte[]> entries;
        BasicFileAttributes attrs;
        long lastModified;

        Zip(String name, int num, int szMax, boolean prefix, boolean clean) {
            this.name = name;
            entries = new LinkedHashMap<>(num);
            try {
                Path p = Paths.get(name);
                if (clean) {
                    Files.deleteIfExists(p);
                }
                paths.add(p);
            } catch (Exception x) {
                throw new RuntimeException(x);
            }

            try (FileOutputStream fos = new FileOutputStream(name);
                 BufferedOutputStream bos = new BufferedOutputStream(fos);
                 ZipOutputStream zos = new ZipOutputStream(bos))
            {
                if (prefix) {
                    byte[] bytes = new byte[r.nextInt(1000)];
                    r.nextBytes(bytes);
                    bos.write(bytes);
                }
                CRC32 crc = new CRC32();
                for (int i = 0; i < num; i++) {
                    String ename = "entry-" + i + "-name-" + r.nextLong();
                    ZipEntry ze = new ZipEntry(ename);
                    int method = r.nextBoolean() ? ZipEntry.STORED : ZipEntry.DEFLATED;
                    writeEntry(zos, crc, ze, method, szMax);
                }
                // add some manifest entries
                for (int i = 0; i < r.nextInt(20); i++) {
                    String meta = "META-INF/" + "entry-" + i + "-metainf-" + r.nextLong();
                    ZipEntry ze = new ZipEntry(meta);
                    writeEntry(zos, crc, ze, ZipEntry.STORED, szMax);
                }
            } catch (Exception x) {
                throw new RuntimeException(x);
            }
            try {
                this.attrs = Files.readAttributes(Paths.get(name), BasicFileAttributes.class);
                this.lastModified = new File(name).lastModified();
            } catch (Exception x) {
                throw new RuntimeException(x);
            }
        }

        private void writeEntry(ZipOutputStream zos, CRC32 crc,
                                ZipEntry ze, int method, int szMax)
            throws IOException
        {
            ze.setMethod(method);
            byte[] data = new byte[r.nextInt(szMax + 1)];
            r.nextBytes(data);
            if (method == ZipEntry.STORED) {  // must set size/csize/crc
                ze.setSize(data.length);
                ze.setCompressedSize(data.length);
                crc.reset();
                crc.update(data);
                ze.setCrc(crc.getValue());
            }
            ze.setTime(System.currentTimeMillis());
            ze.setComment(ze.getName());
            zos.putNextEntry(ze);
            zos.write(data);
            zos.closeEntry();
            entries.put(ze, data);
        }
    }

    //--------------------- Infrastructure ---------------------------
    static volatile int passed = 0, failed = 0;
    static void pass() {passed++;}
    static void pass(String msg) {System.out.println(msg); passed++;}
    static void fail() {failed++; Thread.dumpStack();}
    static void fail(String msg) {System.out.println(msg); fail();}
    static void unexpected(Throwable t) {failed++; t.printStackTrace();}

    static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}

    public static void main(String[] args) {
        try {realMain(args);} catch (Throwable t) {unexpected(t);}
        System.out.println("\nPassed = " + passed + " failed = " + failed);
        if (failed > 0) throw new AssertionError("Some tests failed");}
}

Messung V0.5
C=89 H=88 G=88

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.