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;
|
||||
|
||||
import datadog.trace.bootstrap.WeakMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
//import datadog.trace.bootstrap.WeakMap;
|
||||
//import java.util.HashMap;
|
||||
//import java.util.Map;
|
||||
|
||||
/** A registry which is scoped per-classloader able to hold key-value pairs with weak keys. */
|
||||
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
|
||||
* provided supplier.
|
||||
*/
|
||||
public synchronized Object getOrCreate(
|
||||
ClassLoader classLoader, Object key, Supplier valueSupplier) {
|
||||
Map<Object, Object> classLoaderMap = map.get(classLoader);
|
||||
if (classLoaderMap == null) {
|
||||
classLoaderMap = new HashMap<>();
|
||||
map.put(classLoader, classLoaderMap);
|
||||
}
|
||||
// public Object getOrCreate(
|
||||
//// public synchronized Object getOrCreate(
|
||||
// ClassLoader classLoader, Object key, Supplier valueSupplier) {
|
||||
//// Map<Object, Object> classLoaderMap = map.get(classLoader);
|
||||
//// if (classLoaderMap == null) {
|
||||
//// 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;
|
||||
// }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
public static Object bbb(ClassLoaderScopedWeakMapSupplier aaa) {
|
||||
System.out.println("[STD LOG] bbb" + ClassLoaderScopedWeakMapSupplier.class.getName());
|
||||
return aaa.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;
|
||||
|
||||
import datadog.trace.agent.tooling.ClassLoaderScopedWeakMap;
|
||||
import datadog.trace.agent.tooling.ClassLoaderScopedWeakMapSupplier;
|
||||
import datadog.trace.context.TraceScope;
|
||||
import datadog.trace.instrumentation.netty40.client.HttpClientTracingHandler;
|
||||
import datadog.trace.instrumentation.netty40.server.HttpServerTracingHandler;
|
||||
|
@ -9,49 +10,65 @@ import io.opentracing.Span;
|
|||
|
||||
public class AttributeKeys {
|
||||
|
||||
static {
|
||||
System.out.println("Canone!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||
}
|
||||
|
||||
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>
|
||||
PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY =
|
||||
(AttributeKey<TraceScope.Continuation>)
|
||||
ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
|
||||
AttributeKey.class.getClassLoader(),
|
||||
PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME,
|
||||
new ClassLoaderScopedWeakMap.Supplier() {
|
||||
@Override
|
||||
public Object get() {
|
||||
return new AttributeKey<>(PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME);
|
||||
}
|
||||
});
|
||||
PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY = new AttributeKey<>(PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME);
|
||||
// public static final AttributeKey<TraceScope.Continuation>
|
||||
// PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY =
|
||||
// (AttributeKey<TraceScope.Continuation>)
|
||||
// ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
|
||||
// AttributeKey.class.getClassLoader(),
|
||||
// PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY_NAME,
|
||||
// new ClassLoaderScopedWeakMap.Supplier() {
|
||||
// @Override
|
||||
// public Object get() {
|
||||
// return new AttributeKey<>(PARENT_CONNECT_CONTINUATION_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 =
|
||||
(AttributeKey<Span>)
|
||||
ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
|
||||
AttributeKey.class.getClassLoader(),
|
||||
SERVER_ATTRIBUTE_KEY_NAME,
|
||||
new ClassLoaderScopedWeakMap.Supplier() {
|
||||
@Override
|
||||
public Object get() {
|
||||
return new AttributeKey<>(SERVER_ATTRIBUTE_KEY_NAME);
|
||||
}
|
||||
});
|
||||
public static final AttributeKey<Span> SERVER_ATTRIBUTE_KEY = new AttributeKey<>(SERVER_ATTRIBUTE_KEY_NAME);
|
||||
// public static final AttributeKey<Span> SERVER_ATTRIBUTE_KEY =
|
||||
// (AttributeKey<Span>)
|
||||
// ClassLoaderScopedWeakMap.INSTANCE.getOrCreate(
|
||||
// AttributeKey.class.getClassLoader(),
|
||||
// SERVER_ATTRIBUTE_KEY_NAME,
|
||||
// new ClassLoaderScopedWeakMap.Supplier() {
|
||||
// @Override
|
||||
// public Object get() {
|
||||
// return new AttributeKey<>(SERVER_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 =
|
||||
(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);
|
||||
}
|
||||
});
|
||||
// public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY = new AttributeKey<>(CLIENT_ATTRIBUTE_KEY_NAME);
|
||||
// public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY = (AttributeKey<Span>) ClassLoaderScopedWeakMap.aaa(new AttributeKey<>(CLIENT_ATTRIBUTE_KEY_NAME));
|
||||
public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY = (AttributeKey<Span>) ClassLoaderScopedWeakMap.bbb(new ClassLoaderScopedWeakMapSupplier() {
|
||||
@Override
|
||||
public Object get() {
|
||||
System.out.println("[STD LOG] executing the getter");
|
||||
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
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.agent.tooling.ClassLoaderScopedWeakMapSupplier",
|
||||
"datadog.trace.agent.tooling.ClassLoaderScopedWeakMap",
|
||||
packageName + ".AttributeKeys",
|
||||
"datadog.trace.agent.decorator.BaseDecorator",
|
||||
// client helpers
|
||||
|
|
|
@ -55,6 +55,8 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
|
|||
@Override
|
||||
public String[] helperClassNames() {
|
||||
return new String[] {
|
||||
"datadog.trace.agent.tooling.ClassLoaderScopedWeakMapSupplier",
|
||||
"datadog.trace.agent.tooling.ClassLoaderScopedWeakMap",
|
||||
packageName + ".AttributeKeys",
|
||||
"datadog.trace.agent.decorator.BaseDecorator",
|
||||
// client helpers
|
||||
|
|
|
@ -20,6 +20,7 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
|||
|
||||
@Override
|
||||
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)) {
|
||||
ctx.write(msg, prm);
|
||||
return;
|
||||
|
|
|
@ -50,45 +50,45 @@ class Netty40ClientTest extends HttpClientTest<NettyHttpClientDecorator> {
|
|||
false
|
||||
}
|
||||
|
||||
def "connection error (unopened port)"() {
|
||||
given:
|
||||
def uri = new URI("http://localhost:$UNUSABLE_PORT/")
|
||||
|
||||
when:
|
||||
runUnderTrace("parent") {
|
||||
doRequest(method, uri)
|
||||
}
|
||||
|
||||
then:
|
||||
def ex = thrown(Exception)
|
||||
def thrownException = ex instanceof ExecutionException ? ex.cause : ex
|
||||
|
||||
and:
|
||||
assertTraces(1) {
|
||||
trace(0, 2) {
|
||||
basicSpan(it, 0, "parent", thrownException)
|
||||
|
||||
span(1) {
|
||||
operationName "netty.connect"
|
||||
resourceName "netty.connect"
|
||||
childOf span(0)
|
||||
errored true
|
||||
tags {
|
||||
"$Tags.COMPONENT.key" "netty"
|
||||
Class errorClass = ConnectException
|
||||
try {
|
||||
errorClass = Class.forName('io.netty.channel.AbstractChannel$AnnotatedConnectException')
|
||||
} catch (ClassNotFoundException e) {
|
||||
// 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"
|
||||
defaultTags()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
}
|
||||
// def "connection error (unopened port)"() {
|
||||
// given:
|
||||
// def uri = new URI("http://localhost:$UNUSABLE_PORT/")
|
||||
//
|
||||
// when:
|
||||
// runUnderTrace("parent") {
|
||||
// doRequest(method, uri)
|
||||
// }
|
||||
//
|
||||
// then:
|
||||
// def ex = thrown(Exception)
|
||||
// def thrownException = ex instanceof ExecutionException ? ex.cause : ex
|
||||
//
|
||||
// and:
|
||||
// assertTraces(1) {
|
||||
// trace(0, 2) {
|
||||
// basicSpan(it, 0, "parent", thrownException)
|
||||
//
|
||||
// span(1) {
|
||||
// operationName "netty.connect"
|
||||
// resourceName "netty.connect"
|
||||
// childOf span(0)
|
||||
// errored true
|
||||
// tags {
|
||||
// "$Tags.COMPONENT.key" "netty"
|
||||
// Class errorClass = ConnectException
|
||||
// try {
|
||||
// errorClass = Class.forName('io.netty.channel.AbstractChannel$AnnotatedConnectException')
|
||||
// } catch (ClassNotFoundException e) {
|
||||
// // 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"
|
||||
// defaultTags()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// where:
|
||||
// method = "GET"
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -88,232 +88,232 @@ abstract class HttpClientTest<T extends HttpClientDecorator> extends AgentTestRu
|
|||
where:
|
||||
path | tagQueryString
|
||||
"/success" | false
|
||||
"/success" | true
|
||||
"/success?with=params" | false
|
||||
"/success?with=params" | true
|
||||
"/success#with+fragment" | true
|
||||
"/success?with=params#and=fragment" | true
|
||||
// "/success" | true
|
||||
// "/success?with=params" | false
|
||||
// "/success?with=params" | true
|
||||
// "/success#with+fragment" | true
|
||||
// "/success?with=params#and=fragment" | true
|
||||
|
||||
method = "GET"
|
||||
url = server.address.resolve(path)
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "basic #method request with parent"() {
|
||||
when:
|
||||
def status = runUnderTrace("parent") {
|
||||
doRequest(method, server.address.resolve("/success"))
|
||||
}
|
||||
|
||||
then:
|
||||
status == 200
|
||||
assertTraces(2) {
|
||||
server.distributedRequestTrace(it, 0, trace(1).last())
|
||||
trace(1, size(2)) {
|
||||
basicSpan(it, 0, "parent")
|
||||
clientSpan(it, 1, span(0), method, false)
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
method << BODY_METHODS
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "basic #method request with split-by-domain"() {
|
||||
when:
|
||||
def status = withConfigOverride(Config.HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "true") {
|
||||
doRequest(method, server.address.resolve("/success"))
|
||||
}
|
||||
|
||||
then:
|
||||
status == 200
|
||||
assertTraces(2) {
|
||||
server.distributedRequestTrace(it, 0, trace(1).last())
|
||||
trace(1, size(1)) {
|
||||
clientSpan(it, 0, null, method, true)
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
method = "HEAD"
|
||||
}
|
||||
|
||||
def "trace request without propagation"() {
|
||||
when:
|
||||
def status = withConfigOverride(Config.HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "$renameService") {
|
||||
runUnderTrace("parent") {
|
||||
doRequest(method, server.address.resolve("/success"), ["is-dd-server": "false"])
|
||||
}
|
||||
}
|
||||
|
||||
then:
|
||||
status == 200
|
||||
// only one trace (client).
|
||||
assertTraces(1) {
|
||||
trace(0, size(2)) {
|
||||
basicSpan(it, 0, "parent")
|
||||
clientSpan(it, 1, span(0), method, renameService)
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
renameService << [false, true]
|
||||
}
|
||||
|
||||
def "trace request with callback and parent"() {
|
||||
when:
|
||||
def status = runUnderTrace("parent") {
|
||||
doRequest(method, server.address.resolve("/success"), ["is-dd-server": "false"]) {
|
||||
runUnderTrace("child") {}
|
||||
}
|
||||
}
|
||||
|
||||
then:
|
||||
status == 200
|
||||
// only one trace (client).
|
||||
assertTraces(1) {
|
||||
trace(0, size(3)) {
|
||||
basicSpan(it, 0, "parent")
|
||||
span(1) {
|
||||
operationName "child"
|
||||
childOf span(0)
|
||||
}
|
||||
clientSpan(it, 2, span(0), method, false)
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
}
|
||||
|
||||
def "trace request with callback and no parent"() {
|
||||
when:
|
||||
def status = doRequest(method, server.address.resolve("/success"), ["is-dd-server": "false"]) {
|
||||
runUnderTrace("child") {
|
||||
// Ensure consistent ordering of traces for assertion.
|
||||
TEST_WRITER.waitForTraces(1)
|
||||
}
|
||||
}
|
||||
|
||||
then:
|
||||
status == 200
|
||||
// only one trace (client).
|
||||
assertTraces(2) {
|
||||
trace(0, size(1)) {
|
||||
clientSpan(it, 0, null, method, false)
|
||||
}
|
||||
trace(1, 1) {
|
||||
span(0) {
|
||||
operationName "child"
|
||||
parent()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "basic #method request with 1 redirect"() {
|
||||
given:
|
||||
assumeTrue(testRedirects())
|
||||
def uri = server.address.resolve("/redirect")
|
||||
|
||||
when:
|
||||
def status = doRequest(method, uri)
|
||||
|
||||
then:
|
||||
status == 200
|
||||
assertTraces(3) {
|
||||
server.distributedRequestTrace(it, 0, trace(2).last())
|
||||
server.distributedRequestTrace(it, 1, trace(2).last())
|
||||
trace(2, size(1)) {
|
||||
clientSpan(it, 0, null, method, false, false, uri)
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "basic #method request with 2 redirects"() {
|
||||
given:
|
||||
assumeTrue(testRedirects())
|
||||
def uri = server.address.resolve("/another-redirect")
|
||||
|
||||
when:
|
||||
def status = doRequest(method, uri)
|
||||
|
||||
then:
|
||||
status == 200
|
||||
assertTraces(4) {
|
||||
server.distributedRequestTrace(it, 0, trace(3).last())
|
||||
server.distributedRequestTrace(it, 1, trace(3).last())
|
||||
server.distributedRequestTrace(it, 2, trace(3).last())
|
||||
trace(3, size(1)) {
|
||||
clientSpan(it, 0, null, method, false, false, uri)
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
}
|
||||
|
||||
@Unroll
|
||||
def "basic #method request with circular redirects"() {
|
||||
given:
|
||||
assumeTrue(testRedirects())
|
||||
def uri = server.address.resolve("/circular-redirect")
|
||||
|
||||
when:
|
||||
doRequest(method, uri)//, ["is-dd-server": "false"])
|
||||
|
||||
then:
|
||||
def ex = thrown(Exception)
|
||||
def thrownException = ex instanceof ExecutionException ? ex.cause : ex
|
||||
|
||||
and:
|
||||
assertTraces(3) {
|
||||
server.distributedRequestTrace(it, 0, trace(2).last())
|
||||
server.distributedRequestTrace(it, 1, trace(2).last())
|
||||
trace(2, size(1)) {
|
||||
clientSpan(it, 0, null, method, false, false, uri, statusOnRedirectError(), thrownException)
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
}
|
||||
|
||||
def "connection error (unopened port)"() {
|
||||
given:
|
||||
assumeTrue(testConnectionFailure())
|
||||
def uri = new URI("http://localhost:$UNUSABLE_PORT/")
|
||||
|
||||
when:
|
||||
runUnderTrace("parent") {
|
||||
doRequest(method, uri)
|
||||
}
|
||||
|
||||
then:
|
||||
def ex = thrown(Exception)
|
||||
def thrownException = ex instanceof ExecutionException ? ex.cause : ex
|
||||
|
||||
and:
|
||||
assertTraces(1) {
|
||||
trace(0, 2) {
|
||||
basicSpan(it, 0, "parent", thrownException)
|
||||
clientSpan(it, 1, span(0), method, false, false, uri, null, thrownException)
|
||||
}
|
||||
}
|
||||
|
||||
where:
|
||||
method = "GET"
|
||||
}
|
||||
// @Unroll
|
||||
// def "basic #method request with parent"() {
|
||||
// when:
|
||||
// def status = runUnderTrace("parent") {
|
||||
// doRequest(method, server.address.resolve("/success"))
|
||||
// }
|
||||
//
|
||||
// then:
|
||||
// status == 200
|
||||
// assertTraces(2) {
|
||||
// server.distributedRequestTrace(it, 0, trace(1).last())
|
||||
// trace(1, size(2)) {
|
||||
// basicSpan(it, 0, "parent")
|
||||
// clientSpan(it, 1, span(0), method, false)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// where:
|
||||
// method << BODY_METHODS
|
||||
// }
|
||||
//
|
||||
// @Unroll
|
||||
// def "basic #method request with split-by-domain"() {
|
||||
// when:
|
||||
// def status = withConfigOverride(Config.HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "true") {
|
||||
// doRequest(method, server.address.resolve("/success"))
|
||||
// }
|
||||
//
|
||||
// then:
|
||||
// status == 200
|
||||
// assertTraces(2) {
|
||||
// server.distributedRequestTrace(it, 0, trace(1).last())
|
||||
// trace(1, size(1)) {
|
||||
// clientSpan(it, 0, null, method, true)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// where:
|
||||
// method = "HEAD"
|
||||
// }
|
||||
//
|
||||
// def "trace request without propagation"() {
|
||||
// when:
|
||||
// def status = withConfigOverride(Config.HTTP_CLIENT_HOST_SPLIT_BY_DOMAIN, "$renameService") {
|
||||
// runUnderTrace("parent") {
|
||||
// doRequest(method, server.address.resolve("/success"), ["is-dd-server": "false"])
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// then:
|
||||
// status == 200
|
||||
// // only one trace (client).
|
||||
// assertTraces(1) {
|
||||
// trace(0, size(2)) {
|
||||
// basicSpan(it, 0, "parent")
|
||||
// clientSpan(it, 1, span(0), method, renameService)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// where:
|
||||
// method = "GET"
|
||||
// renameService << [false, true]
|
||||
// }
|
||||
//
|
||||
// def "trace request with callback and parent"() {
|
||||
// when:
|
||||
// def status = runUnderTrace("parent") {
|
||||
// doRequest(method, server.address.resolve("/success"), ["is-dd-server": "false"]) {
|
||||
// runUnderTrace("child") {}
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// then:
|
||||
// status == 200
|
||||
// // only one trace (client).
|
||||
// assertTraces(1) {
|
||||
// trace(0, size(3)) {
|
||||
// basicSpan(it, 0, "parent")
|
||||
// span(1) {
|
||||
// operationName "child"
|
||||
// childOf span(0)
|
||||
// }
|
||||
// clientSpan(it, 2, span(0), method, false)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// where:
|
||||
// method = "GET"
|
||||
// }
|
||||
//
|
||||
// def "trace request with callback and no parent"() {
|
||||
// when:
|
||||
// def status = doRequest(method, server.address.resolve("/success"), ["is-dd-server": "false"]) {
|
||||
// runUnderTrace("child") {
|
||||
// // Ensure consistent ordering of traces for assertion.
|
||||
// TEST_WRITER.waitForTraces(1)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// then:
|
||||
// status == 200
|
||||
// // only one trace (client).
|
||||
// assertTraces(2) {
|
||||
// trace(0, size(1)) {
|
||||
// clientSpan(it, 0, null, method, false)
|
||||
// }
|
||||
// trace(1, 1) {
|
||||
// span(0) {
|
||||
// operationName "child"
|
||||
// parent()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// where:
|
||||
// method = "GET"
|
||||
// }
|
||||
//
|
||||
// @Unroll
|
||||
// def "basic #method request with 1 redirect"() {
|
||||
// given:
|
||||
// assumeTrue(testRedirects())
|
||||
// def uri = server.address.resolve("/redirect")
|
||||
//
|
||||
// when:
|
||||
// def status = doRequest(method, uri)
|
||||
//
|
||||
// then:
|
||||
// status == 200
|
||||
// assertTraces(3) {
|
||||
// server.distributedRequestTrace(it, 0, trace(2).last())
|
||||
// server.distributedRequestTrace(it, 1, trace(2).last())
|
||||
// trace(2, size(1)) {
|
||||
// clientSpan(it, 0, null, method, false, false, uri)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// where:
|
||||
// method = "GET"
|
||||
// }
|
||||
//
|
||||
// @Unroll
|
||||
// def "basic #method request with 2 redirects"() {
|
||||
// given:
|
||||
// assumeTrue(testRedirects())
|
||||
// def uri = server.address.resolve("/another-redirect")
|
||||
//
|
||||
// when:
|
||||
// def status = doRequest(method, uri)
|
||||
//
|
||||
// then:
|
||||
// status == 200
|
||||
// assertTraces(4) {
|
||||
// server.distributedRequestTrace(it, 0, trace(3).last())
|
||||
// server.distributedRequestTrace(it, 1, trace(3).last())
|
||||
// server.distributedRequestTrace(it, 2, trace(3).last())
|
||||
// trace(3, size(1)) {
|
||||
// clientSpan(it, 0, null, method, false, false, uri)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// where:
|
||||
// method = "GET"
|
||||
// }
|
||||
//
|
||||
// @Unroll
|
||||
// def "basic #method request with circular redirects"() {
|
||||
// given:
|
||||
// assumeTrue(testRedirects())
|
||||
// def uri = server.address.resolve("/circular-redirect")
|
||||
//
|
||||
// when:
|
||||
// doRequest(method, uri)//, ["is-dd-server": "false"])
|
||||
//
|
||||
// then:
|
||||
// def ex = thrown(Exception)
|
||||
// def thrownException = ex instanceof ExecutionException ? ex.cause : ex
|
||||
//
|
||||
// and:
|
||||
// assertTraces(3) {
|
||||
// server.distributedRequestTrace(it, 0, trace(2).last())
|
||||
// server.distributedRequestTrace(it, 1, trace(2).last())
|
||||
// trace(2, size(1)) {
|
||||
// clientSpan(it, 0, null, method, false, false, uri, statusOnRedirectError(), thrownException)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// where:
|
||||
// method = "GET"
|
||||
// }
|
||||
//
|
||||
// def "connection error (unopened port)"() {
|
||||
// given:
|
||||
// assumeTrue(testConnectionFailure())
|
||||
// def uri = new URI("http://localhost:$UNUSABLE_PORT/")
|
||||
//
|
||||
// when:
|
||||
// runUnderTrace("parent") {
|
||||
// doRequest(method, uri)
|
||||
// }
|
||||
//
|
||||
// then:
|
||||
// def ex = thrown(Exception)
|
||||
// def thrownException = ex instanceof ExecutionException ? ex.cause : ex
|
||||
//
|
||||
// and:
|
||||
// assertTraces(1) {
|
||||
// trace(0, 2) {
|
||||
// basicSpan(it, 0, "parent", thrownException)
|
||||
// clientSpan(it, 1, span(0), method, false, false, uri, null, thrownException)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// where:
|
||||
// method = "GET"
|
||||
// }
|
||||
|
||||
// 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) {
|
||||
|
|
|
@ -38,7 +38,7 @@ public class ListWriter extends CopyOnWriteArrayList<List<DDSpan>> implements Wr
|
|||
}
|
||||
latches.add(latch);
|
||||
}
|
||||
if (!latch.await(20, TimeUnit.SECONDS)) {
|
||||
if (!latch.await(5, TimeUnit.SECONDS)) {
|
||||
throw new TimeoutException(
|
||||
"Timeout waiting for " + number + " trace(s). ListWriter.size() == " + size());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue