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

reta pushed a commit to branch 3.6.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/3.6.x-fixes by this push:
     new 0c0b8b5372a Improve tracing test diagnostics for flaky test 
investigation (#2999)
0c0b8b5372a is described below

commit 0c0b8b5372af77ea34663c877201e5e8163977df
Author: Guillaume Nodet <[email protected]>
AuthorDate: Fri May 8 01:32:13 2026 +0200

    Improve tracing test diagnostics for flaky test investigation (#2999)
    
    * Improve tracing test diagnostics: use untilAsserted with span list output
    
    Replace await().until(() -> spans.size() == N) with
    await().untilAsserted(() -> assertThat(message, size, equalTo(N)))
    across all tracing system tests. When the Awaitility wait times out,
    the error message now includes the actual span count and the full
    list of collected spans, making it much easier to diagnose whether
    the failure is caused by missing spans, extra spans from cross-test
    contamination, or a timing issue.
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
    
    * Extract HasSize matcher to reduce assertion duplication in tracing tests
    
    Address review feedback: replace verbose untilAsserted assertions with
    a custom HasSize matcher that includes span list contents on mismatch.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
    
    ---------
    
    Co-authored-by: Claude Opus 4.6 <[email protected]>
    (cherry picked from commit 440137a58e82769ada0a4fc8b431f288ff78dc53)
---
 .../test/java/org/apache/cxf/systest/HasSize.java  | 52 ++++++++++++++++++++++
 .../JaxrsOpenTelemetryTracingTest.java             | 22 ++++-----
 .../opentracing/JaxrsOpenTracingTracingTest.java   | 22 ++++-----
 .../JaxwsOpenTelemetryTracingTest.java             |  6 +--
 .../opentracing/JaxwsOpenTracingTracingTest.java   |  6 +--
 5 files changed, 74 insertions(+), 34 deletions(-)

diff --git a/systests/tracing/src/test/java/org/apache/cxf/systest/HasSize.java 
b/systests/tracing/src/test/java/org/apache/cxf/systest/HasSize.java
new file mode 100644
index 00000000000..af74e6cb784
--- /dev/null
+++ b/systests/tracing/src/test/java/org/apache/cxf/systest/HasSize.java
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest;
+
+import java.util.Collection;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+
+public class HasSize extends TypeSafeMatcher<Collection<?>> {
+    private final int expectedSize;
+
+    public HasSize(int expectedSize) {
+        this.expectedSize = expectedSize;
+    }
+
+    @Override
+    protected boolean matchesSafely(Collection<?> collection) {
+        return collection.size() == expectedSize;
+    }
+
+    @Override
+    public void describeTo(Description description) {
+        description.appendText("a collection with size 
").appendValue(expectedSize);
+    }
+
+    @Override
+    protected void describeMismatchSafely(Collection<?> collection, 
Description description) {
+        description.appendText("size was ").appendValue(collection.size())
+            .appendText(", contents: ").appendValue(collection);
+    }
+
+    public static HasSize hasSize(int size) {
+        return new HasSize(size);
+    }
+}
diff --git 
a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentelemetry/JaxrsOpenTelemetryTracingTest.java
 
b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentelemetry/JaxrsOpenTelemetryTracingTest.java
index 0ca554c9752..4c8eed86d20 100644
--- 
a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentelemetry/JaxrsOpenTelemetryTracingTest.java
+++ 
b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentelemetry/JaxrsOpenTelemetryTracingTest.java
@@ -81,6 +81,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 
+import static org.apache.cxf.systest.HasSize.hasSize;
 import static 
org.apache.cxf.systest.jaxrs.tracing.opentelemetry.HasAttribute.hasAttribute;
 import static 
org.apache.cxf.systest.jaxrs.tracing.opentelemetry.HasSpan.hasSpan;
 import static 
org.apache.cxf.systest.jaxrs.tracing.opentelemetry.IsLogContaining.hasItem;
@@ -258,10 +259,9 @@ public class JaxrsOpenTelemetryTracingTest extends 
AbstractClientServerTestBase
             final Response r = 
withTrace(createWebClient("/bookstore/books/async")).get();
             assertEquals(Status.OK.getStatusCode(), r.getStatus());
 
-            await().atMost(Duration.ofSeconds(1L)).until(() -> 
otelRule.getSpans().size() == 2);
+            await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(otelRule.getSpans(), hasSize(2)));
 
             final List<SpanData> spans = getSpansSorted();
-            assertThat(spans.size(), equalTo(2));
 
             assertEquals("Processing books", spans.get(0).getName());
             assertEquals("GET /bookstore/books/async", spans.get(1).getName());
@@ -288,10 +288,9 @@ public class JaxrsOpenTelemetryTracingTest extends 
AbstractClientServerTestBase
         final Response r = createWebClient("/bookstore/books/async").get();
         assertEquals(Status.OK.getStatusCode(), r.getStatus());
 
-        await().atMost(Duration.ofSeconds(1L)).until(() -> 
otelRule.getSpans().size() == 2);
+        await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(otelRule.getSpans(), hasSize(2)));
 
         final List<SpanData> spans = getSpansSorted();
-        assertThat(spans.size(), equalTo(2));
         assertThat(spans.get(0).getName(), equalTo("Processing books"));
         assertThat(spans.get(1).getName(), equalTo("GET 
/bookstore/books/async"));
     }
@@ -304,9 +303,8 @@ public class JaxrsOpenTelemetryTracingTest extends 
AbstractClientServerTestBase
         final Response r = client.async().get().get(1L, TimeUnit.SECONDS);
         assertEquals(Status.OK.getStatusCode(), r.getStatus());
 
-        await().atMost(Duration.ofSeconds(1L)).until(() -> 
otelRule.getSpans().size() == 3);
+        await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(otelRule.getSpans(), hasSize(3)));
 
-        assertThat(otelRule.getSpans().size(), equalTo(3));
         assertThat(otelRule.getSpans().get(0).getName(), equalTo("Get Books"));
         assertThat(otelRule.getSpans().get(1).getName(), equalTo("GET 
/bookstore/books"));
         assertThat(otelRule.getSpans().get(1).getKind(), 
equalTo(SpanKind.SERVER));
@@ -374,9 +372,8 @@ public class JaxrsOpenTelemetryTracingTest extends 
AbstractClientServerTestBase
         }
 
         // Await till flush happens, usually every second
-        await().atMost(Duration.ofSeconds(1L)).until(() -> 
otelRule.getSpans().size() == 4);
+        await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(otelRule.getSpans(), hasSize(4)));
 
-        assertThat(otelRule.getSpans().size(), equalTo(4));
         assertThat(otelRule.getSpans().get(3).getName(), equalTo("test span"));
         
assertThat(otelRule.getSpans().get(3).getParentSpanContext().isValid(), 
equalTo(false));
     }
