Browse Source

Migrate to spock 2 (#4458)

* Migrate to spock 2

* Fix smoke test suites

* address review comments

* review comment

Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
Lauri Tulmin 3 years ago
parent
commit
9b8ab5eeec
72 changed files with 865 additions and 699 deletions
  1. 14 2
      conventions/src/main/kotlin/otel.java-conventions.gradle.kts
  2. 3 3
      dependencyManagement/build.gradle.kts
  3. 12 2
      instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/aws/SnsCamelTest.groovy
  4. 5 5
      instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/test_before_1_11_106/groovy/Aws0ClientTest.groovy
  5. 3 3
      instrumentation/grpc-1.6/testing/src/main/groovy/io/opentelemetry/instrumentation/grpc/v1_6/AbstractGrpcStreamingTest.groovy
  6. 3 0
      instrumentation/gwt-2.0/javaagent/src/test/groovy/GwtTest.groovy
  7. 3 3
      instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/test/groovy/ProcedureCallTest.groovy
  8. 4 4
      instrumentation/http-url-connection/javaagent/src/test/groovy/HttpUrlConnectionTest.groovy
  9. 2 3
      instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-arquillian-testing/build.gradle.kts
  10. 0 75
      instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-arquillian-testing/src/main/groovy/ArquillianRestTest.groovy
  11. 70 0
      instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-arquillian-testing/src/main/java/AbstractArquillianRestTest.java
  12. 2 2
      instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxRsFilterTest.groovy
  13. 1 1
      instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxRsHttpServerTest.groovy
  14. 8 0
      instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-cxf-3.2/javaagent/src/test/groovy/CxfFilterTest.groovy
  15. 1 2
      instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-payara-testing/src/test/java/PayaraArquillianRestTest.java
  16. 0 11
      instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-tomee-testing/src/test/groovy/TomeeRestTest.groovy
  17. 1 2
      instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-tomee-testing/src/test/java/TomeeArquillianRestTest.java
  18. 6 0
      instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-wildfly-testing/src/test/java/WildflyArquillianRestTest.java
  19. 2 3
      instrumentation/jaxws/jaxws-2.0-arquillian-testing/build.gradle.kts
  20. 0 143
      instrumentation/jaxws/jaxws-2.0-arquillian-testing/src/main/groovy/ArquillianJaxWsTest.groovy
  21. 122 0
      instrumentation/jaxws/jaxws-2.0-arquillian-testing/src/main/java/AbstractArquillianJaxWsTest.java
  22. 6 0
      instrumentation/jaxws/jaxws-2.0-common-testing/src/main/groovy/AbstractJaxWsTest.groovy
  23. 0 19
      instrumentation/jaxws/jaxws-2.0-tomee-testing/src/test/groovy/TomeeJaxWsTest.groovy
  24. 15 0
      instrumentation/jaxws/jaxws-2.0-tomee-testing/src/test/java/TomeeArquillianJaxWsTest.java
  25. 0 15
      instrumentation/jaxws/jaxws-2.0-wildfly-testing/src/test/groovy/WildflyJaxWsTest.groovy
  26. 15 0
      instrumentation/jaxws/jaxws-2.0-wildfly-testing/src/test/java/WildflyArquillianJaxWsTest.java
  27. 10 5
      instrumentation/jdbc/javaagent/src/test/groovy/JdbcInstrumentationTest.groovy
  28. 1 2
      instrumentation/jetty/jetty-11.0/javaagent/src/test/groovy/JettyHandlerTest.groovy
  29. 1 2
      instrumentation/jetty/jetty-8.0/javaagent/src/test/groovy/JettyHandlerTest.groovy
  30. 1 1
      instrumentation/jetty/jetty-8.0/javaagent/src/test/groovy/QueuedThreadPoolTest.groovy
  31. 8 0
      instrumentation/jsf/jsf-common/testing/src/main/groovy/BaseJsfTest.groovy
  32. 14 14
      instrumentation/lettuce/lettuce-4.0/javaagent/src/test/groovy/LettuceAsyncClientTest.groovy
  33. 14 14
      instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceAsyncClientTest.groovy
  34. 4 4
      instrumentation/mongo/mongo-4.0/javaagent/src/test/groovy/Mongo4ReactiveClientTest.groovy
  35. 2 2
      instrumentation/mongo/mongo-4.0/javaagent/src/test/groovy/MongoClientTest.groovy
  36. 3 3
      instrumentation/mongo/mongo-async-3.3/javaagent/src/test/groovy/MongoAsyncClientTest.groovy
  37. 1 1
      instrumentation/netty/netty-4.1/javaagent/src/test/groovy/Netty41ClientTest.groovy
  38. 2 2
      instrumentation/netty/netty-4.1/javaagent/src/test/groovy/Netty41NativeClientTest.groovy
  39. 2 2
      instrumentation/rabbitmq-2.7/javaagent/src/test/groovy/RabbitMqTest.groovy
  40. 8 0
      instrumentation/servlet/servlet-3.0/javaagent/src/test/groovy/AbstractServlet3MappingTest.groovy
  41. 1 1
      instrumentation/servlet/servlet-3.0/javaagent/src/test/groovy/TomcatServlet3Test.groovy
  42. 8 0
      instrumentation/servlet/servlet-5.0/javaagent/src/test/groovy/AbstractServlet5MappingTest.groovy
  43. 1 1
      instrumentation/servlet/servlet-5.0/javaagent/src/test/groovy/TomcatServlet5Test.groovy
  44. 3 4
      instrumentation/spring/spring-webmvc-3.1/wildfly-testing/build.gradle.kts
  45. 0 165
      instrumentation/spring/spring-webmvc-3.1/wildfly-testing/src/test/groovy/OpenTelemetryHandlerMappingFilterTest.groovy
  46. 72 0
      instrumentation/spring/spring-webmvc-3.1/wildfly-testing/src/test/java/AbstractOpenTelemetryHandlerMappingFilterTest.java
  47. 36 0
      instrumentation/spring/spring-webmvc-3.1/wildfly-testing/src/test/java/LibsInEarOpenTelemetryHandlerMappingFilterTest.java
  48. 36 0
      instrumentation/spring/spring-webmvc-3.1/wildfly-testing/src/test/java/LibsInWarOpenTelemetryHandlerMappingFilterTest.java
  49. 41 0
      instrumentation/spring/spring-webmvc-3.1/wildfly-testing/src/test/java/MixedLibsOpenTelemetryHandlerMappingFilterTest.java
  50. 6 0
      instrumentation/spring/spring-ws-2.0/javaagent/src/test/groovy/test/boot/SpringWsTest.groovy
  51. 8 0
      instrumentation/tapestry-5.4/javaagent/src/test/groovy/TapestryTest.groovy
  52. 4 0
      instrumentation/vaadin-14.2/testing/src/main/groovy/test/vaadin/AbstractVaadinTest.groovy
  53. 8 0
      instrumentation/wicket-8.0/javaagent/src/test/groovy/WicketTest.groovy
  54. 3 4
      javaagent-tooling/src/test/groovy/io/opentelemetry/javaagent/tooling/config/ConfigInitializerTest.groovy
  55. 9 7
      javaagent-tooling/src/test/groovy/io/opentelemetry/javaagent/tooling/config/ConfigurationFileTest.groovy
  56. 1 1
      muzzle/src/test/groovy/io/opentelemetry/javaagent/tooling/muzzle/ReferenceMatcherTest.groovy
  57. 6 6
      smoke-tests/build.gradle.kts
  58. 6 1
      smoke-tests/images/servlet/build.gradle
  59. 9 6
      smoke-tests/src/test/groovy/io/opentelemetry/smoketest/AppServerTest.groovy
  60. 14 5
      smoke-tests/src/test/groovy/io/opentelemetry/smoketest/GlassFishSmokeTest.groovy
  61. 39 10
      smoke-tests/src/test/groovy/io/opentelemetry/smoketest/JettySmokeTest.groovy
  62. 20 7
      smoke-tests/src/test/groovy/io/opentelemetry/smoketest/LibertySmokeTest.groovy
  63. 46 11
      smoke-tests/src/test/groovy/io/opentelemetry/smoketest/TomcatSmokeTest.groovy
  64. 50 17
      smoke-tests/src/test/groovy/io/opentelemetry/smoketest/TomeeSmokeTest.groovy
  65. 44 15
      smoke-tests/src/test/groovy/io/opentelemetry/smoketest/WildflySmokeTest.groovy
  66. 0 2
      smoke-tests/src/test/java/io/opentelemetry/smoketest/AppServer.java
  67. 0 59
      smoke-tests/src/test/java/io/opentelemetry/smoketest/AppServerTestRunner.java
  68. 0 19
      smoke-tests/src/test/java/io/opentelemetry/smoketest/AppServers.java
  69. 14 1
      testing-common/build.gradle.kts
  70. 2 2
      testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpClientTest.groovy
  71. 9 1
      testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpServerTest.groovy
  72. 0 4
      testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpServerTestTrait.groovy

+ 14 - 2
conventions/src/main/kotlin/otel.java-conventions.gradle.kts

@@ -102,12 +102,24 @@ dependencies {
   testRuntimeOnly("org.junit.vintage:junit-vintage-engine")
 
   testImplementation("org.objenesis:objenesis")
-  testImplementation("org.spockframework:spock-core")
+  testImplementation("org.spockframework:spock-core") {
+    // exclude optional dependencies
+    exclude(group = "cglib", module = "cglib-nodep")
+    exclude(group = "net.bytebuddy", module = "byte-buddy")
+    exclude(group = "org.junit.platform", module = "junit-platform-testkit")
+    exclude(group = "org.jetbrains", module = "annotations")
+    exclude(group = "org.objenesis", module = "objenesis")
+    exclude(group = "org.ow2.asm", module = "asm")
+  }
+  testImplementation("org.spockframework:spock-junit4") {
+    // spock-core is already added as dependency
+    // exclude it here to avoid pulling in optional dependencies
+    exclude(group = "org.spockframework", module = "spock-core")
+  }
   testImplementation("ch.qos.logback:logback-classic")
   testImplementation("org.slf4j:log4j-over-slf4j")
   testImplementation("org.slf4j:jcl-over-slf4j")
   testImplementation("org.slf4j:jul-to-slf4j")
-  testImplementation("info.solidsoft.spock:spock-global-unroll")
   testImplementation("com.github.stefanbirkner:system-rules")
 }
 

+ 3 - 3
dependencyManagement/build.gradle.kts

@@ -18,7 +18,7 @@ val grpcVersion = "1.41.0"
 rootProject.extra["otelVersion"] = otelVersion
 
 // Need both BOM and -all
-val groovyVersion = "2.5.11"
+val groovyVersion = "2.5.14"
 
 rootProject.extra["caffeine2Version"] = "2.9.2"
 rootProject.extra["caffeine3Version"] = "3.0.4"
@@ -105,14 +105,14 @@ val DEPENDENCIES = listOf(
   "commons-lang:commons-lang:2.6",
   "commons-logging:commons-logging:1.2",
   "commons-validator:commons-validator:1.7",
-  "info.solidsoft.spock:spock-global-unroll:0.5.1",
   "io.netty:netty:3.10.6.Final",
   "org.assertj:assertj-core:3.21.0",
   "org.awaitility:awaitility:4.1.0",
   "com.google.code.findbugs:jsr305:3.0.2",
   "org.codehaus.groovy:groovy-all:${groovyVersion}",
   "org.objenesis:objenesis:3.2",
-  "org.spockframework:spock-core:1.3-groovy-2.5",
+  "org.spockframework:spock-core:2.0-groovy-2.5",
+  "org.spockframework:spock-junit4:2.0-groovy-2.5",
   "org.scala-lang:scala-library:2.11.12",
   "org.springframework.boot:spring-boot-dependencies:2.3.1.RELEASE",
   "io.grpc:grpc-netty-shaded:${grpcVersion}"

+ 12 - 2
instrumentation/apache-camel-2.20/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/apachecamel/aws/SnsCamelTest.groovy

@@ -24,7 +24,12 @@ class SnsCamelTest extends AgentInstrumentationSpecification {
     String queueName = "snsCamelTest"
     def camelApp = new CamelSpringApp(awsConnector, SnsConfig, ImmutableMap.of("topicName", topicName, "queueName", queueName))
 
-    def (queueUrl, topicArn) = setupTestInfrastructure(queueName, topicName)
+    // TODO: def (queueUrl, topicArn) fails to compile, switch back when this is fixed in spock
+    // https://github.com/spockframework/spock/pull/1333
+    // def (queueUrl, topicArn) = setupTestInfrastructure(queueName, topicName)
+    Tuple tuple = setupTestInfrastructure(queueName, topicName)
+    def queueUrl = tuple.get(0)
+    def topicArn = tuple.get(1)
     waitAndClearSetupTraces(queueUrl, queueName)
 
     when:
@@ -61,7 +66,12 @@ class SnsCamelTest extends AgentInstrumentationSpecification {
     String queueName = "snsCamelTest"
     def camelApp = new CamelSpringApp(awsConnector, SnsConfig, ImmutableMap.of("topicName", topicName, "queueName", queueName))
 
-    def (queueUrl, topicArn) = setupTestInfrastructure(queueName, topicName)
+    // TODO: def (queueUrl, topicArn) fails to compile, switch back when this is fixed in spock
+    // https://github.com/spockframework/spock/pull/1333
+    // def (queueUrl, topicArn) = setupTestInfrastructure(queueName, topicName)
+    Tuple tuple = setupTestInfrastructure(queueName, topicName)
+    def queueUrl = tuple.get(0)
+    def topicArn = tuple.get(1)
     waitAndClearSetupTraces(queueUrl, queueName)
 
     when:

+ 5 - 5
instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/test_before_1_11_106/groovy/Aws0ClientTest.groovy

@@ -129,17 +129,17 @@ class Aws0ClientTest extends AgentInstrumentationSpecification {
     request.request().headers().get("traceparent") == null
 
     where:
-    service | operation           | method | path                  | handlerCount | client                                                    | additionalAttributes              | call                                                                                                                                   | body
-    "S3"    | "CreateBucket"      | "PUT"  | "/testbucket/"        | 1            | new AmazonS3Client().withEndpoint("${server.httpUri()}")  | ["aws.bucket.name": "testbucket"] | { client -> client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).build()); client.createBucket("testbucket") } | ""
-    "S3"    | "GetObject"         | "GET"  | "/someBucket/someKey" | 1            | new AmazonS3Client().withEndpoint("${server.httpUri()}")  | ["aws.bucket.name": "someBucket"] | { client -> client.getObject("someBucket", "someKey") }                                                                                | ""
-    "EC2"   | "AllocateAddress"   | "POST" | "/"                   | 4            | new AmazonEC2Client().withEndpoint("${server.httpUri()}") | [:]                               | { client -> client.allocateAddress() }                                                                                                 | """
+    service | operation           | method | path                  | handlerCount | client                                                    | additionalAttributes              | call                                                                                                                    | body
+    "S3"    | "CreateBucket"      | "PUT"  | "/testbucket/"        | 1            | new AmazonS3Client().withEndpoint("${server.httpUri()}")  | ["aws.bucket.name": "testbucket"] | { c -> c.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).build()); c.createBucket("testbucket") } | ""
+    "S3"    | "GetObject"         | "GET"  | "/someBucket/someKey" | 1            | new AmazonS3Client().withEndpoint("${server.httpUri()}")  | ["aws.bucket.name": "someBucket"] | { c -> c.getObject("someBucket", "someKey") }                                                                           | ""
+    "EC2"   | "AllocateAddress"   | "POST" | "/"                   | 4            | new AmazonEC2Client().withEndpoint("${server.httpUri()}") | [:]                               | { c -> c.allocateAddress() }                                                                                            | """
             <AllocateAddressResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
                <requestId>59dbff89-35bd-4eac-99ed-be587EXAMPLE</requestId> 
                <publicIp>192.0.2.1</publicIp>
                <domain>standard</domain>
             </AllocateAddressResponse>
             """
-    "RDS"   | "DeleteOptionGroup" | "POST" | "/"                   | 1            | new AmazonRDSClient().withEndpoint("${server.httpUri()}") | [:]                               | { client -> client.deleteOptionGroup(new DeleteOptionGroupRequest()) }                                                                 | """
+    "RDS"   | "DeleteOptionGroup" | "POST" | "/"                   | 1            | new AmazonRDSClient().withEndpoint("${server.httpUri()}") | [:]                               | { c -> c.deleteOptionGroup(new DeleteOptionGroupRequest()) }                                                            | """
         <DeleteOptionGroupResponse xmlns="http://rds.amazonaws.com/doc/2014-09-01/">
           <ResponseMetadata>
             <RequestId>0ac9cda2-bbf4-11d3-f92b-31fa5e8dbc99</RequestId>

+ 3 - 3
instrumentation/grpc-1.6/testing/src/main/groovy/io/opentelemetry/instrumentation/grpc/v1_6/AbstractGrpcStreamingTest.groovy

@@ -81,7 +81,7 @@ abstract class AbstractGrpcStreamingTest extends InstrumentationSpecification {
     GreeterGrpc.GreeterStub client = GreeterGrpc.newStub(channel).withWaitForReady()
 
     when:
-    def observer = client.conversation(new StreamObserver<Helloworld.Response>() {
+    def observer2 = client.conversation(new StreamObserver<Helloworld.Response>() {
       @Override
       void onNext(Helloworld.Response value) {
         clientReceived << value.message
@@ -99,9 +99,9 @@ abstract class AbstractGrpcStreamingTest extends InstrumentationSpecification {
 
     clientRange.each {
       def message = Helloworld.Response.newBuilder().setMessage("call $it").build()
-      observer.onNext(message)
+      observer2.onNext(message)
     }
-    observer.onCompleted()
+    observer2.onCompleted()
 
     then:
     assertTraces(1) {

+ 3 - 0
instrumentation/gwt-2.0/javaagent/src/test/groovy/GwtTest.groovy

@@ -51,6 +51,8 @@ class GwtTest extends AgentInstrumentationSpecification implements HttpServerTes
   }
 
   def setupSpec() {
+    setupServer()
+
     Testcontainers.exposeHostPorts(port)
 
     browser = new BrowserWebDriverContainer<>()
@@ -62,6 +64,7 @@ class GwtTest extends AgentInstrumentationSpecification implements HttpServerTes
   }
 
   def cleanupSpec() {
+    cleanupServer()
     browser?.stop()
   }
 

+ 3 - 3
instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/test/groovy/ProcedureCallTest.groovy

@@ -10,7 +10,7 @@ import org.hibernate.SessionFactory
 import org.hibernate.cfg.Configuration
 import org.hibernate.exception.SQLGrammarException
 import org.hibernate.procedure.ProcedureCall
-import org.junit.Assume
+import org.junit.jupiter.api.Assumptions
 import spock.lang.Shared
 
 import javax.persistence.ParameterMode
@@ -62,7 +62,7 @@ class ProcedureCallTest extends AgentInstrumentationSpecification {
       call.getOutputs()
     } catch (Exception exception) {
       // ignore failures on hibernate 6 where this functionality has not been implemented yet
-      Assume.assumeFalse("org.hibernate.NotYetImplementedFor6Exception" == exception.getClass().getName())
+      Assumptions.assumeFalse("org.hibernate.NotYetImplementedFor6Exception" == exception.getClass().getName())
       throw exception
     }
   }
@@ -127,7 +127,7 @@ class ProcedureCallTest extends AgentInstrumentationSpecification {
 
     ProcedureCall call = session.createStoredProcedureCall("TEST_PROC")
     def parameterRegistration = call.registerParameter("nonexistent", Long, ParameterMode.IN)
-    Assume.assumeTrue(parameterRegistration.metaClass.getMetaMethod("bindValue", Object) != null)
+    Assumptions.assumeTrue(parameterRegistration.metaClass.getMetaMethod("bindValue", Object) != null)
     parameterRegistration.bindValue(420L)
     try {
       callProcedure(call)

+ 4 - 4
instrumentation/http-url-connection/javaagent/src/test/groovy/HttpUrlConnectionTest.groovy

@@ -154,11 +154,11 @@ class HttpUrlConnectionTest extends HttpClientTest<HttpURLConnection> implements
     setup:
     def url = resolveAddress("/success").toURL()
     HttpURLConnection connection = runWithSpan("someTrace") {
-      HttpURLConnection connection = url.openConnection()
-      connection.setRequestProperty("Connection", "close")
+      HttpURLConnection con = url.openConnection()
+      con.setRequestProperty("Connection", "close")
       assert Span.current().getSpanContext().isValid()
-      assert connection.getResponseCode() == STATUS
-      return connection
+      assert con.getResponseCode() == STATUS
+      return con
     }
 
     expect:

+ 2 - 3
instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-arquillian-testing/build.gradle.kts

@@ -8,9 +8,8 @@ dependencies {
   api(project(":testing-common"))
   implementation("io.opentelemetry:opentelemetry-api")
 
-  val arquillianVersion = "1.4.0.Final"
-  implementation("org.jboss.arquillian.junit:arquillian-junit-container:$arquillianVersion")
+  val arquillianVersion = "1.7.0.Alpha10"
+  implementation("org.jboss.arquillian.junit5:arquillian-junit5-container:$arquillianVersion")
   implementation("org.jboss.arquillian.protocol:arquillian-protocol-servlet:$arquillianVersion")
-  implementation("org.jboss.arquillian.spock:arquillian-spock-container:1.0.0.CR1")
   api("org.jboss.shrinkwrap:shrinkwrap-impl-base:1.2.6")
 }

+ 0 - 75
instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-arquillian-testing/src/main/groovy/ArquillianRestTest.groovy

@@ -1,75 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
-import io.opentelemetry.testing.internal.armeria.client.WebClient
-import io.opentelemetry.testing.internal.armeria.common.AggregatedHttpResponse
-import org.jboss.arquillian.container.test.api.Deployment
-import org.jboss.arquillian.container.test.api.RunAsClient
-import org.jboss.arquillian.spock.ArquillianSputnik
-import org.jboss.arquillian.test.api.ArquillianResource
-import org.jboss.shrinkwrap.api.ShrinkWrap
-import org.jboss.shrinkwrap.api.asset.EmptyAsset
-import org.jboss.shrinkwrap.api.spec.WebArchive
-import org.junit.runner.RunWith
-import spock.lang.Unroll
-import test.CdiRestResource
-import test.EjbRestResource
-import test.RestApplication
-
-import static io.opentelemetry.api.trace.SpanKind.SERVER
-
-@RunWith(ArquillianSputnik)
-@RunAsClient
-abstract class ArquillianRestTest extends AgentInstrumentationSpecification {
-
-  static WebClient client = WebClient.of()
-
-  @ArquillianResource
-  static URI url
-
-  @Deployment
-  static WebArchive createDeployment() {
-    return ShrinkWrap.create(WebArchive)
-      .addClass(RestApplication)
-      .addClass(CdiRestResource)
-      .addClass(EjbRestResource)
-      .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
-  }
-
-  def getContextRoot() {
-    return url.getPath()
-  }
-
-  @Unroll
-  def "test #path"() {
-    when:
-    AggregatedHttpResponse response = client.get(url.resolve(path).toString()).aggregate().join()
-
-    then:
-    response.status().code() == 200
-    response.contentUtf8() == "hello"
-
-    and:
-    assertTraces(1) {
-      trace(0, 2) {
-        span(0) {
-          name getContextRoot() + path
-          kind SERVER
-          hasNoParent()
-        }
-        span(1) {
-          name className + ".hello"
-          childOf span(0)
-        }
-      }
-    }
-
-    where:
-    path                | className
-    "rest-app/cdiHello" | "CdiRestResource"
-    "rest-app/ejbHello" | "EjbRestResource"
-  }
-}

+ 70 - 0
instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-arquillian-testing/src/main/java/AbstractArquillianRestTest.java

@@ -0,0 +1,70 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
+import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
+import io.opentelemetry.testing.internal.armeria.client.WebClient;
+import io.opentelemetry.testing.internal.armeria.common.AggregatedHttpResponse;
+import java.net.URI;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.RunAsClient;
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import test.CdiRestResource;
+import test.EjbRestResource;
+import test.RestApplication;
+
+@ExtendWith(ArquillianExtension.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@RunAsClient
+public abstract class AbstractArquillianRestTest {
+
+  @RegisterExtension
+  static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
+
+  public final WebClient client = WebClient.of();
+
+  @ArquillianResource public URI url;
+
+  @Deployment
+  static WebArchive createDeployment() {
+    return ShrinkWrap.create(WebArchive.class)
+        .addClass(RestApplication.class)
+        .addClass(CdiRestResource.class)
+        .addClass(EjbRestResource.class)
+        .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
+  }
+
+  private String getContextRoot() {
+    return url.getPath();
+  }
+
+  @ParameterizedTest
+  @CsvSource({"rest-app/cdiHello, CdiRestResource", "rest-app/ejbHello, EjbRestResource"})
+  public void testHelloRequest(String path, String className) {
+    AggregatedHttpResponse response = client.get(url.resolve(path).toString()).aggregate().join();
+
+    assertThat(response.status().code()).isEqualTo(200);
+    assertThat(response.contentUtf8()).isEqualTo("hello");
+
+    testing.waitAndAssertTraces(
+        trace ->
+            trace.hasSpansSatisfyingExactly(
+                span ->
+                    span.hasName(getContextRoot() + path).hasKind(SpanKind.SERVER).hasNoParent(),
+                span -> span.hasName(className + ".hello").hasParent(trace.getSpan(0))));
+  }
+}

+ 2 - 2
instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxRsFilterTest.groovy

@@ -5,7 +5,7 @@
 
 import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
 import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
-import org.junit.Assume
+import org.junit.jupiter.api.Assumptions
 import spock.lang.Shared
 import spock.lang.Unroll
 
@@ -51,7 +51,7 @@ abstract class JaxRsFilterTest extends AgentInstrumentationSpecification {
   }
 
   def "test #resource, #abortNormal, #abortPrematch"() {
-    Assume.assumeTrue(!abortPrematch || testAbortPrematch())
+    Assumptions.assumeTrue(!abortPrematch || testAbortPrematch())
 
     given:
     simpleRequestFilter.abort = abortNormal

+ 1 - 1
instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-common/testing/src/main/groovy/JaxRsHttpServerTest.groovy

@@ -21,7 +21,7 @@ import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEn
 import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.PATH_PARAM
 import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.SUCCESS
 import static java.util.concurrent.TimeUnit.SECONDS
-import static org.junit.Assume.assumeTrue
+import static org.junit.jupiter.api.Assumptions.assumeTrue
 
 abstract class JaxRsHttpServerTest<S> extends HttpServerTest<S> implements AgentTestTrait {
 

+ 8 - 0
instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-cxf-3.2/javaagent/src/test/groovy/CxfFilterTest.groovy

@@ -14,6 +14,14 @@ import static Resource.Test3
 
 class CxfFilterTest extends JaxRsFilterTest implements HttpServerTestTrait<Server> {
 
+  def setupSpec() {
+    setupServer()
+  }
+
+  def cleanupSpec() {
+    cleanupServer()
+  }
+
   @Override
   boolean testAbortPrematch() {
     false

+ 1 - 2
instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-wildfly-testing/src/test/groovy/WildflyRestTest.groovy → instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-payara-testing/src/test/java/PayaraArquillianRestTest.java

@@ -3,5 +3,4 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 
-class WildflyRestTest extends ArquillianRestTest {
-}
+public class PayaraArquillianRestTest extends AbstractArquillianRestTest {}

+ 0 - 11
instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-tomee-testing/src/test/groovy/TomeeRestTest.groovy

@@ -1,11 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-import javax.enterprise.inject.Vetoed
-
-// exclude this class from CDI as it causes NullPointerException when tomee is run with jdk8
-@Vetoed
-class TomeeRestTest extends ArquillianRestTest {
-}

+ 1 - 2
instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-payara-testing/src/test/groovy/PayaraRestTest.groovy → instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-tomee-testing/src/test/java/TomeeArquillianRestTest.java

@@ -3,5 +3,4 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 
-class PayaraRestTest extends ArquillianRestTest {
-}
+public class TomeeArquillianRestTest extends AbstractArquillianRestTest {}

+ 6 - 0
instrumentation/jaxrs/jaxrs-2.0/jaxrs-2.0-wildfly-testing/src/test/java/WildflyArquillianRestTest.java

@@ -0,0 +1,6 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+public class WildflyArquillianRestTest extends AbstractArquillianRestTest {}

+ 2 - 3
instrumentation/jaxws/jaxws-2.0-arquillian-testing/build.gradle.kts

@@ -9,9 +9,8 @@ dependencies {
   implementation("io.opentelemetry:opentelemetry-api")
   implementation("org.jsoup:jsoup:1.13.1")
 
-  val arquillianVersion = "1.4.0.Final"
-  implementation("org.jboss.arquillian.junit:arquillian-junit-container:$arquillianVersion")
+  val arquillianVersion = "1.7.0.Alpha10"
+  implementation("org.jboss.arquillian.junit5:arquillian-junit5-container:$arquillianVersion")
   implementation("org.jboss.arquillian.protocol:arquillian-protocol-servlet:$arquillianVersion")
-  implementation("org.jboss.arquillian.spock:arquillian-spock-container:1.0.0.CR1")
   api("org.jboss.shrinkwrap:shrinkwrap-impl-base:1.2.6")
 }

+ 0 - 143
instrumentation/jaxws/jaxws-2.0-arquillian-testing/src/main/groovy/ArquillianJaxWsTest.groovy

@@ -1,143 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
-import io.opentelemetry.instrumentation.test.asserts.TraceAssert
-import io.opentelemetry.sdk.trace.data.SpanData
-import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
-import io.opentelemetry.testing.internal.armeria.client.WebClient
-import org.jboss.arquillian.container.test.api.Deployment
-import org.jboss.arquillian.container.test.api.RunAsClient
-import org.jboss.arquillian.spock.ArquillianSputnik
-import org.jboss.arquillian.test.api.ArquillianResource
-import org.jboss.shrinkwrap.api.ShrinkWrap
-import org.jboss.shrinkwrap.api.asset.EmptyAsset
-import org.jboss.shrinkwrap.api.spec.WebArchive
-import org.jsoup.Jsoup
-import org.junit.runner.RunWith
-import spock.lang.Unroll
-import test.EjbHelloServiceImpl
-import test.HelloService
-import test.HelloServiceImpl
-
-import static io.opentelemetry.api.trace.SpanKind.INTERNAL
-import static io.opentelemetry.api.trace.SpanKind.SERVER
-import static io.opentelemetry.api.trace.StatusCode.ERROR
-
-@RunWith(ArquillianSputnik)
-@RunAsClient
-abstract class ArquillianJaxWsTest extends AgentInstrumentationSpecification {
-
-  static WebClient client = WebClient.of()
-
-  @ArquillianResource
-  static URI url
-
-  @Deployment
-  static WebArchive createDeployment() {
-    return ShrinkWrap.create(WebArchive)
-      .addClass(HelloService)
-      .addClass(HelloServiceImpl)
-      .addClass(EjbHelloServiceImpl)
-      .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
-  }
-
-  def getContextRoot() {
-    return url.getPath()
-  }
-
-  def getServicePath(String service) {
-    service
-  }
-
-  def getAddress(String service) {
-    return url.resolve(getServicePath(service)).toString()
-  }
-
-  @Unroll
-  def "test #service"() {
-    setup:
-    def soapMessage =
-      """<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hel="http://opentelemetry.io/test/hello-web-service">
-         <soapenv:Header/>
-         <soapenv:Body>
-            <hel:helloRequest>
-               <name>Test</name>
-            </hel:helloRequest>
-         </soapenv:Body>
-      </soapenv:Envelope>"""
-
-    def response = client.post(getAddress(service), soapMessage).aggregate().join()
-    def doc = Jsoup.parse(response.contentUtf8())
-
-    expect:
-    response.status().code() == 200
-    doc.selectFirst("message").text() == "Hello Test"
-
-    and:
-    def methodName = "hello"
-    assertTraces(1) {
-      trace(0, 3) {
-        serverSpan(it, 0, serverSpanName(service, methodName))
-        handlerSpan(it, 1, service, methodName, span(0))
-        annotationHandlerSpan(it, 2, service, methodName, span(1))
-      }
-    }
-
-    where:
-    service << ["HelloService", "EjbHelloService"]
-  }
-
-  def serverSpanName(String service, String operation) {
-    return getContextRoot() + getServicePath(service) + "/" + service + "/" + operation
-  }
-
-  static serverSpan(TraceAssert trace, int index, String operation, Throwable exception = null) {
-    trace.span(index) {
-      hasNoParent()
-      name operation
-      kind SERVER
-      if (exception != null) {
-        status ERROR
-      }
-    }
-  }
-
-  static handlerSpan(TraceAssert trace, int index, String service, String operation, Object parentSpan = null, Throwable exception = null) {
-    trace.span(index) {
-      if (parentSpan == null) {
-        hasNoParent()
-      } else {
-        childOf((SpanData) parentSpan)
-      }
-      name service + "/" + operation
-      kind INTERNAL
-      if (exception) {
-        status ERROR
-        errorEvent(exception.class, exception.message)
-      }
-    }
-  }
-
-  static annotationHandlerSpan(TraceAssert trace, int index, String service, String methodName, Object parentSpan = null, Throwable exception = null) {
-    trace.span(index) {
-      if (parentSpan == null) {
-        hasNoParent()
-      } else {
-        childOf((SpanData) parentSpan)
-      }
-      name service + "Impl." + methodName
-      kind INTERNAL
-      if (exception) {
-        status ERROR
-        errorEvent(exception.class, exception.message)
-      }
-      attributes {
-        "${SemanticAttributes.CODE_NAMESPACE.key}" "test." + service + "Impl"
-        "${SemanticAttributes.CODE_FUNCTION.key}" methodName
-      }
-    }
-  }
-}

+ 122 - 0
instrumentation/jaxws/jaxws-2.0-arquillian-testing/src/main/java/AbstractArquillianJaxWsTest.java

@@ -0,0 +1,122 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
+
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
+import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
+import io.opentelemetry.sdk.testing.assertj.SpanDataAssert;
+import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
+import io.opentelemetry.testing.internal.armeria.client.WebClient;
+import io.opentelemetry.testing.internal.armeria.common.AggregatedHttpResponse;
+import java.net.URI;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.RunAsClient;
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import test.EjbHelloServiceImpl;
+import test.HelloService;
+import test.HelloServiceImpl;
+
+@ExtendWith(ArquillianExtension.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@RunAsClient
+public abstract class AbstractArquillianJaxWsTest {
+
+  @RegisterExtension
+  static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
+
+  public final WebClient client = WebClient.of();
+
+  @ArquillianResource public URI url;
+
+  @Deployment
+  static WebArchive createDeployment() {
+    return ShrinkWrap.create(WebArchive.class)
+        .addClass(HelloService.class)
+        .addClass(HelloServiceImpl.class)
+        .addClass(EjbHelloServiceImpl.class)
+        .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
+  }
+
+  private String getContextRoot() {
+    return url.getPath();
+  }
+
+  protected String getServicePath(String service) {
+    return service;
+  }
+
+  private String getAddress(String service) {
+    return url.resolve(getServicePath(service)).toString();
+  }
+
+  @ParameterizedTest
+  @ValueSource(strings = {"HelloService", "EjbHelloService"})
+  public void testHelloRequest(String service) {
+    String soapMessage =
+        "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:hel=\"http://opentelemetry.io/test/hello-web-service\">"
+            + "   <soapenv:Header/>"
+            + "   <soapenv:Body>"
+            + "      <hel:helloRequest>"
+            + "         <name>Test</name>"
+            + "      </hel:helloRequest>"
+            + "   </soapenv:Body>"
+            + "</soapenv:Envelope>";
+
+    AggregatedHttpResponse response =
+        client.post(getAddress(service), soapMessage).aggregate().join();
+    Document doc = Jsoup.parse(response.contentUtf8());
+
+    assertThat(response.status().code()).isEqualTo(200);
+    assertThat(doc.selectFirst("message").text()).isEqualTo("Hello Test");
+
+    String methodName = "hello";
+    testing.waitAndAssertTraces(
+        trace ->
+            trace.hasSpansSatisfyingExactly(
+                span -> assertServerSpan(span, serverSpanName(service, methodName)).hasNoParent(),
+                span -> assertHandlerSpan(span, service, methodName).hasParent(trace.getSpan(0)),
+                span ->
+                    assertAnnotationHandlerSpan(span, service, methodName)
+                        .hasParent(trace.getSpan(1))));
+  }
+
+  private String serverSpanName(String service, String operation) {
+    return getContextRoot() + getServicePath(service) + "/" + service + "/" + operation;
+  }
+
+  private static SpanDataAssert assertServerSpan(SpanDataAssert span, String operation) {
+    return span.hasName(operation).hasKind(SpanKind.SERVER);
+  }
+
+  private static SpanDataAssert assertHandlerSpan(
+      SpanDataAssert span, String service, String methodName) {
+    return span.hasName(service + "/" + methodName).hasKind(SpanKind.INTERNAL);
+  }
+
+  private static SpanDataAssert assertAnnotationHandlerSpan(
+      SpanDataAssert span, String service, String methodName) {
+    return span.hasName(service + "Impl." + methodName)
+        .hasKind(SpanKind.INTERNAL)
+        .hasAttributesSatisfying(
+            attrs -> {
+              assertThat(attrs)
+                  .containsEntry(SemanticAttributes.CODE_NAMESPACE, "test." + service + "Impl");
+              assertThat(attrs).containsEntry(SemanticAttributes.CODE_FUNCTION, methodName);
+            });
+  }
+}

+ 6 - 0
instrumentation/jaxws/jaxws-2.0-common-testing/src/main/groovy/AbstractJaxWsTest.groovy

@@ -33,10 +33,16 @@ abstract class AbstractJaxWsTest extends AgentInstrumentationSpecification imple
   protected WebServiceTemplate webServiceTemplate = new WebServiceTemplate(marshaller)
 
   def setupSpec() {
+    setupServer()
+
     marshaller.setPackagesToScan(ClassUtils.getPackageName(HelloRequest))
     marshaller.afterPropertiesSet()
   }
 
+  def cleanupSpec() {
+    cleanupServer()
+  }
+
   @Override
   Server startServer(int port) {
     List<String> configurationClasses = new ArrayList<>()

+ 0 - 19
instrumentation/jaxws/jaxws-2.0-tomee-testing/src/test/groovy/TomeeJaxWsTest.groovy

@@ -1,19 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-import javax.enterprise.inject.Vetoed
-
-// exclude this class from CDI as it causes NullPointerException when tomee is run with jdk8
-@Vetoed
-class TomeeJaxWsTest extends ArquillianJaxWsTest {
-
-  @Override
-  def getServicePath(String service) {
-    if (service == "EjbHelloService") {
-      service = "webservices/EjbHelloServiceImpl"
-    }
-    return service
-  }
-}

+ 15 - 0
instrumentation/jaxws/jaxws-2.0-tomee-testing/src/test/java/TomeeArquillianJaxWsTest.java

@@ -0,0 +1,15 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+public class TomeeArquillianJaxWsTest extends AbstractArquillianJaxWsTest {
+
+  @Override
+  protected String getServicePath(String service) {
+    if ("EjbHelloService".equals(service)) {
+      service = "webservices/EjbHelloServiceImpl";
+    }
+    return service;
+  }
+}

+ 0 - 15
instrumentation/jaxws/jaxws-2.0-wildfly-testing/src/test/groovy/WildflyJaxWsTest.groovy

@@ -1,15 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-class WildflyJaxWsTest extends ArquillianJaxWsTest {
-
-  @Override
-  def getServicePath(String service) {
-    if (service == "EjbHelloService") {
-      service = "EjbHelloService/EjbHelloServiceImpl"
-    }
-    return service
-  }
-}

+ 15 - 0
instrumentation/jaxws/jaxws-2.0-wildfly-testing/src/test/java/WildflyArquillianJaxWsTest.java

@@ -0,0 +1,15 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+public class WildflyArquillianJaxWsTest extends AbstractArquillianJaxWsTest {
+
+  @Override
+  protected String getServicePath(String service) {
+    if ("EjbHelloService".equals(service)) {
+      service = "EjbHelloService/EjbHelloServiceImpl";
+    }
+    return service;
+  }
+}

+ 10 - 5
instrumentation/jdbc/javaagent/src/test/groovy/JdbcInstrumentationTest.groovy

@@ -495,15 +495,20 @@ class JdbcInstrumentationTest extends AgentInstrumentationSpecification {
       connection = driver.connect(jdbcUrl, null)
     }
 
-    def (Statement statement, ResultSet rs) = runWithSpan("parent") {
+    // TODO: def (Statement statement, ResultSet rs) fails to compile, switch back when this is fixed in spock
+    // https://github.com/spockframework/spock/pull/1333
+    // def (Statement statement, ResultSet rs) = runWithSpan("parent") {
+    Tuple tuple = runWithSpan("parent") {
       if (prepareStatement) {
-        def statement = connection.prepareStatement(query)
-        return new Tuple(statement, statement.executeQuery())
+        def stmt = connection.prepareStatement(query)
+        return new Tuple(stmt, stmt.executeQuery())
       }
 
-      def statement = connection.createStatement()
-      return new Tuple(statement, statement.executeQuery(query))
+      def stmt = connection.createStatement()
+      return new Tuple(stmt, stmt.executeQuery(query))
     }
+    Statement statement = tuple.get(0)
+    ResultSet rs = tuple.get(1)
 
     then:
     rs.next()

+ 1 - 2
instrumentation/jetty/jetty-11.0/javaagent/src/test/groovy/JettyHandlerTest.groovy

@@ -30,8 +30,7 @@ import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEn
 
 class JettyHandlerTest extends HttpServerTest<Server> implements AgentTestTrait {
 
-  @Shared
-  ErrorHandler errorHandler = new ErrorHandler() {
+  static ErrorHandler errorHandler = new ErrorHandler() {
     @Override
     protected void handleErrorPage(HttpServletRequest request, Writer writer, int code, String message) throws IOException {
       Throwable th = (Throwable) request.getAttribute("jakarta.servlet.error.exception")

+ 1 - 2
instrumentation/jetty/jetty-8.0/javaagent/src/test/groovy/JettyHandlerTest.groovy

@@ -31,8 +31,7 @@ import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEn
 
 class JettyHandlerTest extends HttpServerTest<Server> implements AgentTestTrait {
 
-  @Shared
-  ErrorHandler errorHandler = new ErrorHandler() {
+  static ErrorHandler errorHandler = new ErrorHandler() {
     @Override
     protected void handleErrorPage(HttpServletRequest request, Writer writer, int code, String message) throws IOException {
       Throwable th = (Throwable) request.getAttribute("javax.servlet.error.exception")

+ 1 - 1
instrumentation/jetty/jetty-8.0/javaagent/src/test/groovy/QueuedThreadPoolTest.groovy

@@ -7,7 +7,7 @@ import io.opentelemetry.api.trace.SpanKind
 import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
 import org.eclipse.jetty.util.thread.QueuedThreadPool
 
-import static org.junit.Assume.assumeTrue
+import static org.junit.jupiter.api.Assumptions.assumeTrue
 
 class QueuedThreadPoolTest extends AgentInstrumentationSpecification {
 

+ 8 - 0
instrumentation/jsf/jsf-common/testing/src/main/groovy/BaseJsfTest.groovy

@@ -27,6 +27,14 @@ import static io.opentelemetry.api.trace.StatusCode.ERROR
 
 abstract class BaseJsfTest extends AgentInstrumentationSpecification implements HttpServerTestTrait<Server> {
 
+  def setupSpec() {
+    setupServer()
+  }
+
+  def cleanupSpec() {
+    cleanupServer()
+  }
+
   @Override
   Server startServer(int port) {
     String jsfVersion = getJsfVersion()

+ 14 - 14
instrumentation/lettuce/lettuce-4.0/javaagent/src/test/groovy/LettuceAsyncClientTest.groovy

@@ -230,11 +230,11 @@ class LettuceAsyncClientTest extends AgentInstrumentationSpecification {
     String successStr = "KEY MISSING"
     BiFunction<String, Throwable, String> firstStage = new BiFunction<String, Throwable, String>() {
       @Override
-      String apply(String res, Throwable throwable) {
+      String apply(String res, Throwable error) {
         runWithSpan("callback1") {
           conds.evaluate {
             assert res == null
-            assert throwable == null
+            assert error == null
           }
         }
         return (res == null ? successStr : res)
@@ -295,7 +295,7 @@ class LettuceAsyncClientTest extends AgentInstrumentationSpecification {
     def conds = new AsyncConditions()
     BiConsumer<String, Throwable> biConsumer = new BiConsumer<String, Throwable>() {
       @Override
-      void accept(String keyRetrieved, Throwable throwable) {
+      void accept(String keyRetrieved, Throwable error) {
         runWithSpan("callback") {
           conds.evaluate {
             assert keyRetrieved != null
@@ -353,9 +353,9 @@ class LettuceAsyncClientTest extends AgentInstrumentationSpecification {
         RedisFuture<Map<String, String>> hmGetAllFuture = asyncCommands.hgetall("TESTHM")
         hmGetAllFuture.exceptionally(new Function<Throwable, Map<String, String>>() {
           @Override
-          Map<String, String> apply(Throwable throwable) {
-            println("unexpected:" + throwable.toString())
-            throwable.printStackTrace()
+          Map<String, String> apply(Throwable error) {
+            println("unexpected:" + error.toString())
+            error.printStackTrace()
             assert false
             return null
           }
@@ -406,13 +406,13 @@ class LettuceAsyncClientTest extends AgentInstrumentationSpecification {
     RedisFuture redisFuture = asyncCommands.del("key1", "key2")
     boolean completedExceptionally = ((AsyncCommand) redisFuture).completeExceptionally(new IllegalStateException("TestException"))
     redisFuture.exceptionally({
-      throwable ->
+      error ->
         conds.evaluate {
-          assert throwable != null
-          assert throwable instanceof IllegalStateException
-          assert throwable.getMessage() == "TestException"
+          assert error != null
+          assert error instanceof IllegalStateException
+          assert error.getMessage() == "TestException"
         }
-        throw throwable
+        throw error
     })
 
     when:
@@ -448,11 +448,11 @@ class LettuceAsyncClientTest extends AgentInstrumentationSpecification {
       asyncCommands.sadd("SKEY", "1", "2")
     }
     redisFuture.whenCompleteAsync({
-      res, throwable ->
+      res, error ->
         runWithSpan("callback") {
           conds.evaluate {
-            assert throwable != null
-            assert throwable instanceof CancellationException
+            assert error != null
+            assert error instanceof CancellationException
           }
         }
     })

+ 14 - 14
instrumentation/lettuce/lettuce-5.0/javaagent/src/test/groovy/LettuceAsyncClientTest.groovy

@@ -237,11 +237,11 @@ class LettuceAsyncClientTest extends AgentInstrumentationSpecification {
     String successStr = "KEY MISSING"
     BiFunction<String, Throwable, String> firstStage = new BiFunction<String, Throwable, String>() {
       @Override
-      String apply(String res, Throwable throwable) {
+      String apply(String res, Throwable error) {
         runWithSpan("callback1") {
           conds.evaluate {
             assert res == null
-            assert throwable == null
+            assert error == null
           }
         }
         return (res == null ? successStr : res)
@@ -303,7 +303,7 @@ class LettuceAsyncClientTest extends AgentInstrumentationSpecification {
     def conds = new AsyncConditions()
     BiConsumer<String, Throwable> biConsumer = new BiConsumer<String, Throwable>() {
       @Override
-      void accept(String keyRetrieved, Throwable throwable) {
+      void accept(String keyRetrieved, Throwable error) {
         runWithSpan("callback") {
           conds.evaluate {
             assert keyRetrieved != null
@@ -361,9 +361,9 @@ class LettuceAsyncClientTest extends AgentInstrumentationSpecification {
         RedisFuture<Map<String, String>> hmGetAllFuture = asyncCommands.hgetall("TESTHM")
         hmGetAllFuture.exceptionally(new Function<Throwable, Map<String, String>>() {
           @Override
-          Map<String, String> apply(Throwable throwable) {
-            println("unexpected:" + throwable.toString())
-            throwable.printStackTrace()
+          Map<String, String> apply(Throwable error) {
+            println("unexpected:" + error.toString())
+            error.printStackTrace()
             assert false
             return null
           }
@@ -416,13 +416,13 @@ class LettuceAsyncClientTest extends AgentInstrumentationSpecification {
     RedisFuture redisFuture = asyncCommands.del("key1", "key2")
     boolean completedExceptionally = ((AsyncCommand) redisFuture).completeExceptionally(new IllegalStateException("TestException"))
     redisFuture.exceptionally({
-      throwable ->
+      error ->
         conds.evaluate {
-          assert throwable != null
-          assert throwable instanceof IllegalStateException
-          assert throwable.getMessage() == "TestException"
+          assert error != null
+          assert error instanceof IllegalStateException
+          assert error.getMessage() == "TestException"
         }
-        throw throwable
+        throw error
     })
 
     when:
@@ -459,11 +459,11 @@ class LettuceAsyncClientTest extends AgentInstrumentationSpecification {
       asyncCommands.sadd("SKEY", "1", "2")
     }
     redisFuture.whenCompleteAsync({
-      res, throwable ->
+      res, error ->
         runWithSpan("callback") {
           conds.evaluate {
-            assert throwable != null
-            assert throwable instanceof CancellationException
+            assert error != null
+            assert error instanceof CancellationException
           }
         }
     })

+ 4 - 4
instrumentation/mongo/mongo-4.0/javaagent/src/test/groovy/Mongo4ReactiveClientTest.groovy

@@ -16,7 +16,7 @@ import io.opentelemetry.instrumentation.test.AgentTestTrait
 import org.bson.BsonDocument
 import org.bson.BsonString
 import org.bson.Document
-import org.junit.AssumptionViolatedException
+import org.opentest4j.TestAbortedException
 import org.reactivestreams.Subscriber
 import org.reactivestreams.Subscription
 import spock.lang.Shared
@@ -52,7 +52,7 @@ class Mongo4ReactiveClientTest extends AbstractMongoClientTest<MongoCollection<D
 
   @Override
   void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) {
-    throw new AssumptionViolatedException("not tested on 4.0")
+    throw new TestAbortedException("not tested on 4.0")
   }
 
   @Override
@@ -157,12 +157,12 @@ class Mongo4ReactiveClientTest extends AbstractMongoClientTest<MongoCollection<D
 
   @Override
   MongoCollection<Document> setupGetMore(String dbName, String collectionName) {
-    throw new AssumptionViolatedException("not tested on reactive")
+    throw new TestAbortedException("not tested on reactive")
   }
 
   @Override
   void getMore(MongoCollection<Document> collection) {
-    throw new AssumptionViolatedException("not tested on reactive")
+    throw new TestAbortedException("not tested on reactive")
   }
 
   @Override

+ 2 - 2
instrumentation/mongo/mongo-4.0/javaagent/src/test/groovy/MongoClientTest.groovy

@@ -14,7 +14,7 @@ import io.opentelemetry.instrumentation.test.AgentTestTrait
 import org.bson.BsonDocument
 import org.bson.BsonString
 import org.bson.Document
-import org.junit.AssumptionViolatedException
+import org.opentest4j.TestAbortedException
 import spock.lang.Shared
 
 class MongoClientTest extends AbstractMongoClientTest<MongoCollection<Document>> implements AgentTestTrait {
@@ -45,7 +45,7 @@ class MongoClientTest extends AbstractMongoClientTest<MongoCollection<Document>>
 
   @Override
   void createCollectionWithAlreadyBuiltClientOptions(String dbName, String collectionName) {
-    throw new AssumptionViolatedException("not tested on 4.0")
+    throw new TestAbortedException("not tested on 4.0")
   }
 
   @Override

+ 3 - 3
instrumentation/mongo/mongo-async-3.3/javaagent/src/test/groovy/MongoAsyncClientTest.groovy

@@ -18,7 +18,7 @@ import io.opentelemetry.instrumentation.test.AgentTestTrait
 import org.bson.BsonDocument
 import org.bson.BsonString
 import org.bson.Document
-import org.junit.AssumptionViolatedException
+import org.opentest4j.TestAbortedException
 import spock.lang.Shared
 
 import java.util.concurrent.CompletableFuture
@@ -168,12 +168,12 @@ class MongoAsyncClientTest extends AbstractMongoClientTest<MongoCollection<Docum
 
   @Override
   MongoCollection<Document> setupGetMore(String dbName, String collectionName) {
-    throw new AssumptionViolatedException("not tested on async")
+    throw new TestAbortedException("not tested on async")
   }
 
   @Override
   void getMore(MongoCollection<Document> collection) {
-    throw new AssumptionViolatedException("not tested on async")
+    throw new TestAbortedException("not tested on async")
   }
 
   @Override

+ 1 - 1
instrumentation/netty/netty-4.1/javaagent/src/test/groovy/Netty41ClientTest.groovy

@@ -37,7 +37,7 @@ import spock.lang.Unroll
 import java.util.concurrent.CompletableFuture
 import java.util.concurrent.TimeUnit
 
-import static org.junit.Assume.assumeTrue
+import static org.junit.jupiter.api.Assumptions.assumeTrue
 
 @Unroll
 class Netty41ClientTest extends HttpClientTest<DefaultFullHttpRequest> implements AgentTestTrait {

+ 2 - 2
instrumentation/netty/netty-4.1/javaagent/src/test/groovy/Netty41NativeClientTest.groovy

@@ -11,7 +11,7 @@ import io.netty.channel.epoll.EpollSocketChannel
 import io.netty.channel.kqueue.KQueue
 import io.netty.channel.kqueue.KQueueEventLoopGroup
 import io.netty.channel.kqueue.KQueueSocketChannel
-import org.junit.Assume
+import org.junit.jupiter.api.Assumptions
 
 // netty client test with epoll/kqueue native library
 class Netty41NativeClientTest extends Netty41ClientTest {
@@ -27,7 +27,7 @@ class Netty41NativeClientTest extends Netty41ClientTest {
     }
 
     // skip test when native library was not found
-    Assume.assumeTrue("Native library was not found", false)
+    Assumptions.assumeTrue(false, "Native library was not found")
     return super.buildEventLoopGroup()
   }
 

+ 2 - 2
instrumentation/rabbitmq-2.7/javaagent/src/test/groovy/RabbitMqTest.groovy

@@ -221,13 +221,13 @@ class RabbitMqTest extends AgentInstrumentationSpecification implements WithRabb
     closure.call(channel)
 
     then:
-    def throwable = thrown(exception)
+    def error = thrown(exception)
 
     and:
 
     assertTraces(1) {
       trace(0, 1) {
-        rabbitSpan(it, null, null, operation, command, null, null, throwable, errorMsg)
+        rabbitSpan(it, null, null, operation, command, null, null, error, errorMsg)
       }
     }
 

+ 8 - 0
instrumentation/servlet/servlet-3.0/javaagent/src/test/groovy/AbstractServlet3MappingTest.groovy

@@ -19,6 +19,14 @@ import static io.opentelemetry.api.trace.StatusCode.ERROR
 
 abstract class AbstractServlet3MappingTest<SERVER, CONTEXT> extends AgentInstrumentationSpecification implements HttpServerTestTrait<SERVER> {
 
+  def setupSpec() {
+    setupServer()
+  }
+
+  def cleanupSpec() {
+    cleanupServer()
+  }
+
   abstract void addServlet(CONTEXT context, String path, Class<Servlet> servlet)
 
   protected void setupServlets(CONTEXT context) {

+ 1 - 1
instrumentation/servlet/servlet-3.0/javaagent/src/test/groovy/TomcatServlet3Test.groovy

@@ -35,7 +35,7 @@ import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEn
 import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.QUERY_PARAM
 import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.REDIRECT
 import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.SUCCESS
-import static org.junit.Assume.assumeTrue
+import static org.junit.jupiter.api.Assumptions.assumeTrue
 
 @Unroll
 abstract class TomcatServlet3Test extends AbstractServlet3Test<Tomcat, Context> {

+ 8 - 0
instrumentation/servlet/servlet-5.0/javaagent/src/test/groovy/AbstractServlet5MappingTest.groovy

@@ -18,6 +18,14 @@ import static io.opentelemetry.api.trace.StatusCode.ERROR
 
 abstract class AbstractServlet5MappingTest<SERVER, CONTEXT> extends AgentInstrumentationSpecification implements HttpServerTestTrait<SERVER> {
 
+  def setupSpec() {
+    setupServer()
+  }
+
+  def cleanupSpec() {
+    cleanupServer()
+  }
+
   abstract void addServlet(CONTEXT context, String path, Class<Servlet> servlet)
 
   protected void setupServlets(CONTEXT context) {

+ 1 - 1
instrumentation/servlet/servlet-5.0/javaagent/src/test/groovy/TomcatServlet5Test.groovy

@@ -35,7 +35,7 @@ import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEn
 import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.QUERY_PARAM
 import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.REDIRECT
 import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEndpoint.SUCCESS
-import static org.junit.Assume.assumeTrue
+import static org.junit.jupiter.api.Assumptions.assumeTrue
 
 @Unroll
 abstract class TomcatServlet5Test extends AbstractServlet5Test<Tomcat, Context> {

+ 3 - 4
instrumentation/spring/spring-webmvc-3.1/wildfly-testing/build.gradle.kts

@@ -13,10 +13,9 @@ dependencies {
   appLibrary("org.springframework:spring-webmvc:3.1.0.RELEASE")
   testImplementation("javax.servlet:javax.servlet-api:3.1.0")
 
-  val arquillianVersion = "1.4.0.Final"
-  testImplementation("org.jboss.arquillian.junit:arquillian-junit-container:$arquillianVersion")
-  testImplementation("org.jboss.arquillian.protocol:arquillian-protocol-servlet:$arquillianVersion")
-  testImplementation("org.jboss.arquillian.spock:arquillian-spock-container:1.0.0.CR1")
+  val arquillianVersion = "1.7.0.Alpha10"
+  implementation("org.jboss.arquillian.junit5:arquillian-junit5-container:$arquillianVersion")
+  implementation("org.jboss.arquillian.protocol:arquillian-protocol-servlet:$arquillianVersion")
   testImplementation("org.jboss.shrinkwrap:shrinkwrap-impl-base:1.2.6")
 
   testRuntimeOnly("org.wildfly.arquillian:wildfly-arquillian-container-embedded:2.2.0.Final")

+ 0 - 165
instrumentation/spring/spring-webmvc-3.1/wildfly-testing/src/test/groovy/OpenTelemetryHandlerMappingFilterTest.groovy

@@ -1,165 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-import com.example.hello.HelloController
-import com.example.hello.TestFilter
-import io.opentelemetry.api.trace.StatusCode
-import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
-import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
-import io.opentelemetry.testing.internal.armeria.client.WebClient
-import io.opentelemetry.testing.internal.armeria.common.AggregatedHttpResponse
-import org.jboss.arquillian.container.test.api.Deployment
-import org.jboss.arquillian.container.test.api.RunAsClient
-import org.jboss.arquillian.spock.ArquillianSputnik
-import org.jboss.arquillian.test.api.ArquillianResource
-import org.jboss.shrinkwrap.api.Archive
-import org.jboss.shrinkwrap.api.ShrinkWrap
-import org.jboss.shrinkwrap.api.spec.EnterpriseArchive
-import org.jboss.shrinkwrap.api.spec.WebArchive
-import org.junit.runner.RunWith
-
-import static io.opentelemetry.api.trace.SpanKind.INTERNAL
-import static io.opentelemetry.api.trace.SpanKind.SERVER
-
-@RunWith(ArquillianSputnik)
-@RunAsClient
-// Test that OpenTelemetryHandlerMappingFilter injection works when spring libraries are in various
-// locations inside deployment.
-abstract class OpenTelemetryHandlerMappingFilterTest extends AgentInstrumentationSpecification {
-
-  static WebClient client = WebClient.of()
-
-  @ArquillianResource
-  static URI url
-
-  def getAddress(String service) {
-    return url.resolve(service).toString()
-  }
-
-  def "test success"() {
-    when:
-    AggregatedHttpResponse response = client.get(getAddress("hello/world")).aggregate().join()
-
-    then:
-    response.status().code() == 200
-    response.contentUtf8() == "hello world"
-
-    and:
-    assertTraces(1) {
-      trace(0, 2) {
-        span(0) {
-          name "/hello/{name}"
-          kind SERVER
-          hasNoParent()
-        }
-        span(1) {
-          name "HelloController.hello"
-          kind INTERNAL
-          childOf(span(0))
-        }
-      }
-    }
-  }
-
-  def "test exception"() {
-    when:
-    AggregatedHttpResponse response = client.get(getAddress("hello/exception")).aggregate().join()
-
-    then:
-    response.status().code() == 500
-
-    and:
-    assertTraces(1) {
-      trace(0, 1) {
-        span(0) {
-          name "/hello/{name}"
-          kind SERVER
-          status StatusCode.ERROR
-          hasNoParent()
-
-          event(0) {
-            eventName(SemanticAttributes.EXCEPTION_EVENT_NAME)
-            attributes {
-              "${SemanticAttributes.EXCEPTION_TYPE.key}" "javax.servlet.ServletException"
-              "${SemanticAttributes.EXCEPTION_MESSAGE.key}" "exception"
-              "${SemanticAttributes.EXCEPTION_STACKTRACE.key}" { it == null || it instanceof String }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-
-// spring is inside ear/lib
-class LibsInEarTest extends OpenTelemetryHandlerMappingFilterTest {
-  @Deployment
-  static Archive<?> createDeployment() {
-    WebArchive war = ShrinkWrap.create(WebArchive, "test.war")
-      .addAsWebInfResource("web.xml")
-      .addAsWebInfResource("dispatcher-servlet.xml")
-      .addAsWebInfResource("applicationContext.xml")
-      .addClass(HelloController)
-      .addClass(TestFilter)
-
-    EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive)
-      .setApplicationXML("application.xml")
-      .addAsModule(war)
-      .addAsLibraries(new File("build/app-libs").listFiles())
-
-    return ear
-  }
-}
-
-// spring is inside war/WEB-INF/lib
-class LibsInWarTest extends OpenTelemetryHandlerMappingFilterTest {
-  @Deployment
-  static Archive<?> createDeployment() {
-    WebArchive war = ShrinkWrap.create(WebArchive, "test.war")
-      .addAsWebInfResource("web.xml")
-      .addAsWebInfResource("dispatcher-servlet.xml")
-      .addAsWebInfResource("applicationContext.xml")
-      .addClass(HelloController)
-      .addClass(TestFilter)
-      .addAsLibraries(new File("build/app-libs").listFiles())
-
-    EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive)
-      .setApplicationXML("application.xml")
-      .addAsModule(war)
-
-    return ear
-  }
-}
-
-// Everything except spring-webmvc is in ear/lib, spring-webmvc is in war/WEB-INF/lib
-class MixedLibsTest extends OpenTelemetryHandlerMappingFilterTest {
-  @Deployment
-  static Archive<?> createDeployment() {
-    WebArchive war = ShrinkWrap.create(WebArchive, "test.war")
-      .addAsWebInfResource("web.xml")
-      .addAsWebInfResource("dispatcher-servlet.xml")
-      .addAsWebInfResource("applicationContext.xml")
-      .addClass(HelloController)
-      .addClass(TestFilter)
-      .addAsLibraries(new File("build/app-libs").listFiles(new FilenameFilter() {
-        @Override
-        boolean accept(File dir, String name) {
-          return name.contains("spring-webmvc")
-        }
-      }))
-
-    EnterpriseArchive ear = ShrinkWrap.create(EnterpriseArchive)
-      .setApplicationXML("application.xml")
-      .addAsModule(war)
-      .addAsLibraries(new File("build/app-libs").listFiles(new FilenameFilter() {
-        @Override
-        boolean accept(File dir, String name) {
-          return !name.contains("spring-webmvc")
-        }
-      }))
-
-    return ear
-  }
-}

+ 72 - 0
instrumentation/spring/spring-webmvc-3.1/wildfly-testing/src/test/java/AbstractOpenTelemetryHandlerMappingFilterTest.java

@@ -0,0 +1,72 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
+
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
+import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
+import io.opentelemetry.sdk.trace.data.StatusData;
+import io.opentelemetry.testing.internal.armeria.client.WebClient;
+import io.opentelemetry.testing.internal.armeria.common.AggregatedHttpResponse;
+import java.net.URI;
+import javax.servlet.ServletException;
+import org.jboss.arquillian.container.test.api.RunAsClient;
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+@ExtendWith(ArquillianExtension.class)
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+@RunAsClient
+public abstract class AbstractOpenTelemetryHandlerMappingFilterTest {
+
+  @RegisterExtension
+  static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
+
+  public final WebClient client = WebClient.of();
+
+  @ArquillianResource public URI url;
+
+  private String getAddress(String service) {
+    return url.resolve(service).toString();
+  }
+
+  @Test
+  public void testSuccess() {
+    AggregatedHttpResponse response = client.get(getAddress("hello/world")).aggregate().join();
+
+    assertThat(response.status().code()).isEqualTo(200);
+    assertThat(response.contentUtf8()).isEqualTo("hello world");
+
+    testing.waitAndAssertTraces(
+        trace ->
+            trace.hasSpansSatisfyingExactly(
+                span -> span.hasName("/hello/{name}").hasKind(SpanKind.SERVER).hasNoParent(),
+                span ->
+                    span.hasName("HelloController.hello")
+                        .hasKind(SpanKind.INTERNAL)
+                        .hasParent(trace.getSpan(0))));
+  }
+
+  public void testException() {
+    AggregatedHttpResponse response = client.get(getAddress("hello/world")).aggregate().join();
+
+    assertThat(response.status().code()).isEqualTo(500);
+
+    testing.waitAndAssertTraces(
+        trace ->
+            trace.hasSpansSatisfyingExactly(
+                span ->
+                    span.hasName("/hello/{name}")
+                        .hasKind(SpanKind.SERVER)
+                        .hasStatus(StatusData.error())
+                        .hasNoParent()
+                        .hasException(new ServletException("exception"))));
+  }
+}

+ 36 - 0
instrumentation/spring/spring-webmvc-3.1/wildfly-testing/src/test/java/LibsInEarOpenTelemetryHandlerMappingFilterTest.java

@@ -0,0 +1,36 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import com.example.hello.HelloController;
+import com.example.hello.TestFilter;
+import java.io.File;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+
+// spring is inside ear/lib
+public class LibsInEarOpenTelemetryHandlerMappingFilterTest
+    extends AbstractOpenTelemetryHandlerMappingFilterTest {
+  @Deployment
+  static Archive<?> createDeployment() {
+    WebArchive war =
+        ShrinkWrap.create(WebArchive.class, "test.war")
+            .addAsWebInfResource("web.xml")
+            .addAsWebInfResource("dispatcher-servlet.xml")
+            .addAsWebInfResource("applicationContext.xml")
+            .addClass(HelloController.class)
+            .addClass(TestFilter.class);
+
+    EnterpriseArchive ear =
+        ShrinkWrap.create(EnterpriseArchive.class)
+            .setApplicationXML("application.xml")
+            .addAsModule(war)
+            .addAsLibraries(new File("build/app-libs").listFiles());
+
+    return ear;
+  }
+}

+ 36 - 0
instrumentation/spring/spring-webmvc-3.1/wildfly-testing/src/test/java/LibsInWarOpenTelemetryHandlerMappingFilterTest.java

@@ -0,0 +1,36 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import com.example.hello.HelloController;
+import com.example.hello.TestFilter;
+import java.io.File;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+
+// spring is inside war/WEB-INF/lib
+public class LibsInWarOpenTelemetryHandlerMappingFilterTest
+    extends AbstractOpenTelemetryHandlerMappingFilterTest {
+  @Deployment
+  static Archive<?> createDeployment() {
+    WebArchive war =
+        ShrinkWrap.create(WebArchive.class, "test.war")
+            .addAsWebInfResource("web.xml")
+            .addAsWebInfResource("dispatcher-servlet.xml")
+            .addAsWebInfResource("applicationContext.xml")
+            .addClass(HelloController.class)
+            .addClass(TestFilter.class)
+            .addAsLibraries(new File("build/app-libs").listFiles());
+
+    EnterpriseArchive ear =
+        ShrinkWrap.create(EnterpriseArchive.class)
+            .setApplicationXML("application.xml")
+            .addAsModule(war);
+
+    return ear;
+  }
+}

+ 41 - 0
instrumentation/spring/spring-webmvc-3.1/wildfly-testing/src/test/java/MixedLibsOpenTelemetryHandlerMappingFilterTest.java

@@ -0,0 +1,41 @@
+/*
+ * Copyright The OpenTelemetry Authors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import com.example.hello.HelloController;
+import com.example.hello.TestFilter;
+import java.io.File;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.EnterpriseArchive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+
+// Everything except spring-webmvc is in ear/lib, spring-webmvc is in war/WEB-INF/lib
+public class MixedLibsOpenTelemetryHandlerMappingFilterTest
+    extends AbstractOpenTelemetryHandlerMappingFilterTest {
+  @Deployment
+  static Archive<?> createDeployment() {
+    WebArchive war =
+        ShrinkWrap.create(WebArchive.class, "test.war")
+            .addAsWebInfResource("web.xml")
+            .addAsWebInfResource("dispatcher-servlet.xml")
+            .addAsWebInfResource("applicationContext.xml")
+            .addClass(HelloController.class)
+            .addClass(TestFilter.class)
+            .addAsLibraries(
+                new File("build/app-libs")
+                    .listFiles((dir, name) -> name.contains("spring-webmvc")));
+
+    EnterpriseArchive ear =
+        ShrinkWrap.create(EnterpriseArchive.class)
+            .setApplicationXML("application.xml")
+            .addAsModule(war)
+            .addAsLibraries(
+                new File("build/app-libs")
+                    .listFiles((dir, name) -> !name.contains("spring-webmvc")));
+
+    return ear;
+  }
+}

+ 6 - 0
instrumentation/spring/spring-ws-2.0/javaagent/src/test/groovy/test/boot/SpringWsTest.groovy

@@ -35,10 +35,16 @@ class SpringWsTest extends AgentInstrumentationSpecification implements HttpServ
   private Jaxb2Marshaller marshaller = new Jaxb2Marshaller()
 
   def setupSpec() {
+    setupServer()
+
     marshaller.setPackagesToScan(ClassUtils.getPackageName(HelloRequest))
     marshaller.afterPropertiesSet()
   }
 
+  def cleanupSpec() {
+    cleanupServer()
+  }
+
   @Override
   ConfigurableApplicationContext startServer(int port) {
     def app = new SpringApplication(AppConfig, WebServiceConfig)

+ 8 - 0
instrumentation/tapestry-5.4/javaagent/src/test/groovy/TapestryTest.groovy

@@ -24,6 +24,14 @@ import static io.opentelemetry.api.trace.StatusCode.ERROR
 
 class TapestryTest extends AgentInstrumentationSpecification implements HttpServerTestTrait<Server> {
 
+  def setupSpec() {
+    setupServer()
+  }
+
+  def cleanupSpec() {
+    cleanupServer()
+  }
+
   @Override
   Server startServer(int port) {
     WebAppContext webAppContext = new WebAppContext()

+ 4 - 0
instrumentation/vaadin-14.2/testing/src/main/groovy/test/vaadin/AbstractVaadinTest.groovy

@@ -11,6 +11,7 @@ import io.opentelemetry.api.trace.SpanKind
 import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
 import io.opentelemetry.instrumentation.test.asserts.TraceAssert
 import io.opentelemetry.instrumentation.test.base.HttpServerTestTrait
+
 import org.openqa.selenium.chrome.ChromeOptions
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
@@ -45,6 +46,8 @@ abstract class AbstractVaadinTest extends AgentInstrumentationSpecification impl
   }
 
   def setupSpec() {
+    setupServer()
+
     Testcontainers.exposeHostPorts(port)
 
     browser = new BrowserWebDriverContainer<>()
@@ -56,6 +59,7 @@ abstract class AbstractVaadinTest extends AgentInstrumentationSpecification impl
   }
 
   def cleanupSpec() {
+    cleanupServer()
     browser?.stop()
   }
 

+ 8 - 0
instrumentation/wicket-8.0/javaagent/src/test/groovy/WicketTest.groovy

@@ -20,6 +20,14 @@ import javax.servlet.DispatcherType
 
 class WicketTest extends AgentInstrumentationSpecification implements HttpServerTestTrait<Server> {
 
+  def setupSpec() {
+    setupServer()
+  }
+
+  def cleanupSpec() {
+    cleanupServer()
+  }
+
   @Override
   Server startServer(int port) {
     def server = new Server(port)

+ 3 - 4
javaagent-tooling/src/test/groovy/io/opentelemetry/javaagent/tooling/config/ConfigInitializerTest.groovy

@@ -5,15 +5,14 @@
 
 package io.opentelemetry.javaagent.tooling.config
 
-
 import org.junit.Rule
 import org.junit.contrib.java.lang.system.EnvironmentVariables
-import org.junit.contrib.java.lang.system.RestoreSystemProperties
 import spock.lang.Specification
+import spock.util.environment.RestoreSystemProperties
 
+@RestoreSystemProperties
 class ConfigInitializerTest extends Specification {
-  @Rule
-  public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties()
+
   @Rule
   public final EnvironmentVariables environmentVariables = new EnvironmentVariables()
 

+ 9 - 7
javaagent-tooling/src/test/groovy/io/opentelemetry/javaagent/tooling/config/ConfigurationFileTest.groovy

@@ -7,18 +7,20 @@ package io.opentelemetry.javaagent.tooling.config
 
 import org.junit.Rule
 import org.junit.contrib.java.lang.system.EnvironmentVariables
-import org.junit.contrib.java.lang.system.RestoreSystemProperties
-import org.junit.rules.TemporaryFolder
+import spock.lang.Shared
 import spock.lang.Specification
+import spock.lang.TempDir
+import spock.util.environment.RestoreSystemProperties
 
+@RestoreSystemProperties
 class ConfigurationFileTest extends Specification {
 
-  @Rule
-  public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties()
   @Rule
   public final EnvironmentVariables environmentVariables = new EnvironmentVariables()
-  @Rule
-  public final TemporaryFolder tmpFolder = new TemporaryFolder()
+
+  @TempDir
+  @Shared
+  public File tmpDir
 
   def "should use env property"() {
     given:
@@ -80,7 +82,7 @@ class ConfigurationFileTest extends Specification {
   }
 
   def createFile(String name, String contents) {
-    def file = tmpFolder.newFile(name)
+    def file = new File(tmpDir, name)
     file.write(contents)
     return file.getAbsolutePath()
   }

+ 1 - 1
muzzle/src/test/groovy/io/opentelemetry/javaagent/tooling/muzzle/ReferenceMatcherTest.groovy

@@ -96,7 +96,7 @@ class ReferenceMatcherTest extends Specification {
     cl.count == countAfterFirstMatch
   }
 
-  def "matching ref #referenceName #referenceFlags against #classToCheck produces #expectedMismatches"() {
+  def "matching ref #referenceName #referenceFlag against #classToCheck produces #expectedMismatches"() {
     setup:
     def ref = ClassRef.newBuilder(referenceName)
       .addFlag(referenceFlag)

+ 6 - 6
smoke-tests/build.gradle.kts

@@ -56,12 +56,12 @@ tasks {
     enabled = enabled && gradle.startParameter.taskNames.any { it.startsWith(":smoke-tests:") }
 
     val suites = mapOf(
-      "glassfish" to listOf("**/GlassFishSmokeTest.*"),
-      "jetty" to listOf("**/JettySmokeTest.*"),
-      "liberty" to listOf("**/LibertySmokeTest.*", "**/LibertyServletOnlySmokeTest.*"),
-      "tomcat" to listOf("**/TomcatSmokeTest.*"),
-      "tomee" to listOf("**/TomeeSmokeTest.*"),
-      "wildfly" to listOf("**/WildflySmokeTest.*")
+      "glassfish" to listOf("**/GlassFish*.*"),
+      "jetty" to listOf("**/Jetty*.*"),
+      "liberty" to listOf("**/Liberty*.*"),
+      "tomcat" to listOf("**/Tomcat*.*"),
+      "tomee" to listOf("**/Tomee*.*"),
+      "wildfly" to listOf("**/Wildfly*.*")
     )
 
     val smokeTestSuite: String? by project

+ 6 - 1
smoke-tests/images/servlet/build.gradle

@@ -69,17 +69,22 @@ def targets = [
 ]
 
 tasks.register("printSmokeTestsConfigurations") {
-  linuxTargets.each { server, matrices ->
+  targets.each { server, matrices ->
     def smokeTestServer = findProperty('smokeTestServer')
     if (smokeTestServer != null && server != smokeTestServer) {
       return
     }
     println server
+    def serverName = String.valueOf(Character.toUpperCase(server.charAt(0))) + server.substring(1)
     matrices.forEach { entry ->
       entry.version.forEach { version ->
+        def dotIndex = version.indexOf('.')
+        def majorVersion = dotIndex != -1 ? version.substring(0, dotIndex) : version
         entry.jdk.forEach { jdk ->
           entry.vm.forEach { vm ->
             println "@AppServer(version = \"$version\", jdk = \"$jdk${vm == 'hotspot' ? '' : '-openj9'}\")"
+            println "class ${serverName}${majorVersion}Jdk${jdk}${vm == 'hotspot' ? '' : 'Openj9'} extends ${serverName}SmokeTest {"
+            println "}"
           }
         }
       }

+ 9 - 6
smoke-tests/src/test/groovy/io/opentelemetry/smoketest/AppServerTest.groovy

@@ -6,7 +6,6 @@
 package io.opentelemetry.smoketest
 
 import io.opentelemetry.proto.trace.v1.Span
-import org.junit.runner.RunWith
 import spock.lang.Shared
 import spock.lang.Unroll
 
@@ -18,7 +17,6 @@ import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.Os
 import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.OsTypeValues.WINDOWS
 import static org.junit.Assume.assumeTrue
 
-@RunWith(AppServerTestRunner)
 abstract class AppServerTest extends SmokeTest {
   @Shared
   String jdk
@@ -28,15 +26,20 @@ abstract class AppServerTest extends SmokeTest {
   boolean isWindows
 
   def setupSpec() {
-    def appServer = AppServerTestRunner.currentAppServer(this.getClass())
-    serverVersion = appServer.version()
-    jdk = appServer.jdk()
-
+    (serverVersion, jdk) = getAppServer()
     isWindows = System.getProperty("os.name").toLowerCase().contains("windows") &&
       "1" != System.getenv("USE_LINUX_CONTAINERS")
     startTarget(jdk, serverVersion, isWindows)
   }
 
+  protected Tuple<String> getAppServer() {
+    def appServer = getClass().getAnnotation(AppServer)
+    if (appServer == null) {
+      throw new IllegalStateException("Server not specified, either add @AppServer annotation or override getAppServer method")
+    }
+    return new Tuple(appServer.version(), appServer.jdk())
+  }
+
   @Override
   protected String getTargetImage(String jdk) {
     throw new UnsupportedOperationException("App servers tests should use getTargetImagePrefix")

+ 14 - 5
smoke-tests/src/test/groovy/io/opentelemetry/smoketest/GlassFishSmokeTest.groovy

@@ -7,11 +7,7 @@ package io.opentelemetry.smoketest
 
 import java.time.Duration
 
-@AppServer(version = "5.2020.6", jdk = "8")
-@AppServer(version = "5.2020.6", jdk = "8-openj9")
-@AppServer(version = "5.2020.6", jdk = "11")
-@AppServer(version = "5.2020.6", jdk = "11-openj9")
-class GlassFishSmokeTest extends AppServerTest {
+abstract class GlassFishSmokeTest extends AppServerTest {
 
   protected String getTargetImagePrefix() {
     "ghcr.io/open-telemetry/opentelemetry-java-instrumentation/smoke-test-servlet-payara"
@@ -46,3 +42,16 @@ class GlassFishSmokeTest extends AppServerTest {
     false
   }
 }
+
+@AppServer(version = "5.2020.6", jdk = "8")
+class GlassFish5Jdk8 extends GlassFishSmokeTest {
+}
+@AppServer(version = "5.2020.6", jdk = "8-openj9")
+class GlassFish5Jdk8Openj9 extends GlassFishSmokeTest {
+}
+@AppServer(version = "5.2020.6", jdk = "11")
+class GlassFish5Jdk11 extends GlassFishSmokeTest {
+}
+@AppServer(version = "5.2020.6", jdk = "11-openj9")
+class GlassFish5Jdk11Openj9 extends GlassFishSmokeTest {
+}

+ 39 - 10
smoke-tests/src/test/groovy/io/opentelemetry/smoketest/JettySmokeTest.groovy

@@ -5,23 +5,52 @@
 
 package io.opentelemetry.smoketest
 
+abstract class JettySmokeTest extends AppServerTest {
+
+  protected String getTargetImagePrefix() {
+    "ghcr.io/open-telemetry/opentelemetry-java-instrumentation/smoke-test-servlet-jetty"
+  }
+}
+
 @AppServer(version = "9.4.39", jdk = "8")
-@AppServer(version = "9.4.39", jdk = "8-openj9")
+class Jetty9Jdk8 extends JettySmokeTest {
+}
 @AppServer(version = "9.4.39", jdk = "11")
-@AppServer(version = "9.4.39", jdk = "11-openj9")
+class Jetty9Jdk11 extends JettySmokeTest {
+}
 @AppServer(version = "9.4.39", jdk = "17")
+class Jetty9Jdk17 extends JettySmokeTest {
+}
+@AppServer(version = "9.4.39", jdk = "8-openj9")
+class Jetty9Jdk8Openj9 extends JettySmokeTest {
+}
+@AppServer(version = "9.4.39", jdk = "11-openj9")
+class Jetty9Jdk11Openj9 extends JettySmokeTest {
+}
 @AppServer(version = "9.4.39", jdk = "16-openj9")
+class Jetty9Jdk16Openj9 extends JettySmokeTest {
+}
 @AppServer(version = "10.0.7", jdk = "11")
-@AppServer(version = "10.0.7", jdk = "11-openj9")
+class Jetty10Jdk11 extends JettySmokeTest {
+}
 @AppServer(version = "10.0.7", jdk = "17")
+class Jetty10Jdk17 extends JettySmokeTest {
+}
+@AppServer(version = "10.0.7", jdk = "11-openj9")
+class Jetty10Jdk11Openj9 extends JettySmokeTest {
+}
 @AppServer(version = "10.0.7", jdk = "16-openj9")
+class Jetty10Jdk16Openj9 extends JettySmokeTest {
+}
 @AppServer(version = "11.0.7", jdk = "11")
-@AppServer(version = "11.0.7", jdk = "11-openj9")
+class Jetty11Jdk11 extends JettySmokeTest {
+}
 @AppServer(version = "11.0.7", jdk = "17")
-@AppServer(version = "11.0.7", jdk = "16-openj9")
-class JettySmokeTest extends AppServerTest {
-
-  protected String getTargetImagePrefix() {
-    "ghcr.io/open-telemetry/opentelemetry-java-instrumentation/smoke-test-servlet-jetty"
-  }
+class Jetty11Jdk17 extends JettySmokeTest {
+}
+@AppServer(version = "11.0.7", jdk = "11-openj9")
+class Jetty11Jdk11Openj9 extends JettySmokeTest {
 }
+@AppServer(version = "11.0.7", jdk = "16-openj9")
+class Jetty11Jdk16Openj9 extends JettySmokeTest {
+}

+ 20 - 7
smoke-tests/src/test/groovy/io/opentelemetry/smoketest/LibertySmokeTest.groovy

@@ -7,13 +7,7 @@ package io.opentelemetry.smoketest
 
 import java.time.Duration
 
-@AppServer(version = "20.0.0.12", jdk = "8")
-@AppServer(version = "20.0.0.12", jdk = "8-openj9")
-@AppServer(version = "20.0.0.12", jdk = "11")
-@AppServer(version = "20.0.0.12", jdk = "11-openj9")
-@AppServer(version = "20.0.0.12", jdk = "16")
-@AppServer(version = "20.0.0.12", jdk = "16-openj9")
-class LibertySmokeTest extends AppServerTest {
+abstract class LibertySmokeTest extends AppServerTest {
 
   protected String getTargetImagePrefix() {
     "ghcr.io/open-telemetry/opentelemetry-java-instrumentation/smoke-test-servlet-liberty"
@@ -24,3 +18,22 @@ class LibertySmokeTest extends AppServerTest {
     return new TargetWaitStrategy.Log(Duration.ofMinutes(3), ".*server is ready to run a smarter planet.*")
   }
 }
+
+@AppServer(version = "20.0.0.12", jdk = "8")
+class Liberty20Jdk8 extends LibertySmokeTest {
+}
+@AppServer(version = "20.0.0.12", jdk = "8-openj9")
+class Liberty20Jdk8Openj9 extends LibertySmokeTest {
+}
+@AppServer(version = "20.0.0.12", jdk = "11")
+class Liberty20Jdk11 extends LibertySmokeTest {
+}
+@AppServer(version = "20.0.0.12", jdk = "11-openj9")
+class Liberty20Jdk11Openj9 extends LibertySmokeTest {
+}
+@AppServer(version = "20.0.0.12", jdk = "16")
+class Liberty20Jdk16 extends LibertySmokeTest {
+}
+@AppServer(version = "20.0.0.12", jdk = "16-openj9")
+class Liberty20Jdk16Openj9 extends LibertySmokeTest {
+}

+ 46 - 11
smoke-tests/src/test/groovy/io/opentelemetry/smoketest/TomcatSmokeTest.groovy

@@ -5,26 +5,61 @@
 
 package io.opentelemetry.smoketest
 
+abstract class TomcatSmokeTest extends AppServerTest {
+
+  protected String getTargetImagePrefix() {
+    "ghcr.io/open-telemetry/opentelemetry-java-instrumentation/smoke-test-servlet-tomcat"
+  }
+}
+
 @AppServer(version = "7.0.109", jdk = "8")
+class Tomcat7Jdk8 extends TomcatSmokeTest {
+}
 @AppServer(version = "7.0.109", jdk = "8-openj9")
+class Tomcat7Jdk8Openj9 extends TomcatSmokeTest {
+}
 @AppServer(version = "8.5.71", jdk = "8")
-@AppServer(version = "8.5.71", jdk = "8-openj9")
+class Tomcat8Jdk8 extends TomcatSmokeTest {
+}
 @AppServer(version = "8.5.71", jdk = "11")
-@AppServer(version = "8.5.71", jdk = "11-openj9")
+class Tomcat8Jdk11 extends TomcatSmokeTest {
+}
 @AppServer(version = "8.5.71", jdk = "17")
+class Tomcat8Jdk17 extends TomcatSmokeTest {
+}
+@AppServer(version = "8.5.71", jdk = "8-openj9")
+class Tomcat8Jdk8Openj9 extends TomcatSmokeTest {
+}
+@AppServer(version = "8.5.71", jdk = "11-openj9")
+class Tomcat8Jdk11Openj9 extends TomcatSmokeTest {
+}
 @AppServer(version = "9.0.53", jdk = "8")
-@AppServer(version = "9.0.53", jdk = "8-openj9")
+class Tomcat9Jdk8 extends TomcatSmokeTest {
+}
 @AppServer(version = "9.0.53", jdk = "11")
-@AppServer(version = "9.0.53", jdk = "11-openj9")
+class Tomcat9Jdk11 extends TomcatSmokeTest {
+}
 @AppServer(version = "9.0.53", jdk = "17")
+class Tomcat9Jdk17 extends TomcatSmokeTest {
+}
+@AppServer(version = "9.0.53", jdk = "8-openj9")
+class Tomcat9Jdk8Openj9 extends TomcatSmokeTest {
+}
+@AppServer(version = "9.0.53", jdk = "11-openj9")
+class Tomcat9Jdk11Openj9 extends TomcatSmokeTest {
+}
 @AppServer(version = "10.0.11", jdk = "8")
-@AppServer(version = "10.0.11", jdk = "8-openj9")
+class Tomcat10Jdk8 extends TomcatSmokeTest {
+}
 @AppServer(version = "10.0.11", jdk = "11")
-@AppServer(version = "10.0.11", jdk = "11-openj9")
+class Tomcat10Jdk11 extends TomcatSmokeTest {
+}
 @AppServer(version = "10.0.11", jdk = "17")
-class TomcatSmokeTest extends AppServerTest {
-
-  protected String getTargetImagePrefix() {
-    "ghcr.io/open-telemetry/opentelemetry-java-instrumentation/smoke-test-servlet-tomcat"
-  }
+class Tomcat10Jdk17 extends TomcatSmokeTest {
+}
+@AppServer(version = "10.0.11", jdk = "8-openj9")
+class Tomcat10Jdk8Openj9 extends TomcatSmokeTest {
 }
+@AppServer(version = "10.0.11", jdk = "11-openj9")
+class Tomcat10Jdk11Openj9 extends TomcatSmokeTest {
+}

+ 50 - 17
smoke-tests/src/test/groovy/io/opentelemetry/smoketest/TomeeSmokeTest.groovy

@@ -7,23 +7,7 @@ package io.opentelemetry.smoketest
 
 import java.time.Duration
 
-@AppServer(version = "7.0.9", jdk = "8")
-@AppServer(version = "7.0.9", jdk = "8-openj9")
-@AppServer(version = "7.1.4", jdk = "8")
-@AppServer(version = "7.1.4", jdk = "8-openj9")
-@AppServer(version = "8.0.8", jdk = "8")
-@AppServer(version = "8.0.8", jdk = "8-openj9")
-@AppServer(version = "8.0.8", jdk = "11")
-@AppServer(version = "8.0.8", jdk = "11-openj9")
-@AppServer(version = "8.0.8", jdk = "17")
-@AppServer(version = "8.0.8", jdk = "16-openj9")
-@AppServer(version = "9.0.0-M7", jdk = "8")
-@AppServer(version = "9.0.0-M7", jdk = "8-openj9")
-@AppServer(version = "9.0.0-M7", jdk = "11")
-@AppServer(version = "9.0.0-M7", jdk = "11-openj9")
-@AppServer(version = "9.0.0-M7", jdk = "17")
-@AppServer(version = "9.0.0-M7", jdk = "16-openj9")
-class TomeeSmokeTest extends AppServerTest {
+abstract class TomeeSmokeTest extends AppServerTest {
 
   protected String getTargetImagePrefix() {
     "ghcr.io/open-telemetry/opentelemetry-java-instrumentation/smoke-test-servlet-tomee"
@@ -43,3 +27,52 @@ class TomeeSmokeTest extends AppServerTest {
     return super.getSpanName(path)
   }
 }
+
+@AppServer(version = "7.0.9", jdk = "8")
+class Tomee70Jdk8 extends TomeeSmokeTest {
+}
+@AppServer(version = "7.0.9", jdk = "8-openj9")
+class Tomee70Jdk8Openj9 extends TomeeSmokeTest {
+}
+@AppServer(version = "7.1.4", jdk = "8")
+class Tomee71Jdk8 extends TomeeSmokeTest {
+}
+@AppServer(version = "7.1.4", jdk = "8-openj9")
+class Tomee71Jdk8Openj9 extends TomeeSmokeTest {
+}
+@AppServer(version = "8.0.8", jdk = "8")
+class Tomee8Jdk8 extends TomeeSmokeTest {
+}
+@AppServer(version = "8.0.8", jdk = "11")
+class Tomee8Jdk11 extends TomeeSmokeTest {
+}
+@AppServer(version = "8.0.8", jdk = "17")
+class Tomee8Jdk17 extends TomeeSmokeTest {
+}
+@AppServer(version = "8.0.8", jdk = "8-openj9")
+class Tomee8Jdk8Openj9 extends TomeeSmokeTest {
+}
+@AppServer(version = "8.0.8", jdk = "11-openj9")
+class Tomee8Jdk11Openj9 extends TomeeSmokeTest {
+}
+@AppServer(version = "8.0.8", jdk = "16-openj9")
+class Tomee8Jdk16Openj9 extends TomeeSmokeTest {
+}
+@AppServer(version = "9.0.0-M7", jdk = "8")
+class Tomee9Jdk8 extends TomeeSmokeTest {
+}
+@AppServer(version = "9.0.0-M7", jdk = "11")
+class Tomee9Jdk11 extends TomeeSmokeTest {
+}
+@AppServer(version = "9.0.0-M7", jdk = "17")
+class Tomee9Jdk17 extends TomeeSmokeTest {
+}
+@AppServer(version = "9.0.0-M7", jdk = "8-openj9")
+class Tomee9Jdk8Openj9 extends TomeeSmokeTest {
+}
+@AppServer(version = "9.0.0-M7", jdk = "11-openj9")
+class Tomee9Jdk11Openj9 extends TomeeSmokeTest {
+}
+@AppServer(version = "9.0.0-M7", jdk = "16-openj9")
+class Tomee9Jdk16Openj9 extends TomeeSmokeTest {
+}

+ 44 - 15
smoke-tests/src/test/groovy/io/opentelemetry/smoketest/WildflySmokeTest.groovy

@@ -8,21 +8,7 @@ package io.opentelemetry.smoketest
 import io.opentelemetry.proto.trace.v1.Span
 import spock.lang.Unroll
 
-@AppServer(version = "13.0.0.Final", jdk = "8")
-@AppServer(version = "13.0.0.Final", jdk = "8-openj9")
-@AppServer(version = "17.0.1.Final", jdk = "8")
-@AppServer(version = "17.0.1.Final", jdk = "8-openj9")
-@AppServer(version = "17.0.1.Final", jdk = "11")
-@AppServer(version = "17.0.1.Final", jdk = "11-openj9")
-@AppServer(version = "17.0.1.Final", jdk = "17")
-@AppServer(version = "17.0.1.Final", jdk = "16-openj9")
-@AppServer(version = "21.0.0.Final", jdk = "8")
-@AppServer(version = "21.0.0.Final", jdk = "8-openj9")
-@AppServer(version = "21.0.0.Final", jdk = "11")
-@AppServer(version = "21.0.0.Final", jdk = "11-openj9")
-@AppServer(version = "21.0.0.Final", jdk = "17")
-@AppServer(version = "21.0.0.Final", jdk = "16-openj9")
-class WildflySmokeTest extends AppServerTest {
+abstract class WildflySmokeTest extends AppServerTest {
 
   protected String getTargetImagePrefix() {
     "ghcr.io/open-telemetry/opentelemetry-java-instrumentation/smoke-test-servlet-wildfly"
@@ -47,3 +33,46 @@ class WildflySmokeTest extends AppServerTest {
     [appServer, jdk] << getTestParams()
   }
 }
+
+@AppServer(version = "13.0.0.Final", jdk = "8")
+class Wildfly13Jdk8 extends WildflySmokeTest {
+}
+@AppServer(version = "13.0.0.Final", jdk = "8-openj9")
+class Wildfly13Jdk8Openj9 extends WildflySmokeTest {
+}
+@AppServer(version = "17.0.1.Final", jdk = "8")
+class Wildfly17Jdk8 extends WildflySmokeTest {
+}
+@AppServer(version = "17.0.1.Final", jdk = "11")
+class Wildfly17Jdk11 extends WildflySmokeTest {
+}
+@AppServer(version = "17.0.1.Final", jdk = "17")
+class Wildfly17Jdk17 extends WildflySmokeTest {
+}
+@AppServer(version = "21.0.0.Final", jdk = "8")
+class Wildfly21Jdk8 extends WildflySmokeTest {
+}
+@AppServer(version = "21.0.0.Final", jdk = "11")
+class Wildfly21Jdk11 extends WildflySmokeTest {
+}
+@AppServer(version = "21.0.0.Final", jdk = "17")
+class Wildfly21Jdk17 extends WildflySmokeTest {
+}
+@AppServer(version = "17.0.1.Final", jdk = "8-openj9")
+class Wildfly17Jdk8Openj9 extends WildflySmokeTest {
+}
+@AppServer(version = "17.0.1.Final", jdk = "11-openj9")
+class Wildfly17Jdk11Openj9 extends WildflySmokeTest {
+}
+@AppServer(version = "17.0.1.Final", jdk = "16-openj9")
+class Wildfly17Jdk16Openj9 extends WildflySmokeTest {
+}
+@AppServer(version = "21.0.0.Final", jdk = "8-openj9")
+class Wildfly21Jdk8Openj9 extends WildflySmokeTest {
+}
+@AppServer(version = "21.0.0.Final", jdk = "11-openj9")
+class Wildfly21Jdk11Openj9 extends WildflySmokeTest {
+}
+@AppServer(version = "21.0.0.Final", jdk = "16-openj9")
+class Wildfly21Jdk16Openj9 extends WildflySmokeTest {
+}

+ 0 - 2
smoke-tests/src/test/java/io/opentelemetry/smoketest/AppServer.java

@@ -7,14 +7,12 @@ package io.opentelemetry.smoketest;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Inherited;
-import java.lang.annotation.Repeatable;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
-@Repeatable(AppServers.class)
 @Inherited
 public @interface AppServer {
   String version();

+ 0 - 59
smoke-tests/src/test/java/io/opentelemetry/smoketest/AppServerTestRunner.java

@@ -1,59 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.smoketest;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import org.junit.runner.notification.RunNotifier;
-import org.junit.runners.model.InitializationError;
-import org.spockframework.runtime.Sputnik;
-
-/**
- * Customized spock test runner that runs tests on multiple app server versions based on {@link
- * AppServer} annotations. This runner selects first server based on {@link AppServer} annotation
- * calls setupSpec, all test method and cleanupSpec, selects next {@link AppServer} and calls the
- * same methods. This process is repeated until tests have run for all {@link AppServer}
- * annotations. Tests should start server in setupSpec and stop it in cleanupSpec.
- */
-public class AppServerTestRunner extends Sputnik {
-  private static final Map<Class<?>, AppServer> runningAppServer =
-      Collections.synchronizedMap(new HashMap<>());
-  private final Class<?> testClass;
-  private final AppServer[] appServers;
-
-  public AppServerTestRunner(Class<?> clazz) throws InitializationError {
-    super(clazz);
-    testClass = clazz;
-    appServers = clazz.getAnnotationsByType(AppServer.class);
-    if (appServers.length == 0) {
-      throw new IllegalStateException("Add AppServer or AppServers annotation to test class");
-    }
-  }
-
-  @Override
-  public void run(RunNotifier notifier) {
-    // run tests for all app servers
-    try {
-      for (AppServer appServer : appServers) {
-        runningAppServer.put(testClass, appServer);
-        super.run(notifier);
-      }
-    } finally {
-      runningAppServer.remove(testClass);
-    }
-  }
-
-  // expose currently running app server
-  // used to get current server and jvm version inside the test class
-  public static AppServer currentAppServer(Class<?> testClass) {
-    AppServer appServer = runningAppServer.get(testClass);
-    if (appServer == null) {
-      throw new IllegalStateException("Test not running for " + testClass);
-    }
-    return appServer;
-  }
-}

+ 0 - 19
smoke-tests/src/test/java/io/opentelemetry/smoketest/AppServers.java

@@ -1,19 +0,0 @@
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.smoketest;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-@Inherited
-public @interface AppServers {
-  AppServer[] value();
-}

+ 14 - 1
testing-common/build.gradle.kts

@@ -15,7 +15,20 @@ sourceSets {
 
 dependencies {
   api("org.codehaus.groovy:groovy-all")
-  api("org.spockframework:spock-core")
+  api("org.spockframework:spock-core") {
+    // exclude optional dependencies
+    exclude(group = "cglib", module = "cglib-nodep")
+    exclude(group = "net.bytebuddy", module = "byte-buddy")
+    exclude(group = "org.junit.platform", module = "junit-platform-testkit")
+    exclude(group = "org.jetbrains", module = "annotations")
+    exclude(group = "org.objenesis", module = "objenesis")
+    exclude(group = "org.ow2.asm", module = "asm")
+  }
+  api("org.spockframework:spock-junit4") {
+    // spock-core is already added as dependency
+    // exclude it here to avoid pulling in optional dependencies
+    exclude(group = "org.spockframework", module = "spock-core")
+  }
   api("org.junit.jupiter:junit-jupiter-api")
   api("org.junit.jupiter:junit-jupiter-params")
 

+ 2 - 2
testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpClientTest.groovy

@@ -5,6 +5,8 @@
 
 package io.opentelemetry.instrumentation.test.base
 
+import static org.junit.jupiter.api.Assumptions.assumeTrue
+
 import io.opentelemetry.api.common.AttributeKey
 import io.opentelemetry.api.trace.SpanId
 import io.opentelemetry.instrumentation.test.InstrumentationSpecification
@@ -19,8 +21,6 @@ import spock.lang.Requires
 import spock.lang.Shared
 import spock.lang.Unroll
 
-import static org.junit.Assume.assumeTrue
-
 @Unroll
 abstract class HttpClientTest<REQUEST> extends InstrumentationSpecification {
   protected static final BODY_METHODS = ["POST", "PUT"]

+ 9 - 1
testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpServerTest.groovy

@@ -38,7 +38,7 @@ import static io.opentelemetry.instrumentation.test.base.HttpServerTest.ServerEn
 import static io.opentelemetry.instrumentation.test.utils.TraceUtils.runUnderTrace
 import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.NetTransportValues.IP_TCP
 import static java.util.Collections.singletonList
-import static org.junit.Assume.assumeTrue
+import static org.junit.jupiter.api.Assumptions.assumeTrue
 
 @Unroll
 abstract class HttpServerTest<SERVER> extends InstrumentationSpecification implements HttpServerTestTrait<SERVER> {
@@ -46,6 +46,14 @@ abstract class HttpServerTest<SERVER> extends InstrumentationSpecification imple
   static final String TEST_REQUEST_HEADER = "X-Test-Request"
   static final String TEST_RESPONSE_HEADER = "X-Test-Response"
 
+  def setupSpec() {
+    setupServer()
+  }
+
+  def cleanupSpec() {
+    cleanupServer()
+  }
+
   static CapturedHttpHeaders capturedHttpHeadersForTesting() {
     CapturedHttpHeaders.create(
       singletonList(TEST_REQUEST_HEADER),

+ 0 - 4
testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpServerTestTrait.groovy

@@ -13,8 +13,6 @@ import io.opentelemetry.testing.internal.armeria.client.ClientFactory
 import io.opentelemetry.testing.internal.armeria.client.WebClient
 import io.opentelemetry.testing.internal.armeria.client.logging.LoggingClient
 import io.opentelemetry.testing.internal.armeria.common.HttpHeaderNames
-import org.junit.AfterClass
-import org.junit.BeforeClass
 import org.slf4j.Logger
 import org.slf4j.LoggerFactory
 
@@ -44,7 +42,6 @@ trait HttpServerTestTrait<SERVER> implements RetryOnAddressAlreadyInUseTrait {
   static int port
   static URI address
 
-  @BeforeClass
   def setupServer() {
     withRetryOnAddressAlreadyInUse({
       setupSpecUnderRetry()
@@ -64,7 +61,6 @@ trait HttpServerTestTrait<SERVER> implements RetryOnAddressAlreadyInUseTrait {
 
   abstract SERVER startServer(int port)
 
-  @AfterClass
   def cleanupServer() {
     if (server == null) {
       println getClass().name + " can't stop null server"