1 /* 2 * Copyright (C) 2007 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.io; 18 19 import static org.easymock.EasyMock.createStrictMock; 20 import static org.easymock.EasyMock.expectLastCall; 21 import static org.easymock.EasyMock.replay; 22 import static org.easymock.EasyMock.reset; 23 import static org.easymock.EasyMock.verify; 24 25 import junit.framework.TestCase; 26 27 import java.io.Closeable; 28 import java.io.Flushable; 29 import java.io.IOException; 30 31 /** 32 * Unit tests for {@link Closeables} and {@link Flushables}. 33 * 34 * <p>Checks proper closing and flushing behavior, and ensures that 35 * IOExceptions on Closeable.close() or Flushable.flush() are not 36 * propagated out from the {@link Closeables#close} method if {@code 37 * swallowException} is true. 38 * 39 * @author Michael Lancaster 40 */ 41 public class CloseablesTest extends TestCase { 42 private Closeable mockCloseable; 43 private Flushable mockFlushable; 44 testClose_closeableClean()45 public void testClose_closeableClean() throws IOException { 46 // make sure that no exception is thrown regardless of value of 47 // 'swallowException' when the mock does not throw an exception. 48 setupCloseable(false); 49 doClose(mockCloseable, false, false); 50 51 setupCloseable(false); 52 doClose(mockCloseable, true, false); 53 } 54 testClose_closeableWithEatenException()55 public void testClose_closeableWithEatenException() throws IOException { 56 // make sure that no exception is thrown if 'swallowException' is true 57 // when the mock does throw an exception. 58 setupCloseable(true); 59 doClose(mockCloseable, true); 60 } 61 testClose_closeableWithThrownException()62 public void testClose_closeableWithThrownException() throws IOException { 63 // make sure that the exception is thrown if 'swallowException' is false 64 // when the mock does throw an exception. 65 setupCloseable(true); 66 doClose(mockCloseable, false); 67 } 68 testCloseQuietly_closeableWithEatenException()69 public void testCloseQuietly_closeableWithEatenException() 70 throws IOException { 71 // make sure that no exception is thrown by CloseQuietly when the mock does 72 // throw an exception, either on close, on flush, or both. 73 setupCloseable(true); 74 Closeables.closeQuietly(mockCloseable); 75 } 76 testFlush_clean()77 public void testFlush_clean() throws IOException { 78 // make sure that no exception is thrown regardless of value of 79 // 'swallowException' when the mock does not throw an exception. 80 setupFlushable(false); 81 doFlush(mockFlushable, false, false); 82 83 setupFlushable(false); 84 doFlush(mockFlushable, true, false); 85 } 86 testFlush_flushableWithEatenException()87 public void testFlush_flushableWithEatenException() throws IOException { 88 // make sure that no exception is thrown if 'swallowException' is true 89 // when the mock does throw an exception on flush. 90 setupFlushable(true); 91 doFlush(mockFlushable, true, false); 92 } 93 testFlush_flushableWithThrownException()94 public void testFlush_flushableWithThrownException() throws IOException { 95 // make sure that the exception is thrown if 'swallowException' is false 96 // when the mock does throw an exception on flush. 97 setupFlushable(true); 98 doFlush(mockFlushable, false, true); 99 } 100 testFlushQuietly_flushableWithEatenException()101 public void testFlushQuietly_flushableWithEatenException() 102 throws IOException { 103 // make sure that no exception is thrown by CloseQuietly when the mock does 104 // throw an exception on flush. 105 setupFlushable(true); 106 Flushables.flushQuietly(mockFlushable); 107 } 108 testCloseNull()109 public void testCloseNull() throws IOException { 110 Closeables.close(null, true); 111 Closeables.close(null, false); 112 Closeables.closeQuietly(null); 113 } 114 setUp()115 @Override protected void setUp() throws Exception { 116 mockCloseable = createStrictMock(Closeable.class); 117 mockFlushable = createStrictMock(Flushable.class); 118 } 119 expectThrown()120 private void expectThrown() { 121 expectLastCall().andThrow(new IOException("This should only appear in the " 122 + "logs. It should not be rethrown.")); 123 } 124 125 // Set up a closeable to expect to be closed, and optionally to throw an 126 // exception. setupCloseable(boolean shouldThrow)127 private void setupCloseable(boolean shouldThrow) throws IOException { 128 reset(mockCloseable); 129 mockCloseable.close(); 130 if (shouldThrow) { 131 expectThrown(); 132 } 133 replay(mockCloseable); 134 } 135 136 // Set up a flushable to expect to be flushed and closed, and optionally to 137 // throw an exception. setupFlushable(boolean shouldThrowOnFlush)138 private void setupFlushable(boolean shouldThrowOnFlush) throws IOException { 139 reset(mockFlushable); 140 mockFlushable.flush(); 141 if (shouldThrowOnFlush) { 142 expectThrown(); 143 } 144 replay(mockFlushable); 145 } 146 doClose(Closeable closeable, boolean swallowException)147 private void doClose(Closeable closeable, boolean swallowException) { 148 doClose(closeable, swallowException, !swallowException); 149 } 150 151 // Close the closeable using the Closeables, passing in the swallowException 152 // parameter. expectThrown determines whether we expect an exception to 153 // be thrown by Closeables.close; doClose(Closeable closeable, boolean swallowException, boolean expectThrown)154 private void doClose(Closeable closeable, boolean swallowException, 155 boolean expectThrown) { 156 try { 157 Closeables.close(closeable, swallowException); 158 if (expectThrown) { 159 fail("Didn't throw exception."); 160 } 161 } catch (IOException e) { 162 if (!expectThrown) { 163 fail("Threw exception"); 164 } 165 } 166 verify(closeable); 167 } 168 169 // Flush the flushable using the Flushables, passing in the swallowException 170 // parameter. expectThrown determines whether we expect an exception to 171 // be thrown by Flushables.flush; doFlush(Flushable flushable, boolean swallowException, boolean expectThrown)172 private void doFlush(Flushable flushable, boolean swallowException, 173 boolean expectThrown) { 174 try { 175 Flushables.flush(flushable, swallowException); 176 if (expectThrown) { 177 fail("Didn't throw exception."); 178 } 179 } catch (IOException e) { 180 if (!expectThrown) { 181 fail("Threw exception"); 182 } 183 } 184 verify(flushable); 185 } 186 } 187