You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by wi...@apache.org on 2018/11/20 19:02:54 UTC
[geode-benchmarks] branch develop updated: Adding new class to
evaluate a test run against a baseline
This is an automated email from the ASF dual-hosted git repository.
wirebaron pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode-benchmarks.git
The following commit(s) were added to refs/heads/develop by this push:
new 178ad74 Adding new class to evaluate a test run against a baseline
178ad74 is described below
commit 178ad74147914224ce8d61c7d9282a50908e1721
Author: Brian Rowe <br...@pivotal.io>
AuthorDate: Tue Nov 20 11:02:50 2018 -0800
Adding new class to evaluate a test run against a baseline
Adding new class to evaluate a test run against a baseline and output the relative performance.
---
.../perftest/analysis/BenchmarkRunAnalyzer.java | 102 +++++++++++++++
.../geode/perftest/analysis/ProbeResultParser.java | 34 +++++
.../YardstickPercentileSensorParser.java | 43 +++++--
.../YardstickThroughputSensorParser.java | 70 +++++++----
.../analysis/BenchmarkRunAnalyzerTest.java | 139 +++++++++++++++++++++
.../YardstickPercentileSensorParserTest.java | 4 +-
.../YardstickThroughputSensorParserTest.java | 4 +-
7 files changed, 362 insertions(+), 34 deletions(-)
diff --git a/harness/src/main/java/org/apache/geode/perftest/analysis/BenchmarkRunAnalyzer.java b/harness/src/main/java/org/apache/geode/perftest/analysis/BenchmarkRunAnalyzer.java
new file mode 100644
index 0000000..c095876
--- /dev/null
+++ b/harness/src/main/java/org/apache/geode/perftest/analysis/BenchmarkRunAnalyzer.java
@@ -0,0 +1,102 @@
+/*
+ * 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.analysis;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Analyzer that takes in benchmarks, probes, and result directories and produces
+ * a comparison of the results to a provided writer.
+ *
+ * This currently handles data in the format
+ * <pre>
+ * Result1
+ * /BenchmarkA
+ * /client1
+ * /Probe1.csv
+ * /client2
+ * /Probe2.csv
+ * /BenchmarkB
+ * ...
+ * </pre>
+ */
+public class BenchmarkRunAnalyzer {
+ private final List<SensorData> benchmarks = new ArrayList<>();
+ private final List<ProbeResultParser> probes = new ArrayList<>();
+
+ /**
+ * Add a benchmark to be analyzed. The benchmark is expected to exist
+ * in both result directories passed to {@link #analyzeTestRun(File, File, Writer)}
+ */
+ public void addBenchmark(String name, String testResultDir, List<String> nodeNames) {
+ benchmarks.add(new SensorData(name, testResultDir, nodeNames));
+ }
+
+ /**
+ * Add a probe to produce a comparison for. The probe expects to find output files
+ * in the result directory for each node of each benchmark.
+ */
+ public void addProbe(ProbeResultParser probeResultParser) {
+ probes.add(probeResultParser);
+ }
+
+ public void analyzeTestRun(File testResultDir, File baselineResultDir, Writer output)
+ throws IOException {
+ PrintWriter stream = new PrintWriter(output);
+ for (SensorData benchmark : benchmarks) {
+ stream.println("-- " + benchmark.benchmarkName + " --");
+ for (ProbeResultParser probe : probes) {
+ stream.println(probe.getResultDescription());
+ for (String node : benchmark.nodesToParse) {
+ probe.parseResults(new File(new File(testResultDir, benchmark.benchmarkSubdirectory), node));
+ }
+ double testResult = probe.getProbeResult();
+ stream.println("Result: " + String.valueOf(testResult));
+ probe.reset();
+ for (String node : benchmark.nodesToParse) {
+ probe.parseResults(new File(new File(baselineResultDir, benchmark.benchmarkSubdirectory), node));
+ }
+ double baselineResult = probe.getProbeResult();
+ stream.println("Baseline: " + String.valueOf(baselineResult));
+ stream.println("Relative performance: " + String.valueOf(testResult / baselineResult));
+ stream.println();
+ }
+ }
+
+ stream.flush();
+ }
+
+ // TODO: depending on how run output is stored, this data may be excessive or insufficient
+ // The present assumption is each benchmark contains an arbitrarily named result directory
+ // containing subdirectories for each node. Those subdirectories then contain the probe output
+ // files for the run, for that node.
+ private static class SensorData {
+ private final String benchmarkName;
+ private final String benchmarkSubdirectory;
+ private final List<String> nodesToParse;
+
+ public SensorData(String benchmarkName, String benchmarkSubdirectory, List<String> nodesNames) {
+ this.benchmarkName = benchmarkName;
+ this.benchmarkSubdirectory = benchmarkSubdirectory;
+ this.nodesToParse = nodesNames;
+ }
+ }
+
+}
diff --git a/harness/src/main/java/org/apache/geode/perftest/analysis/ProbeResultParser.java b/harness/src/main/java/org/apache/geode/perftest/analysis/ProbeResultParser.java
new file mode 100644
index 0000000..bcc76d4
--- /dev/null
+++ b/harness/src/main/java/org/apache/geode/perftest/analysis/ProbeResultParser.java
@@ -0,0 +1,34 @@
+/*
+ * 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.analysis;
+
+import java.io.File;
+import java.io.IOException;
+
+public interface ProbeResultParser {
+ // Given a output directory for a benchmark, parse out the data for the desired probe. Note that
+ // this method may be passed several csv files for a run and is expected to appropriately
+ // aggregate the result of interest.
+ void parseResults(File benchmarkOutputDir) throws IOException;
+
+ // Reset the parser to a clean state where parseResults can be called again
+ void reset();
+
+ // Get a single float value summarizing the data for the probe.
+ double getProbeResult();
+
+ // Get a text description of what the probe result is depicting
+ String getResultDescription();
+}
diff --git a/harness/src/main/java/org/apache/geode/perftest/yardstick/YardstickPercentileSensorParser.java b/harness/src/main/java/org/apache/geode/perftest/yardstick/analysis/YardstickPercentileSensorParser.java
similarity index 75%
rename from harness/src/main/java/org/apache/geode/perftest/yardstick/YardstickPercentileSensorParser.java
rename to harness/src/main/java/org/apache/geode/perftest/yardstick/analysis/YardstickPercentileSensorParser.java
index 429cb41..77af444 100644
--- a/harness/src/main/java/org/apache/geode/perftest/yardstick/YardstickPercentileSensorParser.java
+++ b/harness/src/main/java/org/apache/geode/perftest/yardstick/analysis/YardstickPercentileSensorParser.java
@@ -12,7 +12,7 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
-package org.apache.geode.perftest.yardstick;
+package org.apache.geode.perftest.yardstick.analysis;
import static java.lang.Math.abs;
@@ -22,12 +22,21 @@ import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
-public class YardstickPercentileSensorParser {
- static final String sensorOutputFile = "PercentileProbe.csv";
+import org.yardstickframework.probes.PercentileProbe;
+
+import org.apache.geode.perftest.analysis.ProbeResultParser;
+
+/**
+ * Parses the output from {@link PercentileProbe} and reports the
+ * 99% percentile latency in microseconds.
+ */
+public class YardstickPercentileSensorParser implements ProbeResultParser {
+ public static final String sensorOutputFile = "PercentileProbe.csv";
+ public static final String probeResultDescription = "99th percentile latency";
private class SensorBucket {
public int latencyBucket;
- public float bucketPercentage;
+ public double bucketPercentage;
SensorBucket(String dataLine) throws IOException {
String[] data = dataLine.split(",");
@@ -36,7 +45,7 @@ public class YardstickPercentileSensorParser {
}
try {
latencyBucket = Integer.parseInt(data[0]);
- bucketPercentage = Float.parseFloat(data[1]);
+ bucketPercentage = Double.parseDouble(data[1]);
} catch (NumberFormatException e) {
throw new IOException("Invalid data line: " + dataLine);
}
@@ -60,6 +69,22 @@ public class YardstickPercentileSensorParser {
}
}
+ @Override
+ public void reset() {
+ buckets = new ArrayList<>();
+ }
+
+ @Override
+ // Default probe result is the 99th percentile latency for the benchmark
+ public double getProbeResult() {
+ return getPercentile(99);
+ }
+
+ @Override
+ public String getResultDescription() {
+ return probeResultDescription;
+ }
+
private void normalizeBuckets() {
float totalPercentage = 0;
for (SensorBucket bucket : buckets) {
@@ -73,11 +98,11 @@ public class YardstickPercentileSensorParser {
}
}
- public float getPercentile(int target) {
+ public double getPercentile(int target) {
if (target < 0 || target > 100) {
throw new RuntimeException("Percentile must be in the range (0, 100), invalid value: " + target);
}
- float targetPercent = target / 100f;
+ double targetPercent = target / 100.0;
normalizeBuckets();
if (buckets.size() == 1) {
@@ -86,7 +111,7 @@ public class YardstickPercentileSensorParser {
SensorBucket[] bucketArray = buckets.toArray(new SensorBucket[buckets.size()]);
- float accumulator = 0;
+ double accumulator = 0;
int i = -1;
while (targetPercent - accumulator > 0.0001) {
++i;
@@ -100,7 +125,7 @@ public class YardstickPercentileSensorParser {
bucketArray[i + 1].latencyBucket - targetBucket.latencyBucket :
targetBucket.latencyBucket - bucketArray[i - 1].latencyBucket;
- float percentileLocationInTargetBucket = 1.0f - ((accumulator - targetPercent) / targetBucket.bucketPercentage);
+ double percentileLocationInTargetBucket = 1.0 - ((accumulator - targetPercent) / targetBucket.bucketPercentage);
return targetBucket.latencyBucket + bucketSize * percentileLocationInTargetBucket;
}
diff --git a/harness/src/main/java/org/apache/geode/perftest/yardstick/YardstickThroughputSensorParser.java b/harness/src/main/java/org/apache/geode/perftest/yardstick/analysis/YardstickThroughputSensorParser.java
similarity index 68%
rename from harness/src/main/java/org/apache/geode/perftest/yardstick/YardstickThroughputSensorParser.java
rename to harness/src/main/java/org/apache/geode/perftest/yardstick/analysis/YardstickThroughputSensorParser.java
index 981080e..6c577f9 100644
--- a/harness/src/main/java/org/apache/geode/perftest/yardstick/YardstickThroughputSensorParser.java
+++ b/harness/src/main/java/org/apache/geode/perftest/yardstick/analysis/YardstickThroughputSensorParser.java
@@ -12,7 +12,7 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
-package org.apache.geode.perftest.yardstick;
+package org.apache.geode.perftest.yardstick.analysis;
import java.io.BufferedReader;
import java.io.File;
@@ -21,28 +21,17 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-public class YardstickThroughputSensorParser {
- static final String sensorOutputFile = "ThroughputLatencyProbe.csv";
+import org.yardstickframework.probes.ThroughputLatencyProbe;
- private class SensorDatapoint {
- public int second;
- public float opsPerSec;
- public float avgLatency;
+import org.apache.geode.perftest.analysis.ProbeResultParser;
- SensorDatapoint(String dataLine) throws IOException {
- String[] data = dataLine.split(",");
- if (data.length != 3) {
- throw new IOException("Invalid data line: " + dataLine);
- }
- try {
- second = Integer.parseInt(data[0]);
- opsPerSec = Float.parseFloat(data[1]);
- avgLatency = Float.parseFloat(data[2]);
- } catch (NumberFormatException e) {
- throw new IOException("Invalid data line: " + dataLine);
- }
- }
- }
+/**
+ * Parses the results from a {@link ThroughputLatencyProbe} and
+ * reports the average throughput in operations/second.
+ */
+public class YardstickThroughputSensorParser implements ProbeResultParser {
+ public static final String sensorOutputFile = "ThroughputLatencyProbe.csv";
+ public static final String probeResultDescription = "average ops/second";
private List<SensorDatapoint> datapoints = new ArrayList<>();
@@ -61,11 +50,46 @@ public class YardstickThroughputSensorParser {
}
}
- public float getAverageThroughput() {
- float accumulator = 0;
+ @Override
+ public void reset() {
+ datapoints = new ArrayList<>();
+ }
+
+ @Override
+ public double getProbeResult() {
+ return getAverageThroughput();
+ }
+
+ @Override
+ public String getResultDescription() {
+ return probeResultDescription;
+ }
+
+ public double getAverageThroughput() {
+ double accumulator = 0;
for (SensorDatapoint datapoint : datapoints) {
accumulator += datapoint.opsPerSec;
}
return accumulator / datapoints.size();
}
+
+ private static class SensorDatapoint {
+ private int second;
+ private double opsPerSec;
+ private double avgLatency;
+
+ SensorDatapoint(String dataLine) throws IOException {
+ String[] data = dataLine.split(",");
+ if (data.length != 3) {
+ throw new IOException("Invalid data line: " + dataLine);
+ }
+ try {
+ second = Integer.parseInt(data[0]);
+ opsPerSec = Float.parseFloat(data[1]);
+ avgLatency = Float.parseFloat(data[2]);
+ } catch (NumberFormatException e) {
+ throw new IOException("Invalid data line: " + dataLine);
+ }
+ }
+ }
}
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
new file mode 100644
index 0000000..1911c0c
--- /dev/null
+++ b/harness/src/test/java/org/apache/geode/perftest/analysis/BenchmarkRunAnalyzerTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.analysis;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import org.apache.geode.perftest.analysis.BenchmarkRunAnalyzer;
+import org.apache.geode.perftest.yardstick.analysis.YardstickPercentileSensorParser;
+import org.apache.geode.perftest.yardstick.analysis.YardstickThroughputSensorParser;
+
+public class BenchmarkRunAnalyzerTest {
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ @Test
+ public void verifyResultHarvester() throws IOException {
+ final File testFolder = temporaryFolder.newFolder("testFolder");
+ final File testBenchmarkA1 = temporaryFolder.newFolder("testFolder","BenchmarkA","client1");
+ final File testBenchmarkA2 = temporaryFolder.newFolder("testFolder","BenchmarkA","client2");
+ final File testBenchmarkB1 = temporaryFolder.newFolder("testFolder","BenchmarkB","client1");
+ final File testBenchmarkB2 = temporaryFolder.newFolder("testFolder","BenchmarkB","client2");
+ final File baseFolder = temporaryFolder.newFolder("baseFolder");
+ final File baseBenchmarkA1 = temporaryFolder.newFolder("baseFolder","BenchmarkA","client1");
+ final File baseBenchmarkA2 = temporaryFolder.newFolder("baseFolder","BenchmarkA","client2");
+ final File baseBenchmarkB1 = temporaryFolder.newFolder("baseFolder","BenchmarkB","client1");
+ final File baseBenchmarkB2 = temporaryFolder.newFolder("baseFolder","BenchmarkB","client2");
+
+ populateThroughputCSV(testBenchmarkA1, new double[] {10, 15, 20, 25, 30}); // Avg 20
+ populatePercentileCSV(testBenchmarkA1, new double[] {0, 0, 99, 1}); // 200
+ populateThroughputCSV(testBenchmarkB1, new double[] {10, 15, 20, 25, 30, 35, 40}); // Avg 25
+ populatePercentileCSV(testBenchmarkB1, new double[] {0, 0, 0, 99, 1}); // 300
+ populateThroughputCSV(baseBenchmarkA1, new double[] {15, 20, 25, 30, 35}); // Avg 25
+ populatePercentileCSV(baseBenchmarkA1, new double[] {0, 99, 1}); // 100
+ populateThroughputCSV(baseBenchmarkB1, new double[] {10, 15, 20, 25, 30}); // Avg 20
+ populatePercentileCSV(baseBenchmarkB1, new double[] {0, 0, 0, 99, 1}); // 300
+
+ populateThroughputCSV(testBenchmarkA2, new double[] {10, 15, 20, 25, 30}); // Avg 20
+ populatePercentileCSV(testBenchmarkA2, new double[] {0, 0, 99, 1}); // 200
+ populateThroughputCSV(testBenchmarkB2, new double[] {10, 15, 20, 25, 30, 35, 40}); // Avg 25
+ populatePercentileCSV(testBenchmarkB2, new double[] {0, 0, 0, 99, 1}); // 300
+ populateThroughputCSV(baseBenchmarkA2, new double[] {15, 20, 25, 30, 35}); // Avg 25
+ populatePercentileCSV(baseBenchmarkA2, new double[] {0, 99, 1}); // 100
+ populateThroughputCSV(baseBenchmarkB2, new double[] {10, 15, 20, 25, 30}); // Avg 20
+ populatePercentileCSV(baseBenchmarkB2, new double[] {0, 0, 0, 99, 1}); // 300
+
+ List<String> nodes = new ArrayList(2);
+ nodes.add("client1");
+ nodes.add("client2");
+
+ BenchmarkRunAnalyzer harvester = new BenchmarkRunAnalyzer();
+ harvester.addBenchmark("Alpha", "BenchmarkA", nodes);
+ harvester.addBenchmark("Beta", "BenchmarkB", nodes);
+ harvester.addProbe(new YardstickThroughputSensorParser());
+ harvester.addProbe(new YardstickPercentileSensorParser());
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(4000);
+ StringWriter writer = new StringWriter();
+
+ harvester.analyzeTestRun(testFolder, baseFolder, writer);
+ System.out.println(writer.toString());
+ BufferedReader resultReader = new BufferedReader(new StringReader(writer.toString()));
+
+ validatedBenchmark(resultReader, "Alpha", 20, 300, 25, 200);
+ validatedBenchmark(resultReader, "Beta", 25, 400, 20, 400);
+ }
+
+ private void populateThroughputCSV(File targetDirectory, double[] perSecondThroughputs)
+ throws FileNotFoundException {
+ final File testFile = new File(targetDirectory, YardstickThroughputSensorParser.sensorOutputFile);
+ PrintStream output = new PrintStream(testFile);
+ for (int i = 0; i < perSecondThroughputs.length; ++i) {
+ output.println(String.format("%d,%f,%f", i, perSecondThroughputs[i], 1d));
+ }
+ output.close();
+ }
+
+ private void populatePercentileCSV(File targetDirectory, double[] hundredUsBuckets)
+ throws FileNotFoundException {
+ final File testFile = new File(targetDirectory, YardstickPercentileSensorParser.sensorOutputFile);
+ PrintStream output = new PrintStream(testFile);
+ for (int i = 0; i < hundredUsBuckets.length; ++i) {
+ output.println(String.format("%d,%f", 100*i, hundredUsBuckets[i]));
+ }
+ output.close();
+ }
+
+ private void validatedBenchmark(BufferedReader input, String benchmarkName, double testValA, double testValB, double baseValA, double baseValB)
+ throws IOException {
+ String line = input.readLine();
+ Assert.assertEquals("-- " + benchmarkName + " --", line);
+ validateProbe(input, YardstickThroughputSensorParser.probeResultDescription, testValA, baseValA);
+ validateProbe(input, YardstickPercentileSensorParser.probeResultDescription, testValB, baseValB);
+ }
+
+ private void validateProbe(BufferedReader input, String description, double testVal, double baseVal)
+ throws IOException {
+ String line = input.readLine();
+ Assert.assertEquals(description, line);
+ Scanner scanner = new Scanner(input.readLine());
+ while (!scanner.hasNextDouble()) {scanner.next();}
+ Assert.assertEquals(testVal, scanner.nextDouble(), 0.01 * testVal);
+ scanner = new Scanner(input.readLine());
+ while (!scanner.hasNextDouble()) {scanner.next();}
+ Assert.assertEquals(baseVal, scanner.nextDouble(), 0.01 * baseVal);
+ scanner = new Scanner(input.readLine());
+ while (!scanner.hasNextDouble()) {scanner.next();}
+ Assert.assertEquals(testVal / baseVal, scanner.nextDouble(), 0.1);
+ line = input.readLine();
+ Assert.assertEquals("", line);
+ }
+}
\ No newline at end of file
diff --git a/harness/src/test/java/org/apache/geode/perftest/yardstick/YardstickPercentileSensorParserTest.java b/harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickPercentileSensorParserTest.java
similarity index 97%
rename from harness/src/test/java/org/apache/geode/perftest/yardstick/YardstickPercentileSensorParserTest.java
rename to harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickPercentileSensorParserTest.java
index bb55def..73e1385 100644
--- a/harness/src/test/java/org/apache/geode/perftest/yardstick/YardstickPercentileSensorParserTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickPercentileSensorParserTest.java
@@ -12,7 +12,7 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
-package org.apache.geode.perftest.yardstick;
+package org.apache.geode.perftest.yardstick.analysis;
import java.io.BufferedWriter;
import java.io.File;
@@ -24,6 +24,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import org.apache.geode.perftest.yardstick.analysis.YardstickPercentileSensorParser;
+
public class YardstickPercentileSensorParserTest {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
diff --git a/harness/src/test/java/org/apache/geode/perftest/yardstick/YardstickThroughputSensorParserTest.java b/harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickThroughputSensorParserTest.java
similarity index 96%
rename from harness/src/test/java/org/apache/geode/perftest/yardstick/YardstickThroughputSensorParserTest.java
rename to harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickThroughputSensorParserTest.java
index 23c0114..7dfa9e6 100644
--- a/harness/src/test/java/org/apache/geode/perftest/yardstick/YardstickThroughputSensorParserTest.java
+++ b/harness/src/test/java/org/apache/geode/perftest/yardstick/analysis/YardstickThroughputSensorParserTest.java
@@ -13,7 +13,7 @@
* the License.
*/
-package org.apache.geode.perftest.yardstick;
+package org.apache.geode.perftest.yardstick.analysis;
import java.io.BufferedWriter;
import java.io.File;
@@ -25,6 +25,8 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import org.apache.geode.perftest.yardstick.analysis.YardstickThroughputSensorParser;
+
public class YardstickThroughputSensorParserTest {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();