diff --git a/addons/common/persistence/filesystem/src/main/java/org/kie/kogito/persistence/KogitoProcessInstancesFactory.java b/addons/common/persistence/filesystem/src/main/java/org/kie/kogito/persistence/KogitoProcessInstancesFactory.java index 24a64cfdcb6..cc8b6fec9c9 100644 --- a/addons/common/persistence/filesystem/src/main/java/org/kie/kogito/persistence/KogitoProcessInstancesFactory.java +++ b/addons/common/persistence/filesystem/src/main/java/org/kie/kogito/persistence/KogitoProcessInstancesFactory.java @@ -33,4 +33,6 @@ public FileSystemProcessInstances createProcessInstances(Process process) { public abstract String path(); + public abstract void setPath(String path); + } diff --git a/addons/common/persistence/filesystem/src/test/java/org/kie/persistence/filesystem/FileSystemProcessInstancesTest.java b/addons/common/persistence/filesystem/src/test/java/org/kie/persistence/filesystem/FileSystemProcessInstancesTest.java index 0ed2e6761fc..300b150abc7 100644 --- a/addons/common/persistence/filesystem/src/test/java/org/kie/persistence/filesystem/FileSystemProcessInstancesTest.java +++ b/addons/common/persistence/filesystem/src/test/java/org/kie/persistence/filesystem/FileSystemProcessInstancesTest.java @@ -244,5 +244,11 @@ public FileSystemProcessInstances createProcessInstances(Process process) { public String path() { return "target"; } + + @Override + public void setPath(String path) { + // TODO Auto-generated method stub + + } } } diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstances.java b/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstances.java index fd22acd8db5..443b59e574e 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstances.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstances.java @@ -30,6 +30,19 @@ default Collection> values() { return values(ProcessInstanceReadMode.READ_ONLY); } + default Optional> findByBusinessKey(String businessKey) { + return findByBusinessKey(businessKey, ProcessInstanceReadMode.READ_ONLY); + } + + default Optional> findByBusinessKey(String businessKey, ProcessInstanceReadMode mode) { + for (ProcessInstance instance : values(mode)) { + if (businessKey.equals(instance.businessKey())) { + return Optional.of(instance); + } + } + return Optional.empty(); + } + Collection> values(ProcessInstanceReadMode mode); Integer size(); diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/Processes.java b/api/kogito-api/src/main/java/org/kie/kogito/process/Processes.java index c74fea8edb1..40150283060 100644 --- a/api/kogito-api/src/main/java/org/kie/kogito/process/Processes.java +++ b/api/kogito-api/src/main/java/org/kie/kogito/process/Processes.java @@ -33,4 +33,8 @@ default void activate() { default void deactivate() { } + + default ProcessInstancesFactory processInstancesFactory() { + return null; + } } diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java b/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java index 0864fe02e4b..0b1eefad9c7 100644 --- a/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java +++ b/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java @@ -55,6 +55,13 @@ public ProcessInstance createInstance() { return new BpmnProcessInstance(this, createModel(), this.createProcessRuntime()); } + @Override + public ProcessInstance createInstance(String businessKey, Model m) { + BpmnVariables vars = new BpmnVariables(); + vars.fromMap(m.toMap()); + return createInstance(businessKey, vars); + } + @Override public ProcessInstance createInstance(String businessKey, BpmnVariables variables) { BpmnVariables variablesModel = createModel(); diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightProcessRuntime.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightProcessRuntime.java index 19627b5b07a..f0fe7521b6c 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightProcessRuntime.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightProcessRuntime.java @@ -150,6 +150,7 @@ private ProcessInstance startProcess(String processId, Map param KogitoProcessInstance processInstance = createProcessInstance(processId, parameters); if (processInstance != null) { processInstanceManager.addProcessInstance(processInstance); + runtimeContext.setupParameters((org.jbpm.process.instance.ProcessInstance) processInstance, parameters); return kogitoProcessRuntime.startProcessInstance(processInstance.getStringId(), trigger, agendaFilter); } return null; @@ -164,6 +165,7 @@ public KogitoProcessInstance startProcess(String processId, CorrelationKey corre KogitoProcessInstance processInstance = createProcessInstance(processId, correlationKey, parameters); if (processInstance != null) { processInstanceManager.addProcessInstance(processInstance); + runtimeContext.setupParameters((org.jbpm.process.instance.ProcessInstance) processInstance, parameters); return (KogitoProcessInstance) startProcessInstance(processInstance.getId()); } return null; @@ -188,7 +190,6 @@ public KogitoProcessInstance createProcessInstance(String processId, Correlation private org.jbpm.process.instance.ProcessInstance createProcessInstance(Process process, CorrelationKey correlationKey, Map parameters) { org.jbpm.process.instance.ProcessInstance pi = runtimeContext.createProcessInstance(process, correlationKey); pi.setKnowledgeRuntime(knowledgeRuntime); - runtimeContext.setupParameters(pi, parameters); return pi; } diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightWorkItemManager.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightWorkItemManager.java index 590d6faeec2..f90ddb5cbdb 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightWorkItemManager.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/LightWorkItemManager.java @@ -27,6 +27,7 @@ import java.util.function.Function; import org.drools.core.process.instance.WorkItem; +import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemHandler; import org.jbpm.process.instance.impl.workitem.Abort; import org.jbpm.process.instance.impl.workitem.Active; import org.jbpm.process.instance.impl.workitem.Complete; @@ -205,7 +206,9 @@ private void transitionWorkItem(InternalKogitoWorkItem workItem, Transition t workItem.setResults((Map) transition.data()); workItem.setPhaseId(Complete.ID); workItem.setPhaseStatus(Complete.STATUS); - completePhase.apply(workItem, transition); + if (handler instanceof HumanTaskWorkItemHandler) { + completePhase.apply(workItem, transition); + } internalCompleteWorkItem(workItem); } processInstance.signalEvent("workItemTransition", transition); diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/RuleSetNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/RuleSetNode.java index b2067182d78..771b69ce52b 100755 --- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/RuleSetNode.java +++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/RuleSetNode.java @@ -41,6 +41,10 @@ public class RuleSetNode extends StateBasedNode implements ContextContainer, Mappable { + public RuleSetNode() { + // do nothing + } + public static abstract class RuleType implements Serializable { private static final String UNIT_RULEFLOW_PREFIX = "unit:"; diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java index 774487ccc05..dad125a641f 100644 --- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java +++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java @@ -215,6 +215,10 @@ public void setProcessInstancesFactory(ProcessInstancesFactory processInstancesF this.processInstancesFactory = processInstancesFactory; } + public ProcessInstancesFactory getProcessInstancesFactory() { + return processInstancesFactory; + } + public EventListener eventListener() { return completionEventListener; } diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java index a0db9ee297c..bf13e90a2ce 100644 --- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java +++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java @@ -222,6 +222,10 @@ public void start(String trigger, String referenceId) { getProcessRuntime().getProcessInstanceManager().addProcessInstance(this.processInstance); this.id = processInstance.getStringId(); addCompletionEventListener(); + + for (Entry entry : variables.toMap().entrySet()) { + processInstance().setVariable(entry.getKey(), entry.getValue()); + } KogitoProcessInstance processInstance = getProcessRuntime().getKogitoProcessRuntime().startProcessInstance(this.id, trigger); addToUnitOfWork(pi -> ((MutableProcessInstances) process.instances()).create(pi.id(), pi)); unbind(variables, processInstance.getVariables()); diff --git a/kogito-bom/pom.xml b/kogito-bom/pom.xml index 730d8c8dd21..d186d1fa7ae 100755 --- a/kogito-bom/pom.xml +++ b/kogito-bom/pom.xml @@ -1807,6 +1807,28 @@ kogito-spring-boot-test-utils ${project.version} + + + org.kie.kogito + kogito-junit5-extension + ${project.version} + + + org.kie.kogito + kogito-junit5-core + ${project.version} + + + org.kie.kogito + kogito-junit5-runtime-java + ${project.version} + + + org.kie.kogito + kogito-junit5-persistence-fs + ${project.version} + + diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessContainerGenerator.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessContainerGenerator.java index 49441f1e5f4..325ee64bb5c 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessContainerGenerator.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/ProcessContainerGenerator.java @@ -24,12 +24,16 @@ import org.kie.kogito.codegen.api.template.InvalidTemplateException; import org.kie.kogito.codegen.api.template.TemplatedGenerator; import org.kie.kogito.codegen.core.AbstractApplicationSection; +import org.kie.kogito.process.ProcessInstancesFactory; import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.Modifier.Keyword; import com.github.javaparser.ast.NodeList; -import com.github.javaparser.ast.body.BodyDeclaration; +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; +import com.github.javaparser.ast.body.VariableDeclarator; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.LambdaExpr; import com.github.javaparser.ast.expr.MethodCallExpr; @@ -40,6 +44,7 @@ import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.stmt.IfStmt; import com.github.javaparser.ast.stmt.ReturnStmt; +import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.ast.type.UnknownType; import static com.github.javaparser.ast.NodeList.nodeList; @@ -49,7 +54,6 @@ public class ProcessContainerGenerator extends AbstractApplicationSection { public static final String SECTION_CLASS_NAME = "Processes"; private final List processes; - private final List> factoryMethods; private BlockStmt byProcessIdBody = new BlockStmt(); private BlockStmt processesBody = new BlockStmt(); @@ -58,11 +62,11 @@ public class ProcessContainerGenerator extends AbstractApplicationSection { public ProcessContainerGenerator(KogitoBuildContext context) { super(context, SECTION_CLASS_NAME); this.processes = new ArrayList<>(); - this.factoryMethods = new ArrayList<>(); this.templatedGenerator = TemplatedGenerator.builder() .withTargetTypeName(SECTION_CLASS_NAME) .build(context, "ProcessContainer"); + } public void addProcess(ProcessGenerator p) { @@ -74,6 +78,9 @@ public void addProcessToApplication(ProcessGenerator r) { ObjectCreationExpr newProcess = new ObjectCreationExpr() .setType(r.targetCanonicalName()) .addArgument("application"); + if (context.getAddonsConfig().usePersistence() && !context.hasDI()) { + newProcess.addArgument("processInstancesFactory"); + } MethodCallExpr expr = new MethodCallExpr(newProcess, "configure"); MethodCallExpr method = new MethodCallExpr(new NameExpr("mappedProcesses"), "computeIfAbsent", nodeList(new StringLiteralExpr(r.processId()), @@ -90,6 +97,27 @@ public CompilationUnit compilationUnit() { CompilationUnit compilationUnit = templatedGenerator.compilationUnitOrThrow("Invalid Template: No CompilationUnit"); registerProcessesExplicitly(compilationUnit); + if (context.getAddonsConfig().usePersistence() && !context.hasDI()) { + ClassOrInterfaceDeclaration clazz = compilationUnit.findFirst(ClassOrInterfaceDeclaration.class).get(); + + Expression expression = new ObjectCreationExpr(null, new ClassOrInterfaceType(null, "org.kie.kogito.persistence.KogitoProcessInstancesFactoryImpl"), NodeList.nodeList()); + FieldDeclaration pathField = new FieldDeclaration().addVariable(new VariableDeclarator() + .setType(new ClassOrInterfaceType(null, ProcessInstancesFactory.class.getCanonicalName())) + .setName("processInstancesFactory") + .setInitializer(expression)); + + clazz.addMember(pathField); + + BlockStmt getMethodBody = new BlockStmt(); + getMethodBody.addStatement(new ReturnStmt(new NameExpr("processInstancesFactory"))); + + MethodDeclaration getMethod = new MethodDeclaration() + .addModifier(Keyword.PUBLIC) + .setName("processInstancesFactory") + .setType("org.kie.kogito.process.ProcessInstancesFactory") + .setBody(getMethodBody); + clazz.addMember(getMethod); + } return compilationUnit; } diff --git a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/persistence/PersistenceGenerator.java b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/persistence/PersistenceGenerator.java index dc7f49db118..d47957958cf 100644 --- a/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/persistence/PersistenceGenerator.java +++ b/kogito-codegen-modules/kogito-codegen-processes/src/main/java/org/kie/kogito/codegen/process/persistence/PersistenceGenerator.java @@ -50,6 +50,8 @@ import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.body.VariableDeclarator; +import com.github.javaparser.ast.expr.AssignExpr; +import com.github.javaparser.ast.expr.AssignExpr.Operator; import com.github.javaparser.ast.expr.BooleanLiteralExpr; import com.github.javaparser.ast.expr.ConditionalExpr; import com.github.javaparser.ast.expr.EnclosedExpr; @@ -394,28 +396,48 @@ protected Collection fileSystemBasedPersistence() { .addExtendedType(KOGITO_PROCESS_INSTANCE_FACTORY_PACKAGE); Optional generatedClientFile = Optional.empty(); + if (context().hasDI()) { context().getDependencyInjectionAnnotator().withApplicationComponent(persistenceProviderClazz); + } - FieldDeclaration pathField = new FieldDeclaration().addVariable(new VariableDeclarator() - .setType(new ClassOrInterfaceType(null, new SimpleName(Optional.class.getCanonicalName()), NodeList.nodeList(new ClassOrInterfaceType(null, String.class.getCanonicalName())))) - .setName(PATH_NAME)); + FieldDeclaration pathField = new FieldDeclaration().addVariable(new VariableDeclarator() + .setType(new ClassOrInterfaceType(null, new SimpleName(Optional.class.getCanonicalName()), NodeList.nodeList(new ClassOrInterfaceType(null, String.class.getCanonicalName())))) + .setName(PATH_NAME)); + + if (context().hasDI()) { context().getDependencyInjectionAnnotator().withConfigInjection(pathField, KOGITO_PERSISTENCE_FS_PATH_PROP); - // allow to inject path for the file system storage - BlockStmt pathMethodBody = new BlockStmt(); - pathMethodBody.addStatement(new ReturnStmt(new MethodCallExpr(new NameExpr(PATH_NAME), OR_ELSE).addArgument(new StringLiteralExpr("/tmp")))); + } - MethodDeclaration pathMethod = new MethodDeclaration() - .addModifier(Keyword.PUBLIC) - .setName(PATH_NAME) - .setType(String.class) - .setBody(pathMethodBody); + BlockStmt setPathMethodBody = new BlockStmt(); + setPathMethodBody.addStatement(new AssignExpr(new NameExpr(PATH_NAME), + new MethodCallExpr(new NameExpr("java.util.Optional"), "of").addArgument("storagePath"), Operator.ASSIGN)); + + ClassOrInterfaceType type = new ClassOrInterfaceType(null, "java.lang.String"); + Parameter param = new Parameter(type, "storagePath"); + MethodDeclaration setPathMethod = new MethodDeclaration() + .addModifier(Keyword.PUBLIC) + .setName("setPath") + .setType("void") + .addParameter(param) + .setBody(setPathMethodBody); + + // allow to inject path for the file system storage + BlockStmt pathMethodBody = new BlockStmt(); + pathMethodBody.addStatement(new ReturnStmt(new MethodCallExpr(new NameExpr(PATH_NAME), OR_ELSE).addArgument(new StringLiteralExpr("/tmp")))); + + MethodDeclaration pathMethod = new MethodDeclaration() + .addModifier(Keyword.PUBLIC) + .setName(PATH_NAME) + .setType(String.class) + .setBody(pathMethodBody); + + persistenceProviderClazz.addMember(pathField); + persistenceProviderClazz.addMember(pathMethod); + persistenceProviderClazz.addMember(setPathMethod); + generatedClientFile = generatePersistenceProviderClazz(persistenceProviderClazz, + new CompilationUnit(KOGITO_PROCESS_INSTANCE_PACKAGE).addType(persistenceProviderClazz)); - persistenceProviderClazz.addMember(pathField); - persistenceProviderClazz.addMember(pathMethod); - generatedClientFile = generatePersistenceProviderClazz(persistenceProviderClazz, - new CompilationUnit(KOGITO_PROCESS_INSTANCE_PACKAGE).addType(persistenceProviderClazz)); - } Collection generatedFiles = protobufBasedPersistence(); generatedClientFile.ifPresent(generatedFiles::add); diff --git a/kogito-tck/kogito-junit-examples/pom.xml b/kogito-tck/kogito-junit-examples/pom.xml new file mode 100644 index 00000000000..a76848ab69a --- /dev/null +++ b/kogito-tck/kogito-junit-examples/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + org.kie.kogito + kogito-tck + 2.0.0-SNAPSHOT + + + kogito-junit-examples + + Kogito Test Compatibilty Kit Test Cases Example + + + UTF-8 + standalone + src/resources/test/logging-test.properties + + + + + org.apache.commons + commons-lang3 + + + ch.qos.logback + logback-classic + test + + + + org.kie.kogito + kogito-junit5-extension + + + org.kie.kogito + kogito-junit5-core + + + + org.kie.kogito + kogito-junit5-runtime-java + + + + org.kie.kogito + kogito-junit5-persistence-fs + + + + diff --git a/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/domain/Address.java b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/domain/Address.java new file mode 100644 index 00000000000..e8a98b379a1 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/domain/Address.java @@ -0,0 +1,95 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.test.engine.domain; + +import java.io.Serializable; + +public class Address implements Serializable { + private static final long serialVersionUID = 1L; + + private String street; + private int number; + private String city; + + public Address() { + this("", 0, ""); + } + + public Address(String street, int number, String city) { + super(); + this.street = street; + this.number = number; + this.city = city; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((city == null) ? 0 : city.hashCode()); + result = prime * result + number; + result = prime * result + ((street == null) ? 0 : street.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Address other = (Address) obj; + if (city == null) { + if (other.city != null) + return false; + } else if (!city.equals(other.city)) + return false; + if (number != other.number) + return false; + if (street == null) { + if (other.street != null) + return false; + } else if (!street.equals(other.street)) + return false; + return true; + } + +} diff --git a/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/domain/Person.java b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/domain/Person.java new file mode 100644 index 00000000000..96013cb5383 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/domain/Person.java @@ -0,0 +1,132 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.test.engine.domain; + +import java.io.Serializable; + +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class Person implements Serializable { + + private static final long serialVersionUID = -5411807328989112195L; + + private int id = 0; + private String name = ""; + private int age; + private String likes; + private Address address; + + public Person() { + } + + public Person(String name) { + super(); + this.name = name; + } + + public Person(String name, int age) { + this.name = name; + this.age = age; + } + + public Person(String name, String likes, int age) { + this.name = name; + this.likes = likes; + this.age = age; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + + @Override + public String toString() { + return "Person [id=" + id + ", name=" + name + ", age=" + age + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + id; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Person other = (Person) obj; + if (id != other.id) { + return false; + } + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + return true; + } + + public void setAge(int age) { + this.age = age; + } + + public int getAge() { + return age; + } + + public void setLikes(String likes) { + this.likes = likes; + } + + public String getLikes() { + return likes; + } + +} diff --git a/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/domain/PersonUnit.java b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/domain/PersonUnit.java new file mode 100644 index 00000000000..d7adf600fdb --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/domain/PersonUnit.java @@ -0,0 +1,53 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.test.engine.domain; + +import org.kie.kogito.conf.Clock; +import org.kie.kogito.conf.ClockType; +import org.kie.kogito.conf.SessionsPool; +import org.kie.kogito.rules.DataSource; +import org.kie.kogito.rules.DataStore; +import org.kie.kogito.rules.RuleUnitData; + +@SessionsPool(1) +@Clock(ClockType.PSEUDO) +public class PersonUnit implements RuleUnitData { + + private DataStore persons; + + public PersonUnit() { + this(DataSource.createStore()); + } + + public PersonUnit(DataStore persons) { + this.persons = persons; + } + + public PersonUnit(DataStore persons, int adultAge) { + this.persons = persons; + + } + + public DataStore getPersons() { + return persons; + } + + @Override + public String toString() { + return "PersonUnit()"; + } +} diff --git a/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/event/BoundaryErrorEventTest.java b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/event/BoundaryErrorEventTest.java new file mode 100644 index 00000000000..df987246d19 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/event/BoundaryErrorEventTest.java @@ -0,0 +1,97 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.test.engine.event; + +import org.junit.jupiter.api.Test; +import org.kie.kogito.Model; +import org.kie.kogito.junit.api.KogitoUnitTestContext; +import org.kie.kogito.junit.api.KogitoUnitTestDeployment; +import org.kie.kogito.junit.api.KogitoUnitTestDeploymentException; +import org.kie.kogito.junit.api.KogitoUnitTestListeners; +import org.kie.kogito.junit.api.KogitoUnitTestResource; +import org.kie.kogito.junit.api.KogitoUnitTestWorkItemHandler; +import org.kie.kogito.junit.api.KogitoUnitTestWorkItemHandlerRegistry; +import org.kie.kogito.junit.listeners.FlowProcessEventListenerTracker; +import org.kie.kogito.junit.wih.ExceptionWorkItemHandler; +import org.kie.kogito.process.ProcessInstance; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.kie.kogito.junit.asserts.ProcessAssertions.assertThat; +import static org.kie.kogito.junit.util.ProcessUtil.startProcess; + +@KogitoUnitTestWorkItemHandlerRegistry( + entries = { @KogitoUnitTestWorkItemHandler(name = "Human Task", handler = ExceptionWorkItemHandler.class) }) +@KogitoUnitTestListeners({ FlowProcessEventListenerTracker.class }) +public class BoundaryErrorEventTest { + + private static final String PROCESS_PREFIX = "org/kie/kogito/test/engine/event/BoundaryErrorEvent-"; + private static final String PROCESS_ID = "org.jbpm.test.regression.event.BoundaryErrorEvent"; + + @Test + @KogitoUnitTestDeployment( + resources = { @KogitoUnitTestResource(path = PROCESS_PREFIX + "WithErrorCodeWithoutStructureRef.bpmn2") }) + public void testBoundaryErrorEventDefaultHandlerWithErrorCodeWithoutStructureRef(KogitoUnitTestContext context) { + ProcessInstance instance = startProcess(context, PROCESS_ID); + assertThat(context.find(FlowProcessEventListenerTracker.class)) + .checkEventsProcessInstanceThat(instance.id()) + .step("Start") + .entered("User Task"); + } + + @Test + @KogitoUnitTestDeployment( + resources = { @KogitoUnitTestResource(path = PROCESS_PREFIX + "WithErrorCodeMatchWithStructureRef.bpmn2") }) + public void testBoundaryErrorEventDefaultHandlerWithErrorCodeMatchWithStructureRef(KogitoUnitTestContext context) { + ProcessInstance instance = startProcess(context, PROCESS_ID); + assertThat(context.find(FlowProcessEventListenerTracker.class)) + .checkEventsProcessInstanceThat(instance.id()) + .step("Start") + .step("User Task") + .exited("MyBoundaryErrorEvent") + .step("Script Task 1"); + } + + @Test + @KogitoUnitTestDeployment( + resources = { @KogitoUnitTestResource(path = PROCESS_PREFIX + "WithErrorCodeMatchWithoutStructureRef.bpmn2") }) + public void testBoundaryErrorEventDefaultHandlerWithErrorCodeMatchWithoutStructureRef(KogitoUnitTestContext context) { + ProcessInstance instance = startProcess(context, PROCESS_ID); + assertThat(context.find(FlowProcessEventListenerTracker.class)) + .checkEventsProcessInstanceThat(instance.id()) + .step("Start") + .entered("User Task") + .exited("MyBoundaryErrorEvent"); + } + + @Test + @KogitoUnitTestDeployment( + resources = { @KogitoUnitTestResource(path = PROCESS_PREFIX + "WithoutErrorCodeWithStructureRef.bpmn2") }) + @KogitoUnitTestDeploymentException + public void testBoundaryErrorEventDefaultHandlerWithoutErrorCodeWithStructureRef(KogitoUnitTestContext context) { + + assertNotNull(context.find(Throwable.class)); + } + + @Test + @KogitoUnitTestDeployment( + resources = { @KogitoUnitTestResource(path = PROCESS_PREFIX + "WithoutErrorCodeWithoutStructureRef.bpmn2") }) + @KogitoUnitTestDeploymentException + public void testBoundaryErrorEventDefaultHandlerWithoutErrorCodeWithoutStructureRef(KogitoUnitTestContext context) { + assertNotNull(context.find(Throwable.class)); + } + +} diff --git a/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/CorrelationKeyTest.java b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/CorrelationKeyTest.java new file mode 100644 index 00000000000..c9b12412c56 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/CorrelationKeyTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.test.engine.flow; + +import java.util.Optional; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.kie.kogito.Model; +import org.kie.kogito.junit.api.KogitoUnitTestContext; +import org.kie.kogito.junit.api.KogitoUnitTestDeployment; +import org.kie.kogito.junit.api.KogitoUnitTestResource; +import org.kie.kogito.junit.asserts.ProcessAssertions; +import org.kie.kogito.process.ProcessInstance; + +import static org.kie.kogito.junit.util.ProcessUtil.startProcess; + +@KogitoUnitTestDeployment( + resources = { @KogitoUnitTestResource(path = "org/kie/kogito/test/engine/flow/CorrelationKey.bpmn2") }) +public class CorrelationKeyTest { + + private static final String PROCESS_ID = "org.jbpm.test.functional.CorrelationKey"; + private static final String SIMPLE_KEY = "mySimpleCorrelationKey"; + + @Test + public void testSimpleKey(KogitoUnitTestContext context) { + ProcessInstance instance = startProcess(context, PROCESS_ID, SIMPLE_KEY); + ProcessAssertions.assertThat(instance).isActive(); + + Optional> instanceFound = context.findByBusinessKey(PROCESS_ID, SIMPLE_KEY); + + Assertions.assertThat(instanceFound).isPresent(); + Assertions.assertThat(instanceFound.get().id()).isEqualTo(instance.id()); + } + + @Test + @Disabled + public void testNotUniqueSimpleKey(KogitoUnitTestContext context) { + ProcessInstance instance = startProcess(context, PROCESS_ID, SIMPLE_KEY); + ProcessAssertions.assertThat(instance).isActive(); + + try { + startProcess(context, PROCESS_ID, SIMPLE_KEY); + Assertions.fail("Not unique correlation key used. Exception should have been thrown."); + } catch (RuntimeException ex) { + ex.printStackTrace(); + Assertions.assertThat(ex.getMessage()).contains("already exists"); + } + } + + @Test + public void testGetNotExistingSimpleKey(KogitoUnitTestContext context) { + Optional> instanceFound = context.findByBusinessKey(PROCESS_ID, SIMPLE_KEY); + Assertions.assertThat(instanceFound).isEmpty(); + } + +} diff --git a/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/DataObjectTest.java b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/DataObjectTest.java new file mode 100644 index 00000000000..209cba7f9ac --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/DataObjectTest.java @@ -0,0 +1,99 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package org.kie.kogito.test.engine.flow; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.kie.api.runtime.process.WorkItem; +import org.kie.kogito.Model; +import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.junit.api.KogitoUnitTestContext; +import org.kie.kogito.junit.api.KogitoUnitTestDeployment; +import org.kie.kogito.junit.api.KogitoUnitTestResource; +import org.kie.kogito.junit.api.KogitoUnitTestWorkItemHandler; +import org.kie.kogito.junit.listeners.FlowProcessEventListenerTracker; +import org.kie.kogito.junit.util.ProcessUtil; +import org.kie.kogito.junit.wih.WorkItemHandlerTracker; +import org.kie.kogito.process.ProcessInstance; +import org.kie.kogito.test.engine.domain.Person; + +import static org.kie.kogito.junit.asserts.ProcessAssertions.assertThat; + +/** + * Testing data object and association. + */ + +public class DataObjectTest { + + public static final String PROCESS_ID = "org.jbpm.test.functional.DataObject"; + + /** + * DataObject is linked via association with Human Task. Work item should + * obtain this DataObject in parameters. + */ + @Test + @Disabled + @KogitoUnitTestDeployment( + namespace = "org.kie.kogito.test.engine.flow", + resources = { @KogitoUnitTestResource(path = "org/kie/kogito/test/engine/flow/DataObject.bpmn2") }, + workItemsHandlers = { @KogitoUnitTestWorkItemHandler(name = "Human Task", handler = WorkItemHandlerTracker.class) }, + listeners = { FlowProcessEventListenerTracker.class }) + public void testDataObject(KogitoUnitTestContext context) { + Map params = new HashMap(); + Person mojmir = new Person("Mojmir"); + params.put("person", mojmir); + + ProcessInstance instance = ProcessUtil.startProcess(context, PROCESS_ID, params); + FlowProcessEventListenerTracker listener = context.find(FlowProcessEventListenerTracker.class); + + WorkItemHandlerTracker tracker = context.find(WorkItemHandlerTracker.class); + + Collection items = tracker.getWorkItems(); + Assertions.assertTrue(items.size() == 1); + + WorkItem wi = items.iterator().next(); + Assertions.assertTrue(wi.getParameters().containsKey("PersonInput")); + Object param = wi.getParameter("PersonInput"); + Assertions.assertTrue(param instanceof Person); + Person userTaskInput = (Person) param; + Assertions.assertEquals("Mojmir", userTaskInput.getName()); + + items.forEach(item -> instance.completeWorkItem(item.getStringId(), Collections.emptyMap())); + + assertThat(listener) + .checkStepsForProcessInstance(instance.id()) + .varAssert("person", (p) -> p.equals(mojmir)) + .started() + .step("start") + .step("userTask") + .step("end") + .completed(); + + } + +} diff --git a/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/EventListenersTest.java b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/EventListenersTest.java new file mode 100644 index 00000000000..fbdb39e3d80 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/EventListenersTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.test.engine.flow; + +import org.junit.jupiter.api.Test; +import org.kie.kogito.Model; +import org.kie.kogito.junit.api.KogitoUnitTestContext; +import org.kie.kogito.junit.api.KogitoUnitTestDeployment; +import org.kie.kogito.junit.api.KogitoUnitTestResource; +import org.kie.kogito.junit.listeners.FlowProcessEventListenerTracker; +import org.kie.kogito.process.ProcessInstance; +import org.kie.kogito.process.impl.Sig; + +import static org.kie.kogito.junit.asserts.ProcessAssertions.assertThat; +import static org.kie.kogito.junit.util.ProcessUtil.startProcess; + +@KogitoUnitTestDeployment( + resources = { @KogitoUnitTestResource(path = EventListenersTest.PROCESS) }, + listeners = { FlowProcessEventListenerTracker.class }) +public class EventListenersTest { + + public static final String PROCESS = "org/kie/kogito/test/engine/flow/EventListeners.bpmn2"; + public static final String PROCESS_ID = "org.jbpm.test.functional.EventListeners"; + + @Test + public void testClearExecution(KogitoUnitTestContext context) { + ProcessInstance instance = startProcess(context, PROCESS_ID); + + FlowProcessEventListenerTracker tracker = context.find(FlowProcessEventListenerTracker.class); + instance.send(Sig.of("other-branch", "hello world!")); + assertThat(tracker) + .checkEventsProcessInstanceThat(instance.id()) + .step("introduction") + .notStep("script-warning") + .varChanged("signalData") + .varNotChanged("stringVariable") + .completed(); + + } + + @Test + public void testUnfinishedProcess(KogitoUnitTestContext context) { + ProcessInstance instance = startProcess(context, PROCESS_ID); + + FlowProcessEventListenerTracker tracker = context.find(FlowProcessEventListenerTracker.class); + + assertThat(tracker) + .checkEventsProcessInstanceThat(instance.id()) + .step("introduction") + .step("split") + .notStep("xor-gateway"); + + assertThat(instance).isActive(); + + } + + @Test + public void testBadSignal(KogitoUnitTestContext context) { + ProcessInstance instance = startProcess(context, PROCESS_ID); + + FlowProcessEventListenerTracker tracker = context.find(FlowProcessEventListenerTracker.class); + instance.send(Sig.of("bad-signal", "bad signal!")); + + assertThat(tracker) + .checkEventsProcessInstanceThat(instance.id()) + .started() + .step("introduction") + .notStep("info") + .step("script-warning") + .varNotChanged("signalData") + .varNotChanged("stringVariable") + .completed(); + + } + +} diff --git a/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/FireUntilHaltTest.java b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/FireUntilHaltTest.java new file mode 100644 index 00000000000..2d580499907 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/FireUntilHaltTest.java @@ -0,0 +1,91 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.test.engine.flow; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.kie.kogito.Model; +import org.kie.kogito.junit.api.KogitoUnitTestContext; +import org.kie.kogito.junit.api.KogitoUnitTestDeployment; +import org.kie.kogito.junit.api.KogitoUnitTestEnvironment; +import org.kie.kogito.junit.api.KogitoUnitTestEnvironmentProperty; +import org.kie.kogito.junit.api.KogitoUnitTestResource; +import org.kie.kogito.junit.api.KogitoUnitTestResourceType; +import org.kie.kogito.junit.listeners.FlowProcessEventListenerTracker; +import org.kie.kogito.junit.listeners.TrackingAgendaEventListener; +import org.kie.kogito.process.ProcessInstance; +import org.kie.kogito.test.engine.domain.Person; + +import static java.util.Collections.singletonMap; +import static org.assertj.core.api.Assertions.assertThat; +import static org.kie.kogito.junit.asserts.ProcessAssertions.assertThat; +import static org.kie.kogito.junit.util.ProcessUtil.startProcess; + +/** + * Tests fireUntilHalt with jBPM process - this test makes sense only with singleton strategy + */ + +@KogitoUnitTestEnvironment( + entries = @KogitoUnitTestEnvironmentProperty(name = "org.jbpm.rule.task.waitstate", value = "true")) +public class FireUntilHaltTest { + + private static final String PROCESS = "org/kie/kogito/test/engine/flow/FireUntilHalt.bpmn2"; + private static final String PROCESS_DRL = "org/kie/kogito/test/engine/flow/FireUntilHalt.drl"; + private static final String PROCESS_ID = "org.jbpm.test.functional.FireUntilHalt"; + + @Test + @KogitoUnitTestDeployment( + resources = { @KogitoUnitTestResource(path = PROCESS), + @KogitoUnitTestResource(path = PROCESS_DRL, type = KogitoUnitTestResourceType.RULES) }, + listeners = { FlowProcessEventListenerTracker.class, TrackingAgendaEventListener.class }) + public void testFireUntilHaltWithProcess(KogitoUnitTestContext context) throws Exception { + + List persons = new ArrayList<>(); + + final int wantedPersonsNum = 3; + final int unwantedPersonsNum = 2; + + // insert 3 wanted persons + for (int i = 0; i < wantedPersonsNum; i++) { + Person p = new Person("wanted person"); + p.setId(i); + persons.add(p); + } + // insert 2 unwanted persons + for (int i = 0; i < unwantedPersonsNum; i++) { + Person p = new Person("unwanted person"); + p.setId(i); + persons.add(p); + } + + ProcessInstance pi = startProcess(context, PROCESS_ID, singletonMap("persons", persons)); + + TrackingAgendaEventListener listener = context.find(TrackingAgendaEventListener.class); + + // wantedPersonsNum + unwantedPersonsNum should be acknowledge + assertThat(listener.ruleFiredCount("person detector")).isEqualTo(wantedPersonsNum + unwantedPersonsNum); + + // we start defined process + assertThat(listener.ruleFiredCount("initial actions")).isEqualTo(1); + assertThat(listener.ruleFiredCount("wanted person detector")).isEqualTo(wantedPersonsNum); + assertThat(listener.ruleFiredCount("change unwanted person to wanted")).isEqualTo(unwantedPersonsNum); + assertThat(pi).isCompleted(); + } + +} diff --git a/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/FlexibleProcessTest.java b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/FlexibleProcessTest.java new file mode 100644 index 00000000000..d5bdb469f44 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/FlexibleProcessTest.java @@ -0,0 +1,121 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package org.kie.kogito.test.engine.flow; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.kie.kogito.Model; +import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.junit.api.KogitoUnitTestContext; +import org.kie.kogito.junit.api.KogitoUnitTestDeployment; +import org.kie.kogito.junit.api.KogitoUnitTestResource; +import org.kie.kogito.junit.api.KogitoUnitTestWorkItemHandler; +import org.kie.kogito.junit.listeners.FlowProcessEventListenerTracker; +import org.kie.kogito.junit.wih.WorkItemHandlerTracker; +import org.kie.kogito.process.ProcessInstance; +import org.kie.kogito.process.impl.Sig; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.kie.kogito.junit.asserts.ProcessAssertions.assertThat; +import static org.kie.kogito.junit.util.ProcessUtil.startProcess; + +@KogitoUnitTestDeployment( + resources = { @KogitoUnitTestResource(path = FlexibleProcessTest.PROCESS) }, + listeners = { FlowProcessEventListenerTracker.class }, + workItemsHandlers = { @KogitoUnitTestWorkItemHandler(name = "Human Task", handler = WorkItemHandlerTracker.class), + @KogitoUnitTestWorkItemHandler(name = "addedWorkItem", handler = WorkItemHandlerTracker.class) }) +public class FlexibleProcessTest { + + public static final String PROCESS = "org/kie/kogito/test/engine/flow/FlexibleProcess.bpmn2"; + public static final String PROCESS_ID = "org.jbpm.test.functional.FlexibleProcess"; + + /** + * Flexible process with four fragments. -default - with start node, without + * end event -two fragments which will be signaled -one fragment which won't + * be signaled - it should not be executed + */ + @Test + public void testFlexibleProcess(KogitoUnitTestContext context) throws Exception { + ProcessInstance instance = startProcess(context, PROCESS_ID); + + FlowProcessEventListenerTracker tracker = context.find(FlowProcessEventListenerTracker.class); + WorkItemHandlerTracker handler = context.find(WorkItemHandlerTracker.class); + + assertThat(tracker) + .checkEventsProcessInstanceThat(instance.id()) + .step("start") + .step("task1"); + + instance.send(Sig.of("userTask", null)); + + assertThat(tracker) + .checkEventsProcessInstanceThat(instance.id()) + .entered("userTask"); + + assertThat(tracker.eventsForProcess(instance.id())).isNotEmpty(); + + KogitoWorkItem item = handler.getWorkItems().iterator().next(); + + instance.completeWorkItem(item.getStringId(), null); + + assertThat(tracker) + .checkEventsProcessInstanceThat(instance.id()) + .entered("userTask2"); + + instance.send(Sig.of("task21", null)); + + assertThat(tracker) + .checkEventsProcessInstanceThat(instance.id()) + .step("task21") + .step("task22") + .step("end1") + .completed() + .notEntered("task3") + .notEntered("end2"); + } + + /** + * Tests dynamic insertion of work item node into adhoc top-level process. + * DynamicUtils does not support adhoc processes yet, but there is improved + * version on jbpm master branch. + */ + @Test + @Disabled + public void testFlexibleProcessAddWorkItem(KogitoUnitTestContext context) { + ProcessInstance instance = startProcess(context, PROCESS_ID); + + FlowProcessEventListenerTracker tracker = context.find(FlowProcessEventListenerTracker.class); + WorkItemHandlerTracker handler = context.find(WorkItemHandlerTracker.class); + + assertThat(tracker) + .checkEventsProcessInstanceThat(instance.id()) + .started(); + // this is no where to find supported ? + // DynamicUtils.addDynamicWorkItem(pi, instance., "addedWorkItem", Collections.emptyMap()); + + KogitoWorkItem item = handler.getWorkItems().iterator().next(); + instance.completeWorkItem(item.getStringId(), null); + + assertThat(item.getName()).isEqualTo("addedWorkItem"); + } + +} diff --git a/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/LaneTest.java b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/LaneTest.java new file mode 100644 index 00000000000..d78cb33b9f3 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/flow/LaneTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package org.kie.kogito.test.engine.flow; + +import org.junit.jupiter.api.Test; +import org.kie.kogito.Model; +import org.kie.kogito.junit.api.KogitoUnitTestContext; +import org.kie.kogito.junit.api.KogitoUnitTestDeployment; +import org.kie.kogito.junit.api.KogitoUnitTestResource; +import org.kie.kogito.junit.asserts.ProcessAssertions; +import org.kie.kogito.junit.listeners.FlowProcessEventListenerTracker; +import org.kie.kogito.process.ProcessInstance; + +import static org.kie.kogito.junit.util.ProcessUtil.startProcess; + +/** + * Simple testing of lanes - there is nothing special to test. + */ +public class LaneTest { + + public static final String PROCESS = "org/kie/kogito/test/engine/flow/Lane.bpmn2"; + public static final String PROCESS_ID = "org.jbpm.test.functional.Lane"; + + @Test + @KogitoUnitTestDeployment( + resources = { @KogitoUnitTestResource(path = PROCESS) }, + listeners = { FlowProcessEventListenerTracker.class }) + public void testLane(KogitoUnitTestContext context) { + ProcessInstance instance = startProcess(context, PROCESS_ID); + + FlowProcessEventListenerTracker tracker = context.find(FlowProcessEventListenerTracker.class); + ProcessAssertions.assertThat(tracker) + .checkStepsForProcessInstance(instance.id()) + .started() + .step("start") + .entered("fork") + .exited("fork") + .step("scriptTask2") + .step("end2") + .exited("fork") + .step("scriptTask1") + .step("end1") + .completed(); + } + +} diff --git a/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/subprocess/AdHocSubprocessTest.java b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/subprocess/AdHocSubprocessTest.java new file mode 100644 index 00000000000..fc5442d3e11 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/java/org/kie/kogito/test/engine/subprocess/AdHocSubprocessTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.test.engine.subprocess; + +import org.junit.jupiter.api.Test; +import org.kie.kogito.junit.api.KogitoUnitTestContext; +import org.kie.kogito.junit.api.KogitoUnitTestDeployment; +import org.kie.kogito.junit.api.KogitoUnitTestDeploymentException; +import org.kie.kogito.junit.api.KogitoUnitTestResource; +import org.kie.kogito.junit.listeners.FlowProcessEventListenerTracker; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class AdHocSubprocessTest { + + private static final String EMPTY_COMPLETION_CONDITION = + "org/kie/kogito/test/engine/subprocess/AdHocSubprocess-emptyCompletionCondition.bpmn2"; + + @Test + @KogitoUnitTestDeployment( + resources = { @KogitoUnitTestResource(path = EMPTY_COMPLETION_CONDITION) }, + listeners = { FlowProcessEventListenerTracker.class }) + @KogitoUnitTestDeploymentException + public void testEmptyCompletionCondition(KogitoUnitTestContext context) { + assertNotNull(context.find(Throwable.class)); + } + +} diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/junit-platform.properties b/kogito-tck/kogito-junit-examples/src/test/resources/junit-platform.properties new file mode 100644 index 00000000000..003f0895fd6 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/junit-platform.properties @@ -0,0 +1,3 @@ +junit.jupiter.extensions.autodetection.enabled=true +junit.jupiter.testinstance.lifecycle.default=per_class +junit.jupiter.execution.parallel.enabled=true \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/logback-test.xml b/kogito-tck/kogito-junit-examples/src/test/resources/logback-test.xml new file mode 100644 index 00000000000..99d6c50da62 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/logback-test.xml @@ -0,0 +1,21 @@ + + + + + + + + %d [%t] %-5p %m%n + + + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/AsyncDataExecutor.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/AsyncDataExecutor.bpmn2 new file mode 100644 index 00000000000..c33f7fe6614 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/AsyncDataExecutor.bpmn2 @@ -0,0 +1,200 @@ + + + + + + + + + + + + _D519CA30-57FB-40B7-A7EE-8280EDF92881 + + + _D519CA30-57FB-40B7-A7EE-8280EDF92881 + _A7A79CEC-E977-42B6-8EC3-E97F235866E3 + + + + + + + _85216098-3371-4858-BF6E-B9924580B87B + _CE2E7B58-6AFB-410D-B16D-E7AE8BB7B81F + + + + + _A7A79CEC-E977-42B6-8EC3-E97F235866E3 + _85216098-3371-4858-BF6E-B9924580B87B + + + + + + + _870BEA75-CEE4-4E98-8C41-6BFBDACB0D78_CommandClassInputX + _870BEA75-CEE4-4E98-8C41-6BFBDACB0D78_UserInInputX + _870BEA75-CEE4-4E98-8C41-6BFBDACB0D78_TaskNameInputX + + + _870BEA75-CEE4-4E98-8C41-6BFBDACB0D78_UserOutOutputX + + + + _870BEA75-CEE4-4E98-8C41-6BFBDACB0D78_TaskNameInputX + + async + _870BEA75-CEE4-4E98-8C41-6BFBDACB0D78_TaskNameInputX + + + + command + _870BEA75-CEE4-4E98-8C41-6BFBDACB0D78_CommandClassInputX + + + user + _870BEA75-CEE4-4E98-8C41-6BFBDACB0D78_UserInInputX + + + _870BEA75-CEE4-4E98-8C41-6BFBDACB0D78_UserOutOutputX + user + + + + _CE2E7B58-6AFB-410D-B16D-E7AE8BB7B81F + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _aV964BCpEeSRMc8_ZkNxBg + _aV964BCpEeSRMc8_ZkNxBg + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/HelloWorldProcess1.bpmn b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/HelloWorldProcess1.bpmn new file mode 100644 index 00000000000..ff909eab4f2 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/HelloWorldProcess1.bpmn @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/HelloWorldProcess2.bpmn b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/HelloWorldProcess2.bpmn new file mode 100644 index 00000000000..1985f514c47 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/HelloWorldProcess2.bpmn @@ -0,0 +1,221 @@ + + + + + + + + + + + + _26020D52-3E6B-4A7E-B373-B1D45AC44BD0 + + + _26020D52-3E6B-4A7E-B373-B1D45AC44BD0 + _5E0C042F-ADF8-4703-B6C0-2CDEA4852EEE + + + + _D902F506-30A2-4E76-A866-BE5BAAE1BE55 + + + + _CF4C96F9-3131-45DA-9963-35D7F8028424 + _B3D9BDA7-6C05-4833-9FA2-207D25C81415 + _A1386BB9-4B7D-4CDF-A34E-705F307F6591 + + + _B6F8DF5F-57AC-44DB-9C92-FC0FF53ABDD5 + _B3D9BDA7-6C05-4833-9FA2-207D25C81415 + + + + _A1386BB9-4B7D-4CDF-A34E-705F307F6591 + _D902F506-30A2-4E76-A866-BE5BAAE1BE55 + + + + + + + + + _5E0C042F-ADF8-4703-B6C0-2CDEA4852EEE + _CF4C96F9-3131-45DA-9963-35D7F8028424 + _B6F8DF5F-57AC-44DB-9C92-FC0FF53ABDD5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _8Wj84JKGEeSzKuqwkg58Fg + _8Wj84JKGEeSzKuqwkg58Fg + + diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/HumanTask.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/HumanTask.bpmn2 new file mode 100644 index 00000000000..286a6872482 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/HumanTask.bpmn2 @@ -0,0 +1,74 @@ + + + + + _B2922E55-53E6-4D2B-AD8B-E60085D0526A + + + + + + + + + + + _B2922E55-53E6-4D2B-AD8B-E60085D0526A + _923B162E-5192-456B-929F-F0D6DA7DED68 + + + + + _C5F413C5-E92E-41BC-AA96-2BD52A474782_SkippableInput + _C5F413C5-E92E-41BC-AA96-2BD52A474782_TaskNameInput + + + + + _C5F413C5-E92E-41BC-AA96-2BD52A474782_TaskNameInput + + user task + _C5F413C5-E92E-41BC-AA96-2BD52A474782_TaskNameInput + + + + _C5F413C5-E92E-41BC-AA96-2BD52A474782_SkippableInput + + false + _C5F413C5-E92E-41BC-AA96-2BD52A474782_SkippableInput + + + + + john + + + + + _923B162E-5192-456B-929F-F0D6DA7DED68 + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/HumanTaskWithMultipleActors.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/HumanTaskWithMultipleActors.bpmn2 new file mode 100644 index 00000000000..76b942e9dc3 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/HumanTaskWithMultipleActors.bpmn2 @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + SequenceFlow_1 + + + + + + + + SequenceFlow_1 + SequenceFlow_2 + + + + + + + + + + + _DataInput_9 + _DataInput_10 + _DataInput_11 + _DataInput_12 + _DataInput_13 + _DataInput_14 + _DataInput_15 + + + + + + _DataInput_9 + + + _DataInput_10 + + + _DataInput_11 + + + _DataInput_12 + + + _DataInput_13 + + + _DataInput_14 + + + _DataInput_15 + + + + krisv + + + + + john + + + + + + + SequenceFlow_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/ParentProcessInfo-Caller.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/ParentProcessInfo-Caller.bpmn2 new file mode 100644 index 00000000000..e2845f2aa2d --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/ParentProcessInfo-Caller.bpmn2 @@ -0,0 +1,69 @@ + + + + + + + + + + + bpmn20:_14880C49-7E1A-43A1-94C7-EA2D793EF63D + + + bpmn20:_14880C49-7E1A-43A1-94C7-EA2D793EF63D + bpmn20:_EEE00E24-387C-4E45-9CB2-1E3E4344F5EB + + + + + + + DataOutput_3 + DataOutput_4 + DataOutput_5 + + + + DataOutput_3 + _parentProcessInstanceId + + + DataOutput_4 + _parentNodeInstanceId + + + DataOutput_5 + _parentNodeId + + + + + bpmn20:_EEE00E24-387C-4E45-9CB2-1E3E4344F5EB + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/ParentProcessInfo.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/ParentProcessInfo.bpmn2 new file mode 100644 index 00000000000..07b54044cab --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/common/ParentProcessInfo.bpmn2 @@ -0,0 +1,53 @@ + + + + + + _53C28B63-0536-47F9-8C48-A93B80EB1024 + + + _53C28B63-0536-47F9-8C48-A93B80EB1024 + _AA96716C-BFA5-478A-9E24-B719D534067B + System.out.println("Loading information about parent process ..."); + +org.jbpm.process.instance.ProcessInstance processInstance = (org.jbpm.process.instance.ProcessInstance) kcontext.getProcessInstance(); +java.util.Map<String, Object> metaData = processInstance.getMetaData(); + +kcontext.setVariable("parentProcessInstanceId", metaData.get("ParentProcessInstanceId")); +kcontext.setVariable("parentNodeInstanceId", metaData.get("ParentNodeInstanceId")); +kcontext.setVariable("parentNodeId", metaData.get("ParentNodeId")); + +System.out.println("\tParentProcessInstanceId=" + metaData.get("ParentProcessInstanceId")); +System.out.println("\tParentNodeInstanceId=" + metaData.get("ParentNodeInstanceId")); +System.out.println("\tParentNodeId=" + metaData.get("ParentNodeId")); + + + + + _AA96716C-BFA5-478A-9E24-B719D534067B + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithErrorCodeMatchWithStructureRef.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithErrorCodeMatchWithStructureRef.bpmn2 new file mode 100644 index 00000000000..c6a2475524c --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithErrorCodeMatchWithStructureRef.bpmn2 @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + SequenceFlow_3 + + + SequenceFlow_3 + SequenceFlow_4 + + SequenceFlow_5 + SequenceFlow_6 + + + + + + + + + + + _DataInput_9 + _DataInput_10 + _DataInput_11 + _DataInput_12 + _DataInput_13 + _DataInput_14 + _DataInput_15 + + + + + + _DataInput_9 + + + _DataInput_10 + + + _DataInput_11 + + + _DataInput_12 + + + _DataInput_13 + + + _DataInput_14 + + + _DataInput_15 + + + + SequenceFlow_5 + + + + SequenceFlow_6 + + + + + + + SequenceFlow_7 + + + DataOutput_1 + var1 + + + DataOutput_1 + + + + + SequenceFlow_7 + SequenceFlow_8 + System.out.println("Error is handled : var1 = " + var1); + + + + SequenceFlow_8 + + + + SequenceFlow_4 + SequenceFlow_9 + System.out.println("Process is finishing"); + + + SequenceFlow_9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithErrorCodeMatchWithoutStructureRef.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithErrorCodeMatchWithoutStructureRef.bpmn2 new file mode 100644 index 00000000000..930db6b4280 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithErrorCodeMatchWithoutStructureRef.bpmn2 @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + SequenceFlow_3 + + + SequenceFlow_3 + SequenceFlow_4 + + SequenceFlow_5 + SequenceFlow_6 + + + + + + + + + + + _DataInput_9 + _DataInput_10 + _DataInput_11 + _DataInput_12 + _DataInput_13 + _DataInput_14 + _DataInput_15 + + + + + + _DataInput_9 + + + _DataInput_10 + + + _DataInput_11 + + + _DataInput_12 + + + _DataInput_13 + + + _DataInput_14 + + + _DataInput_15 + + + + SequenceFlow_5 + + + + SequenceFlow_6 + + + + + + + SequenceFlow_7 + + + DataOutput_1 + var1 + + + DataOutput_1 + + + + + SequenceFlow_7 + SequenceFlow_8 + System.out.println("Error is handled : var1 = " + var1); + + + + SequenceFlow_8 + + + + SequenceFlow_4 + SequenceFlow_9 + System.out.println("Process is finishing"); + + + SequenceFlow_9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithErrorCodeWithoutStructureRef.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithErrorCodeWithoutStructureRef.bpmn2 new file mode 100644 index 00000000000..9cb3fe1bd61 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithErrorCodeWithoutStructureRef.bpmn2 @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + SequenceFlow_3 + + + SequenceFlow_3 + SequenceFlow_4 + + SequenceFlow_5 + SequenceFlow_6 + + + + + + + + + + + _DataInput_9 + _DataInput_10 + _DataInput_11 + _DataInput_12 + _DataInput_13 + _DataInput_14 + _DataInput_15 + + + + + + _DataInput_9 + + + _DataInput_10 + + + _DataInput_11 + + + _DataInput_12 + + + _DataInput_13 + + + _DataInput_14 + + + _DataInput_15 + + + + SequenceFlow_5 + + + + SequenceFlow_6 + + + + + + + SequenceFlow_7 + + + DataOutput_1 + var1 + + + DataOutput_1 + + + + + SequenceFlow_7 + SequenceFlow_8 + System.out.println("Error is handled : var1 = " + var1); + + + + SequenceFlow_8 + + + + SequenceFlow_4 + SequenceFlow_9 + System.out.println("Process is finishing"); + + + SequenceFlow_9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithoutErrorCodeWithStructureRef.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithoutErrorCodeWithStructureRef.bpmn2 new file mode 100644 index 00000000000..4253ba6d84f --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithoutErrorCodeWithStructureRef.bpmn2 @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + SequenceFlow_3 + + + SequenceFlow_3 + SequenceFlow_4 + + SequenceFlow_5 + SequenceFlow_6 + + + + + + + + + + + _DataInput_9 + _DataInput_10 + _DataInput_11 + _DataInput_12 + _DataInput_13 + _DataInput_14 + _DataInput_15 + + + + + + _DataInput_9 + + + _DataInput_10 + + + _DataInput_11 + + + _DataInput_12 + + + _DataInput_13 + + + _DataInput_14 + + + _DataInput_15 + + + + SequenceFlow_5 + + + + SequenceFlow_6 + + + + + + + SequenceFlow_7 + + + DataOutput_1 + var1 + + + DataOutput_1 + + + + + SequenceFlow_7 + SequenceFlow_8 + System.out.println("Error is handled : var1 = " + var1); + + + + SequenceFlow_8 + + + + SequenceFlow_4 + SequenceFlow_9 + System.out.println("Process is finishing"); + + + SequenceFlow_9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithoutErrorCodeWithoutStructureRef.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithoutErrorCodeWithoutStructureRef.bpmn2 new file mode 100644 index 00000000000..315a2d061f3 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/event/BoundaryErrorEvent-WithoutErrorCodeWithoutStructureRef.bpmn2 @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + SequenceFlow_3 + + + SequenceFlow_3 + SequenceFlow_4 + + SequenceFlow_5 + SequenceFlow_6 + + + + + + + + + + + _DataInput_9 + _DataInput_10 + _DataInput_11 + _DataInput_12 + _DataInput_13 + _DataInput_14 + _DataInput_15 + + + + + + _DataInput_9 + + + _DataInput_10 + + + _DataInput_11 + + + _DataInput_12 + + + _DataInput_13 + + + _DataInput_14 + + + _DataInput_15 + + + + SequenceFlow_5 + + + + SequenceFlow_6 + + + + + + + SequenceFlow_7 + + + DataOutput_1 + var1 + + + DataOutput_1 + + + + + SequenceFlow_7 + SequenceFlow_8 + System.out.println("Error is handled : var1 = " + var1); + + + + SequenceFlow_8 + + + + SequenceFlow_4 + SequenceFlow_9 + System.out.println("Process is finishing"); + + + SequenceFlow_9 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/CorrelationKey.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/CorrelationKey.bpmn2 new file mode 100644 index 00000000000..69b4072a441 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/CorrelationKey.bpmn2 @@ -0,0 +1,133 @@ + + + + + + + + _D1410740-EA2E-46E4-9C4F-8768E2BA9B63 + + + _D1410740-EA2E-46E4-9C4F-8768E2BA9B63 + _4F8A73CE-295A-4939-8A60-3148091FECE8 + + + + + _44DF4E92-82D0-4F92-B9F0-35C7F1F38849_SkippableInputX + _44DF4E92-82D0-4F92-B9F0-35C7F1F38849_TaskNameInputX + + + + + _44DF4E92-82D0-4F92-B9F0-35C7F1F38849_TaskNameInputX + + task + _44DF4E92-82D0-4F92-B9F0-35C7F1F38849_TaskNameInputX + + + + _44DF4E92-82D0-4F92-B9F0-35C7F1F38849_SkippableInputX + + true + _44DF4E92-82D0-4F92-B9F0-35C7F1F38849_SkippableInputX + + + + + john + + + + + + _4F8A73CE-295A-4939-8A60-3148091FECE8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _qd6wkLNlEeSe3MiymD9o_Q + _qd6wkLNlEeSe3MiymD9o_Q + + diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/DataObject.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/DataObject.bpmn2 new file mode 100644 index 00000000000..d2dfaf1c173 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/DataObject.bpmn2 @@ -0,0 +1,27 @@ + + + + + + + + + + dataInput1 + + + + + person + dataInput1 + + + + + + + + + diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/EventListeners.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/EventListeners.bpmn2 new file mode 100644 index 00000000000..7889a85c2dd --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/EventListeners.bpmn2 @@ -0,0 +1,160 @@ + + + + + + + + + _1-_4 + + + SequenceFlow_10 + _2-_3 + + + _2_Output + signalData + + + _2_Output + + + + + _2-_3 + SequenceFlow_11 + System.out.println("received signal..."); + + + _1-_4 + SequenceFlow_9 + System.out.println("started..."); + + + SequenceFlow_11 + SequenceFlow_1 + System.out.println("joined..."); + + + SequenceFlow_4 + + + + SequenceFlow_12 + _9-_10 + + + + _9-_10 + SequenceFlow_3 + System.out.println("bad signal received..."); + + + + + + SequenceFlow_1 + SequenceFlow_3 + SequenceFlow_4 + + + + + + SequenceFlow_9 + SequenceFlow_10 + SequenceFlow_12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/FireUntilHalt.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/FireUntilHalt.bpmn2 new file mode 100644 index 00000000000..de50cae05d8 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/FireUntilHalt.bpmn2 @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + _7B8CC121-6F99-464A-93F8-9EAC4BE4601A_personsInputX + + + + persons + _7B8CC121-6F99-464A-93F8-9EAC4BE4601A_personsInputX + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/FireUntilHalt.drl b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/FireUntilHalt.drl new file mode 100644 index 00000000000..d962061b5c9 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/FireUntilHalt.drl @@ -0,0 +1,48 @@ +package org.kie.kogito.test.engine.domain + +unit PersonUnit; + +import org.kie.kogito.test.engine.domain.Person; + +rule "initial actions" + when + then + System.out.println("Rule in initial actions ruleflow-group fired."); +end + +rule "add new person" + when + then + insert( new Person() ); + System.out.println("new person was inserted"); +end + +rule "person detector" + when + $person: /persons + then + System.out.println("There is a person."); +end + + +rule "wanted person detector" + when + $person: /persons[name == "wanted person"] + then + System.out.println("Wanted person"); +end + +rule "change unwanted person to wanted" + when + $person: /persons[name == "unwanted person"] + then + modify ($person){ + setName("unwanted") + }; + System.out.println("Unwanted person."); +end + + + + + diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/FlexibleProcess.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/FlexibleProcess.bpmn2 new file mode 100644 index 00000000000..231ddbaf7a3 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/FlexibleProcess.bpmn2 @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + userTasktaskNameInput + + userTask + userTasktaskNameInput + + + + + + + + + + + userTask2taskNameInput + + userTask2 + userTask2taskNameInput + + + + + + + + diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/Lane.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/Lane.bpmn2 new file mode 100644 index 00000000000..77ce7fcb27e --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/flow/Lane.bpmn2 @@ -0,0 +1,34 @@ + + + + + + + start + fork + scriptTask1 + end1 + + + scriptTask2 + end2 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/subprocess/AdHocSubprocess-emptyCompletionCondition.bpmn2 b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/subprocess/AdHocSubprocess-emptyCompletionCondition.bpmn2 new file mode 100644 index 00000000000..b032c35afd9 --- /dev/null +++ b/kogito-tck/kogito-junit-examples/src/test/resources/org/kie/kogito/test/engine/subprocess/AdHocSubprocess-emptyCompletionCondition.bpmn2 @@ -0,0 +1,95 @@ + + + + + _3BA7D86D-BE00-472B-9DC4-FF7358FFF7E5 + + + _3BA7D86D-BE00-472B-9DC4-FF7358FFF7E5 + _8AB6D592-6186-442E-989E-83E7D7473470 + + + + + _8AB6D592-6186-442E-989E-83E7D7473470 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _4gFlMKVLEeSEndqhOVytSw + _4gFlMKVLEeSEndqhOVytSw + + diff --git a/kogito-tck/kogito-junit5-core/pom.xml b/kogito-tck/kogito-junit5-core/pom.xml new file mode 100644 index 00000000000..c3b3b93366d --- /dev/null +++ b/kogito-tck/kogito-junit5-core/pom.xml @@ -0,0 +1,53 @@ + + 4.0.0 + + org.kie.kogito + kogito-tck + 2.0.0-SNAPSHOT + + kogito-junit5-core + + + + org.kie.kogito + kogito-api + + + org.kie.kogito + kogito-legacy-api + + + org.reflections + reflections + + + + + org.kie.kogito + kogito-codegen-api + + + org.kie.kogito + kogito-codegen-core + + + org.kie.kogito + kogito-codegen-processes + + + org.kie.kogito + kogito-codegen-rules + + + org.kie.kogito + kogito-codegen-decisions + + + org.kie.kogito + kogito-codegen-predictions + + + + \ No newline at end of file diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/Deployment.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/Deployment.java new file mode 100644 index 00000000000..db7a785d464 --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/Deployment.java @@ -0,0 +1,77 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; + +public class Deployment implements Cloneable { + + private String namespace; + private List> eventListeners; + private Map> workItemHandlers; + private List resources = new ArrayList<>(); + + public Deployment(String namespace) { + this.namespace = namespace; + this.eventListeners = new ArrayList<>(); + this.workItemHandlers = new HashMap<>(); + } + + @Override + public Deployment clone() throws CloneNotSupportedException { + Deployment newDeployment = new Deployment(namespace); + eventListeners.stream().forEach(e -> newDeployment.addEventListener(e)); + workItemHandlers.entrySet().forEach((k) -> newDeployment.addWorkItemHandler(k.getKey(), k.getValue())); + resources.stream().forEach(e -> newDeployment.addResource(e)); + return newDeployment; + } + + public void addResource(DeploymentResource resource) { + resources.add(resource); + } + + public String namespace() { + return namespace; + } + + public void addEventListener(Class listener) { + eventListeners.add(listener); + } + + public void addWorkItemHandler(String name, Class handler) { + workItemHandlers.put(name, handler); + } + + public List> getEventListeners() { + return Collections.unmodifiableList(eventListeners); + } + + public Map> getWorkItemHandlers() { + return Collections.unmodifiableMap(workItemHandlers); + } + + public List getResources() { + return Collections.unmodifiableList(resources); + } + +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/DeploymentContext.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/DeploymentContext.java new file mode 100644 index 00000000000..0feceb9cedf --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/DeploymentContext.java @@ -0,0 +1,44 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment; + +import java.util.ServiceLoader; + +import org.kie.kogito.junit.deployment.spi.DeploymentInstanceBuilder; + +public class DeploymentContext { + + private Deployment deployment; + private DeploymentInstance deploymentInstance; + + public DeploymentContext(Deployment deployment) { + this.deployment = deployment; + } + + public void init() { + DeploymentInstanceBuilder builder = ServiceLoader.load(DeploymentInstanceBuilder.class, DeploymentContext.class.getClassLoader()).findFirst().orElseThrow(); + this.deploymentInstance = builder.build(deployment); + } + + public DeploymentInstance get() { + return deploymentInstance; + } + + public void destroy() { + this.deploymentInstance.destroy(); + } +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/DeploymentInstance.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/DeploymentInstance.java new file mode 100644 index 00000000000..550f9641074 --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/DeploymentInstance.java @@ -0,0 +1,54 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.kie.kogito.Model; +import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.process.Process; +import org.kie.kogito.process.ProcessInstance; + +public interface DeploymentInstance { + + Process processById(String processId); + + @SuppressWarnings("unchecked") + default Optional> findById(String processId, String id) { + Optional pi = processById(processId).instances().findById(id); + return (Optional>) pi; + } + + @SuppressWarnings("unchecked") + default Optional> findByBusinessKey(String processId, String businessKey) { + Optional pi = processById(processId).instances().findByBusinessKey(businessKey); + return (Optional>) pi; + } + + void destroy(); + + Map getWorkItemHandlers(); + + List getProcessEventListeners(); + + void registerWorkItemHandler(String name, KogitoWorkItemHandler handler); + + void register(Object defaultProcessEventListener); + +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/DeploymentResource.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/DeploymentResource.java new file mode 100644 index 00000000000..ce5afcd769c --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/DeploymentResource.java @@ -0,0 +1,44 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment; + +public class DeploymentResource { + + public enum Type { + PROCESS, + RULES, + DECISION, + JAVA, + PREDICTION + } + + private Type type; + private String relativePath; + + public DeploymentResource(String relativePath, Type type) { + this.relativePath = relativePath; + this.type = type; + } + + public String getRelativePath() { + return relativePath; + } + + public Type getType() { + return type; + } +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/DeploymentInstanceBuilder.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/DeploymentInstanceBuilder.java new file mode 100644 index 00000000000..28d864ec941 --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/DeploymentInstanceBuilder.java @@ -0,0 +1,26 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment.spi; + +import org.kie.kogito.junit.deployment.Deployment; +import org.kie.kogito.junit.deployment.DeploymentInstance; + +public interface DeploymentInstanceBuilder { + + DeploymentInstance build(Deployment deployment); + +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/RuntimeBuildContextProvider.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/RuntimeBuildContextProvider.java new file mode 100644 index 00000000000..bd5683bfbd6 --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/RuntimeBuildContextProvider.java @@ -0,0 +1,24 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment.spi; + +import org.kie.kogito.codegen.api.context.KogitoBuildContext; + +public interface RuntimeBuildContextProvider { + + KogitoBuildContext.Builder newBuildContext(); +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/RuntimeBuildGeneratorProvider.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/RuntimeBuildGeneratorProvider.java new file mode 100644 index 00000000000..becf0c9f939 --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/RuntimeBuildGeneratorProvider.java @@ -0,0 +1,30 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment.spi; + +import java.util.Collection; +import java.util.Optional; + +import org.kie.kogito.codegen.api.Generator; +import org.kie.kogito.codegen.api.context.KogitoBuildContext; +import org.kie.kogito.codegen.api.io.CollectedResource; + +public interface RuntimeBuildGeneratorProvider { + + Optional buildCodegenGenerator(KogitoBuildContext context, Collection resources); + +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/RuntimeBuildPropertiesProvider.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/RuntimeBuildPropertiesProvider.java new file mode 100644 index 00000000000..3649a4fd813 --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/RuntimeBuildPropertiesProvider.java @@ -0,0 +1,25 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment.spi; + +import java.util.Properties; + +public interface RuntimeBuildPropertiesProvider { + + void provide(Properties properties); + +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/RuntimeTestPersistenceProvider.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/RuntimeTestPersistenceProvider.java new file mode 100644 index 00000000000..41f449fc4de --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/RuntimeTestPersistenceProvider.java @@ -0,0 +1,25 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment.spi; + +import org.kie.kogito.process.ProcessInstancesFactory; + +public interface RuntimeTestPersistenceProvider { + + void prepare(T prepare); + +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/AbstractDeploymentInstanceBuilder.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/AbstractDeploymentInstanceBuilder.java new file mode 100644 index 00000000000..5f6c34d95f9 --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/AbstractDeploymentInstanceBuilder.java @@ -0,0 +1,185 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment.spi.impl; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.Properties; +import java.util.ServiceLoader; +import java.util.stream.Collectors; + +import org.drools.compiler.compiler.io.memory.MemoryFileSystem; +import org.kie.kogito.codegen.api.AddonsConfig; +import org.kie.kogito.codegen.api.AddonsConfig.AddonsConfigBuilder; +import org.kie.kogito.codegen.api.GeneratedFile; +import org.kie.kogito.codegen.api.context.KogitoBuildContext; +import org.kie.kogito.codegen.api.io.CollectedResource; +import org.kie.kogito.codegen.core.ApplicationGenerator; +import org.kie.kogito.codegen.core.io.CollectedResourceProducer; +import org.kie.kogito.junit.deployment.Deployment; +import org.kie.kogito.junit.deployment.DeploymentInstance; +import org.kie.kogito.junit.deployment.spi.DeploymentInstanceBuilder; +import org.kie.kogito.junit.deployment.spi.RuntimeBuildContextProvider; +import org.kie.kogito.junit.deployment.spi.RuntimeBuildGeneratorProvider; +import org.kie.kogito.junit.deployment.spi.RuntimeBuildPropertiesProvider; +import org.kie.kogito.junit.deployment.spi.RuntimeTestPersistenceProvider; +import org.kie.memorycompiler.CompilationProblem; +import org.kie.memorycompiler.CompilationResult; +import org.kie.memorycompiler.JavaCompiler; +import org.kie.memorycompiler.JavaCompilerFactory; +import org.kie.memorycompiler.JavaConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractDeploymentInstanceBuilder implements DeploymentInstanceBuilder { + + private static final Logger logger = LoggerFactory.getLogger(AbstractDeploymentInstanceBuilder.class); + + private static final JavaCompiler JAVA_COMPILER = JavaCompilerFactory.loadCompiler(JavaConfiguration.CompilerType.NATIVE, "8"); + + private static final String DUMMY_PROCESS_RUNTIME = + "package org.drools.project.model;\n" + + "\n" + + "import org.kie.api.KieBase;\n" + + "import org.kie.api.builder.model.KieBaseModel;\n" + + "import org.kie.api.runtime.KieSession;\n" + + "import org.drools.modelcompiler.builder.KieBaseBuilder;\n" + + "\n" + + "\n" + + "public class ProjectRuntime implements org.kie.kogito.legacy.rules.KieRuntimeBuilder {\n" + + "\n" + + " public static final ProjectRuntime INSTANCE = new ProjectRuntime();\n" + + "\n" + + " @Override\n" + + " public KieBase getKieBase() {\n" + + " return null;\n" + + " }\n" + + "\n" + + " @Override\n" + + " public KieBase getKieBase(String name) {\n" + + " return null;\n" + + " }\n" + + "\n" + + " @Override\n" + + " public KieSession newKieSession() {\n" + + " return null;\n" + + " }\n" + + "\n" + + " @Override\n" + + " public KieSession newKieSession(String sessionName) {\n" + + " return null;\n" + + " }\n" + + "\n" + + " @Override\n" + + " public KieSession newKieSession(String sessionName, org.kie.kogito.rules.RuleConfig ruleConfig) {\n" + + " return null;\n" + + " }\n" + + "\n" + + "}"; + + public DeploymentInstance build(Deployment deployment) { + try { + Properties properties = new Properties(); + ServiceLoader.load(RuntimeBuildPropertiesProvider.class).forEach(propertiesProvider -> propertiesProvider.provide(properties)); + + AddonsConfigBuilder addonsConfigBuilder = AddonsConfig.builder(); + addonsConfigBuilder.withPersistence(properties.containsKey("kogito.persistence.type")); + AddonsConfig addonsConfig = addonsConfigBuilder.build(); + + RuntimeBuildContextProvider loaderBuildContext = ServiceLoader.load(RuntimeBuildContextProvider.class).findFirst().orElseThrow(); + KogitoBuildContext.Builder kogitoBuildContextBuilder = loaderBuildContext.newBuildContext(); + + KogitoBuildContext context = kogitoBuildContextBuilder + .withApplicationProperties(properties) + .withPackageName(deployment.namespace()) + .withAddonsConfig(addonsConfig) + .build(); + + List resourcesPath = deployment.getResources().stream().map(r -> r.getRelativePath()).collect(Collectors.toList()); + Collection resources = toCollectedResources("src/test/resources", resourcesPath); + + ApplicationGenerator appGen = new ApplicationGenerator(context); + ServiceLoader.load(RuntimeBuildGeneratorProvider.class).forEach(generatorProvider -> { + generatorProvider.buildCodegenGenerator(context, resources).ifPresent(gen -> appGen.registerGeneratorIfEnabled(gen)); + }); + + Collection generatedFiles = appGen.generate(); + MemoryFileSystem srcMfs = new MemoryFileSystem(); + MemoryFileSystem trgMfs = new MemoryFileSystem(); + + List sources = new ArrayList<>(); + for (GeneratedFile entry : generatedFiles) { + String fileName = entry.relativePath(); + logger.trace("Entry: {}\n{}", entry.path(), new String(entry.contents())); + trgMfs.write(fileName, entry.contents()); + if (fileName.endsWith(".java")) { + sources.add(fileName); + srcMfs.write(fileName, entry.contents()); + } + } + + // maybe there is a way to get rid of this + sources.add("org/drools/project/model/ProjectRuntime.java"); + srcMfs.write("org/drools/project/model/ProjectRuntime.java", DUMMY_PROCESS_RUNTIME.getBytes()); + + CompilationResult result = JAVA_COMPILER.compile(sources.toArray(new String[sources.size()]), srcMfs, trgMfs, AbstractDeploymentInstanceBuilder.class.getClassLoader()); + if (result.getErrors().length > 0) { + for (CompilationProblem problem : result.getErrors()) { + logger.error(problem.toString()); + } + throw new RuntimeException("compilation errors"); + } + + Path buildPath = Files.createTempDirectory("KOGITO_TESTS"); + logger.debug("Created working directory {} for namespace {}", buildPath, deployment.namespace()); + for (String fileName : trgMfs.getFileNames()) { + Path fpath = buildPath.resolve(fileName); + fpath.getParent().toFile().mkdirs(); + Files.write(fpath, trgMfs.getBytes(fileName)); + } + + return createDeploymentInstance(deployment, buildPath); + } catch (Exception e) { + throw new RuntimeException("could not create deployment instance", e); + } + } + + public Optional getRuntimeTestPersistenceProvider() { + return (Optional) ServiceLoader.load(RuntimeTestPersistenceProvider.class).findFirst(); + } + + protected abstract DeploymentInstance createDeploymentInstance(Deployment deployment, Path path) throws Exception; + + private Collection toCollectedResources(String basePath, List strings) { + + File[] files = strings + .stream() + .map(resource -> new File(basePath, resource)) + .toArray(File[]::new); + for (File file : files) { + logger.debug("Resource {} collected for deployment {}", file, file.isFile()); + } + return CollectedResourceProducer.fromFiles(Paths.get(basePath), files); + } + +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/BuildIncrementalRuleRuntimeBuildGeneratorProvider.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/BuildIncrementalRuleRuntimeBuildGeneratorProvider.java new file mode 100644 index 00000000000..38a22ecb748 --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/BuildIncrementalRuleRuntimeBuildGeneratorProvider.java @@ -0,0 +1,35 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment.spi.impl; + +import java.util.Collection; +import java.util.Optional; + +import org.kie.kogito.codegen.api.Generator; +import org.kie.kogito.codegen.api.context.KogitoBuildContext; +import org.kie.kogito.codegen.api.io.CollectedResource; +import org.kie.kogito.codegen.rules.IncrementalRuleCodegen; +import org.kie.kogito.junit.deployment.spi.RuntimeBuildGeneratorProvider; + +public class BuildIncrementalRuleRuntimeBuildGeneratorProvider implements RuntimeBuildGeneratorProvider { + + @Override + public Optional buildCodegenGenerator(KogitoBuildContext context, Collection resources) { + return Optional.of(IncrementalRuleCodegen.ofCollectedResources(context, resources)); + } + +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/DecisionRuntimeBuildGeneratorProvider.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/DecisionRuntimeBuildGeneratorProvider.java new file mode 100644 index 00000000000..1ba9631350c --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/DecisionRuntimeBuildGeneratorProvider.java @@ -0,0 +1,35 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment.spi.impl; + +import java.util.Collection; +import java.util.Optional; + +import org.kie.kogito.codegen.api.Generator; +import org.kie.kogito.codegen.api.context.KogitoBuildContext; +import org.kie.kogito.codegen.api.io.CollectedResource; +import org.kie.kogito.codegen.decision.DecisionCodegen; +import org.kie.kogito.junit.deployment.spi.RuntimeBuildGeneratorProvider; + +public class DecisionRuntimeBuildGeneratorProvider implements RuntimeBuildGeneratorProvider { + + @Override + public Optional buildCodegenGenerator(KogitoBuildContext context, Collection resources) { + return Optional.of(DecisionCodegen.ofCollectedResources(context, resources)); + } + +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/PersistenceRuntimeBuildGeneratorProvider.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/PersistenceRuntimeBuildGeneratorProvider.java new file mode 100644 index 00000000000..dc8f2f3b4a2 --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/PersistenceRuntimeBuildGeneratorProvider.java @@ -0,0 +1,63 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment.spi.impl; + +import java.util.Collection; +import java.util.Optional; +import java.util.Set; + +import org.kie.kogito.Model; +import org.kie.kogito.codegen.api.Generator; +import org.kie.kogito.codegen.api.context.KogitoBuildContext; +import org.kie.kogito.codegen.api.io.CollectedResource; +import org.kie.kogito.codegen.process.persistence.PersistenceGenerator; +import org.kie.kogito.codegen.process.persistence.proto.ReflectionProtoGenerator; +import org.kie.kogito.junit.deployment.spi.RuntimeBuildGeneratorProvider; +import org.kie.kogito.process.ProcessInstancesFactory; +import org.reflections.Reflections; +import org.reflections.util.ConfigurationBuilder; + +@SuppressWarnings({ "unchecked" }) +public class PersistenceRuntimeBuildGeneratorProvider implements RuntimeBuildGeneratorProvider { + + @Override + public Optional buildCodegenGenerator(KogitoBuildContext context, Collection resources) { + if (!context.getAddonsConfig().usePersistence()) { + return Optional.empty(); + } + + ConfigurationBuilder builder = new ConfigurationBuilder(); + builder.addClassLoader(PersistenceRuntimeBuildGeneratorProvider.class.getClassLoader()); + + Reflections reflections = new Reflections(builder); + + Set> modelClasses = (Set) reflections.getSubTypesOf(Model.class); + + // collect constructor parameters so the generated class can create constructor with injection + Class persistenceClass = reflections.getSubTypesOf(ProcessInstancesFactory.class) + .stream() + .filter(c -> !c.isInterface()) + .findFirst() + .orElse(null); + + ReflectionProtoGenerator protoGenerator = ReflectionProtoGenerator.builder() + .withPersistenceClass(persistenceClass) + .build(modelClasses); + return Optional.of(new PersistenceGenerator(context, protoGenerator)); + } + +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/PredictionRuntimeBuildGeneratorProvider.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/PredictionRuntimeBuildGeneratorProvider.java new file mode 100644 index 00000000000..e1b6448cc49 --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/PredictionRuntimeBuildGeneratorProvider.java @@ -0,0 +1,35 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment.spi.impl; + +import java.util.Collection; +import java.util.Optional; + +import org.kie.kogito.codegen.api.Generator; +import org.kie.kogito.codegen.api.context.KogitoBuildContext; +import org.kie.kogito.codegen.api.io.CollectedResource; +import org.kie.kogito.codegen.prediction.PredictionCodegen; +import org.kie.kogito.junit.deployment.spi.RuntimeBuildGeneratorProvider; + +public class PredictionRuntimeBuildGeneratorProvider implements RuntimeBuildGeneratorProvider { + + @Override + public Optional buildCodegenGenerator(KogitoBuildContext context, Collection resources) { + return Optional.of(PredictionCodegen.ofCollectedResources(context, resources)); + } + +} diff --git a/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/ProcessRuntimeBuildGeneratorProvider.java b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/ProcessRuntimeBuildGeneratorProvider.java new file mode 100644 index 00000000000..594b9308836 --- /dev/null +++ b/kogito-tck/kogito-junit5-core/src/main/java/org/kie/kogito/junit/deployment/spi/impl/ProcessRuntimeBuildGeneratorProvider.java @@ -0,0 +1,35 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.deployment.spi.impl; + +import java.util.Collection; +import java.util.Optional; + +import org.kie.kogito.codegen.api.Generator; +import org.kie.kogito.codegen.api.context.KogitoBuildContext; +import org.kie.kogito.codegen.api.io.CollectedResource; +import org.kie.kogito.codegen.process.ProcessCodegen; +import org.kie.kogito.junit.deployment.spi.RuntimeBuildGeneratorProvider; + +public class ProcessRuntimeBuildGeneratorProvider implements RuntimeBuildGeneratorProvider { + + @Override + public Optional buildCodegenGenerator(KogitoBuildContext context, Collection resources) { + return Optional.of(ProcessCodegen.ofCollectedResources(context, resources)); + } + +} diff --git a/kogito-tck/kogito-junit5-extension/pom.xml b/kogito-tck/kogito-junit5-extension/pom.xml new file mode 100644 index 00000000000..2215c50cc34 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + org.kie.kogito + kogito-tck + 2.0.0-SNAPSHOT + + + kogito-junit5-extension + + kogito-junit5-extension + http://maven.apache.org + + + UTF-8 + + + + org.kie.kogito + kogito-api + + + + org.assertj + assertj-core + compile + + + + org.kie.kogito + jbpm-flow + + + + org.kie.kogito + kogito-junit5-core + + + + org.junit.jupiter + junit-jupiter-api + compile + + + org.junit.jupiter + junit-jupiter-engine + compile + + + + org.junit.platform + junit-platform-commons + compile + + + diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestContext.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestContext.java new file mode 100644 index 00000000000..a183e758846 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestContext.java @@ -0,0 +1,74 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.api; + +import java.util.Collection; +import java.util.Optional; + +import org.kie.api.event.process.ProcessEventListener; +import org.kie.kogito.Model; +import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.process.Process; +import org.kie.kogito.process.ProcessInstance; +import org.kie.kogito.process.ProcessInstanceReadMode; +import org.kie.kogito.process.ProcessInstances; + +import static java.util.Collections.emptyList; + +public interface KogitoUnitTestContext { + + default boolean isSupported(Class clazz) { + return find(clazz) != null; + } + + T find(Class class1); + + Process processById(String processId); + + Optional> processInstanceById(String processId, String id); + + Optional> findByBusinessKey(String processId, String businessKey); + + default ProcessInstances instances(String processId) { + return new ProcessInstances() { + + @Override + public Optional> findById(String id, ProcessInstanceReadMode mode) { + return Optional.empty(); + } + + @Override + public Collection> values(ProcessInstanceReadMode mode) { + return emptyList(); + } + + @Override + public Integer size() { + return 0; + } + }; + } + + default void registerWorkItemHandler(String string, KogitoWorkItemHandler signallingTaskHandlerDecorator) { + } + + default void registerEventListener(ProcessEventListener defaultProcessEventListener) { + } + + void destroy(); + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestDeployment.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestDeployment.java new file mode 100644 index 00000000000..089ae1a122a --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestDeployment.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface KogitoUnitTestDeployment { + + String namespace() default "org.kie.kogito.test.engine"; + + KogitoUnitTestResource[] resources(); + + Class[] listeners() default {}; + + KogitoUnitTestWorkItemHandler[] workItemsHandlers() default {}; + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestDeploymentException.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestDeploymentException.java new file mode 100644 index 00000000000..b3f2951bd2c --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestDeploymentException.java @@ -0,0 +1,28 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface KogitoUnitTestDeploymentException { + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestEnvironment.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestEnvironment.java new file mode 100644 index 00000000000..97611dbdf41 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestEnvironment.java @@ -0,0 +1,30 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +public @interface KogitoUnitTestEnvironment { + + KogitoUnitTestEnvironmentProperty[] entries(); + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestEnvironmentProperty.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestEnvironmentProperty.java new file mode 100644 index 00000000000..e4d3ec84ef8 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestEnvironmentProperty.java @@ -0,0 +1,25 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.api; + +public @interface KogitoUnitTestEnvironmentProperty { + + String name(); + + String value(); + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestListeners.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestListeners.java new file mode 100644 index 00000000000..3f79ccef9da --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestListeners.java @@ -0,0 +1,28 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface KogitoUnitTestListeners { + Class[] value(); +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestProcessDebug.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestProcessDebug.java new file mode 100644 index 00000000000..bc176f33c06 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestProcessDebug.java @@ -0,0 +1,28 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface KogitoUnitTestProcessDebug { + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestResource.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestResource.java new file mode 100644 index 00000000000..0235e6ac9b1 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestResource.java @@ -0,0 +1,25 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.api; + +public @interface KogitoUnitTestResource { + + String path(); + + KogitoUnitTestResourceType type() default KogitoUnitTestResourceType.PROCESS; + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestResourceType.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestResourceType.java new file mode 100644 index 00000000000..636c7385f0d --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestResourceType.java @@ -0,0 +1,25 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.api; + +public enum KogitoUnitTestResourceType { + PROCESS, + RULES, + DECISION, + JAVA, + PREDICTION +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestWorkItemHandler.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestWorkItemHandler.java new file mode 100644 index 00000000000..ebc7770f9b4 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestWorkItemHandler.java @@ -0,0 +1,27 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.api; + +import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; + +public @interface KogitoUnitTestWorkItemHandler { + + String name(); + + Class handler(); + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestWorkItemHandlerRegistry.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestWorkItemHandlerRegistry.java new file mode 100644 index 00000000000..5819f1c51e8 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/api/KogitoUnitTestWorkItemHandlerRegistry.java @@ -0,0 +1,28 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface KogitoUnitTestWorkItemHandlerRegistry { + KogitoUnitTestWorkItemHandler[] entries(); +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/IterableTrackProcessPredicateAssert.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/IterableTrackProcessPredicateAssert.java new file mode 100644 index 00000000000..dfe8c7c5268 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/IterableTrackProcessPredicateAssert.java @@ -0,0 +1,122 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.asserts; + +import java.util.Iterator; +import java.util.function.Function; + +import org.junit.jupiter.api.Assertions; +import org.kie.api.event.process.ProcessCompletedEvent; +import org.kie.api.event.process.ProcessNodeLeftEvent; +import org.kie.api.event.process.ProcessNodeTriggeredEvent; +import org.kie.api.event.process.ProcessStartedEvent; +import org.kie.api.event.process.ProcessVariableChangedEvent; +import org.kie.kogito.junit.listeners.ProcessTrackedEvent; + +public class IterableTrackProcessPredicateAssert { + + private Iterator events; + + public IterableTrackProcessPredicateAssert(Iterable eventsForProcess) { + events = eventsForProcess.iterator(); + } + + public IterableTrackProcessPredicateAssert started() { + ProcessTrackedEvent event = nextEvent(); + if (!(event.getEvent() instanceof ProcessStartedEvent)) { + Assertions.fail("Process has not started"); + } + return this; + } + + public IterableTrackProcessPredicateAssert step(String nodeName) { + entered(nodeName); + exited(nodeName); + return this; + } + + public IterableTrackProcessPredicateAssert entered(String nodeName) { + ProcessTrackedEvent event = nextEvent(); + if (!(event.getEvent() instanceof ProcessNodeTriggeredEvent)) { + Assertions.fail("Node " + nodeName + " has no entered"); + } + ProcessNodeTriggeredEvent nodeTriggeredEvent = event.getEvent(); + String nodeNameEntered = nodeTriggeredEvent.getNodeInstance().getNodeName(); + if (!nodeName.equals(nodeNameEntered)) { + Assertions.fail("expected entering node name " + nodeName + " but it was " + nodeNameEntered); + } + return this; + } + + public IterableTrackProcessPredicateAssert varAssert(String varName, Function assertion) { + ProcessTrackedEvent event = nextEvent(); + while (event != null) { + if (!(event.getEvent() instanceof ProcessVariableChangedEvent)) { + event = nextEvent(); + continue; + } + ProcessVariableChangedEvent varChanged = event.getEvent(); + String nodeVarName = varChanged.getVariableId(); + if (!varName.equals(nodeVarName)) { + Assertions.fail("Expecting variable change in " + varName + " but found " + nodeVarName); + } else { + assertion.apply(varChanged.getNewValue()); + break; + } + } + return this; + } + + public IterableTrackProcessPredicateAssert exited(String nodeName) { + ProcessTrackedEvent event = nextEvent(); + while (event != null) { + if (event.getEvent() instanceof ProcessNodeTriggeredEvent) { + ProcessNodeTriggeredEvent nodeTriggeredEvent = event.getEvent(); + Assertions.fail("Expected leaving node name " + nodeName + " but entering node " + nodeTriggeredEvent.getNodeInstance().getNodeName()); + } + if (!(event.getEvent() instanceof ProcessNodeLeftEvent)) { + event = nextEvent(); + continue; + } + ProcessNodeLeftEvent nodeLeftEvent = event.getEvent(); + String nodeNameLeft = nodeLeftEvent.getNodeInstance().getNodeName(); + if (!nodeName.equals(nodeNameLeft)) { + Assertions.fail("expected leaving node name " + nodeName + " but it was " + nodeNameLeft); + } else { + break; + } + } + return this; + } + + public IterableTrackProcessPredicateAssert completed() { + ProcessTrackedEvent event = nextEvent(); + if (!(event.getEvent() instanceof ProcessCompletedEvent)) { + Assertions.fail("Process has not ended"); + } + return this; + } + + private ProcessTrackedEvent nextEvent() { + ProcessTrackedEvent event = events.next(); + if (event == null) { + Assertions.fail("there are no more events to process"); + } + return event; + } + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/ListTrackProcessPredicateAssert.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/ListTrackProcessPredicateAssert.java new file mode 100644 index 00000000000..bba10019523 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/ListTrackProcessPredicateAssert.java @@ -0,0 +1,160 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.asserts; + +import java.util.Optional; +import java.util.function.Function; + +import org.junit.jupiter.api.Assertions; +import org.kie.api.event.process.ProcessCompletedEvent; +import org.kie.api.event.process.ProcessNodeEvent; +import org.kie.api.event.process.ProcessNodeLeftEvent; +import org.kie.api.event.process.ProcessNodeTriggeredEvent; +import org.kie.api.event.process.ProcessStartedEvent; +import org.kie.api.event.process.ProcessVariableChangedEvent; +import org.kie.kogito.junit.listeners.ProcessEvents; +import org.kie.kogito.junit.listeners.ProcessTrackedEvent; + +public class ListTrackProcessPredicateAssert { + + private ProcessEvents events; + + public ListTrackProcessPredicateAssert(ProcessEvents eventsForProcess) { + events = eventsForProcess; + } + + private Optional findNodeEvent(Class type) { + for (ProcessTrackedEvent trackedEvent : events.getEvents()) { + if (!type.isAssignableFrom(trackedEvent.getEvent().getClass())) { + continue; + } + return Optional.of(trackedEvent); + } + return Optional.empty(); + } + + private Optional findNodeEvent(Class type, String nodeName) { + for (ProcessTrackedEvent trackedEvent : events.getEvents()) { + if (!type.isAssignableFrom(trackedEvent.getEvent().getClass())) { + continue; + } + ProcessNodeEvent event = trackedEvent.getEvent(); + if (event.getNodeInstance().getNodeName().equals(nodeName)) { + return Optional.of(trackedEvent); + } + } + return Optional.empty(); + } + + private Optional findVarEvent(Class type, String varName) { + for (ProcessTrackedEvent trackedEvent : events.getEvents()) { + if (!type.isAssignableFrom(trackedEvent.getEvent().getClass())) { + continue; + } + ProcessVariableChangedEvent event = trackedEvent.getEvent(); + if (event.getVariableId().equals(varName)) { + return Optional.of(trackedEvent); + } + } + return Optional.empty(); + } + + public ListTrackProcessPredicateAssert started() { + if (!findNodeEvent(ProcessStartedEvent.class).isPresent()) { + Assertions.fail("Process has not started"); + } + return this; + } + + public ListTrackProcessPredicateAssert step(String nodeName) { + entered(nodeName); + exited(nodeName); + return this; + } + + public ListTrackProcessPredicateAssert entered(String nodeName) { + if (!findNodeEvent(ProcessNodeTriggeredEvent.class, nodeName).isPresent()) { + Assertions.fail("Node " + nodeName + " has no entered"); + } + return this; + } + + public ListTrackProcessPredicateAssert varChanged(String varName) { + Optional event = findVarEvent(ProcessVariableChangedEvent.class, varName); + if (!event.isPresent()) { + Assertions.fail("Expecting variable change in " + varName + " but not found "); + } + return this; + } + + public ListTrackProcessPredicateAssert notStep(String nodeName) { + notEntered(nodeName); + notExited(nodeName); + return this; + } + + public ListTrackProcessPredicateAssert notEntered(String nodeName) { + if (findNodeEvent(ProcessNodeTriggeredEvent.class, nodeName).isPresent()) { + Assertions.fail("Node " + nodeName + " has entered"); + } + return this; + } + + public ListTrackProcessPredicateAssert notExited(String nodeName) { + if (findNodeEvent(ProcessNodeLeftEvent.class, nodeName).isPresent()) { + Assertions.fail("Node " + nodeName + "has exited"); + } + return this; + } + + public ListTrackProcessPredicateAssert varNotChanged(String varName) { + Optional event = findVarEvent(ProcessVariableChangedEvent.class, varName); + if (event.isPresent()) { + Assertions.fail("Expecting variable not to change in " + varName + " but found "); + } + return this; + } + + public ListTrackProcessPredicateAssert varAssert(String varName, Function assertion) { + Optional event = findVarEvent(ProcessVariableChangedEvent.class, varName); + if (!event.isPresent()) { + Assertions.fail("Expecting variable change in " + varName + " but not found "); + } + + ProcessVariableChangedEvent varChangedEvent = event.get().getEvent(); + if (assertion.apply(varChangedEvent.getNewValue())) { + Assertions.fail("Variable assertion failed for " + varName); + } + + return this; + } + + public ListTrackProcessPredicateAssert exited(String nodeName) { + if (!findNodeEvent(ProcessNodeLeftEvent.class, nodeName).isPresent()) { + Assertions.fail("Node " + nodeName + " has no entered"); + } + return this; + } + + public ListTrackProcessPredicateAssert completed() { + if (!findNodeEvent(ProcessCompletedEvent.class).isPresent()) { + Assertions.fail("Process has not ended"); + } + return this; + } + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/ModelPredicateAssert.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/ModelPredicateAssert.java new file mode 100644 index 00000000000..25096e02fd8 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/ModelPredicateAssert.java @@ -0,0 +1,42 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.asserts; + +import org.assertj.core.api.ObjectAssert; +import org.junit.jupiter.api.Assertions; +import org.kie.kogito.Model; + +public class ModelPredicateAssert { + + private T model; + + public ModelPredicateAssert(T model) { + this.model = model; + } + + @SuppressWarnings("unchecked") + public ObjectAssert output(String name) { + return new ObjectAssert((T) model.toMap().get(name)); + } + + public ModelPredicateAssert hasSize(int size) { + if (model.toMap().size() != size) { + Assertions.fail("model size does not match. Expecting " + size); + } + return this; + } +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/ProcessAssertions.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/ProcessAssertions.java new file mode 100644 index 00000000000..f3f2fa2e33b --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/ProcessAssertions.java @@ -0,0 +1,41 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.asserts; + +import org.kie.kogito.Model; +import org.kie.kogito.junit.listeners.FlowProcessEventListenerTracker; +import org.kie.kogito.process.ProcessInstance; + +public final class ProcessAssertions { + + private ProcessAssertions() { + // do nothing + } + + public static > ProcessPredicateAssert assertThat(T instance) { + return new ProcessPredicateAssert(instance); + } + + public static ModelPredicateAssert assertThat(T model) { + return new ModelPredicateAssert(model); + } + + public static TrackProcessPredicateAssert assertThat(FlowProcessEventListenerTracker tracker) { + return new TrackProcessPredicateAssert(tracker); + } + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/ProcessPredicateAssert.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/ProcessPredicateAssert.java new file mode 100644 index 00000000000..35f730b8598 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/ProcessPredicateAssert.java @@ -0,0 +1,64 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.asserts; + +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.kie.kogito.Model; +import org.kie.kogito.process.ProcessInstance; + +public class ProcessPredicateAssert> { + + private T instance; + + public ProcessPredicateAssert(T instance) { + this.instance = instance; + } + + public void isCompleted() { + if (this.instance.status() != ProcessInstance.STATE_COMPLETED) { + Assertions.fail("Process instance " + instance.id() + " is not completed"); + } + } + + public void isActive() { + if (this.instance.status() != ProcessInstance.STATE_ACTIVE) { + Assertions.fail("Process instance " + instance.id() + " is not active"); + } + } + + public void isAborted() { + if (this.instance.status() != ProcessInstance.STATE_ABORTED) { + Assertions.fail("Process instance " + instance.id() + " is not aborted"); + } + } + + public void isEnded() { + List finished = Arrays.asList(ProcessInstance.STATE_ABORTED, ProcessInstance.STATE_ACTIVE); + if (!finished.contains(this.instance.status())) { + Assertions.fail("Process instance " + instance.id() + " has no ended"); + } + } + + public void isError() { + if (this.instance.status() != ProcessInstance.STATE_ERROR) { + Assertions.fail("Process instance " + instance.id() + " is not in error state"); + } + } +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/TrackProcessPredicateAssert.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/TrackProcessPredicateAssert.java new file mode 100644 index 00000000000..9c3d512a290 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/asserts/TrackProcessPredicateAssert.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.asserts; + +import org.kie.kogito.junit.listeners.FlowProcessEventListenerTracker; + +public class TrackProcessPredicateAssert { + + private FlowProcessEventListenerTracker tracker; + + public TrackProcessPredicateAssert(FlowProcessEventListenerTracker tracker) { + this.tracker = tracker; + } + + public IterableTrackProcessPredicateAssert checkStepsForProcessInstance(String id) { + return new IterableTrackProcessPredicateAssert(tracker.eventsForProcess(id)); + } + + public ListTrackProcessPredicateAssert checkEventsProcessInstanceThat(String id) { + return new ListTrackProcessPredicateAssert(tracker.eventsForProcess(id)); + } +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/extension/KogitoUnitTestContextImpl.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/extension/KogitoUnitTestContextImpl.java new file mode 100644 index 00000000000..3ae40d90b57 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/extension/KogitoUnitTestContextImpl.java @@ -0,0 +1,92 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.extension; + +import java.util.Optional; + +import org.kie.api.event.process.ProcessEventListener; +import org.kie.kogito.Model; +import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.junit.api.KogitoUnitTestContext; +import org.kie.kogito.junit.deployment.DeploymentContext; +import org.kie.kogito.process.Process; +import org.kie.kogito.process.ProcessInstance; +import org.kie.kogito.process.ProcessInstances; + +public class KogitoUnitTestContextImpl implements KogitoUnitTestContext { + + private DeploymentContext deploymentContext; + + public KogitoUnitTestContextImpl(DeploymentContext deploymentContext) { + this.deploymentContext = deploymentContext; + } + + @Override + public T find(Class clazz) { + if (KogitoWorkItemHandler.class.isAssignableFrom(clazz)) { + for (KogitoWorkItemHandler wih : deploymentContext.get().getWorkItemHandlers().values()) { + if (wih.getClass().equals(clazz)) { + return clazz.cast(wih); + } + } + } else { + for (Object listener : deploymentContext.get().getProcessEventListeners()) { + if (listener.getClass().equals(clazz)) { + return clazz.cast(listener); + } + } + } + + return null; + } + + @Override + public Process processById(String processId) { + return deploymentContext.get().processById(processId); + } + + @Override + public ProcessInstances instances(String processId) { + return deploymentContext.get().processById(processId).instances(); + } + + @Override + public Optional> processInstanceById(String processId, String id) { + return deploymentContext.get().findById(processId, id); + } + + @Override + public Optional> findByBusinessKey(String processId, String businessKey) { + return deploymentContext.get().findByBusinessKey(processId, businessKey); + } + + @Override + public void registerEventListener(ProcessEventListener defaultProcessEventListener) { + deploymentContext.get().register(defaultProcessEventListener); + } + + @Override + public void registerWorkItemHandler(String name, KogitoWorkItemHandler handler) { + deploymentContext.get().registerWorkItemHandler(name, handler); + } + + @Override + public void destroy() { + deploymentContext.destroy(); + } + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/extension/KogitoUnitTestDeploymentExtension.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/extension/KogitoUnitTestDeploymentExtension.java new file mode 100644 index 00000000000..6dc22df426e --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/extension/KogitoUnitTestDeploymentExtension.java @@ -0,0 +1,229 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.extension; + +import java.io.File; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.Extension; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolutionException; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.junit.api.KogitoUnitTestContext; +import org.kie.kogito.junit.api.KogitoUnitTestDeployment; +import org.kie.kogito.junit.api.KogitoUnitTestDeploymentException; +import org.kie.kogito.junit.api.KogitoUnitTestListeners; +import org.kie.kogito.junit.api.KogitoUnitTestProcessDebug; +import org.kie.kogito.junit.api.KogitoUnitTestResource; +import org.kie.kogito.junit.api.KogitoUnitTestResourceType; +import org.kie.kogito.junit.api.KogitoUnitTestWorkItemHandler; +import org.kie.kogito.junit.api.KogitoUnitTestWorkItemHandlerRegistry; +import org.kie.kogito.junit.deployment.Deployment; +import org.kie.kogito.junit.deployment.DeploymentContext; +import org.kie.kogito.junit.deployment.DeploymentResource; +import org.kie.kogito.junit.listeners.DebugProcessEventListener; + +public class KogitoUnitTestDeploymentExtension implements Extension, BeforeEachCallback, AfterEachCallback, BeforeAllCallback, + AfterAllCallback, ParameterResolver { + + private Map unitTestContexts; + private Deployment defaultDeployment; + + public KogitoUnitTestDeploymentExtension() { + unitTestContexts = new ConcurrentHashMap<>(); + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, + ExtensionContext extensionContext) throws ParameterResolutionException { + Class type = parameterContext.getParameter().getType(); + return KogitoUnitTestContext.class.isAssignableFrom(type) || unitTestContexts.get(extensionContext.getUniqueId()).isSupported(type) || Throwable.class.isAssignableFrom(type); + + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, + ExtensionContext extensionContext) throws ParameterResolutionException { + Class type = parameterContext.getParameter().getType(); + if (KogitoUnitTestContext.class.isAssignableFrom(type)) { + return unitTestContexts.get(extensionContext.getUniqueId()); + } else { + return unitTestContexts.get(extensionContext.getUniqueId()).find(type); + } + } + + @Override + public void beforeAll(ExtensionContext context) throws Exception { + Class testClass = context.getTestClass().get(); + if (testClass.isAnnotationPresent(KogitoUnitTestDeployment.class)) { + KogitoUnitTestDeployment archive = testClass.getAnnotation(KogitoUnitTestDeployment.class); + defaultDeployment = toDeployment(archive); + } + } + + @Override + public void afterAll(ExtensionContext context) throws Exception { + defaultDeployment = null; + } + + @Override + public void afterEach(ExtensionContext context) throws Exception { + unitTestContexts.remove(context.getUniqueId()).destroy(); + } + + @Override + public void beforeEach(ExtensionContext context) { + Method testMethod = context.getTestMethod().get(); + try { + // template + Deployment currentDeployment = defaultDeployment != null ? defaultDeployment.clone() : null; + + if (testMethod.isAnnotationPresent(KogitoUnitTestDeployment.class)) { + // override default deployment with current deployment + KogitoUnitTestDeployment archive = testMethod.getAnnotation(KogitoUnitTestDeployment.class); + currentDeployment = toDeployment(archive); + } + + if (currentDeployment == null) { + throw new RuntimeException("No deployment specified !"); + } + + // time to add default listeners at class / test level + Class testClass = context.getTestClass().get(); + KogitoUnitTestListeners methodListeners = testMethod.getAnnotation(KogitoUnitTestListeners.class); + KogitoUnitTestListeners classListeners = testClass.getAnnotation(KogitoUnitTestListeners.class); + for (Class listener : merge(classListeners, methodListeners)) { + currentDeployment.addEventListener(listener); + } + KogitoUnitTestWorkItemHandlerRegistry methodWih = testMethod.getAnnotation(KogitoUnitTestWorkItemHandlerRegistry.class); + KogitoUnitTestWorkItemHandlerRegistry classWith = testClass.getAnnotation(KogitoUnitTestWorkItemHandlerRegistry.class); + for (Map.Entry> handler : merge(classWith, methodWih)) { + currentDeployment.addWorkItemHandler(handler.getKey(), handler.getValue()); + } + + if (testMethod.isAnnotationPresent(KogitoUnitTestProcessDebug.class)) { + currentDeployment.addEventListener(DebugProcessEventListener.class); + } + + DeploymentContext deploymentContext = new DeploymentContext(currentDeployment); + deploymentContext.init(); + KogitoUnitTestContextImpl unitTestContext = new KogitoUnitTestContextImpl(deploymentContext); + unitTestContexts.put(context.getUniqueId(), unitTestContext); + } catch (Throwable ex) { + if (testMethod.isAnnotationPresent(KogitoUnitTestDeploymentException.class)) { + unitTestContexts.put(context.getUniqueId(), new KogitoUnitTestErrorContextImpl(ex)); + } else { + throw new RuntimeException(ex); + } + } + } + + private List> merge(KogitoUnitTestListeners classListeners, KogitoUnitTestListeners methodListeners) { + List> list = new ArrayList<>(); + if (classListeners != null) { + list.addAll(Arrays.asList(classListeners.value())); + } + if (methodListeners != null) { + list.addAll(Arrays.asList(methodListeners.value())); + } + return list; + } + + private Set>> merge(KogitoUnitTestWorkItemHandlerRegistry classWith, KogitoUnitTestWorkItemHandlerRegistry methodWih) { + Map> registry = new HashMap<>(); + if (classWith != null) { + for (KogitoUnitTestWorkItemHandler wih : classWith.entries()) { + registry.put(wih.name(), wih.handler()); + } + } + if (methodWih != null) { + for (KogitoUnitTestWorkItemHandler wih : methodWih.entries()) { + registry.put(wih.name(), wih.handler()); + } + } + return registry.entrySet(); + } + + public Deployment toDeployment(KogitoUnitTestDeployment archive) { + Deployment deployment = new Deployment(archive.namespace()); + + // both listeners / wih have default values. + for (Class listener : archive.listeners()) { + deployment.addEventListener(listener); + } + + for (KogitoUnitTestWorkItemHandler handler : archive.workItemsHandlers()) { + deployment.addWorkItemHandler(handler.name(), handler.handler()); + } + + toResources(archive).stream().forEach(e -> deployment.addResource(e)); + + return deployment; + } + + private List toResources(KogitoUnitTestDeployment archive) { + File file = new File(getClass().getClassLoader().getResource(".").getFile()); + String absolutePath = file.getAbsolutePath(); + + List resources = new ArrayList<>(); + for (KogitoUnitTestResource resource : archive.resources()) { + KogitoUnitTestResourceType type = resource.type(); + Path resourcePath = Paths.get(absolutePath, resource.path()); + if (!Files.exists(resourcePath)) { + throw new RuntimeException("File " + resource.path() + " does not exists!"); + } + DeploymentResource.Type deploymentResourceType = null; + switch (type) { + case RULES: + deploymentResourceType = DeploymentResource.Type.RULES; + break; + case DECISION: + deploymentResourceType = DeploymentResource.Type.DECISION; + break; + case JAVA: + deploymentResourceType = DeploymentResource.Type.JAVA; + break; + case PROCESS: + deploymentResourceType = DeploymentResource.Type.PROCESS; + break; + case PREDICTION: + deploymentResourceType = DeploymentResource.Type.PREDICTION; + break; + } + resources.add(new DeploymentResource(resource.path(), deploymentResourceType)); + + } + return resources; + } + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/extension/KogitoUnitTestEnvironmentExtension.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/extension/KogitoUnitTestEnvironmentExtension.java new file mode 100644 index 00000000000..d2cfe6c6b1d --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/extension/KogitoUnitTestEnvironmentExtension.java @@ -0,0 +1,73 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.extension; + +import java.util.Optional; + +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.Extension; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.kie.kogito.junit.api.KogitoUnitTestEnvironment; +import org.kie.kogito.junit.api.KogitoUnitTestEnvironmentProperty; + +public class KogitoUnitTestEnvironmentExtension implements Extension, BeforeAllCallback, AfterAllCallback { + + @Override + public void beforeAll(ExtensionContext context) throws Exception { + Optional> testClass = context.getTestClass(); + if (!testClass.isPresent()) { + return; + } + Class clazz = testClass.get(); + KogitoUnitTestEnvironment env = clazz.getAnnotation(KogitoUnitTestEnvironment.class); + if (env != null) { + setEnvEntries(env); + } + + } + + private void setEnvEntries(KogitoUnitTestEnvironment env) { + for (KogitoUnitTestEnvironmentProperty property : env.entries()) { + if (property.value() != null) { + System.setProperty(property.name(), property.value()); + } else { + System.clearProperty(property.name()); + } + } + } + + @Override + public void afterAll(ExtensionContext context) throws Exception { + Optional> testClass = context.getTestClass(); + if (!testClass.isPresent()) { + return; + } + Class clazz = testClass.get(); + KogitoUnitTestEnvironment env = clazz.getAnnotation(KogitoUnitTestEnvironment.class); + if (env != null) { + clearEnvEntries(env); + } + } + + private void clearEnvEntries(KogitoUnitTestEnvironment env) { + for (KogitoUnitTestEnvironmentProperty property : env.entries()) { + System.clearProperty(property.name()); + } + } + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/extension/KogitoUnitTestErrorContextImpl.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/extension/KogitoUnitTestErrorContextImpl.java new file mode 100644 index 00000000000..dad363fda96 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/extension/KogitoUnitTestErrorContextImpl.java @@ -0,0 +1,62 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.extension; + +import java.util.Optional; + +import org.kie.kogito.Model; +import org.kie.kogito.junit.api.KogitoUnitTestContext; +import org.kie.kogito.process.Process; +import org.kie.kogito.process.ProcessInstance; + +public class KogitoUnitTestErrorContextImpl implements KogitoUnitTestContext { + + private Throwable throwable; + + public KogitoUnitTestErrorContextImpl(Throwable throwable) { + this.throwable = throwable; + } + + @Override + public T find(Class clazz) { + if (Throwable.class.isAssignableFrom(clazz)) { + return clazz.cast(throwable); + } + return null; + } + + @Override + public Process processById(String processId) { + return null; + } + + @Override + public Optional> processInstanceById(String processId, String id) { + return Optional.empty(); + } + + @Override + public Optional> findByBusinessKey(String processId, String businessKey) { + return Optional.empty(); + } + + @Override + public void destroy() { + // nothing + } + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/CompletedProcessEventListener.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/CompletedProcessEventListener.java new file mode 100644 index 00000000000..e9a19da2b13 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/CompletedProcessEventListener.java @@ -0,0 +1,55 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.listeners; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.kie.api.event.process.ProcessCompletedEvent; +import org.kie.api.event.process.ProcessStartedEvent; +import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; + +/** + * Simple listener for watching process flow + */ +public class CompletedProcessEventListener extends DefaultKogitoProcessEventListener { + + private CountDownLatch latch; + + public CompletedProcessEventListener() { + latch = new CountDownLatch(1); + } + + @Override + public void beforeProcessStarted(ProcessStartedEvent event) { + + super.beforeProcessStarted(event); + } + + @Override + public void afterProcessCompleted(ProcessCompletedEvent event) { + latch.countDown(); + } + + public void waitForCompletion(long seconds) throws InterruptedException { + latch.await(seconds, TimeUnit.SECONDS); + } + + public void waitForCompletion() throws InterruptedException { + latch.await(); + } +} \ No newline at end of file diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/DebugProcessEventListener.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/DebugProcessEventListener.java new file mode 100644 index 00000000000..11eabb9f896 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/DebugProcessEventListener.java @@ -0,0 +1,104 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.listeners; + +import org.kie.api.event.process.ProcessCompletedEvent; +import org.kie.api.event.process.ProcessEvent; +import org.kie.api.event.process.ProcessNodeEvent; +import org.kie.api.event.process.ProcessNodeLeftEvent; +import org.kie.api.event.process.ProcessNodeTriggeredEvent; +import org.kie.api.event.process.ProcessStartedEvent; +import org.kie.api.event.process.ProcessVariableChangedEvent; +import org.kie.api.runtime.process.NodeInstance; +import org.kie.api.runtime.process.ProcessInstance; +import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Simple listener for watching process flow + */ +public class DebugProcessEventListener extends DefaultKogitoProcessEventListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(DebugProcessEventListener.class); + + @Override + public void afterNodeLeft(ProcessNodeLeftEvent event) { + LOGGER.info(formatNodeMessage("afterNodeLeft", event)); + } + + @Override + public void afterNodeTriggered(ProcessNodeTriggeredEvent event) { + LOGGER.info(formatNodeMessage("afterNodeTriggered", event)); + } + + @Override + public void afterProcessCompleted(ProcessCompletedEvent event) { + LOGGER.info(formatProcessMessage("afterProcessCompleted", event)); + } + + @Override + public void afterProcessStarted(ProcessStartedEvent event) { + LOGGER.info(formatProcessMessage("afterProcessStarted", event)); + } + + @Override + public void afterVariableChanged(ProcessVariableChangedEvent event) { + LOGGER.info(formatVariableChangedMessage("afterVariableChanged", event)); + } + + @Override + public void beforeNodeLeft(ProcessNodeLeftEvent event) { + LOGGER.info(formatNodeMessage("beforeNodeLeft", event)); + } + + @Override + public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { + LOGGER.info(formatNodeMessage("beforeNodeTriggered", event)); + } + + @Override + public void beforeProcessCompleted(ProcessCompletedEvent event) { + LOGGER.info(formatProcessMessage("beforeProcessCompleted", event)); + } + + @Override + public void beforeProcessStarted(ProcessStartedEvent event) { + LOGGER.info(formatProcessMessage("beforeProcessStarted", event)); + } + + @Override + public void beforeVariableChanged(ProcessVariableChangedEvent event) { + LOGGER.info(formatVariableChangedMessage("beforeVariableChanged", event)); + } + + private String formatNodeMessage(String when, ProcessNodeEvent event) { + NodeInstance ni = event.getNodeInstance(); + return String.format("<%s> name:%s, id:%s", when, ni.getNodeName(), ni.getNodeId()); + } + + private String formatProcessMessage(String when, ProcessEvent event) { + ProcessInstance pi = event.getProcessInstance(); + return String.format("<%s> name:%s, id:%s, state:%s", when, pi.getProcessName(), pi.getProcessId(), + pi.getState()); + } + + private String formatVariableChangedMessage(String when, ProcessVariableChangedEvent event) { + return String.format("<%s> id:%s, old:%s, new:%s", when, event.getVariableId(), event.getOldValue(), + event.getNewValue()); + } +} \ No newline at end of file diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/FlowProcessEventListenerTracker.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/FlowProcessEventListenerTracker.java new file mode 100644 index 00000000000..c21d562c819 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/FlowProcessEventListenerTracker.java @@ -0,0 +1,98 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.listeners; + +import java.util.HashMap; +import java.util.Map; + +import org.drools.core.event.KogitoProcessVariableChangedEventImpl; +import org.jbpm.workflow.instance.WorkflowProcessInstance; +import org.kie.api.event.process.ProcessCompletedEvent; +import org.kie.api.event.process.ProcessEvent; +import org.kie.api.event.process.ProcessNodeLeftEvent; +import org.kie.api.event.process.ProcessNodeTriggeredEvent; +import org.kie.api.event.process.ProcessStartedEvent; +import org.kie.api.event.process.ProcessVariableChangedEvent; +import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; + +public class FlowProcessEventListenerTracker extends DefaultKogitoProcessEventListener { + + public static final String BEFORE_STARTED = "beforeProcessStarted"; + public static final String AFTER_STARTED = "afterProcessStarted"; + public static final String BEFORE_COMPLETED = "beforeProcessCompleted"; + public static final String AFTER_COMPLETED = "afterProcessCompleted"; + public static final String BEFORE_TRIGGERED = "beforeNodeTriggered"; + public static final String AFTER_TRIGGERED = "afterNodeTriggered"; + public static final String BEFORE_LEFT = "beforeNodeLeft"; + public static final String AFTER_LEFT = "afterNodeLeft"; + public static final String BEFORE_VARIABLE = "beforeVariableChanged"; + public static final String AFTER_VARIABLE = "afterVariableChanged"; + + private final Map eventsByProcess; + + public FlowProcessEventListenerTracker() { + eventsByProcess = new HashMap<>(); + } + + public ProcessEvents eventsForProcess(String id) { + return eventsByProcess.getOrDefault(id, new ProcessEvents(id)); + } + + private ProcessEvents getEventsForProcess(ProcessEvent event) { + return eventsByProcess.computeIfAbsent(getStringId(event), (key) -> new ProcessEvents(key)); + } + + private String getStringId(ProcessEvent event) { + if (event instanceof KogitoProcessVariableChangedEventImpl) { + return ((WorkflowProcessInstance) ((KogitoProcessVariableChangedEventImpl) event).getSource()).getStringId(); + } else { + return ((WorkflowProcessInstance) event.getProcessInstance()).getStringId(); + } + } + + @Override + public void beforeProcessStarted(ProcessStartedEvent event) { + getEventsForProcess(event).push(new ProcessTrackedEvent(event, BEFORE_STARTED)); + } + + @Override + public void beforeProcessCompleted(ProcessCompletedEvent event) { + getEventsForProcess(event).push(new ProcessTrackedEvent(event, BEFORE_COMPLETED)); + } + + @Override + public void beforeNodeTriggered(ProcessNodeTriggeredEvent event) { + getEventsForProcess(event).push(new ProcessTrackedEvent(event, BEFORE_TRIGGERED)); + } + + @Override + public void beforeNodeLeft(ProcessNodeLeftEvent event) { + getEventsForProcess(event).push(new ProcessTrackedEvent(event, BEFORE_LEFT)); + } + + @Override + public void afterVariableChanged(ProcessVariableChangedEvent event) { + getEventsForProcess(event).push(new ProcessTrackedEvent(event, AFTER_VARIABLE)); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + eventsByProcess.values().forEach(events -> builder.append(events).append("\n")); + return builder.toString(); + } +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/ProcessEventListenerTracker.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/ProcessEventListenerTracker.java new file mode 100644 index 00000000000..ef7af8a5736 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/ProcessEventListenerTracker.java @@ -0,0 +1,58 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.listeners; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.kie.api.event.process.ProcessCompletedEvent; +import org.kie.api.event.process.ProcessStartedEvent; +import org.kie.kogito.internal.process.event.DefaultKogitoProcessEventListener; + +/** + * Simple listener for watching process flow + */ +public class ProcessEventListenerTracker extends DefaultKogitoProcessEventListener { + + private Map counterStarted; + private Map counterCompleted; + + public ProcessEventListenerTracker() { + counterStarted = new ConcurrentHashMap<>(); + counterCompleted = new ConcurrentHashMap<>(); + } + + @Override + public void beforeProcessStarted(ProcessStartedEvent event) { + counterStarted.computeIfAbsent(event.getProcessInstance().getProcessId(), (key) -> 1); + counterStarted.computeIfPresent(event.getProcessInstance().getProcessId(), (key, counter) -> counter + 1); + } + + @Override + public void afterProcessCompleted(ProcessCompletedEvent event) { + counterCompleted.computeIfAbsent(event.getProcessInstance().getProcessId(), (key) -> 1); + counterCompleted.computeIfPresent(event.getProcessInstance().getProcessId(), (key, counter) -> counter + 1); + } + + public int countForProcessIdStarted(String processId) { + return counterStarted.getOrDefault(processId, 0); + } + + public int countForProcessIdCompleted(String processId) { + return counterStarted.getOrDefault(processId, 0); + } +} \ No newline at end of file diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/ProcessEvents.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/ProcessEvents.java new file mode 100644 index 00000000000..4a1fe340a7e --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/ProcessEvents.java @@ -0,0 +1,75 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.listeners; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +public class ProcessEvents implements Iterable { + + private String id; + private List events; + + public ProcessEvents(String id) { + this.id = id; + this.events = new ArrayList<>(); + } + + public String getId() { + return id; + } + + public List getEvents() { + return new ArrayList<>(events); + } + + @Override + public Iterator iterator() { + // TODO Auto-generated method stub + return new Iterator() { + private int idx = 0; + + @Override + public boolean hasNext() { + return idx < events.size(); + } + + @Override + public ProcessTrackedEvent next() { + return idx < events.size() ? events.get(idx++) : null; + } + }; + } + + public void push(ProcessTrackedEvent processTrackedEvent) { + this.events.add(processTrackedEvent); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("ProcessId : "); + builder.append(id); + for (ProcessTrackedEvent event : events) { + builder.append(event); + builder.append("\n"); + } + return builder.toString(); + } + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/ProcessTrackedEvent.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/ProcessTrackedEvent.java new file mode 100644 index 00000000000..0ff7b6d29d0 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/ProcessTrackedEvent.java @@ -0,0 +1,43 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.listeners; + +import org.kie.api.event.process.ProcessEvent; + +public class ProcessTrackedEvent { + private final ProcessEvent event; + private final String method; + + public ProcessTrackedEvent(ProcessEvent event, String method) { + this.event = event; + this.method = method; + } + + @SuppressWarnings("unchecked") + public T getEvent() { + return (T) event; + } + + public String getMethod() { + return method; + } + + @Override + public String toString() { + return method + "(" + event.toString() + ")"; + } +} \ No newline at end of file diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/TrackingAgendaEventListener.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/TrackingAgendaEventListener.java new file mode 100644 index 00000000000..05a56e48a58 --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/listeners/TrackingAgendaEventListener.java @@ -0,0 +1,79 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.listeners; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.kie.api.event.rule.AfterMatchFiredEvent; +import org.kie.api.event.rule.DefaultAgendaEventListener; + +public class TrackingAgendaEventListener extends DefaultAgendaEventListener { + + private Map rulesFired; + + public TrackingAgendaEventListener() { + rulesFired = new HashMap(); + } + + @Override + public void afterMatchFired(AfterMatchFiredEvent event) { + String rule = event.getMatch().getRule().getName(); + if (isRuleFired(rule)) { + rulesFired.put(rule, rulesFired.get(rule) + 1); + } else { + rulesFired.put(rule, 1); + } + } + + /** + * Return true if the rule was fired at least once + * + * @param rule - name of the rule + * @return true if the rule was fired + */ + public boolean isRuleFired(String rule) { + return rulesFired.containsKey(rule); + } + + /** + * Returns number saying how many times the rule was fired + * + * @param rule - name ot the rule + * @return number how many times rule was fired, 0 if rule wasn't fired + */ + public int ruleFiredCount(String rule) { + if (isRuleFired(rule)) { + return rulesFired.get(rule); + } else { + return 0; + } + } + + /** + * @return how many rules were fired + */ + public int rulesCount() { + return rulesFired.size(); + } + + public Collection getFiredRules() { + return rulesFired.keySet(); + } + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/util/ProcessUtil.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/util/ProcessUtil.java new file mode 100644 index 00000000000..5c10aa4a47a --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/util/ProcessUtil.java @@ -0,0 +1,69 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.util; + +import java.util.List; +import java.util.Map; + +import org.kie.kogito.Model; +import org.kie.kogito.junit.api.KogitoUnitTestContext; +import org.kie.kogito.process.Process; +import org.kie.kogito.process.ProcessInstance; +import org.kie.kogito.process.ProcessInstances; +import org.kie.kogito.process.WorkItem; + +public final class ProcessUtil { + + public static void completeFirstPendingWorkItem(ProcessInstance instance, Map outcome) { + completeWorkItem(instance, 0, outcome); + } + + public static void completeWorkItem(ProcessInstance instance, int idx, Map outcome) { + List workItems = instance.workItems(); + WorkItem workItem = workItems.get(idx); + instance.completeWorkItem(workItem.getId(), outcome); + } + + public static ProcessInstance startProcess(KogitoUnitTestContext context, String processId, Map params) { + Process process = context.processById(processId); + Model model = process.createModel(); + model.update(params); + ProcessInstance instance = process.createInstance(model); + instance.start(); + return instance; + } + + public static ProcessInstance startProcess(KogitoUnitTestContext context, String processId, String businessKey) { + Process process = context.processById(processId); + Model model = process.createModel(); + ProcessInstance instance = process.createInstance(businessKey, model); + instance.start(); + return instance; + } + + public static ProcessInstance startProcess(KogitoUnitTestContext context, String processId) { + Process process = context.processById(processId); + Model model = process.createModel(); + ProcessInstance instance = process.createInstance(model); + instance.start(); + return instance; + } + + public static ProcessInstance firstProcessInstance(ProcessInstances instances) { + return instances.values().iterator().next(); + } +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/wih/ExceptionWorkItemHandler.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/wih/ExceptionWorkItemHandler.java new file mode 100644 index 00000000000..01760ecd4da --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/wih/ExceptionWorkItemHandler.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.wih; + +import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; + +public class ExceptionWorkItemHandler implements KogitoWorkItemHandler { + + @Override + public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + throw new RuntimeException("broken work item"); + + } + + @Override + public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + // do nothing + } + +} \ No newline at end of file diff --git a/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/wih/WorkItemHandlerTracker.java b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/wih/WorkItemHandlerTracker.java new file mode 100644 index 00000000000..d455fea686f --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/java/org/kie/kogito/junit/wih/WorkItemHandlerTracker.java @@ -0,0 +1,91 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kie.kogito.junit.wih; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.kie.kogito.internal.process.runtime.KogitoWorkItem; +import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.internal.process.runtime.KogitoWorkItemManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WorkItemHandlerTracker implements KogitoWorkItemHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(WorkItemHandlerTracker.class); + + private final List workItems; + + public WorkItemHandlerTracker() { + workItems = Collections.synchronizedList(new ArrayList<>()); + } + + public String getFirstId() { + return workItems.get(0).getStringId(); + } + + public Collection getWorkItems() { + synchronized (workItems) { + return Collections.unmodifiableCollection(new ArrayList<>(workItems)); + } + } + + @Override + public void executeWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + LOGGER.info("executing: " + workItem.getStringId()); + workItems.add(workItem); + } + + @Override + public void abortWorkItem(KogitoWorkItem workItem, KogitoWorkItemManager manager) { + LOGGER.info("aborting: " + workItem.getStringId()); + workItems.remove(workItem); + } + + public String getIdForNodeName(String nodeName) { + for (KogitoWorkItem kwi : workItems) { + if (kwi.getState() == KogitoWorkItem.PENDING && kwi.getNodeInstance().getNodeName().equals(nodeName)) { + return kwi.getStringId(); + } + } + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + for (KogitoWorkItem kwi : workItems) { + builder.append(kwi); + builder.append("\n"); + } + return builder.toString(); + } + + public List getWorkItemsFor(String processId) { + List tmp = new ArrayList<>(); + for (KogitoWorkItem kwi : workItems) { + if (kwi.getState() == KogitoWorkItem.PENDING && kwi.getProcessInstance().getProcessId().equals(processId)) { + tmp.add(kwi); + } + } + return tmp; + } + +} diff --git a/kogito-tck/kogito-junit5-extension/src/main/resources/META-INF/services/org.junit.jupiter.api.extension.Extension b/kogito-tck/kogito-junit5-extension/src/main/resources/META-INF/services/org.junit.jupiter.api.extension.Extension new file mode 100644 index 00000000000..c433b48ca5b --- /dev/null +++ b/kogito-tck/kogito-junit5-extension/src/main/resources/META-INF/services/org.junit.jupiter.api.extension.Extension @@ -0,0 +1,2 @@ +org.kie.kogito.junit.extension.KogitoUnitTestEnvironmentExtension +org.kie.kogito.junit.extension.KogitoUnitTestDeploymentExtension \ No newline at end of file diff --git a/kogito-tck/kogito-junit5-persistence-fs/pom.xml b/kogito-tck/kogito-junit5-persistence-fs/pom.xml new file mode 100644 index 00000000000..33cf01f196b --- /dev/null +++ b/kogito-tck/kogito-junit5-persistence-fs/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + org.kie.kogito + kogito-tck + 2.0.0-SNAPSHOT + + kogito-junit5-persistence-fs + kogito-junit5-persistence-fs + http://maven.apache.org + + + UTF-8 + + + + + org.kie.kogito + kogito-junit5-core + + + org.kie.kogito + kogito-addons-persistence-filesystem + + + org.kie.kogito + process-serialization-protobuf + + + diff --git a/kogito-tck/kogito-junit5-persistence-fs/src/main/java/org/kogito/junit5/persistence/fs/FileSystemPersistenceRuntimeBuildPropertiesProvider.java b/kogito-tck/kogito-junit5-persistence-fs/src/main/java/org/kogito/junit5/persistence/fs/FileSystemPersistenceRuntimeBuildPropertiesProvider.java new file mode 100644 index 00000000000..ffb754cfce8 --- /dev/null +++ b/kogito-tck/kogito-junit5-persistence-fs/src/main/java/org/kogito/junit5/persistence/fs/FileSystemPersistenceRuntimeBuildPropertiesProvider.java @@ -0,0 +1,31 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kogito.junit5.persistence.fs; + +import java.util.Properties; + +import org.kie.kogito.codegen.process.persistence.PersistenceGenerator; +import org.kie.kogito.junit.deployment.spi.RuntimeBuildPropertiesProvider; + +public class FileSystemPersistenceRuntimeBuildPropertiesProvider implements RuntimeBuildPropertiesProvider { + + @Override + public void provide(Properties properties) { + properties.setProperty("kogito.persistence.type", PersistenceGenerator.FILESYSTEM_PERSISTENCE_TYPE); + } + +} diff --git a/kogito-tck/kogito-junit5-persistence-fs/src/main/java/org/kogito/junit5/persistence/fs/FileSystemRuntimeTestPersistenceProvider.java b/kogito-tck/kogito-junit5-persistence-fs/src/main/java/org/kogito/junit5/persistence/fs/FileSystemRuntimeTestPersistenceProvider.java new file mode 100644 index 00000000000..0161e27494d --- /dev/null +++ b/kogito-tck/kogito-junit5-persistence-fs/src/main/java/org/kogito/junit5/persistence/fs/FileSystemRuntimeTestPersistenceProvider.java @@ -0,0 +1,37 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kogito.junit5.persistence.fs; + +import java.nio.file.Files; +import java.nio.file.Path; + +import org.kie.kogito.junit.deployment.spi.RuntimeTestPersistenceProvider; +import org.kie.kogito.persistence.KogitoProcessInstancesFactory; + +public class FileSystemRuntimeTestPersistenceProvider implements RuntimeTestPersistenceProvider { + + @Override + public void prepare(KogitoProcessInstancesFactory prepare) { + try { + Path buildPath = Files.createTempDirectory("KOGITO_FS_STORAGE_"); + prepare.setPath(buildPath.toString()); + } catch (Exception e) { + throw new RuntimeException("cannot create kogito fs storage", e); + } + } + +} diff --git a/kogito-tck/kogito-junit5-persistence-fs/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.RuntimeBuildPropertiesProvider b/kogito-tck/kogito-junit5-persistence-fs/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.RuntimeBuildPropertiesProvider new file mode 100644 index 00000000000..dc413ec66f6 --- /dev/null +++ b/kogito-tck/kogito-junit5-persistence-fs/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.RuntimeBuildPropertiesProvider @@ -0,0 +1 @@ +org.kogito.junit5.persistence.fs.FileSystemPersistenceRuntimeBuildPropertiesProvider \ No newline at end of file diff --git a/kogito-tck/kogito-junit5-persistence-fs/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.RuntimeTestPersistenceProvider b/kogito-tck/kogito-junit5-persistence-fs/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.RuntimeTestPersistenceProvider new file mode 100644 index 00000000000..ed552c591d8 --- /dev/null +++ b/kogito-tck/kogito-junit5-persistence-fs/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.RuntimeTestPersistenceProvider @@ -0,0 +1 @@ +org.kogito.junit5.persistence.fs.FileSystemRuntimeTestPersistenceProvider diff --git a/kogito-tck/kogito-junit5-runtime-java/pom.xml b/kogito-tck/kogito-junit5-runtime-java/pom.xml new file mode 100644 index 00000000000..4f793a22feb --- /dev/null +++ b/kogito-tck/kogito-junit5-runtime-java/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + org.kie.kogito + kogito-tck + 2.0.0-SNAPSHOT + + + kogito-junit5-runtime-java + kogito-junit5-runtime-java + http://maven.apache.org + + + UTF-8 + + + + org.kie.kogito + kogito-junit5-core + + + diff --git a/kogito-tck/kogito-junit5-runtime-java/src/main/java/org/kogito/junit5/runtime/java/JavaDeploymentInstance.java b/kogito-tck/kogito-junit5-runtime-java/src/main/java/org/kogito/junit5/runtime/java/JavaDeploymentInstance.java new file mode 100644 index 00000000000..2ee8eba0f9c --- /dev/null +++ b/kogito-tck/kogito-junit5-runtime-java/src/main/java/org/kogito/junit5/runtime/java/JavaDeploymentInstance.java @@ -0,0 +1,113 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kogito.junit5.runtime.java; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.kie.api.event.process.ProcessEventListener; +import org.kie.api.event.rule.AgendaEventListener; +import org.kie.kogito.Application; +import org.kie.kogito.Model; +import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.junit.deployment.DeploymentInstance; +import org.kie.kogito.process.Process; +import org.kie.kogito.process.ProcessConfig; +import org.kie.kogito.process.Processes; +import org.kie.kogito.process.impl.CachedWorkItemHandlerConfig; +import org.kie.kogito.rules.RuleConfig; + +public class JavaDeploymentInstance implements DeploymentInstance { + + private JavaFolderClassLoader classLoader; + private Application application; + + private ProcessConfig processConfig; + private RuleConfig ruleConfig; + private List eventListeners; + private Map workItemHandlers; + + public JavaDeploymentInstance(JavaFolderClassLoader classLoader) { + this.classLoader = classLoader; + this.eventListeners = new ArrayList<>(); + this.workItemHandlers = new HashMap<>(); + + } + + public void setProcessConfig(ProcessConfig processConfig) { + this.processConfig = processConfig; + } + + public ProcessConfig getProcessConfig() { + return processConfig; + } + + public void setRuleConfig(RuleConfig ruleConfig) { + this.ruleConfig = ruleConfig; + } + + public RuleConfig getRuleConfig() { + return ruleConfig; + } + + public void registerWorkItemHandler(String name, KogitoWorkItemHandler handler) { + workItemHandlers.put(name, handler); + ((CachedWorkItemHandlerConfig) getProcessConfig().workItemHandlers()).register(name, handler); + } + + public void register(Object processEventListener) { + if (processEventListener instanceof ProcessEventListener) { + eventListeners.add(processEventListener); + getProcessConfig().processEventListeners().listeners().add((ProcessEventListener) processEventListener); + } else if (processEventListener instanceof AgendaEventListener) { + eventListeners.add(processEventListener); + getRuleConfig().ruleEventListeners().agendaListeners().add((AgendaEventListener) processEventListener); + } + } + + public Map getWorkItemHandlers() { + return Collections.unmodifiableMap(workItemHandlers); + } + + public List getProcessEventListeners() { + return Collections.unmodifiableList(eventListeners); + } + + public void setApplication(Application application) { + this.application = application; + this.setProcessConfig(this.getApplication().config().get(ProcessConfig.class)); + this.setRuleConfig(this.application.config().get(RuleConfig.class)); + } + + public Application getApplication() { + return application; + } + + @Override + public Process processById(String processId) { + return application.get(Processes.class).processById(processId); + } + + @Override + public void destroy() { + classLoader.destroy(); + } + +} \ No newline at end of file diff --git a/kogito-tck/kogito-junit5-runtime-java/src/main/java/org/kogito/junit5/runtime/java/JavaDeploymentInstanceBuilder.java b/kogito-tck/kogito-junit5-runtime-java/src/main/java/org/kogito/junit5/runtime/java/JavaDeploymentInstanceBuilder.java new file mode 100644 index 00000000000..8be13ab2c74 --- /dev/null +++ b/kogito-tck/kogito-junit5-runtime-java/src/main/java/org/kogito/junit5/runtime/java/JavaDeploymentInstanceBuilder.java @@ -0,0 +1,54 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kogito.junit5.runtime.java; + +import java.nio.file.Path; +import java.util.Map; + +import org.kie.kogito.Application; +import org.kie.kogito.internal.process.runtime.KogitoWorkItemHandler; +import org.kie.kogito.junit.deployment.Deployment; +import org.kie.kogito.junit.deployment.DeploymentInstance; +import org.kie.kogito.junit.deployment.spi.impl.AbstractDeploymentInstanceBuilder; +import org.kie.kogito.process.Processes; + +public class JavaDeploymentInstanceBuilder extends AbstractDeploymentInstanceBuilder { + + @SuppressWarnings("unchecked") + @Override + protected DeploymentInstance createDeploymentInstance(Deployment deployment, Path path) throws Exception { + JavaFolderClassLoader classLoader = new JavaFolderClassLoader(JavaFolderClassLoader.class.getClassLoader(), path); + + JavaDeploymentInstance instance = new JavaDeploymentInstance(classLoader); + + instance.setApplication((Application) classLoader.loadClass(deployment.namespace() + ".Application").getConstructor().newInstance()); + + getRuntimeTestPersistenceProvider().ifPresent(persistence -> persistence.prepare(instance.getApplication().get(Processes.class).processInstancesFactory())); + + for (Class listener : deployment.getEventListeners()) { + instance.register(listener.getConstructor().newInstance()); + } + + for (Map.Entry> entry : deployment.getWorkItemHandlers().entrySet()) { + KogitoWorkItemHandler handler = entry.getValue().getConstructor().newInstance(); + String name = entry.getKey(); + instance.registerWorkItemHandler(name, handler); + } + + return instance; + } +} diff --git a/kogito-tck/kogito-junit5-runtime-java/src/main/java/org/kogito/junit5/runtime/java/JavaFolderClassLoader.java b/kogito-tck/kogito-junit5-runtime-java/src/main/java/org/kogito/junit5/runtime/java/JavaFolderClassLoader.java new file mode 100644 index 00000000000..739053e7a71 --- /dev/null +++ b/kogito-tck/kogito-junit5-runtime-java/src/main/java/org/kogito/junit5/runtime/java/JavaFolderClassLoader.java @@ -0,0 +1,85 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kogito.junit5.runtime.java; + +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Comparator; +import java.util.stream.Stream; + +public class JavaFolderClassLoader extends ClassLoader { + + private Path path; + + public JavaFolderClassLoader(ClassLoader parentClassLoader, Path path) { + this.path = path; + } + + @Override + public Class loadClass(String name) + throws ClassNotFoundException { + Class clazz = getClass(name); + return clazz != null ? clazz : super.loadClass(name); + } + + private Class getClass(String name) + throws ClassNotFoundException { + String file = name.replace('.', File.separatorChar) + ".class"; + try { + byte[] clazzBytes = loadClassData(file); + Class c = defineClass(name, clazzBytes, 0, clazzBytes.length); + resolveClass(c); + return c; + } catch (IOException e) { + return null; + } + } + + private byte[] loadClassData(String name) throws IOException { + // Opening the file + InputStream stream = new FileInputStream(path.resolve(name).toFile()); + int size = stream.available(); + byte buff[] = new byte[size]; + DataInputStream in = new DataInputStream(stream); + // Reading the binary data + in.readFully(buff); + in.close(); + return buff; + } + + public void destroy() { + try { + // create a stream + Stream files = Files.walk(path); + + files.sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach(File::deleteOnExit); + + // close the stream + files.close(); + + } catch (IOException ex) { + // do nothing + } + } +} diff --git a/kogito-tck/kogito-junit5-runtime-java/src/main/java/org/kogito/junit5/runtime/java/JavaRuntimeBuildContextProvider.java b/kogito-tck/kogito-junit5-runtime-java/src/main/java/org/kogito/junit5/runtime/java/JavaRuntimeBuildContextProvider.java new file mode 100644 index 00000000000..540aebc998a --- /dev/null +++ b/kogito-tck/kogito-junit5-runtime-java/src/main/java/org/kogito/junit5/runtime/java/JavaRuntimeBuildContextProvider.java @@ -0,0 +1,30 @@ +/* + * Copyright 2021 Red Hat, Inc. and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kogito.junit5.runtime.java; + +import org.kie.kogito.codegen.api.context.KogitoBuildContext.Builder; +import org.kie.kogito.codegen.api.context.impl.JavaKogitoBuildContext; +import org.kie.kogito.junit.deployment.spi.RuntimeBuildContextProvider; + +public class JavaRuntimeBuildContextProvider implements RuntimeBuildContextProvider { + + @Override + public Builder newBuildContext() { + return JavaKogitoBuildContext.builder(); + } + +} diff --git a/kogito-tck/kogito-junit5-runtime-java/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.DeploymentInstanceBuilder b/kogito-tck/kogito-junit5-runtime-java/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.DeploymentInstanceBuilder new file mode 100644 index 00000000000..aebe44a4b98 --- /dev/null +++ b/kogito-tck/kogito-junit5-runtime-java/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.DeploymentInstanceBuilder @@ -0,0 +1,2 @@ +org.kogito.junit5.runtime.java.JavaDeploymentInstanceBuilder + diff --git a/kogito-tck/kogito-junit5-runtime-java/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.RuntimeBuildContextProvider b/kogito-tck/kogito-junit5-runtime-java/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.RuntimeBuildContextProvider new file mode 100644 index 00000000000..ccb4e07b492 --- /dev/null +++ b/kogito-tck/kogito-junit5-runtime-java/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.RuntimeBuildContextProvider @@ -0,0 +1 @@ +org.kogito.junit5.runtime.java.JavaRuntimeBuildContextProvider \ No newline at end of file diff --git a/kogito-tck/kogito-junit5-runtime-java/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.RuntimeBuildGeneratorProvider b/kogito-tck/kogito-junit5-runtime-java/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.RuntimeBuildGeneratorProvider new file mode 100644 index 00000000000..8465e6c00c6 --- /dev/null +++ b/kogito-tck/kogito-junit5-runtime-java/src/main/resources/META-INF/services/org.kie.kogito.junit.deployment.spi.RuntimeBuildGeneratorProvider @@ -0,0 +1,6 @@ +org.kie.kogito.junit.deployment.spi.impl.DecisionRuntimeBuildGeneratorProvider +org.kie.kogito.junit.deployment.spi.impl.ProcessRuntimeBuildGeneratorProvider +org.kie.kogito.junit.deployment.spi.impl.BuildIncrementalRuleRuntimeBuildGeneratorProvider +org.kie.kogito.junit.deployment.spi.impl.PredictionRuntimeBuildGeneratorProvider +org.kie.kogito.junit.deployment.spi.impl.PersistenceRuntimeBuildGeneratorProvider + diff --git a/kogito-tck/pom.xml b/kogito-tck/pom.xml new file mode 100644 index 00000000000..c3061359c6f --- /dev/null +++ b/kogito-tck/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + org.kie.kogito + kogito-build-parent + 2.0.0-SNAPSHOT + ../kogito-build/kogito-build-parent/pom.xml + + + kogito-tck + pom + + Kogito Test Compatibilty Kit Parent + + + UTF-8 + + + + + + kogito-junit5-extension + kogito-junit5-core + kogito-junit5-runtime-java + kogito-junit5-persistence-fs + + + kogito-junit-examples + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index e0329492cab..3a25be6d7ab 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,5 @@ - + org.jboss @@ -131,6 +130,7 @@ addons kogito-workitems kogito-serverless-workflow + kogito-tck @@ -157,4 +157,5 @@ +