Quick WA for codenarc outdate
* Quickly switch to internal test solution
* TODO those approach must be refactored and
allighned
* Orig: https://gerrit.mcp.mirantis.com/gitweb?p=mcp-ci/
jenkins-jobs.git;a=blob;f=jenkins-jobs/pipelines/
job-test-codenarc.groovy;h=24f35718ff0e02ef9749d88e3f5b8f2b1d354b5e;hb=refs/heads/master
Change-Id: I1a468a3cfd50bb54dc7b8b1b1f798929c3ec06b0
Bug-related: PROD-26337 (PROD:26337)
diff --git a/test-groovy-pipeline.groovy b/test-groovy-pipeline.groovy
index d00d646..99a9c39 100644
--- a/test-groovy-pipeline.groovy
+++ b/test-groovy-pipeline.groovy
@@ -1,95 +1,173 @@
/**
-* Groovy code testing pipeline
-* CREDENTIALS_ID - gerrit credentials id
-* GRADLE_IMAGE - gradle image name
-* GRADLE_CMD - command(s) for gradle
-*
-**/
+ * Groovy syntax code testing pipeline
+ * CREDENTIALS_ID - gerrit credentials id
+ * GRADLE_IMAGE - gradle image name
+ *
+ **/
-gerrit = new com.mirantis.mk.Gerrit()
common = new com.mirantis.mk.Common()
-def gerritRef
-try {
- gerritRef = GERRIT_REFSPEC
-} catch (MissingPropertyException e) {
- gerritRef = null
+// Guess username for acessing git repo
+String git_user = ''
+if (env.GERRIT_USER) {
+ git_user = "${env.GERRIT_USER}@"
+} else if (env.CREDENTIALS_ID) {
+ def mkCommon = new com.mirantis.mk.Common()
+ def cred = mkCommon.getCredentials(env.CREDENTIALS_ID, 'key')
+ git_user = "${cred.username}@"
}
-def defaultGitRef, defaultGitUrl
-try {
- defaultGitRef = DEFAULT_GIT_REF
- defaultGitUrl = DEFAULT_GIT_URL
-} catch (MissingPropertyException e) {
- defaultGitRef = null
- defaultGitUrl = null
+// Use gerrit parameters if set with fallback to job param
+String git_repo_url = env.GERRIT_HOST ? "${env.GERRIT_SCHEME}://${git_user}${env.GERRIT_HOST}:${env.GERRIT_PORT}/${env.GERRIT_PROJECT}" : env.GIT_URL
+String git_ref = env.GERRIT_REFSPEC ?: env.GIT_REF
+String git_credentials_id = env.CREDENTIALS_ID
+
+String docker_registry = env.DOCKER_REGISTRY ?: 'docker-dev-virtual.docker.mirantis.net'
+String docker_image_name = env.IMAGE_NAME ?: 'mirantis/openstack-ci/jenkins-job-tests:latest'
+
+String slave_label = env.SLAVE_LABEL ?: 'docker'
+
+String docker_image = (docker_registry ? "${docker_registry}/" : '') + "${docker_image_name}"
+
+String gradle_report_dir = 'build/reports/codenarc'
+String gradle_report_path = gradle_report_dir + '/main.*'
+String gradle_log_path = gradle_report_dir + '/main.log'
+
+String jjb_dir = 'jenkins-jobs'
+
+// Make codenarc happy
+String scm_class = 'GitSCM'
+
+String reporting_config = '''
+codenarcMain {
+ reports {
+ text.enabled = true
+ html.enabled = true
+ }
}
-def checkouted = false
-timeout(time: 12, unit: 'HOURS') {
- node("docker"){
- try {
- stage("stop old tests"){
- if (gerritRef) {
- def runningTestBuildNums = _getRunningTriggeredTestsBuildNumbers(env["JOB_NAME"], GERRIT_CHANGE_NUMBER, GERRIT_PATCHSET_NUMBER)
- for(int i=0; i<runningTestBuildNums.size(); i++){
- common.infoMsg("Old test with run number ${runningTestBuildNums[i]} found, stopping")
- Jenkins.instance.getItemByFullName(env["JOB_NAME"]).getBuildByNumber(runningTestBuildNums[i]).finish(hudson.model.Result.ABORTED, new java.io.IOException("Aborting build"));
- }
+'''
+
+// Set current build description
+if (env.GERRIT_CHANGE_URL) {
+ currentBuild.description = """
+ <p>
+ Triggered by change: <a href="${env.GERRIT_CHANGE_URL}">${env.GERRIT_CHANGE_NUMBER},${env.GERRIT_PATCHSET_NUMBER}</a><br/>
+ Project: <b>${env.GERRIT_PROJECT}</b><br/>
+ Branch: <b>${env.GERRIT_BRANCH}</b><br/>
+ Subject: <b>${env.GERRIT_CHANGE_SUBJECT}</b><br/>
+ </p>
+ """
+} else {
+ currentBuild.description = """
+ <p>
+ Triggered manually<br/>
+ Git repository URL: <b>${git_repo_url}</b><br/>
+ Git revision: <b>${git_ref}</b><br/>
+ </p>
+ """
+}
+timeout(time: 1, unit: 'HOURS') {
+ node(slave_label) {
+ // Get & prepare source code
+ stage('SCM checkout') {
+ echo "Checking out git repository from ${git_repo_url} @ ${git_ref}"
+
+ checkout([
+ $class : scm_class,
+ branches : [
+ [name: 'FETCH_HEAD'],
+ ],
+ userRemoteConfigs: [
+ [url: git_repo_url, refspec: git_ref, credentialsId: git_credentials_id],
+ ],
+ extensions : [
+ [$class: 'WipeWorkspace'],
+ ],
+ ])
+
+ echo 'Checking out mcp-ci/jenkins-jobs for default configs'
+ String jjb_repo_url = "${env.DEFAULT_GIT_BASE_URL ?: 'https://gerrit.mcp.mirantis.net'}/mcp-ci/jenkins-jobs"
+ checkout([
+ $class : scm_class,
+ userRemoteConfigs: [
+ [url: jjb_repo_url, credentialsId: env.CREDENTIALS_ID],
+ ],
+ extensions : [
+ [$class: 'RelativeTargetDirectory', relativeTargetDir: jjb_dir]
+ ],
+ ])
+ }
+
+ // Run test
+ stage('CodeNarc') {
+ // Check existence of configuration files and use ones from jenkins-jobs if not exists
+ sh "test -f build.gradle || cp ${jjb_dir}/build.gradle ."
+ sh "test -f codenarcRules.groovy || cp ${jjb_dir}/codenarcRules.groovy ."
+ // Remove not needed anymore jenkins-jobs project
+ dir(jjb_dir) {
+ deleteDir()
}
- }
- stage ('Checkout source code'){
- if (gerritRef) {
- // job is triggered by Gerrit
- checkouted = gerrit.gerritPatchsetCheckout ([
- credentialsId : CREDENTIALS_ID
- ])
- } else if(defaultGitRef && defaultGitUrl) {
- checkouted = gerrit.gerritPatchsetCheckout(defaultGitUrl, defaultGitRef, "HEAD", CREDENTIALS_ID)
- }
- if(!checkouted){
- throw new Exception("Cannot checkout gerrit patchset, GERRIT_REFSPEC and DEFAULT_GIT_REF is null")
- }
- }
- stage ('Run Codenarc tests'){
- if(checkouted){
- def workspace = common.getWorkspace()
- def jenkinsUID = common.getJenkinsUid()
- def jenkinsGID = common.getJenkinsGid()
- def gradle_report = sh (script: "docker run --rm -v ${workspace}:/usr/bin/app:rw -u ${jenkinsUID}:${jenkinsGID} ${GRADLE_IMAGE} ${GRADLE_CMD}", returnStdout: true).trim()
- // Compilation failure doesn't fail the build
- // Check gradle output explicitly
- common.infoMsg(gradle_report)
- if ( gradle_report =~ /Compilation failed/ ) {
- throw new Exception("COMPILATION FAILED!")
+
+ // Force HTML and plain text reports
+ sh "sed -ri '/^\\s*reportFormat\\s*=/ d' build.gradle" // Remove existing report config
+ sh "echo '${reporting_config}' >> build.gradle" // Append new one report configuration
+
+ String userID = sh([script: 'id -u', returnStdout: true]).trim()
+ String docker_args = [
+ '-u root',
+ '-t',
+ '--privileged',
+ "-e 'WORKSPACE=${env.WORKSPACE}'",
+ "-w '${env.WORKSPACE}'",
+ "-v '${env.WORKSPACE}':'${env.WORKSPACE}'",
+ "--name '${env.BUILD_TAG}'",
+ ].join(' ')
+
+ def dockerImage = docker.image(docker_image)
+ dockerImage.pull()
+
+ sh "mkdir -p ${gradle_report_dir}"
+ catchError {
+ dockerImage.withRun(docker_args, '/bin/cat') {
+ sh "docker exec -t -u root ${env.BUILD_TAG} usermod -u ${userID} jenkins"
+ sh "docker exec -t -u jenkins ${env.BUILD_TAG} gradle --no-daemon --info --console=plain --offline check 2>&1 | tee ${gradle_log_path}"
}
- }
- }
+ }
- } catch (Throwable e) {
- currentBuild.result = 'FAILURE'
- try{
- def errLog = readFile('build/reports/codenarc/main.txt')
- if(errLog){
- common.errorMsg("Error log: ${errLog}")
- }
- }catch(ex){
- common.errorMsg("Exception occured while reading codenarc output file", ex)
- }
- throw e
- } finally {
- // send notification
- common.sendNotification(currentBuild.result, "" ,["slack"])
- }
- }
-}
-@NonCPS
-def _getRunningTriggeredTestsBuildNumbers(jobName, gerritChangeNumber, excludePatchsetNumber){
- def gerrit = new com.mirantis.mk.Gerrit()
- def jenkinsUtils = new com.mirantis.mk.JenkinsUtils()
- def triggeredBuilds= gerrit.getGerritTriggeredBuilds(jenkinsUtils.getJobRunningBuilds(jobName), gerritChangeNumber, excludePatchsetNumber)
- def buildNums =[]
- for(int i=0;i<triggeredBuilds.size();i++){
- buildNums.add(triggeredBuilds[i].number)
- }
- return buildNums
+ String gradle_log = readFile([file: gradle_log_path])
+
+ // Don't fail immediately to archive artifacts
+ catchError {
+ // Using pipe without shell option `pipefail` hides errors by the exit status of the latest command
+ // Check gradle output explicitly
+ if (gradle_log ==~ /(?ms).*Build failed with an exception.*/) {
+ error 'TEST FAILED!'
+ }
+
+ // Normally compilation failure doesn't fail the build
+ if (gradle_log ==~ /(?ms).*Compilation failed.*/) {
+ error 'COMPILATION FAILED!'
+ }
+
+ // Fail if there are internal errors
+ if (gradle_log ==~ /(?ms).*Error processing filePath.*/) {
+ error 'ERROR PROCESSING SOME FILE(S)!'
+ }
+ }
+ sh 'cat build/reports/codenarc/main.txt'
+ common.infoMsg("CodeNarc HTML report: ${env.BUILD_URL}artifact/build/reports/codenarc/main.html")
+
+ if (currentBuild.resultIsWorseOrEqualTo('UNSTABLE')) {
+ setGerritReview customUrl: "- ${env.JOB_NAME} ${env.BUILD_URL}artifact/build/reports/codenarc/main.html"
+ }
+ }
+
+ // Save results
+ stage('Record test results') {
+ archiveArtifacts([
+ artifacts : gradle_report_path,
+ allowEmptyArchive: true,
+ ])
+ }
+ }
}