Move Apache HttpClient tests to instrumentation

And add latest test.
This commit is contained in:
Tyler Benson 2018-05-18 11:55:58 +10:00
parent f74710a3bc
commit 024d414844
3 changed files with 96 additions and 52 deletions

View File

@ -13,17 +13,25 @@ versionScan {
// "org.apache.http.HttpException" : null, // "org.apache.http.HttpException" : null,
// "org.apache.http.HttpRequest" : null, // "org.apache.http.HttpRequest" : null,
// "org.apache.http.client.RedirectStrategy" : null, // "org.apache.http.client.RedirectStrategy" : null,
"org.apache.http.client.methods.CloseableHttpResponse" : null, "org.apache.http.client.methods.CloseableHttpResponse": null,
"org.apache.http.client.methods.HttpExecutionAware" : null, "org.apache.http.client.methods.HttpExecutionAware" : null,
"org.apache.http.client.methods.HttpRequestWrapper" : null, "org.apache.http.client.methods.HttpRequestWrapper" : null,
"org.apache.http.client.protocol.HttpClientContext" : null, "org.apache.http.client.protocol.HttpClientContext" : null,
// "org.apache.http.conn.routing.HttpRoute" : null, // "org.apache.http.conn.routing.HttpRoute" : null,
"org.apache.http.impl.execchain.ClientExecChain": null "org.apache.http.impl.execchain.ClientExecChain" : null
] ]
} }
apply from: "${rootDir}/gradle/java.gradle" apply from: "${rootDir}/gradle/java.gradle"
apply plugin: 'org.unbroken-dome.test-sets'
testSets {
latestDepTest {
dirName = 'test'
}
}
dependencies { dependencies {
compileOnly group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3' compileOnly group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3'
@ -33,4 +41,10 @@ dependencies {
compile deps.opentracing compile deps.opentracing
annotationProcessor deps.autoservice annotationProcessor deps.autoservice
implementation deps.autoservice implementation deps.autoservice
testCompile project(':dd-java-agent:testing')
testCompile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3'
latestDepTestCompile group: 'org.apache.httpcomponents', name: 'httpclient', version: '+'
} }

View File

@ -1,38 +1,49 @@
package datadog.trace.agent.integration.httpclient
import datadog.opentracing.DDSpan import datadog.opentracing.DDSpan
import datadog.opentracing.DDTracer import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.integration.TestHttpServer
import datadog.trace.agent.test.IntegrationTestUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.common.writer.ListWriter import io.opentracing.Scope
import io.opentracing.SpanContext
import io.opentracing.propagation.Format
import io.opentracing.propagation.TextMap
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import io.opentracing.util.GlobalTracer
import org.apache.http.HttpResponse import org.apache.http.HttpResponse
import org.apache.http.client.HttpClient import org.apache.http.client.HttpClient
import org.apache.http.client.methods.HttpGet import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.HttpClientBuilder import org.apache.http.impl.client.HttpClientBuilder
import org.apache.http.message.BasicHeader import org.apache.http.message.BasicHeader
import ratpack.handling.Context
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification
class ApacheHttpClientTest extends Specification { import static datadog.trace.agent.test.TestUtils.runUnderTrace
import static ratpack.groovy.test.embed.GroovyEmbeddedApp.ratpack
class ApacheHttpClientTest extends AgentTestRunner {
@Shared @Shared
def writer = new ListWriter() def server = ratpack {
@Shared handlers {
def tracer = new DDTracer(writer) get {
String msg = "<html><body><h1>Hello test.</h1>\n"
boolean isDDServer = true
if (context.request.getHeaders().contains("is-dd-server")) {
isDDServer = Boolean.parseBoolean(context.request.getHeaders().get("is-dd-server"))
}
if (isDDServer) {
final SpanContext extractedContext =
GlobalTracer.get()
.extract(Format.Builtin.HTTP_HEADERS, new RatpackResponseAdapter(context))
Scope scope =
GlobalTracer.get()
.buildSpan("test-http-server")
.asChildOf(extractedContext)
.startActive(true)
scope.close()
}
def setupSpec() { response.status(200).send(msg)
IntegrationTestUtils.registerOrReplaceGlobalTracer(tracer) }
TestHttpServer.startServer() }
}
def cleanupSpec() {
TestHttpServer.stopServer()
}
def setup() {
writer.clear()
} }
def "trace request with propagation"() { def "trace request with propagation"() {
@ -40,10 +51,9 @@ class ApacheHttpClientTest extends Specification {
final HttpClientBuilder builder = HttpClientBuilder.create() final HttpClientBuilder builder = HttpClientBuilder.create()
final HttpClient client = builder.build() final HttpClient client = builder.build()
IntegrationTestUtils.runUnderTrace("someTrace") { runUnderTrace("someTrace") {
try { try {
HttpResponse response = HttpResponse response = client.execute(new HttpGet(server.getAddress()))
client.execute(new HttpGet(new URI("http://localhost:" + TestHttpServer.getPort())))
assert response.getStatusLine().getStatusCode() == 200 assert response.getStatusLine().getStatusCode() == 200
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace() e.printStackTrace()
@ -53,11 +63,11 @@ class ApacheHttpClientTest extends Specification {
expect: expect:
// one trace on the server, one trace on the client // one trace on the server, one trace on the client
writer.size() == 2 TEST_WRITER.size() == 2
final List<DDSpan> serverTrace = writer.get(0) final List<DDSpan> serverTrace = TEST_WRITER.get(0)
serverTrace.size() == 1 serverTrace.size() == 1
final List<DDSpan> clientTrace = writer.get(1) final List<DDSpan> clientTrace = TEST_WRITER.get(1)
clientTrace.size() == 3 clientTrace.size() == 3
clientTrace.get(0).getOperationName() == "someTrace" clientTrace.get(0).getOperationName() == "someTrace"
// our instrumentation makes 2 spans for apache-httpclient // our instrumentation makes 2 spans for apache-httpclient
@ -71,9 +81,9 @@ class ApacheHttpClientTest extends Specification {
clientSpan.getType() == DDSpanTypes.HTTP_CLIENT clientSpan.getType() == DDSpanTypes.HTTP_CLIENT
clientSpan.getTags()[Tags.HTTP_METHOD.getKey()] == "GET" clientSpan.getTags()[Tags.HTTP_METHOD.getKey()] == "GET"
clientSpan.getTags()[Tags.HTTP_STATUS.getKey()] == 200 clientSpan.getTags()[Tags.HTTP_STATUS.getKey()] == 200
clientSpan.getTags()[Tags.HTTP_URL.getKey()] == "http://localhost:" + TestHttpServer.getPort() clientSpan.getTags()[Tags.HTTP_URL.getKey()] == server.getAddress().toString()
clientSpan.getTags()[Tags.PEER_HOSTNAME.getKey()] == "localhost" clientSpan.getTags()[Tags.PEER_HOSTNAME.getKey()] == "localhost"
clientSpan.getTags()[Tags.PEER_PORT.getKey()] == TestHttpServer.getPort() clientSpan.getTags()[Tags.PEER_PORT.getKey()] == server.getAddress().port
clientSpan.getTags()[Tags.SPAN_KIND.getKey()] == Tags.SPAN_KIND_CLIENT clientSpan.getTags()[Tags.SPAN_KIND.getKey()] == Tags.SPAN_KIND_CLIENT
// client trace propagates to server // client trace propagates to server
@ -82,17 +92,15 @@ class ApacheHttpClientTest extends Specification {
clientSpan.getSpanId() == serverTrace.get(0).getParentId() clientSpan.getSpanId() == serverTrace.get(0).getParentId()
} }
def "trace request without propagation"() { def "trace request without propagation"() {
setup: setup:
final HttpClientBuilder builder = HttpClientBuilder.create() final HttpClientBuilder builder = HttpClientBuilder.create()
final HttpClient client = builder.build() final HttpClient client = builder.build()
IntegrationTestUtils.runUnderTrace("someTrace") { runUnderTrace("someTrace") {
try { try {
HttpGet request = new HttpGet(new URI("http://localhost:" HttpGet request = new HttpGet(server.getAddress())
+ TestHttpServer.getPort())) request.addHeader(new BasicHeader("is-dd-server", "false"))
request.addHeader(new BasicHeader(TestHttpServer.IS_DD_SERVER, "false"))
HttpResponse response = client.execute(request) HttpResponse response = client.execute(request)
assert response.getStatusLine().getStatusCode() == 200 assert response.getStatusLine().getStatusCode() == 200
} catch (Exception e) { } catch (Exception e) {
@ -102,8 +110,8 @@ class ApacheHttpClientTest extends Specification {
} }
expect: expect:
// only one trace (client). // only one trace (client).
writer.size() == 1 TEST_WRITER.size() == 1
final List<DDSpan> clientTrace = writer.get(0) final List<DDSpan> clientTrace = TEST_WRITER.get(0)
clientTrace.size() == 3 clientTrace.size() == 3
clientTrace.get(0).getOperationName() == "someTrace" clientTrace.get(0).getOperationName() == "someTrace"
// our instrumentation makes 2 spans for apache-httpclient // our instrumentation makes 2 spans for apache-httpclient
@ -115,10 +123,27 @@ class ApacheHttpClientTest extends Specification {
clientSpan.getOperationName() == "http.request" clientSpan.getOperationName() == "http.request"
clientSpan.getTags()[Tags.HTTP_METHOD.getKey()] == "GET" clientSpan.getTags()[Tags.HTTP_METHOD.getKey()] == "GET"
clientSpan.getTags()[Tags.HTTP_STATUS.getKey()] == 200 clientSpan.getTags()[Tags.HTTP_STATUS.getKey()] == 200
clientSpan.getTags()[Tags.HTTP_URL.getKey()] == "http://localhost:" + TestHttpServer.getPort() clientSpan.getTags()[Tags.HTTP_URL.getKey()] == server.getAddress().toString()
clientSpan.getTags()[Tags.PEER_HOSTNAME.getKey()] == "localhost" clientSpan.getTags()[Tags.PEER_HOSTNAME.getKey()] == "localhost"
clientSpan.getTags()[Tags.PEER_PORT.getKey()] == TestHttpServer.getPort() clientSpan.getTags()[Tags.PEER_PORT.getKey()] == server.getAddress().port
clientSpan.getTags()[Tags.SPAN_KIND.getKey()] == Tags.SPAN_KIND_CLIENT clientSpan.getTags()[Tags.SPAN_KIND.getKey()] == Tags.SPAN_KIND_CLIENT
} }
private static class RatpackResponseAdapter implements TextMap {
final Context context
RatpackResponseAdapter(Context context) {
this.context = context
}
@Override
void put(String key, String value) {
context.response.set(key, value)
}
@Override
Iterator<Map.Entry<String, String>> iterator() {
return context.request.getHeaders().asMultiValueMap().entrySet().iterator()
}
}
} }

View File

@ -196,14 +196,19 @@ public class PendingTrace extends ConcurrentLinkedDeque<DDSpan> {
void start() { void start() {
executorService.scheduleAtFixedRate(new SpanCleaner(), 0, CLEAN_FREQUENCY, TimeUnit.SECONDS); executorService.scheduleAtFixedRate(new SpanCleaner(), 0, CLEAN_FREQUENCY, TimeUnit.SECONDS);
Runtime.getRuntime() try {
.addShutdownHook( Runtime.getRuntime()
new Thread() { .addShutdownHook(
@Override new Thread() {
public void run() { @Override
PendingTrace.SpanCleaner.this.close(); public void run() {
} PendingTrace.SpanCleaner.this.close();
}); }
});
} catch (final IllegalStateException ex) {
// The JVM might be shutting down.
log.debug("Error adding shutdown hook.", ex);
}
} }
@Override @Override