Skip to content

Commit

Permalink
Fixed thread safety issues and enabled parallel requirement processing
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-molak committed Jan 4, 2024
1 parent a345254 commit 6286a1e
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,33 +1,24 @@
package net.thucydides.model.requirements;

import net.serenitybdd.model.collect.NewList;
import net.serenitybdd.model.di.ModelInfrastructure;
import net.serenitybdd.model.environment.EnvironmentSpecificConfiguration;
import net.thucydides.model.ThucydidesSystemProperty;
import net.thucydides.model.domain.TestOutcome;
import net.thucydides.model.environment.SystemEnvironmentVariables;
import net.thucydides.model.requirements.model.Requirement;
import net.thucydides.model.statistics.service.AnnotationBasedTagProvider;
import net.thucydides.model.statistics.service.FeatureStoryTagProvider;
import net.thucydides.model.util.EnvironmentVariables;
import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;

public class AggregateRequirementsService extends BaseRequirementsService implements RequirementsService {

private List<RequirementsTagProvider> requirementsTagProviders;
private final List<RequirementsTagProvider> requirementsTagProviders;

public AggregateRequirementsService(EnvironmentVariables environmentVariables,
RequirementsTagProvider... tagProviders) {
super(environmentVariables);
this.requirementsTagProviders = NewList.of(tagProviders);
this.requirementsTagProviders = List.of(tagProviders);
}


private static final Logger LOGGER = LoggerFactory.getLogger(AggregateRequirementsService.class);

@Override
Expand All @@ -36,10 +27,9 @@ public List<Requirement> getRequirements() {
StopWatch stopWatch = StopWatch.createStarted();

requirements = getRequirementsTagProviders().stream()
// todo: enable parallel processing
// .parallel()
.parallel()
.flatMap(RequirementsProvided::asStream)
.collect(Collectors.toCollection(MergedRequirementList::new));
.collect(RequirementsCollector.merging());

stopWatch.split();
LOGGER.debug("Requirements loaded in {}", stopWatch.formatSplitTime());
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;

public class MultiSourceRequirementsService extends BaseRequirementsService implements RequirementsService {

Expand All @@ -41,7 +40,7 @@ public List<Requirement> getRequirements() {
requirements = getRequirementsTagProviders().stream()
.parallel()
.flatMap(RequirementsProvided::asStream)
.collect(Collectors.toCollection(MergedRequirementList::new));
.collect(RequirementsCollector.merging());

stopWatch.split();
LOGGER.debug("Requirements loaded in {}", stopWatch.formatSplitTime());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package net.thucydides.model.requirements;

import net.thucydides.model.requirements.model.Requirement;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;

public class RequirementsCollector {

private static final Collector<Requirement, ?, List<Requirement>> INSTANCE =
Collectors.collectingAndThen(
Collectors.toMap(
req -> req, // Using the requirement itself as the key since we have no unique ID to rely on
req -> req,
Requirement::merge
),
map -> new ArrayList<>(map.values())
);

public static Collector<Requirement, ?, List<Requirement>> merging() {
return INSTANCE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;

public class RequirementsProvided {

private static final Logger LOGGER = LoggerFactory.getLogger(RequirementsTagProvider.class);

private static final Iterable<Requirement> NO_REQUIREMENTS = new ArrayList<>();
private static final List<Requirement> EMPTY_REQUIREMENTS = new ArrayList<>();
private static final Iterable<Requirement> NO_REQUIREMENTS = Collections.emptyList();
private static final List<Requirement> EMPTY_REQUIREMENTS = Collections.emptyList();

public static Iterable<Requirement> by(RequirementsTagProvider tagProvider) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
class RequirementAncestryTest {

/**
* Parent ID must be set to an empty string for the {@link MergedRequirementList}
* to correctly merge the requirements discovered by different tag providers.
* Parent ID must be set to an empty string for the {@link Requirement#merge}
* to correctly merge the requirements discovered by the different tag providers.
*/
@Test
void sets_the_parent_id_to_empty_string_when_parent_does_not_exist() {
Expand Down

0 comments on commit 6286a1e

Please sign in to comment.