@@ -393,9 +390,8 @@ public class JaxrsOpenTelemetryTracingTest extends 
AbstractClientServerTestBase
             assertThat(Span.current().getSpanContext().getSpanId(),
                        equalTo(span.getSpanContext().getSpanId()));
 
-            await().atMost(Duration.ofSeconds(1L)).until(() -> 
otelRule.getSpans().size() == 3);
+            await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(otelRule.getSpans(), hasSize(3)));
 
-            assertThat(otelRule.getSpans().size(), equalTo(3));
             assertThat(otelRule.getSpans().get(0).getName(), equalTo("Get 
Books"));
             assertThat(otelRule.getSpans().get(0).getParentSpanContext(), 
notNullValue());
             assertThat(otelRule.getSpans().get(1).getName(), equalTo("GET 
/bookstore/books"));
@@ -407,9 +403,8 @@ public class JaxrsOpenTelemetryTracingTest extends 
AbstractClientServerTestBase
         }
 
         // Await till flush happens, usually every second
-        await().atMost(Duration.ofSeconds(1L)).until(() -> 
otelRule.getSpans().size() == 4);
+        await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(otelRule.getSpans(), hasSize(4)));
 
-        assertThat(otelRule.getSpans().size(), equalTo(4));
         assertThat(otelRule.getSpans().get(3).getName(), equalTo("test span"));
         
assertThat(otelRule.getSpans().get(3).getParentSpanContext().isValid(), 
equalTo(false));
     }
@@ -444,8 +439,7 @@ public class JaxrsOpenTelemetryTracingTest extends 
AbstractClientServerTestBase
         try {
             client.get();
         } finally {
-            await().atMost(Duration.ofSeconds(1L)).until(() -> 
otelRule.getSpans().size() == 2);
-            assertThat(otelRule.getSpans().toString(), 
otelRule.getSpans().size(), equalTo(2));
+            await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(otelRule.getSpans(), hasSize(2)));
             assertThat(otelRule.getSpans().get(0).getName(), equalTo("GET " + 
client.getCurrentURI()));
             assertThat(otelRule.getSpans().get(0).getStatus().getStatusCode(), 
equalTo(StatusCode.ERROR));
             assertThat(otelRule.getSpans().get(1).getName(), equalTo("GET 
/bookstore/books/long"));
diff --git 
a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/JaxrsOpenTracingTracingTest.java
 
b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/JaxrsOpenTracingTracingTest.java
index d63f498e627..50c006889c1 100644
--- 
a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/JaxrsOpenTracingTracingTest.java
+++ 
b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxrs/tracing/opentracing/JaxrsOpenTracingTracingTest.java
@@ -72,6 +72,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 
+import static org.apache.cxf.systest.HasSize.hasSize;
 import static org.apache.cxf.systest.jaxrs.tracing.opentracing.HasSpan.hasSpan;
 import static 
org.apache.cxf.systest.jaxrs.tracing.opentracing.IsLogContaining.hasItem;
 import static 
org.apache.cxf.systest.jaxrs.tracing.opentracing.IsTagContaining.hasItem;
@@ -201,10 +202,9 @@ public class JaxrsOpenTracingTracingTest extends 
AbstractClientServerTestBase {
         final Response r = 
withTrace(createWebClient("/bookstore/books/async"), spanId).get();
         assertEquals(Status.OK.getStatusCode(), r.getStatus());
 
-        await().atMost(Duration.ofSeconds(1L)).until(()-> 
REPORTER.getSpans().size() == 2);
+        await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(REPORTER.getSpans(), hasSize(2)));
 
         final List<JaegerSpan> spans = getSpansSorted();
-        assertThat(spans.size(), equalTo(2));
         assertEquals("Processing books", spans.get(0).getOperationName());
         assertEquals("GET /bookstore/books/async", 
spans.get(1).getOperationName());
         assertThat(spans.get(1).getReferences(), not(empty()));
@@ -228,10 +228,9 @@ public class JaxrsOpenTracingTracingTest extends 
AbstractClientServerTestBase {
         final Response r = createWebClient("/bookstore/books/async").get();
         assertEquals(Status.OK.getStatusCode(), r.getStatus());
 
-        await().atMost(Duration.ofSeconds(1L)).until(()-> 
REPORTER.getSpans().size() == 2);
+        await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(REPORTER.getSpans(), hasSize(2)));
 
         final List<JaegerSpan> spans = getSpansSorted();
-        assertThat(spans.size(), equalTo(2));
         assertThat(spans.get(0).getOperationName(), equalTo("Processing 
books"));
         assertThat(spans.get(1).getOperationName(), equalTo("GET 
/bookstore/books/async"));
     }
@@ -243,9 +242,8 @@ public class JaxrsOpenTracingTracingTest extends 
AbstractClientServerTestBase {
         final Response r = client.async().get().get(1L, TimeUnit.SECONDS);
         assertEquals(Status.OK.getStatusCode(), r.getStatus());
 
-        await().atMost(Duration.ofSeconds(1L)).until(()-> 
REPORTER.getSpans().size() == 3);
+        await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(REPORTER.getSpans(), hasSize(3)));
 
-        assertThat(REPORTER.getSpans().size(), equalTo(3));
         assertThat(REPORTER.getSpans().get(0).getOperationName(), equalTo("Get 
Books"));
         assertThat(REPORTER.getSpans().get(1).getOperationName(), equalTo("GET 
/bookstore/books"));
         assertThat(REPORTER.getSpans().get(1).getTags(), 
hasItem(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER));
@@ -327,9 +325,8 @@ public class JaxrsOpenTracingTracingTest extends 
AbstractClientServerTestBase {
         }
 
         // Await till flush happens, usually every second
-        await().atMost(Duration.ofSeconds(1L)).until(()-> 
REPORTER.getSpans().size() == 4);
+        await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(REPORTER.getSpans(), hasSize(4)));
 
-        assertThat(REPORTER.getSpans().size(), equalTo(4));
         assertThat(REPORTER.getSpans().get(3).getOperationName(), 
equalTo("test span"));
         assertThat(REPORTER.getSpans().get(3).getReferences(), empty());
     }
@@ -344,9 +341,8 @@ public class JaxrsOpenTracingTracingTest extends 
AbstractClientServerTestBase {
             assertEquals(Status.OK.getStatusCode(), r.getStatus());
             assertThat(tracer.activeSpan().context(), equalTo(span.context()));
 
-            await().atMost(Duration.ofSeconds(1L)).until(()-> 
REPORTER.getSpans().size() == 3);
+            await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(REPORTER.getSpans(), hasSize(3)));
 
-            assertThat(REPORTER.getSpans().size(), equalTo(3));
             assertThat(REPORTER.getSpans().get(0).getOperationName(), 
equalTo("Get Books"));
             assertThat(REPORTER.getSpans().get(0).getReferences(), 
not(empty()));
             assertThat(REPORTER.getSpans().get(1).getOperationName(), 
equalTo("GET /bookstore/books"));
@@ -358,9 +354,8 @@ public class JaxrsOpenTracingTracingTest extends 
AbstractClientServerTestBase {
         }
 
         // Await till flush happens, usually every second
-        await().atMost(Duration.ofSeconds(1L)).until(()-> 
REPORTER.getSpans().size() == 4);
+        await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(REPORTER.getSpans(), hasSize(4)));
 
-        assertThat(REPORTER.getSpans().size(), equalTo(4));
         assertThat(REPORTER.getSpans().get(3).getOperationName(), 
equalTo("test span"));
         assertThat(REPORTER.getSpans().get(3).getReferences(), empty());
     }
@@ -393,8 +388,7 @@ public class JaxrsOpenTracingTracingTest extends 
AbstractClientServerTestBase {
         try {
             client.get();
         } finally {
-            await().atMost(Duration.ofSeconds(1L)).until(()-> 
REPORTER.getSpans().size() == 2);
-            assertThat(REPORTER.getSpans().toString(), 
REPORTER.getSpans().size(), equalTo(2));
+            await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(REPORTER.getSpans(), hasSize(2)));
             assertThat(REPORTER.getSpans().get(0).getOperationName(), 
equalTo("GET " + client.getCurrentURI()));
             assertThat(REPORTER.getSpans().get(0).getTags(), 
hasItem(Tags.ERROR.getKey(), Boolean.TRUE));
             assertThat(REPORTER.getSpans().get(1).getOperationName(), 
equalTo("GET /bookstore/books/long"));
diff --git 
a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentelemetry/JaxwsOpenTelemetryTracingTest.java
 
b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentelemetry/JaxwsOpenTelemetryTracingTest.java
index d71ea64b51e..7ba35543372 100644
--- 
a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentelemetry/JaxwsOpenTelemetryTracingTest.java
+++ 
b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentelemetry/JaxwsOpenTelemetryTracingTest.java
@@ -67,6 +67,7 @@ import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Test;
 
+import static org.apache.cxf.systest.HasSize.hasSize;
 import static 
org.apache.cxf.systest.jaxrs.tracing.opentelemetry.HasAttribute.hasAttribute;
 import static org.awaitility.Awaitility.await;
 import static org.hamcrest.CoreMatchers.containsString;
@@ -248,9 +249,8 @@ public class JaxwsOpenTelemetryTracingTest extends 
AbstractClientServerTestBase
             }
 
             // Await till flush happens, usually every second
-            await().atMost(Duration.ofSeconds(1L)).until(() -> 
otelRule.getSpans().size() == 4);
+            await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(otelRule.getSpans(), hasSize(4)));
 
-            assertThat(otelRule.getSpans().size(), equalTo(4));
             assertThat(otelRule.getSpans().get(3).getName(), equalTo("test 
span"));
             
assertThat(otelRule.getSpans().get(3).getParentSpanContext().isValid(), 
equalTo(false));
         }
@@ -332,7 +332,7 @@ public class JaxwsOpenTelemetryTracingTest extends 
AbstractClientServerTestBase
         service.orderBooks();
 
         // Await till flush happens, usually every second
-        await().atMost(Duration.ofSeconds(1L)).until(() -> 
otelRule.getSpans().size() == 2);
+        await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(otelRule.getSpans(), hasSize(2)));
 
         assertThat(otelRule.getSpans().get(0).getName(), equalTo("POST 
/BookStore"));
         assertThat(otelRule.getSpans().get(1).getName(),
diff --git 
a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/JaxwsOpenTracingTracingTest.java
 
b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/JaxwsOpenTracingTracingTest.java
index 1027dcf6c3f..8e9c291fa27 100644
--- 
a/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/JaxwsOpenTracingTracingTest.java
+++ 
b/systests/tracing/src/test/java/org/apache/cxf/systest/jaxws/tracing/opentracing/JaxwsOpenTracingTracingTest.java
@@ -58,6 +58,7 @@ import org.junit.After;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import static org.apache.cxf.systest.HasSize.hasSize;
 import static 
org.apache.cxf.systest.jaxrs.tracing.opentracing.IsTagContaining.hasItem;
 import static org.awaitility.Awaitility.await;
 import static org.hamcrest.CoreMatchers.equalTo;
@@ -179,9 +180,8 @@ public class JaxwsOpenTracingTracingTest extends 
AbstractClientServerTestBase {
         }
 
         // Await till flush happens, usually every second
-        await().atMost(Duration.ofSeconds(1L)).until(()-> 
REPORTER.getSpans().size() == 4);
+        await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(REPORTER.getSpans(), hasSize(4)));
 
-        assertThat(REPORTER.getSpans().size(), equalTo(4));
         assertThat(REPORTER.getSpans().get(3).getOperationName(), 
equalTo("test span"));
         assertThat(REPORTER.getSpans().get(3).getReferences(), empty());
     }
@@ -235,7 +235,7 @@ public class JaxwsOpenTracingTracingTest extends 
AbstractClientServerTestBase {
         service.orderBooks();
 
         // Await till flush happens, usually every second
-        await().atMost(Duration.ofSeconds(1L)).until(() -> 
REPORTER.getSpans().size() == 2);
+        await().atMost(Duration.ofSeconds(5L)).untilAsserted(() -> 
assertThat(REPORTER.getSpans(), hasSize(2)));
 
         assertThat(REPORTER.getSpans().get(0).getOperationName(), 
equalTo("POST /BookStore"));
         assertThat(REPORTER.getSpans().get(1).getOperationName(),

Reply via email to