Skip to content

Commit

Permalink
AbstractInMemorySpanBuilder to respect FOLLOWS_FROM (#1063)
Browse files Browse the repository at this point in the history
Motivation:
OpenTracing semantics defines a FOLLOWS_FROM relationship which is an
alternative means of representing a parent relationship. However
AbstractInMemorySpanBuilder doesn't respect this Reference type and only
recognizes CHILD_OF.

Modifications:
- AbstractInMemorySpanBuilder#parent() should also match References
against FOLLOWS_FROM

Result:
AbstractInMemorySpanBuilder#parent() respects the FOLLOWS_FROM
relationship.
  • Loading branch information
Scottmitch authored May 21, 2020
1 parent 97f0d60 commit 5c38aaa
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 5 deletions.
3 changes: 3 additions & 0 deletions servicetalk-opentracing-inmemory/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ dependencies {
implementation project(":servicetalk-utils-internal")
implementation "com.google.code.findbugs:jsr305:$jsr305Version"
implementation "org.slf4j:slf4j-api:$slf4jVersion"

testImplementation "junit:junit:$junitVersion"
testImplementation "org.mockito:mockito-core:$mockitoCoreVersion"
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import io.servicetalk.opentracing.inmemory.api.InMemorySpanBuilder;
import io.servicetalk.opentracing.inmemory.api.InMemorySpanContext;

import io.opentracing.References;
import io.opentracing.Span;
import io.opentracing.SpanContext;
import io.opentracing.tag.Tags;
Expand All @@ -33,6 +32,8 @@
import java.util.Map;
import javax.annotation.Nullable;

import static io.opentracing.References.CHILD_OF;
import static io.opentracing.References.FOLLOWS_FROM;
import static java.util.Objects.requireNonNull;

abstract class AbstractInMemorySpanBuilder implements InMemorySpanBuilder {
Expand All @@ -52,13 +53,13 @@ protected AbstractInMemorySpanBuilder(String operationName, int maxTagSize) {

@Override
public final InMemorySpanBuilder asChildOf(SpanContext parent) {
addReference(References.CHILD_OF, parent);
addReference(CHILD_OF, parent);
return this;
}

@Override
public final InMemorySpanBuilder asChildOf(Span parent) {
addReference(References.CHILD_OF, parent.context());
addReference(CHILD_OF, parent.context());
return this;
}

Expand Down Expand Up @@ -106,8 +107,8 @@ public final InMemorySpan start() {
protected final InMemorySpanContext parent() {
// Use old-style for loop to save a bit of garbage creation
for (int i = 0; i < references.size(); i++) {
InMemoryReference reference = references.get(i);
if (References.CHILD_OF.equals(reference.type())) {
final InMemoryReference reference = references.get(i);
if (CHILD_OF.equals(reference.type()) || FOLLOWS_FROM.equals(reference.type())) {
return reference.referredTo();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright © 2020 Apple Inc. and the ServiceTalk project 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.servicetalk.opentracing.inmemory;

import io.servicetalk.opentracing.inmemory.api.InMemoryScopeManager;
import io.servicetalk.opentracing.inmemory.api.InMemorySpan;
import io.servicetalk.opentracing.inmemory.api.InMemorySpanBuilder;
import io.servicetalk.opentracing.inmemory.api.InMemorySpanContext;
import io.servicetalk.opentracing.inmemory.api.InMemoryTraceState;
import io.servicetalk.opentracing.inmemory.api.InMemoryTracer;

import org.junit.Test;

import static io.opentracing.References.CHILD_OF;
import static io.opentracing.References.FOLLOWS_FROM;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class DefaultInMemoryTracerTest {
@Test
public void childOfReferenceRespected() {
verifyParentReference("childOfReferenceRespected", true);
}

@Test
public void followsFromReferenceRespected() {
verifyParentReference("followsFromReferenceRespected", false);
}

private static void verifyParentReference(final String parentTraceIdHex, boolean childOf) {
InMemoryScopeManager mockScopeManager = mock(InMemoryScopeManager.class);
InMemorySpanContext mockParentContext = mock(InMemorySpanContext.class);
InMemoryTraceState mockParentTraceState = mock(InMemoryTraceState.class);
when(mockParentContext.traceState()).thenReturn(mockParentTraceState);
when(mockParentTraceState.traceIdHex()).thenReturn(parentTraceIdHex);
InMemoryTracer tracer = new DefaultInMemoryTracer.Builder(mockScopeManager).build();
InMemorySpanBuilder spanBuilder = tracer.buildSpan("foo");
spanBuilder.addReference(childOf ? CHILD_OF : FOLLOWS_FROM, mockParentContext);
InMemorySpan span = spanBuilder.start();
assertEquals(parentTraceIdHex, span.context().traceState().traceIdHex());
}
}

0 comments on commit 5c38aaa

Please sign in to comment.