/* * Copyright (C) 2007 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.io; import com.google.common.collect.Sets; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import junit.framework.TestCase; /** * Base test case class for I/O tests. * * @author Chris Nokleberg * @author Colin Decker */ public abstract class IoTestCase extends TestCase { private static final Logger logger = Logger.getLogger(IoTestCase.class.getName()); static final String I18N = "\u00CE\u00F1\u0163\u00E9\u0072\u00F1\u00E5\u0163\u00EE\u00F6" + "\u00F1\u00E5\u013C\u00EE\u017E\u00E5\u0163\u00EE\u00F6\u00F1"; static final String ASCII = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; private File testDir; private File tempDir; private final Set<File> filesToDelete = Sets.newHashSet(); @Override protected void tearDown() { for (File file : filesToDelete) { if (file.exists()) { delete(file); } } filesToDelete.clear(); } private File getTestDir() throws IOException { if (testDir != null) { return testDir; } URL testFileUrl = IoTestCase.class.getResource("testdata/i18n.txt"); if (testFileUrl == null) { throw new RuntimeException("unable to locate testdata directory"); } if (testFileUrl.getProtocol().equals("file")) { try { File testFile = new File(testFileUrl.toURI()); testDir = testFile.getParentFile(); // the testdata directory } catch (Exception ignore) { // probably URISyntaxException or IllegalArgumentException // fall back to copying URLs to files in the testDir == null block below } } if (testDir == null) { // testdata resources aren't file:// urls, so create a directory to store them in and then // copy the resources to the filesystem as needed testDir = createTempDir(); } return testDir; } /** * Returns the file with the given name under the testdata directory. */ protected final File getTestFile(String name) throws IOException { File file = new File(getTestDir(), name); if (!file.exists()) { URL resourceUrl = IoTestCase.class.getResource("testdata/" + name); if (resourceUrl == null) { return null; } copy(resourceUrl, file); } return file; } /** * Creates a new temp dir for testing. The returned directory and all contents of it will be * deleted in the tear-down for this test. */ protected final File createTempDir() throws IOException { File tempFile = File.createTempFile("IoTestCase", ""); if (!tempFile.delete() || !tempFile.mkdir()) { throw new IOException("failed to create temp dir"); } filesToDelete.add(tempFile); return tempFile; } /** * Gets a temp dir for testing. The returned directory and all contents of it will be deleted in * the tear-down for this test. Subsequent invocations of this method will return the same * directory. */ protected final File getTempDir() throws IOException { if (tempDir == null) { tempDir = createTempDir(); } return tempDir; } /** * Creates a new temp file in the temp directory returned by {@link #getTempDir()}. The file will * be deleted in the tear-down for this test. */ protected final File createTempFile() throws IOException { return File.createTempFile("test", null, getTempDir()); } /** * Returns a byte array of length size that has values 0 .. size - 1. */ static byte[] newPreFilledByteArray(int size) { return newPreFilledByteArray(0, size); } /** * Returns a byte array of length size that has values offset .. offset + size - 1. */ static byte[] newPreFilledByteArray(int offset, int size) { byte[] array = new byte[size]; for (int i = 0; i < size; i++) { array[i] = (byte) (offset + i); } return array; } private static void copy(URL url, File file) throws IOException { InputStream in = url.openStream(); try { OutputStream out = new FileOutputStream(file); try { byte[] buf = new byte[4096]; for (int read = in.read(buf); read != -1; read = in.read(buf)) { out.write(buf, 0, read); } } finally { out.close(); } } finally { in.close(); } } @CanIgnoreReturnValue private boolean delete(File file) { if (file.isDirectory()) { File[] files = file.listFiles(); if (files != null) { for (File f : files) { if (!delete(f)) { return false; } } } } if (!file.delete()) { logger.log(Level.WARNING, "couldn't delete file: {0}", new Object[] {file}); return false; } return true; } }