Merge pull request #562 from DataDog/tyler/fix-latest-dep-tests

Add assertion to ensure latestDepTest dependencies are different from test
This commit is contained in:
Tyler Benson 2018-11-14 13:47:13 -08:00 committed by GitHub
commit 2ad1dee113
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 352 additions and 342 deletions

View File

@ -95,13 +95,6 @@ configurations.test_1_11_106Compile {
}
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'com.amazonaws', name: 'aws-java-sdk', version: '+'
}
}
dependencies {
compileOnly group: 'com.amazonaws', name: 'aws-java-sdk-core', version: '1.11.0'

View File

@ -36,10 +36,6 @@ dependencies {
testCompile project(':dd-java-agent:testing')
testCompile group: 'com.datastax.cassandra', name: 'cassandra-driver-core', version: '3.2.0'
testCompile group: 'org.cassandraunit', name: 'cassandra-unit', version: '3.1.3.2'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'com.datastax.cassandra', name: 'cassandra-driver-core', version: '+'
}
latestDepTestCompile group: 'com.datastax.cassandra', name: 'cassandra-driver-core', version: '+'
}

View File

@ -53,7 +53,7 @@ dependencies {
testCompile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.0'
testCompile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.11.0'
latestDepTestCompile group: 'org.elasticsearch.plugin', name: 'transport-netty4-client', version: '+'
latestDepTestCompile group: 'org.elasticsearch.client', name: 'transport', version: '+'
latestDepTestCompile group: 'org.elasticsearch.client', name: 'elasticsearch-rest-client', version: '+'
// Limit tests to <6.5 as the latest versions have a breaking change for the tests.
latestDepTestCompile group: 'org.elasticsearch.plugin', name: 'transport-netty4-client', version: '(6.1,6.5)'
latestDepTestCompile group: 'org.elasticsearch.client', name: 'transport', version: '(6.1,6.5)'
}

View File

@ -60,12 +60,7 @@ dependencies {
testCompile group: 'io.grpc', name: 'grpc-stub', version: grpcVersion
latestDepTestCompile sourceSets.test.output // include the protobuf generated classes
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'io.grpc', name: 'grpc-netty', version: '+'
force group: 'io.grpc', name: 'grpc-protobuf', version: '+'
force group: 'io.grpc', name: 'grpc-stub', version: '+'
}
latestDepTestCompile group: 'io.grpc', name: 'grpc-netty', version: '+'
latestDepTestCompile group: 'io.grpc', name: 'grpc-protobuf', version: '+'
latestDepTestCompile group: 'io.grpc', name: 'grpc-stub', version: '+'
}

View File

@ -32,10 +32,6 @@ dependencies {
testCompile project(':dd-java-agent:instrumentation:java-concurrent')
testCompile project(':dd-java-agent:instrumentation:trace-annotation')
testCompile group: 'com.netflix.hystrix', name: 'hystrix-core', version: '1.4.0'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'com.netflix.hystrix', name: 'hystrix-core', version: '+'
}
latestDepTestCompile group: 'com.netflix.hystrix', name: 'hystrix-core', version: '+'
}

View File

@ -33,17 +33,13 @@ dependencies {
testCompile group: 'org.apache.tomcat', name: 'tomcat-juli', version: '7.0.19'
testCompile group: 'com.zaxxer', name: 'HikariCP', version: '2.4.0'
testCompile group: 'com.mchange', name: 'c3p0', version: '0.9.5'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'com.h2database', name: 'h2', version: '+'
force group: 'org.apache.derby', name: 'derby', version: '+'
force group: 'org.hsqldb', name: 'hsqldb', version: '+'
latestDepTestCompile group: 'com.h2database', name: 'h2', version: '+'
latestDepTestCompile group: 'org.apache.derby', name: 'derby', version: '+'
latestDepTestCompile group: 'org.hsqldb', name: 'hsqldb', version: '+'
force group: 'org.apache.tomcat', name: 'tomcat-jdbc', version: '+'
force group: 'org.apache.tomcat', name: 'tomcat-juli', version: '+'
force group: 'com.zaxxer', name: 'HikariCP', version: '+'
force group: 'com.mchange', name: 'c3p0', version: '+'
}
latestDepTestCompile group: 'org.apache.tomcat', name: 'tomcat-jdbc', version: '+'
latestDepTestCompile group: 'org.apache.tomcat', name: 'tomcat-juli', version: '+'
latestDepTestCompile group: 'com.zaxxer', name: 'HikariCP', version: '+'
latestDepTestCompile group: 'com.mchange', name: 'c3p0', version: '+'
}

View File

@ -33,9 +33,3 @@ dependencies {
latestDepTestCompile group: 'redis.clients', name: 'jedis', version: '+'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'redis.clients', name: 'jedis', version: '+'
}
}

View File

@ -33,11 +33,9 @@ dependencies {
}
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-continuation', version: '8.0.0.v20110901'
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'org.eclipse.jetty', name: 'jetty-server', version: '+'
force group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '+'
}
latestDepTestCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '+'
latestDepTestCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '+'
latestDepTestCompile group: 'org.eclipse.jetty', name: 'jetty-continuation', version: '+'
}

View File

