ResultFormatTest.java
/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.openjdk.jmh.results.format;
import org.junit.Assert;
import org.junit.Test;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.infra.BenchmarkParams;
import org.openjdk.jmh.infra.IterationParams;
import org.openjdk.jmh.results.*;
import org.openjdk.jmh.runner.IterationType;
import org.openjdk.jmh.runner.WorkloadParams;
import org.openjdk.jmh.runner.options.TimeValue;
import org.openjdk.jmh.util.FileUtils;
import org.openjdk.jmh.util.Utils;
import java.io.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* These tests seal the machine-readable format.
* Any change to these tests should be discussed with the maintainers first!
*/
public class ResultFormatTest {
/**
* Use constant dummy for JVM instead of current JVM to compare with golden file.
*/
private static final String JVM_DUMMY = "javadummy";
/**
* Use constant dummy for JVM instead of current JVM to compare with golden file.
*/
private static final String JDK_VERSION_DUMMY = "1.8-dummy";
private static final String VM_NAME_DUMMY = "DummyVM";
private static final String VM_VERSION_DUMMY = "4711";
private static final String JMH_VERSION_DUMMY = "1.18";
private Collection<RunResult> getStub() {
Collection<RunResult> results = new TreeSet<>(RunResult.DEFAULT_SORT_COMPARATOR);
Random r = new Random(12345);
Random ar = new Random(12345);
for (int b = 0; b < r.nextInt(10); b++) {
WorkloadParams ps = new WorkloadParams();
ps.put("param0", "value0", 0);
ps.put("param1", "[value1]", 1);
ps.put("param2", "{value2}", 2);
ps.put("param3", "'value3'", 3);
ps.put("param4", "\"value4\"", 4);
BenchmarkParams params = new BenchmarkParams(
"benchmark_" + b,
JSONResultFormat.class.getName() + ".benchmark_" + b + "_" + Mode.Throughput,
false,
r.nextInt(1000),
new int[]{ r.nextInt(1000) },
Collections.<String>emptyList(),
r.nextInt(1000),
r.nextInt(1000),
new IterationParams(IterationType.WARMUP, r.nextInt(1000), TimeValue.seconds(r.nextInt(1000)), 1),
new IterationParams(IterationType.MEASUREMENT, r.nextInt(1000), TimeValue.seconds(r.nextInt(1000)), 1),
Mode.Throughput,
ps,
TimeUnit.SECONDS, 1,
JVM_DUMMY,
Collections.<String>emptyList(),
JDK_VERSION_DUMMY, VM_NAME_DUMMY, VM_VERSION_DUMMY, JMH_VERSION_DUMMY,
TimeValue.days(1));
Collection<BenchmarkResult> benchmarkResults = new ArrayList<>();
for (int f = 0; f < r.nextInt(10); f++) {
Collection<IterationResult> iterResults = new ArrayList<>();
for (int c = 0; c < r.nextInt(10); c++) {
IterationResult res = new IterationResult(params, params.getMeasurement(), null);
res.addResult(new ThroughputResult(ResultRole.PRIMARY, "test", r.nextInt(1000), 1000 * 1000, TimeUnit.MILLISECONDS));
res.addResult(new ThroughputResult(ResultRole.SECONDARY, "secondary1", r.nextInt(1000), 1000 * 1000, TimeUnit.MILLISECONDS));
res.addResult(new ThroughputResult(ResultRole.SECONDARY, "secondary2", r.nextInt(1000), 1000 * 1000, TimeUnit.MILLISECONDS));
if (ar.nextBoolean()) {
res.addResult(new ThroughputResult(ResultRole.SECONDARY, "secondary3", ar.nextInt(1000), 1000 * 1000, TimeUnit.MILLISECONDS));
}
iterResults.add(res);
}
benchmarkResults.add(new BenchmarkResult(params, iterResults));
}
results.add(new RunResult(params, benchmarkResults));
}
return results;
}
private void compare(String actualFile, String goldenFile) throws IOException {
BufferedReader actualReader = new BufferedReader(new FileReader(actualFile));
BufferedReader goldenReader = new BufferedReader(new InputStreamReader(ResultFormatTest.class.getResourceAsStream("/org/openjdk/jmh/results/format/" + goldenFile)));
String actualLines = Utils.join(FileUtils.readAllLines(actualReader), "\n");
String goldenLines = Utils.join(FileUtils.readAllLines(goldenReader), "\n");
Assert.assertEquals("Mismatch", goldenLines, actualLines);
}
public void test(ResultFormatType type, Locale locale, String suffix) throws IOException {
Locale prevLocale = Locale.getDefault();
Locale.setDefault(locale);
String actualFileName = "test." + type.toString().toLowerCase() + suffix;
String goldenFileName = "output-golden." + type.toString().toLowerCase() + suffix;
try {
String actualFile = FileUtils.tempFile(actualFileName).getAbsolutePath();
ResultFormatFactory.getInstance(type, actualFile).writeOut(getStub());
compare(actualFile, goldenFileName);
PrintStream ps = new PrintStream(actualFile, "UTF-8");
ResultFormatFactory.getInstance(type, ps).writeOut(getStub());
ps.close();
compare(actualFile, goldenFileName);
} finally {
Locale.setDefault(prevLocale);
}
}
/*
* JSON has a strict format for numbers, the results should be Locale-agnostic.
*/
@Test
public void jsonTest_ROOT() throws IOException {
test(ResultFormatType.JSON, Locale.ROOT, "");
}
@Test
public void jsonTest_US() throws IOException {
test(ResultFormatType.JSON, Locale.US, "");
}
@Test
public void jsonTest_RU() throws IOException {
test(ResultFormatType.JSON, new Locale("RU"), "");
}
/*
* CSV and SCSV data should conform to the Locale.
*/
@Test
public void csvTest_ROOT() throws IOException {
test(ResultFormatType.CSV, Locale.ROOT, ".root");
}
@Test
public void csvTest_US() throws IOException {
test(ResultFormatType.CSV, Locale.US, ".us");
}
@Test
public void csvTest_RU() throws IOException {
test(ResultFormatType.CSV, new Locale("RU"), ".ru");
}
@Test
public void scsvTest_ROOT() throws IOException {
test(ResultFormatType.SCSV, Locale.ROOT, ".root");
}
@Test
public void scsvTest_US() throws IOException {
test(ResultFormatType.SCSV, Locale.US, ".us");
}
@Test
public void scsvTest_RU() throws IOException {
test(ResultFormatType.SCSV, new Locale("RU"), ".ru");
}
/*
* LaTeX output should conform to the Locale.
*/
@Test
public void latexTest_ROOT() throws IOException {
test(ResultFormatType.LATEX, Locale.ROOT, ".root");
}
@Test
public void latexTest_US() throws IOException {
test(ResultFormatType.LATEX, Locale.US, ".us");
}
@Test
public void latexTest_RU() throws IOException {
test(ResultFormatType.LATEX, new Locale("RU"), ".ru");
}
/*
* Text output should conform to the Locale.
*/
@Test
public void textTest_ROOT() throws IOException {
test(ResultFormatType.TEXT, Locale.ROOT, ".root");
}
@Test
public void textTest_US() throws IOException {
test(ResultFormatType.TEXT, Locale.US, ".us");
}
@Test
public void textTest_RU() throws IOException {
test(ResultFormatType.TEXT, new Locale("RU"), ".ru");
}
}