Added Scala Slick test that fails due to executor wrapping problems
MODIFY
dd-java-agent/instrumentation/java-concurrent/java-concurrent.gradle
dd-java-agent/instrumentation/java-concurrent/java-concurrent.gradle
apply from: "${rootDir}/gradle/java.gradle"
+apply from: "${rootDir}/gradle/test-with-scala.gradle"
+
+apply plugin: 'org.unbroken-dome.test-sets'
dependencies {
compile project(':dd-trace-api')

ADD
dd-java-agent/instrumentation/java-concurrent/slick-testing/slick-testing.gradle
+apply from: "${rootDir}/gradle/java.gradle"
+apply from: "${rootDir}/gradle/test-with-scala.gradle"
+
+apply plugin: 'org.unbroken-dome.test-sets'
+
+dependencies {
+ compile project(':dd-trace-api')
+ compile project(':dd-trace-ot')
+
+ testCompile project(':dd-java-agent:testing')
+ testCompile project(':dd-java-agent:instrumentation:java-concurrent')
+ testCompile project(':dd-java-agent:instrumentation:trace-annotation')
+ testCompile project(':dd-java-agent:instrumentation:jdbc')
+ testCompile group: 'org.scala-lang', name: 'scala-library', version: '2.11.12'
+ testCompile group: 'com.typesafe.slick', name: 'slick_2.11', version: '3.2.0'
+ testCompile group: 'com.h2database', name: 'h2', version: '1.4.197'
+}

ADD
dd-java-agent/instrumentation/java-concurrent/slick-testing/src/test/groovy/SlickTest.groovy
+import datadog.trace.agent.test.AgentTestRunner
+import spock.lang.Shared
+
+class SlickTest extends AgentTestRunner {
+
+ @Shared
+ def database = new SlickUtils()
+
+ def "Basic statement generates spans"() {
+ setup:
+ def future = database.startQuery(SlickUtils.TestQuery())
+ def result = database.getResults(future)
+ TEST_WRITER.waitForTraces(1)
+
+ expect:
+ result == SlickUtils.TestValue()
+
+ TEST_WRITER.size() == 1
+
+ def trace = TEST_WRITER.firstTrace()
+ trace.size() == 2
+
+ def rootSpan = trace[0]
+ rootSpan.serviceName == "unnamed-java-app"
+ rootSpan.resourceName == "SlickUtils.startQuery"
+
+ def dbSpan = trace[1]
+ dbSpan.context().operationName == "${SlickUtils.Driver()}.query"
+ dbSpan.serviceName == SlickUtils.Driver()
+ dbSpan.resourceName == SlickUtils.TestQuery()
+ dbSpan.type == "sql"
+ !dbSpan.context().getErrorFlag()
+ dbSpan.context().parentId == rootSpan.spanId
+
+ def tags = dbSpan.context().tags
+ tags["db.type"] == SlickUtils.Driver()
+ tags["db.user"] == null
+ tags["span.kind"] == "client"
+ tags["span.type"] == "sql"
+ tags["component"] == "java-jdbc-prepared_statement"
+
+ tags["db.jdbc.url"].contains(SlickUtils.Driver())
+ tags["span.origin.type"] != null
+
+ tags["thread.name"] != null
+ tags["thread.id"] != null
+ tags.size() == 8
+ }
+
+ def "Concurrent requests do not throw exception"() {
+ setup:
+ def sleepFuture = database.startQuery(SlickUtils.SleepQuery())
+
+ def future = database.startQuery(SlickUtils.TestQuery())
+ def result = database.getResults(future)
+
+ database.getResults(sleepFuture)
+ TEST_WRITER.waitForTraces(2)
+
+ expect:
+ result == SlickUtils.TestValue()
+ TEST_WRITER.size() == 2 // Since we have two DB queries
+
+ def trace = TEST_WRITER.firstTrace()
+ trace.size() == 2
+ }
+}

ADD
dd-java-agent/instrumentation/java-concurrent/slick-testing/src/test/scala/SlickUtils.scala
+import datadog.trace.api.Trace
+import datadog.trace.context.TraceScope
+import io.opentracing.util.GlobalTracer
+import slick.jdbc.H2Profile.api._
+
+import scala.concurrent.{Await, Future}
+import scala.concurrent.duration.Duration
+
+class SlickUtils {
+ import SlickUtils._
+
+ val database = Database.forURL(s"jdbc:${Driver}:mem:test",
+ driver="org.h2.Driver",
+ keepAliveConnection=true,
+ // Limit numbner of threads to hit Slick-specific case when we need to avoid re-wrapping
+ // wrapped runnables.
+ executor=AsyncExecutor("test", numThreads=1, queueSize=1000)
+ )
+ Await.result(database.run(sqlu"""CREATE ALIAS SLEEP FOR "java.lang.Thread.sleep(long)""""), Duration.Inf)
+
+ @Trace
+ def startQuery(query: String): Future[Vector[Int]] = {
+ GlobalTracer.get().scopeManager().active().asInstanceOf[TraceScope].setAsyncPropagation(true)
+ database.run(sql"#$query".as[Int])
+ }
+
+ def getResults(future: Future[Vector[Int]]): Int = {
+ Await.result(future, Duration.Inf).head
+ }
+
+}
+
+object SlickUtils {
+
+ var Driver = "h2"
+ val TestValue = 3
+ val TestQuery = "SELECT 3"
+
+ var SleepQuery = "CALL SLEEP(3000)"
+
+}

MODIFY
settings.gradle
settings.gradle
@@ -24,6 +24,7 @@ include ':dd-java-agent:instrumentation:jax-rs-client'
include ':dd-java-agent:instrumentation:java-concurrent'
include ':dd-java-agent:instrumentation:java-concurrent:scala-testing'
include ':dd-java-agent:instrumentation:java-concurrent:akka-testing'
+include ':dd-java-agent:instrumentation:java-concurrent:slick-testing'
include ':dd-java-agent:instrumentation:jboss-classloading'
include ':dd-java-agent:instrumentation:jdbc'
include ':dd-java-agent:instrumentation:jedis-1.4'

Added Scala Slick test that fails due to executor wrapping problems