blob: ed34a7945fb73ea0f81acd3422d15660b8de59e2 [file] [log] [blame]
Dean Birch62c4f082020-01-17 16:13:26 +00001#!/usr/bin/env groovy
2//-------------------------------------------------------------------------------
3// Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
4//
5// SPDX-License-Identifier: BSD-3-Clause
6//
7//-------------------------------------------------------------------------------
8
Dean Birchd0f9f8c2020-03-26 11:10:33 +00009@Library('trustedfirmware') _
10import org.trustedfirmware.Gerrit
11import org.trustedfirmware.Summary
Dean Bircha6ede7e2020-03-13 14:00:33 +000012
Mark Horvath8d281cd2020-12-07 15:20:26 +010013mapPlatform = ["cypress/psoc64": "psoc64",
14 "mps2/an519": "AN519",
15 "mps2/an521": "AN521",
16 "mps2/an539": "AN539",
17 "mps2/sse-200_aws": "SSE-200_AWS",
18 "mps3/an524": "AN524",
19 "musca_a": "MUSCA_A",
20 "musca_b1/sse_200": "MUSCA_B1",
21 "musca_b1/secure_enclave": "MUSCA_B1_SE",
22 "musca_s1": "MUSCA_S1"]
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +080023
24mapCompiler = ["toolchain_GNUARM.cmake": "GNUARM",
25 "toolchain_ARMCLANG.cmake": "ARMCLANG"]
26
27mapBL2 = ["True": "--bl2",
28 "False": ""]
29
30mapTestPsaApi = ["OFF": "",
31 "INTERNAL_TRUSTED_STORAGE": "ITS",
32 "PROTECTED_STORAGE": "PS",
33 "CRYPTO": "Crypto",
34 "INITIAL_ATTESTATION": "Attest",
35 "IPC": "FF"]
36
Xinyu Zhangdbfadae2020-12-07 14:42:59 +080037// BL2, NS, PSA_API, ISOLATION_LEVEL, TEST_REG, TEST_PSA_API, PROFILE, CONFIG_NAME
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +080038mapConfigs = [
39 ["True", "True", "False", "1", "False", "OFF", "N.A", "Default"],
40 ["True", "True", "True", "1", "False", "OFF", "N.A", "CoreIPC"],
41 ["True", "True", "True", "2", "False", "OFF", "N.A", "CoreIPCTfmLevel2"],
42 ["True", "True", "True", "3", "False", "OFF", "N.A", "CoreIPCTfmLevel3"],
43 ["True", "True", "False", "1", "False", "OFF", "profile_small", "DefaultProfileS"],
44 ["True", "True", "True", "2", "False", "OFF", "profile_medium", "DefaultProfileM"],
45 ["True", "True", "False", "1", "True", "OFF", "N.A", "Regression"],
46 ["True", "True", "True", "1", "True", "OFF", "N.A", "RegressionIPC"],
47 ["True", "True", "True", "2", "True", "OFF", "N.A", "RegressionIPCTfmLevel2"],
48 ["True", "True", "True", "3", "True", "OFF", "N.A", "RegressionIPCTfmLevel3"],
49 ["True", "True", "False", "1", "True", "OFF", "profile_small", "RegressionProfileS"],
50 ["True", "True", "True", "2", "True", "OFF", "profile_medium", "RegressionProfileM"],
51 ["True", "True", "False", "1", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTest (ITS)"],
52 ["True", "True", "False", "1", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTest (PS)"],
53 ["True", "True", "False", "1", "False", "CRYPTO", "N.A", "PsaApiTest (Crypto)"],
54 ["True", "True", "False", "1", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTest (Attest)"],
55 ["True", "True", "False", "1", "False", "IPC", "N.A", "PsaApiTest (FF)"],
56 ["True", "True", "True", "1", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTestIPC (ITS)"],
57 ["True", "True", "True", "1", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTestIPC (PS)"],
58 ["True", "True", "True", "1", "False", "CRYPTO", "N.A", "PsaApiTestIPC (Crypto)"],
59 ["True", "True", "True", "1", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPC (Attest)"],
60 ["True", "True", "True", "1", "False", "IPC", "N.A", "PsaApiTestIPC (FF)"],
61 ["True", "True", "True", "2", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel2 (ITS)"],
62 ["True", "True", "True", "2", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel2 (PS)"],
63 ["True", "True", "True", "2", "False", "CRYPTO", "N.A", "PsaApiTestIPCTfmLevel2 (Crypto)"],
64 ["True", "True", "True", "2", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPCTfmLevel2 (Attest)"],
65 ["True", "True", "True", "2", "False", "IPC", "N.A", "PsaApiTestIPCTfmLevel2 (FF)"],
66 ["True", "True", "True", "3", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel3 (ITS)"],
67 ["True", "True", "True", "3", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel3 (PS)"],
68 ["True", "True", "True", "3", "False", "CRYPTO", "N.A", "PsaApiTestIPCTfmLevel3 (Crypto)"],
69 ["True", "True", "True", "3", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPCTfmLevel3 (Attest)"],
70 ["True", "True", "True", "3", "False", "IPC", "N.A", "PsaApiTestIPCTfmLevel3 (FF)"],
71]
72
73cfgs = ["Default", "CoreIPC", "CoreIPCTfmLevel2", "CoreIPCTfmLevel3",
74 "Regression", "RegressionIPC",
75 "RegressionIPCTfmLevel2", "RegressionIPCTfmLevel3",
76 "DefaultProfileS", "RegressionProfileS",
77 "DefaultProfileM", "RegressionProfileM", "RegressionProfileM PSOFF",
78 "PsaApiTest (Attest)", "PsaApiTestIPC (Attest)",
79 "PsaApiTestIPCTfmLevel2 (Attest)",
80 "PsaApiTest (Crypto)", "PsaApiTestIPC (Crypto)",
81 "PsaApiTestIPCTfmLevel2 (Crypto)",
82 "PsaApiTest (PS)", "PsaApiTestIPC (PS)",
83 "PsaApiTestIPCTfmLevel2 (PS)",
84 "PsaApiTest (ITS)", "PsaApiTestIPC (ITS)",
85 "PsaApiTestIPCTfmLevel2 (ITS)",
86 "PsaApiTestIPC (FF)",
87 "PsaApiTestIPCTfmLevel2 (FF)",
88 "PsaApiTestIPCTfmLevel3 (ITS)", "PsaApiTestIPCTfmLevel3 (PS)",
89 "PsaApiTestIPCTfmLevel3 (Crypto)", "PsaApiTestIPCTfmLevel3 (Attest)",
90 "PsaApiTestIPCTfmLevel3 (FF)"]
91
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +080092def generateLavaParam(build_params) {
93 def params = []
94 params += string(name: "TARGET_PLATFORM", \
95 value: mapPlatform[build_params["TFM_PLATFORM"]])
96 params += string(name: "COMPILER", \
97 value: mapCompiler[build_params["TOOLCHAIN_FILE"]])
98 params += string(name: "PSA_API_SUITE", \
99 value: mapTestPsaApi[build_params["TEST_PSA_API"]])
100
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800101 configName = "Config"
102 config_params = [build_params["BL2"], build_params["NS"], \
103 build_params["PSA_API"], build_params["ISOLATION_LEVEL"], \
104 build_params["TEST_REGRESSION"], build_params["TEST_PSA_API"], \
105 build_params["PROFILE"]]
106 for (config in mapConfigs) {
107 if (config_params == config[0..6]) {
108 configName += config[7].split(' ')[0]
109 break
110 }
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800111 }
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800112 if (configName == "Config") {
113 configName = "ConfigDefault"
114 }
115 params += string(name: "PROJ_CONFIG", value: configName)
116
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800117 return params
118}
119
Dean Birch62c4f082020-01-17 16:13:26 +0000120def listConfigs(ci_scripts_dir, config_list, filter_group) {
121 dir(ci_scripts_dir) {
122 echo "Obtaining list of configs."
Matthew Hartfb6fd362020-03-04 21:03:59 +0000123 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}"
Dean Birch62c4f082020-01-17 16:13:26 +0000124 def build_config_list_raw = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000125python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}
Dean Birch62c4f082020-01-17 16:13:26 +0000126""", returnStdout: true).trim()
127 def build_config_list = build_config_list_raw.tokenize('\n')
128 config_list.addAll(build_config_list)
129 }
130}
131
Matthew Hartfb6fd362020-03-04 21:03:59 +0000132def buildConfig(ci_scripts_dir, config, filter_group, results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000133 def params = []
Matthew Hartfb6fd362020-03-04 21:03:59 +0000134 def params_collection = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000135 def build_config_params
136 dir(ci_scripts_dir) {
137 echo "Obtaining build configuration for config ${config}"
Matthew Hartfb6fd362020-03-04 21:03:59 +0000138 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}"
Dean Birch62c4f082020-01-17 16:13:26 +0000139 build_config_params = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000140python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}
Dean Birch62c4f082020-01-17 16:13:26 +0000141""", returnStdout: true).trim()
142 }
143 def lines = build_config_params.tokenize('\n')
144 for (String line : lines) {
145 def key, value
146 (key, value) = line.tokenize('=')
147 params += string(name: key, value: value)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000148 params_collection[key] = value
Dean Birch62c4f082020-01-17 16:13:26 +0000149 }
150 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000151 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
152 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
153 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000154 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800155 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000156 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Karl Zhangf6f467e2020-07-10 16:24:45 +0800157 params += string(name: 'CODE_COVERAGE_EN', value: env.CODE_COVERAGE_EN)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000158 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000159 return { -> results
160 def build_res = build(job: 'tf-m-build-config', parameters: params, propagate: false)
161 def build_info = [build_res, config, params_collection]
162 results['builds'][build_res.number] = build_info
163 def build_url = build_res.getAbsoluteUrl()
164 print("${build_res.number}: ${config} ${build_res.result} ${build_url}")
165 failure_states = ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]
166 if (build_res.result in failure_states) {
167 error("Build failed at ${build_url}")
168 }
Karl Zhang2b10b342020-11-09 14:50:11 +0800169 else if (params_collection["NS"] == "False" || \
170 (params_collection["PROFILE"] == "profile_medium" && \
171 params_collection["PARTITION_PS"] == "OFF")) {
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800172 print("LAVA is not needed for ${build_url}")
173 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000174 else {
175 print("Doing LAVA stuff for ${build_url}")
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800176 params += generateLavaParam(params_collection)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000177 params += string(name: 'BUILD_NUMBER', value: "${build_res.number}")
178 params += string(name: 'BUILD_URL', value: build_url)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000179 params += string(name: 'LAVA_URL', value: env.LAVA_URL)
Dean Birch956416f2020-08-12 10:36:16 +0100180 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
181 params += string(name: 'LAVA_CREDENTIALS', value: env.LAVA_CREDENTIALS)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000182 def lava_res = build(job: 'tf-m-lava-submit', parameters: params, propagate: false)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000183 if (lava_res.result in failure_states) {
184 error("LAVA Create and Submit failed at ${lava_res.getAbsoluteUrl()}")
185 }
186 else {
187 results['lava_jobs'] += lava_res.getDescription()
188 }
Dean Birch62c4f082020-01-17 16:13:26 +0000189 }
190 }
191}
192
Matthew Hart06340d72020-06-15 16:08:20 +0100193def buildDocs(results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000194 def params = []
195 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000196 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
197 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
198 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000199 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800200 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000201 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000202 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Matthew Hart06340d72020-06-15 16:08:20 +0100203 return { -> results
Dean Birch62c4f082020-01-17 16:13:26 +0000204 def res = build(job: 'tf-m-build-docs', parameters: params, propagate:false)
205 print("${res.number}: Docs ${res.result} ${res.getAbsoluteUrl()}")
Matthew Hart06340d72020-06-15 16:08:20 +0100206 results['docs'] = [res.number, res.result, params]
Dean Bircha6ede7e2020-03-13 14:00:33 +0000207 if (res.result in ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]) {
Dean Birch62c4f082020-01-17 16:13:26 +0000208 error("Build failed at ${res.getAbsoluteUrl()}")
209 }
210 }
211}
212
Xinyu Zhang38a18872020-11-23 16:45:28 +0800213def generateEmailBody(stage, failed_jobs) {
214 body = "Check console output at ${env.BUILD_URL} \n\n"
215
216 body += "Failed Jobs:\n"
217 failed_jobs.each { job ->
218 body += "${job.key} ${job.value}\n"
219 }
220
221 body += "\nFor detailed ${stage} results please refer to \
222 ${env.BUILD_URL}artifact/${stage}_results.csv \n"
223 return body
224}
225
226def emailNotification(results, stage, failed_jobs) {
Karl Zhang0413e972020-09-18 17:59:26 +0800227 script {
228 if (env.JOB_NAME.equals("tf-m-nightly") && !env.EMAIL_NOTIFICATION.equals('')) {
229 def result = "Fail."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800230 if (results == true) {
Karl Zhang0413e972020-09-18 17:59:26 +0800231 result = "Success."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800232 print("Skip sending as ${result} for ${stage}")
233 }
234 else {
235 emailext (
236 subject: ("Job ${env.JOB_NAME} ${stage} ${env.BUILD_NUMBER} ${result}"),
Xinyu Zhang38a18872020-11-23 16:45:28 +0800237 body: generateEmailBody(stage, failed_jobs),
Karl Zhang182ecdf2020-10-10 09:52:12 +0800238 to: "${EMAIL_NOTIFICATION}"
239 )
240 }
Karl Zhang0413e972020-09-18 17:59:26 +0800241 }
242 } /* script */
243}
244
Xinyu Zhang38a18872020-11-23 16:45:28 +0800245def filterFailedBuild(results) {
246 def failed_builds = [:]
247 results.each { result ->
248 if (result.value[0].getResult() == "FAILURE") {
249 failed_builds[result.value[1]] = result.value[0].getAbsoluteUrl()
250 }
251 }
252 return failed_builds
253}
254
255def filterFailedTest(string) {
256 def failed_tests = [:]
257 line = lineInString(string, "FAILURE_TESTS:")
258 a = line.split(' ')
259 if (a.size() > 1) {
260 a = line.split(' ')[1..-1]
261 a.each { fail_test ->
262 config_link = fail_test.split(':')
263 failed_tests[config_link[0]] = config_link[1..-1].join(':')
264 }
265 }
266 return failed_tests
267}
268
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800269@NonCPS
270def generateCsvContent(results) {
271 def resultsParam = []
272 results.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800273 if (result.value[2]['BL2'] == "True") {
274 resultsParam.add([result.value[1], \
275 result.value[0].getResult(), \
276 result.value[2]['TFM_PLATFORM'], \
277 result.value[2]['TOOLCHAIN_FILE'], \
278 result.value[2]['CMAKE_BUILD_TYPE'], \
279 result.value[2]['BL2'], \
280 result.value[2]['NS'], \
281 result.value[2]['PSA_API'], \
282 result.value[2]['ISOLATION_LEVEL'], \
283 result.value[2]['TEST_REGRESSION'], \
284 result.value[2]['TEST_PSA_API'], \
285 result.value[2]['PROFILE'], \
286 result.value[2]['PARTITION_PS'], \
287 result.value[2]['OTP']])
288 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800289 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800290 resultsParam.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800291 if (result[2] == 'musca_b1') {
292 if (result[13] != 'off') {
293 result[2] = 'musca_b1_OTP'
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800294 }
295 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800296 result[3] = mapCompiler[result[3]]
297 build_params = result[5..12]
298 configName = ""
299 for (map_cfg in mapConfigs) {
300 if (build_params[0..6] == map_cfg[0..6]) {
301 configName = map_cfg[7]
302 break
303 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800304 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800305 if (configName == "") {
306 configName = "Default"
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800307 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800308 else if (configName == "RegressionProfileM") {
309 if (build_params[7] == "OFF") {
310 configName = "RegressionProfileM PSOFF"
311 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800312 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800313 result.add(configName)
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800314 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800315 def csvContent = []
316 resultsParam.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800317 current_row = result[2..4]
318 cfgs.each {cfg ->
319 if (cfg == result[14]) {
320 current_row.add(cfg)
321 current_row.add(result[1])
322 }
323 }
324 csvContent.add(current_row)
325 }
326 csvContent.sort{a,b -> a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2]}
327 build_summary = []
328 current_platform = ""
329 current_compiler = ""
330 current_build_type = ""
331 csvContent.each { build_cfg ->
332 if (current_platform != build_cfg[0] || \
333 current_compiler != build_cfg[1] || \
334 current_build_type != build_cfg[2]) {
335 current_platform = build_cfg[0]
336 current_compiler = build_cfg[1]
337 current_build_type = build_cfg[2]
338 csv_line = [current_platform, current_compiler, current_build_type]
339 cfgs.each {
340 csv_line.add("N.A.")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800341 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800342 build_summary.add(csv_line)
343 }
344 i = 0
345 cfgs.each { cfg ->
346 if (cfg == build_cfg[3]) {
347 build_summary[-1][3+i] = build_cfg[4]
348 }
349 i += 1
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800350 }
351 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800352 build_summary.add(0, ['Platform', 'Compiler', 'Cmake Build Type'])
353 build_summary[0] += cfgs
354 return build_summary
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800355}
356
357def generateBuildCsv(results) {
358 def csvContent = generateCsvContent(results)
359 node("master") {
360 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
361 archiveArtifacts 'build_results.csv'
362 }
363}
Dean Bircha6ede7e2020-03-13 14:00:33 +0000364
365def buildCsv(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000366 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000367 def csvContent = summary.getBuildCsv(results)
368 node("master") {
369 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
370 archiveArtifacts 'build_results.csv'
371 }
372}
373
374def writeSummary(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000375 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000376 def buildLinks = summary.getLinks(results)
377 node("master") {
378 writeFile file: "build_links.html", text: buildLinks
379 archiveArtifacts 'build_links.html'
380 }
381}
382
Matthew Hartfb6fd362020-03-04 21:03:59 +0000383def lineInString(string, match) {
384 def lines = string.split("\n")
385 def result = lines.findAll { it.contains(match) }
386 return result[0]
387}
388
389def getResult(string, match) {
390 line = lineInString(string, match)
Dean Birch1d545c02020-05-29 14:09:21 +0100391 a = line.split(match)[1].split(' ')
392 score = a[0]
393 if (a.size() > 1)
394 {
395 fail_text = a[1..-1].join(" ")
396 return [score, fail_text]
397 }
398 return [score, ""]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000399}
400
401def submitJobsToList(results) {
402 def all_jobs = []
403 for (String result : results){
404 jobs_s = result.split('JOBS: ')
405 if (jobs_s.size() > 1) {
406 all_jobs += jobs_s[1]
407 }
408 }
409 return(all_jobs)
410}
411
Dean Birch62c4f082020-01-17 16:13:26 +0000412def configs = []
413def builds = [:]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000414def results = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000415
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000416node("docker-amd64-tf-m-bionic") {
Dean Birch62c4f082020-01-17 16:13:26 +0000417 stage("Init") {
418 cleanWs()
419 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000420 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Birch62c4f082020-01-17 16:13:26 +0000421 }
422 }
423 stage("Configs") {
424 // Populate configs
425 listConfigs('tf-m-ci-scripts', configs, env.FILTER_GROUP)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000426 results['builds'] = [:]
427 results['lava_jobs'] = []
Dean Birch62c4f082020-01-17 16:13:26 +0000428 for (config in configs) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000429 builds[config] = buildConfig("tf-m-ci-scripts", config, env.FILTER_GROUP, results)
Dean Birch62c4f082020-01-17 16:13:26 +0000430 }
Matthew Hart06340d72020-06-15 16:08:20 +0100431 builds["docs"] = buildDocs(results)
Dean Birch62c4f082020-01-17 16:13:26 +0000432 }
433}
Karl Zhangfec84102020-06-24 09:56:36 +0800434
Dean Birch62c4f082020-01-17 16:13:26 +0000435stage("Builds") {
436 def verify = 1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800437 def success = true
Dean Birch62c4f082020-01-17 16:13:26 +0000438 try {
439 parallel(builds)
440 } catch (Exception e) {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000441 print(e)
Dean Birch62c4f082020-01-17 16:13:26 +0000442 manager.buildFailure()
443 verify = -1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800444 success = false
Dean Birch62c4f082020-01-17 16:13:26 +0000445 } finally {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000446 print("Verifying status")
Xinyu Zhang38a18872020-11-23 16:45:28 +0800447 def failed_builds = filterFailedBuild(results['builds'])
448 emailNotification(success, 'build', failed_builds)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000449 g = new Gerrit()
450 g.verifyStatus(verify, 'tf-m-build', 'build')
Dean Bircha6ede7e2020-03-13 14:00:33 +0000451 print("Building CSV")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800452 generateBuildCsv(results['builds'])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000453 writeSummary(results['builds'])
Dean Birch62c4f082020-01-17 16:13:26 +0000454 }
455}
Matthew Hart06340d72020-06-15 16:08:20 +0100456
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000457node("docker-amd64-tf-m-bionic") {
Matthew Hart06340d72020-06-15 16:08:20 +0100458 stage("Copy Docs") {
Karl Zhang32497972020-09-21 14:38:29 +0800459 if (env.JOB_NAME.equals("tf-m-build-and-test")) {
460 step([$class: 'CopyArtifact', projectName: 'tf-m-build-docs',
461 selector: specific("${results['docs'][0]}"), target: './docs/',
462 optional: true])
463 archiveArtifacts artifacts: 'docs/**', allowEmptyArchive: true
464 }
465 else {
466 print("No doc copy for job: ${env.JOB_NAME}")
467 }
Matthew Hart06340d72020-06-15 16:08:20 +0100468 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000469 stage("Tests") {
470 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000471 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000472 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000473 def all_jobs = []
474 def success = true
Dean Bircha6ede7e2020-03-13 14:00:33 +0000475 print("Wait for LAVA results here...")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000476 try {
477 all_jobs = submitJobsToList(results['lava_jobs'])
478 if (all_jobs.size() > 0) {
479 dir("tf-m-ci-scripts") {
Dean Birch956416f2020-08-12 10:36:16 +0100480 withCredentials([usernamePassword(credentialsId: env.LAVA_CREDENTIALS, passwordVariable: 'LAVA_TOKEN', usernameVariable: 'LAVA_USER')]) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000481 output = sh(script: """./lava_helper/lava_wait_jobs.py --job-ids ${all_jobs.join(",")} \
482 --lava-url ${env.LAVA_URL} --lava-user ${LAVA_USER} --lava-token ${LAVA_TOKEN} \
Matthew Hart05a59b52020-05-27 17:54:51 +0100483 --artifacts-path lava_artifacts --lava-timeout 7200 \
Matthew Hartfb6fd362020-03-04 21:03:59 +0000484 """, returnStdout: true).trim()
485 archiveArtifacts artifacts: 'test_summary.*', allowEmptyArchive: true
Xinyu Zhang1b8f5152020-11-13 16:10:58 +0800486 archiveArtifacts artifacts: 'test_results.csv', allowEmptyArchive: true
Matthew Hartfb6fd362020-03-04 21:03:59 +0000487 g = new Gerrit()
Dean Birch1d545c02020-05-29 14:09:21 +0100488 def (boot_result, boot_output) = getResult(output, 'BOOT_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000489 if (boot_result) {
490 g.verifyStatus(boot_result, "lava_boot", "test")
491 }
Dean Birch1d545c02020-05-29 14:09:21 +0100492 def (test_result, test_output) = getResult(output, 'TEST_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000493 if (test_result) {
494 g.verifyStatus(test_result, "lava_test", "test")
495 }
496 if (boot_result.toInteger() < 1 || test_result.toInteger() < 1) {
Dean Birch1d545c02020-05-29 14:09:21 +0100497 error("Marking job as failed due to failed boots: ${boot_output} or tests: ${test_output}")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000498 }
499 }
500 }
501 }
502 else {
503 print("There were no LAVA jobs to test.")
504 }
505 }
506 catch (Exception e) {
507 print("ERROR: ${e}")
508 success = false
509 } finally {
510 archiveArtifacts artifacts: 'tf-m-ci-scripts/lava_artifacts/**', allowEmptyArchive: true
Xinyu Zhang91609012020-12-09 17:35:49 +0800511 if (all_jobs.size() > 0) {
512 emailNotification(success, 'test', filterFailedTest(output))
513 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000514 cleanWs()
515 if (!success) {
516 error("There was an Error waiting for LAVA jobs")
517 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000518 }
519 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000520}