Skip to content

Commit

Permalink
Fix issues with @tempdir cleanup mode support
Browse files Browse the repository at this point in the history
- Use correct versions in @SInCE tags and @API declarations
- Add missing @SInCE tags and @API declarations
- Add missing Javadoc
- Fix configuration parameter name for default cleanup mode
- Clarify meaning of DEFAULT cleanup mode
- Improve Javadoc
- Polish tests

See #2729
  • Loading branch information
sbrannen committed Dec 31, 2021
1 parent ef2574c commit 206ef35
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,20 @@
* Enumeration of cleanup modes for a {@code TempDir}.
*
* <p>When a test with a temporary directory completes, it might be useful in
* some cases to be able to view the contents of the directory resulting from
* the test. {@code CleanupMode} allows control of how a {@code TempDir}
* some cases to be able to view the contents of the temporary directory used by
* the test. {@code CleanupMode} allows you to control how a {@code TempDir}
* is cleaned up.
*
* @since 5.4
* @since 5.9
* @see TempDir
*/
@API(status = EXPERIMENTAL, since = "5.4")
@API(status = EXPERIMENTAL, since = "5.9")
public enum CleanupMode {

/**
* Defer to the configured cleanup mode.
* Use the default cleanup mode.
*
* @see TempDir#DEFAULT_CLEANUP_MODE_PROPERTY_NAME
*/
DEFAULT,

Expand All @@ -39,12 +41,13 @@ public enum CleanupMode {
ALWAYS,

/**
* Don't clean up a temporary directory after the test has completed.
* Only clean up a temporary directory if the test completed successfully.
*/
NEVER,
ON_SUCCESS,

/**
* Only clean up a temporary directory if the test completed successfully.
* Never clean up a temporary directory after the test has completed.
*/
ON_SUCCESS
NEVER;

}
Original file line number Diff line number Diff line change
Expand Up @@ -67,22 +67,22 @@
* {@link org.junit.jupiter.api.AfterEach @AfterEach} methods &mdash; each test
* will use its own temporary directory.
*
* <h3>Deletion</h3>
* <h3>Clean Up</h3>
*
* <p>By default, when the end of the scope of a temporary directory is reached,
* i.e. when the test method or class has finished execution, JUnit will attempt
* to recursively delete all files and directories in the temporary directory
* and, finally, the temporary directory itself. In case deletion of a file or
* directory fails, an {@link IOException} will be thrown that will cause the
* test or test class to fail.
* &mdash; when the test method or class has finished execution &mdash; JUnit will
* attempt to clean up the temporary directory by recursively deleting all files
* and directories in the temporary directory and, finally, the temporary directory
* itself. In case deletion of a file or directory fails, an {@link IOException}
* will be thrown that will cause the test or test class to fail.
*
* <p>The {@code @TempDir} annotation has a {@link CleanupMode} parameter that
* allows overriding the default behavior. If the cleanup mode is set to
* {@link CleanupMode#NEVER}, then the temporary directory will not be deleted
* after the test completes. If the cleanup mode is set to
* {@link CleanupMode#ON_SUCCESS}, then the temporary directory will only be
* deleted if the test completes successfully. The default behavior can be
* altered by setting the {@value #DEFAULT_CLEANUP_MODE_PROPERTY_NAME}
* <p>The {@link #cleanup} attribute allows you to configure the {@link CleanupMode}.
* If the cleanup mode is set to {@link CleanupMode#NEVER NEVER}, the temporary
* directory will not be cleaned up after the test completes. If the cleanup mode is
* set to {@link CleanupMode#ON_SUCCESS ON_SUCCESS}, the temporary directory will
* only be cleaned up if the test completes successfully. By default, the
* {@link CleanupMode#ALWAYS ALWAYS} clean up mode will be used, but this can be
* configured globally by setting the {@value #DEFAULT_CLEANUP_MODE_PROPERTY_NAME}
* configuration parameter.
*
* @since 5.4
Expand All @@ -93,11 +93,24 @@
@API(status = EXPERIMENTAL, since = "5.4")
public @interface TempDir {

String DEFAULT_CLEANUP_MODE_PROPERTY_NAME = "junit.jupiter.cleanup.mode.default";
/**
* The name of the configuration parameter that is used to configure the
* default {@link CleanupMode}.
*
* <p>If this configuration parameter is not set, {@link CleanupMode#ALWAYS}
* will be used as the default.
*
* @since 5.9
*/
@API(status = EXPERIMENTAL, since = "5.9")
String DEFAULT_CLEANUP_MODE_PROPERTY_NAME = "junit.jupiter.tempdir.cleanup.mode.default";

/**
* How the temporary directory gets cleaned up after the test completes.
*
* @since 5.9
*/
@API(status = EXPERIMENTAL, since = "5.9")
CleanupMode cleanup() default CleanupMode.DEFAULT;

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
package org.junit.jupiter.engine.extension;

import static java.nio.file.Files.deleteIfExists;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.io.CleanupMode.ALWAYS;
import static org.junit.jupiter.api.io.CleanupMode.NEVER;
import static org.junit.jupiter.api.io.CleanupMode.ON_SUCCESS;
Expand All @@ -31,9 +30,8 @@
import org.opentest4j.TestAbortedException;

/**
* Integration tests for cleanup of the {@link TempDirectory}
* when {@link TempDir} is set to {@link CleanupMode#ALWAYS} or
* {@link CleanupMode#NEVER}.
* Integration tests for cleanup of the {@link TempDirectory} when the {@link CleanupMode} is
* set to {@link CleanupMode#ALWAYS}, {@link CleanupMode#NEVER}, or {@link CleanupMode#ON_SUCCESS}.
*
* @since 5.9
*
Expand All @@ -42,67 +40,65 @@
*/
class CloseablePathCleanupTests extends AbstractJupiterTestEngineTests {

private TempDirectory.CloseablePath path;
private final ExtensionContext extensionContext = mock(ExtensionContext.class);

private TempDirectory.CloseablePath closeablePath;

@AfterEach
void cleanupTempDirectory() throws IOException {
deleteIfExists(path.get());
deleteIfExists(closeablePath.get());
}

/**
* Ensure a closeable path is cleaned up for a cleanup mode of ALWAYS.
*/
@Test
void testAlways() throws IOException {
ExtensionContext extensionContext = mock(ExtensionContext.class);
path = TempDirectory.createTempDir(ALWAYS, extensionContext);
assertTrue(path.get().toFile().exists());
void always() throws IOException {
closeablePath = TempDirectory.createTempDir(ALWAYS, extensionContext);
assertThat(closeablePath.get()).exists();

path.close();
assertFalse(path.get().toFile().exists());
closeablePath.close();
assertThat(closeablePath.get()).doesNotExist();
}

/**
* Ensure a closeable path is not cleaned up for a cleanup mode of NEVER.
*/
@Test
void testNever() throws IOException {
ExtensionContext extensionContext = mock(ExtensionContext.class);
path = TempDirectory.createTempDir(NEVER, extensionContext);
assertTrue(path.get().toFile().exists());
void never() throws IOException {
closeablePath = TempDirectory.createTempDir(NEVER, extensionContext);
assertThat(closeablePath.get()).exists();

path.close();
assertTrue(path.get().toFile().exists());
closeablePath.close();
assertThat(closeablePath.get()).exists();
}

/**
* Ensure a closeable path is not cleaned up for a cleanup mode of ON_SUCCESS, if there is a TestAbortedException.
*/
@Test
void testOnSuccessWithTestAbortedException() throws IOException {
ExtensionContext extensionContext = mock(ExtensionContext.class);
void onSuccessWithTestAbortedException() throws IOException {
when(extensionContext.getExecutionException()).thenReturn(Optional.of(new TestAbortedException()));

path = TempDirectory.createTempDir(ON_SUCCESS, extensionContext);
assertTrue(path.get().toFile().exists());
closeablePath = TempDirectory.createTempDir(ON_SUCCESS, extensionContext);
assertThat(closeablePath.get()).exists();

path.close();
assertTrue(path.get().toFile().exists());
closeablePath.close();
assertThat(closeablePath.get()).exists();
}

/**
* Ensure a closeable path is cleaned up for a cleanup mode of ON_SUCCESS, if there is no exception.
*/
@Test
void testOnSuccessWithNoTestAbortedException() throws IOException {
ExtensionContext extensionContext = mock(ExtensionContext.class);
void onSuccessWithNoTestAbortedException() throws IOException {
when(extensionContext.getExecutionException()).thenReturn(Optional.empty());

path = TempDirectory.createTempDir(ON_SUCCESS, extensionContext);
assertTrue(path.get().toFile().exists());
closeablePath = TempDirectory.createTempDir(ON_SUCCESS, extensionContext);
assertThat(closeablePath.get()).exists();

path.close();
assertFalse(path.get().toFile().exists());
closeablePath.close();
assertThat(closeablePath.get()).doesNotExist();
}

}

0 comments on commit 206ef35

Please sign in to comment.