Adds a router to SNI proxy topology. (#137)

* Update JUnit
* Adds withRouter option.
* Adds withRouterImage option.
diff --git a/README.md b/README.md
index 9d662da..b49a9a9 100644
--- a/README.md
+++ b/README.md
@@ -57,6 +57,8 @@
     -PwithSecurityManager : Flag to start Geode with the example implementation of SecurityManager
     -PwithSniProxy        : Use SNI proxy topology.
     -PwithSniProxyImage   : Provide an alternative Docker image coordinate for SNI proxy.
+    -PwithRouter          : Use router with SNI proxy topology.
+    -PwithRouterImage     : Provide an alternative Docker image coordinate for router.
     -PwithGc              : Select which GC to use. Valid values CMS (default), G1, Z.
     -PwithHeap            : Specify how large a heap the benchmark VMs should use, default "8g". Accepts any `-Xmx` value, like "32g".
     -PwithThreads         : Specify how many threads to use when executing the benchmark. Default varies by benchmark.
@@ -164,9 +166,24 @@
 The `withSniProxyImage` property can be used to provide an alternative Docker image to one of the 
 supported proxy implementations. The value should be set to a valid Docker image coordinate. 
  
-To run a test, e.g. `PartitionedGetBenchmark`, with HAProxy SNI Proxy:
-
-`./run_tests.sh -t anytagname -- -PwithSniProxy=HAProxy --tests=PartitionedGetBenchmark`
+To run a test, e.g. `PartitionedGetBenchmark`, with default SNI Proxy:
+```console
+./run_tests.sh -t anytagname -- -PwithSniProxy --tests=PartitionedGetBenchmark
+```
 
 Since SNI is a feature of TLS, running with the SNI topology incurs TLS overheads with implied `-PwithSsl`.
 
+### Router
+An alternative topology uses a router sitting in front of the SNI proxy to simulate off network access
+to the cluster, enabled with `-PwithRouter`.
+
+Enabling the router implies `-PwithSniProxy`.
+
+The `withRouter` property accepts:
+ * `HAProxy` for HAProxy based router (default).
+ * `Manual` for providing your own router and managing its lifecycle.
+
+Example:
+```console
+./run_tests.sh -t anytagname -- -PwithRouter --tests=PartitionedGetBenchmark
+```
diff --git a/geode-benchmarks/build.gradle b/geode-benchmarks/build.gradle
index c58f7ea..b35b7ef 100644
--- a/geode-benchmarks/build.gradle
+++ b/geode-benchmarks/build.gradle
@@ -113,6 +113,11 @@
   }
   systemProperty 'withSniProxyImage', project.findProperty('withSniProxyImage')
 
+  if (project.hasProperty('withRouter')) {
+    systemProperty 'withRouter', project.findProperty('withRouter')
+  }
+  systemProperty 'withRouterImage', project.findProperty('withRouterImage')
+
   systemProperty 'withSecurityManager', project.hasProperty('withSecurityManager')
   systemProperty 'benchmark.profiler.argument', project.findProperty('benchmark.profiler.argument')
 
diff --git a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartClientSNI.java b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartClientWithSniProxy.java
similarity index 89%
rename from geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartClientSNI.java
rename to geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartClientWithSniProxy.java
index 76fe1c7..643d5bb 100644
--- a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartClientSNI.java
+++ b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartClientWithSniProxy.java
@@ -17,23 +17,25 @@
 
 package org.apache.geode.benchmark.tasks;
 
-import static org.apache.geode.benchmark.topology.Roles.PROXY;
-
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.util.Properties;
 
+import org.apache.geode.benchmark.topology.Roles;
 import org.apache.geode.cache.client.ClientCacheFactory;
 import org.apache.geode.perftest.TestContext;
 
-public class StartClientSNI extends StartClient {
+public class StartClientWithSniProxy extends StartClient {
 
   private final int proxyPort;
+  private final Roles proxyRole;
 
-  public StartClientSNI(final int locatorPort, final int proxyPort) {
+  public StartClientWithSniProxy(final int locatorPort, final int proxyPort,
+      final Roles proxyRole) {
     super(locatorPort);
     this.proxyPort = proxyPort;
+    this.proxyRole = proxyRole;
   }
 
   @Override
@@ -48,7 +50,7 @@
         super.createClientCacheFactory(locator, statsFile, properties, context);
 
     final InetAddress proxyInetAddress =
-        context.getHostsForRole(PROXY.name()).stream().findFirst().get();
+        context.getHostsForRole(proxyRole.name()).stream().findFirst().get();
     return reflectivelySetSniSocketFactory(cacheFactory, proxyInetAddress);
   }
 
diff --git a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartEnvoy.java b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartEnvoy.java
index a32b476..49ae0d8 100644
--- a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartEnvoy.java
+++ b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartEnvoy.java
@@ -169,11 +169,12 @@
     final StartEnvoy that = (StartEnvoy) o;
     return locatorPort == that.locatorPort &&
         serverPort == that.serverPort &&
-        proxyPort == that.proxyPort;
+        proxyPort == that.proxyPort &&
+        Objects.equals(image, that.image);
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(locatorPort, serverPort, proxyPort);
+    return Objects.hash(locatorPort, serverPort, proxyPort, image);
   }
 }
diff --git a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartHAProxy.java b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartHAProxy.java
index be12957..543c96b 100644
--- a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartHAProxy.java
+++ b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartHAProxy.java
@@ -132,11 +132,12 @@
     final StartHAProxy that = (StartHAProxy) o;
     return locatorPort == that.locatorPort &&
         serverPort == that.serverPort &&
-        proxyPort == that.proxyPort;
+        proxyPort == that.proxyPort &&
+        Objects.equals(image, that.image);
   }
 
   @Override
   public int hashCode() {
-    return Objects.hash(locatorPort, serverPort, proxyPort);
+    return Objects.hash(locatorPort, serverPort, proxyPort, image);
   }
 }
