• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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