All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.cucumber.core.plugin.ScenarioContextParallel Maven / Gradle / Ivy
package io.cucumber.core.plugin;
import net.serenitybdd.model.exceptions.SerenityManagedException;
import net.thucydides.core.steps.events.StepEventBusEvent;
import io.cucumber.messages.types.Scenario;
import io.cucumber.messages.types.Step;
import io.cucumber.messages.types.Tag;
import io.cucumber.plugin.event.TestCase;
import io.cucumber.plugin.event.TestStep;
import net.thucydides.model.domain.DataTable;
import net.thucydides.model.domain.DataTableRow;
import net.thucydides.model.domain.TestTag;
import net.thucydides.core.steps.BaseStepListener;
import net.thucydides.core.steps.StepEventBus;
import net.thucydides.core.steps.session.TestSession;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URI;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.stream.Collectors.toList;
public class ScenarioContextParallel {
private static final Logger LOGGER = LoggerFactory.getLogger(ScenarioContextParallel.class);
private final Map> highPriorityEventBusEvents = Collections.synchronizedMap(new HashMap<>());
private final Map> stepQueue = Collections.synchronizedMap(new HashMap<>());
private final Map> testStepQueue = Collections.synchronizedMap(new HashMap<>());
private final Map examplesRunningMap = Collections.synchronizedMap(new HashMap<>());
private final Map addingScenarioOutlineStepsMap = Collections.synchronizedMap(new HashMap<>());
private final Map tableMap = Collections.synchronizedMap(new HashMap<>());
//map1: keys are scenario ids
//map2: keys are line numbers, entries are example rows (key=header, value=rowValue )
private final Map>> exampleRowsMap = Collections.synchronizedMap(new HashMap<>());
//keys are line numbers
private Map> exampleTags;
private final Map exampleCountMap = Collections.synchronizedMap(new HashMap<>());
//key- ScenarioId
private final Map waitingToProcessBackgroundSteps = Collections.synchronizedMap(new HashMap<>());
private final List currentScenarioIdList = Collections.synchronizedList(new ArrayList<>());
//key - scenarioId
private final Map currentScenarioDefinitionMap = Collections.synchronizedMap(new HashMap<>());
private final Map currentScenarioMap = Collections.synchronizedMap(new HashMap<>());
private List featureTags = new ArrayList<>();
private final FeaturePathFormatter featurePathFormatter = new FeaturePathFormatter();
private final List baseStepListeners;
// key-line in feature file; value - list with StepBusEvents corresponding to this line.
private final Map> allTestEventsByLine = Collections.synchronizedMap(new TreeMap<>());
private final URI scenarioContextURI;
private StepEventBus stepEventBus;
// key - scenarioId
private final Map> scenarioTags = Collections.synchronizedMap(new HashMap<>());
public ScenarioContextParallel(URI scenarioContextURI) {
this.baseStepListeners = Collections.synchronizedList(new ArrayList<>());
this.scenarioContextURI = scenarioContextURI;
this.stepEventBus = stepEventBus(scenarioContextURI);
}
public synchronized Scenario currentScenarioOutline(String scenarioId) {
return currentScenarioDefinitionMap.get(scenarioId);
}
public synchronized Queue getStepQueue(TestCase testCase) {
stepQueue.computeIfAbsent(testCase.getId(), k -> new LinkedList<>());
return stepQueue.get(testCase.getId());
}
public synchronized Queue getTestStepQueue(TestCase testCase/*String scenarioId*/) {
testStepQueue.computeIfAbsent(testCase.getId(), k -> new LinkedList<>());
return testStepQueue.get(testCase.getId());
}
public synchronized boolean examplesAreRunning(String scenarioId) {
if (!examplesRunningMap.containsKey(scenarioId)) {
return false;
}
return examplesRunningMap.get(scenarioId);
}
public synchronized Map> getExampleRows(String scenarioId) {
return exampleRowsMap.get(scenarioId);
}
public synchronized void setExampleRows(String scenarioId, Map> exampleRows) {
this.exampleRowsMap.put(scenarioId, exampleRows);
}
public synchronized Map> getExampleTags() {
return exampleTags;
}
//TODO - use a map with scenarioId as key
public synchronized void setExampleTags(Map> exampleTags) {
this.exampleTags = exampleTags;
}
public synchronized int getExampleCount(String scenarioId) {
if (exampleCountMap.containsKey(scenarioId)) {
return exampleCountMap.get(scenarioId).get();
}
return 0;
}
public synchronized int decrementExampleCount(String scenarioId) {
if (exampleCountMap.get(scenarioId) != null) {
return exampleCountMap.get(scenarioId).decrementAndGet();
}
//single example
return 0;
}
public synchronized DataTable getTable(String scenarioId) {
return tableMap.get(scenarioId);
}
public synchronized boolean isWaitingToProcessBackgroundSteps(String scenarioId) {
return waitingToProcessBackgroundSteps.getOrDefault(scenarioId, false);
}
public synchronized void addCurrentScenarioId(String scenarioId) {
if (scenarioId != null) {
currentScenarioIdList.add(scenarioId);
} else {
currentScenarioIdList.clear();
}
}
public synchronized Scenario getCurrentScenarioDefinition(String scenarioId) {
return currentScenarioDefinitionMap.get(scenarioId);
}
public synchronized String getCurrentScenario(String scenarioId) {
return currentScenarioMap.get(scenarioId);
}
public synchronized void setCurrentScenario(String scenarioId, String currentScenario) {
this.currentScenarioMap.put(scenarioId, currentScenario);
}
public synchronized List getFeatureTags() {
return featureTags;
}
public synchronized boolean isAddingScenarioOutlineSteps(String scenarioId) {
return addingScenarioOutlineStepsMap.get(scenarioId) != null ? addingScenarioOutlineStepsMap.get(scenarioId) : false;
}
public synchronized void doneAddingScenarioOutlineSteps(String scenarioId) {
this.addingScenarioOutlineStepsMap.put(scenarioId, false);
}
public synchronized void setFeatureTags(List tags) {
this.featureTags = new ArrayList<>(tags);
}
public synchronized void setCurrentScenarioDefinitionFrom(String scenarioId, TestSourcesModel.AstNode astNode) {
this.currentScenarioDefinitionMap.put(scenarioId, TestSourcesModel.getScenarioDefinition(astNode));
}
public synchronized boolean isAScenarioOutline(String scenarioId) {
return currentScenarioDefinitionMap.get(scenarioId) != null &&
currentScenarioDefinitionMap.get(scenarioId).getExamples().size() > 0;
}
public synchronized void startNewExample(String scenarioId) {
examplesRunningMap.put(scenarioId, true);
addingScenarioOutlineStepsMap.put(scenarioId, true);
}
public synchronized void setExamplesRunning(String scenarioId, boolean examplesRunning) {
examplesRunningMap.put(scenarioId, examplesRunning);
}
/*public synchronized List getScenarioTags() {
return currentScenarioDefinition.getTags();
}
public synchronized String getScenarioName() {
return currentScenarioDefinition.getName();
}
public synchronized List getScenarioExamples() {
return currentScenarioDefinition.getExamples();
}*/
public synchronized void clearStepQueue(TestCase testCase/*String scenarioId*/) {
getStepQueue(testCase).clear();
}
public synchronized void clearStepQueue() {
//TODO check
stepQueue.clear();
//simpleStepQueue.clear();
}
public synchronized void clearTestStepQueue() {
testStepQueue.clear();
//simpleStepTestQueue.clear();
}
public synchronized void queueStep(TestCase testCase/*String scenarioId,*/, Step step) {
getStepQueue(testCase).add(step);
}
public synchronized void queueTestStep(/*String scenarioId*/TestCase testCase, TestStep testStep) {
getTestStepQueue(testCase).add(testStep);
}
public synchronized Step getCurrentStep(TestCase testCase/*String scenarioId*/) {
return getStepQueue(testCase/*scenarioId*/).peek();
}
public synchronized Step nextStep(TestCase testCase/*String scenarioId*/) {
return getStepQueue(testCase/*scenarioId*/).poll();
}
public synchronized TestStep nextTestStep(TestCase testCase/*String scenarioId*/) {
return getTestStepQueue(testCase/*scenarioId*/).poll();
}
public synchronized boolean noStepsAreQueued(/*String scenarioId*/TestCase testCase) {
return getStepQueue(testCase/*scenarioId*/).isEmpty();
}
public synchronized boolean hasScenarioId(String scenarioId) {
return (currentScenarioIdList.contains(scenarioId));
}
public synchronized void setTable(String scenarioId, DataTable table) {
this.tableMap.put(scenarioId, table);
exampleCountMap.put(scenarioId, new AtomicInteger(table.getSize()));
}
public synchronized void addTableRows(String scenarioId, List headers,
List> rows,
String name,
String description,
Map lineNumbersOfEachRow) {
DataTable table = tableMap.get(scenarioId);
table.startNewDataSet(name, description);
AtomicInteger rowNumber = new AtomicInteger();
rows.forEach(
row -> table.appendRow(newRow(headers, lineNumbersOfEachRow, rowNumber.getAndIncrement(), row))
);
table.updateLineNumbers(lineNumbersOfEachRow);
exampleCountMap.put(scenarioId, new AtomicInteger(table.getSize()));
}
@NotNull
private DataTableRow newRow(List headers,
Map lineNumbersOfEachRow,
int rowNumber,
Map row) {
return new DataTableRow(
rowValuesFrom(headers, row),
lineNumbersOfEachRow.getOrDefault(rowNumber, 0L));
}
private List rowValuesFrom(List headers, Map row) {
return headers.stream().map(row::get).collect(toList());
}
public synchronized void addTableTags(String scenarioId, List tags) {
DataTable table = tableMap.get(scenarioId);
table.addTagsToLatestDataSet(tags);
}
public synchronized void clearTable() {
tableMap.clear();
}
private synchronized StepEventBus stepEventBus(URI featurePath) {
URI prefixedPath = featurePathFormatter.featurePathWithPrefixIfNecessary(featurePath);
return StepEventBus.eventBusFor(prefixedPath);
}
public synchronized StepEventBus stepEventBus() {
return this.stepEventBus;
}
public void setStepEventBus(StepEventBus stepEventBus) {
this.stepEventBus = stepEventBus;
}
public void addBaseStepListener(BaseStepListener baseStepListener) {
baseStepListeners.add(baseStepListener);
stepEventBus.registerListener(baseStepListener);
}
public synchronized void collectAllBaseStepListeners(List allBaseStepListeners) {
allBaseStepListeners.addAll(baseStepListeners);
}
public void setWaitingToProcessBackgroundSteps(String scenarioId, boolean waitingToProcessBackgroundSteps) {
this.waitingToProcessBackgroundSteps.put(scenarioId, waitingToProcessBackgroundSteps);
}
/**
* Some events have to be added ad the beginning of the event list.
*
* @param scenarioId
* @param event
*/
public void addHighPriorityStepEventBusEvent(String scenarioId, StepEventBusEvent event) {
LOGGER.debug("SRP:addHighPriorityStepEventBusEvent " + event + " " + Thread.currentThread() + " " + scenarioId);
List eventList = highPriorityEventBusEvents.computeIfAbsent(scenarioId, k -> Collections.synchronizedList(new LinkedList<>()));
eventList.add(event);
event.setStepEventBus(stepEventBus);
}
public void addStepEventBusEvent(StepEventBusEvent event) {
if (TestSession.isSessionStarted()) {
TestSession.addEvent(event);
event.setStepEventBus(stepEventBus);
} else {
LOGGER.debug("SRP:ignored event " + event + " " + Thread.currentThread() + " because session not opened ", new Exception());
}
}
/**
* Called with TestCaseFinished
*
* @param line
* @param testCase
*/
public void storeAllStepEventBusEventsForLine(int line, TestCase testCase) {
if (TestSession.isSessionStarted()) {
TestSession.closeSession();
List stepEventBusEvents = TestSession.getSessionEvents();
List clonedEvents = new ArrayList<>(stepEventBusEvents);
allTestEventsByLine.put(line, clonedEvents);
TestSession.cleanupSession();
}
}
/**
* Called with TestRunFinished - all tests events are replayed
*/
public synchronized void playAllTestEvents() {
LOGGER.debug("SRP:playAllTestEvents for URI " + scenarioContextURI + "--" + allTestEventsByLine);
for (var entry : allTestEventsByLine.entrySet()) {
try {
replayAllTestCaseEventsForLine(entry.getKey(), entry.getValue());
} catch (Throwable exception) {
LOGGER.error("An unrecoverable error occurred during test execution: " + exception.getMessage(), exception);
exception.printStackTrace();
recordUnexpectedFailure(new SerenityManagedException("An unrecoverable error occurred during test execution: " + exception.getMessage(),
exception));
}
}
clearEventBus();
}
public synchronized void recordUnexpectedFailure(Throwable throwable) {
stepEventBus.getBaseStepListener().getCurrentTestOutcome().testFailedWith(throwable);
}
public synchronized void clearEventBus() {
stepEventBus.clear();
StepEventBus.getParallelEventBus().clear();
}
private void replayAllTestCaseEventsForLine(Integer lineNumber, List stepEventBusEvents) {
LOGGER.debug("SRP:PLAY session events for line " + lineNumber);
Optional eventWithScenarioId = stepEventBusEvents.stream().filter(event -> !event.getScenarioId().isEmpty()).findFirst();
LOGGER.debug("SRP:EventWithscenarioId " + eventWithScenarioId);
if (eventWithScenarioId.isPresent() && highPriorityEventBusEvents.get(eventWithScenarioId.get().getScenarioId()) != null) {
List highPriorityEvents = highPriorityEventBusEvents.get(eventWithScenarioId.get().getScenarioId());
for (StepEventBusEvent currentStepBusEvent : highPriorityEvents) {
LOGGER.trace("SRP:PLAY session high priority event " + currentStepBusEvent);
currentStepBusEvent.play();
}
highPriorityEventBusEvents.remove(eventWithScenarioId.get().getScenarioId());
}
for (StepEventBusEvent currentStepBusEvent : stepEventBusEvents) {
LOGGER.trace("SRP:PLAY session event " + currentStepBusEvent + " " + Thread.currentThread() + " " + currentStepBusEvent.hashCode());
currentStepBusEvent.play();
}
}
public List getScenarioTags(String scenarioId) {
return scenarioTags.get(scenarioId);
}
public void setScenarioTags(String scenarioId, List scenarioTags) {
this.scenarioTags.put(scenarioId, scenarioTags);
}
}