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    *      https://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  
18  package org.apache.commons.io.build;
19  
20  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
21  import static org.junit.jupiter.api.Assertions.assertEquals;
22  import static org.junit.jupiter.api.Assertions.assertFalse;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertTrue;
25  
26  import java.io.File;
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.io.OutputStream;
30  import java.io.RandomAccessFile;
31  import java.io.Reader;
32  import java.io.Writer;
33  import java.nio.charset.Charset;
34  import java.nio.file.Files;
35  import java.nio.file.OpenOption;
36  import java.nio.file.Path;
37  import java.nio.file.Paths;
38  import java.nio.file.StandardOpenOption;
39  import java.util.Objects;
40  
41  import org.apache.commons.io.FileUtils;
42  import org.apache.commons.io.build.AbstractOrigin.RandomAccessFileOrigin;
43  import org.junit.jupiter.api.BeforeEach;
44  import org.junit.jupiter.api.Test;
45  import org.junit.jupiter.params.ParameterizedTest;
46  import org.junit.jupiter.params.provider.EnumSource;
47  
48  /**
49   * Tests {@link AbstractOrigin} and subclasses.
50   *
51   * @param <T> the type of instances to build.
52   * @param <B> the type of builder subclass.
53   */
54  public abstract class AbstractOriginTest<T, B extends AbstractOrigin<T, B>> {
55  
56      protected static final String FILE_RES_RO = "/org/apache/commons/io/test-file-20byteslength.bin";
57      protected static final String FILE_NAME_RO = "src/test/resources" + FILE_RES_RO;
58      protected static final String FILE_NAME_RW = "target/" + AbstractOriginTest.class.getSimpleName() + ".txt";
59      private static final int RO_LENGTH = 20;
60  
61      protected AbstractOrigin<T, B> originRo;
62      protected AbstractOrigin<T, B> originRw;
63  
64      @BeforeEach
65      public void beforeEach() throws IOException {
66          setOriginRo(newOriginRo());
67          setOriginRw(newOriginRw());
68      }
69  
70      protected AbstractOrigin<T, B> getOriginRo() {
71          return Objects.requireNonNull(originRo, "originRo");
72      }
73  
74      protected AbstractOrigin<T, B> getOriginRw() {
75          return Objects.requireNonNull(originRw, "originRw");
76      }
77  
78      @SuppressWarnings("resource")
79      private boolean isValid(final RandomAccessFile raf) throws IOException {
80          return Objects.requireNonNull(raf).getFD().valid();
81      }
82  
83      protected abstract B newOriginRo() throws IOException;
84  
85      protected abstract B newOriginRw() throws IOException;
86  
87      protected void setOriginRo(final AbstractOrigin<T, B> origin) {
88          this.originRo = origin;
89      }
90  
91      protected void setOriginRw(final AbstractOrigin<T, B> origin) {
92          this.originRw = origin;
93      }
94  
95      @Test
96      void testGetByteArray() throws IOException {
97          assertArrayEquals(Files.readAllBytes(Paths.get(FILE_NAME_RO)), getOriginRo().getByteArray());
98      }
99  
100     @Test
101     void testGetByteArrayAt_0_0() throws IOException {
102         assertArrayEquals(new byte[] {}, getOriginRo().getByteArray(0, 0));
103     }
104 
105     @Test
106     void testGetByteArrayAt_0_1() throws IOException {
107         assertArrayEquals(new byte[] { '1' }, getOriginRo().getByteArray(0, 1));
108     }
109 
110     @Test
111     void testGetByteArrayAt_1_1() throws IOException {
112         assertArrayEquals(new byte[] { '2' }, getOriginRo().getByteArray(1, 1));
113     }
114 
115     @Test
116     void testGetCharSequence() throws IOException {
117         assertNotNull(getOriginRo().getCharSequence(Charset.defaultCharset()));
118     }
119 
120     @Test
121     void testGetFile() throws IOException {
122         testGetFile(getOriginRo().getFile(), RO_LENGTH);
123         FileUtils.touch(getOriginRw().getFile());
124         testGetFile(getOriginRw().getFile(), 0);
125     }
126 
127     private void testGetFile(final File file, final long expectedLen) throws IOException {
128         assertNotNull(file);
129         assertTrue(file.exists(), () -> "File does not exist: " + file);
130         final int length = FileUtils.readFileToByteArray(file).length;
131         assertEquals(length, expectedLen, () -> String.format("File %s, actual length=%,d", file, length));
132     }
133 
134     @Test
135     void testGetInputStream() throws IOException {
136         try (InputStream inputStream = getOriginRo().getInputStream()) {
137             assertNotNull(inputStream);
138         }
139     }
140 
141     @Test
142     void testGetOutputStream() throws IOException {
143         try (OutputStream output = getOriginRw().getOutputStream()) {
144             assertNotNull(output);
145         }
146     }
147 
148     @Test
149     void testGetPath() throws IOException {
150         testGetPath(getOriginRo().getPath(), RO_LENGTH);
151         FileUtils.touch(getOriginRw().getPath().toFile());
152         testGetPath(getOriginRw().getPath(), 0);
153     }
154 
155     private void testGetPath(final Path path, final long expectedLen) throws IOException {
156         assertNotNull(path);
157         assertTrue(Files.exists(path));
158         final int length = Files.readAllBytes(path).length;
159         assertEquals(length, expectedLen, () -> String.format("Path %s, actual length=%,d", path, length));
160     }
161 
162     @Test
163     void testGetRandomAccessFile() throws IOException {
164         // Default
165         try (RandomAccessFile raf = getOriginRo().getRandomAccessFile()) {
166             assertNotNull(raf);
167             assertTrue(isValid(raf));
168         }
169         final boolean isRafOriginRo = getOriginRo() instanceof RandomAccessFileOrigin;
170         final boolean isRafOriginRw = getOriginRw() instanceof RandomAccessFileOrigin;
171         // Same as above, but underlying resource is now closed.
172         try (RandomAccessFile raf = getOriginRo().getRandomAccessFile()) {
173             assertNotNull(raf);
174             assertFalse(isRafOriginRo && isValid(raf));
175         }
176         // Read
177         try (RandomAccessFile raf = getOriginRo().getRandomAccessFile(StandardOpenOption.READ)) {
178             assertNotNull(raf);
179             assertFalse(isRafOriginRo && isValid(raf));
180         }
181         // Write, first access
182         try (RandomAccessFile raf = getOriginRw().getRandomAccessFile(StandardOpenOption.WRITE)) {
183             assertNotNull(raf);
184             if (isRafOriginRw || getOriginRw().getFile() != null) {
185                 assertTrue(isValid(raf), () -> getOriginRw().toString());
186             } else {
187                 // Can't get there from here.
188                 assertFalse(isValid(raf), () -> getOriginRw().toString());
189             }
190         }
191         // Read, Write, underlying resource is now closed.
192         try (RandomAccessFile raf = getOriginRw().getRandomAccessFile(StandardOpenOption.READ, StandardOpenOption.WRITE)) {
193             assertNotNull(raf);
194             assertFalse(isRafOriginRw && isValid(raf));
195         }
196     }
197 
198     @ParameterizedTest
199     @EnumSource(StandardOpenOption.class)
200     void testGetRandomAccessFile(final OpenOption openOption) throws IOException {
201         // Default
202         try (RandomAccessFile raf = getOriginRw().getRandomAccessFile()) {
203             assertNotNull(raf);
204             assertTrue(isValid(raf));
205         }
206         // Same as above, but underlying resource is now closed.
207         final boolean isRafOrigin = getOriginRw() instanceof RandomAccessFileOrigin;
208         try (RandomAccessFile raf = getOriginRw().getRandomAccessFile()) {
209             assertNotNull(raf);
210             assertFalse(isRafOrigin && isValid(raf));
211         }
212         try (RandomAccessFile raf = getOriginRw().getRandomAccessFile(openOption)) {
213             assertNotNull(raf);
214             assertFalse(isRafOrigin && isValid(raf));
215         }
216         try (RandomAccessFile raf = getOriginRw().getRandomAccessFile(openOption)) {
217             assertNotNull(raf);
218             assertFalse(isRafOrigin && isValid(raf));
219         }
220     }
221 
222     @Test
223     void testGetReader() throws IOException {
224         try (Reader reader = getOriginRo().getReader(Charset.defaultCharset())) {
225             assertNotNull(reader);
226         }
227         try (Reader reader = getOriginRo().getReader(null)) {
228             assertNotNull(reader);
229         }
230     }
231 
232     @Test
233     void testGetWriter() throws IOException {
234         try (Writer writer = getOriginRw().getWriter(Charset.defaultCharset())) {
235             assertNotNull(writer);
236         }
237         setOriginRw(newOriginRw());
238         try (Writer writer = getOriginRw().getWriter(null)) {
239             assertNotNull(writer);
240         }
241     }
242 
243     @Test
244     void testSize() throws IOException {
245         assertEquals(Files.size(Paths.get(FILE_NAME_RO)), getOriginRo().getByteArray().length);
246     }
247 }