This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch 
camel-23223-fix-flaky-test-managedmessagehistorya
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 3267a443fcb8b6319a0920fea2d9e61b2a8870f3
Author: Guillaume Nodet <[email protected]>
AuthorDate: Sat Jul 4 17:17:26 2026 +0000

    CAMEL-23223: Stabilize flaky ManagedMessageHistoryAutoConfigIT
    
    Replace the short 1-second Awaitility wait (which only waited for any
    log to appear) with untilAsserted using a 20-second timeout that
    retries the full set of metric assertions. This handles slow CI
    architectures where the OTel periodic reader may not export Camel
    metrics within 1 second, and avoids failures from incomplete early
    metric exports during message processing.
    
    Also make MemoryLogHandler thread-safe with CopyOnWriteArrayList
    since publish() is called from the OTel exporter thread while
    getLogs()/hasLogs() are called from the test thread.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    Signed-off-by: Guillaume Nodet <[email protected]>
---
 .../metrics/integration/MemoryLogHandler.java      |  5 ++-
 .../ManagedMessageHistoryAutoConfigIT.java         | 46 ++++++++++++----------
 2 files changed, 29 insertions(+), 22 deletions(-)

diff --git 
a/components/camel-opentelemetry-metrics/src/test/java/org/apache/camel/opentelemetry/metrics/integration/MemoryLogHandler.java
 
b/components/camel-opentelemetry-metrics/src/test/java/org/apache/camel/opentelemetry/metrics/integration/MemoryLogHandler.java
index 9ab5ac70f8d4..70a29a8bc99a 100644
--- 
a/components/camel-opentelemetry-metrics/src/test/java/org/apache/camel/opentelemetry/metrics/integration/MemoryLogHandler.java
+++ 
b/components/camel-opentelemetry-metrics/src/test/java/org/apache/camel/opentelemetry/metrics/integration/MemoryLogHandler.java
@@ -18,11 +18,14 @@ package org.apache.camel.opentelemetry.metrics.integration;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.logging.ConsoleHandler;
 import java.util.logging.LogRecord;
 
 public class MemoryLogHandler extends ConsoleHandler {
-    private List<LogRecord> logs = new ArrayList<>();
+    // CopyOnWriteArrayList for thread safety: publish() is called from the 
OTel
+    // exporter thread while hasLogs()/getLogs() are called from the test 
thread
+    private final List<LogRecord> logs = new CopyOnWriteArrayList<>();
 
     public MemoryLogHandler() {
         super();
diff --git 
a/components/camel-opentelemetry-metrics/src/test/java/org/apache/camel/opentelemetry/metrics/integration/messagehistory/ManagedMessageHistoryAutoConfigIT.java
 
b/components/camel-opentelemetry-metrics/src/test/java/org/apache/camel/opentelemetry/metrics/integration/messagehistory/ManagedMessageHistoryAutoConfigIT.java
index 9fbf9a0d7a94..0621aeaecd5c 100644
--- 
a/components/camel-opentelemetry-metrics/src/test/java/org/apache/camel/opentelemetry/metrics/integration/messagehistory/ManagedMessageHistoryAutoConfigIT.java
+++ 
b/components/camel-opentelemetry-metrics/src/test/java/org/apache/camel/opentelemetry/metrics/integration/messagehistory/ManagedMessageHistoryAutoConfigIT.java
@@ -98,30 +98,34 @@ public class ManagedMessageHistoryAutoConfigIT extends 
CamelTestSupport {
 
         MockEndpoint.assertIsSatisfied(context);
 
-        await().atMost(Duration.ofMillis(1000L)).until(handler::hasLogs);
-
-        List<LogRecord> logs = new ArrayList<>(handler.getLogs());
-        assertFalse(logs.isEmpty(), "No metrics were exported");
-        int dataCount = 0;
-        for (LogRecord log : logs) {
-            if (log.getParameters() != null && log.getParameters().length > 0) 
{
-                MetricData metricData = (MetricData) log.getParameters()[0];
-                // Skip non-Camel metrics (e.g. otel.sdk.* internal metrics 
added in OTel 1.60+)
-                if (!metricData.getName().startsWith("camel.")) {
-                    continue;
+        // Use Awaitility to retry assertions until the OTel periodic reader 
has exported
+        // Camel metrics. On slow CI architectures the first export may be 
delayed well
+        // beyond the 300ms export interval. Assert on the last exported Camel 
metric data
+        // because earlier exports during message processing may contain 
incomplete data.
+        await().atMost(Duration.ofSeconds(20)).untilAsserted(() -> {
+            List<LogRecord> logs = new ArrayList<>(handler.getLogs());
+            assertFalse(logs.isEmpty(), "No metrics were exported");
+
+            MetricData lastCamelMetric = null;
+            for (LogRecord log : logs) {
+                if (log.getParameters() != null && log.getParameters().length 
> 0) {
+                    MetricData metricData = (MetricData) 
log.getParameters()[0];
+                    // Skip non-Camel metrics (e.g. otel.sdk.* internal 
metrics added in OTel 1.60+)
+                    if (!metricData.getName().startsWith("camel.")) {
+                        continue;
+                    }
+                    assertEquals(DEFAULT_CAMEL_MESSAGE_HISTORY_METER_NAME, 
metricData.getName());
+                    lastCamelMetric = metricData;
                 }
-                assertEquals(DEFAULT_CAMEL_MESSAGE_HISTORY_METER_NAME, 
metricData.getName());
-
-                assertPointDataForRouteId(metricData, "route1");
+            }
+            assertThat(lastCamelMetric).as("No Camel metric data 
found").isNotNull();
 
-                assertMetricDataHasNodeId(metricData, "route1", "foo");
-                assertMetricDataHasNodeId(metricData, "route2", "bar");
-                assertMetricDataHasNodeId(metricData, "route2", "baz");
+            assertPointDataForRouteId(lastCamelMetric, "route1");
 
-                dataCount++;
-            }
-        }
-        assertTrue(dataCount > 0, "No metric data found");
+            assertMetricDataHasNodeId(lastCamelMetric, "route1", "foo");
+            assertMetricDataHasNodeId(lastCamelMetric, "route2", "bar");
+            assertMetricDataHasNodeId(lastCamelMetric, "route2", "baz");
+        });
     }
 
     private void assertMetricDataHasNodeId(MetricData metricData, String 
routeId, String nodeId) {

Reply via email to