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.testtools;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertTrue;
21  import static org.junit.jupiter.api.Assertions.fail;
22  
23  import java.io.BufferedOutputStream;
24  import java.io.File;
25  import java.io.FileInputStream;
26  import java.io.FileOutputStream;
27  import java.io.FileReader;
28  import java.io.IOException;
29  import java.io.InputStream;
30  import java.io.OutputStream;
31  import java.io.OutputStreamWriter;
32  import java.io.PrintWriter;
33  import java.io.Reader;
34  import java.io.Writer;
35  import java.util.Arrays;
36  
37  import org.apache.commons.io.FileUtils;
38  import org.apache.commons.io.output.ByteArrayOutputStream;
39  
40  /**
41   * Base class for testcases doing tests with files.
42   */
43  public abstract class TestUtils {
44  
45      private TestUtils() {
46  
47      }
48  
49      public static void createFile(final File file, final long size)
50              throws IOException {
51          if (!file.getParentFile().exists()) {
52              throw new IOException("Cannot create file " + file
53                      + " as the parent directory does not exist");
54          }
55          try (final BufferedOutputStream output =
56                  new BufferedOutputStream(new java.io.FileOutputStream(file))) {
57              generateTestData(output, size);
58          }
59      }
60  
61      public static byte[] generateTestData(final long size) {
62          try {
63              final ByteArrayOutputStream baout = new ByteArrayOutputStream();
64              generateTestData(baout, size);
65              return baout.toByteArray();
66          } catch (final IOException ioe) {
67              throw new RuntimeException("This should never happen: " + ioe.getMessage());
68          }
69      }
70  
71      public static void generateTestData(final OutputStream out, final long size)
72              throws IOException {
73          for (int i = 0; i < size; i++) {
74              //output.write((byte)'X');
75  
76              // nice varied byte pattern compatible with Readers and Writers
77              out.write((byte) ((i % 127) + 1));
78          }
79      }
80  
81      public static void createLineBasedFile(final File file, final String[] data) throws IOException {
82          if (file.getParentFile() != null && !file.getParentFile().exists()) {
83              throw new IOException("Cannot create file " + file + " as the parent directory does not exist");
84          }
85          try (final PrintWriter output = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"))) {
86              for (final String element : data) {
87                  output.println(element);
88              }
89          }
90      }
91  
92      public static File newFile(final File testDirectory, final String filename) throws IOException {
93          final File destination = new File(testDirectory, filename);
94          /*
95          assertTrue( filename + "Test output data file shouldn't previously exist",
96                      !destination.exists() );
97          */
98          if (destination.exists()) {
99              FileUtils.forceDelete(destination);
100         }
101         return destination;
102     }
103 
104     public static void checkFile(final File file, final File referenceFile)
105             throws Exception {
106         assertTrue(file.exists(), "Check existence of output file");
107         assertEqualContent(referenceFile, file);
108     }
109 
110     /**
111      * Assert that the content of two files is the same.
112      */
113     private static void assertEqualContent(final File f0, final File f1)
114             throws IOException {
115         /* This doesn't work because the filesize isn't updated until the file
116          * is closed.
117         assertTrue( "The files " + f0 + " and " + f1 +
118                     " have differing file sizes (" + f0.length() +
119                     " vs " + f1.length() + ")", ( f0.length() == f1.length() ) );
120         */
121         try (InputStream is0 = new FileInputStream(f0)) {
122             try (InputStream is1 = new FileInputStream(f1)) {
123                 final byte[] buf0 = new byte[1024];
124                 final byte[] buf1 = new byte[1024];
125                 int n0 = 0;
126                 int n1;
127 
128                 while (-1 != n0) {
129                     n0 = is0.read(buf0);
130                     n1 = is1.read(buf1);
131                     assertTrue((n0 == n1),
132                             "The files " + f0 + " and " + f1 +
133                             " have differing number of bytes available (" + n0 + " vs " + n1 + ")");
134 
135                     assertTrue(Arrays.equals(buf0, buf1),
136                             "The files " + f0 + " and " + f1 + " have different content");
137                 }
138             }
139         }
140     }
141 
142     /**
143      * Assert that the content of a file is equal to that in a byte[].
144      *
145      * @param b0   the expected contents
146      * @param file the file to check
147      * @throws IOException If an I/O error occurs while reading the file contents
148      */
149     public static void assertEqualContent(final byte[] b0, final File file) throws IOException {
150         int count = 0, numRead = 0;
151         final byte[] b1 = new byte[b0.length];
152         try (InputStream is = new FileInputStream(file)) {
153             while (count < b0.length && numRead >= 0) {
154                 numRead = is.read(b1, count, b0.length);
155                 count += numRead;
156             }
157             assertEquals(b0.length, count, "Different number of bytes: ");
158             for (int i = 0; i < count; i++) {
159                 assertEquals(b0[i], b1[i], "byte " + i + " differs");
160             }
161         }
162     }
163 
164     /**
165      * Assert that the content of a file is equal to that in a char[].
166      *
167      * @param c0   the expected contents
168      * @param file the file to check
169      * @throws IOException If an I/O error occurs while reading the file contents
170      */
171     public static void assertEqualContent(final char[] c0, final File file) throws IOException {
172         int count = 0, numRead = 0;
173         final char[] c1 = new char[c0.length];
174         try (Reader ir = new FileReader(file)) {
175             while (count < c0.length && numRead >= 0) {
176                 numRead = ir.read(c1, count, c0.length);
177                 count += numRead;
178             }
179             assertEquals(c0.length, count, "Different number of chars: ");
180             for (int i = 0; i < count; i++) {
181                 assertEquals(c0[i], c1[i], "char " + i + " differs");
182             }
183         }
184     }
185 
186     public static void checkWrite(final OutputStream output) throws Exception {
187         try {
188             new java.io.PrintStream(output).write(0);
189         } catch (final Throwable t) {
190             fail("The copy() method closed the stream when it shouldn't have. " + t.getMessage());
191         }
192     }
193 
194     public static void checkWrite(final Writer output) throws Exception {
195         try {
196             new java.io.PrintWriter(output).write('a');
197         } catch (final Throwable t) {
198             fail("The copy() method closed the stream when it shouldn't have. " + t.getMessage());
199         }
200     }
201 
202     public static void deleteFile(final File file)
203             throws Exception {
204         if (file.exists()) {
205             assertTrue(file.delete(), "Couldn't delete file: " + file);
206         }
207     }
208 
209     /**
210      * Sleep for a guaranteed number of milliseconds unless interrupted.
211      *
212      * This method exists because Thread.sleep(100) can sleep for 0, 70, 100 or 200ms or anything else
213      * it deems appropriate. Read the docs on Thread.sleep for further details.
214      *
215      * @param ms the number of milliseconds to sleep for
216      * @throws InterruptedException if interrupted
217      */
218     public static void sleep(final long ms) throws InterruptedException {
219         final long finishAt = System.currentTimeMillis() + ms;
220         long remaining = ms;
221         do {
222             Thread.sleep(remaining);
223             remaining = finishAt - System.currentTimeMillis();
224         } while (remaining > 0);
225     }
226 
227     public static void sleepQuietly(final long ms) {
228         try {
229             sleep(ms);
230         } catch (final InterruptedException ignored){
231         }
232     }
233 
234 }