Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/temp dir cleanup #2729

Merged
merged 57 commits into from Nov 29, 2021
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
71d885e
Add TempDirCleanupStrategy, and plumb into config, and tests.
Sep 25, 2021
b90db93
Fix style problem
Sep 25, 2021
dca9fca
Fix style problem
Sep 25, 2021
900ec13
Set a default value for the cleanup mode of ALWAYS
Sep 25, 2021
5c6028c
Rename to TempDirStrategy to provide for more potential flexibility o…
Sep 25, 2021
d295303
Spotless fix of * imports
Sep 25, 2021
2242f47
Spotless fix of indentation
Sep 25, 2021
3019634
Spotless fix of indentation
Sep 25, 2021
313fd6b
Spotless fix of indentation
Sep 25, 2021
e596f0b
Spotless fix of indentation
Sep 25, 2021
118ffe7
Get Always and Never tests passing
Sep 25, 2021
ed98bc1
Spotless fix of indentation
Sep 25, 2021
476ba11
Spotless fix of indentation
Sep 25, 2021
099aed9
Move to version 5.9
Sep 26, 2021
ede3aee
Prevent TempDirStrategy annotations from being added to inner classes…
Sep 26, 2021
4934c90
Allow TempDirStrategy annotations from being added to inner classes, …
Sep 26, 2021
5209310
Remove ON_SUCCESS cleanup mode, and add demo test for documentation
Sep 26, 2021
73821e6
Add lifecycle tests for temp directory cleanup in different modes
Sep 26, 2021
bbfdf18
Add lifecycle tests for temp directory cleanup of nested tests
Sep 26, 2021
87e2be1
Add documentation for TempDirStrategy
Sep 26, 2021
2c63046
Use static imports of CleanupMode
Sep 26, 2021
29e4d0e
Apply spotless corrections
Sep 26, 2021
a15cae6
Documentation of the cleanup.mode.default configuration parameter
Sep 26, 2021
eafc5c1
Documentation; configuration parameters link
Sep 26, 2021
1fc600c
Fix @API problem
Sep 26, 2021
4dcaef5
Fix @API problem
Sep 26, 2021
5b09b66
Move to CleanupMode parameter in TempDir.
Nov 7, 2021
90d2a75
Typo
Nov 7, 2021
f9e67f6
Make CloseablePath responsive to ON_SUCCESS, and unit test.
Nov 7, 2021
13abd0d
Set cleanup mode for injected TempDir fields, and tests.
Nov 8, 2021
6ce9387
Rename
Nov 8, 2021
e6363b7
Add API annotation to CleanupMode
Nov 8, 2021
bf1fdf4
Spotless
Nov 8, 2021
47a9655
Use configured cleanup mode if none defined.
Nov 8, 2021
5e8c72e
Final polish
Nov 13, 2021
825991a
Address easy parts of review changes
Nov 13, 2021
da487dc
AnnotationSupport fix
Nov 13, 2021
056f08d
Better parameter resolution, and test.
Nov 13, 2021
5b4451c
Inject and use JupiterConfiguration
Nov 14, 2021
0fa4415
Move DEFAULT_TEST_CLASS_ORDER_PROPERTY_NAME
Nov 14, 2021
90eeee2
Move DEFAULT_TEST_CLASS_ORDER_PROPERTY_NAME
Nov 14, 2021
38ef09f
Fix accidental class rename, and update release documentation.
Nov 15, 2021
66cec30
Move TempDirectory out of stateless extension list.
Nov 15, 2021
66577d9
Cleanup test directories.
Nov 15, 2021
05afc2b
Add TempDir parameter tests.
Nov 15, 2021
33cd7e6
Rework TempDirectoryParameterResolverTests using AbstractJupiterTestE…
Nov 18, 2021
56118f0
Retrigger build.
Nov 18, 2021
c32ccba
Retrigger build.
Nov 19, 2021
a18d400
Use nio for safer deletes.
Nov 22, 2021
05b5f17
Update documentation/src/docs/asciidoc/release-notes/release-notes-5.…
Nov 29, 2021
1311ce0
Update documentation/src/docs/asciidoc/user-guide/writing-tests.adoc
Nov 29, 2021
9894363
Update documentation/src/docs/asciidoc/user-guide/writing-tests.adoc
Nov 29, 2021
7b6a36d
Update junit-jupiter-engine/src/test/java/org/junit/jupiter/engine/ex…
Nov 29, 2021
32f9094
Simplify parameter directory deletion.
Nov 29, 2021
682463e
Simplify closeable path deletion.
Nov 29, 2021
55aabfe
Clean up the temp directory after use.
Nov 29, 2021
85493ee
Rerun build.
Nov 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,6 @@ GitHub.

