From c1eb04b68aa3cabfe34fae6699e68d8f29055ac3 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 2 Dec 2015 19:03:24 +0100 Subject: [PATCH] Fixed Travis script for branches Added test to ensure that traces are cleared, added fix for Hystrix commands --- .travis.yml | 2 +- .../instrument/hystrix/TraceCommand.java | 11 ++- .../instrument/hystrix/TraceCommandTest.java | 79 +++++++++++++++++++ 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTest.java diff --git a/.travis.yml b/.travis.yml index 2cb57aecf..b446039a7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ before_install: - gem install asciidoctor install: - ./mvnw install -P docs -q -U -DskipTests=true -Dmaven.test.redirectTestOutputToFile=true -- ./docs/src/main/asciidoc/ghpages.sh +- '[ "${TRAVIS_BRANCH}" != "master" ] || ./docs/src/main/asciidoc/ghpages.sh' script: - '[ "${TRAVIS_PULL_REQUEST}" != "false" ] || ./mvnw -s .settings.xml deploy -nsu -Dmaven.test.redirectTestOutputToFile=true' - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] || ./mvnw install -nsu -Dmaven.test.redirectTestOutputToFile=true' diff --git a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommand.java b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommand.java index 965c13993..3850fc9bd 100644 --- a/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommand.java +++ b/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommand.java @@ -16,6 +16,7 @@ package org.springframework.cloud.sleuth.instrument.hystrix; +import org.springframework.cloud.sleuth.Span; import org.springframework.cloud.sleuth.Trace; import org.springframework.cloud.sleuth.TraceManager; @@ -35,36 +36,42 @@ import com.netflix.hystrix.HystrixThreadPoolKey; */ public abstract class TraceCommand extends HystrixCommand { - private TraceManager traceManager; + private final TraceManager traceManager; + private final Span parentSpan; protected TraceCommand(TraceManager traceManager, HystrixCommandGroupKey group) { super(group); this.traceManager = traceManager; + this.parentSpan = traceManager.getCurrentSpan(); } protected TraceCommand(TraceManager traceManager, HystrixCommandGroupKey group, HystrixThreadPoolKey threadPool) { super(group, threadPool); this.traceManager = traceManager; + this.parentSpan = traceManager.getCurrentSpan(); } protected TraceCommand(TraceManager traceManager, HystrixCommandGroupKey group, int executionIsolationThreadTimeoutInMilliseconds) { super(group, executionIsolationThreadTimeoutInMilliseconds); this.traceManager = traceManager; + this.parentSpan = traceManager.getCurrentSpan(); } protected TraceCommand(TraceManager traceManager, HystrixCommandGroupKey group, HystrixThreadPoolKey threadPool, int executionIsolationThreadTimeoutInMilliseconds) { super(group, threadPool, executionIsolationThreadTimeoutInMilliseconds); this.traceManager = traceManager; + this.parentSpan = traceManager.getCurrentSpan(); } protected TraceCommand(TraceManager traceManager, Setter setter) { super(setter); this.traceManager = traceManager; + this.parentSpan = traceManager.getCurrentSpan(); } @Override protected R run() throws Exception { - Trace trace = this.traceManager.startSpan(getCommandKey().name()); + Trace trace = this.traceManager.startSpan(getCommandKey().name(), parentSpan); try { return doRun(); } finally { diff --git a/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTest.java b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTest.java new file mode 100644 index 000000000..c006080f9 --- /dev/null +++ b/spring-cloud-sleuth-core/src/test/java/org/springframework/cloud/sleuth/instrument/hystrix/TraceCommandTest.java @@ -0,0 +1,79 @@ +package org.springframework.cloud.sleuth.instrument.hystrix; + +import static com.netflix.hystrix.HystrixCommand.Setter.withGroupKey; +import static com.netflix.hystrix.HystrixCommandGroupKey.Factory.asKey; +import static org.assertj.core.api.BDDAssertions.then; + +import org.junit.After; +import org.junit.Test; +import org.mockito.Mockito; +import org.springframework.cloud.sleuth.MilliSpan; +import org.springframework.cloud.sleuth.Trace; +import org.springframework.cloud.sleuth.TraceManager; +import org.springframework.cloud.sleuth.sampler.AlwaysSampler; +import org.springframework.cloud.sleuth.trace.DefaultTraceManager; +import org.springframework.cloud.sleuth.trace.TraceContextHolder; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.util.JdkIdGenerator; + +import com.netflix.hystrix.HystrixCommandKey; +import com.netflix.hystrix.HystrixThreadPoolProperties; + +public class TraceCommandTest { + + static final String EXPECTED_TRACE_ID = "A"; + TraceManager traceManager = new DefaultTraceManager(new AlwaysSampler(), + new JdkIdGenerator(), Mockito.mock(ApplicationEventPublisher.class)); + + @Test + public void should_remove_span_from_thread_local_after_finishing_work() + throws Exception { + Trace firstTraceFromHystrix = givenACommandWasExecuted(traceReturningCommand()); + + Trace secondTraceFromHystrix = whenCommandIsExecuted(traceReturningCommand()); + + then(secondTraceFromHystrix.getSpan().getTraceId()).as("second trace id") + .isNotEqualTo(firstTraceFromHystrix.getSpan().getTraceId()).as("first trace id"); + then(secondTraceFromHystrix.getSavedTrace()).as("saved trace as remnant of first trace") + .isNull(); + } + + @Test + public void should_run_Hystrix_command_with_span_passed_from_parent_thread() { + givenATraceIsPresentInTheCurrentThread(); + TraceCommand command = traceReturningCommand(); + + Trace traceFromCommand = whenCommandIsExecuted(command); + + then(traceFromCommand).as("Trace from the Hystrix Thread").isNotNull(); + then(traceFromCommand.getSpan().getTraceId()).isEqualTo(EXPECTED_TRACE_ID); + } + + @After + public void cleanUpTrace() { + TraceContextHolder.removeCurrentTrace(); + } + + private Trace givenATraceIsPresentInTheCurrentThread() { + return traceManager.startSpan("test", MilliSpan.builder().traceId(EXPECTED_TRACE_ID).build()); + } + + private TraceCommand traceReturningCommand() { + return new TraceCommand(traceManager, withGroupKey(asKey("")) + .andCommandKey(HystrixCommandKey.Factory.asKey("")).andThreadPoolPropertiesDefaults( + HystrixThreadPoolProperties.Setter().withMaxQueueSize(1).withCoreSize(1))) { + @Override + public Trace doRun() throws Exception { + return TraceContextHolder.getCurrentTrace(); + } + }; + } + + private Trace whenCommandIsExecuted(TraceCommand command) { + return command.execute(); + } + + private Trace givenACommandWasExecuted(TraceCommand command) { + return whenCommandIsExecuted(command); + } +} \ No newline at end of file