upthewaterspout closed pull request #2: Cleaning up benchmark output
URL: https://github.com/apache/geode-benchmarks/pull/2
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/README.md b/README.md
index 06833b2..7c563ed 100644
--- a/README.md
+++ b/README.md
@@ -14,11 +14,9 @@ To run all benchmarks, run the benchmark task and pass in a 
list of hosts.
 
 For example:
 ```
-./gradlew benchmark -Phosts=localhost,localhost,localhost
+./gradlew benchmark -Phosts=localhost,localhost,localhost 
-PoutputDir=/tmp/results
 ```
 
-Performance results will be written to geode-benchmarks/output
-
 ## Project structure
 
 The project is divided into two modules
diff --git a/geode-benchmarks/build.gradle b/geode-benchmarks/build.gradle
index 67b6a8c..9b90312 100644
--- a/geode-benchmarks/build.gradle
+++ b/geode-benchmarks/build.gradle
@@ -43,7 +43,10 @@ task benchmark(type: Test) {
         exceptionFormat = 'full'
     }
 
+    def outputDir = project.hasProperty('outputDir') ? 
project.findProperty('outputDir') : new File(project.buildDir, 
"benchmarks").getAbsolutePath();
+
     systemProperty 'TEST_HOSTS', project.findProperty('hosts');
