1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.java.util.zip;
18
19import java.io.File;
20import java.io.FilenameFilter;
21import java.io.InputStream;
22import java.security.cert.Certificate;
23import java.util.Arrays;
24import java.util.Enumeration;
25import java.util.Random;
26import java.util.jar.JarEntry;
27import java.util.jar.JarFile;
28import java.util.zip.Deflater;
29import java.util.zip.Inflater;
30import java.util.zip.ZipEntry;
31import java.util.zip.ZipFile;
32import junit.framework.TestCase;
33
34public final class OldAndroidZipStressTest extends TestCase {
35    /**
36     * JarEntry.getCertificates() is really slow. http://b/1046174
37     */
38    public void checkJarCertificates(File file) throws Exception {
39        JarFile jarFile = new JarFile(file);
40        JarEntry je = jarFile.getJarEntry("AndroidManifest.xml");
41        byte[] readBuffer = new byte[1024];
42
43        long t0 = System.currentTimeMillis();
44
45        // We must read the stream for the JarEntry to retrieve its certificates.
46        InputStream is = jarFile.getInputStream(je);
47        while (is.read(readBuffer, 0, readBuffer.length) != -1) {
48        }
49        is.close();
50        Certificate[] certs = je != null ? je.getCertificates() : null;
51
52        long t1 = System.currentTimeMillis();
53        System.out.println("loadCertificates() took " + (t1 - t0) + " ms");
54        if (certs == null) {
55            System.out.println("We have no certificates");
56        } else {
57            System.out.println("We have " + certs.length + " certificates");
58        }
59    }
60
61    private File[] getFiles() {
62        File[] result = new File("/system/app").listFiles(new FilenameFilter() {
63            public boolean accept(File dir, String name) {
64                return name.endsWith(".apk");
65            }
66        });
67        return result != null ? result : new File[0];
68    }
69
70    public void testJarCertificates() throws Exception {
71        for (File file : getFiles()) {
72            checkJarCertificates(file);
73        }
74    }
75
76    // Boot-time package scan is slow. Not expected to fail. Please see log if
77    // you are interested in the results. http://b/1212257
78    public void testZipStressManifest() throws Exception {
79        long time0 = System.currentTimeMillis();
80        byte[] buffer = new byte[512];
81        for (File file : getFiles()) {
82            System.out.println("ZIP stress test processing " + file + "...");
83
84            ZipFile zip = new ZipFile(file);
85            ZipEntry entry = zip.getEntry("AndroidManifest.xml");
86            InputStream stream = zip.getInputStream(entry);
87            int j = stream.read(buffer);
88            while (j != -1) {
89                j = stream.read(buffer);
90            }
91            stream.close();
92        }
93        long time1 = System.currentTimeMillis();
94        System.out.println("ZIP stress test finished, time was " + (time1- time0) + "ms");
95    }
96
97    public void testZipStressAllFiles() throws Exception {
98        long time0 = System.currentTimeMillis();
99        byte[] buffer = new byte[512];
100        for (File file : getFiles()) {
101            System.out.println("ZIP stress test processing " + file + "...");
102            ZipFile zip = new ZipFile(file);
103            Enumeration<? extends ZipEntry> entries = zip.entries();
104            while (entries.hasMoreElements()) {
105                InputStream stream = zip.getInputStream(entries.nextElement());
106                int j = stream.read(buffer);
107                while (j != -1) {
108                    j = stream.read(buffer);
109                }
110                stream.close();
111            }
112        }
113        long time1 = System.currentTimeMillis();
114        System.out.println("ZIP stress test finished, time was " + (time1- time0) + "ms");
115    }
116
117    private void assertEquals(byte[] a, byte[] b) {
118        assertTrue(Arrays.equals(a, b));
119    }
120
121    /**
122     * Native memory allocated by Deflater in system_server. The fix reduced
123     * some internal ZLIB buffers in size, so this test is trying to execute a
124     * lot of deflating to ensure that things are still working properly.
125     * http://b/1185084
126     */
127    public void testZipDeflateInflateStress() throws Exception {
128        final int DATA_SIZE = 16384;
129        Random random = new Random(42); // Seed makes test reproducible
130        // Outer loop selects "mode" of test.
131        for (int j = 1; j <= 2; j++) {
132            byte[] input = new byte[DATA_SIZE];
133
134            if (j == 1) {
135                // Totally random content
136                random.nextBytes(input);
137            } else {
138                // Random contents with longer repetitions
139                int pos = 0;
140                while (pos < input.length) {
141                    byte what = (byte)random.nextInt(256);
142                    int howMany = random.nextInt(32);
143                    if (pos + howMany >= input.length) {
144                        howMany = input.length - pos;
145                    }
146                    Arrays.fill(input, pos, pos + howMany, what);
147                    pos += howMany;
148                }
149            }
150
151            // Inner loop tries all 9 compression levels.
152            for (int i = 1; i <= 9; i++) {
153                System.out.println("ZipDeflateInflateStress test (" + j + "," + i + ")...");
154                byte[] zipped = new byte[2 * DATA_SIZE]; // Just to make sure...
155
156                Deflater deflater = new Deflater(i);
157                deflater.setInput(input);
158                deflater.finish();
159                deflater.deflate(zipped);
160                deflater.end();
161
162                byte[] output = new byte[DATA_SIZE];
163
164                Inflater inflater = new Inflater();
165                inflater.setInput(zipped);
166                inflater.finished();
167                inflater.inflate(output);
168                inflater.end();
169                assertEquals(input, output);
170            }
171        }
172    }
173}
174