From 2dbf330ec6f581f3e418e233a43bdc6ba3b2774b Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Wed, 15 Dec 2021 09:27:16 +0100 Subject: [PATCH] Setup build benchmark jobs (#80941) Setting up automatic benchmark builds. This PR allows testing impact on build changes on the build performance by comparing the PR source against master and run different scenarios to verify build performance by using the gradle profiler (see https://github.com/gradle/gradle-profiler) they can be triggered by adding the `build-benchmark` GitHub label --- ...ticsearch+pull-request+build-benchmark.yml | 51 +++++++++++ .ci/scripts/install-gradle-profiler.sh | 8 ++ .ci/scripts/run-gradle-profiler.sh | 24 ++++++ build-tools-internal/build.gradle | 10 +++ .../elasticsearch-build-tool-update.scenarios | 86 +++++++++++++++++++ .../elasticsearch.build-complete.gradle | 4 +- 6 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 .ci/jobs.t/elastic+elasticsearch+pull-request+build-benchmark.yml create mode 100755 .ci/scripts/install-gradle-profiler.sh create mode 100755 .ci/scripts/run-gradle-profiler.sh create mode 100644 build-tools-internal/performance/elasticsearch-build-tool-update.scenarios diff --git a/.ci/jobs.t/elastic+elasticsearch+pull-request+build-benchmark.yml b/.ci/jobs.t/elastic+elasticsearch+pull-request+build-benchmark.yml new file mode 100644 index 000000000000..f1db0bb2ad61 --- /dev/null +++ b/.ci/jobs.t/elastic+elasticsearch+pull-request+build-benchmark.yml @@ -0,0 +1,51 @@ +--- +- job: + name: "elastic+elasticsearch+pull-request+build-benchmark" + display-name: "elastic / elasticsearch - pull request build benchmark" + description: "Testing of Elasticsearch pull requests - build benchmark" + workspace: "/dev/shm/elastic+elasticsearch+pull-request+build-bench" + scm: + - git: + refspec: "+refs/pull/${ghprbPullId}/*:refs/remotes/origin/pr/${ghprbPullId}/*" + branches: + - "${ghprbActualCommit}" + properties: + - inject: + properties-content: | + BUILD_PERFORMANCE_TEST=true + COMPOSE_HTTP_TIMEOUT=120 + JOB_BRANCH=%BRANCH% + HOME=$JENKINS_HOME + GRADLEW=./gradlew --parallel --scan --build-cache -Dorg.elasticsearch.build.cache.url=https://gradle-enterprise.elastic.co/cache/ + GRADLEW_BAT=./gradlew.bat --parallel --scan --build-cache -Dorg.elasticsearch.build.cache.url=https://gradle-enterprise.elastic.co/cache/ + triggers: + - github-pull-request: + org-list: + - elastic + allow-whitelist-orgs-as-admins: true + trigger-phrase: '.*run\W+elasticsearch-ci/build-bench.*' + github-hooks: true + status-context: elasticsearch-ci/build-benchmark + cancel-builds-on-update: true + black-list-target-branches: + - 6.8 + excluded-regions: + - ^docs/.* + black-list-labels: + - '>test-mute' + white-list-labels: + - 'build-benchmark' + builders: + - inject: + properties-file: '.ci/java-versions.properties' + properties-content: | + JAVA_HOME=$HOME/.java/$ES_BUILD_JAVA + RUNTIME_JAVA_HOME=$HOME/.java/$ES_RUNTIME_JAVA + JAVA8_HOME=$HOME/.java/java8 + JAVA11_HOME=$HOME/.java/java11 + - shell: | + #!/usr/local/bin/runbld --redirect-stderr + $WORKSPACE/.ci/scripts/run-gradle.sh :build-tools-internal:bootstrapPerformanceTests + $WORKSPACE/.ci/scripts/install-gradle-profiler.sh + $WORKSPACE/.ci/scripts/run-gradle-profiler.sh --benchmark --scenario-file build-tools-internal/build/performanceTests/elasticsearch-build-tool-update.scenarios --project-dir . --output-dir profile-out + tar -czf build/${BUILD_NUMBER}.tar.bz2 profile-out \ No newline at end of file diff --git a/.ci/scripts/install-gradle-profiler.sh b/.ci/scripts/install-gradle-profiler.sh new file mode 100755 index 000000000000..84bde5e11b2b --- /dev/null +++ b/.ci/scripts/install-gradle-profiler.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -e +# profiler version we wanna install +PROFILER_VERSION="0.16.0" +wget https://repo.gradle.org/gradle/ext-releases-local/org/gradle/profiler/gradle-profiler/$PROFILER_VERSION/gradle-profiler-$PROFILER_VERSION.zip -O $WORKSPACE/gradle-profiler-$PROFILER_VERSION.zip +unzip $WORKSPACE/gradle-profiler-$PROFILER_VERSION.zip +mv $WORKSPACE/gradle-profiler-$PROFILER_VERSION $WORKSPACE/gradle-profiler diff --git a/.ci/scripts/run-gradle-profiler.sh b/.ci/scripts/run-gradle-profiler.sh new file mode 100755 index 000000000000..c649c47e079e --- /dev/null +++ b/.ci/scripts/run-gradle-profiler.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# drop page cache and kernel slab objects on linux +[[ -x /usr/local/sbin/drop-caches ]] && sudo /usr/local/sbin/drop-caches +rm -Rfv $WORKSPACE/gradle-user-home +mkdir -p $WORKSPACE/gradle-user-home/init.d && cp -v $WORKSPACE/.ci/init.gradle $WORKSPACE/gradle-user-home +if [ "$(uname -m)" = "arm64" ] || [ "$(uname -m)" = "aarch64" ]; then + MAX_WORKERS=16 +elif [ -f /proc/cpuinfo ]; then + MAX_WORKERS=`grep '^cpu\scores' /proc/cpuinfo | uniq | sed 's/\s\+//g' | cut -d':' -f 2` +else + if [[ "$OSTYPE" == "darwin"* ]]; then + MAX_WORKERS=`sysctl -n hw.physicalcpu | sed 's/\s\+//g'` + else + echo "Unsupported OS Type: $OSTYPE" + exit 1 + fi +fi +if pwd | grep -v -q ^/dev/shm ; then + echo "Not running on a ramdisk, reducing number of workers" + MAX_WORKERS=$(($MAX_WORKERS*2/3)) +fi +set -e +GRADLE_PROFILER="$WORKSPACE/gradle-profiler/bin/gradle-profiler" +$GRADLE_PROFILER "-Dorg.gradle.workers.max=$MAX_WORKERS" $@ \ No newline at end of file diff --git a/build-tools-internal/build.gradle b/build-tools-internal/build.gradle index f58c8683e6fc..3ea3163d1093 100644 --- a/build-tools-internal/build.gradle +++ b/build-tools-internal/build.gradle @@ -6,6 +6,9 @@ * Side Public License, v 1. */ +import org.apache.tools.ant.filters.ReplaceTokens +import org.elasticsearch.gradle.internal.conventions.info.GitInfo + plugins { id 'java-gradle-plugin' id 'groovy-gradle-plugin' @@ -281,3 +284,10 @@ tasks.register("integTest", Test) { } tasks.named("check").configure { dependsOn("integTest") } + +tasks.register("bootstrapPerformanceTests", Copy) { + from('performance') + into('build/performanceTests') + def root = file('..') + filter(ReplaceTokens, tokens: [testGitCommit:GitInfo.gitInfo(root).revision]) +} \ No newline at end of file diff --git a/build-tools-internal/performance/elasticsearch-build-tool-update.scenarios b/build-tools-internal/performance/elasticsearch-build-tool-update.scenarios new file mode 100644 index 000000000000..9bd85cedbaf4 --- /dev/null +++ b/build-tools-internal/performance/elasticsearch-build-tool-update.scenarios @@ -0,0 +1,86 @@ +# Can specify scenarios to use when none are specified on the command line +default-scenarios = ["buildConfiguration_master", "buildConfiguration_branch", "single_project_branch", "single_project_master", "precommit_master", "precommit_branch"] + +buildConfiguration_branch { + title = "configuration phase (@testGitCommit@)" + tasks = ["help"] + gradle-args = ["--no-scan", "--no-build-cache"] + run-using = cli // value can be "cli" or "tooling-api" + daemon = warm // value can be "warm", "cold", or "none" + warm-ups = 5 + iterations = 10 + git-checkout = { + build = "@testGitCommit@" + } +} + +buildConfiguration_master { + title = "configuration phase (master)" + tasks = ["help"] + gradle-args = ["--no-scan", "--no-build-cache"] + run-using = cli // value can be "cli" or "tooling-api" + daemon = warm // value can be "warm", "cold", or "none" + warm-ups = 5 + iterations = 10 + git-checkout = { + build = "master" + } +} + +precommit_branch { + title = "precommit (@testGitCommit@)" + cleanup-tasks = ["clean"] + tasks = ["precommit"] + gradle-args = ["--no-scan", "--no-build-cache"] + run-using = cli // value can be "cli" or "tooling-api" + daemon = warm // value can be "warm", "cold", or "none" + warm-ups = 5 + iterations = 10 + git-checkout = { + build = "@testGitCommit@" + } +} + +precommit_master { + title = "precommit (master)" + cleanup-tasks = ["clean"] + tasks = ["precommit"] + gradle-args = ["--no-scan", "--no-build-cache"] + run-using = cli // value can be "cli" or "tooling-api" + daemon = warm // value can be "warm", "cold", or "none" + warm-ups = 5 + iterations = 10 + git-checkout = { + build = "master" + } +} + +single_project_branch { + title = "single project (@testGitCommit@)" + cleanup-tasks = [":server:clean"] + tasks = [":server:spotlessApply", ":server:precommit"] + gradle-args = ["--no-scan"] + apply-abi-change-to = "server/src/main/java/org/elasticsearch/Build.java" + run-using = cli // value can be "cli" or "tooling-api" + daemon = warm // value can be "warm", "cold", or "none" + warm-ups = 5 + iterations = 10 + git-checkout = { + build = "@testGitCommit@" + } +} + +single_project_master { + title = "single project (master)" + cleanup-tasks = [":server:clean"] + tasks = [":server:spotlessApply", ":server:precommit"] + gradle-args = ["--no-scan"] + apply-abi-change-to = "server/src/main/java/org/elasticsearch/Build.java" + run-using = cli // value can be "cli" or "tooling-api" + daemon = warm // value can be "warm", "cold", or "none" + warm-ups = 5 + iterations = 10 + git-checkout = { + build = "master" + } +} diff --git a/build-tools-internal/src/main/groovy/elasticsearch.build-complete.gradle b/build-tools-internal/src/main/groovy/elasticsearch.build-complete.gradle index 5d0716d5d995..a81a20939723 100644 --- a/build-tools-internal/src/main/groovy/elasticsearch.build-complete.gradle +++ b/build-tools-internal/src/main/groovy/elasticsearch.build-complete.gradle @@ -9,8 +9,8 @@ import java.nio.file.Files String buildNumber = System.getenv('BUILD_NUMBER') - -if (buildNumber) { +String performanceTest = System.getenv('BUILD_PERFORMANCE_TEST') +if (buildNumber && performanceTest != null) { File uploadFile = file("build/${buildNumber}.tar.bz2") project.gradle.buildFinished { result -> println "build complete, generating: $uploadFile"