diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index 76c07774f..2eb9c7701 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -33,7 +33,7 @@ 1.8 1.8 2.3.0.BUILD-SNAPSHOT - 5.12.1 + 5.12.2 3.14.6 diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java index 416a0f288..631919c6b 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/app/webflux/SleuthBenchmarkingSpringWebFluxApp.java @@ -19,11 +19,10 @@ package org.springframework.cloud.sleuth.benchmarks.app.webflux; import java.util.regex.Pattern; import brave.sampler.Sampler; +import brave.handler.SpanHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Mono; -import zipkin2.Span; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.WebApplicationType; @@ -80,8 +79,10 @@ public class SleuthBenchmarkingSpringWebFluxApp } @Bean - public Reporter reporter() { - return Reporter.NOOP; + public SpanHandler spanHandler() { + return new SpanHandler() { + // intentionally anonymous to prevent logging fallback on NOOP + }; } @Override diff --git a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxBenchmarks.java b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxBenchmarks.java index 9378dd669..ca0cfd1cd 100644 --- a/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxBenchmarks.java +++ b/benchmarks/src/main/java/org/springframework/cloud/sleuth/benchmarks/jmh/benchmarks/SpringWebFluxBenchmarks.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.util.concurrent.TimeUnit; import brave.Tracing; +import brave.handler.SpanHandler; import brave.http.HttpTracing; import brave.httpclient.TracingHttpClientBuilder; import brave.propagation.CurrentTraceContext; @@ -45,7 +46,6 @@ import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; -import zipkin2.reporter.Reporter; import org.springframework.boot.SpringApplication; import org.springframework.boot.WebApplicationType; @@ -61,6 +61,9 @@ import org.springframework.context.ConfigurableApplicationContext; @Threads(2) @State(Scope.Benchmark) public class SpringWebFluxBenchmarks { + static final SpanHandler FAKE_SPAN_HANDLER = new SpanHandler() { + // intentionally anonymous to prevent logging fallback on NOOP + }; protected static TraceContext defaultTraceContext = TraceContext.newBuilder() .traceIdHigh(333L).traceId(444L).spanId(3).sampled(true).build(); @@ -109,9 +112,9 @@ public class SpringWebFluxBenchmarks { baseUrl = "http://127.0.0.1:" + springWebFluxApp.port + "/foo"; client = newClient(); tracedClient = newClient(HttpTracing - .create(Tracing.newBuilder().spanReporter(Reporter.NOOP).build())); + .create(Tracing.newBuilder().addSpanHandler(FAKE_SPAN_HANDLER).build())); unsampledClient = newClient(HttpTracing.create(Tracing.newBuilder() - .sampler(Sampler.NEVER_SAMPLE).spanReporter(Reporter.NOOP).build())); + .sampler(Sampler.NEVER_SAMPLE).addSpanHandler(FAKE_SPAN_HANDLER).build())); postSetUp(); } diff --git a/pom.xml b/pom.xml index 4690ec55f..17030f1b8 100644 --- a/pom.xml +++ b/pom.xml @@ -243,7 +243,7 @@ 3.1.0.BUILD-SNAPSHOT 3.0.0-SNAPSHOT 3.0.0-SNAPSHOT - 5.12.1 + 5.12.2 2.1.7.RELEASE false 3.14.6 diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/ArrayListSpanReporter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/ArrayListSpanReporter.java deleted file mode 100644 index 14eccc356..000000000 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/ArrayListSpanReporter.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed 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 - * - * https://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.springframework.cloud.sleuth.util; - -import java.util.ArrayList; -import java.util.List; - -import zipkin2.Span; -import zipkin2.reporter.Reporter; - -/** - * Accumulator of closed spans. - * - * @author Marcin Grzejszczak - * @since 2.0.0 - * @deprecated This type will be removed in 3.0. Use io.zipkin.brave:brave-tests instead - */ -@Deprecated -public class ArrayListSpanReporter implements Reporter { - - private final List spans = new ArrayList<>(); - - public List getSpans() { - synchronized (this.spans) { - return new ArrayList<>(this.spans); - } - } - - @Override - public String toString() { - return "ArrayListSpanAccumulator{" + "spans=" + getSpans() + '}'; - } - - @Override - public void report(Span span) { - synchronized (this.spans) { - this.spans.add(span); - } - } - - public void clear() { - synchronized (this.spans) { - this.spans.clear(); - } - } - -} diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/BlockingQueueSpanReporter.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/BlockingQueueSpanReporter.java deleted file mode 100644 index eff2686dc..000000000 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/util/BlockingQueueSpanReporter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2013-2020 the original author or authors. - * - * Licensed 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 - * - * https://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.springframework.cloud.sleuth.util; - -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; - -import zipkin2.Span; -import zipkin2.reporter.Reporter; - -/** - * Like {@link ArrayListSpanReporter}, except appropriate for async instrumentation. - */ -public class BlockingQueueSpanReporter implements Reporter { - - private final LinkedBlockingQueue spans = new LinkedBlockingQueue<>(); - - /** - * Blocks until a span is reported or throws an {@link AssertionError}. - * @return the first span not yet taken. - */ - public Span takeSpan() { - Span result = takeSpan(3_000); - if (result == null) { - throw new AssertionError("Span was not reported"); - } - return result; - } - - @Override - public String toString() { - return "BlockingQueueSpanReporter{spans=" + spans + '}'; - } - - @Override - public void report(Span span) { - spans.add(span); - } - - /** Use this as a post-condition to ensure all spans are accounted for. */ - public void assertEmpty() { - if (takeSpan(100) != null) { - throw new AssertionError( - "Span remaining in queue. Check for redundant reporting!"); - } - } - - private Span takeSpan(long timeout) { - Span result; - try { - result = spans.poll(timeout, TimeUnit.MILLISECONDS); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new AssertionError(e); - } - return result; - } - -} diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanHandlerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanHandlerTests.java index 85cf3f5f5..d4e26cbc3 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanHandlerTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/SpanHandlerTests.java @@ -22,16 +22,15 @@ import brave.handler.MutableSpan; import brave.handler.SpanHandler; import brave.propagation.TraceContext; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -45,14 +44,14 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen public class SpanHandlerTests { @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @Autowired Tracer tracer; @BeforeEach public void setup() { - this.reporter.clear(); + this.spans.clear(); } @Test @@ -61,8 +60,8 @@ public class SpanHandlerTests { hello.finish(); - BDDAssertions.then(this.reporter.getSpans()).hasSize(1); - BDDAssertions.then(this.reporter.getSpans().get(0).name()).isEqualTo("foo bar"); + BDDAssertions.then(this.spans).hasSize(1); + BDDAssertions.then(this.spans.get(0).name()).isEqualTo("foo bar"); } @Configuration @@ -75,8 +74,8 @@ public class SpanHandlerTests { } @Bean - Reporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } // tag::spanHandler[] diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectFluxTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectFluxTests.java index eb68c75dc..4fff90af9 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectFluxTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectFluxTests.java @@ -16,17 +16,18 @@ package org.springframework.cloud.sleuth.annotation; -import java.util.ArrayList; import java.util.Iterator; -import java.util.List; +import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import brave.Span; import brave.Tracer; +import brave.handler.SpanHandler; import brave.propagation.TraceContext; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.apache.commons.lang.StringUtils; import org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeEach; @@ -34,13 +35,10 @@ import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.context.Context; -import zipkin2.Annotation; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -59,7 +57,7 @@ public class SleuthSpanCreatorAspectFluxTests { Tracer tracer; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; private static String toHexString(Long value) { then(value).isNotNull(); @@ -82,7 +80,7 @@ public class SleuthSpanCreatorAspectFluxTests { @BeforeEach public void setup() { - this.reporter.clear(); + this.spans.clear(); this.testBean.reset(); } @@ -93,10 +91,9 @@ public class SleuthSpanCreatorAspectFluxTests { verifyNoSpansUntilFluxComplete(flux); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("test-method"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("test-method"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -108,10 +105,9 @@ public class SleuthSpanCreatorAspectFluxTests { verifyNoSpansUntilFluxComplete(flux); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("test-method2"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("test-method2"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -123,10 +119,9 @@ public class SleuthSpanCreatorAspectFluxTests { verifyNoSpansUntilFluxComplete(flux); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method3"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method3"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -138,10 +133,9 @@ public class SleuthSpanCreatorAspectFluxTests { verifyNoSpansUntilFluxComplete(flux); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method4"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method4"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -155,11 +149,10 @@ public class SleuthSpanCreatorAspectFluxTests { verifyNoSpansUntilFluxComplete(flux); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method5"); - then(spans.get(0).tags()).containsEntry("testTag", "test"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method5"); + then(this.spans.get(0).tags()).containsEntry("testTag", "test"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -171,11 +164,10 @@ public class SleuthSpanCreatorAspectFluxTests { verifyNoSpansUntilFluxComplete(flux); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method6"); - then(spans.get(0).tags()).containsEntry("testTag6", "test"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method6"); + then(this.spans.get(0).tags()).containsEntry("testTag6", "test"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -187,10 +179,9 @@ public class SleuthSpanCreatorAspectFluxTests { verifyNoSpansUntilFluxComplete(flux); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method8"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method8"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -202,12 +193,11 @@ public class SleuthSpanCreatorAspectFluxTests { verifyNoSpansUntilFluxComplete(flux); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method9"); - then(spans.get(0).tags()).containsEntry("class", "TestBean") + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method9"); + then(this.spans.get(0).tags()).containsEntry("class", "TestBean") .containsEntry("method", "testMethod9"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -226,14 +216,13 @@ public class SleuthSpanCreatorAspectFluxTests { } Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); then(spans).hasSize(1); then(spans.get(0).name()).isEqualTo("foo"); then(spans.get(0).tags()).containsEntry("customTestTag10", "test"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("customTest.before", "customTest.after"); - then(spans.get(0).duration()).isNotZero(); + then(spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -244,14 +233,13 @@ public class SleuthSpanCreatorAspectFluxTests { verifyNoSpansUntilFluxComplete(flux); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("test-method10"); - then(spans.get(0).tags()).containsEntry("customTestTag10", "test"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("test-method10"); + then(this.spans.get(0).tags()).containsEntry("customTestTag10", "test"); + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("customTest.before", "customTest.after"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -270,14 +258,13 @@ public class SleuthSpanCreatorAspectFluxTests { } Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("foo"); - then(spans.get(0).tags()).containsEntry("customTestTag10", "test"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("foo"); + then(this.spans.get(0).tags()).containsEntry("customTestTag10", "test"); + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("customTest.before", "customTest.after"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -297,16 +284,15 @@ public class SleuthSpanCreatorAspectFluxTests { } Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("foo"); - then(spans.get(0).tags()).containsEntry("class", "TestBean") + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("foo"); + then(this.spans.get(0).tags()).containsEntry("class", "TestBean") .containsEntry("method", "testMethod11") .containsEntry("customTestTag11", "test"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("customTest.before", "customTest.after"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -316,7 +302,7 @@ public class SleuthSpanCreatorAspectFluxTests { try { Flux flux = this.testBean.testMethod12("test"); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); flux.toIterable().iterator().next(); } @@ -324,12 +310,11 @@ public class SleuthSpanCreatorAspectFluxTests { } Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("test-method12"); - then(spans.get(0).tags()).containsEntry("testTag12", "test") + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("test-method12"); + then(this.spans.get(0).tags()).containsEntry("testTag12", "test") .containsEntry("error", "test exception 12"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -342,7 +327,7 @@ public class SleuthSpanCreatorAspectFluxTests { // tag::continue_span_execution[] Flux flux = this.testBean.testMethod13(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); flux.toIterable().iterator().next(); // end::continue_span_execution[] @@ -354,14 +339,13 @@ public class SleuthSpanCreatorAspectFluxTests { } Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("foo"); - then(spans.get(0).tags()).containsEntry("error", "test exception 13"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("foo"); + then(this.spans.get(0).tags()).containsEntry("error", "test exception 13"); + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("testMethod13.before", "testMethod13.afterFailure", "testMethod13.after"); - then(spans.get(0).duration()).isNotZero(); + then(spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -372,8 +356,7 @@ public class SleuthSpanCreatorAspectFluxTests { verifyNoSpansUntilFluxComplete(flux); Awaitility.await().untilAsserted(() -> { - List spans = new ArrayList<>(this.reporter.getSpans()); - then(spans).isEmpty(); + then(this.spans).isEmpty(); then(this.tracer.currentSpan()).isNull(); }); } @@ -384,10 +367,9 @@ public class SleuthSpanCreatorAspectFluxTests { Long newSpanId = flux.blockFirst(); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("span-in-trace-context"); - then(spans.get(0).id()).isEqualTo(toHexString(newSpanId)); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("span-in-trace-context"); + then(this.spans.get(0).id()).isEqualTo(toHexString(newSpanId)); then(this.tracer.currentSpan()).isNull(); }); } @@ -398,10 +380,9 @@ public class SleuthSpanCreatorAspectFluxTests { Long newSpanId = flux.blockFirst(); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("span-in-subscriber-context"); - then(spans.get(0).id()).isEqualTo(toHexString(newSpanId)); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("span-in-subscriber-context"); + then(this.spans.get(0).id()).isEqualTo(toHexString(newSpanId)); then(this.tracer.currentSpan()).isNull(); }); } @@ -409,12 +390,12 @@ public class SleuthSpanCreatorAspectFluxTests { private void verifyNoSpansUntilFluxComplete(Flux flux) { Iterator iterator = flux.toIterable().iterator(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); this.testBean.proceed(); String result1 = iterator.next(); then(result1).isEqualTo(TEST_STRING1); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); this.testBean.proceed(); String result2 = iterator.next(); @@ -623,8 +604,8 @@ public class SleuthSpanCreatorAspectFluxTests { } @Bean - Reporter spanReporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectMonoTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectMonoTests.java index 6713f3574..81f0d0c53 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectMonoTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectMonoTests.java @@ -16,8 +16,6 @@ package org.springframework.cloud.sleuth.annotation; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collector; @@ -27,18 +25,18 @@ import javax.annotation.concurrent.NotThreadSafe; import brave.Span; import brave.Tracer; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; -import zipkin2.Annotation; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.annotation.DirtiesContext; @@ -63,7 +61,7 @@ public class SleuthSpanCreatorAspectMonoTests { Tracer tracer; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; protected static String id(Tracer tracer) { if (tracer.currentSpan() == null) { @@ -74,22 +72,21 @@ public class SleuthSpanCreatorAspectMonoTests { @BeforeEach public void setup() { - this.reporter.clear(); + this.spans.clear(); } @Test public void shouldCreateSpanWhenAnnotationOnInterfaceMethod() { Mono mono = this.testBean.testMethod(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); mono.block(); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("test-method"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("test-method"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -98,15 +95,14 @@ public class SleuthSpanCreatorAspectMonoTests { public void shouldCreateSpanWhenAnnotationOnClassMethod() { Mono mono = this.testBean.testMethod2(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); mono.block(); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("test-method2"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("test-method2"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -115,16 +111,15 @@ public class SleuthSpanCreatorAspectMonoTests { public void shouldCreateSpanWithCustomNameWhenAnnotationOnClassMethod() { Mono mono = this.testBean.testMethod3(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); String result = mono.block(); Awaitility.await().untilAsserted(() -> { then(result).isEqualTo(TEST_STRING); - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method3"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method3"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -133,15 +128,14 @@ public class SleuthSpanCreatorAspectMonoTests { public void shouldCreateSpanWithCustomNameWhenAnnotationOnInterfaceMethod() { Mono mono = this.testBean.testMethod4(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); mono.block(); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method4"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method4"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -152,16 +146,15 @@ public class SleuthSpanCreatorAspectMonoTests { Mono mono = this.testBean.testMethod5("test"); // end::execution[] - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); mono.block(); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method5"); - then(spans.get(0).tags()).containsEntry("testTag", "test"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method5"); + then(this.spans.get(0).tags()).containsEntry("testTag", "test"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -170,16 +163,15 @@ public class SleuthSpanCreatorAspectMonoTests { public void shouldCreateSpanWithTagWhenAnnotationOnClassMethod() { Mono mono = this.testBean.testMethod6("test"); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); mono.block(); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method6"); - then(spans.get(0).tags()).containsEntry("testTag6", "test"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method6"); + then(this.spans.get(0).tags()).containsEntry("testTag6", "test"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -188,15 +180,14 @@ public class SleuthSpanCreatorAspectMonoTests { public void shouldCreateSpanWithLogWhenAnnotationOnInterfaceMethod() { Mono mono = this.testBean.testMethod8("test"); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); mono.block(); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method8"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method8"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -205,17 +196,16 @@ public class SleuthSpanCreatorAspectMonoTests { public void shouldCreateSpanWithLogWhenAnnotationOnClassMethod() { Mono mono = this.testBean.testMethod9("test"); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); mono.block(); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method9"); - then(spans.get(0).tags()).containsEntry("class", "TestBean") + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method9"); + then(this.spans.get(0).tags()).containsEntry("class", "TestBean") .containsEntry("method", "testMethod9"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -227,7 +217,7 @@ public class SleuthSpanCreatorAspectMonoTests { try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span.start())) { Mono mono = this.testBean.testMethod10("test"); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); mono.block(); } @@ -236,14 +226,13 @@ public class SleuthSpanCreatorAspectMonoTests { } Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("foo"); - then(spans.get(0).tags()).containsEntry("customTestTag10", "test"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("foo"); + then(this.spans.get(0).tags()).containsEntry("customTestTag10", "test"); + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("customTest.before", "customTest.after"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -253,14 +242,13 @@ public class SleuthSpanCreatorAspectMonoTests { this.testBean.testMethod10("test").block(); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("test-method10"); - then(spans.get(0).tags()).containsEntry("customTestTag10", "test"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("test-method10"); + then(this.spans.get(0).tags()).containsEntry("customTestTag10", "test"); + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("customTest.before", "customTest.after"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -272,7 +260,7 @@ public class SleuthSpanCreatorAspectMonoTests { try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span.start())) { Mono mono = this.testBean.testMethod10_v2("test"); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); mono.block(); } @@ -281,14 +269,13 @@ public class SleuthSpanCreatorAspectMonoTests { } Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("foo"); - then(spans.get(0).tags()).containsEntry("customTestTag10", "test"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("foo"); + then(this.spans.get(0).tags()).containsEntry("customTestTag10", "test"); + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("customTest.before", "customTest.after"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -301,7 +288,7 @@ public class SleuthSpanCreatorAspectMonoTests { // tag::continue_span_execution[] Mono mono = this.testBean.testMethod11("test"); // end::continue_span_execution[] - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); mono.block(); } @@ -310,16 +297,15 @@ public class SleuthSpanCreatorAspectMonoTests { } Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("foo"); - then(spans.get(0).tags()).containsEntry("class", "TestBean") + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("foo"); + then(this.spans.get(0).tags()).containsEntry("class", "TestBean") .containsEntry("method", "testMethod11") .containsEntry("customTestTag11", "test"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("customTest.before", "customTest.after"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -329,7 +315,7 @@ public class SleuthSpanCreatorAspectMonoTests { try { Mono mono = this.testBean.testMethod12("test"); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); mono.block(); } @@ -337,12 +323,11 @@ public class SleuthSpanCreatorAspectMonoTests { } Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("test-method12"); - then(spans.get(0).tags()).containsEntry("testTag12", "test") + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("test-method12"); + then(this.spans.get(0).tags()).containsEntry("testTag12", "test") .containsEntry("error", "test exception 12"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -355,7 +340,7 @@ public class SleuthSpanCreatorAspectMonoTests { // tag::continue_span_execution[] Mono mono = this.testBean.testMethod13(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); mono.block(); // end::continue_span_execution[] @@ -367,14 +352,13 @@ public class SleuthSpanCreatorAspectMonoTests { } Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("foo"); - then(spans.get(0).tags()).containsEntry("error", "test exception 13"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("foo"); + then(this.spans.get(0).tags()).containsEntry("error", "test exception 13"); + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("testMethod13.before", "testMethod13.afterFailure", "testMethod13.after"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); }); } @@ -385,8 +369,7 @@ public class SleuthSpanCreatorAspectMonoTests { mono.block(); Awaitility.await().untilAsserted(() -> { - List spans = new ArrayList<>(this.reporter.getSpans()); - then(spans).isEmpty(); + then(this.spans).isEmpty(); then(this.tracer.currentSpan()).isNull(); }); } @@ -395,15 +378,14 @@ public class SleuthSpanCreatorAspectMonoTests { public void shouldReturnNewSpanFromTraceContext() { Mono mono = this.testBean.newSpanInTraceContext(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); String newSpanId = mono.block(); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("span-in-trace-context"); - then(spans.get(0).id()).isEqualTo(newSpanId); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("span-in-trace-context"); + then(this.spans.get(0).id()).isEqualTo(newSpanId); then(this.tracer.currentSpan()).isNull(); }); } @@ -413,7 +395,7 @@ public class SleuthSpanCreatorAspectMonoTests { Mono, String>> mono = this.testBeanOuter .outerNewSpanInTraceContext(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); Pair, String> pair = mono.block(); String outerSpanIdBefore = pair.getFirst().getFirst(); @@ -422,14 +404,13 @@ public class SleuthSpanCreatorAspectMonoTests { then(outerSpanIdBefore).isNotEqualTo(innerSpanId); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - zipkin2.Span outerSpan = spans.stream() + MutableSpan outerSpan = spans.spans().stream() .filter(span -> span.name().equals("outer-span-in-trace-context")) .findFirst().orElseThrow(() -> new AssertionError( "No span with name [outer-span-in-trace-context] found")); then(outerSpan.name()).isEqualTo("outer-span-in-trace-context"); then(outerSpan.id()).isEqualTo(outerSpanIdBefore); - zipkin2.Span innerSpan = spans.stream() + MutableSpan innerSpan = spans.spans().stream() .filter(span -> span.name().equals("span-in-trace-context")) .findFirst().orElseThrow(() -> new AssertionError( "No span with name [span-in-trace-context] found")); @@ -443,15 +424,14 @@ public class SleuthSpanCreatorAspectMonoTests { public void shouldReturnNewSpanFromSubscriberContext() { Mono mono = this.testBean.newSpanInSubscriberContext(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); String newSpanId = mono.block(); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("span-in-subscriber-context"); - then(spans.get(0).id()).isEqualTo(newSpanId); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("span-in-subscriber-context"); + then(this.spans.get(0).id()).isEqualTo(newSpanId); then(this.tracer.currentSpan()).isNull(); }); } @@ -461,7 +441,7 @@ public class SleuthSpanCreatorAspectMonoTests { Mono, String>> mono = this.testBeanOuter .outerNewSpanInSubscriberContext(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); Pair, String> pair = mono.block(); String outerSpanIdBefore = pair.getFirst().getFirst(); @@ -470,14 +450,13 @@ public class SleuthSpanCreatorAspectMonoTests { then(outerSpanIdBefore).isNotEqualTo(innerSpanId); Awaitility.await().untilAsserted(() -> { - List spans = this.reporter.getSpans(); - zipkin2.Span outerSpan = spans.stream().filter( + MutableSpan outerSpan = spans.spans().stream().filter( span -> span.name().equals("outer-span-in-subscriber-context")) .findFirst().orElseThrow(() -> new AssertionError( "No span with name [outer-span-in-subscriber-context] found")); then(outerSpan.name()).isEqualTo("outer-span-in-subscriber-context"); then(outerSpan.id()).isEqualTo(outerSpanIdBefore); - zipkin2.Span innerSpan = spans.stream() + MutableSpan innerSpan = spans.spans().stream() .filter(span -> span.name().equals("span-in-subscriber-context")) .findFirst().orElseThrow(() -> new AssertionError( "No span with name [span-in-subscriber-context] found")); @@ -694,8 +673,8 @@ public class SleuthSpanCreatorAspectMonoTests { } @Bean - Reporter spanReporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectNegativeTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectNegativeTests.java index c2bedb006..4a5a79342 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectNegativeTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectNegativeTests.java @@ -16,18 +16,15 @@ package org.springframework.cloud.sleuth.annotation; -import java.util.List; - +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import zipkin2.Span; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -43,27 +40,26 @@ public class SleuthSpanCreatorAspectNegativeTests { TestBeanInterface annotatedTestBean; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @BeforeEach public void setup() { - this.reporter.clear(); + this.spans.clear(); } @Test public void shouldNotCallAdviceForNotAnnotatedBean() { this.testBean.testMethod(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); } @Test public void shouldCallAdviceForAnnotatedBean() throws Throwable { this.annotatedTestBean.testMethod(); - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("test-method"); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("test-method"); } protected interface NotAnnotatedTestBeanInterface { @@ -142,8 +138,8 @@ public class SleuthSpanCreatorAspectNegativeTests { protected static class TestConfiguration { @Bean - Reporter spanReporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java index 8067f75c3..6ed435601 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorAspectTests.java @@ -16,21 +16,20 @@ package org.springframework.cloud.sleuth.annotation; -import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import brave.Span; import brave.Tracer; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import zipkin2.Annotation; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.annotation.DirtiesContext; @@ -50,21 +49,20 @@ public class SleuthSpanCreatorAspectTests { Tracer tracer; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @BeforeEach public void setup() { - this.reporter.clear(); + this.spans.clear(); } @Test public void shouldCreateSpanWhenAnnotationOnInterfaceMethod() { this.testBean.testMethod(); - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("test-method"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("test-method"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -72,10 +70,9 @@ public class SleuthSpanCreatorAspectTests { public void shouldCreateSpanWhenAnnotationOnClassMethod() { this.testBean.testMethod2(); - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("test-method2"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("test-method2"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -83,10 +80,9 @@ public class SleuthSpanCreatorAspectTests { public void shouldCreateSpanWithCustomNameWhenAnnotationOnClassMethod() { this.testBean.testMethod3(); - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method3"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method3"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -94,10 +90,9 @@ public class SleuthSpanCreatorAspectTests { public void shouldCreateSpanWithCustomNameWhenAnnotationOnInterfaceMethod() { this.testBean.testMethod4(); - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method4"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method4"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -107,11 +102,10 @@ public class SleuthSpanCreatorAspectTests { this.testBean.testMethod5("test"); // end::execution[] - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method5"); - then(spans.get(0).tags()).containsEntry("testTag", "test"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method5"); + then(this.spans.get(0).tags()).containsEntry("testTag", "test"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -119,11 +113,10 @@ public class SleuthSpanCreatorAspectTests { public void shouldCreateSpanWithTagWhenAnnotationOnClassMethod() { this.testBean.testMethod6("test"); - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method6"); - then(spans.get(0).tags()).containsEntry("testTag6", "test"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method6"); + then(this.spans.get(0).tags()).containsEntry("testTag6", "test"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -131,10 +124,9 @@ public class SleuthSpanCreatorAspectTests { public void shouldCreateSpanWithLogWhenAnnotationOnInterfaceMethod() { this.testBean.testMethod8("test"); - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method8"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method8"); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -142,12 +134,11 @@ public class SleuthSpanCreatorAspectTests { public void shouldCreateSpanWithLogWhenAnnotationOnClassMethod() { this.testBean.testMethod9("test"); - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("custom-name-on-test-method9"); - then(spans.get(0).tags()).containsEntry("class", "TestBean") + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("custom-name-on-test-method9"); + then(this.spans.get(0).tags()).containsEntry("class", "TestBean") .containsEntry("method", "testMethod9"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -162,14 +153,13 @@ public class SleuthSpanCreatorAspectTests { span.finish(); } - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("foo"); - then(spans.get(0).tags()).containsEntry("customTestTag10", "test"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("foo"); + then(this.spans.get(0).tags()).containsEntry("customTestTag10", "test"); + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("customTest.before", "customTest.after"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -177,14 +167,13 @@ public class SleuthSpanCreatorAspectTests { public void shouldStartAndCloseSpanOnContinueSpanIfSpanNotSet() { this.testBean.testMethod10("test"); - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("test-method10"); - then(spans.get(0).tags()).containsEntry("customTestTag10", "test"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("test-method10"); + then(this.spans.get(0).tags()).containsEntry("customTestTag10", "test"); + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("customTest.before", "customTest.after"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -199,14 +188,13 @@ public class SleuthSpanCreatorAspectTests { span.finish(); } - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("foo"); - then(spans.get(0).tags()).containsEntry("customTestTag10", "test"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("foo"); + then(this.spans.get(0).tags()).containsEntry("customTestTag10", "test"); + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("customTest.before", "customTest.after"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -223,16 +211,15 @@ public class SleuthSpanCreatorAspectTests { span.finish(); } - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("foo"); - then(spans.get(0).tags()).containsEntry("class", "TestBean") + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("foo"); + then(this.spans.get(0).tags()).containsEntry("class", "TestBean") .containsEntry("method", "testMethod11") .containsEntry("customTestTag11", "test"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("customTest.before", "customTest.after"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -244,12 +231,11 @@ public class SleuthSpanCreatorAspectTests { catch (RuntimeException ignored) { } - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("test-method12"); - then(spans.get(0).tags()).containsEntry("testTag12", "test") + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("test-method12"); + then(this.spans.get(0).tags()).containsEntry("testTag12", "test") .containsEntry("error", "test exception 12"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -268,14 +254,13 @@ public class SleuthSpanCreatorAspectTests { span.finish(); } - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("foo"); - then(spans.get(0).tags()).containsEntry("error", "test exception 13"); - then(spans.get(0).annotations().stream().map(Annotation::value) + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("foo"); + then(this.spans.get(0).tags()).containsEntry("error", "test exception 13"); + then(this.spans.get(0).annotations().stream().map(Map.Entry::getValue) .collect(Collectors.toList())).contains("testMethod13.before", "testMethod13.afterFailure", "testMethod13.after"); - then(spans.get(0).duration()).isNotZero(); + then(this.spans.get(0).finishTimestamp()).isNotZero(); then(this.tracer.currentSpan()).isNull(); } @@ -283,8 +268,7 @@ public class SleuthSpanCreatorAspectTests { public void shouldNotCreateSpanWhenNotAnnotated() { this.testBean.testMethod7(); - List spans = this.reporter.getSpans(); - then(spans).isEmpty(); + then(this.spans).isEmpty(); then(this.tracer.currentSpan()).isNull(); } @@ -424,8 +408,8 @@ public class SleuthSpanCreatorAspectTests { } @Bean - Reporter spanReporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorCircularDependencyTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorCircularDependencyTests.java index 5793d1280..58ee9fd50 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorCircularDependencyTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/annotation/SleuthSpanCreatorCircularDependencyTests.java @@ -16,14 +16,13 @@ package org.springframework.cloud.sleuth.annotation; +import brave.handler.SpanHandler; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.Test; -import zipkin2.Span; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -62,8 +61,8 @@ public class SleuthSpanCreatorCircularDependencyTests { protected static class TestConfiguration { @Bean - Reporter spanReporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/baggage/BaggageTagSpanHandlerTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/baggage/BaggageTagSpanHandlerTest.java index 55e6d8aeb..9bc688c8d 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/baggage/BaggageTagSpanHandlerTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/baggage/BaggageTagSpanHandlerTest.java @@ -16,20 +16,18 @@ package org.springframework.cloud.sleuth.baggage; -import java.util.List; -import java.util.Map; - import brave.ScopedSpan; import brave.Tracer; import brave.baggage.BaggageField; +import brave.handler.SpanHandler; import brave.propagation.TraceContext; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ActiveProfiles; @@ -53,13 +51,13 @@ public class BaggageTagSpanHandlerTest { private Tracer tracer; @Autowired - private ArrayListSpanReporter arrayListSpanReporter; + private TestSpanHandler spans; private ScopedSpan span; @BeforeEach public void setUp() { - this.arrayListSpanReporter.clear(); + this.spans.clear(); this.span = this.tracer.startScopedSpan("my-scoped-span"); TraceContext context = this.span.context(); COUNTRY_CODE.updateValue(context, "FO"); @@ -70,11 +68,10 @@ public class BaggageTagSpanHandlerTest { public void shouldReportWithBaggageInTags() { this.span.finish(); - List spans = this.arrayListSpanReporter.getSpans(); - assertThat(spans).hasSize(1); - Map tags = spans.get(0).tags(); - assertThat(tags).hasSize(1); // REQUEST_ID is not in the tag-fields - assertThat(tags).containsEntry(COUNTRY_CODE.name(), "FO"); + assertThat(this.spans).hasSize(1); + assertThat(this.spans.get(0).tags()).hasSize(1) // REQUEST_ID is not in the + // tag-fields + .containsEntry(COUNTRY_CODE.name(), "FO"); } @EnableAutoConfiguration @@ -82,8 +79,8 @@ public class BaggageTagSpanHandlerTest { static class Config { @Bean - ArrayListSpanReporter spanReporter() { - return new ArrayListSpanReporter(); + public SpanHandler testSpanHandler() { + return new TestSpanHandler(); } } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java index c0b7c3a73..debb0c7d1 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/documentation/SpringCloudSleuthDocTests.java @@ -16,7 +16,6 @@ package org.springframework.cloud.sleuth.documentation; -import java.util.List; import java.util.Optional; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; @@ -27,8 +26,10 @@ import java.util.concurrent.Future; import brave.Span; import brave.Tracer; import brave.Tracing; +import brave.handler.MutableSpan; import brave.propagation.StrictCurrentTraceContext; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -39,7 +40,6 @@ import org.springframework.cloud.sleuth.SpanNamer; import org.springframework.cloud.sleuth.instrument.async.TraceCallable; import org.springframework.cloud.sleuth.instrument.async.TraceRunnable; import org.springframework.cloud.sleuth.internal.DefaultSpanNamer; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -53,18 +53,18 @@ import static org.assertj.core.api.BDDAssertions.then; */ public class SpringCloudSleuthDocTests { - ArrayListSpanReporter reporter = new ArrayListSpanReporter(); + TestSpanHandler spans = new TestSpanHandler(); StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) - .sampler(Sampler.ALWAYS_SAMPLE).spanReporter(this.reporter).build(); + .sampler(Sampler.ALWAYS_SAMPLE).addSpanHandler(this.spans).build(); Tracer tracer = this.tracing.tracer(); @BeforeEach public void setup() { - this.reporter.clear(); + this.spans.clear(); } @AfterEach @@ -87,9 +87,8 @@ public class SpringCloudSleuthDocTests { future.get(); // end::span_name_annotated_runnable_execution[] - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("calculatetax"); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("calculateTax"); } @Test @@ -115,9 +114,8 @@ public class SpringCloudSleuthDocTests { future.get(); // end::span_name_to_string_runnable_execution[] - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("calculatetax"); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("calculateTax"); executorService.shutdown(); } @@ -144,11 +142,10 @@ public class SpringCloudSleuthDocTests { } // end::manual_span_creation[] - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("calculatetax"); - then(spans.get(0).tags()).containsEntry("taxValue", "10"); - then(spans.get(0).annotations()).hasSize(1); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("calculateTax"); + then(this.spans.get(0).tags()).containsEntry("taxValue", "10"); + then(this.spans.get(0).annotations()).hasSize(1); } @Test @@ -182,9 +179,8 @@ public class SpringCloudSleuthDocTests { newSpan.finish(); } - List spans = this.reporter.getSpans(); BDDAssertions.then(spans).hasSize(1); - BDDAssertions.then(spans.get(0).name()).isEqualTo("calculatetax"); + BDDAssertions.then(spans.get(0).name()).isEqualTo("calculateTax"); BDDAssertions.then(spans.get(0).tags()).containsEntry("taxValue", "10"); BDDAssertions.then(spans.get(0).annotations()).hasSize(1); executorService.shutdown(); @@ -222,9 +218,8 @@ public class SpringCloudSleuthDocTests { // end::manual_span_joining[] }).get(); - List spans = this.reporter.getSpans(); - Optional calculateTax = spans.stream() - .filter(span -> span.name().equals("calculatecommission")).findFirst(); + Optional calculateTax = spans.spans().stream() + .filter(span -> span.name().equals("calculateCommission")).findFirst(); BDDAssertions.then(calculateTax).isPresent(); BDDAssertions.then(calculateTax.get().tags()).containsEntry("commissionValue", "10"); diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspectTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspectTest.java index 79c07b429..59fb342d0 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspectTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncAspectTest.java @@ -18,6 +18,7 @@ package org.springframework.cloud.sleuth.instrument.async; import brave.Tracing; import brave.propagation.StrictCurrentTraceContext; +import brave.test.TestSpanHandler; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.reflect.MethodSignature; import org.assertj.core.api.BDDAssertions; @@ -28,7 +29,6 @@ import org.mockito.BDDMockito; import org.mockito.Mockito; import org.springframework.cloud.sleuth.internal.DefaultSpanNamer; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; /** * @author Marcin Grzejszczak @@ -37,10 +37,10 @@ public class TraceAsyncAspectTest { StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); - ArrayListSpanReporter reporter = new ArrayListSpanReporter(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) - .spanReporter(this.reporter).build(); + .addSpanHandler(this.spans).build(); ProceedingJoinPoint point = Mockito.mock(ProceedingJoinPoint.class); @@ -73,9 +73,9 @@ public class TraceAsyncAspectTest { asyncAspect.traceBackgroundThread(this.point); - BDDAssertions.then(this.reporter.getSpans()).hasSize(1); - BDDAssertions.then(this.reporter.getSpans().get(0).name()).isEqualTo("foo-bar"); - BDDAssertions.then(this.reporter.getSpans().get(0).timestamp()).isPositive(); + BDDAssertions.then(this.spans).hasSize(1); + BDDAssertions.then(this.spans.get(0).name()).isEqualTo("foo-bar"); + BDDAssertions.then(this.spans.get(0).finishTimestamp()).isPositive(); } } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java index 1086330f3..2c2baae05 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceCallableTests.java @@ -24,6 +24,7 @@ import brave.Span; import brave.Tracer; import brave.Tracing; import brave.propagation.StrictCurrentTraceContext; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -31,7 +32,6 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.cloud.sleuth.SpanName; import org.springframework.cloud.sleuth.internal.DefaultSpanNamer; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import static org.assertj.core.api.BDDAssertions.then; @@ -42,10 +42,10 @@ public class TraceCallableTests { StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); - ArrayListSpanReporter reporter = new ArrayListSpanReporter(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) - .spanReporter(this.reporter).build(); + .addSpanHandler(this.spans).build(); Tracer tracer = this.tracing.tracer(); @@ -53,7 +53,7 @@ public class TraceCallableTests { public void clean() { this.executor.shutdown(); this.tracing.close(); - this.reporter.clear(); + this.spans.clear(); this.currentTraceContext.close(); } @@ -98,9 +98,8 @@ public class TraceCallableTests { public void should_take_name_of_span_from_span_name_annotation() throws Exception { whenATraceKeepingCallableGetsSubmitted(); - then(this.reporter.getSpans()).hasSize(1); - then(this.reporter.getSpans().get(0).name()) - .isEqualTo("some-callable-name-from-annotation"); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("some-callable-name-from-annotation"); } @Test @@ -108,9 +107,8 @@ public class TraceCallableTests { throws Exception { whenCallableGetsSubmitted(thatRetrievesTraceFromThreadLocal()); - then(this.reporter.getSpans()).hasSize(1); - then(this.reporter.getSpans().get(0).name()) - .isEqualTo("some-callable-name-from-to-string"); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("some-callable-name-from-to-string"); } private Callable thatRetrievesTraceFromThreadLocal() { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java index 429d635dd..fd0b2fdfc 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceRunnableTests.java @@ -24,6 +24,7 @@ import brave.Span; import brave.Tracer; import brave.Tracing; import brave.propagation.StrictCurrentTraceContext; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -31,7 +32,6 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.cloud.sleuth.SpanName; import org.springframework.cloud.sleuth.internal.DefaultSpanNamer; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import static org.assertj.core.api.BDDAssertions.then; @@ -42,10 +42,10 @@ public class TraceRunnableTests { StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); - ArrayListSpanReporter reporter = new ArrayListSpanReporter(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) - .spanReporter(this.reporter).build(); + .addSpanHandler(this.spans).build(); Tracer tracer = this.tracing.tracer(); @@ -53,7 +53,7 @@ public class TraceRunnableTests { public void clean() { this.executor.shutdown(); this.tracing.close(); - this.reporter.clear(); + this.spans.clear(); this.currentTraceContext.close(); } @@ -102,9 +102,8 @@ public class TraceRunnableTests { whenRunnableGetsSubmitted(traceKeepingRunnable); - then(this.reporter.getSpans()).hasSize(1); - then(this.reporter.getSpans().get(0).name()) - .isEqualTo("some-runnable-name-from-annotation"); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("some-runnable-name-from-annotation"); } @Test @@ -115,9 +114,8 @@ public class TraceRunnableTests { whenRunnableGetsSubmitted(runnable); - then(this.reporter.getSpans()).hasSize(1); - then(this.reporter.getSpans().get(0).name()) - .isEqualTo("some-runnable-name-from-to-string"); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("some-runnable-name-from-to-string"); } private TraceKeepingRunnable runnableThatRetrievesTraceFromThreadLocal() { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java index f67ea1976..d33c1bedc 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceableExecutorServiceTests.java @@ -33,6 +33,7 @@ import brave.Tracer; import brave.Tracing; import brave.propagation.StrictCurrentTraceContext; import brave.propagation.TraceContext; +import brave.test.TestSpanHandler; import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -47,7 +48,6 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.beans.factory.BeanFactory; import org.springframework.cloud.sleuth.SpanNamer; import org.springframework.cloud.sleuth.internal.DefaultSpanNamer; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import static java.util.stream.Collectors.toList; import static org.assertj.core.api.BDDAssertions.then; @@ -66,10 +66,10 @@ public class TraceableExecutorServiceTests { StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); - ArrayListSpanReporter reporter = new ArrayListSpanReporter(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) - .spanReporter(this.reporter).build(); + .addSpanHandler(this.spans).build(); Tracer tracer = this.tracing.tracer(); @@ -79,7 +79,7 @@ public class TraceableExecutorServiceTests { public void setup() { this.traceManagerableExecutorService = new TraceableExecutorService( beanFactory(true), this.executorService); - this.reporter.clear(); + this.spans.clear(); this.spanVerifyingRunnable.clear(); } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java index d6e638bdc..762e8e814 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerIntegrationTests.java @@ -21,7 +21,10 @@ import java.util.concurrent.atomic.AtomicReference; import brave.ScopedSpan; import brave.Span; import brave.Tracer; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -31,7 +34,6 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JCircuitBreakerFactory; import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -41,7 +43,7 @@ import static org.assertj.core.api.BDDAssertions.then; public class CircuitBreakerIntegrationTests { @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @Autowired Tracer tracer; @@ -51,7 +53,7 @@ public class CircuitBreakerIntegrationTests { @BeforeEach public void setup() { - this.reporter.clear(); + this.spans.clear(); } @Test @@ -91,7 +93,7 @@ public class CircuitBreakerIntegrationTests { throw new IllegalStateException("boom2"); })).isInstanceOf(IllegalStateException.class).hasMessageContaining("boom2"); - then(this.reporter.getSpans()).hasSize(2); + then(this.spans).hasSize(2); then(scopedSpan.context().traceIdString()) .isEqualTo(first.get().context().traceIdString()); then(scopedSpan.context().traceIdString()) @@ -99,12 +101,12 @@ public class CircuitBreakerIntegrationTests { then(first.get().context().spanIdString()) .isNotEqualTo(second.get().context().spanIdString()); - zipkin2.Span reportedSpan = this.reporter.getSpans().get(0); - then(reportedSpan.name()).contains("circuitbreakerintegrationtests"); + MutableSpan reportedSpan = this.spans.get(0); + then(reportedSpan.name()).contains("CircuitBreakerIntegrationTests"); then(reportedSpan.tags().get("error")).contains("boom"); - reportedSpan = this.reporter.getSpans().get(1); - then(reportedSpan.name()).contains("circuitbreakerintegrationtests"); + reportedSpan = this.spans.get(1); + then(reportedSpan.name()).contains("CircuitBreakerIntegrationTests"); then(reportedSpan.tags().get("error")).contains("boom2"); } finally { @@ -117,8 +119,8 @@ public class CircuitBreakerIntegrationTests { static class Config { @Bean - ArrayListSpanReporter arrayListSpanReporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerTests.java index c1adce93c..c8d182945 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/circuitbreaker/CircuitBreakerTests.java @@ -22,15 +22,16 @@ import brave.ScopedSpan; import brave.Span; import brave.Tracer; import brave.Tracing; +import brave.handler.MutableSpan; import brave.propagation.StrictCurrentTraceContext; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.cloud.circuitbreaker.resilience4j.Resilience4JCircuitBreakerFactory; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import static org.assertj.core.api.BDDAssertions.then; @@ -38,16 +39,16 @@ public class CircuitBreakerTests { StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); - ArrayListSpanReporter reporter = new ArrayListSpanReporter(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) - .spanReporter(this.reporter).sampler(Sampler.ALWAYS_SAMPLE).build(); + .addSpanHandler(this.spans).sampler(Sampler.ALWAYS_SAMPLE).build(); Tracer tracer = this.tracing.tracer(); @BeforeEach public void setup() { - this.reporter.clear(); + this.spans.clear(); } @AfterEach @@ -96,7 +97,7 @@ public class CircuitBreakerTests { }))).isInstanceOf(IllegalStateException.class) .hasMessageContaining("boom2"); - then(this.reporter.getSpans()).hasSize(2); + then(this.spans).hasSize(2); then(scopedSpan.context().traceIdString()) .isEqualTo(first.get().context().traceIdString()); then(scopedSpan.context().traceIdString()) @@ -104,8 +105,8 @@ public class CircuitBreakerTests { then(first.get().context().spanIdString()) .isNotEqualTo(second.get().context().spanIdString()); - zipkin2.Span reportedSpan = this.reporter.getSpans().get(1); - then(reportedSpan.name()).contains("circuitbreakertests"); + MutableSpan reportedSpan = this.spans.get(1); + then(reportedSpan.name()).contains("CircuitBreakerTests"); then(reportedSpan.tags().get("error")).contains("boom2"); } finally { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfigurationIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfigurationIntegrationTests.java index eabd95418..a98769248 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfigurationIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfigurationIntegrationTests.java @@ -16,18 +16,19 @@ package org.springframework.cloud.sleuth.instrument.messaging; +import brave.handler.SpanHandler; import brave.messaging.MessagingRequest; import brave.messaging.MessagingRuleSampler; import brave.sampler.Matchers; import brave.sampler.RateLimitingSampler; import brave.sampler.Sampler; import brave.sampler.SamplerFunction; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -52,8 +53,8 @@ public class TraceMessagingAutoConfigurationIntegrationTests { public static class Config { @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } // tag::custom_messaging_consumer_sampler[] diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java index 0903497e3..2bb44a436 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TracingChannelInterceptorTest.java @@ -21,13 +21,15 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import brave.Span; import brave.Tracing; +import brave.handler.MutableSpan; import brave.propagation.B3Propagation; import brave.propagation.StrictCurrentTraceContext; import brave.propagation.TraceContext; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import zipkin2.Span; import org.springframework.amqp.support.AmqpHeaders; import org.springframework.integration.channel.DirectChannel; @@ -55,14 +57,14 @@ public class TracingChannelInterceptorTest { StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); - List spans = new ArrayList<>(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) // SINGLE_NO_PARENT more appropriate for messaging, but we check parent // hereTraceMessageHeaders .propagationFactory( B3Propagation.newFactoryBuilder().injectFormat(SINGLE).build()) - .spanReporter(this.spans::add).build(); + .addSpanHandler(this.spans).build(); ChannelInterceptor interceptor = TracingChannelInterceptor.create(tracing); @@ -100,7 +102,7 @@ public class TracingChannelInterceptorTest { this.channel.send(MessageBuilder.withPayload("foo").build()); assertThat(this.channel.receive().getHeaders()).containsKey("b3"); - assertThat(this.spans).hasSize(1).flatExtracting(Span::kind) + assertThat(this.spans).hasSize(1).extracting(MutableSpan::kind) .containsExactly(Span.Kind.PRODUCER); } @@ -112,7 +114,7 @@ public class TracingChannelInterceptorTest { assertThat(this.message).isNotNull(); assertThat(this.message.getHeaders()).containsKeys("b3", "nativeHeaders"); - assertThat(this.spans).flatExtracting(Span::kind).contains(Span.Kind.CONSUMER, + assertThat(this.spans).extracting(MutableSpan::kind).contains(Span.Kind.CONSUMER, Span.Kind.PRODUCER); } @@ -174,7 +176,7 @@ public class TracingChannelInterceptorTest { assertThat(this.channel.receive().getHeaders()).containsKeys("b3", "nativeHeaders"); - assertThat(this.spans).hasSize(1).flatExtracting(Span::kind) + assertThat(this.spans).hasSize(1).extracting(MutableSpan::kind) .containsExactly(Span.Kind.CONSUMER); } @@ -199,7 +201,7 @@ public class TracingChannelInterceptorTest { assertThat(messages.get(0).getHeaders()).doesNotContainKeys("b3", "nativeHeaders"); - assertThat(this.spans).flatExtracting(Span::kind) + assertThat(this.spans).extracting(MutableSpan::kind) .containsExactly(Span.Kind.CONSUMER, null); } @@ -240,7 +242,7 @@ public class TracingChannelInterceptorTest { this.channel.send(MessageBuilder.withPayload("foo").build()); this.channel.receive(); - assertThat(this.spans).flatExtracting(Span::kind) + assertThat(this.spans).extracting(MutableSpan::kind) .containsExactlyInAnyOrder(Span.Kind.CONSUMER, Span.Kind.PRODUCER); } @@ -253,7 +255,7 @@ public class TracingChannelInterceptorTest { channel.send(MessageBuilder.withPayload("foo").build()); - assertThat(this.spans).flatExtracting(Span::kind) + assertThat(this.spans).extracting(MutableSpan::kind) .containsExactly(Span.Kind.CONSUMER, null, Span.Kind.PRODUCER); } @@ -339,7 +341,8 @@ public class TracingChannelInterceptorTest { headers.put(KafkaHeaders.MESSAGE_KEY, "hello"); channel.send(MessageBuilder.createMessage("foo", new MessageHeaders(headers))); - assertThat(this.spans).flatExtracting(Span::remoteServiceName).contains("kafka"); + assertThat(this.spans).extracting(MutableSpan::remoteServiceName) + .contains("kafka"); } @Test @@ -353,7 +356,7 @@ public class TracingChannelInterceptorTest { headers.put(AmqpHeaders.RECEIVED_ROUTING_KEY, "hello"); channel.send(MessageBuilder.createMessage("foo", new MessageHeaders(headers))); - assertThat(this.spans).flatExtracting(Span::remoteServiceName) + assertThat(this.spans).extracting(MutableSpan::remoteServiceName) .contains("rabbitmq"); } @@ -367,7 +370,7 @@ public class TracingChannelInterceptorTest { Map headers = new HashMap<>(); channel.send(MessageBuilder.createMessage("foo", new MessageHeaders(headers))); - assertThat(this.spans).flatExtracting(Span::remoteServiceName) + assertThat(this.spans).extracting(MutableSpan::remoteServiceName) .containsOnly("broker", null); } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/MultipleHopsIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/MultipleHopsIntegrationTests.java index 3975d5c91..dc67e774b 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/MultipleHopsIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/multiple/MultipleHopsIntegrationTests.java @@ -28,7 +28,10 @@ import brave.Tracer.SpanInScope; import brave.baggage.BaggageField; import brave.baggage.BaggagePropagationConfig; import brave.baggage.BaggagePropagationConfig.SingleBaggageField; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -37,7 +40,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.servlet.context.ServletWebServerInitializedEvent; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -69,7 +71,7 @@ public class MultipleHopsIntegrationTests { Tracer tracer; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @Autowired RestTemplate restTemplate; @@ -82,7 +84,7 @@ public class MultipleHopsIntegrationTests { @BeforeEach public void setup() { - this.reporter.clear(); + this.spans.clear(); } @Test @@ -91,16 +93,15 @@ public class MultipleHopsIntegrationTests { "http://localhost:" + this.config.port + "/greeting", String.class); await().atMost(5, SECONDS).untilAsserted(() -> { - then(this.reporter.getSpans()).hasSize(14); + then(this.spans).hasSize(14); }); - then(this.reporter.getSpans().stream().map(zipkin2.Span::name).collect(toList())) - .containsAll(asList("get /greeting", "send")); - then(this.reporter.getSpans().stream().map(zipkin2.Span::kind) + then(this.spans).extracting(MutableSpan::name) + .containsAll(asList("GET /greeting", "send")); + then(this.spans).extracting(MutableSpan::kind) // no server kind due to test constraints - .collect(toList())) - .containsAll(asList(zipkin2.Span.Kind.CONSUMER, - zipkin2.Span.Kind.PRODUCER, zipkin2.Span.Kind.SERVER)); - then(this.reporter.getSpans().stream().map(span -> span.tags().get("channel")) + .containsAll( + asList(Span.Kind.CONSUMER, Span.Kind.PRODUCER, Span.Kind.SERVER)); + then(this.spans.spans().stream().map(span -> span.tags().get("channel")) .filter(Objects::nonNull).distinct().collect(toList())).hasSize(3) .containsAll(asList("words", "counts", "greetings")); } @@ -131,10 +132,10 @@ public class MultipleHopsIntegrationTests { } await().atMost(5, SECONDS).untilAsserted(() -> { - then(this.reporter.getSpans()).isNotEmpty(); + then(this.spans).isNotEmpty(); }); - List withBagTags = this.reporter.getSpans().stream() + List withBagTags = this.spans.spans().stream() .filter(s -> s.tags().containsKey(BUSINESS_PROCESS.name())) .collect(toList()); @@ -177,8 +178,8 @@ public class MultipleHopsIntegrationTests { } @Bean - ArrayListSpanReporter arrayListSpanAccumulator() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/opentracing/BraveTracerTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/opentracing/OpenTracingTest.java similarity index 93% rename from spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/opentracing/BraveTracerTest.java rename to spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/opentracing/OpenTracingTest.java index 26cfd89b0..f2dca8a95 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/opentracing/BraveTracerTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/opentracing/OpenTracingTest.java @@ -22,22 +22,22 @@ import java.util.Map; import brave.Span; import brave.Tracer.SpanInScope; import brave.Tracing; +import brave.handler.SpanHandler; import brave.opentracing.BraveSpan; import brave.opentracing.BraveSpanContext; import brave.opentracing.BraveTracer; import brave.propagation.TraceContext; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import io.opentracing.Scope; import io.opentracing.propagation.Format; import io.opentracing.propagation.TextMapAdapter; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import zipkin2.Annotation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -57,10 +57,10 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen */ @SpringBootTest(webEnvironment = NONE, properties = "spring.sleuth.baggage.remote-fields=country-code") -public class BraveTracerTest { +public class OpenTracingTest { @Autowired - ArrayListSpanReporter spans; + TestSpanHandler spans; @Autowired Tracing brave; @@ -144,13 +144,12 @@ public class BraveTracerTest { } void checkSpanReportedToZipkin() { - assertThat(this.spans.getSpans()).first().satisfies(s -> { + assertThat(this.spans).first().satisfies(s -> { assertThat(s.name()).isEqualTo("encode"); - assertThat(s.timestamp()).isEqualTo(1L); - assertThat(s.annotations()) - .containsExactly(Annotation.create(2L, "pump fake")); + assertThat(s.startTimestamp()).isEqualTo(1L); + assertThat(s.annotations()).containsExactly(entry(2L, "pump fake")); assertThat(s.tags()).containsExactly(entry("lc", "codec")); - assertThat(s.duration()).isEqualTo(2L); + assertThat(s.finishTimestamp()).isEqualTo(3L); }); } @@ -251,14 +250,14 @@ public class BraveTracerTest { public void ignoresErrorFalseTag_beforeStart() { this.opentracing.buildSpan("encode").withTag("error", false).start().finish(); - assertThat(this.spans.getSpans().get(0).tags()).isEmpty(); + assertThat(this.spans.get(0).tags()).isEmpty(); } @Test public void ignoresErrorFalseTag_afterStart() { this.opentracing.buildSpan("encode").start().setTag("error", false).finish(); - assertThat(this.spans.getSpans().get(0).tags()).isEmpty(); + assertThat(this.spans.get(0).tags()).isEmpty(); } @BeforeEach @@ -276,8 +275,8 @@ public class BraveTracerTest { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListenerTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListenerTest.java index 8baa51d41..64edae492 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListenerTest.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/quartz/TracingJobListenerTest.java @@ -16,16 +16,17 @@ package org.springframework.cloud.sleuth.instrument.quartz; -import java.util.ArrayDeque; import java.util.HashMap; import java.util.Properties; -import java.util.Queue; import java.util.concurrent.CompletableFuture; import brave.Tracer.SpanInScope; import brave.Tracing; +import brave.handler.MutableSpan; import brave.propagation.Propagation.Setter; import brave.propagation.StrictCurrentTraceContext; +import brave.test.IntegrationTestSpanHandler; +import org.junit.Rule; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -45,7 +46,6 @@ import org.quartz.impl.StdSchedulerFactory; import org.quartz.listeners.JobListenerSupport; import org.quartz.listeners.TriggerListenerSupport; import org.quartz.utils.StringKeyDirtyFlagMap; -import zipkin2.Span; import static org.assertj.core.api.Assertions.assertThat; import static org.quartz.JobBuilder.newJob; @@ -59,6 +59,9 @@ import static org.springframework.cloud.sleuth.instrument.quartz.TracingJobListe */ public class TracingJobListenerTest { + @Rule + public IntegrationTestSpanHandler spanHandler = new IntegrationTestSpanHandler(); + private static final JobKey SUCCESSFUL_JOB_KEY = new JobKey("SuccessfulJob"); private static final JobKey EXCEPTIONAL_JOB_KEY = new JobKey("ExceptionalJob"); @@ -74,9 +77,7 @@ public class TracingJobListenerTest { private StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext .create(); - private Queue spans = new ArrayDeque<>(); - - private Tracing tracing = Tracing.newBuilder().spanReporter(spans::add) + private Tracing tracing = Tracing.newBuilder().addSpanHandler(spanHandler) .currentTraceContext(currentTraceContext).build(); @BeforeEach @@ -124,7 +125,7 @@ public class TracingJobListenerTest { runJob(trigger); // expect - takeSpan(); + spanHandler.takeLocalSpan(); } @Test @@ -138,7 +139,7 @@ public class TracingJobListenerTest { runJob(trigger); // expect - Span span = takeSpan(); + MutableSpan span = spanHandler.takeLocalSpan(); assertThat(span.name()).isEqualToIgnoringCase(SUCCESSFUL_JOB_KEY.toString()); assertThat(span.tags().get(TRIGGER_TAG_KEY)) .isEqualToIgnoringCase(TRIGGER_KEY.toString()); @@ -153,7 +154,7 @@ public class TracingJobListenerTest { runJob(trigger); // expect - takeSpan(); + spanHandler.takeLocalSpan(); } @Test @@ -166,7 +167,7 @@ public class TracingJobListenerTest { runJob(trigger); // expect - takeSpan(); + spanHandler.takeLocalSpan(); } @Test @@ -179,15 +180,13 @@ public class TracingJobListenerTest { // when runJob(trigger); - // expect - requireNoSpan(); + // expect no span } @Test public void should_have_parent_and_child_span_when_trigger_contains_span_info() throws Exception { // given - brave.Span span = tracing.tracer().nextSpan(); JobDataMap data = new JobDataMap(); addSpanToJobData(data); Trigger trigger = newTrigger().forJob(SUCCESSFUL_JOB_KEY).usingJobData(data) @@ -197,8 +196,8 @@ public class TracingJobListenerTest { runJob(trigger); // expect - Span parent = takeSpan(); - Span child = takeSpan(); + MutableSpan parent = spanHandler.takeLocalSpan(); + MutableSpan child = spanHandler.takeLocalSpan(); assertThat(parent.parentId()).isNull(); assertThat(child.parentId()).isEqualTo(parent.id()); } @@ -216,8 +215,8 @@ public class TracingJobListenerTest { runJob(trigger); // expect - Span parent = takeSpan(); - Span child = takeSpan(); + MutableSpan parent = spanHandler.takeLocalSpan(); + MutableSpan child = spanHandler.takeLocalSpan(); assertThat(parent.parentId()).isNull(); assertThat(child.parentId()).isEqualTo(parent.id()); } @@ -239,7 +238,7 @@ public class TracingJobListenerTest { } void addSpanToJobData(JobDataMap data) { - brave.Span span = tracing.tracer().nextSpan(); + brave.Span span = tracing.tracer().nextSpan().start(); try (SpanInScope spanInScope = tracing.tracer().withSpanInScope(span)) { tracing.propagation() .injector((Setter) StringKeyDirtyFlagMap::put) @@ -250,19 +249,6 @@ public class TracingJobListenerTest { } } - Span takeSpan() throws InterruptedException { - Span result = spans.poll(); - assertThat(result).withFailMessage("Span was not reported, but was expected") - .isNotNull(); - return result; - } - - void requireNoSpan() throws InterruptedException { - Span result = spans.poll(); - assertThat(result).withFailMessage("Span was reported, but was not expected") - .isNull(); - } - public static class CompleteableTriggerListener extends CompletableFuture implements TriggerListener, JobListener { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java index 7b5635e00..9dcb70489 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java @@ -16,18 +16,19 @@ package org.springframework.cloud.sleuth.instrument.rpc; +import brave.handler.SpanHandler; import brave.rpc.RpcRequest; import brave.rpc.RpcRuleSampler; import brave.sampler.Matcher; import brave.sampler.RateLimitingSampler; import brave.sampler.Sampler; import brave.sampler.SamplerFunction; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -54,8 +55,8 @@ public class TraceRpcAutoConfigurationIntegrationTests { public static class Config { @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } // tag::custom_rpc_server_sampler[] diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java index 44d995be2..bb0fee980 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/IgnoreAutoConfiguredSkipPatternsIntegrationTests.java @@ -17,7 +17,9 @@ package org.springframework.cloud.sleuth.instrument.web; import brave.Tracer; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -28,7 +30,6 @@ import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.cloud.sleuth.DisableSecurity; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.bind.annotation.GetMapping; @@ -45,7 +46,7 @@ import static org.assertj.core.api.BDDAssertions.then; public class IgnoreAutoConfiguredSkipPatternsIntegrationTests { @Autowired - ArrayListSpanReporter accumulator; + TestSpanHandler spans; @Autowired Tracer tracer; @@ -56,7 +57,7 @@ public class IgnoreAutoConfiguredSkipPatternsIntegrationTests { @BeforeEach @AfterEach public void clearSpans() { - this.accumulator.clear(); + this.spans.clear(); } @Test @@ -66,7 +67,7 @@ public class IgnoreAutoConfiguredSkipPatternsIntegrationTests { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.accumulator.getSpans()).hasSize(1); + then(this.spans).hasSize(1); } @Test @@ -76,7 +77,7 @@ public class IgnoreAutoConfiguredSkipPatternsIntegrationTests { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.accumulator.getSpans()).hasSize(1); + then(this.spans).hasSize(1); } @Test @@ -86,7 +87,7 @@ public class IgnoreAutoConfiguredSkipPatternsIntegrationTests { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.accumulator.getSpans()).hasSize(0); + then(this.spans).hasSize(0); } @EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class) @@ -104,8 +105,8 @@ public class IgnoreAutoConfiguredSkipPatternsIntegrationTests { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java index 683abdcc9..35b8a0306 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithBasePath.java @@ -17,7 +17,9 @@ package org.springframework.cloud.sleuth.instrument.web; import brave.Tracer; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -28,7 +30,6 @@ import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.cloud.sleuth.DisableSecurity; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.bind.annotation.GetMapping; @@ -45,7 +46,7 @@ import static org.assertj.core.api.BDDAssertions.then; public class SkipEndPointsIntegrationTestsWithContextPathWithBasePath { @Autowired - ArrayListSpanReporter accumulator; + TestSpanHandler spans; @Autowired Tracer tracer; @@ -56,7 +57,7 @@ public class SkipEndPointsIntegrationTestsWithContextPathWithBasePath { @BeforeEach @AfterEach public void clearSpans() { - this.accumulator.clear(); + this.spans.clear(); } @Test @@ -66,7 +67,7 @@ public class SkipEndPointsIntegrationTestsWithContextPathWithBasePath { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.accumulator.getSpans()).hasSize(0); + then(this.spans).hasSize(0); } @Test @@ -76,7 +77,7 @@ public class SkipEndPointsIntegrationTestsWithContextPathWithBasePath { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.accumulator.getSpans()).hasSize(1); + then(this.spans).hasSize(1); } @EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class) @@ -90,8 +91,8 @@ public class SkipEndPointsIntegrationTestsWithContextPathWithBasePath { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java index 41b24a38d..c8b5b3250 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath.java @@ -17,7 +17,9 @@ package org.springframework.cloud.sleuth.instrument.web; import brave.Tracer; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -28,7 +30,6 @@ import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.cloud.sleuth.DisableSecurity; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.bind.annotation.GetMapping; @@ -49,7 +50,7 @@ public class SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath { int port; @Autowired - private ArrayListSpanReporter spanReporter; + private TestSpanHandler spans; @Autowired private Tracer tracer; @@ -57,7 +58,7 @@ public class SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath { @BeforeEach @AfterEach public void clearSpans() { - this.spanReporter.clear(); + this.spans.clear(); } @Test @@ -67,7 +68,7 @@ public class SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.spanReporter.getSpans()).hasSize(1); + then(this.spans).hasSize(1); } @Test @@ -77,7 +78,7 @@ public class SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.spanReporter.getSpans()).hasSize(1); + then(this.spans).hasSize(1); } @Test @@ -86,7 +87,7 @@ public class SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath { "http://localhost:" + this.port + "/context-path/health", String.class); then(this.tracer.currentSpan()).isNull(); - then(this.spanReporter.getSpans()).hasSize(0); + then(this.spans).hasSize(0); } @Test @@ -96,7 +97,7 @@ public class SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.spanReporter.getSpans()).hasSize(0); + then(this.spans).hasSize(0); } @EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class) @@ -118,8 +119,8 @@ public class SkipEndPointsIntegrationTestsWithContextPathWithoutBasePath { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java index 9bc90e42c..68a0ba929 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath.java @@ -17,7 +17,9 @@ package org.springframework.cloud.sleuth.instrument.web; import brave.Tracer; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -28,7 +30,6 @@ import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.cloud.sleuth.DisableSecurity; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.bind.annotation.GetMapping; @@ -47,7 +48,7 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath { int port; @Autowired - private ArrayListSpanReporter spanReporter; + private TestSpanHandler spans; @Autowired private Tracer tracer; @@ -55,7 +56,7 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath { @BeforeEach @AfterEach public void clearSpans() { - this.spanReporter.clear(); + this.spans.clear(); } @Test @@ -64,7 +65,7 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.spanReporter.getSpans()).hasSize(1); + then(this.spans).hasSize(1); } @Test @@ -73,7 +74,7 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.spanReporter.getSpans()).hasSize(1); + then(this.spans).hasSize(1); } @Test @@ -82,7 +83,7 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath { "http://localhost:" + this.port + "/actuator/health", String.class); then(this.tracer.currentSpan()).isNull(); - then(this.spanReporter.getSpans()).hasSize(0); + then(this.spans).hasSize(0); } @Test @@ -91,7 +92,7 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath { "http://localhost:" + this.port + "/actuator/metrics?xyz", String.class); then(this.tracer.currentSpan()).isNull(); - then(this.spanReporter.getSpans()).hasSize(0); + then(this.spans).hasSize(0); } @EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class) @@ -113,8 +114,8 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithBasePath { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java index d1c173404..5a049e773 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath.java @@ -17,7 +17,9 @@ package org.springframework.cloud.sleuth.instrument.web; import brave.Tracer; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -28,7 +30,6 @@ import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.server.LocalServerPort; import org.springframework.cloud.sleuth.DisableSecurity; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.bind.annotation.GetMapping; @@ -48,7 +49,7 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath { int port; @Autowired - private ArrayListSpanReporter spanReporter; + private TestSpanHandler spans; @Autowired private Tracer tracer; @@ -56,7 +57,7 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath { @BeforeEach @AfterEach public void clearSpans() { - this.spanReporter.clear(); + this.spans.clear(); } @Test @@ -65,7 +66,7 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.spanReporter.getSpans()).hasSize(1); + then(this.spans).hasSize(1); } @Test @@ -74,7 +75,7 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.spanReporter.getSpans()).hasSize(1); + then(this.spans).hasSize(1); } @Test @@ -83,7 +84,7 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.spanReporter.getSpans()).hasSize(0); + then(this.spans).hasSize(0); } @Test @@ -92,7 +93,7 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath { String.class); then(this.tracer.currentSpan()).isNull(); - then(this.spanReporter.getSpans()).hasSize(0); + then(this.spans).hasSize(0); } @EnableAutoConfiguration(exclude = RabbitAutoConfiguration.class) @@ -114,8 +115,8 @@ public class SkipEndPointsIntegrationTestsWithoutContextPathWithoutBasePath { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java index f3657d089..27fef3797 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterTests.java @@ -31,11 +31,11 @@ import brave.propagation.StrictScopeDecorator; import brave.propagation.ThreadLocalCurrentTraceContext; import brave.sampler.Sampler; import brave.servlet.TracingFilter; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -54,12 +54,12 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder */ public class TraceFilterTests { - ArrayListSpanReporter reporter = new ArrayListSpanReporter(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder() .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder() .addScopeDecorator(StrictScopeDecorator.create()).build()) - .spanReporter(this.reporter).build(); + .addSpanHandler(this.spans).build(); Tracer tracer = this.tracing.tracer(); @@ -102,14 +102,14 @@ public class TraceFilterTests { neverSampleFilter().doFilter(this.request, this.response, this.filterChain); then(Tracing.current().tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); } private Filter neverSampleFilter() { Tracing tracing = Tracing.newBuilder() .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder() .addScopeDecorator(StrictScopeDecorator.create()).build()) - .spanReporter(this.reporter).sampler(Sampler.NEVER_SAMPLE) + .addSpanHandler(this.spans).sampler(Sampler.NEVER_SAMPLE) .supportsJoin(false).build(); HttpTracing httpTracing = HttpTracing.newBuilder(tracing) .clientParser(new HttpClientParser()).serverParser(new HttpServerParser()) @@ -123,8 +123,8 @@ public class TraceFilterTests { public void startsNewTrace() throws Exception { this.filter.doFilter(this.request, this.response, this.filterChain); - then(this.reporter.getSpans()).hasSize(1); - then(this.reporter.getSpans().get(0).tags()).containsEntry("http.path", "/") + then(this.spans).hasSize(1); + then(this.spans.get(0).tags()).containsEntry("http.path", "/") .containsEntry("http.method", HttpMethod.GET.toString()); // we don't check for status_code anymore cause Brave doesn't support it oob // .containsEntry("http.status_code", "200") @@ -137,9 +137,8 @@ public class TraceFilterTests { this.filter.doFilter(this.request, this.response, this.filterChain); then(Tracing.current().tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).hasSize(1); - then(this.reporter.getSpans().get(0).tags()) - .doesNotContainKey("http.status_code"); + then(this.spans).hasSize(1); + then(this.spans.get(0).tags()).doesNotContainKey("http.status_code"); } @Test @@ -151,9 +150,9 @@ public class TraceFilterTests { this.filter.doFilter(this.request, this.response, this.filterChain); then(Tracing.current().tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).hasSize(1); - then(this.reporter.getSpans().get(0).id()).isEqualTo("0000000000000003"); - then(this.reporter.getSpans().get(0).tags()).containsEntry("http.path", "/") + then(this.spans).hasSize(1); + then(this.spans.get(0).id()).isEqualTo("0000000000000003"); + then(this.spans.get(0).tags()).containsEntry("http.path", "/") .containsEntry("http.method", HttpMethod.GET.toString()); } @@ -189,7 +188,7 @@ public class TraceFilterTests { this.filter.doFilter(this.request, this.response, this.filterChain); then(Tracing.current().tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).hasSize(1); + then(this.spans).hasSize(1); } @Test @@ -218,7 +217,7 @@ public class TraceFilterTests { Tracing tracing = Tracing.newBuilder() .currentTraceContext(ThreadLocalCurrentTraceContext.newBuilder() .addScopeDecorator(StrictScopeDecorator.create()).build()) - .spanReporter(this.reporter).supportsJoin(false).build(); + .addSpanHandler(this.spans).supportsJoin(false).build(); HttpTracing httpTracing = HttpTracing.create(tracing); this.request = builder().header("b3", "0000000000000014-000000000000000a") .buildRequest(new MockServletContext()); @@ -227,8 +226,8 @@ public class TraceFilterTests { this.filterChain); then(Tracing.current().tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).hasSize(1); - then(this.reporter.getSpans().get(0).parentId()).isEqualTo("000000000000000a"); + then(this.spans).hasSize(1); + then(this.spans.get(0).parentId()).isEqualTo("000000000000000a"); } @Test @@ -253,8 +252,8 @@ public class TraceFilterTests { then(Tracing.current().tracer().currentSpan()).isNull(); verifyParentSpanHttpTags(); - then(this.reporter.getSpans()).hasSize(1); - then(this.reporter.getSpans().get(0).tags()).containsEntry("error", "Planned"); + then(this.spans).hasSize(1); + then(this.spans.get(0).tags()).containsEntry("error", "Planned"); } @Test @@ -277,7 +276,7 @@ public class TraceFilterTests { this.filter.doFilter(this.request, this.response, this.filterChain); then(Tracing.current().tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).hasSize(1); + then(this.spans).hasSize(1); } @Test @@ -289,7 +288,7 @@ public class TraceFilterTests { this.filter.doFilter(this.request, this.response, this.filterChain); then(Tracing.current().tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).hasSize(1); + then(this.spans).hasSize(1); } @Test @@ -300,7 +299,7 @@ public class TraceFilterTests { this.filter.doFilter(this.request, this.response, this.filterChain); then(Tracing.current().tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).isNotEmpty(); + then(this.spans).isNotEmpty(); then(this.response.getStatus()).isEqualTo(HttpStatus.OK.value()); } @@ -312,7 +311,7 @@ public class TraceFilterTests { this.filter.doFilter(this.request, this.response, this.filterChain); then(Tracing.current().tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).isNotEmpty(); + then(this.spans).isNotEmpty(); then(this.response.getStatus()).isEqualTo(HttpStatus.OK.value()); } @@ -323,7 +322,7 @@ public class TraceFilterTests { neverSampleFilter().doFilter(this.request, this.response, this.filterChain); then(Tracing.current().tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).isNotEmpty(); + then(this.spans).isNotEmpty(); } @SuppressWarnings("Duplicates") @@ -335,7 +334,7 @@ public class TraceFilterTests { neverSampleFilter().doFilter(this.request, this.response, this.filterChain); then(Tracing.current().tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); } // #668 @@ -348,8 +347,8 @@ public class TraceFilterTests { this.filter.doFilter(this.request, this.response, this.filterChain); then(Tracing.current().tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).hasSize(1); - then(this.reporter.getSpans().get(0).tags()).containsEntry("http.path", "/") + then(this.spans).hasSize(1); + then(this.spans.get(0).tags()).containsEntry("http.path", "/") .containsEntry("http.method", HttpMethod.GET.toString()); // we don't check for status_code anymore cause Brave doesn't support it oob // .containsEntry("http.status_code", "295") @@ -362,13 +361,13 @@ public class TraceFilterTests { neverSampleFilter().doFilter(this.request, this.response, this.filterChain); then(Tracing.current().tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).hasSize(1); - then(this.reporter.getSpans().get(0).name()).isEqualTo("get"); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("GET"); } public void verifyParentSpanHttpTags() { - then(this.reporter.getSpans().size()).isGreaterThan(0); - then(this.reporter.getSpans().get(0).tags()).containsEntry("http.path", "/") + then(this.spans).isNotEmpty(); + then(this.spans.get(0).tags()).containsEntry("http.path", "/") .containsEntry("http.method", HttpMethod.GET.toString()); } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceRestTemplateInterceptorTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceRestTemplateInterceptorTests.java index 660971168..c902fe139 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceRestTemplateInterceptorTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceRestTemplateInterceptorTests.java @@ -18,23 +18,23 @@ package org.springframework.cloud.sleuth.instrument.web; import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; import brave.Span; import brave.Tracer; import brave.Tracing; import brave.http.HttpClientParser; +import brave.http.HttpRequestParser; +import brave.http.HttpTags; import brave.http.HttpTracing; import brave.propagation.StrictCurrentTraceContext; import brave.sampler.Sampler; import brave.spring.web.TracingClientHttpRequestInterceptor; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; -import org.springframework.cloud.sleuth.util.SpanUtil; import org.springframework.http.HttpHeaders; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.test.web.client.MockMvcClientHttpRequestFactory; @@ -56,10 +56,10 @@ public class TraceRestTemplateInterceptorTests { StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); - ArrayListSpanReporter reporter = new ArrayListSpanReporter(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) - .spanReporter(this.reporter).build(); + .addSpanHandler(this.spans).build(); Tracer tracer = this.tracing.tracer(); @@ -111,19 +111,19 @@ public class TraceRestTemplateInterceptorTests { } // Default inject format for client spans is B3 multi - then(headers.get("X-B3-TraceId")) - .isEqualTo(SpanUtil.idToHex(span.context().traceId())); - then(headers.get("X-B3-SpanId")) - .isNotEqualTo(SpanUtil.idToHex(span.context().spanId())); - then(headers.get("X-B3-ParentSpanId")) - .isEqualTo(SpanUtil.idToHex(span.context().spanId())); + then(headers.get("X-B3-TraceId")).isEqualTo(span.context().traceIdString()); + then(headers.get("X-B3-SpanId")).isNotEqualTo(span.context().spanIdString()); + then(headers.get("X-B3-ParentSpanId")).isEqualTo(span.context().spanIdString()); } // Issue #290 @Test public void requestHeadersAddedWhenTracing() { setInterceptors(HttpTracing.newBuilder(this.tracing) - .clientParser(new HttpClientParser()).build()); + .clientRequestParser((request, context, span) -> { + HttpTags.URL.tag(request, context, span); + HttpRequestParser.DEFAULT.parse(request, context, span); + }).build()); Span span = this.tracer.nextSpan().name("new trace"); try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span.start())) { @@ -133,17 +133,16 @@ public class TraceRestTemplateInterceptorTests { span.finish(); } - List spans = this.reporter.getSpans(); - then(spans).isNotEmpty(); - then(spans.get(0).tags()).containsEntry("http.path", "/foo") - .containsEntry("http.method", "GET"); + then(this.spans).isNotEmpty(); + then(this.spans.get(0).tags()).containsEntry("http.url", "/foo?a=b") + .containsEntry("http.path", "/foo").containsEntry("http.method", "GET"); } @Test public void notSampledHeaderAddedWhenNotSampled() { this.tracing.close(); this.tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) - .spanReporter(this.reporter).sampler(Sampler.NEVER_SAMPLE).build(); + .addSpanHandler(this.spans).sampler(Sampler.NEVER_SAMPLE).build(); this.template.setInterceptors(Arrays.asList( TracingClientHttpRequestInterceptor.create(HttpTracing.create(tracing)))); @@ -157,7 +156,7 @@ public class TraceRestTemplateInterceptorTests { span.finish(); } - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); } // issue #198 @@ -195,8 +194,7 @@ public class TraceRestTemplateInterceptorTests { span.finish(); } - List spans = this.reporter.getSpans(); - then(spans).hasSize(2); + then(this.spans).hasSize(2); } @RestController diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java index 2278c588d..3af667278 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/ReactorNettyHttpClientSpringBootTests.java @@ -16,17 +16,17 @@ package org.springframework.cloud.sleuth.instrument.web.client; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; - +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; import brave.propagation.B3SinglePropagation; import brave.propagation.CurrentTraceContext; import brave.propagation.CurrentTraceContext.Scope; import brave.propagation.Propagation; import brave.propagation.TraceContext; import brave.sampler.Sampler; +import brave.test.IntegrationTestSpanHandler; import io.netty.handler.codec.http.HttpResponseStatus; +import org.junit.ClassRule; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; @@ -36,8 +36,6 @@ import reactor.netty.http.client.HttpClient; import reactor.netty.http.client.HttpClientResponse; import reactor.netty.http.client.PrematureCloseException; import reactor.netty.http.server.HttpServer; -import zipkin2.Span; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -46,6 +44,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.function.client.WebClient; +import static brave.Span.Kind.CLIENT; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -62,14 +61,14 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; webEnvironment = SpringBootTest.WebEnvironment.NONE) public class ReactorNettyHttpClientSpringBootTests { + @ClassRule + public static IntegrationTestSpanHandler spanHandler = new IntegrationTestSpanHandler(); + DisposableServer disposableServer; @Autowired HttpClient httpClient; - @Autowired - BlockingQueue spans; - @Autowired CurrentTraceContext currentTraceContext; @@ -81,7 +80,6 @@ public class ReactorNettyHttpClientSpringBootTests { if (disposableServer != null) { disposableServer.disposeNow(); } - this.spans.clear(); } @Test @@ -94,12 +92,10 @@ public class ReactorNettyHttpClientSpringBootTests { assertThat(response.status()).isEqualTo(HttpResponseStatus.OK); - Span clientSpan = takeClientSpan(); + MutableSpan clientSpan = spanHandler.takeRemoteSpan(CLIENT); - assertThat(clientSpan.remoteEndpoint()).satisfiesAnyOf( - ep -> assertThat(ep.ipv4()).isNotNull(), - ep -> assertThat(ep.ipv6()).isNotNull()); - assertThat(clientSpan.remoteEndpoint().portAsInt()).isNotZero(); + assertThat(clientSpan.remoteIp()).isNotNull(); + assertThat(clientSpan.remotePort()).isNotZero(); } @Test @@ -116,7 +112,7 @@ public class ReactorNettyHttpClientSpringBootTests { .uri("/").responseContent().aggregate().asString().block(); } - Span clientSpan = takeClientSpan(); + MutableSpan clientSpan = spanHandler.takeRemoteSpan(CLIENT); assertThat(b3SingleHeaderReadByServer).isEqualTo(context.traceIdString() + "-" + clientSpan.id() + "-1-" + context.spanIdString()); @@ -135,14 +131,14 @@ public class ReactorNettyHttpClientSpringBootTests { String b3SingleHeaderReadByServer = request.block(); - Span clientSpan = takeClientSpan(); + MutableSpan clientSpan = spanHandler.takeRemoteSpan(CLIENT); assertThat(b3SingleHeaderReadByServer) .isEqualTo(clientSpan.traceId() + "-" + clientSpan.id() + "-1"); } @Test - public void shouldTagOnRequestError() throws InterruptedException { + public void shouldRecordRequestError() { disposableServer = HttpServer.create().port(0).handle((req, resp) -> { throw new RuntimeException("test"); }).bindNow(); @@ -153,17 +149,7 @@ public class ReactorNettyHttpClientSpringBootTests { assertThatThrownBy(request::block) .hasCauseInstanceOf(PrematureCloseException.class); - Span clientSpan = takeClientSpan(); - - assertThat(clientSpan.tags()).containsKey("error"); - } - - /** Call this to block until a span was reported */ - Span takeClientSpan() throws InterruptedException { - Span result = spans.poll(1, TimeUnit.SECONDS); - assertThat(result).withFailMessage("Span was not reported").isNotNull(); - assertThat(result.kind()).isEqualTo(Span.Kind.CLIENT); - return result; + spanHandler.takeRemoteSpanWithError(CLIENT); } @Configuration @@ -180,17 +166,9 @@ public class ReactorNettyHttpClientSpringBootTests { return Sampler.ALWAYS_SAMPLE; } - /** - * Use a blocking queue as it is simpler than wrapping everything in awaitility - */ @Bean - BlockingQueue spans() { - return new LinkedBlockingQueue<>(); - } - - @Bean - Reporter spanReporter(BlockingQueue spans) { - return spans::add; + SpanHandler testSpanHandler() { + return spanHandler; } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java index cdb5f662d..285f2d268 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRequestHttpHeadersFilterTests.java @@ -22,12 +22,12 @@ import java.util.Collections; import brave.Tracing; import brave.http.HttpTracing; import brave.propagation.StrictCurrentTraceContext; +import brave.test.TestSpanHandler; import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.http.HttpHeaders; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; import org.springframework.mock.web.server.MockServerWebExchange; @@ -37,10 +37,10 @@ public class TraceRequestHttpHeadersFilterTests { StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); - ArrayListSpanReporter reporter = new ArrayListSpanReporter(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) - .spanReporter(this.reporter).build(); + .addSpanHandler(this.spans).build(); HttpTracing httpTracing = HttpTracing.newBuilder(this.tracing).build(); diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilterTests.java index 222d56002..b29e84af0 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilterTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceResponseHttpHeadersFilterTests.java @@ -19,12 +19,12 @@ package org.springframework.cloud.sleuth.instrument.web.client; import brave.Tracing; import brave.http.HttpTracing; import brave.propagation.StrictCurrentTraceContext; +import brave.test.TestSpanHandler; import org.assertj.core.api.BDDAssertions; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.http.HttpHeaders; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; import org.springframework.mock.web.server.MockServerWebExchange; @@ -33,10 +33,10 @@ public class TraceResponseHttpHeadersFilterTests { StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); - ArrayListSpanReporter reporter = new ArrayListSpanReporter(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) - .spanReporter(this.reporter).build(); + .addSpanHandler(this.spans).build(); HttpTracing httpTracing = HttpTracing.newBuilder(this.tracing).build(); @@ -58,7 +58,7 @@ public class TraceResponseHttpHeadersFilterTests { filter.filter(httpHeaders, exchange); - BDDAssertions.then(this.reporter.getSpans()).isEmpty(); + BDDAssertions.then(this.spans).isEmpty(); } @Test @@ -75,7 +75,7 @@ public class TraceResponseHttpHeadersFilterTests { filter.filter(httpHeaders, exchange); - BDDAssertions.then(this.reporter.getSpans()).isNotEmpty(); + BDDAssertions.then(this.spans).isNotEmpty(); } } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java index bf0ab8dcf..76ff5b98f 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceRestTemplateInterceptorIntegrationTests.java @@ -23,9 +23,11 @@ import java.util.Map; import brave.Span; import brave.Tracer; import brave.Tracing; +import brave.handler.MutableSpan; import brave.http.HttpTracing; import brave.propagation.StrictCurrentTraceContext; import brave.spring.web.TracingClientHttpRequestInterceptor; +import brave.test.TestSpanHandler; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.SocketPolicy; @@ -34,7 +36,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; @@ -61,10 +62,10 @@ public class TraceRestTemplateInterceptorIntegrationTests { StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); - ArrayListSpanReporter reporter = new ArrayListSpanReporter(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) - .spanReporter(this.reporter).build(); + .addSpanHandler(this.spans).build(); Tracer tracer = this.tracing.tracer(); @@ -104,10 +105,10 @@ public class TraceRestTemplateInterceptorIntegrationTests { } // 1 span "new race", 1 span "rest template" - BDDAssertions.then(this.reporter.getSpans()).hasSize(2); - zipkin2.Span span1 = this.reporter.getSpans().get(0); - BDDAssertions.then(span1.tags()).containsEntry("error", "Read timed out"); - BDDAssertions.then(span1.kind().ordinal()).isEqualTo(Span.Kind.CLIENT.ordinal()); + BDDAssertions.then(this.spans).hasSize(2); + MutableSpan span1 = this.spans.get(0); + BDDAssertions.then(span1.error()).hasMessage("Read timed out"); + BDDAssertions.then(span1.kind()).isEqualTo(Span.Kind.CLIENT); } private ClientHttpRequestFactory clientHttpRequestFactory() { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/discoveryexception/WebClientDiscoveryExceptionTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/discoveryexception/WebClientDiscoveryExceptionTests.java index 54e068956..281e11a01 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/discoveryexception/WebClientDiscoveryExceptionTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/discoveryexception/WebClientDiscoveryExceptionTests.java @@ -24,12 +24,13 @@ import java.util.Map; import brave.Span; import brave.Tracer; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -42,7 +43,6 @@ import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.ResponseEntity; @@ -72,11 +72,11 @@ public class WebClientDiscoveryExceptionTests { Tracer tracer; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @BeforeEach public void close() { - this.reporter.clear(); + this.spans.clear(); } // issue #240 @@ -94,8 +94,9 @@ public class WebClientDiscoveryExceptionTests { span.finish(); } - List spans = this.reporter.getSpans(); - then(spans.stream().filter(span1 -> span1.kind() == zipkin2.Span.Kind.CLIENT) + // hystrix commands should finish at this point + Thread.sleep(200); + then(this.spans.spans().stream().filter(span1 -> span1.kind() == Span.Kind.CLIENT) .findFirst().get().tags()).containsKey("error"); } @@ -148,8 +149,8 @@ public class WebClientDiscoveryExceptionTests { } @Bean - Reporter mySpanReporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java index 8ea37df44..1126a191d 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exception/WebClientExceptionTests.java @@ -23,7 +23,9 @@ import java.util.stream.Stream; import brave.Span; import brave.Tracer; import brave.Tracing; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.BeforeEach; @@ -38,7 +40,6 @@ import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @@ -69,11 +70,11 @@ public class WebClientExceptionTests { Tracing tracer; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @BeforeEach public void open() { - this.reporter.clear(); + this.spans.clear(); } // issue #198 @@ -96,8 +97,8 @@ public class WebClientExceptionTests { } then(this.tracer.tracer().currentSpan()).isNull(); - then(this.reporter.getSpans()).isNotEmpty(); - then(this.reporter.getSpans().get(0).tags()).containsKey("error"); + then(this.spans).isNotEmpty(); + then(this.spans.get(0).tags()).containsKey("error"); } static Stream parametersForShouldCloseSpanUponException() { @@ -145,8 +146,8 @@ public class WebClientExceptionTests { } @Bean - ArrayListSpanReporter accumulator() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } } diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java index fdf6c1d2a..37cae3b86 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/FeignRetriesTests.java @@ -21,9 +21,11 @@ import java.nio.charset.Charset; import java.util.HashMap; import java.util.concurrent.atomic.AtomicInteger; +import brave.Span; import brave.Tracing; import brave.http.HttpTracing; import brave.propagation.StrictCurrentTraceContext; +import brave.test.TestSpanHandler; import feign.Client; import feign.Feign; import feign.FeignException; @@ -39,10 +41,8 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.BDDMockito; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import zipkin2.Span; import org.springframework.beans.factory.BeanFactory; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; import static org.assertj.core.api.BDDAssertions.then; @@ -70,10 +70,10 @@ public class FeignRetriesTests { StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); - ArrayListSpanReporter reporter = new ArrayListSpanReporter(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) - .spanReporter(this.reporter).build(); + .addSpanHandler(this.spans).build(); HttpTracing httpTracing = HttpTracing.newBuilder(this.tracing).build(); @@ -138,10 +138,8 @@ public class FeignRetriesTests { then(api.decodedPost()).isEqualTo("OK"); // request interception should take place only twice (1st request & 2nd retry) then(atomicInteger.get()).isEqualTo(2); - then(this.reporter.getSpans().get(0).tags()).containsEntry("error", - "IOException"); - then(this.reporter.getSpans().get(1).kind().ordinal()) - .isEqualTo(Span.Kind.CLIENT.ordinal()); + then(this.spans.get(0).error()).isInstanceOf(IOException.class); + then(this.spans.get(1).kind()).isEqualTo(Span.Kind.CLIENT); } interface TestInterface { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClientTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClientTests.java index 82e9153ff..fedac0010 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClientTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/feign/TracingFeignClientTests.java @@ -17,15 +17,14 @@ package org.springframework.cloud.sleuth.instrument.web.client.feign; import java.io.IOException; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import brave.Span; import brave.Tracer; import brave.Tracing; import brave.http.HttpTracing; import brave.propagation.StrictCurrentTraceContext; +import brave.test.TestSpanHandler; import feign.Client; import feign.Request; import feign.RequestTemplate; @@ -59,10 +58,10 @@ public class TracingFeignClientTests { StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); - List spans = new ArrayList<>(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder().currentTraceContext(currentTraceContext) - .spanReporter(spans::add).build(); + .addSpanHandler(spans).build(); Tracer tracer = this.tracing.tracer(); @@ -95,15 +94,15 @@ public class TracingFeignClientTests { span.finish(); } - then(spans.get(0)).extracting("kind.ordinal") - .isEqualTo(Span.Kind.CLIENT.ordinal()); + then(spans.get(0).kind()).isEqualTo(Span.Kind.CLIENT); } @Test public void should_log_error_when_exception_thrown() throws IOException { + RuntimeException error = new RuntimeException("exception has occurred"); Span span = this.tracer.nextSpan().name("foo"); BDDMockito.given(this.client.execute(BDDMockito.any(), BDDMockito.any())) - .willThrow(new RuntimeException("exception has occurred")); + .willThrow(error); try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(span.start())) { this.traceFeignClient.execute(this.request, this.options); @@ -115,9 +114,8 @@ public class TracingFeignClientTests { span.finish(); } - then(this.spans.get(0)).extracting("kind.ordinal") - .isEqualTo(Span.Kind.CLIENT.ordinal()); - then(this.spans.get(0).tags()).containsEntry("error", "exception has occurred"); + then(this.spans.get(0).kind()).isEqualTo(Span.Kind.CLIENT); + then(this.spans.get(0).error()).isSameAs(error); } @Test diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java index 3eb894b6b..0de3372a8 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/integration/WebClientTests.java @@ -16,7 +16,6 @@ package org.springframework.cloud.sleuth.instrument.web.client.integration; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -33,11 +32,14 @@ import brave.Span; import brave.Tracer; import brave.Tracing; import brave.baggage.BaggagePropagation; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; import brave.propagation.B3Propagation; import brave.propagation.B3SingleFormat; import brave.propagation.SamplingFlags; import brave.propagation.TraceContextOrSamplingFlags; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpResponse; @@ -55,8 +57,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; import org.reactivestreams.Subscription; import reactor.core.publisher.BaseSubscriber; -import zipkin2.Annotation; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -75,7 +75,6 @@ import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient; import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @@ -126,7 +125,7 @@ public class WebClientTests { HttpAsyncClientBuilder httpAsyncClientBuilder; // #845 @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @Autowired Tracer tracer; @@ -149,7 +148,7 @@ public class WebClientTests { @AfterEach @BeforeEach public void close() { - this.reporter.clear(); + this.spans.clear(); this.testErrorController.clear(); this.fooController.clear(); } @@ -163,10 +162,9 @@ public class WebClientTests { Awaitility.await().atMost(2, TimeUnit.SECONDS).untilAsserted(() -> { then(getHeader(response, "b3")).isNull(); - List spans = this.reporter.getSpans(); - then(spans).isNotEmpty(); - Optional noTraceSpan = new ArrayList<>(spans).stream() - .filter(span -> "get".equals(span.name()) && !span.tags().isEmpty() + then(this.spans).isNotEmpty(); + Optional noTraceSpan = this.spans.spans().stream() + .filter(span -> "GET".equals(span.name()) && !span.tags().isEmpty() && span.tags().containsKey("http.path")) .findFirst(); then(noTraceSpan.isPresent()).isTrue(); @@ -224,7 +222,7 @@ public class WebClientTests { span.finish(); } - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); then(this.tracer.currentSpan()).isNull(); } @@ -254,7 +252,7 @@ public class WebClientTests { } then(this.tracer.currentSpan()).isNull(); - then(this.reporter.getSpans()).isNotEmpty(); + then(this.spans).isNotEmpty(); } @Test @@ -272,9 +270,9 @@ public class WebClientTests { } then(this.tracer.currentSpan()).isNull(); - then(this.reporter.getSpans()).isNotEmpty().extracting("traceId", String.class) + then(this.spans).isNotEmpty().extracting("traceId", String.class) .containsOnly(span.context().traceIdString()); - then(this.reporter.getSpans()).extracting("kind.name").contains("CLIENT"); + then(this.spans).extracting("kind.name").contains("CLIENT"); } @Test @@ -311,9 +309,9 @@ public class WebClientTests { } then(this.tracer.currentSpan()).isNull(); - then(this.reporter.getSpans()).isNotEmpty().extracting("traceId", String.class) + then(this.spans).isNotEmpty().extracting("traceId", String.class) .containsOnly(span.context().traceIdString()); - then(this.reporter.getSpans()).extracting("kind.name").contains("CLIENT"); + then(this.spans).extracting("kind.name").contains("CLIENT"); } @Test @@ -329,8 +327,7 @@ public class WebClientTests { span.finish(); } then(this.tracer.currentSpan()).isNull(); - then(this.reporter.getSpans()).isNotEmpty().extracting("kind.name") - .contains("CLIENT"); + then(this.spans).isNotEmpty().extracting("kind.name").contains("CLIENT"); } @Test @@ -350,8 +347,7 @@ public class WebClientTests { } then(this.tracer.currentSpan()).isNull(); - then(this.reporter.getSpans()).isNotEmpty().extracting("kind.name") - .contains("CLIENT"); + then(this.spans).isNotEmpty().extracting("kind.name").contains("CLIENT"); } /** @@ -369,18 +365,18 @@ public class WebClientTests { } }); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); } @Test public void shouldRespectSkipPattern() { this.webClient.get().uri("http://localhost:" + this.port + "/skip").retrieve() .bodyToMono(String.class).block(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); this.webClient.get().uri("http://localhost:" + this.port + "/doNotSkip") .retrieve().bodyToMono(String.class).block(); - then(this.reporter.getSpans()).isNotEmpty(); + then(this.spans).isNotEmpty(); } static Stream parametersForShouldAttachTraceIdWhenCallingAnotherService() { @@ -404,7 +400,7 @@ public class WebClientTests { } then(this.tracer.currentSpan()).isNull(); - then(this.reporter.getSpans()).isNotEmpty(); + then(this.spans).isNotEmpty(); } static Stream parametersForShouldAttachTraceIdWhenUsingFeignClientWithoutResponseBody() { @@ -425,22 +421,20 @@ public class WebClientTests { } then(this.tracer.currentSpan()).isNull(); - Optional storedSpan = this.reporter.getSpans().stream() + Optional storedSpan = this.spans.spans().stream() .filter(span -> "404".equals(span.tags().get("http.status_code"))) .findFirst(); then(storedSpan.isPresent()).isTrue(); - List spans = this.reporter.getSpans(); - spans.stream().forEach(span -> { + this.spans.spans().stream().forEach(span -> { int initialSize = span.annotations().size(); - int distinctSize = span.annotations().stream().map(Annotation::value) + int distinctSize = span.annotations().stream().map(Map.Entry::getValue) .distinct().collect(Collectors.toList()).size(); log.info("logs " + span.annotations()); then(initialSize).as("there are no duplicate log entries") .isEqualTo(distinctSize); }); - then(this.reporter.getSpans()).isNotEmpty().extracting("kind.name") - .contains("CLIENT"); + then(this.spans).isNotEmpty().extracting("kind.name").contains("CLIENT"); } @Test @@ -466,7 +460,7 @@ public class WebClientTests { } then(this.tracer.currentSpan()).isNull(); then(this.customizer.isExecuted()).isTrue(); - then(this.reporter.getSpans()).extracting("kind.name").contains("CLIENT"); + then(this.spans).extracting("kind.name").contains("CLIENT"); } @Test @@ -563,8 +557,8 @@ public class WebClientTests { } @Bean - Reporter spanReporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/sampler/SamplerAutoConfigurationTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/sampler/SamplerAutoConfigurationTests.java index eea86834d..e6518167e 100644 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/sampler/SamplerAutoConfigurationTests.java +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/sampler/SamplerAutoConfigurationTests.java @@ -140,7 +140,7 @@ public class SamplerAutoConfigurationTests { static class WithSpanHandler { @Bean - SpanHandler spanHandler() { + SpanHandler testSpanHandler() { return new SpanHandler() { @Override public boolean end(TraceContext context, MutableSpan span, Cause cause) { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/BlockingQueueSpanReporterTests.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/BlockingQueueSpanReporterTests.java deleted file mode 100644 index 190388a29..000000000 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/BlockingQueueSpanReporterTests.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2013-2020 the original author or authors. - * - * Licensed 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 - * - * https://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.springframework.cloud.sleuth.util; - -import org.junit.jupiter.api.Test; -import zipkin2.Span; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class BlockingQueueSpanReporterTests { - - Span span1 = Span.newBuilder().traceId("1").id("1").build(); - - Span span2 = Span.newBuilder().traceId("1").id("2").build(); - - BlockingQueueSpanReporter reporter = new BlockingQueueSpanReporter(); - - @Test - void takeSpan_fifo_order() { - reporter.report(span1); - reporter.report(span2); - - assertThat(reporter.takeSpan()).isSameAs(span1); - assertThat(reporter.takeSpan()).isSameAs(span2); - } - - @Test - void assertEmpty() { - reporter.assertEmpty(); - } - - @Test - void assertEmpty_fails_when_not_empty() { - reporter.report(span1); - - assertThatThrownBy(reporter::assertEmpty).isInstanceOf(AssertionError.class) - .hasMessage("Span remaining in queue. Check for redundant reporting!"); - } - -} diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/SpanUtil.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/SpanUtil.java deleted file mode 100644 index fad18d7a3..000000000 --- a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/util/SpanUtil.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2013-2019 the original author or authors. - * - * Licensed 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 - * - * https://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.springframework.cloud.sleuth.util; - -/** - * @author Marcin Grzejszczak - * @since - */ -public final class SpanUtil { - - private SpanUtil() { - throw new IllegalStateException("Can't instantiate a utility class"); - } - - static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f' }; - - // Represents given long id as 16-character lower-hex string - public static String idToHex(long id) { - char[] data = new char[16]; - writeHexLong(data, 0, id); - return new String(data); - } - - // Inspired by {@code okio.Buffer.writeLong} - static void writeHexLong(char[] data, int pos, long v) { - writeHexByte(data, pos + 0, (byte) ((v >>> 56L) & 0xff)); - writeHexByte(data, pos + 2, (byte) ((v >>> 48L) & 0xff)); - writeHexByte(data, pos + 4, (byte) ((v >>> 40L) & 0xff)); - writeHexByte(data, pos + 6, (byte) ((v >>> 32L) & 0xff)); - writeHexByte(data, pos + 8, (byte) ((v >>> 24L) & 0xff)); - writeHexByte(data, pos + 10, (byte) ((v >>> 16L) & 0xff)); - writeHexByte(data, pos + 12, (byte) ((v >>> 8L) & 0xff)); - writeHexByte(data, pos + 14, (byte) (v & 0xff)); - } - - static void writeHexByte(char[] data, int pos, byte b) { - data[pos + 0] = HEX_DIGITS[(b >> 4) & 0xf]; - data[pos + 1] = HEX_DIGITS[b & 0xf]; - } - -} diff --git a/spring-cloud-sleuth-dependencies/pom.xml b/spring-cloud-sleuth-dependencies/pom.xml index 4b0ba8336..04dcec616 100644 --- a/spring-cloud-sleuth-dependencies/pom.xml +++ b/spring-cloud-sleuth-dependencies/pom.xml @@ -31,8 +31,8 @@ spring-cloud-sleuth-dependencies Spring Cloud Sleuth Dependencies - 5.12.1 - 0.37.1 + 5.12.2 + 0.37.2 3.4.1 diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleFeignApplication.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleFeignApplication.java index a5eeb24c3..7b04adf26 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleFeignApplication.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-feign/src/main/java/sample/SampleFeignApplication.java @@ -16,10 +16,11 @@ package sample; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; +import brave.propagation.TraceContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import zipkin2.Span; -import zipkin2.reporter.Reporter; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -43,11 +44,12 @@ public class SampleFeignApplication { // Use this for debugging (or if there is no Zipkin server running on port 9411) @Bean @ConditionalOnProperty(value = "sample.zipkin.enabled", havingValue = "false") - public Reporter spanReporter() { - return new Reporter() { + public SpanHandler spanHandler() { + return new SpanHandler() { @Override - public void report(Span span) { + public boolean end(TraceContext context, MutableSpan span, Cause cause) { logger.info(span); + return true; } }; } diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml index 8fc6abfa9..5ef07808e 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/pom.xml @@ -96,6 +96,11 @@ spring-boot-starter-test test + + io.zipkin.brave + brave-tests + test + org.assertj assertj-core diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanReporter.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanHandler.java similarity index 69% rename from spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanReporter.java rename to spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanHandler.java index f1e27e1e7..a77301e60 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanReporter.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/IntegrationTestZipkinSpanHandler.java @@ -20,26 +20,28 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; +import brave.propagation.TraceContext; import org.apache.commons.logging.Log; -import zipkin2.Span; -import zipkin2.reporter.Reporter; /** * Span Collector that logs spans and adds Spans to a list. * * @author Marcin Grzejszczak */ -public class IntegrationTestZipkinSpanReporter implements Reporter { +public class IntegrationTestZipkinSpanHandler extends SpanHandler { private static final Log log = org.apache.commons.logging.LogFactory - .getLog(IntegrationTestZipkinSpanReporter.class); + .getLog(IntegrationTestZipkinSpanHandler.class); - public List hashedSpans = Collections.synchronizedList(new LinkedList<>()); + public List spans = Collections.synchronizedList(new LinkedList<>()); @Override - public void report(Span span) { + public boolean end(TraceContext context, MutableSpan span, Cause cause) { log.debug(span); - this.hashedSpans.add(span); + this.spans.add(span); + return true; } } diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java index 280fe20dd..90448cd8a 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-messaging/src/test/java/integration/MessagingApplicationTests.java @@ -21,6 +21,9 @@ import java.util.Optional; import java.util.Random; import java.util.stream.Collectors; +import brave.Span; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; import brave.sampler.Sampler; import integration.MessagingApplicationTests.IntegrationSpanCollectorConfig; import org.junit.jupiter.api.AfterEach; @@ -28,8 +31,6 @@ import org.junit.jupiter.api.Test; import sample.SampleMessagingApplication; import tools.AbstractIntegrationTest; import tools.SpanUtil; -import zipkin2.Span; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -54,11 +55,11 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { private static String sampleAppUrl = "http://localhost:" + port; @Autowired - IntegrationTestZipkinSpanReporter integrationTestSpanCollector; + IntegrationTestZipkinSpanHandler testSpanHandler; @AfterEach public void cleanup() { - this.integrationTestSpanCollector.hashedSpans.clear(); + this.testSpanHandler.spans.clear(); } @Test @@ -103,18 +104,15 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { } private void thenThereIsAtLeastOneTagWithKey(String key) { - then(this.integrationTestSpanCollector.hashedSpans.stream().map(Span::tags) + then(this.testSpanHandler.spans.stream().map(MutableSpan::tags) .flatMap(m -> m.keySet().stream()).anyMatch(b -> b.equals(key))).isTrue(); } private void thenAllSpansHaveTraceIdEqualTo(long traceId) { String traceIdHex = Long.toHexString(traceId); - log.info( - "Stored spans: [\n" - + this.integrationTestSpanCollector.hashedSpans.stream() - .map(Span::toString).collect(Collectors.joining("\n")) - + "\n]"); - then(this.integrationTestSpanCollector.hashedSpans.stream() + log.info("Stored spans: [\n" + this.testSpanHandler.spans.stream() + .map(MutableSpan::toString).collect(Collectors.joining("\n")) + "\n]"); + then(this.testSpanHandler.spans.stream() .filter(span -> !span.traceId().equals(SpanUtil.idToHex(traceId))) .collect(Collectors.toList())) .describedAs("All spans have same trace id [" + traceIdHex + "]") @@ -122,62 +120,62 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { } private void thenTheSpansHaveProperParentStructure() { - Optional firstHttpSpan = findFirstHttpRequestSpan(); - List eventSpans = findAllEventRelatedSpans(); - Optional eventSentSpan = findSpanWithKind(Span.Kind.SERVER); - Optional producerSpan = findSpanWithKind(Span.Kind.PRODUCER); - Optional lastHttpSpansParent = findLastHttpSpansParent(); + Optional firstHttpSpan = findFirstHttpRequestSpan(); + List eventSpans = findAllEventRelatedSpans(); + Optional eventSentSpan = findSpanWithKind(Span.Kind.SERVER); + Optional producerSpan = findSpanWithKind(Span.Kind.PRODUCER); + Optional lastHttpSpansParent = findLastHttpSpansParent(); // "http:/parent/" -> "message:messages" -> "http:/foo" (CS + CR) -> "http:/foo" // (SS) thenAllSpansArePresent(firstHttpSpan, eventSpans, lastHttpSpansParent, eventSentSpan, producerSpan); - then(this.integrationTestSpanCollector.hashedSpans).as("There were 6 spans") - .hasSize(6); + then(this.testSpanHandler.spans).as("There were 6 spans").hasSize(6); log.info("Checking the parent child structure"); - List> parentChild = this.integrationTestSpanCollector.hashedSpans - .stream().filter(span -> span.parentId() != null) - .map(span -> this.integrationTestSpanCollector.hashedSpans.stream() + List> parentChild = this.testSpanHandler.spans.stream() + .filter(span -> span.parentId() != null) + .map(span -> this.testSpanHandler.spans.stream() .filter(span1 -> span1.id().equals(span.parentId())).findAny()) .collect(Collectors.toList()); log.info("List of parents and children " + parentChild); then(parentChild.stream().allMatch(Optional::isPresent)).isTrue(); } - private Optional findLastHttpSpansParent() { - return this.integrationTestSpanCollector.hashedSpans.stream() - .filter(span -> "get /".equals(span.name()) && span.kind() != null) + private Optional findLastHttpSpansParent() { + return this.testSpanHandler.spans.stream() + .filter(span -> "GET /".equals(span.name()) && span.kind() != null) .findFirst(); } - private Optional findSpanWithKind(Span.Kind kind) { - return this.integrationTestSpanCollector.hashedSpans.stream() + private Optional findSpanWithKind(Span.Kind kind) { + return this.testSpanHandler.spans.stream() .filter(span -> kind.equals(span.kind())).findFirst(); } - private List findAllEventRelatedSpans() { - return this.integrationTestSpanCollector.hashedSpans.stream() + private List findAllEventRelatedSpans() { + return this.testSpanHandler.spans.stream() .filter(span -> "send".equals(span.name()) && span.parentId() != null) .collect(Collectors.toList()); } - private Optional findFirstHttpRequestSpan() { - return this.integrationTestSpanCollector.hashedSpans.stream() + private Optional findFirstHttpRequestSpan() { + return this.testSpanHandler.spans.stream() // home is the name of the method .filter(span -> span.tags().values().stream().anyMatch("home"::equals)) .findFirst(); } - private void thenAllSpansArePresent(Optional firstHttpSpan, - List eventSpans, Optional lastHttpSpan, - Optional eventSentSpan, Optional eventReceivedSpan) { + private void thenAllSpansArePresent(Optional firstHttpSpan, + List eventSpans, Optional lastHttpSpan, + Optional eventSentSpan, + Optional eventReceivedSpan) { log.info("Found following spans"); log.info("First http span " + firstHttpSpan); log.info("Event spans " + eventSpans); log.info("Event sent span " + eventSentSpan); log.info("Event received span " + eventReceivedSpan); log.info("Last http span " + lastHttpSpan); - log.info("All found spans \n" + this.integrationTestSpanCollector.hashedSpans - .stream().map(Span::toString).collect(Collectors.joining("\n"))); + log.info("All found spans \n" + this.testSpanHandler.spans.stream() + .map(MutableSpan::toString).collect(Collectors.joining("\n"))); then(firstHttpSpan.isPresent()).isTrue(); then(eventSpans).isNotEmpty(); then(eventSentSpan.isPresent()).isTrue(); @@ -189,8 +187,8 @@ public class MessagingApplicationTests extends AbstractIntegrationTest { public static class IntegrationSpanCollectorConfig { @Bean - Reporter integrationTestZipkinSpanReporter() { - return new IntegrationTestZipkinSpanReporter(); + SpanHandler testSpanHandler() { + return new IntegrationTestZipkinSpanHandler(); } @Bean diff --git a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleZipkinApplication.java b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleZipkinApplication.java index dd1ae450c..7aa16a024 100644 --- a/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleZipkinApplication.java +++ b/spring-cloud-sleuth-samples/spring-cloud-sleuth-sample-zipkin/src/main/java/sample/SampleZipkinApplication.java @@ -16,8 +16,9 @@ package sample; -import zipkin2.Span; -import zipkin2.reporter.Reporter; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; +import brave.propagation.TraceContext; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -45,8 +46,14 @@ public class SampleZipkinApplication { // Use this for debugging (or if there is no Zipkin server running on port 9411) @Bean @ConditionalOnProperty(value = "sample.zipkin.enabled", havingValue = "false") - public Reporter spanReporter() { - return Reporter.CONSOLE; + public SpanHandler spanHandler() { + return new SpanHandler() { + @Override + public boolean end(TraceContext context, MutableSpan span, Cause cause) { + System.out.println(span.toString()); + return true; + } + }; } } diff --git a/tests/spring-cloud-sleuth-instrumentation-async-tests/pom.xml b/tests/spring-cloud-sleuth-instrumentation-async-tests/pom.xml index ad2995d34..003082667 100644 --- a/tests/spring-cloud-sleuth-instrumentation-async-tests/pom.xml +++ b/tests/spring-cloud-sleuth-instrumentation-async-tests/pom.xml @@ -60,13 +60,13 @@ spring-cloud-starter-sleuth - io.zipkin.brave - brave-tests + org.springframework.boot + spring-boot-starter-test test - org.springframework.boot - spring-boot-starter-test + io.zipkin.brave + brave-tests test diff --git a/tests/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncIntegrationTests.java b/tests/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncIntegrationTests.java index bb4044863..6c500c12d 100644 --- a/tests/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncIntegrationTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-async-tests/src/test/java/org/springframework/cloud/sleuth/instrument/async/TraceAsyncIntegrationTests.java @@ -33,11 +33,13 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.test.annotation.DirtiesContext; import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = { TraceAsyncIntegrationTests.TraceAsyncITestConfiguration.class }) +@DirtiesContext // flakey otherwise public class TraceAsyncIntegrationTests { @ClassRule @@ -54,54 +56,36 @@ public class TraceAsyncIntegrationTests { @Test public void should_set_span_on_an_async_annotated_method() { - asyncLogic.invokeAsync(); + try (Scope ws = currentTraceContext.maybeScope(context)) { + asyncLogic.invokeAsync(); - assertSpan_invokeAsync(takeDesirableSpan()); + MutableSpan span = takeDesirableSpan(); + assertThat(span.name()).isEqualTo("invoke-async"); + assertThat(span.containsAnnotation("@Async")).isTrue(); + assertThat(span.tags()).containsEntry("class", "AsyncLogic") + .containsEntry("method", "invokeAsync"); + + // continues the trace + assertThat(span.traceId()).isEqualTo(context.traceIdString()); + } } @Test public void should_set_span_with_custom_method_on_an_async_annotated_method() { - asyncLogic.invokeAsync_customName(); - - assertSpan_invokeAsync_customName(takeDesirableSpan()); - } - - @Test - public void should_continue_a_span_on_an_async_annotated_method() { - try (Scope ws = currentTraceContext.maybeScope(context)) { - asyncLogic.invokeAsync(); - - MutableSpan span = assertSpan_invokeAsync(takeDesirableSpan()); - assertThat(span.traceId()).isEqualTo(context.traceIdString()); - } - } - - @Test - public void should_continue_a_span_with_custom_method_on_an_async_annotated_method() { try (Scope ws = currentTraceContext.maybeScope(context)) { asyncLogic.invokeAsync_customName(); - MutableSpan span = assertSpan_invokeAsync_customName(takeDesirableSpan()); + MutableSpan span = takeDesirableSpan(); + assertThat(span.name()).isEqualTo("foo"); + assertThat(span.containsAnnotation("@Async")).isTrue(); + assertThat(span.tags()).containsEntry("class", "AsyncLogic") + .containsEntry("method", "invokeAsync_customName"); + + // continues the trace assertThat(span.traceId()).isEqualTo(context.traceIdString()); } } - static MutableSpan assertSpan_invokeAsync_customName(MutableSpan span) { - assertThat(span.name()).isEqualTo("foo"); - assertThat(span.containsAnnotation("@Async")).isTrue(); - assertThat(span.tags()).containsEntry("class", "AsyncLogic") - .containsEntry("method", "invokeAsync_customName"); - return span; - } - - static MutableSpan assertSpan_invokeAsync(MutableSpan span) { - assertThat(span.name()).isEqualTo("invoke-async"); - assertThat(span.containsAnnotation("@Async")).isTrue(); - assertThat(span.tags()).containsEntry("class", "AsyncLogic") - .containsEntry("method", "invokeAsync"); - return span; - } - // Sleuth adds spans named "async" with no tags when an executor is used. // We don't want that one. MutableSpan takeDesirableSpan() { @@ -121,7 +105,7 @@ public class TraceAsyncIntegrationTests { } @Bean - SpanHandler spanHandler() { + SpanHandler testSpanHandler() { return spans; } diff --git a/tests/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml b/tests/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml index 09d22e452..4a22c5dce 100644 --- a/tests/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml +++ b/tests/spring-cloud-sleuth-instrumentation-feign-tests/pom.xml @@ -81,6 +81,11 @@ spring-boot-starter-test test + + io.zipkin.brave + brave-tests + test + org.awaitility awaitility diff --git a/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue1125/ManuallyCreatedLoadBalancerFeignClientTests.java b/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue1125/ManuallyCreatedLoadBalancerFeignClientTests.java index 5606c8931..f53a90f34 100644 --- a/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue1125/ManuallyCreatedLoadBalancerFeignClientTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue1125/ManuallyCreatedLoadBalancerFeignClientTests.java @@ -19,19 +19,18 @@ package org.springframework.cloud.sleuth.instrument.feign.issues.issue1125; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.HashMap; -import java.util.List; +import brave.handler.SpanHandler; import brave.http.HttpRequest; import brave.sampler.Sampler; import brave.sampler.SamplerFunction; +import brave.test.TestSpanHandler; import feign.Client; import feign.Request; import feign.RequestTemplate; import feign.Response; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import zipkin2.Span; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -41,7 +40,6 @@ import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient; import org.springframework.cloud.sleuth.instrument.web.HttpClientSampler; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.annotation.DirtiesContext; @@ -60,14 +58,14 @@ public class ManuallyCreatedLoadBalancerFeignClientTests { AnnotatedFeignClient annotatedFeignClient; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @Autowired MyBlockingClient myClient; @BeforeEach public void open() { - this.reporter.clear(); + this.spans.clear(); } @Test @@ -76,10 +74,9 @@ public class ManuallyCreatedLoadBalancerFeignClientTests { // then(this.myClient.wasCalled()).isTrue(); then(response).isEqualTo("foo"); - List spans = this.reporter.getSpans(); // retries - then(spans).hasSize(1); - then(spans.get(0).tags().get("http.path")).isEqualTo("/test"); + then(this.spans).hasSize(1); + then(this.spans.get(0).tags().get("http.path")).isEqualTo("/test"); } @Test @@ -91,10 +88,9 @@ public class ManuallyCreatedLoadBalancerFeignClientTests { @Test public void span_captured() { this.annotatedFeignClient.get(); - List spans = this.reporter.getSpans(); // retries - then(spans).hasSize(1); - then(spans.get(0).tags().get("http.path")).isEqualTo("/test"); + then(this.spans).hasSize(1); + then(this.spans.get(0).tags().get("http.path")).isEqualTo("/test"); } } @@ -115,8 +111,8 @@ class Application { } @Bean - public Reporter spanReporter() { - return new ArrayListSpanReporter(); + public SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean(name = HttpClientSampler.NAME) diff --git a/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue1125delegates/ManuallyCreatedDelegateLoadBalancerFeignClientTests.java b/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue1125delegates/ManuallyCreatedDelegateLoadBalancerFeignClientTests.java index bc03aef4f..7055a84ba 100644 --- a/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue1125delegates/ManuallyCreatedDelegateLoadBalancerFeignClientTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue1125delegates/ManuallyCreatedDelegateLoadBalancerFeignClientTests.java @@ -18,11 +18,12 @@ package org.springframework.cloud.sleuth.instrument.feign.issues.issue1125delega import java.nio.charset.StandardCharsets; import java.util.HashMap; -import java.util.List; +import brave.handler.SpanHandler; import brave.http.HttpRequest; import brave.sampler.Sampler; import brave.sampler.SamplerFunction; +import brave.test.TestSpanHandler; import feign.Client; import feign.Contract; import feign.Feign; @@ -34,8 +35,6 @@ import feign.codec.Decoder; import feign.codec.Encoder; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import zipkin2.Span; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -43,7 +42,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClientsConfiguration; import org.springframework.cloud.sleuth.instrument.web.HttpClientSampler; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -66,14 +64,14 @@ public class ManuallyCreatedDelegateLoadBalancerFeignClientTests { AnnotatedFeignClient annotatedFeignClient; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @Autowired MyDelegateClient myClient; @BeforeEach public void open() { - this.reporter.clear(); + this.spans.clear(); } @Test @@ -83,10 +81,9 @@ public class ManuallyCreatedDelegateLoadBalancerFeignClientTests { // then(this.myClient.wasCalled()).isTrue(); then(this.myDelegateClient.wasCalled()).isTrue(); then(response).isEqualTo("foo"); - List spans = this.reporter.getSpans(); // retries - then(spans).hasSize(1); - then(spans.get(0).tags().get("http.path")).isEqualTo("/test"); + then(this.spans).hasSize(1); + then(this.spans.get(0).tags().get("http.path")).isEqualTo("/test"); } @Test @@ -99,10 +96,9 @@ public class ManuallyCreatedDelegateLoadBalancerFeignClientTests { @Test public void span_captured() { this.annotatedFeignClient.get(); - List spans = this.reporter.getSpans(); // retries - then(spans).hasSize(1); - then(spans.get(0).tags().get("http.path")).isEqualTo("/test"); + then(this.spans).hasSize(1); + then(this.spans.get(0).tags().get("http.path")).isEqualTo("/test"); } } @@ -131,8 +127,8 @@ class Application { } @Bean - public Reporter spanReporter() { - return new ArrayListSpanReporter(); + public SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean(name = HttpClientSampler.NAME) diff --git a/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue362/Issue362Tests.java b/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue362/Issue362Tests.java index eef3b5346..020630202 100644 --- a/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue362/Issue362Tests.java +++ b/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue362/Issue362Tests.java @@ -18,14 +18,15 @@ package org.springframework.cloud.sleuth.instrument.feign.issues.issue362; import java.io.IOException; import java.util.Date; -import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; import brave.Tracing; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import feign.Client; import feign.Logger; import feign.Request; @@ -35,15 +36,12 @@ import feign.Retryer; import feign.codec.ErrorDecoder; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import zipkin2.Span; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; @@ -87,12 +85,12 @@ public class Issue362Tests { Tracing tracer; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @BeforeEach public void setup() { this.feignComponentAsserter.executedComponents.clear(); - this.reporter.clear(); + this.spans.clear(); } @Test @@ -105,9 +103,8 @@ public class Issue362Tests { then(response.getBody()).isEqualTo("I'm OK"); then(this.feignComponentAsserter.executedComponents).containsEntry(Client.class, true); - List spans = this.reporter.getSpans(); - then(spans).hasSize(1); - then(spans.get(0).tags()).containsEntry("http.path", "/service/ok"); + then(this.spans).hasSize(1); + then(this.spans.get(0).tags()).containsEntry("http.path", "/service/ok"); } @Test @@ -124,10 +121,9 @@ public class Issue362Tests { then(this.feignComponentAsserter.executedComponents) .containsEntry(ErrorDecoder.class, true) .containsEntry(Client.class, true); - List spans = this.reporter.getSpans(); // retries - then(spans).hasSize(5); - then(spans.stream().map(span -> span.tags().get("http.status_code")) + then(this.spans).hasSize(5); + then(this.spans.spans().stream().map(span -> span.tags().get("http.status_code")) .collect(Collectors.toList())).containsOnly("409"); } @@ -167,8 +163,8 @@ class Application { } @Bean - public Reporter spanReporter() { - return new ArrayListSpanReporter(); + public SpanHandler testSpanHandler() { + return new TestSpanHandler(); } } diff --git a/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue393/Issue393Tests.java b/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue393/Issue393Tests.java index 9b2657d50..def1a9e21 100644 --- a/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue393/Issue393Tests.java +++ b/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue393/Issue393Tests.java @@ -16,16 +16,15 @@ package org.springframework.cloud.sleuth.instrument.feign.issues.issue393; -import java.util.List; import java.util.stream.Collectors; import brave.Tracing; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import feign.okhttp.OkHttpClient; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import zipkin2.Span; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -33,7 +32,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.FeignClient; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.ResponseEntity; @@ -67,14 +65,14 @@ public class Issue393Tests { RestTemplate template = new RestTemplate(); @Autowired - ArrayListSpanReporter reporter; + Tracing tracer; @Autowired - Tracing tracer; + TestSpanHandler spans; @BeforeEach public void open() { - this.reporter.clear(); + this.spans.clear(); } @Test @@ -84,10 +82,9 @@ public class Issue393Tests { ResponseEntity response = this.template.getForEntity(url, String.class); then(response.getBody()).isEqualTo("mikesarver foo"); - List spans = this.reporter.getSpans(); // retries - then(spans).hasSize(2); - then(spans.stream().map(span -> span.tags().get("http.path")) + then(this.spans).hasSize(2); + then(this.spans.spans().stream().map(span -> span.tags().get("http.path")) .collect(Collectors.toList())).containsOnly("/name/mikesarver"); } @@ -124,8 +121,8 @@ class Application { } @Bean - public Reporter spanReporter() { - return new ArrayListSpanReporter(); + public SpanHandler testSpanHandler() { + return new TestSpanHandler(); } } diff --git a/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue502/Issue502Tests.java b/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue502/Issue502Tests.java index 494c856d3..d3c1d5d90 100644 --- a/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue502/Issue502Tests.java +++ b/tests/spring-cloud-sleuth-instrumentation-feign-tests/src/test/java/org/springframework/cloud/sleuth/instrument/feign/issues/issue502/Issue502Tests.java @@ -18,19 +18,18 @@ package org.springframework.cloud.sleuth.instrument.feign.issues.issue502; import java.nio.charset.StandardCharsets; import java.util.HashMap; -import java.util.List; +import brave.handler.SpanHandler; import brave.http.HttpRequest; import brave.sampler.Sampler; import brave.sampler.SamplerFunction; +import brave.test.TestSpanHandler; import feign.Client; import feign.Request; import feign.RequestTemplate; import feign.Response; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import zipkin2.Span; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -38,7 +37,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.sleuth.instrument.web.HttpClientSampler; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.bind.annotation.RequestMapping; @@ -68,11 +66,11 @@ public class Issue502Tests { MyNameRemote myNameRemote; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @BeforeEach public void open() { - this.reporter.clear(); + this.spans.clear(); } @Test @@ -81,10 +79,9 @@ public class Issue502Tests { then(this.myClient.wasCalled()).isTrue(); then(response).isEqualTo("foo"); - List spans = this.reporter.getSpans(); // retries - then(spans).hasSize(1); - then(spans.get(0).tags().get("http.path")).isEqualTo(""); + then(this.spans).hasSize(1); + then(this.spans.get(0).tags().get("http.path")).isEqualTo(""); } } @@ -105,8 +102,8 @@ class Application { } @Bean - public Reporter spanReporter() { - return new ArrayListSpanReporter(); + public SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean(name = HttpClientSampler.NAME) diff --git a/tests/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml b/tests/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml index eeb77ab11..e3087a265 100644 --- a/tests/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml +++ b/tests/spring-cloud-sleuth-instrumentation-grpc-tests/pom.xml @@ -64,6 +64,11 @@ spring-boot-starter-test test + + io.zipkin.brave + brave-tests + test + org.awaitility awaitility diff --git a/tests/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/GrpcTracingIntegrationTests.java b/tests/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/GrpcTracingIntegrationTests.java index e117eb7df..618d469ea 100644 --- a/tests/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/GrpcTracingIntegrationTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-grpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/grpc/GrpcTracingIntegrationTests.java @@ -19,7 +19,10 @@ package org.springframework.cloud.sleuth.instrument.grpc; import java.util.List; import java.util.concurrent.TimeUnit; +import brave.Span.Kind; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import io.grpc.ClientInterceptor; import io.grpc.ManagedChannel; import io.grpc.ServerBuilder; @@ -31,8 +34,6 @@ import org.lognet.springboot.grpc.GRpcServerBuilderConfigurer; import org.lognet.springboot.grpc.GRpcService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import zipkin2.Span; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -42,7 +43,6 @@ import org.springframework.cloud.sleuth.instrument.grpc.stubs.HelloRequest; import org.springframework.cloud.sleuth.instrument.grpc.stubs.HelloServiceGrpc; import org.springframework.cloud.sleuth.instrument.grpc.stubs.HelloServiceGrpc.HelloServiceBlockingStub; import org.springframework.cloud.sleuth.instrument.grpc.stubs.HelloServiceGrpc.HelloServiceImplBase; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -71,16 +71,16 @@ public class GrpcTracingIntegrationTests { SpringAwareManagedChannelBuilder clientManagedChannelBuilder; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @BeforeEach public void beforeTest() { - this.reporter.clear(); + this.spans.clear(); } @AfterEach public void afterTest() { - this.reporter.clear(); + this.spans.clear(); } @Test @@ -93,10 +93,9 @@ public class GrpcTracingIntegrationTests { assertThat(client.sayHello("Testy McTest Face")) .isEqualTo("Hello Testy McTest Face"); - List spans = this.reporter.getSpans(); - assertThat(spans).hasSize(2); - assertThat(spans.get(0).kind()).isEqualTo(Span.Kind.SERVER); - assertThat(spans.get(1).kind()).isEqualTo(Span.Kind.CLIENT); + assertThat(this.spans).hasSize(2); + assertThat(this.spans.get(0).kind()).isEqualTo(Kind.SERVER); + assertThat(this.spans.get(1).kind()).isEqualTo(Kind.CLIENT); // ManagedChannel does not implement Closeable... inProcessManagedChannel.shutdownNow(); @@ -139,9 +138,8 @@ public class GrpcTracingIntegrationTests { } @Bean - Reporter reporter() { - return new ArrayListSpanReporter(); - + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/tests/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml b/tests/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml index fd7192f67..e1e722482 100644 --- a/tests/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml +++ b/tests/spring-cloud-sleuth-instrumentation-lettuce-tests/pom.xml @@ -64,6 +64,11 @@ spring-boot-starter-test test + + io.zipkin.brave + brave-tests + test + org.awaitility awaitility diff --git a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml index 0e3b682f2..e138f6c16 100644 --- a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml +++ b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/pom.xml @@ -83,6 +83,11 @@ https://www.w3.org/2001/XMLSchema-instance "> + + io.zipkin.brave + brave-tests + test + org.awaitility awaitility diff --git a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/ITTracingChannelInterceptorTests.java b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/ITTracingChannelInterceptorTests.java index 71c87a90b..49aa1b6d3 100644 --- a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/ITTracingChannelInterceptorTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/ITTracingChannelInterceptorTests.java @@ -16,8 +16,6 @@ package org.springframework.cloud.sleuth.instrument.messaging; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -26,7 +24,9 @@ import javax.annotation.PreDestroy; import brave.Span; import brave.Tracer; import brave.Tracing; +import brave.handler.SpanHandler; import brave.propagation.StrictCurrentTraceContext; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -72,6 +72,9 @@ public class ITTracingChannelInterceptorTests implements MessageHandler { @Autowired Tracer tracer; + @Autowired + TestSpanHandler spans; + Message message; Span currentSpan; @@ -140,8 +143,8 @@ public class ITTracingChannelInterceptorTests implements MessageHandler { ExecutorService service = Executors.newSingleThreadExecutor(); @Bean - List spans() { - return new ArrayList<>(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean @@ -152,7 +155,7 @@ public class ITTracingChannelInterceptorTests implements MessageHandler { @Bean Tracing tracing() { return Tracing.newBuilder().currentTraceContext(currentTraceContext()) - .spanReporter(spans()::add).build(); + .addSpanHandler(testSpanHandler()).build(); } @Bean diff --git a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/JmsTracingConfigurationTest.java b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/JmsTracingConfigurationTest.java index 1b896cc70..d6c202a35 100644 --- a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/JmsTracingConfigurationTest.java +++ b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/JmsTracingConfigurationTest.java @@ -18,10 +18,6 @@ package org.springframework.cloud.sleuth.instrument.messaging; import java.util.Arrays; import java.util.List; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.Callable; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; import javax.jms.Connection; import javax.jms.ConnectionFactory; @@ -33,15 +29,18 @@ import javax.jms.XAConnection; import javax.jms.XAConnectionFactory; import javax.resource.spi.ResourceAdapter; +import brave.Span.Kind; import brave.Tracing; +import brave.handler.MutableSpan; import brave.propagation.CurrentTraceContext; import brave.propagation.TraceContext; +import brave.test.IntegrationTestSpanHandler; import org.apache.activemq.ra.ActiveMQActivationSpec; import org.apache.activemq.ra.ActiveMQResourceAdapter; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.junit.ClassRule; import org.junit.jupiter.api.Test; -import zipkin2.Span; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -73,16 +72,15 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class JmsTracingConfigurationTest { + @ClassRule + public static IntegrationTestSpanHandler spanHandler = new IntegrationTestSpanHandler(); + final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withConfiguration(AutoConfigurations.of(JmsTestTracingConfiguration.class, AnnotationJmsListenerConfiguration.class, XAConfiguration.class, SimpleJmsListenerConfiguration.class, JcaJmsListenerConfiguration.class)); - static void clearSpans(AssertableApplicationContext ctx) throws JMSException { - ctx.getBean(JmsTestTracingConfiguration.class).clearSpan(); - } - static void checkConnection(AssertableApplicationContext ctx) throws JMSException { // Not using try-with-resources as that doesn't exist in JMS 1.1 Connection con = ctx.getBean(ConnectionFactory.class).createConnection(); @@ -135,7 +133,6 @@ public class JmsTracingConfigurationTest { @Test public void tracesXAConnectionFactories() { this.contextRunner.withUserConfiguration(XAConfiguration.class).run(ctx -> { - clearSpans(ctx); checkConnection(ctx); checkXAConnection(ctx); }); @@ -144,7 +141,6 @@ public class JmsTracingConfigurationTest { @Test public void tracesTopicConnectionFactories() { this.contextRunner.withUserConfiguration(XAConfiguration.class).run(ctx -> { - clearSpans(ctx); checkConnection(ctx); checkTopicConnection(ctx); }); @@ -154,17 +150,37 @@ public class JmsTracingConfigurationTest { public void tracesListener_jmsMessageListener() { this.contextRunner.withUserConfiguration(SimpleJmsListenerConfiguration.class) .run(ctx -> { - clearSpans(ctx); ctx.getBean(JmsTemplate.class).convertAndSend("myQueue", "foo"); - Callable takeSpan = ctx.getBean("takeSpan", Callable.class); - List trace = Arrays.asList(takeSpan.call(), takeSpan.call(), - takeSpan.call()); + MutableSpan producer = spanHandler.takeRemoteSpan(Kind.PRODUCER); + MutableSpan consumer = spanHandler.takeRemoteSpan(Kind.CONSUMER); + MutableSpan listener = spanHandler.takeLocalSpan(); + + List trace = Arrays.asList(producer, consumer, listener); assertThat(trace).allSatisfy(s -> assertThat(s.traceId()) .isEqualTo(trace.get(0).traceId())); - assertThat(trace).isNotNull().extracting(Span::name).contains("send", - "receive", "on-message"); + assertThat(trace).isNotNull().extracting(MutableSpan::name) + .contains("send", "receive", "on-message"); + }); + } + + @Test + public void tracesListener_annotationMessageListener() { + this.contextRunner.withUserConfiguration(AnnotationJmsListenerConfiguration.class) + .run(ctx -> { + ctx.getBean(JmsTemplate.class).convertAndSend("myQueue", "foo"); + + MutableSpan producer = spanHandler.takeRemoteSpan(Kind.PRODUCER); + MutableSpan consumer = spanHandler.takeRemoteSpan(Kind.CONSUMER); + MutableSpan listener = spanHandler.takeLocalSpan(); + + List trace = Arrays.asList(producer, consumer, listener); + + assertThat(trace).allSatisfy(s -> assertThat(s.traceId()) + .isEqualTo(trace.get(0).traceId())); + assertThat(trace).isNotNull().extracting(MutableSpan::name) + .containsExactlyInAnyOrder("send", "receive", "on-message"); }); } @@ -172,16 +188,17 @@ public class JmsTracingConfigurationTest { public void tracesListener_jcaMessageListener() { this.contextRunner.withUserConfiguration(JcaJmsListenerConfiguration.class) .run(ctx -> { - clearSpans(ctx); ctx.getBean(JmsTemplate.class).convertAndSend("myQueue", "foo"); - Callable takeSpan = ctx.getBean("takeSpan", Callable.class); - List trace = Arrays.asList(takeSpan.call(), takeSpan.call(), - takeSpan.call()); + MutableSpan producer = spanHandler.takeRemoteSpan(Kind.PRODUCER); + MutableSpan consumer = spanHandler.takeRemoteSpan(Kind.CONSUMER); + MutableSpan listener = spanHandler.takeLocalSpan(); + + List trace = Arrays.asList(producer, consumer, listener); assertThat(trace).allSatisfy(s -> assertThat(s.traceId()) .isEqualTo(trace.get(0).traceId())); - assertThat(trace).isNotNull().extracting(Span::name) + assertThat(trace).isNotNull().extracting(MutableSpan::name) .containsExactlyInAnyOrder("send", "receive", "on-message"); }); } @@ -289,41 +306,16 @@ public class JmsTracingConfigurationTest { } -} + @Configuration + @EnableAutoConfiguration(exclude = KafkaAutoConfiguration.class) + static class JmsTestTracingConfiguration { -@Configuration -@EnableAutoConfiguration(exclude = KafkaAutoConfiguration.class) -class JmsTestTracingConfiguration { + @Bean + Tracing tracing(CurrentTraceContext currentTraceContext) { + return Tracing.newBuilder().addSpanHandler(spanHandler) + .currentTraceContext(currentTraceContext).build(); + } - /** - * When testing servers or asynchronous clients, spans are reported on a worker - * thread. In order to read them on the main thread, we use a concurrent queue. As - * some implementations report after a response is sent, we use a blocking queue to - * prevent race conditions in tests. - */ - BlockingQueue spans = new LinkedBlockingQueue<>(); - - void clearSpan() { - this.spans.clear(); - } - - /** - * Call this to block until a span was reported. - * @return span from queue - */ - @Bean - Callable takeSpan() { - return () -> { - Span result = this.spans.poll(3, TimeUnit.SECONDS); - assertThat(result).withFailMessage("Span was not reported").isNotNull(); - return result; - }; - } - - @Bean - Tracing tracing(CurrentTraceContext currentTraceContext) { - return Tracing.newBuilder().spanReporter(spans::add) - .currentTraceContext(currentTraceContext).build(); } } diff --git a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceContextPropagationChannelInterceptorTests.java b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceContextPropagationChannelInterceptorTests.java index 269a45ffa..776d7eac7 100644 --- a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceContextPropagationChannelInterceptorTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceContextPropagationChannelInterceptorTests.java @@ -19,9 +19,11 @@ package org.springframework.cloud.sleuth.instrument.messaging; import brave.Span; import brave.Tracer; import brave.Tracing; +import brave.handler.SpanHandler; import brave.propagation.B3SingleFormat; import brave.propagation.TraceContext; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; @@ -29,8 +31,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.instrument.util.SpanUtil; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.integration.channel.QueueChannel; @@ -56,17 +56,17 @@ public class TraceContextPropagationChannelInterceptorTests { private Tracing tracing; @Autowired - private ArrayListSpanReporter reporter; + private TestSpanHandler spans; @AfterEach public void close() { - this.reporter.clear(); + this.spans.clear(); } @Test public void testSpanPropagation() { Span span = this.tracing.tracer().nextSpan().name("http:testSendMessage").start(); - String expectedSpanId = SpanUtil.idToHex(span.context().spanId()); + String expectedSpanId = span.context().spanIdString(); try (Tracer.SpanInScope ws = this.tracing.tracer().withSpanInScope(span)) { this.channel.send(MessageBuilder.withPayload("hi").build()); @@ -105,8 +105,8 @@ public class TraceContextPropagationChannelInterceptorTests { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } } diff --git a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfigurationTests.java b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfigurationTests.java index 4b5aa526c..7a42733fd 100644 --- a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfigurationTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceMessagingAutoConfigurationTests.java @@ -17,6 +17,7 @@ package org.springframework.cloud.sleuth.instrument.messaging; import brave.Tracer; +import brave.handler.SpanHandler; import brave.kafka.clients.KafkaTracing; import brave.messaging.MessagingRequest; import brave.messaging.MessagingTracing; @@ -24,6 +25,7 @@ import brave.sampler.Sampler; import brave.sampler.SamplerFunction; import brave.sampler.SamplerFunctions; import brave.spring.rabbit.SpringRabbitTracing; +import brave.test.TestSpanHandler; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.producer.Producer; @@ -40,7 +42,6 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.kafka.annotation.KafkaListener; @@ -61,7 +62,7 @@ public class TraceMessagingAutoConfigurationTests { RabbitTemplate rabbitTemplate; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @Autowired TestSleuthRabbitBeanPostProcessor postProcessor; @@ -159,8 +160,8 @@ public class TraceMessagingAutoConfigurationTests { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceStreamChannelInterceptorTests.java b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceStreamChannelInterceptorTests.java index 9c1617d59..54f42ec60 100644 --- a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceStreamChannelInterceptorTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/TraceStreamChannelInterceptorTests.java @@ -19,9 +19,11 @@ package org.springframework.cloud.sleuth.instrument.messaging; import brave.Span; import brave.Tracer; import brave.Tracing; +import brave.handler.SpanHandler; import brave.propagation.B3SingleFormat; import brave.propagation.TraceContext; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; @@ -29,8 +31,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.instrument.util.SpanUtil; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.cloud.stream.binder.test.OutputDestination; import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration; import org.springframework.cloud.stream.function.StreamBridge; @@ -59,17 +59,17 @@ public class TraceStreamChannelInterceptorTests { private StreamBridge streamBridge; @Autowired - private ArrayListSpanReporter reporter; + private TestSpanHandler spans; @AfterEach public void close() { - this.reporter.clear(); + this.spans.clear(); } @Test public void testSpanPropagationViaBridge() { Span span = this.tracing.tracer().nextSpan().name("http:testSendMessage").start(); - String expectedSpanId = SpanUtil.idToHex(span.context().spanId()); + String expectedSpanId = span.context().spanIdString(); try (Tracer.SpanInScope ws = this.tracing.tracer().withSpanInScope(span)) { this.streamBridge.send("testSupplier-out-0", "hi"); @@ -104,8 +104,8 @@ public class TraceStreamChannelInterceptorTests { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } } diff --git a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloSpringIntegration.java b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloSpringIntegration.java index 32b80db76..aa6ae20f8 100644 --- a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloSpringIntegration.java +++ b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/HelloSpringIntegration.java @@ -16,13 +16,14 @@ package org.springframework.cloud.sleuth.instrument.messaging.issues.issue_943; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ImportResource; import org.springframework.integration.config.EnableIntegration; @@ -51,8 +52,8 @@ public class HelloSpringIntegration { } @Bean - ArrayListSpanReporter accumulator() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } } diff --git a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/Issue943Tests.java b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/Issue943Tests.java index 28a929945..7353a6f64 100644 --- a/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/Issue943Tests.java +++ b/tests/spring-cloud-sleuth-instrumentation-messaging-tests/src/test/java/org/springframework/cloud/sleuth/instrument/messaging/issues/issue_943/Issue943Tests.java @@ -20,10 +20,10 @@ import java.util.stream.Collectors; import brave.Span; import brave.Tracer; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.Test; import org.springframework.boot.SpringApplication; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.web.client.RestTemplate; @@ -59,12 +59,11 @@ public class Issue943Tests { } // then - ArrayListSpanReporter accumulator = applicationContext - .getBean(ArrayListSpanReporter.class); + TestSpanHandler spans = applicationContext.getBean(TestSpanHandler.class); then(object).contains("Hellow World Message 1 Persist into DB") .contains("Hellow World Message 2 Persist into DB") .contains("Hellow World Message 3 Persist into DB"); - then(accumulator.getSpans().stream().filter( + then(spans.spans().stream().filter( span -> span.traceId().equals(newSpan.context().traceIdString())) .map(span -> span.tags().getOrDefault("channel", span.tags().get("http.path"))) diff --git a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml index 781237618..3a683ace4 100644 --- a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml +++ b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/pom.xml @@ -69,6 +69,11 @@ spring-boot-starter-test test + + io.zipkin.brave + brave-tests + test + org.awaitility awaitility diff --git a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceAsyncIntegrationTests.java b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceAsyncIntegrationTests.java index 4451503b8..fc2c5d9b0 100644 --- a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceAsyncIntegrationTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceAsyncIntegrationTests.java @@ -21,7 +21,10 @@ import java.util.concurrent.atomic.AtomicReference; import brave.Span; import brave.Tracer; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.awaitility.Awaitility; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -31,7 +34,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.cloud.sleuth.SpanName; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.task.SimpleAsyncTaskExecutor; @@ -52,11 +54,11 @@ public class TraceAsyncIntegrationTests { Tracer tracer; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @BeforeEach public void cleanup() { - this.reporter.clear(); + this.spans.clear(); this.classPerformingAsyncLogic.clear(); } @@ -118,11 +120,11 @@ public class TraceAsyncIntegrationTests { Awaitility.await().atMost(5, SECONDS).untilAsserted(() -> { then(TraceAsyncIntegrationTests.this.classPerformingAsyncLogic.getSpan() .context().traceId()).isEqualTo(span.context().traceId()); - then(this.reporter.getSpans()).hasSize(2); + then(this.spans).hasSize(2); // HTTP - then(this.reporter.getSpans().get(0).name()).isEqualTo("http:existing"); + then(this.spans.get(0).name()).isEqualTo("http:existing"); // ASYNC - then(this.reporter.getSpans().get(1).tags()) + then(this.spans.get(1).tags()) .containsEntry("class", "ClassPerformingAsyncLogic") .containsEntry("method", "invokeAsynchronousLogic"); }); @@ -130,8 +132,8 @@ public class TraceAsyncIntegrationTests { private void thenANewAsyncSpanGetsCreated() { Awaitility.await().atMost(5, SECONDS).untilAsserted(() -> { - then(this.reporter.getSpans()).hasSize(1); - zipkin2.Span storedSpan = this.reporter.getSpans().get(0); + then(this.spans).hasSize(1); + MutableSpan storedSpan = this.spans.get(0); then(storedSpan.name()).isEqualTo("invoke-asynchronous-logic"); then(storedSpan.tags()).containsEntry("class", "ClassPerformingAsyncLogic") .containsEntry("method", "invokeAsynchronousLogic"); @@ -143,11 +145,11 @@ public class TraceAsyncIntegrationTests { Awaitility.await().atMost(5, SECONDS).untilAsserted(() -> { then(TraceAsyncIntegrationTests.this.classPerformingAsyncLogic.getSpan() .context().traceId()).isEqualTo(span.context().traceId()); - then(this.reporter.getSpans()).hasSize(2); + then(this.spans).hasSize(2); // HTTP - then(this.reporter.getSpans().get(0).name()).isEqualTo("http:existing"); + then(this.spans.get(0).name()).isEqualTo("http:existing"); // ASYNC - then(this.reporter.getSpans().get(1).tags()) + then(this.spans.get(1).tags()) .containsEntry("class", "ClassPerformingAsyncLogic") .containsEntry("method", "customNameInvokeAsynchronousLogic"); }); @@ -155,8 +157,8 @@ public class TraceAsyncIntegrationTests { private void thenAsyncSpanHasCustomName() { Awaitility.await().atMost(5, SECONDS).untilAsserted(() -> { - then(this.reporter.getSpans()).hasSize(1); - zipkin2.Span storedSpan = this.reporter.getSpans().get(0); + then(this.spans).hasSize(1); + MutableSpan storedSpan = this.spans.get(0); then(storedSpan.name()).isEqualTo("foo"); then(storedSpan.tags()).containsEntry("class", "ClassPerformingAsyncLogic") .containsEntry("method", "customNameInvokeAsynchronousLogic"); @@ -165,7 +167,7 @@ public class TraceAsyncIntegrationTests { @AfterEach public void cleanTrace() { - this.reporter.clear(); + this.spans.clear(); } @EnableAutoConfiguration @@ -184,8 +186,8 @@ public class TraceAsyncIntegrationTests { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterIntegrationTests.java b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterIntegrationTests.java index 261d00891..5b934084b 100644 --- a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterIntegrationTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterIntegrationTests.java @@ -30,8 +30,11 @@ import javax.servlet.http.HttpServletResponse; import brave.Span; import brave.Tracer; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; import brave.sampler.Sampler; import brave.servlet.TracingFilter; +import brave.test.TestSpanHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.AfterEach; @@ -43,7 +46,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.cloud.sleuth.util.SpanUtil; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -78,7 +80,7 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { MyFilter myFilter; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @Autowired Tracer tracer; @@ -86,15 +88,15 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { @BeforeEach @AfterEach public void clearSpans() { - this.reporter.clear(); + this.spans.clear(); } @Test public void should_create_a_trace() throws Exception { whenSentPingWithoutTracingData(); - then(this.reporter.getSpans()).hasSize(1); - zipkin2.Span span = this.reporter.getSpans().get(0); + then(this.spans).hasSize(1); + MutableSpan span = this.spans.get(0); then(span.tags()).containsKey(TraceWebFilter.MVC_CONTROLLER_CLASS_KEY) .containsKey(TraceWebFilter.MVC_CONTROLLER_METHOD_KEY); then(this.tracer.currentSpan()).isNull(); @@ -108,7 +110,7 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { // https://github.com/spring-cloud/spring-cloud-sleuth/issues/327 // we don't want to respond with any tracing data then(notSampledHeaderIsPresent(mvcResult)).isEqualTo(false); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); then(this.tracer.currentSpan()).isNull(); } @@ -119,7 +121,7 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { whenSentPingWithTraceId(expectedTraceId); - then(this.reporter.getSpans()).hasSize(1); + then(this.spans).hasSize(1); then(this.tracer.currentSpan()).isNull(); } @@ -131,7 +133,7 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { whenSentPingWithTraceId(expectedTraceId); then(MDC.getCopyOfContextMap()).isEmpty(); - then(this.reporter.getSpans()).hasSize(1); + then(this.spans).hasSize(1); then(this.tracer.currentSpan()).isNull(); } @@ -155,7 +157,7 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { this.mockMvc.perform(asyncDispatch(mvcResult)).andExpect(status().isOk()) .andReturn(); - Optional taggedSpan = this.reporter.getSpans().stream() + Optional taggedSpan = this.spans.spans().stream() .filter(span -> span.tags().containsKey("tag")).findFirst(); then(taggedSpan.isPresent()).isTrue(); then(taggedSpan.get().tags()).containsEntry("tag", "value") @@ -172,8 +174,8 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { whenSentToNonExistentEndpointWithTraceId(expectedTraceId); // it's a span with the same ids - then(this.reporter.getSpans()).hasSize(1); - zipkin2.Span serverSpan = this.reporter.getSpans().get(0); + then(this.spans).hasSize(1); + MutableSpan serverSpan = this.spans.get(0); then(serverSpan.tags()).containsEntry("custom", "tag") .containsEntry("http.status_code", "404"); then(this.tracer.currentSpan()).isNull(); @@ -194,8 +196,8 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { // we need to dump the span cause it's not in TracingFilter since TF // has also error dispatch and the ErrorController would report the span - then(this.reporter.getSpans()).hasSize(1); - then(this.reporter.getSpans().get(0).tags()).containsEntry("error", + then(this.spans).hasSize(1); + then(this.spans.get(0).tags()).containsEntry("error", "Request processing failed; nested exception is java.lang.RuntimeException"); } @@ -207,9 +209,8 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { whenSentRequestWithTraceIdAndNoSpanId(expectedTraceId); whenSentRequestWithTraceIdAndNoSpanId(expectedTraceId); - then(this.reporter.getSpans().stream() - .filter(span -> span.id().equals(span.traceId())).findAny().isPresent()) - .as("a root span exists").isTrue(); + then(this.spans.spans().stream().filter(span -> span.id().equals(span.traceId())) + .findAny().isPresent()).as("a root span exists").isTrue(); then(this.tracer.currentSpan()).isNull(); } @@ -222,8 +223,8 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { then(mvcResult.getResponse().getHeader("ZIPKIN-TRACE-ID")) .isEqualTo(SpanUtil.idToHex(expectedTraceId)); - then(this.reporter.getSpans()).hasSize(1); - then(this.reporter.getSpans().get(0).tags()).containsEntry("custom", "tag"); + then(this.spans).hasSize(1); + then(this.spans.get(0).tags()).containsEntry("custom", "tag"); } @Override @@ -310,8 +311,8 @@ public class TraceFilterIntegrationTests extends AbstractMvcIntegrationTest { private static final Log log = LogFactory.getLog(Config.class); @Bean - public ArrayListSpanReporter testSpanReporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterWebIntegrationMultipleFiltersTests.java b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterWebIntegrationMultipleFiltersTests.java index d94612ae0..efc436b4e 100644 --- a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterWebIntegrationMultipleFiltersTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterWebIntegrationMultipleFiltersTests.java @@ -30,7 +30,9 @@ import javax.servlet.ServletResponse; import brave.Span; import brave.Tracing; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -38,7 +40,6 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.servlet.FilterRegistrationBean; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @@ -69,7 +70,7 @@ public class TraceFilterWebIntegrationMultipleFiltersTests { MyFilter myFilter; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; // issue #550 @Autowired @@ -93,7 +94,7 @@ public class TraceFilterWebIntegrationMultipleFiltersTests { then(this.tracer.tracer().currentSpan()).isNull(); then(this.myFilter.getSpan().get()).isNotNull(); - then(this.reporter.getSpans()).isNotEmpty(); + then(this.spans).isNotEmpty(); } private int port() { @@ -152,8 +153,8 @@ public class TraceFilterWebIntegrationMultipleFiltersTests { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } } diff --git a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterWebIntegrationTests.java b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterWebIntegrationTests.java index 10e2ed90a..8d420a8d2 100644 --- a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterWebIntegrationTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceFilterWebIntegrationTests.java @@ -32,22 +32,21 @@ import brave.propagation.CurrentTraceContext.Scope; import brave.propagation.TraceContext; import brave.sampler.Sampler; import brave.sampler.SamplerFunction; +import brave.test.IntegrationTestSpanHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.assertj.core.api.BDDAssertions; -import org.junit.jupiter.api.AfterEach; +import org.junit.ClassRule; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import zipkin2.Span; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.system.CapturedOutput; import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.cloud.sleuth.util.BlockingQueueSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @@ -71,15 +70,15 @@ import static org.assertj.core.api.BDDAssertions.then; @ExtendWith(OutputCaptureExtension.class) public class TraceFilterWebIntegrationTests { + @ClassRule + public static IntegrationTestSpanHandler spanHandler = new IntegrationTestSpanHandler(); + private static final Logger log = LoggerFactory .getLogger(TraceFilterWebIntegrationTests.class); @Autowired CurrentTraceContext currentTraceContext; - @Autowired - BlockingQueueSpanReporter reporter; - @Autowired @HttpServerSampler SamplerFunction sampler; @@ -87,18 +86,13 @@ public class TraceFilterWebIntegrationTests { @Autowired Environment environment; - @AfterEach - public void cleanup() { - this.reporter.assertEmpty(); - } - @Test public void should_tag_url() { new RestTemplate().getForObject("http://localhost:" + port() + "/good", String.class); then(this.currentTraceContext.get()).isNull(); - then(this.reporter.takeSpan().tags()).containsKey("http.url"); + then(spanHandler.takeRemoteSpan(Kind.SERVER).tags()).containsKey("http.url"); } @Test @@ -113,11 +107,11 @@ public class TraceFilterWebIntegrationTests { } then(this.currentTraceContext.get()).isNull(); - Span fromFirstTraceFilterFlow = this.reporter.takeSpan(); + MutableSpan fromFirstTraceFilterFlow = spanHandler.takeRemoteSpanWithErrorTag( + Kind.SERVER, + "Request processing failed; nested exception is java.lang.RuntimeException: Throwing exception"); then(fromFirstTraceFilterFlow.tags()).containsEntry("http.method", "GET") - .containsEntry("mvc.controller.class", "ExceptionThrowingController") - .containsEntry("error", - "Request processing failed; nested exception is java.lang.RuntimeException: Throwing exception"); + .containsEntry("mvc.controller.class", "BasicErrorController"); // Trace IDs in logs: issue#714 String hex = fromFirstTraceFilterFlow.traceId(); thenLogsForExceptionLoggingFilterContainTracingInformation(capture, hex); @@ -144,8 +138,7 @@ public class TraceFilterWebIntegrationTests { } then(this.currentTraceContext.get()).isNull(); - Span span = this.reporter.takeSpan(); - then(span.kind().ordinal()).isEqualTo(Span.Kind.SERVER.ordinal()); + MutableSpan span = spanHandler.takeRemoteSpanWithErrorTag(Kind.SERVER, "400"); then(span.tags()).containsEntry("http.status_code", "400"); then(span.tags()).containsEntry("http.path", "/test_bad_request"); } @@ -177,8 +170,8 @@ public class TraceFilterWebIntegrationTests { } @Bean - BlockingQueueSpanReporter reporter() { - return new BlockingQueueSpanReporter(); + SpanHandler testSpanHandler() { + return spanHandler; } @Bean diff --git a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/RestTemplateTraceAspectIntegrationTests.java b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/RestTemplateTraceAspectIntegrationTests.java index bb23e354b..a839fd82a 100644 --- a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/RestTemplateTraceAspectIntegrationTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/RestTemplateTraceAspectIntegrationTests.java @@ -21,20 +21,22 @@ import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; +import brave.Span; import brave.Tracing; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; import brave.propagation.CurrentTraceContext; import brave.sampler.Sampler; import brave.spring.web.TracingAsyncClientHttpRequestInterceptor; +import brave.test.TestSpanHandler; import org.awaitility.Awaitility; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import zipkin2.Span; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; import org.springframework.core.env.Environment; @@ -80,7 +82,7 @@ public class RestTemplateTraceAspectIntegrationTests { Tracing tracer; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @Autowired RestTemplate restTemplate; @@ -91,7 +93,7 @@ public class RestTemplateTraceAspectIntegrationTests { public void init() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); this.controller.reset(); - this.reporter.clear(); + this.spans.clear(); } @BeforeEach @@ -143,7 +145,7 @@ public class RestTemplateTraceAspectIntegrationTests { whenARequestIsSentToASyncEndpointThatShouldBeFilteredOut(); then(this.currentTraceContext.get()).isNull(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); } private void whenARequestIsSentToAnAsyncRestTemplateEndpoint() throws Exception { @@ -170,7 +172,7 @@ public class RestTemplateTraceAspectIntegrationTests { // Brave was never designed to run tests of server and client in one test // that's why we have to pick only CLIENT side private void thenClientKindIsReported() { - assertThat(this.reporter.getSpans().stream().map(Span::kind) + assertThat(this.spans.spans().stream().map(MutableSpan::kind) .collect(Collectors.toList())).contains(Span.Kind.CLIENT); } @@ -209,8 +211,8 @@ public class RestTemplateTraceAspectIntegrationTests { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } } diff --git a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebAsyncClientAutoConfigurationTests.java b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebAsyncClientAutoConfigurationTests.java index 571b26fa4..59d6b07f0 100644 --- a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebAsyncClientAutoConfigurationTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TraceWebAsyncClientAutoConfigurationTests.java @@ -20,19 +20,21 @@ import java.util.ArrayList; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import brave.Span; import brave.Tracer; import brave.Tracing; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.assertj.core.api.BDDAssertions; import org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import zipkin2.Span; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; @@ -61,14 +63,14 @@ public class TraceWebAsyncClientAutoConfigurationTests { Environment environment; @Autowired - ArrayListSpanReporter accumulator; + TestSpanHandler spans; @Autowired Tracing tracer; @BeforeEach public void setup() { - this.accumulator.clear(); + this.spans.clear(); } @Test @@ -89,17 +91,17 @@ public class TraceWebAsyncClientAutoConfigurationTests { } Awaitility.await().untilAsserted(() -> { - then(this.accumulator.getSpans().stream() + then(this.spans.spans().stream() .filter(span -> Span.Kind.CLIENT == span.kind()).findFirst().get()) - .matches(span -> span.duration() >= TimeUnit.MILLISECONDS - .toMicros(100)); + .matches(span -> span.finishTimestamp() + - span.startTimestamp() >= TimeUnit.MILLISECONDS + .toMicros(100)); then(this.tracer.tracer().currentSpan()).isNull(); }); } @Test - public void should_close_span_upon_failure_callback() - throws ExecutionException, InterruptedException { + public void should_close_span_upon_failure_callback() { ListenableFuture> future; try { future = this.asyncRestTemplate.getForEntity( @@ -111,10 +113,10 @@ public class TraceWebAsyncClientAutoConfigurationTests { } Awaitility.await().untilAsserted(() -> { - Span reportedRpcSpan = new ArrayList<>(this.accumulator.getSpans()).stream() + MutableSpan reportedRpcSpan = new ArrayList<>(this.spans.spans()).stream() .filter(span -> Span.Kind.CLIENT == span.kind()).findFirst().get(); - then(reportedRpcSpan).matches( - span -> span.duration() >= TimeUnit.MILLISECONDS.toMicros(100)); + then(reportedRpcSpan).matches(span -> span.finishTimestamp() + - span.startTimestamp() >= TimeUnit.MILLISECONDS.toMicros(100)); then(reportedRpcSpan.tags()).containsKey("error"); then(this.tracer.tracer().currentSpan()).isNull(); }); @@ -132,8 +134,8 @@ public class TraceWebAsyncClientAutoConfigurationTests { public static class TestConfiguration { @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exceptionresolver/Issue585Tests.java b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exceptionresolver/Issue585Tests.java index 623328967..b459009ce 100644 --- a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exceptionresolver/Issue585Tests.java +++ b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/exceptionresolver/Issue585Tests.java @@ -22,8 +22,10 @@ import javax.servlet.http.HttpServletRequest; import brave.Span; import brave.Tracing; +import brave.handler.SpanHandler; import brave.propagation.CurrentTraceContext; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import com.fasterxml.jackson.annotation.JsonInclude; import org.junit.jupiter.api.Test; import org.slf4j.Logger; @@ -34,7 +36,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -58,7 +59,7 @@ public class Issue585Tests { CurrentTraceContext currentTraceContext; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @LocalServerPort int port; @@ -71,7 +72,7 @@ public class Issue585Tests { then(this.currentTraceContext.get()).isNull(); then(entity.getStatusCode().value()).isEqualTo(500); - then(this.reporter.getSpans().get(0).tags()).containsEntry("custom", "tag") + then(this.spans.get(0).tags()).containsEntry("custom", "tag") .containsKeys("error"); } @@ -81,8 +82,8 @@ public class Issue585Tests { class TestConfig { @Bean - ArrayListSpanReporter testSpanReporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/view/Issue469.java b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/view/Issue469.java index 9310b5657..c1323aaac 100644 --- a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/view/Issue469.java +++ b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/view/Issue469.java @@ -16,10 +16,11 @@ package org.springframework.cloud.sleuth.instrument.web.view; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; @@ -35,8 +36,8 @@ public class Issue469 extends WebMvcConfigurerAdapter { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/view/Issue469Tests.java b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/view/Issue469Tests.java index f1a894d27..d6d0da8f2 100644 --- a/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/view/Issue469Tests.java +++ b/tests/spring-cloud-sleuth-instrumentation-mvc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/view/Issue469Tests.java @@ -16,11 +16,11 @@ package org.springframework.cloud.sleuth.instrument.web.view; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.core.env.Environment; import org.springframework.test.context.TestPropertySource; import org.springframework.web.client.RestTemplate; @@ -34,7 +34,7 @@ import static org.assertj.core.api.BDDAssertions.then; public class Issue469Tests { @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @Autowired Environment environment; @@ -42,8 +42,7 @@ public class Issue469Tests { RestTemplate restTemplate = new RestTemplate(); @Test - public void should_not_result_in_tracing_exceptions_when_using_view_controllers() - throws Exception { + public void should_not_result_in_tracing_exceptions_when_using_view_controllers() { try { this.restTemplate.getForObject("http://localhost:" + port() + "/welcome", String.class); @@ -53,7 +52,7 @@ public class Issue469Tests { then(e).hasMessageContaining("404"); } - then(this.reporter.getSpans()).isNotEmpty(); + then(this.spans).isNotEmpty(); } private int port() { diff --git a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml index fe4a223dd..6ca6a8be1 100644 --- a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml +++ b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/pom.xml @@ -75,6 +75,11 @@ spring-boot-starter-test test + + io.zipkin.brave + brave-tests + test + org.awaitility awaitility diff --git a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/sample/FlatMapTests.java b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/sample/FlatMapTests.java index 174e9aefd..4c88726d7 100644 --- a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/sample/FlatMapTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/reactor/sample/FlatMapTests.java @@ -21,7 +21,10 @@ import java.util.List; import java.util.stream.Collectors; import brave.Tracer; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.awaitility.Awaitility; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -31,7 +34,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import zipkin2.Span; import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -41,7 +43,6 @@ import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.cloud.context.refresh.ContextRefresher; import org.springframework.cloud.sleuth.instrument.reactor.Issue866Configuration; import org.springframework.cloud.sleuth.instrument.reactor.TraceReactorAutoConfigurationAccessorConfiguration; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -114,30 +115,30 @@ public class FlatMapTests { private void assertReactorTracing(ConfigurableApplicationContext context, CapturedOutput capture) { - ArrayListSpanReporter accumulator = context.getBean(ArrayListSpanReporter.class); + TestSpanHandler spans = context.getBean(TestSpanHandler.class); int port = context.getBean(Environment.class).getProperty("local.server.port", Integer.class); RequestSender sender = context.getBean(RequestSender.class); TestConfiguration config = context.getBean(TestConfiguration.class); FactoryUser factoryUser = context.getBean(FactoryUser.class); sender.port = port; - accumulator.clear(); + spans.clear(); Awaitility.await().untilAsserted(() -> { // when LOGGER.info("Start"); - accumulator.clear(); - String firstTraceId = flatMapTraceId(accumulator, callFlatMap(port).block()); + spans.clear(); + String firstTraceId = flatMapTraceId(spans, callFlatMap(port).block()); // then LOGGER.info("Checking first trace id"); thenAllWebClientCallsHaveSameTraceId(firstTraceId, sender); thenSpanInFooHasSameTraceId(firstTraceId, config); - accumulator.clear(); + spans.clear(); LOGGER.info("All web client calls have same trace id"); // when LOGGER.info("Second trace start"); - String secondTraceId = flatMapTraceId(accumulator, callFlatMap(port).block()); + String secondTraceId = flatMapTraceId(spans, callFlatMap(port).block()); // then then(firstTraceId).as("Id will not be reused between calls") .isNotEqualTo(secondTraceId); @@ -174,15 +175,14 @@ public class FlatMapTests { .exchange(); } - private String flatMapTraceId(ArrayListSpanReporter accumulator, - ClientResponse response) { + private String flatMapTraceId(TestSpanHandler spans, ClientResponse response) { then(response.statusCode().value()).isEqualTo(200); - then(accumulator.getSpans()).isNotEmpty(); - LOGGER.info("Accumulated spans: " + accumulator.getSpans()); - List traceIdOfFlatMap = accumulator.getSpans().stream() + then(spans).isNotEmpty(); + LOGGER.info("Accumulated spans: " + spans); + List traceIdOfFlatMap = spans.spans().stream() .filter(span -> span.tags().containsKey("http.path") && span.tags().get("http.path").equals("/withFlatMap")) - .map(Span::traceId).collect(Collectors.toList()); + .map(MutableSpan::traceId).collect(Collectors.toList()); then(traceIdOfFlatMap).hasSize(1); return traceIdOfFlatMap.get(0); } @@ -224,8 +224,8 @@ public class FlatMapTests { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TestHttpCallbackSubscriber.java b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TestHttpCallbackSubscriber.java index 7973eb0db..d25d6d1f0 100644 --- a/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TestHttpCallbackSubscriber.java +++ b/tests/spring-cloud-sleuth-instrumentation-reactor-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/client/TestHttpCallbackSubscriber.java @@ -24,7 +24,6 @@ import reactor.core.CoreSubscriber; import reactor.core.publisher.Mono; import reactor.core.publisher.Operators; import reactor.util.context.Context; -import zipkin2.Callback; /** * {@link #subscribe} is made for reactor-netty and WebFlux client requests used in tests. @@ -32,8 +31,8 @@ import zipkin2.Callback; * signalling, or missing signals. * *

- * The implementation forwards signals to the supplied {@link Callback}, enforcing - * assumptions about a non-empty, {@link Mono} subscription. + * The implementation forwards signals to the supplied {@linkplain BiConsumer callback}, + * enforcing assumptions about a non-empty, {@link Mono} subscription. */ final class TestHttpCallbackSubscriber implements CoreSubscriber { diff --git a/tests/spring-cloud-sleuth-instrumentation-rpc-tests/pom.xml b/tests/spring-cloud-sleuth-instrumentation-rpc-tests/pom.xml index 5b2aa23f0..17b522317 100644 --- a/tests/spring-cloud-sleuth-instrumentation-rpc-tests/pom.xml +++ b/tests/spring-cloud-sleuth-instrumentation-rpc-tests/pom.xml @@ -64,6 +64,11 @@ spring-boot-starter-test test + + io.zipkin.brave + brave-tests + test + org.awaitility awaitility diff --git a/tests/spring-cloud-sleuth-instrumentation-rpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java b/tests/spring-cloud-sleuth-instrumentation-rpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java index 7b5635e00..9dcb70489 100644 --- a/tests/spring-cloud-sleuth-instrumentation-rpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-rpc-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rpc/TraceRpcAutoConfigurationIntegrationTests.java @@ -16,18 +16,19 @@ package org.springframework.cloud.sleuth.instrument.rpc; +import brave.handler.SpanHandler; import brave.rpc.RpcRequest; import brave.rpc.RpcRuleSampler; import brave.sampler.Matcher; import brave.sampler.RateLimitingSampler; import brave.sampler.Sampler; import brave.sampler.SamplerFunction; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -54,8 +55,8 @@ public class TraceRpcAutoConfigurationIntegrationTests { public static class Config { @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } // tag::custom_rpc_server_sampler[] diff --git a/tests/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml b/tests/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml index 779baaa5b..84c1d5c03 100644 --- a/tests/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml +++ b/tests/spring-cloud-sleuth-instrumentation-rxjava-tests/pom.xml @@ -60,6 +60,11 @@ spring-boot-starter-test test + + io.zipkin.brave + brave-tests + test + org.awaitility awaitility diff --git a/tests/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHookTests.java b/tests/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHookTests.java index df8e65801..9a220c6f8 100644 --- a/tests/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHookTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaSchedulersHookTests.java @@ -29,6 +29,7 @@ import java.util.concurrent.ThreadFactory; import brave.Tracer; import brave.Tracing; import brave.propagation.StrictCurrentTraceContext; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -38,8 +39,6 @@ import rx.plugins.RxJavaObservableExecutionHook; import rx.plugins.RxJavaPlugins; import rx.plugins.RxJavaSchedulersHook; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; - import static org.assertj.core.api.BDDAssertions.then; /** @@ -53,17 +52,17 @@ public class SleuthRxJavaSchedulersHookTests { StrictCurrentTraceContext currentTraceContext = StrictCurrentTraceContext.create(); - ArrayListSpanReporter reporter = new ArrayListSpanReporter(); + TestSpanHandler spans = new TestSpanHandler(); Tracing tracing = Tracing.newBuilder().currentTraceContext(this.currentTraceContext) - .spanReporter(this.reporter).build(); + .addSpanHandler(this.spans).build(); Tracer tracer = this.tracing.tracer(); @AfterEach public void clean() { this.tracing.close(); - this.reporter.clear(); + this.spans.clear(); this.currentTraceContext.close(); } @@ -101,7 +100,7 @@ public class SleuthRxJavaSchedulersHookTests { then(action).isInstanceOf(SleuthRxJavaSchedulersHook.TraceAction.class); then(caller.toString()).isEqualTo("called_from_schedulers_hook"); - then(this.reporter.getSpans()).isNotEmpty(); + then(this.spans).isNotEmpty(); then(this.tracer.currentSpan()).isNull(); } @@ -122,7 +121,7 @@ public class SleuthRxJavaSchedulersHookTests { hello.get(); - then(this.reporter.getSpans()).isEmpty(); + then(this.spans).isEmpty(); then(this.tracer.currentSpan()).isNull(); } diff --git a/tests/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaTests.java b/tests/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaTests.java index b4f2a250e..1452f09ab 100644 --- a/tests/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-rxjava-tests/src/test/java/org/springframework/cloud/sleuth/instrument/rxjava/SleuthRxJavaTests.java @@ -18,7 +18,9 @@ package org.springframework.cloud.sleuth.instrument.rxjava; import brave.Span; import brave.Tracer; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -31,7 +33,6 @@ import rx.schedulers.Schedulers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.annotation.DirtiesContext; @@ -45,7 +46,7 @@ import static org.awaitility.Awaitility.await; public class SleuthRxJavaTests { @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @Autowired Tracer tracer; @@ -60,7 +61,7 @@ public class SleuthRxJavaTests { @BeforeEach public void clean() { - this.reporter.clear(); + this.spans.clear(); } @Test @@ -73,11 +74,9 @@ public class SleuthRxJavaTests { then(this.caller.toString()).isEqualTo("actual_action"); then(this.tracer.currentSpan()).isNull(); - await().atMost(5, SECONDS) - .untilAsserted(() -> then(this.reporter.getSpans()).hasSize(1)); - then(this.reporter.getSpans()).hasSize(1); - zipkin2.Span span = this.reporter.getSpans().get(0); - then(span.name()).isEqualTo("rxjava"); + await().atMost(5, SECONDS).untilAsserted(() -> then(this.spans).hasSize(1)); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("rxjava"); } @Test @@ -97,9 +96,8 @@ public class SleuthRxJavaTests { then(this.caller.toString()).isEqualTo("actual_action"); then(this.tracer.currentSpan()).isNull(); // making sure here that no new spans were created or reported as closed - then(this.reporter.getSpans()).hasSize(1); - zipkin2.Span span = this.reporter.getSpans().get(0); - then(span.name()).isEqualTo("current_span"); + then(this.spans).hasSize(1); + then(this.spans.get(0).name()).isEqualTo("current_span"); } @Configuration @@ -112,8 +110,8 @@ public class SleuthRxJavaTests { } @Bean - ArrayListSpanReporter spanReporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } } diff --git a/tests/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml b/tests/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml index a89f7c1df..2f522666d 100644 --- a/tests/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml +++ b/tests/spring-cloud-sleuth-instrumentation-scheduling-tests/pom.xml @@ -60,6 +60,11 @@ spring-boot-starter-test test + + io.zipkin.brave + brave-tests + test + org.awaitility awaitility diff --git a/tests/spring-cloud-sleuth-instrumentation-scheduling-tests/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java b/tests/spring-cloud-sleuth-instrumentation-scheduling-tests/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java index 462a0c786..721cfd400 100644 --- a/tests/spring-cloud-sleuth-instrumentation-scheduling-tests/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-scheduling-tests/src/test/java/org/springframework/cloud/sleuth/instrument/scheduling/TracingOnScheduledTests.java @@ -21,17 +21,18 @@ import java.util.concurrent.atomic.AtomicBoolean; import brave.Span; import brave.Tracing; +import brave.handler.MutableSpan; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import zipkin2.reporter.Reporter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; @@ -56,13 +57,13 @@ public class TracingOnScheduledTests { TestBeanWithScheduledMethodThatThrowsAnException throwsAnException; @Autowired - ArrayListSpanReporter reporter; + TestSpanHandler spans; @BeforeEach public void setup() { this.beanWithScheduledMethod.clear(); this.beanWithScheduledMethodToBeIgnored.clear(); - this.reporter.clear(); + this.spans.clear(); } @Test @@ -104,28 +105,28 @@ public class TracingOnScheduledTests { Span storedSpan = TracingOnScheduledTests.this.beanWithScheduledMethod.getSpan(); then(storedSpan).isNotNull(); then(storedSpan.context().traceId()).isNotNull(); - zipkin2.Span foundSpan = this.reporter.getSpans().stream() + MutableSpan foundSpan = spans.spans().stream() .filter(span -> !span.tags().containsKey("error") && span.tags().containsValue("TestBeanWithScheduledMethod")) .findFirst().orElseThrow(() -> new AssertionError("Span is missing")); then(foundSpan.tags()).contains( new AbstractMap.SimpleEntry<>("class", "TestBeanWithScheduledMethod"), new AbstractMap.SimpleEntry<>("method", "scheduledMethod")); - then(foundSpan.durationAsLong()).isGreaterThan(0L); + then(foundSpan.finishTimestamp()).isGreaterThan(0L); } private void spanIsSetOnAScheduledMethodWithErrorTag() { Span storedSpan = TracingOnScheduledTests.this.beanWithScheduledMethod.getSpan(); then(storedSpan).isNotNull(); then(storedSpan.context().traceId()).isNotNull(); - zipkin2.Span foundSpan = this.reporter.getSpans().stream() + MutableSpan foundSpan = spans.spans().stream() .filter(span -> span.tags().containsKey("error")).findFirst() .orElseThrow(() -> new AssertionError("Span is missing")); then(foundSpan.tags()).contains( new AbstractMap.SimpleEntry<>("class", "TestBeanWithScheduledMethodThatThrowsAnException"), new AbstractMap.SimpleEntry<>("method", "scheduledMethod")); - then(foundSpan.durationAsLong()).isGreaterThan(0L); + then(foundSpan.finishTimestamp()).isGreaterThan(0L); then(foundSpan.tags().get("error")).isNotEmpty(); } @@ -142,8 +143,8 @@ public class TracingOnScheduledTests { class ScheduledTestConfiguration { @Bean - Reporter testRepoter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/tests/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml b/tests/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml index 1deade14f..380caa852 100644 --- a/tests/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml +++ b/tests/spring-cloud-sleuth-instrumentation-webflux-tests/pom.xml @@ -69,6 +69,11 @@ spring-boot-starter-test test + + io.zipkin.brave + brave-tests + test + org.awaitility awaitility diff --git a/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/GH1102Tests.java b/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/GH1102Tests.java index 206e2a862..ffd9b7f49 100644 --- a/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/GH1102Tests.java +++ b/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/GH1102Tests.java @@ -18,7 +18,9 @@ package org.springframework.cloud.sleuth.instrument.web; import brave.ScopedSpan; import brave.Tracer; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.assertj.core.api.BDDAssertions; @@ -30,7 +32,6 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.MultiValueMap; @@ -85,8 +86,8 @@ public class GH1102Tests { } @Bean - ArrayListSpanReporter reporter() { - return new ArrayListSpanReporter(); + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean diff --git a/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxTests.java b/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxTests.java index adbc07863..fa87f7dcf 100644 --- a/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxTests.java +++ b/tests/spring-cloud-sleuth-instrumentation-webflux-tests/src/test/java/org/springframework/cloud/sleuth/instrument/web/TraceWebFluxTests.java @@ -16,12 +16,11 @@ package org.springframework.cloud.sleuth.instrument.web; -import java.util.List; -import java.util.stream.Collectors; - import brave.Span; import brave.Tracer; +import brave.handler.SpanHandler; import brave.sampler.Sampler; +import brave.test.TestSpanHandler; import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; import org.slf4j.Logger; @@ -33,7 +32,6 @@ import reactor.core.publisher.Mono; import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.sleuth.util.ArrayListSpanReporter; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -65,75 +63,69 @@ public class TraceWebFluxTests { "security.basic.enabled=false", "management.security.enabled=false") .run(); - ArrayListSpanReporter accumulator = context.getBean(ArrayListSpanReporter.class); + TestSpanHandler spans = context.getBean(TestSpanHandler.class); int port = context.getBean(Environment.class).getProperty("local.server.port", Integer.class); Controller2 controller2 = context.getBean(Controller2.class); - clean(accumulator, controller2); + clean(spans, controller2); // when ClientResponse response = whenRequestIsSent(port, "/api/c2/10"); // then - thenSpanWasReportedWithTags(accumulator, response); - clean(accumulator, controller2); + thenSpanWasReportedWithTags(spans, response); + clean(spans, controller2); // when response = whenRequestIsSent(port, "/api/fn/20"); // then - thenFunctionalSpanWasReportedWithTags(accumulator, response); - accumulator.clear(); + thenFunctionalSpanWasReportedWithTags(spans, response); + spans.clear(); // when ClientResponse nonSampledResponse = whenNonSampledRequestIsSent(port); // then - thenNoSpanWasReported(accumulator, nonSampledResponse, controller2); - accumulator.clear(); + thenNoSpanWasReported(spans, nonSampledResponse, controller2); + spans.clear(); // when ClientResponse skippedPatternResponse = whenRequestIsSentToSkippedPattern(port); // then - thenNoSpanWasReported(accumulator, skippedPatternResponse, controller2); + thenNoSpanWasReported(spans, skippedPatternResponse, controller2); // cleanup context.close(); } - private void clean(ArrayListSpanReporter accumulator, Controller2 controller2) { - accumulator.clear(); + private void clean(TestSpanHandler spans, Controller2 controller2) { + spans.clear(); controller2.span = null; } - private void thenSpanWasReportedWithTags(ArrayListSpanReporter accumulator, + private void thenSpanWasReportedWithTags(TestSpanHandler spans, ClientResponse response) { Awaitility.await() .untilAsserted(() -> then(response.statusCode().value()).isEqualTo(200)); - List spans = accumulator.getSpans().stream() - .filter(span -> "get /api/c2/{id}".equals(span.name())) - .collect(Collectors.toList()); then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("get /api/c2/{id}"); + then(spans.get(0).name()).isEqualTo("GET /api/c2/{id}"); then(spans.get(0).tags()).containsEntry("mvc.controller.method", "successful") .containsEntry("mvc.controller.class", "Controller2"); } - private void thenFunctionalSpanWasReportedWithTags(ArrayListSpanReporter accumulator, + private void thenFunctionalSpanWasReportedWithTags(TestSpanHandler spans, ClientResponse response) { Awaitility.await() .untilAsserted(() -> then(response.statusCode().value()).isEqualTo(200)); - List spans = accumulator.getSpans().stream() - .filter(span -> "get /api/fn/{id}".equals(span.name())) - .collect(Collectors.toList()); then(spans).hasSize(1); - then(spans.get(0).name()).isEqualTo("get /api/fn/{id}"); + then(spans.get(0).name()).isEqualTo("GET /api/fn/{id}"); then(spans.get(0).tags()).hasEntrySatisfying("mvc.controller.class", value -> then(value).startsWith("TraceWebFluxTests$Config$$Lambda$")); } - private void thenNoSpanWasReported(ArrayListSpanReporter accumulator, - ClientResponse response, Controller2 controller2) { + private void thenNoSpanWasReported(TestSpanHandler spans, ClientResponse response, + Controller2 controller2) { Awaitility.await().untilAsserted(() -> { then(response.statusCode().value()).isEqualTo(200); - then(accumulator.getSpans()).isEmpty(); + then(spans).isEmpty(); }); then(controller2.span).isNotNull(); then(controller2.span.context().traceIdString()).isEqualTo(EXPECTED_TRACE_ID); @@ -176,15 +168,8 @@ public class TraceWebFluxTests { } @Bean - ArrayListSpanReporter spanReporter() { - return new ArrayListSpanReporter() { - @Override - public List getSpans() { - List spans = super.getSpans(); - log.info("Reported the following spans: \n\n" + spans); - return spans; - } - }; + SpanHandler testSpanHandler() { + return new TestSpanHandler(); } @Bean