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