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.tests.java.util.zip;
18
19import java.io.ByteArrayInputStream;
20import java.io.ByteArrayOutputStream;
21import java.io.File;
22import java.io.FileInputStream;
23import java.io.FileOutputStream;
24import java.io.IOException;
25import java.io.InputStream;
26import java.net.URL;
27import java.util.zip.Checksum;
28import java.util.zip.GZIPInputStream;
29import java.util.zip.GZIPOutputStream;
30import libcore.junit.junit3.TestCaseWithRules;
31import libcore.junit.util.ResourceLeakageDetector;
32import libcore.junit.util.ResourceLeakageDetector.DisableResourceLeakageDetection;
33import org.junit.Rule;
34import org.junit.rules.TestRule;
35import tests.support.resource.Support_Resources;
36
37public class GZIPInputStreamTest extends TestCaseWithRules {
38    @Rule
39    public TestRule guardRule = ResourceLeakageDetector.getRule();
40
41    File resources;
42
43    class TestGZIPInputStream extends GZIPInputStream {
44        TestGZIPInputStream(InputStream in) throws IOException {
45            super(in);
46        }
47
48        TestGZIPInputStream(InputStream in, int size) throws IOException {
49            super(in, size);
50        }
51
52        Checksum getChecksum() {
53            return crc;
54        }
55
56        boolean endofInput() {
57            return eos;
58        }
59    }
60
61    /**
62     * @tests java.util.zip.GZIPInputStream#GZIPInputStream(java.io.InputStream)
63     */
64    public void test_ConstructorLjava_io_InputStream() {
65        // test method java.util.zip.GZIPInputStream.constructor
66        try {
67            Support_Resources.copyFile(resources, null, "hyts_gInput.txt.gz");
68            final URL gInput = new File(resources.toString() + "/hyts_gInput.txt.gz").toURL();
69            TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
70                    .openConnection().getInputStream());
71            assertNotNull("the constructor for GZIPInputStream is null",
72                    inGZIP);
73            assertEquals("the CRC value of the inputStream is not zero", 0, inGZIP
74                    .getChecksum().getValue());
75            inGZIP.close();
76        } catch (IOException e) {
77            fail(
78                    "an IO error occured while trying to open the input file");
79        }
80    }
81
82    /**
83     * @tests java.util.zip.GZIPInputStream#GZIPInputStream(java.io.InputStream,
84     *int)
85     */
86    @DisableResourceLeakageDetection(
87            why = "InflaterInputStream does not clean up the default Inflater created in the"
88                    + " constructor if the constructor fails; i.e. constructor calls"
89                    + " this(..., new Inflater(), ...) and that constructor fails but does not know"
90                    + " that it needs to call Inflater.end() as the caller has no access to it",
91            bug = "31798154")
92    public void test_ConstructorLjava_io_InputStreamI() {
93        // test method java.util.zip.GZIPInputStream.constructorI
94        try {
95            Support_Resources.copyFile(resources, null, "hyts_gInput.txt.gz");
96            final URL gInput = new File(resources.toString() + "/hyts_gInput.txt.gz").toURL();
97            TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
98                    .openConnection().getInputStream(), 200);
99            assertNotNull("the constructor for GZIPInputStream is null",
100                    inGZIP);
101            assertEquals("the CRC value of the inputStream is not zero", 0, inGZIP
102                    .getChecksum().getValue());
103            inGZIP.close();
104
105            try {
106                TestGZIPInputStream inGZIP1 = new TestGZIPInputStream(gInput
107                        .openConnection().getInputStream(), 0);
108                fail("IllegalArgumentException expected");
109            } catch (IllegalArgumentException ioe) {
110                //expected
111            }
112
113            Support_Resources.copyFile(resources, null, "hyts_checkInput.txt");
114            final URL jarInput = new File(resources.toString() + "/hyts_checkInput.txt").toURL();
115            try {
116                TestGZIPInputStream inGZIP1 = new TestGZIPInputStream(jarInput
117                        .openConnection().getInputStream(), 200);
118                fail("IOException expected");
119            } catch (IOException ex) {
120                //expected
121            }
122
123        } catch (IOException e) {
124            fail(
125                    "an IO error occured while trying to open the input file");
126        }
127    }
128
129    /**
130     * @tests java.util.zip.GZIPInputStream#read(byte[], int, int)
131     */
132    public void test_read$BII() throws IOException {
133        // test method java.util.zip.GZIPInputStream.readBII
134        byte orgBuf[] = { '3', '5', '2', 'r', 'g', 'e', 'f', 'd', 'e', 'w' };
135        byte outBuf[] = new byte[100];
136        int result = 0;
137        Support_Resources.copyFile(resources, null, "hyts_gInput.txt.gz");
138        final URL gInput = new File(resources.toString() + "/hyts_gInput.txt.gz").toURL();
139        TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
140                .openConnection().getInputStream());
141        while (!(inGZIP.endofInput())) {
142            result += inGZIP.read(outBuf, result, outBuf.length - result);
143        }
144        assertEquals(
145                "the checkSum value of the compressed and decompressed data does not equal",
146                2074883667L, inGZIP.getChecksum().getValue());
147        for (int i = 0; i < orgBuf.length; i++) {
148            assertEquals(
149                    "the decompressed data does not equal the original data decompressed",
150                    orgBuf[i], outBuf[i]);
151            // System.out.println(orgBuf[i] + " " + outBuf[i]);
152        }
153        int r = 0;
154        try {
155            inGZIP.read(outBuf, 100, 1);
156        } catch (IndexOutOfBoundsException e) {
157            r = 1;
158        }
159        inGZIP.close();
160        // line below fails on RI also, comment out.
161        // assertEquals("Boundary Check was not present", 1, r);
162
163        // Create compressed data which is exactly 512 bytes (after the
164        // header),
165        // the size of the InflaterStream internal buffer
166        byte[] test = new byte[507];
167        for (int i = 0; i < 256; i++) {
168            test[i] = (byte) i;
169        }
170        for (int i = 256; i < test.length; i++) {
171            test[i] = (byte) (256 - i);
172        }
173        ByteArrayOutputStream bout = new ByteArrayOutputStream();
174        GZIPOutputStream out = new GZIPOutputStream(bout);
175        out.write(test);
176        out.close();
177        byte[] comp = bout.toByteArray();
178        int total;
179        try (GZIPInputStream gin2 = new GZIPInputStream(new ByteArrayInputStream(comp), 512)) {
180            total = 0;
181            while ((result = gin2.read(test)) != -1) {
182                total += result;
183            }
184            assertEquals("Should return -1", -1, gin2.read());
185        }
186        assertEquals("Incorrectly decompressed", test.length, total);
187
188        try (GZIPInputStream gin2 = new GZIPInputStream(new ByteArrayInputStream(comp), 512)) {
189            total = 0;
190            while ((result = gin2.read(new byte[200])) != -1) {
191                total += result;
192            }
193            assertEquals("Should return -1", -1, gin2.read());
194        }
195        assertEquals("Incorrectly decompressed", test.length, total);
196
197        try (GZIPInputStream gin2 = new GZIPInputStream(new ByteArrayInputStream(comp), 516)) {
198            total = 0;
199            while ((result = gin2.read(new byte[200])) != -1) {
200                total += result;
201            }
202            assertEquals("Should return -1", -1, gin2.read());
203        }
204        assertEquals("Incorrectly decompressed", test.length, total);
205
206        comp[40] = 0;
207        try (GZIPInputStream gin2 = new GZIPInputStream(new ByteArrayInputStream(comp), 512)) {
208            boolean exception = false;
209            try {
210                while (gin2.read(test) != -1) {
211                    ;
212                }
213            } catch (IOException e) {
214                exception = true;
215            }
216            assertTrue("Exception expected", exception);
217        }
218
219        ByteArrayOutputStream baos = new ByteArrayOutputStream();
220        try (GZIPOutputStream zipout = new GZIPOutputStream(baos)) {
221            zipout.write(test);
222        }
223        outBuf = new byte[530];
224        try (GZIPInputStream in = new GZIPInputStream(
225                new ByteArrayInputStream(baos.toByteArray()))) {
226            try {
227                in.read(outBuf, 530, 1);
228                fail("Test failed IOOBE was not thrown");
229            } catch (IndexOutOfBoundsException e) {
230            }
231            while (true) {
232                result = in.read(outBuf, 0, 5);
233                if (result == -1) {
234                    //"EOF was reached";
235                    break;
236                }
237            }
238            result = -10;
239            result = in.read(null, 100, 1);
240            result = in.read(outBuf, -100, 1);
241            result = in.read(outBuf, -1, 1);// 100, 1);
242        }
243    }
244
245    /**
246     * @tests java.util.zip.GZIPInputStream#close()
247     */
248    public void test_close() {
249        // test method java.util.zip.GZIPInputStream.close
250        byte outBuf[] = new byte[100];
251        try {
252            int result = 0;
253            Support_Resources.copyFile(resources, null, "hyts_gInput.txt.gz");
254            final URL gInput = new File(resources.toString() + "/hyts_gInput.txt.gz").toURL();
255            TestGZIPInputStream inGZIP = new TestGZIPInputStream(gInput
256                    .openConnection().getInputStream());
257            while (!(inGZIP.endofInput())) {
258                result += inGZIP.read(outBuf, result, outBuf.length - result);
259            }
260            assertEquals("the checkSum value of the compressed and decompressed data does not equal",
261                    2074883667L, inGZIP.getChecksum().getValue());
262            inGZIP.close();
263            int r = 0;
264            try {
265                inGZIP.read(outBuf, 0, 1);
266            } catch (IOException e) {
267                r = 1;
268            }
269            assertEquals("GZIPInputStream can still be used after close is called",
270                    1, r);
271        } catch (IOException e) {
272            e.printStackTrace();
273            fail("unexpected: " + e);
274        }
275    }
276
277    /**
278     * Regression test for HARMONY-3703.
279     *
280     * @tests java.util.zip.GZIPInputStream#read()
281     */
282    public void test_read() throws IOException {
283        int result = 0;
284        byte[] buffer = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
285        File f = new File(resources.getAbsolutePath() + "test.gz");
286        FileOutputStream out = new FileOutputStream(f);
287        GZIPOutputStream gout = new GZIPOutputStream(out);
288
289        // write 100 bytes to the stream
290        for (int i = 0; i < 10; i++) {
291            gout.write(buffer);
292        }
293        gout.finish();
294        out.write(1);
295        out.close();
296        gout.close();
297
298        GZIPInputStream gis = new GZIPInputStream(new FileInputStream(f));
299        buffer = new byte[100];
300        gis.read(buffer);
301        result = gis.read();
302        gis.close();
303        f.delete();
304
305        assertEquals("Incorrect value returned at the end of the file", -1, result);
306    }
307
308    @Override
309    protected void setUp() {
310        resources = Support_Resources.createTempFolder();
311    }
312
313    @Override
314    protected void tearDown() {
315    }
316
317}
318