package betsy.bpmn.engines; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.List; import java.util.Objects; import betsy.bpmn.model.BPMNAssertions; import betsy.bpmn.model.BPMNProcess; import betsy.common.tasks.FileTasks; import betsy.common.tasks.WaitTasks; import org.apache.log4j.Logger; import pebl.benchmark.test.TestCase; import pebl.benchmark.test.TestStep; import pebl.benchmark.test.assertions.AssertTrace; import pebl.benchmark.test.steps.CheckDeployment; import pebl.benchmark.test.steps.DelayTesting; import pebl.benchmark.test.steps.GatherTraces; import pebl.benchmark.test.steps.vars.StartProcess; import pebl.benchmark.test.steps.vars.Variable; public class GenericBPMNTester { private static final Logger LOGGER = Logger.getLogger(GenericBPMNTester.class); private final BPMNProcess bpmnProcess; private final TestCase testCase; private final Path instanceLogFile; private final BPMNTester bpmnTester; private final BPMNProcessInstanceOutcomeChecker checkerOutcomeAfter; private final BPMNProcessStarter processStarter; private final BPMNProcessInstanceOutcomeChecker checkerOutcomeBefore; public GenericBPMNTester(BPMNProcess bpmnProcess, TestCase testCase, Path instanceLogFile, BPMNTester bpmnTester, BPMNProcessInstanceOutcomeChecker checkerOutcomeBefore, BPMNProcessInstanceOutcomeChecker checkerOutcomeAfter, BPMNProcessStarter processStarter) { this.bpmnProcess = bpmnProcess; this.testCase = Objects.requireNonNull(testCase); this.instanceLogFile = Objects.requireNonNull(instanceLogFile); this.bpmnTester = Objects.requireNonNull(bpmnTester); this.checkerOutcomeBefore = Objects.requireNonNull(checkerOutcomeBefore); this.checkerOutcomeAfter = Objects.requireNonNull(checkerOutcomeAfter); this.processStarter = Objects.requireNonNull(processStarter); } /** * runs a single test */ public void runTest() { for (TestStep testStep : testCase.getTestSteps()) { if (testStep instanceof CheckDeployment) { BPMNProcessInstanceOutcomeChecker.ProcessInstanceOutcome outcomeBeforeTest = checkerOutcomeBefore .checkProcessOutcome(bpmnProcess.getName()); if (outcomeBeforeTest == BPMNProcessInstanceOutcomeChecker.ProcessInstanceOutcome.UNDEPLOYED_PROCESS) { BPMNAssertions.appendToFile(instanceLogFile, BPMNAssertions.ERROR_DEPLOYMENT); } } else if (testStep instanceof StartProcess) { try { StartProcess processStartWithVariablesTestStep = (StartProcess) testStep; List<Variable> variables = processStartWithVariablesTestStep.getVariables(); processStarter.start(processStartWithVariablesTestStep.getProcessName(), variables); } catch (Exception e) { LOGGER.info("Could not start process", e); BPMNProcessInstanceOutcomeChecker.ProcessInstanceOutcome outcomeAfterTest = checkerOutcomeAfter.checkProcessOutcome(bpmnProcess.getName()); if (outcomeAfterTest == BPMNProcessInstanceOutcomeChecker.ProcessInstanceOutcome.PROCESS_INSTANCE_ABORTED_BECAUSE_ERROR_EVENT_THROWN) { // do not log at this time } else { BPMNAssertions.appendToFile(instanceLogFile, BPMNAssertions.ERROR_RUNTIME); } } } else if (testStep instanceof DelayTesting) { WaitTasks.sleep(((DelayTesting) testStep).getMilliseconds()); } else if (testStep instanceof GatherTraces) { if(shouldDeploymentFail(testStep)) { // Skip further processing if process is expected to be undeployed break; } BPMNProcessInstanceOutcomeChecker.ProcessInstanceOutcome outcomeAfterTest = checkerOutcomeAfter.checkProcessOutcome(bpmnProcess.getName()); if (outcomeAfterTest == BPMNProcessInstanceOutcomeChecker.ProcessInstanceOutcome.RUNTIME) { BPMNAssertions.appendToFile(instanceLogFile, BPMNAssertions.ERROR_RUNTIME); } else if (outcomeAfterTest == BPMNProcessInstanceOutcomeChecker.ProcessInstanceOutcome.PROCESS_INSTANCE_ABORTED_BECAUSE_ERROR_EVENT_THROWN) { BPMNAssertions.appendToFile(instanceLogFile, BPMNAssertions.ERROR_THROWN_ERROR_EVENT); } else if (outcomeAfterTest == BPMNProcessInstanceOutcomeChecker.ProcessInstanceOutcome.PROCESS_INSTANCE_ABORTED) { BPMNAssertions.appendToFile(instanceLogFile, BPMNAssertions.ERROR_PROCESS_ABORTED); } else if (outcomeAfterTest == BPMNProcessInstanceOutcomeChecker.ProcessInstanceOutcome.PROCESS_INSTANCE_ABORTED_BECAUSE_ERROR_EVENT_THROWN) { BPMNAssertions.appendToFile(instanceLogFile, BPMNAssertions.ERROR_THROWN_ERROR_EVENT); } else if (outcomeAfterTest == BPMNProcessInstanceOutcomeChecker.ProcessInstanceOutcome.PROCESS_INSTANCE_ABORTED_BECAUSE_ESCALATION_EVENT_THROWN) { BPMNAssertions.appendToFile(instanceLogFile, BPMNAssertions.ERROR_THROWN_ESCALATION_EVENT); } // Check on parallel execution BPMNEnginesUtil.checkParallelExecution(testCase, instanceLogFile); // Check whether MARKER file exists BPMNEnginesUtil.checkMarkerFileExists(testCase, instanceLogFile); // Check data type BPMNEnginesUtil.checkDataLog(testCase, instanceLogFile); BPMNEnginesUtil.substituteSpecificErrorsForGenericError(testCase, instanceLogFile); } } LOGGER.info("contents of log file " + instanceLogFile + ": " + FileTasks.readAllLines(instanceLogFile)); bpmnTester.test(); } private boolean shouldDeploymentFail(TestStep testStep) { if(testStep.getTestAssertions().stream().filter(a -> a instanceof AssertTrace && ((AssertTrace) a).getTrace().equals( BPMNAssertions.ERROR_DEPLOYMENT.toString())) .findFirst().isPresent()) { // Ensure existence of instanceLogFile for JUnit test execution if(!Files.exists(instanceLogFile)) { try { Files.createFile(instanceLogFile); } catch (IOException e) { LOGGER.warn("Creation of log file failed.", e); } } return true; } return false; } }