diff --git a/buildSrc/src/main/java/gov/nasa/ziggy/buildutil/ZiggyCpp.java b/buildSrc/src/main/java/gov/nasa/ziggy/buildutil/ZiggyCpp.java index cc0b395..3813ae5 100644 --- a/buildSrc/src/main/java/gov/nasa/ziggy/buildutil/ZiggyCpp.java +++ b/buildSrc/src/main/java/gov/nasa/ziggy/buildutil/ZiggyCpp.java @@ -7,7 +7,6 @@ import org.gradle.api.Project; import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.OutputFile; -import org.gradle.api.tasks.Input; import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.Input; @@ -30,163 +29,6 @@ * */ public class ZiggyCpp extends DefaultTask { - - /** - * Data and methods used to perform the C++ compile and link. - */ - private ZiggyCppPojo ziggyCppPojo = new ZiggyCppPojo(); - - /** - * Default constructor. Provides the ZiggyCppPojo object with directories for the - * project and default options, if set - */ - public ZiggyCpp() { - Project project = getProject(); - ziggyCppPojo.setBuildDir(project.getBuildDir()); - ziggyCppPojo.setRootDir(pipelineRootDir(project)); - if (project.hasProperty(ZiggyCppPojo.DEFAULT_COMPILE_OPTIONS_GRADLE_PROPERTY)) { - ziggyCppPojo.setCompileOptions(ZiggyCppPojo.gradlePropertyToList( - project.property(ZiggyCppPojo.DEFAULT_COMPILE_OPTIONS_GRADLE_PROPERTY))); - } - if (project.hasProperty(ZiggyCppPojo.DEFAULT_LINK_OPTIONS_GRADLE_PROPERTY)) { - ziggyCppPojo.setLinkOptions(ZiggyCppPojo.gradlePropertyToList( - project.property(ZiggyCppPojo.DEFAULT_LINK_OPTIONS_GRADLE_PROPERTY))); - } - if (project.hasProperty(ZiggyCppPojo.DEFAULT_RELEASE_OPTS_GRADLE_PROPERTY)) { - ziggyCppPojo.setReleaseOptimizations(ZiggyCppPojo.gradlePropertyToList( - project.findProperty(ZiggyCppPojo.DEFAULT_RELEASE_OPTS_GRADLE_PROPERTY))); - } - if (project.hasProperty(ZiggyCppPojo.DEFAULT_DEBUG_OPTS_GRADLE_PROPERTY)) { - ziggyCppPojo.setDebugOptimizations(ZiggyCppPojo.gradlePropertyToList( - project.findProperty(ZiggyCppPojo.DEFAULT_DEBUG_OPTS_GRADLE_PROPERTY))); - } - } - - /** - * Returns the root directory of the pipeline - * @param project Current project - * @return rootDir if the pipelineRootDir project property is not set; if that - * property is set, the contents of the pipelineRootDir property are returned as a File - */ - public static File pipelineRootDir(Project project) { - File pipelineRootDir = null; - if (project.hasProperty(ZiggyCppPojo.PIPELINE_ROOT_DIR_PROP_NAME)) { - pipelineRootDir = new File(project.property( - ZiggyCppPojo.PIPELINE_ROOT_DIR_PROP_NAME).toString()); - } else { - pipelineRootDir = project.getRootDir(); - } - return pipelineRootDir; - } - - /** Provides access to the ZiggyCppPojo action() method for Gradle. */ - @TaskAction - public void action() { - ziggyCppPojo.action(); - } - - /** - * Provides access to the ZiggyCppPojo list of C++ files for Gradle, and - * specifies for gradle that those files are the inputs for this task. - * @return List of C++ files found in the C++ source file directory. - */ - @InputFiles - public List getCppFiles() { - return ziggyCppPojo.getCppFiles(); - } - - /** - * Provides Gradle with access to the ZiggyCppPojo File that will be the final product - * of the build. Also specifies that this file is the output for this task. - * @return File containing the target product for a task. - */ - @OutputFile - public File getBuiltFile() { - return ziggyCppPojo.getBuiltFile(); - } - - // Below are setters and getters for the ZiggyCppPojo members that must be mutated - // by ZiggyCpp tasks in gradle. In principle only setters are needed, but in the - // interest of sanity getters are also provided. Note that not all ZiggyCppPojo - // members need to be set by ZiggyCpp, there are a number that are used internally - // and are not set as part of a task. - // - // Note that the setters take Object and List rather than String and List. - // This is because Gradle allows its text string objects to be either Java String class or - // Groovy GString class. Consequently, we pass everything to ZiggyCppPojo as Objects, and - // ZiggyCppPojo uses the toString() methods to convert everything to Java Strings. - - // Path to the C++ source files - public void setCppFilePaths(List cppFilePaths) { - ziggyCppPojo.setCppFilePaths(cppFilePaths); - } - @Input - public List getCppFilePaths() { - return ziggyCppPojo.getCppFilePaths(); - } - - // Paths for include files - public void setIncludeFilePaths(List includeFilePaths) { - ziggyCppPojo.setIncludeFilePaths(includeFilePaths); - } - @Input - public List getIncludeFilePaths() { - return ziggyCppPojo.getIncludeFilePaths(); - } - - // paths for libraries that must be linked in - public void setLibraryPaths(List libraryPaths) { - ziggyCppPojo.setLibraryPaths(libraryPaths); - } - @Input - public List getLibraryPaths() { - return ziggyCppPojo.getLibraryPaths(); - } - - // Libraries that must be linked in - public void setLibraries(List libraries) { - ziggyCppPojo.setLibraries(libraries); - } - @Input - public List getLibraries() { - return ziggyCppPojo.getLibraries(); - } - - // compiler options - public void setCompileOptions(List compileOptions) { - ziggyCppPojo.setCompileOptions(compileOptions);; - } - @Input - public List getCompileOptions() { - return ziggyCppPojo.getCompileOptions(); - } - - // linker options - public void setLinkOptions(List linkOptions) { - ziggyCppPojo.setLinkOptions(linkOptions); - } - @Input - public List getLinkOptions() { - return ziggyCppPojo.getLinkOptions(); - } - - // output type (executable, shared library, static library) - public void setOutputType(Object outputType) { - ziggyCppPojo.setOutputType(outputType); - } - @Input - public BuildType getOutputType() { - return ziggyCppPojo.getOutputType(); - } - - // Name of file to be produced - public void setOutputName(Object name) { - ziggyCppPojo.setOutputName(name); - } - @Input - public String getOutputName() { - return ziggyCppPojo.getOutputName(); - } /** * Data and methods used to perform the C++ compile and link. diff --git a/doc/user-manual/data-receipt.md b/doc/user-manual/data-receipt.md index 7adbc0d..32b8f57 100644 --- a/doc/user-manual/data-receipt.md +++ b/doc/user-manual/data-receipt.md @@ -18,4 +18,4 @@ Let's fix that now. [[Previous]](delete-tasks.md) [[Up]](user-manual.md) -[[Next]](data-receipt-execution.md) \ No newline at end of file +[[Next]](data-receipt-execution.md) diff --git a/doc/user-manual/delete-tasks.md b/doc/user-manual/delete-tasks.md index 1277715..7133da3 100644 --- a/doc/user-manual/delete-tasks.md +++ b/doc/user-manual/delete-tasks.md @@ -32,4 +32,4 @@ This is the same idea, except it's the pop-up menu for the instance table, and y [[Previous]](rerun-task.md) [[Up]](ziggy-gui-troubleshooting.md) -[[Next]](select-hpc.md)data-receipt.md) +[[Next]](select-hpc.md) diff --git a/doc/user-manual/downloading-and-building-ziggy.md b/doc/user-manual/downloading-and-building-ziggy.md index 62977c1..06e4357 100644 --- a/doc/user-manual/downloading-and-building-ziggy.md +++ b/doc/user-manual/downloading-and-building-ziggy.md @@ -1,4 +1,4 @@ -[Previous] [Up] [Next] + [[Previous]](pipeline-architecture.md) [[Up]](user-manual.md) diff --git a/doc/user-manual/event-handler-examples.md b/doc/user-manual/event-handler-examples.md index 8712289..2b5fad1 100644 --- a/doc/user-manual/event-handler-examples.md +++ b/doc/user-manual/event-handler-examples.md @@ -4,7 +4,7 @@ [[Up]](event-handler.md) [[Next]](event-handler-labels.md) -## Event Handler: Examples +## Event Handler Examples Now that we've looked at the general concept of event handlers, and we've talked about how to define an event handler, let's work through some examples using the sample pipeline. @@ -185,4 +185,3 @@ The first column is the event ID -- this is a simple, monotonically-increasing i [[Previous]](event-handler-definition.md) [[Up]](event-handler.md) [[Next]](event-handler-labels.md) - diff --git a/doc/user-manual/event-handler-intro.md b/doc/user-manual/event-handler-intro.md index d16565c..7b270e5 100644 --- a/doc/user-manual/event-handler-intro.md +++ b/doc/user-manual/event-handler-intro.md @@ -4,7 +4,7 @@ [[Up]](event-handler.md) [[Next]](event-handler-definition.md) -## Event Handler: Introduction +## Introduction to Event Handlers Ziggy's predecessors in the pipeline infrastructure field (the Kepler SOC's PI module and TESS SPOC's Spiffy) were designed to require a lot of in-person handling by pipeline users. In particular, they had no capacity to take actions without somebody, somewhere, issuing a command or pressing a button on the console. @@ -160,5 +160,4 @@ As soon as the pipeline starts, Ziggy deletes the ready files for reeves-gabrels [[Previous]](event-handler.md) [[Up]](event-handler.md) -[[Next]](event-handler-definition.md)event-handler-definition.md) - +[[Next]](event-handler-definition.md)) diff --git a/doc/user-manual/event-handler-labels.md b/doc/user-manual/event-handler-labels.md index 5f3ffc5..e3bd2cc 100644 --- a/doc/user-manual/event-handler-labels.md +++ b/doc/user-manual/event-handler-labels.md @@ -4,7 +4,7 @@ [[Up]](event-handler.md) [[Next]](dusty-corners.md) -## Event Handler: Algorithms +## Sending Event Information to Algorithms The event handler, and all of the information associated with it, is mainly intended for use by Ziggy: Ziggy uses the information to select a pipeline to start, to figure out which data receipt directories it can import, etc. That said, it's possible that event information can be useful to the algorithms as well. In the case when an algorithm runs in a pipeline that got kicked off by an event, there can be some value in giving the algorithm information about the handler and the event. diff --git a/doc/user-manual/remote-dialog.md b/doc/user-manual/remote-dialog.md index 2c93e58..05ffe12 100644 --- a/doc/user-manual/remote-dialog.md +++ b/doc/user-manual/remote-dialog.md @@ -80,4 +80,4 @@ Alternately, you may want to discard all your changes and start over tuning the [[Previous]](select-hpc.md) [[Up]](select-hpc.md) -[[Next]](hpc-cost.md)hpc-cost.md) +[[Next]](hpc-cost.md) diff --git a/src/main/java/gov/nasa/ziggy/data/management/Acknowledgement.java b/src/main/java/gov/nasa/ziggy/data/management/Acknowledgement.java index 3c0086f..3b5c3aa 100644 --- a/src/main/java/gov/nasa/ziggy/data/management/Acknowledgement.java +++ b/src/main/java/gov/nasa/ziggy/data/management/Acknowledgement.java @@ -149,8 +149,7 @@ public static boolean validAcknowledgementExists(Path workingDir, Manifest manif xmlManager = new ValidatingXmlManager<>(Acknowledgement.class); Acknowledgement ack = xmlManager.unmarshal(acknowledgementPath.toFile()); return ack.transferStatus.equals(DataReceiptStatus.VALID); - } catch (InstantiationException | IllegalAccessException | SAXException | JAXBException - | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { + } catch (InstantiationException | IllegalAccessException | SAXException | JAXBException e) { throw new PipelineException( "Unable to read acknowledgement " + acknowledgementPath.toString(), e); } @@ -417,11 +416,11 @@ public int hashCode() { @Override public boolean equals(Object obj) { if (this == obj) { - return true; - } + return true; + } if (obj == null || getClass() != obj.getClass()) { - return false; - } + return false; + } AcknowledgementEntry other = (AcknowledgementEntry) obj; return Objects.equals(name, other.name) && Objects.equals(checksum, other.checksum) && size == other.size && transferStatus == other.transferStatus diff --git a/src/main/java/gov/nasa/ziggy/data/management/Manifest.java b/src/main/java/gov/nasa/ziggy/data/management/Manifest.java index 105ddf2..0136cab 100644 --- a/src/main/java/gov/nasa/ziggy/data/management/Manifest.java +++ b/src/main/java/gov/nasa/ziggy/data/management/Manifest.java @@ -412,11 +412,11 @@ public int hashCode() { @Override public boolean equals(Object obj) { if (this == obj) { - return true; - } + return true; + } if (obj == null || getClass() != obj.getClass()) { - return false; - } + return false; + } ManifestEntry other = (ManifestEntry) obj; return Objects.equals(checksum, other.checksum) && Objects.equals(name, other.name) && size == other.size; diff --git a/src/main/java/gov/nasa/ziggy/module/PipelineInputs.java b/src/main/java/gov/nasa/ziggy/module/PipelineInputs.java index 27726ef..b530eed 100644 --- a/src/main/java/gov/nasa/ziggy/module/PipelineInputs.java +++ b/src/main/java/gov/nasa/ziggy/module/PipelineInputs.java @@ -255,17 +255,11 @@ public void writeSubTaskInputs(int seqNum) { String moduleName = moduleName(); String filename = ModuleInterfaceUtils.inputsFileName(moduleName, seqNum); log.info("Writing file " + filename + " to sub-task directory"); - - // Note: you might think that we shouldn't need this getProperty call when - // constructing the File for use as the inputs file. And you'd be right! The - // problem is that starting in Java 11, changing the user.dir property doesn't - // change the working directory, but does change the value of the system - // property. Thus we need to include its value here so that unit tests work - // correctly. - File f = new File(System.getProperty("user.dir"), ModuleInterfaceUtils.inputsFileName(moduleName, seqNum)); - hdf5ModuleInterface.writeFile( - f, this, - true); + hdf5ModuleInterface.writeFile(DirectoryProperties.workingDir() + .resolve(ModuleInterfaceUtils.inputsFileName(moduleName, seqNum)) + .toFile(), this, true); +// hdf5ModuleInterface.writeFile( +// new File(ModuleInterfaceUtils.inputsFileName(moduleName, seqNum)), this, true); ModuleInterfaceUtils.writeCompanionXmlFile(this, moduleName, seqNum); } diff --git a/src/main/java/gov/nasa/ziggy/util/io/FileUtil.java b/src/main/java/gov/nasa/ziggy/util/io/FileUtil.java index a1df804..b8af79c 100644 --- a/src/main/java/gov/nasa/ziggy/util/io/FileUtil.java +++ b/src/main/java/gov/nasa/ziggy/util/io/FileUtil.java @@ -272,7 +272,7 @@ public static Set modeToPosixFilePermissions(int mode) { */ public static void cleanDirectoryTree(Path directory, boolean force) throws IOException { if (force) { - setPosixPermissionsRecursively(directory, "rw-r--r--", "rwxr-xr-x"); + prepareDirectoryTreeForOverwrites(directory); } try (DirectoryStream stream = Files.newDirectoryStream(directory)) { for (Path file : stream) { diff --git a/src/test/java/gov/nasa/ziggy/ZiggyDirectoryRule.java b/src/test/java/gov/nasa/ziggy/ZiggyDirectoryRule.java index d8bdbf9..eb514b7 100644 --- a/src/test/java/gov/nasa/ziggy/ZiggyDirectoryRule.java +++ b/src/test/java/gov/nasa/ziggy/ZiggyDirectoryRule.java @@ -54,7 +54,7 @@ public Statement apply(Statement statement, Description description) { Files.createDirectories(directory); // Clean the new directory prior to use. - FileUtil.cleanDirectoryTree(directory); + FileUtil.cleanDirectoryTree(directory, true); return new Statement() { @Override diff --git a/src/test/java/gov/nasa/ziggy/data/management/DataFileManagerTest.java b/src/test/java/gov/nasa/ziggy/data/management/DataFileManagerTest.java index ba52c87..75f3b52 100644 --- a/src/test/java/gov/nasa/ziggy/data/management/DataFileManagerTest.java +++ b/src/test/java/gov/nasa/ziggy/data/management/DataFileManagerTest.java @@ -24,7 +24,6 @@ import java.util.TreeSet; import java.util.stream.Collectors; -import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -34,8 +33,8 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; -//import com.google.common.io.Files; +import gov.nasa.ziggy.ZiggyDirectoryRule; import gov.nasa.ziggy.ZiggyPropertyRule; import gov.nasa.ziggy.data.management.DataFileTestUtils.DataFileInfoSample1; import gov.nasa.ziggy.data.management.DataFileTestUtils.DataFileInfoSample2; @@ -46,7 +45,6 @@ import gov.nasa.ziggy.pipeline.definition.PipelineDefinitionNode; import gov.nasa.ziggy.pipeline.definition.PipelineTask; import gov.nasa.ziggy.pipeline.definition.crud.PipelineTaskCrud; -import gov.nasa.ziggy.services.config.PropertyNames; import gov.nasa.ziggy.uow.TaskConfigurationParameters; /** @@ -56,7 +54,7 @@ */ public class DataFileManagerTest { - private String datastoreRoot = new File(Filenames.BUILD_TEST, "datastore").getAbsolutePath(); + private String datastoreRoot; private String taskDirRoot; private String taskDir; private String subtaskDir; @@ -76,7 +74,7 @@ public class DataFileManagerTest { public ZiggyDirectoryRule directoryRule = new ZiggyDirectoryRule(); public ZiggyPropertyRule datastoreRootDirPropertyRule = new ZiggyPropertyRule( - DATASTORE_ROOT_DIR_PROP_NAME, datastoreRoot); + DATASTORE_ROOT_DIR_PROP_NAME, directoryRule, "datastore"); @Rule public ZiggyPropertyRule useSymlinksPropertyRule = new ZiggyPropertyRule(USE_SYMLINKS_PROP_NAME, @@ -101,7 +99,7 @@ public void setup() throws IOException { this.taskDirRoot = taskDirRoot.toString(); makeTaskDir("pa-5-10"); - Path externalTemp = dirRule.testDirPath().resolve("tmp"); + Path externalTemp = directoryRule.directory().resolve("tmp"); Files.createDirectories(externalTemp); externalTempDir = externalTemp.toAbsolutePath().toString(); @@ -131,17 +129,6 @@ public void setup() throws IOException { DataFileTestUtils.initializeDataFileTypeSamples(); } - @After - public void teardown() throws InterruptedException, IOException { - // NB: execution is so fast that some deleteDirectory commands fail because - // (apparently) write-locks have not yet had time to release! Address this by - // adding a short nap. - Thread.sleep(10); - FileUtils.deleteDirectory(new File(taskDirRoot)); - FileUtil.setPosixPermissionsRecursively(new File(datastoreRoot).toPath(), "rwxrwxrwx"); - FileUtils.forceDelete(new File(Filenames.BUILD_TEST)); - } - private void makeTaskDir(String taskDirName) { File taskDir = new File(taskDirRoot, taskDirName); taskDir.mkdirs(); diff --git a/src/test/java/gov/nasa/ziggy/data/management/DataFileTypeImporterTest.java b/src/test/java/gov/nasa/ziggy/data/management/DataFileTypeImporterTest.java index 0daa234..c7972a9 100644 --- a/src/test/java/gov/nasa/ziggy/data/management/DataFileTypeImporterTest.java +++ b/src/test/java/gov/nasa/ziggy/data/management/DataFileTypeImporterTest.java @@ -13,6 +13,8 @@ import com.google.common.collect.ImmutableList; +import gov.nasa.ziggy.ZiggyPropertyRule; +import gov.nasa.ziggy.pipeline.definition.ModelType; import gov.nasa.ziggy.pipeline.definition.crud.DataFileTypeCrud; import gov.nasa.ziggy.pipeline.definition.crud.ModelCrud; import gov.nasa.ziggy.services.config.DirectoryProperties; @@ -55,10 +57,11 @@ public void testBasicImport() throws JAXBException { importerSpy.importFromFiles(); assertEquals(6, importerSpy.getDataFileImportedCount()); - Mockito.verify(dataFileTypeCrud, Mockito.times(1)).create(ArgumentMatchers.anyList()); + Mockito.verify(dataFileTypeCrud, Mockito.times(1)) + .create(ArgumentMatchers. anyList()); assertEquals(2, importerSpy.getModelFileImportedCount()); - Mockito.verify(modelCrud, Mockito.times(1)).create(ArgumentMatchers.anyList()); + Mockito.verify(modelCrud, Mockito.times(1)).create(ArgumentMatchers. anyList()); } @@ -74,9 +77,10 @@ public void testDryRun() throws JAXBException { importerSpy.importFromFiles(); assertEquals(6, importerSpy.getDataFileImportedCount()); - Mockito.verify(dataFileTypeCrud, Mockito.times(0)).create(ArgumentMatchers.anyList()); + Mockito.verify(dataFileTypeCrud, Mockito.times(0)) + .create(ArgumentMatchers. anyList()); assertEquals(2, importerSpy.getModelFileImportedCount()); - Mockito.verify(modelCrud, Mockito.times(0)).create(ArgumentMatchers.anyList()); + Mockito.verify(modelCrud, Mockito.times(0)).create(ArgumentMatchers. anyList()); } // Test with missing and non-regular files -- should still import from the present, @@ -92,7 +96,8 @@ public void testWithInvalidFiles() throws JAXBException { importerSpy.importFromFiles(); assertEquals(6, importerSpy.getDataFileImportedCount()); - Mockito.verify(dataFileTypeCrud, Mockito.times(1)).create(ArgumentMatchers.anyList()); + Mockito.verify(dataFileTypeCrud, Mockito.times(1)) + .create(ArgumentMatchers. anyList()); } // Test with a file that has an entry that is valid XML but instantiates to an @@ -108,7 +113,8 @@ public void testWithInvalidDataFileType() throws JAXBException { importerSpy.importFromFiles(); assertEquals(5, importerSpy.getDataFileImportedCount()); - Mockito.verify(dataFileTypeCrud, Mockito.times(1)).create(ArgumentMatchers.anyList()); + Mockito.verify(dataFileTypeCrud, Mockito.times(1)) + .create(ArgumentMatchers. anyList()); } // Test with a file that has an entry that is invalid XML @@ -123,7 +129,8 @@ public void testWithInvalidDataXml() throws JAXBException { importerSpy.importFromFiles(); assertEquals(5, importerSpy.getDataFileImportedCount()); - Mockito.verify(dataFileTypeCrud, Mockito.times(1)).create(ArgumentMatchers.anyList()); + Mockito.verify(dataFileTypeCrud, Mockito.times(1)) + .create(ArgumentMatchers. anyList()); } @Test(expected = IllegalStateException.class) diff --git a/src/test/java/gov/nasa/ziggy/data/management/DataReceiptPipelineModuleTest.java b/src/test/java/gov/nasa/ziggy/data/management/DataReceiptPipelineModuleTest.java index 410e7e9..d951141 100644 --- a/src/test/java/gov/nasa/ziggy/data/management/DataReceiptPipelineModuleTest.java +++ b/src/test/java/gov/nasa/ziggy/data/management/DataReceiptPipelineModuleTest.java @@ -29,8 +29,10 @@ import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.RuleChain; import org.mockito.ArgumentMatchers; import org.mockito.Mockito; import org.xml.sax.SAXException; @@ -38,6 +40,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import gov.nasa.ziggy.ZiggyDirectoryRule; import gov.nasa.ziggy.ZiggyPropertyRule; import gov.nasa.ziggy.collections.ZiggyDataType; import gov.nasa.ziggy.data.management.DatastoreProducerConsumer.DataReceiptFileType; @@ -71,12 +74,10 @@ public class DataReceiptPipelineModuleTest { private PipelineTask pipelineTask = Mockito.mock(PipelineTask.class); - private Path dataImporterPath = Paths.get(System.getProperty("user.dir"), "build", "test", - "data-import"); + private Path dataImporterPath; private Path dataImporterSubdirPath; private Path modelImporterSubdirPath; - private Path datastoreRootPath = Paths.get(System.getProperty("user.dir"), "build", "test", - "datastore"); + private Path datastoreRootPath; private UnitOfWork singleUow = new UnitOfWork(); private UnitOfWork dataSubdirUow = new UnitOfWork(); private UnitOfWork modelSubdirUow = new UnitOfWork(); @@ -88,17 +89,17 @@ public class DataReceiptPipelineModuleTest { public ZiggyDirectoryRule directoryRule = new ZiggyDirectoryRule(); public ZiggyPropertyRule dataReceiptDirPropertyRule = new ZiggyPropertyRule( - DATA_RECEIPT_DIR_PROP_NAME, dataImporterPath.toString()); + DATA_RECEIPT_DIR_PROP_NAME, directoryRule, "data-import"); public ZiggyPropertyRule datastoreRootDirPropertyRule = new ZiggyPropertyRule( - DATASTORE_ROOT_DIR_PROP_NAME, datastoreRootPath.toString()); + DATASTORE_ROOT_DIR_PROP_NAME, directoryRule, "datastore"); @Rule public ZiggyPropertyRule pipelineHomeDirPropertyRule = new ZiggyPropertyRule( PIPELINE_HOME_DIR_PROP_NAME, (String) null); public ZiggyPropertyRule resultsDirPropertyRule = new ZiggyPropertyRule(RESULTS_DIR_PROP_NAME, - Paths.get(System.getProperty("user.dir"), "build", "test").toString()); + directoryRule); @Rule public ZiggyPropertyRule useSymlinksPropertyRule = new ZiggyPropertyRule(USE_SYMLINKS_PROP_NAME, @@ -124,7 +125,9 @@ public void setUp() throws IOException { DataFileTestUtils.initializeDataFileTypeSamples(); // Construct the necessary directories. + dataImporterPath = Paths.get(dataReceiptDirPropertyRule.getProperty()); dataImporterPath.toFile().mkdirs(); + datastoreRootPath = Paths.get(datastoreRootDirPropertyRule.getProperty()); datastoreRootPath.toFile().mkdirs(); dataImporterSubdirPath = dataImporterPath.resolve("sub-dir"); dataImporterSubdirPath.toFile().mkdirs(); @@ -174,19 +177,6 @@ public void setUp() throws IOException { public void shutDown() throws InterruptedException, IOException { Thread.interrupted(); execThread.shutdownNow(); - // NB: execution is so fast that some deleteDirectory commands fail because - // (apparently) write-locks have not yet had time to release! Address this by - // adding a short nap. - Thread.sleep(10); - FileUtil.setPosixPermissionsRecursively(datastoreRootPath, "rwxrwxrwx"); - FileUtil.setPosixPermissionsRecursively(dataImporterPath, "rwxrwxrwx"); - FileUtils.forceDelete(datastoreRootPath.toFile()); - FileUtils.forceDelete(dataImporterPath.getParent().toFile()); - if (Files.exists(DirectoryProperties.manifestsDir())) { - FileUtil.setPosixPermissionsRecursively(DirectoryProperties.manifestsDir(), - "rwxrwxrwx"); - FileUtils.forceDelete(DirectoryProperties.manifestsDir().toFile()); - } AlertService.setInstance(null); } @@ -633,7 +623,7 @@ public void testCleanupFailOnNonEmptyDir() throws IOException, InstantiationExce public void testInterruptInAlgorithm() throws IOException, InstantiationException, IllegalAccessException, SAXException, InterruptedException, JAXBException, IllegalArgumentException, InvocationTargetException, - NoSuchMethodException, SecurityException { + NoSuchMethodException, SecurityException, ExecutionException { // Populate the models setUpModelsForImport(dataImporterPath); diff --git a/src/test/java/gov/nasa/ziggy/module/AlgorithmMonitorTest.java b/src/test/java/gov/nasa/ziggy/module/AlgorithmMonitorTest.java index bc97cf9..f7e3d57 100644 --- a/src/test/java/gov/nasa/ziggy/module/AlgorithmMonitorTest.java +++ b/src/test/java/gov/nasa/ziggy/module/AlgorithmMonitorTest.java @@ -12,6 +12,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.RuleChain; import org.mockito.ArgumentMatchers; import org.mockito.Mockito; @@ -176,7 +177,7 @@ public void testExecutionFailed() stateFile.setNumFailed(5); stateFile.persist(); Mockito.when(jobMonitor.isFinished(ArgumentMatchers.any(StateFile.class))).thenReturn(true); - Thread.sleep(210L); + iterateAlgorithmMonitorRunMethod(3); // No state file remains in the monitoring system. assertNull(monitor.getStateFile(stateFile)); diff --git a/src/test/java/gov/nasa/ziggy/pipeline/xml/ValidatingXmlManagerTest.java b/src/test/java/gov/nasa/ziggy/pipeline/xml/ValidatingXmlManagerTest.java index 3ef5842..9b5c9fd 100644 --- a/src/test/java/gov/nasa/ziggy/pipeline/xml/ValidatingXmlManagerTest.java +++ b/src/test/java/gov/nasa/ziggy/pipeline/xml/ValidatingXmlManagerTest.java @@ -14,8 +14,7 @@ import gov.nasa.ziggy.ZiggyPropertyRule; import gov.nasa.ziggy.pipeline.definition.PipelineDefinitionFile; -import gov.nasa.ziggy.services.config.PropertyNames; -import gov.nasa.ziggy.util.io.Filenames; +import gov.nasa.ziggy.services.config.DirectoryProperties; import jakarta.xml.bind.JAXBException; import jakarta.xml.bind.UnmarshalException; diff --git a/src/test/java/gov/nasa/ziggy/services/events/ZiggyEventHandlerTest.java b/src/test/java/gov/nasa/ziggy/services/events/ZiggyEventHandlerTest.java index 4c6befc..9ebd7de 100644 --- a/src/test/java/gov/nasa/ziggy/services/events/ZiggyEventHandlerTest.java +++ b/src/test/java/gov/nasa/ziggy/services/events/ZiggyEventHandlerTest.java @@ -33,6 +33,7 @@ import com.google.common.collect.Sets; import gov.nasa.ziggy.ZiggyDatabaseRule; +import gov.nasa.ziggy.ZiggyDirectoryRule; import gov.nasa.ziggy.ZiggyPropertyRule; import gov.nasa.ziggy.data.management.DataFileTypeImporter; import gov.nasa.ziggy.data.management.DataReceiptPipelineModule; @@ -61,7 +62,6 @@ import gov.nasa.ziggy.uow.DirectoryUnitOfWorkGenerator; import gov.nasa.ziggy.uow.UnitOfWork; import gov.nasa.ziggy.uow.UnitOfWorkGenerator; -import gov.nasa.ziggy.util.io.Filenames; import jakarta.xml.bind.JAXBException; /** @@ -83,6 +83,20 @@ public class ZiggyEventHandlerTest { private PipelineOperations pipelineOperations = Mockito.spy(PipelineOperations.class); private PipelineExecutor pipelineExecutor = Mockito.spy(PipelineExecutor.class); + @Rule + public ZiggyDirectoryRule directoryRule = new ZiggyDirectoryRule(); + + @Rule + public ZiggyDatabaseRule databaseRule = new ZiggyDatabaseRule(); + + @Rule + public ZiggyPropertyRule ziggyHomeDirPropertyRule = new ZiggyPropertyRule( + ZIGGY_HOME_DIR_PROP_NAME, DirectoryProperties.ziggyCodeBuildDir().toString()); + + @Rule + public ZiggyPropertyRule dataReceiptDirPropertyRule = new ZiggyPropertyRule( + DATA_RECEIPT_DIR_PROP_NAME, TEST_DATA_DIR); + @Before public void setUp() throws IOException { testDataDir = directoryRule.directory().resolve(TEST_DATA_DIR); @@ -256,7 +270,7 @@ public void testStartPipeline() throws IOException, InterruptedException { // Re-create the ready-indicator file to see that the pipeline gets // fired again Files.createFile(readyIndicator1); - Thread.sleep(240L); + ziggyEventHandler.run(); events = (List) DatabaseTransactionFactory .performTransaction(() -> new ZiggyEventCrud().retrieveAllEvents()); assertEquals(2, events.size()); @@ -311,7 +325,6 @@ public void testExceptionInRunnable() throws IOException, InterruptedException { // The ready-indicator file should still be present and the event handler should // be disabled assertTrue(Files.exists(readyIndicator1)); - Thread.sleep(50L); assertFalse(ziggyEventHandler.isRunning()); } diff --git a/src/test/java/gov/nasa/ziggy/services/messaging/MessageHandlersForTest.java b/src/test/java/gov/nasa/ziggy/services/messaging/MessageHandlersForTest.java index cef71a9..1de8475 100644 --- a/src/test/java/gov/nasa/ziggy/services/messaging/MessageHandlersForTest.java +++ b/src/test/java/gov/nasa/ziggy/services/messaging/MessageHandlersForTest.java @@ -8,10 +8,10 @@ import gov.nasa.ziggy.services.messages.PipelineMessage; import gov.nasa.ziggy.services.messages.WorkerShutdownMessage; -import gov.nasa.ziggy.ui.cli.ClusterController; +import gov.nasa.ziggy.ui.ClusterController; import gov.nasa.ziggy.ui.common.ProcessHeartbeatManager; import gov.nasa.ziggy.ui.common.ProcessHeartbeatManager.HeartbeatManagerExternalMethods; -import gov.nasa.ziggy.ui.messaging.PigMessageDispatcher; +import gov.nasa.ziggy.ui.messaging.ConsoleMessageDispatcher; import gov.nasa.ziggy.ui.mon.alerts.AlertMessageTableModel; import gov.nasa.ziggy.ui.mon.master.Indicator; import gov.nasa.ziggy.ui.mon.master.WorkerStatusPanel; @@ -21,7 +21,6 @@ * Assorted message handling classes for testing purposes. * * @author PT - * */ public class MessageHandlersForTest { diff --git a/src/test/java/gov/nasa/ziggy/services/messaging/RmiInterProcessCommunicationTest.java b/src/test/java/gov/nasa/ziggy/services/messaging/RmiInterProcessCommunicationTest.java index 6a8401a..75a30ce 100644 --- a/src/test/java/gov/nasa/ziggy/services/messaging/RmiInterProcessCommunicationTest.java +++ b/src/test/java/gov/nasa/ziggy/services/messaging/RmiInterProcessCommunicationTest.java @@ -1,6 +1,5 @@ package gov.nasa.ziggy.services.messaging; -import static gov.nasa.ziggy.services.config.PropertyNames.HEARTBEAT_INTERVAL_PROP_NAME; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -25,8 +24,8 @@ import gov.nasa.ziggy.TestEventDetector; import gov.nasa.ziggy.ZiggyDirectoryRule; import gov.nasa.ziggy.services.messaging.MessageHandlersForTest.ClientSideMessageHandlerForTest; +import gov.nasa.ziggy.services.messaging.MessageHandlersForTest.ConsoleMessageDispatcherForTest; import gov.nasa.ziggy.services.messaging.MessageHandlersForTest.InstrumentedWorkerHeartbeatManager; -import gov.nasa.ziggy.services.messaging.MessageHandlersForTest.PigMessageDispatcherForTest; import gov.nasa.ziggy.ui.common.ProcessHeartbeatManager; import gov.nasa.ziggy.util.os.ProcessUtils; @@ -108,7 +107,8 @@ public void testInterProcessCommunication() throws IOException, InterruptedExcep ClientSideMessageHandlerForTest messageHandler = (ClientSideMessageHandlerForTest) UiCommunicator .getMessageHandler(); - TestEventDetector.detectTestEvent(1000L, () -> (messageHandler.getMessagesFromServer().size() > 0)); + TestEventDetector.detectTestEvent(1000L, + () -> messageHandler.getMessagesFromServer().size() > 0); Set messagesFromServer = messageHandler.getMessagesFromServer(); assertEquals(1, messagesFromServer.size()); } diff --git a/src/test/java/gov/nasa/ziggy/services/messaging/RmiIntraProcessCommunicationTest.java b/src/test/java/gov/nasa/ziggy/services/messaging/RmiIntraProcessCommunicationTest.java index f226d54..b15dfdb 100644 --- a/src/test/java/gov/nasa/ziggy/services/messaging/RmiIntraProcessCommunicationTest.java +++ b/src/test/java/gov/nasa/ziggy/services/messaging/RmiIntraProcessCommunicationTest.java @@ -1,6 +1,5 @@ package gov.nasa.ziggy.services.messaging; -import static gov.nasa.ziggy.services.config.PropertyNames.HEARTBEAT_INTERVAL_PROP_NAME; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -25,6 +24,7 @@ import gov.nasa.ziggy.TestEventDetector; import gov.nasa.ziggy.services.messages.WorkerHeartbeatMessage; import gov.nasa.ziggy.services.messaging.MessageHandlersForTest.ClientSideMessageHandlerForTest; +import gov.nasa.ziggy.services.messaging.MessageHandlersForTest.ConsoleMessageDispatcherForTest; import gov.nasa.ziggy.services.messaging.MessageHandlersForTest.InstrumentedWorkerHeartbeatManager; import gov.nasa.ziggy.services.messaging.MessageHandlersForTest.ServerSideMessageHandlerForTest; import gov.nasa.ziggy.ui.common.ProcessHeartbeatManager; @@ -118,7 +118,7 @@ public void testReinitializeWorker() throws InterruptedException { ClientSideMessageHandlerForTest msg = (ClientSideMessageHandlerForTest) UiCommunicator .getMessageHandler(); final ClientSideMessageHandlerForTest msgFinal = msg; - TestEventDetector.detectTestEvent(1000L, () -> (msgFinal.getMessagesFromServer().size() > 0)); + TestEventDetector.detectTestEvent(1000L, () -> msgFinal.getMessagesFromServer().size() > 0); assertEquals(1, msg.getMessagesFromServer().size()); // Emulate a worker crashing and coming back by resetting it and running the @@ -133,7 +133,8 @@ public void testReinitializeWorker() throws InterruptedException { // IRL, the UiCommunicator will be restarted by the heartbeat monitor, but since // we're not using that here we have to manually restart it UiCommunicator.restart(); - TestEventDetector.detectTestEvent(1000L, () -> (WorkerCommunicator.getClientMessageServiceStubs().size() > 0)); + TestEventDetector.detectTestEvent(1000L, + () -> WorkerCommunicator.getClientMessageServiceStubs().size() > 0); // Now the worker should have a MessageHandlerService from the UiCommunicator assertEquals(1, WorkerCommunicator.getClientMessageServiceStubs().size()); @@ -142,7 +143,8 @@ public void testReinitializeWorker() throws InterruptedException { WorkerCommunicator.broadcast(new MessageFromServer("zing!")); msg = (ClientSideMessageHandlerForTest) UiCommunicator.getMessageHandler(); final ClientSideMessageHandlerForTest msgFinal2 = msg; - TestEventDetector.detectTestEvent(1000L, () -> (msgFinal2.getMessagesFromServer().size() > 0)); + TestEventDetector.detectTestEvent(1000L, + () -> msgFinal2.getMessagesFromServer().size() > 0); assertEquals(2, msg.getMessagesFromServer().size()); ServerSideMessageHandlerForTest msg2 = (ServerSideMessageHandlerForTest) WorkerCommunicator .getMessageHandler(); @@ -167,7 +169,7 @@ public void testReinitializeUi() throws InterruptedException { ClientSideMessageHandlerForTest msg = (ClientSideMessageHandlerForTest) UiCommunicator .getMessageHandler(); final ClientSideMessageHandlerForTest msgFinal = msg; - TestEventDetector.detectTestEvent(1000L, () -> (msgFinal.getMessagesFromServer().size() > 0)); + TestEventDetector.detectTestEvent(1000L, () -> msgFinal.getMessagesFromServer().size() > 0); assertEquals(1, msg.getMessagesFromServer().size()); // Emulate the shutdown of a UI by resetting the existing one @@ -177,14 +179,16 @@ public void testReinitializeUi() throws InterruptedException { UiCommunicator.setHeartbeatManager(heartbeatManager); UiCommunicator.initializeInstance(messageHandler2, port); UiCommunicator.stopHeartbeatListener(); - TestEventDetector.detectTestEvent(1000L, () -> (WorkerCommunicator.getClientMessageServiceStubs().size() >= 2)); + TestEventDetector.detectTestEvent(1000L, + () -> WorkerCommunicator.getClientMessageServiceStubs().size() >= 2); // there should now be 2 client services in the worker assertEquals(2, WorkerCommunicator.getClientMessageServiceStubs().size()); // broadcast a message assertEquals(1, messageHandler2.getMessagesFromServer().size()); WorkerCommunicator.broadcast(new MessageFromServer("zing!")); - TestEventDetector.detectTestEvent(1000L, () -> (messageHandler2.getMessagesFromServer().size() >= 2)); + TestEventDetector.detectTestEvent(1000L, + () -> messageHandler2.getMessagesFromServer().size() >= 2); assertEquals(2, messageHandler2.getMessagesFromServer().size()); // the UI should be able to communicate with the worker as well @@ -259,7 +263,7 @@ public void testHeartbeatManagement() throws InterruptedException, IOException { // Start the heartbeat manager and communicator MessageHandler messageHandler = new MessageHandler( - new PigMessageDispatcherForTest(null, null, false)); + new ConsoleMessageDispatcherForTest(null, null, false)); InstrumentedWorkerHeartbeatManager h = new InstrumentedWorkerHeartbeatManager( messageHandler); UiCommunicator.setHeartbeatManager(h); @@ -312,18 +316,4 @@ public void testHeartbeatManagement() throws InterruptedException, IOException { } } - public static class PigMessageDispatcherForTest extends PigMessageDispatcher { - - public PigMessageDispatcherForTest(AlertMessageTableModel tableModel, WorkerStatusPanel statusPanel, - boolean shutdownEnabled) { - super(tableModel, statusPanel, shutdownEnabled); - } - - @Override - public void handleShutdownMessage(WorkerShutdownMessage message) { - - } - - } - } diff --git a/src/test/java/gov/nasa/ziggy/util/io/FileUtilTest.java b/src/test/java/gov/nasa/ziggy/util/io/FileUtilTest.java index 797f325..405a721 100644 --- a/src/test/java/gov/nasa/ziggy/util/io/FileUtilTest.java +++ b/src/test/java/gov/nasa/ziggy/util/io/FileUtilTest.java @@ -8,6 +8,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -15,13 +16,13 @@ import java.nio.file.attribute.PosixFilePermissions; import java.util.Map; +import org.apache.commons.io.FileUtils; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import gov.nasa.ziggy.ZiggyDirectoryRule; import gov.nasa.ziggy.ZiggyPropertyRule; -import gov.nasa.ziggy.ZiggyUnitTestUtils; /** * Tests the {@link FileUtil} class. @@ -29,11 +30,11 @@ * @author Bill Wohler */ public class FileUtilTest { - private Path testDir; - private Path archiveDir; - private Path testRegularFile; - private Path testSubdir; - private Path testSubdirRegularFile; + private File testDir; + private File archiveDir; + private File testRegularFile; + private File testSubdir; + private File testSubdirRegularFile; @Rule public ZiggyDirectoryRule directoryRule = new ZiggyDirectoryRule(); @@ -48,38 +49,42 @@ public class FileUtilTest { @Before public void setUp() throws IOException { - testDir = directoryRule.directory(); - archiveDir = testDir.resolve("testTar"); - Files.createDirectories(archiveDir); - testRegularFile = testDir.resolve("regular-file.txt"); - Files.createFile(testRegularFile); - testSubdir = testDir.resolve("sub-dir"); - Files.createDirectories(testSubdir); - testSubdirRegularFile = testSubdir.resolve("another-regular-file.txt"); - Files.createFile(testSubdirRegularFile); + testDir = directoryRule.directory().toFile(); + testDir.mkdir(); + archiveDir = new File(testDir, "testTar"); + archiveDir.mkdir(); + testRegularFile = new File(testDir, "regular-file.txt"); + FileUtils.touch(testRegularFile); + testSubdir = new File(testDir, "sub-dir"); + testSubdir.mkdir(); + testSubdirRegularFile = new File(testSubdir, "another-regular-file.txt"); + FileUtils.touch(testSubdirRegularFile); } @Test public void testRegularFilesInDirTree() throws IOException { // Get a file to find size of - Path testDirPath = testDir; - Path testSrcFile = ZiggyUnitTestUtils.TEST_DATA.resolve("configuration") - .resolve("pipeline-definition.xml"); - Path testFile = testDir.resolve("pipeline-definition.xml"); + Path testDirPath = testDir.toPath(); + Path testSubdirPath = testSubdir.toPath(); + Path codeRoot = Paths.get(System.getProperty("user.dir")); + Path testSrcFile = codeRoot + .resolve(Paths.get("test", "data", "configuration", "pipeline-definition.xml")); + Path testFile = testDir.toPath().resolve("pipeline-definition.xml"); Files.copy(testSrcFile, testFile); // Real file in a subdirectory - Path subDirTestFile = testSubdir.resolve(Paths.get("pipeline-definition.xml")); + new File(testDir, "sub-dir").mkdirs(); + Path subDirTestFile = testSubdirPath.resolve(Paths.get("pipeline-definition.xml")); Files.copy(testSrcFile, subDirTestFile); // Symlinked file in a real directory - Files.createSymbolicLink(testSubdir.resolve(Paths.get("pipeline-definition-symlink.xml")), - testSrcFile); + Files.createSymbolicLink( + testSubdirPath.resolve(Paths.get("pipeline-definition-symlink.xml")), testSrcFile); // Symbolic link to a directory Path symlinkSubdir = testDirPath.resolve(Paths.get("symlink-sub-dir")); - Files.createSymbolicLink(symlinkSubdir, testSubdir.toAbsolutePath()); + Files.createSymbolicLink(symlinkSubdir, testSubdirPath.toAbsolutePath()); Map regularFiles = FileUtil.regularFilesInDirTree(testDirPath); assertEquals(8, regularFiles.size()); @@ -89,14 +94,14 @@ public void testRegularFilesInDirTree() throws IOException { assertNotNull(valuePath); assertEquals(testFile.toAbsolutePath(), valuePath); - valuePath = regularFiles.get(testDirPath.relativize(testRegularFile)); + valuePath = regularFiles.get(testDirPath.relativize(testRegularFile.toPath())); assertNotNull(valuePath); - assertEquals(testRegularFile.toAbsolutePath(), valuePath); + assertEquals(testRegularFile.toPath().toAbsolutePath(), valuePath); // sub-dir directory - valuePath = regularFiles.get(testDirPath.relativize(testSubdirRegularFile)); + valuePath = regularFiles.get(testDirPath.relativize(testSubdirRegularFile.toPath())); assertNotNull(valuePath); - assertEquals(testSubdirRegularFile.toAbsolutePath(), valuePath); + assertEquals(testSubdirRegularFile.toPath().toAbsolutePath(), valuePath); valuePath = regularFiles.get(testDirPath.relativize(subDirTestFile)); assertNotNull(valuePath); @@ -149,12 +154,12 @@ public void testSetPosixPermissionsRecursively() throws IOException { // Set permissions restrictively assertNotEquals("r-x------", - PosixFilePermissions.toString(Files.getPosixFilePermissions(testDir))); - FileUtil.setPosixPermissionsRecursively(testDir, "r--------", "r-x------"); + PosixFilePermissions.toString(Files.getPosixFilePermissions(testDir.toPath()))); + FileUtil.setPosixPermissionsRecursively(testDir.toPath(), "r--------", "r-x------"); assertEquals("r-x------", - PosixFilePermissions.toString(Files.getPosixFilePermissions(testDir))); + PosixFilePermissions.toString(Files.getPosixFilePermissions(testDir.toPath()))); assertEquals("r-x------", - PosixFilePermissions.toString(Files.getPosixFilePermissions(testSubdir))); + PosixFilePermissions.toString(Files.getPosixFilePermissions(testSubdir.toPath()))); assertEquals("r--------", PosixFilePermissions.toString(Files.getPosixFilePermissions(testRegularFile.toPath()))); assertEquals("r--------", PosixFilePermissions @@ -203,9 +208,9 @@ public void testReadOnlyPermissions() throws IOException { @Test public void testCleanDirectoryTree() throws IOException { - FileUtil.cleanDirectoryTree(testDir); - assertTrue(Files.isDirectory(testDir)); - assertFalse(Files.exists(archiveDir)); - assertFalse(Files.exists(testSubdir)); + FileUtil.cleanDirectoryTree(testDir.toPath()); + assertTrue(testDir.exists()); + assertFalse(archiveDir.exists()); + assertFalse(testSubdir.exists()); } }