View Javadoc
1   package org.codehaus.plexus.util;
2   
3   /*
4    * Copyright The Codehaus Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.io.BufferedOutputStream;
20  import java.io.ByteArrayOutputStream;
21  import java.io.File;
22  import java.io.IOException;
23  import java.io.OutputStream;
24  import java.io.PrintStream;
25  import java.io.PrintWriter;
26  import java.io.Writer;
27  import java.lang.reflect.Method;
28  import java.nio.file.Files;
29  
30  import org.junit.jupiter.api.BeforeEach;
31  import org.junit.jupiter.api.TestInfo;
32  
33  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
34  import static org.junit.jupiter.api.Assertions.assertTrue;
35  import static org.junit.jupiter.api.Assertions.fail;
36  
37  /**
38   * Base class for testcases doing tests with files.
39   *
40   * @author Jeremias Maerki
41   * @version $Id: $Id
42   * @since 3.4.0
43   */
44  public abstract class FileBasedTestCase {
45      private static File testDir;
46  
47      private TestInfo testInfo;
48  
49      /**
50       * <p>getTestDirectory.</p>
51       *
52       * @return a {@link java.io.File} object.
53       */
54      public static File getTestDirectory() {
55          if (testDir == null) {
56              testDir = (new File("target/test/io/")).getAbsoluteFile();
57          }
58          return testDir;
59      }
60  
61      /**
62       * <p>createFile.</p>
63       *
64       * @param file a {@link java.io.File} object.
65       * @param size a long.
66       * @return an array of {@link byte} objects.
67       * @throws java.io.IOException if any.
68       */
69      protected byte[] createFile(final File file, final long size) throws IOException {
70          if (!file.getParentFile().exists()) {
71              throw new IOException("Cannot create file " + file + " as the parent directory does not exist");
72          }
73  
74          byte[] data = generateTestData(size);
75  
76          final BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(file.toPath()));
77  
78          try {
79              output.write(data);
80  
81              return data;
82          } finally {
83              output.close();
84          }
85      }
86  
87      /**
88       * <p>createSymlink.</p>
89       *
90       * @param link a {@link java.io.File} object.
91       * @param target a {@link java.io.File} object.
92       * @return a boolean.
93       */
94      protected boolean createSymlink(final File link, final File target) {
95          try {
96              String[] args = {"ln", "-s", target.getAbsolutePath(), link.getAbsolutePath()};
97              Process process = Runtime.getRuntime().exec(args);
98              process.waitFor();
99              if (0 != process.exitValue()) {
100                 return false;
101             }
102         } catch (Exception e) {
103             // assume platform does not support "ln" command, tests should be skipped
104             return false;
105         }
106         return true;
107     }
108 
109     /**
110      * <p>generateTestData.</p>
111      *
112      * @param size a long.
113      * @return an array of {@link byte} objects.
114      */
115     protected byte[] generateTestData(final long size) {
116         try {
117             ByteArrayOutputStream baout = new ByteArrayOutputStream();
118             generateTestData(baout, size);
119             return baout.toByteArray();
120         } catch (IOException ioe) {
121             throw new RuntimeException("This should never happen: " + ioe.getMessage());
122         }
123     }
124 
125     /**
126      * <p>generateTestData.</p>
127      *
128      * @param out a {@link java.io.OutputStream} object.
129      * @param size a long.
130      * @throws java.io.IOException if any.
131      */
132     protected void generateTestData(final OutputStream out, final long size) throws IOException {
133         for (int i = 0; i < size; i++) {
134             // output.write((byte)'X');
135 
136             // nice varied byte pattern compatible with Readers and Writers
137             out.write((byte) ((i % 127) + 1));
138         }
139     }
140 
141     /**
142      * <p>newFile.</p>
143      *
144      * @param filename a {@link java.lang.String} object.
145      * @return a {@link java.io.File} object.
146      * @throws java.io.IOException if any.
147      */
148     protected File newFile(String filename) throws IOException {
149         final File destination = new File(getTestDirectory(), filename);
150         /*
151          * assertTrue( filename + "Test output data file shouldn't previously exist", !destination.exists() );
152          */
153         if (destination.exists()) {
154             FileUtils.forceDelete(destination);
155         }
156         return destination;
157     }
158 
159     /**
160      * <p>checkFile.</p>
161      *
162      * @param file a {@link java.io.File} object.
163      * @param referenceFile a {@link java.io.File} object.
164      * @throws java.lang.Exception if any.
165      */
166     protected void checkFile(final File file, final File referenceFile) throws Exception {
167         assertTrue(file.exists(), "Check existence of output file");
168         assertEqualContent(referenceFile, file);
169     }
170 
171     /**
172      * <p>checkWrite.</p>
173      *
174      * @param output a {@link java.io.OutputStream} object.
175      * @throws java.lang.Exception if any.
176      */
177     protected void checkWrite(final OutputStream output) throws Exception {
178         try {
179             new PrintStream(output).write(0);
180         } catch (final Throwable t) {
181             fail("The copy() method closed the stream " + "when it shouldn't have. " + t.getMessage());
182         }
183     }
184 
185     /**
186      * <p>checkWrite.</p>
187      *
188      * @param output a {@link java.io.Writer} object.
189      * @throws java.lang.Exception if any.
190      */
191     protected void checkWrite(final Writer output) throws Exception {
192         try {
193             new PrintWriter(output).write('a');
194         } catch (final Throwable t) {
195             fail("The copy() method closed the stream " + "when it shouldn't have. " + t.getMessage());
196         }
197     }
198 
199     /**
200      * <p>deleteFile.</p>
201      *
202      * @param file a {@link java.io.File} object.
203      * @throws java.lang.Exception if any.
204      */
205     protected void deleteFile(final File file) throws Exception {
206         if (file.exists()) {
207             assertTrue(file.delete(), "Couldn't delete file: " + file);
208         }
209     }
210 
211     // ----------------------------------------------------------------------
212     // Assertions
213     // ----------------------------------------------------------------------
214 
215     /** Assert that the content of two files is the same. */
216     private void assertEqualContent(final File f0, final File f1) throws IOException {
217         /*
218          * This doesn't work because the filesize isn't updated until the file is closed. assertTrue( "The files " + f0
219          * + " and " + f1 + " have differing file sizes (" + f0.length() + " vs " + f1.length() + ")", ( f0.length() ==
220          * f1.length() ) );
221          */
222         byte[] buf0 = Files.readAllBytes(f0.toPath());
223         byte[] buf1 = Files.readAllBytes(f0.toPath());
224         assertArrayEquals(buf0, buf1, "The files " + f0 + " and " + f1 + " have different content");
225     }
226 
227     /**
228      * Assert that the content of a file is equal to that in a byte[].
229      *
230      * @param b0 an array of {@link byte} objects.
231      * @param file a {@link java.io.File} object.
232      * @throws java.io.IOException if any.
233      */
234     protected void assertEqualContent(final byte[] b0, final File file) throws IOException {
235         byte[] b1 = Files.readAllBytes(file.toPath());
236         assertArrayEquals(b0, b1, "Content differs");
237     }
238 
239     /**
240      * <p>assertIsDirectory.</p>
241      *
242      * @param file a {@link java.io.File} object.
243      */
244     protected void assertIsDirectory(File file) {
245         assertTrue(file.exists(), "The File doesn't exists: " + file.getAbsolutePath());
246 
247         assertTrue(file.isDirectory(), "The File isn't a directory: " + file.getAbsolutePath());
248     }
249 
250     /**
251      * <p>assertIsFile.</p>
252      *
253      * @param file a {@link java.io.File} object.
254      */
255     protected void assertIsFile(File file) {
256         assertTrue(file.exists(), "The File doesn't exists: " + file.getAbsolutePath());
257 
258         assertTrue(file.isFile(), "The File isn't a file: " + file.getAbsolutePath());
259     }
260 
261     @BeforeEach
262     void init(TestInfo testInfo) {
263         this.testInfo = testInfo;
264     }
265 
266     protected String getTestMethodName() {
267         return testInfo.getTestMethod().map(Method::getName).orElse(null);
268     }
269 }