@ -16,7 +16,6 @@ import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class)
public final class HandlerInstrumentation extends Instrumenter.Default {
public static final String SERVLET_OPERATION_NAME = "jetty.request";
public HandlerInstrumentation() {
super("jetty", "jetty-8");

View File

@ -1,7 +1,6 @@
import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.TestUtils
import datadog.trace.agent.test.utils.OkHttpUtils
import datadog.trace.api.Config
import datadog.trace.api.DDSpanTypes
import okhttp3.OkHttpClient
import org.eclipse.jetty.continuation.Continuation
@ -11,9 +10,11 @@ import org.eclipse.jetty.server.Request
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.server.handler.AbstractHandler
import javax.servlet.DispatcherType
import javax.servlet.ServletException
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import java.util.concurrent.atomic.AtomicBoolean
class JettyHandlerTest extends AgentTestRunner {
@ -55,31 +56,30 @@ class JettyHandlerTest extends AgentTestRunner {
expect:
response.body().string().trim() == "Hello World"
TEST_WRITER.waitForTraces(1)
TEST_WRITER.size() == 1
def trace = TEST_WRITER.firstTrace()
trace.size() == 1
def context = trace[0].context()
context.serviceName == "unnamed-java-app"
context.operationName == "jetty.request"
context.resourceName == "GET ${handler.class.name}"
context.spanType == DDSpanTypes.HTTP_SERVER
!context.getErrorFlag()
context.parentId == "0"
def tags = context.tags
tags["http.url"] == "http://localhost:$port/"
tags["http.method"] == "GET"
tags["span.kind"] == "server"
tags["span.type"] == DDSpanTypes.HTTP_SERVER
tags["component"] == "jetty-handler"
tags["http.status_code"] == 200
tags["thread.name"] != null
tags["thread.id"] != null
tags[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
tags["span.origin.type"] == handler.class.name
tags.size() == 10
}
assertTraces(1) {
trace(0, 1) {
span(0) {
serviceName "unnamed-java-app"
operationName "jetty.request"
resourceName "GET ${handler.class.name}"
spanType DDSpanTypes.HTTP_SERVER
errored false
parent()
tags {
"http.url" "http://localhost:$port/"
"http.method" "GET"
"span.kind" "server"
"component" "jetty-handler"
"span.origin.type" handler.class.name
"span.type" DDSpanTypes.HTTP_SERVER
"http.status_code" 200
defaultTags()
}
}
}
}
}
def "handler instrumentation clears state after async request"() {
setup:
@ -87,7 +87,7 @@ class JettyHandlerTest extends AgentTestRunner {
@Override
void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
final Continuation continuation = ContinuationSupport.getContinuation(request)
continuation.suspend()
continuation.suspend(response)
// By the way, this is a terrible async server
new Thread() {
@Override
@ -128,12 +128,18 @@ class JettyHandlerTest extends AgentTestRunner {
def "call to jetty with error creates a trace"() {
setup:
def errorHandlerCalled = new AtomicBoolean(false)
Handler handler = new AbstractHandler() {
@Override
void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
if (baseRequest.dispatcherType == DispatcherType.ERROR) {
errorHandlerCalled.set(true)
baseRequest.setHandled(true)
} else {
throw new RuntimeException()
}
}
}
server.setHandler(handler)
server.start()
def request = new okhttp3.Request.Builder()
@ -144,31 +150,52 @@ class JettyHandlerTest extends AgentTestRunner {
expect:
response.body().string().trim() == ""
TEST_WRITER.waitForTraces(1)
TEST_WRITER.size() == 1
def trace = TEST_WRITER.firstTrace()
trace.size() == 1
def context = trace[0].context()
context.serviceName == "unnamed-java-app"
context.operationName == "jetty.request"
context.resourceName == "GET ${handler.class.name}"
context.spanType == DDSpanTypes.HTTP_SERVER
context.getErrorFlag()
context.parentId == "0"
def tags = context.tags
tags["http.url"] == "http://localhost:$port/"
tags["http.method"] == "GET"
tags["span.kind"] == "server"
tags["span.type"] == DDSpanTypes.HTTP_SERVER
tags["component"] == "jetty-handler"
tags["http.status_code"] == 500
tags["thread.name"] != null
tags["thread.id"] != null
tags[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
tags["span.origin.type"] == handler.class.name
tags["error"] == true
tags["error.type"] == RuntimeException.name
tags["error.stack"] != null
tags.size() == 13
assertTraces(errorHandlerCalled.get() ? 2 : 1) {
trace(0, 1) {
span(0) {
serviceName "unnamed-java-app"
operationName "jetty.request"
resourceName "GET ${handler.class.name}"
spanType DDSpanTypes.HTTP_SERVER
errored true
parent()
tags {
"http.url" "http://localhost:$port/"
"http.method" "GET"
"span.kind" "server"
"component" "jetty-handler"
"span.origin.type" handler.class.name
"span.type" DDSpanTypes.HTTP_SERVER
"http.status_code" 500
errorTags RuntimeException
defaultTags()
}
}
}
if (errorHandlerCalled.get()) {
trace(1, 1) {
span(0) {
serviceName "unnamed-java-app"
operationName "jetty.request"
resourceName "GET ${handler.class.name}"
spanType DDSpanTypes.HTTP_SERVER
errored true
parent()
tags {
"http.url" "http://localhost:$port/"
"http.method" "GET"
"span.kind" "server"
"component" "jetty-handler"
"span.origin.type" handler.class.name
"span.type" DDSpanTypes.HTTP_SERVER
"http.status_code" 500
"error" true
defaultTags()
}
}
}
}
}
}
}

View File

@ -38,14 +38,10 @@ dependencies {
testCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '7.0.37'
testCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-logging-juli', version: '7.0.37'
testCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '7.0.37'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'javax.servlet.jsp', name: 'javax.servlet.jsp-api', version: '+'
force group: 'javax.servlet', name: 'javax.servlet-api', version: '+'
force group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '+'
force group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '+'
force group: 'org.apache.tomcat.embed', name: 'tomcat-embed-logging-juli', version: '+'
}
latestDepTestCompile group: 'javax.servlet.jsp', name: 'javax.servlet.jsp-api', version: '+'
latestDepTestCompile group: 'javax.servlet', name: 'javax.servlet-api', version: '+'
latestDepTestCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '+'
latestDepTestCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '+'
latestDepTestCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-logging-juli', version: '+'
}

View File

@ -16,15 +16,19 @@ import io.opentracing.Scope;
import io.opentracing.Span;
import io.opentracing.tag.Tags;
import io.opentracing.util.GlobalTracer;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.HttpJspPage;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.slf4j.LoggerFactory;
@AutoService(Instrumenter.class)
public final class JSPInstrumentation extends Instrumenter.Default {
@ -68,19 +72,28 @@ public final class JSPInstrumentation extends Instrumenter.Default {
// get the JSP file name being rendered in an include action
final Object includeServletPath = req.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
String resourceName = req.getServletPath();
if (includeServletPath != null && includeServletPath instanceof String) {
if (includeServletPath instanceof String) {
resourceName = includeServletPath.toString();
}
span.setTag(DDTags.RESOURCE_NAME, resourceName);
final Object forwardOrigin = req.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH);
if (forwardOrigin != null && forwardOrigin instanceof String) {
if (forwardOrigin instanceof String) {
span.setTag("jsp.forwardOrigin", forwardOrigin.toString());
}
// add the request URL as a tag to provide better context when looking at spans produced by
// actions
span.setTag("jsp.requestURL", req.getRequestURL().toString());
// actions. Tomcat 9 has relative path symbols in the value returned from
// HttpServletRequest#getRequestURL(),
// normalizing the URL should remove those symbols for readability and consistency
try {
span.setTag(
"jsp.requestURL", (new URI(req.getRequestURL().toString())).normalize().toString());
} catch (final URISyntaxException uriSE) {
LoggerFactory.getLogger(HttpJspPage.class)
.warn("Failed to get and normalize request URL: " + uriSE.getMessage());
}
Tags.COMPONENT.set(span, "jsp-http-servlet");
return scope;

View File

@ -45,17 +45,23 @@ class JSPInstrumentationBasicTests extends AgentTestRunner {
OkHttpClient client = OkHttpUtils.client()
def setupSpec() {
port = TestUtils.randomOpenPort()
tomcatServer = new Tomcat()
tomcatServer.setPort(port)
// comment to debug
tomcatServer.setSilent(true)
baseDir = Files.createTempDir()
baseDir.deleteOnExit()
expectedJspClassFilesDir = baseDir.getCanonicalFile().getAbsolutePath() + expectedJspClassFilesDir
baseUrl = "http://localhost:$port/$jspWebappContext"
port = TestUtils.randomOpenPort()
tomcatServer = new Tomcat()
tomcatServer.setBaseDir(baseDir.getAbsolutePath())
tomcatServer.setPort(port)
tomcatServer.getConnector()
// comment to debug
tomcatServer.setSilent(true)
// this is needed in tomcat 9, this triggers the creation of a connector, will not
// affect tomcat 7 and 8
// https://stackoverflow.com/questions/48998387/code-works-with-embedded-apache-tomcat-8-but-not-with-9-whats-changed
tomcatServer.getConnector()
baseUrl = "http://localhost:$port/$jspWebappContext"
appContext = tomcatServer.addWebapp("/$jspWebappContext",
JSPInstrumentationBasicTests.getResource("/webapps/jsptest").getPath())
@ -344,7 +350,14 @@ class JSPInstrumentationBasicTests extends AgentTestRunner {
"span.origin.type" jspClassName
"servlet.context" "/$jspWebappContext"
"jsp.requestURL" reqUrl
errorTags(exceptionClass, errorMessage)
"error" true
"error.type" { String tagExceptionType ->
return tagExceptionType == exceptionClass.getName() || tagExceptionType.contains(exceptionClass.getSimpleName())
}
"error.msg" { String tagErrorMsg ->
return errorMessageOptional || tagErrorMsg instanceof String
}
"error.stack" String
defaultTags()
}
}
@ -373,10 +386,10 @@ class JSPInstrumentationBasicTests extends AgentTestRunner {
res.close()
where:
test | jspFileName | jspClassName | exceptionClass | errorMessage
"java runtime error" | "runtimeError.jsp" | "runtimeError_jsp" | ArithmeticException | String
"invalid write" | "invalidWrite.jsp" | "invalidWrite_jsp" | StringIndexOutOfBoundsException | String
"missing query gives null" | "getQuery.jsp" | "getQuery_jsp" | NullPointerException | null
test | jspFileName | jspClassName | exceptionClass | errorMessageOptional
"java runtime error" | "runtimeError.jsp" | "runtimeError_jsp" | ArithmeticException | false
"invalid write" | "invalidWrite.jsp" | "invalidWrite_jsp" | IndexOutOfBoundsException | true
"missing query gives null" | "getQuery.jsp" | "getQuery_jsp" | NullPointerException | true
}
def "non-erroneous include plain HTML GET"() {

View File

@ -43,17 +43,24 @@ class JSPInstrumentationForwardTests extends AgentTestRunner {
OkHttpClient client = OkHttpUtils.client()
def setupSpec() {
port = TestUtils.randomOpenPort()
tomcatServer = new Tomcat()
tomcatServer.setPort(port)
// comment to debug
tomcatServer.setSilent(true)
baseDir = Files.createTempDir()
baseDir.deleteOnExit()
expectedJspClassFilesDir = baseDir.getCanonicalFile().getAbsolutePath() + expectedJspClassFilesDir
baseUrl = "http://localhost:$port/$jspWebappContext"
port = TestUtils.randomOpenPort()
tomcatServer = new Tomcat()
tomcatServer.setBaseDir(baseDir.getAbsolutePath())
tomcatServer.setPort(port)
tomcatServer.getConnector()
// comment to debug
tomcatServer.setSilent(true)
// this is needed in tomcat 9, this triggers the creation of a connector, will not
// affect tomcat 7 and 8
// https://stackoverflow.com/questions/48998387/code-works-with-embedded-apache-tomcat-8-but-not-with-9-whats-changed
tomcatServer.getConnector()
baseUrl = "http://localhost:$port/$jspWebappContext"
appContext = tomcatServer.addWebapp("/$jspWebappContext",
JSPInstrumentationForwardTests.getResource("/webapps/jsptest").getPath())

View File

@ -32,12 +32,9 @@ dependencies {
testCompile group: 'org.springframework.kafka', name: 'spring-kafka', version: '1.3.3.RELEASE'
testCompile group: 'org.springframework.kafka', name: 'spring-kafka-test', version: '1.3.3.RELEASE'
testCompile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.3'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'org.apache.kafka', name: 'kafka-clients', version: '+'
force group: 'org.springframework.kafka', name: 'spring-kafka', version: '+'
force group: 'org.springframework.kafka', name: 'spring-kafka-test', version: '+'
}
latestDepTestCompile group: 'org.apache.kafka', name: 'kafka-clients', version: '+'
latestDepTestCompile group: 'org.springframework.kafka', name: 'spring-kafka', version: '+'
latestDepTestCompile group: 'org.springframework.kafka', name: 'spring-kafka-test', version: '+'
latestDepTestCompile group: 'org.assertj', name: 'assertj-core', version: '3.+'
}

View File

@ -21,6 +21,6 @@ public class TextMapInjectAdapter implements TextMap {
@Override
public void put(final String key, final String value) {
headers.add(key, value.getBytes(StandardCharsets.UTF_8));
headers.remove(key).add(key, value.getBytes(StandardCharsets.UTF_8));
}
}

View File

@ -7,7 +7,6 @@ import org.springframework.kafka.core.DefaultKafkaProducerFactory
import org.springframework.kafka.core.KafkaTemplate
import org.springframework.kafka.listener.KafkaMessageListenerContainer
import org.springframework.kafka.listener.MessageListener
import org.springframework.kafka.listener.config.ContainerProperties
import org.springframework.kafka.test.rule.KafkaEmbedded
import org.springframework.kafka.test.utils.ContainerTestUtils
import org.springframework.kafka.test.utils.KafkaTestUtils
@ -36,7 +35,13 @@ class KafkaClientTest extends AgentTestRunner {
def consumerFactory = new DefaultKafkaConsumerFactory<String, String>(consumerProperties)
// set the topic that needs to be consumed
ContainerProperties containerProperties = new ContainerProperties(SHARED_TOPIC)
def containerProperties
try {
// Different class names for test and latestDepTest.
containerProperties = Class.forName("org.springframework.kafka.listener.config.ContainerProperties").newInstance(SHARED_TOPIC)
} catch (ClassNotFoundException | NoClassDefFoundError e) {
containerProperties = Class.forName("org.springframework.kafka.listener.ContainerProperties").newInstance(SHARED_TOPIC)
}
// create a Kafka MessageListenerContainer
def container = new KafkaMessageListenerContainer<>(consumerFactory, containerProperties)
@ -126,7 +131,7 @@ class KafkaClientTest extends AgentTestRunner {
cleanup:
producerFactory.stop()
container.stop()
container?.stop()
}
}

View File

@ -35,13 +35,10 @@ dependencies {
testCompile group: 'org.springframework.kafka', name: 'spring-kafka', version: '1.3.3.RELEASE'
testCompile group: 'org.springframework.kafka', name: 'spring-kafka-test', version: '1.3.3.RELEASE'
testCompile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.2.3'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'org.apache.kafka', name: 'kafka-clients', version: '+'
force group: 'org.apache.kafka', name: 'kafka-streams', version: '+'
force group: 'org.springframework.kafka', name: 'spring-kafka', version: '+'
force group: 'org.springframework.kafka', name: 'spring-kafka-test', version: '+'
}
latestDepTestCompile group: 'org.apache.kafka', name: 'kafka-clients', version: '+'
latestDepTestCompile group: 'org.apache.kafka', name: 'kafka-streams', version: '+'
latestDepTestCompile group: 'org.springframework.kafka', name: 'spring-kafka', version: '+'
latestDepTestCompile group: 'org.springframework.kafka', name: 'spring-kafka-test', version: '+'
latestDepTestCompile group: 'org.assertj', name: 'assertj-core', version: '3.+'
}

View File

@ -1,11 +1,9 @@
import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.api.Config
import org.apache.kafka.clients.consumer.ConsumerRecord
import org.apache.kafka.common.serialization.Serdes
import org.apache.kafka.streams.KafkaStreams
import org.apache.kafka.streams.StreamsConfig
import org.apache.kafka.streams.kstream.KStream
import org.apache.kafka.streams.kstream.KStreamBuilder
import org.apache.kafka.streams.kstream.ValueMapper
import org.junit.ClassRule
import org.springframework.kafka.core.DefaultKafkaConsumerFactory
@ -13,7 +11,6 @@ import org.springframework.kafka.core.DefaultKafkaProducerFactory
import org.springframework.kafka.core.KafkaTemplate
import org.springframework.kafka.listener.KafkaMessageListenerContainer
import org.springframework.kafka.listener.MessageListener
import org.springframework.kafka.listener.config.ContainerProperties
import org.springframework.kafka.test.rule.KafkaEmbedded
import org.springframework.kafka.test.utils.ContainerTestUtils
import org.springframework.kafka.test.utils.KafkaTestUtils
@ -41,7 +38,15 @@ class KafkaStreamsTest extends AgentTestRunner {
// CONFIGURE CONSUMER
def consumerFactory = new DefaultKafkaConsumerFactory<String, String>(KafkaTestUtils.consumerProps("sender", "false", embeddedKafka))
def consumerContainer = new KafkaMessageListenerContainer<>(consumerFactory, new ContainerProperties(STREAM_PROCESSED))
def containerProperties
try {
// Different class names for test and latestDepTest.
containerProperties = Class.forName("org.springframework.kafka.listener.config.ContainerProperties").newInstance(STREAM_PROCESSED)
} catch (ClassNotFoundException | NoClassDefFoundError e) {
containerProperties = Class.forName("org.springframework.kafka.listener.ContainerProperties").newInstance(STREAM_PROCESSED)
}
def consumerContainer = new KafkaMessageListenerContainer<>(consumerFactory, containerProperties)
// create a thread safe queue to store the processed message
def records = new LinkedBlockingQueue<ConsumerRecord<String, String>>()
@ -65,9 +70,15 @@ class KafkaStreamsTest extends AgentTestRunner {
ContainerTestUtils.waitForAssignment(consumerContainer, embeddedKafka.getPartitionsPerTopic())
// CONFIGURE PROCESSOR
final KStreamBuilder builder = new KStreamBuilder()
def builder
try {
// Different class names for test and latestDepTest.
builder = Class.forName("org.apache.kafka.streams.kstream.KStreamBuilder").newInstance()
} catch (ClassNotFoundException | NoClassDefFoundError e) {
builder = Class.forName("org.apache.kafka.streams.StreamsBuilder").newInstance()
}
KStream<String, String> textLines = builder.stream(STREAM_PENDING)
textLines
def values = textLines
.mapValues(new ValueMapper<String, String>() {
@Override
String apply(String textLine) {
@ -76,8 +87,18 @@ class KafkaStreamsTest extends AgentTestRunner {
return textLine.toLowerCase()
}
})
.to(Serdes.String(), Serdes.String(), STREAM_PROCESSED)
KafkaStreams streams = new KafkaStreams(builder, config)
KafkaStreams streams
try {
// Different api for test and latestDepTest.
values.to(Serdes.String(), Serdes.String(), STREAM_PROCESSED)
streams = new KafkaStreams(builder, config)
} catch (MissingMethodException e) {
def producer = Class.forName("org.apache.kafka.streams.kstream.Produced")
.with(Serdes.String(), Serdes.String())
values.to(STREAM_PROCESSED, producer)
streams = new KafkaStreams(builder.build(), config)
}
streams.start()
// CONFIGURE PRODUCER
@ -94,101 +115,89 @@ class KafkaStreamsTest extends AgentTestRunner {
received.value() == greeting.toLowerCase()
received.key() == null
TEST_WRITER.waitForTraces(3)
TEST_WRITER.size() == 3
assertTraces(3) {
trace(0, 1) {
// PRODUCER span 0
span(0) {
serviceName "kafka"
operationName "kafka.produce"
resourceName "Produce Topic $STREAM_PENDING"
spanType "queue"
errored false
parent()
tags {
"component" "java-kafka"
"span.kind" "producer"
"span.type" "queue"
defaultTags()
}
}
}
trace(1, 2) {
def t1 = TEST_WRITER.get(0)
t1.size() == 1
def t2 = TEST_WRITER.get(1)
t2.size() == 2
def t3 = TEST_WRITER.get(2)
t3.size() == 1
// STREAMING span 0
span(0) {
serviceName "kafka"
operationName "kafka.produce"
resourceName "Produce Topic $STREAM_PROCESSED"
spanType "queue"
errored false
childOf span(1)
and: // PRODUCER span 0
def t1span1 = t1[0]
tags {
"component" "java-kafka"
"span.kind" "producer"
"span.type" "queue"
defaultTags()
}
}
t1span1.context().operationName == "kafka.produce"
t1span1.serviceName == "kafka"
t1span1.resourceName == "Produce Topic $STREAM_PENDING"
t1span1.type == "queue"
!t1span1.context().getErrorFlag()
t1span1.context().parentId == "0"
// STREAMING span 1
span(1) {
serviceName "kafka"
operationName "kafka.consume"
resourceName "Consume Topic $STREAM_PENDING"
spanType "queue"
errored false
childOf TEST_WRITER[0][0]
def t1tags1 = t1span1.context().tags
t1tags1["component"] == "java-kafka"
t1tags1["span.kind"] == "producer"
t1tags1["span.type"] == "queue"
t1tags1["thread.name"] != null
t1tags1["thread.id"] != null
t1tags1[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
t1tags1.size() == 6
and: // STREAMING span 0
def t2span1 = t2[0]
t2span1.context().operationName == "kafka.produce"
t2span1.serviceName == "kafka"
t2span1.resourceName == "Produce Topic $STREAM_PROCESSED"
t2span1.type == "queue"
!t2span1.context().getErrorFlag()
def t2tags1 = t2span1.context().tags
t2tags1["component"] == "java-kafka"
t2tags1["span.kind"] == "producer"
t2tags1["span.type"] == "queue"
t2tags1["thread.name"] != null
t2tags1["thread.id"] != null
t2tags1.size() == 5
and: // STREAMING span 1
def t2span2 = t2[1]
t2span1.context().parentId == t2span2.context().spanId
t2span2.context().operationName == "kafka.consume"
t2span2.serviceName == "kafka"
t2span2.resourceName == "Consume Topic $STREAM_PENDING"
t2span2.type == "queue"
!t2span2.context().getErrorFlag()
t2span2.context().parentId == t1span1.context().spanId
def t2tags2 = t2span2.context().tags
t2tags2["component"] == "java-kafka"
t2tags2["span.kind"] == "consumer"
t2tags2["span.type"] == "queue"
t2tags2["partition"] >= 0
t2tags2["offset"] == 0
t2tags2["thread.name"] != null
t2tags2["thread.id"] != null
t2tags2[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
t2tags2["asdf"] == "testing"
t2tags2.size() == 9
and: // CONSUMER span 0
def t3span1 = t3[0]
t3span1.context().operationName == "kafka.consume"
t3span1.serviceName == "kafka"
t3span1.resourceName == "Consume Topic $STREAM_PROCESSED"
t3span1.type == "queue"
!t3span1.context().getErrorFlag()
t3span1.context().parentId == t2span1.context().spanId
def t3tags1 = t3span1.context().tags
t3tags1["component"] == "java-kafka"
t3tags1["span.kind"] == "consumer"
t3tags1["span.type"] == "queue"
t3tags1["partition"] >= 0
t3tags1["offset"] == 0
t3tags1["thread.name"] != null
t3tags1["thread.id"] != null
t3tags1[Config.RUNTIME_ID_TAG] == Config.get().runtimeId
t3tags1["testing"] == 123
t3tags1.size() == 9
tags {
"component" "java-kafka"
"span.kind" "consumer"
"span.type" "queue"
"partition" { it >= 0 }
"offset" 0
defaultTags(true)
"asdf" "testing"
}
}
}
trace(2, 1) {
// CONSUMER span 0
span(0) {
serviceName "kafka"
operationName "kafka.consume"
resourceName "Consume Topic $STREAM_PROCESSED"
spanType "queue"
errored false
childOf TEST_WRITER[1][0]
tags {
"component" "java-kafka"
"span.kind" "consumer"
"span.type" "queue"
"partition" { it >= 0 }
"offset" 0
defaultTags(true)
"testing" 123
}
}
}
}
def headers = received.headers()
headers.iterator().hasNext()
new String(headers.headers("x-datadog-trace-id").iterator().next().value()) == "$t2span1.traceId"
new String(headers.headers("x-datadog-parent-id").iterator().next().value()) == "$t2span1.spanId"
new String(headers.headers("x-datadog-trace-id").iterator().next().value()) == "${TEST_WRITER[1][0].traceId}"
new String(headers.headers("x-datadog-parent-id").iterator().next().value()) == "${TEST_WRITER[1][0].spanId}"
cleanup:

View File

@ -61,10 +61,7 @@ dependencies {
testCompile group: 'com.github.kstyrc', name: 'embedded-redis', version: '0.6'
testCompile group: 'io.lettuce', name: 'lettuce-core', version: '5.0.0.RELEASE'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'io.lettuce', name: 'lettuce-core', version: '+'
}
// FIXME: Tests need to be updated to support 5.1+
latestDepTestCompile group: 'io.lettuce', name: 'lettuce-core', version: '5.0.+'
}

View File

@ -29,10 +29,5 @@ dependencies {
testCompile project(':dd-trace-ot')
testCompile group: 'org.mongodb', name: 'mongo-java-driver', version: '3.1.0'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'org.mongodb', name: 'mongo-java-driver', version: '+'
}
latestDepTestCompile group: 'org.mongodb', name: 'mongo-java-driver', version: '+'
}

View File

@ -44,6 +44,9 @@ dependencies {
testCompile group: 'io.netty', name: 'netty-codec-http', version: '4.0.0.Final'
testCompile group: 'org.asynchttpclient', name: 'async-http-client', version: '2.0.0'
latestDepTestCompile group: 'io.netty', name: 'netty-codec-http', version: '4.0.56.Final'
latestDepTestCompile group: 'org.asynchttpclient', name: 'async-http-client', version: '2.0.+'
}
// We need to force the dependency to the earliest supported version because other libraries declare newer versions.
@ -57,11 +60,3 @@ configurations.testCompile {
}
}
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'io.netty', name: 'netty-codec-http', version: '4.0.56.Final'
force group: 'org.asynchttpclient', name: 'async-http-client', version: '2.0.+'
}
}

View File

@ -2,6 +2,7 @@ import datadog.trace.agent.test.AgentTestRunner
import datadog.trace.agent.test.TestUtils
import datadog.trace.api.DDSpanTypes
import datadog.trace.api.DDTags
import io.netty.channel.AbstractChannel
import io.opentracing.tag.Tags
import org.asynchttpclient.AsyncHttpClient
import org.asynchttpclient.DefaultAsyncHttpClientConfig
@ -105,7 +106,11 @@ class Netty40ClientTest extends AgentTestRunner {
errored true
tags {
"$Tags.COMPONENT.key" "netty"
try {
errorTags ConnectException, "Connection refused: localhost/127.0.0.1:$invalidPort"
} catch (AssertionError e) {
errorTags AbstractChannel.AnnotatedConnectException, "Connection refused: localhost/127.0.0.1:$invalidPort"
}
defaultTags()
}
}

View File

@ -42,6 +42,10 @@ dependencies {
testCompile project(':dd-java-agent:instrumentation:java-concurrent')
testCompile group: 'io.netty', name: 'netty-codec-http', version: '4.1.0.Final'
testCompile group: 'org.asynchttpclient', name: 'async-http-client', version: '2.1.0'
latestDepTestCompile group: 'io.netty', name: 'netty-codec-http', version: '(,5.0)'
// latest async-http-client incompatable with 5.0+ netty
latestDepTestCompile group: 'org.asynchttpclient', name: 'async-http-client', version: '+'
}
// We need to force the dependency to the earliest supported version because other libraries declare newer versions.
@ -55,11 +59,3 @@ configurations.testCompile {
}
}
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'io.netty', name: 'netty-codec-http', version: '+'
force group: 'org.asynchttpclient', name: 'async-http-client', version: '+'
}
}

View File

@ -27,12 +27,10 @@ dependencies {
annotationProcessor deps.autoservice
implementation deps.autoservice
testCompile project(':dd-java-agent:testing')
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.0.0'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'com.squareup.okhttp3', name: 'okhttp', version: '+'
testCompile(project(':dd-java-agent:testing')) {
exclude module: 'okhttp'
}
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.0.0'
latestDepTestCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '[3.11.0,)'
}

View File

@ -66,10 +66,5 @@ dependencies {
testCompile project(':dd-java-agent:testing')
testCompile group: 'io.ratpack', name: 'ratpack-groovy-test', version: '1.4.0'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'io.ratpack', name: 'ratpack-groovy-test', version: '+'
}
latestDepTestCompile group: 'io.ratpack', name: 'ratpack-groovy-test', version: '+'
}

View File

@ -41,13 +41,9 @@ dependencies {
testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '8.2.0.v20160908'
testCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '8.0.41'
testCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '8.0.41'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'org.eclipse.jetty', name: 'jetty-server', version: '+'
force group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '+'
force group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '+'
force group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '+'
}
latestDepTestCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '+'
latestDepTestCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '+'
latestDepTestCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '+'
latestDepTestCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '+'
}

View File

@ -7,7 +7,6 @@ import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.eclipse.jetty.http.HttpHeaders
import org.eclipse.jetty.security.ConstraintMapping
import org.eclipse.jetty.security.ConstraintSecurityHandler
import org.eclipse.jetty.security.HashLoginService
@ -16,6 +15,7 @@ import org.eclipse.jetty.security.authentication.BasicAuthenticator
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.servlet.ServletContextHandler
import org.eclipse.jetty.util.security.Constraint
import spock.lang.Shared
class JettyServlet3Test extends AgentTestRunner {
@ -29,11 +29,14 @@ class JettyServlet3Test extends AgentTestRunner {
})
.build()
@Shared
int port
@Shared
private Server jettyServer
@Shared
private ServletContextHandler servletContext
def setup() {
def setupSpec() {
port = TestUtils.randomOpenPort()
jettyServer = new Server(port)
servletContext = new ServletContextHandler()
@ -53,7 +56,7 @@ class JettyServlet3Test extends AgentTestRunner {
"Jetty server: http://localhost:" + port + "/")
}
def cleanup() {
def cleanupSpec() {
jettyServer.stop()
jettyServer.destroy()
}
@ -68,7 +71,7 @@ class JettyServlet3Test extends AgentTestRunner {
requestBuilder.header("x-datadog-parent-id", "456")
}
if (auth) {
requestBuilder.header(HttpHeaders.AUTHORIZATION, Credentials.basic("user", "password"))
requestBuilder.header("Authorization", Credentials.basic("user", "password"))
}
def response = client.newCall(requestBuilder.build()).execute()

View File

@ -10,19 +10,24 @@ import org.apache.catalina.core.ApplicationFilterChain
import org.apache.catalina.startup.Tomcat
import org.apache.tomcat.JarScanFilter
import org.apache.tomcat.JarScanType
import spock.lang.Shared
class TomcatServlet3Test extends AgentTestRunner {
OkHttpClient client = OkHttpUtils.client()
@Shared
int port
@Shared
Tomcat tomcatServer
@Shared
Context appContext
def setup() {
def setupSpec() {
port = TestUtils.randomOpenPort()
tomcatServer = new Tomcat()
tomcatServer.setPort(port)
tomcatServer.getConnector()
def baseDir = Files.createTempDir()
baseDir.deleteOnExit()
@ -52,7 +57,7 @@ class TomcatServlet3Test extends AgentTestRunner {
"Tomcat server: http://" + tomcatServer.getHost().getName() + ":" + port + "/")
}
def cleanup() {
def cleanupSpec() {
tomcatServer.stop()
tomcatServer.destroy()
}

View File

@ -54,9 +54,3 @@ dependencies {
latestDepTestCompile group: 'com.sparkjava', name: 'spark-core', version: '+'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'com.sparkjava', name: 'spark-core', version: '+'
}
}

View File

@ -74,12 +74,9 @@ dependencies {
testCompile group: 'org.spockframework', name: 'spock-spring', version: '1.1-groovy-2.4'
testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '2.0.0.RELEASE'
testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-reactor-netty', version: '2.0.0.RELEASE'
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: '+'
force group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '+'
force group: 'org.springframework.boot', name: 'spring-boot-starter-reactor-netty', version: '+'
}
// FIXME: Tests need to be updated to support 2.1+
latestDepTestCompile group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: '2.0.+'
latestDepTestCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '2.0.+'
latestDepTestCompile group: 'org.springframework.boot', name: 'spring-boot-starter-reactor-netty', version: '2.0.+'
}

View File

@ -13,7 +13,6 @@ import okhttp3.RequestBody
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.web.server.LocalServerPort
import org.springframework.web.server.ResponseStatusException
import spock.lang.Unroll
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = SpringWebFluxTestApplication)
class SpringWebfluxTest extends AgentTestRunner {
@ -27,7 +26,6 @@ class SpringWebfluxTest extends AgentTestRunner {
OkHttpClient client = OkHttpUtils.client()
@Unroll
def "Basic GET test #testName to functional API"() {
setup:
String url = "http://localhost:$port/greet$urlSuffix"
@ -82,7 +80,6 @@ class SpringWebfluxTest extends AgentTestRunner {
"with two parameters" | "/World/Test1" | "/{name}/{word}" | SpringWebFluxTestApplication.GreetingHandler.DEFAULT_RESPONSE + " World Test1"
}
@Unroll
def "Basic GET test #testName to annotations API"() {
setup:
String url = "http://localhost:$port/foo$urlSuffix"
@ -417,7 +414,6 @@ class SpringWebfluxTest extends AgentTestRunner {
}
}
@Unroll
def "Flux x#count GET test with functional API endpoint"() {
setup:
String expectedResponseBodyStr = FooModel.createXFooModelsStringFromArray(FooModel.createXFooModels(count))
@ -471,7 +467,6 @@ class SpringWebfluxTest extends AgentTestRunner {
count << [0, 1, 10]
}
@Unroll
def "Flux x#count GET test with spring annotations endpoint"() {
setup:
String expectedResponseBodyStr = FooModel.createXFooModelsStringFromArray(FooModel.createXFooModels(count))

View File

@ -33,11 +33,6 @@ dependencies {
testCompile group: 'net.spy', name: 'spymemcached', version: '2.12.0'
testCompile deps.testcontainers
}
configurations.latestDepTestCompile {
resolutionStrategy {
force group: 'net.spy', name: 'spymemcached', version: '+'
}
latestDepTestCompile group: 'net.spy', name: 'spymemcached', version: '+'
}

View File

@ -20,13 +20,13 @@ muzzle {
}
}
apply plugin: 'org.unbroken-dome.test-sets'
testSets {
latestDepTest {
dirName = 'test'
}
}
//apply plugin: 'org.unbroken-dome.test-sets'
//
//testSets {
// latestDepTest {
// dirName = 'test'
// }
//}
sourceCompatibility = 1.8
targetCompatibility = 1.8

View File

@ -7,10 +7,11 @@ import java.util.concurrent.TimeUnit
class OkHttpUtils {
static clientBuilder() {
def unit = TimeUnit.MINUTES
new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES)
.writeTimeout(1, TimeUnit.MINUTES)
.readTimeout(1, TimeUnit.MINUTES)
.connectTimeout(1, unit)
.writeTimeout(1, unit)
.readTimeout(1, unit)
}
static client() {

View File

@ -118,6 +118,18 @@ artifacts {
archives javaDocJar
}
project.afterEvaluate {
if (project.plugins.hasPlugin('org.unbroken-dome.test-sets') && configurations.hasProperty("latestDepTestRuntime")) {
tasks.withType(Test) {
doFirst{
def testArtifacts = configurations.testRuntime.resolvedConfiguration.resolvedArtifacts
def latestTestArtifacts = configurations.latestDepTestRuntime.resolvedConfiguration.resolvedArtifacts
assert testArtifacts != latestTestArtifacts : "latestDepTest dependencies are identical to test"
}
}
}
}
if (project.plugins.hasPlugin('com.github.johnrengelman.shadow')) {
// Remove the no-deps jar from the archives to prevent publication
configurations.archives.with {