View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io.input;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertNotNull;
21  import static org.junit.jupiter.api.Assertions.assertThrows;
22  
23  import java.io.IOException;
24  import java.io.InputStream;
25  
26  import org.junit.jupiter.api.Test;
27  import org.junit.jupiter.params.ParameterizedTest;
28  import org.junit.jupiter.params.provider.MethodSource;
29  
30  /**
31   * Tests {@link BrokenInputStream}.
32   */
33  public class BrokenInputStreamTest {
34  
35      private static BrokenInputStream createBrokenInputStream(final Throwable exception) {
36          if (exception instanceof IOException) {
37              return new BrokenInputStream((IOException) exception);
38          }
39          return new BrokenInputStream(exception);
40      }
41  
42      @ParameterizedTest
43      @MethodSource("org.apache.commons.io.BrokenTestFactories#parameters")
44      public void testAvailable(final Class<Exception> clazz) throws Exception {
45          final Throwable exception = clazz.newInstance();
46          @SuppressWarnings("resource")
47          final BrokenInputStream stream = createBrokenInputStream(exception);
48          assertEquals(exception, assertThrows(clazz, () -> stream.available()));
49      }
50  
51      @ParameterizedTest
52      @MethodSource("org.apache.commons.io.BrokenTestFactories#parameters")
53      public void testClose(final Class<Exception> clazz) throws Exception {
54          final Throwable exception = clazz.newInstance();
55          @SuppressWarnings("resource")
56          final BrokenInputStream stream = createBrokenInputStream(exception);
57          assertEquals(exception, assertThrows(clazz, () -> stream.close()));
58      }
59  
60      @Test
61      public void testInstance() {
62          assertNotNull(BrokenInputStream.INSTANCE);
63      }
64  
65      @Test
66      public void testIO469() throws Throwable {
67          // The exception handling and nested blocks here look ugly.
68          // Do NOT try to rationalize them by combining them, using try-with-resources or assertThrows,
69          // or any similar improvements one would make in normal code. This tests
70          // a very specific bug that comes up in unusual exception structures like this.
71          // If this is improved, that bug will no longer be tested.
72          final InputStream in = new BrokenInputStream();
73          Throwable localThrowable2 = null;
74          try {
75              try {
76                  in.read();
77              } catch (Throwable localThrowable1) {
78                  localThrowable2 = localThrowable1;
79                  throw localThrowable1;
80              } finally {
81                  try {
82                      in.close();
83                  } catch (Throwable x2) {
84                      localThrowable2.addSuppressed(x2);
85                  }
86              }
87          } catch (IOException expected) {
88              final Throwable[] suppressed = expected.getSuppressed();
89              assertEquals(1, suppressed.length);
90          }
91      }
92  
93      @ParameterizedTest
94      @MethodSource("org.apache.commons.io.BrokenTestFactories#parameters")
95      public void testRead(final Class<Exception> clazz) throws Exception {
96          final Throwable exception = clazz.newInstance();
97          @SuppressWarnings("resource")
98          final BrokenInputStream stream = createBrokenInputStream(exception);
99          assertEquals(exception, assertThrows(clazz, () -> stream.read()));
100         assertEquals(exception, assertThrows(clazz, () -> stream.read(new byte[1])));
101         assertEquals(exception, assertThrows(clazz, () -> stream.read(new byte[1], 0, 1)));
102     }
103 
104     @ParameterizedTest
105     @MethodSource("org.apache.commons.io.BrokenTestFactories#parameters")
106     public void testReset(final Class<Exception> clazz) throws Exception {
107         final Throwable exception = clazz.newInstance();
108         @SuppressWarnings("resource")
109         final BrokenInputStream stream = createBrokenInputStream(exception);
110         assertEquals(exception, assertThrows(clazz, () -> stream.reset()));
111     }
112 
113     @ParameterizedTest
114     @MethodSource("org.apache.commons.io.BrokenTestFactories#parameters")
115     public void testSkip(final Class<Exception> clazz) throws Exception {
116         final Throwable exception = clazz.newInstance();
117         @SuppressWarnings("resource")
118         final BrokenInputStream stream = createBrokenInputStream(exception);
119         assertEquals(exception, assertThrows(clazz, () -> stream.skip(1)));
120     }
121 
122     @Test
123     public void testTryWithResources() {
124         final IOException thrown = assertThrows(IOException.class, () -> {
125             try (InputStream newStream = new BrokenInputStream()) {
126                 newStream.read();
127             }
128         });
129         assertEquals("Broken input stream", thrown.getMessage());
130 
131         final Throwable[] suppressed = thrown.getSuppressed();
132         assertEquals(1, suppressed.length);
133         assertEquals(IOException.class, suppressed[0].getClass());
134         assertEquals("Broken input stream", suppressed[0].getMessage());
135     }
136 
137 }