1/*
2 * Copyright (C) 2014 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 android.support.multidex;
18
19import android.support.multidex.ZipUtil.CentralDirectory;
20
21import org.junit.Assert;
22import org.junit.BeforeClass;
23import org.junit.Test;
24
25import java.io.EOFException;
26import java.io.File;
27import java.io.FileOutputStream;
28import java.io.IOException;
29import java.io.InputStream;
30import java.io.OutputStream;
31import java.io.RandomAccessFile;
32import java.nio.ByteBuffer;
33import java.nio.ByteOrder;
34import java.util.Enumeration;
35import java.util.HashMap;
36import java.util.Map;
37import java.util.zip.ZipEntry;
38import java.util.zip.ZipException;
39import java.util.zip.ZipFile;
40
41/**
42 * Tests of ZipUtil class.
43 *
44 * The test assumes that ANDROID_BUILD_TOP environment variable is defined and point to the top of a
45 * built android tree. This is the case when the console used for running the tests is setup for
46 * android tree compilation.
47 */
48public class ZipUtilTest {
49    private static final File zipFile = new File(System.getenv("ANDROID_BUILD_TOP"),
50        "out/target/common/obj/JAVA_LIBRARIES/android-support-multidex_intermediates/javalib.jar");
51    @BeforeClass
52    public static void setupClass() throws ZipException, IOException {
53        // just verify the zip is valid
54        new ZipFile(zipFile).close();
55    }
56
57    @Test
58    public void testCrcDoNotCrash() throws IOException {
59
60        long crc =
61                ZipUtil.getZipCrc(zipFile);
62        System.out.println("crc is " + crc);
63
64    }
65
66    @Test
67    public void testCrcRange() throws IOException {
68        RandomAccessFile raf = new RandomAccessFile(zipFile, "r");
69        CentralDirectory dir = ZipUtil.findCentralDirectory(raf);
70        byte[] dirData = new byte[(int) dir.size];
71        int length = dirData.length;
72        int off = 0;
73        raf.seek(dir.offset);
74        while (length > 0) {
75            int read = raf.read(dirData, off, length);
76            if (length == -1) {
77                throw new EOFException();
78            }
79            length -= read;
80            off += read;
81        }
82        raf.close();
83        ByteBuffer buffer = ByteBuffer.wrap(dirData);
84        Map<String, ZipEntry> toCheck = new HashMap<String, ZipEntry>();
85        while (buffer.hasRemaining()) {
86            buffer = buffer.slice();
87            buffer.order(ByteOrder.LITTLE_ENDIAN);
88            ZipEntry entry = ZipEntryReader.readEntry(buffer);
89            toCheck.put(entry.getName(), entry);
90        }
91
92        ZipFile zip = new ZipFile(zipFile);
93        Assert.assertEquals(zip.size(), toCheck.size());
94        Enumeration<? extends ZipEntry> ref = zip.entries();
95        while (ref.hasMoreElements()) {
96            ZipEntry refEntry = ref.nextElement();
97            ZipEntry checkEntry = toCheck.get(refEntry.getName());
98            Assert.assertNotNull(checkEntry);
99            Assert.assertEquals(refEntry.getName(), checkEntry.getName());
100            Assert.assertEquals(refEntry.getComment(), checkEntry.getComment());
101            Assert.assertEquals(refEntry.getTime(), checkEntry.getTime());
102            Assert.assertEquals(refEntry.getCrc(), checkEntry.getCrc());
103            Assert.assertEquals(refEntry.getCompressedSize(), checkEntry.getCompressedSize());
104            Assert.assertEquals(refEntry.getSize(), checkEntry.getSize());
105            Assert.assertEquals(refEntry.getMethod(), checkEntry.getMethod());
106            Assert.assertArrayEquals(refEntry.getExtra(), checkEntry.getExtra());
107        }
108        zip.close();
109    }
110
111    @Test
112    public void testCrcValue() throws IOException {
113        ZipFile zip = new ZipFile(zipFile);
114        Enumeration<? extends ZipEntry> ref = zip.entries();
115        byte[] buffer = new byte[0x2000];
116        while (ref.hasMoreElements()) {
117            ZipEntry refEntry = ref.nextElement();
118            if (refEntry.getSize() > 0) {
119                File tmp = File.createTempFile("ZipUtilTest", ".fakezip");
120                InputStream in = zip.getInputStream(refEntry);
121                OutputStream out = new FileOutputStream(tmp);
122                int read = in.read(buffer);
123                while (read != -1) {
124                    out.write(buffer, 0, read);
125                    read = in.read(buffer);
126                }
127                in.close();
128                out.close();
129                RandomAccessFile raf = new RandomAccessFile(tmp, "r");
130                CentralDirectory dir = new CentralDirectory();
131                dir.offset = 0;
132                dir.size = raf.length();
133                long crc = ZipUtil.computeCrcOfCentralDir(raf, dir);
134                Assert.assertEquals(refEntry.getCrc(), crc);
135                raf.close();
136                tmp.delete();
137            }
138        }
139        zip.close();
140    }
141    @Test
142    public void testInvalidCrcValue() throws IOException {
143        ZipFile zip = new ZipFile(zipFile);
144        Enumeration<? extends ZipEntry> ref = zip.entries();
145        byte[] buffer = new byte[0x2000];
146        while (ref.hasMoreElements()) {
147            ZipEntry refEntry = ref.nextElement();
148            if (refEntry.getSize() > 0) {
149                File tmp = File.createTempFile("ZipUtilTest", ".fakezip");
150                InputStream in = zip.getInputStream(refEntry);
151                OutputStream out = new FileOutputStream(tmp);
152                int read = in.read(buffer);
153                while (read != -1) {
154                    out.write(buffer, 0, read);
155                    read = in.read(buffer);
156                }
157                in.close();
158                out.close();
159                RandomAccessFile raf = new RandomAccessFile(tmp, "r");
160                CentralDirectory dir = new CentralDirectory();
161                dir.offset = 0;
162                dir.size = raf.length() - 1;
163                long crc = ZipUtil.computeCrcOfCentralDir(raf, dir);
164                Assert.assertNotEquals(refEntry.getCrc(), crc);
165                raf.close();
166                tmp.delete();
167            }
168        }
169        zip.close();
170    }
171
172}
173