+    systemProperty 'OUTPUT_DIR', outputDir;
 
     doFirst {
         if(!project.hasProperty('hosts')) {
diff --git 
a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/GetTask.java 
b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/GetTask.java
new file mode 100644
index 0000000..0f94741
--- /dev/null
+++ 
b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/GetTask.java
@@ -0,0 +1,46 @@
+/*
+ * 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 java.io.Serializable;
+import java.util.Map;
+
+import org.yardstickframework.BenchmarkConfiguration;
+import org.yardstickframework.BenchmarkDriverAdapter;
+
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.client.ClientCache;
+import org.apache.geode.cache.client.ClientCacheFactory;
+
+public class GetTask extends BenchmarkDriverAdapter implements Serializable {
+
+  private Region<Object, Object> region;
+
+  @Override
+  public void setUp(BenchmarkConfiguration cfg) throws Exception {
+    super.setUp(cfg);
+    ClientCache cache = ClientCacheFactory.getAnyInstance();
+    region = cache.getRegion("region");
+  }
+
+  @Override
+  public boolean test(Map<Object, Object> ctx) throws Exception {
+    region.get(1);
+    return true;
+  }
+}
diff --git 
a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartClient.java
 
b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartClient.java
index dab4d8f..f69c284 100644
--- 
a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartClient.java
+++ 
b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartClient.java
@@ -17,6 +17,7 @@
 
 package org.apache.geode.benchmark.tasks;
 
+import java.io.File;
 import java.net.InetAddress;
 
 import org.apache.geode.cache.client.ClientCache;
@@ -38,10 +39,12 @@ public void run(TestContext context) throws Exception {
 
     InetAddress locator = context.getHostsForRole("locator").iterator().next();
 
+    String statsFile = new File(context.getOutputDir(), 
"stats.gfs").getAbsolutePath();
+
     ClientCache clientCache = new ClientCacheFactory()
         .addPoolLocator(locator.getHostAddress(), locatorPort)
         .set(ConfigurationProperties.STATISTIC_SAMPLING_ENABLED,"true")
-        .set(ConfigurationProperties.STATISTIC_ARCHIVE_FILE,"output/stats.gfs")
+        .set(ConfigurationProperties.STATISTIC_ARCHIVE_FILE, statsFile)
         .create();
 
     clientCache.createClientRegionFactory(ClientRegionShortcut.PROXY)
diff --git 
a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartLocator.java
 
b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartLocator.java
index f04b3e0..5bc6d39 100644
--- 
a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartLocator.java
+++ 
b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartLocator.java
@@ -17,6 +17,7 @@
 
 package org.apache.geode.benchmark.tasks;
 
+import java.io.File;
 import java.net.InetAddress;
 import java.util.Properties;
 
@@ -35,9 +36,12 @@ public StartLocator(int locatorPort) {
   @Override
   public void run(TestContext context) throws Exception {
     Properties properties = new Properties();
-    properties.setProperty(ConfigurationProperties.NAME,"locator-"+ 
InetAddress.getLocalHost());
+
+    String statsFile = new File(context.getOutputDir(), 
"stats.gfs").getAbsolutePath();
     
properties.setProperty(ConfigurationProperties.STATISTIC_SAMPLING_ENABLED,"true");
-    
properties.setProperty(ConfigurationProperties.STATISTIC_ARCHIVE_FILE,"output/stats.gfs");
+    properties.setProperty(ConfigurationProperties.STATISTIC_ARCHIVE_FILE, 
statsFile);
+
+    properties.setProperty(ConfigurationProperties.NAME,"locator-"+ 
InetAddress.getLocalHost());
     Locator.startLocatorAndDS(locatorPort, null, properties);
   }
 }
diff --git 
a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartServer.java
 
b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartServer.java
index d2bb8aa..46f9445 100644
--- 
a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartServer.java
+++ 
b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tasks/StartServer.java
@@ -17,6 +17,7 @@
 
 package org.apache.geode.benchmark.tasks;
 
+import java.io.File;
 import java.net.InetAddress;
 
 import org.apache.geode.cache.Cache;
@@ -39,12 +40,13 @@ public StartServer(int locatorPort) {
   public void run(TestContext context) throws Exception {
 
     String locatorString = LocatorUtil.getLocatorString(context, locatorPort);
+    String statsFile = new File(context.getOutputDir(), 
"stats.gfs").getAbsolutePath();
 
     Cache cache = new CacheFactory()
         .set(ConfigurationProperties.LOCATORS,locatorString)
         .set(ConfigurationProperties.NAME,"server-"+ 
InetAddress.getLocalHost())
         .set(ConfigurationProperties.STATISTIC_SAMPLING_ENABLED,"true")
-        .set(ConfigurationProperties.STATISTIC_ARCHIVE_FILE,"output/stats.gfs")
+        .set(ConfigurationProperties.STATISTIC_ARCHIVE_FILE, statsFile)
         .create();
 
     CacheServer cacheServer = ((Cache) cache).addCacheServer();
diff --git 
a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tests/PartitionedGetBenchmark.java
 
b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tests/PartitionedGetBenchmark.java
new file mode 100644
index 0000000..a5ceeb7
--- /dev/null
+++ 
b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tests/PartitionedGetBenchmark.java
@@ -0,0 +1,57 @@
+/*
+ * 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.tests;
+
+import org.junit.Test;
+
+import org.apache.geode.benchmark.tasks.GetTask;
+import org.apache.geode.benchmark.tasks.StartClient;
+import org.apache.geode.benchmark.tasks.StartLocator;
+import org.apache.geode.benchmark.tasks.StartServer;
+import org.apache.geode.perftest.TestConfig;
+import org.apache.geode.perftest.TestRunners;
+
+/**
+ * Benchmark of gets on a partitioned region.
+ *
+ * TODO - this is not populating the region!
+ * TODO - this is only getting a single key!
+ */
+public class PartitionedGetBenchmark {
+
+  @Test
+  public void run() throws Exception {
+    TestRunners.defaultRunner().runTest(this::configure);
+  }
+
+  public void configure(TestConfig config) {
+
+    int locatorPort = 10334;
+
+    config.name(PartitionedGetBenchmark.class.getCanonicalName());
+    config.warmupSeconds(2);
+    config.durationSeconds(5);
+    config.role("locator", 1);
+    config.role("server", 1);
+    config.role("client", 1);
+    config.before(new StartLocator(locatorPort), "locator");
+    config.before(new StartServer(locatorPort), "server");
+    config.before(new StartClient(locatorPort), "client");
+    config.workload(new GetTask(),"client");
+  }
+}
diff --git 
a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tests/PartitionedPutBenchmark.java
 
b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tests/PartitionedPutBenchmark.java
index cd13c33..6689911 100644
--- 
a/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tests/PartitionedPutBenchmark.java
+++ 
b/geode-benchmarks/src/main/java/org/apache/geode/benchmark/tests/PartitionedPutBenchmark.java
@@ -37,8 +37,9 @@ public void configure(TestConfig config) {
 
     int locatorPort = 10334;
 
-    config.warmupSeconds(5);
-    config.durationSeconds(30);
+    config.name(PartitionedPutBenchmark.class.getCanonicalName());
+    config.warmupSeconds(2);
+    config.durationSeconds(5);
     config.role("locator", 1);
     config.role("server", 1);
     config.role("client", 1);
diff --git 
a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/PartitionedPutBenchmarkTest.java
 
b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/PartitionedPutBenchmarkTest.java
index 377c464..4822dab 100644
--- 
a/geode-benchmarks/src/test/java/org/apache/geode/benchmark/PartitionedPutBenchmarkTest.java
+++ 
b/geode-benchmarks/src/test/java/org/apache/geode/benchmark/PartitionedPutBenchmarkTest.java
@@ -17,20 +17,23 @@
 
 package org.apache.geode.benchmark;
 
+import java.io.File;
+
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 
-import org.apache.geode.benchmark.tasks.PutTask;
-import org.apache.geode.benchmark.tasks.StartClient;
-import org.apache.geode.benchmark.tasks.StartLocator;
-import org.apache.geode.benchmark.tasks.StartServer;
 import org.apache.geode.benchmark.tests.PartitionedPutBenchmark;
-import org.apache.geode.perftest.TestConfig;
 import org.apache.geode.perftest.TestRunners;
 
 public class PartitionedPutBenchmarkTest {
 
+  @Rule
+  public TemporaryFolder folder = new TemporaryFolder();
+
   @Test
   public void benchmarkRunsSuccessfully() throws Exception {
-    TestRunners.minimalRunner().runTest(new 
PartitionedPutBenchmark()::configure);
+    TestRunners.minimalRunner(folder.newFolder())
+        .runTest(new PartitionedPutBenchmark()::configure);
   }
 }
diff --git a/harness/src/main/java/org/apache/geode/perftest/TestConfig.java 
b/harness/src/main/java/org/apache/geode/perftest/TestConfig.java
index 985ad1e..1d5a6f6 100644
--- a/harness/src/main/java/org/apache/geode/perftest/TestConfig.java
+++ b/harness/src/main/java/org/apache/geode/perftest/TestConfig.java
@@ -39,6 +39,7 @@
   private List<TestStep> before = new ArrayList<>();
   private List<TestStep> workload = new ArrayList<>();
   private List<TestStep> after = new ArrayList<>();
+  private String name;
 
   /**
    * Define a role for the test.
@@ -108,6 +109,14 @@ public void warmupSeconds(long warmupSeconds) {
     workloadConfig.warmupSeconds(warmupSeconds);
   }
 
+  /**
+   * Set the name of this benchmark. This name must be unique within a 
benchmarking run. Comparisons
+   * between runs will use this name to identify the same benchmark in both 
runs.
+   */
+  public void name(String name) {
+    this.name = name;
+  }
+
   public long getDurationSeconds() {
     return workloadConfig.getDurationSeconds();
   }
@@ -132,6 +141,10 @@ public long getWarmupSeconds() {
     return after;
   }
 
+  public String getName() {
+    return name;
+  }
+
   /**
    * Return the total number of JVMs required to run this test
    * @return
diff --git a/harness/src/main/java/org/apache/geode/perftest/TestContext.java 
b/harness/src/main/java/org/apache/geode/perftest/TestContext.java
index 9a4425c..589900f 100644
--- a/harness/src/main/java/org/apache/geode/perftest/TestContext.java
+++ b/harness/src/main/java/org/apache/geode/perftest/TestContext.java
@@ -17,10 +17,13 @@
 
 package org.apache.geode.perftest;
 
+import java.io.File;
 import java.io.Serializable;
 import java.net.InetAddress;
 import java.util.Set;
 
 public interface TestContext extends Serializable {
   Set<InetAddress> getHostsForRole(String role);
+
+  File getOutputDir();
 }
diff --git a/harness/src/main/java/org/apache/geode/perftest/TestRunners.java 
b/harness/src/main/java/org/apache/geode/perftest/TestRunners.java
index fc6282a..685aafb 100644
--- a/harness/src/main/java/org/apache/geode/perftest/TestRunners.java
+++ b/harness/src/main/java/org/apache/geode/perftest/TestRunners.java
@@ -17,7 +17,8 @@
 
 package org.apache.geode.perftest;
 
-import org.apache.geode.perftest.infrastructure.InfrastructureFactory;
+import java.io.File;
+
 import 
org.apache.geode.perftest.infrastructure.local.LocalInfrastructureFactory;
 import org.apache.geode.perftest.infrastructure.ssh.SshInfrastructureFactory;
 import org.apache.geode.perftest.jvms.RemoteJVMFactory;
@@ -37,10 +38,12 @@
 public class TestRunners {
 
   public static final String TEST_HOSTS = "TEST_HOSTS";
+  public static final String OUTPUT_DIR = "OUTPUT_DIR";
 
 
-  public static TestRunner defaultRunner(String username, String ... hosts) {
-    return new DefaultTestRunner(new SshInfrastructureFactory(username, 
hosts), new RemoteJVMFactory());
+  public static TestRunner defaultRunner(String username, File outputDir, 
String ... hosts) {
+    return new DefaultTestRunner(new RemoteJVMFactory(new 
SshInfrastructureFactory(username, hosts)),
+        outputDir);
   }
   /**
    * The default runner, which gets a list of hosts to run on from the
@@ -49,25 +52,27 @@ public static TestRunner defaultRunner(String username, 
String ... hosts) {
    */
   public static TestRunner defaultRunner() {
     String testHosts = System.getProperty(TEST_HOSTS);
+    String outputDir = System.getProperty(OUTPUT_DIR, "output");
 
-    return defaultRunner(testHosts);
+    return defaultRunner(testHosts, new File(outputDir));
   }
 
-  static TestRunner defaultRunner(String testHosts) {
+  static TestRunner defaultRunner(String testHosts, File outputDir) {
     if(testHosts == null) {
       throw new IllegalStateException("You must set the TEST_HOSTS system 
property to a comma separated list of hosts to run the benchmarks on.");
     }
 
     String userName = System.getProperty("user.name");
-    return defaultRunner(userName, testHosts.split(",\\s*"));
+    return defaultRunner(userName, outputDir, testHosts.split(",\\s*"));
   }
 
   /**
    * A test runner that runs the test with the minimal tuning - only
    * 1 second duration on local infrastructure.
+   * @param outputDir
    */
-  public static TestRunner minimalRunner() {
-    return new DefaultTestRunner(new LocalInfrastructureFactory(), new 
RemoteJVMFactory()) {
+  public static TestRunner minimalRunner(final File outputDir) {
+    return new DefaultTestRunner(new RemoteJVMFactory(new 
LocalInfrastructureFactory()), outputDir) {
       @Override
       public void runTest(TestConfig config) throws Exception {
         config.warmupSeconds(0);
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/infrastructure/Infrastructure.java
 
b/harness/src/main/java/org/apache/geode/perftest/infrastructure/Infrastructure.java
index f779acb..cb66845 100644
--- 
a/harness/src/main/java/org/apache/geode/perftest/infrastructure/Infrastructure.java
+++ 
b/harness/src/main/java/org/apache/geode/perftest/infrastructure/Infrastructure.java
@@ -43,9 +43,14 @@ int onNode(Node node, String[] shellCommand)
   void close() throws InterruptedException, IOException;
 
   /**
-   * Copy a list of files to a directory on the node
+   * Copy a list of files to a directory on the node.
+   *
+   * @param files A list of files on the local system to copy
+   * @param destDir The directory on the remote machine to copy to
+   * @param removeExisting If true, remove all existing files in the directory 
on the remote
+   * machine
    */
-  void copyToNodes(Iterable<File> files, String destDir) throws IOException;
+  void copyToNodes(Iterable<File> files, String destDir, boolean 
removeExisting) throws IOException;
 
   void copyFromNode(Node node, String directory, File destDir) throws 
IOException;
 
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/infrastructure/local/LocalInfrastructure.java
 
b/harness/src/main/java/org/apache/geode/perftest/infrastructure/local/LocalInfrastructure.java
index f902a72..5b90fa4 100644
--- 
a/harness/src/main/java/org/apache/geode/perftest/infrastructure/local/LocalInfrastructure.java
+++ 
b/harness/src/main/java/org/apache/geode/perftest/infrastructure/local/LocalInfrastructure.java
@@ -24,9 +24,9 @@
 import java.net.UnknownHostException;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
@@ -85,10 +85,10 @@ public void close() throws InterruptedException, 
IOException {
   }
 
   @Override
-  public void copyToNodes(Iterable<File> files, String destDirName) throws 
IOException {
+  public void copyToNodes(Iterable<File> files, String destDirName, boolean 
removeExisting) throws IOException {
     for(LocalNode node : nodes) {
       Path destDir = new File(node.getWorkingDir(), destDirName).toPath();
-      destDir.toFile().mkdir();
+      destDir.toFile().mkdirs();
 
       for(File file : files) {
         Files.copy(file.toPath(), destDir.resolve(file.getName()));
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/infrastructure/ssh/SshInfrastructure.java
 
b/harness/src/main/java/org/apache/geode/perftest/infrastructure/ssh/SshInfrastructure.java
index 33f2ed3..4ff90e4 100644
--- 
a/harness/src/main/java/org/apache/geode/perftest/infrastructure/ssh/SshInfrastructure.java
+++ 
b/harness/src/main/java/org/apache/geode/perftest/infrastructure/ssh/SshInfrastructure.java
@@ -102,7 +102,7 @@ public void close() throws InterruptedException, 
IOException {
   }
 
   @Override
-  public void copyToNodes(Iterable<File> files, String destDir) throws 
IOException {
+  public void copyToNodes(Iterable<File> files, String destDir, boolean 
removeExisting) throws IOException {
     Set<InetAddress> uniqueNodes = 
getNodes().stream().map(Node::getAddress).collect(Collectors.toSet());
 
     List<CompletableFuture<Void>> futures = new ArrayList<>();
@@ -112,9 +112,11 @@ public void copyToNodes(Iterable<File> files, String 
destDir) throws IOException
           try (Session session = client.startSession()) {
             client.useCompression();
 
-            String script = "mkdir -p " + destDir;
-            final Session.Command cmd = session.exec(script);
-            cmd.join();
+            if(removeExisting) {
+              session.exec(String.format("/bin/sh -c \"rm -rf '%s'; mkdir -p 
'%s'\"", destDir, destDir)).join();
+            }else {
+              session.exec(String.format("mkdir -p '%s'", destDir)).join();
+            }
             for (File file : files) {
               logger.info("Copying " + file + " to " + address);
               client.newSCPFileTransfer().upload(new FileSystemFile(file), 
destDir);
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/jdk/SystemInterface.java 
b/harness/src/main/java/org/apache/geode/perftest/jdk/SystemInterface.java
index 91a18e8..7d25070 100644
--- a/harness/src/main/java/org/apache/geode/perftest/jdk/SystemInterface.java
+++ b/harness/src/main/java/org/apache/geode/perftest/jdk/SystemInterface.java
@@ -24,7 +24,7 @@
  */
 public class SystemInterface {
 
-  public static String getProperty(String property) {
+  public String getProperty(String property) {
     return System.getProperty(property);
   }
 
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/jvms/JVMLauncher.java 
b/harness/src/main/java/org/apache/geode/perftest/jvms/JVMLauncher.java
index b6794ef..eb26879 100644
--- a/harness/src/main/java/org/apache/geode/perftest/jvms/JVMLauncher.java
+++ b/harness/src/main/java/org/apache/geode/perftest/jvms/JVMLauncher.java
@@ -32,20 +32,25 @@
 class JVMLauncher {
   private static final Logger logger = 
LoggerFactory.getLogger(RemoteJVMFactory.class);
 
+  JVMLauncher() {
+  }
+
   CompletableFuture<Void> launchProcesses(Infrastructure infra, int rmiPort,
-                                          List<JVMMapping> mapping)
+                                          List<JVMMapping> mapping, String 
libDir)
       throws UnknownHostException {
     List<CompletableFuture<Void>> futures = new 
ArrayList<CompletableFuture<Void>>();
     for (JVMMapping entry : mapping) {
-      futures.add(launchWorker(infra, rmiPort, entry.getId(), 
entry.getNode()));
+      futures.add(launchWorker(infra, rmiPort, entry.getId(), entry.getNode(), 
libDir, entry.getOutputDir()));
     }
     return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
   }
 
   CompletableFuture<Void> launchWorker(Infrastructure infra, int rmiPort,
-                                       int id, final Infrastructure.Node node)
+                                       int id, final Infrastructure.Node node, 
String libDir,
+                                       String outputDir)
       throws UnknownHostException {
-    String[] shellCommand = 
buildCommand(InetAddress.getLocalHost().getHostAddress(), rmiPort, id);
+    String[] shellCommand = 
buildCommand(InetAddress.getLocalHost().getHostAddress(), rmiPort, id,
+        libDir, outputDir);
     CompletableFuture<Void> future = new CompletableFuture<Void>();
     Thread thread = new Thread("Worker " + node.getAddress()) {
       public void run() {
@@ -67,15 +72,17 @@ public void run() {
     return future;
   }
 
-  String[] buildCommand(String rmiHost, int rmiPort, int id) {
+  String[] buildCommand(String rmiHost, int rmiPort, int id, String libDir,
+                        String outputDir) {
 
     List<String> command = new ArrayList<String>();
     command.add("java");
     command.add("-classpath");
-    command.add("lib/*");
+    command.add(libDir + "/*");
     command.add("-D" + RemoteJVMFactory.RMI_HOST + "=" + rmiHost);
     command.add("-D" + RemoteJVMFactory.RMI_PORT_PROPERTY + "=" + rmiPort);
     command.add("-D" + RemoteJVMFactory.JVM_ID + "=" + id);
+    command.add("-D" + RemoteJVMFactory.OUTPUT_DIR + "=" + outputDir);
     command.add(ChildJVM.class.getName());
 
     return command.toArray(new String[0]);
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/jvms/JVMMapping.java 
b/harness/src/main/java/org/apache/geode/perftest/jvms/JVMMapping.java
index e01f1f9..0ae6236 100644
--- a/harness/src/main/java/org/apache/geode/perftest/jvms/JVMMapping.java
+++ b/harness/src/main/java/org/apache/geode/perftest/jvms/JVMMapping.java
@@ -44,4 +44,7 @@ public int getId() {
     return id;
   }
 
+  public String getOutputDir() {
+    return "output/" + role + "-" + id;
+  }
 }
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/jvms/RemoteJVMFactory.java 
b/harness/src/main/java/org/apache/geode/perftest/jvms/RemoteJVMFactory.java
index d105339..af18ddc 100644
--- a/harness/src/main/java/org/apache/geode/perftest/jvms/RemoteJVMFactory.java
+++ b/harness/src/main/java/org/apache/geode/perftest/jvms/RemoteJVMFactory.java
@@ -17,7 +17,6 @@
 
 package org.apache.geode.perftest.jvms;
 
-import java.rmi.registry.Registry;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -30,10 +29,11 @@
 import org.slf4j.LoggerFactory;
 
 import org.apache.geode.perftest.infrastructure.Infrastructure;
-import org.apache.geode.perftest.jdk.RMI;
+import org.apache.geode.perftest.infrastructure.InfrastructureFactory;
 import org.apache.geode.perftest.jvms.classpath.ClassPathCopier;
 import org.apache.geode.perftest.jvms.rmi.Controller;
 import org.apache.geode.perftest.jvms.rmi.ControllerFactory;
+import org.apache.geode.perftest.runner.SharedContext;
 
 /**
  * Factory for launching JVMs and a given infrastructure and setting up RMI
@@ -45,55 +45,66 @@
   public static final String RMI_HOST = "RMI_HOST";
   public static final String RMI_PORT_PROPERTY = "RMI_PORT";
   public static final String CONTROLLER = "CONTROLLER";
+  public static final String OUTPUT_DIR = "OUTPUT_DIR";
   public static final String JVM_ID = "JVM_ID";
   public static final int RMI_PORT = 33333;
   public static final String CLASSPATH = System.getProperty("java.class.path");
   public static final String JAVA_HOME = System.getProperty("java.home");
+  private static final String LIB_DIR = ".geode-performance/lib";
   private final JVMLauncher jvmLauncher;
   private final ClassPathCopier classPathCopier;
   private final ControllerFactory controllerFactory;
+  private final InfrastructureFactory infrastructureFactory;
 
-  public RemoteJVMFactory(JVMLauncher jvmLauncher, RMI rmi,
+  public RemoteJVMFactory(InfrastructureFactory infrastructureFactory,
+                          JVMLauncher jvmLauncher,
                           ClassPathCopier classPathCopier,
                           ControllerFactory controllerFactory) {
+    this.infrastructureFactory = infrastructureFactory;
     this.jvmLauncher = jvmLauncher;
     this.classPathCopier = classPathCopier;
     this.controllerFactory = controllerFactory;
   }
-  public RemoteJVMFactory() {
-    this(new JVMLauncher(), new RMI(), new ClassPathCopier(CLASSPATH, 
JAVA_HOME), new ControllerFactory());
+  public RemoteJVMFactory(InfrastructureFactory infrastructureFactory) {
+    this(infrastructureFactory, new JVMLauncher(), new 
ClassPathCopier(CLASSPATH, JAVA_HOME), new ControllerFactory());
   }
 
   /**
    * Start all requested JVMs on the infrastructure
-   * @param infra The infrastructure to use
    * @param roles The JVMs to start. Keys a roles and values are the number
    * of JVMs in that role.
    *
    * @return a {@link RemoteJVMs} object used to access the JVMs through RMI
    */
-  public RemoteJVMs launch(Infrastructure infra,
-                           Map<String, Integer> roles) throws Exception {
+  public RemoteJVMs launch(Map<String, Integer> roles) throws Exception {
+    int numWorkers = roles.values().stream().mapToInt(Integer::intValue).sum();
+
+    Infrastructure infra = infrastructureFactory.create(numWorkers);
 
     Set<Infrastructure.Node> nodes = infra.getNodes();
-    int numWorkers = roles.values().stream().mapToInt(Integer::intValue).sum();
 
     if(nodes.size() < numWorkers) {
       throw new IllegalStateException("Too few nodes for test. Need " + 
numWorkers + ", have " + nodes.size());
     }
 
-    Controller controller = controllerFactory.createController(numWorkers);
+    List<JVMMapping> mapping = mapRolesToNodes(roles, nodes);
 
-    classPathCopier.copyToNodes(infra);
+    Controller controller = controllerFactory.createController(new 
SharedContext(mapping), numWorkers);
 
-    List<JVMMapping> mapping = mapRolesToNodes(roles, nodes);
-    CompletableFuture<Void> processesExited = 
jvmLauncher.launchProcesses(infra, RMI_PORT, mapping);
+    classPathCopier.copyToNodes(infra, LIB_DIR);
+
+    CompletableFuture<Void> processesExited = 
jvmLauncher.launchProcesses(infra, RMI_PORT, mapping,
+        LIB_DIR);
 
     if(!controller.waitForWorkers(5, TimeUnit.MINUTES)) {
       throw new IllegalStateException("Workers failed to start in 1 minute");
     }
 
-    return new RemoteJVMs(mapping, controller, processesExited);
+    return new RemoteJVMs(infra, mapping, controller, processesExited);
+  }
+
+  public InfrastructureFactory getInfrastructureFactory() {
+    return infrastructureFactory;
   }
 
   private List<JVMMapping> mapRolesToNodes(Map<String, Integer> roles,
@@ -113,5 +124,4 @@ public RemoteJVMs launch(Infrastructure infra,
     }
     return mapping;
   }
-
 }
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/jvms/RemoteJVMs.java 
b/harness/src/main/java/org/apache/geode/perftest/jvms/RemoteJVMs.java
index 5e30a3e..aa1e546 100644
--- a/harness/src/main/java/org/apache/geode/perftest/jvms/RemoteJVMs.java
+++ b/harness/src/main/java/org/apache/geode/perftest/jvms/RemoteJVMs.java
@@ -17,9 +17,8 @@
 
 package org.apache.geode.perftest.jvms;
 
-import java.rmi.NoSuchObjectException;
-import java.rmi.registry.Registry;
-import java.rmi.server.UnicastRemoteObject;
+import java.io.File;
+import java.io.IOException;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
@@ -40,15 +39,16 @@
 public class RemoteJVMs implements AutoCloseable {
   private final List<JVMMapping> jvmMappings;
   private final Controller controller;
-  private final TestContext context;
   private final CompletableFuture<Void> exited;
+  private final Infrastructure infra;
 
 
-  public RemoteJVMs(List<JVMMapping> mapping, Controller controller,
+  public RemoteJVMs(Infrastructure infra,
+                    List<JVMMapping> mapping, Controller controller,
                     CompletableFuture<Void> exited) {
+    this.infra = infra;
     this.jvmMappings = mapping;
     this.controller = controller;
-    this.context = new DefaultTestContext(jvmMappings);
     this.exited = exited;
   }
 
@@ -61,21 +61,24 @@ public void execute(Task task, String ... roleArray) {
 
     Stream<CompletableFuture> futures = jvmMappings.stream()
         .filter(mapping -> roles.contains(mapping.getRole()))
-        .map(mapping -> controller.onWorker(mapping.getId(), task, context));
+        .map(mapping -> controller.onWorker(mapping.getId(), task));
 
     futures.forEach(CompletableFuture::join);
   }
 
-  public void close() throws NoSuchObjectException, ExecutionException, 
InterruptedException {
+  public void close() throws IOException, ExecutionException, 
InterruptedException {
+    infra.close();
     controller.close();
     exited.get();
   }
 
-  public String getRole(Infrastructure.Node node) {
-    return jvmMappings.stream()
-        .filter(mapping -> mapping.getNode().equals(node))
-        .map(JVMMapping::getRole)
-        .findFirst()
-        .orElse("no-role");
+  /**
+   * Copy results to the provided output directory
+   */
+  public void copyResults(File benchmarkOutput) throws IOException {
+    benchmarkOutput.mkdirs();
+    for (JVMMapping jvm : jvmMappings) {
+      infra.copyFromNode(jvm.getNode(), jvm.getOutputDir(), new 
File(benchmarkOutput, jvm.getRole() + "-" + jvm.getId()));
+    }
   }
 }
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/jvms/classpath/ClassPathCopier.java
 
b/harness/src/main/java/org/apache/geode/perftest/jvms/classpath/ClassPathCopier.java
index af0f240..8d98b61 100644
--- 
a/harness/src/main/java/org/apache/geode/perftest/jvms/classpath/ClassPathCopier.java
+++ 
b/harness/src/main/java/org/apache/geode/perftest/jvms/classpath/ClassPathCopier.java
@@ -42,10 +42,9 @@ public ClassPathCopier(String classpath, String javaHome) {
   /**
    * Copy the current classpath to a lib directory on all of the nodes in the 
infrastructure
    */
-  public void copyToNodes(Infrastructure infrastructure) throws IOException {
+  public void copyToNodes(Infrastructure infrastructure, String destDir) 
throws IOException {
     String[] fileArray = classpath.split(File.pathSeparator);
 
-    String destDir = "lib";
     Iterable<File> files = Arrays.asList(fileArray)
         .stream()
         .filter(path -> !path.contains(javaHome))
@@ -54,7 +53,7 @@ public void copyToNodes(Infrastructure infrastructure) throws 
IOException {
         .filter(File::exists)
         .collect(Collectors.toSet());
 
-    infrastructure.copyToNodes(files, destDir);
+    infrastructure.copyToNodes(files, destDir, true);
   }
 
   private File jarDir(File file) {
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/ChildJVM.java 
b/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/ChildJVM.java
index 478902b..45d4c6a 100644
--- a/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/ChildJVM.java
+++ b/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/ChildJVM.java
@@ -20,9 +20,14 @@
 import java.io.File;
 import java.io.PrintStream;
 
+import org.apache.commons.io.FileUtils;
+import org.bouncycastle.jcajce.provider.drbg.DRBG;
+
 import org.apache.geode.perftest.jdk.RMI;
 import org.apache.geode.perftest.jdk.SystemInterface;
 import org.apache.geode.perftest.jvms.RemoteJVMFactory;
+import org.apache.geode.perftest.runner.DefaultTestContext;
+import org.apache.geode.perftest.runner.SharedContext;
 
 /**
  * Main method for a JVM running on a remote node
@@ -48,17 +53,29 @@ void run() {
     try {
       String RMI_HOST = system.getProperty(RemoteJVMFactory.RMI_HOST);
       String RMI_PORT = system.getProperty(RemoteJVMFactory.RMI_PORT_PROPERTY);
+      String OUTPUT_DIR = system.getProperty(RemoteJVMFactory.OUTPUT_DIR);
       int id = system.getInteger(RemoteJVMFactory.JVM_ID);
-      File outputDir = new File("output");
+
+
+      if(RMI_HOST == null || RMI_PORT == null || OUTPUT_DIR == null) {
+        throw new IllegalStateException("ChildJVM must be launched with all 
required system properties set.");
+      }
+
+      File outputDir = new File(OUTPUT_DIR);
+      //Clean up the output directory before the test runs
+      FileUtils.deleteQuietly(outputDir);
       outputDir.mkdirs();
-      PrintStream out = new PrintStream(new File(outputDir, "ChildJVM-" + id + 
".txt"));
+      PrintStream out = new PrintStream(new File(outputDir, "system.log"));
       system.setOut(out);
       system.setErr(out);
 
       ControllerRemote controller = (ControllerRemote) rmi
           .lookup("//" + RMI_HOST + ":" + RMI_PORT + "/" + 
RemoteJVMFactory.CONTROLLER);
 
-      Worker worker = new Worker();
+      SharedContext sharedContext = controller.getsharedContext();
+      DefaultTestContext context = new DefaultTestContext(sharedContext, 
outputDir);
+
+      Worker worker = new Worker(context);
 
       controller.addWorker(id, worker);
 
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/Controller.java 
b/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/Controller.java
index 1e20a96..e40c2fd 100644
--- a/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/Controller.java
+++ b/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/Controller.java
@@ -28,21 +28,23 @@
 import java.util.concurrent.TimeUnit;
 
 import org.apache.geode.perftest.Task;
-import org.apache.geode.perftest.TestContext;
+import org.apache.geode.perftest.runner.SharedContext;
 
 /**
  * RMI object that lives on the main controller JVM
  */
 public class Controller extends UnicastRemoteObject implements 
ControllerRemote {
   private final Registry registry;
-  private Map<Integer, WorkerRemote> workers = new ConcurrentHashMap<>();
+  private final SharedContext context;
+  private final Map<Integer, WorkerRemote> workers = new ConcurrentHashMap<>();
   private final CountDownLatch workersStarted;
   private volatile boolean isClosed;
 
 
-  Controller(int numWorkers, Registry registry) throws RemoteException {
+  Controller(int numWorkers, Registry registry, SharedContext context) throws 
RemoteException {
     this.workersStarted = new CountDownLatch(numWorkers);
     this.registry = registry;
+    this.context = context;
   }
 
   public void close() throws NoSuchObjectException {
@@ -66,7 +68,12 @@ public boolean ping() throws RemoteException {
     return !isClosed;
   }
 
-  public CompletableFuture<Void> onWorker(int id, Task task, TestContext 
context) {
+  @Override
+  public SharedContext getsharedContext() throws RemoteException {
+    return context;
+  }
+
+  public CompletableFuture<Void> onWorker(int id, Task task) {
     WorkerRemote worker = workers.get(id);
     if(worker == null) {
       throw new IllegalStateException("Worker number " + id + " is not set");
@@ -74,7 +81,7 @@ public boolean ping() throws RemoteException {
 
     return CompletableFuture.runAsync(() -> {
       try {
-        worker.execute(task, context);
+        worker.execute(task);
       } catch (Exception e) {
         throw new RuntimeException(e);
       }
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/ControllerFactory.java
 
b/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/ControllerFactory.java
index d580831..4aaa47f 100644
--- 
a/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/ControllerFactory.java
+++ 
b/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/ControllerFactory.java
@@ -25,14 +25,16 @@
 import java.rmi.registry.Registry;
 
 import org.apache.geode.perftest.jdk.RMI;
+import org.apache.geode.perftest.runner.SharedContext;
 
 public class ControllerFactory {
 
   private final RMI rmi = new RMI();
 
-  public Controller createController(int numWorkers) throws RemoteException, 
AlreadyBoundException {
+  public Controller createController(SharedContext sharedContext,
+                                     int numWorkers) throws RemoteException, 
AlreadyBoundException {
     Registry registry = rmi.createRegistry(RMI_PORT);
-    Controller controller = new Controller(numWorkers, registry);
+    Controller controller = new Controller(numWorkers, registry, 
sharedContext);
     registry.bind(CONTROLLER, controller);
     return controller;
   }
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/ControllerRemote.java
 
b/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/ControllerRemote.java
index 918d8d5..f29d361 100644
--- 
a/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/ControllerRemote.java
+++ 
b/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/ControllerRemote.java
@@ -20,9 +20,13 @@
 import java.rmi.Remote;
 import java.rmi.RemoteException;
 
+import org.apache.geode.perftest.runner.SharedContext;
+
 public interface ControllerRemote extends Remote {
 
   void addWorker(int id, WorkerRemote remote) throws RemoteException;
 
   boolean ping() throws RemoteException;
+
+  SharedContext getsharedContext() throws RemoteException;
 }
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/Worker.java 
b/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/Worker.java
index a452af1..0653c0e 100644
--- a/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/Worker.java
+++ b/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/Worker.java
@@ -21,15 +21,17 @@
 import java.rmi.server.UnicastRemoteObject;
 
 import org.apache.geode.perftest.Task;
-import org.apache.geode.perftest.TestContext;
+import org.apache.geode.perftest.runner.DefaultTestContext;
 
 public class Worker extends UnicastRemoteObject implements WorkerRemote {
 
-  public Worker() throws RemoteException {
-    super();
+  private DefaultTestContext context;
+
+  public Worker(DefaultTestContext context) throws RemoteException {
+    this.context = context;
   }
   @Override
-  public void execute(Task task, TestContext context) throws Exception {
+  public void execute(Task task) throws Exception {
     task.run(context);
   }
 }
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/WorkerRemote.java 
b/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/WorkerRemote.java
index a4020b8..f5f2859 100644
--- a/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/WorkerRemote.java
+++ b/harness/src/main/java/org/apache/geode/perftest/jvms/rmi/WorkerRemote.java
@@ -20,8 +20,7 @@
 import java.rmi.Remote;
 
 import org.apache.geode.perftest.Task;
-import org.apache.geode.perftest.TestContext;
 
 public interface WorkerRemote extends Remote {
-  void execute(Task task, TestContext context) throws Exception;
+  void execute(Task task) throws Exception;
 }
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/runner/DefaultTestContext.java
 
b/harness/src/main/java/org/apache/geode/perftest/runner/DefaultTestContext.java
index b649fa9..92a7182 100644
--- 
a/harness/src/main/java/org/apache/geode/perftest/runner/DefaultTestContext.java
+++ 
b/harness/src/main/java/org/apache/geode/perftest/runner/DefaultTestContext.java
@@ -17,27 +17,29 @@
 
 package org.apache.geode.perftest.runner;
 
+import java.io.File;
 import java.net.InetAddress;
-import java.util.List;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 import org.apache.geode.perftest.TestContext;
-import org.apache.geode.perftest.jvms.JVMMapping;
 
 public class DefaultTestContext implements TestContext {
 
-  private List<JVMMapping> jvmMappings;
+  private SharedContext sharedContext;
+  private File outputDir;
 
-  public DefaultTestContext(List<JVMMapping> jvmMappings) {
+  public DefaultTestContext(SharedContext sharedContext, File outputDir) {
+    this.sharedContext = sharedContext;
+    this.outputDir = outputDir;
+  }
 
-    this.jvmMappings = jvmMappings;
+  @Override
+  public Set<InetAddress> getHostsForRole(String role) {
+    return sharedContext.getHostsForRole(role);
   }
 
-  @Override public Set<InetAddress> getHostsForRole(String role) {
-    return jvmMappings.stream()
-        .filter(mapping -> mapping.getRole().equals(role))
-        .map(mapping -> mapping.getNode().getAddress())
-        .collect(Collectors.toSet());
+  @Override
+  public File getOutputDir() {
+    return outputDir;
   }
 }
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/runner/DefaultTestRunner.java 
b/harness/src/main/java/org/apache/geode/perftest/runner/DefaultTestRunner.java
index 54774f5..07ac6b5 100644
--- 
a/harness/src/main/java/org/apache/geode/perftest/runner/DefaultTestRunner.java
+++ 
b/harness/src/main/java/org/apache/geode/perftest/runner/DefaultTestRunner.java
@@ -18,10 +18,8 @@
 package org.apache.geode.perftest.runner;
 
 import java.io.File;
-import java.io.IOException;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ExecutionException;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -46,12 +44,12 @@
   private static final Logger logger = 
LoggerFactory.getLogger(DefaultTestRunner.class);
 
 
-  private final InfrastructureFactory infrastructureFactory;
   private final RemoteJVMFactory remoteJvmFactory;
+  private File outputDir;
 
-  public DefaultTestRunner(InfrastructureFactory infrastructureFactory, 
RemoteJVMFactory remoteJvmFactory) {
-    this.infrastructureFactory = infrastructureFactory;
+  public DefaultTestRunner(RemoteJVMFactory remoteJvmFactory, File outputDir) {
     this.remoteJvmFactory = remoteJvmFactory;
+    this.outputDir = outputDir;
   }
 
   @Override
@@ -65,35 +63,34 @@ protected void runTest(TestConfig config)
       throws Exception {
     int nodes = config.getTotalJVMs();
 
-    try (Infrastructure infra = infrastructureFactory.create(nodes)){
-      Map<String, Integer> roles = config.getRoles();
+    if(config.getName() == null) {
+      throw new IllegalStateException("Benchmark must have a name.");
+    }
+    File benchmarkOutput = new File(outputDir, config.getName());
+    if(benchmarkOutput.exists()) {
+      throw new IllegalStateException("Benchmark output directory already 
exists: " + benchmarkOutput.getPath());
+    }
 
-      logger.info("Lauching JVMs...");
-      //launch JVMs in parallel, hook them up
-      try (RemoteJVMs remoteJVMs = remoteJvmFactory.launch(infra, roles)) {
 
-        logger.info("Starting before tasks...");
-        runTasks(config.getBefore(), remoteJVMs);
+    Map<String, Integer> roles = config.getRoles();
 
-        logger.info("Starting workload tasks...");
-        runTasks(config.getWorkload(), remoteJVMs);
+    logger.info("Lauching JVMs...");
+    //launch JVMs in parallel, hook them up
+    try (RemoteJVMs remoteJVMs = remoteJvmFactory.launch(roles)) {
 
-        logger.info("Starting after tasks...");
-        runTasks(config.getAfter(), remoteJVMs);
+      logger.info("Starting before tasks...");
+      runTasks(config.getBefore(), remoteJVMs);
 
-        logger.info("Copying results...");
-        File outputDir = new File("output");
-        int nodeId = 0;
-        for (Infrastructure.Node node : infra.getNodes()) {
-          String role = remoteJVMs.getRole(node);
-          infra.copyFromNode(node, "output", new File(outputDir, role + 
nodeId++));
-        }
-      }
-    }
-  }
+      logger.info("Starting workload tasks...");
+      runTasks(config.getWorkload(), remoteJVMs);
+
+      logger.info("Starting after tasks...");
+      runTasks(config.getAfter(), remoteJVMs);
 
-  public InfrastructureFactory getInfrastructureFactory() {
-    return infrastructureFactory;
+      logger.info("Copying results...");
+      remoteJVMs.copyResults(benchmarkOutput);
+
+    }
   }
 
   private void runTasks(List<TestConfig.TestStep> steps,
@@ -102,4 +99,8 @@ private void runTasks(List<TestConfig.TestStep> steps,
       remoteJVMs.execute(testStep.getTask(), testStep.getRoles());
     });
   }
+
+  public RemoteJVMFactory getRemoteJvmFactory() {
+    return remoteJvmFactory;
+  }
 }
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/runner/SharedContext.java 
b/harness/src/main/java/org/apache/geode/perftest/runner/SharedContext.java
new file mode 100644
index 0000000..50aeadf
--- /dev/null
+++ b/harness/src/main/java/org/apache/geode/perftest/runner/SharedContext.java
@@ -0,0 +1,48 @@
+/*
+ * 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.perftest.runner;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.geode.perftest.jvms.JVMMapping;
+
+/**
+ * Context for a running test that is the same for all JVMs
+ * running the test. This context is created at the beginning of the
+ * test run and passed to all JVMs.
+ */
+public class SharedContext implements Serializable {
+
+  private List<JVMMapping> jvmMappings;
+
+  public SharedContext(List<JVMMapping> jvmMappings) {
+
+    this.jvmMappings = jvmMappings;
+  }
+
+  public Set<InetAddress> getHostsForRole(String role) {
+    return jvmMappings.stream()
+        .filter(mapping -> mapping.getRole().equals(role))
+        .map(mapping -> mapping.getNode().getAddress())
+        .collect(Collectors.toSet());
+  }
+}
diff --git 
a/harness/src/main/java/org/apache/geode/perftest/yardstick/YardstickTask.java 
b/harness/src/main/java/org/apache/geode/perftest/yardstick/YardstickTask.java
index 1e25056..9046327 100644
--- 
a/harness/src/main/java/org/apache/geode/perftest/yardstick/YardstickTask.java
+++ 
b/harness/src/main/java/org/apache/geode/perftest/yardstick/YardstickTask.java
@@ -75,7 +75,7 @@ public int threads() {
 
       @Override
       public String outputFolder() {
-        return "output";
+        return context.getOutputDir().getAbsolutePath();
       }
     };
     cfg.output(System.out);
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 c011da6..12bdbe0 100644
--- 
a/harness/src/test/java/org/apache/geode/perftest/TestRunnerIntegrationTest.java
+++ 
b/harness/src/test/java/org/apache/geode/perftest/TestRunnerIntegrationTest.java
@@ -17,23 +17,75 @@
 
 package org.apache.geode.perftest;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 
+import org.apache.geode.perftest.benchmarks.EmptyBenchmark;
 import 
org.apache.geode.perftest.infrastructure.local.LocalInfrastructureFactory;
 import org.apache.geode.perftest.jvms.RemoteJVMFactory;
 import org.apache.geode.perftest.runner.DefaultTestRunner;
+import 
org.apache.geode.perftest.yardstick.analysis.YardstickThroughputSensorParser;
 
 public class TestRunnerIntegrationTest {
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
+  private TestRunner runner;
+  private File outputDir;
+  public static final String SAMPLE_BENCHMARK = "SampleBenchmark";
+
+  @Before
+  public void setup() throws IOException {
+    outputDir = temporaryFolder.newFolder();
+    runner = new DefaultTestRunner(new RemoteJVMFactory(new 
LocalInfrastructureFactory()),
+        outputDir);
+  }
 
   @Test
   public void runsBeforeWorkload() throws Exception {
-    TestRunner runner = new DefaultTestRunner(new 
LocalInfrastructureFactory(), new RemoteJVMFactory());
-
     runner.runTest(testConfig -> {
+      testConfig.name(SAMPLE_BENCHMARK);
       testConfig.role("all", 1);
       testConfig.before(context -> System.out.println("hello"), "all");
+    });
+  }
+
+  @Test
+  public void generatesOutputDirectoryPerBenchmark() throws Exception {
 
+    runner.runTest(testConfig -> {
+      testConfig.name(SAMPLE_BENCHMARK);
+      testConfig.role("all", 1);
+      testConfig.workload(new EmptyBenchmark(), "all");
     });
 
+    File expectedBenchmarkDir = new File(outputDir, SAMPLE_BENCHMARK);
+    assertTrue(expectedBenchmarkDir.exists());
+
+    //Node directory name is the role + a number
+    File expectedNodeDir = new File(expectedBenchmarkDir, "all-0");
+    assertTrue(expectedNodeDir.exists());
+
+    //We expect the node directory to have benchmark results
+    Stream<Path>
+        outputFiles = Files.walk(expectedNodeDir.toPath())
+        .filter(nameMatches(YardstickThroughputSensorParser.sensorOutputFile));
+
+    assertEquals(1, outputFiles.count());
+  }
+
+  private Predicate<Path> nameMatches(String sensorOutputFile) {
+    return path -> path.toString().contains(sensorOutputFile);
   }
 }
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 0ae3fee..2b1027b 100644
--- a/harness/src/test/java/org/apache/geode/perftest/TestRunnerJUnitTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/TestRunnerJUnitTest.java
@@ -25,7 +25,11 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import java.io.File;
+
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.mockito.InOrder;
 
 import org.apache.geode.perftest.infrastructure.InfrastructureFactory;
@@ -36,24 +40,25 @@
 
 public class TestRunnerJUnitTest {
 
+  @Rule
+  public TemporaryFolder folder = new TemporaryFolder();
+
   @Test
   public void testRunnerRunsBeforeAndAfterTasks() throws Exception {
 
-    InfrastructureFactory infrastructureFactory = 
mock(InfrastructureFactory.class);
-    Infrastructure infrastructure = mock(Infrastructure.class);
     RemoteJVMFactory remoteJvmFactory = mock(RemoteJVMFactory.class);
 
-    when(infrastructureFactory.create(anyInt())).thenReturn(infrastructure);
-
     RemoteJVMs remoteJVMs = mock(RemoteJVMs.class);
-    when(remoteJvmFactory.launch(eq(infrastructure), 
any())).thenReturn(remoteJVMs);
+    when(remoteJvmFactory.launch(any())).thenReturn(remoteJVMs);
 
-    TestRunner runner = new DefaultTestRunner(infrastructureFactory, 
remoteJvmFactory);
+    TestRunner runner = new DefaultTestRunner(remoteJvmFactory,
+        folder.newFolder());
 
     Task before = mock(Task.class);
     Task after = mock(Task.class);
 
     PerformanceTest test = config -> {
+      config.name("SampleBenchmark");
       config.role("before", 1);
       config.role("workload", 1);
       config.role("after", 1);
diff --git 
a/harness/src/test/java/org/apache/geode/perftest/TestRunnersTest.java 
b/harness/src/test/java/org/apache/geode/perftest/TestRunnersTest.java
index 05b21b8..99e33eb 100644
--- a/harness/src/test/java/org/apache/geode/perftest/TestRunnersTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/TestRunnersTest.java
@@ -17,18 +17,12 @@
 
 package org.apache.geode.perftest;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
 
 import java.util.Arrays;
 
-import jdk.nashorn.internal.objects.NativeDebug;
-import org.junit.Rule;
 import org.junit.Test;
 
-import org.apache.geode.perftest.infrastructure.InfrastructureFactory;
-import org.apache.geode.perftest.infrastructure.local.LocalInfrastructure;
-import 
org.apache.geode.perftest.infrastructure.local.LocalInfrastructureFactory;
-import org.apache.geode.perftest.infrastructure.ssh.SshInfrastructure;
 import org.apache.geode.perftest.infrastructure.ssh.SshInfrastructureFactory;
 import org.apache.geode.perftest.runner.DefaultTestRunner;
 
@@ -36,16 +30,16 @@
 
   @Test
   public void defaultRunnerShouldParseHosts() {
-    DefaultTestRunner runner = (DefaultTestRunner) 
TestRunners.defaultRunner("localhost,localhost");
+    DefaultTestRunner runner = (DefaultTestRunner) 
TestRunners.defaultRunner("localhost,localhost", null);
 
     SshInfrastructureFactory infrastructureFactory =
-        (SshInfrastructureFactory) runner.getInfrastructureFactory();
+        (SshInfrastructureFactory) 
runner.getRemoteJvmFactory().getInfrastructureFactory();
 
     assertEquals(Arrays.asList("localhost", "localhost") , 
infrastructureFactory.getHosts());
   }
   
   @Test(expected = IllegalStateException.class)
   public void defaultRunnerShouldFailWithNoHosts() {
-    TestRunners.defaultRunner(null);
+    TestRunners.defaultRunner(null, null);
   }
 }
\ No newline at end of file
diff --git 
a/harness/src/test/java/org/apache/geode/perftest/benchmarks/EmptyBenchmark.java
 
b/harness/src/test/java/org/apache/geode/perftest/benchmarks/EmptyBenchmark.java
new file mode 100644
index 0000000..02e0626
--- /dev/null
+++ 
b/harness/src/test/java/org/apache/geode/perftest/benchmarks/EmptyBenchmark.java
@@ -0,0 +1,43 @@
+/*
+ * 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.perftest.benchmarks;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.yardstickframework.BenchmarkDriverAdapter;
+
+public class EmptyBenchmark extends BenchmarkDriverAdapter implements 
Serializable {
+  private AtomicInteger invocations = new AtomicInteger();
+
+  @Override
+  public boolean test(Map<Object, Object> ctx) throws Exception {
+    invocations.incrementAndGet();
+    return true;
+  }
+
+  public int getInvocations() {
+    return this.invocations.get();
+  }
+
+  @Override
+  public void onException(Throwable e) {
+    e.printStackTrace();
+  }
+}
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 9205b51..9715b4e 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
@@ -57,7 +57,7 @@ public void copyToNodesPutsFileOnNode() throws IOException, 
InterruptedException
 
     File expectedDir = new File(nodedir, "lib");
     assertFalse(expectedDir.exists());
-    infra.copyToNodes(Arrays.asList(someFile), "lib");
+    infra.copyToNodes(Arrays.asList(someFile), "lib", true);
     assertTrue(expectedDir.exists());
     assertTrue(new File(expectedDir, someFile.getName()).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 94f6d71..2936e80 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
@@ -70,12 +70,31 @@ public void copyToNodesPutsFileOnNode() throws IOException, 
InterruptedException
 
     assertFalse(targetFolder.exists());
 
-    infra.copyToNodes(Arrays.asList(someFile), targetFolder.getPath());
+    infra.copyToNodes(Arrays.asList(someFile), targetFolder.getPath(), false);
 
     assertTrue(targetFolder.exists());
     assertTrue(new File(targetFolder, someFile.getName()).exists());
   }
 
+  @Test
+  public void copyToNodesCleansDirectory() throws IOException, 
InterruptedException {
+    SshInfrastructure infra = new SshInfrastructure(HOSTS, USER);
+
+    File someFile = temporaryFolder.newFile();
+    File targetFolder = new File(temporaryFolder.newFolder(), "dest");
+
+    targetFolder.mkdirs();
+    File fileToRemove = new File(targetFolder, "removethis");
+    fileToRemove.createNewFile();
+    assertTrue(fileToRemove.exists());
+
+    infra.copyToNodes(Arrays.asList(someFile), targetFolder.getPath(), true);
+
+    assertTrue(targetFolder.exists());
+    assertTrue(new File(targetFolder, someFile.getName()).exists());
+    assertFalse(fileToRemove.exists());
+  }
+
 
   @Test
   public void canCopyFilesFromANode()
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 6528907..03e2931 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
@@ -28,6 +28,7 @@
 import org.junit.rules.TemporaryFolder;
 
 import org.apache.geode.perftest.infrastructure.local.LocalInfrastructure;
+import 
org.apache.geode.perftest.infrastructure.local.LocalInfrastructureFactory;
 
 public class RemoteJVMFactoryIntegrationTest {
   @Rule
@@ -35,9 +36,9 @@
 
   @Test
   public void canExecuteCodeOnWorker() throws Exception {
-    RemoteJVMFactory remoteJvmFactory = new RemoteJVMFactory();
+    RemoteJVMFactory remoteJvmFactory = new RemoteJVMFactory(new 
LocalInfrastructureFactory());
     Map<String, Integer> roles = Collections.singletonMap("worker", 1);
-    try (RemoteJVMs jvms = remoteJvmFactory.launch(new LocalInfrastructure(1), 
roles)) {
+    try (RemoteJVMs jvms = remoteJvmFactory.launch(roles)) {
       File tempFile = new File(temporaryFolder.newFolder(), 
"tmpfile").getAbsoluteFile();
       jvms.execute(context -> {
         tempFile.createNewFile();
diff --git 
a/harness/src/test/java/org/apache/geode/perftest/jvms/RemoteJVMFactoryTest.java
 
b/harness/src/test/java/org/apache/geode/perftest/jvms/RemoteJVMFactoryTest.java
index 3433aeb..cb576f0 100644
--- 
a/harness/src/test/java/org/apache/geode/perftest/jvms/RemoteJVMFactoryTest.java
+++ 
b/harness/src/test/java/org/apache/geode/perftest/jvms/RemoteJVMFactoryTest.java
@@ -37,7 +37,7 @@
 import org.mockito.InOrder;
 
 import org.apache.geode.perftest.infrastructure.Infrastructure;
-import org.apache.geode.perftest.jdk.RMI;
+import org.apache.geode.perftest.infrastructure.InfrastructureFactory;
 import org.apache.geode.perftest.jvms.classpath.ClassPathCopier;
 import org.apache.geode.perftest.jvms.rmi.Controller;
 import org.apache.geode.perftest.jvms.rmi.ControllerFactory;
@@ -45,11 +45,11 @@
 public class RemoteJVMFactoryTest {
 
   private JVMLauncher jvmLauncher;
-  private RMI rmi;
   private ClassPathCopier classPathCopier;
   private RemoteJVMFactory factory;
   private Controller controller;
   private ControllerFactory controllerFactory;
+  private Infrastructure infra;
 
   @Before
   public void setUp() throws AlreadyBoundException, RemoteException {
@@ -57,14 +57,15 @@ public void setUp() throws AlreadyBoundException, 
RemoteException {
     jvmLauncher = mock(JVMLauncher.class);
     controller = mock(Controller.class);
     controllerFactory = mock(ControllerFactory.class);
-    when(controllerFactory.createController(anyInt())).thenReturn(controller);
-    factory = new RemoteJVMFactory(jvmLauncher, rmi, classPathCopier, 
controllerFactory);
+    when(controllerFactory.createController(any(), 
anyInt())).thenReturn(controller);
+    infra = mock(Infrastructure.class);
+    InfrastructureFactory infraFactory = nodes -> infra;
+    factory = new RemoteJVMFactory(infraFactory, jvmLauncher, classPathCopier, 
controllerFactory);
   }
 
   @Test
   public void launchMethodCreatesControllerAndLaunchesNodes() throws Exception 
{
     Map<String, Integer> roles = Collections.singletonMap("role", 2);
-    Infrastructure infra = mock(Infrastructure.class);
 
     Infrastructure.Node node1 = mock(Infrastructure.Node.class);
     Infrastructure.Node node2 = mock(Infrastructure.Node.class);
@@ -73,12 +74,12 @@ public void launchMethodCreatesControllerAndLaunchesNodes() 
throws Exception {
 
     when(controller.waitForWorkers(anyInt(), any())).thenReturn(true);
 
-    factory.launch(infra, roles);
+    factory.launch(roles);
 
     InOrder inOrder = inOrder(controller, controllerFactory, jvmLauncher, 
classPathCopier, infra);
 
-    inOrder.verify(controllerFactory).createController(eq(2));
-    inOrder.verify(jvmLauncher).launchProcesses(eq(infra), anyInt(), any());
+    inOrder.verify(controllerFactory).createController(any(), eq(2));
+    inOrder.verify(jvmLauncher).launchProcesses(eq(infra), anyInt(), any(), 
any());
     inOrder.verify(controller).waitForWorkers(anyInt(), any());
 
 
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 146ab61..2d61883 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
@@ -17,6 +17,10 @@
 
 package org.apache.geode.perftest.jvms.rmi;
 
+import static org.apache.geode.perftest.jvms.RemoteJVMFactory.OUTPUT_DIR;
+import static org.apache.geode.perftest.jvms.RemoteJVMFactory.RMI_HOST;
+import static 
org.apache.geode.perftest.jvms.RemoteJVMFactory.RMI_PORT_PROPERTY;
+import static org.junit.Assert.assertFalse;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
@@ -24,12 +28,16 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import java.io.File;
+import java.io.IOException;
 import java.net.MalformedURLException;
 import java.rmi.NotBoundException;
 import java.rmi.RemoteException;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 
 import org.apache.geode.perftest.jdk.RMI;
 import org.apache.geode.perftest.jdk.SystemInterface;
@@ -37,14 +45,21 @@
 
 public class ChildJVMTest {
 
+  @Rule
+  public TemporaryFolder temporaryFolder = new TemporaryFolder();
   private RMI rmi;
   private ChildJVM jvm;
   private SystemInterface system;
   private Controller controller;
+  private File folder;
 
   @Before
-  public void setUp() throws RemoteException, NotBoundException, 
MalformedURLException {
+  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 = temporaryFolder.newFolder();
+    when(system.getProperty(OUTPUT_DIR)).thenReturn(folder.getAbsolutePath());
     rmi = mock(RMI.class);
     jvm = new ChildJVM(rmi, system, 1);
 
@@ -69,4 +84,14 @@ public void childRetriesUntilControllerExits() throws 
RemoteException {
     verify(controller, times(3)).ping();
   }
 
+  @Test
+  public void childCleansOutputDir() throws IOException {
+    File expectedFile = new File(folder, "somefile.txt");
+    expectedFile.createNewFile();
+
+    jvm.run();
+
+    assertFalse(expectedFile.exists());
+  }
+
 }
\ No newline at end of file
diff --git 
a/harness/src/test/java/org/apache/geode/perftest/runner/DefaultTestContextTest.java
 b/harness/src/test/java/org/apache/geode/perftest/runner/SharedContextTest.java
similarity index 93%
rename from 
harness/src/test/java/org/apache/geode/perftest/runner/DefaultTestContextTest.java
rename to 
harness/src/test/java/org/apache/geode/perftest/runner/SharedContextTest.java
index 704374f..7784105 100644
--- 
a/harness/src/test/java/org/apache/geode/perftest/runner/DefaultTestContextTest.java
+++ 
b/harness/src/test/java/org/apache/geode/perftest/runner/SharedContextTest.java
@@ -33,7 +33,7 @@
 import org.apache.geode.perftest.infrastructure.Infrastructure;
 import org.apache.geode.perftest.jvms.JVMMapping;
 
-public class DefaultTestContextTest {
+public class SharedContextTest {
 
   @Test
   public void getHostsForRoleShouldReturnCorrectList() throws 
UnknownHostException {
@@ -47,7 +47,7 @@ public void getHostsForRoleShouldReturnCorrectList() throws 
UnknownHostException
     when(node2.getAddress()).thenReturn(host2);
     JVMMapping mapping2 = new JVMMapping(node2, "role", 2);
 
-    DefaultTestContext context = new 
DefaultTestContext(Arrays.asList(mapping1, mapping2));
+    SharedContext context = new SharedContext(Arrays.asList(mapping1, 
mapping2));
 
     Set<InetAddress> hosts = context.getHostsForRole("role");
 
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 7d60d9b..8a29d2e 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
@@ -17,50 +17,43 @@
 
 package org.apache.geode.perftest.yardstick;
 
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
+import static org.junit.Assert.assertTrue;
 
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.io.File;
+import java.nio.file.Files;
 
 import org.junit.Assert;
+import org.junit.Rule;
 import org.junit.Test;
-import org.yardstickframework.BenchmarkDriverAdapter;
+import org.junit.rules.TemporaryFolder;
 
 import org.apache.geode.perftest.Task;
+import org.apache.geode.perftest.TestContext;
 import org.apache.geode.perftest.WorkloadConfig;
+import org.apache.geode.perftest.benchmarks.EmptyBenchmark;
+import org.apache.geode.perftest.runner.DefaultTestContext;
 
 public class YardstickTaskTest {
 
+  @Rule
+  public final TemporaryFolder folder = new TemporaryFolder();
+
   @Test
   public void testExecuteBenchmark() throws Exception {
     EmptyBenchmark benchmark = new EmptyBenchmark();
     WorkloadConfig workloadConfig = new WorkloadConfig();
     workloadConfig.threads(1);
     Task task = new YardstickTask(benchmark, workloadConfig);
-    task.run(null);
+    File outputDir = folder.newFolder();
+    TestContext context = new DefaultTestContext(null, outputDir);
+    task.run(context);
+
+    assertTrue(1 <= benchmark.getInvocations());
 
-    Assert.assertTrue(1 <= benchmark.invocations.get());
+    assertTrue(Files.walk(outputDir.toPath()).findFirst().isPresent());
 
     //TODO -verify probes are shutdown
     //TODO -verify benchmark is shutdown
-    //TODO - pass in probes to yardstick util, turn it into a real class
-
   }
 
-  private static class EmptyBenchmark extends BenchmarkDriverAdapter {
-    private AtomicInteger invocations = new AtomicInteger();
-
-    @Override
-    public boolean test(Map<Object, Object> ctx) throws Exception {
-      invocations.incrementAndGet();
-      return true;
-    }
-
-    @Override
-    public void onException(Throwable e) {
-      e.printStackTrace();
-    }
-  }
 }
\ No newline at end of file


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to