Remove testing module dependencies on GlobalTracer

This commit is contained in:
Trask Stalnaker 2019-10-04 15:03:31 -07:00
parent 86bd9793bd
commit a45dc34c5c
6 changed files with 58 additions and 125 deletions

View File

@ -8,11 +8,9 @@ import datadog.trace.agent.test.asserts.TraceAssert
import datadog.trace.agent.test.utils.OkHttpUtils import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.agent.test.utils.PortUtils import datadog.trace.agent.test.utils.PortUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.context.TraceScope
import groovy.transform.stc.ClosureParams import groovy.transform.stc.ClosureParams
import groovy.transform.stc.SimpleType import groovy.transform.stc.SimpleType
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import io.opentracing.util.GlobalTracer
import okhttp3.HttpUrl import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
@ -30,6 +28,8 @@ import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.REDIRE
import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS import static datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint.SUCCESS
import static datadog.trace.agent.test.utils.TraceUtils.basicSpan import static datadog.trace.agent.test.utils.TraceUtils.basicSpan
import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace import static datadog.trace.agent.test.utils.TraceUtils.runUnderTrace
import static datadog.trace.instrumentation.api.AgentTracer.activeScope
import static datadog.trace.instrumentation.api.AgentTracer.activeSpan
import static org.junit.Assume.assumeTrue import static org.junit.Assume.assumeTrue
@Unroll @Unroll
@ -152,8 +152,8 @@ abstract class HttpServerTest<SERVER, DECORATOR extends HttpServerDecorator> ext
} }
static <T> T controller(ServerEndpoint endpoint, Closure<T> closure) { static <T> T controller(ServerEndpoint endpoint, Closure<T> closure) {
assert GlobalTracer.get().activeSpan() != null: "Controller should have a parent span." assert activeSpan() != null: "Controller should have a parent span."
assert ((TraceScope) GlobalTracer.get().scopeManager().active()).asyncPropagating: "Scope should be propagating async." assert activeScope().asyncPropagating: "Scope should be propagating async."
if (endpoint == NOT_FOUND) { if (endpoint == NOT_FOUND) {
return closure() return closure()
} }

View File

@ -1,11 +1,12 @@
package datadog.trace.agent.test.base; package datadog.trace.agent.test.base;
import static datadog.trace.instrumentation.api.AgentTracer.activateSpan;
import static datadog.trace.instrumentation.api.AgentTracer.activeSpan;
import static datadog.trace.instrumentation.api.AgentTracer.startSpan;
import datadog.trace.api.DDTags; import datadog.trace.api.DDTags;
import datadog.trace.context.TraceScope; import datadog.trace.instrumentation.api.AgentScope;
import io.opentracing.Scope; import datadog.trace.instrumentation.api.AgentSpan;
import io.opentracing.Tracer;
import io.opentracing.noop.NoopScopeManager;
import io.opentracing.util.GlobalTracer;
import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice;
public abstract class HttpServerTestAdvice { public abstract class HttpServerTestAdvice {
@ -16,28 +17,26 @@ public abstract class HttpServerTestAdvice {
*/ */
public static class ServerEntryAdvice { public static class ServerEntryAdvice {
@Advice.OnMethodEnter @Advice.OnMethodEnter
public static Scope methodEnter() { public static AgentScope methodEnter() {
if (!HttpServerTest.ENABLE_TEST_ADVICE.get()) { if (!HttpServerTest.ENABLE_TEST_ADVICE.get()) {
// Skip if not running the HttpServerTest. // Skip if not running the HttpServerTest.
return NoopScopeManager.NoopScope.INSTANCE; return null;
} }
final Tracer tracer = GlobalTracer.get(); if (activeSpan() != null) {
if (tracer.activeSpan() != null) { return null;
return NoopScopeManager.NoopScope.INSTANCE;
} else { } else {
final Scope scope = final AgentSpan span = startSpan("TEST_SPAN").setTag(DDTags.RESOURCE_NAME, "ServerEntry");
tracer final AgentScope scope = activateSpan(span, true);
.buildSpan("TEST_SPAN") scope.setAsyncPropagation(true);
.withTag(DDTags.RESOURCE_NAME, "ServerEntry")
.startActive(true);
((TraceScope) scope).setAsyncPropagation(true);
return scope; return scope;
} }
} }
@Advice.OnMethodExit(onThrowable = Throwable.class) @Advice.OnMethodExit(onThrowable = Throwable.class)
public static void methodExit(@Advice.Enter final Scope scope) { public static void methodExit(@Advice.Enter final AgentScope scope) {
if (scope != null) {
scope.close(); scope.close();
} }
} }
}
} }

View File

@ -3,11 +3,14 @@ package datadog.trace.agent.test.log.injection
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.utils.ConfigUtils import datadog.trace.agent.test.utils.ConfigUtils
import datadog.trace.api.CorrelationIdentifier import datadog.trace.api.CorrelationIdentifier
import io.opentracing.Scope import datadog.trace.instrumentation.api.AgentScope
import io.opentracing.util.GlobalTracer import datadog.trace.instrumentation.api.AgentSpan
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
import static datadog.trace.instrumentation.api.AgentTracer.activateSpan
import static datadog.trace.instrumentation.api.AgentTracer.startSpan
/** /**
* This class represents the standard test cases that new logging library integrations MUST * This class represents the standard test cases that new logging library integrations MUST
* satisfy in order to support log injection. * satisfy in order to support log injection.
@ -33,7 +36,8 @@ abstract class LogContextInjectionTestBase extends AgentTestRunner {
def "Log context shows trace and span ids for active scope"() { def "Log context shows trace and span ids for active scope"() {
when: when:
put("foo", "bar") put("foo", "bar")
Scope rootScope = GlobalTracer.get().buildSpan("root").startActive(true) AgentSpan rootSpan = startSpan("root")
AgentScope rootScope = activateSpan(rootSpan, true)
then: then:
get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId()
@ -41,7 +45,8 @@ abstract class LogContextInjectionTestBase extends AgentTestRunner {
get("foo") == "bar" get("foo") == "bar"
when: when:
Scope childScope = GlobalTracer.get().buildSpan("child").startActive(true) AgentSpan childSpan = startSpan("child")
AgentScope childScope = activateSpan(childSpan, true)
then: then:
get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId() get(CorrelationIdentifier.getTraceIdKey()) == CorrelationIdentifier.getTraceId()
@ -85,7 +90,8 @@ abstract class LogContextInjectionTestBase extends AgentTestRunner {
@Override @Override
void run() { void run() {
// other trace in scope // other trace in scope
final Scope thread2Scope = GlobalTracer.get().buildSpan("root2").startActive(true) final AgentSpan thread2Span = startSpan("root2")
final AgentScope thread2Scope = activateSpan(thread2Span, true)
try { try {
thread2TraceId.set(get(CorrelationIdentifier.getTraceIdKey())) thread2TraceId.set(get(CorrelationIdentifier.getTraceIdKey()))
} finally { } finally {
@ -93,7 +99,8 @@ abstract class LogContextInjectionTestBase extends AgentTestRunner {
} }
} }
} }
final Scope mainScope = GlobalTracer.get().buildSpan("root").startActive(true) final AgentSpan mainSpan = startSpan("root")
final AgentScope mainScope = activateSpan(mainSpan, true)
thread1.start() thread1.start()
thread2.start() thread2.start()
final String mainThreadTraceId = get(CorrelationIdentifier.getTraceIdKey()) final String mainThreadTraceId = get(CorrelationIdentifier.getTraceIdKey())

View File

@ -2,11 +2,8 @@ package datadog.trace.agent.test.server.http
import datadog.opentracing.DDSpan import datadog.opentracing.DDSpan
import datadog.trace.agent.test.asserts.ListWriterAssert import datadog.trace.agent.test.asserts.ListWriterAssert
import io.opentracing.SpanContext import datadog.trace.instrumentation.api.AgentSpan
import io.opentracing.Tracer
import io.opentracing.propagation.Format
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import io.opentracing.util.GlobalTracer
import org.eclipse.jetty.http.HttpMethods import org.eclipse.jetty.http.HttpMethods
import org.eclipse.jetty.server.Handler import org.eclipse.jetty.server.Handler
import org.eclipse.jetty.server.Request import org.eclipse.jetty.server.Request
@ -19,6 +16,10 @@ import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse import javax.servlet.http.HttpServletResponse
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
import static datadog.trace.agent.test.server.http.HttpServletRequestExtractAdapter.GETTER
import static datadog.trace.instrumentation.api.AgentTracer.propagate
import static datadog.trace.instrumentation.api.AgentTracer.startSpan
class TestHttpServer implements AutoCloseable { class TestHttpServer implements AutoCloseable {
static TestHttpServer httpServer(boolean start = true, static TestHttpServer httpServer(boolean start = true,
@ -38,8 +39,6 @@ class TestHttpServer implements AutoCloseable {
private final Server internalServer private final Server internalServer
private HandlersSpec handlers private HandlersSpec handlers
public Tracer tracer = GlobalTracer.get()
private URI address private URI address
private final AtomicReference<HandlerApi.RequestApi> last = new AtomicReference<>() private final AtomicReference<HandlerApi.RequestApi> last = new AtomicReference<>()
@ -233,15 +232,14 @@ class TestHttpServer implements AutoCloseable {
isDDServer = Boolean.parseBoolean(request.getHeader("is-dd-server")) isDDServer = Boolean.parseBoolean(request.getHeader("is-dd-server"))
} }
if (isDDServer) { if (isDDServer) {
final SpanContext extractedContext = final AgentSpan.Context extractedContext = propagate().extract(req, GETTER)
tracer.extract(Format.Builtin.HTTP_HEADERS, new HttpServletRequestExtractAdapter(req))
def builder = tracer
.buildSpan("test-http-server")
.withTag(Tags.SPAN_KIND.key, Tags.SPAN_KIND_SERVER)
if (extractedContext != null) { if (extractedContext != null) {
builder.asChildOf(extractedContext) startSpan("test-http-server", extractedContext)
.setTag(Tags.SPAN_KIND.key, Tags.SPAN_KIND_SERVER).finish()
} else {
startSpan("test-http-server")
.setTag(Tags.SPAN_KIND.key, Tags.SPAN_KIND_SERVER).finish()
} }
builder.start().finish()
} }
} }

View File

@ -1,14 +1,7 @@
package datadog.trace.agent.test.server.http; package datadog.trace.agent.test.server.http;
import io.opentracing.propagation.TextMap; import datadog.trace.instrumentation.api.AgentPropagation;
import java.util.AbstractMap; import java.util.Collections;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
/** /**
@ -17,80 +10,19 @@ import javax.servlet.http.HttpServletRequest;
* @author Pavol Loffay * @author Pavol Loffay
*/ */
// FIXME: This code is duplicated in several places. Extract to a common dependency. // FIXME: This code is duplicated in several places. Extract to a common dependency.
public class HttpServletRequestExtractAdapter implements TextMap { public class HttpServletRequestExtractAdapter
implements AgentPropagation.Getter<HttpServletRequest> {
private final Map<String, List<String>> headers; public static final HttpServletRequestExtractAdapter GETTER =
new HttpServletRequestExtractAdapter();
public HttpServletRequestExtractAdapter(final HttpServletRequest httpServletRequest) { @Override
headers = servletHeadersToMultiMap(httpServletRequest); public Iterable<String> keys(final HttpServletRequest carrier) {
return Collections.list(carrier.getHeaderNames());
} }
@Override @Override
public Iterator<Map.Entry<String, String>> iterator() { public String get(final HttpServletRequest carrier, final String key) {
return new MultivaluedMapFlatIterator<>(headers.entrySet()); return carrier.getHeader(key);
}
@Override
public void put(final String key, final String value) {
throw new UnsupportedOperationException("This class should be used only with Tracer.inject()!");
}
protected Map<String, List<String>> servletHeadersToMultiMap(
final HttpServletRequest httpServletRequest) {
final Map<String, List<String>> headersResult = new HashMap<>();
final Enumeration<?> headerNamesIt = httpServletRequest.getHeaderNames();
while (headerNamesIt.hasMoreElements()) {
final String headerName = headerNamesIt.nextElement().toString();
final Enumeration<?> valuesIt = httpServletRequest.getHeaders(headerName);
final List<String> valuesList = new ArrayList<>(1);
while (valuesIt.hasMoreElements()) {
valuesList.add(valuesIt.nextElement().toString());
}
headersResult.put(headerName, valuesList);
}
return headersResult;
}
public static final class MultivaluedMapFlatIterator<K, V> implements Iterator<Map.Entry<K, V>> {
private final Iterator<Map.Entry<K, List<V>>> mapIterator;
private Map.Entry<K, List<V>> mapEntry;
private Iterator<V> listIterator;
public MultivaluedMapFlatIterator(final Set<Map.Entry<K, List<V>>> multiValuesEntrySet) {
mapIterator = multiValuesEntrySet.iterator();
}
@Override
public boolean hasNext() {
if (listIterator != null && listIterator.hasNext()) {
return true;
}
return mapIterator.hasNext();
}
@Override
public Map.Entry<K, V> next() {
if (mapEntry == null || (!listIterator.hasNext() && mapIterator.hasNext())) {
mapEntry = mapIterator.next();
listIterator = mapEntry.getValue().iterator();
}
if (listIterator.hasNext()) {
return new AbstractMap.SimpleImmutableEntry<>(mapEntry.getKey(), listIterator.next());
} else {
return new AbstractMap.SimpleImmutableEntry<>(mapEntry.getKey(), null);
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
} }
} }

View File

@ -1,10 +1,9 @@
package server package server
import datadog.opentracing.DDTracer
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.asserts.ListWriterAssert import datadog.trace.agent.test.asserts.ListWriterAssert
import datadog.trace.agent.test.utils.OkHttpUtils import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.common.writer.ListWriter
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.Request import okhttp3.Request
import spock.lang.Shared import spock.lang.Shared
@ -300,8 +299,6 @@ class ServerTest extends AgentTestRunner {
} }
} }
} }
def writer = new ListWriter()
server.tracer = new DDTracer(writer)
when: when:
def request = new Request.Builder() def request = new Request.Builder()
@ -315,7 +312,7 @@ class ServerTest extends AgentTestRunner {
response.code() == 200 response.code() == 200
response.body().string().trim() == "done" response.body().string().trim() == "done"
ListWriterAssert.assertTraces(writer, 1) { ListWriterAssert.assertTraces(TEST_WRITER, 1) {
server.distributedRequestTrace(it, 0) server.distributedRequestTrace(it, 0)
} }