IoTestCase.java revision 0888a09821a98ac0680fad765217302858e70fa4
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
17package com.google.common.io;
18
19import com.google.common.collect.Sets;
20
21import junit.framework.TestCase;
22
23import java.io.File;
24import java.io.FileOutputStream;
25import java.io.IOException;
26import java.io.InputStream;
27import java.io.OutputStream;
28import java.net.URL;
29import java.util.Set;
30import java.util.logging.Level;
31import java.util.logging.Logger;
32
33/**
34 * Base test case class for I/O tests.
35 *
36 * @author Chris Nokleberg
37 * @author Colin Decker
38 */
39public 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 = Sets.newHashSet();
55
56  @Override
57  protected void tearDown() {
58    for (File file : filesToDelete) {
59      if (file.exists()) {
60        delete(file);
61      }
62    }
63    filesToDelete.clear();
64  }
65
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  /**
96   * Returns the file with the given name under the testdata directory.
97   */
98  protected final File getTestFile(String name) throws IOException {
99    File file = new File(getTestDir(), name);
100    if (!file.exists()) {
101      URL resourceUrl = IoTestCase.class.getResource("testdata/" + name);
102      if (resourceUrl == null) {
103        return null;
104      }
105      copy(resourceUrl, file);
106    }
107
108    return file;
109  }
110
111  /**
112   * Creates a new temp dir for testing. The returned directory and all contents of it will be
113   * deleted in the tear-down for this test.
114   */
115  protected final File createTempDir() throws IOException {
116    File tempFile = File.createTempFile("IoTestCase", "");
117    if (!tempFile.delete() || !tempFile.mkdir()) {
118      throw new IOException("failed to create temp dir");
119    }
120    filesToDelete.add(tempFile);
121    return tempFile;
122  }
123
124  /**
125   * Gets a temp dir for testing. The returned directory and all contents of it will be deleted in
126   * the tear-down for this test. Subsequent invocations of this method will return the same
127   * directory.
128   */
129  protected final File getTempDir() throws IOException {
130    if (tempDir == null) {
131      tempDir = createTempDir();
132    }
133
134    return tempDir;
135  }
136
137  /**
138   * Creates a new temp file in the temp directory returned by {@link #getTempDir()}. The file will
139   * be deleted in the tear-down for this test.
140   */
141  protected final File createTempFile() throws IOException {
142    return File.createTempFile("test", null, getTempDir());
143  }
144
145  /**
146   * Returns a byte array of length size that has values 0 .. size - 1.
147   */
148  static byte[] newPreFilledByteArray(int size) {
149    return newPreFilledByteArray(0, size);
150  }
151
152  /**
153   * Returns a byte array of length size that has values offset .. offset + size - 1.
154   */
155  static byte[] newPreFilledByteArray(int offset, int size) {
156    byte[] array = new byte[size];
157    for (int i = 0; i < size; i++) {
158      array[i] = (byte) (offset + i);
159    }
160    return array;
161  }
162
163  private static void copy(URL url, File file) throws IOException {
164    InputStream in = url.openStream();
165    try {
166      OutputStream out = new FileOutputStream(file);
167      try {
168        byte[] buf = new byte[4096];
169        for (int read = in.read(buf); read != -1; read = in.read(buf)) {
170          out.write(buf, 0, read);
171        }
172      } finally {
173        out.close();
174      }
175    } finally {
176      in.close();
177    }
178  }
179
180  private boolean delete(File file) {
181    if (file.isDirectory()) {
182      File[] files = file.listFiles();
183      if (files != null) {
184        for (File f : files) {
185          if (!delete(f)) {
186            return false;
187          }
188        }
189      }
190    }
191
192    if (!file.delete()) {
193      logger.log(Level.WARNING, "couldn't delete file: {0}", new Object[] {file});
194      return false;
195    }
196
197    return true;
198  }
199}
200