result = new ArrayList<>();
47 | for (ResultsWriterFactory factory : loader) {
48 | ResultsWriter writer = factory.forUri(uri);
49 | if (writer != null) {
50 | result.add(writer);
51 | }
52 | }
53 |
54 | return result.isEmpty() ? null : new CompositeResultsWriter(result);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/main/java/jmh/mbr/core/ResultsWriterFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core;
11 |
12 | /**
13 | * SPI for {@link ResultsWriter} plugins. Uses an opaque {@code uri} to specify the desired target where results can be
14 | * written to.
15 | *
16 | * @see java.util.ServiceLoader
17 | */
18 | public interface ResultsWriterFactory {
19 |
20 | /**
21 | * Creates a new {@link ResultsWriter} for {@code uri}. Implementations may return {@literal null} if the {@code uri}
22 | * is not supported.
23 | *
24 | * @param uri target location to which results are written to (may be null or empty).
25 | * @return the {@link ResultsWriter} implementation or {@literal null} if the {@code uri} is not supported.
26 | */
27 | ResultsWriter forUri(String uri);
28 | }
29 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/main/java/jmh/mbr/core/StringUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core;
11 |
12 | import java.util.Collection;
13 | import java.util.Iterator;
14 |
15 | /**
16 | * Miscellaneous {@link String} utility methods.
17 | */
18 | public class StringUtils {
19 |
20 | /**
21 | * Check whether the given {@link String} is empty.
22 | *
23 | * @param theString the candidate String
24 | * @return {@literal true} if the string is empty.
25 | */
26 | public static boolean isEmpty(Object theString) {
27 | return (theString == null || "".equals(theString));
28 | }
29 |
30 | /**
31 | * Check whether the given {@link String} contains actual text.
32 | *
33 | * @param theString the {@link String} to check (may be {@code null})
34 | * @return {@code true} if the {@link String} is not {@code null}, its length is greater than 0, and it does not
35 | * contain whitespace only
36 | */
37 | public static boolean hasText(String theString) {
38 | return (theString != null && !theString.isEmpty() && containsText(theString));
39 | }
40 |
41 | private static boolean containsText(CharSequence str) {
42 |
43 | int length = str.length();
44 |
45 | for (int i = 0; i < length; i++) {
46 | if (!Character.isWhitespace(str.charAt(i))) {
47 | return true;
48 | }
49 | }
50 | return false;
51 | }
52 |
53 | /**
54 | * Convert a {@link Collection} into a delimited {@link String} (e.g. CSV).
55 | *
56 | * Useful for {@link #toString()} implementations.
57 | *
58 | * @param c the {@code Collection} to convert (potentially {@code null} or empty).
59 | * @param delim the delimiter to use (typically a ",")
60 | * @return the delimited {@link String}
61 | */
62 | public static String collectionToDelimitedString(Collection> c, String delim) {
63 |
64 | if (c.isEmpty()) {
65 | return "";
66 | }
67 |
68 | StringBuilder sb = new StringBuilder();
69 | Iterator> it = c.iterator();
70 | while (it.hasNext()) {
71 | sb.append(it.next());
72 | if (it.hasNext()) {
73 | sb.append(delim);
74 | }
75 | }
76 | return sb.toString();
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/main/java/jmh/mbr/core/model/BenchmarkClass.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core.model;
11 |
12 | import java.util.ArrayList;
13 | import java.util.Collection;
14 | import java.util.List;
15 | import java.util.Objects;
16 |
17 | /**
18 | * {@link BenchmarkDescriptor} for a single {@link Class benchmark class} along its children.
19 | *
20 | * @see BenchmarkMethod
21 | * @see HierarchicalBenchmarkDescriptor
22 | */
23 | public class BenchmarkClass extends HierarchicalBenchmarkDescriptor {
24 |
25 | private BenchmarkClass(ClassDescriptor descriptor, List children) {
26 | super(descriptor, children);
27 | }
28 |
29 | /**
30 | * Create a new {@link BenchmarkClass} given {@link Class the benchmark class} and its children.
31 | *
32 | * @param benchmarkClass the actual {@link Class benchmark class} to inspect.
33 | * @param children child descriptors.
34 | * @return the {@link BenchmarkClass} descriptor.
35 | */
36 | public static BenchmarkClass create(Class> benchmarkClass, Collection extends BenchmarkDescriptor> children) {
37 |
38 | Objects.requireNonNull(benchmarkClass, "Benchmark class must not be null!");
39 | Objects.requireNonNull(children, "Children must not be null!");
40 |
41 | return new BenchmarkClass(new ClassDescriptor(benchmarkClass), new ArrayList<>(children));
42 | }
43 |
44 | public Class> getJavaClass() {
45 | return ((ClassDescriptor) getDescriptor()).benchmarkClass;
46 | }
47 |
48 | private static class ClassDescriptor implements BenchmarkDescriptor {
49 |
50 | private final Class> benchmarkClass;
51 |
52 | private ClassDescriptor(Class> benchmarkClass) {
53 | this.benchmarkClass = benchmarkClass;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/main/java/jmh/mbr/core/model/BenchmarkDescriptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core.model;
11 |
12 | /**
13 | * Marker interfaces for types implementing a benchmark component descriptor.
14 | *
15 | * @see BenchmarkClass
16 | * @see BenchmarkMethod
17 | * @see ParametrizedBenchmarkMethod
18 | * @see BenchmarkFixture
19 | */
20 | public interface BenchmarkDescriptor {}
21 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/main/java/jmh/mbr/core/model/BenchmarkDescriptorFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core.model;
11 |
12 | import jmh.mbr.core.model.BenchmarkParameters.BenchmarkArgument;
13 |
14 | import java.lang.reflect.Method;
15 | import java.lang.reflect.Parameter;
16 | import java.util.ArrayList;
17 | import java.util.Arrays;
18 | import java.util.Collection;
19 | import java.util.Collections;
20 | import java.util.Iterator;
21 | import java.util.List;
22 | import java.util.Objects;
23 | import java.util.Optional;
24 | import java.util.function.Predicate;
25 | import java.util.stream.Collectors;
26 | import java.util.stream.Stream;
27 |
28 | import org.openjdk.jmh.annotations.Benchmark;
29 |
30 | /**
31 | * Factory to create a {@link BenchmarkDescriptor} from a benchmark class.
32 | */
33 | public class BenchmarkDescriptorFactory {
34 |
35 | private final Class> benchmarkClass;
36 |
37 | private BenchmarkDescriptorFactory(Class> benchmarkClass) {
38 | this.benchmarkClass = benchmarkClass;
39 | }
40 |
41 | public static BenchmarkDescriptorFactory create(Class> benchmarkClass) {
42 |
43 | Objects.requireNonNull(benchmarkClass, "Benchmark class must not be null");
44 |
45 | return new BenchmarkDescriptorFactory(benchmarkClass);
46 | }
47 |
48 | /**
49 | * @return the {@link BenchmarkDescriptor} for the underlying {@link Class}.
50 | */
51 | public BenchmarkClass createDescriptor() {
52 |
53 | List children = getBenchmarkMethods(it -> it.isAnnotationPresent(Benchmark.class)).map(it -> {
54 |
55 | if (it.isParametrized()) {
56 |
57 | List fixtures = createFixtures(it);
58 |
59 | return new ParametrizedBenchmarkMethod(it, fixtures);
60 | }
61 |
62 | return it;
63 | }).collect(Collectors.toList());
64 |
65 | return BenchmarkClass.create(benchmarkClass, children);
66 | }
67 |
68 | /**
69 | * Creates {@link BenchmarkFixture} for a parametrized {@link BenchmarkMethod}.
70 | *
71 | * @param method the {@link BenchmarkMethod} to inspect.
72 | * @return list of fixtures if parameterized. Empty list if the method is not parametrized.
73 | */
74 | public List createFixtures(BenchmarkMethod method) {
75 |
76 | List stateClasses = new ArrayList<>();
77 |
78 | if (StateClass.isParametrized(method.getDeclaringClass())) {
79 | stateClasses.add(StateClass.create(method.getDeclaringClass()));
80 | }
81 |
82 | List argumentStateClasses = Arrays.stream(method.getParameters())//
83 | .map(Parameter::getType) //
84 | .filter(StateClass::isParametrized) //
85 | .map(StateClass::create) //
86 | .collect(Collectors.toList());
87 |
88 | stateClasses.addAll(argumentStateClasses);
89 |
90 | Collection arguments = BenchmarkParameters.discover(stateClasses);
91 | Iterator iterator = arguments.iterator();
92 |
93 | return iterator.hasNext() ? createFixtures(iterator.next(), iterator) : Collections.emptyList();
94 | }
95 |
96 | private List createFixtures(BenchmarkArgument argument, Iterator iterator) {
97 |
98 | List fixtures = new ArrayList<>(argument.getParameterCount());
99 |
100 | for (String parameter : argument.getParameters()) {
101 | fixtures.add(BenchmarkFixture.create(argument.getName(), parameter));
102 | }
103 |
104 | while (iterator.hasNext()) {
105 | fixtures = enhance(fixtures, iterator.next());
106 | }
107 |
108 | return fixtures;
109 |
110 | }
111 |
112 | private List enhance(List fixtures, BenchmarkArgument argument) {
113 |
114 | List enhanced = new ArrayList<>(fixtures.size() * argument.getParameterCount());
115 |
116 | for (BenchmarkFixture fixture : fixtures) {
117 |
118 | for (String parameter : argument.getParameters()) {
119 | enhanced.add(fixture.enhance(argument.getName(), parameter));
120 | }
121 | }
122 |
123 | return enhanced;
124 | }
125 |
126 | public Optional getBenchmarkMethod(String name, Class>... parameterTypes) {
127 |
128 | return getBenchmarkMethods(it -> it.getName().equals(name) && it.getParameterCount() == parameterTypes.length
129 | && Arrays.equals(parameterTypes, it.getParameterTypes())).findFirst();
130 | }
131 |
132 | public BenchmarkMethod getRequiredBenchmarkMethod(String name, Class>... parameterTypes) {
133 | return getBenchmarkMethod(name, parameterTypes)
134 | .orElseThrow(() -> new IllegalArgumentException("Cannot find method " + name));
135 | }
136 |
137 | private Stream getBenchmarkMethods(Predicate filter) {
138 |
139 | return Stream.concat(Arrays.stream(benchmarkClass.getMethods()), Arrays.stream(benchmarkClass.getDeclaredMethods())) //
140 | .filter(filter) //
141 | .distinct() //
142 | .map(BenchmarkMethod::new);
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/main/java/jmh/mbr/core/model/BenchmarkFixture.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core.model;
11 |
12 |
13 | import java.util.Collections;
14 | import java.util.LinkedHashMap;
15 | import java.util.Map;
16 |
17 | /**
18 | * Represents a parametrized fixture.
19 | */
20 | public class BenchmarkFixture implements BenchmarkDescriptor {
21 |
22 | private final Map fixture;
23 |
24 | private BenchmarkFixture(Map fixture) {
25 | this.fixture = fixture;
26 | }
27 |
28 | /**
29 | * Create a {@link BenchmarkFixture}.
30 | *
31 | * @param name name of the fixture parameter. Typically a field name.
32 | * @param parameter value of the fixture parameter.
33 | * @return the {@link BenchmarkFixture}.
34 | * @see org.openjdk.jmh.annotations.Param
35 | */
36 | public static BenchmarkFixture create(String name, String parameter) {
37 | return new BenchmarkFixture(Collections.singletonMap(name, parameter));
38 | }
39 |
40 | /**
41 | * Create an enhanced {@link BenchmarkFixture} that contains all parameter values and the given parameter tuple.
42 | *
43 | * @param name name of the fixture parameter. Typically a field name.
44 | * @param parameter value of the fixture parameter.
45 | * @return the {@link BenchmarkFixture}.
46 | */
47 | public BenchmarkFixture enhance(String name, String parameter) {
48 |
49 | Map fixture = new LinkedHashMap<>(this.fixture.size() + 1);
50 | fixture.putAll(this.fixture);
51 | fixture.put(name, parameter);
52 |
53 | return new BenchmarkFixture(fixture);
54 | }
55 |
56 | public Map getFixture() {
57 | return fixture;
58 | }
59 |
60 | public String getDisplayName() {
61 |
62 | String name = fixture.toString();
63 | if (name.startsWith("{") && name.endsWith("}")) {
64 | return "[" + name.substring(1, name.length() - 1) + "]";
65 | }
66 |
67 | return name;
68 | }
69 |
70 | @Override
71 | public String toString() {
72 | StringBuffer sb = new StringBuffer();
73 | sb.append(getClass().getSimpleName());
74 | sb.append(fixture);
75 | return sb.toString();
76 | }
77 |
78 | @Override
79 | public boolean equals(Object o) {
80 | if (this == o) return true;
81 | if (o == null || getClass() != o.getClass()) return false;
82 |
83 | BenchmarkFixture that = (BenchmarkFixture) o;
84 |
85 | return fixture != null ? fixture.equals(that.fixture) : that.fixture == null;
86 | }
87 |
88 | @Override
89 | public int hashCode() {
90 | return fixture != null ? fixture.hashCode() : 0;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/main/java/jmh/mbr/core/model/BenchmarkMethod.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core.model;
11 |
12 | import java.lang.annotation.Annotation;
13 | import java.lang.reflect.Method;
14 | import java.lang.reflect.Parameter;
15 | import java.util.Arrays;
16 | import java.util.Objects;
17 |
18 | /**
19 | * {@link BenchmarkDescriptor} for a {@link org.openjdk.jmh.annotations.Benchmark} {@link Method}.
20 | */
21 | public class BenchmarkMethod implements BenchmarkDescriptor, MethodAware {
22 |
23 | private final Method method;
24 |
25 | /**
26 | * Creates a new {@link BenchmarkMethod} for {@link Method}.
27 | *
28 | * @param method the underlying {@link Method}.
29 | */
30 | public BenchmarkMethod(Method method) {
31 |
32 | Objects.requireNonNull(method, "Method must not be null!");
33 |
34 | this.method = method;
35 | }
36 |
37 | @Override
38 | public Method getMethod() {
39 | return method;
40 | }
41 |
42 | @Override
43 | public boolean isUnderlyingMethod(Method method) {
44 | return this.method.equals(method);
45 | }
46 |
47 | /**
48 | * @return the method's name.
49 | */
50 | public String getName() {
51 | return method.getName();
52 | }
53 |
54 | /**
55 | * @return the method's parameters.
56 | */
57 | public Parameter[] getParameters() {
58 | return method.getParameters();
59 | }
60 |
61 | /**
62 | * @return the method's parameter types.
63 | */
64 | private Class>[] getParameterTypes() {
65 | return method.getParameterTypes();
66 | }
67 |
68 | /**
69 | * @return the return type of the method.
70 | */
71 | public Class> getReturnType() {
72 | return method.getReturnType();
73 | }
74 |
75 | /**
76 | * @return the class where the method is actually declared.
77 | */
78 | public Class> getDeclaringClass() {
79 | return method.getDeclaringClass();
80 | }
81 |
82 | @Override
83 | public boolean equals(Object obj) {
84 | if (!BenchmarkMethod.class.isInstance(obj)) {
85 | return false;
86 | }
87 | return ((BenchmarkMethod) obj).method.equals(method);
88 | }
89 |
90 | @Override
91 | public int hashCode() {
92 | return method.hashCode();
93 | }
94 |
95 | /**
96 | * @return the annotations on this method.
97 | */
98 | public Annotation[] getAnnotations() {
99 | return method.getAnnotations();
100 | }
101 |
102 | /**
103 | * Returns the annotation of type {@code annotationType} on this method, if one exists.
104 | *
105 | * @param annotationType type of annotation to retrieve.
106 | * @param annotation type.
107 | * @return the annotation or {@literal null} if not found.
108 | */
109 | public T getAnnotation(Class annotationType) {
110 | return method.getAnnotation(annotationType);
111 | }
112 |
113 | @Override
114 | public String toString() {
115 | return method.toString();
116 | }
117 |
118 | /**
119 | * @return {@literal true} whether the method is a parametrized one.
120 | */
121 | public boolean isParametrized() {
122 |
123 | if (StateClass.isParametrized(method.getDeclaringClass())) {
124 | return true;
125 | }
126 |
127 | return Arrays.stream(method.getParameters()) //
128 | .map(Parameter::getType) //
129 | .anyMatch(StateClass::isParametrized);
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/main/java/jmh/mbr/core/model/BenchmarkParameters.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core.model;
11 |
12 | import java.util.Collection;
13 | import java.util.LinkedHashMap;
14 | import java.util.LinkedHashSet;
15 | import java.util.List;
16 | import java.util.Map;
17 | import java.util.Set;
18 |
19 | /**
20 | * Utility class to discover {@link BenchmarkArgument} along with their parameter values from {@link StateClass state
21 | * classes}.
22 | */
23 | class BenchmarkParameters {
24 |
25 | static Collection discover(List stateClasses) {
26 |
27 | Map argumentMap = new LinkedHashMap<>();
28 |
29 | stateClasses.stream().map(StateClass::getParametrizedFields).flatMap(Collection::stream).forEach(it -> {
30 |
31 | List parameterValues = StateClass.getParameterValues(it);
32 |
33 | BenchmarkArgument benchmarkArgument = argumentMap.computeIfAbsent(it.getName(), BenchmarkArgument::new);
34 | benchmarkArgument.getParameters().addAll(parameterValues);
35 | });
36 |
37 | return argumentMap.values();
38 | }
39 |
40 | static class BenchmarkArgument {
41 |
42 | final String name;
43 | final Set parameters = new LinkedHashSet<>();
44 |
45 | public BenchmarkArgument(String name) {
46 | this.name = name;
47 | }
48 |
49 | int getParameterCount() {
50 | return parameters.size();
51 | }
52 |
53 | Set getParameters() {
54 | return parameters;
55 | }
56 |
57 | String getName() {
58 | return name;
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/main/java/jmh/mbr/core/model/BenchmarkResults.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2020 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * https://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core.model;
11 |
12 | import java.time.Instant;
13 | import java.util.ArrayList;
14 | import java.util.Collection;
15 | import java.util.Iterator;
16 | import java.util.LinkedHashMap;
17 | import java.util.List;
18 | import java.util.Map;
19 | import java.util.Map.Entry;
20 | import java.util.function.BiFunction;
21 | import java.util.stream.Stream;
22 |
23 | import jmh.mbr.core.Environment;
24 | import jmh.mbr.core.model.BenchmarkResults.BenchmarkResult;
25 | import org.openjdk.jmh.infra.BenchmarkParams;
26 | import org.openjdk.jmh.results.Result;
27 | import org.openjdk.jmh.results.RunResult;
28 |
29 | /**
30 | * Wrapper for {@link RunResult RunResults}.
31 | */
32 | public class BenchmarkResults implements Iterable {
33 |
34 | private final List runResults;
35 | private final MetaData metaData;
36 |
37 | public BenchmarkResults(MetaData metaData, Collection runResults) {
38 |
39 | this.runResults = new ArrayList<>(runResults);
40 | this.metaData = metaData;
41 | }
42 |
43 | /**
44 | * Obtain a {@link Stream} of {@link BenchmarkResult}.
45 | *
46 | * @return a {@link Stream} of {@link BenchmarkResult}.
47 | */
48 | public Stream stream() {
49 | return runResults.stream().map(it -> new BenchmarkResult(metaData, it));
50 | }
51 |
52 | public MetaData getMetaData() {
53 | return metaData;
54 | }
55 |
56 | /**
57 | * @return the raw {@link RunResult jmh results}.
58 | */
59 | public List getRawResults() {
60 | return runResults;
61 | }
62 |
63 | @Override
64 | public Iterator iterator() {
65 | return runResults.stream().map(it -> new BenchmarkResult(metaData, it))
66 | .iterator();
67 | }
68 |
69 | /**
70 | * Wrapper for a single {@link RunResult} along with execution {@link MetaData}.
71 | */
72 | public static class BenchmarkResult {
73 |
74 | private final MetaData metaData;
75 | private final RunResult runResult;
76 |
77 | public BenchmarkResult(MetaData metaData, RunResult runResult) {
78 |
79 | this.metaData = metaData;
80 | this.runResult = runResult;
81 | }
82 |
83 | public T map(BiFunction function) {
84 | return function.apply(metaData, runResult);
85 | }
86 |
87 | public MetaData getMetaData() {
88 | return metaData;
89 | }
90 |
91 | public Collection getBenchmarkResults() {
92 | return runResult.getBenchmarkResults();
93 | }
94 |
95 | public Result getPrimaryResult() {
96 | return runResult.getPrimaryResult();
97 | }
98 |
99 | public Map getSecondaryResults() {
100 | return runResult.getSecondaryResults();
101 | }
102 |
103 | public org.openjdk.jmh.results.BenchmarkResult getAggregatedResult() {
104 | return runResult.getAggregatedResult();
105 | }
106 |
107 | public BenchmarkParams getParams() {
108 | return runResult.getParams();
109 | }
110 | }
111 |
112 | public static class MetaData {
113 |
114 | private String project;
115 | private String version;
116 | private Instant time;
117 | private String os;
118 | private Map additionalParameters = new LinkedHashMap<>();
119 |
120 | private MetaData() {
121 | this.time = Instant.now();
122 | }
123 |
124 | public MetaData(String project, String version) {
125 | this();
126 | this.project = project;
127 | this.version = version;
128 | }
129 |
130 | public static MetaData none() {
131 | return new MetaData();
132 | }
133 |
134 | public String getProject() {
135 | return project;
136 | }
137 |
138 | public String getVersion() {
139 | return version;
140 | }
141 |
142 | public Instant getTime() {
143 | return time;
144 | }
145 |
146 | public String getOs() {
147 | return os != null ? os : Environment.getOsName();
148 | }
149 |
150 | public Map getAdditionalParameters() {
151 | return additionalParameters;
152 | }
153 |
154 | public boolean hasAdditionalMetadata() {
155 | return !additionalParameters.isEmpty();
156 | }
157 |
158 | public static MetaData from(Map metadata) {
159 |
160 | MetaData target = new MetaData();
161 |
162 | for (Entry entry : metadata.entrySet()) {
163 |
164 | switch (entry.getKey()) {
165 | case "os":
166 | target.os = entry.getValue().toString();
167 | continue;
168 | case "jmh.mbr.project":
169 | target.project = entry.getValue().toString();
170 | continue;
171 | case "jmh.mbr.project.version":
172 | target.version = entry.getValue().toString();
173 | continue;
174 | default:
175 | target.additionalParameters.put(entry.getKey(), entry.getValue());
176 | }
177 | }
178 |
179 | return target;
180 | }
181 |
182 | @Override
183 | public String toString() {
184 | return "MetaData{" +
185 | "project='" + project + '\'' +
186 | ", version='" + version + '\'' +
187 | ", time=" + time +
188 | ", os='" + os + '\'' +
189 | ", additionalParameters=" + additionalParameters +
190 | '}';
191 | }
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/main/java/jmh/mbr/core/model/HierarchicalBenchmarkDescriptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core.model;
11 |
12 | import java.util.ArrayList;
13 | import java.util.Collection;
14 | import java.util.Collections;
15 | import java.util.List;
16 | import java.util.Objects;
17 |
18 | /**
19 | * {@link BenchmarkDescriptor} that represents a hierarchy of benchmark configurations.
20 | */
21 | public class HierarchicalBenchmarkDescriptor implements BenchmarkDescriptor {
22 |
23 | private final BenchmarkDescriptor descriptor;
24 | private final List extends BenchmarkDescriptor> children;
25 |
26 | HierarchicalBenchmarkDescriptor(BenchmarkDescriptor descriptor, List extends BenchmarkDescriptor> children) {
27 |
28 | Objects.requireNonNull(descriptor, "BenchmarkDescriptor must not be null!");
29 | Objects.requireNonNull(children, "Children must not be null!");
30 |
31 | this.descriptor = descriptor;
32 | this.children = Collections.unmodifiableList(children);
33 | }
34 |
35 | /**
36 | * Create a {@link HierarchicalBenchmarkDescriptor} without children.
37 | *
38 | * @param descriptor the {@link BenchmarkDescriptor} that hosts benchmark.
39 | * @return the {@link HierarchicalBenchmarkDescriptor} for {@link BenchmarkDescriptor}.
40 | */
41 | public static HierarchicalBenchmarkDescriptor create(BenchmarkDescriptor descriptor) {
42 |
43 | Objects.requireNonNull(descriptor, "BenchmarkDescriptor must not be null!");
44 |
45 | return new HierarchicalBenchmarkDescriptor(descriptor, Collections.emptyList());
46 | }
47 |
48 | /**
49 | * Create a {@link HierarchicalBenchmarkDescriptor} with children.
50 | *
51 | * @param descriptor the {@link BenchmarkDescriptor} that hosts benchmark.
52 | * @param children benchmark children.
53 | * @return the {@link HierarchicalBenchmarkDescriptor} for {@link BenchmarkDescriptor}.
54 | */
55 | public static HierarchicalBenchmarkDescriptor create(BenchmarkDescriptor descriptor,
56 | Collection children) {
57 |
58 | Objects.requireNonNull(descriptor, "BenchmarkDescriptor must not be null!");
59 | Objects.requireNonNull(children, "Children must not be null!");
60 |
61 | return new HierarchicalBenchmarkDescriptor(descriptor, new ArrayList<>(children));
62 | }
63 |
64 | public BenchmarkDescriptor getDescriptor() {
65 | return descriptor;
66 | }
67 |
68 | public List extends BenchmarkDescriptor> getChildren() {
69 | return children;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/main/java/jmh/mbr/core/model/MethodAware.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core.model;
11 |
12 | import java.lang.reflect.Method;
13 |
14 | /**
15 | * Interface exposing {@link Method} awareness of a specific descriptor object.
16 | */
17 | public interface MethodAware {
18 |
19 | /**
20 | * @return the underlying method.
21 | */
22 | Method getMethod();
23 |
24 | /**
25 | * Check whether the given {@code method} is represented by this object.
26 | *
27 | * @param method must not be {@literal null}.
28 | * @return {@literal true} if the underlying {@link Method} is {@code method.}
29 | */
30 | boolean isUnderlyingMethod(Method method);
31 | }
32 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/main/java/jmh/mbr/core/model/ParametrizedBenchmarkMethod.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core.model;
11 |
12 | import java.lang.reflect.Method;
13 | import java.util.List;
14 |
15 | /**
16 | * Represents a parametrized benchmark method along with the actual {@link BenchmarkFixture fixtures}.
17 | */
18 | public class ParametrizedBenchmarkMethod extends HierarchicalBenchmarkDescriptor implements MethodAware {
19 |
20 | ParametrizedBenchmarkMethod(BenchmarkMethod descriptor, List children) {
21 | super(descriptor, children);
22 | }
23 |
24 | @Override
25 | public BenchmarkMethod getDescriptor() {
26 | return (BenchmarkMethod) super.getDescriptor();
27 | }
28 |
29 | @Override
30 | public List getChildren() {
31 | return (List) super.getChildren();
32 | }
33 |
34 | @Override
35 | public Method getMethod() {
36 | return getDescriptor().getMethod();
37 | }
38 |
39 | @Override
40 | public boolean isUnderlyingMethod(Method method) {
41 | return getDescriptor().isUnderlyingMethod(method);
42 | }
43 |
44 | @Override
45 | public int hashCode() {
46 | return super.hashCode();
47 | }
48 |
49 | @Override
50 | public boolean equals(Object obj) {
51 | return super.equals(obj);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/main/java/jmh/mbr/core/model/StateClass.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core.model;
11 |
12 | import java.lang.reflect.Field;
13 | import java.util.Arrays;
14 | import java.util.Collections;
15 | import java.util.List;
16 | import java.util.Objects;
17 | import java.util.stream.Collectors;
18 | import java.util.stream.Stream;
19 |
20 | import org.openjdk.jmh.annotations.Param;
21 | import org.openjdk.jmh.annotations.State;
22 |
23 | /**
24 | * Value object to encapsulate a JMH {@code @State} class.
25 | */
26 | class StateClass {
27 |
28 | private final Class> stateClass;
29 |
30 | public StateClass(Class> stateClass) {
31 | this.stateClass = stateClass;
32 | }
33 |
34 | /**
35 | * Create a {@link StateClass} given {@link Class}.
36 | *
37 | * @param stateClass
38 | * @return
39 | */
40 | public static StateClass create(Class> stateClass) {
41 |
42 | Objects.requireNonNull(stateClass, "State class must not be null!");
43 |
44 | return new StateClass(stateClass);
45 | }
46 |
47 | /**
48 | * @param stateClass
49 | * @return {@literal true} if the state class is parametrized.
50 | * @see Param
51 | */
52 | public static boolean isParametrized(Class> stateClass) {
53 |
54 | Objects.requireNonNull(stateClass, "Class must not be null!");
55 |
56 | if (!stateClass.isAnnotationPresent(State.class)) {
57 | return false;
58 | }
59 |
60 | return Stream.concat(Arrays.stream(stateClass.getFields()), Arrays.stream(stateClass.getDeclaredFields()))
61 | .anyMatch(it -> it.isAnnotationPresent(Param.class));
62 | }
63 |
64 | /**
65 | * @param field
66 | * @return the possible {@link Param} values for a {@link Field}.
67 | */
68 | public static List getParameterValues(Field field) {
69 |
70 | Param annotation = field.getAnnotation(Param.class);
71 |
72 | if (annotation != null
73 | && (annotation.value().length == 0
74 | || (annotation.value().length == 1 && annotation.value()[0].equals(Param.BLANK_ARGS)))
75 | && field.getType().isEnum()) {
76 | return Arrays.asList(field.getType().getEnumConstants()).stream().map(Object::toString)
77 | .collect(Collectors.toList());
78 | }
79 |
80 | if (annotation == null || annotation.value().length == 0
81 | || (annotation.value().length == 1 && annotation.value()[0].equals(Param.BLANK_ARGS))) {
82 | return Collections.emptyList();
83 | }
84 |
85 | return Arrays.asList(annotation.value());
86 | }
87 |
88 | /**
89 | * @return {@link List}of {@link Param} fields.
90 | */
91 | public List getParametrizedFields() {
92 |
93 | return Stream.concat(Arrays.stream(stateClass.getFields()), Arrays.stream(stateClass.getDeclaredFields()))
94 | .filter(it -> it.isAnnotationPresent(Param.class)) //
95 | .distinct() //
96 | .collect(Collectors.toList());
97 | }
98 |
99 | @Override
100 | public String toString() {
101 | StringBuffer sb = new StringBuffer();
102 | sb.append(getClass().getSimpleName());
103 | sb.append(" [").append(stateClass.getName());
104 | sb.append(']');
105 | return sb.toString();
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/test/java/jmh/mbr/core/JmhSupportUnitTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core;
11 |
12 | import static org.assertj.core.api.Assertions.*;
13 |
14 | import java.io.IOException;
15 | import java.util.Collection;
16 | import java.util.Collections;
17 |
18 | import jmh.mbr.core.model.BenchmarkResults;
19 | import jmh.mbr.core.model.BenchmarkResults.MetaData;
20 | import org.junit.jupiter.api.Test;
21 | import org.openjdk.jmh.infra.BenchmarkParams;
22 | import org.openjdk.jmh.infra.IterationParams;
23 | import org.openjdk.jmh.results.BenchmarkResult;
24 | import org.openjdk.jmh.results.IterationResult;
25 | import org.openjdk.jmh.results.RunResult;
26 | import org.openjdk.jmh.runner.format.OutputFormat;
27 |
28 | /**
29 | * Unit tests for {@link JmhSupport}.
30 | */
31 | class JmhSupportUnitTests {
32 |
33 | @Test
34 | void shouldConsiderCompositeResultWriterUri() {
35 |
36 | TestResultsWriterFactory.REGISTRY.put("foo", FooResultWriter::new);
37 | TestResultsWriterFactory.REGISTRY.put("bar", BarResultWriter::new);
38 |
39 | System.setProperty("jmh.mbr.report.publishTo", "foo,bar,none");
40 |
41 | try {
42 | JmhSupport support = new JmhSupport(BenchmarkConfiguration.defaultOptions());
43 | RunResult runResult = new RunResult(null, Collections.emptyList());
44 | support.publishResults(SilentOutputFormat.INSTANCE, new BenchmarkResults(MetaData.none(), Collections.singleton(runResult)));
45 | } finally {
46 | System.clearProperty("jmh.mbr.report.publishTo");
47 | TestResultsWriterFactory.REGISTRY.remove("foo");
48 | TestResultsWriterFactory.REGISTRY.remove("bar");
49 | }
50 |
51 | assertThat(FooResultWriter.written).isTrue();
52 | assertThat(BarResultWriter.written).isTrue();
53 | }
54 |
55 | @Test
56 | void shouldBeAbleToWriteToEmptyUri() {
57 |
58 | TestResultsWriterFactory.REGISTRY.put("", FooResultWriter::new);
59 |
60 | try {
61 | JmhSupport support = new JmhSupport(BenchmarkConfiguration.defaultOptions());
62 | RunResult runResult = new RunResult(null, Collections.emptyList());
63 | support.publishResults(SilentOutputFormat.INSTANCE, new BenchmarkResults(MetaData.none(), Collections.singleton(runResult)));
64 | } finally {
65 | TestResultsWriterFactory.REGISTRY.remove("");
66 | }
67 |
68 | assertThat(FooResultWriter.written).isTrue();
69 | }
70 |
71 | static class FooResultWriter implements ResultsWriter {
72 |
73 | static boolean written = false;
74 |
75 | @Override
76 | public void write(OutputFormat output, BenchmarkResults results) {
77 | written = true;
78 | }
79 | }
80 |
81 | static class BarResultWriter implements ResultsWriter {
82 |
83 | static boolean written = false;
84 |
85 | @Override
86 | public void write(OutputFormat output, BenchmarkResults results) {
87 | written = true;
88 | }
89 | }
90 |
91 | enum SilentOutputFormat implements OutputFormat {
92 |
93 | INSTANCE;
94 |
95 | @Override
96 | public void iteration(BenchmarkParams benchParams, IterationParams params, int iteration) {
97 |
98 | }
99 |
100 | @Override
101 | public void iterationResult(BenchmarkParams benchParams, IterationParams params, int iteration,
102 | IterationResult data) {
103 |
104 | }
105 |
106 | @Override
107 | public void startBenchmark(BenchmarkParams benchParams) {
108 |
109 | }
110 |
111 | @Override
112 | public void endBenchmark(BenchmarkResult result) {
113 |
114 | }
115 |
116 | @Override
117 | public void startRun() {
118 |
119 | }
120 |
121 | @Override
122 | public void endRun(Collection result) {
123 |
124 | }
125 |
126 | @Override
127 | public void print(String s) {
128 |
129 | }
130 |
131 | @Override
132 | public void println(String s) {
133 |
134 | }
135 |
136 | @Override
137 | public void flush() {
138 |
139 | }
140 |
141 | @Override
142 | public void close() {
143 |
144 | }
145 |
146 | @Override
147 | public void verbosePrintln(String s) {
148 |
149 | }
150 |
151 | @Override
152 | public void write(int b) {
153 |
154 | }
155 |
156 | @Override
157 | public void write(byte[] b) throws IOException {
158 |
159 | }
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/test/java/jmh/mbr/core/ResultsWriterFactoryTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core;
11 |
12 | import org.junit.jupiter.api.Test;
13 |
14 | import static org.assertj.core.api.Assertions.assertThat;
15 |
16 | class ResultsWriterFactoryTests {
17 |
18 | @Test
19 | void test() {
20 | assertThat(ResultsWriter.forUri("urn:empty")).isNotNull();
21 | }
22 |
23 | @Test
24 | void nouri() {
25 | assertThat(ResultsWriter.forUri("")).isNull();
26 | }
27 |
28 | @Test
29 | void empty() {
30 | assertThat(ResultsWriter.forUri("file:./target")).isNull();
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/test/java/jmh/mbr/core/TestResultsWriterFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core;
11 |
12 | import java.util.Collection;
13 | import java.util.HashMap;
14 | import java.util.Map;
15 | import java.util.function.Supplier;
16 |
17 | import jmh.mbr.core.model.BenchmarkResults;
18 | import org.openjdk.jmh.results.RunResult;
19 | import org.openjdk.jmh.runner.format.OutputFormat;
20 |
21 | public class TestResultsWriterFactory implements ResultsWriterFactory {
22 |
23 | static Map> REGISTRY = new HashMap<>();
24 |
25 | static {
26 | REGISTRY.put("urn:empty", TestResultsWriter::new);
27 | }
28 |
29 | @Override
30 | public ResultsWriter forUri(String uri) {
31 | return REGISTRY.getOrDefault(uri, () -> null).get();
32 | }
33 |
34 | static class TestResultsWriter implements ResultsWriter {
35 |
36 | @Override
37 | public void write(OutputFormat output, BenchmarkResults results) {
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/test/java/jmh/mbr/core/model/BenchmarkDescriptorFactoryUnitTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.core.model;
11 |
12 | import static org.assertj.core.api.Assertions.*;
13 |
14 | import jmh.mbr.core.model.BenchmarkDescriptorFactoryUnitTests.BenchmarkClass.OneParameter;
15 | import jmh.mbr.core.model.BenchmarkDescriptorFactoryUnitTests.BenchmarkClass.Three1;
16 | import jmh.mbr.core.model.BenchmarkDescriptorFactoryUnitTests.BenchmarkClass.Three2;
17 | import jmh.mbr.core.model.BenchmarkDescriptorFactoryUnitTests.BenchmarkClass.TwoParameters;
18 |
19 | import java.util.List;
20 |
21 | import org.junit.jupiter.api.Test;
22 | import org.openjdk.jmh.annotations.Benchmark;
23 | import org.openjdk.jmh.annotations.Param;
24 | import org.openjdk.jmh.annotations.Scope;
25 | import org.openjdk.jmh.annotations.State;
26 |
27 | /**
28 | * Unit tests for {@link BenchmarkDescriptorFactory}.
29 | */
30 | class BenchmarkDescriptorFactoryUnitTests {
31 |
32 | @Test
33 | void shouldNotCreateFixtures() {
34 |
35 | BenchmarkDescriptorFactory factory = BenchmarkDescriptorFactory.create(BenchmarkClass.class);
36 | BenchmarkMethod simple = factory.getRequiredBenchmarkMethod("simple");
37 |
38 | List fixtures = factory.createFixtures(simple);
39 | assertThat(fixtures).isEmpty();
40 | }
41 |
42 | @Test
43 | void shouldCreateOneFixtureForSingleParametrizedMethod() {
44 |
45 | BenchmarkDescriptorFactory factory = BenchmarkDescriptorFactory.create(BenchmarkClass.class);
46 | BenchmarkMethod single = factory.getRequiredBenchmarkMethod("single", OneParameter.class);
47 |
48 | List fixtures = factory.createFixtures(single);
49 | assertThat(fixtures).hasSize(1);
50 | }
51 |
52 | @Test
53 | void shouldCreateMultipleFixtureForParametrizedMethodWithTwoParams() {
54 |
55 | BenchmarkDescriptorFactory factory = BenchmarkDescriptorFactory.create(BenchmarkClass.class);
56 | BenchmarkMethod single = factory.getRequiredBenchmarkMethod("single", TwoParameters.class);
57 |
58 | List fixtures = factory.createFixtures(single);
59 | assertThat(fixtures).hasSize(2);
60 | }
61 |
62 | @Test
63 | void shouldCreateMultipleFixturesForParameterMatrix() {
64 |
65 | BenchmarkDescriptorFactory factory = BenchmarkDescriptorFactory.create(BenchmarkClass.class);
66 | BenchmarkMethod single = factory.getRequiredBenchmarkMethod("multi", OneParameter.class, TwoParameters.class);
67 |
68 | List fixtures = factory.createFixtures(single);
69 | assertThat(fixtures).hasSize(2);
70 | }
71 |
72 | @Test
73 | public void shouldCreateMultipleFixturesFor3x3ParameterMatrix() {
74 |
75 | BenchmarkDescriptorFactory factory = BenchmarkDescriptorFactory.create(BenchmarkClass.class);
76 | BenchmarkMethod single = factory.getRequiredBenchmarkMethod("nine", Three1.class, Three2.class);
77 |
78 | List fixtures = factory.createFixtures(single);
79 | assertThat(fixtures).hasSize(9);
80 | }
81 |
82 | @Test
83 | public void shouldCreateMultipleFixturesParametrizedBenchmarkClass() {
84 |
85 | BenchmarkDescriptorFactory factory = BenchmarkDescriptorFactory.create(ParametrizedBenchmarkClass.class);
86 | BenchmarkMethod single = factory.getRequiredBenchmarkMethod("simple");
87 |
88 | List fixtures = factory.createFixtures(single);
89 | assertThat(fixtures).hasSize(3);
90 | }
91 |
92 | @Test
93 | public void shouldCreateMultipleFixturesEnumParametrizedBenchmarkClass() {
94 |
95 | BenchmarkDescriptorFactory factory = BenchmarkDescriptorFactory.create(EnumParametrizedBenchmarkClass.class);
96 | BenchmarkMethod single = factory.getRequiredBenchmarkMethod("simple");
97 |
98 | List fixtures = factory.createFixtures(single);
99 | assertThat(fixtures).hasSize(3);
100 | }
101 |
102 | static class BenchmarkClass {
103 |
104 | @Benchmark
105 | void simple() {
106 |
107 | }
108 |
109 | @Benchmark
110 | void single(OneParameter single) {
111 |
112 | }
113 |
114 | @Benchmark
115 | void single(TwoParameters two) {
116 |
117 | }
118 |
119 | @Benchmark
120 | void multi(OneParameter one, TwoParameters two) {
121 |
122 | }
123 |
124 | @Benchmark
125 | void nine(Three1 one, Three2 two) {
126 |
127 | }
128 |
129 | @State(Scope.Benchmark)
130 | static class OneParameter {
131 |
132 | @Param("bar") String foo;
133 | }
134 |
135 | @State(Scope.Benchmark)
136 | static class TwoParameters {
137 |
138 | @Param({ "1", "2" }) String param2;
139 | }
140 |
141 | @State(Scope.Benchmark)
142 | static class Three1 {
143 |
144 | @Param({ "1", "2", "3" }) String foo;
145 | }
146 |
147 | @State(Scope.Benchmark)
148 | static class Three2 {
149 |
150 | @Param({ "1", "2", "3" }) String bar;
151 | }
152 | }
153 |
154 | @State(Scope.Benchmark)
155 | static class ParametrizedBenchmarkClass {
156 |
157 | @Param({ "1", "2", "3" }) String foo;
158 |
159 | @Benchmark
160 | void simple() {
161 |
162 | }
163 | }
164 |
165 | @State(Scope.Benchmark)
166 | static class EnumParametrizedBenchmarkClass {
167 |
168 | public static enum Sample {
169 | ONE, TWO, THREE
170 | }
171 |
172 | @Param Sample foo;
173 |
174 | @Benchmark
175 | void simple() {
176 |
177 | }
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/microbenchmark-runner-core/src/test/resources/META-INF/services/jmh.mbr.core.ResultsWriterFactory:
--------------------------------------------------------------------------------
1 | jmh.mbr.core.TestResultsWriterFactory
2 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | com.github.mp911de.microbenchmark-runner
9 | microbenchmark-runner-parent
10 | 0.6.0.BUILD-SNAPSHOT
11 |
12 |
13 | microbenchmark-runner-extras
14 | Microbenchmark Runner Extras such as CSV Results Writer
15 |
16 |
17 |
18 |
19 | org.openjdk.jmh
20 | jmh-core
21 |
22 |
23 |
24 | com.github.mp911de.microbenchmark-runner
25 | microbenchmark-runner-core
26 | ${project.version}
27 |
28 |
29 |
30 | org.elasticsearch.client
31 | elasticsearch-rest-high-level-client
32 | 7.5.0
33 | true
34 |
35 |
36 |
37 | org.junit.jupiter
38 | junit-jupiter-api
39 | test
40 |
41 |
42 |
43 | org.junit.jupiter
44 | junit-jupiter-engine
45 | test
46 |
47 |
48 |
49 | org.assertj
50 | assertj-core
51 |
52 |
53 |
54 | org.mockito
55 | mockito-junit-jupiter
56 | 3.1.0
57 | test
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/main/java/jmh/mbr/extras/writer/CsvResultsFormatter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras.writer;
11 |
12 | import java.util.Collection;
13 | import java.util.LinkedHashMap;
14 | import java.util.Map;
15 |
16 | import org.openjdk.jmh.results.Result;
17 | import org.openjdk.jmh.results.RunResult;
18 | import org.openjdk.jmh.util.ScoreFormatter;
19 | import org.openjdk.jmh.util.Statistics;
20 |
21 | /**
22 | * Utility to create a CSV-formatted report.
23 | */
24 | class CsvResultsFormatter {
25 |
26 | /**
27 | * Create a report in CSV format.
28 | *
29 | * @param results
30 | * @return
31 | */
32 | static String createReport(Collection results) {
33 |
34 | StringBuilder report = new StringBuilder(System.lineSeparator());
35 | Map params = detectParameters(results);
36 | Map auxes = detectAuxes(results);
37 |
38 | StringBuilder header = new StringBuilder();
39 | header.append("class, method, ");
40 | params.forEach((key, value) -> header.append(key).append(", "));
41 | auxes.forEach((key, value) -> header.append(propertyName(key)).append(", "));
42 | header.append("median, mean, range");
43 | report.append(header.toString()).append(System.lineSeparator());
44 |
45 | for (RunResult result : results) {
46 | StringBuilder builder = new StringBuilder();
47 | if (result.getParams() != null) {
48 | String benchmark = result.getParams().getBenchmark();
49 | String cls = benchmark.contains(".")
50 | ? benchmark.substring(0, benchmark.lastIndexOf("."))
51 | : benchmark;
52 | String mthd = benchmark.substring(benchmark.lastIndexOf(".") + 1);
53 | builder.append(cls).append(", ").append(mthd).append(", ");
54 | for (int i = 0; i < params.values().size(); i++) {
55 | boolean found = false;
56 | for (String param : result.getParams().getParamsKeys()) {
57 | if (params.get(param) == i) {
58 | builder.append(result.getParams().getParam(param))
59 | .append(", ");
60 | found = true;
61 | }
62 | }
63 | if (!found) {
64 | builder.append(", ");
65 | }
66 | }
67 | }
68 |
69 | if (result.getAggregatedResult() != null) {
70 |
71 | Map second = result.getAggregatedResult()
72 | .getSecondaryResults();
73 | for (int i = 0; i < auxes.values().size(); i++) {
74 | boolean found = false;
75 | for (String param : second.keySet()) {
76 | if (auxes.get(param) == i) {
77 | builder.append(ScoreFormatter.format(
78 | second.get(param).getStatistics().getPercentile(0.5)))
79 | .append(", ");
80 | found = true;
81 | }
82 | }
83 | if (!found) {
84 | builder.append(", ");
85 | }
86 | }
87 | // primary result is derived from aggregate result
88 | Statistics statistics = result.getPrimaryResult().getStatistics();
89 | builder.append(ScoreFormatter.format(statistics.getPercentile(0.5)));
90 | builder.append(", ");
91 | builder.append(ScoreFormatter.format(statistics.getMean()));
92 | builder.append(", ");
93 | double error = (statistics.getMax() - statistics.getMin()) / 2;
94 | builder.append(ScoreFormatter.format(error));
95 |
96 | report.append(builder.toString()).append(System.lineSeparator());
97 | }
98 | }
99 |
100 | return report.toString();
101 | }
102 |
103 | private static Map detectAuxes(Collection results) {
104 | Map auxes = new LinkedHashMap<>();
105 | int auxPlaces = 0;
106 | for (RunResult result : results) {
107 | if (result.getAggregatedResult() != null) {
108 | @SuppressWarnings("rawtypes")
109 | Map second = result.getAggregatedResult()
110 | .getSecondaryResults();
111 | if (second != null) {
112 | for (String aux : second.keySet()) {
113 | int count = auxPlaces;
114 | auxes.computeIfAbsent(aux, key -> count);
115 | auxPlaces++;
116 | }
117 | }
118 | }
119 | }
120 | return auxes;
121 | }
122 |
123 | private static Map detectParameters(Collection results) {
124 | Map params = new LinkedHashMap<>();
125 | int paramPlaces = 0;
126 | for (RunResult result : results) {
127 | if (result.getParams() != null) {
128 | for (String param : result.getParams().getParamsKeys()) {
129 | int count = paramPlaces;
130 | if (params.containsKey(param)) {
131 | continue;
132 | }
133 | params.put(param, count);
134 | paramPlaces++;
135 | }
136 | }
137 | }
138 | return params;
139 | }
140 |
141 | private static String propertyName(String key) {
142 | if (key.matches("get[A-Z].*")) {
143 | key = changeFirstCharacterCase(key.substring(3), false);
144 | }
145 | return key;
146 | }
147 |
148 | private static String changeFirstCharacterCase(String str, boolean capitalize) {
149 | if (str == null || str.length() == 0) {
150 | return str;
151 | }
152 |
153 | char baseChar = str.charAt(0);
154 | char updatedChar;
155 | if (capitalize) {
156 | updatedChar = Character.toUpperCase(baseChar);
157 | }
158 | else {
159 | updatedChar = Character.toLowerCase(baseChar);
160 | }
161 | if (baseChar == updatedChar) {
162 | return str;
163 | }
164 |
165 | char[] chars = str.toCharArray();
166 | chars[0] = updatedChar;
167 | return new String(chars, 0, chars.length);
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/main/java/jmh/mbr/extras/writer/CsvResultsWriter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2020 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras.writer;
11 |
12 | import java.io.File;
13 | import java.io.FileNotFoundException;
14 | import java.io.IOException;
15 | import java.util.Collections;
16 |
17 | import jmh.mbr.core.ResultsWriter;
18 | import jmh.mbr.core.model.BenchmarkResults;
19 | import org.openjdk.jmh.runner.format.OutputFormat;
20 | import org.openjdk.jmh.util.FileUtils;
21 |
22 | class CsvResultsWriter implements ResultsWriter {
23 |
24 | private final String uri;
25 |
26 | public CsvResultsWriter(String uri) {
27 | this.uri = uri;
28 | }
29 |
30 | @Override
31 | public void write(OutputFormat output, BenchmarkResults results) {
32 |
33 | String report;
34 |
35 | try {
36 | report = CsvResultsFormatter.createReport(results.getRawResults());
37 | }
38 | catch (Exception e) {
39 | output.println("Report creation failed: " + StackTraceCapture.from(e));
40 | return;
41 | }
42 | try {
43 |
44 | File file = new File(uri.substring("csv:".length())).getCanonicalFile();
45 | output.println(System.lineSeparator());
46 | output.println("Writing result to file: " + file);
47 |
48 | File parent = file.getParentFile();
49 | if (parent != null) {
50 |
51 | parent.mkdirs();
52 |
53 | if (parent.exists()) {
54 | FileUtils.writeLines(file, Collections.singleton(report));
55 | return;
56 | }
57 | }
58 |
59 | throw new FileNotFoundException("Parent directory " + parent + " does not exist");
60 | }
61 | catch (IOException e) {
62 | output.println("Write failed: " + e
63 | .getMessage() + " " + StackTraceCapture.from(e));
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/main/java/jmh/mbr/extras/writer/CsvResultsWriterFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras.writer;
11 |
12 | import jmh.mbr.core.ResultsWriter;
13 | import jmh.mbr.core.ResultsWriterFactory;
14 |
15 | /**
16 | * A {@link ResultsWriterFactory} that writes the output in csv format (to the console and to a file). Activated with
17 | * -Djmh.mbr.report.publishTo=csv:./path/to/file.csv
. The file will be overwritten if it already exists. If the file
18 | * cannot be written a warning will be printed on the console.
19 | */
20 | public class CsvResultsWriterFactory implements ResultsWriterFactory {
21 |
22 | @Override
23 | public ResultsWriter forUri(String uri) {
24 |
25 | if (!uri.startsWith("csv:")) {
26 | return null;
27 | }
28 |
29 | return new CsvResultsWriter(uri);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/main/java/jmh/mbr/extras/writer/ElasticsearchResultsWriter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2020 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * https://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras.writer;
11 |
12 | import java.io.IOException;
13 | import java.util.Base64;
14 |
15 | import jmh.mbr.core.ResultsWriter;
16 | import jmh.mbr.core.model.BenchmarkResults;
17 | import jmh.mbr.core.model.BenchmarkResults.BenchmarkResult;
18 | import org.apache.http.Header;
19 | import org.apache.http.HttpHeaders;
20 | import org.apache.http.HttpHost;
21 | import org.apache.http.message.BasicHeader;
22 | import org.elasticsearch.action.index.IndexRequest;
23 | import org.elasticsearch.client.RequestOptions;
24 | import org.elasticsearch.client.RestClient;
25 | import org.elasticsearch.client.RestClientBuilder;
26 | import org.elasticsearch.client.RestHighLevelClient;
27 | import org.elasticsearch.common.xcontent.XContentType;
28 | import org.openjdk.jmh.runner.format.OutputFormat;
29 |
30 | /**
31 | * {@link ResultsWriter} to write {@link BenchmarkResults} to Elasticserarch.
32 | */
33 | public class ElasticsearchResultsWriter implements ResultsWriter {
34 |
35 | private final RestHighLevelClient client;
36 |
37 | public ElasticsearchResultsWriter(String uri) {
38 | this(createClient(ConnectionString.fromUri(uri)));
39 | }
40 |
41 | ElasticsearchResultsWriter(RestHighLevelClient client) {
42 | this.client = client;
43 | }
44 |
45 | @Override
46 | public void write(OutputFormat output, BenchmarkResults results) {
47 | results.forEach(result -> formatAndPublish(output, result));
48 | }
49 |
50 | private void formatAndPublish(OutputFormat output, BenchmarkResult result) {
51 | publishJson(output, result.getMetaData().getProject(), result
52 | .map(JsonResultsFormatter::format));
53 | }
54 |
55 | void publishJson(OutputFormat output, String index, String json) {
56 |
57 | IndexRequest request = new IndexRequest(index);
58 | request.source(json, XContentType.JSON);
59 |
60 | try {
61 | client.index(request, RequestOptions.DEFAULT);
62 | }
63 | catch (IOException e) {
64 | output.println("Write failed: " + e
65 | .getMessage() + " " + StackTraceCapture.from(e));
66 | }
67 | }
68 |
69 | static RestHighLevelClient createClient(ConnectionString connectionString) {
70 |
71 | RestClientBuilder builder = RestClient.builder(connectionString.getHttpHost());
72 |
73 | if (connectionString.hasCredentials()) {
74 | builder.setDefaultHeaders(new Header[] {
75 | new BasicHeader(HttpHeaders.AUTHORIZATION, connectionString
76 | .getBasicAuth())
77 | });
78 | }
79 |
80 | return new RestHighLevelClient(builder);
81 | }
82 |
83 | /**
84 | * elasticsearch://[username]:[password]@[host]:[port]/
85 | */
86 | static class ConnectionString {
87 |
88 | final String host;
89 | final int port;
90 | final String username;
91 | final char[] password;
92 | final boolean ssl;
93 |
94 | ConnectionString(String host, int port, String username, char[] password, boolean ssl) {
95 |
96 | this.host = host;
97 | this.port = port;
98 | this.username = username;
99 | this.password = password;
100 | this.ssl = ssl;
101 | }
102 |
103 | static ConnectionString fromUri(String uri) {
104 |
105 | boolean ssl = isSsl(uri);
106 |
107 | if (!uri.contains("://")) {
108 | return new ConnectionString("localhost", 9200, null, null, ssl);
109 | }
110 |
111 | String authority = uri.substring(uri.indexOf("://") + 3);
112 |
113 | UserPassword upw = UserPassword.from(authority);
114 | HostPort hostPort = HostPort.from(authority);
115 |
116 | return new ConnectionString(hostPort.host, hostPort.port, upw.username, upw.password, ssl);
117 | }
118 |
119 | HttpHost getHttpHost() {
120 | return new HttpHost(this.host, this.port, this.ssl ? "https" : "http");
121 | }
122 |
123 | boolean hasCredentials() {
124 | return this.username != null && this.password != null;
125 | }
126 |
127 | private String getBasicAuth() {
128 |
129 | String credentialsString = this.username + ":" + new String(this.password);
130 | byte[] encodedBytes = Base64.getEncoder()
131 | .encode(credentialsString.getBytes());
132 | return "Basic " + new String(encodedBytes);
133 | }
134 |
135 | private static boolean isSsl(String uri) {
136 | return uri.startsWith("elasticsearchs");
137 | }
138 |
139 | private static class UserPassword {
140 |
141 | final String username;
142 | final char[] password;
143 |
144 | public UserPassword(String username, char[] password) {
145 | this.username = username;
146 | this.password = password;
147 | }
148 |
149 | static UserPassword none() {
150 | return new UserPassword(null, null);
151 | }
152 |
153 | static UserPassword from(String connectionString) {
154 |
155 | if (!connectionString.contains("@")) {
156 | return none();
157 | }
158 |
159 | String[] args = connectionString.split("@");
160 |
161 | if (!args[0].contains(":")) {
162 | return none();
163 | }
164 |
165 | String[] userPwd = args[0].split(":");
166 | return new UserPassword(userPwd[0], userPwd[1].toCharArray());
167 | }
168 | }
169 |
170 | private static class HostPort {
171 |
172 | final String host;
173 | final int port;
174 |
175 | public HostPort(String host, int port) {
176 | this.host = host;
177 | this.port = port;
178 | }
179 |
180 | static HostPort local() {
181 | return new HostPort("localhost", 9200);
182 | }
183 |
184 | static HostPort from(String connectionString) {
185 |
186 | String part = connectionString;
187 |
188 | if (connectionString.contains("@")) {
189 | String[] args = connectionString.split("@");
190 | part = args[1];
191 | }
192 |
193 | if (!part.contains(":")) {
194 | return local();
195 | }
196 |
197 | String[] hostPort = part.split(":");
198 | return new HostPort(hostPort[0], Integer.parseInt(hostPort[1]));
199 | }
200 | }
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/main/java/jmh/mbr/extras/writer/ElasticserachResultsWriterFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2020 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * https://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras.writer;
11 |
12 | import jmh.mbr.core.ResultsWriter;
13 | import jmh.mbr.core.ResultsWriterFactory;
14 |
15 | /**
16 | * {@link ResultsWriterFactory} for Elasticsearch.
17 | * Activated with -Djmh.mbr.report.publishTo=elasticsearch://[username]:[password]@[host]:[port]/
. The index is derived from the project name ({@code jmh.mbr.project}).
18 | *
19 | * @see ElasticsearchResultsWriter
20 | */
21 | public class ElasticserachResultsWriterFactory implements ResultsWriterFactory {
22 |
23 | @Override
24 | public ResultsWriter forUri(String uri) {
25 |
26 | if (uri == null || !uri.startsWith("elasticsearch")) {
27 | return null;
28 | }
29 |
30 | return new ElasticsearchResultsWriter(uri);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/main/java/jmh/mbr/extras/writer/StackTraceCapture.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras.writer;
11 |
12 | import java.io.PrintWriter;
13 | import java.io.StringWriter;
14 |
15 | /**
16 | * Utility to capture a {@link Throwable#getStackTrace() stack trace} to {@link String}.
17 | */
18 | class StackTraceCapture {
19 |
20 | static String from(Throwable throwable) {
21 | StringWriter trace = new StringWriter();
22 | throwable.printStackTrace(new PrintWriter(trace));
23 | return trace.toString();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/main/java/jmh/mbr/extras/writer/SysoutCsvResultsWriter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2020 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras.writer;
11 |
12 | import jmh.mbr.core.ResultsWriter;
13 | import jmh.mbr.core.model.BenchmarkResults;
14 | import org.openjdk.jmh.runner.format.OutputFormat;
15 |
16 | class SysoutCsvResultsWriter implements ResultsWriter {
17 |
18 | private final String uri;
19 |
20 | SysoutCsvResultsWriter(String uri) {
21 | this.uri = uri;
22 | }
23 |
24 | @Override
25 | public void write(OutputFormat output, BenchmarkResults results) {
26 |
27 | try {
28 |
29 | String report = CsvResultsFormatter.createReport(results.getRawResults());
30 | output.println(report);
31 | } catch (Exception e) {
32 | output.println("Report creation failed: " + StackTraceCapture.from(e));
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/main/java/jmh/mbr/extras/writer/SysoutCsvResultsWriterFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras.writer;
11 |
12 | import jmh.mbr.core.ResultsWriter;
13 | import jmh.mbr.core.ResultsWriterFactory;
14 |
15 | /**
16 | * A {@link ResultsWriterFactory} that writes the output in csv format (to the console). Activated with
17 | * -Djmh.mbr.report.publishTo=sysout
.
18 | */
19 | public class SysoutCsvResultsWriterFactory implements ResultsWriterFactory {
20 |
21 | @Override
22 | public ResultsWriter forUri(String uri) {
23 |
24 | if (uri == null || uri.trim().isEmpty() || uri.equals("sysout")) {
25 | return new SysoutCsvResultsWriter(uri);
26 | }
27 |
28 | return null;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/main/resources/META-INF/services/jmh.mbr.core.ResultsWriterFactory:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2019-2020 the original author or authors.
3 | #
4 | # All rights reserved. This program and the accompanying materials are
5 | # made available under the terms of the Eclipse Public License v2.0 which
6 | # accompanies this distribution and is available at
7 | #
8 | # http://www.eclipse.org/legal/epl-v20.html
9 | #
10 | jmh.mbr.extras.writer.CsvResultsWriterFactory
11 | jmh.mbr.extras.writer.SysoutCsvResultsWriterFactory
12 | jmh.mbr.extras.writer.ElasticserachResultsWriterFactory
13 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/test/java/jmh/mbr/extras/RunResultGenerator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * https://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras;
11 |
12 | import java.util.ArrayList;
13 | import java.util.Collection;
14 | import java.util.Collections;
15 | import java.util.Random;
16 | import java.util.TreeSet;
17 | import java.util.concurrent.TimeUnit;
18 |
19 | import org.openjdk.jmh.annotations.Mode;
20 | import org.openjdk.jmh.infra.BenchmarkParams;
21 | import org.openjdk.jmh.infra.IterationParams;
22 | import org.openjdk.jmh.results.BenchmarkResult;
23 | import org.openjdk.jmh.results.IterationResult;
24 | import org.openjdk.jmh.results.ResultRole;
25 | import org.openjdk.jmh.results.RunResult;
26 | import org.openjdk.jmh.results.ThroughputResult;
27 | import org.openjdk.jmh.runner.IterationType;
28 | import org.openjdk.jmh.runner.WorkloadParams;
29 | import org.openjdk.jmh.runner.options.TimeValue;
30 |
31 |
32 | public class RunResultGenerator {
33 |
34 | private static final String JVM_DUMMY = "javadummy";
35 |
36 | private static final String JDK_VERSION_DUMMY = "jdk-11.0.1.jdk";
37 |
38 | private static final String VM_NAME_DUMMY = "DummyVM";
39 |
40 | private static final String VM_VERSION_DUMMY = "4711";
41 |
42 | private static final String JMH_VERSION_DUMMY = "11.0.1+13-LTS";
43 |
44 | public static Collection generate(String name) {
45 |
46 | BenchmarkParams params = params(name);
47 | return generate(params, benchmarkResults(params, 3, 10, 20, 30));
48 | }
49 |
50 | public static Collection generate(BenchmarkParams params, Collection results) {
51 | return Collections.singleton(new RunResult(params, results));
52 | }
53 |
54 |
55 | public static BenchmarkParams params(String name) {
56 |
57 | BenchmarkParams params = new BenchmarkParams(
58 | name+".log",
59 | name + ".benchmark_" + Mode.Throughput,
60 | false,
61 | 1,
62 | new int[]{1},
63 | Collections.emptyList(),
64 |
65 | 1,
66 | 1,
67 | new IterationParams(IterationType.WARMUP, 10, TimeValue.seconds(5), 1),
68 | new IterationParams(IterationType.MEASUREMENT, 10, TimeValue.seconds(10), 1),
69 | Mode.Throughput,
70 | new WorkloadParams(),
71 | TimeUnit.SECONDS, 1,
72 | JVM_DUMMY,
73 | Collections.emptyList(),
74 | JDK_VERSION_DUMMY, VM_NAME_DUMMY, VM_VERSION_DUMMY, JMH_VERSION_DUMMY,
75 | TimeValue.days(1));
76 |
77 | return params;
78 | }
79 |
80 | public static Collection benchmarkResults(BenchmarkParams params, int iterations, Integer... ops) {
81 |
82 | Collection benchmarkResults = new ArrayList<>();
83 | Collection iterationResults = new ArrayList<>(iterations);
84 |
85 | for (int iteration = 0; iteration < iterations; iteration++) {
86 | IterationResult iterationResult = generateIterationResult(iteration, params, ops);
87 | iterationResults.add(iterationResult);
88 | }
89 |
90 | benchmarkResults.add(new BenchmarkResult(params, iterationResults));
91 | return benchmarkResults;
92 | }
93 |
94 | private static IterationResult generateIterationResult(int iteration, BenchmarkParams params, Integer[] ops) {
95 |
96 | IterationResult iterationResult = new IterationResult(params, params.getMeasurement(), null);
97 | for (Integer operations : ops) {
98 | iterationResult.addResult(new ThroughputResult(ResultRole.PRIMARY, params.getBenchmark()+".log", operations, 1000 * 1000, TimeUnit.MILLISECONDS));
99 | }
100 | return iterationResult;
101 | }
102 |
103 |
104 | public static Collection random() {
105 |
106 | Collection results = new TreeSet<>(RunResult.DEFAULT_SORT_COMPARATOR);
107 |
108 | Random r = new Random(12345);
109 | Random ar = new Random(12345);
110 |
111 | for (int b = 0; b < r.nextInt(10); b++) {
112 |
113 | WorkloadParams ps = new WorkloadParams();
114 | ps.put("param0", "value0", 0);
115 | ps.put("param1", "[value1]", 1);
116 | ps.put("param2", "{value2}", 2);
117 | ps.put("param3", "'value3'", 3);
118 | ps.put("param4", "\"value4\"", 4);
119 | BenchmarkParams params = new BenchmarkParams(
120 | "benchmark_" + b,
121 | RunResultGenerator.class.getName() + ".benchmark_" + b + "_" + Mode.Throughput,
122 | false,
123 | r.nextInt(1000),
124 | new int[]{r.nextInt(1000)},
125 | Collections.emptyList(),
126 |
127 | r.nextInt(1000),
128 | r.nextInt(1000),
129 | new IterationParams(IterationType.WARMUP, r.nextInt(1000), TimeValue.seconds(r.nextInt(1000)), 1),
130 | new IterationParams(IterationType.MEASUREMENT, r.nextInt(1000), TimeValue.seconds(r.nextInt(1000)), 1),
131 | Mode.Throughput,
132 | ps,
133 | TimeUnit.SECONDS, 1,
134 | JVM_DUMMY,
135 | Collections.emptyList(),
136 | JDK_VERSION_DUMMY, VM_NAME_DUMMY, VM_VERSION_DUMMY, JMH_VERSION_DUMMY,
137 | TimeValue.days(1));
138 |
139 | Collection benchmarkResults = new ArrayList<>();
140 | for (int f = 0; f < r.nextInt(10); f++) {
141 | Collection iterResults = new ArrayList<>();
142 | for (int c = 0; c < r.nextInt(10); c++) {
143 | IterationResult res = new IterationResult(params, params.getMeasurement(), null);
144 | res.addResult(new ThroughputResult(ResultRole.PRIMARY, "test", r.nextInt(1000), 1000 * 1000, TimeUnit.MILLISECONDS));
145 | res.addResult(new ThroughputResult(ResultRole.SECONDARY, "secondary1", r.nextInt(1000), 1000 * 1000, TimeUnit.MILLISECONDS));
146 | res.addResult(new ThroughputResult(ResultRole.SECONDARY, "secondary2", r.nextInt(1000), 1000 * 1000, TimeUnit.MILLISECONDS));
147 | if (ar.nextBoolean()) {
148 | res.addResult(new ThroughputResult(ResultRole.SECONDARY, "secondary3", ar.nextInt(1000), 1000 * 1000, TimeUnit.MILLISECONDS));
149 | }
150 | iterResults.add(res);
151 | }
152 | benchmarkResults.add(new BenchmarkResult(params, iterResults));
153 | }
154 | results.add(new RunResult(params, benchmarkResults));
155 | }
156 | return results;
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/test/java/jmh/mbr/extras/writer/CsvResultsWriterFactoryTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras.writer;
11 |
12 | import java.io.ByteArrayOutputStream;
13 | import java.io.File;
14 | import java.io.OutputStream;
15 | import java.io.PrintStream;
16 | import java.util.Arrays;
17 | import java.util.Collections;
18 |
19 | import jmh.mbr.core.model.BenchmarkResults;
20 | import jmh.mbr.core.model.BenchmarkResults.MetaData;
21 | import org.junit.jupiter.api.BeforeEach;
22 | import org.junit.jupiter.api.Test;
23 | import org.openjdk.jmh.results.RunResult;
24 | import org.openjdk.jmh.runner.format.OutputFormat;
25 | import org.openjdk.jmh.runner.format.OutputFormatFactory;
26 | import org.openjdk.jmh.runner.options.VerboseMode;
27 |
28 | import static org.assertj.core.api.Assertions.*;
29 |
30 | class CsvResultsWriterFactoryTests {
31 |
32 | private static String TARGET_FILE = "target/result.csv";
33 |
34 | private CsvResultsWriterFactory factory = new CsvResultsWriterFactory();
35 |
36 | @BeforeEach
37 | void init() {
38 | File target = new File(TARGET_FILE);
39 | if (target.exists()) {
40 | assertThat(target.delete()).isTrue();
41 | }
42 | }
43 |
44 | @Test
45 | void validUri() {
46 | assertThat(factory.forUri("csv:target/empty.csv")).isNotNull();
47 | }
48 |
49 | @Test
50 | void writeEmptyResults() {
51 | RunResult runResult = new RunResult(null, Collections.emptyList());
52 | output(runResult);
53 | assertThat(new File(TARGET_FILE)).exists();
54 | }
55 |
56 | private String output(RunResult... runResult) {
57 | OutputStream stream = new ByteArrayOutputStream();
58 | OutputFormat output = OutputFormatFactory
59 | .createFormatInstance(new PrintStream(stream), VerboseMode.NORMAL);
60 | factory.forUri("csv:" + TARGET_FILE).write(output, new BenchmarkResults(MetaData.none(), Arrays.asList(runResult)));
61 | return stream.toString();
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/test/java/jmh/mbr/extras/writer/ElasticsearchResultsWriterFactoryTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * https://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras.writer;
11 |
12 | import static org.assertj.core.api.Assertions.*;
13 |
14 | import org.junit.jupiter.api.Test;
15 |
16 | class ElasticsearchResultsWriterFactoryTests {
17 |
18 | private ElasticserachResultsWriterFactory factory = new ElasticserachResultsWriterFactory();
19 |
20 | @Test
21 | void nullUri() {
22 | assertThat(factory.forUri(null)).isNull();
23 | }
24 |
25 | @Test
26 | void emptyUri() {
27 | assertThat(factory.forUri("")).isNull();
28 | }
29 |
30 | @Test
31 | void elasticsearchEnablesFactory() {
32 | assertThat(factory.forUri("elasticsearch")).isNotNull();
33 | }
34 |
35 | @Test
36 | void elasticsearchWithSslEnablesFactory() {
37 | assertThat(factory.forUri("elasticsearchs")).isNotNull();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/test/java/jmh/mbr/extras/writer/ElasticsearchResultsWriterUnitTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * https://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras.writer;
11 |
12 | import static org.assertj.core.api.Assertions.*;
13 |
14 | import jmh.mbr.extras.writer.ElasticsearchResultsWriter.ConnectionString;
15 | import org.junit.jupiter.api.Test;
16 |
17 | class ElasticsearchResultsWriterUnitTests {
18 |
19 | // todo: test all the escaping paths for usernames containing : and @ but that is furture work
20 |
21 | @Test
22 | void justHostAndPort() {
23 |
24 | ConnectionString connectionString = ElasticsearchResultsWriter.ConnectionString.fromUri("elasticsearch://es-server:666");
25 | assertThat(connectionString.host).isEqualTo("es-server");
26 | assertThat(connectionString.port).isEqualTo(666);
27 | assertThat(connectionString.password).isNull();
28 | assertThat(connectionString.username).isNull();
29 | assertThat(connectionString.ssl).isFalse();
30 | }
31 |
32 | @Test
33 | void justServicename() {
34 |
35 | ConnectionString connectionString = ElasticsearchResultsWriter.ConnectionString.fromUri("elasticsearch");
36 | assertThat(connectionString.host).isEqualTo("localhost");
37 | assertThat(connectionString.port).isEqualTo(9200);
38 | assertThat(connectionString.password).isNull();
39 | assertThat(connectionString.username).isNull();
40 | assertThat(connectionString.ssl).isFalse();
41 | }
42 |
43 | @Test
44 | void withSSL() {
45 |
46 | ConnectionString connectionString = ElasticsearchResultsWriter.ConnectionString.fromUri("elasticsearchs://es-server:666");
47 | assertThat(connectionString.host).isEqualTo("es-server");
48 | assertThat(connectionString.port).isEqualTo(666);
49 | assertThat(connectionString.password).isNull();
50 | assertThat(connectionString.username).isNull();
51 | assertThat(connectionString.ssl).isTrue();
52 | }
53 |
54 | @Test
55 | void withUserPassword() {
56 |
57 | ConnectionString connectionString = ElasticsearchResultsWriter.ConnectionString.fromUri("elasticsearch://es-user:es-pwd@es-host:666");
58 | assertThat(connectionString.host).isEqualTo("es-host");
59 | assertThat(connectionString.port).isEqualTo(666);
60 | assertThat(connectionString.password).isEqualTo("es-pwd".toCharArray());
61 | assertThat(connectionString.username).isEqualTo("es-user");
62 | assertThat(connectionString.ssl).isFalse();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/test/java/jmh/mbr/extras/writer/JsonResultsFormatterUnitTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * https://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras.writer;
11 |
12 | import static org.openjdk.jmh.results.format.ResultFormatType.*;
13 |
14 | import java.io.ByteArrayOutputStream;
15 | import java.io.PrintStream;
16 | import java.io.UnsupportedEncodingException;
17 | import java.nio.charset.StandardCharsets;
18 | import java.util.LinkedHashMap;
19 | import java.util.List;
20 | import java.util.Map;
21 |
22 | import jmh.mbr.core.model.BenchmarkResults;
23 | import jmh.mbr.core.model.BenchmarkResults.MetaData;
24 | import jmh.mbr.extras.RunResultGenerator;
25 | import org.assertj.core.api.Assertions;
26 | import org.junit.jupiter.api.Disabled;
27 | import org.junit.jupiter.api.Test;
28 | import org.openjdk.jmh.results.format.ResultFormatFactory;
29 | import org.openjdk.jmh.results.format.ResultFormatType;
30 |
31 | class JsonResultsFormatterUnitTests {
32 |
33 | @Test
34 | @Disabled
35 | void nativeJson() throws UnsupportedEncodingException {
36 |
37 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
38 | ResultFormatFactory.getInstance(ResultFormatType.JSON, new PrintStream(baos, true, "UTF-8")).writeOut(RunResultGenerator.random());
39 |
40 | String results = new String(baos.toByteArray(), StandardCharsets.UTF_8);
41 | System.out.println("results: " + results);
42 | }
43 |
44 | @Test
45 | @Disabled
46 | void nativeText() throws UnsupportedEncodingException {
47 |
48 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
49 | ResultFormatFactory.getInstance(TEXT, new PrintStream(baos, true, "UTF-8")).writeOut(RunResultGenerator.random());
50 |
51 | String results = new String(baos.toByteArray(), StandardCharsets.UTF_8);
52 | System.out.println("results: " + results);
53 | }
54 |
55 | @Test
56 | void json() {
57 |
58 | MetaData metaData = new MetaData("test-project", "1.0.0.SNAPSHOT");
59 | BenchmarkResults results = new BenchmarkResults(metaData, RunResultGenerator.generate("UnitTest"));
60 |
61 | List json = JsonResultsFormatter.createReport(results);
62 |
63 | json.forEach(result -> {
64 |
65 | Assertions.assertThat(result)
66 | .contains("\"project\" : \"test-project\"")
67 | .contains("\"group\" : \"UnitTest\"")
68 | .contains("\"benchmark\" : \"log\"");
69 | });
70 | }
71 |
72 | @Test
73 | void metadata() {
74 |
75 | Map raw = new LinkedHashMap<>();
76 | raw.put("jmh.mbr.project", "test-project");
77 | raw.put("jmh.mbr.project.version", "1.0.0.SNAPSHOT");
78 | raw.put("jmh.mbr.marker-1", "1-marker");
79 | raw.put("jmh.mbr.marker-2", "2-marker");
80 |
81 | MetaData metaData = MetaData.from(raw);
82 | BenchmarkResults results = new BenchmarkResults(metaData, RunResultGenerator.generate("UnitTest"));
83 |
84 | List json = JsonResultsFormatter.createReport(results);
85 |
86 | json.forEach(result -> {
87 |
88 | Assertions.assertThat(result)
89 | .contains(" \"jmh.mbr.marker-1\" : \"1-marker\",")
90 | .contains("\"jmh.mbr.marker-2\" : \"2-marker\"");
91 | });
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/microbenchmark-runner-extras/src/test/java/jmh/mbr/extras/writer/SysoutResultsWriterFactoryTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.extras.writer;
11 |
12 | import static org.assertj.core.api.Assertions.*;
13 |
14 | import java.io.ByteArrayOutputStream;
15 | import java.io.OutputStream;
16 | import java.io.PrintStream;
17 | import java.util.Arrays;
18 | import java.util.Collection;
19 | import java.util.Collections;
20 | import java.util.concurrent.TimeUnit;
21 |
22 | import jmh.mbr.core.ResultsWriter;
23 | import jmh.mbr.core.model.BenchmarkResults;
24 | import jmh.mbr.core.model.BenchmarkResults.MetaData;
25 | import org.junit.jupiter.api.Test;
26 | import org.openjdk.jmh.annotations.Mode;
27 | import org.openjdk.jmh.infra.BenchmarkParams;
28 | import org.openjdk.jmh.results.AverageTimeResult;
29 | import org.openjdk.jmh.results.BenchmarkResult;
30 | import org.openjdk.jmh.results.IterationResult;
31 | import org.openjdk.jmh.results.ResultRole;
32 | import org.openjdk.jmh.results.RunResult;
33 | import org.openjdk.jmh.runner.WorkloadParams;
34 | import org.openjdk.jmh.runner.format.OutputFormat;
35 | import org.openjdk.jmh.runner.format.OutputFormatFactory;
36 | import org.openjdk.jmh.runner.options.TimeValue;
37 | import org.openjdk.jmh.runner.options.VerboseMode;
38 | import org.openjdk.jmh.util.ScoreFormatter;
39 |
40 | class SysoutResultsWriterFactoryTests {
41 |
42 | private SysoutCsvResultsWriterFactory factory = new SysoutCsvResultsWriterFactory();
43 |
44 | @Test
45 | void emptyUri() {
46 | ResultsWriter writer = factory.forUri(null);
47 | assertThat(writer).isNotNull();
48 | }
49 |
50 | @Test
51 | void sysoutEnablesStdOut() {
52 | ResultsWriter writer = factory.forUri("sysout");
53 | assertThat(writer).isNotNull();
54 | }
55 |
56 | @Test
57 | void noneDisablesStdOut() {
58 | ResultsWriter writer = factory.forUri("none");
59 | assertThat(writer).isNull();
60 | }
61 |
62 | @Test
63 | void writeActualResults() {
64 | BenchmarkParams params = params();
65 | Collection data = Collections
66 | .singletonList(new BenchmarkResult(null, data()));
67 | RunResult runResult = new RunResult(params, data);
68 | String result = output(runResult);
69 | assertThat(result)
70 | .containsSubsequence("class, method, median, mean, range", "Foo, exec");
71 | }
72 |
73 | @Test
74 | void writeParamResult() {
75 | BenchmarkParams params = params("a=b");
76 | Collection data = Collections
77 | .singletonList(new BenchmarkResult(null, data()));
78 | RunResult runResult = new RunResult(params, data);
79 | String result = output(runResult);
80 | assertThat(result)
81 | .containsSubsequence("class, method, a, median, mean, range", "Foo, exec, b");
82 | }
83 |
84 | @Test
85 | void writeSecondaryResult() {
86 | BenchmarkParams params = params("a=b");
87 | Collection data = Collections
88 | .singletonList(new BenchmarkResult(null, data("bar")));
89 | RunResult runResult = new RunResult(params, data);
90 | String result = output(runResult);
91 | assertThat(result)
92 | .containsSubsequence("class, method, a, bar, median, mean, range", "Foo, exec, b");
93 | }
94 |
95 | @Test
96 | void writeMixedParamResults() {
97 | Collection data = Collections
98 | .singletonList(new BenchmarkResult(null, data()));
99 | String result = output(new RunResult(params("a=b"), data), new RunResult(params("a=e", "c=d"), data));
100 | assertThat(result)
101 | .containsSubsequence("class, method, a, c, median, mean, range", "Foo, exec, b, ,", "e, d");
102 | }
103 |
104 | @Test
105 | void writeMixedSecondaryResults() {
106 | Collection data = Collections
107 | .singletonList(new BenchmarkResult(null, data()));
108 | Collection seconds = Collections
109 | .singletonList(new BenchmarkResult(null, data("bar", "spam")));
110 | String result = output(new RunResult(params(), data), new RunResult(params(), seconds));
111 | assertThat(result)
112 | .containsSubsequence("class, method, bar, spam, median, mean, range", "Foo, exec, , ",
113 | "Foo, exec, " + ScoreFormatter.format(1.000));
114 | }
115 |
116 | private BenchmarkParams params(String... workloads) {
117 | WorkloadParams workload = new WorkloadParams();
118 | for (int i = 0; i < workloads.length; i++) {
119 | String pair = workloads[i];
120 | String key = pair;
121 | String value = "";
122 | if (pair.contains("=")) {
123 | key = pair.split("=")[0];
124 | value = pair.split("=")[1].trim();
125 | workload.put(key, value, i);
126 | }
127 | }
128 | return new BenchmarkParams("com.example.Foo.exec", "bar", true, 1, new int[]{1}, Collections
129 | .singletonList("thread"), 1, 0,
130 | null, null, Mode.AverageTime, workload, TimeUnit.MILLISECONDS, 1, "", Collections
131 | .emptyList(), "1.8", "JDK",
132 | "1.8", "1.21", TimeValue.NONE);
133 | }
134 |
135 | private static Collection data(String... seconds) {
136 | IterationResult result = new IterationResult(null, null, null);
137 | result.addResult(new AverageTimeResult(ResultRole.PRIMARY, "foo", 15, 300000000, TimeUnit.MILLISECONDS));
138 | for (String label : seconds) {
139 | result.addResult(new AverageTimeResult(ResultRole.SECONDARY, label, 1, 1000000, TimeUnit.MILLISECONDS));
140 | }
141 | return Collections.singletonList(result);
142 | }
143 |
144 | private String output(RunResult... runResult) {
145 | OutputStream stream = new ByteArrayOutputStream();
146 | OutputFormat output = OutputFormatFactory
147 | .createFormatInstance(new PrintStream(stream), VerboseMode.NORMAL);
148 | factory.forUri("sysout").write(output, new BenchmarkResults(MetaData.none(), Arrays.asList(runResult)));
149 | return stream.toString();
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit4/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | com.github.mp911de.microbenchmark-runner
9 | microbenchmark-runner-parent
10 | 0.6.0.BUILD-SNAPSHOT
11 |
12 |
13 | microbenchmark-runner-junit4
14 |
15 |
16 |
17 |
18 | com.github.mp911de.microbenchmark-runner
19 | microbenchmark-runner-core
20 | ${project.version}
21 |
22 |
23 |
24 | junit
25 | junit
26 |
27 |
28 |
29 | org.openjdk.jmh
30 | jmh-generator-annprocess
31 |
32 |
33 |
34 | org.assertj
35 | assertj-core
36 |
37 |
38 |
39 | org.junit.jupiter
40 | junit-jupiter-api
41 | test
42 |
43 |
44 |
45 | org.junit.jupiter
46 | junit-jupiter-engine
47 | test
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit4/src/test/java/jmh/mbr/junit4/MicrobenchmarkUnitTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.junit4;
11 |
12 | import static org.assertj.core.api.Assertions.*;
13 |
14 | import org.junit.jupiter.api.Test;
15 | import org.junit.runner.Description;
16 | import org.junit.runners.model.InitializationError;
17 |
18 | class MicrobenchmarkUnitTests {
19 |
20 | @Test
21 | void shouldDescribeParametrizedBenchmark() throws InitializationError {
22 |
23 | Microbenchmark runner = new Microbenchmark(ParametrizedBenchmark.class);
24 | Description description = runner.getDescription();
25 |
26 | assertThat(description.getTestClass()).isEqualTo(ParametrizedBenchmark.class);
27 | assertThat(description.getMethodName()).isNull();
28 | assertThat(description.getChildren()).hasSize(2);
29 |
30 | Description fixture = description.getChildren().get(0);
31 |
32 | assertThat(fixture.getTestClass()).isNull();
33 | assertThat(fixture.getMethodName()).isNull();
34 | assertThat(fixture.getDisplayName()).isEqualTo("[foo=a]");
35 | assertThat(fixture.getChildren()).hasSize(1);
36 |
37 | Description method = fixture.getChildren().get(0);
38 |
39 | assertThat(method.getTestClass()).isEqualTo(ParametrizedBenchmark.class);
40 | assertThat(method.getMethodName()).isEqualTo("foo");
41 | }
42 |
43 | @Test
44 | void shouldDescribeSimpleBenchmark() throws InitializationError {
45 |
46 | Microbenchmark runner = new Microbenchmark(SimpleBenchmark.class);
47 | Description description = runner.getDescription();
48 |
49 | assertThat(description.getTestClass()).isEqualTo(SimpleBenchmark.class);
50 | assertThat(description.getMethodName()).isNull();
51 | assertThat(description.getChildren()).hasSize(1);
52 |
53 | Description method = description.getChildren().get(0);
54 |
55 | assertThat(method.getTestClass()).isEqualTo(SimpleBenchmark.class);
56 | assertThat(method.getMethodName()).isEqualTo("foo");
57 | assertThat(method.getChildren()).isEmpty();
58 | }
59 |
60 | @Test
61 | void shouldDescribePartiallyParametrizedBenchmark() throws InitializationError {
62 |
63 | Microbenchmark runner = new Microbenchmark(PartiallyParametrizedBenchmark.class);
64 | Description description = runner.getDescription();
65 |
66 | assertThat(description.getTestClass()).isEqualTo(PartiallyParametrizedBenchmark.class);
67 | assertThat(description.getMethodName()).isNull();
68 | assertThat(description.getChildren()).hasSize(3);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit4/src/test/java/jmh/mbr/junit4/ParametrizedBenchmark.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.junit4;
11 |
12 | import org.junit.runner.RunWith;
13 | import org.openjdk.jmh.annotations.Benchmark;
14 | import org.openjdk.jmh.annotations.Fork;
15 | import org.openjdk.jmh.annotations.Measurement;
16 | import org.openjdk.jmh.annotations.Param;
17 | import org.openjdk.jmh.annotations.Scope;
18 | import org.openjdk.jmh.annotations.State;
19 | import org.openjdk.jmh.annotations.Warmup;
20 |
21 | @Warmup(iterations = 1, time = 1)
22 | @Measurement(iterations = 1, time = 1)
23 | @Fork(value = 1, warmups = 1)
24 | @State(Scope.Benchmark)
25 | @RunWith(Microbenchmark.class)
26 | public class ParametrizedBenchmark {
27 |
28 | @Param({ "a", "b" }) String foo;
29 |
30 | @Benchmark
31 | public void foo() {}
32 | }
33 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit4/src/test/java/jmh/mbr/junit4/PartiallyParametrizedBenchmark.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.junit4;
11 |
12 | import org.junit.runner.RunWith;
13 | import org.openjdk.jmh.annotations.Benchmark;
14 | import org.openjdk.jmh.annotations.Fork;
15 | import org.openjdk.jmh.annotations.Measurement;
16 | import org.openjdk.jmh.annotations.Param;
17 | import org.openjdk.jmh.annotations.Scope;
18 | import org.openjdk.jmh.annotations.State;
19 | import org.openjdk.jmh.annotations.Warmup;
20 |
21 | @Warmup(iterations = 1, time = 1)
22 | @Measurement(iterations = 1, time = 1)
23 | @Fork(value = 1, warmups = 1)
24 | @RunWith(Microbenchmark.class)
25 | public class PartiallyParametrizedBenchmark {
26 |
27 | @State(Scope.Benchmark)
28 | public static class ParamState {
29 | @Param({ "a", "b" }) String foo;
30 | }
31 |
32 | @Benchmark
33 | public void foo() {}
34 |
35 | @Benchmark
36 | public void bar(ParamState paramState) {}
37 | }
38 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit4/src/test/java/jmh/mbr/junit4/SimpleBenchmark.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.junit4;
11 |
12 | import org.junit.runner.RunWith;
13 | import org.openjdk.jmh.annotations.Benchmark;
14 | import org.openjdk.jmh.annotations.Fork;
15 | import org.openjdk.jmh.annotations.Measurement;
16 | import org.openjdk.jmh.annotations.Scope;
17 | import org.openjdk.jmh.annotations.State;
18 | import org.openjdk.jmh.annotations.Warmup;
19 |
20 | @RunWith(Microbenchmark.class)
21 | public class SimpleBenchmark {
22 |
23 | @Benchmark
24 | public void foo() {}
25 | }
26 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit5-smoke-tests/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | microbenchmark-runner-parent
7 | com.github.mp911de.microbenchmark-runner
8 | 0.6.0.BUILD-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | microbenchmark-runner-junit5-smoke-tests
13 |
14 |
15 |
16 | com.github.mp911de.microbenchmark-runner
17 | microbenchmark-runner-junit5
18 | ${project.parent.version}
19 |
20 |
21 | com.github.mp911de.microbenchmark-runner
22 | microbenchmark-runner-extras
23 | ${project.parent.version}
24 |
25 |
26 | org.openjdk.jmh
27 | jmh-generator-annprocess
28 | ${jmh.version}
29 | test
30 |
31 |
32 | org.elasticsearch.client
33 | elasticsearch-rest-high-level-client
34 | 7.5.0
35 | test
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit5-smoke-tests/src/test/java/jmh/mbr/junit5/InnerStateSmokeTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * https://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.junit5;
11 |
12 | import java.util.concurrent.TimeUnit;
13 |
14 | import org.junit.platform.commons.annotation.Testable;
15 | import org.openjdk.jmh.annotations.AuxCounters;
16 | import org.openjdk.jmh.annotations.AuxCounters.Type;
17 | import org.openjdk.jmh.annotations.Benchmark;
18 | import org.openjdk.jmh.annotations.Measurement;
19 | import org.openjdk.jmh.annotations.Param;
20 | import org.openjdk.jmh.annotations.Scope;
21 | import org.openjdk.jmh.annotations.State;
22 | import org.openjdk.jmh.annotations.Warmup;
23 |
24 | @Warmup(iterations = 1, time = 100, timeUnit = TimeUnit.MILLISECONDS)
25 | @Measurement(iterations = 1, time = 100, timeUnit = TimeUnit.MILLISECONDS)
26 | @Microbenchmark
27 | public class InnerStateSmokeTests {
28 |
29 | @Benchmark
30 | @Testable
31 | public double log1p(MainState state) {
32 | return Math.log1p(state.getValue());
33 | }
34 |
35 | @State(Scope.Thread)
36 | @AuxCounters(Type.EVENTS)
37 | public static class MainState {
38 |
39 | public enum Sample {
40 | one, two;
41 | }
42 |
43 | @Param
44 | private Sample sample = Sample.one;
45 |
46 | public double getValue() {
47 | return sample == Sample.one ? Math.PI : Math.E;
48 | }
49 |
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit5-smoke-tests/src/test/java/jmh/mbr/junit5/ResultsWriterSmokeTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019-2020 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * https://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.junit5;
11 |
12 | import java.util.concurrent.TimeUnit;
13 |
14 | import org.junit.platform.commons.annotation.Testable;
15 | import org.openjdk.jmh.annotations.Benchmark;
16 | import org.openjdk.jmh.annotations.Measurement;
17 | import org.openjdk.jmh.annotations.Scope;
18 | import org.openjdk.jmh.annotations.State;
19 | import org.openjdk.jmh.annotations.Warmup;
20 |
21 | @Microbenchmark
22 | @State(Scope.Thread)
23 | public class ResultsWriterSmokeTests {
24 |
25 | double x1 = Math.PI;
26 |
27 | @Benchmark
28 | @Warmup(iterations = 1, time = 100, timeUnit = TimeUnit.MILLISECONDS)
29 | @Measurement(iterations = 1, time = 100, timeUnit = TimeUnit.MILLISECONDS)
30 | @Testable
31 | public double log() {
32 | return Math.log(x1);
33 | }
34 |
35 | @Benchmark
36 | @Warmup(iterations = 1, time = 100, timeUnit = TimeUnit.MILLISECONDS)
37 | @Measurement(iterations = 5, time = 100, timeUnit = TimeUnit.MILLISECONDS)
38 | @Testable
39 | public double log10() {
40 | return Math.log10(x1);
41 | }
42 |
43 | @Benchmark
44 | @Warmup(iterations = 1, time = 100, timeUnit = TimeUnit.MILLISECONDS)
45 | @Measurement(iterations = 5, time = 100, timeUnit = TimeUnit.MILLISECONDS)
46 | @Testable
47 | public double log1p() {
48 | return Math.log1p(x1);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit5/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | com.github.mp911de.microbenchmark-runner
9 | microbenchmark-runner-parent
10 | 0.6.0.BUILD-SNAPSHOT
11 |
12 |
13 | microbenchmark-runner-junit5
14 |
15 |
16 |
17 |
18 | com.github.mp911de.microbenchmark-runner
19 | microbenchmark-runner-core
20 | ${project.version}
21 |
22 |
23 |
24 | org.junit.platform
25 | junit-platform-engine
26 |
27 |
28 |
29 | org.openjdk.jmh
30 | jmh-generator-annprocess
31 |
32 |
33 |
34 | org.assertj
35 | assertj-core
36 |
37 |
38 |
39 | org.junit.jupiter
40 | junit-jupiter-api
41 |
42 |
43 |
44 | org.junit.jupiter
45 | junit-jupiter-engine
46 |
47 |
48 |
49 | org.junit.platform
50 | junit-platform-launcher
51 | test
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/Microbenchmark.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.junit5;
11 |
12 | import java.lang.annotation.Documented;
13 | import java.lang.annotation.ElementType;
14 | import java.lang.annotation.Retention;
15 | import java.lang.annotation.RetentionPolicy;
16 | import java.lang.annotation.Target;
17 |
18 | import org.junit.platform.commons.annotation.Testable;
19 |
20 | /**
21 | * {@code @Microbenchmark} is used to signal that the annotated type is a microbenchmark class that should be
22 | * ran using the Microbenchmark Runner.
23 | *
24 | * Benchmark classes executed with the Microbenchmark Runner can participate in tooling support without the need to
25 | * integrate with JMH-specific tool support.
26 | */
27 | @Retention(RetentionPolicy.SOURCE)
28 | @Target(ElementType.TYPE)
29 | @Documented
30 | @Testable
31 | public @interface Microbenchmark {
32 | }
33 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/MicrobenchmarkEngine.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.junit5;
11 |
12 | import jmh.mbr.junit5.discovery.DiscoverySelectorResolver;
13 | import jmh.mbr.junit5.execution.JmhRunner;
14 |
15 | import java.util.Optional;
16 |
17 | import org.junit.jupiter.engine.config.DefaultJupiterConfiguration;
18 | import org.junit.jupiter.engine.config.JupiterConfiguration;
19 | import org.junit.jupiter.engine.extension.MutableExtensionRegistry;
20 | import org.junit.platform.engine.EngineDiscoveryRequest;
21 | import org.junit.platform.engine.ExecutionRequest;
22 | import org.junit.platform.engine.TestDescriptor;
23 | import org.junit.platform.engine.TestEngine;
24 | import org.junit.platform.engine.UniqueId;
25 |
26 | /**
27 | * Microbenchmark Runner Engine.
28 | */
29 | public class MicrobenchmarkEngine implements TestEngine {
30 |
31 | public static final String ENGINE_ID = "microbenchmark-engine";
32 |
33 | @Override
34 | public String getId() {
35 | return ENGINE_ID;
36 | }
37 |
38 | @Override
39 | public TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId uniqueId) {
40 |
41 | MicrobenchmarkEngineDescriptor engineDescriptor = new MicrobenchmarkEngineDescriptor(uniqueId);
42 | new DiscoverySelectorResolver()
43 | .resolveSelectors(discoveryRequest, engineDescriptor);
44 | return engineDescriptor;
45 | }
46 |
47 | @Override
48 | public void execute(ExecutionRequest request) {
49 |
50 | JupiterConfiguration jupiterConfiguration = new DefaultJupiterConfiguration(request
51 | .getConfigurationParameters(), request.getOutputDirectoryProvider());
52 | MutableExtensionRegistry extensionRegistry = MutableExtensionRegistry
53 | .createRegistryWithDefaultExtensions(jupiterConfiguration);
54 |
55 | JupiterConfiguration configuration = new DefaultJupiterConfiguration(request.getConfigurationParameters(), request.getOutputDirectoryProvider());
56 | new JmhRunner(configuration, extensionRegistry)
57 | .execute(request.getRootTestDescriptor(), request
58 | .getEngineExecutionListener());
59 | }
60 |
61 | @Override
62 | public Optional getGroupId() {
63 | return Optional.of("com.github.mp911de.microbenchmark-runner");
64 | }
65 |
66 | @Override
67 | public Optional getArtifactId() {
68 | return Optional.of("microbenchmark-runner-junit5");
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/MicrobenchmarkEngineDescriptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.junit5;
11 |
12 | import org.junit.platform.engine.UniqueId;
13 | import org.junit.platform.engine.support.descriptor.EngineDescriptor;
14 |
15 | /**
16 | * {@link EngineDescriptor} for Microbenchmark Runner.
17 | */
18 | class MicrobenchmarkEngineDescriptor extends EngineDescriptor {
19 |
20 | MicrobenchmarkEngineDescriptor(UniqueId uniqueId) {
21 | super(uniqueId, "Microbenchmark Runner");
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/descriptor/AbstractBenchmarkDescriptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.junit5.descriptor;
11 |
12 | import java.util.Collections;
13 | import java.util.Set;
14 |
15 | import org.junit.jupiter.api.extension.ExtensionContext;
16 | import org.junit.jupiter.engine.config.JupiterConfiguration;
17 | import org.junit.jupiter.engine.extension.ExtensionRegistry;
18 | import org.junit.jupiter.engine.extension.MutableExtensionRegistry;
19 | import org.junit.platform.engine.EngineExecutionListener;
20 | import org.junit.platform.engine.TestSource;
21 | import org.junit.platform.engine.TestTag;
22 | import org.junit.platform.engine.UniqueId;
23 | import org.junit.platform.engine.support.descriptor.AbstractTestDescriptor;
24 | import org.junit.platform.engine.support.descriptor.ClassSource;
25 | import org.junit.platform.engine.support.descriptor.MethodSource;
26 |
27 | /**
28 | * Abstract base class for Benchmark descriptors. Exposes {@link TestTag tags} and allows contextual {@link org.junit.jupiter.api.extension.Extension} retrieval.
29 | */
30 | public abstract class AbstractBenchmarkDescriptor extends AbstractTestDescriptor {
31 |
32 | private final Set tags;
33 |
34 | /**
35 | * Creates a new {@link AbstractBenchmarkDescriptor} given {@link UniqueId}, {@code displayName} and a {@link TestSource}.
36 | *
37 | * @param uniqueId the {@link UniqueId} for this descriptor.
38 | * @param displayName
39 | * @param source source this descriptor.
40 | */
41 | public AbstractBenchmarkDescriptor(UniqueId uniqueId, String displayName, TestSource source) {
42 | super(uniqueId, displayName, source);
43 |
44 | Set tags = Collections.emptySet();
45 | if (source instanceof ClassSource) {
46 | tags = DescriptorUtils.getTags(((ClassSource) source).getJavaClass());
47 | }
48 | if (source instanceof MethodSource) {
49 | try {
50 | tags = DescriptorUtils
51 | .getTags(Class.forName(((MethodSource) source).getClassName()));
52 | }
53 | catch (ClassNotFoundException e) {
54 | throw new IllegalStateException(e);
55 | }
56 | }
57 |
58 | this.tags = tags;
59 | }
60 |
61 | @Override
62 | public Set getTags() {
63 | return tags;
64 | }
65 |
66 | /**
67 | * Creates a {@link ExtensionContext} for this descriptor containing scoped extensions.
68 | *
69 | * @param parent optional parent {@link ExtensionContext}. {@literal null} to use no parent so the resulting context serves as root {@link ExtensionContext}.
70 | * @param engineExecutionListener the listener.
71 | * @param configuration configuration parameters.
72 | * @return the {@link ExtensionContext} for this descriptor.
73 | */
74 | public abstract ExtensionContext getExtensionContext(ExtensionContext parent, EngineExecutionListener engineExecutionListener, JupiterConfiguration configuration);
75 |
76 | /**
77 | * Creates an {@link MutableExtensionRegistry} that contains extensions derived from the benchmark source (annotations on class/method level).
78 | *
79 | * @param parent the parent {@link MutableExtensionRegistry}.
80 | * @return the {@link ExtensionRegistry} derived from this descriptor.
81 | */
82 | public abstract ExtensionRegistry getExtensionRegistry(MutableExtensionRegistry parent);
83 | }
84 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/descriptor/BenchmarkClassDescriptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.junit5.descriptor;
11 |
12 | import jmh.mbr.core.model.BenchmarkClass;
13 |
14 | import org.junit.jupiter.api.extension.ExtensionContext;
15 | import org.junit.jupiter.engine.config.JupiterConfiguration;
16 | import org.junit.jupiter.engine.extension.ExtensionRegistry;
17 | import org.junit.jupiter.engine.extension.MutableExtensionRegistry;
18 | import org.junit.platform.engine.EngineExecutionListener;
19 | import org.junit.platform.engine.UniqueId;
20 | import org.junit.platform.engine.support.descriptor.ClassSource;
21 |
22 | /**
23 | * {@link org.junit.platform.engine.TestDescriptor} for a {@link BenchmarkClass}.
24 | */
25 | public class BenchmarkClassDescriptor extends AbstractBenchmarkDescriptor {
26 |
27 | private final BenchmarkClass benchmarkClass;
28 |
29 | public BenchmarkClassDescriptor(UniqueId uniqueId, BenchmarkClass benchmarkClass) {
30 |
31 | super(uniqueId, benchmarkClass.getJavaClass().getName(), ClassSource.from(benchmarkClass.getJavaClass()));
32 | this.benchmarkClass = benchmarkClass;
33 | }
34 |
35 | @Override
36 | public Type getType() {
37 | return Type.CONTAINER;
38 | }
39 |
40 | public BenchmarkClass getBenchmarkClass() {
41 | return benchmarkClass;
42 | }
43 |
44 | public Class> getJavaClass() {
45 | return benchmarkClass.getJavaClass();
46 | }
47 |
48 | @Override
49 | public ExtensionContext getExtensionContext(ExtensionContext parent, EngineExecutionListener engineExecutionListener, JupiterConfiguration configuration) {
50 | return new BenchmarkClassExtensionContext(parent, engineExecutionListener, this, configuration);
51 | }
52 |
53 | @Override
54 | public ExtensionRegistry getExtensionRegistry(MutableExtensionRegistry parent) {
55 | return ExtensionUtils.populateNewExtensionRegistryFromExtendWithAnnotation(parent, getJavaClass());
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/microbenchmark-runner-junit5/src/main/java/jmh/mbr/junit5/descriptor/BenchmarkClassExtensionContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-2019 the original author or authors.
3 | *
4 | * All rights reserved. This program and the accompanying materials are
5 | * made available under the terms of the Eclipse Public License v2.0 which
6 | * accompanies this distribution and is available at
7 | *
8 | * http://www.eclipse.org/legal/epl-v20.html
9 | */
10 | package jmh.mbr.junit5.descriptor;
11 |
12 | import java.lang.reflect.AnnotatedElement;
13 | import java.lang.reflect.Method;
14 | import java.util.Collections;
15 | import java.util.List;
16 | import java.util.Optional;
17 |
18 | import org.junit.jupiter.api.TestInstance.Lifecycle;
19 | import org.junit.jupiter.api.extension.ExtensionContext;
20 | import org.junit.jupiter.api.extension.TestInstances;
21 | import org.junit.jupiter.engine.config.JupiterConfiguration;
22 | import org.junit.platform.engine.EngineExecutionListener;
23 | import org.junit.platform.engine.support.hierarchical.Node.ExecutionMode;
24 |
25 | /**
26 | * {@link ExtensionContext} for a {@link BenchmarkClassDescriptor}.
27 | */
28 | class BenchmarkClassExtensionContext extends AbstractExtensionContext {
29 |
30 | BenchmarkClassExtensionContext(ExtensionContext parent, EngineExecutionListener engineExecutionListener, BenchmarkClassDescriptor testDescriptor, JupiterConfiguration configuration) {
31 | super(parent, engineExecutionListener, testDescriptor, configuration);
32 | }
33 |
34 | @Override
35 | public Optional getElement() {
36 | return Optional.of(getBenchmarkDescriptor().getJavaClass());
37 | }
38 |
39 | @Override
40 | public Optional> getTestClass() {
41 | return Optional.of(getBenchmarkDescriptor().getJavaClass());
42 | }
43 |
44 | @Override
45 | public Optional getTestInstanceLifecycle() {
46 | return Optional.empty();
47 | }
48 |
49 | @Override
50 | public Optional