Add akka-http to play 2.6 tests

This commit is contained in:
Andrew Kent 2018-06-11 15:46:47 -07:00
parent 5a77ac3749
commit 7ac2bdfc22
4 changed files with 168 additions and 69 deletions

View File

@ -27,11 +27,13 @@ class LagomTest extends AgentTestRunner {
@After @After
@Override @Override
void afterTest() { void afterTest() {
// FIXME: // 'akka/stream/impl/VirtualProcessor$WrappedSubscription$PassThrough$.class' declares
// skipping error check // itself an implementation of 'VirtualProcessor$WrappedSubscription$$SubscriptionState',
// bytebuddy is having trouble resolving akka.stream.impl.VirtualProcessor$WrappedSubscription$$SubscriptionState // but this interface does not exist on the classpath.
// possibly due to '$$' in class name? // The closest thing on the classpath is 'VirtualProcessor$WrappedSubscription$SubscriptionState' (only one $).
// class is on the classpath.
// Looks like a compiler/packaging issue on akka's end. Or maybe this interface is dynamically generated.
// Either way, we're going to error out.
} }
def setupSpec() { def setupSpec() {

View File

@ -23,6 +23,7 @@ dependencies {
testCompile project(':dd-java-agent:testing') testCompile project(':dd-java-agent:testing')
testCompile project(':dd-java-agent:instrumentation:java-concurrent') testCompile project(':dd-java-agent:instrumentation:java-concurrent')
testCompile project(':dd-java-agent:instrumentation:trace-annotation') testCompile project(':dd-java-agent:instrumentation:trace-annotation')
testCompile project(':dd-java-agent:instrumentation:akka-http-10.0')
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0' testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
latestDepTestCompile group: 'org.scala-lang', name: 'scala-library', version: '2.11.12' latestDepTestCompile group: 'org.scala-lang', name: 'scala-library', version: '2.11.12'

View File

@ -1,4 +1,3 @@
import datadog.opentracing.DDSpan
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.TestUtils import datadog.trace.agent.test.TestUtils
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
@ -7,7 +6,13 @@ import play.api.test.TestServer
import play.test.Helpers import play.test.Helpers
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
class Play26Test extends AgentTestRunner { class Play26Test extends AgentTestRunner {
static {
System.setProperty("dd.integration.akkahttp.enabled", "true")
}
@Shared @Shared
int port = TestUtils.randomOpenPort() int port = TestUtils.randomOpenPort()
@Shared @Shared
@ -32,30 +37,49 @@ class Play26Test extends AgentTestRunner {
.get() .get()
.build() .build()
def response = client.newCall(request).execute() def response = client.newCall(request).execute()
TEST_WRITER.waitForTraces(1)
DDSpan[] playTrace = TEST_WRITER.get(0)
DDSpan root = playTrace[0]
expect: expect:
testServer != null
response.code() == 200 response.code() == 200
response.body().string() == "hello spock" response.body().string() == "hello spock"
assertTraces(TEST_WRITER, 1) {
// async work is linked to play trace trace(0, 3) {
playTrace.size() == 2 span(0) {
playTrace[1].operationName == 'TracedWork$.doWork' traceId 123
parentId 456
root.traceId == 123 serviceName "unnamed-java-app"
root.parentId == 456 operationName "akkahttp.request"
root.serviceName == "unnamed-java-app" resourceName "GET /helloplay/:from"
root.operationName == "play.request" errored false
root.resourceName == "GET /helloplay/:from" tags {
!root.context().getErrorFlag() defaultTags()
root.context().tags["http.status_code"] == 200 "http.status_code" 200
root.context().tags["http.url"] == "/helloplay/:from" "http.url" "http://localhost:$port/helloplay/spock"
root.context().tags["http.method"] == "GET" "http.method" "GET"
root.context().tags["span.kind"] == "server" "span.kind" "server"
root.context().tags["component"] == "play-action" "span.type" "web"
"component" "akkahttp-action"
}
}
span(1) {
childOf span(0)
operationName "play.request"
resourceName "GET /helloplay/:from"
tags {
defaultTags()
"http.status_code" 200
"http.url" "/helloplay/:from"
"http.method" "GET"
"span.kind" "server"
"span.type" "web"
"component" "play-action"
}
}
span(2) {
childOf span(1)
operationName 'TracedWork$.doWork'
}
}
}
} }
def "5xx errors trace" () { def "5xx errors trace" () {
@ -66,23 +90,45 @@ class Play26Test extends AgentTestRunner {
.get() .get()
.build() .build()
def response = client.newCall(request).execute() def response = client.newCall(request).execute()
TEST_WRITER.waitForTraces(1)
DDSpan[] playTrace = TEST_WRITER.get(0)
DDSpan root = playTrace[0]
expect: expect:
testServer != null
response.code() == 500 response.code() == 500
assertTraces(TEST_WRITER, 1) {
root.serviceName == "unnamed-java-app" trace(0, 2) {
root.operationName == "play.request" span(0) {
root.resourceName == "GET /make-error" serviceName "unnamed-java-app"
root.context().getErrorFlag() operationName "akkahttp.request"
root.context().tags["http.status_code"] == 500 resourceName "GET /make-error"
root.context().tags["http.url"] == "/make-error" errored true
root.context().tags["http.method"] == "GET" tags {
root.context().tags["span.kind"] == "server" defaultTags()
root.context().tags["component"] == "play-action" "http.status_code" 500
"http.url" "http://localhost:$port/make-error"
"http.method" "GET"
"span.kind" "server"
"span.type" "web"
"component" "akkahttp-action"
"error" true
}
}
span(1) {
childOf span(0)
operationName "play.request"
resourceName "GET /make-error"
errored true
tags {
defaultTags()
"http.status_code" 500
"http.url" "/make-error"
"http.method" "GET"
"span.kind" "server"
"span.type" "web"
"component" "play-action"
"error" true
}
}
}
}
} }
def "error thrown in request" () { def "error thrown in request" () {
@ -93,26 +139,49 @@ class Play26Test extends AgentTestRunner {
.get() .get()
.build() .build()
def response = client.newCall(request).execute() def response = client.newCall(request).execute()
TEST_WRITER.waitForTraces(1)
DDSpan[] playTrace = TEST_WRITER.get(0)
DDSpan root = playTrace[0]
expect: expect:
testServer != null testServer != null
response.code() == 500 response.code() == 500
assertTraces(TEST_WRITER, 1) {
root.context().getErrorFlag() trace(0, 2) {
root.context().tags["error.msg"] == "oh no" span(0) {
root.context().tags["error.type"] == RuntimeException.getName() serviceName "unnamed-java-app"
operationName "akkahttp.request"
root.serviceName == "unnamed-java-app" resourceName "GET /exception"
root.operationName == "play.request" errored true
root.resourceName == "GET /exception" tags {
root.context().tags["http.status_code"] == 500 defaultTags()
root.context().tags["http.url"] == "/exception" "http.status_code" 500
root.context().tags["http.method"] == "GET" "http.url" "http://localhost:$port/exception"
root.context().tags["span.kind"] == "server" "http.method" "GET"
root.context().tags["component"] == "play-action" "span.kind" "server"
"span.type" "web"
"component" "akkahttp-action"
"error" true
}
}
span(1) {
childOf span(0)
operationName "play.request"
resourceName "GET /exception"
errored true
tags {
defaultTags()
"http.status_code" 500
"http.url" "/exception"
"http.method" "GET"
"span.kind" "server"
"span.type" "web"
"component" "play-action"
"error" true
"error.msg" "oh no"
"error.type" RuntimeException.getName()
"error.stack" tag("error.stack")
}
}
}
}
} }
def "4xx errors trace" () { def "4xx errors trace" () {
@ -123,22 +192,42 @@ class Play26Test extends AgentTestRunner {
.get() .get()
.build() .build()
def response = client.newCall(request).execute() def response = client.newCall(request).execute()
TEST_WRITER.waitForTraces(1)
DDSpan[] playTrace = TEST_WRITER.get(0)
DDSpan root = playTrace[0]
expect: expect:
testServer != null
response.code() == 404 response.code() == 404
root.serviceName == "unnamed-java-app" assertTraces(TEST_WRITER, 1) {
root.operationName == "play.request" trace(0, 2) {
root.resourceName == "404" span(0) {
!root.context().getErrorFlag() serviceName "unnamed-java-app"
root.context().tags["http.status_code"] == 404 operationName "akkahttp.request"
root.context().tags["http.url"] == null resourceName "404"
root.context().tags["http.method"] == "GET" errored false
root.context().tags["span.kind"] == "server" tags {
root.context().tags["component"] == "play-action" defaultTags()
"http.status_code" 404
"http.url" "http://localhost:$port/nowhere"
"http.method" "GET"
"span.kind" "server"
"span.type" "web"
"component" "akkahttp-action"
}
}
span(1) {
childOf span(0)
operationName "play.request"
resourceName "404"
errored false
tags {
defaultTags()
"http.status_code" 404
"http.method" "GET"
"span.kind" "server"
"span.type" "web"
"component" "play-action"
}
}
}
}
} }
} }

View File

@ -130,6 +130,13 @@ public final class PlayInstrumentation extends Instrumenter.Configurable {
scope.span().finish(); scope.span().finish();
} }
scope.close(); scope.close();
final Span rootSpan = GlobalTracer.get().activeSpan();
if (rootSpan != null && !pathOption.isEmpty()) {
// set the resource name on the upstream akka/netty span
final String path = (String) pathOption.get();
rootSpan.setTag(DDTags.RESOURCE_NAME, req.method() + " " + path);
}
} }
} }