ReleasableInputStream extends InputStream { @Override public int read() throws IOException { try { int read = delegate.read(); if (read < 0) { safeClose(); } return read; } catch (IOException e) { safeClose(); throw e; } } ReleasableInputStream(InputStream delegate, Runnable onClose); @Override int read(); @Override int read(byte[] bytes); @Override int read(byte[] bytes, int i, int i1); @Override long skip(long l); @Override int available(); @Override void close(); @Override void mark(int i); @Override void reset(); @Override boolean markSupported();  }
@Test public void read() throws Exception { releasableInputStream.read(); assertFalse(wasCalled.get()); }
@Test(expected = IOException.class) public void failedRead() throws Exception { failedReleasableInputStream.read(); assertTrue(wasCalled.get()); }
@Test public void read1() throws Exception { releasableInputStream.read(new byte[1024]); assertFalse(wasCalled.get()); }
@Test(expected = IOException.class) public void failedRead1() throws Exception { failedReleasableInputStream.read(new byte[1024]); assertTrue(wasCalled.get()); }
@Test public void read2() throws Exception { releasableInputStream.read(new byte[1024], 0, 1024); assertFalse(wasCalled.get()); }
@Test(expected = IOException.class) public void failedRead2() throws Exception { failedReleasableInputStream.read(new byte[1024], 0, 1024); assertTrue(wasCalled.get()); }