blob: f742d50c957e862de9c711e5ee075c82ae90b515 [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 Zhangaa3747f2020-12-24 16:27:06 +080092@NonCPS
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +080093def generateLavaParam(build_params) {
94 def params = []
95 params += string(name: "TARGET_PLATFORM", \
96 value: mapPlatform[build_params["TFM_PLATFORM"]])
97 params += string(name: "COMPILER", \
98 value: mapCompiler[build_params["TOOLCHAIN_FILE"]])
99 params += string(name: "PSA_API_SUITE", \
100 value: mapTestPsaApi[build_params["TEST_PSA_API"]])
101
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800102 configName = "Config"
103 config_params = [build_params["BL2"], build_params["NS"], \
104 build_params["PSA_API"], build_params["ISOLATION_LEVEL"], \
105 build_params["TEST_REGRESSION"], build_params["TEST_PSA_API"], \
106 build_params["PROFILE"]]
107 for (config in mapConfigs) {
108 if (config_params == config[0..6]) {
109 configName += config[7].split(' ')[0]
110 break
111 }
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800112 }
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800113 if (configName == "Config") {
114 configName = "ConfigDefault"
115 }
116 params += string(name: "PROJ_CONFIG", value: configName)
Xinyu Zhangaa3747f2020-12-24 16:27:06 +0800117 print("Params of ${configName} :")
118 print(config_params)
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800119 return params
120}
121
Dean Birch62c4f082020-01-17 16:13:26 +0000122def listConfigs(ci_scripts_dir, config_list, filter_group) {
123 dir(ci_scripts_dir) {
124 echo "Obtaining list of configs."
Matthew Hartfb6fd362020-03-04 21:03:59 +0000125 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}"
Dean Birch62c4f082020-01-17 16:13:26 +0000126 def build_config_list_raw = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000127python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}
Dean Birch62c4f082020-01-17 16:13:26 +0000128""", returnStdout: true).trim()
129 def build_config_list = build_config_list_raw.tokenize('\n')
130 config_list.addAll(build_config_list)
131 }
132}
133
Matthew Hartfb6fd362020-03-04 21:03:59 +0000134def buildConfig(ci_scripts_dir, config, filter_group, results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000135 def params = []
Matthew Hartfb6fd362020-03-04 21:03:59 +0000136 def params_collection = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000137 def build_config_params
138 dir(ci_scripts_dir) {
139 echo "Obtaining build configuration for config ${config}"
Matthew Hartfb6fd362020-03-04 21:03:59 +0000140 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}"
Dean Birch62c4f082020-01-17 16:13:26 +0000141 build_config_params = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000142python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}
Dean Birch62c4f082020-01-17 16:13:26 +0000143""", returnStdout: true).trim()
144 }
145 def lines = build_config_params.tokenize('\n')
146 for (String line : lines) {
147 def key, value
148 (key, value) = line.tokenize('=')
149 params += string(name: key, value: value)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000150 params_collection[key] = value
Dean Birch62c4f082020-01-17 16:13:26 +0000151 }
152 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000153 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
154 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
155 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000156 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800157 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000158 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Karl Zhangf6f467e2020-07-10 16:24:45 +0800159 params += string(name: 'CODE_COVERAGE_EN', value: env.CODE_COVERAGE_EN)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000160 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000161 return { -> results
162 def build_res = build(job: 'tf-m-build-config', parameters: params, propagate: false)
163 def build_info = [build_res, config, params_collection]
164 results['builds'][build_res.number] = build_info
165 def build_url = build_res.getAbsoluteUrl()
166 print("${build_res.number}: ${config} ${build_res.result} ${build_url}")
167 failure_states = ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]
168 if (build_res.result in failure_states) {
169 error("Build failed at ${build_url}")
170 }
Karl Zhang2b10b342020-11-09 14:50:11 +0800171 else if (params_collection["NS"] == "False" || \
172 (params_collection["PROFILE"] == "profile_medium" && \
173 params_collection["PARTITION_PS"] == "OFF")) {
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800174 print("LAVA is not needed for ${build_url}")
175 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000176 else {
177 print("Doing LAVA stuff for ${build_url}")
Xinyu Zhangaa3747f2020-12-24 16:27:06 +0800178 params += generateLavaParam(params_collection)
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}