Skip to content

Commit 48276fd

Browse files
committed
Fix handling of CleanupMode.ON_SUCCESS
Prior to this commit, when a test failed all temp dirs created subsequently with `CleanupMode.ON_SUCCESS` were not deleted even if those tests passed. Fixes #4464.
1 parent f7f1d51 commit 48276fd

File tree

3 files changed

+71
-18
lines changed

3 files changed

+71
-18
lines changed

Diff for: documentation/src/docs/asciidoc/release-notes/release-notes-5.12.2.adoc

+3-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ on GitHub.
3535
[[release-notes-5.12.2-junit-jupiter-bug-fixes]]
3636
==== Bug Fixes
3737

38-
*
38+
* Fix handling of `CleanupMode.ON_SUCCESS` with `@TempDir` that caused no temporary
39+
directories (using that mode) to be deleted after the first failure even if the
40+
corresponding tests passed.
3941

4042
[[release-notes-5.12.2-junit-jupiter-deprecations-and-breaking-changes]]
4143
==== Deprecations and Breaking Changes

Diff for: junit-jupiter-engine/src/main/java/org/junit/jupiter/engine/extension/TempDirectory.java

+16-7
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,17 @@ public void beforeEach(ExtensionContext context) {
129129
}
130130

131131
private static void installFailureTracker(ExtensionContext context) {
132-
context.getStore(NAMESPACE).put(FAILURE_TRACKER, (CloseableResource) () -> context.getParent() //
133-
.ifPresent(parentContext -> {
134-
if (selfOrChildFailed(context)) {
135-
parentContext.getStore(NAMESPACE).put(CHILD_FAILED, true);
136-
}
137-
}));
132+
context.getParent() //
133+
.filter(parentContext -> !context.getRoot().equals(parentContext)) //
134+
.ifPresent(parentContext -> installFailureTracker(context, parentContext));
135+
}
136+
137+
private static void installFailureTracker(ExtensionContext context, ExtensionContext parentContext) {
138+
context.getStore(NAMESPACE).put(FAILURE_TRACKER, (CloseableResource) () -> {
139+
if (selfOrChildFailed(context)) {
140+
getContextSpecificStore(parentContext).put(CHILD_FAILED, true);
141+
}
142+
});
138143
}
139144

