Skip to content

Commit

Permalink
WIP - use 'TestCases' over 'TestCase' as per junit-pioneer#552 (comment)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbduncan committed Dec 9, 2021
1 parent 09c8878 commit 50c8df6
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ private <T> T runSequentially(Invocation<T> invocation,
List<ReentrantLock> locks = findSharedOnExecutable(invocationContext.getExecutable())
// Sort by @Shared's name to prevent deadlocks when locking later.
// This is a well-known solution to the "dining philosophers problem".
// See ResourcesParallelismTests.ThrowIfTestsRunInParallelTestCase for more info.
// See ResourcesParallelismTests.ThrowIfTestsRunInParallelTestCases for more info.
.sorted(comparing(Shared::name))
.map(shared -> findLockForShared(shared, store))
.collect(toList());
Expand Down
85 changes: 66 additions & 19 deletions src/test/java/org/junitpioneer/jupiter/ResourcesDirTests.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,78 @@
/*
* Copyright 2016-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
*
* http://www.eclipse.org/legal/epl-v20.html
*/

package org.junitpioneer.jupiter;

import org.assertj.core.api.Assertions;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junitpioneer.testkit.ExecutionResults;
import org.junitpioneer.testkit.PioneerTestKit;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junitpioneer.testkit.assertion.PioneerAssert.assertThat;

class ResourcesDirTests {

@DisplayName("when a test class has a test method with a @Dir-annotated parameter")
@Nested
class WhenTestClassHasTestMethodWithDirParameterTests {

@DisplayName("then the parameter is populated with a new readable and writeable temporary directory "
+ "that lasts as long as the test")
@Test
void thenParameterIsPopulatedWithNewReadableAndWriteableTempDirThatLastsAsLongAsTheTest() {
ExecutionResults executionResults = PioneerTestKit
.executeTestClass(ResourcesTests.SingleTestMethodWithDirParameterTestCase.class);
assertThat(executionResults).hasSingleSucceededTest();
assertThat(ResourcesTests.SingleTestMethodWithDirParameterTestCase.recordedPath).doesNotExist();
}

}
@DisplayName("when a test class has a test method with a @Dir-annotated parameter")
@Nested
class WhenTestClassHasTestMethodWithDirParameterTests {

@DisplayName("then the parameter is populated with a new readable and writeable temporary directory "
+ "that lasts as long as the test")
@Test
void thenParameterIsPopulatedWithNewReadableAndWriteableTempDirThatLastsAsLongAsTheTest() {
ExecutionResults executionResults = PioneerTestKit
.executeTestClass(SingleTestMethodWithDirParameterTestCases.class);
assertThat(executionResults).hasSingleSucceededTest();
assertThat(SingleTestMethodWithDirParameterTestCases.recordedPath).doesNotExist();
}

}

static class SingleTestMethodWithDirParameterTestCases {

static Path recordedPath;

@Test
void theTest(@Dir Path tempDir) {
assertEmptyReadableWriteableTemporaryDirectory(tempDir);
assertCanAddAndReadTextFile(tempDir);

recordedPath = tempDir;
}

}

private static void assertEmptyReadableWriteableTemporaryDirectory(Path tempDir) {
assertThat(tempDir).isEmptyDirectory().startsWith(ROOT_TMP_DIR).isReadable().isWritable();
}

private static void assertCanAddAndReadTextFile(Path tempDir) {
try {
Path testFile = Files.createTempFile(tempDir, "some-test-file", ".txt");
Files.write(testFile, singletonList("some-text"));
assertThat(Files.readAllLines(testFile)).containsExactly("some-text");
}
catch (IOException e) {
fail(e);
}
}

private static final Path ROOT_TMP_DIR = Paths.get(System.getProperty("java.io.tmpdir"));

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ class WhenANumberOfSharedResourcesAreUsedInSameTestSuiteTests {
@Test
void thenTestsDoNotRunInParallel() {
ExecutionResults executionResults = assertTimeoutPreemptively(Duration.ofSeconds(15),
() -> PioneerTestKit.executeTestClass(ThrowIfTestsRunInParallelTestCase.class),
"The tests in ThrowIfTestsRunInParallelTestCase became deadlocked!");
() -> PioneerTestKit.executeTestClass(ThrowIfTestsRunInParallelTestCases.class),
"The tests in ThrowIfTestsRunInParallelTestCases became deadlocked!");
assertThat(executionResults).hasNumberOfSucceededTests(3);
}

Expand All @@ -53,8 +53,8 @@ void thenTestsDoNotRunInParallel() {
@Test
void thenTestFactoriesDoNotRunInParallel() {
ExecutionResults executionResults = assertTimeoutPreemptively(Duration.ofSeconds(15),
() -> PioneerTestKit.executeTestClass(ThrowIfTestFactoriesRunInParallelTestCase.class),
"The tests in ThrowIfTestFactoriesRunInParallelTestCase became deadlocked!");
() -> PioneerTestKit.executeTestClass(ThrowIfTestFactoriesRunInParallelTestCases.class),
"The tests in ThrowIfTestFactoriesRunInParallelTestCases became deadlocked!");
assertThat(executionResults).hasNumberOfSucceededTests(9);
}

Expand All @@ -63,8 +63,8 @@ void thenTestFactoriesDoNotRunInParallel() {
@Test
void thenTestTemplatesDoNotRunInParallel() {
ExecutionResults executionResults = assertTimeoutPreemptively(Duration.ofSeconds(15),
() -> PioneerTestKit.executeTestClass(ThrowIfTestTemplatesRunInParallelTestCase.class),
"The tests in ThrowIfTestTemplatesRunInParallelTestCase became deadlocked!");
() -> PioneerTestKit.executeTestClass(ThrowIfTestTemplatesRunInParallelTestCases.class),
"The tests in ThrowIfTestTemplatesRunInParallelTestCases became deadlocked!");
assertThat(executionResults).hasNumberOfSucceededTests(9);
}

Expand All @@ -74,10 +74,10 @@ void thenTestTemplatesDoNotRunInParallel() {
void thenTestClassConstructorsDoNotRunInParallel() {
ExecutionResults executionResults = assertTimeoutPreemptively(Duration.ofSeconds(15),
() -> PioneerTestKit
.executeTestClasses(asList(ThrowIfTestClassConstructorsRunInParallelTestCase1.class,
ThrowIfTestClassConstructorsRunInParallelTestCase2.class,
ThrowIfTestClassConstructorsRunInParallelTestCase3.class)),
"The tests in ThrowIfTestTemplatesRunInParallelTestCase(1|2|3) became deadlocked!");
.executeTestClasses(asList(ThrowIfTestClassConstructorsRunInParallelTestCases1.class,
ThrowIfTestClassConstructorsRunInParallelTestCases2.class,
ThrowIfTestClassConstructorsRunInParallelTestCases3.class)),
"The tests in ThrowIfTestTemplatesRunInParallelTestCases(1|2|3) became deadlocked!");
assertThat(executionResults).hasNumberOfSucceededTests(3);
}

Expand All @@ -89,7 +89,7 @@ void thenTestClassConstructorsDoNotRunInParallel() {
private static final String SHARED_RESOURCE_B_NAME = "shared-resource-b";
private static final String SHARED_RESOURCE_C_NAME = "shared-resource-c";

static class ThrowIfTestsRunInParallelTestCase {
static class ThrowIfTestsRunInParallelTestCases {

// In ResourceExtension, we wrap shared resources in locks. This prevents them from being
// used concurrently, which in turn prevents race conditions.
Expand Down Expand Up @@ -148,7 +148,7 @@ void test3(

}

static class ThrowIfTestFactoriesRunInParallelTestCase {
static class ThrowIfTestFactoriesRunInParallelTestCases {

@TestFactory
Stream<DynamicTest> test1(
Expand Down Expand Up @@ -187,7 +187,7 @@ Stream<DynamicTest> test3(

}

static class ThrowIfTestTemplatesRunInParallelTestCase {
static class ThrowIfTestTemplatesRunInParallelTestCases {

@ParameterizedTest
@ValueSource(ints = { 1, 2, 3 })
Expand Down Expand Up @@ -220,9 +220,9 @@ void test3(@SuppressWarnings("unused") int iteration,

}

static class ThrowIfTestClassConstructorsRunInParallelTestCase1 {
static class ThrowIfTestClassConstructorsRunInParallelTestCases1 {

ThrowIfTestClassConstructorsRunInParallelTestCase1(
ThrowIfTestClassConstructorsRunInParallelTestCases1(
// we don't actually use the resources, we just have them injected to verify whether sharing the
// same resources prevent the test constructors from running in parallel
@SuppressWarnings("unused") @Shared(factory = TemporaryDirectory.class, name = SHARED_RESOURCE_A_NAME) Path directoryA,
Expand All @@ -237,9 +237,9 @@ void fakeTest() {

}

static class ThrowIfTestClassConstructorsRunInParallelTestCase2 {
static class ThrowIfTestClassConstructorsRunInParallelTestCases2 {

ThrowIfTestClassConstructorsRunInParallelTestCase2(
ThrowIfTestClassConstructorsRunInParallelTestCases2(
@SuppressWarnings("unused") @Shared(factory = TemporaryDirectory.class, name = SHARED_RESOURCE_B_NAME) Path directoryB,
@SuppressWarnings("unused") @Shared(factory = TemporaryDirectory.class, name = SHARED_RESOURCE_C_NAME) Path directoryC)
throws Exception {
Expand All @@ -252,9 +252,9 @@ void fakeTest() {

}

static class ThrowIfTestClassConstructorsRunInParallelTestCase3 {
static class ThrowIfTestClassConstructorsRunInParallelTestCases3 {

ThrowIfTestClassConstructorsRunInParallelTestCase3(
ThrowIfTestClassConstructorsRunInParallelTestCases3(
@SuppressWarnings("unused") @Shared(factory = TemporaryDirectory.class, name = SHARED_RESOURCE_C_NAME) Path directoryC,
@SuppressWarnings("unused") @Shared(factory = TemporaryDirectory.class, name = SHARED_RESOURCE_A_NAME) Path directoryA)
throws Exception {
Expand Down
Loading

0 comments on commit 50c8df6

Please sign in to comment.