You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bn...@apache.org on 2022/08/25 19:02:20 UTC
[trafficserver-ci] branch main updated: add autest sharding to pr builds
This is an automated email from the ASF dual-hosted git repository.
bnolsen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/trafficserver-ci.git
The following commit(s) were added to refs/heads/main by this push:
new d78e373 add autest sharding to pr builds
new 2e218c3 Merge pull request #109 from traeak/pr_autest_shards
d78e373 is described below
commit d78e3736fb5ebfa3531b3de27817169a552167b5
Author: Brian Olsen <bn...@gmail.com>
AuthorDate: Wed Aug 24 14:19:12 2022 +0000
add autest sharding to pr builds
---
jenkins/github/autest.pipeline | 255 ++++++++++++----------
jenkins/github/toplevel.pipeline | 449 ++++++++++++++++++++-------------------
2 files changed, 384 insertions(+), 320 deletions(-)
diff --git a/jenkins/github/autest.pipeline b/jenkins/github/autest.pipeline
index 9987b87..f5a5ee0 100644
--- a/jenkins/github/autest.pipeline
+++ b/jenkins/github/autest.pipeline
@@ -1,112 +1,153 @@
pipeline {
- agent {
- docker {
- image 'ci.trafficserver.apache.org/ats/rockylinux:8'
- registryUrl 'https://ci.trafficserver.apache.org/'
- args '--init --cap-add=SYS_PTRACE --network=host -v ${HOME}/ccache:/tmp/ccache:rw'
- label 'docker'
- }
- }
- environment {
- CCACHE_DIR = "/tmp/ccache"
- CCACHE_BASEDIR = "${WORKSPACE}"
- }
- stages {
- stage('Clone') {
- steps {
- dir('src') {
- echo "${sha1}"
- checkout([$class: 'GitSCM',
- branches: [[name: sha1]],
- extensions: [
- // We have to set an idenity for the merge step because Git requires
- // the user.name and user.email to be set to do a merge.
- [$class: "UserIdentity",
- name: "ATS CI User",
- email: "noreply@trafficserver.apache.org"
- ],
- [$class: "PreBuildMerge",
- options: [
- mergeTarget: "${GITHUB_PR_TARGET_BRANCH}",
- fastForwardMode: "NO_FF",
- mergeRemote: "origin",
- mergeStrategy: "DEFAULT"
- ]
- ],
- ],
- userRemoteConfigs: [[url: github_url, refspec: '+refs/pull/*:refs/remotes/origin/pr/*']]])
- sh 'git show -n 10 --decorate --graph --oneline --no-patch'
- }
- echo 'Finished Cloning'
- }
- }
- stage('Build') {
- steps {
- echo 'Starting build'
- dir('src') {
- // For Jenkins debugging. We comit the top of README in our debug PRs.
- sh('head README')
+ agent {
+ docker {
+ image 'ci.trafficserver.apache.org/ats/rockylinux:8'
+ registryUrl 'https://ci.trafficserver.apache.org/'
+ args '--init --cap-add=SYS_PTRACE --network=host -v ${HOME}/ccache:/tmp/ccache:rw'
+ label 'docker'
+ }
+ }
+ environment {
+ CCACHE_DIR = "/tmp/ccache"
+ CCACHE_BASEDIR = "${WORKSPACE}"
+ }
+ stages {
+ stage('Initialization') {
+ steps {
+ script {
+ if (env.AUTEST_SHARD) {
+ String[] arr = env.AUTEST_SHARD.split('of')
+ if (2 == arr.length) {
+ shard = arr[0] as int
+ shardcnt = arr[1] as int
+ if (shard < shardcnt) {
+ env.SHARD = shard
+ env.SHARDCNT = shardcnt
+ }
+ }
+ }
- sh '''#!/bin/bash
-
- set -x
- set -e
- source /opt/rh/gcc-toolset-11/enable
- sudo update-crypto-policies --set LEGACY
+ if (! env.SHARD || ! env.SHARDCNT) {
+ env.SHARD = 0
+ env.SHARDCNT = 0
+ }
+ }
+ }
+ }
+ stage('Clone') {
+ steps {
+ dir('src') {
+ echo "${sha1}"
+ checkout([$class: 'GitSCM',
+ branches: [[name: sha1]],
+ extensions: [
+ // We have to set an idenity for the merge step because Git requires
+ // the user.name and user.email to be set to do a merge.
+ [$class: "UserIdentity",
+ name: "ATS CI User",
+ email: "noreply@trafficserver.apache.org"
+ ],
+ [$class: "PreBuildMerge",
+ options: [
+ mergeTarget: "${GITHUB_PR_TARGET_BRANCH}",
+ fastForwardMode: "NO_FF",
+ mergeRemote: "origin",
+ mergeStrategy: "DEFAULT"
+ ]
+ ],
+ ],
+ userRemoteConfigs: [[url: github_url, refspec: '+refs/pull/*:refs/remotes/origin/pr/*']]])
+ sh 'git show -n 10 --decorate --graph --oneline --no-patch'
+ }
+ echo 'Finished Cloning'
+ }
+ }
+ stage('Build') {
+ steps {
+ echo 'Starting build'
+ dir('src') {
+ // For Jenkins debugging. We comit the top of README in our debug PRs.
+ sh('head README')
- # We want to pick up the OpenSSL-QUIC version of curl in /opt/bin.
- # The HTTP/3 AuTests depend upon this, so update the PATH accordingly.
- export PATH=/opt/bin:${PATH}
+ sh '''#!/bin/bash
+
+ set -x
+ set -e
+ source /opt/rh/gcc-toolset-11/enable
+ sudo update-crypto-policies --set LEGACY
- # Change permissions so that all files are readable
- # (default user umask may change and make these unreadable)
- sudo chmod -R o+r .
- autoreconf -fiv
- ./configure --with-openssl=/opt/openssl-quic --enable-experimental-plugins --enable-example-plugins --prefix=/tmp/ats --enable-werror --enable-debug --enable-wccp --enable-luajit --enable-ccache
- make -j4
- make install
- '''
- }
- }
- }
- stage('AuTest') {
- steps {
- echo 'Starting AuTest'
- dir('src/tests') {
- sh '''
- set +e
- # We want to pick up the OpenSSL-QUIC version of curl in /opt/bin.
- # The HTTP/3 AuTests depend upon this, so update the PATH accordingly.
- export PATH=/opt/bin:${PATH}
-
- export_dir="${WORKSPACE}/output/${GITHUB_PR_NUMBER}"
- mkdir -p ${export_dir}
- ./autest.sh --ats-bin /tmp/ats/bin/ --sandbox /tmp/sandbox || true
- if [ -n "$(ls -A /tmp/sandbox/)" ]; then
- cp -rf /tmp/sandbox/ "${export_dir}"
- ls "${export_dir}"
- sudo chmod -R 777 ${WORKSPACE}
- exit 1
- else
- touch ${export_dir}/No_autest_failures
- sudo chmod -R 777 ${WORKSPACE}
- exit 0
- fi
- '''
- }
- }
- }
- }
-
- post {
- always {
- // We exclude socket files because archiveArtifacts doesn't deal well with
- // their file type.
- archiveArtifacts artifacts: 'output/**/*', fingerprint: false, allowEmptyArchive: true, excludes: '**/*.sock, **/cache.db'
- echo "See the build job description for a link to the sandbox."
- }
- cleanup {
- cleanWs()
- }
- }
+ # We want to pick up the OpenSSL-QUIC version of curl in /opt/bin.
+ # The HTTP/3 AuTests depend upon this, so update the PATH accordingly.
+ export PATH=/opt/bin:${PATH}
+
+ # Change permissions so that all files are readable
+ # (default user umask may change and make these unreadable)
+ sudo chmod -R o+r .
+ autoreconf -fiv
+ ./configure --with-openssl=/opt/openssl-quic --enable-experimental-plugins --enable-example-plugins --prefix=/tmp/ats --enable-werror --enable-debug --enable-wccp --enable-luajit --enable-ccache
+ make -j4
+ make install
+ '''
+ }
+ }
+ }
+ stage('AuTest') {
+ steps {
+ echo 'Starting AuTest'
+ dir('src/tests') {
+ sh '''#!/bin/bash -x
+ set +e
+ # We want to pick up the OpenSSL-QUIC version of curl in /opt/bin.
+ # The HTTP/3 AuTests depend upon this, so update the PATH accordingly.
+ export PATH=/opt/bin:${PATH}
+
+ export_dir="${WORKSPACE}/output/${GITHUB_PR_NUMBER}"
+ mkdir -p ${export_dir}
+
+ if [ ${SHARDCNT} -le 0 ]; then
+ ./autest.sh --ats-bin /tmp/ats/bin/ --sandbox /tmp/sandbox || true
+ else
+ testsall=( $( find . -iname "*.test.py" | awk -F'/' '{print $NF}' | awk -F'.' '{print $1}' ) )
+ testsall=( $(
+ for el in "${testsall[@]}" ; do
+ echo $el
+ done | sort) )
+ ntests=${#testsall[@]}
+
+ shardsize=$((${ntests} / ${SHARDCNT}))
+ [ 0 -ne $((${ntests} % ${shardsize})) ] && shardsize=$((${shardsize} + 1))
+ shardbeg=$((${shardsize} * ${SHARD}))
+ sliced=${testsall[@]:${shardbeg}:${shardsize}}
+ ./autest.sh --ats-bin /tmp/ats/bin/ --sandbox /tmp/sandbox -f ${sliced[@]} || true
+
+ fi
+
+ if [ -n "$(ls -A /tmp/sandbox/)" ]; then
+ touch ${export_dir}/Autest_failures
+ cp -rf /tmp/sandbox/ "${export_dir}"
+ ls "${export_dir}"
+ sudo chmod -R 777 ${WORKSPACE}
+ exit 1
+ else
+ touch ${export_dir}/No_autest_failures
+ sudo chmod -R 777 ${WORKSPACE}
+ exit 0
+ fi
+ '''
+ }
+ }
+ }
+ }
+
+ post {
+ always {
+ // We exclude socket files because archiveArtifacts doesn't deal well with
+ // their file type.
+ archiveArtifacts artifacts: 'output/**/*', fingerprint: false, allowEmptyArchive: true, excludes: '**/*.sock, **/cache.db'
+ echo "See the build job description for a link to the sandbox."
+ }
+ cleanup {
+ cleanWs()
+ }
+ }
}
diff --git a/jenkins/github/toplevel.pipeline b/jenkins/github/toplevel.pipeline
index 626642b..7d3f895 100644
--- a/jenkins/github/toplevel.pipeline
+++ b/jenkins/github/toplevel.pipeline
@@ -1,225 +1,248 @@
TOP_JOB_DESC = "Builds:\\n"
-String buildJob(String ghcontext, String jobName) {
- setGitHubPullRequestStatus(context: ghcontext, message: 'Building', state: 'PENDING')
-
- if (currentBuild.description == null) {
- currentBuild.description = "Builds:<br>"
- }
- currentBuild.displayName = "PR: #${GITHUB_PR_NUMBER} - Build: #${BUILD_NUMBER}"
- https_github_url = GITHUB_REPO_GIT_URL.replace("git://", "https://")
- def jobBuild = build job: jobName, propagate: false, parameters: [string(name: 'SHA1', value: GITHUB_PR_HEAD_SHA), string(name: 'GITHUB_URL', value: https_github_url), string(name: 'GITHUB_PR_NUMBER', value: GITHUB_PR_NUMBER), string(name:'GITHUB_PR_TARGET_BRANCH', value: GITHUB_PR_TARGET_BRANCH)]
- def jobURL = jobBuild.getAbsoluteUrl()
- currentBuild.description += " ${jobName} - <a href=${jobURL}>${jobURL}</a> <br>"
+String buildJob(String ghcontext, String jobName, String shard='') {
+ setGitHubPullRequestStatus(context: ghcontext, message: 'Building', state: 'PENDING')
+
+ if (currentBuild.description == null) {
+ currentBuild.description = "Builds:<br>"
+ }
+ currentBuild.displayName = "PR: #${GITHUB_PR_NUMBER} - Build: #${BUILD_NUMBER}"
+ https_github_url = GITHUB_REPO_GIT_URL.replace("git://", "https://")
- def jobResult = jobBuild.getResult()
+ def parms = [
+ string(name: 'SHA1', value: GITHUB_PR_HEAD_SHA),
+ string(name: 'GITHUB_URL', value: https_github_url),
+ string(name: 'GITHUB_PR_NUMBER', value: GITHUB_PR_NUMBER),
+ string(name: 'GITHUB_PR_TARGET_BRANCH', value: GITHUB_PR_TARGET_BRANCH),
+ ]
- echo "Build of '${jobName}' returned result: ${jobResult}"
+ def displayname = jobName
+ if (shard != '') {
+ parms << string(name: 'AUTEST_SHARD', value: shard)
+ displayname += ' ' + shard
+ }
- if (jobResult == 'SUCCESS') {
- setGitHubPullRequestStatus(context: ghcontext, message: "Success - ${jobURL}", state: jobResult)
- } else {
- //setGitHubPullRequestStatus(context: ghcontext, message: "Failure - ${jobURL}", state: jobResult, targetUrl: "${jobURL}")
- setGitHubPullRequestStatus(context: ghcontext, message: "Failure - ${jobURL}", state: jobResult)
- }
- return jobResult
+ def jobBuild = build job: jobName, propagate: false, parameters: parms
+ def jobURL = jobBuild.getAbsoluteUrl()
+ currentBuild.description += " ${displayname} - <a href=${jobURL}>${jobURL}</a> <br>"
+
+ def jobResult = jobBuild.getResult()
+
+ echo "Build of '${displayname}' returned result: ${jobResult}"
+
+ if (jobResult == 'SUCCESS') {
+ setGitHubPullRequestStatus(context: ghcontext, message: "Success - ${jobURL}", state: jobResult)
+ } else {
+ setGitHubPullRequestStatus(context: ghcontext, message: "Failure - ${jobURL}", state: jobResult)
+ }
+ return jobResult
}
pipeline {
- agent none
-
- stages {
- stage('Quick Checks') {
- parallel {
- stage('Clang-Format') {
- when {
- anyOf {
- environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
- expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*clang-format.*/ }
- }
- }
- steps {
- script {
- echo GITHUB_PR_COMMENT_BODY_MATCH
- result = buildJob('Clang-Format', 'Github_Builds/clang-format')
- if (result == 'FAILURE') {
- error('Clang-Format failed')
- }
- }
- }
- }
- stage('RAT') {
- when {
- anyOf {
- environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
- expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*RAT.*/ }
- }
- }
- steps {
- script {
- result = buildJob('RAT', 'Github_Builds/rat')
- if (result == 'FAILURE') {
- error('RAT failed')
- }
- }
- }
- }
- stage('Docs') {
- when {
- anyOf {
- environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
- expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*docs.*/ }
- }
- }
- steps {
- script {
- result = buildJob('Docs', 'Github_Builds/docs')
- if (result == 'FAILURE') {
- error('Docs failed')
- }
- }
- }
- }
- }
- }
-
-
- stage('Build and Test') {
- parallel {
- stage('Ubuntu Build') {
- when {
- anyOf {
- environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
- expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*ubuntu.*/ }
- }
- }
- steps {
- script {
- result = buildJob('Ubuntu', 'Github_Builds/ubuntu')
- if (result == 'FAILURE') {
- error('Ubuntu build failed')
- }
- }
- }
- }
- stage('Fedora Build') {
- when {
- anyOf {
- environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
- expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*fedora.*/ }
- }
- }
- steps {
- script {
- result = buildJob('Fedora', 'Github_Builds/fedora')
- if (result == 'FAILURE') {
- error('Fedora build failed')
- }
- }
- }
- }
- stage('Debian Build') {
- when {
- anyOf {
- environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
- expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*debian.*/ }
- }
- }
- steps {
- script {
- result = buildJob('Debian', 'Github_Builds/debian')
- if (result == 'FAILURE') {
- error('Debian build failed')
- }
- result = 'SUCCESS'
- }
- }
- }
+ agent none
+
+ stages {
+ stage('Quick Checks') {
+ parallel {
+ stage('Clang-Format') {
+ when {
+ anyOf {
+ environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
+ expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*clang-format.*/ }
+ }
+ }
+ steps {
+ script {
+ echo GITHUB_PR_COMMENT_BODY_MATCH
+ result = buildJob('Clang-Format', 'Github_Builds/clang-format')
+ if (result == 'FAILURE') {
+ error('Clang-Format failed')
+ }
+ }
+ }
+ }
+ stage('RAT') {
+ when {
+ anyOf {
+ environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
+ expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*RAT.*/ }
+ }
+ }
+ steps {
+ script {
+ result = buildJob('RAT', 'Github_Builds/rat')
+ if (result == 'FAILURE') {
+ error('RAT failed')
+ }
+ }
+ }
+ }
+ stage('Docs') {
+ when {
+ anyOf {
+ environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
+ expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*docs.*/ }
+ }
+ }
+ steps {
+ script {
+ result = buildJob('Docs', 'Github_Builds/docs')
+ if (result == 'FAILURE') {
+ error('Docs failed')
+ }
+ }
+ }
+ }
+ }
+ }
+
+ stage('Build and Test') {
+ parallel {
+ stage('Ubuntu Build') {
+ when {
+ anyOf {
+ environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
+ expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*ubuntu.*/ }
+ }
+ }
+ steps {
+ script {
+ result = buildJob('Ubuntu', 'Github_Builds/ubuntu')
+ if (result == 'FAILURE') {
+ error('Ubuntu build failed')
+ }
+ }
+ }
+ }
+ stage('Fedora Build') {
+ when {
+ anyOf {
+ environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
+ expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*fedora.*/ }
+ }
+ }
+ steps {
+ script {
+ result = buildJob('Fedora', 'Github_Builds/fedora')
+ if (result == 'FAILURE') {
+ error('Fedora build failed')
+ }
+ }
+ }
+ }
+ stage('Debian Build') {
+ when {
+ anyOf {
+ environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
+ expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*debian.*/ }
+ }
+ }
+ steps {
+ script {
+ result = buildJob('Debian', 'Github_Builds/debian')
+ if (result == 'FAILURE') {
+ error('Debian build failed')
+ }
+ result = 'SUCCESS'
+ }
+ }
+ }
- stage('Rocky Build') {
- when {
- anyOf {
- environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
- expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*rocky.*/ }
- }
- }
- steps {
- script {
- result = buildJob('Rocky', 'Github_Builds/rocky')
- if (result == 'FAILURE') {
- error('Rocky build failed')
- }
- }
- }
- }
-
- stage('OSX Build') {
- when {
- anyOf {
- environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
- expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*osx.*/ }
- }
- }
- steps {
- script {
- result = buildJob('OSX', 'Github_Builds/osx')
- if (result == 'FAILURE') {
- error('OSX build failed')
- }
- }
- }
- }
+ stage('Rocky Build') {
+ when {
+ anyOf {
+ environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
+ expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*rocky.*/ }
+ }
+ }
+ steps {
+ script {
+ result = buildJob('Rocky', 'Github_Builds/rocky')
+ if (result == 'FAILURE') {
+ error('Rocky build failed')
+ }
+ }
+ }
+ }
+
+ stage('OSX Build') {
+ when {
+ anyOf {
+ environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
+ expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*osx.*/ }
+ }
+ }
+ steps {
+ script {
+ result = buildJob('OSX', 'Github_Builds/osx')
+ if (result == 'FAILURE') {
+ error('OSX build failed')
+ }
+ }
+ }
+ }
- stage('FreeBSD Build') {
- when {
- anyOf {
- environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
- expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*freebsd.*/ }
- }
- }
- steps {
- script {
- result = buildJob('FreeBSD', 'Github_Builds/freebsd')
- if (result == 'FAILURE') {
- error('FreeBSD build failed')
- }
- }
- }
- }
+ stage('FreeBSD Build') {
+ when {
+ anyOf {
+ environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
+ expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*freebsd.*/ }
+ }
+ }
+ steps {
+ script {
+ result = buildJob('FreeBSD', 'Github_Builds/freebsd')
+ if (result == 'FAILURE') {
+ error('FreeBSD build failed')
+ }
+ }
+ }
+ }
- stage('Clang-Analyzer') {
- when {
- anyOf {
- environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
- expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*clang-analyzer.*/ }
- }
- }
- steps {
- script {
- result = buildJob('Clang-Analyzer', 'Github_Builds/clang-analyzer')
- if (result == 'FAILURE') {
- error('Clang-Analyzer failed')
- }
- }
- }
- }
- stage('AuTest') {
- when {
- anyOf {
- environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
- expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*autest.*/ }
- }
- }
- steps {
- script {
- result = buildJob('AuTest', 'Github_Builds/autest')
- if (result == 'FAILURE') {
- error('AuTest failed')
- }
- }
- }
- }
- } // parallel for "Build and Test"
- } // End Stage("Build and Test")
- } // End Stages
+ stage('Clang-Analyzer') {
+ when {
+ anyOf {
+ environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
+ expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*clang-analyzer.*/ }
+ }
+ }
+ steps {
+ script {
+ result = buildJob('Clang-Analyzer', 'Github_Builds/clang-analyzer')
+ if (result == 'FAILURE') {
+ error('Clang-Analyzer failed')
+ }
+ }
+ }
+ }
+ stage('AuTest') {
+ when {
+ anyOf {
+ environment name: 'GITHUB_PR_COMMENT_BODY_MATCH', value: ''
+ expression { GITHUB_PR_COMMENT_BODY_MATCH ==~ /.*autest.*/ }
+ }
+ }
+ steps {
+ script {
+ String jobpath = 'Github_Builds/autest'
+ if (env.AUTEST_SHARDS) {
+ def nshards = env.AUTEST_SHARDS as int
+ def jobs = [:]
+ for (index = 0 ; index < nshards ; index++) {
+ String shard = index + "of" + env.AUTEST_SHARDS
+ jobs[shard] = { buildJob('AuTest ' + shard, jobpath, shard) }
+ }
+ parallel jobs
+ } else {
+ result = buildJob('AuTest', jobpath)
+ if (result == 'FAILURE') {
+ error('AuTest failed')
+ }
+ }
+ }
+ }
+ }
+ } // parallel for "Build and Test"
+ } // End Stage("Build and Test")
+ } // End Stages
}