• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.io;
18 
19 import com.google.errorprone.annotations.CanIgnoreReturnValue;
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.net.URL;
26 import java.util.HashSet;
27 import java.util.Set;
28 import java.util.logging.Level;
29 import java.util.logging.Logger;
30 import junit.framework.TestCase;
31 import org.checkerframework.checker.nullness.qual.Nullable;
32 
33 /**
34  * Base test case class for I/O tests.
35  *
36  * @author Chris Nokleberg
37  * @author Colin Decker
38  */
39 public abstract class IoTestCase extends TestCase {
40 
41   private static final Logger logger = Logger.getLogger(IoTestCase.class.getName());
42 
43   static final String I18N =
44       "\u00CE\u00F1\u0163\u00E9\u0072\u00F1\u00E5\u0163\u00EE\u00F6"
45           + "\u00F1\u00E5\u013C\u00EE\u017E\u00E5\u0163\u00EE\u00F6\u00F1";
46 
47   static final String ASCII =
48       " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"
49           + "[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
50 
51   private File testDir;
52   private File tempDir;
53 
54   private final Set<File> filesToDelete = new HashSet<>();
55 
56   @Override
tearDown()57   protected void tearDown() {
58     for (File file : filesToDelete) {
59       if (file.exists()) {
60         delete(file);
61       }
62     }
63     filesToDelete.clear();
64   }
65 
getTestDir()66   private File getTestDir() throws IOException {
67     if (testDir != null) {
68       return testDir;
69     }
70 
71     URL testFileUrl = IoTestCase.class.getResource("testdata/i18n.txt");
72     if (testFileUrl == null) {
73       throw new RuntimeException("unable to locate testdata directory");
74     }
75 
76     if (testFileUrl.getProtocol().equals("file")) {
77       try {
78         File testFile = new File(testFileUrl.toURI());
79         testDir = testFile.getParentFile(); // the testdata directory
80       } catch (Exception ignore) {
81         // probably URISyntaxException or IllegalArgumentException
82         // fall back to copying URLs to files in the testDir == null block below
83       }
84     }
85 
86     if (testDir == null) {
87       // testdata resources aren't file:// urls, so create a directory to store them in and then
88       // copy the resources to the filesystem as needed
89       testDir = createTempDir();
90     }
91 
92     return testDir;
93   }
94 
95   /** Returns the file with the given name under the testdata directory. */
getTestFile(String name)96   protected final @Nullable File getTestFile(String name) throws IOException {
97     File file = new File(getTestDir(), name);
98     if (!file.exists()) {
99       URL resourceUrl = IoTestCase.class.getResource("testdata/" + name);
100       if (resourceUrl == null) {
101         return null;
102       }
103       copy(resourceUrl, file);
104     }
105 
106     return file;
107   }
108 
109   /**
110    * Creates a new temp dir for testing. The returned directory and all contents of it will be
111    * deleted in the tear-down for this test.
112    */
createTempDir()113   protected final File createTempDir() throws IOException {
114     File tempFile = File.createTempFile("IoTestCase", "");
115     if (!tempFile.delete() || !tempFile.mkdir()) {
116       throw new IOException("failed to create temp dir");
117     }
118     filesToDelete.add(tempFile);
119     return tempFile;
120   }
121 
122   /**
123    * Gets a temp dir for testing. The returned directory and all contents of it will be deleted in
124    * the tear-down for this test. Subsequent invocations of this method will return the same
125    * directory.
126    */
getTempDir()127   protected final File getTempDir() throws IOException {
128     if (tempDir == null) {
129       tempDir = createTempDir();
130     }
131 
132     return tempDir;
133   }
134 
135   /**
136    * Creates a new temp file in the temp directory returned by {@link #getTempDir()}. The file will
137    * be deleted in the tear-down for this test.
138    */
createTempFile()139   protected final File createTempFile() throws IOException {
140     return File.createTempFile("test", null, getTempDir());
141   }
142 
143   /** Returns a byte array of length size that has values 0 .. size - 1. */
newPreFilledByteArray(int size)144   static byte[] newPreFilledByteArray(int size) {
145     return newPreFilledByteArray(0, size);
146   }
147 
148   /** Returns a byte array of length size that has values offset .. offset + size - 1. */
newPreFilledByteArray(int offset, int size)149   static byte[] newPreFilledByteArray(int offset, int size) {
150     byte[] array = new byte[size];
151     for (int i = 0; i < size; i++) {
152       array[i] = (byte) (offset + i);
153     }
154     return array;
155   }
156 
copy(URL url, File file)157   private static void copy(URL url, File file) throws IOException {
158     InputStream in = url.openStream();
159     try {
160       OutputStream out = new FileOutputStream(file);
161       try {
162         byte[] buf = new byte[4096];
163         for (int read = in.read(buf); read != -1; read = in.read(buf)) {
164           out.write(buf, 0, read);
165         }
166       } finally {
167         out.close();
168       }
169     } finally {
170       in.close();
171     }
172   }
173 
174   @CanIgnoreReturnValue
delete(File file)175   private boolean delete(File file) {
176     if (file.isDirectory()) {
177       File[] files = file.listFiles();
178       if (files != null) {
179         for (File f : files) {
180           if (!delete(f)) {
181             return false;
182           }
183         }
184       }
185     }
186 
187     if (!file.delete()) {
188       logger.log(Level.WARNING, "couldn't delete file: {0}", new Object[] {file});
189       return false;
190     }
191 
192     return true;
193   }
194 }
195