Skip to content

Commit 3e9cdf4

Browse files
authored
fix fixtures for parallel testng execution (fixes allure-framework#219, fixes allure-framework#284, via allure-framework#324)
1 parent 09257f6 commit 3e9cdf4

3 files changed

Lines changed: 55 additions & 46 deletions

File tree

allure-testng/src/main/java/io/qameta/allure/testng/AllureTestNg.java

Lines changed: 52 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
import java.util.Optional;
6262
import java.util.UUID;
6363
import java.util.concurrent.ConcurrentHashMap;
64+
import java.util.concurrent.locks.ReadWriteLock;
65+
import java.util.concurrent.locks.ReentrantReadWriteLock;
6466
import java.util.function.Consumer;
6567
import java.util.stream.Collectors;
6668
import java.util.stream.Stream;
@@ -106,37 +108,26 @@ public class AllureTestNg implements
106108
/**
107109
* Store current testng result uuid to attach before/after methods into.
108110
*/
109-
private final ThreadLocal<Current> currentTestResult = new InheritableThreadLocal<Current>() {
110-
@Override
111-
protected Current initialValue() {
112-
return new Current();
113-
}
114-
};
111+
private final ThreadLocal<Current> currentTestResult = ThreadLocal
112+
.withInitial(Current::new);
115113

116114
/**
117115
* Store current container uuid for fake containers around before/after methods.
118116
*/
119-
private final ThreadLocal<String> currentTestContainer = new InheritableThreadLocal<String>() {
120-
@Override
121-
protected String initialValue() {
122-
return UUID.randomUUID().toString();
123-
}
124-
};
117+
private final ThreadLocal<String> currentTestContainer = ThreadLocal
118+
.withInitial(() -> UUID.randomUUID().toString());
125119

126120
/**
127121
* Store uuid for current executable item to catch steps and attachments.
128122
*/
129-
private final ThreadLocal<String> currentExecutable = new InheritableThreadLocal<String>() {
130-
@Override
131-
protected String initialValue() {
132-
return UUID.randomUUID().toString();
133-
}
134-
};
123+
private final ThreadLocal<String> currentExecutable = ThreadLocal
124+
.withInitial(() -> UUID.randomUUID().toString());
135125

136126
/**
137127
* Store uuid for class test containers.
138128
*/
139129
private final Map<ITestClass, String> classContainerUuidStorage = new ConcurrentHashMap<>();
130+
private final ReadWriteLock lock = new ReentrantReadWriteLock();
140131

141132
private final AllureLifecycle lifecycle;
142133

@@ -215,16 +206,14 @@ public void onBeforeClass(final ITestClass testClass) {
215206
.setUuid(uuid)
216207
.setName(testClass.getName());
217208
getLifecycle().startTestContainer(container);
218-
classContainerUuidStorage.put(testClass, uuid);
209+
setClassContainer(testClass, uuid);
219210
}
220211

221212
public void onAfterClass(final ITestClass testClass) {
222-
if (!classContainerUuidStorage.containsKey(testClass)) {
223-
return;
224-
}
225-
final String uuid = classContainerUuidStorage.get(testClass);
226-
getLifecycle().stopTestContainer(uuid);
227-
getLifecycle().writeTestContainer(uuid);
213+
getClassContainer(testClass).ifPresent(uuid -> {
214+
getLifecycle().stopTestContainer(uuid);
215+
getLifecycle().writeTestContainer(uuid);
216+
});
228217
}
229218

230219
@Override
@@ -242,11 +231,7 @@ public void onTestStart(final ITestResult testResult) {
242231
Optional.of(testResult)
243232
.map(ITestResult::getMethod)
244233
.map(ITestNGMethod::getTestClass)
245-
.map(classContainerUuidStorage::get)
246-
.ifPresent(testClassContainerUuid -> getLifecycle().updateTestContainer(
247-
testClassContainerUuid,
248-
container -> container.getChildren().add(uuid)
249-
));
234+
.ifPresent(clazz -> addClassContainerChild(clazz, uuid));
250235
}
251236

252237
protected void startTestCase(final ITestResult testResult,
@@ -400,12 +385,12 @@ private void ifSuiteFixtureStarted(final ISuite suite, final ITestNGMethod testM
400385

401386
private void ifClassFixtureStarted(final ITestNGMethod testMethod) {
402387
if (testMethod.isBeforeClassConfiguration()) {
403-
final String parentUuid = classContainerUuidStorage.get(testMethod.getTestClass());
404-
startBefore(parentUuid, testMethod);
388+
getClassContainer(testMethod.getTestClass())
389+
.ifPresent(parentUuid -> startBefore(parentUuid, testMethod));
405390
}
406391
if (testMethod.isAfterClassConfiguration()) {
407-
final String parentUuid = classContainerUuidStorage.get(testMethod.getTestClass());
408-
startAfter(parentUuid, testMethod);
392+
getClassContainer(testMethod.getTestClass())
393+
.ifPresent(parentUuid -> startAfter(parentUuid, testMethod));
409394
}
410395
}
411396

@@ -696,6 +681,39 @@ private Consumer<TestResult> setStatus(final Status status, final StatusDetails
696681
};
697682
}
698683

684+
private void addClassContainerChild(final ITestClass clazz, final String childUuid) {
685+
lock.writeLock().lock();
686+
try {
687+
final String parentUuid = classContainerUuidStorage.get(clazz);
688+
if (nonNull(parentUuid)) {
689+
getLifecycle().updateTestContainer(
690+
parentUuid,
691+
container -> container.getChildren().add(childUuid)
692+
);
693+
}
694+
} finally {
695+
lock.writeLock().unlock();
696+
}
697+
}
698+
699+
private Optional<String> getClassContainer(final ITestClass clazz) {
700+
lock.readLock().lock();
701+
try {
702+
return Optional.ofNullable(classContainerUuidStorage.get(clazz));
703+
} finally {
704+
lock.readLock().unlock();
705+
}
706+
}
707+
708+
private void setClassContainer(final ITestClass clazz, final String uuid) {
709+
lock.writeLock().lock();
710+
try {
711+
classContainerUuidStorage.put(clazz, uuid);
712+
} finally {
713+
lock.writeLock().unlock();
714+
}
715+
}
716+
699717
private Current refreshContext() {
700718
currentTestResult.remove();
701719
return currentTestResult.get();

allure-testng/src/test/java/io/qameta/allure/testng/AllureTestNgTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ public void perSuiteFixtures(final XmlSuite.ParallelMode mode, final int threadC
335335
}
336336

337337
@AllureFeatures.Fixtures
338-
@Test(description = "Class fixtures", dataProvider = "parallelConfiguration", enabled = false)
338+
@Test(description = "Class fixtures", dataProvider = "parallelConfiguration")
339339
public void perClassFixtures(final XmlSuite.ParallelMode mode, final int threadCount) {
340340
final AllureResults results = runTestNgSuites(
341341
parallel(mode, threadCount),
@@ -496,7 +496,7 @@ public void testBeforeSuiteParameter() {
496496
}
497497

498498
@AllureFeatures.Parallel
499-
@Test(description = "Parallel methods", enabled = false)
499+
@Test(description = "Parallel methods")
500500
public void parallelMethods() {
501501
String before1 = "io.qameta.allure.testng.samples.ParallelMethods.beforeMethod";
502502
String before2 = "io.qameta.allure.testng.samples.ParallelMethods.beforeMethod2";
@@ -928,8 +928,7 @@ public void shouldProcessCyrillicDescriptions() {
928928
@Issue("219")
929929
@Test(
930930
description = "Should not mix up fixtures during parallel run",
931-
dataProvider = "parallelConfiguration",
932-
enabled = false
931+
dataProvider = "parallelConfiguration"
933932
)
934933
public void shouldAddCorrectBeforeMethodFixturesInCaseOfParallelRun(
935934
final XmlSuite.ParallelMode mode, final int threadCount) {

allure-testng/src/test/java/io/qameta/allure/testng/samples/BeforeMethods.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,6 @@
2929
*/
3030
public class BeforeMethods {
3131

32-
// @BeforeSuite
33-
// public void beforeSuite() {
34-
// }
35-
//
36-
// @AfterSuite
37-
// public void afterSuite() {
38-
// }
39-
4032
@BeforeTest
4133
public void beforeTest() {
4234
}

0 commit comments

Comments
 (0)