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 */ 17 18 package org.apache.harmony.tests.java.util.zip; 19 20 import java.io.ByteArrayInputStream; 21 import java.io.IOException; 22 import java.io.InputStream; 23 import java.util.Arrays; 24 import java.util.zip.DataFormatException; 25 import java.util.zip.Deflater; 26 import java.util.zip.DeflaterInputStream; 27 import libcore.io.Streams; 28 import libcore.junit.junit3.TestCaseWithRules; 29 import libcore.junit.util.ResourceLeakageDetector; 30 import libcore.junit.util.ResourceLeakageDetector.DisableResourceLeakageDetection; 31 import org.junit.Rule; 32 import org.junit.rules.TestRule; 33 34 public class DeflaterInputStreamTest extends TestCaseWithRules { 35 @Rule 36 public TestRule guardRule = ResourceLeakageDetector.getRule(); 37 38 private static final String TEST_STR = "Hi,this is a test"; 39 40 private static final byte[] TEST_STRING_DEFLATED_BYTES = { 41 120, -100, -13, -56, -44, 41, -55, -56, 44, 86, 42 0, -94, 68, -123, -110, -44, -30, 18, 0, 52, 43 34, 5, -13 }; 44 45 private InputStream is; 46 47 @Override setUp()48 protected void setUp() throws Exception { 49 super.setUp(); 50 is = new ByteArrayInputStream(TEST_STR.getBytes("UTF-8")); 51 } 52 53 @Override tearDown()54 protected void tearDown() throws Exception { 55 is.close(); 56 super.tearDown(); 57 } 58 59 /** 60 * DeflaterInputStream#available() 61 */ testAvailable()62 public void testAvailable() throws IOException { 63 byte[] buf = new byte[1024]; 64 DeflaterInputStream dis = new DeflaterInputStream(is); 65 assertEquals(1, dis.available()); 66 assertEquals(120, dis.read()); 67 assertEquals(1, dis.available()); 68 assertEquals(22, dis.read(buf, 0, 1024)); 69 assertEquals(0, dis.available()); 70 assertEquals(-1, dis.read()); 71 assertEquals(0, dis.available()); 72 dis.close(); 73 try { 74 dis.available(); 75 fail("should throw IOException"); 76 } catch (IOException e) { 77 // expected 78 } 79 } 80 81 /** 82 * DeflaterInputStream#close() 83 */ testClose()84 public void testClose() throws IOException { 85 byte[] buf = new byte[1024]; 86 DeflaterInputStream dis = new DeflaterInputStream(is); 87 assertEquals(1, dis.available()); 88 dis.close(); 89 try { 90 dis.available(); 91 fail("should throw IOException"); 92 } catch (IOException e) { 93 // expected 94 } 95 try { 96 dis.read(buf, 0, 1024); 97 fail("should throw IOException"); 98 } catch (IOException e) { 99 // expected 100 } 101 // can close after close 102 dis.close(); 103 } 104 105 /** 106 * DeflaterInputStream#mark() 107 */ testMark()108 public void testMark() throws IOException { 109 // mark do nothing 110 DeflaterInputStream dis = new DeflaterInputStream(is); 111 dis.mark(-1); 112 dis.mark(0); 113 dis.mark(1); 114 dis.close(); 115 dis.mark(1); 116 } 117 118 /** 119 * DeflaterInputStream#markSupported() 120 */ testMarkSupported()121 public void testMarkSupported() throws IOException { 122 DeflaterInputStream dis = new DeflaterInputStream(is); 123 assertFalse(dis.markSupported()); 124 dis.close(); 125 assertFalse(dis.markSupported()); 126 } 127 128 /** 129 * DeflaterInputStream#read() 130 */ testRead()131 public void testRead() throws IOException { 132 DeflaterInputStream dis = new DeflaterInputStream(is); 133 assertEquals(1, dis.available()); 134 assertEquals(120, dis.read()); 135 assertEquals(1, dis.available()); 136 assertEquals(156, dis.read()); 137 assertEquals(1, dis.available()); 138 assertEquals(243, dis.read()); 139 assertEquals(1, dis.available()); 140 dis.close(); 141 try { 142 dis.read(); 143 fail("should throw IOException"); 144 } catch (IOException e) { 145 // expected 146 } 147 } 148 testRead_golden()149 public void testRead_golden() throws Exception { 150 try (DeflaterInputStream dis = new DeflaterInputStream(is)) { 151 byte[] contents = Streams.readFully(dis); 152 assertTrue(Arrays.equals(TEST_STRING_DEFLATED_BYTES, contents)); 153 } 154 155 try (DeflaterInputStream dis = new DeflaterInputStream( 156 new ByteArrayInputStream(TEST_STR.getBytes("UTF-8")))) { 157 byte[] result = new byte[32]; 158 int count = 0; 159 int bytesRead; 160 while ((bytesRead = dis.read(result, count, 4)) != -1) { 161 count += bytesRead; 162 } 163 assertEquals(23, count); 164 byte[] splicedResult = new byte[23]; 165 System.arraycopy(result, 0, splicedResult, 0, 23); 166 assertTrue(Arrays.equals(TEST_STRING_DEFLATED_BYTES, splicedResult)); 167 } 168 } 169 testRead_leavesBufUnmodified()170 public void testRead_leavesBufUnmodified() throws Exception { 171 DeflaterInputStreamWithPublicBuffer dis = new DeflaterInputStreamWithPublicBuffer(is); 172 byte[] contents = Streams.readFully(dis); 173 assertTrue(Arrays.equals(TEST_STRING_DEFLATED_BYTES, contents)); 174 175 // protected field buf is a part of the public API of this class. 176 // we guarantee that it's only used as an input buffer, and not for 177 // anything else. 178 byte[] buf = dis.getBuffer(); 179 byte[] expected = TEST_STR.getBytes("UTF-8"); 180 181 byte[] splicedBuf = new byte[expected.length]; 182 System.arraycopy(buf, 0, splicedBuf, 0, splicedBuf.length); 183 assertTrue(Arrays.equals(expected, splicedBuf)); 184 } 185 186 /** 187 * DeflaterInputStream#read(byte[], int, int) 188 */ testReadByteArrayIntInt()189 public void testReadByteArrayIntInt() throws IOException { 190 byte[] buf1 = new byte[256]; 191 byte[] buf2 = new byte[256]; 192 try (DeflaterInputStream dis = new DeflaterInputStream(is)) { 193 assertEquals(23, dis.read(buf1, 0, 256)); 194 } 195 196 try (DeflaterInputStream dis = new DeflaterInputStream(is)) { 197 assertEquals(8, dis.read(buf2, 0, 256)); 198 } 199 200 is = new ByteArrayInputStream(TEST_STR.getBytes("UTF-8")); 201 DeflaterInputStream dis = new DeflaterInputStream(is); 202 assertEquals(1, dis.available()); 203 assertEquals(120, dis.read()); 204 assertEquals(1, dis.available()); 205 assertEquals(22, dis.read(buf2, 0, 256)); 206 assertEquals(0, dis.available()); 207 assertEquals(-1, dis.read()); 208 assertEquals(0, dis.available()); 209 try { 210 dis.read(buf1, 0, 512); 211 fail("should throw IndexOutOfBoundsException"); 212 } catch (IndexOutOfBoundsException e) { 213 // expected 214 } 215 try { 216 dis.read(null, 0, 0); 217 fail("should throw NullPointerException"); 218 } catch (NullPointerException e) { 219 // expected 220 } 221 try { 222 dis.read(null, -1, 0); 223 fail("should throw NullPointerException"); 224 } catch (NullPointerException e) { 225 // expected 226 } 227 try { 228 dis.read(null, -1, -1); 229 fail("should throw NullPointerException"); 230 } catch (NullPointerException e) { 231 // expected 232 } 233 try { 234 dis.read(buf1, -1, -1); 235 fail("should throw IndexOutOfBoundsException"); 236 } catch (IndexOutOfBoundsException e) { 237 // expected 238 } 239 try { 240 dis.read(buf1, 0, -1); 241 fail("should throw IndexOutOfBoundsException"); 242 } catch (IndexOutOfBoundsException e) { 243 // expected 244 } 245 dis.close(); 246 try { 247 dis.read(buf1, 0, 512); 248 fail("should throw IOException"); 249 } catch (IOException e) { 250 // expected 251 } 252 try { 253 dis.read(buf1, 0, 1); 254 fail("should throw IOException"); 255 } catch (IOException e) { 256 // expected 257 } 258 try { 259 dis.read(null, 0, 0); 260 fail("should throw IOException"); 261 } catch (IOException e) { 262 // expected 263 } 264 try { 265 dis.read(null, -1, 0); 266 fail("should throw IOException"); 267 } catch (IOException e) { 268 // expected 269 } 270 try { 271 dis.read(null, -1, -1); 272 fail("should throw IOException"); 273 } catch (IOException e) { 274 // expected 275 } 276 try { 277 dis.read(buf1, -1, -1); 278 fail("should throw IOException"); 279 } catch (IOException e) { 280 // expected 281 } 282 try { 283 dis.read(buf1, 0, -1); 284 fail("should throw IOException"); 285 } catch (IOException e) { 286 // expected 287 } 288 } 289 290 /** 291 * DeflaterInputStream#reset() 292 */ testReset()293 public void testReset() throws IOException { 294 DeflaterInputStream dis = new DeflaterInputStream(is); 295 try { 296 dis.reset(); 297 fail("should throw IOException"); 298 } catch (IOException e) { 299 // expected 300 } 301 dis.close(); 302 try { 303 dis.reset(); 304 fail("should throw IOException"); 305 } catch (IOException e) { 306 // expected 307 } 308 } 309 310 /** 311 * DeflaterInputStream#skip() 312 */ testSkip()313 public void testSkip() throws IOException { 314 byte[] buf = new byte[1024]; 315 try (DeflaterInputStream dis = new DeflaterInputStream(is)) { 316 assertEquals(1, dis.available()); 317 dis.skip(1); 318 assertEquals(1, dis.available()); 319 assertEquals(22, dis.read(buf, 0, 1024)); 320 assertEquals(0, dis.available()); 321 assertEquals(0, dis.available()); 322 is = new ByteArrayInputStream(TEST_STR.getBytes("UTF-8")); 323 } 324 325 is = new ByteArrayInputStream(TEST_STR.getBytes("UTF-8")); 326 try (DeflaterInputStream dis = new DeflaterInputStream(is)) { 327 assertEquals(23, dis.skip(Long.MAX_VALUE)); 328 assertEquals(0, dis.available()); 329 } 330 331 DeflaterInputStream dis = new DeflaterInputStream(is); 332 assertEquals(1, dis.available()); 333 dis.skip(56); 334 assertEquals(0, dis.available()); 335 assertEquals(-1, dis.read(buf, 0, 1024)); 336 337 assertEquals(0, dis.available()); 338 // can still skip 339 dis.skip(1); 340 dis.close(); 341 try { 342 dis.skip(1); 343 fail("should throw IOException"); 344 } catch (IOException e) { 345 // expected 346 } 347 } 348 349 /** 350 * DeflaterInputStream#DeflaterInputStream(InputStream) 351 */ 352 @DisableResourceLeakageDetection( 353 why = "DeflaterInputStream does not clean up the default Deflater created in the" 354 + " constructor if the constructor fails; i.e. constructor calls" 355 + " this(..., new Deflater(), ...) and that constructor fails but does not know" 356 + " that it needs to call Deflater.end() as the caller has no access to it", 357 bug = "31798154") testDeflaterInputStreamInputStream()358 public void testDeflaterInputStreamInputStream() throws IOException { 359 // ok 360 new DeflaterInputStream(is).close(); 361 // fail 362 try { 363 new DeflaterInputStream(null); 364 fail("should throw NullPointerException"); 365 } catch (NullPointerException e) { 366 // expected 367 } 368 } 369 370 /** 371 * DataFormatException#DataFormatException() 372 */ testDataFormatException()373 public void testDataFormatException() { 374 new DataFormatException(); 375 } 376 377 /** 378 * DeflaterInputStream#DeflaterInputStream(InputStream, Deflater) 379 */ testDeflaterInputStreamInputStreamDeflater()380 public void testDeflaterInputStreamInputStreamDeflater() throws IOException { 381 // ok 382 Deflater deflater = new Deflater(); 383 try { 384 new DeflaterInputStream(is, deflater).close(); 385 // fail 386 try { 387 new DeflaterInputStream(is, null); 388 fail("should throw NullPointerException"); 389 } catch (NullPointerException e) { 390 // expected 391 } 392 try { 393 new DeflaterInputStream(null, deflater); 394 fail("should throw NullPointerException"); 395 } catch (NullPointerException e) { 396 // expected 397 } 398 } finally { 399 deflater.end(); 400 } 401 } 402 403 /** 404 * DeflaterInputStream#DeflaterInputStream(InputStream, Deflater, int) 405 */ testDeflaterInputStreamInputStreamDeflaterInt()406 public void testDeflaterInputStreamInputStreamDeflaterInt() { 407 // ok 408 Deflater deflater = new Deflater(); 409 try { 410 new DeflaterInputStream(is, deflater, 1024); 411 // fail 412 try { 413 new DeflaterInputStream(is, null, 1024); 414 fail("should throw NullPointerException"); 415 } catch (NullPointerException e) { 416 // expected 417 } 418 try { 419 new DeflaterInputStream(null, deflater, 1024); 420 fail("should throw NullPointerException"); 421 } catch (NullPointerException e) { 422 // expected 423 } 424 try { 425 new DeflaterInputStream(is, deflater, -1); 426 fail("should throw IllegalArgumentException"); 427 } catch (IllegalArgumentException e) { 428 // expected 429 } 430 try { 431 new DeflaterInputStream(null, deflater, -1); 432 fail("should throw NullPointerException"); 433 } catch (NullPointerException e) { 434 // expected 435 } 436 try { 437 new DeflaterInputStream(is, null, -1); 438 fail("should throw NullPointerException"); 439 } catch (NullPointerException e) { 440 // expected 441 } 442 } finally { 443 deflater.end(); 444 } 445 } 446 447 public static final class DeflaterInputStreamWithPublicBuffer extends DeflaterInputStream { 448 DeflaterInputStreamWithPublicBuffer(InputStream in)449 public DeflaterInputStreamWithPublicBuffer(InputStream in) { 450 super(in); 451 } 452 getBuffer()453 public byte[] getBuffer() { 454 return buf; 455 } 456 } 457 } 458