blob: b499db18504c3863086eaf42f542de5a137d9def [file] [log] [blame]
Denis Egorenko358a4fc2018-11-27 17:57:22 +04001/*
Denis Egorenko86164872018-12-10 17:34:46 +04002 Global CI wrapper for testing next projects:
Denis Egorenko358a4fc2018-11-27 17:57:22 +04003 - salt-models/reclass-system
4 - mk/cookiecutter-templates
Denis Egorenkod71aaa02018-12-11 16:03:37 +04005
6 Wrapper allows to test cross-project patches, based on
7 'Depends-On: http://<gerrit_address>/<change_number>' key phrase
Denis Egorenko358a4fc2018-11-27 17:57:22 +04008 */
9
10import groovy.json.JsonOutput
Denis Egorenko6c325112018-12-05 19:58:34 +040011gerrit = new com.mirantis.mk.Gerrit()
Denis Egorenko358a4fc2018-11-27 17:57:22 +040012
13cookiecutterTemplatesRepo='mk/cookiecutter-templates'
14reclassSystemRepo='salt-models/reclass-system'
Denis Egorenko6c6b08e2018-12-13 13:23:43 +040015slaveNode = env.getProperty('SLAVE_NODE') ?: 'virtual'
Denis Egorenko358a4fc2018-11-27 17:57:22 +040016
Denis Egorenko76a0be82018-12-04 13:36:07 +040017voteMatrix = [
18 'test-mk-cookiecutter-templates': true,
19 'test-drivetrain': true,
20 'oscore-test-cookiecutter-models': false,
21 'test-salt-model-infra': true,
Denis Egorenko43d31dc2019-01-28 19:58:17 +040022 'test-salt-model-mcp-virtual-lab': false,
Denis Egorenko76a0be82018-12-04 13:36:07 +040023]
24
Denis Egorenko6c325112018-12-05 19:58:34 +040025baseGerritConfig = [:]
Denis Egorenkod71aaa02018-12-11 16:03:37 +040026buildTestParams = [:]
Denis Egorenkof4d3f522018-12-06 16:33:11 +040027jobResultComments = [:]
28commentLock = false
Denis Egorenko6c325112018-12-05 19:58:34 +040029
Denis Egorenko86164872018-12-10 17:34:46 +040030// post Gerrit review comment to patch
31def setGerritReviewComment() {
Denis Egorenko6c325112018-12-05 19:58:34 +040032 if (baseGerritConfig) {
Denis Egorenko42ea6612019-01-31 18:00:25 +040033 while (commentLock) {
Denis Egorenkof4d3f522018-12-06 16:33:11 +040034 sleep 5
35 }
36 commentLock = true
Denis Egorenko6c325112018-12-05 19:58:34 +040037 LinkedHashMap config = baseGerritConfig.clone()
Denis Egorenkof4d3f522018-12-06 16:33:11 +040038 String jobResultComment = ''
Denis Egorenko42ea6612019-01-31 18:00:25 +040039 jobResultComments.each { threadName, info ->
40 String skipped = voteMatrix.get(info.job, 'true') ? '' : '(non-voting)'
41 jobResultComment += "- ${threadName} ${info.url}console : ${info.status} ${skipped}".trim() + '\n'
Denis Egorenkof4d3f522018-12-06 16:33:11 +040042 }
43 config['message'] = sh(script: "echo '${jobResultComment}'", returnStdout: true).trim()
Denis Egorenko6c325112018-12-05 19:58:34 +040044 gerrit.postGerritComment(config)
Denis Egorenkof4d3f522018-12-06 16:33:11 +040045 commentLock = false
Denis Egorenko6c325112018-12-05 19:58:34 +040046 }
Denis Egorenko76a0be82018-12-04 13:36:07 +040047}
48
Denis Egorenko86164872018-12-10 17:34:46 +040049// get job parameters for YAML-based job parametrization
50def yamlJobParameters(LinkedHashMap jobParams) {
51 return [
52 [$class: 'TextParameterValue', name: 'EXTRA_VARIABLES_YAML', value: JsonOutput.toJson(jobParams) ]
53 ]
54}
55
56// run needed job with params
Denis Egorenko42ea6612019-01-31 18:00:25 +040057def runTests(String jobName, ArrayList jobParams, String threadName = '') {
58 threadName = threadName ? threadName : jobName
Denis Egorenko76a0be82018-12-04 13:36:07 +040059 def propagateStatus = voteMatrix.get(jobName, true)
Denis Egorenko358a4fc2018-11-27 17:57:22 +040060 return {
Denis Egorenko86164872018-12-10 17:34:46 +040061 def jobBuild = build job: jobName, propagate: false, parameters: jobParams
Denis Egorenko42ea6612019-01-31 18:00:25 +040062 jobResultComments[threadName] = [ 'url': jobBuild.absoluteUrl, 'status': jobBuild.result, 'job': jobName ]
Denis Egorenkof4d3f522018-12-06 16:33:11 +040063 setGerritReviewComment()
Denis Egorenko76a0be82018-12-04 13:36:07 +040064 if (propagateStatus && jobBuild.result == 'FAILURE') {
Denis Egorenko42ea6612019-01-31 18:00:25 +040065 throw new Exception("Build ${threadName} is failed!")
Denis Egorenko358a4fc2018-11-27 17:57:22 +040066 }
67 }
68}
69
Denis Egorenkod71aaa02018-12-11 16:03:37 +040070// set params based on depending patches
71def setupDependingVars(LinkedHashMap dependingProjects) {
72 if (dependingProjects) {
73 if (dependingProjects.containsKey(reclassSystemRepo)) {
74 buildTestParams['RECLASS_SYSTEM_GIT_REF'] = dependingProjects[reclassSystemRepo].ref
75 buildTestParams['RECLASS_SYSTEM_BRANCH'] = dependingProjects[reclassSystemRepo].branch
76 }
77 if (dependingProjects.containsKey(cookiecutterTemplatesRepo)) {
78 buildTestParams['COOKIECUTTER_TEMPLATE_REF'] = dependingProjects[cookiecutterTemplatesRepo].ref
79 buildTestParams['COOKIECUTTER_TEMPLATE_BRANCH'] = dependingProjects[cookiecutterTemplatesRepo].branch
80 }
81 }
82}
83
Denis Egorenko358a4fc2018-11-27 17:57:22 +040084timeout(time: 12, unit: 'HOURS') {
85 node(slaveNode) {
86 def common = new com.mirantis.mk.Common()
Denis Egorenko358a4fc2018-11-27 17:57:22 +040087
Denis Egorenko28f8c812018-12-10 16:06:37 +040088 // Var EXTRA_VARIABLES_YAML contains any additional parameters for tests,
Denis Egorenko358a4fc2018-11-27 17:57:22 +040089 // like manually specified Gerrit Refs/URLs, additional parameters and so on
Denis Egorenko28f8c812018-12-10 16:06:37 +040090 def buildTestParamsYaml = env.getProperty('EXTRA_VARIABLES_YAML')
Denis Egorenko76a0be82018-12-04 13:36:07 +040091 if (buildTestParamsYaml) {
92 common.mergeEnv(env, buildTestParamsYaml)
93 buildTestParams = readYaml text: buildTestParamsYaml
Denis Egorenko358a4fc2018-11-27 17:57:22 +040094 }
95
96 // init required job variables
97 LinkedHashMap job_env = env.getEnvironment().findAll { k, v -> v }
98
99 // Gerrit parameters
100 String gerritCredentials = job_env.get('CREDENTIALS_ID', 'gerrit')
Denis Egorenko86164872018-12-10 17:34:46 +0400101 String gerritRef = job_env.get('GERRIT_REFSPEC')
102 String gerritProject = job_env.get('GERRIT_PROJECT')
103 String gerritName = job_env.get('GERRIT_NAME')
104 String gerritScheme = job_env.get('GERRIT_SCHEME')
105 String gerritHost = job_env.get('GERRIT_HOST')
106 String gerritPort = job_env.get('GERRIT_PORT')
107 String gerritChangeNumber = job_env.get('GERRIT_CHANGE_NUMBER')
108 String gerritPatchSetNumber = job_env.get('GERRIT_PATCHSET_NUMBER')
109 String gerritBranch = job_env.get('GERRIT_BRANCH')
Denis Egorenkoe581f9e2018-12-11 18:56:14 +0400110 Boolean gateMode = job_env.get('GERRIT_CI_MERGE_TRIGGER', false).toBoolean()
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400111
112 // Common and manual build parameters
113 LinkedHashMap projectsMap = [:]
Denis Egorenko86164872018-12-10 17:34:46 +0400114 String distribRevision = 'nightly'
115 //checking if the branch is from release
116 if (gerritBranch.startsWith('release')) {
117 def distribRevisionRelease = gerritBranch.tokenize('/')[-1]
118 if (!common.checkRemoteBinary([apt_mk_version: distribRevisionRelease]).linux_system_repo_url) {
119 common.infoMsg("Binary release ${distribRevisionRelease} does not exist on http://mirror.mirantis.com. Falling back to 'proposed'.")
120 distribRevision = 'proposed'
121 }
122 distribRevision = distribRevisionRelease
123 }
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400124 ArrayList testModels = job_env.get('TEST_MODELS', 'mcp-virtual-lab,infra').split(',')
125
Denis Egorenko86164872018-12-10 17:34:46 +0400126 stage('Gerrit prepare') {
127 // check if change aren't already merged
128 def gerritChange = gerrit.getGerritChange(gerritName, gerritHost, gerritChangeNumber, gerritCredentials)
129 if (gerritChange.status == "MERGED") {
130 common.successMsg('Patch set is alredy merged, no need to test it')
131 currentBuild.result = 'SUCCESS'
132 return
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400133 }
Denis Egorenko86164872018-12-10 17:34:46 +0400134 buildTestParams << job_env.findAll { k,v -> k ==~ /GERRIT_.+/ }
135 baseGerritConfig = [
136 'gerritName': gerritName,
137 'gerritHost': gerritHost,
azvyagintsev86352972019-01-29 19:08:55 +0200138 'gerritPort': gerritPort,
Denis Egorenko86164872018-12-10 17:34:46 +0400139 'gerritChangeNumber': gerritChangeNumber,
140 'credentialsId': gerritCredentials,
141 'gerritPatchSetNumber': gerritPatchSetNumber,
142 ]
Denis Egorenkod71aaa02018-12-11 16:03:37 +0400143 LinkedHashMap gerritDependingProjects = gerrit.getDependentPatches(baseGerritConfig)
144 setupDependingVars(gerritDependingProjects)
145 ArrayList descriptionMsgs = [
146 "Running with next parameters:",
147 "Ref for ${gerritProject} => ${gerritRef}",
148 "Branch for ${gerritProject} => ${gerritBranch}"
149 ]
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400150 descriptionMsgs.add("Distrib revision => ${distribRevision}")
Denis Egorenkod71aaa02018-12-11 16:03:37 +0400151 for(String project in gerritDependingProjects.keySet()) {
152 descriptionMsgs.add("---")
153 descriptionMsgs.add("Depending patch to ${project} found:")
154 descriptionMsgs.add("Ref for ${project} => ${gerritDependingProjects[project]['ref']}")
155 descriptionMsgs.add("Branch for ${project} => ${gerritDependingProjects[project]['branch']}")
156 }
Denis Egorenko76a0be82018-12-04 13:36:07 +0400157 currentBuild.description = descriptionMsgs.join('<br/>')
Denis Egorenko86164872018-12-10 17:34:46 +0400158 gerrit.gerritPatchsetCheckout([
159 credentialsId: gerritCredentials
160 ])
161 }
162
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400163 stage("Run tests") {
Denis Egorenko86164872018-12-10 17:34:46 +0400164 def documentationOnly = sh(script: "git diff-tree --no-commit-id --name-only -r HEAD | grep -v .releasenotes", returnStatus: true) == 1
165 if (documentationOnly) {
166 common.infoMsg("Tests skipped, documenation only changed!")
167 currentBuild.result = 'SUCCESS'
168 return
169 }
170
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400171 def branches = [:]
Vasyl Saienkob121eb82018-12-27 17:34:28 +0200172 branches.failFast = false
Denis Egorenkof4d3f522018-12-06 16:33:11 +0400173 String branchJobName = ''
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400174
Denis Egorenko86164872018-12-10 17:34:46 +0400175 if (gerritProject == reclassSystemRepo && gerritBranch == 'master') {
Denis Egorenkobbc12682018-12-11 18:38:43 +0400176 sh("git diff-tree --no-commit-id --diff-filter=d --name-only -r HEAD | grep .yml | xargs -I {} python -c \"import yaml; yaml.load(open('{}', 'r'))\" \\;")
Denis Egorenkod71aaa02018-12-11 16:03:37 +0400177 def defaultSystemURL = "${gerritScheme}://${gerritName}@${gerritHost}:${gerritPort}/${gerritProject}"
Denis Egorenko86164872018-12-10 17:34:46 +0400178 for (int i = 0; i < testModels.size(); i++) {
179 def cluster = testModels[i]
Denis Egorenkod71aaa02018-12-11 16:03:37 +0400180 def clusterGitUrl = defaultSystemURL.substring(0, defaultSystemURL.lastIndexOf("/") + 1) + cluster
Denis Egorenko86164872018-12-10 17:34:46 +0400181 branchJobName = "test-salt-model-${cluster}"
182 def jobParams = [
183 [$class: 'StringParameterValue', name: 'DEFAULT_GIT_URL', value: clusterGitUrl],
184 [$class: 'StringParameterValue', name: 'DEFAULT_GIT_REF', value: "HEAD"],
Denis Egorenkod71aaa02018-12-11 16:03:37 +0400185 [$class: 'StringParameterValue', name: 'SYSTEM_GIT_URL', value: defaultSystemURL ],
186 [$class: 'StringParameterValue', name: 'SYSTEM_GIT_REF', value: gerritRef ],
Denis Egorenko86164872018-12-10 17:34:46 +0400187 ]
188 branches[branchJobName] = runTests(branchJobName, jobParams)
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400189 }
190 }
Denis Egorenko86164872018-12-10 17:34:46 +0400191 if (gerritProject == reclassSystemRepo || gerritProject == cookiecutterTemplatesRepo) {
Denis Egorenkof4d3f522018-12-06 16:33:11 +0400192 branchJobName = 'test-mk-cookiecutter-templates'
Denis Egorenko86164872018-12-10 17:34:46 +0400193 branches[branchJobName] = runTests(branchJobName, yamlJobParameters(buildTestParams))
Denis Egorenko80d45b22019-01-31 22:28:38 +0400194 }
195
196 if (!gateMode) {
Denis Egorenko42ea6612019-01-31 18:00:25 +0400197 // testing backward compatibility
198 if (gerritBranch == 'master' && gerritProject == reclassSystemRepo) {
199 def backwardCompatibilityRefsToTest = ['proposed', 'release/2018.11.0', 'release/2019.2.0']
200 for (String oldRef in backwardCompatibilityRefsToTest) {
Denis Egorenko80d45b22019-01-31 22:28:38 +0400201 LinkedHashMap buildTestParamsOld = buildTestParams.clone()
202 buildTestParamsOld['COOKIECUTTER_TEMPLATE_REF'] = ''
203 buildTestParamsOld['COOKIECUTTER_TEMPLATE_BRANCH'] = oldRef
204 String threadName = "${branchJobName}-${oldRef}"
205 branches[threadName] = runTests(branchJobName, yamlJobParameters(buildTestParamsOld), threadName)
Denis Egorenko42ea6612019-01-31 18:00:25 +0400206 }
207 }
Denis Egorenko28f8c812018-12-10 16:06:37 +0400208 if (gerritProject == cookiecutterTemplatesRepo) {
209 branchJobName = 'test-drivetrain'
210 branches[branchJobName] = runTests(branchJobName, yamlJobParameters(buildTestParams))
211 branchJobName = 'oscore-test-cookiecutter-models'
212 branches[branchJobName] = runTests(branchJobName, yamlJobParameters(buildTestParams))
213 }
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400214 }
215
Denis Egorenkof4d3f522018-12-06 16:33:11 +0400216 branches.keySet().each { key ->
217 if (branches[key] instanceof Closure) {
218 jobResultComments[key] = [ 'url': job_env.get('BUILD_URL'), 'status': 'WAITING' ]
219 }
220 }
Denis Egorenko86164872018-12-10 17:34:46 +0400221 setGerritReviewComment()
Denis Egorenkod8d13e82018-12-07 16:16:31 +0400222 parallel branches
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400223 }
224 }
225}