Skip to content

Commit

Permalink
Changes for adding benchmark compare feature
Browse files Browse the repository at this point in the history
Signed-off-by: Rishabh Singh <[email protected]>
  • Loading branch information
rishabh6788 committed Aug 9, 2024
1 parent b6040a3 commit ed8ce10
Show file tree
Hide file tree
Showing 8 changed files with 383 additions and 16 deletions.
39 changes: 31 additions & 8 deletions jenkins/opensearch/benchmark-pull-request.jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* compatible open source license.
*/

lib = library(identifier: '[email protected].0', retriever: modernSCM([
lib = library(identifier: '[email protected].2', retriever: modernSCM([

$class: 'GitSCMSource',
remote: 'https://github.com/opensearch-project/opensearch-build-libraries.git',
Expand Down Expand Up @@ -158,6 +158,7 @@ pipeline {
genericVariables: [
[key: 'pull_request_number', value: '$.pull_request_number'],
[key: 'repository', value: '$.repository'],
[key: 'baseline_cluster_config', value: '$.baseline_cluster_config'],
[key: 'DISTRIBUTION_URL', value: '$.DISTRIBUTION_URL'],
[key: 'DISTRIBUTION_VERSION', value: '$.DISTRIBUTION_VERSION'],
[key: 'TEST_WORKLOAD', value: '$.TEST_WORKLOAD'],
Expand Down Expand Up @@ -278,9 +279,29 @@ pipeline {
"""
script {
if (currentBuild.rawBuild.getCauses().toString().contains("GenericCause")) {
withCredentials([usernamePassword(credentialsId: 'jenkins-github-bot-token', passwordVariable: 'GITHUB_TOKEN', usernameVariable: 'GITHUB_USER')]) {
def pull_request = Integer.parseInt("${pull_request_number}")
sh ("gh pr comment ${pull_request} --repo ${repository} --body-file final_result_${BUILD_NUMBER}.md")
if ("${pull_request_number}" != '' && "${repository}" != '') {
withCredentials([usernamePassword(credentialsId: 'jenkins-github-bot-token', passwordVariable: 'GITHUB_TOKEN', usernameVariable: 'GITHUB_USER')]) {
def pull_request = Integer.parseInt("${pull_request_number}")
sh ("gh pr comment ${pull_request} --repo ${repository} --body-file final_result_${BUILD_NUMBER}.md")
}
if ("${baseline_cluster_config}" != '') {
Map <String, String> benchmarkTestIds = getCompareBenchmarkIds(
baselineClusterConfig: "${baseline_cluster_config}",
distributionVersion: "${DISTRIBUTION_VERSION}-SNAPSHOT",
workload: "${TEST_WORKLOAD}",
pullRequestNumber: "${pull_request_number}"
)
// Trigger compare-benchmarks job
build job: 'compare-benchmarks',
parameters: [
string(name:'BASELINE_TEST_EXECUTION_ID', value: "${benchmarkTestIds.baseline}"),
string(name:'BASELINE_TEST_EXECUTION_ID', value: "${benchmarkTestIds.contender}"),
string(name:'PULL_REQUEST_NUMBER', value: "${pull_request_number}"),
string(name:'REPOSITORY', value: "${repository}")
],
wait: false,
propagate: false
}
}
}
}
Expand All @@ -290,11 +311,14 @@ pipeline {
failure {
script {
if (currentBuild.rawBuild.getCauses().toString().contains("GenericCause")) {
withCredentials([usernamePassword(credentialsId: 'jenkins-github-bot-token', passwordVariable: 'GITHUB_TOKEN', usernameVariable: 'GITHUB_USER')]) {
def pull_request = Integer.parseInt("${pull_request_number}")
sh ("gh pr comment ${pull_request} --repo ${repository} --body \"The benchmark job ${BUILD_URL} failed.\n Please see logs to debug.\"")
if ("${pull_request_number}" != '' && "${repository}" != '') {
withCredentials([usernamePassword(credentialsId: 'jenkins-github-bot-token', passwordVariable: 'GITHUB_TOKEN', usernameVariable: 'GITHUB_USER')]) {
def pull_request = Integer.parseInt("${pull_request_number}")
sh ("gh pr comment ${pull_request} --repo ${repository} --body \"The benchmark job ${BUILD_URL} failed.\n Please see logs to debug.\"")
}
}
}
postCleanup()
}

}
Expand Down Expand Up @@ -325,7 +349,6 @@ pipeline {
}
}
postCleanup()

}
}
}
Expand Down
102 changes: 102 additions & 0 deletions jenkins/opensearch/compare-benchmarks.jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

lib = library(identifier: '[email protected]', retriever: modernSCM([

$class: 'GitSCMSource',
remote: 'https://github.com/opensearch-project/opensearch-build-libraries.git',
]))

pipeline {
agent { label 'Jenkins-Agent-AL2023-X64-M52xlarge-Benchmark-Test' }
options {
timeout(time: 24, unit: 'HOURS')
buildDiscarder(logRotator(daysToKeepStr: '30'))
throttleJobProperty(
categories: [],
limitOneJobWithMatchingParams: false,
maxConcurrentPerNode: 0,
maxConcurrentTotal: 20,
paramsToUseForLimit: '',
throttleEnabled: true,
throttleOption: 'project',
)
}
environment {
JOB_NAME = 'compare-benchmarks'
}
parameters {
string(
name: 'BASELINE_TEST_EXECUTION_ID',
description: 'opensearch-benchmark test-execution-id for baseline run, sample format: `61a34b4e-4ae4-40b7-9d58-6570b9166f6a`',
trim: true
)
string(
name: 'CONTENDER_TEST_EXECUTION_ID',
description: 'opensearch-benchmark test-execution-id of candidate for comparison, mainly from pull requests.',
trim: true
)
string(
name: 'PULL_REQUEST_NUMBER',
trim: true
)
string(
name: 'REPOSITORY',
defaultValue: 'opensearch-project/OpenSearch'
)
}
stages {
stage('validate-and-set-parameters') {
steps {
script {
if (BASELINE_TEST_EXECUTION_ID == '' || CONTENDER_TEST_EXECUTION_ID == '') {
currentBuild.result = 'ABORTED'
error('Benchmark test failed to start. Please provide BASELINE_TEST_EXECUTION_ID and CONTENDER_TEST_EXECUTION_ID to run the job.')
}
}
}
}
stage('benchmark-pull-request') {
steps {
script {
runBenchmarkTestScript(
command: 'compare',
baseline: "${BASELINE_TEST_EXECUTION_ID}",
contender: "${CONTENDER_TEST_EXECUTION_ID}",
suffix: "${BUILD_NUMBER}"
)
}
}
post {
success {
sh """
echo '<details><summary>Benchmark Baseline Comparison Results</summary>' > temp_result_${BUILD_NUMBER}.md
echo '' >> temp_result_${BUILD_NUMBER}.md
echo '#### Benchmark Results for Job: ${BUILD_URL}' >> temp_result_${BUILD_NUMBER}.md
cat final_result_${BUILD_NUMBER}.md >> temp_result_${BUILD_NUMBER}.md
echo '</details>' >> temp_result_${BUILD_NUMBER}.md
mv temp_result_${BUILD_NUMBER}.md final_result_${BUILD_NUMBER}.md
"""
script {
if ("${PULL_REQUEST_NUMBER}" != '' && "${REPOSITORY}" != '') {
withCredentials([usernamePassword(credentialsId: 'jenkins-github-bot-token', passwordVariable: 'GITHUB_TOKEN', usernameVariable: 'GITHUB_USER')]) {
def pull_request = Integer.parseInt("${PULL_REQUEST_NUMBER}")
sh ("gh pr comment ${pull_request} --repo ${REPOSITORY} --body-file final_result_${BUILD_NUMBER}.md")
}
}
}
postCleanup()
}
failure {
postCleanup()
}
}
}
}
}
2 changes: 1 addition & 1 deletion scripts/benchmark/benchmark-pull-request.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

JENKINS_URL="https://build.ci.opensearch.org"
TRIGGER_TOKEN=$1
PAYLOAD_JSON="{\"pull_request_number\": \"$PR_NUMBER\", \"repository\": \"$REPOSITORY\", \"DISTRIBUTION_URL\": \"$DISTRIBUTION_URL\", \"DISTRIBUTION_VERSION\": \"$OPENSEARCH_VERSION\", \"SECURITY_ENABLED\": \"$SECURITY_ENABLED\", \"SINGLE_NODE_CLUSTER\": \"$SINGLE_NODE_CLUSTER\", \"MIN_DISTRIBUTION\": \"$MIN_DISTRIBUTION\", \"TEST_WORKLOAD\": \"$TEST_WORKLOAD\", \"MANAGER_NODE_COUNT\": \"$MANAGER_NODE_COUNT\", \"DATA_NODE_COUNT\": \"$DATA_NODE_COUNT\", \"DATA_INSTANCE_TYPE\": \"$DATA_INSTANCE_TYPE\", \"DATA_NODE_STORAGE\": \"$DATA_NODE_STORAGE\", \"JVM_SYS_PROPS\": \"$JVM_SYS_PROPS\", \"ADDITIONAL_CONFIG\": \"$ADDITIONAL_CONFIG\", \"USER_TAGS\": \"$USER_TAGS\", \"WORKLOAD_PARAMS\": $WORKLOAD_PARAMS, \"TEST_PROCEDURE\": \"$TEST_PROCEDURE\", \"EXCLUDE_TASKS\": \"$EXCLUDE_TASKS\", \"INCLUDE_TASKS\": \"$INCLUDE_TASKS\", \"CAPTURE_NODE_STAT\": \"$CAPTURE_NODE_STAT\"}"
PAYLOAD_JSON="{\"pull_request_number\": \"$PR_NUMBER\", \"repository\": \"$REPOSITORY\", \"baseline_cluster_config\": \"$BASELINE_CLUSTER_CONFIG\", \"DISTRIBUTION_URL\": \"$DISTRIBUTION_URL\", \"DISTRIBUTION_VERSION\": \"$OPENSEARCH_VERSION\", \"SECURITY_ENABLED\": \"$SECURITY_ENABLED\", \"SINGLE_NODE_CLUSTER\": \"$SINGLE_NODE_CLUSTER\", \"MIN_DISTRIBUTION\": \"$MIN_DISTRIBUTION\", \"TEST_WORKLOAD\": \"$TEST_WORKLOAD\", \"MANAGER_NODE_COUNT\": \"$MANAGER_NODE_COUNT\", \"DATA_NODE_COUNT\": \"$DATA_NODE_COUNT\", \"DATA_INSTANCE_TYPE\": \"$DATA_INSTANCE_TYPE\", \"DATA_NODE_STORAGE\": \"$DATA_NODE_STORAGE\", \"JVM_SYS_PROPS\": \"$JVM_SYS_PROPS\", \"ADDITIONAL_CONFIG\": \"$ADDITIONAL_CONFIG\", \"USER_TAGS\": \"$USER_TAGS\", \"WORKLOAD_PARAMS\": $WORKLOAD_PARAMS, \"TEST_PROCEDURE\": \"$TEST_PROCEDURE\", \"EXCLUDE_TASKS\": \"$EXCLUDE_TASKS\", \"INCLUDE_TASKS\": \"$INCLUDE_TASKS\", \"CAPTURE_NODE_STAT\": \"$CAPTURE_NODE_STAT\"}"
echo "Trigger Jenkins workflows"
JENKINS_REQ=`curl -s -XPOST \
-H "Authorization: Bearer $TRIGGER_TOKEN" \
Expand Down
10 changes: 9 additions & 1 deletion tests/jenkins/TestBenchmarkPullRequest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class TestBenchmarkPullRequest extends BuildPipelineTest {

helper.registerSharedLibrary(
library().name('jenkins')
.defaultVersion('6.8.0')
.defaultVersion('6.8.2')
.allowOverride(true)
.implicit(true)
.targetPath('vars')
Expand Down Expand Up @@ -104,15 +104,22 @@ class TestBenchmarkPullRequest extends BuildPipelineTest {
binding.setVariable('TELEMETRY_PARAMS', '')
binding.setVariable('pull_request_number', '1234')
binding.setVariable('pull_request', 1234)
binding.setVariable('baseline_cluster_config', 'test-cluster-config')
binding.setVariable('repository','opensearch-project/OpenSearch')

helper.registerAllowedMethod("GenericTrigger", [Map], { println 'GenericTrigger called with params: ' + it })
helper.registerAllowedMethod("sh", [Map.class], { map ->
return '{"hits":{"total":{"value":1},"hits":[{"_source":{"test-execution-id":"test-id"}}]}}'
})
}

@Test
public void testBenchmarkPullRequestGenericCause_verifyPipeline() {
binding.getVariable('currentBuild').rawBuild = [:]
binding.getVariable('currentBuild').rawBuild.getCauses = { return "jenkins.branch.GenericCause@123abc" }
helper.registerAllowedMethod('getCompareBenchmarkIds', [Map.class], { params ->
return [baseline: "mockBaseline", contender: "mockContender"]
})

super.testPipeline("jenkins/opensearch/benchmark-pull-request.jenkinsfile",
"tests/jenkins/jenkinsjob-regression-files/opensearch/benchmark-pull-request-generic.jenkinsfile")
Expand Down Expand Up @@ -147,6 +154,7 @@ class TestBenchmarkPullRequest extends BuildPipelineTest {
}
assertThat(testGhCliCommand.size(), equalTo(1))
assertThat(testGhCliCommand, hasItem('gh pr comment 1234 --repo opensearch-project/OpenSearch --body-file final_result_307.md'))
assertCallStack().contains(" benchmark-pull-request.getCompareBenchmarkIds({baselineClusterConfig=test-cluster-config, distributionVersion=3.0.0-SNAPSHOT, workload=nyc-taxis, pullRequestNumber=1234})")
}

@Test
Expand Down
111 changes: 111 additions & 0 deletions tests/jenkins/TestCompareBenchmarks.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

import jenkins.tests.BuildPipelineTest
import org.junit.Before
import org.junit.Test

import static com.lesfurets.jenkins.unit.MethodCall.callArgsToString
import static org.hamcrest.CoreMatchers.equalTo
import static org.hamcrest.CoreMatchers.hasItem
import static org.hamcrest.CoreMatchers.hasItems
import static org.hamcrest.MatcherAssert.assertThat

import static com.lesfurets.jenkins.unit.global.lib.LibraryConfiguration.library
import static com.lesfurets.jenkins.unit.global.lib.GitSource.gitSource

class TestCompareBenchmarks extends BuildPipelineTest {
@Override
@Before
void setUp() {
super.setUp()

helper.registerSharedLibrary(
library().name('jenkins')
.defaultVersion('6.8.2')
.allowOverride(true)
.implicit(true)
.targetPath('vars')
.retriever(gitSource('https://github.com/opensearch-project/opensearch-build-libraries.git'))
.build()
)
helper.registerAllowedMethod("s3Download", [Map])
helper.registerAllowedMethod("uploadTestResults", [Map])
helper.registerAllowedMethod("withAWS", [Map, Closure], {
args,
closure ->
closure.delegate = delegate
return helper.callClosure(closure)
})
helper.registerAllowedMethod('findFiles', [Map.class], null)
helper.registerAllowedMethod("withCredentials", [Map])
helper.registerAllowedMethod("downloadBuildManifest", [Map], {
c -> lib.jenkins.BuildManifest.new(readYaml(file: 'tests/jenkins/data/opensearch-1.3.0-non-security-bundle.yml'))
})
helper.registerAllowedMethod("throttleJobProperty", [Map])

binding.setVariable('AGENT_LABEL', 'Jenkins-Agent-AL2-X64-M52xlarge-Docker-Host-Benchmark-Test')
binding.setVariable('ARCHITECTURE', 'x64')
binding.setVariable('ARTIFACT_BUCKET_NAME', 'test_bucket')
binding.setVariable('ARTIFACT_DOWNLOAD_ROLE_NAME', 'Dummy_Download_Role')
binding.setVariable('AWS_ACCOUNT_PUBLIC', 'dummy_account')
binding.setVariable('env', ['BUILD_NUMBER': '307'])
binding.setVariable('BUILD_URL', 'test://artifact.url')
binding.setVariable('BUILD_NUMBER', '307')
binding.setVariable('JOB_NAME', 'compare-benchmarks')
binding.setVariable('BENCHMARK_TEST_CONFIG_LOCATION', 'test_config')
binding.setVariable('PULL_REQUEST_NUMBER', '1234')
binding.setVariable('pull_request', 1234)
binding.setVariable('REPOSITORY','opensearch-project/OpenSearch')
binding.setVariable('BASELINE_TEST_EXECUTION_ID', 'baseline-id')
binding.setVariable('CONTENDER_TEST_EXECUTION_ID', 'contender-id')
}

@Test
public void testCompareBenchmark_verifyPipeline() {

super.testPipeline("jenkins/opensearch/compare-benchmarks.jenkinsfile",
"tests/jenkins/jenkinsjob-regression-files/opensearch/compare-benchmarks.jenkinsfile")
}

@Test
void testCompareBenchmark_verifyScriptExecutions() {
runScript("jenkins/opensearch/compare-benchmarks.jenkinsfile")

def testScriptCommands = getCommandExecutions('sh', './test.sh').findAll {
shCommand -> shCommand.contains('./test.sh')
}
assertThat(testScriptCommands.size(), equalTo(1))
assertThat(testScriptCommands, hasItems("set +x && ./test.sh benchmark-test compare baseline-id contender-id --benchmark-config /tmp/workspace/benchmark.ini --suffix 307"))

def testGhCliCommand = getCommandExecutions('sh', 'gh').findAll {
shCommand -> shCommand.contains('gh')
}
assertThat(testGhCliCommand.size(), equalTo(1))
assertThat(testGhCliCommand, hasItem('gh pr comment 1234 --repo opensearch-project/OpenSearch --body-file final_result_307.md'))
assertCallStack().contains("compare-benchmarks.runBenchmarkTestScript({command=compare, baseline=baseline-id, contender=contender-id, suffix=307})")
}

def getCommandExecutions(methodName, command) {
def shCommands = helper.callStack.findAll {
call ->
call.methodName == methodName
}.
collect {
call ->
callArgsToString(call)
}.findAll {
shCommand ->
shCommand.contains(command)
}

return shCommands
}

}
Loading

0 comments on commit ed8ce10

Please sign in to comment.