#78 - Fix benchmark filtering.

We now check the specified benchmark filter expression against the JUnit class to make sure JMH does not spin up benchmark classes that are different than the actual JUnit class.
This commit is contained in:
Mark Paluch
2018-08-08 10:50:56 +02:00
parent 237612810c
commit 478a12bcb7
2 changed files with 35 additions and 9 deletions

View File

@@ -58,9 +58,10 @@ class JmhSupport {
* name separator.
*
* @return never {@literal null}.
* @param name
* @param methods
*/
protected List<String> includes(Collection<FrameworkMethod> methods) {
protected List<String> includes(Class<?> testClass, Collection<FrameworkMethod> methods) {
String tests = environment.getProperty("benchmark", String.class);
@@ -70,12 +71,16 @@ class JmhSupport {
.collect(Collectors.toList());
}
if (!tests.contains("#")) {
return Collections.singletonList(".*" + tests + ".*");
if (tests.contains(testClass.getName()) || tests.contains(testClass.getSimpleName())) {
if (!tests.contains("#")) {
return Collections.singletonList(".*" + tests + ".*");
}
String[] args = tests.split("#");
return Collections.singletonList(".*" + args[0] + "." + args[1]);
}
String[] args = tests.split("#");
return Collections.singletonList(".*" + args[0] + "." + args[1]);
return Collections.emptyList();
}
/**

View File

@@ -25,6 +25,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Function;
@@ -47,6 +48,7 @@ import org.openjdk.jmh.results.BenchmarkResult;
import org.openjdk.jmh.results.IterationResult;
import org.openjdk.jmh.results.RunResult;
import org.openjdk.jmh.runner.Defaults;
import org.openjdk.jmh.runner.NoBenchmarksException;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.format.OutputFormat;
import org.openjdk.jmh.runner.format.OutputFormatFactory;
@@ -189,18 +191,33 @@ public class Microbenchmark extends BlockJUnit4ClassRunner {
Collection<FrameworkMethod> methods = getFilteredChildren();
CacheFunction cache = new CacheFunction(methods, this::describeChild);
if (methods.isEmpty()) {
return new Statement() {
@Override
public void evaluate() {}
};
}
return new Statement() {
@Override
public void evaluate() throws Throwable {
doRun(notifier, methods, cache);
try {
doRun(notifier, methods, cache);
} catch (NoBenchmarksException | NoTestsRemainException e) {
methods.forEach(it -> notifier.fireTestIgnored(describeChild(it)));
}
}
};
}
private void doRun(RunNotifier notifier, Collection<FrameworkMethod> methods, CacheFunction cache) throws Exception {
void doRun(RunNotifier notifier, Collection<FrameworkMethod> methods, CacheFunction cache) throws Exception {
List<String> includes = jmhRunner.includes(methods);
List<String> includes = jmhRunner.includes(getTestClass().getJavaClass(), methods);
if (includes.isEmpty()) {
throw new NoTestsRemainException();
}
ChainedOptionsBuilder optionsBuilder = jmhRunner.options();
@@ -466,7 +483,11 @@ public class Microbenchmark extends BlockJUnit4ClassRunner {
public Description apply(String benchmarkName) {
FrameworkMethod frameworkMethod = methodMap.computeIfAbsent(benchmarkName, key -> {
return methods.stream().filter(method -> getBenchmarkName(method).equals(key)).findFirst().get();
Optional<FrameworkMethod> method = methods.stream().filter(it -> getBenchmarkName(it).equals(key)).findFirst();
return method.orElseThrow(() -> new IllegalArgumentException(
String.format("Cannot resolve %s to a FrameworkMethod!", benchmarkName)));
});
return describeFunction.apply(frameworkMethod);