1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17package org.apache.harmony.archive.tests.java.util.zip;
18
19import java.io.ByteArrayInputStream;
20import java.io.ByteArrayOutputStream;
21import java.io.File;
22import java.io.FileOutputStream;
23import java.io.IOException;
24import java.util.zip.CRC32;
25import java.util.zip.ZipEntry;
26import java.util.zip.ZipException;
27import java.util.zip.ZipInputStream;
28import java.util.zip.ZipOutputStream;
29
30public class ZipOutputStreamTest extends junit.framework.TestCase {
31
32	ZipOutputStream zos;
33
34	ByteArrayOutputStream bos;
35
36	ZipInputStream zis;
37
38	static final String data = "HelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorldHelloWorld";
39
40	/**
41     * @tests java.util.zip.ZipOutputStream#close()
42     */
43	public void test_close() throws Exception {
44        try {
45            zos.close();
46            fail("Close on empty stream failed to throw exception");
47        } catch (ZipException e) {
48            // expected
49        }
50
51        zos = new ZipOutputStream(bos);
52        zos.putNextEntry(new ZipEntry("XX"));
53        zos.closeEntry();
54        zos.close();
55
56        // Regression for HARMONY-97
57        ZipOutputStream zos = new ZipOutputStream(new ByteArrayOutputStream());
58        zos.putNextEntry(new ZipEntry("myFile"));
59        zos.close();
60        zos.close(); // Should be a no-op
61    }
62
63    /**
64     * @tests java.util.zip.ZipOutputStream#closeEntry()
65     */
66    public void test_closeEntry() throws IOException {
67        ZipEntry ze = new ZipEntry("testEntry");
68        ze.setTime(System.currentTimeMillis());
69        zos.putNextEntry(ze);
70        zos.write("Hello World".getBytes("UTF-8"));
71        zos.closeEntry();
72        assertTrue("closeEntry failed to update required fields",
73                ze.getSize() == 11 && ze.getCompressedSize() == 13);
74
75    }
76
77    /**
78     * @tests java.util.zip.ZipOutputStream#finish()
79     */
80    public void test_finish() throws Exception {
81        ZipEntry ze = new ZipEntry("test");
82        zos.putNextEntry(ze);
83        zos.write("Hello World".getBytes());
84        zos.finish();
85        assertEquals("Finish failed to closeCurrentEntry", 11, ze.getSize());
86
87        ZipOutputStream zos = new ZipOutputStream(new ByteArrayOutputStream());
88        zos.putNextEntry(new ZipEntry("myFile"));
89        zos.finish();
90        zos.close();
91        try {
92            zos.finish();
93            fail("Assert 0: Expected IOException");
94        } catch (IOException e) {
95            // Expected
96        }
97    }
98
99    /**
100     * @tests java.util.zip.ZipOutputStream#putNextEntry(java.util.zip.ZipEntry)
101     */
102    public void test_putNextEntryLjava_util_zip_ZipEntry() throws IOException {
103        ZipEntry ze = new ZipEntry("testEntry");
104        ze.setTime(System.currentTimeMillis());
105        zos.putNextEntry(ze);
106        zos.write("Hello World".getBytes());
107        zos.closeEntry();
108        zos.close();
109        zis = new ZipInputStream(new ByteArrayInputStream(bos.toByteArray()));
110        ZipEntry ze2 = zis.getNextEntry();
111        zis.closeEntry();
112        assertEquals("Failed to write correct entry", ze.getName(), ze2.getName());
113        assertEquals("Failed to write correct entry", ze.getCrc(), ze2.getCrc());
114        try {
115            zos.putNextEntry(ze);
116            fail("Entry with incorrect setting failed to throw exception");
117        } catch (IOException e) {
118            // expected
119        }
120    }
121
122    /**
123     * @tests java.util.zip.ZipOutputStream#setComment(java.lang.String)
124     */
125    public void test_setCommentLjava_lang_String() {
126        // There is no way to get the comment back, so no way to determine if
127        // the comment is set correct
128        zos.setComment("test setComment");
129
130        try {
131            zos.setComment(new String(new byte[0xFFFF + 1]));
132            fail("Comment over 0xFFFF in length should throw exception");
133        } catch (IllegalArgumentException e) {
134            // Passed
135        }
136    }
137
138    /**
139     * @tests java.util.zip.ZipOutputStream#setLevel(int)
140     */
141    public void test_setLevelI() throws IOException {
142        ZipEntry ze = new ZipEntry("test");
143        zos.putNextEntry(ze);
144        zos.write(data.getBytes());
145        zos.closeEntry();
146        long csize = ze.getCompressedSize();
147        zos.setLevel(9); // Max Compression
148        zos.putNextEntry(ze = new ZipEntry("test2"));
149        zos.write(data.getBytes());
150        zos.closeEntry();
151        assertTrue("setLevel failed", csize <= ze.getCompressedSize());
152    }
153
154    /**
155     * @tests java.util.zip.ZipOutputStream#setMethod(int)
156     */
157    public void test_setMethodI() throws IOException {
158        ZipEntry ze = new ZipEntry("test");
159        zos.setMethod(ZipOutputStream.STORED);
160        CRC32 tempCrc = new CRC32();
161        tempCrc.update(data.getBytes());
162        ze.setCrc(tempCrc.getValue());
163        ze.setSize(new String(data).length());
164        zos.putNextEntry(ze);
165        zos.write(data.getBytes());
166        zos.closeEntry();
167        long csize = ze.getCompressedSize();
168        zos.setMethod(ZipOutputStream.DEFLATED);
169        zos.putNextEntry(ze = new ZipEntry("test2"));
170        zos.write(data.getBytes());
171        zos.closeEntry();
172        assertTrue("setLevel failed", csize >= ze.getCompressedSize());
173    }
174
175    /**
176     * @tests java.util.zip.ZipOutputStream#write(byte[], int, int)
177     */
178    public void test_write$BII() throws IOException {
179        ZipEntry ze = new ZipEntry("test");
180        zos.putNextEntry(ze);
181        zos.write(data.getBytes());
182        zos.closeEntry();
183        zos.close();
184        zos = null;
185        zis = new ZipInputStream(new ByteArrayInputStream(bos.toByteArray()));
186        zis.getNextEntry();
187        byte[] b = new byte[data.length()];
188        int r = 0;
189        int count = 0;
190        while (count != b.length && (r = zis.read(b, count, b.length)) != -1) {
191            count += r;
192        }
193        zis.closeEntry();
194        assertEquals("Write failed to write correct bytes", new String(b), data);
195
196        File f = File.createTempFile("testZip", "tst");
197        f.deleteOnExit();
198        FileOutputStream stream = new FileOutputStream(f);
199        ZipOutputStream zip = new ZipOutputStream(stream);
200        zip.setMethod(ZipEntry.STORED);
201
202        try {
203            zip.putNextEntry(new ZipEntry("Second"));
204            fail("Not set an entry. Should have thrown ZipException.");
205        } catch (ZipException e) {
206            // expected -- We have not set an entry
207        }
208
209        try {
210            // We try to write data without entry
211            zip.write(new byte[2]);
212            fail("Writing data without an entry. Should have thrown IOException");
213        } catch (IOException e) {
214            // expected
215        }
216
217        try {
218            // Try to write without an entry and with nonsense offset and
219            // length
220            zip.write(new byte[2], 0, 12);
221            fail("Writing data without an entry. Should have thrown IndexOutOfBoundsException");
222        } catch (IndexOutOfBoundsException e) {
223            // expected
224        }
225
226        // Regression for HARMONY-4405
227        try {
228            zip.write(null, 0, -2);
229            fail();
230        } catch (NullPointerException expected) {
231        } catch (IndexOutOfBoundsException expected) {
232        }
233        try {
234            zip.write(null, 0, 2);
235            fail();
236        } catch (NullPointerException expected) {
237        }
238        try {
239            zip.write(new byte[2], 0, -2);
240            fail();
241        } catch (IndexOutOfBoundsException expected) {
242        }
243
244        // Close stream because ZIP is invalid
245        stream.close();
246    }
247
248    /**
249     * @tests java.util.zip.ZipOutputStream#write(byte[], int, int)
250     */
251    public void test_write$BII_2() throws IOException {
252        // Regression for HARMONY-577
253        File f1 = File.createTempFile("testZip1", "tst");
254        f1.deleteOnExit();
255        FileOutputStream stream1 = new FileOutputStream(f1);
256        ZipOutputStream zip1 = new ZipOutputStream(stream1);
257        zip1.putNextEntry(new ZipEntry("one"));
258        zip1.setMethod(ZipOutputStream.STORED);
259        zip1.setMethod(ZipEntry.STORED);
260
261        zip1.write(new byte[2]);
262
263        try {
264            zip1.putNextEntry(new ZipEntry("Second"));
265            fail("ZipException expected");
266        } catch (ZipException e) {
267            // expected - We have not set an entry
268        }
269
270        try {
271            zip1.write(new byte[2]); // try to write data without entry
272            fail("expected IOE there");
273        } catch (IOException e2) {
274            // expected
275        }
276
277        zip1.close();
278    }
279
280    @Override
281    protected void setUp() throws Exception {
282        super.setUp();
283        zos = new ZipOutputStream(bos = new ByteArrayOutputStream());
284    }
285
286    @Override
287    protected void tearDown() throws Exception {
288        try {
289            if (zos != null) {
290                zos.close();
291            }
292            if (zis != null) {
293                zis.close();
294            }
295        } catch (Exception e) {}
296        super.tearDown();
297    }
298}
299