Merge pull request #444 from DataDog/tyler/test-http-server

Replace Ratpack test server with Jetty wrapped with groovy
This commit is contained in:
Tyler Benson 2018-08-17 11:38:21 +10:00 committed by GitHub
commit f7407708a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
79 changed files with 978 additions and 502 deletions

View File

@ -11,6 +11,7 @@ dependencies {
testCompile deps.opentracingMock testCompile deps.opentracingMock
testCompile deps.testLogging testCompile deps.testLogging
testCompile deps.guava
testCompile group: 'org.mongodb', name: 'mongo-java-driver', version: '3.4.2' testCompile group: 'org.mongodb', name: 'mongo-java-driver', version: '3.4.2'
testCompile group: 'org.mongodb', name: 'mongodb-driver-async', version: '3.4.2' testCompile group: 'org.mongodb', name: 'mongodb-driver-async', version: '3.4.2'

View File

@ -41,6 +41,3 @@ dependencies {
test.dependsOn lagomTest test.dependsOn lagomTest
testJava8Minimum += '*Test*.class' testJava8Minimum += '*Test*.class'
// These classes use Ratpack which requires Java 8. (Currently also incompatible with Java 9.)
testJava8Only += '**/AkkaHttpClientInstrumentationTest.class'

View File

@ -14,7 +14,7 @@ import java.util.function.Function
import static com.lightbend.lagom.javadsl.testkit.ServiceTest.TestServer import static com.lightbend.lagom.javadsl.testkit.ServiceTest.TestServer
import static com.lightbend.lagom.javadsl.testkit.ServiceTest.defaultSetup import static com.lightbend.lagom.javadsl.testkit.ServiceTest.defaultSetup
import static com.lightbend.lagom.javadsl.testkit.ServiceTest.startServer import static com.lightbend.lagom.javadsl.testkit.ServiceTest.startServer
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class LagomTest extends AgentTestRunner { class LagomTest extends AgentTestRunner {
static { static {

View File

@ -8,18 +8,18 @@ import akka.stream.StreamTcpException
import akka.stream.javadsl.Sink import akka.stream.javadsl.Sink
import akka.stream.javadsl.Source import akka.stream.javadsl.Source
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.RatpackUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import scala.util.Try import scala.util.Try
import spock.lang.AutoCleanup
import spock.lang.Shared import spock.lang.Shared
import java.util.concurrent.CompletionStage import java.util.concurrent.CompletionStage
import java.util.concurrent.ExecutionException import java.util.concurrent.ExecutionException
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static ratpack.groovy.test.embed.GroovyEmbeddedApp.ratpack import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
class AkkaHttpClientInstrumentationTest extends AgentTestRunner { class AkkaHttpClientInstrumentationTest extends AgentTestRunner {
static { static {
@ -29,26 +29,23 @@ class AkkaHttpClientInstrumentationTest extends AgentTestRunner {
private static final String MESSAGE = "an\nmultiline\nhttp\nresponse" private static final String MESSAGE = "an\nmultiline\nhttp\nresponse"
private static final long TIMEOUT = 10000L private static final long TIMEOUT = 10000L
@AutoCleanup
@Shared @Shared
def server = ratpack { def server = httpServer {
handlers { handlers {
prefix("success") { prefix("success") {
all { handleDistributedRequest()
RatpackUtils.handleDistributedRequest(context)
response.status(200).send(MESSAGE) response.status(200).send(MESSAGE)
} }
}
prefix("error") { prefix("error") {
all { handleDistributedRequest()
RatpackUtils.handleDistributedRequest(context)
throw new RuntimeException("error") throw new RuntimeException("error")
} }
} }
} }
}
@Shared @Shared
ActorSystem system = ActorSystem.create() ActorSystem system = ActorSystem.create()
@ -77,16 +74,7 @@ class AkkaHttpClientInstrumentationTest extends AgentTestRunner {
} }
assertTraces(TEST_WRITER, 2) { assertTraces(TEST_WRITER, 2) {
trace(0, 1) { server.distributedRequestTrace(it, 0, TEST_WRITER[1][0])
span(0) {
operationName "test-http-server"
childOf(TEST_WRITER[1][0])
errored false
tags {
defaultTags()
}
}
}
trace(1, 1) { trace(1, 1) {
span(0) { span(0) {
parent() parent()
@ -98,7 +86,7 @@ class AkkaHttpClientInstrumentationTest extends AgentTestRunner {
tags { tags {
defaultTags() defaultTags()
"$Tags.HTTP_STATUS.key" expectedStatus "$Tags.HTTP_STATUS.key" expectedStatus
"$Tags.HTTP_URL.key" "${server.address}$route" "$Tags.HTTP_URL.key" "${server.address}/$route"
"$Tags.HTTP_METHOD.key" "GET" "$Tags.HTTP_METHOD.key" "GET"
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_CLIENT "$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_CLIENT
@ -206,16 +194,7 @@ class AkkaHttpClientInstrumentationTest extends AgentTestRunner {
} }
assertTraces(TEST_WRITER, 2) { assertTraces(TEST_WRITER, 2) {
trace(0, 1) { server.distributedRequestTrace(it, 0, TEST_WRITER[1][0])
span(0) {
operationName "test-http-server"
childOf(TEST_WRITER[1][0])
errored false
tags {
defaultTags()
}
}
}
trace(1, 1) { trace(1, 1) {
span(0) { span(0) {
parent() parent()
@ -227,7 +206,7 @@ class AkkaHttpClientInstrumentationTest extends AgentTestRunner {
tags { tags {
defaultTags() defaultTags()
"$Tags.HTTP_STATUS.key" expectedStatus "$Tags.HTTP_STATUS.key" expectedStatus
"$Tags.HTTP_URL.key" "${server.address}$route" "$Tags.HTTP_URL.key" "${server.address}/$route"
"$Tags.HTTP_METHOD.key" "GET" "$Tags.HTTP_METHOD.key" "GET"
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
"$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_CLIENT "$DDTags.SPAN_TYPE" DDSpanTypes.HTTP_CLIENT

View File

@ -6,7 +6,7 @@ import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class AkkaHttpServerInstrumentationTest extends AgentTestRunner { class AkkaHttpServerInstrumentationTest extends AgentTestRunner {
static { static {

View File

@ -24,9 +24,6 @@ versionScan {
apply from: "${rootDir}/gradle/java.gradle" apply from: "${rootDir}/gradle/java.gradle"
// These classes use Ratpack which requires Java 8. (Currently also incompatible with Java 9.)
testJava8Only += '**/ApacheHttpClientTest.class'
apply plugin: 'org.unbroken-dome.test-sets' apply plugin: 'org.unbroken-dome.test-sets'
testSets { testSets {

View File

@ -1,8 +1,6 @@
import datadog.opentracing.DDSpan import datadog.opentracing.DDSpan
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.ListWriterAssert import datadog.trace.agent.test.asserts.TraceAssert
import datadog.trace.agent.test.RatpackUtils
import datadog.trace.agent.test.TraceAssert
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
@ -13,40 +11,33 @@ import org.apache.http.client.config.RequestConfig
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 spock.lang.AutoCleanup
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static ratpack.groovy.test.embed.GroovyEmbeddedApp.ratpack import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
class ApacheHttpClientTest extends AgentTestRunner { class ApacheHttpClientTest extends AgentTestRunner {
@AutoCleanup
@Shared @Shared
def server = ratpack { def server = httpServer {
handlers { handlers {
prefix("success") { prefix("success") {
get { handleDistributedRequest()
RatpackUtils.handleDistributedRequest(context)
String msg = "<html><body><h1>Hello test.</h1>\n" String msg = "<html><body><h1>Hello test.</h1>\n"
response.status(200).send(msg) response.status(200).send(msg)
} }
}
prefix("redirect") { prefix("redirect") {
get { handleDistributedRequest()
RatpackUtils.handleDistributedRequest(context)
redirect(server.address.resolve("/success").toURL().toString()) redirect(server.address.resolve("/success").toURL().toString())
} }
}
prefix("another-redirect") { prefix("another-redirect") {
get { handleDistributedRequest()
RatpackUtils.handleDistributedRequest(context)
redirect(server.address.resolve("/redirect").toURL().toString()) redirect(server.address.resolve("/redirect").toURL().toString())
} }
} }
} }
}
@Shared @Shared
int port = server.address.port int port = server.address.port
@Shared @Shared
@ -67,7 +58,7 @@ class ApacheHttpClientTest extends AgentTestRunner {
response.getStatusLine().getStatusCode() == 200 response.getStatusLine().getStatusCode() == 200
// one trace on the server, one trace on the client // one trace on the server, one trace on the client
assertTraces(TEST_WRITER, 2) { assertTraces(TEST_WRITER, 2) {
serverTrace(it, 0, TEST_WRITER[1][1]) server.distributedRequestTrace(it, 0, TEST_WRITER[1][1])
trace(1, 2) { trace(1, 2) {
clientParentSpan(it, 0) clientParentSpan(it, 0)
successClientSpan(it, 1, span(0)) successClientSpan(it, 1, span(0))
@ -90,8 +81,8 @@ class ApacheHttpClientTest extends AgentTestRunner {
response.getStatusLine().getStatusCode() == 200 response.getStatusLine().getStatusCode() == 200
// two traces on the server, one trace on the client // two traces on the server, one trace on the client
assertTraces(TEST_WRITER, 3) { assertTraces(TEST_WRITER, 3) {
serverTrace(it, 0, TEST_WRITER[2][2]) server.distributedRequestTrace(it, 0, TEST_WRITER[2][2])
serverTrace(it, 1, TEST_WRITER[2][1]) server.distributedRequestTrace(it, 1, TEST_WRITER[2][1])
trace(2, 3) { trace(2, 3) {
clientParentSpan(it, 0) clientParentSpan(it, 0)
successClientSpan(it, 1, span(0)) successClientSpan(it, 1, span(0))
@ -114,8 +105,8 @@ class ApacheHttpClientTest extends AgentTestRunner {
response.getStatusLine().getStatusCode() == 200 response.getStatusLine().getStatusCode() == 200
// two traces on the server, one trace on the client // two traces on the server, one trace on the client
assertTraces(TEST_WRITER, 3) { assertTraces(TEST_WRITER, 3) {
serverTrace(it, 0, TEST_WRITER[2][2]) server.distributedRequestTrace(it, 0, TEST_WRITER[2][2])
serverTrace(it, 1, TEST_WRITER[2][1]) server.distributedRequestTrace(it, 1, TEST_WRITER[2][1])
trace(2, 3) { trace(2, 3) {
clientParentSpan(it, 0) clientParentSpan(it, 0)
successClientSpan(it, 1, span(0)) successClientSpan(it, 1, span(0))
@ -139,8 +130,8 @@ class ApacheHttpClientTest extends AgentTestRunner {
def exception = thrown(ClientProtocolException) def exception = thrown(ClientProtocolException)
// two traces on the server, one trace on the client // two traces on the server, one trace on the client
assertTraces(TEST_WRITER, 3) { assertTraces(TEST_WRITER, 3) {
serverTrace(it, 0, TEST_WRITER[2][2]) server.distributedRequestTrace(it, 0, TEST_WRITER[2][2])
serverTrace(it, 1, TEST_WRITER[2][1]) server.distributedRequestTrace(it, 1, TEST_WRITER[2][1])
trace(2, 3) { trace(2, 3) {
clientParentSpan(it, 0, exception) clientParentSpan(it, 0, exception)
redirectClientSpan(it, 1, span(0)) redirectClientSpan(it, 1, span(0))
@ -168,21 +159,6 @@ class ApacheHttpClientTest extends AgentTestRunner {
} }
} }
def serverTrace(ListWriterAssert writer, int index, DDSpan parent) {
writer.trace(index, 1) {
span(0) {
childOf parent
serviceName "unnamed-java-app"
operationName "test-http-server"
resourceName "test-http-server"
errored false
tags {
defaultTags()
}
}
}
}
def clientParentSpan(TraceAssert trace, int index, Throwable exception = null) { def clientParentSpan(TraceAssert trace, int index, Throwable exception = null) {
trace.span(index) { trace.span(index) {
parent() parent()

View File

@ -46,9 +46,6 @@ testSets {
} }
} }
// These classes use Ratpack which requires Java 8. (Currently also incompatible with Java 9.)
testJava8Only += '**/AWSClientTest.class'
dependencies { dependencies {
compileOnly group: 'com.amazonaws', name: 'aws-java-sdk-core', version: '1.11.0' compileOnly group: 'com.amazonaws', name: 'aws-java-sdk-core', version: '1.11.0'

View File

@ -9,12 +9,12 @@ import com.amazonaws.services.s3.S3ClientOptions
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import ratpack.http.Headers import spock.lang.AutoCleanup
import spock.lang.Shared import spock.lang.Shared
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
import static ratpack.groovy.test.embed.GroovyEmbeddedApp.ratpack import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
class AWSClientTest extends AgentTestRunner { class AWSClientTest extends AgentTestRunner {
def setupSpec() { def setupSpec() {
@ -27,15 +27,13 @@ class AWSClientTest extends AgentTestRunner {
System.clearProperty(SDKGlobalConfiguration.SECRET_KEY_SYSTEM_PROPERTY) System.clearProperty(SDKGlobalConfiguration.SECRET_KEY_SYSTEM_PROPERTY)
} }
@Shared
def receivedHeaders = new AtomicReference<Headers>()
@Shared @Shared
def responseBody = new AtomicReference<String>() def responseBody = new AtomicReference<String>()
@AutoCleanup
@Shared @Shared
def server = ratpack { def server = httpServer {
handlers { handlers {
all { all {
receivedHeaders.set(request.headers)
response.status(200).send(responseBody.get()) response.status(200).send(responseBody.get())
} }
} }
@ -148,8 +146,8 @@ class AWSClientTest extends AgentTestRunner {
tags["thread.id"] != null tags["thread.id"] != null
tags.size() == 13 tags.size() == 13
receivedHeaders.get().get("x-datadog-trace-id") == "$span.traceId" server.lastRequest.headers.get("x-datadog-trace-id") == "$span.traceId"
receivedHeaders.get().get("x-datadog-parent-id") == "$span.spanId" server.lastRequest.headers.get("x-datadog-parent-id") == "$span.spanId"
where: where:
service | operation | method | url | handlerCount | call | body | params | client service | operation | method | url | handlerCount | call | body | params | client

View File

@ -19,9 +19,6 @@ testSets {
} }
} }
// These classes use Ratpack which requires Java 8. (Currently also incompatible with Java 9.)
testJava8Only += '**/AWSClientTest.class'
dependencies { dependencies {
compileOnly group: 'com.amazonaws', name: 'aws-java-sdk-core', version: '1.11.106' compileOnly group: 'com.amazonaws', name: 'aws-java-sdk-core', version: '1.11.106'

View File

@ -14,12 +14,12 @@ import com.amazonaws.services.s3.AmazonS3ClientBuilder
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import ratpack.http.Headers import spock.lang.AutoCleanup
import spock.lang.Shared import spock.lang.Shared
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
import static ratpack.groovy.test.embed.GroovyEmbeddedApp.ratpack import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
class AWSClientTest extends AgentTestRunner { class AWSClientTest extends AgentTestRunner {
def setupSpec() { def setupSpec() {
@ -35,14 +35,12 @@ class AWSClientTest extends AgentTestRunner {
@Shared @Shared
def credentialsProvider = new AWSStaticCredentialsProvider(new AnonymousAWSCredentials()) def credentialsProvider = new AWSStaticCredentialsProvider(new AnonymousAWSCredentials())
@Shared @Shared
def receivedHeaders = new AtomicReference<Headers>()
@Shared
def responseBody = new AtomicReference<String>() def responseBody = new AtomicReference<String>()
@AutoCleanup
@Shared @Shared
def server = ratpack { def server = httpServer {
handlers { handlers {
all { all {
receivedHeaders.set(request.headers)
response.status(200).send(responseBody.get()) response.status(200).send(responseBody.get())
} }
} }
@ -177,8 +175,8 @@ class AWSClientTest extends AgentTestRunner {
tags["thread.id"] != null tags["thread.id"] != null
tags.size() == 13 tags.size() == 13
receivedHeaders.get().get("x-datadog-trace-id") == "$span.traceId" server.lastRequest.headers.get("x-datadog-trace-id") == "$span.traceId"
receivedHeaders.get().get("x-datadog-parent-id") == "$span.spanId" server.lastRequest.headers.get("x-datadog-parent-id") == "$span.spanId"
where: where:
service | operation | method | url | handlerCount | call | body | params | client service | operation | method | url | handlerCount | call | body | params | client

View File

@ -17,7 +17,7 @@ import org.elasticsearch.node.Node
import org.elasticsearch.transport.Netty4Plugin import org.elasticsearch.transport.Netty4Plugin
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class Elasticsearch6RestClientTest extends AgentTestRunner { class Elasticsearch6RestClientTest extends AgentTestRunner {
static { static {

View File

@ -18,7 +18,7 @@ import org.elasticsearch.node.internal.InternalSettingsPreparer
import org.elasticsearch.transport.Netty3Plugin import org.elasticsearch.transport.Netty3Plugin
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING import static org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING
class Elasticsearch5RestClientTest extends AgentTestRunner { class Elasticsearch5RestClientTest extends AgentTestRunner {

View File

@ -11,7 +11,7 @@ import org.elasticsearch.node.Node
import org.elasticsearch.node.NodeBuilder import org.elasticsearch.node.NodeBuilder
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class Elasticsearch2NodeClientTest extends AgentTestRunner { class Elasticsearch2NodeClientTest extends AgentTestRunner {
static { static {

View File

@ -21,7 +21,7 @@ import springdata.Doc
import java.util.concurrent.atomic.AtomicLong import java.util.concurrent.atomic.AtomicLong
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class Elasticsearch2SpringTemplateTest extends AgentTestRunner { class Elasticsearch2SpringTemplateTest extends AgentTestRunner {
static { static {

View File

@ -14,7 +14,7 @@ import org.elasticsearch.node.NodeBuilder
import org.elasticsearch.transport.RemoteTransportException import org.elasticsearch.transport.RemoteTransportException
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class Elasticsearch2TransportClientTest extends AgentTestRunner { class Elasticsearch2TransportClientTest extends AgentTestRunner {
static { static {

View File

@ -8,7 +8,7 @@ import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.AnnotationConfigApplicationContext import org.springframework.context.annotation.AnnotationConfigApplicationContext
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class Elasticsearch2SpringRepositoryTest extends AgentTestRunner { class Elasticsearch2SpringRepositoryTest extends AgentTestRunner {
static { static {

View File

@ -13,7 +13,7 @@ import org.elasticsearch.node.internal.InternalSettingsPreparer
import org.elasticsearch.transport.Netty3Plugin import org.elasticsearch.transport.Netty3Plugin
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING import static org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING
class Elasticsearch5NodeClientTest extends AgentTestRunner { class Elasticsearch5NodeClientTest extends AgentTestRunner {

View File

@ -17,7 +17,7 @@ import org.elasticsearch.transport.RemoteTransportException
import org.elasticsearch.transport.client.PreBuiltTransportClient import org.elasticsearch.transport.client.PreBuiltTransportClient
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING import static org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING
class Elasticsearch5TransportClientTest extends AgentTestRunner { class Elasticsearch5TransportClientTest extends AgentTestRunner {

View File

@ -12,7 +12,7 @@ import org.elasticsearch.node.Node
import org.elasticsearch.transport.Netty4Plugin import org.elasticsearch.transport.Netty4Plugin
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING import static org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING
class Elasticsearch6NodeClientTest extends AgentTestRunner { class Elasticsearch6NodeClientTest extends AgentTestRunner {

View File

@ -16,7 +16,7 @@ import org.elasticsearch.transport.RemoteTransportException
import org.elasticsearch.transport.client.PreBuiltTransportClient import org.elasticsearch.transport.client.PreBuiltTransportClient
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING import static org.elasticsearch.cluster.ClusterName.CLUSTER_NAME_SETTING
class Elasticsearch6TransportClientTest extends AgentTestRunner { class Elasticsearch6TransportClientTest extends AgentTestRunner {

View File

@ -15,7 +15,7 @@ import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class GrpcStreamingTest extends AgentTestRunner { class GrpcStreamingTest extends AgentTestRunner {
static { static {

View File

@ -15,7 +15,7 @@ import io.opentracing.tag.Tags
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class GrpcTest extends AgentTestRunner { class GrpcTest extends AgentTestRunner {
static { static {

View File

@ -1,8 +1,5 @@
apply from: "${rootDir}/gradle/java.gradle" apply from: "${rootDir}/gradle/java.gradle"
// These classes use Ratpack which requires Java 8. (Currently also incompatible with Java 9.)
testJava8Only += '**/*Test.class'
dependencies { dependencies {
compile project(':dd-java-agent:agent-tooling') compile project(':dd-java-agent:agent-tooling')

View File

@ -1,19 +1,15 @@
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.RatpackUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import io.opentracing.propagation.TextMap
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import io.opentracing.util.GlobalTracer import io.opentracing.util.GlobalTracer
import org.springframework.web.client.RestTemplate import org.springframework.web.client.RestTemplate
import ratpack.handling.Context import spock.lang.AutoCleanup
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.TestUtils.runUnderTrace import static datadog.trace.agent.test.TestUtils.runUnderTrace
import static ratpack.groovy.test.embed.GroovyEmbeddedApp.ratpack import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static ratpack.http.HttpMethod.HEAD import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
import static ratpack.http.HttpMethod.POST
class HttpUrlConnectionTest extends AgentTestRunner { class HttpUrlConnectionTest extends AgentTestRunner {
static { static {
@ -23,26 +19,14 @@ class HttpUrlConnectionTest extends AgentTestRunner {
static final RESPONSE = "<html><body><h1>Hello test.</h1>" static final RESPONSE = "<html><body><h1>Hello test.</h1>"
static final STATUS = 202 static final STATUS = 202
@AutoCleanup
@Shared @Shared
def server = ratpack { def server = httpServer {
handlers { handlers {
all { all {
RatpackUtils.handleDistributedRequest(context) handleDistributedRequest()
request.body.then { response.status(STATUS).send(RESPONSE)
if (it != null) {
println "RECEIVED: $it.text"
}
response.status(STATUS)
// Ratpack seems to be sending body with HEAD requests - RFC specifically forbids this.
// This becomes a major problem with keep-alived requests - client seems to fail to parse
// such response properly messing up following requests.
if (request.method.isHead()) {
response.send()
} else {
response.send(RESPONSE)
}
}
} }
} }
} }
@ -73,26 +57,8 @@ class HttpUrlConnectionTest extends AgentTestRunner {
expect: expect:
assertTraces(TEST_WRITER, 3) { assertTraces(TEST_WRITER, 3) {
trace(0, 1) { server.distributedRequestTrace(it, 0, TEST_WRITER[2][2])
span(0) { server.distributedRequestTrace(it, 1, TEST_WRITER[2][1])
operationName "test-http-server"
childOf(TEST_WRITER[2][2])
errored false
tags {
defaultTags()
}
}
}
trace(1, 1) {
span(0) {
operationName "test-http-server"
childOf(TEST_WRITER[2][1])
errored false
tags {
defaultTags()
}
}
}
trace(2, 3) { trace(2, 3) {
span(0) { span(0) {
operationName "someTrace" operationName "someTrace"
@ -221,7 +187,7 @@ class HttpUrlConnectionTest extends AgentTestRunner {
setup: setup:
runUnderTrace("someTrace") { runUnderTrace("someTrace") {
HttpURLConnection connection = server.address.toURL().openConnection() HttpURLConnection connection = server.address.toURL().openConnection()
connection.setRequestMethod(HEAD.name) connection.setRequestMethod("HEAD")
connection.addRequestProperty("is-dd-server", "false") connection.addRequestProperty("is-dd-server", "false")
assert GlobalTracer.get().scopeManager().active() != null assert GlobalTracer.get().scopeManager().active() != null
assert connection.getResponseCode() == STATUS assert connection.getResponseCode() == STATUS
@ -310,7 +276,7 @@ class HttpUrlConnectionTest extends AgentTestRunner {
setup: setup:
runUnderTrace("someTrace") { runUnderTrace("someTrace") {
HttpURLConnection connection = server.address.toURL().openConnection() HttpURLConnection connection = server.address.toURL().openConnection()
connection.setRequestMethod(POST.name) connection.setRequestMethod("POST")
String urlParameters = "q=ASDF&w=&e=&r=12345&t=" String urlParameters = "q=ASDF&w=&e=&r=12345&t="
@ -331,16 +297,7 @@ class HttpUrlConnectionTest extends AgentTestRunner {
expect: expect:
assertTraces(TEST_WRITER, 2) { assertTraces(TEST_WRITER, 2) {
trace(0, 1) { server.distributedRequestTrace(it, 0, TEST_WRITER[1][1])
span(0) {
operationName "test-http-server"
childOf(TEST_WRITER[1][1])
errored false
tags {
defaultTags()
}
}
}
trace(1, 3) { trace(1, 3) {
span(0) { span(0) {
operationName "someTrace" operationName "someTrace"
@ -432,21 +389,12 @@ class HttpUrlConnectionTest extends AgentTestRunner {
runUnderTrace("someTrace") { runUnderTrace("someTrace") {
RestTemplate restTemplate = new RestTemplate() RestTemplate restTemplate = new RestTemplate()
String res = restTemplate.postForObject(server.address.toString(), "Hello", String) String res = restTemplate.postForObject(server.address.toString(), "Hello", String)
assert res == RESPONSE assert res == "$RESPONSE"
} }
expect: expect:
assertTraces(TEST_WRITER, 2) { assertTraces(TEST_WRITER, 2) {
trace(0, 1) { server.distributedRequestTrace(it, 0, TEST_WRITER[1][2])
span(0) {
operationName "test-http-server"
childOf(TEST_WRITER[1][2])
errored false
tags {
defaultTags()
}
}
}
trace(1, 4) { trace(1, 4) {
span(0) { span(0) {
operationName "someTrace" operationName "someTrace"
@ -505,22 +453,4 @@ class HttpUrlConnectionTest extends AgentTestRunner {
} }
} }
} }
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

@ -5,8 +5,8 @@ import datadog.trace.api.DDTags
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import io.opentracing.util.GlobalTracer import io.opentracing.util.GlobalTracer
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.TestUtils.runUnderTrace import static datadog.trace.agent.test.TestUtils.runUnderTrace
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class UrlConnectionTest extends AgentTestRunner { class UrlConnectionTest extends AgentTestRunner {
static { static {
@ -36,7 +36,7 @@ class UrlConnectionTest extends AgentTestRunner {
parent() parent()
errored true errored true
tags { tags {
errorTags ConnectException, "Connection refused (Connection refused)" errorTags ConnectException, String
defaultTags() defaultTags()
} }
} }
@ -52,7 +52,7 @@ class UrlConnectionTest extends AgentTestRunner {
"$Tags.HTTP_METHOD.key" "GET" "$Tags.HTTP_METHOD.key" "GET"
"$Tags.PEER_HOSTNAME.key" "localhost" "$Tags.PEER_HOSTNAME.key" "localhost"
"$Tags.PEER_PORT.key" INVALID_PORT "$Tags.PEER_PORT.key" INVALID_PORT
errorTags ConnectException, "Connection refused (Connection refused)" errorTags ConnectException, String
defaultTags() defaultTags()
} }
} }

View File

@ -6,8 +6,8 @@ import java.util.concurrent.BlockingQueue
import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.LinkedBlockingQueue
import static com.netflix.hystrix.HystrixCommandGroupKey.Factory.asKey import static com.netflix.hystrix.HystrixCommandGroupKey.Factory.asKey
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.TestUtils.runUnderTrace import static datadog.trace.agent.test.TestUtils.runUnderTrace
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class HystrixTest extends AgentTestRunner { class HystrixTest extends AgentTestRunner {
// Uncomment for debugging: // Uncomment for debugging:

View File

@ -4,7 +4,7 @@ import datadog.trace.api.DDTags
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import spock.lang.Shared import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class SlickTest extends AgentTestRunner { class SlickTest extends AgentTestRunner {

View File

@ -9,8 +9,8 @@ import javax.ws.rs.POST
import javax.ws.rs.PUT import javax.ws.rs.PUT
import javax.ws.rs.Path import javax.ws.rs.Path
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.TestUtils.runUnderTrace import static datadog.trace.agent.test.TestUtils.runUnderTrace
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class JaxRsAnnotationsInstrumentationTest extends AgentTestRunner { class JaxRsAnnotationsInstrumentationTest extends AgentTestRunner {

View File

@ -8,11 +8,8 @@
apply from: "${rootDir}/gradle/java.gradle" apply from: "${rootDir}/gradle/java.gradle"
// These classes use Ratpack which requires Java 8. (Currently also incompatible with Java 9.)
testJava8Only += '**/*.class'
dependencies { dependencies {
compileOnly group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.1' compileOnly group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0.1'
compileOnly group: 'javax.annotation', name: 'javax.annotation-api', version: '1.2' compileOnly group: 'javax.annotation', name: 'javax.annotation-api', version: '1.2'
@ -25,14 +22,15 @@ dependencies {
testCompile project(':dd-java-agent:testing') testCompile project(':dd-java-agent:testing')
// testCompile group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.1' testCompile group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0.1'
testCompile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: '2.25.1' testCompile group: 'org.glassfish.jersey.core', name: 'jersey-client', version: '2.25.1'
testCompile group: 'org.apache.cxf', name: 'cxf-rt-rs-client', version: '3.2.2' testCompile group: 'org.apache.cxf', name: 'cxf-rt-rs-client', version: '3.1.16'
testCompile group: 'org.jboss.resteasy', name: 'resteasy-client', version: '3.5.0.Final' testCompile group: 'org.jboss.resteasy', name: 'resteasy-client', version: '3.0.26.Final'
// testCompile group: 'com.sun.jersey', name: 'jersey-core', version: '1.19.4' // testCompile group: 'com.sun.jersey', name: 'jersey-core', version: '1.19.4'
// testCompile group: 'com.sun.jersey', name: 'jersey-servlet', version: '1.19.4' // testCompile group: 'com.sun.jersey', name: 'jersey-servlet', version: '1.19.4'
// testCompile group: 'io.dropwizard', name: 'dropwizard-testing', version: '0.7.1' // testCompile group: 'io.dropwizard', name: 'dropwizard-testing', version: '0.7.1'
// testCompile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.3'
testCompile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.3'
} }

View File

@ -5,7 +5,8 @@ import io.opentracing.tag.Tags
import org.apache.cxf.jaxrs.client.spec.ClientBuilderImpl import org.apache.cxf.jaxrs.client.spec.ClientBuilderImpl
import org.glassfish.jersey.client.JerseyClientBuilder import org.glassfish.jersey.client.JerseyClientBuilder
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder
import ratpack.http.Headers import spock.lang.AutoCleanup
import spock.lang.Shared
import javax.ws.rs.client.AsyncInvoker import javax.ws.rs.client.AsyncInvoker
import javax.ws.rs.client.Client import javax.ws.rs.client.Client
@ -13,16 +14,16 @@ import javax.ws.rs.client.Invocation
import javax.ws.rs.client.WebTarget import javax.ws.rs.client.WebTarget
import javax.ws.rs.core.MediaType import javax.ws.rs.core.MediaType
import javax.ws.rs.core.Response import javax.ws.rs.core.Response
import java.util.concurrent.atomic.AtomicReference
import static ratpack.groovy.test.embed.GroovyEmbeddedApp.ratpack import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
class JaxRsClientTest extends AgentTestRunner { class JaxRsClientTest extends AgentTestRunner {
def receivedHeaders = new AtomicReference<Headers>()
def server = ratpack { @AutoCleanup
@Shared
def server = httpServer {
handlers { handlers {
all { all {
receivedHeaders.set(request.headers)
response.status(200).send("pong") response.status(200).send("pong")
} }
} }
@ -71,11 +72,8 @@ class JaxRsClientTest extends AgentTestRunner {
tags[DDTags.THREAD_ID] != null tags[DDTags.THREAD_ID] != null
tags.size() == 8 tags.size() == 8
receivedHeaders.get().get("x-datadog-trace-id") == "$span.traceId" server.lastRequest.headers.get("x-datadog-trace-id") == "$span.traceId"
receivedHeaders.get().get("x-datadog-parent-id") == "$span.spanId" server.lastRequest.headers.get("x-datadog-parent-id") == "$span.spanId"
cleanup:
server.close()
where: where:
builder | async | lib builder | async | lib

View File

@ -16,7 +16,7 @@ import java.sql.PreparedStatement
import java.sql.ResultSet import java.sql.ResultSet
import java.sql.Statement import java.sql.Statement
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class JDBCInstrumentationTest extends AgentTestRunner { class JDBCInstrumentationTest extends AgentTestRunner {

View File

@ -30,7 +30,9 @@ dependencies {
annotationProcessor deps.autoservice annotationProcessor deps.autoservice
implementation deps.autoservice implementation deps.autoservice
testCompile project(':dd-java-agent:testing') testCompile(project(':dd-java-agent:testing')) {
exclude group: 'org.eclipse.jetty', module: 'jetty-server'
}
testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.0.0.v20110901' testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.0.0.v20110901'
testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '8.0.0.v20110901' testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '8.0.0.v20110901'
} }

View File

@ -16,6 +16,7 @@ import javax.servlet.http.HttpServletRequest;
* *
* @author Pavol Loffay * @author Pavol Loffay
*/ */
// FIXME: This code is duplicated in several places. Extract to a common dependency.
public class HttpServletRequestExtractAdapter implements TextMap { public class HttpServletRequestExtractAdapter implements TextMap {
private final Map<String, List<String>> headers; private final Map<String, List<String>> headers;
@ -61,7 +62,7 @@ public class HttpServletRequestExtractAdapter implements TextMap {
private Iterator<V> listIterator; private Iterator<V> listIterator;
public MultivaluedMapFlatIterator(final Set<Map.Entry<K, List<V>>> multiValuesEntrySet) { public MultivaluedMapFlatIterator(final Set<Map.Entry<K, List<V>>> multiValuesEntrySet) {
this.mapIterator = multiValuesEntrySet.iterator(); mapIterator = multiValuesEntrySet.iterator();
} }
@Override @Override

View File

@ -1,6 +1,6 @@
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils
import datadog.trace.agent.test.TestUtils import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import org.eclipse.jetty.continuation.Continuation import org.eclipse.jetty.continuation.Continuation
@ -14,7 +14,7 @@ import javax.servlet.ServletException
import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse import javax.servlet.http.HttpServletResponse
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class JettyHandlerTest extends AgentTestRunner { class JettyHandlerTest extends AgentTestRunner {

View File

@ -1,5 +1,5 @@
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.ListWriterAssert import datadog.trace.agent.test.asserts.ListWriterAssert
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
@ -17,7 +17,7 @@ import javax.jms.TextMessage
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class JMS1Test extends AgentTestRunner { class JMS1Test extends AgentTestRunner {
@Shared @Shared

View File

@ -1,6 +1,6 @@
import com.google.common.io.Files import com.google.common.io.Files
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.ListWriterAssert import datadog.trace.agent.test.asserts.ListWriterAssert
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
@ -26,7 +26,7 @@ import javax.jms.TextMessage
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class JMS2Test extends AgentTestRunner { class JMS2Test extends AgentTestRunner {
@Shared @Shared

View File

@ -1,9 +1,8 @@
import com.google.common.io.Files import com.google.common.io.Files
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils
import datadog.trace.agent.test.TestUtils import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import io.netty.handler.codec.http.HttpResponseStatus
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
@ -12,10 +11,11 @@ import okhttp3.Response
import org.apache.catalina.Context import org.apache.catalina.Context
import org.apache.catalina.startup.Tomcat import org.apache.catalina.startup.Tomcat
import org.apache.jasper.JasperException import org.apache.jasper.JasperException
import org.eclipse.jetty.http.HttpStatus
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Unroll import spock.lang.Unroll
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class JSPInstrumentationBasicTests extends AgentTestRunner { class JSPInstrumentationBasicTests extends AgentTestRunner {
@ -140,7 +140,7 @@ class JSPInstrumentationBasicTests extends AgentTestRunner {
} }
} }
} }
res.code() == HttpResponseStatus.OK.code() res.code() == HttpStatus.OK_200
cleanup: cleanup:
res.close() res.close()
@ -219,7 +219,7 @@ class JSPInstrumentationBasicTests extends AgentTestRunner {
} }
} }
} }
res.code() == HttpResponseStatus.OK.code() res.code() == HttpStatus.OK_200
cleanup: cleanup:
res.close() res.close()
@ -295,7 +295,7 @@ class JSPInstrumentationBasicTests extends AgentTestRunner {
} }
} }
} }
res.code() == HttpResponseStatus.OK.code() res.code() == HttpStatus.OK_200
cleanup: cleanup:
res.close() res.close()
@ -370,7 +370,7 @@ class JSPInstrumentationBasicTests extends AgentTestRunner {
} }
} }
} }
res.code() == HttpResponseStatus.INTERNAL_SERVER_ERROR.code() res.code() == HttpStatus.INTERNAL_SERVER_ERROR_500
cleanup: cleanup:
res.close() res.close()
@ -448,7 +448,7 @@ class JSPInstrumentationBasicTests extends AgentTestRunner {
} }
} }
} }
res.code() == HttpResponseStatus.OK.code() res.code() == HttpStatus.OK_200
cleanup: cleanup:
res.close() res.close()
@ -588,7 +588,7 @@ class JSPInstrumentationBasicTests extends AgentTestRunner {
} }
} }
} }
res.code() == HttpResponseStatus.OK.code() res.code() == HttpStatus.OK_200
cleanup: cleanup:
res.close() res.close()
@ -647,7 +647,7 @@ class JSPInstrumentationBasicTests extends AgentTestRunner {
} }
} }
} }
res.code() == HttpResponseStatus.INTERNAL_SERVER_ERROR.code() res.code() == HttpStatus.INTERNAL_SERVER_ERROR_500
cleanup: cleanup:
res.close() res.close()

View File

@ -1,19 +1,19 @@
import com.google.common.io.Files import com.google.common.io.Files
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils
import datadog.trace.agent.test.TestUtils import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import io.netty.handler.codec.http.HttpResponseStatus
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.Response import okhttp3.Response
import org.apache.catalina.Context import org.apache.catalina.Context
import org.apache.catalina.startup.Tomcat import org.apache.catalina.startup.Tomcat
import org.apache.jasper.JasperException import org.apache.jasper.JasperException
import org.eclipse.jetty.http.HttpStatus
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Unroll import spock.lang.Unroll
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class JSPInstrumentationForwardTests extends AgentTestRunner { class JSPInstrumentationForwardTests extends AgentTestRunner {
@ -173,7 +173,7 @@ class JSPInstrumentationForwardTests extends AgentTestRunner {
} }
} }
} }
res.code() == HttpResponseStatus.OK.code() res.code() == HttpStatus.OK_200
cleanup: cleanup:
res.close() res.close()
@ -250,7 +250,7 @@ class JSPInstrumentationForwardTests extends AgentTestRunner {
} }
} }
} }
res.code() == HttpResponseStatus.OK.code() res.code() == HttpStatus.OK_200
cleanup: cleanup:
res.close() res.close()
@ -427,7 +427,7 @@ class JSPInstrumentationForwardTests extends AgentTestRunner {
} }
} }
} }
res.code() == HttpResponseStatus.OK.code() res.code() == HttpStatus.OK_200
cleanup: cleanup:
res.close() res.close()
@ -569,7 +569,7 @@ class JSPInstrumentationForwardTests extends AgentTestRunner {
} }
} }
} }
res.code() == HttpResponseStatus.OK.code() res.code() == HttpStatus.OK_200
cleanup: cleanup:
res.close() res.close()
@ -663,7 +663,7 @@ class JSPInstrumentationForwardTests extends AgentTestRunner {
} }
} }
} }
res.code() == HttpResponseStatus.INTERNAL_SERVER_ERROR.code() res.code() == HttpStatus.INTERNAL_SERVER_ERROR_500
cleanup: cleanup:
res.close() res.close()
@ -735,7 +735,7 @@ class JSPInstrumentationForwardTests extends AgentTestRunner {
} }
} }
} }
res.code() == HttpResponseStatus.NOT_FOUND.code() res.code() == HttpStatus.NOT_FOUND_404
cleanup: cleanup:
res.close() res.close()

View File

@ -25,7 +25,7 @@ import java.util.function.BiFunction
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Function import java.util.function.Function
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static datadog.trace.instrumentation.lettuce.LettuceInstrumentationUtil.AGENT_CRASHING_COMMAND_PREFIX import static datadog.trace.instrumentation.lettuce.LettuceInstrumentationUtil.AGENT_CRASHING_COMMAND_PREFIX
class LettuceAsyncClientTest extends AgentTestRunner { class LettuceAsyncClientTest extends AgentTestRunner {

View File

@ -13,7 +13,7 @@ import spock.util.concurrent.AsyncConditions
import java.util.function.Consumer import java.util.function.Consumer
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static datadog.trace.instrumentation.lettuce.LettuceInstrumentationUtil.AGENT_CRASHING_COMMAND_PREFIX import static datadog.trace.instrumentation.lettuce.LettuceInstrumentationUtil.AGENT_CRASHING_COMMAND_PREFIX
class LettuceReactiveClientTest extends AgentTestRunner { class LettuceReactiveClientTest extends AgentTestRunner {

View File

@ -12,7 +12,7 @@ import spock.lang.Shared
import java.util.concurrent.CompletionException import java.util.concurrent.CompletionException
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static datadog.trace.instrumentation.lettuce.LettuceInstrumentationUtil.AGENT_CRASHING_COMMAND_PREFIX import static datadog.trace.instrumentation.lettuce.LettuceInstrumentationUtil.AGENT_CRASHING_COMMAND_PREFIX
class LettuceSyncClientTest extends AgentTestRunner { class LettuceSyncClientTest extends AgentTestRunner {

View File

@ -33,7 +33,6 @@ dependencies {
testCompile project(':dd-java-agent:testing') testCompile project(':dd-java-agent:testing')
// testCompile group: 'io.netty', name: 'netty-all', version: '4.0.0.Final' // testCompile group: 'io.netty', name: 'netty-all', version: '4.0.0.Final'
testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.2.0.v20160908'
testCompile group: 'org.asynchttpclient', name: 'async-http-client', version: '2.0.0' testCompile group: 'org.asynchttpclient', name: 'async-http-client', version: '2.0.0'
} }

View File

@ -1,22 +1,16 @@
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.TestUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import org.asynchttpclient.AsyncHttpClient import org.asynchttpclient.AsyncHttpClient
import org.asynchttpclient.DefaultAsyncHttpClientConfig import org.asynchttpclient.DefaultAsyncHttpClientConfig
import org.eclipse.jetty.server.Handler import spock.lang.AutoCleanup
import org.eclipse.jetty.server.Request
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.server.handler.AbstractHandler
import org.eclipse.jetty.util.MultiMap
import spock.lang.Shared import spock.lang.Shared
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
import static org.asynchttpclient.Dsl.asyncHttpClient import static org.asynchttpclient.Dsl.asyncHttpClient
class Netty40ClientTest extends AgentTestRunner { class Netty40ClientTest extends AgentTestRunner {
@ -24,53 +18,28 @@ class Netty40ClientTest extends AgentTestRunner {
System.setProperty("dd.integration.netty.enabled", "true") System.setProperty("dd.integration.netty.enabled", "true")
} }
@AutoCleanup
@Shared @Shared
int port def server = httpServer {
@Shared handlers {
Server server all {
response.send("Hello World")
}
}
}
@Shared @Shared
def clientConfig = DefaultAsyncHttpClientConfig.Builder.newInstance().setRequestTimeout(TimeUnit.MINUTES.toMillis(1).toInteger()) def clientConfig = DefaultAsyncHttpClientConfig.Builder.newInstance().setRequestTimeout(TimeUnit.MINUTES.toMillis(1).toInteger())
@Shared @Shared
AsyncHttpClient asyncHttpClient = asyncHttpClient(clientConfig) AsyncHttpClient asyncHttpClient = asyncHttpClient(clientConfig)
@Shared
def headers = new MultiMap()
def setupSpec() {
port = TestUtils.randomOpenPort()
server = new Server(port)
Handler handler = [
handle: { String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response ->
request.getHeaderNames().each {
headers.add(it, request.getHeader(it))
}
response.setContentType("text/plaincharset=utf-8")
response.setStatus(HttpServletResponse.SC_OK)
baseRequest.setHandled(true)
response.getWriter().println("Hello World")
}
] as AbstractHandler
server.setHandler(handler)
server.start()
}
def cleanupSpec() {
server.stop()
}
def cleanup() {
headers.clear()
}
def "test server request/response"() { def "test server request/response"() {
setup: setup:
def responseFuture = asyncHttpClient.prepareGet("http://localhost:$port/").execute() def responseFuture = asyncHttpClient.prepareGet("$server.address").execute()
def response = responseFuture.get() def response = responseFuture.get()
expect: expect:
response.statusCode == 200 response.statusCode == 200
response.responseBody == "Hello World\n" response.responseBody == "Hello World"
and: and:
assertTraces(TEST_WRITER, 1) { assertTraces(TEST_WRITER, 1) {
@ -85,7 +54,7 @@ class Netty40ClientTest extends AgentTestRunner {
"$Tags.COMPONENT.key" "netty-client" "$Tags.COMPONENT.key" "netty-client"
"$Tags.HTTP_METHOD.key" "GET" "$Tags.HTTP_METHOD.key" "GET"
"$Tags.HTTP_STATUS.key" 200 "$Tags.HTTP_STATUS.key" 200
"$Tags.HTTP_URL.key" "http://localhost:$port/" "$Tags.HTTP_URL.key" "$server.address/"
"$Tags.PEER_HOSTNAME.key" "localhost" "$Tags.PEER_HOSTNAME.key" "localhost"
"$Tags.PEER_PORT.key" Integer "$Tags.PEER_PORT.key" Integer
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
@ -97,7 +66,7 @@ class Netty40ClientTest extends AgentTestRunner {
} }
and: and:
headers["x-datadog-trace-id"] == "${TEST_WRITER.get(0).get(0).traceId}" server.lastRequest.headers.get("x-datadog-trace-id") == "${TEST_WRITER.get(0).get(0).traceId}"
headers["x-datadog-parent-id"] == "${TEST_WRITER.get(0).get(0).spanId}" server.lastRequest.headers.get("x-datadog-parent-id") == "${TEST_WRITER.get(0).get(0).spanId}"
} }
} }

View File

@ -1,6 +1,6 @@
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils
import datadog.trace.agent.test.TestUtils import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import io.netty.bootstrap.ServerBootstrap import io.netty.bootstrap.ServerBootstrap
@ -28,7 +28,7 @@ import io.opentracing.tag.Tags
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class Netty40ServerTest extends AgentTestRunner { class Netty40ServerTest extends AgentTestRunner {
static { static {

View File

@ -33,7 +33,6 @@ dependencies {
testCompile project(':dd-java-agent:testing') testCompile project(':dd-java-agent:testing')
testCompile group: 'io.netty', name: 'netty-all', version: '4.1.0.Final' testCompile group: 'io.netty', name: 'netty-all', version: '4.1.0.Final'
testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.2.0.v20160908'
testCompile group: 'org.asynchttpclient', name: 'async-http-client', version: '2.0.31' testCompile group: 'org.asynchttpclient', name: 'async-http-client', version: '2.0.31'
// async-http-client:2.0.32+ would require netty:4.1.9.Final // async-http-client:2.0.32+ would require netty:4.1.9.Final
} }

View File

@ -1,22 +1,16 @@
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.TestUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import org.asynchttpclient.AsyncHttpClient import org.asynchttpclient.AsyncHttpClient
import org.asynchttpclient.DefaultAsyncHttpClientConfig import org.asynchttpclient.DefaultAsyncHttpClientConfig
import org.eclipse.jetty.server.Handler import spock.lang.AutoCleanup
import org.eclipse.jetty.server.Request
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.server.handler.AbstractHandler
import org.eclipse.jetty.util.MultiMap
import spock.lang.Shared import spock.lang.Shared
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
import static org.asynchttpclient.Dsl.asyncHttpClient import static org.asynchttpclient.Dsl.asyncHttpClient
class Netty41ClientTest extends AgentTestRunner { class Netty41ClientTest extends AgentTestRunner {
@ -24,53 +18,28 @@ class Netty41ClientTest extends AgentTestRunner {
System.setProperty("dd.integration.netty.enabled", "true") System.setProperty("dd.integration.netty.enabled", "true")
} }
@AutoCleanup
@Shared @Shared
int port def server = httpServer {
@Shared handlers {
Server server all {
response.send("Hello World")
}
}
}
@Shared @Shared
def clientConfig = DefaultAsyncHttpClientConfig.Builder.newInstance().setRequestTimeout(TimeUnit.MINUTES.toMillis(1).toInteger()) def clientConfig = DefaultAsyncHttpClientConfig.Builder.newInstance().setRequestTimeout(TimeUnit.MINUTES.toMillis(1).toInteger())
@Shared @Shared
AsyncHttpClient asyncHttpClient = asyncHttpClient(clientConfig) AsyncHttpClient asyncHttpClient = asyncHttpClient(clientConfig)
@Shared
def headers = new MultiMap()
def setupSpec() {
port = TestUtils.randomOpenPort()
server = new Server(port)
Handler handler = [
handle: { String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response ->
request.getHeaderNames().each {
headers.add(it, request.getHeader(it))
}
response.setContentType("text/plaincharset=utf-8")
response.setStatus(HttpServletResponse.SC_OK)
baseRequest.setHandled(true)
response.getWriter().println("Hello World")
}
] as AbstractHandler
server.setHandler(handler)
server.start()
}
def cleanupSpec() {
server.stop()
}
def cleanup() {
headers.clear()
}
def "test server request/response"() { def "test server request/response"() {
setup: setup:
def responseFuture = asyncHttpClient.prepareGet("http://localhost:$port/").execute() def responseFuture = asyncHttpClient.prepareGet("$server.address").execute()
def response = responseFuture.get() def response = responseFuture.get()
expect: expect:
response.statusCode == 200 response.statusCode == 200
response.responseBody == "Hello World\n" response.responseBody == "Hello World"
and: and:
assertTraces(TEST_WRITER, 1) { assertTraces(TEST_WRITER, 1) {
@ -85,7 +54,7 @@ class Netty41ClientTest extends AgentTestRunner {
"$Tags.COMPONENT.key" "netty-client" "$Tags.COMPONENT.key" "netty-client"
"$Tags.HTTP_METHOD.key" "GET" "$Tags.HTTP_METHOD.key" "GET"
"$Tags.HTTP_STATUS.key" 200 "$Tags.HTTP_STATUS.key" 200
"$Tags.HTTP_URL.key" "http://localhost:$port/" "$Tags.HTTP_URL.key" "$server.address/"
"$Tags.PEER_HOSTNAME.key" "localhost" "$Tags.PEER_HOSTNAME.key" "localhost"
"$Tags.PEER_PORT.key" Integer "$Tags.PEER_PORT.key" Integer
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
@ -97,7 +66,7 @@ class Netty41ClientTest extends AgentTestRunner {
} }
and: and:
headers["x-datadog-trace-id"] == "${TEST_WRITER.get(0).get(0).traceId}" server.lastRequest.headers.get("x-datadog-trace-id") == "${TEST_WRITER.get(0).get(0).traceId}"
headers["x-datadog-parent-id"] == "${TEST_WRITER.get(0).get(0).spanId}" server.lastRequest.headers.get("x-datadog-parent-id") == "${TEST_WRITER.get(0).get(0).spanId}"
} }
} }

View File

@ -1,6 +1,6 @@
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils
import datadog.trace.agent.test.TestUtils import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import io.netty.bootstrap.ServerBootstrap import io.netty.bootstrap.ServerBootstrap
@ -28,7 +28,7 @@ import io.opentracing.tag.Tags
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class Netty41ServerTest extends AgentTestRunner { class Netty41ServerTest extends AgentTestRunner {
static { static {

View File

@ -14,9 +14,6 @@ versionScan {
apply from: "${rootDir}/gradle/java.gradle" apply from: "${rootDir}/gradle/java.gradle"
// These classes use Ratpack which requires Java 8. (Currently also incompatible with Java 9.)
testJava8Only += '**/OkHttp3Test.class'
apply plugin: 'org.unbroken-dome.test-sets' apply plugin: 'org.unbroken-dome.test-sets'
testSets { testSets {

View File

@ -3,22 +3,17 @@ import datadog.trace.api.DDSpanTypes
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import ratpack.http.Headers
import java.util.concurrent.atomic.AtomicReference import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static ratpack.groovy.test.embed.GroovyEmbeddedApp.ratpack
class OkHttp3Test extends AgentTestRunner { class OkHttp3Test extends AgentTestRunner {
def "sending a request creates spans and sends headers"() { def "sending a request creates spans and sends headers"() {
setup: setup:
def receivedHeaders = new AtomicReference<Headers>() def server = httpServer {
def server = ratpack {
handlers { handlers {
all { all {
receivedHeaders.set(request.headers)
response.status(200).send("pong") response.status(200).send("pong")
} }
} }
@ -69,8 +64,8 @@ class OkHttp3Test extends AgentTestRunner {
} }
} }
receivedHeaders.get().get("x-datadog-trace-id") == TEST_WRITER[0][1].traceId server.lastRequest.headers.get("x-datadog-trace-id") == TEST_WRITER[0][1].traceId
receivedHeaders.get().get("x-datadog-parent-id") == TEST_WRITER[0][1].spanId server.lastRequest.headers.get("x-datadog-parent-id") == TEST_WRITER[0][1].spanId
cleanup: cleanup:
server.close() server.close()

View File

@ -7,7 +7,7 @@ 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 import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class Play26Test extends AgentTestRunner { class Play26Test extends AgentTestRunner {
static { static {

View File

@ -57,12 +57,12 @@ dependencies {
compile sourceSets.main_java8.output compile sourceSets.main_java8.output
testCompile project(':dd-java-agent:testing') testCompile project(':dd-java-agent:testing')
testCompile group: 'io.ratpack', name: 'ratpack-test', version: '1.4.0' testCompile group: 'io.ratpack', name: 'ratpack-groovy-test', version: '1.4.0'
} }
configurations.latestDepTestCompile { configurations.latestDepTestCompile {
resolutionStrategy { resolutionStrategy {
force group: 'io.ratpack', name: 'ratpack-test', version: '+' force group: 'io.ratpack', name: 'ratpack-groovy-test', version: '+'
} }
} }

View File

@ -1,6 +1,6 @@
import datadog.opentracing.scopemanager.ContextualScopeManager import datadog.opentracing.scopemanager.ContextualScopeManager
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.instrumentation.ratpack.impl.RatpackScopeManager import datadog.trace.instrumentation.ratpack.impl.RatpackScopeManager
import io.opentracing.Scope import io.opentracing.Scope

View File

@ -22,7 +22,9 @@ dependencies {
annotationProcessor deps.autoservice annotationProcessor deps.autoservice
implementation deps.autoservice implementation deps.autoservice
testCompile project(':dd-java-agent:testing') testCompile(project(':dd-java-agent:testing')) {
exclude group: 'org.eclipse.jetty', module: 'jetty-server'
}
testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '7.0.0.v20091005' testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '7.0.0.v20091005'
testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '7.0.0.v20091005' testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '7.0.0.v20091005'
} }

View File

@ -16,6 +16,7 @@ import javax.servlet.http.HttpServletRequest;
* *
* @author Pavol Loffay * @author Pavol Loffay
*/ */
// FIXME: This code is duplicated in several places. Extract to a common dependency.
public class HttpServletRequestExtractAdapter implements TextMap { public class HttpServletRequestExtractAdapter implements TextMap {
private final Map<String, List<String>> headers; private final Map<String, List<String>> headers;
@ -61,7 +62,7 @@ public class HttpServletRequestExtractAdapter implements TextMap {
private Iterator<V> listIterator; private Iterator<V> listIterator;
public MultivaluedMapFlatIterator(final Set<Map.Entry<K, List<V>>> multiValuesEntrySet) { public MultivaluedMapFlatIterator(final Set<Map.Entry<K, List<V>>> multiValuesEntrySet) {
this.mapIterator = multiValuesEntrySet.iterator(); mapIterator = multiValuesEntrySet.iterator();
} }
@Override @Override

View File

@ -1,6 +1,6 @@
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils
import datadog.trace.agent.test.TestUtils import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import okhttp3.Credentials import okhttp3.Credentials
import okhttp3.Interceptor import okhttp3.Interceptor
@ -17,7 +17,7 @@ import org.eclipse.jetty.security.authentication.BasicAuthenticator
import org.eclipse.jetty.server.Server import org.eclipse.jetty.server.Server
import org.eclipse.jetty.servlet.ServletContextHandler import org.eclipse.jetty.servlet.ServletContextHandler
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class JettyServlet2Test extends AgentTestRunner { class JettyServlet2Test extends AgentTestRunner {

View File

@ -32,7 +32,9 @@ dependencies {
annotationProcessor deps.autoservice annotationProcessor deps.autoservice
implementation deps.autoservice implementation deps.autoservice
testCompile project(':dd-java-agent:testing') testCompile(project(':dd-java-agent:testing')) {
exclude group: 'org.eclipse.jetty', module: 'jetty-server'
}
testCompile project(':dd-java-agent:instrumentation:jetty-8') // See if there's any conflicts. testCompile project(':dd-java-agent:instrumentation:jetty-8') // See if there's any conflicts.
testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.2.0.v20160908' testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.2.0.v20160908'
testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '8.2.0.v20160908' testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '8.2.0.v20160908'

View File

@ -16,6 +16,7 @@ import javax.servlet.http.HttpServletRequest;
* *
* @author Pavol Loffay * @author Pavol Loffay
*/ */
// FIXME: This code is duplicated in several places. Extract to a common dependency.
public class HttpServletRequestExtractAdapter implements TextMap { public class HttpServletRequestExtractAdapter implements TextMap {
private final Map<String, List<String>> headers; private final Map<String, List<String>> headers;
@ -61,7 +62,7 @@ public class HttpServletRequestExtractAdapter implements TextMap {
private Iterator<V> listIterator; private Iterator<V> listIterator;
public MultivaluedMapFlatIterator(final Set<Map.Entry<K, List<V>>> multiValuesEntrySet) { public MultivaluedMapFlatIterator(final Set<Map.Entry<K, List<V>>> multiValuesEntrySet) {
this.mapIterator = multiValuesEntrySet.iterator(); mapIterator = multiValuesEntrySet.iterator();
} }
@Override @Override

View File

@ -1,6 +1,6 @@
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils
import datadog.trace.agent.test.TestUtils import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import okhttp3.Credentials import okhttp3.Credentials
import okhttp3.Interceptor import okhttp3.Interceptor
@ -17,7 +17,7 @@ import org.eclipse.jetty.server.Server
import org.eclipse.jetty.servlet.ServletContextHandler import org.eclipse.jetty.servlet.ServletContextHandler
import org.eclipse.jetty.util.security.Constraint import org.eclipse.jetty.util.security.Constraint
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class JettyServlet3Test extends AgentTestRunner { class JettyServlet3Test extends AgentTestRunner {

View File

@ -1,7 +1,7 @@
import com.google.common.io.Files import com.google.common.io.Files
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils
import datadog.trace.agent.test.TestUtils import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
@ -11,7 +11,7 @@ import org.apache.catalina.startup.Tomcat
import org.apache.tomcat.JarScanFilter import org.apache.tomcat.JarScanFilter
import org.apache.tomcat.JarScanType import org.apache.tomcat.JarScanType
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class TomcatServlet3Test extends AgentTestRunner { class TomcatServlet3Test extends AgentTestRunner {

View File

@ -1,6 +1,6 @@
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils
import datadog.trace.agent.test.TestUtils import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request

View File

@ -1,7 +1,7 @@
package test package test
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.TraceAssert import datadog.trace.agent.test.asserts.TraceAssert
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
@ -13,7 +13,7 @@ import org.springframework.boot.test.web.client.TestRestTemplate
import org.springframework.web.bind.MethodArgumentNotValidException import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.util.NestedServletException import org.springframework.web.util.NestedServletException
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class SpringBootBasedTest extends AgentTestRunner { class SpringBootBasedTest extends AgentTestRunner {

View File

@ -2,7 +2,7 @@ package datadog.trace.instrumentation.spymemcached
import com.google.common.util.concurrent.MoreExecutors import com.google.common.util.concurrent.MoreExecutors
import datadog.trace.agent.test.AgentTestRunner import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.TraceAssert import datadog.trace.agent.test.asserts.TraceAssert
import datadog.trace.api.DDSpanTypes import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags import datadog.trace.api.DDTags
import io.opentracing.tag.Tags import io.opentracing.tag.Tags
@ -26,8 +26,8 @@ import java.util.concurrent.locks.ReentrantLock
import static CompletionListener.COMPONENT_NAME import static CompletionListener.COMPONENT_NAME
import static CompletionListener.OPERATION_NAME import static CompletionListener.OPERATION_NAME
import static CompletionListener.SERVICE_NAME import static CompletionListener.SERVICE_NAME
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.TestUtils.runUnderTrace import static datadog.trace.agent.test.TestUtils.runUnderTrace
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static net.spy.memcached.ConnectionFactoryBuilder.Protocol.BINARY import static net.spy.memcached.ConnectionFactoryBuilder.Protocol.BINARY
// Do not run tests locally on Java7 since testcontainers are not compatible with Java7 // Do not run tests locally on Java7 since testcontainers are not compatible with Java7

View File

@ -5,8 +5,8 @@ import dd.test.trace.annotation.SayTracedHello
import java.util.concurrent.Callable import java.util.concurrent.Callable
import static TraceAnnotationsInstrumentation.DEFAULT_ANNOTATIONS import static TraceAnnotationsInstrumentation.DEFAULT_ANNOTATIONS
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.TestUtils.withSystemProperty import static datadog.trace.agent.test.TestUtils.withSystemProperty
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class ConfiguredTraceAnnotationsTest extends AgentTestRunner { class ConfiguredTraceAnnotationsTest extends AgentTestRunner {

View File

@ -5,7 +5,7 @@ import dd.test.trace.annotation.SayTracedHello
import java.util.concurrent.Callable import java.util.concurrent.Callable
import static datadog.trace.agent.test.ListWriterAssert.assertTraces import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class TraceAnnotationsTest extends AgentTestRunner { class TraceAnnotationsTest extends AgentTestRunner {

View File

@ -3,8 +3,8 @@ import datadog.trace.instrumentation.trace_annotation.TraceConfigInstrumentation
import java.util.concurrent.Callable import java.util.concurrent.Callable
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.TestUtils.withSystemProperty import static datadog.trace.agent.test.TestUtils.withSystemProperty
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class TraceConfigTest extends AgentTestRunner { class TraceConfigTest extends AgentTestRunner {

View File

@ -1,46 +0,0 @@
package datadog.trace.agent.test
import io.opentracing.SpanContext
import io.opentracing.propagation.Format
import io.opentracing.propagation.TextMap
import io.opentracing.util.GlobalTracer
import ratpack.handling.Context
class RatpackUtils {
static handleDistributedRequest(Context context) {
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))
def builder = GlobalTracer.get()
.buildSpan("test-http-server")
if (extractedContext != null) {
builder.asChildOf(extractedContext)
}
builder.start().finish()
}
}
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

@ -1,4 +1,4 @@
package datadog.trace.agent.test package datadog.trace.agent.test.asserts
import datadog.opentracing.DDSpan import datadog.opentracing.DDSpan
import datadog.trace.common.writer.ListWriter import datadog.trace.common.writer.ListWriter
@ -7,7 +7,7 @@ import org.spockframework.runtime.Condition
import org.spockframework.runtime.ConditionNotSatisfiedError import org.spockframework.runtime.ConditionNotSatisfiedError
import org.spockframework.runtime.model.TextPosition import org.spockframework.runtime.model.TextPosition
import static datadog.trace.agent.test.TraceAssert.assertTrace import static TraceAssert.assertTrace
class ListWriterAssert { class ListWriterAssert {
private final ListWriter writer private final ListWriter writer

View File

@ -1,8 +1,8 @@
package datadog.trace.agent.test package datadog.trace.agent.test.asserts
import datadog.opentracing.DDSpan import datadog.opentracing.DDSpan
import static datadog.trace.agent.test.TagsAssert.assertTags import static TagsAssert.assertTags
class SpanAssert { class SpanAssert {
private final DDSpan span private final DDSpan span
@ -18,7 +18,6 @@ class SpanAssert {
clone.delegate = asserter clone.delegate = asserter
clone.resolveStrategy = Closure.DELEGATE_FIRST clone.resolveStrategy = Closure.DELEGATE_FIRST
clone(asserter) clone(asserter)
asserter
} }
def serviceName(String name) { def serviceName(String name) {

View File

@ -1,4 +1,4 @@
package datadog.trace.agent.test package datadog.trace.agent.test.asserts
import datadog.opentracing.DDSpan import datadog.opentracing.DDSpan
@ -18,7 +18,6 @@ class TagsAssert {
clone.resolveStrategy = Closure.DELEGATE_FIRST clone.resolveStrategy = Closure.DELEGATE_FIRST
clone(asserter) clone(asserter)
asserter.assertTagsAllVerified() asserter.assertTagsAllVerified()
asserter
} }
def defaultTags() { def defaultTags() {

View File

@ -1,8 +1,8 @@
package datadog.trace.agent.test package datadog.trace.agent.test.asserts
import datadog.opentracing.DDSpan import datadog.opentracing.DDSpan
import static datadog.trace.agent.test.SpanAssert.assertSpan import static SpanAssert.assertSpan
class TraceAssert { class TraceAssert {
private final List<DDSpan> trace private final List<DDSpan> trace
@ -23,7 +23,6 @@ class TraceAssert {
clone.resolveStrategy = Closure.DELEGATE_FIRST clone.resolveStrategy = Closure.DELEGATE_FIRST
clone(asserter) clone(asserter)
asserter.assertSpansAllVerified() asserter.assertSpansAllVerified()
asserter
} }
DDSpan span(int index) { DDSpan span(int index) {

View File

@ -0,0 +1,320 @@
package datadog.trace.agent.test.server.http
import datadog.opentracing.DDSpan
import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.asserts.ListWriterAssert
import io.opentracing.SpanContext
import io.opentracing.Tracer
import io.opentracing.propagation.Format
import io.opentracing.util.GlobalTracer
import org.eclipse.jetty.http.HttpMethods
import org.eclipse.jetty.server.Handler
import org.eclipse.jetty.server.Request
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.server.handler.AbstractHandler
import org.eclipse.jetty.server.handler.HandlerList
import javax.servlet.ServletException
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import java.util.concurrent.atomic.AtomicReference
class TestHttpServer implements AutoCloseable {
static TestHttpServer httpServer(boolean start = true,
@DelegatesTo(value = TestHttpServer, strategy = Closure.DELEGATE_FIRST) Closure spec) {
def server = new TestHttpServer()
def clone = (Closure) spec.clone()
clone.delegate = server
clone.resolveStrategy = Closure.DELEGATE_FIRST
clone(server)
if (start) {
server.start()
}
return server
}
private final Server internalServer
private HandlersSpec handlers
public Tracer tracer = GlobalTracer.get()
final URI address
private final AtomicReference<HandlerApi.RequestApi> last = new AtomicReference<>()
private TestHttpServer() {
int port = TestUtils.randomOpenPort()
internalServer = new Server(port)
internalServer.stopAtShutdown = true
address = new URI("http://localhost:$port")
}
def start() {
if (internalServer.isStarted()) {
return
}
assert handlers != null: "handlers must be defined"
def handlerList = new HandlerList()
handlerList.handlers = handlers.configured
internalServer.handler = handlerList
System.out.println("Starting server $this on port $address.port")
internalServer.start()
return this
}
def stop() {
System.out.println("Stopping server $this on port $address.port")
internalServer.stop()
return this
}
void close() {
stop()
}
URI getAddress() {
return address
}
def getLastRequest() {
return last.get()
}
void handlers(@DelegatesTo(value = HandlersSpec, strategy = Closure.DELEGATE_FIRST) Closure spec) {
assert handlers == null: "handlers already defined"
handlers = new HandlersSpec()
def clone = (Closure) spec.clone()
clone.delegate = handlers
clone.resolveStrategy = Closure.DELEGATE_FIRST
clone(handlers)
}
static distributedRequestTrace(ListWriterAssert traces, int index, DDSpan parentSpan = null) {
traces.trace(index, 1) {
span(0) {
operationName "test-http-server"
errored false
if (parentSpan == null) {
parent()
} else {
childOf(parentSpan)
}
tags {
defaultTags()
}
}
}
}
private class HandlersSpec {
List<Handler> configured = []
void get(String path, @DelegatesTo(value = HandlerApi, strategy = Closure.DELEGATE_FIRST) Closure<Void> spec) {
assert path != null
configured << new HandlerSpec(HttpMethods.GET, path, spec)
}
void post(String path, @DelegatesTo(value = HandlerApi, strategy = Closure.DELEGATE_FIRST) Closure<Void> spec) {
assert path != null
configured << new HandlerSpec(HttpMethods.POST, path, spec)
}
void put(String path, @DelegatesTo(value = HandlerApi, strategy = Closure.DELEGATE_FIRST) Closure<Void> spec) {
assert path != null
configured << new HandlerSpec(HttpMethods.PUT, path, spec)
}
void prefix(String path, @DelegatesTo(value = HandlerApi, strategy = Closure.DELEGATE_FIRST) Closure<Void> spec) {
configured << new PrefixHandlerSpec(path, spec)
}
void all(@DelegatesTo(value = HandlerApi, strategy = Closure.DELEGATE_FIRST) Closure<Void> spec) {
configured << new AllHandlerSpec(spec)
}
}
private class HandlerSpec extends AllHandlerSpec {
private final String method
private final String path
private HandlerSpec(String method, String path, Closure<Void> spec) {
super(spec)
this.method = method
this.path = path.startsWith("/") ? path : "/" + path
}
@Override
void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
if (request.method == method && target == path) {
send(baseRequest, response)
}
}
}
private class PrefixHandlerSpec extends AllHandlerSpec {
private final String prefix
private PrefixHandlerSpec(String prefix, Closure<Void> spec) {
super(spec)
this.prefix = prefix.startsWith("/") ? prefix : "/" + prefix
}
@Override
void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
if (target.startsWith(prefix)) {
send(baseRequest, response)
}
}
}
private class AllHandlerSpec extends AbstractHandler {
protected final Closure<Void> spec
protected AllHandlerSpec(Closure<Void> spec) {
this.spec = spec
}
@Override
void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
send(baseRequest, response)
}
protected void send(Request baseRequest, HttpServletResponse response) {
def api = new HandlerApi(baseRequest, response)
last.set(api.request)
def clone = (Closure) spec.clone()
clone.delegate = api
clone.resolveStrategy = Closure.DELEGATE_FIRST
try {
clone(api)
} catch (Exception e) {
api.response.status(500).send(e.getMessage())
}
}
}
class HandlerApi {
private final Request req
private final HttpServletResponse resp
private HandlerApi(Request request, HttpServletResponse response) {
this.req = request
this.resp = response
}
def getRequest() {
return new RequestApi()
}
def getResponse() {
return new ResponseApi()
}
void redirect(String uri) {
resp.sendRedirect(uri)
req.handled = true
}
void handleDistributedRequest() {
boolean isDDServer = true
if (request.getHeader("is-dd-server") != null) {
isDDServer = Boolean.parseBoolean(request.getHeader("is-dd-server"))
}
if (isDDServer) {
final SpanContext extractedContext =
tracer.extract(Format.Builtin.HTTP_HEADERS, new HttpServletRequestExtractAdapter(req))
def builder = tracer
.buildSpan("test-http-server")
if (extractedContext != null) {
builder.asChildOf(extractedContext)
}
builder.start().finish()
}
}
class RequestApi {
def path = req.pathInfo
def headers = new Headers(req)
def contentLength = req.contentLength
def contentType = req.contentType?.split(";")
def body = req.inputStream.bytes
def getPath() {
return path
}
def getContentLength() {
return contentLength
}
def getContentType() {
return contentType ? contentType[0] : null
}
def getHeaders() {
return headers
}
String getHeader(String header) {
return headers[header]
}
def getBody() {
return body
}
def getText() {
return new String(body)
}
}
class ResponseApi {
private int status = 200
ResponseApi status(int status) {
this.status = status
return this
}
void send() {
assert !req.handled
req.contentType = "text/plain;charset=utf-8"
resp.status = status
req.handled = true
}
void send(String body) {
assert body != null
send()
resp.writer.print(body)
}
}
static class Headers {
private final Map<String, String> headers
private Headers(Request request) {
this.headers = [:]
request.getHeaderNames().each {
headers.put(it, request.getHeader(it))
}
}
def get(String header) {
return headers[header]
}
}
}
}

View File

@ -1,4 +1,4 @@
package datadog.trace.agent.test package datadog.trace.agent.test.utils
import okhttp3.OkHttpClient import okhttp3.OkHttpClient

View File

@ -0,0 +1,96 @@
package datadog.trace.agent.test.server.http;
import io.opentracing.propagation.TextMap;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
/**
* Tracer extract adapter for {@link HttpServletRequest}.
*
* @author Pavol Loffay
*/
// FIXME: This code is duplicated in several places. Extract to a common dependency.
public class HttpServletRequestExtractAdapter implements TextMap {
private final Map<String, List<String>> headers;
public HttpServletRequestExtractAdapter(final HttpServletRequest httpServletRequest) {
headers = servletHeadersToMultiMap(httpServletRequest);
}
@Override
public Iterator<Map.Entry<String, String>> iterator() {
return new MultivaluedMapFlatIterator<>(headers.entrySet());
}
@Override
public void put(final String key, final String value) {
throw new UnsupportedOperationException("This class should be used only with Tracer.inject()!");
}
protected Map<String, List<String>> servletHeadersToMultiMap(
final HttpServletRequest httpServletRequest) {
final Map<String, List<String>> headersResult = new HashMap<>();
final Enumeration<?> headerNamesIt = httpServletRequest.getHeaderNames();
while (headerNamesIt.hasMoreElements()) {
final String headerName = headerNamesIt.nextElement().toString();
final Enumeration<?> valuesIt = httpServletRequest.getHeaders(headerName);
final List<String> valuesList = new ArrayList<>(1);
while (valuesIt.hasMoreElements()) {
valuesList.add(valuesIt.nextElement().toString());
}
headersResult.put(headerName, valuesList);
}
return headersResult;
}
public static final class MultivaluedMapFlatIterator<K, V> implements Iterator<Map.Entry<K, V>> {
private final Iterator<Map.Entry<K, List<V>>> mapIterator;
private Map.Entry<K, List<V>> mapEntry;
private Iterator<V> listIterator;
public MultivaluedMapFlatIterator(final Set<Map.Entry<K, List<V>>> multiValuesEntrySet) {
mapIterator = multiValuesEntrySet.iterator();
}
@Override
public boolean hasNext() {
if (listIterator != null && listIterator.hasNext()) {
return true;
}
return mapIterator.hasNext();
}
@Override
public Map.Entry<K, V> next() {
if (mapEntry == null || (!listIterator.hasNext() && mapIterator.hasNext())) {
mapEntry = mapIterator.next();
listIterator = mapEntry.getValue().iterator();
}
if (listIterator.hasNext()) {
return new AbstractMap.SimpleImmutableEntry<>(mapEntry.getKey(), listIterator.next());
} else {
return new AbstractMap.SimpleImmutableEntry<>(mapEntry.getKey(), null);
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
}

View File

@ -0,0 +1,330 @@
package server
import datadog.opentracing.DDTracer
import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.common.writer.ListWriter
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request
import spock.lang.Shared
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
/* Don't actually need AgentTestRunner, but it messes up the classloader for AgentTestRunnerTest if this runs first. */
class ServerTest extends AgentTestRunner {
@Shared
def client = OkHttpUtils.client()
def "test server lifecycle"() {
setup:
def server = httpServer(startAutomatically) {
handlers {}
}
expect:
server.internalServer.isRunning() == startAutomatically
when:
server.start()
then:
server.internalServer.isRunning()
when:
server.stop()
then:
!server.internalServer.isRunning()
when:
server.start()
then:
server.internalServer.isRunning()
when:
server.stop()
then:
!server.internalServer.isRunning()
cleanup:
server.stop()
where:
startAutomatically << [true, false]
}
def "server 404's with no handlers"() {
setup:
def server = httpServer {
handlers {}
}
when:
def request = new Request.Builder()
.url("$server.address")
.get()
.build()
def response = client.newCall(request).execute()
then:
response.code() == 404
response.body().string().contains("<title>Error 404 Not Found</title>")
cleanup:
server.stop()
}
def "server accepts #path requests"() {
setup:
def server = httpServer {
handlers {
get("/get") {
response.send("/get response")
}
post("/post") {
response.send("/post response")
}
put("/put") {
response.send("/put response")
}
prefix("/base") {
response.send("${request.path} response")
}
all {
response.send("/all response")
}
}
}
when:
def request = new Request.Builder()
.url("$server.address/$path")
if (method == "get") {
request."$method"()
} else {
request."$method"(body())
}
def response = client.newCall(request.build()).execute()
then:
response.code() == 200
response.body().string().trim() == "/$path response"
cleanup:
server.stop()
where:
method | path
"get" | "get"
"post" | "post"
"put" | "put"
"get" | "base"
"post" | "base"
"get" | "base/get"
"post" | "base/post"
"get" | "all"
"post" | "all"
}
def "server returns different response codes"() {
setup:
def server = httpServer {
handlers {
get("/get") {
response.status(201).send("get response")
}
post("/post") {
response.status(202).send("post response")
}
all {
response.status(203).send("all response")
}
}
}
when:
def request = new Request.Builder()
.url("$server.address/$method")
if (method == "post") {
request."$method"(body())
} else {
request."$method"()
}
def response = client.newCall(request.build()).execute()
then:
response.code() == code
response.body().string().trim() == "$resp"
server.lastRequest.contentType == contentType
server.lastRequest.text.empty == !hasContent
cleanup:
server.stop()
where:
method | resp | code | contentType | hasContent
"get" | "get response" | 201 | null | false
"post" | "post response" | 202 | "multipart/mixed" | true
"head" | "" | 203 | null | false
}
def "server retains details of request sent"() {
setup:
def server = httpServer {
handlers {
all {
response.send()
}
}
}
when:
def request = new Request.Builder()
.url("$server.address")
.get()
.header(headerKey, headerValue)
.build()
def response = client.newCall(request).execute()
then:
response.code() == 200
response.body().string().trim() == ""
server.lastRequest.contentType == null
server.lastRequest.headers.get(headerKey) == headerValue
server.lastRequest.headers.get(newKey) == null
when:
def request2 = new Request.Builder()
.url("$server.address")
.get()
.header(newKey, newValue)
.build()
def response2 = client.newCall(request2).execute()
then:
response2.code() == 200
response2.body().string().trim() == ""
server.lastRequest.contentType == null
server.lastRequest.headers.get(headerKey) == null
server.lastRequest.headers.get(newKey) == newValue
cleanup:
server.stop()
where:
headerKey = "some-key"
headerValue = "some-value"
newKey = "new-key"
newValue = "new-value"
}
def "server redirect"() {
setup:
client = new OkHttpClient().newBuilder().followRedirects(followRedirects).build()
def server = httpServer {
handlers {
get("/redirect") {
redirect("/redirected")
}
get("/redirected") {
response.status(201).send("somewhere else")
}
}
}
when:
def request = new Request.Builder()
.url("$server.address/redirect")
.get()
.build()
def response = client.newCall(request).execute()
then:
response.code() == code
response.body().string() == body
cleanup:
server.stop()
where:
followRedirects | code | body
true | 201 | "somewhere else"
false | 302 | ""
}
def "server sends no body on head request"() {
setup:
def server = httpServer {
handlers {
all {
response.send("invalid content")
}
}
}
when:
def request = new Request.Builder()
.url("$server.address")
.head()
.build()
def response = client.newCall(request).execute()
then:
response.code() == 200
response.body().string().trim() == ""
cleanup:
server.stop()
}
def "server handles distributed request"() {
setup:
def server = httpServer {
handlers {
all {
handleDistributedRequest()
response.send("done")
}
}
}
def writer = new ListWriter()
server.tracer = new DDTracer(writer)
when:
def request = new Request.Builder()
.url("$server.address")
.get()
.build()
def response = client.newCall(request).execute()
then:
response.code() == 200
response.body().string().trim() == "done"
assertTraces(writer, 1) {
server.distributedRequestTrace(it, 0)
}
cleanup:
server.stop()
}
def body() {
return new MultipartBody.Builder().addFormDataPart("key", "value").build()
}
}

View File

@ -3,10 +3,9 @@ apply from: "${rootDir}/gradle/java.gradle"
minimumBranchCoverage = 0.5 minimumBranchCoverage = 0.5
minimumInstructionCoverage = 0.6 minimumInstructionCoverage = 0.6
excludedClassesConverage += [ excludedClassesConverage += [
'datadog.trace.agent.test.*Assert', 'datadog.trace.agent.test.asserts.*Assert',
'datadog.trace.agent.test.AgentTestRunner.ErrorCountingListener', 'datadog.trace.agent.test.AgentTestRunner.ErrorCountingListener',
'datadog.trace.agent.test.*Utils', 'datadog.trace.agent.test.OkHttpUtils'
'datadog.trace.agent.test.*Utils.*'
] ]
dependencies { dependencies {
@ -18,9 +17,9 @@ dependencies {
compile deps.testLogging compile deps.testLogging
compile deps.guava compile deps.guava
compile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.0.0.v20110901'
compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.10.0' compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.10.0'
// Note: this should be the same version as in java.gradle
compileOnly group: 'io.ratpack', name: 'ratpack-groovy-test', version: '1.4.6'
compile project(':dd-trace-ot') compile project(':dd-trace-ot')
compile project(':dd-java-agent:agent-tooling') compile project(':dd-java-agent:agent-tooling')

View File

@ -15,9 +15,6 @@ excludedClassesConverage += [
'datadog.trace.common.sampling.PrioritySampling' 'datadog.trace.common.sampling.PrioritySampling'
] ]
// These classes use Ratpack which requires Java 8. (Currently also incompatible with Java 9.)
testJava8Only += 'datadog/trace/api/writer/DDApiTest.class'
apply plugin: 'org.unbroken-dome.test-sets' apply plugin: 'org.unbroken-dome.test-sets'
testSets { testSets {
@ -38,6 +35,7 @@ dependencies {
// java.lang.NoSuchMethodError: com.fasterxml.jackson.dataformat.smile.SmileGenerator.getOutputContext() // java.lang.NoSuchMethodError: com.fasterxml.jackson.dataformat.smile.SmileGenerator.getOutputContext()
compile group: 'org.msgpack', name: 'jackson-dataformat-msgpack', version: '0.8.14' compile group: 'org.msgpack', name: 'jackson-dataformat-msgpack', version: '0.8.14'
testCompile project(":dd-java-agent:testing")
testCompile deps.autoservice testCompile deps.autoservice
testCompile group: 'org.objenesis', name: 'objenesis', version: '2.6' testCompile group: 'org.objenesis', name: 'objenesis', version: '2.6'
testCompile group: 'cglib', name: 'cglib-nodep', version: '3.2.5' testCompile group: 'cglib', name: 'cglib-nodep', version: '3.2.5'

View File

@ -7,22 +7,19 @@ import datadog.opentracing.SpanFactory
import datadog.trace.common.writer.DDApi import datadog.trace.common.writer.DDApi
import datadog.trace.common.writer.DDApi.ResponseListener import datadog.trace.common.writer.DDApi.ResponseListener
import org.msgpack.jackson.dataformat.MessagePackFactory import org.msgpack.jackson.dataformat.MessagePackFactory
import ratpack.exec.Blocking
import ratpack.http.Headers
import ratpack.http.MediaType
import spock.lang.Specification import spock.lang.Specification
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
import static ratpack.groovy.test.embed.GroovyEmbeddedApp.ratpack import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
class DDApiTest extends Specification { class DDApiTest extends Specification {
static mapper = new ObjectMapper(new MessagePackFactory()) static mapper = new ObjectMapper(new MessagePackFactory())
def "sending an empty list of traces returns no errors"() { def "sending an empty list of traces returns no errors"() {
setup: setup:
def agent = ratpack { def agent = httpServer {
handlers { handlers {
put("v0.4/traces") { put("v0.4/traces") {
def status = request.contentLength > 0 ? 200 : 500 def status = request.contentLength > 0 ? 200 : 500
@ -42,7 +39,7 @@ class DDApiTest extends Specification {
def "non-200 response results in false returned"() { def "non-200 response results in false returned"() {
setup: setup:
def agent = ratpack { def agent = httpServer {
handlers { handlers {
put("v0.4/traces") { put("v0.4/traces") {
response.status(404).send() response.status(404).send()
@ -61,32 +58,24 @@ class DDApiTest extends Specification {
def "content is sent as MSGPACK"() { def "content is sent as MSGPACK"() {
setup: setup:
def requestContentType = new AtomicReference<MediaType>() def agent = httpServer {
def requestHeaders = new AtomicReference<Headers>()
def requestBody = new AtomicReference<byte[]>()
def agent = ratpack {
handlers { handlers {
put("v0.4/traces") { put("v0.4/traces") {
requestContentType.set(request.contentType)
requestHeaders.set(request.headers)
request.body.then {
requestBody.set(it.bytes)
response.send() response.send()
} }
} }
} }
}
def client = new DDApi("localhost", agent.address.port) def client = new DDApi("localhost", agent.address.port)
expect: expect:
client.tracesEndpoint == "http://localhost:${agent.address.port}/v0.4/traces" client.tracesEndpoint == "http://localhost:${agent.address.port}/v0.4/traces"
client.sendTraces(traces) client.sendTraces(traces)
requestContentType.get().type == "application/msgpack" agent.lastRequest.contentType == "application/msgpack"
requestHeaders.get().get("Datadog-Meta-Lang") == "java" agent.lastRequest.headers.get("Datadog-Meta-Lang") == "java"
requestHeaders.get().get("Datadog-Meta-Lang-Version") == System.getProperty("java.version", "unknown") agent.lastRequest.headers.get("Datadog-Meta-Lang-Version") == System.getProperty("java.version", "unknown")
requestHeaders.get().get("Datadog-Meta-Tracer-Version") == "Stubbed-Test-Version" agent.lastRequest.headers.get("Datadog-Meta-Tracer-Version") == "Stubbed-Test-Version"
requestHeaders.get().get("X-Datadog-Trace-Count") == "${traces.size()}" agent.lastRequest.headers.get("X-Datadog-Trace-Count") == "${traces.size()}"
convertList(requestBody.get()) == expectedRequestBody convertList(agent.lastRequest.body) == expectedRequestBody
cleanup: cleanup:
agent.close() agent.close()
@ -128,14 +117,12 @@ class DDApiTest extends Specification {
def "Api ResponseListeners see 200 responses"() { def "Api ResponseListeners see 200 responses"() {
setup: setup:
def agentResponse = new AtomicReference<String>(null) def agentResponse = new AtomicReference<String>(null)
def requestHeaders = new AtomicReference<Headers>()
ResponseListener responseListener = { String endpoint, JsonNode responseJson -> ResponseListener responseListener = { String endpoint, JsonNode responseJson ->
agentResponse.set(responseJson.toString()) agentResponse.set(responseJson.toString())
} }
def agent = ratpack { def agent = httpServer {
handlers { handlers {
put("v0.4/traces") { put("v0.4/traces") {
requestHeaders.set(request.headers)
def status = request.contentLength > 0 ? 200 : 500 def status = request.contentLength > 0 ? 200 : 500
response.status(status).send('{"hello":"test"}') response.status(status).send('{"hello":"test"}')
} }
@ -150,10 +137,10 @@ class DDApiTest extends Specification {
client.sendTraces([]) client.sendTraces([])
then: then:
agentResponse.get() == '{"hello":"test"}' agentResponse.get() == '{"hello":"test"}'
requestHeaders.get().get("Datadog-Meta-Lang") == "java" agent.lastRequest.headers.get("Datadog-Meta-Lang") == "java"
requestHeaders.get().get("Datadog-Meta-Lang-Version") == System.getProperty("java.version", "unknown") agent.lastRequest.headers.get("Datadog-Meta-Lang-Version") == System.getProperty("java.version", "unknown")
requestHeaders.get().get("Datadog-Meta-Tracer-Version") == "Stubbed-Test-Version" agent.lastRequest.headers.get("Datadog-Meta-Tracer-Version") == "Stubbed-Test-Version"
requestHeaders.get().get("X-Datadog-Trace-Count") == "3" // false data shows the value provided via traceCounter. agent.lastRequest.headers.get("X-Datadog-Trace-Count") == "3" // false data shows the value provided via traceCounter.
traceCounter.get() == 0 traceCounter.get() == 0
cleanup: cleanup:
@ -162,7 +149,7 @@ class DDApiTest extends Specification {
def "Api Downgrades to v3 if v0.4 not available"() { def "Api Downgrades to v3 if v0.4 not available"() {
setup: setup:
def v3Agent = ratpack { def v3Agent = httpServer {
handlers { handlers {
put("v0.3/traces") { put("v0.3/traces") {
def status = request.contentLength > 0 ? 200 : 500 def status = request.contentLength > 0 ? 200 : 500
@ -183,21 +170,19 @@ class DDApiTest extends Specification {
def "Api Downgrades to v3 if timeout exceeded (#delayTrace, #badPort)"() { def "Api Downgrades to v3 if timeout exceeded (#delayTrace, #badPort)"() {
// This test is unfortunately only exercising the read timeout, not the connect timeout. // This test is unfortunately only exercising the read timeout, not the connect timeout.
setup: setup:
def agent = ratpack { def agent = httpServer {
handlers { handlers {
put("v0.3/traces") { put("v0.3/traces") {
def status = request.contentLength > 0 ? 200 : 500 def status = request.contentLength > 0 ? 200 : 500
response.status(status).send() response.status(status).send()
} }
put("v0.4/traces") { put("v0.4/traces") {
Blocking.exec {
Thread.sleep(delayTrace) Thread.sleep(delayTrace)
def status = request.contentLength > 0 ? 200 : 500 def status = request.contentLength > 0 ? 200 : 500
response.status(status).send() response.status(status).send()
} }
} }
} }
}
def port = badPort ? 999 : agent.address.port def port = badPort ? 999 : agent.address.port
def client = new DDApi("localhost", port) def client = new DDApi("localhost", port)

View File

@ -69,9 +69,6 @@ dependencies {
testCompile deps.testLogging testCompile deps.testLogging
testCompile 'info.solidsoft.spock:spock-global-unroll:0.5.1' testCompile 'info.solidsoft.spock:spock-global-unroll:0.5.1'
testCompile group: 'com.github.stefanbirkner', name: 'system-rules', version: '1.17.1' testCompile group: 'com.github.stefanbirkner', name: 'system-rules', version: '1.17.1'
if (!project.name.contains("netty")) { // avoid screwing up the classpath...
testCompile group: 'io.ratpack', name: 'ratpack-groovy-test', version: '1.4.6'
}
} }
tasks.withType(Javadoc) { tasks.withType(Javadoc) {