==== New Features and Improvements

* ❓
* `@TempDir` now includes a cleanup mode attribute for preventing a temporary directory
from being deleted after a test. The default cleanup mode can be configured via a
configuration parameter.
This conversation was marked as resolved.
Show resolved Hide resolved
15 changes: 15 additions & 0 deletions documentation/src/docs/asciidoc/user-guide/writing-tests.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -2269,3 +2269,18 @@ method uses a separate directory.
----
include::{testDir}/example/TempDirectoryDemo.java[tags=user_guide_field_injection]
----

The `@TempDir` annotation has an optional `cleanup` attribute that can be set to either
`NEVER`, `ON_SUCCESS` or `ALWAYS`. If the cleanup mode is set to `NEVER`, temporary
This conversation was marked as resolved.
Show resolved Hide resolved
directories are not deleted after a test completes. If it is set to `ON_SUCCESS`,
temporary directories are deleted only after a test completes successfully.
This conversation was marked as resolved.
Show resolved Hide resolved

The default cleanup mode is `ALWAYS`. You can use the
`junit.jupiter.temp.dir.cleanup.mode.default`
<<running-tests-config-params, configuration parameter>> to override this default.

[source,java,indent=0]
.A test class with a temporary directory that doesn't get cleaned up
----
include::{testDir}/example/TempDirCleanupModeDemo.java[tags=user_guide]
----
28 changes: 28 additions & 0 deletions documentation/src/test/java/example/TempDirCleanupModeDemo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2015-2021 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

package example;

import static org.junit.jupiter.api.io.CleanupMode.ON_SUCCESS;

import java.nio.file.Path;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

// tag::user_guide[]
class TempDirCleanupModeDemo {

@Test
void fileTest(@TempDir(cleanup = ON_SUCCESS) Path tempDir) {
// perform test
}
}
// end::user_guide[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright 2015-2021 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/

package org.junit.jupiter.api.io;

import static org.apiguardian.api.API.Status.EXPERIMENTAL;

import org.apiguardian.api.API;

