No matter what, it won't work :) I am now in the mood 'try everything in the world until it works'
This commit is contained in:
parent
cb430c566b
commit
840b8b407d
|
@ -1,42 +1,53 @@
|
||||||
package datadog.trace.agent.tooling;
|
package datadog.trace.agent.tooling;
|
||||||
|
|
||||||
import datadog.trace.bootstrap.WeakMap;
|
//import datadog.trace.bootstrap.WeakMap;
|
||||||
import java.util.HashMap;
|
//import java.util.HashMap;
|
||||||
import java.util.Map;
|
//import java.util.Map;
|
||||||
|
|
||||||
/** A registry which is scoped per-classloader able to hold key-value pairs with weak keys. */
|
/** A registry which is scoped per-classloader able to hold key-value pairs with weak keys. */
|
||||||
public class ClassLoaderScopedWeakMap {
|
public class ClassLoaderScopedWeakMap {
|
||||||
|
|
||||||
public static final ClassLoaderScopedWeakMap INSTANCE = new ClassLoaderScopedWeakMap();
|
// public static final ClassLoaderScopedWeakMap INSTANCE = new ClassLoaderScopedWeakMap();
|
||||||
|
|
||||||
private final WeakMap<ClassLoader, Map<Object, Object>> map = WeakMap.Supplier.DEFAULT.get();
|
// private final WeakMap<ClassLoader, Map<Object, Object>> map = WeakMap.Supplier.DEFAULT.get();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the element registered at the specified key or register as new one retrieved by the
|
* Gets the element registered at the specified key or register as new one retrieved by the
|
||||||
* provided supplier.
|
* provided supplier.
|
||||||
*/
|
*/
|
||||||
public synchronized Object getOrCreate(
|
// public Object getOrCreate(
|
||||||
ClassLoader classLoader, Object key, Supplier valueSupplier) {
|
//// public synchronized Object getOrCreate(
|
||||||
Map<Object, Object> classLoaderMap = map.get(classLoader);
|
// ClassLoader classLoader, Object key, Supplier valueSupplier) {
|
||||||
if (classLoaderMap == null) {
|
//// Map<Object, Object> classLoaderMap = map.get(classLoader);
|
||||||
classLoaderMap = new HashMap<>();
|
//// if (classLoaderMap == null) {
|
||||||
map.put(classLoader, classLoaderMap);
|
//// classLoaderMap = new HashMap<>();
|
||||||
|
//// map.put(classLoader, classLoaderMap);
|
||||||
|
//// }
|
||||||
|
////
|
||||||
|
//// if (classLoaderMap.containsKey(key)) {
|
||||||
|
//// return classLoaderMap.get(key);
|
||||||
|
//// }
|
||||||
|
//
|
||||||
|
// Object value = valueSupplier.get();
|
||||||
|
//// classLoaderMap.put(key, value);
|
||||||
|
// return value;
|
||||||
|
// }
|
||||||
|
|
||||||
|
public static Object aaa(Object aaa) {
|
||||||
|
System.out.println("[STD LOG] aaa " + ClassLoaderScopedWeakMapSupplier.class.getName());
|
||||||
|
return aaa;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classLoaderMap.containsKey(key)) {
|
public static Object bbb(ClassLoaderScopedWeakMapSupplier aaa) {
|
||||||
return classLoaderMap.get(key);
|
System.out.println("[STD LOG] bbb" + ClassLoaderScopedWeakMapSupplier.class.getName());
|
||||||
|
return aaa.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Object value = valueSupplier.get();
|
// /**
|
||||||
classLoaderMap.put(key, value);
|
// * Supplies the value to be stored and it is called only when a value does not exists yet in the
|
||||||
return value;
|
// * registry.
|
||||||
}
|
// */
|
||||||
|
// public interface Supplier {
|
||||||
/**
|
// Object get();
|
||||||
* Supplies the value to be stored and it is called only when a value does not exists yet in the
|
// }
|
||||||
* registry.
|
|
||||||
*/
|
|
||||||
public interface Supplier {
|
|
||||||
Object get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package datadog.trace.agent.tooling;
|
||||||
|
|
||||||
|
public interface ClassLoaderScopedWeakMapSupplier {
|
||||||
|
Object get();
|
||||||
|
}
|
|
@ -60,3 +60,23 @@ configurations.testCompile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
testLogging {
|
||||||
|
// Make sure output from
|
||||||
|
// standard out or error is shown
|
||||||
|
// in Gradle output.
|
||||||
|
showStandardStreams = true
|
||||||
|
|
||||||
|
// Or we use events method:
|
||||||
|
// events 'standard_out', 'standard_error'
|
||||||
|
|
||||||
|
// Or set property events:
|
||||||
|
// events = ['standard_out', 'standard_error']
|
||||||
|
|
||||||
|
// Instead of string values we can
|
||||||
|
// use enum values:
|
||||||
|
// events org.gradle.api.tasks.testing.logging.TestLogEvent.STANDARD_OUT,
|
||||||
|
// org.gradle.api.tasks.testing.logging.TestLogEvent.STANDARD_ERROR,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package datadog.trace.instrumentation.netty40;
|
package datadog.trace.instrumentation.netty40;
|
||||||
|
|
||||||
import datadog.trace.agent.tooling.ClassLoaderScopedWeakMap;
|
import datadog.trace.agent.tooling.ClassLoaderScopedWeakMap;
|
||||||
|
import datadog.trace.agent.tooling.ClassLoaderScopedWeakMapSupplier;
|
||||||
import datadog.trace.context.TraceScope;
|
import datadog.trace.context.TraceScope;
|
||||||
import datadog.trace.instrumentation.netty40.client.HttpClientTracingHandler;
|
import datadog.trace.instrumentation.netty40.client.HttpClientTracingHandler;
|
||||||
import datadog.trace.instrumentation.netty40.server.HttpServerTracingHandler;
|
import datadog.trace.instrumentation.netty40.server.HttpServerTracingHandler;
|
||||||
|
@ -9,49 +10,65 @@ import io.opentracing.Span;
|
||||||
|
|
||||||
public class AttributeKeys {
|
public class AttributeKeys {
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.out.println("Canone!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
|
}
|
||||||
|
|
||||||
private static final String PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME =
|
private static final String PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME =
|
||||||
"datadog.trace.instrumentation.netty40.parent.connect.continuation";
|
"datadog.trace.instrumentation.netty40.parent.connect.continuation";
|
||||||
|
|
||||||
public static final AttributeKey<TraceScope.Continuation>
|
public static final AttributeKey<TraceScope.Continuation>
|
||||||
PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY =
|
PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY = new AttributeKey<>(PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME);
|
||||||
(AttributeKey<TraceScope.Continuation>)
|
// public static final AttributeKey<TraceScope.Continuation>
|
||||||
ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
|
// PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY =
|
||||||
AttributeKey.class.getClassLoader(),
|
// (AttributeKey<TraceScope.Continuation>)
|
||||||
PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME,
|
// ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
|
||||||
new ClassLoaderScopedWeakMap.Supplier() {
|
// AttributeKey.class.getClassLoader(),
|
||||||
@Override
|
// PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME,
|
||||||
public Object get() {
|
// new ClassLoaderScopedWeakMap.Supplier() {
|
||||||
return new AttributeKey<>(PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME);
|
// @Override
|
||||||
}
|
// public Object get() {
|
||||||
});
|
// return new AttributeKey<>(PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
private static final String SERVER_ATTRIBUTE_KEY_NAME =
|
private static final String SERVER_ATTRIBUTE_KEY_NAME =
|
||||||
HttpServerTracingHandler.class.getName() + ".span";
|
HttpServerTracingHandler.class.getName() + ".span";
|
||||||
|
|
||||||
public static final AttributeKey<Span> SERVER_ATTRIBUTE_KEY =
|
public static final AttributeKey<Span> SERVER_ATTRIBUTE_KEY = new AttributeKey<>(SERVER_ATTRIBUTE_KEY_NAME);
|
||||||
(AttributeKey<Span>)
|
// public static final AttributeKey<Span> SERVER_ATTRIBUTE_KEY =
|
||||||
ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
|
// (AttributeKey<Span>)
|
||||||
AttributeKey.class.getClassLoader(),
|
// ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
|
||||||
SERVER_ATTRIBUTE_KEY_NAME,
|
// AttributeKey.class.getClassLoader(),
|
||||||
new ClassLoaderScopedWeakMap.Supplier() {
|
// SERVER_ATTRIBUTE_KEY_NAME,
|
||||||
@Override
|
// new ClassLoaderScopedWeakMap.Supplier() {
|
||||||
public Object get() {
|
// @Override
|
||||||
return new AttributeKey<>(SERVER_ATTRIBUTE_KEY_NAME);
|
// public Object get() {
|
||||||
}
|
// return new AttributeKey<>(SERVER_ATTRIBUTE_KEY_NAME);
|
||||||
});
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
private static final String CLIENT_ATTRIBUTE_KEY_NAME =
|
private static final String CLIENT_ATTRIBUTE_KEY_NAME =
|
||||||
HttpClientTracingHandler.class.getName() + ".span";
|
HttpClientTracingHandler.class.getName() + ".span";
|
||||||
|
|
||||||
public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY =
|
// public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY = new AttributeKey<>(CLIENT_ATTRIBUTE_KEY_NAME);
|
||||||
(AttributeKey<Span>)
|
// public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY = (AttributeKey<Span>) ClassLoaderScopedWeakMap.aaa(new AttributeKey<>(CLIENT_ATTRIBUTE_KEY_NAME));
|
||||||
ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
|
public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY = (AttributeKey<Span>) ClassLoaderScopedWeakMap.bbb(new ClassLoaderScopedWeakMapSupplier() {
|
||||||
AttributeKey.class.getClassLoader(),
|
|
||||||
CLIENT_ATTRIBUTE_KEY_NAME,
|
|
||||||
new ClassLoaderScopedWeakMap.Supplier() {
|
|
||||||
@Override
|
@Override
|
||||||
public Object get() {
|
public Object get() {
|
||||||
|
System.out.println("[STD LOG] executing the getter");
|
||||||
return new AttributeKey<>(CLIENT_ATTRIBUTE_KEY_NAME);
|
return new AttributeKey<>(CLIENT_ATTRIBUTE_KEY_NAME);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY =
|
||||||
|
// (AttributeKey<Span>)
|
||||||
|
// ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
|
||||||
|
// AttributeKey.class.getClassLoader(),
|
||||||
|
// CLIENT_ATTRIBUTE_KEY_NAME,
|
||||||
|
// new ClassLoaderScopedWeakMap.Supplier() {
|
||||||
|
// @Override
|
||||||
|
// public Object get() {
|
||||||
|
// return new AttributeKey<>(CLIENT_ATTRIBUTE_KEY_NAME);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,8 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
|
"datadog.trace.agent.tooling.ClassLoaderScopedWeakMapSupplier",
|
||||||
|
"datadog.trace.agent.tooling.ClassLoaderScopedWeakMap",
|
||||||
packageName + ".AttributeKeys",
|
packageName + ".AttributeKeys",
|
||||||
"datadog.trace.agent.decorator.BaseDecorator",
|
"datadog.trace.agent.decorator.BaseDecorator",
|
||||||
// client helpers
|
// client helpers
|
||||||
|
|
|
@ -55,6 +55,8 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
|
||||||
@Override
|
@Override
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
|
"datadog.trace.agent.tooling.ClassLoaderScopedWeakMapSupplier",
|
||||||
|
"datadog.trace.agent.tooling.ClassLoaderScopedWeakMap",
|
||||||
packageName + ".AttributeKeys",
|
packageName + ".AttributeKeys",
|
||||||
"datadog.trace.agent.decorator.BaseDecorator",
|
"datadog.trace.agent.decorator.BaseDecorator",
|
||||||
// client helpers
|
// client helpers
|
||||||
|
|
|
@ -20,6 +20,7 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise prm) {
|
public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise prm) {
|
||||||
|
System.out.println("[STD LOG] About to write request handler");
|
||||||
if (!(msg instanceof HttpRequest)) {
|
if (!(msg instanceof HttpRequest)) {
|
||||||
ctx.write(msg, prm);
|
ctx.write(msg, prm);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -50,45 +50,45 @@ class Netty40ClientTest extends HttpClientTest<NettyHttpClientDecorator> {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
def "connection error (unopened port)"() {
|
// def "connection error (unopened port)"() {
|
||||||
given:
|
// given:
|
||||||
def uri = new URI("http://localhost:$UNUSABLE_PORT/")
|
// def uri = new URI("http://localhost:$UNUSABLE_PORT/")
|
||||||
|
//
|
||||||
when:
|
// when:
|
||||||
runUnderTrace("parent") {
|
// runUnderTrace("parent") {
|
||||||
doRequest(method, uri)
|
// doRequest(method, uri)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
then:
|
// then:
|
||||||
def ex = thrown(Exception)
|
// def ex = thrown(Exception)
|
||||||
def thrownException = ex instanceof ExecutionException ? ex.cause : ex
|
// def thrownException = ex instanceof ExecutionException ? ex.cause : ex
|
||||||
|
//
|
||||||
and:
|
// and:
|
||||||
assertTraces(1) {
|
// assertTraces(1) {
|
||||||
trace(0, 2) {
|
// trace(0, 2) {
|
||||||
basicSpan(it, 0, "parent", thrownException)
|
// basicSpan(it, 0, "parent", thrownException)
|
||||||
|
//
|
||||||
span(1) {
|
// span(1) {
|
||||||
operationName "netty.connect"
|
// operationName "netty.connect"
|
||||||
resourceName "netty.connect"
|
// resourceName "netty.connect"
|
||||||
childOf span(0)
|
// childOf span(0)
|
||||||
errored true
|
// errored true
|
||||||
tags {
|
// tags {
|
||||||
"$Tags.COMPONENT.key" "netty"
|
// "$Tags.COMPONENT.key" "netty"
|
||||||
Class errorClass = ConnectException
|
// Class errorClass = ConnectException
|
||||||
try {
|
// try {
|
||||||
errorClass = Class.forName('io.netty.channel.AbstractChannel$AnnotatedConnectException')
|
// errorClass = Class.forName('io.netty.channel.AbstractChannel$AnnotatedConnectException')
|
||||||
} catch (ClassNotFoundException e) {
|
// } catch (ClassNotFoundException e) {
|
||||||
// Older versions use 'java.net.ConnectException' and do not have 'io.netty.channel.AbstractChannel$AnnotatedConnectException'
|
// // Older versions use 'java.net.ConnectException' and do not have 'io.netty.channel.AbstractChannel$AnnotatedConnectException'
|
||||||
}
|
// }
|
||||||
errorTags errorClass, "Connection refused: localhost/127.0.0.1:$UNUSABLE_PORT"
|
// errorTags errorClass, "Connection refused: localhost/127.0.0.1:$UNUSABLE_PORT"
|
||||||
defaultTags()
|
// defaultTags()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
where:
|
// where:
|
||||||
method = "GET"
|
// method = "GET"
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,232 +88,232 @@ abstract class HttpClientTest<T extends HttpClientDecorator> extends AgentTestRu
|
||||||
where:
|
where:
|
||||||
path | tagQueryString
|
path | tagQueryString
|
||||||
"/success" | false
|
"/success" | false
|
||||||
"/success" | true
|
// "/success" | true
|
||||||
"/success?with=params" | false
|
// "/success?with=params" | false
|
||||||
"/success?with=params" | true
|
// "/success?with=params" | true
|
||||||
"/success#with+fragment" | true
|
// "/success#with+fragment" | true
|
||||||
"/success?with=params#and=fragment" | true
|
// "/success?with=params#and=fragment" | true
|
||||||
|
|
||||||
method = "GET"
|
method = "GET"
|
||||||
url = server.address.resolve(path)
|
url = server.address.resolve(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unroll
|
// @Unroll
|
||||||
def "basic #method request with parent"() {
|
// def "basic #method request with parent"() {
|
||||||
when:
|
// when:
|
||||||
def status = runUnderTrace("parent") {
|
// def status = runUnderTrace("parent") {
|
||||||
doRequest(method, server.address.resolve("/success"))
|
// doRequest(method, server.address.resolve("/success"))
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
then:
|
// then:
|
||||||
status == 200
|
// status == 200
|
||||||
assertTraces(2) {
|
// assertTraces(2) {
|
||||||
server.distributedRequestTrace(it, 0, trace(1).last())
|
// server.distributedRequestTrace(it, 0, trace(1).last())
|
||||||
trace(1, size(2)) {
|
// trace(1, size(2)) {
|
||||||
basicSpan(it, 0, "parent")
|
// basicSpan(it, 0, "parent")
|
||||||
clientSpan(it, 1, span(0), method, false)
|
// clientSpan(it, 1, span(0), method, false)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
where:
|
// where:
|
||||||
method << BODY_METHODS
|
// method << BODY_METHODS
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Unroll
|
// @Unroll
|
||||||
def "basic #method request with split-by-domain"() {
|
// def "basic #method request with split-by-domain"() {
|
||||||
when:
|
// when:
|
||||||
def status = withConfigOverride(Config.HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "true") {
|
// def status = withConfigOverride(Config.HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "true") {
|
||||||
doRequest(method, server.address.resolve("/success"))
|
// doRequest(method, server.address.resolve("/success"))
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
then:
|
// then:
|
||||||
status == 200
|
// status == 200
|
||||||
assertTraces(2) {
|
// assertTraces(2) {
|
||||||
server.distributedRequestTrace(it, 0, trace(1).last())
|
// server.distributedRequestTrace(it, 0, trace(1).last())
|
||||||
trace(1, size(1)) {
|
// trace(1, size(1)) {
|
||||||
clientSpan(it, 0, null, method, true)
|
// clientSpan(it, 0, null, method, true)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
where:
|
// where:
|
||||||
method = "HEAD"
|
// method = "HEAD"
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
def "trace request without propagation"() {
|
// def "trace request without propagation"() {
|
||||||
when:
|
// when:
|
||||||
def status = withConfigOverride(Config.HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "$renameService") {
|
// def status = withConfigOverride(Config.HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "$renameService") {
|
||||||
runUnderTrace("parent") {
|
// runUnderTrace("parent") {
|
||||||
doRequest(method, server.address.resolve("/success"), ["is-dd-server": "false"])
|
// doRequest(method, server.address.resolve("/success"), ["is-dd-server": "false"])
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
then:
|
// then:
|
||||||
status == 200
|
// status == 200
|
||||||
// only one trace (client).
|
// // only one trace (client).
|
||||||
assertTraces(1) {
|
// assertTraces(1) {
|
||||||
trace(0, size(2)) {
|
// trace(0, size(2)) {
|
||||||
basicSpan(it, 0, "parent")
|
// basicSpan(it, 0, "parent")
|
||||||
clientSpan(it, 1, span(0), method, renameService)
|
// clientSpan(it, 1, span(0), method, renameService)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
where:
|
// where:
|
||||||
method = "GET"
|
// method = "GET"
|
||||||
renameService << [false, true]
|
// renameService << [false, true]
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
def "trace request with callback and parent"() {
|
// def "trace request with callback and parent"() {
|
||||||
when:
|
// when:
|
||||||
def status = runUnderTrace("parent") {
|
// def status = runUnderTrace("parent") {
|
||||||
doRequest(method, server.address.resolve("/success"), ["is-dd-server": "false"]) {
|
// doRequest(method, server.address.resolve("/success"), ["is-dd-server": "false"]) {
|
||||||
runUnderTrace("child") {}
|
// runUnderTrace("child") {}
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
then:
|
// then:
|
||||||
status == 200
|
// status == 200
|
||||||
// only one trace (client).
|
// // only one trace (client).
|
||||||
assertTraces(1) {
|
// assertTraces(1) {
|
||||||
trace(0, size(3)) {
|
// trace(0, size(3)) {
|
||||||
basicSpan(it, 0, "parent")
|
// basicSpan(it, 0, "parent")
|
||||||
span(1) {
|
// span(1) {
|
||||||
operationName "child"
|
// operationName "child"
|
||||||
childOf span(0)
|
// childOf span(0)
|
||||||
}
|
// }
|
||||||
clientSpan(it, 2, span(0), method, false)
|
// clientSpan(it, 2, span(0), method, false)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
where:
|
// where:
|
||||||
method = "GET"
|
// method = "GET"
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
def "trace request with callback and no parent"() {
|
// def "trace request with callback and no parent"() {
|
||||||
when:
|
// when:
|
||||||
def status = doRequest(method, server.address.resolve("/success"), ["is-dd-server": "false"]) {
|
// def status = doRequest(method, server.address.resolve("/success"), ["is-dd-server": "false"]) {
|
||||||
runUnderTrace("child") {
|
// runUnderTrace("child") {
|
||||||
// Ensure consistent ordering of traces for assertion.
|
// // Ensure consistent ordering of traces for assertion.
|
||||||
TEST_WRITER.waitForTraces(1)
|
// TEST_WRITER.waitForTraces(1)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
then:
|
// then:
|
||||||
status == 200
|
// status == 200
|
||||||
// only one trace (client).
|
// // only one trace (client).
|
||||||
assertTraces(2) {
|
// assertTraces(2) {
|
||||||
trace(0, size(1)) {
|
// trace(0, size(1)) {
|
||||||
clientSpan(it, 0, null, method, false)
|
// clientSpan(it, 0, null, method, false)
|
||||||
}
|
// }
|
||||||
trace(1, 1) {
|
// trace(1, 1) {
|
||||||
span(0) {
|
// span(0) {
|
||||||
operationName "child"
|
// operationName "child"
|
||||||
parent()
|
// parent()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
where:
|
// where:
|
||||||
method = "GET"
|
// method = "GET"
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Unroll
|
// @Unroll
|
||||||
def "basic #method request with 1 redirect"() {
|
// def "basic #method request with 1 redirect"() {
|
||||||
given:
|
// given:
|
||||||
assumeTrue(testRedirects())
|
// assumeTrue(testRedirects())
|
||||||
def uri = server.address.resolve("/redirect")
|
// def uri = server.address.resolve("/redirect")
|
||||||
|
//
|
||||||
when:
|
// when:
|
||||||
def status = doRequest(method, uri)
|
// def status = doRequest(method, uri)
|
||||||
|
//
|
||||||
then:
|
// then:
|
||||||
status == 200
|
// status == 200
|
||||||
assertTraces(3) {
|
// assertTraces(3) {
|
||||||
server.distributedRequestTrace(it, 0, trace(2).last())
|
// server.distributedRequestTrace(it, 0, trace(2).last())
|
||||||
server.distributedRequestTrace(it, 1, trace(2).last())
|
// server.distributedRequestTrace(it, 1, trace(2).last())
|
||||||
trace(2, size(1)) {
|
// trace(2, size(1)) {
|
||||||
clientSpan(it, 0, null, method, false, false, uri)
|
// clientSpan(it, 0, null, method, false, false, uri)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
where:
|
// where:
|
||||||
method = "GET"
|
// method = "GET"
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Unroll
|
// @Unroll
|
||||||
def "basic #method request with 2 redirects"() {
|
// def "basic #method request with 2 redirects"() {
|
||||||
given:
|
// given:
|
||||||
assumeTrue(testRedirects())
|
// assumeTrue(testRedirects())
|
||||||
def uri = server.address.resolve("/another-redirect")
|
// def uri = server.address.resolve("/another-redirect")
|
||||||
|
//
|
||||||
when:
|
// when:
|
||||||
def status = doRequest(method, uri)
|
// def status = doRequest(method, uri)
|
||||||
|
//
|
||||||
then:
|
// then:
|
||||||
status == 200
|
// status == 200
|
||||||
assertTraces(4) {
|
// assertTraces(4) {
|
||||||
server.distributedRequestTrace(it, 0, trace(3).last())
|
// server.distributedRequestTrace(it, 0, trace(3).last())
|
||||||
server.distributedRequestTrace(it, 1, trace(3).last())
|
// server.distributedRequestTrace(it, 1, trace(3).last())
|
||||||
server.distributedRequestTrace(it, 2, trace(3).last())
|
// server.distributedRequestTrace(it, 2, trace(3).last())
|
||||||
trace(3, size(1)) {
|
// trace(3, size(1)) {
|
||||||
clientSpan(it, 0, null, method, false, false, uri)
|
// clientSpan(it, 0, null, method, false, false, uri)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
where:
|
// where:
|
||||||
method = "GET"
|
// method = "GET"
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Unroll
|
// @Unroll
|
||||||
def "basic #method request with circular redirects"() {
|
// def "basic #method request with circular redirects"() {
|
||||||
given:
|
// given:
|
||||||
assumeTrue(testRedirects())
|
// assumeTrue(testRedirects())
|
||||||
def uri = server.address.resolve("/circular-redirect")
|
// def uri = server.address.resolve("/circular-redirect")
|
||||||
|
//
|
||||||
when:
|
// when:
|
||||||
doRequest(method, uri)//, ["is-dd-server": "false"])
|
// doRequest(method, uri)//, ["is-dd-server": "false"])
|
||||||
|
//
|
||||||
then:
|
// then:
|
||||||
def ex = thrown(Exception)
|
// def ex = thrown(Exception)
|
||||||
def thrownException = ex instanceof ExecutionException ? ex.cause : ex
|
// def thrownException = ex instanceof ExecutionException ? ex.cause : ex
|
||||||
|
//
|
||||||
and:
|
// and:
|
||||||
assertTraces(3) {
|
// assertTraces(3) {
|
||||||
server.distributedRequestTrace(it, 0, trace(2).last())
|
// server.distributedRequestTrace(it, 0, trace(2).last())
|
||||||
server.distributedRequestTrace(it, 1, trace(2).last())
|
// server.distributedRequestTrace(it, 1, trace(2).last())
|
||||||
trace(2, size(1)) {
|
// trace(2, size(1)) {
|
||||||
clientSpan(it, 0, null, method, false, false, uri, statusOnRedirectError(), thrownException)
|
// clientSpan(it, 0, null, method, false, false, uri, statusOnRedirectError(), thrownException)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
where:
|
// where:
|
||||||
method = "GET"
|
// method = "GET"
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
def "connection error (unopened port)"() {
|
// def "connection error (unopened port)"() {
|
||||||
given:
|
// given:
|
||||||
assumeTrue(testConnectionFailure())
|
// assumeTrue(testConnectionFailure())
|
||||||
def uri = new URI("http://localhost:$UNUSABLE_PORT/")
|
// def uri = new URI("http://localhost:$UNUSABLE_PORT/")
|
||||||
|
//
|
||||||
when:
|
// when:
|
||||||
runUnderTrace("parent") {
|
// runUnderTrace("parent") {
|
||||||
doRequest(method, uri)
|
// doRequest(method, uri)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
then:
|
// then:
|
||||||
def ex = thrown(Exception)
|
// def ex = thrown(Exception)
|
||||||
def thrownException = ex instanceof ExecutionException ? ex.cause : ex
|
// def thrownException = ex instanceof ExecutionException ? ex.cause : ex
|
||||||
|
//
|
||||||
and:
|
// and:
|
||||||
assertTraces(1) {
|
// assertTraces(1) {
|
||||||
trace(0, 2) {
|
// trace(0, 2) {
|
||||||
basicSpan(it, 0, "parent", thrownException)
|
// basicSpan(it, 0, "parent", thrownException)
|
||||||
clientSpan(it, 1, span(0), method, false, false, uri, null, thrownException)
|
// clientSpan(it, 1, span(0), method, false, false, uri, null, thrownException)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
where:
|
// where:
|
||||||
method = "GET"
|
// method = "GET"
|
||||||
}
|
// }
|
||||||
|
|
||||||
// parent span must be cast otherwise it breaks debugging classloading (junit loads it early)
|
// parent span must be cast otherwise it breaks debugging classloading (junit loads it early)
|
||||||
void clientSpan(TraceAssert trace, int index, Object parentSpan, String method = "GET", boolean renameService = false, boolean tagQueryString = false, URI uri = server.address.resolve("/success"), Integer status = 200, Throwable exception = null) {
|
void clientSpan(TraceAssert trace, int index, Object parentSpan, String method = "GET", boolean renameService = false, boolean tagQueryString = false, URI uri = server.address.resolve("/success"), Integer status = 200, Throwable exception = null) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class ListWriter extends CopyOnWriteArrayList<List<DDSpan>> implements Wr
|
||||||
}
|
}
|
||||||
latches.add(latch);
|
latches.add(latch);
|
||||||
}
|
}
|
||||||
if (!latch.await(20, TimeUnit.SECONDS)) {
|
if (!latch.await(5, TimeUnit.SECONDS)) {
|
||||||
throw new TimeoutException(
|
throw new TimeoutException(
|
||||||
"Timeout waiting for " + number + " trace(s). ListWriter.size() == " + size());
|
"Timeout waiting for " + number + " trace(s). ListWriter.size() == " + size());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue