This is an automated email from the ASF dual-hosted git repository.
sergehuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/unomi.git
The following commit(s) were added to refs/heads/master by this push:
new 5ebbe8a81 UNOMI-881: Harden GoalsServiceImplTest against CI flakiness
(#788)
5ebbe8a81 is described below
commit 5ebbe8a818a5d584555f4f156f7d22fdd3c5343c
Author: Serge Huber <[email protected]>
AuthorDate: Mon Jun 29 13:03:19 2026 +0200
UNOMI-881: Harden GoalsServiceImplTest against CI flakiness (#788)
Merge goals test flake fix
---
.../services/impl/goals/GoalsServiceImplTest.java | 89 +++++++++++++---------
1 file changed, 53 insertions(+), 36 deletions(-)
diff --git
a/services/src/test/java/org/apache/unomi/services/impl/goals/GoalsServiceImplTest.java
b/services/src/test/java/org/apache/unomi/services/impl/goals/GoalsServiceImplTest.java
index 54d41ecd8..2884b4a60 100644
---
a/services/src/test/java/org/apache/unomi/services/impl/goals/GoalsServiceImplTest.java
+++
b/services/src/test/java/org/apache/unomi/services/impl/goals/GoalsServiceImplTest.java
@@ -19,8 +19,8 @@ package org.apache.unomi.services.impl.goals;
import org.apache.unomi.api.Metadata;
import org.apache.unomi.api.actions.ActionType;
import org.apache.unomi.api.conditions.Condition;
+import org.apache.unomi.api.conditions.ConditionType;
import org.apache.unomi.api.goals.Goal;
-import org.apache.unomi.api.services.ConditionValidationService;
import org.apache.unomi.api.services.EventService;
import org.apache.unomi.api.services.RulesService;
import org.apache.unomi.api.services.SchedulerService;
@@ -36,6 +36,7 @@ import org.apache.unomi.services.impl.TestTenantService;
import org.apache.unomi.services.impl.cache.MultiTypeCacheServiceImpl;
import org.apache.unomi.services.impl.definitions.DefinitionsServiceImpl;
import org.apache.unomi.services.impl.events.EventServiceImpl;
+import org.apache.unomi.services.impl.rules.RulesServiceImpl;
import org.apache.unomi.services.impl.rules.TestActionExecutorDispatcher;
import org.apache.unomi.services.impl.scheduler.SchedulerServiceImpl;
import org.apache.unomi.tracing.api.TracerService;
@@ -52,6 +53,8 @@ import org.osgi.framework.BundleContext;
import java.io.IOException;
import java.util.*;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
public class GoalsServiceImplTest {
@@ -66,6 +69,7 @@ public class GoalsServiceImplTest {
private EventServiceImpl eventService;
private SchedulerService schedulerService;
private MultiTypeCacheServiceImpl multiTypeCacheService;
+ private TestEventAdmin testEventAdmin;
@Mock
private BundleContext bundleContext;
@@ -74,6 +78,7 @@ public class GoalsServiceImplTest {
TracerService tracerService = TestHelper.createTracerService();
tenantService = new TestTenantService();
+ TestHelper.setupCommonTestData(tenantService);
tenantService.setCurrentTenantId("test-tenant");
ConditionEvaluatorDispatcher conditionEvaluatorDispatcher =
TestConditionEvaluators.createDispatcher();
securityService = TestHelper.createSecurityService();
@@ -90,7 +95,7 @@ public class GoalsServiceImplTest {
TestHelper.createDefinitionServiceWithEventAdmin(persistenceService,
bundleContext, schedulerService,
multiTypeCacheService, executionContextManager, tenantService);
definitionsService = servicePair.getKey();
- TestEventAdmin testEventAdmin = servicePair.getValue();
+ testEventAdmin = servicePair.getValue();
// Inject definitionsService into the dispatcher
TestHelper.injectDefinitionsServiceIntoDispatcher(conditionEvaluatorDispatcher,
definitionsService);
@@ -144,14 +149,21 @@ public class GoalsServiceImplTest {
@AfterEach
public void tearDown() throws Exception {
- // Shutdown TestEventAdmin if it exists (created via
createDefinitionServiceWithEventAdmin)
- // Note: TestEventAdmin is created internally by
createDefinitionService, but we only have access
- // to it when using createDefinitionServiceWithEventAdmin. For now, we
rely on JVM cleanup.
-
- // Stop scheduler service
- if (schedulerService != null && schedulerService instanceof
SchedulerServiceImpl) {
+ if (testEventAdmin != null) {
+ testEventAdmin.shutdown();
+ }
+ if (rulesService != null) {
+ ((RulesServiceImpl) rulesService).preDestroy();
+ }
+ if (eventService != null && rulesService != null) {
+ eventService.removeEventListenerService((RulesServiceImpl)
rulesService);
+ }
+ if (schedulerService instanceof SchedulerServiceImpl) {
((SchedulerServiceImpl) schedulerService).preDestroy();
}
+ if (executionContextManager != null) {
+ executionContextManager.setCurrentContext(null);
+ }
// Clear cache by clearing each tenant
if (multiTypeCacheService != null) {
@@ -181,6 +193,7 @@ public class GoalsServiceImplTest {
eventService = null;
schedulerService = null;
multiTypeCacheService = null;
+ testEventAdmin = null;
bundleContext = null;
}
@@ -247,33 +260,37 @@ public class GoalsServiceImplTest {
@Test
public void testSetGoalWithNestedConditions() {
- // Create a goal with nested conditions
- Goal goal = new Goal();
- goal.setMetadata(new Metadata());
- goal.getMetadata().setId("testGoal");
- goal.getMetadata().setEnabled(true);
-
- // Create parent condition
- Condition parentCondition = new Condition();
- parentCondition.setConditionTypeId("booleanCondition");
-
parentCondition.setConditionType(definitionsService.getConditionType("booleanCondition"));
- parentCondition.setParameter("operator", "and");
-
- // Create child condition
- Condition childCondition = new Condition();
- childCondition.setConditionTypeId("profilePropertyCondition");
-
childCondition.setConditionType(definitionsService.getConditionType("profilePropertyCondition"));
- childCondition.setParameter("propertyName", "profileProperty");
- childCondition.setParameter("comparisonOperator", "exists");
-
- // Set up nested structure
- List<Condition> subConditions = new ArrayList<>();
- subConditions.add(childCondition);
- parentCondition.setParameter("subConditions", subConditions);
-
- goal.setStartEvent(parentCondition);
-
- // Should not throw any exceptions
- goalsService.setGoal(goal);
+ executionContextManager.executeAsSystem(() -> {
+ Goal goal = new Goal();
+ Metadata metadata = new Metadata();
+ metadata.setId("testGoal");
+ metadata.setEnabled(true);
+ goal.setMetadata(metadata);
+ goal.setItemId("testGoal");
+
+ ConditionType booleanConditionType =
definitionsService.getConditionType("booleanCondition");
+ assertNotNull(booleanConditionType, "Boolean condition type should
exist");
+ ConditionType profilePropertyConditionType =
definitionsService.getConditionType("profilePropertyCondition");
+ assertNotNull(profilePropertyConditionType, "Profile property
condition type should exist");
+
+ Condition parentCondition = new Condition();
+ parentCondition.setConditionTypeId("booleanCondition");
+ parentCondition.setConditionType(booleanConditionType);
+ parentCondition.setParameter("operator", "and");
+
+ Condition childCondition = new Condition();
+ childCondition.setConditionTypeId("profilePropertyCondition");
+ childCondition.setConditionType(profilePropertyConditionType);
+ childCondition.setParameter("propertyName", "profileProperty");
+ childCondition.setParameter("comparisonOperator", "exists");
+
+ List<Condition> subConditions = new ArrayList<>();
+ subConditions.add(childCondition);
+ parentCondition.setParameter("subConditions", subConditions);
+
+ goal.setStartEvent(parentCondition);
+ goalsService.setGoal(goal);
+ return null;
+ });
}
}