blob: 118431aa7df47abf9f30ee3ccf7a14033acf8f67 [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 Egorenkoabf63972019-02-06 19:38:27 +040011
Denis Egorenko6c325112018-12-05 19:58:34 +040012gerrit = new com.mirantis.mk.Gerrit()
Denis Egorenko358a4fc2018-11-27 17:57:22 +040013
Denis Egorenkoabf63972019-02-06 19:38:27 +040014cookiecutterTemplatesRepo = 'mk/cookiecutter-templates'
15reclassSystemRepo = 'salt-models/reclass-system'
Denis Egorenko6c6b08e2018-12-13 13:23:43 +040016slaveNode = env.getProperty('SLAVE_NODE') ?: 'virtual'
Denis Egorenko358a4fc2018-11-27 17:57:22 +040017
Denis Egorenko76a0be82018-12-04 13:36:07 +040018voteMatrix = [
Denis Egorenkoabf63972019-02-06 19:38:27 +040019 'test-mk-cookiecutter-templates' : true,
20 'test-drivetrain' : true,
21 'oscore-test-cookiecutter-models': false,
22 'test-salt-model-infra' : true,
23 'test-salt-model-mcp-virtual-lab': false,
Denis Egorenko76a0be82018-12-04 13:36:07 +040024]
25
Denis Egorenko6c325112018-12-05 19:58:34 +040026baseGerritConfig = [:]
Denis Egorenkod71aaa02018-12-11 16:03:37 +040027buildTestParams = [:]
Denis Egorenkof4d3f522018-12-06 16:33:11 +040028jobResultComments = [:]
29commentLock = false
Denis Egorenko6c325112018-12-05 19:58:34 +040030
Denis Egorenko86164872018-12-10 17:34:46 +040031// post Gerrit review comment to patch
32def setGerritReviewComment() {
Denis Egorenko6c325112018-12-05 19:58:34 +040033 if (baseGerritConfig) {
Denis Egorenko42ea6612019-01-31 18:00:25 +040034 while (commentLock) {
Denis Egorenkof4d3f522018-12-06 16:33:11 +040035 sleep 5
36 }
37 commentLock = true
Denis Egorenko6c325112018-12-05 19:58:34 +040038 LinkedHashMap config = baseGerritConfig.clone()
Denis Egorenkof4d3f522018-12-06 16:33:11 +040039 String jobResultComment = ''
Denis Egorenko42ea6612019-01-31 18:00:25 +040040 jobResultComments.each { threadName, info ->
41 String skipped = voteMatrix.get(info.job, 'true') ? '' : '(non-voting)'
42 jobResultComment += "- ${threadName} ${info.url}console : ${info.status} ${skipped}".trim() + '\n'
Denis Egorenkof4d3f522018-12-06 16:33:11 +040043 }
44 config['message'] = sh(script: "echo '${jobResultComment}'", returnStdout: true).trim()
Denis Egorenko6c325112018-12-05 19:58:34 +040045 gerrit.postGerritComment(config)
Denis Egorenkof4d3f522018-12-06 16:33:11 +040046 commentLock = false
Denis Egorenko6c325112018-12-05 19:58:34 +040047 }
Denis Egorenko76a0be82018-12-04 13:36:07 +040048}
49
Denis Egorenko86164872018-12-10 17:34:46 +040050// get job parameters for YAML-based job parametrization
51def yamlJobParameters(LinkedHashMap jobParams) {
52 return [
Denis Egorenkoabf63972019-02-06 19:38:27 +040053 [$class: 'TextParameterValue', name: 'EXTRA_VARIABLES_YAML', value: JsonOutput.toJson(jobParams)]
Denis Egorenko86164872018-12-10 17:34:46 +040054 ]
55}
56
57// run needed job with params
Denis Egorenko04c8a2c2019-02-22 14:30:44 +040058def runTests(String jobName, ArrayList jobParams, String threadName = '', Boolean voteOverride = null) {
Denis Egorenko42ea6612019-01-31 18:00:25 +040059 threadName = threadName ? threadName : jobName
Denis Egorenko04c8a2c2019-02-22 14:30:44 +040060 def propagateStatus = voteOverride != null ? voteOverride : voteMatrix.get(jobName, true)
Denis Egorenko358a4fc2018-11-27 17:57:22 +040061 return {
Denis Egorenko86164872018-12-10 17:34:46 +040062 def jobBuild = build job: jobName, propagate: false, parameters: jobParams
Denis Egorenkoabf63972019-02-06 19:38:27 +040063 jobResultComments[threadName] = ['url': jobBuild.absoluteUrl, 'status': jobBuild.result, 'job': jobName]
Denis Egorenkof4d3f522018-12-06 16:33:11 +040064 setGerritReviewComment()
Denis Egorenko76a0be82018-12-04 13:36:07 +040065 if (propagateStatus && jobBuild.result == 'FAILURE') {
Denis Egorenko42ea6612019-01-31 18:00:25 +040066 throw new Exception("Build ${threadName} is failed!")
Denis Egorenko358a4fc2018-11-27 17:57:22 +040067 }
68 }
69}
70
Denis Egorenkod71aaa02018-12-11 16:03:37 +040071// set params based on depending patches
72def setupDependingVars(LinkedHashMap dependingProjects) {
73 if (dependingProjects) {
74 if (dependingProjects.containsKey(reclassSystemRepo)) {
75 buildTestParams['RECLASS_SYSTEM_GIT_REF'] = dependingProjects[reclassSystemRepo].ref
76 buildTestParams['RECLASS_SYSTEM_BRANCH'] = dependingProjects[reclassSystemRepo].branch
77 }
78 if (dependingProjects.containsKey(cookiecutterTemplatesRepo)) {
79 buildTestParams['COOKIECUTTER_TEMPLATE_REF'] = dependingProjects[cookiecutterTemplatesRepo].ref
80 buildTestParams['COOKIECUTTER_TEMPLATE_BRANCH'] = dependingProjects[cookiecutterTemplatesRepo].branch
81 }
82 }
83}
84
Denis Egorenko358a4fc2018-11-27 17:57:22 +040085timeout(time: 12, unit: 'HOURS') {
86 node(slaveNode) {
87 def common = new com.mirantis.mk.Common()
Denis Egorenko358a4fc2018-11-27 17:57:22 +040088
Denis Egorenko28f8c812018-12-10 16:06:37 +040089 // Var EXTRA_VARIABLES_YAML contains any additional parameters for tests,
Denis Egorenko358a4fc2018-11-27 17:57:22 +040090 // like manually specified Gerrit Refs/URLs, additional parameters and so on
Denis Egorenko28f8c812018-12-10 16:06:37 +040091 def buildTestParamsYaml = env.getProperty('EXTRA_VARIABLES_YAML')
Denis Egorenko76a0be82018-12-04 13:36:07 +040092 if (buildTestParamsYaml) {
93 common.mergeEnv(env, buildTestParamsYaml)
94 buildTestParams = readYaml text: buildTestParamsYaml
Denis Egorenko358a4fc2018-11-27 17:57:22 +040095 }
96
97 // init required job variables
98 LinkedHashMap job_env = env.getEnvironment().findAll { k, v -> v }
99
100 // Gerrit parameters
101 String gerritCredentials = job_env.get('CREDENTIALS_ID', 'gerrit')
Denis Egorenko86164872018-12-10 17:34:46 +0400102 String gerritRef = job_env.get('GERRIT_REFSPEC')
103 String gerritProject = job_env.get('GERRIT_PROJECT')
104 String gerritName = job_env.get('GERRIT_NAME')
105 String gerritScheme = job_env.get('GERRIT_SCHEME')
106 String gerritHost = job_env.get('GERRIT_HOST')
107 String gerritPort = job_env.get('GERRIT_PORT')
108 String gerritChangeNumber = job_env.get('GERRIT_CHANGE_NUMBER')
109 String gerritPatchSetNumber = job_env.get('GERRIT_PATCHSET_NUMBER')
110 String gerritBranch = job_env.get('GERRIT_BRANCH')
Denis Egorenkoe581f9e2018-12-11 18:56:14 +0400111 Boolean gateMode = job_env.get('GERRIT_CI_MERGE_TRIGGER', false).toBoolean()
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400112
113 // Common and manual build parameters
114 LinkedHashMap projectsMap = [:]
Denis Egorenko86164872018-12-10 17:34:46 +0400115 String distribRevision = 'nightly'
116 //checking if the branch is from release
117 if (gerritBranch.startsWith('release')) {
Denis Egorenkoabf63972019-02-06 19:38:27 +0400118 distribRevision = gerritBranch.tokenize('/')[-1]
119 // Check if we are going to test bleeding-edge release, which doesn't have binary release yet
120 // After 2018q4 releases, need to also check 'static' repo, for example ubuntu.
121 binTest = common.checkRemoteBinary(['mcp_version': distribRevision])
122 if (!binTest.linux_system_repo_url || !binTest.linux_system_repo_ubuntu_url) {
123 common.errorMsg("Binary release: ${distribRevision} not exist or not full. Fallback to 'proposed'! ")
124 distribRevision = 'proposed'
Denis Egorenko86164872018-12-10 17:34:46 +0400125 }
Denis Egorenko86164872018-12-10 17:34:46 +0400126 }
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400127 ArrayList testModels = job_env.get('TEST_MODELS', 'mcp-virtual-lab,infra').split(',')
128
Denis Egorenko86164872018-12-10 17:34:46 +0400129 stage('Gerrit prepare') {
130 // check if change aren't already merged
131 def gerritChange = gerrit.getGerritChange(gerritName, gerritHost, gerritChangeNumber, gerritCredentials)
132 if (gerritChange.status == "MERGED") {
133 common.successMsg('Patch set is alredy merged, no need to test it')
134 currentBuild.result = 'SUCCESS'
135 return
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400136 }
Denis Egorenkoabf63972019-02-06 19:38:27 +0400137 buildTestParams << job_env.findAll { k, v -> k ==~ /GERRIT_.+/ }
Denis Egorenko86164872018-12-10 17:34:46 +0400138 baseGerritConfig = [
Denis Egorenkoabf63972019-02-06 19:38:27 +0400139 'gerritName' : gerritName,
140 'gerritHost' : gerritHost,
141 'gerritPort' : gerritPort,
142 'gerritChangeNumber' : gerritChangeNumber,
143 'credentialsId' : gerritCredentials,
Denis Egorenko86164872018-12-10 17:34:46 +0400144 'gerritPatchSetNumber': gerritPatchSetNumber,
145 ]
Denis Egorenkod71aaa02018-12-11 16:03:37 +0400146 LinkedHashMap gerritDependingProjects = gerrit.getDependentPatches(baseGerritConfig)
147 setupDependingVars(gerritDependingProjects)
148 ArrayList descriptionMsgs = [
149 "Running with next parameters:",
150 "Ref for ${gerritProject} => ${gerritRef}",
151 "Branch for ${gerritProject} => ${gerritBranch}"
152 ]
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400153 descriptionMsgs.add("Distrib revision => ${distribRevision}")
Denis Egorenkoabf63972019-02-06 19:38:27 +0400154 for (String project in gerritDependingProjects.keySet()) {
Denis Egorenkod71aaa02018-12-11 16:03:37 +0400155 descriptionMsgs.add("---")
156 descriptionMsgs.add("Depending patch to ${project} found:")
157 descriptionMsgs.add("Ref for ${project} => ${gerritDependingProjects[project]['ref']}")
158 descriptionMsgs.add("Branch for ${project} => ${gerritDependingProjects[project]['branch']}")
159 }
Denis Egorenko76a0be82018-12-04 13:36:07 +0400160 currentBuild.description = descriptionMsgs.join('<br/>')
Denis Egorenko86164872018-12-10 17:34:46 +0400161 gerrit.gerritPatchsetCheckout([
162 credentialsId: gerritCredentials
163 ])
164 }
165
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400166 stage("Run tests") {
Denis Egorenko86164872018-12-10 17:34:46 +0400167 def documentationOnly = sh(script: "git diff-tree --no-commit-id --name-only -r HEAD | grep -v .releasenotes", returnStatus: true) == 1
168 if (documentationOnly) {
169 common.infoMsg("Tests skipped, documenation only changed!")
170 currentBuild.result = 'SUCCESS'
171 return
172 }
173
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400174 def branches = [:]
Vasyl Saienkob121eb82018-12-27 17:34:28 +0200175 branches.failFast = false
Denis Egorenkof4d3f522018-12-06 16:33:11 +0400176 String branchJobName = ''
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400177
Denis Egorenko86164872018-12-10 17:34:46 +0400178 if (gerritProject == reclassSystemRepo && gerritBranch == 'master') {
Denis Egorenkobbc12682018-12-11 18:38:43 +0400179 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 +0400180 def defaultSystemURL = "${gerritScheme}://${gerritName}@${gerritHost}:${gerritPort}/${gerritProject}"
Denis Egorenko86164872018-12-10 17:34:46 +0400181 for (int i = 0; i < testModels.size(); i++) {
182 def cluster = testModels[i]
Denis Egorenkod71aaa02018-12-11 16:03:37 +0400183 def clusterGitUrl = defaultSystemURL.substring(0, defaultSystemURL.lastIndexOf("/") + 1) + cluster
Denis Egorenko86164872018-12-10 17:34:46 +0400184 branchJobName = "test-salt-model-${cluster}"
185 def jobParams = [
186 [$class: 'StringParameterValue', name: 'DEFAULT_GIT_URL', value: clusterGitUrl],
187 [$class: 'StringParameterValue', name: 'DEFAULT_GIT_REF', value: "HEAD"],
Denis Egorenkoabf63972019-02-06 19:38:27 +0400188 [$class: 'StringParameterValue', name: 'SYSTEM_GIT_URL', value: defaultSystemURL],
189 [$class: 'StringParameterValue', name: 'SYSTEM_GIT_REF', value: gerritRef],
Denis Egorenko86164872018-12-10 17:34:46 +0400190 ]
191 branches[branchJobName] = runTests(branchJobName, jobParams)
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400192 }
193 }
Denis Egorenko86164872018-12-10 17:34:46 +0400194 if (gerritProject == reclassSystemRepo || gerritProject == cookiecutterTemplatesRepo) {
Denis Egorenkof4d3f522018-12-06 16:33:11 +0400195 branchJobName = 'test-mk-cookiecutter-templates'
Denis Egorenko86164872018-12-10 17:34:46 +0400196 branches[branchJobName] = runTests(branchJobName, yamlJobParameters(buildTestParams))
Denis Egorenko80d45b22019-01-31 22:28:38 +0400197 }
198
199 if (!gateMode) {
Denis Egorenko42ea6612019-01-31 18:00:25 +0400200 // testing backward compatibility
201 if (gerritBranch == 'master' && gerritProject == reclassSystemRepo) {
202 def backwardCompatibilityRefsToTest = ['proposed', 'release/2018.11.0', 'release/2019.2.0']
203 for (String oldRef in backwardCompatibilityRefsToTest) {
Denis Egorenko80d45b22019-01-31 22:28:38 +0400204 LinkedHashMap buildTestParamsOld = buildTestParams.clone()
205 buildTestParamsOld['COOKIECUTTER_TEMPLATE_REF'] = ''
206 buildTestParamsOld['COOKIECUTTER_TEMPLATE_BRANCH'] = oldRef
207 String threadName = "${branchJobName}-${oldRef}"
Denis Egorenkoc8c4bd12019-02-22 16:18:13 +0400208 // disable votes for release/2018.11.0 branch
209 overrideVote = oldRef == 'release/2018.11.0' ? false : null
Denis Egorenko04c8a2c2019-02-22 14:30:44 +0400210 branches[threadName] = runTests(branchJobName, yamlJobParameters(buildTestParamsOld), threadName, overrideVote)
Denis Egorenko42ea6612019-01-31 18:00:25 +0400211 }
212 }
Denis Egorenko28f8c812018-12-10 16:06:37 +0400213 if (gerritProject == cookiecutterTemplatesRepo) {
214 branchJobName = 'test-drivetrain'
215 branches[branchJobName] = runTests(branchJobName, yamlJobParameters(buildTestParams))
216 branchJobName = 'oscore-test-cookiecutter-models'
217 branches[branchJobName] = runTests(branchJobName, yamlJobParameters(buildTestParams))
218 }
Mykyta Karpin1427cf82019-03-12 16:17:00 +0200219 if (env['GERRIT_EVENT_COMMENT_TEXT'] && new String(env['GERRIT_EVENT_COMMENT_TEXT'].decodeBase64()) =~ /\ntest_schemas.*/) {
220 if (gerritProject == reclassSystemRepo) {
221 branchJobName = 'oscore-test-cookiecutter-models'
222 branches[branchJobName] = runTests(branchJobName, yamlJobParameters(buildTestParams))
223 }
224 }
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400225 }
Denis Egorenkof4d3f522018-12-06 16:33:11 +0400226 branches.keySet().each { key ->
227 if (branches[key] instanceof Closure) {
Denis Egorenkoabf63972019-02-06 19:38:27 +0400228 jobResultComments[key] = ['url': job_env.get('BUILD_URL'), 'status': 'WAITING']
Denis Egorenkof4d3f522018-12-06 16:33:11 +0400229 }
230 }
Denis Egorenko86164872018-12-10 17:34:46 +0400231 setGerritReviewComment()
Denis Egorenkod8d13e82018-12-07 16:16:31 +0400232 parallel branches
Denis Egorenko358a4fc2018-11-27 17:57:22 +0400233 }
234 }
235}