From 6ba0b1cb6414765fc9f5d5aa823122b344600107 Mon Sep 17 00:00:00 2001 From: Carlos Alberto Cortez Date: Thu, 17 Aug 2017 18:13:00 +0200 Subject: [PATCH] Add a late-finish Span example. --- .../late_span_finish/TestLateSpanFinish.java | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/test/java/io/opentracing/contrib/examples/late_span_finish/TestLateSpanFinish.java diff --git a/src/test/java/io/opentracing/contrib/examples/late_span_finish/TestLateSpanFinish.java b/src/test/java/io/opentracing/contrib/examples/late_span_finish/TestLateSpanFinish.java new file mode 100644 index 0000000..f99be00 --- /dev/null +++ b/src/test/java/io/opentracing/contrib/examples/late_span_finish/TestLateSpanFinish.java @@ -0,0 +1,79 @@ +package io.opentracing.contrib.examples.late_span_finish; + +import static io.opentracing.contrib.examples.TestUtils.sleep; +import static org.junit.Assert.assertEquals; + +import io.opentracing.ActiveSpan; +import io.opentracing.Span; +import io.opentracing.mock.MockSpan; +import io.opentracing.mock.MockTracer; +import io.opentracing.mock.MockTracer.Propagator; +import io.opentracing.util.ThreadLocalActiveSpanSource; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import org.junit.Test; + +public class TestLateSpanFinish { + + private final MockTracer tracer = new MockTracer(new ThreadLocalActiveSpanSource(), + Propagator.TEXT_MAP); + private final ExecutorService executor = Executors.newCachedThreadPool(); + + @Test + public void test() throws Exception { + /* Create a Span manually and use it as parent of a pair of subtasks */ + Span parentSpan = tracer.buildSpan("parent").startManual(); + submitTasks(parentSpan); + + /* Wait for the threadpool to be done first, instead of polling/waiting */ + executor.shutdown(); + executor.awaitTermination(15, TimeUnit.SECONDS); + + /* Late-finish the parent Span now */ + parentSpan.finish(); + + List spans = tracer.finishedSpans(); + assertEquals(3, spans.size()); + assertEquals("task1", spans.get(0).operationName()); + assertEquals("task2", spans.get(1).operationName()); + assertEquals("parent", spans.get(2).operationName()); + + for (int i = 0; i < 2; i++) { + assertEquals(true, spans.get(2).finishMicros() >= spans.get(i).finishMicros()); + assertEquals(spans.get(2).context().traceId(), spans.get(i).context().traceId()); + assertEquals(spans.get(2).context().spanId(), spans.get(i).parentId()); + } + } + + /* Fire away a few subtasks, passing a parent Span whose lifetime + * is not tied at-all to the children */ + void submitTasks(final Span parentSpan) { + + executor.submit(new Runnable() { + @Override + public void run() { + // Alternative to calling makeActive() is to pass it manually to asChildOf() for each created Span. + try (ActiveSpan span = tracer.makeActive(parentSpan)) { + try (ActiveSpan childSpan1 = tracer.buildSpan("task1").startActive()) { + sleep(55); + } + span.capture(); // Workaround, prevent parentSpan from being finished here. + } + } + }); + + executor.submit(new Runnable() { + @Override + public void run() { + try (ActiveSpan span = tracer.makeActive(parentSpan)) { + try (ActiveSpan childSpan1 = tracer.buildSpan("task2").startActive()) { + sleep(85); + } + span.capture(); // Workaround, prevent parentSpan from being finished here. + } + } + }); + } +}