Skip to content
This repository has been archived by the owner on May 23, 2023. It is now read-only.

Commit

Permalink
Merge branch 'master' into v0.31.0-opentracing
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosalberto committed Dec 18, 2017
2 parents 39036f9 + 84e22d0 commit 012f965
Show file tree
Hide file tree
Showing 8 changed files with 297 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
* <pre><code>
* Tracer tracer = ...
* io.opentracing.propagation.HttpHeaders httpCarrier = new AnHttpHeaderCarrier(httpRequest);
* SpanContext spanCtx = tracer.extract(Format.Builtin.HTTP_HEADERS, httpHeaderReader);
* SpanContext spanCtx = tracer.extract(Format.Builtin.HTTP_HEADERS, httpCarrier);
* </code></pre>
*
* @see Tracer#inject(SpanContext, Format, Object)
Expand Down
76 changes: 71 additions & 5 deletions opentracing-mock/src/main/java/io/opentracing/mock/MockSpan.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
*/
package io.opentracing.mock;

import io.opentracing.References;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;

import io.opentracing.Span;
Expand All @@ -42,6 +44,7 @@ public final class MockSpan implements Span {
private final Map<String, Object> tags;
private final List<LogEntry> logEntries = new ArrayList<>();
private String operationName;
private final List<Reference> references;

private final List<RuntimeException> errors = new ArrayList<>();

Expand All @@ -57,11 +60,10 @@ public MockSpan setOperationName(String operationName) {
}

/**
* TODO: Support multiple parents in this API.
*
* @return the spanId of the Span's parent context, or 0 if no such parent exists.
* @return the spanId of the Span's first {@value References#CHILD_OF} reference, or the first reference of any type, or 0 if no reference exists.
*
* @see MockContext#spanId()
* @see MockSpan#references()
*/
public long parentId() {
return parentId;
Expand Down Expand Up @@ -97,6 +99,10 @@ public List<RuntimeException> generatedErrors() {
return new ArrayList<>(errors);
}

public List<Reference> references() {
return new ArrayList<>(references);
}

@Override
public synchronized MockContext context() {
return this.context;
Expand Down Expand Up @@ -232,7 +238,39 @@ public long timestampMicros() {
}
}

MockSpan(MockTracer tracer, String operationName, long startMicros, Map<String, Object> initialTags, MockContext parent) {
public static final class Reference {
private final MockContext context;
private final String referenceType;

public Reference(MockContext context, String referenceType) {
this.context = context;
this.referenceType = referenceType;
}

public MockContext getContext() {
return context;
}

public String getReferenceType() {
return referenceType;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Reference reference = (Reference) o;
return Objects.equals(context, reference.context) &&
Objects.equals(referenceType, reference.referenceType);
}

@Override
public int hashCode() {
return Objects.hash(context, referenceType);
}
}

MockSpan(MockTracer tracer, String operationName, long startMicros, Map<String, Object> initialTags, List<Reference> refs) {
this.mockTracer = tracer;
this.operationName = operationName;
this.startMicros = startMicros;
Expand All @@ -241,17 +279,45 @@ public long timestampMicros() {
} else {
this.tags = new HashMap<>(initialTags);
}
if(refs == null) {
this.references = Collections.emptyList();
} else {
this.references = new ArrayList<>(refs);
}
MockContext parent = findPreferredParentRef(this.references);
if (parent == null) {
// We're a root Span.
this.context = new MockContext(nextId(), nextId(), new HashMap<String, String>());
this.parentId = 0;
} else {
// We're a child Span.
this.context = new MockContext(parent.traceId, nextId(), parent.baggage);
this.context = new MockContext(parent.traceId, nextId(), mergeBaggages(this.references));
this.parentId = parent.spanId;
}
}

private static MockContext findPreferredParentRef(List<Reference> references) {
if(references.isEmpty()) {
return null;
}
for (Reference reference : references) {
if (References.CHILD_OF.equals(reference.getReferenceType())) {
return reference.getContext();
}
}
return references.get(0).getContext();
}

private static Map<String, String> mergeBaggages(List<Reference> references) {
Map<String, String> baggage = new HashMap<>();
for(Reference ref : references) {
if(ref.getContext().baggage != null) {
baggage.putAll(ref.getContext().baggage);
}
}
return baggage;
}

static long nextId() {
return nextId.addAndGet(1);
}
Expand Down
61 changes: 35 additions & 26 deletions opentracing-mock/src/main/java/io/opentracing/mock/MockTracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,6 @@
*/
package io.opentracing.mock;

import io.opentracing.Scope;
import io.opentracing.ScopeManager;
import io.opentracing.Span;
import io.opentracing.noop.NoopScopeManager;
import io.opentracing.References;
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import io.opentracing.propagation.Binary;
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMap;
import io.opentracing.util.ThreadLocalScopeManager;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
Expand All @@ -36,6 +24,18 @@
import java.util.List;
import java.util.Map;

import io.opentracing.References;
import io.opentracing.Scope;
import io.opentracing.ScopeManager;
import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.Tracer;
import io.opentracing.noop.NoopScopeManager;
import io.opentracing.propagation.Binary;
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMap;
import io.opentracing.util.ThreadLocalScopeManager;

/**
* MockTracer makes it easy to test the semantics of OpenTracing instrumentation.
*
Expand All @@ -45,16 +45,16 @@
* The MockTracerTest has simple usage examples.
*/
public class MockTracer implements Tracer {
private List<MockSpan> finishedSpans = new ArrayList<>();
private final List<MockSpan> finishedSpans = new ArrayList<>();
private final Propagator propagator;
private ScopeManager scopeManager;
private final ScopeManager scopeManager;

public MockTracer() {
this(new ThreadLocalScopeManager(), Propagator.PRINTER);
this(new ThreadLocalScopeManager(), Propagator.TEXT_MAP);
}

public MockTracer(ScopeManager scopeManager) {
this(scopeManager, Propagator.PRINTER);
this(scopeManager, Propagator.TEXT_MAP);
}

public MockTracer(ScopeManager scopeManager, Propagator propagator) {
Expand Down Expand Up @@ -275,10 +275,19 @@ synchronized void appendFinishedSpan(MockSpan mockSpan) {
this.onSpanFinished(mockSpan);
}

private SpanContext activeSpanContext() {
Span span = activeSpan();
if (span == null) {
return null;
}

return span.context();
}

public final class SpanBuilder implements Tracer.SpanBuilder {
private final String operationName;
private long startMicros;
private MockSpan.MockContext firstParent;
private List<MockSpan.Reference> references = new ArrayList<>();
private boolean ignoringActiveSpan;
private Map<String, Object> initialTags = new HashMap<>();

Expand All @@ -293,6 +302,9 @@ public SpanBuilder asChildOf(SpanContext parent) {

@Override
public SpanBuilder asChildOf(Span parent) {
if (parent == null) {
return this;
}
return addReference(References.CHILD_OF, parent.context());
}

Expand All @@ -304,9 +316,8 @@ public SpanBuilder ignoreActiveSpan() {

@Override
public SpanBuilder addReference(String referenceType, SpanContext referencedContext) {
if (firstParent == null && (
referenceType.equals(References.CHILD_OF) || referenceType.equals(References.FOLLOWS_FROM))) {
this.firstParent = (MockSpan.MockContext)referencedContext;
if (referencedContext != null) {
this.references.add(new MockSpan.Reference((MockSpan.MockContext) referencedContext, referenceType));
}
return this;
}
Expand Down Expand Up @@ -350,13 +361,11 @@ public MockSpan startManual() {
if (this.startMicros == 0) {
this.startMicros = MockSpan.nowMicros();
}
if (firstParent == null && !ignoringActiveSpan) {
Scope activeScope = scopeManager().active();
if (activeScope != null) {
firstParent = (MockSpan.MockContext) activeScope.span().context();
}
SpanContext activeSpanContext = activeSpanContext();
if(references.isEmpty() && !ignoringActiveSpan && activeSpanContext != null) {
references.add(new MockSpan.Reference((MockSpan.MockContext) activeSpanContext, References.CHILD_OF));
}
return new MockSpan(MockTracer.this, operationName, startMicros, initialTags, firstParent);
return new MockSpan(MockTracer.this, operationName, startMicros, initialTags, references);
}
}
}
107 changes: 100 additions & 7 deletions opentracing-mock/src/test/java/io/opentracing/mock/MockTracerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,19 @@
package io.opentracing.mock;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Assert;
import org.junit.Test;

import io.opentracing.References;
import io.opentracing.Scope;
import io.opentracing.Span;
import io.opentracing.SpanContext;
Expand All @@ -24,13 +35,6 @@
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMapExtractAdapter;
import io.opentracing.propagation.TextMapInjectAdapter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.Assert;
import org.junit.Test;

public class MockTracerTest {
@Test
Expand Down Expand Up @@ -262,4 +266,93 @@ public void testReset() {
mockTracer.reset();
assertEquals(0, mockTracer.finishedSpans().size());
}

@Test
public void testFollowFromReference() {
MockTracer tracer = new MockTracer(MockTracer.Propagator.TEXT_MAP);
final MockSpan precedent = tracer.buildSpan("precedent").startManual();

final MockSpan followingSpan = tracer.buildSpan("follows")
.addReference(References.FOLLOWS_FROM, precedent.context())
.startManual();

assertEquals(precedent.context().spanId(), followingSpan.parentId());
assertEquals(1, followingSpan.references().size());

final MockSpan.Reference followsFromRef = followingSpan.references().get(0);

assertEquals(new MockSpan.Reference(precedent.context(), References.FOLLOWS_FROM), followsFromRef);
}

@Test
public void testMultiReferences() {
MockTracer tracer = new MockTracer(MockTracer.Propagator.TEXT_MAP);
final MockSpan parent = tracer.buildSpan("parent").startManual();
final MockSpan precedent = tracer.buildSpan("precedent").startManual();

final MockSpan followingSpan = tracer.buildSpan("follows")
.addReference(References.FOLLOWS_FROM, precedent.context())
.asChildOf(parent.context())
.startManual();

assertEquals(parent.context().spanId(), followingSpan.parentId());
assertEquals(2, followingSpan.references().size());

final MockSpan.Reference followsFromRef = followingSpan.references().get(0);
final MockSpan.Reference parentRef = followingSpan.references().get(1);

assertEquals(new MockSpan.Reference(precedent.context(), References.FOLLOWS_FROM), followsFromRef);
assertEquals(new MockSpan.Reference(parent.context(), References.CHILD_OF), parentRef);
}

@Test
public void testMultiReferencesBaggage() {
MockTracer tracer = new MockTracer(MockTracer.Propagator.TEXT_MAP);
final MockSpan parent = tracer.buildSpan("parent").startManual();
parent.setBaggageItem("parent", "foo");
final MockSpan precedent = tracer.buildSpan("precedent").startManual();
precedent.setBaggageItem("precedent", "bar");

final MockSpan followingSpan = tracer.buildSpan("follows")
.addReference(References.FOLLOWS_FROM, precedent.context())
.asChildOf(parent.context())
.startManual();

assertEquals("foo", followingSpan.getBaggageItem("parent"));
assertEquals("bar", followingSpan.getBaggageItem("precedent"));
}

@Test
public void testNonStandardReference() {
MockTracer tracer = new MockTracer(MockTracer.Propagator.TEXT_MAP);
final MockSpan parent = tracer.buildSpan("parent").startManual();

final MockSpan nextSpan = tracer.buildSpan("follows")
.addReference("a_reference", parent.context())
.startManual();

assertEquals(parent.context().spanId(), nextSpan.parentId());
assertEquals(1, nextSpan.references().size());
assertEquals(nextSpan.references().get(0),
new MockSpan.Reference(parent.context(), "a_reference"));
}

@Test
public void testDefaultConstructor() {
MockTracer mockTracer = new MockTracer();
Scope scope = mockTracer.buildSpan("foo").startActive(true);
assertEquals(scope, mockTracer.scopeManager().active());

Map<String, String> propag = new HashMap<>();
mockTracer.inject(scope.span().context(), Format.Builtin.TEXT_MAP, new TextMapInjectAdapter(propag));
assertFalse(propag.isEmpty());
}

@Test
public void testChildOfWithNullParentDoesNotThrowException() {
MockTracer tracer = new MockTracer();
final Span parent = null;
Span span = tracer.buildSpan("foo").asChildOf(parent).start();
span.finish();
}
}
Loading

0 comments on commit 012f965

Please sign in to comment.