140145
private void injectStaticFields(ExtensionContext context, Class<?> testClass) {
@@ -286,7 +291,11 @@ static CloseablePath createTempDir(TempDirFactory factory, CleanupMode cleanupMo
286291

287292
private static boolean selfOrChildFailed(ExtensionContext context) {
288293
return context.getExecutionException().isPresent() //
289-
|| context.getStore(NAMESPACE).getOrDefault(CHILD_FAILED, Boolean.class, false);
294+
|| getContextSpecificStore(context).getOrDefault(CHILD_FAILED, Boolean.class, false);
295+
}
296+
297+
private static ExtensionContext.Store getContextSpecificStore(ExtensionContext context) {
298+
return context.getStore(NAMESPACE.append(context));
290299
}
291300

292301
static class CloseablePath implements CloseableResource {

Diff for: jupiter-tests/src/test/java/org/junit/jupiter/engine/extension/TempDirectoryCleanupTests.java

+52-10
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import java.util.logging.Level;
2828
import java.util.logging.LogRecord;
2929

30-
import org.junit.jupiter.api.AfterAll;
30+
import org.junit.jupiter.api.AfterEach;
3131
import org.junit.jupiter.api.MethodOrderer;
3232
import org.junit.jupiter.api.Nested;
3333
import org.junit.jupiter.api.Order;
@@ -60,6 +60,7 @@ class TempDirFieldTests {
6060
private static Path alwaysFieldDir;
6161
private static Path onSuccessFailingFieldDir;
6262
private static Path onSuccessPassingFieldDir;
63+
private static Path onSuccessPassingParameterDir;
6364

6465
/**
6566
* Ensure the cleanup mode defaults to ALWAYS for fields.
@@ -152,6 +153,14 @@ void cleanupModeOnSuccessFailingField() {
152153
assertThat(onSuccessFailingFieldDir).exists();
153154
}
154155

156+
@Test
157+
void cleanupModeOnSuccessFailingThenPassingField() {
158+
executeTests(selectClass(OnSuccessFailingFieldCase.class), selectClass(OnSuccessPassingFieldCase.class));
159+
160+
assertThat(onSuccessFailingFieldDir).exists();
161+
assertThat(onSuccessPassingFieldDir).doesNotExist();
162+
}
163+
155164
/**
156165
* Ensure that ON_SUCCESS cleanup modes are obeyed for static fields when tests are failing.
157166
* <p/>
@@ -174,21 +183,20 @@ void cleanupModeOnSuccessFailingStaticField() {
174183
*/
175184
@Test
176185
void cleanupModeOnSuccessFailingStaticFieldWithNesting() {
177-
LauncherDiscoveryRequest request = request()//
178-
.selectors(selectClass(OnSuccessFailingStaticFieldWithNestingCase.class))//
179-
.build();
180-
executeTests(request);
186+
executeTestsForClass(OnSuccessFailingStaticFieldWithNestingCase.class);
181187

182188
assertThat(onSuccessFailingFieldDir).exists();
189+
assertThat(onSuccessPassingParameterDir).doesNotExist();
183190
}
184191

185-
@AfterAll
186-
static void afterAll() throws IOException {
192+
@AfterEach
193+
void deleteTempDirs() throws IOException {
187194
deleteIfNotNullAndExists(defaultFieldDir);
188195
deleteIfNotNullAndExists(neverFieldDir);
189196
deleteIfNotNullAndExists(alwaysFieldDir);
190197
deleteIfNotNullAndExists(onSuccessFailingFieldDir);
191198
deleteIfNotNullAndExists(onSuccessPassingFieldDir);
199+
deleteIfNotNullAndExists(onSuccessPassingParameterDir);
192200
}
193201

194202
static void deleteIfNotNullAndExists(Path dir) throws IOException {
@@ -286,13 +294,21 @@ static class OnSuccessFailingStaticFieldWithNestingCase {
286294
static Path onSuccessFailingFieldDir;
287295

288296
@Nested
297+
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
289298
class NestedTestCase {
290299

291300
@Test
292-
void test() {
301+
@Order(1)
302+
void failingTest() {
293303
TempDirFieldTests.onSuccessFailingFieldDir = onSuccessFailingFieldDir;
294304
fail();
295305
}
306+
307+
@Test
308+
@Order(2)
309+
void passingTest(@TempDir(cleanup = ON_SUCCESS) Path tempDir) {
310+
TempDirFieldTests.onSuccessPassingParameterDir = tempDir;
311+
}
296312
}
297313
}
298314

@@ -400,8 +416,16 @@ void cleanupModeOnSuccessFailingParameter() {
400416
assertThat(onSuccessFailingParameterDir).exists();
401417
}
402418

403-
@AfterAll
404-
static void afterAll() throws IOException {
419+
@Test
420+
void cleanupModeOnSuccessFailingThenPassingParameter() {
421+
executeTestsForClass(OnSuccessFailingThenPassingParameterCase.class);
422+
423+
assertThat(onSuccessFailingParameterDir).exists();
424+
assertThat(onSuccessPassingParameterDir).doesNotExist();
425+
}
426+
427+
@AfterEach
428+
void deleteTempDirs() throws IOException {
405429
TempDirFieldTests.deleteIfNotNullAndExists(defaultParameterDir);
406430
TempDirFieldTests.deleteIfNotNullAndExists(neverParameterDir);
407431
TempDirFieldTests.deleteIfNotNullAndExists(alwaysParameterDir);
@@ -457,6 +481,24 @@ void testOnSuccessFailingParameter(@TempDir(cleanup = ON_SUCCESS) Path onSuccess
457481
}
458482
}
459483

484+
@SuppressWarnings({ "JUnitMalformedDeclaration", "NewClassNamingConvention" })
485+
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
486+
static class OnSuccessFailingThenPassingParameterCase {
487+
488+
@Test
489+
@Order(1)
490+
void testOnSuccessFailingParameter(@TempDir(cleanup = ON_SUCCESS) Path onSuccessFailingParameterDir) {
491+
TempDirParameterTests.onSuccessFailingParameterDir = onSuccessFailingParameterDir;
492+
fail();
493+
}
494+
495+
@Test
496+
@Order(2)
497+
void testOnSuccessPassingParameter(@TempDir(cleanup = ON_SUCCESS) Path onSuccessPassingParameterDir) {
498+
TempDirParameterTests.onSuccessPassingParameterDir = onSuccessPassingParameterDir;
499+
}
500+
}
501+
460502
}
461503

462504
@Nested

0 commit comments

Comments
 (0)