11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2007 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License. 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.io; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static org.easymock.EasyMock.createStrictMock; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static org.easymock.EasyMock.expectLastCall; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static org.easymock.EasyMock.replay; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static org.easymock.EasyMock.reset; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static org.easymock.EasyMock.verify; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport junit.framework.TestCase; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Closeable; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Flushable; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.IOException; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unit tests for {@link Closeables} and {@link Flushables}. 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Checks proper closing and flushing behavior, and ensures that 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * IOExceptions on Closeable.close() or Flushable.flush() are not 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * propagated out from the {@link Closeables#close} method if {@code 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * swallowException} is true. 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Michael Lancaster 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class CloseablesTest extends TestCase { 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Closeable mockCloseable; 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Flushable mockFlushable; 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testClose_closeableClean() throws IOException { 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // make sure that no exception is thrown regardless of value of 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // 'swallowException' when the mock does not throw an exception. 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setupCloseable(false); 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doClose(mockCloseable, false, false); 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setupCloseable(false); 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doClose(mockCloseable, true, false); 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testClose_closeableWithEatenException() throws IOException { 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // make sure that no exception is thrown if 'swallowException' is true 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // when the mock does throw an exception. 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setupCloseable(true); 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doClose(mockCloseable, true); 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testClose_closeableWithThrownException() throws IOException { 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // make sure that the exception is thrown if 'swallowException' is false 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // when the mock does throw an exception. 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setupCloseable(true); 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doClose(mockCloseable, false); 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testCloseQuietly_closeableWithEatenException() 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws IOException { 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // make sure that no exception is thrown by CloseQuietly when the mock does 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // throw an exception, either on close, on flush, or both. 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setupCloseable(true); 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Closeables.closeQuietly(mockCloseable); 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testFlush_clean() throws IOException { 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // make sure that no exception is thrown regardless of value of 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // 'swallowException' when the mock does not throw an exception. 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setupFlushable(false); 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doFlush(mockFlushable, false, false); 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setupFlushable(false); 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doFlush(mockFlushable, true, false); 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testFlush_flushableWithEatenException() throws IOException { 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // make sure that no exception is thrown if 'swallowException' is true 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // when the mock does throw an exception on flush. 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setupFlushable(true); 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doFlush(mockFlushable, true, false); 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testFlush_flushableWithThrownException() throws IOException { 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // make sure that the exception is thrown if 'swallowException' is false 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // when the mock does throw an exception on flush. 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setupFlushable(true); 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doFlush(mockFlushable, false, true); 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testFlushQuietly_flushableWithEatenException() 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throws IOException { 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // make sure that no exception is thrown by CloseQuietly when the mock does 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // throw an exception on flush. 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert setupFlushable(true); 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Flushables.flushQuietly(mockFlushable); 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testCloseNull() throws IOException { 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Closeables.close(null, true); 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Closeables.close(null, false); 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Closeables.closeQuietly(null); 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected void setUp() throws Exception { 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert mockCloseable = createStrictMock(Closeable.class); 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert mockFlushable = createStrictMock(Flushable.class); 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void expectThrown() { 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert expectLastCall().andThrow(new IOException("This should only appear in the " 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert + "logs. It should not be rethrown.")); 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Set up a closeable to expect to be closed, and optionally to throw an 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // exception. 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void setupCloseable(boolean shouldThrow) throws IOException { 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert reset(mockCloseable); 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert mockCloseable.close(); 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (shouldThrow) { 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert expectThrown(); 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert replay(mockCloseable); 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Set up a flushable to expect to be flushed and closed, and optionally to 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // throw an exception. 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void setupFlushable(boolean shouldThrowOnFlush) throws IOException { 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert reset(mockFlushable); 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert mockFlushable.flush(); 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (shouldThrowOnFlush) { 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert expectThrown(); 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert replay(mockFlushable); 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void doClose(Closeable closeable, boolean swallowException) { 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doClose(closeable, swallowException, !swallowException); 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Close the closeable using the Closeables, passing in the swallowException 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // parameter. expectThrown determines whether we expect an exception to 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // be thrown by Closeables.close; 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void doClose(Closeable closeable, boolean swallowException, 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean expectThrown) { 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Closeables.close(closeable, swallowException); 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (expectThrown) { 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail("Didn't throw exception."); 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IOException e) { 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!expectThrown) { 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail("Threw exception"); 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert verify(closeable); 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Flush the flushable using the Flushables, passing in the swallowException 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // parameter. expectThrown determines whether we expect an exception to 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // be thrown by Flushables.flush; 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void doFlush(Flushable flushable, boolean swallowException, 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean expectThrown) { 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Flushables.flush(flushable, swallowException); 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (expectThrown) { 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail("Didn't throw exception."); 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (IOException e) { 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!expectThrown) { 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert fail("Threw exception"); 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert verify(flushable); 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 187