diff options
author | David Srbecky <dsrbecky@google.com> | 2021-02-24 18:57:51 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-02-24 18:57:51 +0000 |
commit | 91c5e5ff9d71ebc00818b310c09b175016c36dc2 (patch) | |
tree | 81124de095a6b4a53b223d0f70cadde9744ee44a /src/main/java/org/junit/rules/TemporaryFolder.java | |
parent | 82af4b8b1d440f44b6ebac4db1fd61ae1d35a15e (diff) | |
parent | 23e304a839c5924c7ac7399076318adc511e9985 (diff) | |
download | junit-91c5e5ff9d71ebc00818b310c09b175016c36dc2.tar.gz |
Merge changes from topic "revert-1601635-AIQYZOHWTP" am: 565f36d281 am: 23e304a839
Original change: https://android-review.googlesource.com/c/platform/external/junit/+/1605377
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: I443f57dd29ed2557b7733b1f3e51718d5d6a2af4
Diffstat (limited to 'src/main/java/org/junit/rules/TemporaryFolder.java')
-rw-r--r-- | src/main/java/org/junit/rules/TemporaryFolder.java | 277 |
1 files changed, 48 insertions, 229 deletions
diff --git a/src/main/java/org/junit/rules/TemporaryFolder.java b/src/main/java/org/junit/rules/TemporaryFolder.java index a726c66..dc75c93 100644 --- a/src/main/java/org/junit/rules/TemporaryFolder.java +++ b/src/main/java/org/junit/rules/TemporaryFolder.java @@ -1,20 +1,15 @@ package org.junit.rules; -import static org.junit.Assert.fail; - import java.io.File; import java.io.IOException; -import java.lang.reflect.Array; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import org.junit.Rule; /** * The TemporaryFolder Rule allows creation of files and folders that should * be deleted when the test method finishes (whether it passes or - * fails). - * By default no exception will be thrown in case the deletion fails. + * fails). Whether the deletion is successful or not is not checked by this rule. + * No exception will be thrown in case the deletion fails. * * <p>Example of usage: * <pre> @@ -31,104 +26,18 @@ import org.junit.Rule; * } * </pre> * - * <p>TemporaryFolder rule supports assured deletion mode, which - * will fail the test in case deletion fails with {@link AssertionError}. - * - * <p>Creating TemporaryFolder with assured deletion: - * <pre> - * @Rule - * public TemporaryFolder folder= TemporaryFolder.builder().assureDeletion().build(); - * </pre> - * * @since 4.7 */ public class TemporaryFolder extends ExternalResource { private final File parentFolder; - private final boolean assureDeletion; private File folder; - private static final int TEMP_DIR_ATTEMPTS = 10000; - private static final String TMP_PREFIX = "junit"; - - /** - * Create a temporary folder which uses system default temporary-file - * directory to create temporary resources. - */ public TemporaryFolder() { - this((File) null); + this(null); } - /** - * Create a temporary folder which uses the specified directory to create - * temporary resources. - * - * @param parentFolder folder where temporary resources will be created. - * If {@code null} then system default temporary-file directory is used. - */ public TemporaryFolder(File parentFolder) { this.parentFolder = parentFolder; - this.assureDeletion = false; - } - - /** - * Create a {@link TemporaryFolder} initialized with - * values from a builder. - */ - protected TemporaryFolder(Builder builder) { - this.parentFolder = builder.parentFolder; - this.assureDeletion = builder.assureDeletion; - } - - /** - * Returns a new builder for building an instance of {@link TemporaryFolder}. - * - * @since 4.13 - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Builds an instance of {@link TemporaryFolder}. - * - * @since 4.13 - */ - public static class Builder { - private File parentFolder; - private boolean assureDeletion; - - protected Builder() {} - - /** - * Specifies which folder to use for creating temporary resources. - * If {@code null} then system default temporary-file directory is - * used. - * - * @return this - */ - public Builder parentFolder(File parentFolder) { - this.parentFolder = parentFolder; - return this; - } - - /** - * Setting this flag assures that no resources are left undeleted. Failure - * to fulfill the assurance results in failure of tests with an - * {@link AssertionError}. - * - * @return this - */ - public Builder assureDeletion() { - this.assureDeletion = true; - return this; - } - - /** - * Builds a {@link TemporaryFolder} instance using the values in this builder. - */ - public TemporaryFolder build() { - return new TemporaryFolder(this); - } } @Override @@ -166,129 +75,66 @@ public class TemporaryFolder extends ExternalResource { * Returns a new fresh file with a random name under the temporary folder. */ public File newFile() throws IOException { - return File.createTempFile(TMP_PREFIX, null, getRoot()); + return File.createTempFile("junit", null, getRoot()); } /** - * Returns a new fresh folder with the given path under the temporary + * Returns a new fresh folder with the given name under the temporary * folder. */ - public File newFolder(String path) throws IOException { - return newFolder(new String[]{path}); + public File newFolder(String folder) throws IOException { + return newFolder(new String[]{folder}); } /** - * Returns a new fresh folder with the given paths under the temporary - * folder. For example, if you pass in the strings {@code "parent"} and {@code "child"} - * then a directory named {@code "parent"} will be created under the temporary folder - * and a directory named {@code "child"} will be created under the newly-created - * {@code "parent"} directory. + * Returns a new fresh folder with the given name(s) under the temporary + * folder. */ - public File newFolder(String... paths) throws IOException { - if (paths.length == 0) { - throw new IllegalArgumentException("must pass at least one path"); - } - - /* - * Before checking if the paths are absolute paths, check if create() was ever called, - * and if it wasn't, throw IllegalStateException. - */ - File root = getRoot(); - for (String path : paths) { - if (new File(path).isAbsolute()) { - throw new IOException("folder path \'" + path + "\' is not a relative path"); - } - } - - File relativePath = null; - File file = root; - boolean lastMkdirsCallSuccessful = true; - for (String path : paths) { - relativePath = new File(relativePath, path); - file = new File(root, relativePath.getPath()); - - lastMkdirsCallSuccessful = file.mkdirs(); - if (!lastMkdirsCallSuccessful && !file.isDirectory()) { - if (file.exists()) { - throw new IOException( - "a file with the path \'" + relativePath.getPath() + "\' exists"); - } else { - throw new IOException( - "could not create a folder with the path \'" + relativePath.getPath() + "\'"); - } + public File newFolder(String... folderNames) throws IOException { + File file = getRoot(); + for (int i = 0; i < folderNames.length; i++) { + String folderName = folderNames[i]; + validateFolderName(folderName); + file = new File(file, folderName); + if (!file.mkdir() && isLastElementInArray(i, folderNames)) { + throw new IOException( + "a folder with the name \'" + folderName + "\' already exists"); } } - if (!lastMkdirsCallSuccessful) { - throw new IOException( - "a folder with the path \'" + relativePath.getPath() + "\' already exists"); - } return file; } - + /** - * Returns a new fresh folder with a random name under the temporary folder. + * Validates if multiple path components were used while creating a folder. + * + * @param folderName + * Name of the folder being created */ - public File newFolder() throws IOException { - return createTemporaryFolderIn(getRoot()); + private void validateFolderName(String folderName) throws IOException { + File tempFile = new File(folderName); + if (tempFile.getParent() != null) { + String errorMsg = "Folder name cannot consist of multiple path components separated by a file separator." + + " Please use newFolder('MyParentFolder','MyFolder') to create hierarchies of folders"; + throw new IOException(errorMsg); + } } - private static File createTemporaryFolderIn(File parentFolder) throws IOException { - try { - return createTemporaryFolderWithNioApi(parentFolder); - } catch (ClassNotFoundException ignore) { - // Fallback for Java 5 and 6 - return createTemporaryFolderWithFileApi(parentFolder); - } catch (InvocationTargetException e) { - Throwable cause = e.getCause(); - if (cause instanceof IOException) { - throw (IOException) cause; - } - if (cause instanceof RuntimeException) { - throw (RuntimeException) cause; - } - IOException exception = new IOException("Failed to create temporary folder in " + parentFolder); - exception.initCause(cause); - throw exception; - } catch (Exception e) { - throw new RuntimeException("Failed to create temporary folder in " + parentFolder, e); - } + private boolean isLastElementInArray(int index, String[] array) { + return index == array.length - 1; } - private static File createTemporaryFolderWithNioApi(File parentFolder) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Class<?> filesClass = Class.forName("java.nio.file.Files"); - Object fileAttributeArray = Array.newInstance(Class.forName("java.nio.file.attribute.FileAttribute"), 0); - Class<?> pathClass = Class.forName("java.nio.file.Path"); - Object tempDir; - if (parentFolder != null) { - Method createTempDirectoryMethod = filesClass.getDeclaredMethod("createTempDirectory", pathClass, String.class, fileAttributeArray.getClass()); - Object parentPath = File.class.getDeclaredMethod("toPath").invoke(parentFolder); - tempDir = createTempDirectoryMethod.invoke(null, parentPath, TMP_PREFIX, fileAttributeArray); - } else { - Method createTempDirectoryMethod = filesClass.getDeclaredMethod("createTempDirectory", String.class, fileAttributeArray.getClass()); - tempDir = createTempDirectoryMethod.invoke(null, TMP_PREFIX, fileAttributeArray); - } - return (File) pathClass.getDeclaredMethod("toFile").invoke(tempDir); + /** + * Returns a new fresh folder with a random name under the temporary folder. + */ + public File newFolder() throws IOException { + return createTemporaryFolderIn(getRoot()); } - private static File createTemporaryFolderWithFileApi(File parentFolder) throws IOException { - File createdFolder = null; - for (int i = 0; i < TEMP_DIR_ATTEMPTS; ++i) { - // Use createTempFile to get a suitable folder name. - String suffix = ".tmp"; - File tmpFile = File.createTempFile(TMP_PREFIX, suffix, parentFolder); - String tmpName = tmpFile.toString(); - // Discard .tmp suffix of tmpName. - String folderName = tmpName.substring(0, tmpName.length() - suffix.length()); - createdFolder = new File(folderName); - if (createdFolder.mkdir()) { - tmpFile.delete(); - return createdFolder; - } - tmpFile.delete(); - } - throw new IOException("Unable to create temporary directory in: " - + parentFolder.toString() + ". Tried " + TEMP_DIR_ATTEMPTS + " times. " - + "Last attempted to create: " + createdFolder.toString()); + private File createTemporaryFolderIn(File parentFolder) throws IOException { + File createdFolder = File.createTempFile("junit", "", parentFolder); + createdFolder.delete(); + createdFolder.mkdir(); + return createdFolder; } /** @@ -304,48 +150,21 @@ public class TemporaryFolder extends ExternalResource { /** * Delete all files and folders under the temporary folder. Usually not - * called directly, since it is automatically applied by the {@link Rule}. - * - * @throws AssertionError if unable to clean up resources - * and deletion of resources is assured. + * called directly, since it is automatically applied by the {@link Rule} */ public void delete() { - if (!tryDelete()) { - if (assureDeletion) { - fail("Unable to clean up temporary folder " + folder); - } - } - } - - /** - * Tries to delete all files and folders under the temporary folder and - * returns whether deletion was successful or not. - * - * @return {@code true} if all resources are deleted successfully, - * {@code false} otherwise. - */ - private boolean tryDelete() { - if (folder == null) { - return true; + if (folder != null) { + recursiveDelete(folder); } - - return recursiveDelete(folder); } - private boolean recursiveDelete(File file) { - // Try deleting file before assuming file is a directory - // to prevent following symbolic links. - if (file.delete()) { - return true; - } + private void recursiveDelete(File file) { File[] files = file.listFiles(); if (files != null) { for (File each : files) { - if (!recursiveDelete(each)) { - return false; - } + recursiveDelete(each); } } - return file.delete(); + file.delete(); } } |