diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/ClassLoaderScopedWeakMap.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/ClassLoaderScopedWeakMap.java index 3feb55c009..9d09ae0fa0 100644 --- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/ClassLoaderScopedWeakMap.java +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/ClassLoaderScopedWeakMap.java @@ -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> map = WeakMap.Supplier.DEFAULT.get(); + // private final WeakMap> 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 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 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(); +// } } diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/ClassLoaderScopedWeakMapSupplier.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/ClassLoaderScopedWeakMapSupplier.java new file mode 100644 index 0000000000..a22d706925 --- /dev/null +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/ClassLoaderScopedWeakMapSupplier.java @@ -0,0 +1,5 @@ +package datadog.trace.agent.tooling; + +public interface ClassLoaderScopedWeakMapSupplier { + Object get(); +} diff --git a/dd-java-agent/instrumentation/netty-4.0/netty-4.0.gradle b/dd-java-agent/instrumentation/netty-4.0/netty-4.0.gradle index 447724743b..7b9975492f 100644 --- a/dd-java-agent/instrumentation/netty-4.0/netty-4.0.gradle +++ b/dd-java-agent/instrumentation/netty-4.0/netty-4.0.gradle @@ -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, + } +} diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/AttributeKeys.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/AttributeKeys.java index 7b21590ce8..a4264d41ba 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/AttributeKeys.java +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/AttributeKeys.java @@ -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 - PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY = - (AttributeKey) - 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 +// PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY = +// (AttributeKey) +// 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 SERVER_ATTRIBUTE_KEY = - (AttributeKey) - 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 SERVER_ATTRIBUTE_KEY = new AttributeKey<>(SERVER_ATTRIBUTE_KEY_NAME); +// public static final AttributeKey SERVER_ATTRIBUTE_KEY = +// (AttributeKey) +// 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 CLIENT_ATTRIBUTE_KEY = - (AttributeKey) - 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 CLIENT_ATTRIBUTE_KEY = new AttributeKey<>(CLIENT_ATTRIBUTE_KEY_NAME); +// public static final AttributeKey CLIENT_ATTRIBUTE_KEY = (AttributeKey) ClassLoaderScopedWeakMap.aaa(new AttributeKey<>(CLIENT_ATTRIBUTE_KEY_NAME)); + public static final AttributeKey CLIENT_ATTRIBUTE_KEY = (AttributeKey) 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 CLIENT_ATTRIBUTE_KEY = +// (AttributeKey) +// ClassLoaderScopedWeakMap.INSTANCE.getOrCreate( +// AttributeKey.class.getClassLoader(), +// CLIENT_ATTRIBUTE_KEY_NAME, +// new ClassLoaderScopedWeakMap.Supplier() { +// @Override +// public Object get() { +// return new AttributeKey<>(CLIENT_ATTRIBUTE_KEY_NAME); +// } +// }); } diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/ChannelFutureListenerInstrumentation.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/ChannelFutureListenerInstrumentation.java index 8dbdc73265..a35c37219a 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/ChannelFutureListenerInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/ChannelFutureListenerInstrumentation.java @@ -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 diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java index 501d133134..b65670ea97 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java @@ -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 diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientRequestTracingHandler.java index 6dbb99246a..283c00b9d7 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientRequestTracingHandler.java @@ -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; diff --git a/dd-java-agent/instrumentation/netty-4.0/src/test/groovy/Netty40ClientTest.groovy b/dd-java-agent/instrumentation/netty-4.0/src/test/groovy/Netty40ClientTest.groovy index cdf7c74d77..5e1e09e548 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/test/groovy/Netty40ClientTest.groovy +++ b/dd-java-agent/instrumentation/netty-4.0/src/test/groovy/Netty40ClientTest.groovy @@ -50,45 +50,45 @@ class Netty40ClientTest extends HttpClientTest { 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" +// } } diff --git a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpClientTest.groovy b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpClientTest.groovy index 23c98b1663..d8dfd4daca 100644 --- a/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpClientTest.groovy +++ b/dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/base/HttpClientTest.groovy @@ -88,232 +88,232 @@ abstract class HttpClientTest 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) { diff --git a/dd-trace-ot/src/main/java/datadog/trace/common/writer/ListWriter.java b/dd-trace-ot/src/main/java/datadog/trace/common/writer/ListWriter.java index a92343350d..f0c4f50e26 100644 --- a/dd-trace-ot/src/main/java/datadog/trace/common/writer/ListWriter.java +++ b/dd-trace-ot/src/main/java/datadog/trace/common/writer/ListWriter.java @@ -38,7 +38,7 @@ public class ListWriter extends CopyOnWriteArrayList> 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()); }