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.testLogging
testCompile deps.guava
testCompile group: 'org.mongodb', name: 'mongo-java-driver', 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
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.defaultSetup
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 {
static {

View File

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

View File

@ -6,7 +6,7 @@ import okhttp3.OkHttpClient
import okhttp3.Request
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 {
static {

View File

@ -24,9 +24,6 @@ versionScan {
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'
testSets {

View File

@ -1,8 +1,6 @@
import datadog.opentracing.DDSpan
import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.ListWriterAssert
import datadog.trace.agent.test.RatpackUtils
import datadog.trace.agent.test.TraceAssert
import datadog.trace.agent.test.asserts.TraceAssert
import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags
import io.opentracing.tag.Tags
@ -13,37 +11,30 @@ import org.apache.http.client.config.RequestConfig
import org.apache.http.client.methods.HttpGet
import org.apache.http.impl.client.HttpClientBuilder
import org.apache.http.message.BasicHeader
import spock.lang.AutoCleanup
import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static ratpack.groovy.test.embed.GroovyEmbeddedApp.ratpack
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
class ApacheHttpClientTest extends AgentTestRunner {
@AutoCleanup
@Shared
def server = ratpack {
def server = httpServer {
handlers {
prefix("success") {
get {
RatpackUtils.handleDistributedRequest(context)
String msg = "<html><body><h1>Hello test.</h1>\n"
response.status(200).send(msg)
}
handleDistributedRequest()
String msg = "<html><body><h1>Hello test.</h1>\n"
response.status(200).send(msg)
}
prefix("redirect") {
get {
RatpackUtils.handleDistributedRequest(context)
redirect(server.address.resolve("/success").toURL().toString())
}
handleDistributedRequest()
redirect(server.address.resolve("/success").toURL().toString())
}
prefix("another-redirect") {
get {
RatpackUtils.handleDistributedRequest(context)
redirect(server.address.resolve("/redirect").toURL().toString())
}
handleDistributedRequest()
redirect(server.address.resolve("/redirect").toURL().toString())
}
}
}
@ -67,7 +58,7 @@ class ApacheHttpClientTest extends AgentTestRunner {
response.getStatusLine().getStatusCode() == 200
// one trace on the server, one trace on the client
assertTraces(TEST_WRITER, 2) {
serverTrace(it, 0, TEST_WRITER[1][1])
server.distributedRequestTrace(it, 0, TEST_WRITER[1][1])
trace(1, 2) {
clientParentSpan(it, 0)
successClientSpan(it, 1, span(0))
@ -90,8 +81,8 @@ class ApacheHttpClientTest extends AgentTestRunner {
response.getStatusLine().getStatusCode() == 200
// two traces on the server, one trace on the client
assertTraces(TEST_WRITER, 3) {
serverTrace(it, 0, TEST_WRITER[2][2])
serverTrace(it, 1, TEST_WRITER[2][1])
server.distributedRequestTrace(it, 0, TEST_WRITER[2][2])
server.distributedRequestTrace(it, 1, TEST_WRITER[2][1])
trace(2, 3) {
clientParentSpan(it, 0)
successClientSpan(it, 1, span(0))
@ -114,8 +105,8 @@ class ApacheHttpClientTest extends AgentTestRunner {
response.getStatusLine().getStatusCode() == 200
// two traces on the server, one trace on the client
assertTraces(TEST_WRITER, 3) {
serverTrace(it, 0, TEST_WRITER[2][2])
serverTrace(it, 1, TEST_WRITER[2][1])
server.distributedRequestTrace(it, 0, TEST_WRITER[2][2])
server.distributedRequestTrace(it, 1, TEST_WRITER[2][1])
trace(2, 3) {
clientParentSpan(it, 0)
successClientSpan(it, 1, span(0))
@ -139,8 +130,8 @@ class ApacheHttpClientTest extends AgentTestRunner {
def exception = thrown(ClientProtocolException)
// two traces on the server, one trace on the client
assertTraces(TEST_WRITER, 3) {
serverTrace(it, 0, TEST_WRITER[2][2])
serverTrace(it, 1, TEST_WRITER[2][1])
server.distributedRequestTrace(it, 0, TEST_WRITER[2][2])
server.distributedRequestTrace(it, 1, TEST_WRITER[2][1])
trace(2, 3) {
clientParentSpan(it, 0, exception)
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) {
trace.span(index) {
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 {
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.api.DDTags
import io.opentracing.tag.Tags
import ratpack.http.Headers
import spock.lang.AutoCleanup
import spock.lang.Shared
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 {
def setupSpec() {
@ -27,15 +27,13 @@ class AWSClientTest extends AgentTestRunner {
System.clearProperty(SDKGlobalConfiguration.SECRET_KEY_SYSTEM_PROPERTY)
}
@Shared
def receivedHeaders = new AtomicReference<Headers>()
@Shared
def responseBody = new AtomicReference<String>()
@AutoCleanup
@Shared
def server = ratpack {
def server = httpServer {
handlers {
all {
receivedHeaders.set(request.headers)
response.status(200).send(responseBody.get())
}
}
@ -148,8 +146,8 @@ class AWSClientTest extends AgentTestRunner {
tags["thread.id"] != null
tags.size() == 13
receivedHeaders.get().get("x-datadog-trace-id") == "$span.traceId"
receivedHeaders.get().get("x-datadog-parent-id") == "$span.spanId"
server.lastRequest.headers.get("x-datadog-trace-id") == "$span.traceId"
server.lastRequest.headers.get("x-datadog-parent-id") == "$span.spanId"
where:
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 {
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.api.DDTags
import io.opentracing.tag.Tags
import ratpack.http.Headers
import spock.lang.AutoCleanup
import spock.lang.Shared
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 {
def setupSpec() {
@ -35,14 +35,12 @@ class AWSClientTest extends AgentTestRunner {
@Shared
def credentialsProvider = new AWSStaticCredentialsProvider(new AnonymousAWSCredentials())
@Shared
def receivedHeaders = new AtomicReference<Headers>()
@Shared
def responseBody = new AtomicReference<String>()
@AutoCleanup
@Shared
def server = ratpack {
def server = httpServer {
handlers {
all {
receivedHeaders.set(request.headers)
response.status(200).send(responseBody.get())
}
}
@ -177,8 +175,8 @@ class AWSClientTest extends AgentTestRunner {
tags["thread.id"] != null
tags.size() == 13
receivedHeaders.get().get("x-datadog-trace-id") == "$span.traceId"
receivedHeaders.get().get("x-datadog-parent-id") == "$span.spanId"
server.lastRequest.headers.get("x-datadog-trace-id") == "$span.traceId"
server.lastRequest.headers.get("x-datadog-parent-id") == "$span.spanId"
where:
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 spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class Elasticsearch6RestClientTest extends AgentTestRunner {
static {

View File

@ -18,7 +18,7 @@ import org.elasticsearch.node.internal.InternalSettingsPreparer
import org.elasticsearch.transport.Netty3Plugin
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
class Elasticsearch5RestClientTest extends AgentTestRunner {

View File

@ -11,7 +11,7 @@ import org.elasticsearch.node.Node
import org.elasticsearch.node.NodeBuilder
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 {
static {

View File

@ -21,7 +21,7 @@ import springdata.Doc
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 {
static {

View File

@ -14,7 +14,7 @@ import org.elasticsearch.node.NodeBuilder
import org.elasticsearch.transport.RemoteTransportException
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 {
static {

View File

@ -8,7 +8,7 @@ import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.AnnotationConfigApplicationContext
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 {
static {

View File

@ -13,7 +13,7 @@ import org.elasticsearch.node.internal.InternalSettingsPreparer
import org.elasticsearch.transport.Netty3Plugin
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
class Elasticsearch5NodeClientTest extends AgentTestRunner {

View File

@ -17,7 +17,7 @@ import org.elasticsearch.transport.RemoteTransportException
import org.elasticsearch.transport.client.PreBuiltTransportClient
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
class Elasticsearch5TransportClientTest extends AgentTestRunner {

View File

@ -12,7 +12,7 @@ import org.elasticsearch.node.Node
import org.elasticsearch.transport.Netty4Plugin
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
class Elasticsearch6NodeClientTest extends AgentTestRunner {

View File

@ -16,7 +16,7 @@ import org.elasticsearch.transport.RemoteTransportException
import org.elasticsearch.transport.client.PreBuiltTransportClient
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
class Elasticsearch6TransportClientTest extends AgentTestRunner {

View File

@ -15,7 +15,7 @@ import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.TimeUnit
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 {
static {

View File

@ -15,7 +15,7 @@ import io.opentracing.tag.Tags
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 {
static {

View File

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

View File

@ -1,19 +1,15 @@
import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.RatpackUtils
import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags
import io.opentracing.propagation.TextMap
import io.opentracing.tag.Tags
import io.opentracing.util.GlobalTracer
import org.springframework.web.client.RestTemplate
import ratpack.handling.Context
import spock.lang.AutoCleanup
import spock.lang.Shared
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.TestUtils.runUnderTrace
import static ratpack.groovy.test.embed.GroovyEmbeddedApp.ratpack
import static ratpack.http.HttpMethod.HEAD
import static ratpack.http.HttpMethod.POST
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.server.http.TestHttpServer.httpServer
class HttpUrlConnectionTest extends AgentTestRunner {
static {
@ -23,26 +19,14 @@ class HttpUrlConnectionTest extends AgentTestRunner {
static final RESPONSE = "<html><body><h1>Hello test.</h1>"
static final STATUS = 202
@AutoCleanup
@Shared
def server = ratpack {
def server = httpServer {
handlers {
all {
RatpackUtils.handleDistributedRequest(context)
handleDistributedRequest()
request.body.then {
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)
}
}
response.status(STATUS).send(RESPONSE)
}
}
}
@ -73,26 +57,8 @@ class HttpUrlConnectionTest extends AgentTestRunner {
expect:
assertTraces(TEST_WRITER, 3) {
trace(0, 1) {
span(0) {
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()
}
}
}
server.distributedRequestTrace(it, 0, TEST_WRITER[2][2])
server.distributedRequestTrace(it, 1, TEST_WRITER[2][1])
trace(2, 3) {
span(0) {
operationName "someTrace"
@ -221,7 +187,7 @@ class HttpUrlConnectionTest extends AgentTestRunner {
setup:
runUnderTrace("someTrace") {
HttpURLConnection connection = server.address.toURL().openConnection()
connection.setRequestMethod(HEAD.name)
connection.setRequestMethod("HEAD")
connection.addRequestProperty("is-dd-server", "false")
assert GlobalTracer.get().scopeManager().active() != null
assert connection.getResponseCode() == STATUS
@ -310,7 +276,7 @@ class HttpUrlConnectionTest extends AgentTestRunner {
setup:
runUnderTrace("someTrace") {
HttpURLConnection connection = server.address.toURL().openConnection()
connection.setRequestMethod(POST.name)
connection.setRequestMethod("POST")
String urlParameters = "q=ASDF&w=&e=&r=12345&t="
@ -331,16 +297,7 @@ class HttpUrlConnectionTest extends AgentTestRunner {
expect:
assertTraces(TEST_WRITER, 2) {
trace(0, 1) {
span(0) {
operationName "test-http-server"
childOf(TEST_WRITER[1][1])
errored false
tags {
defaultTags()
}
}
}
server.distributedRequestTrace(it, 0, TEST_WRITER[1][1])
trace(1, 3) {
span(0) {
operationName "someTrace"
@ -432,21 +389,12 @@ class HttpUrlConnectionTest extends AgentTestRunner {
runUnderTrace("someTrace") {
RestTemplate restTemplate = new RestTemplate()
String res = restTemplate.postForObject(server.address.toString(), "Hello", String)
assert res == RESPONSE
assert res == "$RESPONSE"
}
expect:
assertTraces(TEST_WRITER, 2) {
trace(0, 1) {
span(0) {
operationName "test-http-server"
childOf(TEST_WRITER[1][2])
errored false
tags {
defaultTags()
}
}
}
server.distributedRequestTrace(it, 0, TEST_WRITER[1][2])
trace(1, 4) {
span(0) {
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.util.GlobalTracer
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.TestUtils.runUnderTrace
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class UrlConnectionTest extends AgentTestRunner {
static {
@ -36,7 +36,7 @@ class UrlConnectionTest extends AgentTestRunner {
parent()
errored true
tags {
errorTags ConnectException, "Connection refused (Connection refused)"
errorTags ConnectException, String
defaultTags()
}
}
@ -52,7 +52,7 @@ class UrlConnectionTest extends AgentTestRunner {
"$Tags.HTTP_METHOD.key" "GET"
"$Tags.PEER_HOSTNAME.key" "localhost"
"$Tags.PEER_PORT.key" INVALID_PORT
errorTags ConnectException, "Connection refused (Connection refused)"
errorTags ConnectException, String
defaultTags()
}
}

View File

@ -6,8 +6,8 @@ import java.util.concurrent.BlockingQueue
import java.util.concurrent.LinkedBlockingQueue
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.asserts.ListWriterAssert.assertTraces
class HystrixTest extends AgentTestRunner {
// Uncomment for debugging:

View File

@ -4,7 +4,7 @@ import datadog.trace.api.DDTags
import io.opentracing.tag.Tags
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 {

View File

@ -9,8 +9,8 @@ import javax.ws.rs.POST
import javax.ws.rs.PUT
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.asserts.ListWriterAssert.assertTraces
class JaxRsAnnotationsInstrumentationTest extends AgentTestRunner {

View File

@ -8,11 +8,8 @@
apply from: "${rootDir}/gradle/java.gradle"
// These classes use Ratpack which requires Java 8. (Currently also incompatible with Java 9.)
testJava8Only += '**/*.class'
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'
@ -25,14 +22,15 @@ dependencies {
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.apache.cxf', name: 'cxf-rt-rs-client', version: '3.2.2'
testCompile group: 'org.jboss.resteasy', name: 'resteasy-client', version: '3.5.0.Final'
testCompile group: 'org.apache.cxf', name: 'cxf-rt-rs-client', version: '3.1.16'
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-servlet', version: '1.19.4'
// 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.glassfish.jersey.client.JerseyClientBuilder
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.Client
@ -13,16 +14,16 @@ import javax.ws.rs.client.Invocation
import javax.ws.rs.client.WebTarget
import javax.ws.rs.core.MediaType
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 {
def receivedHeaders = new AtomicReference<Headers>()
def server = ratpack {
@AutoCleanup
@Shared
def server = httpServer {
handlers {
all {
receivedHeaders.set(request.headers)
response.status(200).send("pong")
}
}
@ -71,11 +72,8 @@ class JaxRsClientTest extends AgentTestRunner {
tags[DDTags.THREAD_ID] != null
tags.size() == 8
receivedHeaders.get().get("x-datadog-trace-id") == "$span.traceId"
receivedHeaders.get().get("x-datadog-parent-id") == "$span.spanId"
cleanup:
server.close()
server.lastRequest.headers.get("x-datadog-trace-id") == "$span.traceId"
server.lastRequest.headers.get("x-datadog-parent-id") == "$span.spanId"
where:
builder | async | lib

View File

@ -16,7 +16,7 @@ import java.sql.PreparedStatement
import java.sql.ResultSet
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 {

View File

@ -30,7 +30,9 @@ dependencies {
annotationProcessor 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-servlet', version: '8.0.0.v20110901'
}

View File

@ -16,6 +16,7 @@ import javax.servlet.http.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;
@ -61,7 +62,7 @@ public class HttpServletRequestExtractAdapter implements TextMap {
private Iterator<V> listIterator;
public MultivaluedMapFlatIterator(final Set<Map.Entry<K, List<V>>> multiValuesEntrySet) {
this.mapIterator = multiValuesEntrySet.iterator();
mapIterator = multiValuesEntrySet.iterator();
}
@Override

View File

@ -1,6 +1,6 @@
import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils
import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes
import okhttp3.OkHttpClient
import org.eclipse.jetty.continuation.Continuation
@ -14,7 +14,7 @@ import javax.servlet.ServletException
import javax.servlet.http.HttpServletRequest
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 {

View File

@ -1,5 +1,5 @@
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.DDTags
import io.opentracing.tag.Tags
@ -17,7 +17,7 @@ import javax.jms.TextMessage
import java.util.concurrent.CountDownLatch
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 {
@Shared

View File

@ -1,6 +1,6 @@
import com.google.common.io.Files
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.DDTags
import io.opentracing.tag.Tags
@ -26,7 +26,7 @@ import javax.jms.TextMessage
import java.util.concurrent.CountDownLatch
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 {
@Shared

View File

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

View File

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

View File

@ -25,7 +25,7 @@ import java.util.function.BiFunction
import java.util.function.Consumer
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
class LettuceAsyncClientTest extends AgentTestRunner {

View File

@ -13,7 +13,7 @@ import spock.util.concurrent.AsyncConditions
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
class LettuceReactiveClientTest extends AgentTestRunner {

View File

@ -12,7 +12,7 @@ import spock.lang.Shared
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
class LettuceSyncClientTest extends AgentTestRunner {

View File

@ -33,7 +33,6 @@ dependencies {
testCompile project(':dd-java-agent:testing')
// 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'
}

View File

@ -1,22 +1,16 @@
import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.TestUtils
import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags
import io.opentracing.tag.Tags
import org.asynchttpclient.AsyncHttpClient
import org.asynchttpclient.DefaultAsyncHttpClientConfig
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.util.MultiMap
import spock.lang.AutoCleanup
import spock.lang.Shared
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
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
class Netty40ClientTest extends AgentTestRunner {
@ -24,53 +18,28 @@ class Netty40ClientTest extends AgentTestRunner {
System.setProperty("dd.integration.netty.enabled", "true")
}
@AutoCleanup
@Shared
int port
@Shared
Server server
def server = httpServer {
handlers {
all {
response.send("Hello World")
}
}
}
@Shared
def clientConfig = DefaultAsyncHttpClientConfig.Builder.newInstance().setRequestTimeout(TimeUnit.MINUTES.toMillis(1).toInteger())
@Shared
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"() {
setup:
def responseFuture = asyncHttpClient.prepareGet("http://localhost:$port/").execute()
def responseFuture = asyncHttpClient.prepareGet("$server.address").execute()
def response = responseFuture.get()
expect:
response.statusCode == 200
response.responseBody == "Hello World\n"
response.responseBody == "Hello World"
and:
assertTraces(TEST_WRITER, 1) {
@ -85,7 +54,7 @@ class Netty40ClientTest extends AgentTestRunner {
"$Tags.COMPONENT.key" "netty-client"
"$Tags.HTTP_METHOD.key" "GET"
"$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_PORT.key" Integer
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
@ -97,7 +66,7 @@ class Netty40ClientTest extends AgentTestRunner {
}
and:
headers["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-trace-id") == "${TEST_WRITER.get(0).get(0).traceId}"
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.OkHttpUtils
import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags
import io.netty.bootstrap.ServerBootstrap
@ -28,7 +28,7 @@ import io.opentracing.tag.Tags
import okhttp3.OkHttpClient
import okhttp3.Request
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class Netty40ServerTest extends AgentTestRunner {
static {

View File

@ -33,7 +33,6 @@ dependencies {
testCompile project(':dd-java-agent:testing')
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'
// 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.TestUtils
import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags
import io.opentracing.tag.Tags
import org.asynchttpclient.AsyncHttpClient
import org.asynchttpclient.DefaultAsyncHttpClientConfig
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.util.MultiMap
import spock.lang.AutoCleanup
import spock.lang.Shared
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
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
class Netty41ClientTest extends AgentTestRunner {
@ -24,53 +18,28 @@ class Netty41ClientTest extends AgentTestRunner {
System.setProperty("dd.integration.netty.enabled", "true")
}
@AutoCleanup
@Shared
int port
@Shared
Server server
def server = httpServer {
handlers {
all {
response.send("Hello World")
}
}
}
@Shared
def clientConfig = DefaultAsyncHttpClientConfig.Builder.newInstance().setRequestTimeout(TimeUnit.MINUTES.toMillis(1).toInteger())
@Shared
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"() {
setup:
def responseFuture = asyncHttpClient.prepareGet("http://localhost:$port/").execute()
def responseFuture = asyncHttpClient.prepareGet("$server.address").execute()
def response = responseFuture.get()
expect:
response.statusCode == 200
response.responseBody == "Hello World\n"
response.responseBody == "Hello World"
and:
assertTraces(TEST_WRITER, 1) {
@ -85,7 +54,7 @@ class Netty41ClientTest extends AgentTestRunner {
"$Tags.COMPONENT.key" "netty-client"
"$Tags.HTTP_METHOD.key" "GET"
"$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_PORT.key" Integer
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
@ -97,7 +66,7 @@ class Netty41ClientTest extends AgentTestRunner {
}
and:
headers["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-trace-id") == "${TEST_WRITER.get(0).get(0).traceId}"
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.OkHttpUtils
import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags
import io.netty.bootstrap.ServerBootstrap
@ -28,7 +28,7 @@ import io.opentracing.tag.Tags
import okhttp3.OkHttpClient
import okhttp3.Request
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
class Netty41ServerTest extends AgentTestRunner {
static {

View File

@ -14,9 +14,6 @@ versionScan {
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'
testSets {

View File

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

View File

@ -7,7 +7,7 @@ import play.api.test.TestServer
import play.test.Helpers
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 {
static {

View File

@ -57,12 +57,12 @@ dependencies {
compile sourceSets.main_java8.output
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 {
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.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.instrumentation.ratpack.impl.RatpackScopeManager
import io.opentracing.Scope

View File

@ -22,7 +22,9 @@ dependencies {
annotationProcessor 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-servlet', version: '7.0.0.v20091005'
}

View File

@ -16,6 +16,7 @@ import javax.servlet.http.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;
@ -61,7 +62,7 @@ public class HttpServletRequestExtractAdapter implements TextMap {
private Iterator<V> listIterator;
public MultivaluedMapFlatIterator(final Set<Map.Entry<K, List<V>>> multiValuesEntrySet) {
this.mapIterator = multiValuesEntrySet.iterator();
mapIterator = multiValuesEntrySet.iterator();
}
@Override

View File

@ -1,6 +1,6 @@
import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils
import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes
import okhttp3.Credentials
import okhttp3.Interceptor
@ -17,7 +17,7 @@ import org.eclipse.jetty.security.authentication.BasicAuthenticator
import org.eclipse.jetty.server.Server
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 {

View File

@ -32,7 +32,9 @@ dependencies {
annotationProcessor 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 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'

View File

@ -16,6 +16,7 @@ import javax.servlet.http.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;
@ -61,7 +62,7 @@ public class HttpServletRequestExtractAdapter implements TextMap {
private Iterator<V> listIterator;
public MultivaluedMapFlatIterator(final Set<Map.Entry<K, List<V>>> multiValuesEntrySet) {
this.mapIterator = multiValuesEntrySet.iterator();
mapIterator = multiValuesEntrySet.iterator();
}
@Override

View File

@ -1,6 +1,6 @@
import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils
import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes
import okhttp3.Credentials
import okhttp3.Interceptor
@ -17,7 +17,7 @@ import org.eclipse.jetty.server.Server
import org.eclipse.jetty.servlet.ServletContextHandler
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 {

View File

@ -1,7 +1,7 @@
import com.google.common.io.Files
import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.OkHttpUtils
import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.DDSpanTypes
import okhttp3.OkHttpClient
import okhttp3.Request
@ -11,7 +11,7 @@ import org.apache.catalina.startup.Tomcat
import org.apache.tomcat.JarScanFilter
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 {

View File

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

View File

@ -1,7 +1,7 @@
package test
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.DDTags
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.util.NestedServletException
import static datadog.trace.agent.test.ListWriterAssert.assertTraces
import static datadog.trace.agent.test.asserts.ListWriterAssert.assertTraces
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class SpringBootBasedTest extends AgentTestRunner {

View File

@ -2,7 +2,7 @@ package datadog.trace.instrumentation.spymemcached
import com.google.common.util.concurrent.MoreExecutors
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.DDTags
import io.opentracing.tag.Tags
@ -26,8 +26,8 @@ import java.util.concurrent.locks.ReentrantLock
import static CompletionListener.COMPONENT_NAME
import static CompletionListener.OPERATION_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.asserts.ListWriterAssert.assertTraces
import static net.spy.memcached.ConnectionFactoryBuilder.Protocol.BINARY
// 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 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.asserts.ListWriterAssert.assertTraces
class ConfiguredTraceAnnotationsTest extends AgentTestRunner {

View File

@ -5,7 +5,7 @@ import dd.test.trace.annotation.SayTracedHello
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 {

View File

@ -3,8 +3,8 @@ import datadog.trace.instrumentation.trace_annotation.TraceConfigInstrumentation
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.asserts.ListWriterAssert.assertTraces
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.trace.common.writer.ListWriter
@ -7,7 +7,7 @@ import org.spockframework.runtime.Condition
import org.spockframework.runtime.ConditionNotSatisfiedError
import org.spockframework.runtime.model.TextPosition
import static datadog.trace.agent.test.TraceAssert.assertTrace
import static TraceAssert.assertTrace
class ListWriterAssert {
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 static datadog.trace.agent.test.TagsAssert.assertTags
import static TagsAssert.assertTags
class SpanAssert {
private final DDSpan span
@ -18,7 +18,6 @@ class SpanAssert {
clone.delegate = asserter
clone.resolveStrategy = Closure.DELEGATE_FIRST
clone(asserter)
asserter
}
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
@ -18,7 +18,6 @@ class TagsAssert {
clone.resolveStrategy = Closure.DELEGATE_FIRST
clone(asserter)
asserter.assertTagsAllVerified()
asserter
}
def defaultTags() {

View File

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

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
minimumInstructionCoverage = 0.6
excludedClassesConverage += [
'datadog.trace.agent.test.*Assert',
'datadog.trace.agent.test.asserts.*Assert',
'datadog.trace.agent.test.AgentTestRunner.ErrorCountingListener',
'datadog.trace.agent.test.*Utils',
'datadog.trace.agent.test.*Utils.*'
'datadog.trace.agent.test.OkHttpUtils'
]
dependencies {
@ -18,9 +17,9 @@ dependencies {
compile deps.testLogging
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'
// 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-java-agent:agent-tooling')

View File

@ -15,9 +15,6 @@ excludedClassesConverage += [
'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'
testSets {
@ -38,6 +35,7 @@ dependencies {
// java.lang.NoSuchMethodError: com.fasterxml.jackson.dataformat.smile.SmileGenerator.getOutputContext()
compile group: 'org.msgpack', name: 'jackson-dataformat-msgpack', version: '0.8.14'
testCompile project(":dd-java-agent:testing")
testCompile deps.autoservice
testCompile group: 'org.objenesis', name: 'objenesis', version: '2.6'
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.ResponseListener
import org.msgpack.jackson.dataformat.MessagePackFactory
import ratpack.exec.Blocking
import ratpack.http.Headers
import ratpack.http.MediaType
import spock.lang.Specification
import java.util.concurrent.atomic.AtomicInteger
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 {
static mapper = new ObjectMapper(new MessagePackFactory())
def "sending an empty list of traces returns no errors"() {
setup:
def agent = ratpack {
def agent = httpServer {
handlers {
put("v0.4/traces") {
def status = request.contentLength > 0 ? 200 : 500
@ -42,7 +39,7 @@ class DDApiTest extends Specification {
def "non-200 response results in false returned"() {
setup:
def agent = ratpack {
def agent = httpServer {
handlers {
put("v0.4/traces") {
response.status(404).send()
@ -61,18 +58,10 @@ class DDApiTest extends Specification {
def "content is sent as MSGPACK"() {
setup:
def requestContentType = new AtomicReference<MediaType>()
def requestHeaders = new AtomicReference<Headers>()
def requestBody = new AtomicReference<byte[]>()
def agent = ratpack {
def agent = httpServer {
handlers {
put("v0.4/traces") {
requestContentType.set(request.contentType)
requestHeaders.set(request.headers)
request.body.then {
requestBody.set(it.bytes)
response.send()
}
response.send()
}
}
}
@ -81,12 +70,12 @@ class DDApiTest extends Specification {
expect:
client.tracesEndpoint == "http://localhost:${agent.address.port}/v0.4/traces"
client.sendTraces(traces)
requestContentType.get().type == "application/msgpack"
requestHeaders.get().get("Datadog-Meta-Lang") == "java"
requestHeaders.get().get("Datadog-Meta-Lang-Version") == System.getProperty("java.version", "unknown")
requestHeaders.get().get("Datadog-Meta-Tracer-Version") == "Stubbed-Test-Version"
requestHeaders.get().get("X-Datadog-Trace-Count") == "${traces.size()}"
convertList(requestBody.get()) == expectedRequestBody
agent.lastRequest.contentType == "application/msgpack"
agent.lastRequest.headers.get("Datadog-Meta-Lang") == "java"
agent.lastRequest.headers.get("Datadog-Meta-Lang-Version") == System.getProperty("java.version", "unknown")
agent.lastRequest.headers.get("Datadog-Meta-Tracer-Version") == "Stubbed-Test-Version"
agent.lastRequest.headers.get("X-Datadog-Trace-Count") == "${traces.size()}"
convertList(agent.lastRequest.body) == expectedRequestBody
cleanup:
agent.close()
@ -128,14 +117,12 @@ class DDApiTest extends Specification {
def "Api ResponseListeners see 200 responses"() {
setup:
def agentResponse = new AtomicReference<String>(null)
def requestHeaders = new AtomicReference<Headers>()
ResponseListener responseListener = { String endpoint, JsonNode responseJson ->
agentResponse.set(responseJson.toString())
}
def agent = ratpack {
def agent = httpServer {
handlers {
put("v0.4/traces") {
requestHeaders.set(request.headers)
def status = request.contentLength > 0 ? 200 : 500
response.status(status).send('{"hello":"test"}')
}
@ -150,10 +137,10 @@ class DDApiTest extends Specification {
client.sendTraces([])
then:
agentResponse.get() == '{"hello":"test"}'
requestHeaders.get().get("Datadog-Meta-Lang") == "java"
requestHeaders.get().get("Datadog-Meta-Lang-Version") == System.getProperty("java.version", "unknown")
requestHeaders.get().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("Datadog-Meta-Lang") == "java"
agent.lastRequest.headers.get("Datadog-Meta-Lang-Version") == System.getProperty("java.version", "unknown")
agent.lastRequest.headers.get("Datadog-Meta-Tracer-Version") == "Stubbed-Test-Version"
agent.lastRequest.headers.get("X-Datadog-Trace-Count") == "3" // false data shows the value provided via traceCounter.
traceCounter.get() == 0
cleanup:
@ -162,7 +149,7 @@ class DDApiTest extends Specification {
def "Api Downgrades to v3 if v0.4 not available"() {
setup:
def v3Agent = ratpack {
def v3Agent = httpServer {
handlers {
put("v0.3/traces") {
def status = request.contentLength > 0 ? 200 : 500
@ -183,18 +170,16 @@ class DDApiTest extends Specification {
def "Api Downgrades to v3 if timeout exceeded (#delayTrace, #badPort)"() {
// This test is unfortunately only exercising the read timeout, not the connect timeout.
setup:
def agent = ratpack {
def agent = httpServer {
handlers {
put("v0.3/traces") {
def status = request.contentLength > 0 ? 200 : 500
response.status(status).send()
}
put("v0.4/traces") {
Blocking.exec {
Thread.sleep(delayTrace)
def status = request.contentLength > 0 ? 200 : 500
response.status(status).send()
}
Thread.sleep(delayTrace)
def status = request.contentLength > 0 ? 200 : 500
response.status(status).send()
}
}
}

View File

@ -69,9 +69,6 @@ dependencies {
testCompile deps.testLogging
testCompile 'info.solidsoft.spock:spock-global-unroll:0.5.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) {