diff --git a/README.md b/README.md index 8e9435a786..9349124bae 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,20 @@ If you had a `jar:test-jar` execution, delete it and add to `properties`: You can configure your plugin to treat every commit as a release candidate. See [Incrementals](https://github.com/jenkinsci/incrementals-tools) for details. +## Running Benchmarks + +To run JMH benchmarks from JUnit tests, you must run you must activate the `benchmark` +profile. For example: +```bash +mvn -Dbenchmark test +``` +When the `benchmark` property is set, no tests apart from JMH benchmarks will be run. +The names of the classes containing the benchmark runners should either begin with or +end with the the word `Benchmark`. For example, `FooBenchmark` and `BenchmarkFoo` will +be detected when using `-Dbenchmark`, however, `FooBar` will be ignored. + +See also: [documentation for JMH benchmarks](https://github.com/jenkinsci/jenkins-test-harness/blob/master/docs/jmh-benchmarks.adoc) + ## Baselines It is handy to be able to select different Jenkins baselines with a Maven profile. diff --git a/pom.xml b/pom.xml index be0def0432..f5d74dbce5 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ ${jenkins.version} ${jenkins.version} - 2.49 + 2.50 3.5 1.17 you-must-override-the-java.level-property @@ -1493,5 +1493,28 @@ + + + jmh-benchmark + + + benchmark + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + **/*Benchmark.java + **/Benchmark*.java + + + + + + diff --git a/src/it/benchmark/invoker.properties b/src/it/benchmark/invoker.properties new file mode 100644 index 0000000000..85dbb8329f --- /dev/null +++ b/src/it/benchmark/invoker.properties @@ -0,0 +1 @@ +invoker.goals=-Dbenchmark clean test diff --git a/src/it/benchmark/pom.xml b/src/it/benchmark/pom.xml new file mode 100644 index 0000000000..e56be8c582 --- /dev/null +++ b/src/it/benchmark/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + + org.jenkins-ci.plugins + plugin + @project.version@ + + + org.jenkins-ci.plugins.its + benchmark-it + 1.0-SNAPSHOT + jar + + 2.60.3 + 8 + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + + + repo.jenkins-ci.org + https://repo.jenkins-ci.org/public/ + + + diff --git a/src/it/benchmark/postbuild.groovy b/src/it/benchmark/postbuild.groovy new file mode 100644 index 0000000000..9e3e2089d9 --- /dev/null +++ b/src/it/benchmark/postbuild.groovy @@ -0,0 +1,3 @@ +// check if the benchmark was run +def file = new File(basedir, 'jmh-report.json') +assert file.exists() diff --git a/src/it/benchmark/src/test/java/benchmark/BenchmarkRunner.java b/src/it/benchmark/src/test/java/benchmark/BenchmarkRunner.java new file mode 100644 index 0000000000..0b6aeda151 --- /dev/null +++ b/src/it/benchmark/src/test/java/benchmark/BenchmarkRunner.java @@ -0,0 +1,32 @@ +package benchmark; + +import jenkins.benchmark.jmh.BenchmarkFinder; +import org.junit.Test; +import org.openjdk.jmh.results.format.ResultFormatType; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.ChainedOptionsBuilder; +import org.openjdk.jmh.runner.options.OptionsBuilder; + +import java.util.concurrent.TimeUnit; + +public class BenchmarkRunner { + @Test + public void runThis() throws Exception { + // number of iterations is kept to a minimum just to verify that the benchmarks work without spending extra + // time during builds. + ChainedOptionsBuilder optionsBuilder = + new OptionsBuilder() + .forks(1) + .warmupIterations(1) + .warmupBatchSize(1) + .measurementIterations(1) + .measurementBatchSize(1) + .shouldFailOnError(true) + .result("jmh-report.json") + .timeUnit(TimeUnit.MICROSECONDS) + .resultFormat(ResultFormatType.JSON); + BenchmarkFinder finder = new BenchmarkFinder(this.getClass().getPackage().getName()); + finder.findBenchmarks(optionsBuilder); + new Runner(optionsBuilder.build()).run(); + } +} diff --git a/src/it/benchmark/src/test/java/benchmark/DontRunMeTest.java b/src/it/benchmark/src/test/java/benchmark/DontRunMeTest.java new file mode 100644 index 0000000000..2dfa2c91c0 --- /dev/null +++ b/src/it/benchmark/src/test/java/benchmark/DontRunMeTest.java @@ -0,0 +1,10 @@ +package benchmark; + +import org.junit.Test; + +public class DontRunMeTest { + @Test + public void dontRunThis() throws Exception { + throw new Exception("Normal tests should not be run with benchmarks."); + } +} diff --git a/src/it/benchmark/src/test/java/benchmark/SampleBenchmark.java b/src/it/benchmark/src/test/java/benchmark/SampleBenchmark.java new file mode 100644 index 0000000000..49e5599fc1 --- /dev/null +++ b/src/it/benchmark/src/test/java/benchmark/SampleBenchmark.java @@ -0,0 +1,18 @@ +package benchmark; + +import jenkins.benchmark.jmh.JmhBenchmark; +import jenkins.benchmark.jmh.JmhBenchmarkState; +import org.openjdk.jmh.annotations.Benchmark; + +import java.io.IOException; + +@JmhBenchmark +public class SampleBenchmark { + public static class MyState extends JmhBenchmarkState { + } + + @Benchmark + public void benchmark(MyState state) throws IOException { + state.getJenkins().setSystemMessage("Hello world"); + } +}