blob: 57f3b624205bb6adbf84f8a258108c1a40d897d3 [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 Zhang8f374e52020-12-23 11:01:30 +0800176 lava_params = generateLavaParam(params_collection)
177 print(lava_params)
178 params += lava_params
Dean Bircha6ede7e2020-03-13 14:00:33 +0000179 params += string(name: 'BUILD_NUMBER', value: "${build_res.number}")
180 params += string(name: 'BUILD_URL', value: build_url)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000181 params += string(name: 'LAVA_URL', value: env.LAVA_URL)
Dean Birch956416f2020-08-12 10:36:16 +0100182 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
183 params += string(name: 'LAVA_CREDENTIALS', value: env.LAVA_CREDENTIALS)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000184 def lava_res = build(job: 'tf-m-lava-submit', parameters: params, propagate: false)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000185 if (lava_res.result in failure_states) {
186 error("LAVA Create and Submit failed at ${lava_res.getAbsoluteUrl()}")
187 }
188 else {
189 results['lava_jobs'] += lava_res.getDescription()
190 }
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800191 links = "Build Config: ${config}\n"
192 links += "Build URL: ${build_url}\n"
193 links += "LAVA Submit: ${lava_res.getAbsoluteUrl()}"
194 print(links)
Dean Birch62c4f082020-01-17 16:13:26 +0000195 }
196 }
197}
198
Matthew Hart06340d72020-06-15 16:08:20 +0100199def buildDocs(results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000200 def params = []
201 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000202 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
203 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
204 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000205 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800206 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000207 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000208 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Matthew Hart06340d72020-06-15 16:08:20 +0100209 return { -> results
Dean Birch62c4f082020-01-17 16:13:26 +0000210 def res = build(job: 'tf-m-build-docs', parameters: params, propagate:false)
211 print("${res.number}: Docs ${res.result} ${res.getAbsoluteUrl()}")
Matthew Hart06340d72020-06-15 16:08:20 +0100212 results['docs'] = [res.number, res.result, params]
Dean Bircha6ede7e2020-03-13 14:00:33 +0000213 if (res.result in ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]) {
Dean Birch62c4f082020-01-17 16:13:26 +0000214 error("Build failed at ${res.getAbsoluteUrl()}")
215 }
216 }
217}
218
Xinyu Zhang38a18872020-11-23 16:45:28 +0800219def generateEmailBody(stage, failed_jobs) {
220 body = "Check console output at ${env.BUILD_URL} \n\n"
221
222 body += "Failed Jobs:\n"
223 failed_jobs.each { job ->
224 body += "${job.key} ${job.value}\n"
225 }
226
227 body += "\nFor detailed ${stage} results please refer to \
228 ${env.BUILD_URL}artifact/${stage}_results.csv \n"
229 return body
230}
231
232def emailNotification(results, stage, failed_jobs) {
Karl Zhang0413e972020-09-18 17:59:26 +0800233 script {
234 if (env.JOB_NAME.equals("tf-m-nightly") && !env.EMAIL_NOTIFICATION.equals('')) {
235 def result = "Fail."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800236 if (results == true) {
Karl Zhang0413e972020-09-18 17:59:26 +0800237 result = "Success."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800238 print("Skip sending as ${result} for ${stage}")
239 }
240 else {
241 emailext (
242 subject: ("Job ${env.JOB_NAME} ${stage} ${env.BUILD_NUMBER} ${result}"),
Xinyu Zhang38a18872020-11-23 16:45:28 +0800243 body: generateEmailBody(stage, failed_jobs),
Karl Zhang182ecdf2020-10-10 09:52:12 +0800244 to: "${EMAIL_NOTIFICATION}"
245 )
246 }
Karl Zhang0413e972020-09-18 17:59:26 +0800247 }
248 } /* script */
249}
250
Xinyu Zhang38a18872020-11-23 16:45:28 +0800251def filterFailedBuild(results) {
252 def failed_builds = [:]
253 results.each { result ->
254 if (result.value[0].getResult() == "FAILURE") {
255 failed_builds[result.value[1]] = result.value[0].getAbsoluteUrl()
256 }
257 }
258 return failed_builds
259}
260
261def filterFailedTest(string) {
262 def failed_tests = [:]
263 line = lineInString(string, "FAILURE_TESTS:")
264 a = line.split(' ')
265 if (a.size() > 1) {
266 a = line.split(' ')[1..-1]
267 a.each { fail_test ->
268 config_link = fail_test.split(':')
269 failed_tests[config_link[0]] = config_link[1..-1].join(':')
270 }
271 }
272 return failed_tests
273}
274
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800275@NonCPS
276def generateCsvContent(results) {
277 def resultsParam = []
278 results.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800279 if (result.value[2]['BL2'] == "True") {
280 resultsParam.add([result.value[1], \
281 result.value[0].getResult(), \
282 result.value[2]['TFM_PLATFORM'], \
283 result.value[2]['TOOLCHAIN_FILE'], \
284 result.value[2]['CMAKE_BUILD_TYPE'], \
285 result.value[2]['BL2'], \
286 result.value[2]['NS'], \
287 result.value[2]['PSA_API'], \
288 result.value[2]['ISOLATION_LEVEL'], \
289 result.value[2]['TEST_REGRESSION'], \
290 result.value[2]['TEST_PSA_API'], \
291 result.value[2]['PROFILE'], \
292 result.value[2]['PARTITION_PS'], \
293 result.value[2]['OTP']])
294 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800295 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800296 resultsParam.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800297 if (result[2] == 'musca_b1') {
298 if (result[13] != 'off') {
299 result[2] = 'musca_b1_OTP'
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800300 }
301 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800302 result[3] = mapCompiler[result[3]]
303 build_params = result[5..12]
304 configName = ""
305 for (map_cfg in mapConfigs) {
306 if (build_params[0..6] == map_cfg[0..6]) {
307 configName = map_cfg[7]
308 break
309 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800310 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800311 if (configName == "") {
312 configName = "Default"
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800313 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800314 else if (configName == "RegressionProfileM") {
315 if (build_params[7] == "OFF") {
316 configName = "RegressionProfileM PSOFF"
317 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800318 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800319 result.add(configName)
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800320 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800321 def csvContent = []
322 resultsParam.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800323 current_row = result[2..4]
324 cfgs.each {cfg ->
325 if (cfg == result[14]) {
326 current_row.add(cfg)
327 current_row.add(result[1])
328 }
329 }
330 csvContent.add(current_row)
331 }
332 csvContent.sort{a,b -> a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2]}
333 build_summary = []
334 current_platform = ""
335 current_compiler = ""
336 current_build_type = ""
337 csvContent.each { build_cfg ->
338 if (current_platform != build_cfg[0] || \
339 current_compiler != build_cfg[1] || \
340 current_build_type != build_cfg[2]) {
341 current_platform = build_cfg[0]
342 current_compiler = build_cfg[1]
343 current_build_type = build_cfg[2]
344 csv_line = [current_platform, current_compiler, current_build_type]
345 cfgs.each {
346 csv_line.add("N.A.")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800347 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800348 build_summary.add(csv_line)
349 }
350 i = 0
351 cfgs.each { cfg ->
352 if (cfg == build_cfg[3]) {
353 build_summary[-1][3+i] = build_cfg[4]
354 }
355 i += 1
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800356 }
357 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800358 build_summary.add(0, ['Platform', 'Compiler', 'Cmake Build Type'])
359 build_summary[0] += cfgs
360 return build_summary
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800361}
362
363def generateBuildCsv(results) {
364 def csvContent = generateCsvContent(results)
365 node("master") {
366 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
367 archiveArtifacts 'build_results.csv'
368 }
369}
Dean Bircha6ede7e2020-03-13 14:00:33 +0000370
371def buildCsv(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000372 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000373 def csvContent = summary.getBuildCsv(results)
374 node("master") {
375 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
376 archiveArtifacts 'build_results.csv'
377 }
378}
379
380def writeSummary(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000381 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000382 def buildLinks = summary.getLinks(results)
383 node("master") {
384 writeFile file: "build_links.html", text: buildLinks
385 archiveArtifacts 'build_links.html'
386 }
387}
388
Matthew Hartfb6fd362020-03-04 21:03:59 +0000389def lineInString(string, match) {
390 def lines = string.split("\n")
391 def result = lines.findAll { it.contains(match) }
392 return result[0]
393}
394
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800395def showLinks(string) {
396 def lines = string.split("\n")
397 def result = lines.findAll { it.contains("Build Config: ")}
398 links = result.join("\n")
399 print(links)
400}
401
Matthew Hartfb6fd362020-03-04 21:03:59 +0000402def getResult(string, match) {
403 line = lineInString(string, match)
Dean Birch1d545c02020-05-29 14:09:21 +0100404 a = line.split(match)[1].split(' ')
405 score = a[0]
406 if (a.size() > 1)
407 {
408 fail_text = a[1..-1].join(" ")
409 return [score, fail_text]
410 }
411 return [score, ""]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000412}
413
414def submitJobsToList(results) {
415 def all_jobs = []
416 for (String result : results){
417 jobs_s = result.split('JOBS: ')
418 if (jobs_s.size() > 1) {
419 all_jobs += jobs_s[1]
420 }
421 }
422 return(all_jobs)
423}
424
Dean Birch62c4f082020-01-17 16:13:26 +0000425def configs = []
426def builds = [:]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000427def results = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000428
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000429node("docker-amd64-tf-m-bionic") {
Dean Birch62c4f082020-01-17 16:13:26 +0000430 stage("Init") {
431 cleanWs()
432 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000433 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Birch62c4f082020-01-17 16:13:26 +0000434 }
435 }
436 stage("Configs") {
437 // Populate configs
438 listConfigs('tf-m-ci-scripts', configs, env.FILTER_GROUP)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000439 results['builds'] = [:]
440 results['lava_jobs'] = []
Dean Birch62c4f082020-01-17 16:13:26 +0000441 for (config in configs) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000442 builds[config] = buildConfig("tf-m-ci-scripts", config, env.FILTER_GROUP, results)
Dean Birch62c4f082020-01-17 16:13:26 +0000443 }
Matthew Hart06340d72020-06-15 16:08:20 +0100444 builds["docs"] = buildDocs(results)
Dean Birch62c4f082020-01-17 16:13:26 +0000445 }
446}
Karl Zhangfec84102020-06-24 09:56:36 +0800447
Dean Birch62c4f082020-01-17 16:13:26 +0000448stage("Builds") {
449 def verify = 1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800450 def success = true
Dean Birch62c4f082020-01-17 16:13:26 +0000451 try {
452 parallel(builds)
453 } catch (Exception e) {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000454 print(e)
Dean Birch62c4f082020-01-17 16:13:26 +0000455 manager.buildFailure()
456 verify = -1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800457 success = false
Dean Birch62c4f082020-01-17 16:13:26 +0000458 } finally {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000459 print("Verifying status")
Xinyu Zhang38a18872020-11-23 16:45:28 +0800460 def failed_builds = filterFailedBuild(results['builds'])
461 emailNotification(success, 'build', failed_builds)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000462 g = new Gerrit()
463 g.verifyStatus(verify, 'tf-m-build', 'build')
Dean Bircha6ede7e2020-03-13 14:00:33 +0000464 print("Building CSV")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800465 generateBuildCsv(results['builds'])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000466 writeSummary(results['builds'])
Dean Birch62c4f082020-01-17 16:13:26 +0000467 }
468}
Matthew Hart06340d72020-06-15 16:08:20 +0100469
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000470node("docker-amd64-tf-m-bionic") {
Matthew Hart06340d72020-06-15 16:08:20 +0100471 stage("Copy Docs") {
Karl Zhang32497972020-09-21 14:38:29 +0800472 if (env.JOB_NAME.equals("tf-m-build-and-test")) {
473 step([$class: 'CopyArtifact', projectName: 'tf-m-build-docs',
474 selector: specific("${results['docs'][0]}"), target: './docs/',
475 optional: true])
476 archiveArtifacts artifacts: 'docs/**', allowEmptyArchive: true
477 }
478 else {
479 print("No doc copy for job: ${env.JOB_NAME}")
480 }
Matthew Hart06340d72020-06-15 16:08:20 +0100481 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000482 stage("Tests") {
483 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000484 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000485 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000486 def all_jobs = []
487 def success = true
Dean Bircha6ede7e2020-03-13 14:00:33 +0000488 print("Wait for LAVA results here...")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000489 try {
490 all_jobs = submitJobsToList(results['lava_jobs'])
491 if (all_jobs.size() > 0) {
492 dir("tf-m-ci-scripts") {
Dean Birch956416f2020-08-12 10:36:16 +0100493 withCredentials([usernamePassword(credentialsId: env.LAVA_CREDENTIALS, passwordVariable: 'LAVA_TOKEN', usernameVariable: 'LAVA_USER')]) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000494 output = sh(script: """./lava_helper/lava_wait_jobs.py --job-ids ${all_jobs.join(",")} \
495 --lava-url ${env.LAVA_URL} --lava-user ${LAVA_USER} --lava-token ${LAVA_TOKEN} \
Matthew Hart05a59b52020-05-27 17:54:51 +0100496 --artifacts-path lava_artifacts --lava-timeout 7200 \
Matthew Hartfb6fd362020-03-04 21:03:59 +0000497 """, returnStdout: true).trim()
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800498 showLinks(output)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000499 archiveArtifacts artifacts: 'test_summary.*', allowEmptyArchive: true
Xinyu Zhang1b8f5152020-11-13 16:10:58 +0800500 archiveArtifacts artifacts: 'test_results.csv', allowEmptyArchive: true
Matthew Hartfb6fd362020-03-04 21:03:59 +0000501 g = new Gerrit()
Dean Birch1d545c02020-05-29 14:09:21 +0100502 def (boot_result, boot_output) = getResult(output, 'BOOT_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000503 if (boot_result) {
504 g.verifyStatus(boot_result, "lava_boot", "test")
505 }
Dean Birch1d545c02020-05-29 14:09:21 +0100506 def (test_result, test_output) = getResult(output, 'TEST_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000507 if (test_result) {
508 g.verifyStatus(test_result, "lava_test", "test")
509 }
510 if (boot_result.toInteger() < 1 || test_result.toInteger() < 1) {
Dean Birch1d545c02020-05-29 14:09:21 +0100511 error("Marking job as failed due to failed boots: ${boot_output} or tests: ${test_output}")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000512 }
513 }
514 }
515 }
516 else {
517 print("There were no LAVA jobs to test.")
518 }
519 }
520 catch (Exception e) {
521 print("ERROR: ${e}")
522 success = false
523 } finally {
524 archiveArtifacts artifacts: 'tf-m-ci-scripts/lava_artifacts/**', allowEmptyArchive: true
Xinyu Zhang91609012020-12-09 17:35:49 +0800525 if (all_jobs.size() > 0) {
526 emailNotification(success, 'test', filterFailedTest(output))
527 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000528 cleanWs()
529 if (!success) {
530 error("There was an Error waiting for LAVA jobs")
531 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000532 }
533 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000534}