Skip to content

Commit 4e0a249

Browse files
authored
Add tests for flowable engine
JIRA:LMCROSSITXSADEPLOY-3320
1 parent f50a745 commit 4e0a249

File tree

7 files changed

+712
-4
lines changed

7 files changed

+712
-4
lines changed

multiapps-controller-persistence-test/src/main/java/org/cloudfoundry/multiapps/controller/persistence/test/TestDataSourceProvider.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,26 @@
33
import java.sql.Connection;
44
import java.sql.DriverManager;
55
import java.sql.SQLException;
6-
76
import javax.sql.DataSource;
87

9-
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
10-
118
import liquibase.Liquibase;
129
import liquibase.database.Database;
1310
import liquibase.database.DatabaseFactory;
1411
import liquibase.database.jvm.JdbcConnection;
1512
import liquibase.resource.ClassLoaderResourceAccessor;
13+
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
1614

1715
public final class TestDataSourceProvider {
1816

1917
private TestDataSourceProvider() {
2018

2119
}
2220

21+
public static DataSource getDataSource() throws Exception {
22+
Connection connection = createH2InMemoryConnection();
23+
return new SingleConnectionDataSource(connection, true);
24+
}
25+
2326
public static DataSource getDataSource(String liquibaseChangelogLocation) throws Exception {
2427
// Liquibase closes the connection after it's done, so we need a separate one for it.
2528
Connection connectionForLiquibase = createH2InMemoryConnection();

multiapps-controller-process/pom.xml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
33
<modelVersion>4.0.0</modelVersion>
44

55
<artifactId>multiapps-controller-process</artifactId>
@@ -96,5 +96,15 @@
9696
<groupId>jakarta.xml.bind</groupId>
9797
<artifactId>jakarta.xml.bind-api</artifactId>
9898
</dependency>
99+
<dependency>
100+
<groupId>org.cloudfoundry.multiapps</groupId>
101+
<artifactId>multiapps-controller-persistence-test</artifactId>
102+
<scope>test</scope>
103+
</dependency>
104+
<dependency>
105+
<groupId>com.h2database</groupId>
106+
<artifactId>h2</artifactId>
107+
<scope>test</scope>
108+
</dependency>
99109
</dependencies>
100110
</project>
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
package org.cloudfoundry.multiapps.controller.process.flowable;
2+
3+
import java.util.HashMap;
4+
import java.util.List;
5+
import java.util.Map;
6+
import javax.sql.DataSource;
7+
8+
import org.cloudfoundry.multiapps.common.util.JsonSerializationStrategy;
9+
import org.cloudfoundry.multiapps.common.util.JsonUtil;
10+
import org.cloudfoundry.multiapps.controller.persistence.test.TestDataSourceProvider;
11+
import org.cloudfoundry.multiapps.controller.process.variables.Serializer;
12+
import org.cloudfoundry.multiapps.controller.process.variables.Variable;
13+
import org.cloudfoundry.multiapps.controller.process.variables.Variables;
14+
import org.flowable.engine.ProcessEngine;
15+
import org.flowable.engine.ProcessEngineConfiguration;
16+
import org.flowable.engine.RepositoryService;
17+
import org.flowable.engine.RuntimeService;
18+
import org.flowable.engine.delegate.DelegateExecution;
19+
import org.flowable.engine.delegate.JavaDelegate;
20+
import org.flowable.engine.repository.ProcessDefinition;
21+
import org.flowable.mail.common.api.client.FlowableMailClient;
22+
import org.junit.jupiter.api.AfterEach;
23+
import org.junit.jupiter.api.BeforeEach;
24+
import org.junit.jupiter.api.Test;
25+
import org.mockito.Mock;
26+
import org.mockito.MockitoAnnotations;
27+
28+
import static org.junit.jupiter.api.Assertions.assertEquals;
29+
import static org.junit.jupiter.api.Assertions.assertNotEquals;
30+
31+
/**
32+
* Integration test for Flowable engine with in-memory H2 database. Tests real BPMN process creation, variable setting and retrieval using
33+
* the multiapps-controller variable handling system.
34+
*/
35+
class FlowableEngineTest {
36+
37+
private static final String TEST_PROCESS_KEY = "mtaDeploymentTest";
38+
private static final String MTA_DEPLOYMENT_TEST_PROCESS = "MTA Deployment Test Process";
39+
private static final String FLOWABLE_DB_SCHEMA_STRATEGY_CREATE_DROP = "create-drop";
40+
private static final String TEST_VARIABLE_TASK_BEAN_NAME = "testVariableTask";
41+
private static final String DEPLOYMENT_NAME_OF_DIAGRAM = "MTA Deployment Test";
42+
private static final String TEST_BPMN_DIAGRAM_RESOURCE =
43+
"org/cloudfoundry/multiapps/controller/process/flowable/test-bpmn-diagram.bpmn";
44+
45+
@Mock
46+
private FlowableMailClient flowableMailClient;
47+
48+
private ProcessEngine processEngine;
49+
private RepositoryService repositoryService;
50+
private RuntimeService runtimeService;
51+
private String deploymentId;
52+
private TestVariableTask testVariableTask;
53+
54+
@BeforeEach
55+
void setUp() throws Exception {
56+
MockitoAnnotations.openMocks(this);
57+
testVariableTask = new TestVariableTask();
58+
DataSource dataSource = TestDataSourceProvider.getDataSource();
59+
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
60+
configuration.setDataSource(dataSource);
61+
configuration.setDefaultMailClient(flowableMailClient);
62+
configuration.setDatabaseSchemaUpdate(FLOWABLE_DB_SCHEMA_STRATEGY_CREATE_DROP);
63+
configuration.setBeans(Map.of(TEST_VARIABLE_TASK_BEAN_NAME, testVariableTask));
64+
processEngine = configuration.buildProcessEngine();
65+
repositoryService = processEngine.getRepositoryService();
66+
runtimeService = processEngine.getRuntimeService();
67+
deploymentId = repositoryService.createDeployment()
68+
.name(DEPLOYMENT_NAME_OF_DIAGRAM)
69+
.addClasspathResource(
70+
TEST_BPMN_DIAGRAM_RESOURCE)
71+
.deploy()
72+
.getId();
73+
}
74+
75+
@AfterEach
76+
void tearDown() {
77+
if (deploymentId != null) {
78+
repositoryService.deleteDeployment(deploymentId, true);
79+
}
80+
if (processEngine != null) {
81+
processEngine.close();
82+
}
83+
}
84+
85+
@Test
86+
void testProcessDeployment() {
87+
List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery()
88+
.processDefinitionKey(TEST_PROCESS_KEY)
89+
.list();
90+
91+
assertEquals(1, processDefinitions.size());
92+
assertEquals(TEST_PROCESS_KEY, processDefinitions.get(0)
93+
.getKey());
94+
assertEquals(MTA_DEPLOYMENT_TEST_PROCESS, processDefinitions.get(0)
95+
.getName());
96+
}
97+
98+
@Test
99+
void testProcessWithPredefinedVariables() {
100+
FlowableProcessTestData data = FlowableProcessTestDataUtils.predefinedScenario();
101+
runtimeService.startProcessInstanceByKey(TEST_PROCESS_KEY, buildVariablesMap(data));
102+
assertCapturedVariables(data, true);
103+
}
104+
105+
@Test
106+
void testVariableUpdateAndRetrieval() {
107+
FlowableProcessTestDataUtils.UpdateScenario updateScenario = FlowableProcessTestDataUtils.updateScenario();
108+
testVariableTask.variablesToSetInContext = buildVariablesMap(updateScenario.updated());
109+
runtimeService.startProcessInstanceByKey(TEST_PROCESS_KEY, buildVariablesMap(updateScenario.initial()));
110+
// This assertion intentionally checks that the modified deployment descriptor is different from the initially set one because of flowable caching regression
111+
// https://github.com/flowable/flowable-engine/issues/4130
112+
// The original behaviour must be to have same deployment descriptor as it was set in the task. Modify the test to assert for matching values when the issue is fixed.
113+
assertCapturedVariables(updateScenario.updated(), false);
114+
}
115+
116+
@Test
117+
void testSetVariablesInsideStep() {
118+
FlowableProcessTestData data = FlowableProcessTestDataUtils.insideStepScenario();
119+
testVariableTask.variablesToSetInContext = buildVariablesMap(data);
120+
runtimeService.startProcessInstanceByKey(TEST_PROCESS_KEY);
121+
assertCapturedVariables(data, true);
122+
}
123+
124+
private Map<String, Object> buildVariablesMap(FlowableProcessTestData flowableProcessTestData) {
125+
Map<String, Object> vars = new HashMap<>();
126+
setSerializedValueInMap(vars, Variables.CORRELATION_ID, flowableProcessTestData.getCorrelationId());
127+
setSerializedValueInMap(vars, Variables.SPACE_GUID, flowableProcessTestData.getSpaceGuid());
128+
setSerializedValueInMap(vars, Variables.ORGANIZATION_GUID, flowableProcessTestData.getOrgGuid());
129+
setSerializedValueInMap(vars, Variables.USER, flowableProcessTestData.getUsername());
130+
setSerializedValueInMap(vars, Variables.USER_GUID, flowableProcessTestData.getUserGuid());
131+
setSerializedValueInMap(vars, Variables.MTA_ID, flowableProcessTestData.getMtaId());
132+
setSerializedValueInMap(vars, Variables.KEEP_FILES, flowableProcessTestData.keepFiles());
133+
setSerializedValueInMap(vars, Variables.DELETE_SERVICES, flowableProcessTestData.deleteServices());
134+
setSerializedValueInMap(vars, Variables.APPS_STAGE_TIMEOUT_PROCESS_VARIABLE, flowableProcessTestData.getAppsStageTimeout());
135+
setSerializedValueInMap(vars, Variables.MODULES_COUNT, flowableProcessTestData.getModulesCount());
136+
setSerializedValueInMap(vars, Variables.DEPLOYMENT_DESCRIPTOR_WITH_SYSTEM_PARAMETERS, flowableProcessTestData.getSmallDescriptor());
137+
setSerializedValueInMap(vars, Variables.DEPLOYMENT_DESCRIPTOR, flowableProcessTestData.getBigDescriptor());
138+
setSerializedValueInMap(vars, Variables.DEPLOYED_MTA, flowableProcessTestData.getDeployedMta());
139+
setSerializedValueInMap(vars, Variables.CURRENT_ROUTES, flowableProcessTestData.getRoutes());
140+
setSerializedValueInMap(vars, Variables.STEP_PHASE, flowableProcessTestData.getStepPhase());
141+
setSerializedValueInMap(vars, Variables.APP_STATE_ACTIONS_TO_EXECUTE, flowableProcessTestData.getAppActions());
142+
setSerializedValueInMap(vars, Variables.CLOUD_SERVICE_KEYS_TO_CREATE, flowableProcessTestData.getServiceKeys());
143+
setSerializedValueInMap(vars, Variables.MODULES_FOR_DEPLOYMENT, flowableProcessTestData.getModulesForDeployment());
144+
setSerializedValueInMap(vars, Variables.MTA_EXTENSION_DESCRIPTOR_CHAIN, flowableProcessTestData.getExtensionDescriptors());
145+
return vars;
146+
}
147+
148+
private <T> void setSerializedValueInMap(Map<String, Object> variables, Variable<T> variable, T value) {
149+
if (value == null) {
150+
variables.put(variable.getName(), null);
151+
return;
152+
}
153+
Serializer<T> serializer = variable.getSerializer();
154+
variables.put(variable.getName(), serializer.serialize(value));
155+
}
156+
157+
private <T> T getDeserializedValue(Map<String, Object> variables, Variable<T> variable) {
158+
Object serializedValue = variables.get(variable.getName());
159+
if (serializedValue == null) {
160+
return variable.getDefaultValue();
161+
}
162+
Serializer<T> serializer = variable.getSerializer();
163+
return serializer.deserialize(serializedValue);
164+
}
165+
166+
private void assertCapturedVariables(FlowableProcessTestData expected, boolean expectBigDescriptorMatch) {
167+
Map<String, Object> actual = testVariableTask.capturedVariables;
168+
assertEquals(expected.getCorrelationId(), getDeserializedValue(actual, Variables.CORRELATION_ID));
169+
assertEquals(expected.getSpaceGuid(), getDeserializedValue(actual, Variables.SPACE_GUID));
170+
assertEquals(expected.getOrgGuid(), getDeserializedValue(actual, Variables.ORGANIZATION_GUID));
171+
assertEquals(expected.getUsername(), getDeserializedValue(actual, Variables.USER));
172+
assertEquals(expected.getUserGuid(), getDeserializedValue(actual, Variables.USER_GUID));
173+
assertEquals(expected.getMtaId(), getDeserializedValue(actual, Variables.MTA_ID));
174+
assertEquals(expected.keepFiles(), getDeserializedValue(actual, Variables.KEEP_FILES));
175+
assertEquals(expected.deleteServices(), getDeserializedValue(actual, Variables.DELETE_SERVICES));
176+
assertEquals(expected.getAppsStageTimeout(), getDeserializedValue(actual, Variables.APPS_STAGE_TIMEOUT_PROCESS_VARIABLE));
177+
assertEquals(expected.getModulesCount(), getDeserializedValue(actual, Variables.MODULES_COUNT));
178+
assertEquals(JsonUtil.toJson(expected.getSmallDescriptor()),
179+
JsonUtil.toJson(getDeserializedValue(actual, Variables.DEPLOYMENT_DESCRIPTOR_WITH_SYSTEM_PARAMETERS)));
180+
181+
String expectedBigDescriptor = JsonUtil.toJson(expected.getBigDescriptor());
182+
String actualBigDescriptor = JsonUtil.toJson(getDeserializedValue(actual, Variables.DEPLOYMENT_DESCRIPTOR));
183+
assertBigDescriptor(expectBigDescriptorMatch, expectedBigDescriptor, actualBigDescriptor);
184+
185+
assertEquals(expected.getDeployedMta(), getDeserializedValue(actual, Variables.DEPLOYED_MTA));
186+
assertEquals(expected.getRoutes(), getDeserializedValue(actual, Variables.CURRENT_ROUTES));
187+
assertEquals(expected.getStepPhase(), getDeserializedValue(actual, Variables.STEP_PHASE));
188+
assertEquals(expected.getAppActions(), getDeserializedValue(actual, Variables.APP_STATE_ACTIONS_TO_EXECUTE));
189+
assertEquals(expected.getServiceKeys(), getDeserializedValue(actual, Variables.CLOUD_SERVICE_KEYS_TO_CREATE));
190+
assertEquals(expected.getModulesForDeployment(), getDeserializedValue(actual, Variables.MODULES_FOR_DEPLOYMENT));
191+
assertEquals(JsonUtil.toJson(expected.getExtensionDescriptors(), JsonSerializationStrategy.ALLOW_NULLS),
192+
JsonUtil.toJson(getDeserializedValue(actual, Variables.MTA_EXTENSION_DESCRIPTOR_CHAIN),
193+
JsonSerializationStrategy.ALLOW_NULLS));
194+
}
195+
196+
private static void assertBigDescriptor(boolean expectBigDescriptorMatch, String expectedBigDescriptor, String actualBigDescriptor) {
197+
if (expectBigDescriptorMatch) {
198+
assertEquals(expectedBigDescriptor, actualBigDescriptor);
199+
return;
200+
}
201+
assertNotEquals(expectedBigDescriptor, actualBigDescriptor);
202+
203+
}
204+
205+
private class TestVariableTask implements JavaDelegate {
206+
207+
Map<String, Object> variablesToSetInContext = new HashMap<>();
208+
Map<String, Object> capturedVariables = new HashMap<>();
209+
210+
@Override
211+
public void execute(DelegateExecution execution) {
212+
execution.setVariables(variablesToSetInContext);
213+
capturedVariables = execution.getVariables();
214+
}
215+
}
216+
217+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package org.cloudfoundry.multiapps.controller.process.flowable;
2+
3+
import java.time.Duration;
4+
import java.util.List;
5+
6+
import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudRoute;
7+
import org.cloudfoundry.multiapps.controller.client.facade.domain.CloudServiceKey;
8+
import org.cloudfoundry.multiapps.controller.core.cf.apps.ApplicationStateAction;
9+
import org.cloudfoundry.multiapps.controller.core.model.DeployedMta;
10+
import org.cloudfoundry.multiapps.controller.process.steps.StepPhase;
11+
import org.cloudfoundry.multiapps.mta.model.DeploymentDescriptor;
12+
import org.cloudfoundry.multiapps.mta.model.ExtensionDescriptor;
13+
import org.immutables.value.Value;
14+
15+
@Value.Immutable
16+
public interface FlowableProcessTestData {
17+
18+
String getCorrelationId();
19+
20+
String getSpaceGuid();
21+
22+
String getOrgGuid();
23+
24+
String getUsername();
25+
26+
String getUserGuid();
27+
28+
String getMtaId();
29+
30+
String getMtaVersion();
31+
32+
@Value.Default
33+
default boolean keepFiles() {
34+
return false;
35+
}
36+
37+
@Value.Default
38+
default boolean deleteServices() {
39+
return false;
40+
}
41+
42+
Duration getAppsStageTimeout();
43+
44+
@Value.Default
45+
default int getModulesCount() {
46+
return 0;
47+
}
48+
49+
DeploymentDescriptor getSmallDescriptor();
50+
51+
DeploymentDescriptor getBigDescriptor();
52+
53+
DeployedMta getDeployedMta();
54+
55+
List<CloudRoute> getRoutes();
56+
57+
StepPhase getStepPhase();
58+
59+
List<ApplicationStateAction> getAppActions();
60+
61+
List<CloudServiceKey> getServiceKeys();
62+
63+
List<String> getModulesForDeployment();
64+
65+
List<ExtensionDescriptor> getExtensionDescriptors();
66+
67+
}

0 commit comments

Comments
 (0)