blob: 64393f345a74a9bb25bd3330e908a53af35482cd [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.drill.test;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import org.apache.commons.io.FileUtils;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import java.io.File;
import java.nio.file.Path;
import java.util.List;
/**
* This is a {@link org.junit.rules.TestWatcher} which is used to create and delete sub directories before and after unit tests respectively.
* Ideally a {@link SubDirTestWatcher} would be used in conjunction with a {@link DirTestWatcher} or a sub class of {@link DirTestWatcher}. The
* {@link DirTestWatcher} would be used to create the base directory used by the {@link SubDirTestWatcher} to create all its sub directories. Here
* is an example of using the {@link SubDirTestWatcher} in this way.
*
* <pre>
* package my.proj;
*
* public class MyTestClass {
* public static final String TEST_SUB_DIR = "testSubDir";
* private static File testSubDir;
*
* &#064;org.junit.ClassRule
* public static final DirTestWatcher dirTestWatcher = new DirTestWatcher();
*
* &#064;org.junit.BeforeClass
* public static void setupFiles() {
* testSubDir = new File(dirTestWatcher.getDir(), TEST_SUB_DIR);
* }
*
* &#064;org.junit.Rule
* public final SubDirTestWatcher subDirTestWatcher =
* new SubDirTestWatcher.Builder(dirTestWatcher.getDir())
* .addSubDir(TEST_SUB_DIR)
* .build();
*
* &#064;org.junit.Test
* public void myTestMethod1() {
* // The testSubDir should be created for us by the SubDirTestWatcher
* org.junit.Assert.assertTrue(testSubDir.exists());
*
* // Lets make another sub directory in our sub directory
* File newSubDirectory = new File(testSubDir, "a");
* newSubDirectory.mkdirs();
* org.junit.Assert.assertTrue(newSubDirectory.exists());
* }
*
* &#064;org.junit.Test
* public void myTestMethod2() {
* // The testSubDir should be created for us by the SubDirTestWatcher
* org.junit.Assert.assertTrue(testSubDir.exists());
*
* // The directory we created in the previous test should be gone
* org.junit.Assert.assertFalse(new File(testSubDir, "a").exists());
* }
* }
* </pre>
*/
public class SubDirTestWatcher extends TestWatcher {
private File baseDir;
private boolean createAtBeginning;
private boolean deleteAtEnd;
private List<Path> subDirs;
protected SubDirTestWatcher(File baseDir, boolean createAtBeginning, boolean deleteAtEnd, List<Path> subDirs) {
this.baseDir = Preconditions.checkNotNull(baseDir);
this.createAtBeginning = createAtBeginning;
this.deleteAtEnd = deleteAtEnd;
this.subDirs = Preconditions.checkNotNull(subDirs);
Preconditions.checkArgument(!subDirs.isEmpty(), "The list of subDirs is empty.");
}
@Override
protected void starting(Description description) {
deleteDirs(true);
if (!createAtBeginning) {
return;
}
for (Path subDir: subDirs) {
baseDir.toPath()
.resolve(subDir)
.toFile()
.mkdirs();
}
}
@Override
protected void finished(Description description) {
deleteDirs(deleteAtEnd);
}
@Override
protected void failed(Throwable e, Description description) {
deleteDirs(deleteAtEnd);
}
private void deleteDirs(boolean delete) {
if (!delete) {
return;
}
for (Path subDir: subDirs) {
FileUtils.deleteQuietly(baseDir.toPath().resolve(subDir).toFile());
}
}
/**
* This is a builder for a {@link SubDirTestWatcher}. Create an instance of the builder, configure it, and then call the {@link Builder#build()} to create a
* {@link SubDirTestWatcher}.
*/
public static class Builder {
private File baseDir;
private boolean createAtBeginning = true;
private boolean deleteAtEnd = true;
private List<Path> subDirs = Lists.newArrayList();
/**
* Initializes a builder for a {@link SubDirTestWatcher} with the given baseDir.
* @param baseDir The baseDir is the parent directory in which all sub directories are created.
*/
public Builder(File baseDir) {
this.baseDir = Preconditions.checkNotNull(baseDir);
}
/**
* Sets the createAtBeginning flag.
* @param createAtBeginning This flag determines whether the {@link SubDirTestWatcher} creates the configured sub directories at a beginning of a test. Setting
* This to true will cause the {@link SubDirTestWatcher} to create the configured sub directories at the beginning of each test. Setting
* This to false will prevent the {@link SubDirTestWatcher} from attempting to create the configured sub directories at the beginning of
* at test. Setting this to false is useful for scenarios where you only want to delete directories created in the middle of your tests. By
* default this flag is true.
* @return The {@link SubDirTestWatcher.Builder}.
*/
public Builder setCreateAtBeginning(boolean createAtBeginning) {
this.createAtBeginning = createAtBeginning;
return this;
}
/**
* Sets the deleteAtEnd flag.
* @param deleteAtEnd This flag determines whether the {@link SubDirTestWatcher} deletes the sub directories it manages at the end of a test.
* @return The {@link SubDirTestWatcher.Builder}.
*/
public Builder setDeleteAtEnd(boolean deleteAtEnd) {
this.deleteAtEnd = deleteAtEnd;
return this;
}
/**
* Adds a sub directory to be managed by the {@link SubDirTestWatcher}.
* @param subDir The relative path of the sub directory to be added.
* @return The {@link SubDirTestWatcher.Builder}.
*/
public Builder addSubDir(Path subDir) {
Preconditions.checkNotNull(subDir);
subDirs.add(subDir);
return this;
}
/**
* Builds a {@link SubDirTestWatcher}.
* @return A configured {@link SubDirTestWatcher}.
*/
public SubDirTestWatcher build() {
Preconditions.checkState(!subDirs.isEmpty(), "The list of subDirs is empty.");
return new SubDirTestWatcher(baseDir, createAtBeginning, deleteAtEnd, subDirs);
}
}
}