diff --git a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartRouter.java b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartRouter.java
new file mode 100644
index 0000000..473d4d9
--- /dev/null
+++ b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartRouter.java
@@ -0,0 +1,122 @@
+/*
+ * 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.geode.benchmark.tasks;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
+import static java.lang.String.format;
+import static java.lang.System.getProperty;
+import static org.apache.geode.benchmark.topology.Roles.PROXY;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+import org.apache.geode.perftest.Task;
+import org.apache.geode.perftest.TestContext;
+
+/**
+ * Task to start the SNI proxy
+ */
+public class StartRouter implements Task {
+  public static final String START_DOCKER_DAEMON_COMMAND = "sudo service docker start";
+  public static final String START_ROUTER_COMMAND =
+      "docker run --rm -d -v %s:/usr/local/etc/haproxy:ro --name router -p %d:%d %s";
+
+  private final int proxyPort;
+  private final String image;
+
+  public StartRouter(final int proxyPort, final String image) {
+    this.proxyPort = proxyPort;
+    this.image = isNullOrEmpty(image) ? "haproxy:1.8-alpine" : image;
+  }
+
+  @Override
+  public void run(final TestContext context) throws Exception {
+
+    final Path configPath = Paths.get(getProperty("user.home")).toAbsolutePath();
+    final Path configFile = configPath.resolve("haproxy.cfg");
+    rewriteFile(generateConfig(context), configFile);
+
+    final ProcessControl processControl = new ProcessControl();
+    processControl.runCommand(START_DOCKER_DAEMON_COMMAND);
+    processControl
+        .runCommand(format(START_ROUTER_COMMAND, configPath, proxyPort, proxyPort, image));
+  }
+
+  private void rewriteFile(final String content, final Path path) throws IOException {
+    try (final BufferedWriter writer = new BufferedWriter(new FileWriter(path.toFile(), false))) {
+      writer.write(content);
+    }
+  }
+
+  String generateConfig(final TestContext context) {
+
+    final Set<InetSocketAddress> members = new HashSet<>();
+
+    context.getHostsForRole(PROXY.name()).stream()
+        .map(a -> InetSocketAddress.createUnresolved(a.getHostName(), proxyPort))
+        .forEachOrdered(members::add);
+
+    return generateConfig(members);
+  }
+
+  String generateConfig(final Set<InetSocketAddress> members) {
+    StringBuilder conf = new StringBuilder("global\n"
+        + "  daemon\n"
+        + "  maxconn 64000\n"
+        + "  spread-checks 4\n"
+        + "defaults\n"
+        + "  log global\n"
+        + "  timeout connect 30000ms\n"
+        + "  timeout client 30000ms\n"
+        + "  timeout server 30000ms\n"
+        + "listen router\n"
+        + "  bind *:").append(proxyPort).append("\n"
+            + "  mode tcp\n");
+    members
+        .forEach(s -> conf.append("  server ").append(s.getHostName()).append(" ")
+            .append(s.getHostName())
+            .append(":").append(s.getPort()).append("\n"));
+
+    return conf.toString();
+  }
+
+  @Override
+  public boolean equals(final Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+    final StartRouter that = (StartRouter) o;
+    return proxyPort == that.proxyPort &&
+        Objects.equals(image, that.image);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(proxyPort, image);
+  }
+}
diff --git a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StopRouter.java b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StopRouter.java
new file mode 100644
index 0000000..7ff02d0
--- /dev/null
+++ b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StopRouter.java
@@ -0,0 +1,36 @@
+/*
+ * 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.geode.benchmark.tasks;
+
+import org.apache.geode.perftest.Task;
+import org.apache.geode.perftest.TestContext;
+
+/**
+ * Task to stop the SNI proxy
+ */
+public class StopRouter implements Task {
+
+  public static final String STOP_PROXY_COMMAND = "docker kill router";
+
+  @Override
+  public void run(TestContext context) throws Exception {
+    final ProcessControl processControl = new ProcessControl();
+    processControl.runCommand(STOP_PROXY_COMMAND);
+  }
+
+}
diff --git a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tests/ClientServerBenchmark.java b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tests/ClientServerBenchmark.java
index b4ecf76..1d4c6c7 100644
--- a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tests/ClientServerBenchmark.java
+++ b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tests/ClientServerBenchmark.java
@@ -15,25 +15,25 @@
 
 package org.apache.geode.benchmark.tests;
 
+import static org.apache.geode.benchmark.topology.ClientServerTopologyWithRouterAndSniProxy.WITH_ROUTER_PROPERTY;
+import static org.apache.geode.benchmark.topology.ClientServerTopologyWithSniProxy.WITH_SNI_PROXY_PROPERTY;
+
+import java.util.Properties;
 
 import org.apache.geode.benchmark.topology.ClientServerTopology;
