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 17 package android.core; 18 19 import junit.framework.TestCase; 20 21 import java.io.File; 22 import java.io.FileOutputStream; 23 import java.io.IOException; 24 import java.io.InputStream; 25 import java.io.OutputStream; 26 import java.util.Enumeration; 27 import java.util.zip.ZipEntry; 28 import java.util.zip.ZipFile; 29 import java.util.zip.ZipOutputStream; 30 import android.test.suitebuilder.annotation.MediumTest; 31 32 33 /** 34 * Basic tests for ZipFile. 35 */ 36 public class ZipFileTest extends TestCase { 37 private static final int SAMPLE_SIZE = 128 * 1024; 38 39 @MediumTest 40 public void testZipFile() throws Exception { 41 42 File file = File.createTempFile("ZipFileTest", ".zip"); 43 try { 44 // create a test file; assume it's not going to collide w/anything 45 FileOutputStream outStream = new FileOutputStream(file); 46 createCompressedZip(outStream); 47 // System.out.println("CREATED " + file); 48 49 scanZip(file.getPath()); 50 read2(file.getPath()); 51 } finally { 52 file.delete(); 53 } 54 } 55 56 /* 57 * stepStep == 0 --> >99% compression 58 * stepStep == 1 --> ~30% compression 59 * stepStep == 2 --> no compression 60 */ 61 static byte[] makeSampleFile(int stepStep) throws IOException { 62 byte[] sample = new byte[SAMPLE_SIZE]; 63 byte val, step; 64 int i, j, offset; 65 66 val = 0; 67 step = 1; 68 offset = 0; 69 for (i = 0; i < SAMPLE_SIZE / 256; i++) { 70 for (j = 0; j < 256; j++) { 71 sample[offset++] = val; 72 val += step; 73 } 74 75 step += stepStep; 76 } 77 78 return sample; 79 } 80 81 static void createCompressedZip(OutputStream bytesOut) throws IOException { 82 ZipOutputStream out = new ZipOutputStream(bytesOut); 83 try { 84 int i; 85 86 for (i = 0; i < 3; i++) { 87 byte[] input = makeSampleFile(i); 88 ZipEntry newEntry = new ZipEntry("file-" + i); 89 90 if (i != 1) { 91 newEntry.setComment("this is file " + i); 92 } 93 out.putNextEntry(newEntry); 94 out.write(input, 0, input.length); 95 out.closeEntry(); 96 } 97 98 out.setComment("This is a lovely compressed archive!"); 99 } finally { 100 out.close(); 101 } 102 } 103 104 static void scanZip(String fileName) throws IOException { 105 ZipFile zipFile = new ZipFile(fileName); 106 Enumeration fileList; 107 int idx = 0; 108 109 // System.out.println("Contents of " + zipFile + ":"); 110 for (fileList = zipFile.entries(); fileList.hasMoreElements();) { 111 ZipEntry entry = (ZipEntry) fileList.nextElement(); 112 // System.out.println(" " + entry.getName()); 113 assertEquals(entry.getName(), "file-" + idx); 114 idx++; 115 } 116 117 zipFile.close(); 118 } 119 120 /* 121 * Read compressed data from two different entries at the same time, 122 * to verify that the streams aren't getting confused. If we do 123 * something wrong, the inflater will choke and throw a ZipException. 124 * 125 * This doesn't test synchronization in multi-threaded use. 126 */ 127 static void read2(String fileName) throws IOException { 128 ZipFile zipFile; 129 ZipEntry entry1, entry2; 130 byte buf[] = new byte[16384]; 131 InputStream stream1, stream2; 132 int len, totalLen1, totalLen2; 133 134 /* use file-1 and file-2 because the compressed data is large */ 135 zipFile = new ZipFile(fileName); 136 entry1 = zipFile.getEntry("file-1"); 137 entry2 = zipFile.getEntry("file-2"); 138 139 /* make sure we got the right thing */ 140 assertEquals("file-1", entry1.getName()); 141 assertEquals("file-2", entry2.getName()); 142 143 /* create streams */ 144 stream1 = zipFile.getInputStream(entry1); 145 stream2 = zipFile.getInputStream(entry2); 146 147 /* 148 * Read a piece of file #1. 149 */ 150 totalLen1 = stream1.read(buf); 151 assertTrue("initial read failed on #1", totalLen1 >= 0); 152 153 /* 154 * Read a piece of file #2. 155 */ 156 totalLen2 = stream2.read(buf); 157 assertTrue("initial read failed on #2", totalLen2 >= 0); 158 159 /* 160 * Read the rest of file #1, and close the stream. 161 * 162 * If our streams are crossed up, we'll fail here. 163 */ 164 while ((len = stream1.read(buf)) > 0) { 165 totalLen1 += len; 166 } 167 assertEquals(SAMPLE_SIZE, totalLen1); 168 stream1.close(); 169 170 /* 171 * Read the rest of file #2, and close the stream. 172 */ 173 while ((len = stream2.read(buf)) > 0) { 174 totalLen2 += len; 175 } 176 assertEquals(SAMPLE_SIZE, totalLen2); 177 stream2.close(); 178 179 /* 180 * Open a new one. 181 */ 182 stream1 = zipFile.getInputStream(zipFile.getEntry("file-0")); 183 184 /* 185 * Close the ZipFile. According to the RI, none if its InputStreams can 186 * be read after this point. 187 */ 188 zipFile.close(); 189 190 Exception error = null; 191 try { 192 stream1.read(buf); 193 } catch (Exception ex) { 194 error = ex; 195 } 196 197 assertNotNull("ZipFile shouldn't allow reading of closed files.", error); 198 } 199 } 200 201