Fix finatra tests for latest dependencies (DataDog/dd-trace-java#1706)
MODIFY
instrumentation/finatra-2.9/finatra-2.9.gradle
instrumentation/finatra-2.9/finatra-2.9.gradle
@@ -6,6 +6,12 @@ ext {
apply from: "$rootDir/gradle/instrumentation.gradle"
apply from: "$rootDir/gradle/test-with-scala.gradle"
+apply plugin: 'org.unbroken-dome.test-sets'
+
+testSets {
+ latestDepTest
+}
+
muzzle {
// There are some weird library issues below 2.9 so can't assert inverse
pass {
@@ -36,5 +42,10 @@ dependencies {
// Required for older versions of finatra on JDKs >= 11
testImplementation group: 'com.sun.activation', name: 'javax.activation', version: '1.2.0'
- latestDepTestLibrary group: 'com.twitter', name: 'finatra-http_2.11', version: '20.6.+'
+ // TODO latestDepTestLibrary doesn't work here
+ latestDepTestImplementation group: 'com.twitter', name: 'finatra-http_2.11', version: '+'
+}
+
+compileLatestDepTestGroovy {
+ classpath += files(sourceSets.latestDepTest.scala.classesDirectory)
}

ADD
instrumentation/finatra-2.9/src/latestDepTest/groovy/FinatraServerLatestTest.groovy
+/*
+ * Copyright The OpenTelemetry Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import static io.opentelemetry.auto.test.base.HttpServerTest.ServerEndpoint.SUCCESS
+import static io.opentelemetry.trace.Span.Kind.INTERNAL
+
+import com.twitter.app.lifecycle.Event
+import com.twitter.app.lifecycle.Observer
+import com.twitter.finatra.http.HttpServer
+import com.twitter.util.Await
+import com.twitter.util.Closable
+import com.twitter.util.Duration
+import com.twitter.util.Promise
+import io.opentelemetry.auto.test.asserts.TraceAssert
+import io.opentelemetry.auto.test.base.HttpServerTest
+import io.opentelemetry.sdk.trace.data.SpanData
+
+class FinatraServerLatestTest extends HttpServerTest<HttpServer> {
+ private static final Duration TIMEOUT = Duration.fromSeconds(5)
+ private static final Duration STARTUP_TIMEOUT = Duration.fromSeconds(20)
+
+ static closeAndWait(Closable closable) {
+ if (closable != null) {
+ Await.ready(closable.close(), TIMEOUT)
+ }
+ }
+
+ @Override
+ HttpServer startServer(int port) {
+ HttpServer testServer = new FinatraServer()
+
+ // Starting the server is blocking so start it in a separate thread
+ Thread startupThread = new Thread({
+ testServer.main("-admin.port=:0", "-http.port=:" + port)
+ })
+ startupThread.setDaemon(true)
+ startupThread.start()
+
+ Promise<Boolean> startupPromise = new Promise<>()
+
+ testServer.withObserver(new Observer() {
+ @Override
+ void onSuccess(Event event) {
+ if (event == testServer.startupCompletionEvent()) {
+ startupPromise.setValue(true)
+ }
+ }
+
+ void onEntry(Event event) {
+
+ }
+
+ @Override
+ void onFailure(Event stage, Throwable throwable) {
+ if (stage != Event.Close$.MODULE$) {
+ startupPromise.setException(throwable)
+ }
+ }
+ })
+
+ Await.result(startupPromise, STARTUP_TIMEOUT)
+
+ return testServer
+ }
+
+ @Override
+ boolean hasHandlerSpan() {
+ return true
+ }
+
+ @Override
+ boolean testNotFound() {
+ // Resource name is set to "GET /notFound"
+ false
+ }
+
+ @Override
+ void stopServer(HttpServer httpServer) {
+ Await.ready(httpServer.close(), TIMEOUT)
+ }
+
+ @Override
+ void handlerSpan(TraceAssert trace, int index, Object parent, String method = "GET", ServerEndpoint endpoint = SUCCESS) {
+ trace.span(index) {
+ operationName "FinatraController"
+ spanKind INTERNAL
+ childOf(parent as SpanData)
+ // Finatra doesn't propagate the stack trace or exception to the instrumentation
+ // so the normal errorAttributes() method can't be used
+ errored false
+ attributes {
+ }
+ }
+ }
+}

ADD
instrumentation/finatra-2.9/src/latestDepTest/scala/FinatraController.scala
+/*
+ * Copyright The OpenTelemetry Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.twitter.finagle.http.{Request, Response}
+import com.twitter.finatra.http.Controller
+import com.twitter.util.Future
+import groovy.lang.Closure
+import io.opentelemetry.auto.test.base.HttpServerTest.ServerEndpoint._
+import io.opentelemetry.auto.test.base.HttpServerTest.controller
+
+class FinatraController extends Controller {
+ any(SUCCESS.getPath) { request: Request =>
+ controller(SUCCESS, new Closure[Response](null) {
+ override def call(): Response = {
+ response.ok(SUCCESS.getBody)
+ }
+ })
+ }
+
+ any(ERROR.getPath) { request: Request =>
+ controller(ERROR, new Closure[Response](null) {
+ override def call(): Response = {
+ response.internalServerError(ERROR.getBody)
+ }
+ })
+ }
+
+ any(QUERY_PARAM.getPath) { request: Request =>
+ controller(QUERY_PARAM, new Closure[Response](null) {
+ override def call(): Response = {
+ response.ok(QUERY_PARAM.getBody)
+ }
+ })
+ }
+
+ any(EXCEPTION.getPath) { request: Request =>
+ controller(EXCEPTION, new Closure[Future[Response]](null) {
+ override def call(): Future[Response] = {
+ throw new Exception(EXCEPTION.getBody)
+ }
+ })
+ }
+
+ any(REDIRECT.getPath) { request: Request =>
+ controller(REDIRECT, new Closure[Response](null) {
+ override def call(): Response = {
+ response.found.location(REDIRECT.getBody)
+ }
+ })
+ }
+}

ADD
instrumentation/finatra-2.9/src/latestDepTest/scala/FinatraServer.scala
+/*
+ * Copyright The OpenTelemetry Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.twitter.finagle.http.Request
+import com.twitter.finatra.http.HttpServer
+import com.twitter.finatra.http.filters.ExceptionMappingFilter
+import com.twitter.finatra.http.routing.HttpRouter
+
+class FinatraServer extends HttpServer {
+ override protected def configureHttp(router: HttpRouter): Unit = {
+ router
+ .filter[ExceptionMappingFilter[Request]]
+ .add[FinatraController]
+ .exceptionMapper[ResponseSettingExceptionMapper]
+ }
+}

ADD
instrumentation/finatra-2.9/src/latestDepTest/scala/ResponseSettingExceptionMapper.scala
+/*
+ * Copyright The OpenTelemetry Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.twitter.finagle.http.{Request, Response}
+import com.twitter.finatra.http.exceptions.ExceptionMapper
+import com.twitter.finatra.http.response.ResponseBuilder
+import javax.inject.{Inject, Singleton}
+
+@Singleton
+class ResponseSettingExceptionMapper @Inject()(response: ResponseBuilder)
+ extends ExceptionMapper[Exception] {
+
+ override def toResponse(request: Request, exception: Exception): Response = {
+ response.internalServerError(exception.getMessage)
+ }
+}

Fix finatra tests for latest dependencies (DataDog/dd-trace-java#1706)