/**
* 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}
* is cleaned up.
*
* @since 5.4
* @see TempDir
*/
@API(status = EXPERIMENTAL, since = "5.4")
public enum CleanupMode {

/**
* Defer to the configured cleanup mode.
*/
DEFAULT,

/**
* Always clean up a temporary directory after the test has completed.
*/
ALWAYS,

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

/**
* Only clean up a temporary directory if the test completed successfully.
*/
ON_SUCCESS
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,35 @@
*
* <h3>Deletion</h3>
*
* <p>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
* <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.
*
* <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}
* configuration parameter.
*
* @since 5.4
*/
@Target({ ElementType.FIELD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@API(status = EXPERIMENTAL, since = "5.4")
public @interface TempDir {

String DEFAULT_CLEANUP_MODE_PROPERTY_NAME = "junit.jupiter.cleanup.mode.default";

/**
* How the temporary directory gets cleaned up after the test completes.
*/
CleanupMode cleanup() default CleanupMode.DEFAULT;

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

import static org.apiguardian.api.API.Status.INTERNAL;
import static org.junit.jupiter.api.io.TempDir.DEFAULT_CLEANUP_MODE_PROPERTY_NAME;

import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
Expand All @@ -23,6 +24,7 @@
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.io.CleanupMode;
import org.junit.jupiter.api.parallel.ExecutionMode;

/**
Expand Down Expand Up @@ -107,4 +109,10 @@ public Optional<ClassOrderer> getDefaultTestClassOrderer() {
key -> delegate.getDefaultTestClassOrderer());
}

@Override
public CleanupMode getDefaultTempDirCleanupMode() {
return (CleanupMode) cache.computeIfAbsent(DEFAULT_CLEANUP_MODE_PROPERTY_NAME,
key -> delegate.getDefaultTempDirCleanupMode());
}

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

import static org.apiguardian.api.API.Status.INTERNAL;
import static org.junit.jupiter.api.io.CleanupMode.ALWAYS;
import static org.junit.jupiter.api.io.TempDir.DEFAULT_CLEANUP_MODE_PROPERTY_NAME;

import java.util.Optional;
import java.util.function.Function;
Expand All @@ -22,6 +24,7 @@
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.io.CleanupMode;
import org.junit.jupiter.api.parallel.ExecutionMode;
import org.junit.platform.commons.util.ClassNamePatternFilterUtils;
import org.junit.platform.commons.util.Preconditions;
Expand Down Expand Up @@ -50,6 +53,9 @@ public class DefaultJupiterConfiguration implements JupiterConfiguration {
private static final InstantiatingConfigurationParameterConverter<ClassOrderer> classOrdererConverter = //
new InstantiatingConfigurationParameterConverter<>(ClassOrderer.class, "class orderer");

private static final EnumConfigurationParameterConverter<CleanupMode> cleanupModeConverter = //
new EnumConfigurationParameterConverter<>(CleanupMode.class, "cleanup mode");

private final ConfigurationParameters configurationParameters;

public DefaultJupiterConfiguration(ConfigurationParameters configurationParameters) {
Expand Down Expand Up @@ -117,4 +123,9 @@ public Optional<ClassOrderer> getDefaultTestClassOrderer() {
return classOrdererConverter.get(configurationParameters, DEFAULT_TEST_CLASS_ORDER_PROPERTY_NAME);
}

@Override
public CleanupMode getDefaultTempDirCleanupMode() {
return cleanupModeConverter.get(configurationParameters, DEFAULT_CLEANUP_MODE_PROPERTY_NAME, ALWAYS);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.extension.ExecutionCondition;
import org.junit.jupiter.api.io.CleanupMode;
import org.junit.jupiter.api.parallel.ExecutionMode;
import org.junit.platform.commons.util.ClassNamePatternFilterUtils;

Expand All @@ -42,7 +43,6 @@ public interface JupiterConfiguration {
String DEFAULT_TEST_METHOD_ORDER_PROPERTY_NAME = "junit.jupiter.testmethod.order.default";
String DEFAULT_TEST_CLASS_ORDER_PROPERTY_NAME = "junit.jupiter.testclass.order.default";
String TEMP_DIR_SCOPE_PROPERTY_NAME = "junit.jupiter.tempdir.scope";

String DEFAULT_TIMEOUT_PROPERTY_NAME = "junit.jupiter.execution.timeout.default";
String DEFAULT_TESTABLE_METHOD_TIMEOUT_PROPERTY_NAME = "junit.jupiter.execution.timeout.testable.method.default";
String DEFAULT_TEST_METHOD_TIMEOUT_PROPERTY_NAME = "junit.jupiter.execution.timeout.test.method.default";
Expand Down Expand Up @@ -77,4 +77,6 @@ public interface JupiterConfiguration {

Optional<ClassOrderer> getDefaultTestClassOrderer();

CleanupMode getDefaultTempDirCleanupMode();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can see this is not used. Please inject JupiterConfiguration into TempDirectory when registering default extensions in MutableExtensionRegistry.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now injected and referenced in TempDirectory


}
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,8 @@ public class MutableExtensionRegistry implements ExtensionRegistry, ExtensionReg

private static final Logger logger = LoggerFactory.getLogger(MutableExtensionRegistry.class);

private static final List<Extension> DEFAULT_EXTENSIONS = Collections.unmodifiableList(Arrays.asList(//
private static final List<Extension> DEFAULT_STATELESS_EXTENSIONS = Collections.unmodifiableList(Arrays.asList(//
new DisabledCondition(), //
new TempDirectory(), //
new TimeoutExtension(), //
new RepeatedTestExtension(), //
new TestInfoParameterResolver(), //
Expand All @@ -71,7 +70,9 @@ public class MutableExtensionRegistry implements ExtensionRegistry, ExtensionReg
public static MutableExtensionRegistry createRegistryWithDefaultExtensions(JupiterConfiguration configuration) {
MutableExtensionRegistry extensionRegistry = new MutableExtensionRegistry(null);

DEFAULT_EXTENSIONS.forEach(extensionRegistry::registerDefaultExtension);
DEFAULT_STATELESS_EXTENSIONS.forEach(extensionRegistry::registerDefaultExtension);

extensionRegistry.registerDefaultExtension(new TempDirectory(configuration));

if (configuration.isExtensionAutoDetectionEnabled()) {
registerAutoDetectedExtensions(extensionRegistry);
Expand Down
Loading