/* * sulky-modules - several general-purpose modules. * Copyright (C) 2007-2015 Joern Huxhorn * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* * Copyright 2007-2015 Joern Huxhorn * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.huxhorn.sulky.io; import java.io.IOException; import java.io.OutputStream; import org.easymock.IAnswer; import org.junit.Test; import static org.easymock.EasyMock.createStrictMock; import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.makeThreadSafe; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; public class TimeoutOutputStreamTest { @Test public void normalUse() throws IOException { byte[] bytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; OutputStream mockStream = createStrictMock(OutputStream.class); mockStream.write(eq(bytes)); mockStream.flush(); mockStream.write(eq(17)); mockStream.write(eq(bytes), eq(0), eq(5)); mockStream.close(); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 1000); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); instance.write(bytes); instance.flush(); instance.write(17); instance.write(bytes, 0, 5); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); instance.close(); waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void exceptionInWriteByte() throws IOException { OutputStream mockStream = createStrictMock(OutputStream.class); mockStream.write(17); //noinspection ThrowableInstanceNeverThrown expectLastCall().andThrow(new IOException("Some exception")); mockStream.close(); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 1000); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); try { instance.write(17); fail("Exception should have been thrown!"); } catch(IOException ex) { // expected } waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void exceptionInWriteByteArray() throws IOException { byte[] bytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; OutputStream mockStream = createStrictMock(OutputStream.class); mockStream.write(eq(bytes)); //noinspection ThrowableInstanceNeverThrown expectLastCall().andThrow(new IOException("Some exception")); mockStream.close(); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 1000); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); try { instance.write(bytes); fail("Exception should have been thrown!"); } catch(IOException ex) { // expected } waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void exceptionInWriteByteArrayOffset() throws IOException { byte[] bytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; OutputStream mockStream = createStrictMock(OutputStream.class); mockStream.write(eq(bytes), eq(0), eq(5)); //noinspection ThrowableInstanceNeverThrown expectLastCall().andThrow(new IOException("Some exception")); mockStream.close(); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 1000); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); try { instance.write(bytes, 0, 5); fail("Exception should have been thrown!"); } catch(IOException ex) { // expected } waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void exceptionInFlush() throws IOException { OutputStream mockStream = createStrictMock(OutputStream.class); mockStream.flush(); //noinspection ThrowableInstanceNeverThrown expectLastCall().andThrow(new IOException("Some exception")); mockStream.close(); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 1000); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); try { instance.flush(); fail("Exception should have been thrown!"); } catch(IOException ex) { // expected } waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void exceptionInClose() throws IOException { OutputStream mockStream = createStrictMock(OutputStream.class); mockStream.close(); //noinspection ThrowableInstanceNeverThrown expectLastCall().andThrow(new IOException("Some exception")); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 1000); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); try { instance.close(); fail("Exception should have been thrown!"); } catch(IOException ex) { // expected } waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void runtimeExceptionInWriteByte() throws IOException { OutputStream mockStream = createStrictMock(OutputStream.class); mockStream.write(17); //noinspection ThrowableInstanceNeverThrown expectLastCall().andThrow(new RuntimeException("Some exception")); mockStream.close(); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 1000); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); try { instance.write(17); fail("Exception should have been thrown!"); } catch(RuntimeException ex) { // expected } waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void runtimeExceptionInWriteByteArray() throws IOException { byte[] bytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; OutputStream mockStream = createStrictMock(OutputStream.class); mockStream.write(eq(bytes)); //noinspection ThrowableInstanceNeverThrown expectLastCall().andThrow(new RuntimeException("Some exception")); mockStream.close(); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 1000); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); try { instance.write(bytes); fail("Exception should have been thrown!"); } catch(RuntimeException ex) { // expected } waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void runtimeExceptionInWriteByteArrayOffset() throws IOException { byte[] bytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; OutputStream mockStream = createStrictMock(OutputStream.class); mockStream.write(eq(bytes), eq(0), eq(5)); //noinspection ThrowableInstanceNeverThrown expectLastCall().andThrow(new RuntimeException("Some exception")); mockStream.close(); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 1000); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); try { instance.write(bytes, 0, 5); fail("Exception should have been thrown!"); } catch(RuntimeException ex) { // expected } waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void runtimeExceptionInFlush() throws IOException { OutputStream mockStream = createStrictMock(OutputStream.class); mockStream.flush(); //noinspection ThrowableInstanceNeverThrown expectLastCall().andThrow(new RuntimeException("Some exception")); mockStream.close(); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 1000); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); try { instance.flush(); fail("Exception should have been thrown!"); } catch(RuntimeException ex) { // expected } waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void runtimeExceptionInClose() throws IOException { OutputStream mockStream = createStrictMock(OutputStream.class); mockStream.close(); //noinspection ThrowableInstanceNeverThrown expectLastCall().andThrow(new RuntimeException("Some exception")); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 1000); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); try { instance.close(); fail("Exception should have been thrown!"); } catch(RuntimeException ex) { // expected } waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void timeoutInWriteByte() throws IOException { OutputStream mockStream = createStrictMock(OutputStream.class); makeThreadSafe(mockStream, true); mockStream.write(eq(17)); expectLastCall().andAnswer(new IAnswer<Object>() { public Object answer() throws Throwable { Thread.sleep(300); return null; } }); mockStream.close(); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 100); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); instance.write(17); // would throw exception in case of a real output stream. waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void timeoutInWriteByteArray() throws IOException { byte[] bytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; OutputStream mockStream = createStrictMock(OutputStream.class); makeThreadSafe(mockStream, true); mockStream.write(eq(bytes)); expectLastCall().andAnswer(new IAnswer<Object>() { public Object answer() throws Throwable { Thread.sleep(300); return null; } }); mockStream.close(); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 100); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); instance.write(bytes); // would throw exception in case of a real output stream. waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void timeoutInWriteByteArrayOffset() throws IOException { byte[] bytes = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; OutputStream mockStream = createStrictMock(OutputStream.class); makeThreadSafe(mockStream, true); mockStream.write(eq(bytes), eq(0), eq(5)); expectLastCall().andAnswer(new IAnswer<Object>() { public Object answer() throws Throwable { Thread.sleep(300); return null; } }); mockStream.close(); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 100); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); instance.write(bytes, 0, 5); // would throw exception in case of a real output stream. waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void timeoutInFlush() throws IOException { OutputStream mockStream = createStrictMock(OutputStream.class); makeThreadSafe(mockStream, true); mockStream.flush(); expectLastCall().andAnswer(new IAnswer<Object>() { public Object answer() throws Throwable { Thread.sleep(300); return null; } }); mockStream.close(); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 100); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); instance.flush(); // would throw exception in case of a real output stream. waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } @Test public void timeoutInClose() throws IOException { OutputStream mockStream = createStrictMock(OutputStream.class); makeThreadSafe(mockStream, true); mockStream.close(); expectLastCall().andAnswer(new IAnswer<Object>() { public Object answer() throws Throwable { Thread.sleep(300); return null; } }); replay(mockStream); TimeoutOutputStream instance = new TimeoutOutputStream(mockStream, 100); assertTrue("Stream is already closed!", !instance.isClosed()); assertTrue("Watchdog Thread is not running!", instance.isWatchdogThreadRunning()); instance.close(); // would throw exception in case of a real output stream. waitForSomeTime(); verify(mockStream); assertTrue("Stream is not closed!", instance.isClosed()); assertTrue("Watchdog Thread is still running!", !instance.isWatchdogThreadRunning()); } private void waitForSomeTime() { try { Thread.sleep(100); } catch(InterruptedException e) { IOUtilities.interruptIfNecessary(e); } } }