Skip to content

Commit 1484347

Browse files
committed
Add integration test
Issue: #2229 Signed-off-by: yongjunhong <[email protected]>
1 parent f9af925 commit 1484347

File tree

2 files changed

+192
-0
lines changed

2 files changed

+192
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright 2015-2024 the original author or authors.
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License v2.0 which
6+
* accompanies this distribution and is available at
7+
*
8+
* https://www.eclipse.org/legal/epl-v20.html
9+
*/
10+
11+
package org.junit.vintage.engine.execution;
12+
13+
import static org.assertj.core.api.Assertions.assertThat;
14+
import static org.junit.platform.testkit.engine.EventConditions.event;
15+
import static org.junit.platform.testkit.engine.EventConditions.finishedSuccessfully;
16+
import static org.junit.platform.testkit.engine.EventConditions.finishedWithFailure;
17+
import static org.junit.platform.testkit.engine.EventConditions.started;
18+
import static org.junit.platform.testkit.engine.EventConditions.test;
19+
import static org.junit.vintage.engine.samples.junit4.JUnit4ParallelTestCase.FailingParallelTestCase;
20+
import static org.junit.vintage.engine.samples.junit4.JUnit4ParallelTestCase.SuccessfulParallelTestCase;
21+
22+
import java.time.Instant;
23+
import java.util.Arrays;
24+
import java.util.List;
25+
26+
import org.assertj.core.api.Condition;
27+
import org.junit.jupiter.api.Test;
28+
import org.junit.jupiter.api.TestReporter;
29+
import org.junit.platform.engine.discovery.ClassSelector;
30+
import org.junit.platform.engine.discovery.DiscoverySelectors;
31+
import org.junit.platform.launcher.LauncherDiscoveryRequest;
32+
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
33+
import org.junit.platform.testkit.engine.EngineExecutionResults;
34+
import org.junit.platform.testkit.engine.EngineTestKit;
35+
import org.junit.platform.testkit.engine.Event;
36+
import org.junit.platform.testkit.engine.Events;
37+
import org.junit.vintage.engine.VintageTestEngine;
38+
39+
class ParallelExecutionIntegrationTests {
40+
41+
private static final String PARALLEL_EXECUTION_ENABLED = "junit.vintage.execution.parallel.enabled";
42+
private static final String PARALLEL_POOL_SIZE = "junit.vintage.execution.parallel.pool-size";
43+
44+
@Test
45+
void successfulParallelTest(TestReporter reporter) {
46+
var events = executeInParallelSuccessfully(3, SuccessfulParallelTestCase.class).list();
47+
48+
var startedTimestamps = getTimestampsFor(events, event(test(), started()));
49+
var finishedTimestamps = getTimestampsFor(events, event(test(), finishedSuccessfully()));
50+
51+
reporter.publishEntry("startedTimestamps", startedTimestamps.toString());
52+
reporter.publishEntry("finishedTimestamps", finishedTimestamps.toString());
53+
54+
assertThat(startedTimestamps).hasSize(3);
55+
assertThat(finishedTimestamps).hasSize(3);
56+
}
57+
58+
@Test
59+
void failingParallelTest(TestReporter reporter) {
60+
var events = executeInParallel(3, FailingParallelTestCase.class).list();
61+
62+
var startedTimestamps = getTimestampsFor(events, event(test(), started()));
63+
var finishedTimestamps = getTimestampsFor(events, event(test(), finishedWithFailure()));
64+
reporter.publishEntry("startedTimestamps", startedTimestamps.toString());
65+
reporter.publishEntry("finishedTimestamps", finishedTimestamps.toString());
66+
67+
assertThat(startedTimestamps).hasSize(3);
68+
assertThat(finishedTimestamps).hasSize(3);
69+
}
70+
71+
private List<Instant> getTimestampsFor(List<Event> events, Condition<Event> condition) {
72+
// @formatter:off
73+
return events.stream()
74+
.filter(condition::matches)
75+
.map(Event::getTimestamp)
76+
.toList();
77+
// @formatter:on
78+
}
79+
80+
private Events executeInParallelSuccessfully(int poolSize, Class<?>... testClasses) {
81+
var events = execute(poolSize, testClasses).allEvents();
82+
try {
83+
return events.assertStatistics(it -> it.failed(0));
84+
}
85+
catch (AssertionError error) {
86+
events.debug();
87+
throw error;
88+
}
89+
}
90+
91+
private Events executeInParallel(int poolSize, Class<?>... testClasses) {
92+
return execute(poolSize, testClasses).allEvents();
93+
}
94+
95+
private static EngineExecutionResults execute(int poolSize, Class<?>... testClass) {
96+
return EngineTestKit.execute(new VintageTestEngine(), request(poolSize, testClass));
97+
}
98+
99+
private static LauncherDiscoveryRequest request(int poolSize, Class<?>... testClasses) {
100+
var classSelectors = Arrays.stream(testClasses) //
101+
.map(DiscoverySelectors::selectClass) //
102+
.toArray(ClassSelector[]::new);
103+
104+
return LauncherDiscoveryRequestBuilder.request().selectors(classSelectors).configurationParameter(
105+
PARALLEL_EXECUTION_ENABLED, String.valueOf(true)).configurationParameter(PARALLEL_POOL_SIZE,
106+
String.valueOf(poolSize)).build();
107+
}
108+
109+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2015-2024 the original author or authors.
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License v2.0 which
6+
* accompanies this distribution and is available at
7+
*
8+
* https://www.eclipse.org/legal/epl-v20.html
9+
*/
10+
11+
package org.junit.vintage.engine.samples.junit4;
12+
13+
import static java.util.concurrent.TimeUnit.MILLISECONDS;
14+
import static org.junit.Assert.fail;
15+
16+
import java.util.concurrent.CountDownLatch;
17+
import java.util.concurrent.atomic.AtomicInteger;
18+
19+
import org.junit.BeforeClass;
20+
import org.junit.Test;
21+
import org.junit.experimental.runners.Enclosed;
22+
import org.junit.runner.RunWith;
23+
24+
@RunWith(Enclosed.class)
25+
public class JUnit4ParallelTestCase {
26+
27+
public static class SuccessfulParallelTestCase {
28+
static AtomicInteger sharedResource;
29+
static CountDownLatch countDownLatch;
30+
31+
@BeforeClass
32+
public static void initialize() {
33+
sharedResource = new AtomicInteger();
34+
countDownLatch = new CountDownLatch(3);
35+
}
36+
37+
@Test
38+
public void firstTest() throws Exception {
39+
incrementAndBlock(sharedResource, countDownLatch);
40+
}
41+
42+
@Test
43+
public void secondTest() throws Exception {
44+
incrementAndBlock(sharedResource, countDownLatch);
45+
}
46+
47+
@Test
48+
public void thirdTest() throws Exception {
49+
incrementAndBlock(sharedResource, countDownLatch);
50+
}
51+
}
52+
53+
public static class FailingParallelTestCase {
54+
@Test
55+
public void firstTest() {
56+
fail("failing test");
57+
}
58+
59+
@Test
60+
public void secondTest() {
61+
fail("failing test");
62+
}
63+
64+
@Test
65+
public void thirdTest() {
66+
fail("failing test");
67+
}
68+
}
69+
70+
@SuppressWarnings("ResultOfMethodCallIgnored")
71+
private static int incrementAndBlock(AtomicInteger sharedResource, CountDownLatch countDownLatch)
72+
throws InterruptedException {
73+
var value = sharedResource.incrementAndGet();
74+
countDownLatch.countDown();
75+
countDownLatch.await(estimateSimulatedTestDurationInMiliseconds(), MILLISECONDS);
76+
return value;
77+
}
78+
79+
private static long estimateSimulatedTestDurationInMiliseconds() {
80+
var runningInCi = Boolean.parseBoolean(System.getenv("CI"));
81+
return runningInCi ? 1000 : 100;
82+
}
83+
}

0 commit comments

Comments
 (0)