You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@unomi.apache.org by sh...@apache.org on 2026/05/23 09:00:08 UTC
(unomi) branch UNOMI-937-itests-hardening-ci created (now 2611dea64)
This is an automated email from the ASF dual-hosted git repository.
sergehuber pushed a change to branch UNOMI-937-itests-hardening-ci
in repository https://gitbox.apache.org/repos/asf/unomi.git
at 2611dea64 UNOMI-937: Run GitHub Actions unit and IT jobs via build.sh
This branch includes the following new commits:
new 944c39bdf UNOMI-937: Add build.sh CI mode for non-interactive GitHub Actions
new eb294da69 UNOMI-937: Harden flaky integration tests with keepTrying polling
new c2f30010c UNOMI-937: Add waitForProfileProperty helper for async rule updates
new 2611dea64 UNOMI-937: Run GitHub Actions unit and IT jobs via build.sh
The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(unomi) 01/04: UNOMI-937: Add build.sh CI mode for non-interactive GitHub Actions
Posted by sh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
sergehuber pushed a commit to branch UNOMI-937-itests-hardening-ci
in repository https://gitbox.apache.org/repos/asf/unomi.git
commit 944c39bdf91238e937eac739c532eb7083e39db9
Author: Serge Huber <sh...@apache.org>
AuthorDate: Sat May 23 10:31:07 2026 +0200
UNOMI-937: Add build.sh CI mode for non-interactive GitHub Actions
Non-interactive prompts when CI, GITHUB_ACTIONS, or BUILD_NON_INTERACTIVE is set.
Add --ci (no Karaf, no Maven build cache) and MAVEN_EXTRA_OPTS for matrix ports.
---
build.sh | 48 +++++++++++++++++++++++++++++++++++++++---------
1 file changed, 39 insertions(+), 9 deletions(-)
diff --git a/build.sh b/build.sh
index 19dd5d0f6..80435acc8 100755
--- a/build.sh
+++ b/build.sh
@@ -222,13 +222,23 @@ print_progress() {
fi
}
+# Non-interactive when run from CI or when explicitly requested (e.g. GitHub Actions).
+is_non_interactive() {
+ [ -n "${CI:-}" ] || [ -n "${GITHUB_ACTIONS:-}" ] || [ "${BUILD_NON_INTERACTIVE:-}" = "true" ]
+}
+
# Function to prompt for continuation
prompt_continue() {
local prompt_text="$1"
if [ -z "$prompt_text" ]; then
prompt_text="Continue?"
fi
-
+
+ if is_non_interactive; then
+ print_status "info" "Non-interactive mode: continuing ($prompt_text)"
+ return 0
+ fi
+
read -p "$prompt_text (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
@@ -296,6 +306,7 @@ EOF
echo -e " ${CYAN}--it-debug-port PORT${NC} Set integration test debug port"
echo -e " ${CYAN}--it-debug-suspend${NC} Suspend integration test until debugger connects"
echo -e " ${CYAN}--skip-migration-tests${NC} Skip migration-related tests"
+ echo -e " ${CYAN}--ci${NC} CI mode: no Karaf, no Maven build cache, non-interactive"
else
cat << "EOF"
_ _ _____ _ ____
@@ -329,6 +340,7 @@ EOF
echo " --it-debug-port PORT Set integration test debug port"
echo " --it-debug-suspend Suspend integration test until debugger connects"
echo " --skip-migration-tests Skip migration-related tests"
+ echo " --ci CI mode: no Karaf, no Maven build cache, non-interactive"
fi
echo
@@ -459,6 +471,11 @@ while [ "$1" != "" ]; do
--skip-migration-tests)
SKIP_MIGRATION_TESTS=true
;;
+ --ci)
+ NO_KARAF=true
+ USE_MAVEN_CACHE=false
+ BUILD_NON_INTERACTIVE=true
+ ;;
*)
echo "Unknown option: $1"
usage
@@ -784,10 +801,14 @@ if [ "$MAVEN_OFFLINE" = true ]; then
# Warn if purge cache is enabled with offline mode
if [ "$PURGE_MAVEN_CACHE" = true ]; then
echo "Warning: Purging Maven cache while in offline mode may cause build failures"
- read -p "Continue anyway? (y/N) " -n 1 -r
- echo
- if [[ ! $REPLY =~ ^[Yy]$ ]]; then
- exit 1
+ if is_non_interactive; then
+ print_status "warning" "Non-interactive mode: continuing despite purge + offline"
+ else
+ read -p "Continue anyway? (y/N) " -n 1 -r
+ echo
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ exit 1
+ fi
fi
fi
fi
@@ -797,13 +818,22 @@ if [ "$USE_MAVEN_CACHE" = false ]; then
MVN_OPTS="$MVN_OPTS -Dmaven.build.cache.enabled=false"
fi
+# Extra Maven options (e.g. CI matrix ports: -Delasticsearch.port=9400)
+if [ -n "${MAVEN_EXTRA_OPTS:-}" ]; then
+ MVN_OPTS="$MVN_OPTS $MAVEN_EXTRA_OPTS"
+fi
+
# Verify Maven settings
if [ ! -f ~/.m2/settings.xml ]; then
echo "Warning: Maven settings.xml not found at ~/.m2/settings.xml"
- read -p "Continue anyway? (y/N) " -n 1 -r
- echo
- if [[ ! $REPLY =~ ^[Yy]$ ]]; then
- exit 1
+ if is_non_interactive; then
+ print_status "info" "Non-interactive mode: continuing without ~/.m2/settings.xml"
+ else
+ read -p "Continue anyway? (y/N) " -n 1 -r
+ echo
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
+ exit 1
+ fi
fi
fi
(unomi) 04/04: UNOMI-937: Run GitHub Actions unit and IT jobs via build.sh
Posted by sh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
sergehuber pushed a commit to branch UNOMI-937-itests-hardening-ci
in repository https://gitbox.apache.org/repos/asf/unomi.git
commit 2611dea64f026ea2897bf5c9ef7235d3407f4e28
Author: Serge Huber <sh...@apache.org>
AuthorDate: Sat May 23 10:32:18 2026 +0200
UNOMI-937: Run GitHub Actions unit and IT jobs via build.sh
Align CI with local developer workflow; pass matrix ports via MAVEN_EXTRA_OPTS.
---
.github/workflows/unomi-ci-build-tests.yml | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/unomi-ci-build-tests.yml b/.github/workflows/unomi-ci-build-tests.yml
index e629253cd..2533a8b23 100644
--- a/.github/workflows/unomi-ci-build-tests.yml
+++ b/.github/workflows/unomi-ci-build-tests.yml
@@ -31,7 +31,7 @@ jobs:
sudo apt-get install -y graphviz
dot -V
- name: Build and Unit tests
- run: mvn -U -ntp -e clean install
+ run: ./build.sh --ci
integration-tests:
name: Execute integration tests
@@ -54,16 +54,22 @@ jobs:
distribution: 'temurin'
java-version: '17'
cache: 'maven'
+ - name: Install GraphViz
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y graphviz
+ dot -V
- name: Integration tests
+ env:
+ MAVEN_EXTRA_OPTS: >-
+ -Dopensearch.port=${{ matrix.port }}
+ -Delasticsearch.port=${{ matrix.port }}
run: |
- FLAGS="-Pintegration-tests"
if [ "${{ matrix.search-engine }}" = "opensearch" ]; then
- # Trigger OpenSearch profile activation via property; do not pass any -P profile toggles
- FLAGS="$FLAGS -Duse.opensearch=true"
+ ./build.sh --ci --integration-tests --use-opensearch
+ else
+ ./build.sh --ci --integration-tests
fi
- mvn -ntp clean install $FLAGS \
- -Dopensearch.port=${{ matrix.port }} \
- -Delasticsearch.port=${{ matrix.port }}
- name: Archive code coverage logs
uses: actions/upload-artifact@v4
if: false # UNOMI-746 Reactivate if necessary
(unomi) 02/04: UNOMI-937: Harden flaky integration tests with keepTrying polling
Posted by sh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
sergehuber pushed a commit to branch UNOMI-937-itests-hardening-ci
in repository https://gitbox.apache.org/repos/asf/unomi.git
commit eb294da69a3e5b28cd31cc75c2f6a260350b4ba0
Author: Serge Huber <sh...@apache.org>
AuthorDate: Sat May 23 10:32:18 2026 +0200
UNOMI-937: Harden flaky integration tests with keepTrying polling
Replace fixed sleeps in GraphQLListIT and poll after patch refresh in PatchIT.
---
.../test/java/org/apache/unomi/itests/PatchIT.java | 24 +++++++++++++++-----
.../apache/unomi/itests/graphql/GraphQLListIT.java | 26 ++++++++++++++--------
2 files changed, 35 insertions(+), 15 deletions(-)
diff --git a/itests/src/test/java/org/apache/unomi/itests/PatchIT.java b/itests/src/test/java/org/apache/unomi/itests/PatchIT.java
index 098a03ad2..1c9cd5a43 100644
--- a/itests/src/test/java/org/apache/unomi/itests/PatchIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/PatchIT.java
@@ -49,7 +49,10 @@ public class PatchIT extends BaseIT {
profileService.refresh();
- newCompany = profileService.getPropertyType("company");
+ newCompany = keepTrying("Failed waiting for patched property type",
+ () -> profileService.getPropertyType("company"),
+ pt -> pt != null && "foo".equals(pt.getDefaultValue()),
+ DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
Assert.assertEquals("foo", newCompany.getDefaultValue());
} finally {
profileService.setPropertyType(company);
@@ -68,7 +71,10 @@ public class PatchIT extends BaseIT {
profileService.refresh();
- newGender = profileService.getPropertyType("gender");
+ newGender = keepTrying("Failed waiting for patched property type",
+ () -> profileService.getPropertyType("gender"),
+ pt -> pt != null && "foo".equals(pt.getDefaultValue()),
+ DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
Assert.assertEquals("foo", newGender.getDefaultValue());
} finally {
profileService.setPropertyType(gender);
@@ -86,8 +92,8 @@ public class PatchIT extends BaseIT {
profileService.refresh();
- PropertyType newIncome = profileService.getPropertyType("income");
- Assert.assertNull(newIncome);
+ waitForNullValue("Failed waiting for property type removal",
+ () -> profileService.getPropertyType("income"), DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
} finally {
profileService.setPropertyType(income);
}
@@ -105,7 +111,10 @@ public class PatchIT extends BaseIT {
definitionsService.refresh();
- ConditionType newFormCondition = definitionsService.getConditionType("formEventCondition");
+ ConditionType newFormCondition = keepTrying("Failed waiting for patched condition type",
+ () -> definitionsService.getConditionType("formEventCondition"),
+ ct -> ct != null && !ct.getMetadata().getSystemTags().contains("profileTags"),
+ DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
Assert.assertFalse(newFormCondition.getMetadata().getSystemTags().contains("profileTags"));
} finally {
definitionsService.setConditionType(formCondition);
@@ -124,7 +133,10 @@ public class PatchIT extends BaseIT {
definitionsService.refresh();
- ActionType newMailAction = definitionsService.getActionType("sendMailAction");
+ ActionType newMailAction = keepTrying("Failed waiting for patched action type",
+ () -> definitionsService.getActionType("sendMailAction"),
+ at -> at != null && !at.getMetadata().getSystemTags().contains("availableToEndUser"),
+ DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
Assert.assertFalse(newMailAction.getMetadata().getSystemTags().contains("availableToEndUser"));
} finally {
definitionsService.setActionType(mailAction);
diff --git a/itests/src/test/java/org/apache/unomi/itests/graphql/GraphQLListIT.java b/itests/src/test/java/org/apache/unomi/itests/graphql/GraphQLListIT.java
index 96a6eb986..757904b72 100644
--- a/itests/src/test/java/org/apache/unomi/itests/graphql/GraphQLListIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/graphql/GraphQLListIT.java
@@ -77,15 +77,23 @@ public class GraphQLListIT extends BaseGraphQLIT {
refreshPersistence(UserList.class);
- Thread.sleep(6000);
-
- try (CloseableHttpResponse response = post("graphql/list/find-lists.json")) {
- final ResponseContext context = ResponseContext.parse(response.getEntity());
-
- Assert.assertEquals(1, ((Integer) context.getValue("data.cdp.findLists.totalCount")).intValue());
- Assert.assertEquals("testListId", context.getValue("data.cdp.findLists.edges[0].node.id"));
- Assert.assertEquals(profile.getItemId(), context.getValue("data.cdp.findLists.edges[0].node.active.edges[0].node.cdp_profileIDs[0].id"));
- }
+ final ResponseContext findListsContext = keepTrying("Failed waiting for profile in list query",
+ () -> {
+ try (CloseableHttpResponse response = post("graphql/list/find-lists.json")) {
+ return ResponseContext.parse(response.getEntity());
+ }
+ },
+ context -> {
+ Integer totalCount = (Integer) context.getValue("data.cdp.findLists.totalCount");
+ if (totalCount == null || totalCount != 1) {
+ return false;
+ }
+ Object profileId = context.getValue("data.cdp.findLists.edges[0].node.active.edges[0].node.cdp_profileIDs[0].id");
+ return profile.getItemId().equals(profileId);
+ },
+ DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
+
+ Assert.assertEquals("testListId", findListsContext.getValue("data.cdp.findLists.edges[0].node.id"));
try (CloseableHttpResponse response = post("graphql/list/delete-list.json")) {
final ResponseContext context = ResponseContext.parse(response.getEntity());
(unomi) 03/04: UNOMI-937: Add waitForProfileProperty helper for async rule updates
Posted by sh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
sergehuber pushed a commit to branch UNOMI-937-itests-hardening-ci
in repository https://gitbox.apache.org/repos/asf/unomi.git
commit c2f30010c6a1701f331eac783bde4ee1dc56df41
Author: Serge Huber <sh...@apache.org>
AuthorDate: Sat May 23 10:32:18 2026 +0200
UNOMI-937: Add waitForProfileProperty helper for async rule updates
Poll profile properties after events in PropertiesUpdateActionIT.
---
itests/src/test/java/org/apache/unomi/itests/BaseIT.java | 8 ++++++++
.../org/apache/unomi/itests/PropertiesUpdateActionIT.java | 14 +++++---------
2 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/itests/src/test/java/org/apache/unomi/itests/BaseIT.java b/itests/src/test/java/org/apache/unomi/itests/BaseIT.java
index 1c1bd6f8c..676639b0d 100644
--- a/itests/src/test/java/org/apache/unomi/itests/BaseIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/BaseIT.java
@@ -467,6 +467,14 @@ public abstract class BaseIT extends KarafTestSupport {
return value;
}
+ protected void waitForProfileProperty(String profileId, String propertyName, Object expected)
+ throws InterruptedException {
+ keepTrying("Profile " + profileId + " property " + propertyName + " not updated",
+ () -> profileService.load(profileId),
+ profile -> profile != null && java.util.Objects.equals(expected, profile.getProperty(propertyName)),
+ DEFAULT_TRYING_TIMEOUT, DEFAULT_TRYING_TRIES);
+ }
+
protected <T> void waitForNullValue(String failMessage, Supplier<T> call, int timeout, int retries) throws InterruptedException {
int count = 0;
while (call.get() != null) {
diff --git a/itests/src/test/java/org/apache/unomi/itests/PropertiesUpdateActionIT.java b/itests/src/test/java/org/apache/unomi/itests/PropertiesUpdateActionIT.java
index a1e340680..e07d2bd5c 100644
--- a/itests/src/test/java/org/apache/unomi/itests/PropertiesUpdateActionIT.java
+++ b/itests/src/test/java/org/apache/unomi/itests/PropertiesUpdateActionIT.java
@@ -78,7 +78,7 @@ public class PropertiesUpdateActionIT extends BaseIT {
}
@Test
- public void testUpdateProperties_CurrentProfile() {
+ public void testUpdateProperties_CurrentProfile() throws InterruptedException {
Profile profile = profileService.load(PROFILE_TARGET_TEST_ID);
Assert.assertNull(profile.getProperty("firstName"));
@@ -92,16 +92,13 @@ public class PropertiesUpdateActionIT extends BaseIT {
updateProperties.setProperty(UpdatePropertiesAction.TARGET_ID_KEY, PROFILE_TARGET_TEST_ID);
updateProperties.setProperty(UpdatePropertiesAction.TARGET_TYPE_KEY, "profile");
- int changes = eventService.send(updateProperties);
-
- LOGGER.info("Changes of the event : {}", changes);
+ eventService.send(updateProperties);
- Assert.assertTrue(changes > 0);
- Assert.assertEquals("UPDATED FIRST NAME CURRENT PROFILE", profile.getProperty("firstName"));
+ waitForProfileProperty(PROFILE_TARGET_TEST_ID, "firstName", "UPDATED FIRST NAME CURRENT PROFILE");
}
@Test
- public void testUpdateProperties_NotCurrentProfile() {
+ public void testUpdateProperties_NotCurrentProfile() throws InterruptedException {
Profile profile = profileService.load(PROFILE_TARGET_TEST_ID);
Profile profileToUpdate = profileService.load(PROFILE_TEST_ID);
Assert.assertNull(profileToUpdate.getProperty("firstName"));
@@ -117,8 +114,7 @@ public class PropertiesUpdateActionIT extends BaseIT {
updateProperties.setProperty(UpdatePropertiesAction.TARGET_TYPE_KEY, "profile");
eventService.send(updateProperties);
- profileToUpdate = profileService.load(PROFILE_TEST_ID);
- Assert.assertEquals("UPDATED FIRST NAME", profileToUpdate.getProperty("firstName"));
+ waitForProfileProperty(PROFILE_TEST_ID, "firstName", "UPDATED FIRST NAME");
}
@Test