This is an automated email from the ASF dual-hosted git repository.

ycai pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra-sidecar.git


The following commit(s) were added to refs/heads/trunk by this push:
     new f37beca7 CASSSIDECAR-213: Release resources in unit tests (#195)
f37beca7 is described below

commit f37beca7a541b80f5c139afc71d497819c86455b
Author: Yifan Cai <y...@apache.org>
AuthorDate: Tue Feb 18 18:30:07 2025 -0800

    CASSSIDECAR-213: Release resources in unit tests (#195)
    
    Patch by Yifan Cai; Reviewed by Francisco Guerrero for CASSSIDECAR-213
---
 .circleci/config.yml                               |   1 +
 adapters/base/build.gradle                         |   3 -
 adapters/cassandra41/build.gradle                  |   3 -
 build.gradle                                       |   1 -
 client-common/build.gradle                         |   3 -
 client/build.gradle                                |   3 -
 gradle.properties                                  |   3 -
 gradle/common/java11Options.gradle                 |   3 +-
 gradlew                                            |   5 +-
 server-common/build.gradle                         |   3 -
 server/build.gradle                                |   5 -
 .../sidecar/restore/StorageClientTest.java         |  25 ++--
 .../sidecar/routes/StreamStatsIntegrationTest.java |   5 +-
 .../sidecar/CassandraSidecarDaemonTest.java        |   9 +-
 .../sidecar/TestCassandraAdapterDelegate.java      |   5 +-
 .../org/apache/cassandra/sidecar/TestModule.java   |  64 +++++-----
 .../cassandra/sidecar/TestResourceReaper.java      | 131 +++++++++++++++++++++
 .../org/apache/cassandra/sidecar/UlimitTest.java   |  55 ---------
 .../acl/CassandraIdentityExtractorTest.java        |   8 ++
 .../sidecar/acl/IdentityToRoleCacheTest.java       |   8 ++
 .../sidecar/acl/RoleAuthorizationsCacheTest.java   |   8 ++
 .../MutualTlsAuthenticationHandlerFactoryTest.java |   8 ++
 .../acl/authorization/SuperUserCacheTest.java      |   8 ++
 .../cassandra/sidecar/cdc/CDCLogCacheTest.java     |  15 ++-
 .../sidecar/concurrent/ExecutorPoolsTest.java      |   3 +-
 .../sidecar/config/SidecarConfigurationTest.java   |   2 +-
 .../cassandra/sidecar/db/SidecarSchemaTest.java    |   2 +-
 .../sidecar/job/OperationalJobManagerTest.java     |  11 +-
 .../cassandra/sidecar/job/OperationalJobTest.java  |  12 +-
 .../sidecar/metrics/InstanceHealthMetricsTest.java |   3 +-
 .../sidecar/metrics/SchemaMetricsTest.java         |   8 +-
 .../sidecar/restore/RestoreJobManagerTest.java     |   4 +-
 .../sidecar/restore/RestoreRangeTaskTest.java      |  12 +-
 .../sidecar/routes/AbstractHandlerTest.java        |   4 +
 .../cassandra/sidecar/routes/VertxRoutingTest.java |   1 +
 .../routes/restore/BaseRestoreJobTests.java        |  16 +--
 .../sstableuploads/BaseUploadsHandlerTest.java     |  30 ++---
 .../cassandra/sidecar/server/ServerTest.java       |  33 ++++--
 .../sidecar/tasks/PeriodicTaskExecutorTest.java    |   4 +-
 .../sidecar/utils/AsyncFileSystemUtilsTest.java    |   7 +-
 .../sidecar/utils/DigestVerifierFactoryTest.java   |   7 ++
 .../sidecar/utils/MD5DigestVerifierTest.java       |   7 ++
 .../sidecar/utils/SSTableImporterTest.java         |   2 +
 server/src/test/resources/config/sidecar_cdc.yaml  |   2 +-
 .../sidecar_invalid_accesscontrol_config.yaml      |   2 +-
 .../src/test/resources/config/sidecar_metrics.yaml |   2 +-
 .../config/sidecar_metrics_empty_filters.yaml      |   2 +-
 .../config/sidecar_multiple_instances.yaml         |   2 +-
 .../config/sidecar_no_local_instances.yaml         |   2 +-
 .../sidecar_schema_keyspace_configuration.yaml     |   2 +-
 .../resources/config/sidecar_single_instance.yaml  |   2 +-
 .../sidecar_single_instance_non_zero_port.yaml     |   2 +-
 .../config/sidecar_unrecognized_authenticator.yaml |   2 +-
 .../config/sidecar_unrecognized_authorizer.yaml    |   2 +-
 .../config/sidecar_vertx_filesystem_options.yaml   |   2 +-
 .../snapshots/AbstractSnapshotPathBuilderTest.java |   4 +-
 spotbugs-exclude.xml                               |   7 ++
 .../cassandra/testing/utils/AssertionUtils.java    |   2 +-
 .../impl/MutualTlsAuthenticationProviderTest.java  |  11 +-
 vertx-client/build.gradle                          |   3 -
 60 files changed, 383 insertions(+), 218 deletions(-)

diff --git a/.circleci/config.yml b/.circleci/config.yml
index 48bb955e..13d56ba7 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -79,6 +79,7 @@ jobs:
       - image: cimg/openjdk:11.0
     environment:
       skipIntegrationTest: true
+    resource_class: large
     steps:
       - setup_remote_docker
       - install_common
diff --git a/adapters/base/build.gradle b/adapters/base/build.gradle
index d758599a..2bed834f 100644
--- a/adapters/base/build.gradle
+++ b/adapters/base/build.gradle
@@ -40,9 +40,6 @@ repositories {
 
 test {
     useJUnitPlatform()
-    if (Os.isFamily(Os.FAMILY_MAC)) {
-        jvmArgs "-XX:-MaxFDLimit"
-    }
     maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
     reports {
         junitXml.setRequired(true)
diff --git a/adapters/cassandra41/build.gradle 
b/adapters/cassandra41/build.gradle
index f37db7d0..11ac1570 100644
--- a/adapters/cassandra41/build.gradle
+++ b/adapters/cassandra41/build.gradle
@@ -35,9 +35,6 @@ sourceCompatibility = JavaVersion.VERSION_11
 
 test {
     useJUnitPlatform()
-    if (Os.isFamily(Os.FAMILY_MAC)) {
-        jvmArgs "-XX:-MaxFDLimit"
-    }
     maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
     reports {
         junitXml.setRequired(true)
diff --git a/build.gradle b/build.gradle
index 599f90b1..8669110a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -239,7 +239,6 @@ subprojects {
     }
 
     test {
-        jvmArgs "-XX:-MaxFDLimit"
         finalizedBy jacocoTestReport // report is always generated after tests 
run
     }
 }
diff --git a/client-common/build.gradle b/client-common/build.gradle
index d630c118..a041aa8b 100644
--- a/client-common/build.gradle
+++ b/client-common/build.gradle
@@ -37,9 +37,6 @@ sourceCompatibility = 1.8
 
 test {
     useJUnitPlatform()
-    if (Os.isFamily(Os.FAMILY_MAC)) {
-        jvmArgs "-XX:-MaxFDLimit"
-    }
     maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
     reports {
         junitXml.setRequired(true)
diff --git a/client/build.gradle b/client/build.gradle
index 27610bdf..1921bc7d 100644
--- a/client/build.gradle
+++ b/client/build.gradle
@@ -41,9 +41,6 @@ repositories {
 
 test {
     useJUnitPlatform()
-    if (Os.isFamily(Os.FAMILY_MAC)) {
-        jvmArgs "-XX:-MaxFDLimit"
-    }
     testLogging {
         events "passed", "skipped", "failed"
     }
diff --git a/gradle.properties b/gradle.properties
index eb6cbc28..3974f7be 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -33,6 +33,3 @@ awsSdkVersion=2.26.12
 commonsCodecVersion=1.16.1
 # openSSL
 boringSslVersion=2.0.61.Final
-# If running MacOS then you need to increase the max
-# open FD limit
-org.gradle.jvmargs=-XX:-MaxFDLimit
diff --git a/gradle/common/java11Options.gradle 
b/gradle/common/java11Options.gradle
index 000e8c8f..24146456 100644
--- a/gradle/common/java11Options.gradle
+++ b/gradle/common/java11Options.gradle
@@ -16,8 +16,7 @@
  * limitations under the License.
  */
 
-project.ext.JDK11_OPTIONS = ['-XX:-MaxFDLimit',
-                             '-Djdk.attach.allowAttachSelf=true',
+project.ext.JDK11_OPTIONS = ['-Djdk.attach.allowAttachSelf=true',
                              '--add-exports', 
'java.base/jdk.internal.misc=ALL-UNNAMED',
                              '--add-exports', 
'java.base/jdk.internal.ref=ALL-UNNAMED',
                              '--add-exports', 
'java.base/sun.nio.ch=ALL-UNNAMED',
diff --git a/gradlew b/gradlew
index 019e8835..0e6a11f4 100755
--- a/gradlew
+++ b/gradlew
@@ -163,11 +163,8 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
 fi
 
 # For Darwin, add options to specify how the application appears in the dock
-# In addition, we want to increase the file descriptor limit to the MaxFDLimit 
in MacOS, which,
-# by default, is set to a lower limit than the actual system maximum. This 
line is modified manually, if
-# producing a new gradle wrapper, remember to add the change back.
 if $darwin; then
-    GRADLE_OPTS="$GRADLE_OPTS \"-XX:-MaxFDLimit\" \"-Xdock:name=$APP_NAME\" 
\"-Xdock:icon=$APP_HOME/media/gradle.icns\" 
\"-Dorg.gradle.jvmargs=-XX:-MaxFDLimit\""
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" 
\"-Xdock:icon=$APP_HOME/media/gradle.icns\""
 fi
 
 # Collect all arguments for the java command, stacking in reverse order:
diff --git a/server-common/build.gradle b/server-common/build.gradle
index 114cd72a..163b1f03 100644
--- a/server-common/build.gradle
+++ b/server-common/build.gradle
@@ -36,9 +36,6 @@ sourceCompatibility = JavaVersion.VERSION_11
 
 test {
     useJUnitPlatform()
-    if (Os.isFamily(Os.FAMILY_MAC)) {
-        jvmArgs "-XX:-MaxFDLimit"
-    }
     maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
     reports {
         junitXml.setRequired(true)
diff --git a/server/build.gradle b/server/build.gradle
index d9aaec44..39db5e6b 100644
--- a/server/build.gradle
+++ b/server/build.gradle
@@ -196,9 +196,6 @@ test {
     // ordinarily we don't need integration tests
     // see the integrationTest task
     useJUnitPlatform()
-    if (Os.isFamily(Os.FAMILY_MAC)) {
-        jvmArgs "-XX:-MaxFDLimit"
-    }
     reports {
         junitXml.setRequired(true)
         def destDir = Paths.get(rootProject.rootDir.absolutePath, "build", 
"test-results", "test").toFile()
@@ -220,8 +217,6 @@ tasks.register("containerTest", Test) {
     if (JavaVersion.current().isJava11Compatible()) {
         jvmArgs(project.ext.JDK11_OPTIONS)
         println("JVM arguments for $project.name are $allJvmArgs")
-    } else {
-        jvmArgs '-XX:-MaxFDLimit'
     }
 
     useJUnitPlatform()
diff --git 
a/server/src/test/containerTest/org/apache/cassandra/sidecar/restore/StorageClientTest.java
 
b/server/src/test/containerTest/org/apache/cassandra/sidecar/restore/StorageClientTest.java
index e6d2e25e..aada2612 100644
--- 
a/server/src/test/containerTest/org/apache/cassandra/sidecar/restore/StorageClientTest.java
+++ 
b/server/src/test/containerTest/org/apache/cassandra/sidecar/restore/StorageClientTest.java
@@ -41,6 +41,7 @@ import org.junit.jupiter.api.io.TempDir;
 import com.adobe.testing.s3mock.testcontainers.S3MockContainer;
 import com.datastax.driver.core.utils.UUIDs;
 import io.vertx.core.Vertx;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import org.apache.cassandra.sidecar.common.data.RestoreJobSecrets;
 import org.apache.cassandra.sidecar.common.data.RestoreJobStatus;
 import org.apache.cassandra.sidecar.common.data.SSTableImportOptions;
@@ -89,6 +90,8 @@ class StorageClientTest
     private static RestoreRange testRange;
     private static RestoreRange largeTestRange;
     private static Path largeFilePath;
+    private static Vertx vertx;
+    private static ExecutorPools executorPools;
     private static TaskExecutorPool taskExecutorPool;
 
     @TempDir
@@ -126,7 +129,20 @@ class StorageClientTest
                                       LARGE_FILE_IN_BYTES);
         putObject(largeTestRange, largeFilePath);
 
-        taskExecutorPool = new ExecutorPools(Vertx.vertx(), new 
ServiceConfigurationImpl()).internal();
+        vertx = Vertx.vertx();
+        executorPools = new ExecutorPools(vertx, new 
ServiceConfigurationImpl());
+        taskExecutorPool = executorPools.internal();
+    }
+
+    @AfterAll
+    static void cleanup()
+    {
+        TestResourceReaper.create()
+                          .with(executorPools)
+                          .with(vertx)
+                          .with(() -> s3Mock.stop(),
+                                () -> client.close())
+                          .close();
     }
 
     static S3AsyncClient buildS3AsyncClient(Duration apiCallTimeout) throws 
Exception
@@ -149,13 +165,6 @@ class StorageClientTest
                             .build();
     }
 
-    @AfterAll
-    static void cleanup()
-    {
-        s3Mock.stop();
-        client.close();
-    }
-
     @Test
     void testUnauthenticated()
     {
diff --git 
a/server/src/test/integration/org/apache/cassandra/sidecar/routes/StreamStatsIntegrationTest.java
 
b/server/src/test/integration/org/apache/cassandra/sidecar/routes/StreamStatsIntegrationTest.java
index 28801476..740010b2 100644
--- 
a/server/src/test/integration/org/apache/cassandra/sidecar/routes/StreamStatsIntegrationTest.java
+++ 
b/server/src/test/integration/org/apache/cassandra/sidecar/routes/StreamStatsIntegrationTest.java
@@ -84,7 +84,10 @@ public class StreamStatsIntegrationTest extends 
IntegrationTestBase
         });
     }
 
-    private void startRepairAsync(IUpgradeableInstance node, CountDownLatch 
testStart, QualifiedTableName tableName, AtomicReference<RuntimeException> 
nodetoolError)
+    private void startRepairAsync(IUpgradeableInstance node,
+                                  CountDownLatch testStart,
+                                  QualifiedTableName tableName,
+                                  AtomicReference<RuntimeException> 
nodetoolError)
     {
         startAsync("Repairing node" + node.config().num(),
                    () -> {
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/CassandraSidecarDaemonTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/CassandraSidecarDaemonTest.java
index 09c8b672..bda9c9a0 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/CassandraSidecarDaemonTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/CassandraSidecarDaemonTest.java
@@ -84,11 +84,12 @@ class CassandraSidecarDaemonTest
         assertThat(path).exists();
 
         System.setProperty("sidecar.config", path.toUri().toString());
+        Vertx vertx = Vertx.vertx();
+        WebClient client = WebClient.create(vertx);
         try
         {
             CassandraSidecarDaemon.main(NO_ARGS);
 
-            WebClient client = WebClient.create(Vertx.vertx());
             loopAssert(10, () -> {
                 HttpResponse<String> response = getBlocking(client.get(9043, 
"localhost", "/api/v1/__health")
                                                                   
.as(BodyCodec.string())
@@ -102,6 +103,7 @@ class CassandraSidecarDaemonTest
         finally
         {
             maybeStopCassandraSidecar();
+            TestResourceReaper.create().with(vertx).with(client).close();
         }
     }
 
@@ -118,7 +120,8 @@ class CassandraSidecarDaemonTest
         // Now let's copy the file to the expected location
         Path targetFile = Paths.get("conf/sidecar.yaml");
         List<Path> createdParents = null;
-
+        Vertx vertx = Vertx.vertx();
+        WebClient client = WebClient.create(vertx);
         try
         {
             createdParents = createParents(targetFile.toAbsolutePath());
@@ -126,7 +129,6 @@ class CassandraSidecarDaemonTest
 
             CassandraSidecarDaemon.main(NO_ARGS);
 
-            WebClient client = WebClient.create(Vertx.vertx());
             loopAssert(10, () -> {
                 HttpResponse<String> response = getBlocking(client.get(9043, 
"localhost", "/api/v1/__health")
                                                                   
.as(BodyCodec.string())
@@ -150,6 +152,7 @@ class CassandraSidecarDaemonTest
                     Files.deleteIfExists(createdParent);
                 }
             }
+            TestResourceReaper.create().with(vertx).with(client).close();
         }
     }
 
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/TestCassandraAdapterDelegate.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/TestCassandraAdapterDelegate.java
index d0bda397..af4d97d5 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/TestCassandraAdapterDelegate.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/TestCassandraAdapterDelegate.java
@@ -42,9 +42,9 @@ public class TestCassandraAdapterDelegate extends 
CassandraAdapterDelegate
     NodeSettings nodeSettings;
     boolean isNativeUp = false;
 
-    public TestCassandraAdapterDelegate()
+    public TestCassandraAdapterDelegate(Vertx vertx)
     {
-        super(Vertx.vertx(), 1, null, null, null, null, null, "localhost", 
9042, new InstanceHealthMetrics(registry(1)));
+        super(vertx, 1, null, null, null, null, null, "localhost", 9042, new 
InstanceHealthMetrics(registry(1)));
     }
 
     @Override
@@ -121,6 +121,7 @@ public class TestCassandraAdapterDelegate extends 
CassandraAdapterDelegate
     @Override
     public void close()
     {
+        // no resource to close
     }
 
     private <T> T throwOnNull(T value)
diff --git a/server/src/test/java/org/apache/cassandra/sidecar/TestModule.java 
b/server/src/test/java/org/apache/cassandra/sidecar/TestModule.java
index 0fb64c74..4ddda22b 100644
--- a/server/src/test/java/org/apache/cassandra/sidecar/TestModule.java
+++ b/server/src/test/java/org/apache/cassandra/sidecar/TestModule.java
@@ -33,10 +33,12 @@ import com.google.inject.AbstractModule;
 import com.google.inject.Provides;
 import com.google.inject.Singleton;
 import com.google.inject.name.Named;
+import io.vertx.core.Vertx;
 import org.apache.cassandra.sidecar.cluster.CassandraAdapterDelegate;
 import org.apache.cassandra.sidecar.cluster.InstancesMetadata;
 import org.apache.cassandra.sidecar.cluster.InstancesMetadataImpl;
 import org.apache.cassandra.sidecar.cluster.instance.InstanceMetadata;
+import org.apache.cassandra.sidecar.cluster.instance.InstanceMetadataImpl;
 import org.apache.cassandra.sidecar.common.MockCassandraFactory;
 import org.apache.cassandra.sidecar.common.response.NodeSettings;
 import org.apache.cassandra.sidecar.common.server.StorageOperations;
@@ -62,7 +64,6 @@ import 
org.apache.cassandra.sidecar.config.yaml.SchemaKeyspaceConfigurationImpl;
 import org.apache.cassandra.sidecar.config.yaml.SidecarConfigurationImpl;
 import org.apache.cassandra.sidecar.config.yaml.TestServiceConfiguration;
 import org.apache.cassandra.sidecar.config.yaml.ThrottleConfigurationImpl;
-import org.apache.cassandra.sidecar.metrics.instance.InstanceMetricsImpl;
 import org.apache.cassandra.sidecar.utils.CassandraVersionProvider;
 
 import static org.apache.cassandra.sidecar.utils.TestMetricUtils.registry;
@@ -79,20 +80,11 @@ public class TestModule extends AbstractModule
 
     public TestCassandraAdapterDelegate delegate;
 
-    public TestModule()
-    {
-        this(new TestCassandraAdapterDelegate());
-    }
-
-    public TestModule(TestCassandraAdapterDelegate delegate)
-    {
-        this.delegate = delegate;
-    }
-
     @Singleton
     @Provides
-    public CassandraAdapterDelegate delegate()
+    public CassandraAdapterDelegate delegate(Vertx vertx)
     {
+        this.delegate = new TestCassandraAdapterDelegate(vertx);
         return delegate;
     }
 
@@ -155,9 +147,9 @@ public class TestModule extends AbstractModule
 
     @Provides
     @Singleton
-    public InstancesMetadata instancesMetadata(DnsResolver dnsResolver)
+    public InstancesMetadata instancesMetadata(DnsResolver dnsResolver, 
CassandraAdapterDelegate delegate)
     {
-        return new InstancesMetadataImpl(instancesMetas(), dnsResolver);
+        return new 
InstancesMetadataImpl(instancesMetas((TestCassandraAdapterDelegate) delegate), 
dnsResolver);
     }
 
     @Provides
@@ -170,25 +162,28 @@ public class TestModule extends AbstractModule
                                                              
.inboundGlobalFileBandwidthBytesPerSecond());
     }
 
-    public List<InstanceMetadata> instancesMetas()
+    public List<InstanceMetadata> instancesMetas(TestCassandraAdapterDelegate 
delegate)
     {
-        InstanceMetadata instance1 = mockInstance("localhost",
+        InstanceMetadata instance1 = mockInstance(delegate,
+                                                  "localhost",
                                                   1,
                                                   
"src/test/resources/instance1/data",
                                                   
"src/test/resources/instance1/sstable-staging",
-                                                  
"src/test/resources/instance1/cdc_raw",
+                                                  
"src/test/resources/instance1",
                                                   true);
-        InstanceMetadata instance2 = mockInstance("localhost2",
+        InstanceMetadata instance2 = mockInstance(delegate,
+                                                  "localhost2",
                                                   2,
                                                   
"src/test/resources/instance2/data",
                                                   
"src/test/resources/instance2/sstable-staging",
-                                                  
"src/test/resources/instance2/cdc_raw",
+                                                  
"src/test/resources/instance2",
                                                   false);
-        InstanceMetadata instance3 = mockInstance("localhost3",
+        InstanceMetadata instance3 = mockInstance(delegate,
+                                                  "localhost3",
                                                   3,
                                                   
"src/test/resources/instance3/data",
                                                   
"src/test/resources/instance3/sstable-staging",
-                                                  
"src/test/resources/instance3/cdc_raw",
+                                                  
"src/test/resources/instance3",
                                                   true);
         final List<InstanceMetadata> instanceMetas = new ArrayList<>();
         instanceMetas.add(instance1);
@@ -197,20 +192,11 @@ public class TestModule extends AbstractModule
         return instanceMetas;
     }
 
-    private InstanceMetadata mockInstance(String host, int id, String dataDir, 
String stagingDir, String cdcDir, boolean isUp)
+    private InstanceMetadata mockInstance(TestCassandraAdapterDelegate 
delegate,
+                                          String host, int id, String dataDir, 
String stagingDir, String storageDir, boolean isUp)
     {
-        InstanceMetadata instanceMeta = mock(InstanceMetadata.class);
-        when(instanceMeta.id()).thenReturn(id);
-        when(instanceMeta.host()).thenReturn(host);
-        when(instanceMeta.port()).thenReturn(6475);
-        when(instanceMeta.stagingDir()).thenReturn(stagingDir);
-        when(instanceMeta.cdcDir()).thenReturn(cdcDir);
-        List<String> dataDirectories = Collections.singletonList(dataDir);
-        when(instanceMeta.dataDirs()).thenReturn(dataDirectories);
-        when(instanceMeta.metrics()).thenReturn(new 
InstanceMetricsImpl(registry(id)));
-
         StorageOperations mockStorageOperations = 
mock(StorageOperations.class);
-        
when(mockStorageOperations.dataFileLocations()).thenReturn(dataDirectories);
+        
when(mockStorageOperations.dataFileLocations()).thenReturn(List.of(dataDir));
         Metadata metadata = mock(Metadata.class);
         KeyspaceMetadata keyspaceMetadata = mock(KeyspaceMetadata.class);
         when(metadata.getKeyspace(any())).thenReturn(keyspaceMetadata);
@@ -231,8 +217,16 @@ public class TestModule extends AbstractModule
                                                  .build());
         }
         delegate.setIsNativeUp(isUp);
-        when(instanceMeta.delegate()).thenReturn(delegate);
-        return instanceMeta;
+        return InstanceMetadataImpl.builder()
+                                   .id(id)
+                                   .host(host)
+                                   .port(6475)
+                                   .stagingDir(stagingDir)
+                                   .storageDir(storageDir)
+                                   .dataDirs(List.of(dataDir))
+                                   .metricRegistry(registry(id))
+                                   .delegate(delegate)
+                                   .build();
     }
 
     /**
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/TestResourceReaper.java 
b/server/src/test/java/org/apache/cassandra/sidecar/TestResourceReaper.java
new file mode 100644
index 00000000..42839b75
--- /dev/null
+++ b/server/src/test/java/org/apache/cassandra/sidecar/TestResourceReaper.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.sidecar;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import io.vertx.core.Future;
+import io.vertx.core.Vertx;
+import io.vertx.ext.web.client.WebClient;
+import org.apache.cassandra.sidecar.common.server.utils.ThrowableUtils;
+import org.apache.cassandra.sidecar.concurrent.ExecutorPools;
+import org.apache.cassandra.sidecar.server.Server;
+
+/**
+ * A helper to teardown test resources in the pre-defined order
+ */
+public class TestResourceReaper
+{
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(TestResourceReaper.class);
+    private Vertx vertx;
+    private Server server;
+    private ExecutorPools executorPools;
+    private WebClient webClient;
+    private List<AutoCloseable> parallelCloseables;
+
+    public static TestResourceReaper create()
+    {
+        return new TestResourceReaper();
+    }
+
+    public TestResourceReaper with(Vertx vertx)
+    {
+        this.vertx = vertx;
+        return this;
+    }
+
+    public TestResourceReaper with(Server server)
+    {
+        this.server = server;
+        return this;
+    }
+
+    public TestResourceReaper with(ExecutorPools executorPools)
+    {
+        this.executorPools = executorPools;
+        return this;
+    }
+
+    public TestResourceReaper with(WebClient webClient)
+    {
+        this.webClient = webClient;
+        return this;
+    }
+
+    public TestResourceReaper with(AutoCloseable... closeables)
+    {
+        this.parallelCloseables = List.of(closeables);
+        return this;
+    }
+
+    public Future<?> close()
+    {
+        try
+        {
+            return closeInternal();
+        }
+        catch (Throwable cause)
+        {
+            LOGGER.warn("Failed to trigger close on certain resources", cause);
+            return Future.failedFuture(cause);
+        }
+    }
+
+    private Future<?> closeInternal()
+    {
+        List<Future<?>> closeFutures = new ArrayList<>();
+        if (server != null)
+        {
+            closeFutures.add(server.close());
+        }
+        if (webClient != null)
+        {
+            closeFutures.add(Future.future(p -> {
+                webClient.close();
+                p.complete();
+            }));
+        }
+
+        Future<?> merged = Future.all(closeFutures);
+        if (parallelCloseables != null)
+        {
+            List<Future<?>> batch = parallelCloseables.stream()
+                                                      .map(c -> 
Future.future(p -> {
+                                                          
ThrowableUtils.propagate(c::close);
+                                                          p.complete();
+                                                      }))
+                                                      
.collect(Collectors.toList());
+            merged = merged.andThen(ignored -> Future.all(batch));
+        }
+        if (executorPools != null)
+        {
+            merged = merged.andThen(ignored -> executorPools.close());
+        }
+        if (vertx != null)
+        {
+            merged = merged.andThen(ignored -> vertx.close());
+        }
+        return merged;
+    }
+}
diff --git a/server/src/test/java/org/apache/cassandra/sidecar/UlimitTest.java 
b/server/src/test/java/org/apache/cassandra/sidecar/UlimitTest.java
deleted file mode 100644
index b52c507d..00000000
--- a/server/src/test/java/org/apache/cassandra/sidecar/UlimitTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.cassandra.sidecar;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledOnOs;
-import org.junit.jupiter.api.condition.OS;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-/**
- * Test to ensure that the max file descriptors is large enough to build 
Cassandra Sidecar
- */
-@EnabledOnOs({OS.MAC})
-public class UlimitTest
-{
-
-    /**
-     * Runs a test to ensure that the Max Files isn't too low
-     * @throws Exception when maxFD isn't large enough
-     */
-    @Test
-    void ensureUlimitMaxFilesIsNotTooLow() throws Exception
-    {
-        Process p = new ProcessBuilder("ulimit", "-n").start();
-        p.waitFor();
-        InputStreamReader inputStreamReader = new 
InputStreamReader(p.getInputStream(), StandardCharsets.UTF_8);
-        BufferedReader reader = new BufferedReader(inputStreamReader);
-        String line = reader.readLine();
-        long maxFD = Long.parseLong(line);
-        assertThat(maxFD).isGreaterThan(10240);
-        inputStreamReader.close();
-        reader.close();
-    }
-}
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/acl/CassandraIdentityExtractorTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/acl/CassandraIdentityExtractorTest.java
index 22df77fd..22e03aa4 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/acl/CassandraIdentityExtractorTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/acl/CassandraIdentityExtractorTest.java
@@ -21,12 +21,14 @@ package org.apache.cassandra.sidecar.acl;
 import java.security.cert.X509Certificate;
 import java.util.Collections;
 
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import io.vertx.core.Vertx;
 import io.vertx.ext.auth.authentication.CertificateCredentials;
 import io.vertx.ext.auth.authentication.CredentialValidationException;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import 
org.apache.cassandra.sidecar.acl.authentication.CassandraIdentityExtractor;
 import 
org.apache.cassandra.sidecar.common.server.utils.MillisecondBoundConfiguration;
 import org.apache.cassandra.sidecar.concurrent.ExecutorPools;
@@ -57,6 +59,12 @@ class CassandraIdentityExtractorTest
         executorPools = createdSharedTestPool(vertx);
     }
 
+    @AfterEach
+    void teardown()
+    {
+        TestResourceReaper.create().with(vertx).with(executorPools).close();
+    }
+
     @Test
     void testExtractingIdentityWithRole() throws Exception
     {
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/acl/IdentityToRoleCacheTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/acl/IdentityToRoleCacheTest.java
index 37f8c48e..dc5ddbbf 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/acl/IdentityToRoleCacheTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/acl/IdentityToRoleCacheTest.java
@@ -24,11 +24,13 @@ import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
 import com.google.common.util.concurrent.Uninterruptibles;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import io.vertx.core.Vertx;
 import io.vertx.core.json.JsonObject;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import org.apache.cassandra.sidecar.acl.authorization.PermissionFactoryImpl;
 import org.apache.cassandra.sidecar.common.server.CQLSessionProvider;
 import 
org.apache.cassandra.sidecar.common.server.utils.MillisecondBoundConfiguration;
@@ -60,6 +62,12 @@ class IdentityToRoleCacheTest
         executorPools = createdSharedTestPool(vertx);
     }
 
+    @AfterEach
+    void cleanup()
+    {
+        TestResourceReaper.create().with(vertx).with(executorPools).close();
+    }
+
     @Test
     void testFindRole()
     {
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/acl/RoleAuthorizationsCacheTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/acl/RoleAuthorizationsCacheTest.java
index 57f6d20e..1cef08b5 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/acl/RoleAuthorizationsCacheTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/acl/RoleAuthorizationsCacheTest.java
@@ -24,12 +24,14 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import io.vertx.core.Vertx;
 import io.vertx.core.json.JsonObject;
 import io.vertx.ext.auth.authorization.Authorization;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import org.apache.cassandra.sidecar.acl.authorization.BasicPermissions;
 import org.apache.cassandra.sidecar.acl.authorization.CassandraPermissions;
 import org.apache.cassandra.sidecar.acl.authorization.RoleAuthorizationsCache;
@@ -68,6 +70,12 @@ class RoleAuthorizationsCacheTest
         executorPools = createdSharedTestPool(vertx);
     }
 
+    @AfterEach
+    void cleanup()
+    {
+        TestResourceReaper.create().with(vertx).with(executorPools).close();
+    }
+
     @Test
     void testCacheSizeAlwaysOne() throws InterruptedException
     {
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/acl/authentication/MutualTlsAuthenticationHandlerFactoryTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/acl/authentication/MutualTlsAuthenticationHandlerFactoryTest.java
index 4c306ded..9fa8d99c 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/acl/authentication/MutualTlsAuthenticationHandlerFactoryTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/acl/authentication/MutualTlsAuthenticationHandlerFactoryTest.java
@@ -22,10 +22,12 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import io.vertx.core.Vertx;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import org.apache.cassandra.sidecar.acl.IdentityToRoleCache;
 import org.apache.cassandra.sidecar.concurrent.ExecutorPools;
 import org.apache.cassandra.sidecar.config.AccessControlConfiguration;
@@ -56,6 +58,12 @@ class MutualTlsAuthenticationHandlerFactoryTest
         executorPools = createdSharedTestPool(vertx);
     }
 
+    @AfterEach
+    void cleanup()
+    {
+        TestResourceReaper.create().with(vertx).with(executorPools).close();
+    }
+
     @Test
     void testNullParameters()
     {
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/acl/authorization/SuperUserCacheTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/acl/authorization/SuperUserCacheTest.java
index 00ff99bd..9d4730c0 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/acl/authorization/SuperUserCacheTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/acl/authorization/SuperUserCacheTest.java
@@ -23,11 +23,13 @@ import java.util.HashMap;
 import java.util.Map;
 
 import com.google.common.collect.ImmutableMap;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import io.vertx.core.Vertx;
 import io.vertx.core.json.JsonObject;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import 
org.apache.cassandra.sidecar.common.server.utils.MillisecondBoundConfiguration;
 import org.apache.cassandra.sidecar.concurrent.ExecutorPools;
 import org.apache.cassandra.sidecar.config.AccessControlConfiguration;
@@ -57,6 +59,12 @@ class SuperUserCacheTest
         executorPools = createdSharedTestPool(vertx);
     }
 
+    @AfterEach
+    void cleanup()
+    {
+        TestResourceReaper.create().with(vertx).with(executorPools).close();
+    }
+
     @Test
     void testBulkLoad()
     {
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/cdc/CDCLogCacheTest.java 
b/server/src/test/java/org/apache/cassandra/sidecar/cdc/CDCLogCacheTest.java
index e0651acf..aa681d78 100644
--- a/server/src/test/java/org/apache/cassandra/sidecar/cdc/CDCLogCacheTest.java
+++ b/server/src/test/java/org/apache/cassandra/sidecar/cdc/CDCLogCacheTest.java
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.nio.file.Files;
 import java.util.concurrent.TimeUnit;
 
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -32,6 +33,7 @@ import com.google.inject.util.Modules;
 import io.vertx.core.Vertx;
 import org.apache.cassandra.sidecar.ExecutorPoolsHelper;
 import org.apache.cassandra.sidecar.TestModule;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import org.apache.cassandra.sidecar.cluster.InstancesMetadata;
 import 
org.apache.cassandra.sidecar.common.server.utils.SecondBoundConfiguration;
 import org.apache.cassandra.sidecar.common.utils.Preconditions;
@@ -50,7 +52,9 @@ class CdcLogCacheTest
 {
     private final Injector injector = 
Guice.createInjector(Modules.override(new MainModule()).with(new TestModule()));
     private final InstancesMetadata instancesMetadata = 
injector.getInstance(InstancesMetadata.class);
-    private final CdcLogCache logCache = cdcLogCache();
+    private final Vertx vertx = injector.getInstance(Vertx.class);
+    private final ExecutorPools executorPools = 
injector.getInstance(ExecutorPools.class);
+    private final CdcLogCache logCache = cdcLogCache(executorPools);
 
     @BeforeEach
     void beforeEach()
@@ -60,6 +64,12 @@ class CdcLogCacheTest
         assertThat(logCache.hardlinkCache.size()).isZero();
     }
 
+    @AfterEach
+    void teardown()
+    {
+        TestResourceReaper.create().with(vertx).with(executorPools).close();
+    }
+
     @Test
     void testLinkedFileExpiryInCache() throws IOException
     {
@@ -115,9 +125,8 @@ class CdcLogCacheTest
         return new File(commitLogPathOnInstance1);
     }
 
-    private CdcLogCache cdcLogCache()
+    private CdcLogCache cdcLogCache(ExecutorPools executorPools)
     {
-        ExecutorPools executorPools = 
ExecutorPoolsHelper.createdSharedTestPool(Vertx.vertx());
         // Mock the class because even though the resolution is seconds, for 
testing purposes
         // we hack into the class and allow configuring the cache expiration 
with milliseconds.
         SecondBoundConfiguration mockCacheExpiryConfig = 
mock(SecondBoundConfiguration.class);
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/concurrent/ExecutorPoolsTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/concurrent/ExecutorPoolsTest.java
index 69d7ab5e..c9edc017 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/concurrent/ExecutorPoolsTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/concurrent/ExecutorPoolsTest.java
@@ -27,6 +27,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import io.vertx.core.Vertx;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import org.apache.cassandra.sidecar.config.yaml.ServiceConfigurationImpl;
 import org.apache.cassandra.sidecar.metrics.MetricRegistryFactory;
 import org.apache.cassandra.sidecar.metrics.SidecarMetrics;
@@ -64,7 +65,7 @@ class ExecutorPoolsTest
     public void after()
     {
         registry().removeMatching((name, metric) -> true);
-        vertx.close().onComplete(v -> pools.close()).result();
+        TestResourceReaper.create().with(vertx).with(pools).close();
     }
 
     @Test
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/config/SidecarConfigurationTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/config/SidecarConfigurationTest.java
index 61c4bfc3..e2496450 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/config/SidecarConfigurationTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/config/SidecarConfigurationTest.java
@@ -112,7 +112,7 @@ class SidecarConfigurationTest
         SidecarConfiguration config = 
SidecarConfigurationImpl.readYamlConfiguration(yamlPath);
         
assertThat(config.serviceConfiguration().jmxConfiguration()).isNotNull();
         JmxConfiguration jmxConfiguration = 
config.serviceConfiguration().jmxConfiguration();
-        assertThat(jmxConfiguration.maxRetries()).isEqualTo(42);
+        assertThat(jmxConfiguration.maxRetries()).isEqualTo(1);
         assertThat(jmxConfiguration.retryDelay().quantity()).isEqualTo(1234L);
         
assertThat(jmxConfiguration.retryDelay().unit()).isEqualTo(TimeUnit.MILLISECONDS);
     }
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/db/SidecarSchemaTest.java 
b/server/src/test/java/org/apache/cassandra/sidecar/db/SidecarSchemaTest.java
index c17a46c5..dbfd0bf9 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/db/SidecarSchemaTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/db/SidecarSchemaTest.java
@@ -104,7 +104,7 @@ public class SidecarSchemaTest
         interceptedExecStmts.clear();
         interceptedPrepStmts.clear();
         CountDownLatch closeLatch = new CountDownLatch(1);
-        vertx.close(result -> closeLatch.countDown());
+        server.close().onComplete(result -> closeLatch.countDown());
         if (closeLatch.await(60, TimeUnit.SECONDS))
             logger.info("Close event received before timeout.");
         else
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/job/OperationalJobManagerTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/job/OperationalJobManagerTest.java
index 91e53a83..f7b6cfe9 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/job/OperationalJobManagerTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/job/OperationalJobManagerTest.java
@@ -20,19 +20,20 @@ package org.apache.cassandra.sidecar.job;
 
 import java.util.UUID;
 
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import com.datastax.driver.core.utils.UUIDs;
 import io.vertx.core.Promise;
 import io.vertx.core.Vertx;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import 
org.apache.cassandra.sidecar.common.server.exceptions.OperationalJobException;
 import 
org.apache.cassandra.sidecar.common.server.utils.SecondBoundConfiguration;
 import org.apache.cassandra.sidecar.concurrent.ExecutorPools;
 import org.apache.cassandra.sidecar.concurrent.TaskExecutorPool;
 import org.apache.cassandra.sidecar.config.yaml.ServiceConfigurationImpl;
 import org.apache.cassandra.sidecar.exceptions.OperationalJobConflictException;
-import org.mockito.MockitoAnnotations;
 
 import static 
org.apache.cassandra.sidecar.common.data.OperationalJobStatus.RUNNING;
 import static 
org.apache.cassandra.sidecar.common.data.OperationalJobStatus.SUCCEEDED;
@@ -54,7 +55,6 @@ import static org.mockito.Mockito.when;
 class OperationalJobManagerTest
 {
     protected Vertx vertx;
-
     protected ExecutorPools executorPool;
 
     @BeforeEach
@@ -62,7 +62,12 @@ class OperationalJobManagerTest
     {
         vertx = Vertx.vertx();
         executorPool = new ExecutorPools(vertx, new 
ServiceConfigurationImpl());
-        MockitoAnnotations.openMocks(this);
+    }
+
+    @AfterEach
+    void cleanup()
+    {
+        TestResourceReaper.create().with(vertx).with(executorPool).close();
     }
 
     @Test
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/job/OperationalJobTest.java 
b/server/src/test/java/org/apache/cassandra/sidecar/job/OperationalJobTest.java
index daa644a2..9dab537b 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/job/OperationalJobTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/job/OperationalJobTest.java
@@ -21,12 +21,14 @@ package org.apache.cassandra.sidecar.job;
 import java.util.UUID;
 
 import com.google.common.util.concurrent.Uninterruptibles;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
 
 import com.datastax.driver.core.utils.UUIDs;
 import io.vertx.core.Future;
 import io.vertx.core.Promise;
 import io.vertx.core.Vertx;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import org.apache.cassandra.sidecar.common.data.OperationalJobStatus;
 import 
org.apache.cassandra.sidecar.common.server.exceptions.OperationalJobException;
 import org.apache.cassandra.sidecar.common.server.utils.DurationSpec;
@@ -44,7 +46,9 @@ import static org.assertj.core.api.Assertions.assertThat;
  */
 class OperationalJobTest
 {
-    private final TaskExecutorPool executorPool = new 
ExecutorPools(Vertx.vertx(), new ServiceConfigurationImpl()).internal();
+    private final Vertx vertx = Vertx.vertx();
+    private final ExecutorPools executorPools = new 
ExecutorPools(Vertx.vertx(), new ServiceConfigurationImpl());
+    private final TaskExecutorPool executorPool = executorPools.internal();
 
     public static OperationalJob createOperationalJob(OperationalJobStatus 
jobStatus)
     {
@@ -117,6 +121,12 @@ class OperationalJobTest
         };
     }
 
+    @AfterEach
+    void cleanup()
+    {
+        TestResourceReaper.create().with(vertx).with(executorPools).close();
+    }
+
     @Test
     void testJobCompletion()
     {
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/metrics/InstanceHealthMetricsTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/metrics/InstanceHealthMetricsTest.java
index 157e60e6..a51eaa25 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/metrics/InstanceHealthMetricsTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/metrics/InstanceHealthMetricsTest.java
@@ -47,11 +47,11 @@ public class InstanceHealthMetricsTest
     InstanceHealthMetrics metrics;
     JmxClient jmxClient;
     CassandraAdapterDelegate delegate;
+    Vertx vertx = Vertx.vertx();
 
     @BeforeEach
     void setup()
     {
-        Vertx vertx = Vertx.vertx();
         CassandraVersionProvider mockCassandraVersionProvider = 
mock(CassandraVersionProvider.class);
         CQLSessionProvider mockCqlSessionProvider = 
mock(CQLSessionProvider.class);
         when(mockCqlSessionProvider.get()).thenThrow(new 
CassandraUnavailableException(JMX, "not available"));
@@ -67,6 +67,7 @@ public class InstanceHealthMetricsTest
     {
         registry().removeMatching((name, metric) -> true);
         registry(1).removeMatching((name, metric) -> true);
+        vertx.close();
     }
 
     @Test
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/metrics/SchemaMetricsTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/metrics/SchemaMetricsTest.java
index 63cdb8fe..f72dde45 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/metrics/SchemaMetricsTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/metrics/SchemaMetricsTest.java
@@ -27,6 +27,7 @@ import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.codahale.metrics.SharedMetricRegistries;
 import com.datastax.driver.core.Session;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
@@ -48,7 +49,6 @@ import org.apache.cassandra.sidecar.server.MainModule;
 import org.apache.cassandra.sidecar.server.Server;
 import org.apache.cassandra.sidecar.tasks.PeriodicTaskExecutor;
 
-import static org.apache.cassandra.sidecar.utils.TestMetricUtils.registry;
 import static org.apache.cassandra.testing.utils.AssertionUtils.loopAssert;
 import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
 import static org.mockito.ArgumentMatchers.any;
@@ -61,7 +61,6 @@ import static org.mockito.Mockito.when;
 class SchemaMetricsTest
 {
     private static final Logger logger = 
LoggerFactory.getLogger(SidecarSchemaTest.class);
-    private Vertx vertx;
     private SidecarSchema sidecarSchema;
     private SidecarMetrics metrics;
     Server server;
@@ -72,7 +71,6 @@ class SchemaMetricsTest
         Injector injector = Guice.createInjector(Modules.override(new 
MainModule())
                                                         
.with(Modules.override(new TestModule())
                                                                      .with(new 
SchemaFailureSimulateModule())));
-        this.vertx = injector.getInstance(Vertx.class);
         server = injector.getInstance(Server.class);
         sidecarSchema = injector.getInstance(SidecarSchema.class);
         metrics = injector.getInstance(SidecarMetrics.class);
@@ -88,8 +86,8 @@ class SchemaMetricsTest
     void tearDown() throws InterruptedException
     {
         CountDownLatch closeLatch = new CountDownLatch(1);
-        registry().removeMatching((name, metric) -> true);
-        vertx.close(result -> closeLatch.countDown());
+        SharedMetricRegistries.clear();
+        server.close().onComplete(result -> closeLatch.countDown());
         if (closeLatch.await(60, TimeUnit.SECONDS))
             logger.info("Close event received before timeout.");
         else
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/restore/RestoreJobManagerTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/restore/RestoreJobManagerTest.java
index 9bc00f79..082f8ab8 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/restore/RestoreJobManagerTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/restore/RestoreJobManagerTest.java
@@ -41,6 +41,7 @@ import com.google.inject.util.Modules;
 import io.vertx.core.Vertx;
 import org.apache.cassandra.sidecar.ExecutorPoolsHelper;
 import org.apache.cassandra.sidecar.TestModule;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import org.apache.cassandra.sidecar.cluster.instance.InstanceMetadata;
 import org.apache.cassandra.sidecar.common.server.cluster.locator.TokenRange;
 import 
org.apache.cassandra.sidecar.common.server.utils.MillisecondBoundConfiguration;
@@ -103,8 +104,7 @@ class RestoreJobManagerTest
     void teardown()
     {
         // close in the fire-and-forget way
-        executorPools.close();
-        vertx.close();
+        TestResourceReaper.create().with(vertx).with(executorPools).close();
     }
 
     @Test
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/restore/RestoreRangeTaskTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/restore/RestoreRangeTaskTest.java
index 72558667..c1c347f9 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/restore/RestoreRangeTaskTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/restore/RestoreRangeTaskTest.java
@@ -42,10 +42,12 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.io.TempDir;
 
+import com.codahale.metrics.SharedMetricRegistries;
 import com.datastax.driver.core.utils.UUIDs;
 import io.vertx.core.Future;
 import io.vertx.core.Promise;
 import io.vertx.core.Vertx;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import org.apache.cassandra.sidecar.cluster.instance.InstanceMetadata;
 import org.apache.cassandra.sidecar.cluster.locator.LocalTokenRangesProvider;
 import org.apache.cassandra.sidecar.common.ResourceUtils;
@@ -93,6 +95,8 @@ import static org.mockito.Mockito.when;
 
 class RestoreRangeTaskTest
 {
+    private Vertx vertx;
+    private ExecutorPools executorPools;
     private RestoreRange mockRange;
     private StorageClient mockStorageClient;
     private SSTableImporter mockSSTableImporter;
@@ -123,7 +127,9 @@ class RestoreRangeTaskTest
         mockRange = spy(range);
         mockStorageClient = mock(StorageClient.class);
         mockSSTableImporter = mock(SSTableImporter.class);
-        executorPool = new ExecutorPools(Vertx.vertx(), new 
ServiceConfigurationImpl()).internal();
+        vertx = Vertx.vertx();
+        executorPools = new ExecutorPools(vertx, new 
ServiceConfigurationImpl());
+        executorPool = executorPools.internal();
         MetricRegistryFactory mockRegistryFactory = 
mock(MetricRegistryFactory.class);
         when(mockRegistryFactory.getOrCreate()).thenReturn(registry());
         when(mockRegistryFactory.getOrCreate(1)).thenReturn(registry(1));
@@ -136,8 +142,8 @@ class RestoreRangeTaskTest
     @AfterEach
     void clear()
     {
-        registry().removeMatching((name, metric) -> true);
-        registry(1).removeMatching((name, metric) -> true);
+        SharedMetricRegistries.clear();
+        TestResourceReaper.create().with(executorPools).with(vertx).close();
     }
 
     @Test
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/routes/AbstractHandlerTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/routes/AbstractHandlerTest.java
index 8d7930f5..40d5296f 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/routes/AbstractHandlerTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/routes/AbstractHandlerTest.java
@@ -62,6 +62,10 @@ class AbstractHandlerTest
     @AfterEach
     void after() throws InterruptedException
     {
+        if (server == null)
+        {
+            return;
+        }
         CountDownLatch closeLatch = new CountDownLatch(1);
         server.close().onSuccess(res -> closeLatch.countDown());
         if (closeLatch.await(60, TimeUnit.SECONDS))
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/routes/VertxRoutingTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/routes/VertxRoutingTest.java
index b9b91af9..6acf0041 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/routes/VertxRoutingTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/routes/VertxRoutingTest.java
@@ -68,6 +68,7 @@ class VertxRoutingTest
         {
             client.close();
         }
+        server.close();
         vertx.close(result -> context.completeNow());
         assertThat(context.awaitCompletion(10, TimeUnit.SECONDS)).isTrue();
     }
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/routes/restore/BaseRestoreJobTests.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/routes/restore/BaseRestoreJobTests.java
index 5a109cc6..816d440d 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/routes/restore/BaseRestoreJobTests.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/routes/restore/BaseRestoreJobTests.java
@@ -20,16 +20,19 @@ package org.apache.cassandra.sidecar.routes.restore;
 
 import java.util.List;
 import java.util.UUID;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Supplier;
 import java.util.function.UnaryOperator;
 
+import com.google.common.util.concurrent.Uninterruptibles;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.extension.ExtendWith;
 
+import com.codahale.metrics.SharedMetricRegistries;
 import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
@@ -177,16 +180,13 @@ public abstract class BaseRestoreJobTests
     }
 
     @AfterEach
-    public void tearDown(VertxTestContext context) throws Throwable
+    public void tearDown() throws Throwable
     {
+        SharedMetricRegistries.clear();
+        CountDownLatch latch = new CountDownLatch(1);
         client.close();
-        vertx.close(result -> context.completeNow());
-        assertThat(context.awaitCompletion(10, TimeUnit.SECONDS)).isTrue();
-        assertThat(vertx.deploymentIDs()).isEmpty();
-        if (context.failed())
-        {
-            throw context.causeOfFailure();
-        }
+        server.close().onComplete(ignored -> latch.countDown());
+        Uninterruptibles.awaitUninterruptibly(latch, 10, TimeUnit.SECONDS);
     }
 
     protected void 
mockCreateRestoreJob(Function<CreateRestoreJobRequestPayload, RestoreJob> func)
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/routes/sstableuploads/BaseUploadsHandlerTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/routes/sstableuploads/BaseUploadsHandlerTest.java
index a5798ade..c0fa8978 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/routes/sstableuploads/BaseUploadsHandlerTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/routes/sstableuploads/BaseUploadsHandlerTest.java
@@ -34,6 +34,7 @@ import org.junit.jupiter.api.io.TempDir;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.codahale.metrics.SharedMetricRegistries;
 import com.datastax.driver.core.KeyspaceMetadata;
 import com.datastax.driver.core.Metadata;
 import com.datastax.driver.core.TableMetadata;
@@ -70,7 +71,6 @@ import static 
org.apache.cassandra.sidecar.config.yaml.TrafficShapingConfigurati
 import static 
org.apache.cassandra.sidecar.config.yaml.TrafficShapingConfigurationImpl.DEFAULT_OUTBOUND_GLOBAL_BANDWIDTH_LIMIT;
 import static 
org.apache.cassandra.sidecar.config.yaml.TrafficShapingConfigurationImpl.DEFAULT_PEAK_OUTBOUND_GLOBAL_BANDWIDTH_LIMIT;
 import static 
org.apache.cassandra.sidecar.snapshots.SnapshotUtils.mockInstancesMetadata;
-import static org.apache.cassandra.sidecar.utils.TestMetricUtils.registry;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -100,8 +100,6 @@ class BaseUploadsHandlerTest
     void setup() throws InterruptedException, IOException
     {
         canonicalTemporaryPath = temporaryPath.toFile().getCanonicalPath();
-        testDelegate = new TestCassandraAdapterDelegate();
-        TestModule testModule = new TestModule();
         mockSSTableUploadConfiguration = 
mock(SSTableUploadConfiguration.class);
         
when(mockSSTableUploadConfiguration.concurrentUploadsLimit()).thenReturn(3);
         
when(mockSSTableUploadConfiguration.minimumSpacePercentageRequired()).thenReturn(0F);
@@ -126,12 +124,15 @@ class BaseUploadsHandlerTest
         sidecarConfiguration = SidecarConfigurationImpl.builder()
                                                        
.serviceConfiguration(serviceConfiguration)
                                                        .build();
-        TestModuleOverride testModuleOverride = new 
TestModuleOverride(testDelegate);
+        TestModule testModule = new TestModule();
+        TestModuleOverride testModuleOverride = new TestModuleOverride();
         Injector injector = Guice.createInjector(Modules.override(new 
MainModule())
                                                         
.with(Modules.override(testModule)
                                                                      
.with(testModuleOverride)));
+
         server = injector.getInstance(Server.class);
         vertx = injector.getInstance(Vertx.class);
+        testDelegate = (TestCassandraAdapterDelegate) 
injector.getInstance(CassandraAdapterDelegate.class);
         client = WebClient.create(vertx);
         ingressFileRateLimiter = 
injector.getInstance(Key.get(SidecarRateLimiter.class,
                                                               
Names.named("IngressFileRateLimiter")));
@@ -158,10 +159,9 @@ class BaseUploadsHandlerTest
     void tearDown() throws InterruptedException
     {
         final CountDownLatch closeLatch = new CountDownLatch(1);
-        registry().removeMatching((name, metric) -> true);
-        registry(1).removeMatching((name, metric) -> true);
+        SharedMetricRegistries.clear();
         client.close();
-        server.close().onSuccess(res -> closeLatch.countDown());
+        server.close().onComplete(res -> closeLatch.countDown());
         if (closeLatch.await(60, TimeUnit.SECONDS))
             logger.debug("Close event received before timeout.");
         else
@@ -205,27 +205,13 @@ class BaseUploadsHandlerTest
 
     class TestModuleOverride extends AbstractModule
     {
-        private final CassandraAdapterDelegate delegate;
-
-        TestModuleOverride(CassandraAdapterDelegate delegate)
-        {
-            this.delegate = delegate;
-        }
-
         @Provides
         @Singleton
-        public InstancesMetadata instancesMetadata(Vertx vertx)
+        public InstancesMetadata instancesMetadata(Vertx vertx, 
CassandraAdapterDelegate delegate)
         {
             return mockInstancesMetadata(vertx, canonicalTemporaryPath, 
delegate, null);
         }
 
-        @Singleton
-        @Provides
-        public CassandraAdapterDelegate delegate()
-        {
-            return delegate;
-        }
-
         @Singleton
         @Provides
         public SidecarConfiguration configuration()
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/server/ServerTest.java 
b/server/src/test/java/org/apache/cassandra/sidecar/server/ServerTest.java
index 50f65a51..e811057f 100644
--- a/server/src/test/java/org/apache/cassandra/sidecar/server/ServerTest.java
+++ b/server/src/test/java/org/apache/cassandra/sidecar/server/ServerTest.java
@@ -20,6 +20,7 @@ package org.apache.cassandra.sidecar.server;
 
 import java.nio.file.Path;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
@@ -30,6 +31,7 @@ import org.junit.jupiter.api.io.TempDir;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.codahale.metrics.SharedMetricRegistries;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import io.netty.handler.codec.http.HttpResponseStatus;
@@ -44,6 +46,7 @@ import 
org.apache.cassandra.sidecar.exceptions.ConfigurationException;
 
 import static 
org.apache.cassandra.sidecar.common.ResourceUtils.writeResourceToPath;
 import static org.apache.cassandra.sidecar.utils.TestMetricUtils.registry;
+import static org.apache.cassandra.testing.utils.AssertionUtils.getBlocking;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatException;
 import static 
org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@@ -63,28 +66,34 @@ class ServerTest
     private Server server;
     private Vertx vertx;
     private WebClient client;
+    private AtomicBoolean serverAlreadyClosedInTest = new AtomicBoolean(false);
 
     @BeforeEach
     void setup()
     {
+        serverAlreadyClosedInTest.set(false);
         configureServer("config/sidecar_single_instance.yaml");
     }
 
     @AfterEach
     void tearDown()
     {
-        registry().removeMatching((name, metric) -> true);
-        if (server != null)
+        SharedMetricRegistries.clear();
+        if (server != null && !serverAlreadyClosedInTest.get())
         {
             try
             {
-                
server.close().toCompletionStage().toCompletableFuture().get(30, 
TimeUnit.SECONDS);
+                
server.close().toCompletionStage().toCompletableFuture().get(5, 
TimeUnit.SECONDS);
             }
             catch (Exception ex)
             {
-                LOGGER.error("Unable to close server after 30 seconds", ex);
+                LOGGER.error("Unable to close server after 5 seconds", ex);
             }
         }
+        if (client != null)
+        {
+            client.close();
+        }
     }
 
     @Test
@@ -153,7 +162,10 @@ class ServerTest
 
         server.start()
               .compose(this::validateHealthEndpoint)
-              .compose(deploymentId -> server.close())
+              .compose(deploymentId -> {
+                  serverAlreadyClosedInTest.set(true);
+                  return server.close();
+              })
               .onFailure(context::failNow);
     }
 
@@ -169,7 +181,10 @@ class ServerTest
 
         server.start()
               .compose(this::validateHealthEndpoint)
-              .compose(deploymentId -> server.close())
+              .compose(deploymentId -> {
+                  serverAlreadyClosedInTest.set(true);
+                  return server.close();
+              })
               .onSuccess(v -> assertThatException().isThrownBy(() -> 
server.start())
                                                    
.withMessageContaining("Vert.x closed"))
               .onFailure(context::failNow);
@@ -222,10 +237,8 @@ class ServerTest
 
                   try
                   {
-                      server.close()
-                            .toCompletionStage()
-                            .toCompletableFuture()
-                            .get(1, TimeUnit.MINUTES);
+                      serverAlreadyClosedInTest.set(true);
+                      getBlocking(server.close(), 1, TimeUnit.MINUTES, "Stop 
server");
                   }
                   catch (Exception e)
                   {
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/tasks/PeriodicTaskExecutorTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/tasks/PeriodicTaskExecutorTest.java
index ccf5ec50..87180113 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/tasks/PeriodicTaskExecutorTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/tasks/PeriodicTaskExecutorTest.java
@@ -36,6 +36,7 @@ import org.junit.jupiter.api.Test;
 import io.vertx.core.Future;
 import io.vertx.core.Promise;
 import io.vertx.core.Vertx;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import org.apache.cassandra.sidecar.common.server.utils.DurationSpec;
 import 
org.apache.cassandra.sidecar.common.server.utils.MillisecondBoundConfiguration;
 import org.apache.cassandra.sidecar.concurrent.ExecutorPools;
@@ -76,8 +77,7 @@ class PeriodicTaskExecutorTest
     @AfterAll
     static void teardown()
     {
-        executorPools.close();
-        vertx.close();
+        TestResourceReaper.create().with(vertx).with(executorPools).close();
     }
 
     @Test
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/utils/AsyncFileSystemUtilsTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/utils/AsyncFileSystemUtilsTest.java
index eab3cc52..c1b38a05 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/utils/AsyncFileSystemUtilsTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/utils/AsyncFileSystemUtilsTest.java
@@ -25,6 +25,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import io.vertx.core.Vertx;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import org.apache.cassandra.sidecar.concurrent.ExecutorPools;
 import org.apache.cassandra.sidecar.config.yaml.ServiceConfigurationImpl;
 import org.apache.cassandra.sidecar.exceptions.InsufficientStorageException;
@@ -38,18 +39,20 @@ import static 
org.assertj.core.api.Assertions.assertThatThrownBy;
 
 class AsyncFileSystemUtilsTest
 {
+    private Vertx vertx;
     private ExecutorPools executorPools;
 
     @BeforeEach
     void setup()
     {
-        executorPools = new ExecutorPools(Vertx.vertx(), new 
ServiceConfigurationImpl());
+        vertx = Vertx.vertx();
+        executorPools = new ExecutorPools(vertx, new 
ServiceConfigurationImpl());
     }
 
     @AfterEach
     void teardown()
     {
-        executorPools.close();
+        TestResourceReaper.create().with(vertx).with(executorPools).close();
     }
 
     @Test
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/utils/DigestVerifierFactoryTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/utils/DigestVerifierFactoryTest.java
index f9460cee..2bead862 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/utils/DigestVerifierFactoryTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/utils/DigestVerifierFactoryTest.java
@@ -18,6 +18,7 @@
 
 package org.apache.cassandra.sidecar.utils;
 
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -43,6 +44,12 @@ class DigestVerifierFactoryTest
         options = new HeadersMultiMap();
     }
 
+    @AfterEach
+    void cleanup()
+    {
+        vertx.close();
+    }
+
     @Test
     void testEmptyFactoryReturnsFallbackVerifier()
     {
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/utils/MD5DigestVerifierTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/utils/MD5DigestVerifierTest.java
index 3aa374d4..fb6de409 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/utils/MD5DigestVerifierTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/utils/MD5DigestVerifierTest.java
@@ -27,6 +27,7 @@ import java.util.Base64;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.io.TempDir;
@@ -56,6 +57,12 @@ class MD5DigestVerifierTest
         vertx = Vertx.vertx();
     }
 
+    @AfterAll
+    static void cleanup()
+    {
+        vertx.close();
+    }
+
     @Test
     void testFileDescriptorsClosedWithValidDigest() throws IOException, 
NoSuchAlgorithmException,
                                                            InterruptedException
diff --git 
a/server/src/test/java/org/apache/cassandra/sidecar/utils/SSTableImporterTest.java
 
b/server/src/test/java/org/apache/cassandra/sidecar/utils/SSTableImporterTest.java
index b993ebad..95a0ee44 100644
--- 
a/server/src/test/java/org/apache/cassandra/sidecar/utils/SSTableImporterTest.java
+++ 
b/server/src/test/java/org/apache/cassandra/sidecar/utils/SSTableImporterTest.java
@@ -35,6 +35,7 @@ import io.vertx.core.Vertx;
 import io.vertx.ext.web.handler.HttpException;
 import io.vertx.junit5.VertxExtension;
 import io.vertx.junit5.VertxTestContext;
+import org.apache.cassandra.sidecar.TestResourceReaper;
 import org.apache.cassandra.sidecar.cluster.CassandraAdapterDelegate;
 import org.apache.cassandra.sidecar.cluster.instance.InstanceMetadata;
 import org.apache.cassandra.sidecar.common.server.TableOperations;
@@ -125,6 +126,7 @@ class SSTableImporterTest
     void clear()
     {
         SharedMetricRegistries.clear();
+        TestResourceReaper.create().with(vertx).with(executorPools).close();
     }
 
     @Test
diff --git a/server/src/test/resources/config/sidecar_cdc.yaml 
b/server/src/test/resources/config/sidecar_cdc.yaml
index a32c39b4..070991b4 100644
--- a/server/src/test/resources/config/sidecar_cdc.yaml
+++ b/server/src/test/resources/config/sidecar_cdc.yaml
@@ -59,7 +59,7 @@ sidecar:
   cdc:
     segment_hardlink_cache_expiry: 1m # 1 minute
   jmx:
-    max_retries: 42
+    max_retries: 1
     retry_delay: 1234ms
   schema:
     is_enabled: false
diff --git 
a/server/src/test/resources/config/sidecar_invalid_accesscontrol_config.yaml 
b/server/src/test/resources/config/sidecar_invalid_accesscontrol_config.yaml
index 475c93a8..d9633d1e 100644
--- a/server/src/test/resources/config/sidecar_invalid_accesscontrol_config.yaml
+++ b/server/src/test/resources/config/sidecar_invalid_accesscontrol_config.yaml
@@ -56,7 +56,7 @@ sidecar:
       size: 20
       max_execution_time: 15m # 15 minutes
   jmx:
-    max_retries: 42
+    max_retries: 1
     retry_delay: 1234ms
   schema:
     is_enabled: false
diff --git a/server/src/test/resources/config/sidecar_metrics.yaml 
b/server/src/test/resources/config/sidecar_metrics.yaml
index dc477f83..a216e8ba 100644
--- a/server/src/test/resources/config/sidecar_metrics.yaml
+++ b/server/src/test/resources/config/sidecar_metrics.yaml
@@ -41,7 +41,7 @@ sidecar:
     timeout: 10s
   allowable_time_skew: 1h
   jmx:
-    max_retries: 42
+    max_retries: 1
     retry_delay: 1234ms
 
 #
diff --git 
a/server/src/test/resources/config/sidecar_metrics_empty_filters.yaml 
b/server/src/test/resources/config/sidecar_metrics_empty_filters.yaml
index 472bfead..67a1c205 100644
--- a/server/src/test/resources/config/sidecar_metrics_empty_filters.yaml
+++ b/server/src/test/resources/config/sidecar_metrics_empty_filters.yaml
@@ -41,7 +41,7 @@ sidecar:
     timeout: 10s
   allowable_time_skew: 1h
   jmx:
-    max_retries: 42
+    max_retries: 1
     retry_delay: 1234ms
 
 #
diff --git a/server/src/test/resources/config/sidecar_multiple_instances.yaml 
b/server/src/test/resources/config/sidecar_multiple_instances.yaml
index 4aafdc4e..9bf9e44d 100644
--- a/server/src/test/resources/config/sidecar_multiple_instances.yaml
+++ b/server/src/test/resources/config/sidecar_multiple_instances.yaml
@@ -113,7 +113,7 @@ sidecar:
       size: 20
       max_execution_time: 15m # 15 minutes
   jmx:
-    max_retries: 42
+    max_retries: 1
     retry_delay: 1234ms
   coordination:
     cluster_lease_claim:
diff --git a/server/src/test/resources/config/sidecar_no_local_instances.yaml 
b/server/src/test/resources/config/sidecar_no_local_instances.yaml
index a515ecf2..10948884 100644
--- a/server/src/test/resources/config/sidecar_no_local_instances.yaml
+++ b/server/src/test/resources/config/sidecar_no_local_instances.yaml
@@ -40,7 +40,7 @@ sidecar:
       size: 20
       max_execution_time: 15m # 15 minutes
   jmx:
-    max_retries: 42
+    max_retries: 1
     retry_delay: 1234ms
 
 #
diff --git 
a/server/src/test/resources/config/sidecar_schema_keyspace_configuration.yaml 
b/server/src/test/resources/config/sidecar_schema_keyspace_configuration.yaml
index 6232cc58..60c96e96 100644
--- 
a/server/src/test/resources/config/sidecar_schema_keyspace_configuration.yaml
+++ 
b/server/src/test/resources/config/sidecar_schema_keyspace_configuration.yaml
@@ -52,7 +52,7 @@ sidecar:
       size: 20
       max_execution_time: 15m # 15 minutes
   jmx:
-    max_retries: 42
+    max_retries: 1
     retry_delay: 1234ms
   schema:
     is_enabled: true
diff --git a/server/src/test/resources/config/sidecar_single_instance.yaml 
b/server/src/test/resources/config/sidecar_single_instance.yaml
index 006564bd..1e729a31 100644
--- a/server/src/test/resources/config/sidecar_single_instance.yaml
+++ b/server/src/test/resources/config/sidecar_single_instance.yaml
@@ -56,7 +56,7 @@ sidecar:
       size: 20
       max_execution_time: 15m # 15 minutes
   jmx:
-    max_retries: 42
+    max_retries: 1
     retry_delay: 1234ms
   schema:
     is_enabled: false
diff --git 
a/server/src/test/resources/config/sidecar_single_instance_non_zero_port.yaml 
b/server/src/test/resources/config/sidecar_single_instance_non_zero_port.yaml
index 6e8b7393..3e5438c7 100644
--- 
a/server/src/test/resources/config/sidecar_single_instance_non_zero_port.yaml
+++ 
b/server/src/test/resources/config/sidecar_single_instance_non_zero_port.yaml
@@ -56,7 +56,7 @@ sidecar:
       size: 20
       max_execution_time: 15m # 15 minutes
   jmx:
-    max_retries: 42
+    max_retries: 1
     retry_delay: 1234ms
   schema:
     is_enabled: false
diff --git 
a/server/src/test/resources/config/sidecar_unrecognized_authenticator.yaml 
b/server/src/test/resources/config/sidecar_unrecognized_authenticator.yaml
index f6b4d7f4..da8a862a 100644
--- a/server/src/test/resources/config/sidecar_unrecognized_authenticator.yaml
+++ b/server/src/test/resources/config/sidecar_unrecognized_authenticator.yaml
@@ -56,7 +56,7 @@ sidecar:
       size: 20
       max_execution_time: 15m # 15 minutes
   jmx:
-    max_retries: 42
+    max_retries: 1
     retry_delay: 1234ms
   schema:
     is_enabled: false
diff --git 
a/server/src/test/resources/config/sidecar_unrecognized_authorizer.yaml 
b/server/src/test/resources/config/sidecar_unrecognized_authorizer.yaml
index 0987a975..7a2655f7 100644
--- a/server/src/test/resources/config/sidecar_unrecognized_authorizer.yaml
+++ b/server/src/test/resources/config/sidecar_unrecognized_authorizer.yaml
@@ -56,7 +56,7 @@ sidecar:
       size: 20
       max_execution_time_millis: 900000 # 15 minutes
   jmx:
-    max_retries: 42
+    max_retries: 1
     retry_delay_millis: 1234
   schema:
     is_enabled: false
diff --git 
a/server/src/test/resources/config/sidecar_vertx_filesystem_options.yaml 
b/server/src/test/resources/config/sidecar_vertx_filesystem_options.yaml
index 09471f58..32dc3981 100644
--- a/server/src/test/resources/config/sidecar_vertx_filesystem_options.yaml
+++ b/server/src/test/resources/config/sidecar_vertx_filesystem_options.yaml
@@ -56,7 +56,7 @@ sidecar:
       size: 20
       max_execution_time: 15m # 15 minutes
   jmx:
-    max_retries: 42
+    max_retries: 1
     retry_delay: 1234ms
   schema:
     is_enabled: false
diff --git 
a/server/src/testFixtures/java/org/apache/cassandra/sidecar/snapshots/AbstractSnapshotPathBuilderTest.java
 
b/server/src/testFixtures/java/org/apache/cassandra/sidecar/snapshots/AbstractSnapshotPathBuilderTest.java
index cc07df85..ec343c81 100644
--- 
a/server/src/testFixtures/java/org/apache/cassandra/sidecar/snapshots/AbstractSnapshotPathBuilderTest.java
+++ 
b/server/src/testFixtures/java/org/apache/cassandra/sidecar/snapshots/AbstractSnapshotPathBuilderTest.java
@@ -62,7 +62,7 @@ public abstract class AbstractSnapshotPathBuilderTest
     protected File dataDir1;
 
     protected SnapshotPathBuilder instance;
-    protected Vertx vertx = Vertx.vertx();
+    protected Vertx vertx;
     protected ExecutorPools executorPools;
 
     @SuppressWarnings("ResultOfMethodCallIgnored")
@@ -174,6 +174,8 @@ public abstract class AbstractSnapshotPathBuilderTest
     {
         dataDir0.delete();
         dataDir1.delete();
+        vertx.close();
+        executorPools.close();
     }
 
     protected abstract SnapshotPathBuilder initialize(Vertx vertx,
diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml
index 2e53e520..a6aca58d 100644
--- a/spotbugs-exclude.xml
+++ b/spotbugs-exclude.xml
@@ -121,6 +121,13 @@
     </Match>
 
     <Match>
+        <!-- Unchecked cast warning -->
+        <Bug pattern="BC_UNCONFIRMED_CAST"/>
+        <Class name="org.apache.cassandra.sidecar.TestModule"/>
+        <Method name="instancesMetadata"/>
+   </Match>
+
+   <Match>
         <Bug pattern="SF_SWITCH_FALLTHROUGH" />
         <Class 
name="org.apache.cassandra.sidecar.restore.RestoreJobDiscoverer" /><!-- on 
break by design -->
     </Match>
diff --git 
a/test-common/src/testFixtures/java/org/apache/cassandra/testing/utils/AssertionUtils.java
 
b/test-common/src/testFixtures/java/org/apache/cassandra/testing/utils/AssertionUtils.java
index 4a49fb60..0ed7a52e 100644
--- 
a/test-common/src/testFixtures/java/org/apache/cassandra/testing/utils/AssertionUtils.java
+++ 
b/test-common/src/testFixtures/java/org/apache/cassandra/testing/utils/AssertionUtils.java
@@ -103,7 +103,7 @@ public class AssertionUtils
         }
         catch (TimeoutException te)
         {
-            throw new AssertionError('(' + hint + ") timed out after " + 
timeout + ' ' + timeUnit);
+            throw new AssertionError('(' + hint + ") timed out after " + 
timeout + ' ' + timeUnit, te);
         }
         catch (Exception exception)
         {
diff --git 
a/vertx-auth-mtls/src/test/java/io/vertx/ext/auth/mtls/impl/MutualTlsAuthenticationProviderTest.java
 
b/vertx-auth-mtls/src/test/java/io/vertx/ext/auth/mtls/impl/MutualTlsAuthenticationProviderTest.java
index e1da4a53..d3ed4e70 100644
--- 
a/vertx-auth-mtls/src/test/java/io/vertx/ext/auth/mtls/impl/MutualTlsAuthenticationProviderTest.java
+++ 
b/vertx-auth-mtls/src/test/java/io/vertx/ext/auth/mtls/impl/MutualTlsAuthenticationProviderTest.java
@@ -26,6 +26,7 @@ import java.time.temporal.ChronoUnit;
 import java.util.Collections;
 import java.util.List;
 
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -52,7 +53,7 @@ import static org.mockito.Mockito.when;
  * Tests {@link MutualTlsAuthenticationImpl}
  */
 @ExtendWith(VertxExtension.class)
-public class MutualTlsAuthenticationProviderTest
+class MutualTlsAuthenticationProviderTest
 {
     private static final CertificateValidator ALLOW_ALL_CERTIFICATE_VALIDATOR 
= new AllowAllCertificateValidator();
     Vertx vertx;
@@ -60,12 +61,18 @@ public class MutualTlsAuthenticationProviderTest
     SelfSignedCertificate validCert;
 
     @BeforeEach
-    public void setUp() throws CertificateException
+    void setUp() throws CertificateException
     {
         vertx = Vertx.vertx();
         validCert = new SelfSignedCertificate();
     }
 
+    @AfterEach
+    void cleanup()
+    {
+        vertx.close();
+    }
+
     @Test
     public void testSuccess(VertxTestContext context)
     {
diff --git a/vertx-client/build.gradle b/vertx-client/build.gradle
index 25ca2ef8..11ffff50 100644
--- a/vertx-client/build.gradle
+++ b/vertx-client/build.gradle
@@ -33,9 +33,6 @@ sourceCompatibility = 1.8
 
 test {
     useJUnitPlatform()
-    if (Os.isFamily(Os.FAMILY_MAC)) {
-        jvmArgs "-XX:-MaxFDLimit"
-    }
     maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
     reports {
         junitXml.setRequired(true)


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to