From 34606a1b8fc7d82e953275883450e2f294b411a6 Mon Sep 17 00:00:00 2001 From: Steven van der Vegt Date: Mon, 17 Aug 2026 11:02:44 +0000 Subject: [PATCH] test(e2e): fix flaky e2e tests (#4443) assertJaegerTrace only retried while the trace was entirely absent from Jaeger. Each node exports spans in batches on its own schedule (5s default), so the first query after a flow often finds a partial trace containing only one node's spans, which failed the assertion immediately. Missing services or spans are now retried like a missing trace, up to 10 attempts with 1s sleeps. The gossip test gave propagation of 81 transactions across 4 nodes only 10 seconds, the heaviest propagation assertion in the suite on the same budget as tests waiting for at most 41 transactions. Slow CI runners regularly miss that deadline; it is now 30 seconds. Both were observed as e2e failures on unrelated PRs (#4427, #4439). Assisted-by: AI (cherry picked from commit 4c123a68667766ac24ac1222ab6c41581f617a94) --- e2e-tests/nuts-network/gossip/run-test.sh | 4 ++-- e2e-tests/util.sh | 27 +++++++++++++++-------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/e2e-tests/nuts-network/gossip/run-test.sh b/e2e-tests/nuts-network/gossip/run-test.sh index 35299c91a0..557a2941ac 100755 --- a/e2e-tests/nuts-network/gossip/run-test.sh +++ b/e2e-tests/nuts-network/gossip/run-test.sh @@ -41,8 +41,8 @@ echo "------------------------------------" echo "Performing assertions..." echo "------------------------------------" -waitForTXCount "NodeA" "http://localhost:18081/status/diagnostics" 81 10 -waitForTXCount "NodeD" "http://localhost:48081/status/diagnostics" 81 10 +waitForTXCount "NodeA" "http://localhost:18081/status/diagnostics" 81 30 +waitForTXCount "NodeD" "http://localhost:48081/status/diagnostics" 81 30 echo "------------------------------------" echo "Stopping Docker containers..." diff --git a/e2e-tests/util.sh b/e2e-tests/util.sh index e47e37ee74..3f805a86d7 100644 --- a/e2e-tests/util.sh +++ b/e2e-tests/util.sh @@ -190,7 +190,8 @@ urlencode() { } # assertJaegerTrace verifies a trace exists with expected services and span patterns -# Fetches trace once and validates all expectations +# Retries while expectations are not met: each node exports spans in batches on its +# own schedule, so a trace may be visible in Jaeger before all services reported. # Args: Jaeger URL, trace ID, expected services (space-separated), span patterns (space-separated) function assertJaegerTrace() { local jaeger_url=$1 @@ -198,12 +199,17 @@ function assertJaegerTrace() { local expected_services=$3 local expected_patterns=$4 - for attempt in {1..5}; do + local failure="" + for attempt in {1..10}; do + if [ "$attempt" -gt 1 ]; then + sleep 1 + fi + local response=$(curl -s -m 10 "$jaeger_url/api/traces/$trace_id") local trace_count=$(echo "$response" | jq '.data | length') if [ "$trace_count" -eq 0 ]; then - sleep 1 + failure="FAILED: Trace '$trace_id' not found" continue fi @@ -211,12 +217,16 @@ function assertJaegerTrace() { local span_names=$(echo "$response" | jq -r '.data[0].spans[].operationName') # Check each expected service is present + local missing_services="" for svc in $expected_services; do if ! echo "$actual_services" | grep -q "$svc"; then - echo "FAILED: Trace '$trace_id' missing service '$svc' (found: $actual_services)" 1>&2 - return 1 + missing_services="$missing_services $svc" fi done + if [ -n "$missing_services" ]; then + failure="FAILED: Trace '$trace_id' missing service(s):$missing_services (found: $actual_services)" + continue + fi # Check each expected span pattern is present local missing="" @@ -226,9 +236,8 @@ function assertJaegerTrace() { fi done if [ -n "$missing" ]; then - echo "FAILED: Trace '$trace_id' missing spans:$missing" 1>&2 - echo "Available: $(echo "$span_names" | sort -u | tr '\n' ', ')" 1>&2 - return 1 + failure="FAILED: Trace '$trace_id' missing spans:$missing (available: $(echo "$span_names" | sort -u | tr '\n' ','))" + continue fi local span_count=$(echo "$response" | jq '.data[0].spans | length') @@ -236,6 +245,6 @@ function assertJaegerTrace() { return 0 done - echo "FAILED: Trace '$trace_id' not found after 5 attempts" 1>&2 + echo "$failure after 10 attempts" 1>&2 return 1 }