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.ByteArrayInputStream;
28 import java.io.Closeable;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.Reader;
32 
33 /**
34  * Unit tests for {@link Closeables}.
35  *
36  * <p>Checks proper closing behavior, and ensures that
37  * IOExceptions on Closeable.close() are not
38  * propagated out from the {@link Closeables#close} method if {@code
39  * swallowException} is true.
40  *
41  * @author Michael Lancaster
42  */
43 public class CloseablesTest extends TestCase {
44   private Closeable mockCloseable;
45 
testClose_closeableClean()46   public void testClose_closeableClean() throws IOException {
47     // make sure that no exception is thrown regardless of value of
48     // 'swallowException' when the mock does not throw an exception.
49     setupCloseable(false);
50     doClose(mockCloseable, false, false);
51 
52     setupCloseable(false);
53     doClose(mockCloseable, true, false);
54   }
55 
testClose_closeableWithEatenException()56   public void testClose_closeableWithEatenException() throws IOException {
57     // make sure that no exception is thrown if 'swallowException' is true
58     // when the mock does throw an exception.
59     setupCloseable(true);
60     doClose(mockCloseable, true);
61   }
62 
testClose_closeableWithThrownException()63   public void testClose_closeableWithThrownException() throws IOException {
64     // make sure that the exception is thrown if 'swallowException' is false
65     // when the mock does throw an exception.
66     setupCloseable(true);
67     doClose(mockCloseable, false);
68   }
69 
testCloseQuietly_inputStreamWithEatenException()70   public void testCloseQuietly_inputStreamWithEatenException() throws IOException {
71     TestInputStream in = new TestInputStream(
72         new ByteArrayInputStream(new byte[1]), TestOption.CLOSE_THROWS);
73     Closeables.closeQuietly(in);
74     assertTrue(in.closed());
75   }
76 
testCloseQuietly_readerWithEatenException()77   public void testCloseQuietly_readerWithEatenException() throws IOException {
78     TestReader in = new TestReader(TestOption.CLOSE_THROWS);
79     Closeables.closeQuietly(in);
80     assertTrue(in.closed());
81   }
82 
testCloseNull()83   public void testCloseNull() throws IOException {
84     Closeables.close(null, true);
85     Closeables.close(null, false);
86   }
87 
testCloseQuietlyNull_inputStream()88   public void testCloseQuietlyNull_inputStream() {
89     Closeables.closeQuietly((InputStream) null);
90   }
91 
testCloseQuietlyNull_reader()92   public void testCloseQuietlyNull_reader() {
93     Closeables.closeQuietly((Reader) null);
94   }
95 
setUp()96   @Override protected void setUp() throws Exception {
97     mockCloseable = createStrictMock(Closeable.class);
98   }
99 
expectThrown()100   private void expectThrown() {
101     expectLastCall().andThrow(new IOException("This should only appear in the "
102         + "logs. It should not be rethrown."));
103   }
104 
105   // Set up a closeable to expect to be closed, and optionally to throw an
106   // exception.
setupCloseable(boolean shouldThrow)107   private void setupCloseable(boolean shouldThrow) throws IOException {
108     reset(mockCloseable);
109     mockCloseable.close();
110     if (shouldThrow) {
111       expectThrown();
112     }
113     replay(mockCloseable);
114   }
115 
doClose(Closeable closeable, boolean swallowException)116   private void doClose(Closeable closeable, boolean swallowException) {
117     doClose(closeable, swallowException, !swallowException);
118   }
119 
120   // Close the closeable using the Closeables, passing in the swallowException
121   // parameter. expectThrown determines whether we expect an exception to
122   // be thrown by Closeables.close;
doClose(Closeable closeable, boolean swallowException, boolean expectThrown)123   private void doClose(Closeable closeable, boolean swallowException,
124       boolean expectThrown) {
125     try {
126       Closeables.close(closeable, swallowException);
127       if (expectThrown) {
128         fail("Didn't throw exception.");
129       }
130     } catch (IOException e) {
131       if (!expectThrown) {
132         fail("Threw exception");
133       }
134     }
135     verify(closeable);
136   }
137 }
138