resolver = EngineDiscoveryRequestResolver
+ .builder() //
+ .addClassContainerSelectorResolver(IsBenchmarkClass.INSTANCE)
+ .addSelectorResolver(ctx -> new BenchmarkContainerResolver(ctx.getClassNameFilter())) //
+ .addSelectorResolver(new BenchmarkMethodResolver()) //
+ .addSelectorResolver(new BenchmarkFixtureResolver()) //
+ .build();
- private void pruneTree(TestDescriptor rootDescriptor) {
- rootDescriptor.accept(TestDescriptor::prune);
- }
-
- private JavaElementsResolver createJavaElementsResolver(ConfigurationParameters configurationParameters,
- TestDescriptor engineDescriptor, ClassFilter classFilter) {
- return new JavaElementsResolver(engineDescriptor, classFilter, ElementResolvers.getResolvers());
+ public void resolveSelectors(EngineDiscoveryRequest request, TestDescriptor engineDescriptor) {
+ resolver.resolve(request, engineDescriptor);
}
}
diff --git a/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/discovery/ElementResolver.java b/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/discovery/ElementResolver.java
deleted file mode 100644
index 2a87d8e..0000000
--- a/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/discovery/ElementResolver.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2018 the original author or authors.
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v2.0 which
- * accompanies this distribution and is available at
- *
- * http://www.eclipse.org/legal/epl-v20.html
- */
-package jmh.mbr.junit5.discovery;
-
-import java.lang.reflect.AnnotatedElement;
-import java.util.Optional;
-import java.util.Set;
-
-import org.junit.platform.engine.TestDescriptor;
-import org.junit.platform.engine.UniqueId;
-
-interface ElementResolver {
-
- /**
- * Return a set of {@link TestDescriptor TestDescriptors} that can be resolved by this resolver.
- *
- * Returned set must be empty if {@code element} cannot be resolved.
- */
- Set resolveElement(AnnotatedElement element, TestDescriptor parent);
-
- /**
- * Return an optional {@link TestDescriptor}.
- *
- * Return {@code Optional.empty()} if {@code segment} cannot be resolved.
- */
- Optional resolveUniqueId(UniqueId.Segment segment, TestDescriptor parent);
-
-}
diff --git a/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/discovery/ElementResolvers.java b/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/discovery/ElementResolvers.java
deleted file mode 100644
index 3fb8c72..0000000
--- a/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/discovery/ElementResolvers.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2018 the original author or authors.
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v2.0 which
- * accompanies this distribution and is available at
- *
- * http://www.eclipse.org/legal/epl-v20.html
- */
-package jmh.mbr.junit5.discovery;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-/**
- * Utility to obtain {@link ElementResolver}s.
- */
-class ElementResolvers {
-
- /**
- * @return a {@link Set} of known {@link ElementResolver}s.
- */
- public static Set getResolvers() {
-
- Set resolvers = new LinkedHashSet<>();
- resolvers.add(new BenchmarkContainerResolver());
- resolvers.add(new BenchmarkMethodResolver());
- resolvers.add(new BenchmarkFixtureResolver());
-
- return resolvers;
- }
-}
diff --git a/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/discovery/JavaElementsResolver.java b/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/discovery/JavaElementsResolver.java
deleted file mode 100644
index 92d50e9..0000000
--- a/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/discovery/JavaElementsResolver.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright 2018 the original author or authors.
- *
- * All rights reserved. This program and the accompanying materials are
- * made available under the terms of the Eclipse Public License v2.0 which
- * accompanies this distribution and is available at
- *
- * http://www.eclipse.org/legal/epl-v20.html
- */
-package jmh.mbr.junit5.discovery;
-
-import jmh.mbr.junit5.MicrobenchmarkEngine;
-import jmh.mbr.junit5.descriptor.BenchmarkClassDescriptor;
-import jmh.mbr.junit5.descriptor.ParametrizedBenchmarkMethodDescriptor;
-import jmh.mbr.junit5.discovery.predicates.IsBenchmarkMethod;
-
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.BiConsumer;
-import java.util.stream.Collectors;
-
-import org.junit.platform.commons.logging.Logger;
-import org.junit.platform.commons.logging.LoggerFactory;
-import org.junit.platform.commons.support.scanning.ClassFilter;
-import org.junit.platform.commons.util.BlacklistedExceptions;
-import org.junit.platform.commons.util.ReflectionUtils;
-import org.junit.platform.commons.util.StringUtils;
-import org.junit.platform.engine.TestDescriptor;
-import org.junit.platform.engine.UniqueId;
-import org.junit.platform.engine.UniqueId.Segment;
-import org.junit.platform.engine.discovery.ClassSelector;
-import org.junit.platform.engine.discovery.ClasspathRootSelector;
-import org.junit.platform.engine.discovery.MethodSelector;
-import org.junit.platform.engine.discovery.ModuleSelector;
-import org.junit.platform.engine.discovery.PackageSelector;
-import org.junit.platform.engine.discovery.UniqueIdSelector;
-
-/**
- * Resolve {@link TestDescriptor} by traversing classes and methods and attaching these to the root
- * {@link TestDescriptor test engine descriptor}.
- */
-class JavaElementsResolver {
-
- private static final Logger logger = LoggerFactory.getLogger(JavaElementsResolver.class);
-
- private final TestDescriptor engineDescriptor;
- private final ClassFilter classFilter;
- private final Set resolvers;
-
- JavaElementsResolver(TestDescriptor engineDescriptor, ClassFilter classFilter, Set resolvers) {
- this.engineDescriptor = engineDescriptor;
- this.classFilter = classFilter;
- this.resolvers = resolvers;
- }
-
- void resolveClasspathRoot(ClasspathRootSelector selector) {
- try {
- ReflectionUtils.findAllClassesInClasspathRoot(selector.getClasspathRoot(), this.classFilter)
- .forEach(this::resolveClass);
- } catch (Throwable t) {
- BlacklistedExceptions.rethrowIfBlacklisted(t);
- logger.debug(t,
- () -> String.format("Failed to resolve classes in classpath root '%s'.", selector.getClasspathRoot()));
- }
- }
-
- void resolveModule(ModuleSelector selector) {
- try {
- ReflectionUtils.findAllClassesInModule(selector.getModuleName(), this.classFilter).forEach(this::resolveClass);
- } catch (Throwable t) {
- BlacklistedExceptions.rethrowIfBlacklisted(t);
- logger.debug(t, () -> String.format("Failed to resolve classes in module '%s'.", selector.getModuleName()));
- }
- }
-
- void resolvePackage(PackageSelector selector) {
- try {
- ReflectionUtils.findAllClassesInPackage(selector.getPackageName(), this.classFilter).forEach(this::resolveClass);
- } catch (Throwable t) {
- BlacklistedExceptions.rethrowIfBlacklisted(t);
- logger.debug(t, () -> String.format("Failed to resolve classes in package '%s'.", selector.getPackageName()));
- }
- }
-
- void resolveClass(ClassSelector selector) {
- // Even though resolveClass(Class>) has its own similar try-catch block, the
- // try-catch block is necessary here as well since ClassSelector#getJavaClass()
- // may throw an exception.
- try {
- resolveClass(selector.getJavaClass());
- } catch (Throwable t) {
- BlacklistedExceptions.rethrowIfBlacklisted(t);
- logger.debug(t, () -> String.format("Class '%s' could not be resolved.", selector.getClassName()));
- }
- }
-
- private void resolveClass(Class> testClass) {
- try {
- Set resolvedDescriptors = resolveContainerWithParents(testClass);
- resolvedDescriptors.forEach(this::resolveChildren);
-
- if (resolvedDescriptors.isEmpty()) {
- logger.debug(() -> String.format("Class '%s' could not be resolved.", StringUtils.nullSafeToString(testClass)));
- }
- } catch (Throwable t) {
- BlacklistedExceptions.rethrowIfBlacklisted(t);
- logger.debug(t,
- () -> String.format("Class '%s' could not be resolved.", StringUtils.nullSafeToString(testClass)));
- }
- }
-
- void resolveMethod(MethodSelector selector) {
-
- try {
- Class> testClass = selector.getJavaClass();
- Method testMethod = selector.getJavaMethod();
-
- Set potentialParents = resolveContainerWithParents(testClass);
- Set resolvedDescriptors = resolveForAllParents(testMethod, potentialParents);
- resolvedDescriptors.forEach(this::resolveChildren);
-
- if (resolvedDescriptors.isEmpty()) {
- logger.debug(() -> String.format("Method '%s' could not be resolved.", testMethod.toGenericString()));
- }
- } catch (Throwable t) {
- BlacklistedExceptions.rethrowIfBlacklisted(t);
- logger.debug(t, () -> String.format("Method '%s' in class '%s' could not be resolved.", selector.getMethodName(),
- selector.getClassName()));
- }
- }
-
- void resolveUniqueId(UniqueIdSelector selector) {
-
- UniqueId uniqueId = selector.getUniqueId();
-
- // Ignore Unique IDs from other test engines.
- if (MicrobenchmarkEngine.ENGINE_ID.equals(uniqueId.getEngineId().orElse(null))) {
- try {
- Deque resolvedDescriptors = resolveAllSegments(uniqueId);
- handleResolvedDescriptorsForUniqueId(uniqueId, resolvedDescriptors);
- } catch (Throwable t) {
- BlacklistedExceptions.rethrowIfBlacklisted(t);
- logger.warn(t, () -> String.format("Unique ID '%s' could not be resolved.", selector.getUniqueId()));
- }
- }
- }
-
- private Set resolveContainerWithParents(Class> testClass) {
- return resolveForAllParents(testClass, Collections.singleton(this.engineDescriptor));
- }
-
- /**
- * Attempt to resolve all segments for the supplied unique ID.
- */
- private Deque resolveAllSegments(UniqueId uniqueId) {
-
- List segments = uniqueId.getSegments();
- Deque resolvedDescriptors = new LinkedList<>();
- resolvedDescriptors.addFirst(this.engineDescriptor);
-
- for (int index = 1; index < segments.size() && resolvedDescriptors.size() == index; index++) {
- Segment segment = segments.get(index);
- TestDescriptor parent = resolvedDescriptors.getLast();
- UniqueId partialUniqueId = parent.getUniqueId().append(segment);
-
- Optional resolvedDescriptor = findTestDescriptorByUniqueId(partialUniqueId);
- if (!resolvedDescriptor.isPresent()) {
- resolvedDescriptor = this.resolvers.stream().map(resolver -> resolver.resolveUniqueId(segment, parent))
- .filter(Optional::isPresent).map(Optional::get).findFirst();
- resolvedDescriptor.ifPresent(parent::addChild);
- }
- resolvedDescriptor.ifPresent(resolvedDescriptors::addLast);
- }
- return resolvedDescriptors;
- }
-
- private void handleResolvedDescriptorsForUniqueId(UniqueId uniqueId, Deque resolvedDescriptors) {
- List segments = uniqueId.getSegments();
- int numSegmentsToResolve = segments.size() - 1;
- int numSegmentsResolved = resolvedDescriptors.size() - 1;
-
- if (numSegmentsResolved == 0) {
- logger.warn(() -> String.format("Unique ID '%s' could not be resolved.", uniqueId));
- } else if (numSegmentsResolved != numSegmentsToResolve) {
- logger.warn(() -> {
- List unresolved = segments.subList(1, segments.size()); // Remove engine ID
- unresolved = unresolved.subList(numSegmentsResolved, unresolved.size()); // Remove resolved segments
- return String.format("Unique ID '%s' could only be partially resolved. "
- + "All resolved segments will be executed; however, the " + "following segments could not be resolved: %s",
- uniqueId, unresolved);
- });
- } else {
- resolveChildren(resolvedDescriptors.getLast());
- }
- }
-
- private Set resolveForAllParents(AnnotatedElement element, Set potentialParents) {
- return potentialParents.stream().flatMap(it -> resolve(element, it).stream()).collect(Collectors.toSet());
- }
-
- private void resolveChildren(TestDescriptor descriptor) {
-
- if (descriptor instanceof BenchmarkClassDescriptor) {
-
- Class> testClass = ((BenchmarkClassDescriptor) descriptor).getJavaClass();
- resolveContainedMethods(descriptor, testClass, this::resolve);
- }
-
- if (descriptor instanceof ParametrizedBenchmarkMethodDescriptor) {
-
- Method benchmarkMethod = ((ParametrizedBenchmarkMethodDescriptor) descriptor).getMethod();
- resolve(benchmarkMethod, descriptor);
- }
- }
-
- private void resolveContainedMethods(TestDescriptor containerDescriptor, Class> testClass,
- BiConsumer fixtureResolver) {
-
- List benchmarkMethodCandidates = ReflectionUtils.findMethods(testClass, IsBenchmarkMethod.INSTANCE);
- benchmarkMethodCandidates.forEach(it -> {
- Set methodDescriptors = resolve(it, containerDescriptor);
- methodDescriptors.forEach(methodDescriptor -> fixtureResolver.accept(it, methodDescriptor));
- });
- }
-
- private Set resolve(AnnotatedElement element, TestDescriptor parent) {
-
- return this.resolvers.stream() //
- .map(resolver -> tryToResolveWithResolver(element, parent, resolver)) //
- .filter(testDescriptors -> !testDescriptors.isEmpty()) //
- .flatMap(Collection::stream) //
- .collect(Collectors.toSet());
- }
-
- private Set tryToResolveWithResolver(AnnotatedElement element, TestDescriptor parent,
- ElementResolver resolver) {
-
- Set resolvedDescriptors = resolver.resolveElement(element, parent);
- Set result = new LinkedHashSet<>();
-
- resolvedDescriptors.forEach(testDescriptor -> {
- Optional existingTestDescriptor = findTestDescriptorByUniqueId(testDescriptor.getUniqueId());
- if (existingTestDescriptor.isPresent()) {
- result.add(existingTestDescriptor.get());
- } else {
- parent.addChild(testDescriptor);
- result.add(testDescriptor);
- }
- });
-
- return result;
- }
-
- @SuppressWarnings("unchecked")
- private Optional findTestDescriptorByUniqueId(UniqueId uniqueId) {
- return (Optional) this.engineDescriptor.findByUniqueId(uniqueId);
- }
-}
diff --git a/microbenchmark-runner-junit5/src/test/java/jmh/mbr/junit5/discovery/JavaElementsResolverUnitTests.java b/microbenchmark-runner-junit5/src/test/java/jmh/mbr/junit5/discovery/DiscoverySelectorResolverTests.java
similarity index 56%
rename from microbenchmark-runner-junit5/src/test/java/jmh/mbr/junit5/discovery/JavaElementsResolverUnitTests.java
rename to microbenchmark-runner-junit5/src/test/java/jmh/mbr/junit5/discovery/DiscoverySelectorResolverTests.java
index 3c953a9..a6d0c0e 100644
--- a/microbenchmark-runner-junit5/src/test/java/jmh/mbr/junit5/discovery/JavaElementsResolverUnitTests.java
+++ b/microbenchmark-runner-junit5/src/test/java/jmh/mbr/junit5/discovery/DiscoverySelectorResolverTests.java
@@ -9,45 +9,42 @@
*/
package jmh.mbr.junit5.discovery;
+import static org.assertj.core.api.Assertions.*;
+import static org.junit.platform.engine.discovery.ClassNameFilter.*;
+import static org.junit.platform.engine.discovery.DiscoverySelectors.*;
+
+import jmh.mbr.junit5.MicrobenchmarkEngine;
import jmh.mbr.junit5.PartiallyParametrizedBenchmark;
import jmh.mbr.junit5.descriptor.BenchmarkClassDescriptor;
import jmh.mbr.junit5.descriptor.BenchmarkMethodDescriptor;
import jmh.mbr.junit5.descriptor.ParametrizedBenchmarkMethodDescriptor;
-import static org.assertj.core.api.Assertions.*;
+import java.util.regex.Pattern;
+
import org.junit.jupiter.api.Test;
-import org.junit.platform.commons.support.scanning.ClassFilter;
+import org.junit.platform.engine.Filter;
import org.junit.platform.engine.TestDescriptor;
-import org.junit.platform.engine.UniqueId;
-import org.junit.platform.engine.discovery.DiscoverySelectors;
-import org.junit.platform.engine.support.descriptor.AbstractTestDescriptor;
+import org.junit.platform.testkit.engine.EngineDiscoveryResults;
+import org.junit.platform.testkit.engine.EngineTestKit;
/**
- * Unit tests for {@link JavaElementsResolver}.
+ * Tests for {@link DiscoverySelectorResolver}.
*/
-class JavaElementsResolverUnitTests {
-
- private final TestDescriptor ENGINE = new AbstractTestDescriptor(UniqueId.forEngine("foo"), "foo") {
- @Override
- public Type getType() {
- return Type.CONTAINER;
- }
- };
-
- private final ClassFilter FILTER = ClassFilter.of(it -> true);
+class DiscoverySelectorResolverTests {
@Test
void shouldResolveClassByPackageSelector() {
- JavaElementsResolver resolver = new JavaElementsResolver(ENGINE,
- ClassFilter.of(it -> it.equals(PartiallyParametrizedBenchmark.class)), ElementResolvers.getResolvers());
+ EngineDiscoveryResults results = EngineTestKit.engine(new MicrobenchmarkEngine())
+ .selectors(selectPackage(PartiallyParametrizedBenchmark.class.getPackage().getName()))
+ .filters((Filter>) includeClassNamePatterns(Pattern.quote(PartiallyParametrizedBenchmark.class.getName())))
+ .discover();
- resolver
- .resolvePackage(DiscoverySelectors.selectPackage(PartiallyParametrizedBenchmark.class.getPackage().getName()));
+ TestDescriptor engineDescriptor = results.getEngineDescriptor();
- assertThat(ENGINE.getChildren()).hasSize(1);
+ assertThat(engineDescriptor.getChildren()).hasSize(1);
- TestDescriptor classDescriptor = ENGINE.getChildren().iterator().next();
+ TestDescriptor classDescriptor = engineDescriptor.getChildren().iterator().next();
assertBenchmarkClass(classDescriptor);
@@ -60,13 +57,14 @@ void shouldResolveClassByPackageSelector() {
@Test
void shouldResolveClassByClassSelector() {
- JavaElementsResolver resolver = new JavaElementsResolver(ENGINE, FILTER, ElementResolvers.getResolvers());
+ EngineDiscoveryResults results = EngineTestKit.engine(new MicrobenchmarkEngine())
+ .selectors(selectClass(PartiallyParametrizedBenchmark.class)).discover();
- resolver.resolveClass(DiscoverySelectors.selectClass(PartiallyParametrizedBenchmark.class));
+ TestDescriptor engineDescriptor = results.getEngineDescriptor();
- assertThat(ENGINE.getChildren()).hasSize(1);
+ assertThat(engineDescriptor.getChildren()).hasSize(1);
- TestDescriptor classDescriptor = ENGINE.getChildren().iterator().next();
+ TestDescriptor classDescriptor = engineDescriptor.getChildren().iterator().next();
assertBenchmarkClass(classDescriptor);
@@ -79,14 +77,16 @@ void shouldResolveClassByClassSelector() {
@Test
void shouldResolveBenchmarkMethodByMethodSelector() {
- JavaElementsResolver resolver = new JavaElementsResolver(ENGINE, FILTER, ElementResolvers.getResolvers());
+ EngineDiscoveryResults results = EngineTestKit.engine(new MicrobenchmarkEngine())
+ .selectors(selectMethod(PartiallyParametrizedBenchmark.class, "bar",
+ "jmh.mbr.junit5.PartiallyParametrizedBenchmark$ParamState"))
+ .discover();
- resolver.resolveMethod(DiscoverySelectors.selectMethod(PartiallyParametrizedBenchmark.class, "bar",
- "jmh.mbr.junit5.PartiallyParametrizedBenchmark$ParamState"));
+ TestDescriptor engineDescriptor = results.getEngineDescriptor();
- assertThat(ENGINE.getChildren()).hasSize(1);
+ assertThat(engineDescriptor.getChildren()).hasSize(1);
- TestDescriptor classDescriptor = ENGINE.getChildren().iterator().next();
+ TestDescriptor classDescriptor = engineDescriptor.getChildren().iterator().next();
assertBenchmarkClass(classDescriptor);
@@ -99,14 +99,15 @@ void shouldResolveBenchmarkMethodByMethodSelector() {
@Test
void shouldResolveBenchmarkMethodByUniqueIdSelector() {
- JavaElementsResolver resolver = new JavaElementsResolver(ENGINE, FILTER, ElementResolvers.getResolvers());
+ EngineDiscoveryResults results = EngineTestKit.engine(new MicrobenchmarkEngine()).selectors(selectUniqueId(
+ "[engine:microbenchmark-engine]/[class:jmh.mbr.junit5.PartiallyParametrizedBenchmark]/[method:bar(jmh.mbr.junit5.PartiallyParametrizedBenchmark$ParamState)]/[fixture:%5Bfoo=b%5D]"))
+ .discover();
- resolver.resolveUniqueId(DiscoverySelectors.selectUniqueId(
- "[engine:microbenchmark-engine]/[class:jmh.mbr.junit5.PartiallyParametrizedBenchmark]/[method:bar(jmh.mbr.junit5.PartiallyParametrizedBenchmark$ParamState)]/[fixture:%5Bfoo=b%5D]"));
+ TestDescriptor engineDescriptor = results.getEngineDescriptor();
- assertThat(ENGINE.getChildren()).hasSize(1);
+ assertThat(engineDescriptor.getChildren()).hasSize(1);
- TestDescriptor classDescriptor = ENGINE.getChildren().iterator().next();
+ TestDescriptor classDescriptor = engineDescriptor.getChildren().iterator().next();
assertBenchmarkClass(classDescriptor);