-import org.apache.geode.benchmark.topology.ClientServerTopologyWithSNIProxy;
-import org.apache.geode.benchmark.topology.ClientServerTopologyWithSNIProxy.SniProxyImplementation;
+import org.apache.geode.benchmark.topology.ClientServerTopologyWithRouterAndSniProxy;
+import org.apache.geode.benchmark.topology.ClientServerTopologyWithSniProxy;
 import org.apache.geode.perftest.TestConfig;
 
 public class ClientServerBenchmark extends GeodeBenchmark {
-
-
   public static TestConfig createConfig() {
     final TestConfig config = GeodeBenchmark.createConfig();
 
-    String sniProp = System.getProperty("withSniProxy");
-    if (sniProp != null) {
-      if (sniProp.isEmpty()) {
-        sniProp = SniProxyImplementation.HAProxy.name();
-      }
-      ClientServerTopologyWithSNIProxy.configure(config,
-          SniProxyImplementation.valueOfIgnoreCase(sniProp));
+    final Properties properties = System.getProperties();
+    if (properties.containsKey(WITH_ROUTER_PROPERTY)) {
+      ClientServerTopologyWithRouterAndSniProxy.configure(config);
+    } else if (properties.containsKey(WITH_SNI_PROXY_PROPERTY)) {
+      ClientServerTopologyWithSniProxy.configure(config);
     } else {
       ClientServerTopology.configure(config);
     }
diff --git a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithRouterAndSniProxy.java b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithRouterAndSniProxy.java
new file mode 100644
index 0000000..502df52
--- /dev/null
+++ b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithRouterAndSniProxy.java
@@ -0,0 +1,98 @@
+/*
+ * 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.geode.benchmark.topology;
+
+import static org.apache.geode.benchmark.Config.after;
+import static org.apache.geode.benchmark.Config.before;
+import static org.apache.geode.benchmark.Config.role;
+import static org.apache.geode.benchmark.topology.ClientServerTopologyWithRouterAndSniProxy.RouterImplementation.HAProxy;
+import static org.apache.geode.benchmark.topology.ClientServerTopologyWithRouterAndSniProxy.RouterImplementation.Manual;
+import static org.apache.geode.benchmark.topology.Ports.LOCATOR_PORT;
+import static org.apache.geode.benchmark.topology.Ports.SNI_PROXY_PORT;
+import static org.apache.geode.benchmark.topology.Roles.CLIENT;
+import static org.apache.geode.benchmark.topology.Roles.LOCATOR;
+import static org.apache.geode.benchmark.topology.Roles.PROXY;
+import static org.apache.geode.benchmark.topology.Roles.ROUTER;
+import static org.apache.geode.benchmark.topology.Roles.SERVER;
+
+import com.google.common.base.Strings;
+
+import org.apache.geode.benchmark.tasks.StartClientWithSniProxy;
+import org.apache.geode.benchmark.tasks.StartRouter;
+import org.apache.geode.benchmark.tasks.StopRouter;
+import org.apache.geode.perftest.TestConfig;
+
+public class ClientServerTopologyWithRouterAndSniProxy extends ClientServerTopologyWithSniProxy {
+  public static final String WITH_ROUTER_PROPERTY = "withRouter";
+  public static final String WITH_ROUTER_IMAGE_PROPERTY = "withRouterImage";
+
+  private static final int NUM_LOCATORS = 1;
+  private static final int NUM_SERVERS = 2;
+  private static final int NUM_CLIENTS = 1;
+  private static final int NUM_PROXIES = 1;
+  private static final int NUM_ROUTERS = 1;
+
+  public enum RouterImplementation {
+    Manual,
+    HAProxy;
+
+    public static RouterImplementation valueOfIgnoreCase(String name) {
+      name = name.toLowerCase();
+      for (RouterImplementation routerImplementation : RouterImplementation.values()) {
+        if (routerImplementation.name().toLowerCase().equals(name)) {
+          return routerImplementation;
+        }
+      }
+      throw new IllegalArgumentException();
+    }
+  }
+
+  public static void configure(final TestConfig config) {
+    role(config, LOCATOR, NUM_LOCATORS);
+    role(config, SERVER, NUM_SERVERS);
+    role(config, CLIENT, NUM_CLIENTS);
+    role(config, PROXY, NUM_PROXIES);
+    role(config, ROUTER, NUM_ROUTERS);
+
+    configureBefore(config);
+
+    final String image = System.getProperty(WITH_ROUTER_IMAGE_PROPERTY);
+    switch (getRouterImplementation()) {
+      case HAProxy:
+        before(config, new StartRouter(SNI_PROXY_PORT, image), ROUTER);
+        break;
+      case Manual:
+        // expect router already configured
+    }
+
+    before(config, new StartClientWithSniProxy(LOCATOR_PORT, SNI_PROXY_PORT, ROUTER), CLIENT);
+
+    configureAfter(config);
+
+    if (Manual != getRouterImplementation()) {
+      after(config, new StopRouter(), ROUTER);
+    }
+  }
+
+  private static RouterImplementation getRouterImplementation() {
+    final String router = System.getProperty(WITH_ROUTER_PROPERTY);
+    if (Strings.isNullOrEmpty(router)) {
+      return HAProxy;
+    }
+
+    return RouterImplementation.valueOfIgnoreCase(router);
+  }
+
+}
diff --git a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithSNIProxy.java b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithSniProxy.java
similarity index 72%
rename from geode-benchmarks/src/main/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithSNIProxy.java
rename to geode-benchmarks/src/main/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithSniProxy.java
index 0dd157b..cf6f8ca 100644
--- a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithSNIProxy.java
+++ b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithSniProxy.java
@@ -18,7 +18,8 @@
 import static org.apache.geode.benchmark.Config.before;
 import static org.apache.geode.benchmark.Config.role;
 import static org.apache.geode.benchmark.parameters.Utils.configureGeodeProductJvms;
-import static org.apache.geode.benchmark.topology.ClientServerTopologyWithSNIProxy.SniProxyImplementation.Manual;
+import static org.apache.geode.benchmark.topology.ClientServerTopologyWithSniProxy.SniProxyImplementation.HAProxy;
+import static org.apache.geode.benchmark.topology.ClientServerTopologyWithSniProxy.SniProxyImplementation.Manual;
 import static org.apache.geode.benchmark.topology.Ports.LOCATOR_PORT;
 import static org.apache.geode.benchmark.topology.Ports.SERVER_PORT;
 import static org.apache.geode.benchmark.topology.Ports.SNI_PROXY_PORT;
@@ -27,7 +28,9 @@
 import static org.apache.geode.benchmark.topology.Roles.PROXY;
 import static org.apache.geode.benchmark.topology.Roles.SERVER;
 
-import org.apache.geode.benchmark.tasks.StartClientSNI;
+import com.google.common.base.Strings;
+
+import org.apache.geode.benchmark.tasks.StartClientWithSniProxy;
 import org.apache.geode.benchmark.tasks.StartEnvoy;
 import org.apache.geode.benchmark.tasks.StartHAProxy;
 import org.apache.geode.benchmark.tasks.StartLocator;
@@ -36,7 +39,10 @@
 import org.apache.geode.benchmark.tasks.StopSniProxy;
 import org.apache.geode.perftest.TestConfig;
 
-public class ClientServerTopologyWithSNIProxy extends Topology {
+public class ClientServerTopologyWithSniProxy extends Topology {
+  public static final String WITH_SNI_PROXY_PROPERTY = "withSniProxy";
+  public static final String WITH_SNI_PROXY_IMAGE_PROPERTY = "withSniProxyImage";
+
   private static final int NUM_LOCATORS = 1;
   private static final int NUM_SERVERS = 2;
   private static final int NUM_CLIENTS = 1;
@@ -58,13 +64,20 @@
     }
   }
 
-  public static void configure(final TestConfig config,
-      final SniProxyImplementation sniProxyImplementation) {
+  public static void configure(final TestConfig config) {
     role(config, LOCATOR, NUM_LOCATORS);
     role(config, SERVER, NUM_SERVERS);
     role(config, CLIENT, NUM_CLIENTS);
     role(config, PROXY, NUM_PROXIES);
 
+    configureBefore(config);
+
+    before(config, new StartClientWithSniProxy(LOCATOR_PORT, SNI_PROXY_PORT, PROXY), CLIENT);
+
+    configureAfter(config);
+  }
+
+  protected static void configureBefore(final TestConfig config) {
     configureCommon(config);
 
     configureGeodeProductJvms(config, WITH_SSL_ARGUMENT);
@@ -72,9 +85,8 @@
     before(config, new StartLocator(LOCATOR_PORT), LOCATOR);
     before(config, new StartServer(LOCATOR_PORT, SERVER_PORT), SERVER);
 
-    final String image = System.getProperty("withSniProxyImage");
-
-    switch (sniProxyImplementation) {
+    final String image = System.getProperty(WITH_SNI_PROXY_IMAGE_PROPERTY);
+    switch (getSniProxyImplementation()) {
       case HAProxy:
         before(config, new StartHAProxy(LOCATOR_PORT, SERVER_PORT, SNI_PROXY_PORT, image), PROXY);
         break;
@@ -84,14 +96,23 @@
       case Manual:
         // expect proxy already configured.
     }
+  }
 
-    before(config, new StartClientSNI(LOCATOR_PORT, SNI_PROXY_PORT), CLIENT);
-
+  protected static void configureAfter(final TestConfig config) {
     after(config, new StopClient(), CLIENT);
 
-    if (Manual != sniProxyImplementation) {
+    if (Manual != getSniProxyImplementation()) {
       after(config, new StopSniProxy(), PROXY);
     }
   }
 
+  private static SniProxyImplementation getSniProxyImplementation() {
+    final String sniProp = System.getProperty(WITH_SNI_PROXY_PROPERTY);
+    if (Strings.isNullOrEmpty(sniProp)) {
+      return HAProxy;
+    }
+
+    return SniProxyImplementation.valueOfIgnoreCase(sniProp);
+  }
+
 }
diff --git a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/topology/Roles.java b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/topology/Roles.java
index 82cb9aa..a3842aa 100644
--- a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/topology/Roles.java
+++ b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/topology/Roles.java
@@ -27,7 +27,8 @@
   SERVER(GEODE_PRODUCT),
   CLIENT(GEODE_PRODUCT),
   LOCATOR(GEODE_PRODUCT),
-  PROXY(SUPPORTING);
+  PROXY(SUPPORTING),
+  ROUTER(SUPPORTING);
 
   public final RoleKinds roleKind;
 
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tasks/StartEnvoyTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tasks/StartEnvoyTest.java
index cc1b459..eb9e6ed 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tasks/StartEnvoyTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tasks/StartEnvoyTest.java
@@ -129,4 +129,22 @@
         + "            name: geode_cluster_dns_cache_config\n"
         + "            dns_lookup_family: V4_ONLY\n");
   }
+
+  @Test
+  public void equals() {
+    assertThat(new StartEnvoy(1, 2, 3, null)).isEqualTo(new StartEnvoy(1, 2, 3, null));
+    assertThat(new StartEnvoy(1, 2, 3, "a")).isEqualTo(new StartEnvoy(1, 2, 3, "a"));
+    assertThat(new StartEnvoy(1, 2, 3, "a")).isNotEqualTo(new StartEnvoy(1, 2, 3, "b"));
+  }
+
+  @Test
+  public void hashcode() {
+    assertThat(new StartEnvoy(1, 2, 3, null).hashCode())
+        .isEqualTo(new StartEnvoy(1, 2, 3, null).hashCode());
+    assertThat(new StartEnvoy(1, 2, 3, "a").hashCode())
+        .isEqualTo(new StartEnvoy(1, 2, 3, "a").hashCode());
+    assertThat(new StartEnvoy(1, 2, 3, "a").hashCode())
+        .isNotEqualTo(new StartEnvoy(1, 2, 3, "b").hashCode());
+  }
+
 }
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tasks/StartHAProxyTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tasks/StartHAProxyTest.java
index dde12ef..004b912 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tasks/StartHAProxyTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tasks/StartHAProxyTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.geode.benchmark.tasks;
 
-import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+import static org.assertj.core.api.Assertions.assertThat;
 
 import java.net.InetSocketAddress;
 import java.util.HashSet;
@@ -66,4 +66,22 @@
         + "  mode tcp\n"
         + "  server host l1:1\n");
   }
+
+  @Test
+  public void equals() {
+    assertThat(new StartHAProxy(1, 2, 3, null)).isEqualTo(new StartHAProxy(1, 2, 3, null));
+    assertThat(new StartHAProxy(1, 2, 3, "a")).isEqualTo(new StartHAProxy(1, 2, 3, "a"));
+    assertThat(new StartHAProxy(1, 2, 3, "a")).isNotEqualTo(new StartHAProxy(1, 2, 3, "b"));
+  }
+
+  @Test
+  public void hashcode() {
+    assertThat(new StartHAProxy(1, 2, 3, null).hashCode())
+        .isEqualTo(new StartHAProxy(1, 2, 3, null).hashCode());
+    assertThat(new StartHAProxy(1, 2, 3, "a").hashCode())
+        .isEqualTo(new StartHAProxy(1, 2, 3, "a").hashCode());
+    assertThat(new StartHAProxy(1, 2, 3, "a").hashCode())
+        .isNotEqualTo(new StartHAProxy(1, 2, 3, "b").hashCode());
+  }
+
 }
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tasks/StartRouterTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tasks/StartRouterTest.java
new file mode 100644
index 0000000..423badf
--- /dev/null
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tasks/StartRouterTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.geode.benchmark.tasks;
+
+import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+
+import java.net.InetSocketAddress;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.jupiter.api.Test;
+
+class StartRouterTest {
+
+  @Test
+  void generateConfig() {
+    final Set<InetSocketAddress> members = new HashSet<InetSocketAddress>() {
+      {
+        add(InetSocketAddress.createUnresolved("p1", 1));
+        add(InetSocketAddress.createUnresolved("p2", 2));
+      }
+    };
+    final StartRouter startRouter = new StartRouter(3, null);
+    final String config = startRouter.generateConfig(members);
+
+    assertThat(config).isEqualTo("global\n"
+        + "  daemon\n"
+        + "  maxconn 64000\n"
+        + "  spread-checks 4\n"
+        + "defaults\n"
+        + "  log global\n"
+        + "  timeout connect 30000ms\n"
+        + "  timeout client 30000ms\n"
+        + "  timeout server 30000ms\n"
+        + "listen router\n"
+        + "  bind *:3\n"
+        + "  mode tcp\n"
+        + "  server p1 p1:1\n"
+        + "  server p2 p2:2\n");
+  }
+
+  @Test
+  public void equals() {
+    assertThat(new StartRouter(3, null)).isEqualTo(new StartRouter(3, null));
+    assertThat(new StartRouter(3, "a")).isEqualTo(new StartRouter(3, "a"));
+    assertThat(new StartRouter(3, "a")).isNotEqualTo(new StartRouter(3, "b"));
+  }
+
+  @Test
+  public void hashcode() {
+    assertThat(new StartRouter(3, null).hashCode()).isEqualTo(new StartRouter(3, null).hashCode());
+    assertThat(new StartRouter(3, "a").hashCode()).isEqualTo(new StartRouter(3, "a").hashCode());
+    assertThat(new StartRouter(3, "a").hashCode()).isNotEqualTo(new StartRouter(3, "b").hashCode());
+  }
+
+}
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/GeodeBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ClientServerBenchmarkTest.java
similarity index 100%
rename from geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/GeodeBenchmarkTest.java
rename to geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ClientServerBenchmarkTest.java
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedFunctionExecutionBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedFunctionExecutionBenchmarkTest.java
index 6ebf461..6b4d1df 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedFunctionExecutionBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedFunctionExecutionBenchmarkTest.java
@@ -15,24 +15,16 @@
 package org.apache.geode.benchmark.tests;
 
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class PartitionedFunctionExecutionBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   public void benchmarkRunsSuccessfully() throws Exception {
     PartitionedFunctionExecutionBenchmark test = new PartitionedFunctionExecutionBenchmark();
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedFunctionExecutionWithArgumentsBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedFunctionExecutionWithArgumentsBenchmarkTest.java
index f6b067a..c061986 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedFunctionExecutionWithArgumentsBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedFunctionExecutionWithArgumentsBenchmarkTest.java
@@ -15,25 +15,17 @@
 package org.apache.geode.benchmark.tests;
 
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class PartitionedFunctionExecutionWithArgumentsBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully() throws Exception {
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedFunctionExecutionWithFiltersBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedFunctionExecutionWithFiltersBenchmarkTest.java
index 4fb759a..fbfc898 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedFunctionExecutionWithFiltersBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedFunctionExecutionWithFiltersBenchmarkTest.java
@@ -15,25 +15,17 @@
 package org.apache.geode.benchmark.tests;
 
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class PartitionedFunctionExecutionWithFiltersBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully() throws Exception {
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedGetBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedGetBenchmarkTest.java
index 01b6d5c..268feee 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedGetBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedGetBenchmarkTest.java
@@ -14,27 +14,18 @@
  */
 package org.apache.geode.benchmark.tests;
 
-
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class PartitionedGetBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully()
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedGetLongBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedGetLongBenchmarkTest.java
index 75fd261..6430225 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedGetLongBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedGetLongBenchmarkTest.java
@@ -14,27 +14,18 @@
  */
 package org.apache.geode.benchmark.tests;
 
-
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class PartitionedGetLongBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully()
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedIndexedQueryBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedIndexedQueryBenchmarkTest.java
index 75eff61..972eaf8 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedIndexedQueryBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedIndexedQueryBenchmarkTest.java
@@ -15,24 +15,16 @@
 package org.apache.geode.benchmark.tests;
 
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class PartitionedIndexedQueryBenchmarkTest {
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully() throws Exception {
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedNonIndexedQueryBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedNonIndexedQueryBenchmarkTest.java
index 253f8c2..b9e6de7 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedNonIndexedQueryBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedNonIndexedQueryBenchmarkTest.java
@@ -15,24 +15,16 @@
 package org.apache.geode.benchmark.tests;
 
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class PartitionedNonIndexedQueryBenchmarkTest {
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully() throws Exception {
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutAllBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutAllBenchmarkTest.java
index c6670c0..15b5056 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutAllBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutAllBenchmarkTest.java
@@ -17,28 +17,18 @@
 
 package org.apache.geode.benchmark.tests;
 
-
-
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class PartitionedPutAllBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully()
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutAllLongBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutAllLongBenchmarkTest.java
index 701c043..5f22743 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutAllLongBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutAllLongBenchmarkTest.java
@@ -17,28 +17,18 @@
 
 package org.apache.geode.benchmark.tests;
 
-
-
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class PartitionedPutAllLongBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully()
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutBenchmarkTest.java
index 194a9bc..13bf6f8 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutBenchmarkTest.java
@@ -17,28 +17,18 @@
 
 package org.apache.geode.benchmark.tests;
 
-
-
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class PartitionedPutBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully()
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutLongBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutLongBenchmarkTest.java
index 5f5e6de..21454c8 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutLongBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/PartitionedPutLongBenchmarkTest.java
@@ -17,28 +17,18 @@
 
 package org.apache.geode.benchmark.tests;
 
-
-
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class PartitionedPutLongBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully()
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedFunctionExecutionBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedFunctionExecutionBenchmarkTest.java
index 4f9dc01..c7c086d 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedFunctionExecutionBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedFunctionExecutionBenchmarkTest.java
@@ -15,25 +15,17 @@
 package org.apache.geode.benchmark.tests;
 
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class ReplicatedFunctionExecutionBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   void benchmarkRunsSuccessfully() throws Exception {
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedFunctionExecutionWithArgumentsBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedFunctionExecutionWithArgumentsBenchmarkTest.java
index f86bb63..ef91202 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedFunctionExecutionWithArgumentsBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedFunctionExecutionWithArgumentsBenchmarkTest.java
@@ -15,24 +15,16 @@
 package org.apache.geode.benchmark.tests;
 
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class ReplicatedFunctionExecutionWithArgumentsBenchmarkTest {
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully() throws Exception {
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedFunctionExecutionWithFiltersBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedFunctionExecutionWithFiltersBenchmarkTest.java
index 4a4e47e..0f9d3c0 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedFunctionExecutionWithFiltersBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedFunctionExecutionWithFiltersBenchmarkTest.java
@@ -15,24 +15,16 @@
 package org.apache.geode.benchmark.tests;
 
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class ReplicatedFunctionExecutionWithFiltersBenchmarkTest {
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully() throws Exception {
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedGetBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedGetBenchmarkTest.java
index f97181d..8044204 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedGetBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedGetBenchmarkTest.java
@@ -14,27 +14,18 @@
  */
 package org.apache.geode.benchmark.tests;
 
-
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class ReplicatedGetBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully()
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedGetLongBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedGetLongBenchmarkTest.java
index 96e3b9c..423b4a8 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedGetLongBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedGetLongBenchmarkTest.java
@@ -14,27 +14,18 @@
  */
 package org.apache.geode.benchmark.tests;
 
-
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class ReplicatedGetLongBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully()
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedIndexedQueryBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedIndexedQueryBenchmarkTest.java
index edcebf7..869b6bb 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedIndexedQueryBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedIndexedQueryBenchmarkTest.java
@@ -15,24 +15,17 @@
 package org.apache.geode.benchmark.tests;
 
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class ReplicatedIndexedQueryBenchmarkTest {
-  private File folder;
 
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully() throws Exception {
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedNonIndexedQueryBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedNonIndexedQueryBenchmarkTest.java
index 2f5ecfe..c6d2c09 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedNonIndexedQueryBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedNonIndexedQueryBenchmarkTest.java
@@ -15,24 +15,17 @@
 package org.apache.geode.benchmark.tests;
 
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class ReplicatedNonIndexedQueryBenchmarkTest {
-  private File folder;
 
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully() throws Exception {
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedPutBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedPutBenchmarkTest.java
index fee0bd1..157c48c 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedPutBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedPutBenchmarkTest.java
@@ -18,25 +18,17 @@
 package org.apache.geode.benchmark.tests;
 
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class ReplicatedPutBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully()
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedPutLongBenchmarkTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedPutLongBenchmarkTest.java
index 779d07f..8c1be3f 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedPutLongBenchmarkTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/tests/ReplicatedPutLongBenchmarkTest.java
@@ -18,25 +18,17 @@
 package org.apache.geode.benchmark.tests;
 
 import java.io.File;
-import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.benchmark.LongRange;
 import org.apache.geode.perftest.TestRunners;
 
-@ExtendWith(TempDirectory.class)
 public class ReplicatedPutLongBenchmarkTest {
 
-  private File folder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
+  @TempDir
+  File folder;
 
   @Test
   public void benchmarkRunsSuccessfully()
diff --git a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithSNIProxyTest.java b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithSniProxyTest.java
similarity index 78%
rename from geode-benchmarks/src/test/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithSNIProxyTest.java
rename to geode-benchmarks/src/test/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithSniProxyTest.java
index f2d4fbc..5e989c5 100644
--- a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithSNIProxyTest.java
+++ b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/topology/ClientServerTopologyWithSniProxyTest.java
@@ -15,6 +15,7 @@
 
 package org.apache.geode.benchmark.topology;
 
+import static org.apache.geode.benchmark.topology.ClientServerTopologyWithSniProxy.WITH_SNI_PROXY_PROPERTY;
 import static org.apache.geode.benchmark.topology.Roles.CLIENT;
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -24,11 +25,12 @@
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.EnumSource;
+import org.junitpioneer.jupiter.ClearSystemProperty;
 
-import org.apache.geode.benchmark.topology.ClientServerTopologyWithSNIProxy.SniProxyImplementation;
+import org.apache.geode.benchmark.topology.ClientServerTopologyWithSniProxy.SniProxyImplementation;
 import org.apache.geode.perftest.TestConfig;
 
-public class ClientServerTopologyWithSNIProxyTest {
+public class ClientServerTopologyWithSniProxyTest {
 
   private Properties systemProperties;
 
@@ -44,9 +46,11 @@
 
   @ParameterizedTest
   @EnumSource(SniProxyImplementation.class)
+  @ClearSystemProperty(key = WITH_SNI_PROXY_PROPERTY)
   public void configWithNoSsl(final SniProxyImplementation sniProxyImplementation) {
-    TestConfig testConfig = new TestConfig();
-    ClientServerTopologyWithSNIProxy.configure(testConfig, sniProxyImplementation);
+    System.setProperty(WITH_SNI_PROXY_PROPERTY, sniProxyImplementation.name());
+    final TestConfig testConfig = new TestConfig();
+    ClientServerTopologyWithSniProxy.configure(testConfig);
     assertThat(testConfig.getJvmArgs().get(CLIENT.name())).contains("-DwithSsl=true");
   }
 
diff --git a/gradle/dependency-versions.properties b/gradle/dependency-versions.properties
index c0fe3d2..a6f4102 100644
--- a/gradle/dependency-versions.properties
+++ b/gradle/dependency-versions.properties
@@ -14,10 +14,10 @@
 # limitations under the License.
 
 # Dependency versions
-junit-jupiter-api.version = 5.3.2
-junit-jupiter-engine.version = 5.3.2
-junit-pioneer.version = 0.3.0
-geode-core.version = 1.8.0
+junit-jupiter-api.version = 5.7.0
+junit-jupiter-engine.version = 5.7.0
+junit-pioneer.version = 1.0.0
+geode-core.version = 1.13.0
 slf4j-simple.version = 1.7.25
 sshj.version = 0.26.0
 commons-io.version = 2.6
diff --git a/harness/src/test/java/org/apache/geode/perftest/TestRunnerIntegrationTest.java b/harness/src/test/java/org/apache/geode/perftest/TestRunnerIntegrationTest.java
index 0facf5c..f82cb6c 100644
--- a/harness/src/test/java/org/apache/geode/perftest/TestRunnerIntegrationTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/TestRunnerIntegrationTest.java
@@ -21,7 +21,6 @@
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.File;
-import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.function.Predicate;
@@ -29,8 +28,7 @@
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.perftest.benchmarks.EmptyBenchmark;
 import org.apache.geode.perftest.infrastructure.local.LocalInfrastructureFactory;
@@ -38,26 +36,19 @@
 import org.apache.geode.perftest.runner.DefaultTestRunner;
 import org.apache.geode.perftest.yardstick.analysis.YardstickThroughputSensorParser;
 
-@ExtendWith(TempDirectory.class)
 public class TestRunnerIntegrationTest {
 
-  Path temporaryFolder;
-
-  @BeforeEach
-  void setup(@TempDirectory.TempDir Path tempDirPath) {
-    this.temporaryFolder = tempDirPath;
-    outputDir = temporaryFolder.toFile();
-    runner = new DefaultTestRunner(new RemoteJVMFactory(new LocalInfrastructureFactory()),
-        outputDir);
-  }
-
   private TestRunner runner;
-  private File outputDir;
+
+  @TempDir
+  File outputDir;
+
   public static final String SAMPLE_BENCHMARK = "SampleBenchmark";
 
   @BeforeEach
-  public void setup() throws IOException {
-
+  void beforeEach() {
+    runner = new DefaultTestRunner(new RemoteJVMFactory(new LocalInfrastructureFactory()),
+        outputDir);
   }
 
   @Test
diff --git a/harness/src/test/java/org/apache/geode/perftest/TestRunnerJUnitTest.java b/harness/src/test/java/org/apache/geode/perftest/TestRunnerJUnitTest.java
index 1f36a8f..9c6759d 100644
--- a/harness/src/test/java/org/apache/geode/perftest/TestRunnerJUnitTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/TestRunnerJUnitTest.java
@@ -24,29 +24,20 @@
 import static org.mockito.Mockito.when;
 
 import java.io.File;
-import java.nio.file.Path;
 
 import org.assertj.core.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 import org.mockito.InOrder;
 
 import org.apache.geode.perftest.jvms.RemoteJVMFactory;
 import org.apache.geode.perftest.jvms.RemoteJVMs;
 import org.apache.geode.perftest.runner.DefaultTestRunner;
 
-@ExtendWith(TempDirectory.class)
 public class TestRunnerJUnitTest {
 
-  private static File folder;
-
-  @BeforeAll
-  public static void createTemporaryFolder(@TempDirectory.TempDir Path tempFolder) {
-    folder = tempFolder.toFile();
-  }
-
+  @TempDir
+  static File folder;
 
   @Test
   public void testRunnerRunsBeforeAndAfterTasks() throws Exception {
diff --git a/harness/src/test/java/org/apache/geode/perftest/analysis/BenchmarkRunAnalyzerTest.java b/harness/src/test/java/org/apache/geode/perftest/analysis/BenchmarkRunAnalyzerTest.java
index 61a9de9..153f416 100644
--- a/harness/src/test/java/org/apache/geode/perftest/analysis/BenchmarkRunAnalyzerTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/analysis/BenchmarkRunAnalyzerTest.java
@@ -25,22 +25,16 @@
 import java.io.StringWriter;
 import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.perftest.yardstick.analysis.YardstickPercentileSensorParser;
 import org.apache.geode.perftest.yardstick.analysis.YardstickThroughputSensorParser;
 
-@ExtendWith(TempDirectory.class)
 public class BenchmarkRunAnalyzerTest {
-  private Path temporaryFolder;
 
-  @BeforeEach
-  void createTempFolder(@TempDirectory.TempDir Path tempDir) {
-    temporaryFolder = tempDir;
-  }
+  @TempDir
+  Path temporaryFolder;
 
   @Test
   public void verifyResultHarvester() throws IOException {
diff --git a/harness/src/test/java/org/apache/geode/perftest/infrastructure/local/LocalInfrastructureTest.java b/harness/src/test/java/org/apache/geode/perftest/infrastructure/local/LocalInfrastructureTest.java
index 735ca89..95a9679 100644
--- a/harness/src/test/java/org/apache/geode/perftest/infrastructure/local/LocalInfrastructureTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/infrastructure/local/LocalInfrastructureTest.java
@@ -30,20 +30,18 @@
 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;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
-@ExtendWith(TempDirectory.class)
 public class LocalInfrastructureTest {
 
-  private Path temporaryFolder;
+  @TempDir
+  Path temporaryFolder;
 
   private LocalInfrastructure infra;
   private LocalInfrastructure.LocalNode node;
 
   @BeforeEach
-  public void createInfra(@TempDirectory.TempDir Path tempDir) throws IOException {
-    temporaryFolder = tempDir;
+  public void createInfra() throws IOException {
     infra = new LocalInfrastructure(1);
     node = (LocalInfrastructure.LocalNode) infra.getNodes().iterator().next();
   }
@@ -53,7 +51,6 @@
     infra.close();
   }
 
-
   @Test
   public void copyToNodesPutsFileOnNode() throws IOException, InterruptedException {
 
@@ -65,8 +62,6 @@
     infra.copyToNodes(Arrays.asList(someFile), node -> "lib", true);
     assertTrue(expectedDir.exists());
     assertTrue(new File(expectedDir, someFile.getName()).exists());
-
-
     infra.close();
 
     assertFalse(expectedDir.exists());
diff --git a/harness/src/test/java/org/apache/geode/perftest/infrastructure/ssh/SshInfrastructureTest.java b/harness/src/test/java/org/apache/geode/perftest/infrastructure/ssh/SshInfrastructureTest.java
index be10276..c1948ff 100644
--- a/harness/src/test/java/org/apache/geode/perftest/infrastructure/ssh/SshInfrastructureTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/infrastructure/ssh/SshInfrastructureTest.java
@@ -19,7 +19,6 @@
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junitpioneer.jupiter.TempDirectory.TempDir;
 
 import java.io.File;
 import java.io.IOException;
@@ -37,23 +36,22 @@
 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;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.perftest.infrastructure.Infrastructure;
 
-@ExtendWith(TempDirectory.class)
 public class SshInfrastructureTest {
 
-
   private static final Set<String> HOSTS = Collections.singleton("localhost");
   private static final String USER = System.getProperty("user.name");
+
+  @TempDir
   Path temporaryFolder;
+
   public SshServer server;
 
   @BeforeEach
-  void createTempFolder(@TempDir Path tempDir, @TempDir Path serverPath) throws IOException {
-    temporaryFolder = tempDir;
+  void createTempFolder(@TempDir Path serverPath) throws IOException {
     server = createServer(serverPath);
   }
 
@@ -140,7 +138,6 @@
     assertFalse(fileToRemove.exists());
   }
 
-
   @Test
   public void canCopyFilesFromANode()
       throws IOException, ExecutionException, InterruptedException {
diff --git a/harness/src/test/java/org/apache/geode/perftest/jvms/RemoteJVMFactoryIntegrationTest.java b/harness/src/test/java/org/apache/geode/perftest/jvms/RemoteJVMFactoryIntegrationTest.java
index 8d1a91a..a60734f 100644
--- a/harness/src/test/java/org/apache/geode/perftest/jvms/RemoteJVMFactoryIntegrationTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/jvms/RemoteJVMFactoryIntegrationTest.java
@@ -24,24 +24,16 @@
 import java.util.Collections;
 import java.util.Map;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.perftest.infrastructure.local.LocalInfrastructureFactory;
 
-@ExtendWith(TempDirectory.class)
 public class RemoteJVMFactoryIntegrationTest {
 
-
+  @TempDir
   Path temporaryFolder;
 
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path temporaryFolder) {
-    this.temporaryFolder = temporaryFolder;
-  }
-
   @Test
   public void canExecuteCodeOnWorker() throws Exception {
     RemoteJVMFactory remoteJvmFactory = new RemoteJVMFactory(new LocalInfrastructureFactory());
diff --git a/harness/src/test/java/org/apache/geode/perftest/jvms/rmi/ChildJVMTest.java b/harness/src/test/java/org/apache/geode/perftest/jvms/rmi/ChildJVMTest.java
index 7fb113b..663869c 100644
--- a/harness/src/test/java/org/apache/geode/perftest/jvms/rmi/ChildJVMTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/jvms/rmi/ChildJVMTest.java
@@ -29,35 +29,31 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.nio.file.Path;
 import java.rmi.NotBoundException;
 import java.rmi.RemoteException;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.perftest.jdk.RMI;
 import org.apache.geode.perftest.jdk.SystemInterface;
 import org.apache.geode.perftest.jvms.RemoteJVMFactory;
 
-@ExtendWith(TempDirectory.class)
 public class ChildJVMTest {
-
-
   private RMI rmi;
   private ChildJVM jvm;
   private SystemInterface system;
   private Controller controller;
-  private File folder;
+
+  @TempDir
+  File folder;
 
   @BeforeEach
-  public void setUp(@TempDirectory.TempDir Path tempDir) throws IOException, NotBoundException {
+  public void setUp() throws IOException, NotBoundException {
     system = mock(SystemInterface.class);
     when(system.getProperty(RMI_HOST)).thenReturn("something");
     when(system.getProperty(RMI_PORT_PROPERTY)).thenReturn("0");
-    folder = tempDir.toFile();
     when(system.getProperty(OUTPUT_DIR)).thenReturn(folder.getAbsolutePath());
     rmi = mock(RMI.class);
     jvm = new ChildJVM(rmi, system, 1);
diff --git a/harness/src/test/java/org/apache/geode/perftest/yardstick/YardstickTaskTest.java b/harness/src/test/java/org/apache/geode/perftest/yardstick/YardstickTaskTest.java
index 3a211d0..1d57fbc 100644
--- a/harness/src/test/java/org/apache/geode/perftest/yardstick/YardstickTaskTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/yardstick/YardstickTaskTest.java
@@ -23,10 +23,8 @@
 import java.nio.file.Files;
 import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
 import org.apache.geode.perftest.Task;
 import org.apache.geode.perftest.TestContext;
@@ -35,15 +33,10 @@
 import org.apache.geode.perftest.runner.DefaultTestContext;
 import org.apache.geode.perftest.yardstick.hdrhistogram.HdrHistogramWriter;
 
-@ExtendWith(TempDirectory.class)
 public class YardstickTaskTest {
 
-  public Path folder;
-
-  @BeforeEach
-  void createTempFolder(@TempDirectory.TempDir Path tempDir) {
-    this.folder = tempDir;
-  }
+  @TempDir
+  Path folder;
 
   @Test
   public void testExecuteBenchmark() throws Exception {
diff --git a/harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickPercentileSensorParserTest.java b/harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickPercentileSensorParserTest.java
index 1d12eae..06a14ba 100644
--- a/harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickPercentileSensorParserTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickPercentileSensorParserTest.java
@@ -25,20 +25,13 @@
 import java.nio.file.Path;
 
 import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
-@ExtendWith(TempDirectory.class)
 public class YardstickPercentileSensorParserTest {
 
-  private Path temporaryFolder;
-
-  @BeforeEach
-  void createTemporaryFolder(@TempDirectory.TempDir Path tempDir) {
-    temporaryFolder = tempDir;
-  }
+  @TempDir
+  Path temporaryFolder;
 
   @Test
   public void parsesInputFile() throws IOException {
diff --git a/harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickThroughputSensorParserTest.java b/harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickThroughputSensorParserTest.java
index 27e5d28..68b0fad 100644
--- a/harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickThroughputSensorParserTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickThroughputSensorParserTest.java
@@ -25,22 +25,13 @@
 import java.io.IOException;
 import java.nio.file.Path;
 
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junitpioneer.jupiter.TempDirectory;
+import org.junit.jupiter.api.io.TempDir;
 
-
-@ExtendWith(TempDirectory.class)
 public class YardstickThroughputSensorParserTest {
 
-  public Path temporaryFolder;
-
-  @BeforeEach
-  void createTempFolder(@TempDirectory.TempDir Path tempDir) {
-    this.temporaryFolder = tempDir;
-  }
-
+  @TempDir
+  Path temporaryFolder;
 
   @Test
   public void parsesInputFile() throws IOException {