Test servers now both work
MODIFY
dd-java-agent/instrumentation/play-2.3/src/test/groovy/client/PlayWSClientTest.groovy
dd-java-agent/instrumentation/play-2.3/src/test/groovy/client/PlayWSClientTest.groovy
@@ -8,8 +8,6 @@ import spock.lang.Subject
import java.util.concurrent.TimeUnit
-// Play 2.6+ uses a separately versioned client that shades the underlying dependency
-// This means our built in instrumentation won't work.
class PlayWSClientTest extends HttpClientTest {
@Subject
@Shared

MODIFY
dd-java-agent/instrumentation/play-2.3/src/test/groovy/server/PlayAsyncServerTest.groovy
dd-java-agent/instrumentation/play-2.3/src/test/groovy/server/PlayAsyncServerTest.groovy
package server
-class PlayAsyncServerTest { //extends PlayServerTest {
-// @Override
-// Server startServer(int port) {
-// def router =
-// new RoutingDsl()
-// .GET(SUCCESS.getPath()).routeAsync({
-// CompletableFuture.supplyAsync({
-// controller(SUCCESS) {
-// Results.status(SUCCESS.getStatus(), SUCCESS.getBody())
-// }
-// }, HttpExecution.defaultContext())
-// } as Supplier)
-// .GET(QUERY_PARAM.getPath()).routeAsync({
-// CompletableFuture.supplyAsync({
-// controller(QUERY_PARAM) {
-// Results.status(QUERY_PARAM.getStatus(), QUERY_PARAM.getBody())
-// }
-// }, HttpExecution.defaultContext())
-// } as Supplier)
-// .GET(REDIRECT.getPath()).routeAsync({
-// CompletableFuture.supplyAsync({
-// controller(REDIRECT) {
-// Results.found(REDIRECT.getBody())
-// }
-// }, HttpExecution.defaultContext())
-// } as Supplier)
-// .GET(ERROR.getPath()).routeAsync({
-// CompletableFuture.supplyAsync({
-// controller(ERROR) {
-// Results.status(ERROR.getStatus(), ERROR.getBody())
-// }
-// }, HttpExecution.defaultContext())
-// } as Supplier)
-// .GET(EXCEPTION.getPath()).routeAsync({
-// CompletableFuture.supplyAsync({
-// controller(EXCEPTION) {
-// throw new Exception(EXCEPTION.getBody())
-// }
-// }, HttpExecution.defaultContext())
-// } as Supplier)
-//
-// return Server.forRouter(router.build(), port)
-// }
+import play.api.test.TestServer
+
+class PlayAsyncServerTest extends PlayServerTest {
+ @Override
+ TestServer startServer(int port) {
+ def server = AsyncServer.server(port)
+ server.start()
+ return server
+ }
}

MODIFY
dd-java-agent/instrumentation/play-2.3/src/test/groovy/server/PlayServerTest.groovy
dd-java-agent/instrumentation/play-2.3/src/test/groovy/server/PlayServerTest.groovy
@@ -44,11 +44,6 @@ class PlayServerTest extends HttpServerTest<TestServer> {
"play.request"
}
- boolean testExceptionBody() {
- // I can't figure out how to set a proper exception handler to customize the response body.
- false
- }
-
@Override
void handlerSpan(TraceAssert trace, int index, Object parent, ServerEndpoint endpoint = SUCCESS) {
trace.span(index) {

MODIFY
dd-java-agent/instrumentation/play-2.3/src/test/scala/server/AsyncServer.scala
dd-java-agent/instrumentation/play-2.3/src/test/scala/server/AsyncServer.scala
package server
+import datadog.trace.agent.test.base.HttpServerTest.ServerEndpoint._
+import play.api.libs.concurrent.Execution.{defaultContext => ec}
+import play.api.mvc.{Action, Handler, Results}
+import play.api.test.{FakeApplication, TestServer}
+
+import scala.concurrent.Future
+
object AsyncServer {
+ val routes: PartialFunction[(String, String), Handler] = {
+ case ("GET", "/success") => Action.async { request => Future.successful(Results.Status(SUCCESS.getStatus).apply(SUCCESS.getBody)) }
+ case ("GET", "/redirect") => Action.async { request => Future.successful(Results.Redirect(REDIRECT.getBody, REDIRECT.getStatus)) }
+ case ("GET", "/query") => Action.async { result => Future.successful(Results.Status(QUERY_PARAM.getStatus).apply(QUERY_PARAM.getBody)) }
+ case ("GET", "/error-status") => Action.async { result => Future {
+ throw new RuntimeException(ERROR.getBody)
+ }(ec)
+ }
+ case ("GET", "/exception") => Action.async { result => Future {
+ throw new RuntimeException(ERROR.getBody)
+ }(ec)
+ }
+ }
+ def server(port: Int): TestServer = {
+ TestServer(port, FakeApplication(withGlobal = Some(new Settings()), withRoutes = routes))
+ }
}

ADD
dd-java-agent/instrumentation/play-2.3/src/test/scala/server/Settings.scala
+package server
+
+import play.api.GlobalSettings
+import play.api.mvc.{RequestHeader, Result, Results}
+
+import scala.concurrent.Future
+
+class Settings extends GlobalSettings {
+ override def onError(request: RequestHeader, ex: Throwable): Future[Result] = {
+ Future.successful(Results.InternalServerError(ex.getCause.getMessage))
+ }
+}

MODIFY
dd-java-agent/instrumentation/play-2.3/src/test/scala/server/SyncServer.scala
dd-java-agent/instrumentation/play-2.3/src/test/scala/server/SyncServer.scala
@@ -6,10 +6,14 @@ import play.api.test.{FakeApplication, TestServer}
object SyncServer {
val routes: PartialFunction[(String, String), Handler] = {
- case ("GET", "/success") => Action { request => Results.Status(SUCCESS.getStatus) }
+ case ("GET", "/success") => Action { request => Results.Status(SUCCESS.getStatus).apply(SUCCESS.getBody) }
+ case ("GET", "/redirect") => Action { request => Results.Redirect(REDIRECT.getBody, REDIRECT.getStatus) }
+ case ("GET", "/query") => Action { result => Results.Status(QUERY_PARAM.getStatus).apply(QUERY_PARAM.getBody) }
+ case ("GET", "/error-status") => Action { result => throw new RuntimeException(ERROR.getBody) }
+ case ("GET", "/exception") => Action { result => throw new RuntimeException(EXCEPTION.getBody) }
}
def server(port: Int): TestServer = {
- TestServer(port, FakeApplication(withRoutes = routes))
+ TestServer(port, FakeApplication(withGlobal = Some(new Settings()), withRoutes = routes))
}
}

Test servers now both work