本文首發於:Jenkins 中文社區java
原文連接 做者:abhyudayasharmagit
譯者:Donghui Wanggithub
本文介紹了 Jenkins 插件的微基準測試框架以及如何在插件中運行基準測試web
做爲我 Google 編程夏令營的一部分,我一直致力於改進角色策略插件(Role Strategy Plugin)的性能。 因爲沒有現有的方法來度量性能以及在 Jenkins 插件上作基準測試, 我在項目第一階段的工做是建立一個框架在一個 Jenkins 實例中運行 Jenkins 插件中的基準測試。 爲了讓咱們的工做更容易些,咱們選擇了 Java微基準測試工具來運行這些基準。 這使咱們可以可靠地度量對時間要求嚴格的功能的性能,將有助於讓 Jenkins 爲每一個人更快的運轉。編程
最近在 Jenkins 單元測試工具2.50中發佈了微基準測試框架。 下面的博客文章展現瞭如何在插件中運行基準測試。json
該框架經過爲 JMH 基準的每一個 fork 啓動一個臨時的 Jenkins 實例來運行, 就像 Jenkins 測試工具中的 JenkinsRule
。 基準測試是直接從 JUnit 測試運行的,它容許在運行過程當中失敗構建,而且很容易從 IDE 中運行基準測試,就像單元測試同樣。 你能夠很容易地經過使用 Java 方法或使用 Jenkins plugin:configuration-as-code:[配置即代碼插件]來配置基準並將路徑傳遞到 YAML 文件。bash
要從您的插件運行基準測試,您須要作如下工做:框架
如今,要運行基準測試,您須要有一個包含 [@Test](https://my.oschina.net/azibug)
的基準測試運行程序,以便它能夠像 JUnit 測試同樣運行。 從測試方法內部,能夠使用 JMH 提供的 OptionsBuilder
來配置基準。 例如:ide
public class BenchmarkRunner {
@Test
public void runJmhBenchmarks() throws Exception {
ChainedOptionsBuilder options = new OptionsBuilder()
.mode(Mode.AverageTime)
.forks(2)
.result("jmh-report.json");
// Automatically detect benchmark classes annotated with @JmhBenchmark
new BenchmarkFinder(getClass()).findBenchmarks(options);
new Runner(options.build()).run();
}
}
複製代碼
如今,你能夠編寫第一個基準:函數
@JmhBenchmark
public class JmhStateBenchmark {
public static class MyState extends JmhBenchmarkState {
}
@Benchmark
public void benchmark(MyState state) {
// benchmark code goes here
state.getJenkins().setSystemMessage("Hello world");
}
}
複製代碼
要使用配置即代碼,除了上面的依賴外,還須要在你的 pom.xml
添加以下內容:
<dependency>
<groupId>io.jenkins</groupId>
<artifactId>configuration-as-code</artifactId>
<version>1.21</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.jenkins</groupId>
<artifactId>configuration-as-code</artifactId>
<version>1.21</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
複製代碼
如今配置一個基準很簡單,只需提供 YAML 文件的路徑並指定包含基準狀態的類。
@JmhBenchmark
public class SampleBenchmark {
public static class MyState extends CascJmhBenchmarkState {
@Nonnull
@Override
protected String getResourcePath() {
return "config.yml";
}
@Nonnull
@Override
protected Class<?> getEnclosingClass() {
return SampleBenchmark.class;
}
}
@Benchmark
public void benchmark(MyState state) {
Jenkins jenkins = state.getJenkins(); // jenkins is configured and ready to be benchmarked.
// your benchmark code goes here...
}
}
複製代碼
做爲這個項目的一部分,在角色策略插件(Role Strategy Plugin)中建立了一些基準測試,它們展現了爲各類狀況配置實例。 你能夠在這裏找到它們。
爲了方便從 Maven 運行基準測試,建立了一個 Maven 配置文件來運行基準測試,而且能夠從 Plugin-POM 3.45 版本開始使用。 而後你能夠使用 mvn test -Dbenchmark
從命令行運行基準測試。
若是您的插件託管在 ci.jenkins.io 上,那麼能夠直接從 Jenkinsfile 輕鬆地運行基準測試。 經過在 Jenkinsfile 中的 buildPlugin()
步驟後使用 runBenchmarks()
方法,該步驟如今在 Jenkins 流水線庫。 此函數還接受生成的 JMH 基準報告的路徑做爲可選的參數並存檔基準結果。 在 pull request 構建中運行基準測試容許您不斷地進行測試監視給定更改的性能影響。 例如,來自角色策略插件(Role Strategy Plugin)的 Jenkinsfile :
buildPlugin()
runBenchmarks('jmh-report.json')
複製代碼
能夠使用 plugin:jmh-report[JMH 報告插件]或將基準測試報告傳遞給 JMH 可視化工具 web 服務來可視化生成的基準報告(JSON格式)。 舉個例子,這裏有一些來自角色策略插件(Role Strategy Plugin)中基準測試的可視化報告:
上面所看到的這些改進是經過對插件的一個小的 pull request 得到的,並展現了即便是看起來很小的更改也能夠帶來很大的性能改進。 微基準測試有助於找到這些熱點,並估計更改的影響。
BenchmarkRunner
類名不符合 Maven Surefire 插件的測試條件命名約定,基準測試不會干擾 JUnit 測試。[@Benchmark](https://my.oschina.net/u/3268003)
進行註解,以便 JMH 檢測它們。@JmhBenchmark
時,包含基準的類由 BenchmarkFinder
自動找到。JmhBenchmarkState#getJenkins()
或經過 Jenkins.getInstance()
得到,就像您在其餘狀況下會作的那樣。JmhBenchmarkState
提供了 setup()
和 tearDown()
方法,根據您的基準測試的需求,能夠重寫這些方法來配置 Jenkins 實例。highmem
節點的可用性有限,基於 ci.jenkins.io 的基準測試目前被限流。若是您有任何反饋、評論或問題, 請經過角色策略插件(Role Strategy Plugin) Gitter 聊天室 或經過 Jenkins 開發者郵件列表隨時與我聯繫。