diff --git a/tests/CI/buildAsterisk.sh b/tests/CI/buildAsterisk.sh index fce81fcd81..1e424fae35 100755 --- a/tests/CI/buildAsterisk.sh +++ b/tests/CI/buildAsterisk.sh @@ -38,7 +38,7 @@ common_config_args+=" --with-sounds-cache=/srv/cache/sounds --with-externals-cac common_config_args+=" --enable-dev-mode" export WGET_EXTRA_ARGS="--quiet" -runner ./configure ${common_config_args} CCACHE_DISABLE=1 >tests/CI/output/configure.txt +runner ./configure ${common_config_args} >tests/CI/output/configure.txt runner ${MAKE} menuselect.makeopts diff --git a/tests/CI/gateTestGroups.json b/tests/CI/gateTestGroups.json new file mode 100644 index 0000000000..8c0774a426 --- /dev/null +++ b/tests/CI/gateTestGroups.json @@ -0,0 +1,47 @@ +[ + { + "name": "ari1", + "dir": "tests/CI/output/ari1", + "testcmd": "--test-regex=tests/rest_api/[Ca-d]" + }, + { + "name": "ari2", + "dir": "tests/CI/output/ari2", + "testcmd": "--test-regex=tests/rest_api/[e-z]" + }, + { + "name": "pjsip1", + "dir": "tests/CI/output/pjsip1", + "testcmd": "--test-regex=tests/channels/pjsip/[a-f]" + }, + { + "name": "pjsip2", + "dir": "tests/CI/output/pjsip2", + "testcmd": "--test-regex=tests/channels/pjsip/[g-r]" + }, + { + "name": "pjsip3", + "dir": "tests/CI/output/pjsip3", + "testcmd": "--test-regex=tests/channels/pjsip/[s-z]" + }, + { + "name": "sip1", + "dir": "tests/CI/output/sip1", + "testcmd": "--test-regex=tests/channels/SIP/[Sa-r]" + }, + { + "name": "sip2", + "dir": "tests/CI/output/sip2", + "testcmd": "--test-regex=tests/channels/SIP/[s-z]" + }, + { + "name": "iax2_local", + "dir": "tests/CI/output/iax2_local", + "testcmd": " -t tests/channels/iax2 -t tests/channels/local" + }, + { + "name": "extmwi", + "dir": "tests/CI/output/extmwi", + "testcmd": "--test-regex=tests/channels/pjsip/.*mwi" + } +] diff --git a/tests/CI/gates.jenkinsfile b/tests/CI/gates.jenkinsfile new file mode 100644 index 0000000000..768cf8b66f --- /dev/null +++ b/tests/CI/gates.jenkinsfile @@ -0,0 +1,196 @@ +/* + * This pipeline is the "template" for the Asterisk Gate Tests multi-branch + * parent job. Jenkins will automatically scan the branches in the "asterisk" + * or "Security-asterisk" projects in Gerrit and automatically create a branch- + * specific job for each branch it finds this file in. + * + * This file starts as a declarative pipeline because with a declarative + * pipeline, you can define the trigger in the pipeline file. This keeps + * everything in one place. We transition to scripted pipeline later on because + * we need to dynamically determine which docker image we're going to use and + * you can't do that in a delcarative pipeline. + */ +pipeline { + triggers { + /* + * This trigger will match either the "asterisk" or "Security-asterisk" + * projects. The branch is taken from the branch this job was created + * for. + */ + gerrit customUrl: '', + commentTextParameterMode: 'PLAIN', + commitMessageParameterMode: 'PLAIN', + gerritBuildSuccessfulVerifiedValue: 2, + gerritBuildFailedVerifiedValue: -1, + gerritBuildUnstableVerifiedValue: -1, + gerritProjects: [ + [branches: [[compareType: 'PLAIN', pattern: "${BRANCH_NAME}"]], + compareType: 'REG_EXP', + disableStrictForbiddenFileVerification: false, + pattern: '^(Security-)?asterisk.*' + ] + ], + silentMode: false, + triggerOnEvents: [ + commentAddedContains('^regate$'), + commentAdded(commentAddedTriggerApprovalValue: '+2', verdictCategory: 'Code-Review'), + ], + skipVote: [ + onFailed: false, + onNotBuilt: true, + onSuccessful: false, + onUnstable: false + ] + } + agent { + /* All of the stages need to be performed on a docker host */ + label "swdev-docker" + } + stages { + stage ("->") { + /* + * Jenkins will try to automatically rebuild this job when + * the jenkinsfile changes but since this job is dependent on + * Gerrit, we really don't want to do anything in that case. + */ + when { + not { environment name: 'GERRIT_CHANGE_NUMBER', value: '' } + } + steps { + /* Here's where we switch to scripted pipeline */ + script { + stage ("Checkout") { + /* + * Jenkins has already automatically checked out the base branch + * for this change but we now need to check out the change itself + * and rebase it on the current base branch. If the rebase fails, + * that's an indication to the user that they'll need to sort their + * change out. + * + * The Gerrit Trigger provides all the URLs and refspecs to + * check out the change. + */ + checkout scm: [$class: 'GitSCM', + branches: [[name: env.GERRIT_BRANCH ]], + extensions: [ + [$class: 'CleanBeforeCheckout'], + [$class: 'PreBuildMerge', options: [ + mergeRemote: env.GERRIT_NAME, + mergeTarget: env.GERRIT_BRANCH ] + ], + [$class: 'CloneOption', + noTags: true, + depth: 10, + honorRefspec: true, + shallow: true + ], + [$class: 'BuildChooserSetting', + buildChooser: [$class: 'GerritTriggerBuildChooser'] + ] + ], + userRemoteConfigs: [ + [name: env.GERRIT_NAME, refspec: env.GERRIT_REFSPEC, url: env.GIT_URL ] + ] + ] + } + + def images = env.DOCKER_IMAGES.split(' ') + def r = currentBuild.startTimeInMillis % images.length + def ri = images[(int)r] + def randomImage = env.DOCKER_REGISTRY + "/" + ri + def dockerOptions = "-v /srv/jenkins:/srv/jenkins:rw -v /srv/cache:/srv/cache:rw --entrypoint=''" + + stage ("Build") { + docker.image(randomImage).inside(dockerOptions + " --name ${BUILD_TAG}-build") { + echo 'Building..' + sh './tests/CI/buildAsterisk.sh' + + archiveArtifacts allowEmptyArchive: true, defaultExcludes: false, fingerprint: false, + artifacts: "tests/CI/output/*" + } + } + + def testGroups = readJSON file: "tests/CI/gateTestGroups.json" + def parallelTasks = [ : ] + + for (def testGroup in testGroups) { + /* + * Because each task is a Groovy closure, we need to + * keep local references to some variables. + */ + def groupName = testGroup.name + + parallelTasks[groupName] = { + stage (groupName) { + def groupDir = testGroup.dir + def groupTestcmd = testGroup.testcmd + def testsuiteUrl = env.GIT_URL.replaceAll(/${GERRIT_PROJECT}$/, "testsuite") + + docker.image(randomImage).inside("${dockerOptions} --name ${BUILD_TAG}-${groupName}") { + + lock("${JOB_NAME}.${NODE_NAME}.installer") { + sh 'sudo ./tests/CI/installAsterisk.sh' + } + + checkout scm: [$class: 'GitSCM', + branches: [[name: "${BRANCH_NAME}"]], + extensions: [ + [$class: 'CleanBeforeCheckout'], + [$class: 'RelativeTargetDirectory', relativeTargetDir: groupDir], + [$class: 'CloneOption', + noTags: true, + depth: 10, + honorRefspec: true, + shallow: true + ], + ], + userRemoteConfigs: [[name: env.GERRIT_NAME, url: testsuiteUrl]] + ] + + sh "tests/CI/runTestsuite.sh --testsuite-dir='${groupDir}' --test-command='${groupTestcmd}'" + + archiveArtifacts allowEmptyArchive: true, defaultExcludes: false, fingerprint: true, + artifacts: "${groupDir}**" + + junit testResults: "${groupDir}", + healthScaleFactor: 1.0, + keepLongStdio: true + } + } + } + } + parallel parallelTasks + } + } + } + } + post { + always { + sh "sudo make distclean || : " + sh "sudo rm -rf tests/CI/output || : " + } + /* + * The Gerrit Trigger will automatically post the "Verified" results back + * to Gerrit but the verification publisher publishes extra stuff in the + * "Code Review" section of the review. + */ + success { + gerritverificationpublisher verifyStatusCategory: 'Passed', + verifyStatusURL: '', verifyStatusComment: 'OK', + verifyStatusName: 'Jenkins2', verifyStatusReporter: '', + verifyStatusRerun: 'regate' + } + failure { + gerritverificationpublisher verifyStatusCategory: 'Failed', + verifyStatusURL: '', verifyStatusComment: 'You\'re really screwed', + verifyStatusName: 'Jenkins2', verifyStatusReporter: '', + verifyStatusRerun: 'regate' + } + unstable { + gerritverificationpublisher verifyStatusCategory: 'Failed', + verifyStatusURL: '', verifyStatusComment: 'You\'re screwed', + verifyStatusName: 'Jenkins2', verifyStatusReporter: '', + verifyStatusRerun: 'regate' + } + } +} diff --git a/tests/CI/runTestsuite.sh b/tests/CI/runTestsuite.sh index c96b9a453f..26b09346be 100755 --- a/tests/CI/runTestsuite.sh +++ b/tests/CI/runTestsuite.sh @@ -11,8 +11,6 @@ if [ -f asterisk-test-suite-report.xml ] ; then sudo chown jenkins:users asterisk-test-suite-report.xml fi -runner ${CIDIR}/fixTestResults.py asterisk-test-suite-report.xml asterisk-test-suite-report.xml - if [ -f core* ] ; then echo "*** Found a core file after running unit tests ***" sudo /var/lib/asterisk/scripts/ast_coredumper --no-default-search core*