blob: 613e6b890b706410ac0b58546b93032c1f6918c5 [file] [log] [blame]
Dean Birch62c4f082020-01-17 16:13:26 +00001#!/usr/bin/env groovy
2//-------------------------------------------------------------------------------
Xinyu Zhang433771e2022-04-01 16:49:17 +08003// Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
Dean Birch62c4f082020-01-17 16:13:26 +00004//
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
Xinyu Zhang0aced4c2021-09-03 17:06:21 +080013failure_states = ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]
14
Summer Qin3c2b5722021-05-26 10:43:45 +080015mapPlatform = ["cypress/psoc64": "psoc64",
16 "arm/mps2/an519": "AN519",
17 "arm/mps2/an521": "AN521",
18 "arm/mps2/an539": "AN539",
19 "arm/mps2/sse-200_aws": "SSE-200_AWS",
20 "arm/mps3/an524": "AN524",
Bence Balogh176b78f2022-02-22 13:49:34 +010021 "arm/mps3/an547": "AN547",
22 "arm/mps3/an552": "AN552",
Bence Balogh8731a092022-05-24 17:24:54 +020023 "arm/mps3/corstone310_fvp": "corstone310",
Summer Qin3c2b5722021-05-26 10:43:45 +080024 "arm/musca_b1/sse_200": "MUSCA_B1",
25 "arm/musca_b1/secure_enclave": "MUSCA_B1_SE",
Arthur She19c0e1a2021-06-02 11:06:19 -070026 "arm/musca_s1": "MUSCA_S1",
Jamie Foxf3b8aa82022-09-08 11:52:01 +010027 "arm/rss": "RSS",
Xinyu Zhangfcb6aad2021-08-25 16:24:11 +080028 "stm/stm32l562e_dk": "stm32l562e_dk",
Xinyu Zhang6afdd612021-10-12 17:07:32 +080029 "arm/corstone1000": "corstone1000",
Arthur Shef3657742021-09-07 14:23:18 -070030 "nxp/lpcxpresso55s69": "lpcxpresso55s69"]
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +080031
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +080032mapBL2 = ["True": "--bl2",
33 "False": ""]
34
35mapTestPsaApi = ["OFF": "",
Xinyu Zhang39acb412021-07-09 20:35:19 +080036 "STORAGE": "STORAGE",
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +080037 "CRYPTO": "Crypto",
38 "INITIAL_ATTESTATION": "Attest",
39 "IPC": "FF"]
40
Xinyu Zhang73ed2992021-09-15 11:38:23 +080041// LIB_MODEL, ISOLATION_LEVEL, TEST_REG, TEST_PSA_API, PROFILE, CONFIG_NAME
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +080042mapConfigs = [
Xinyu Zhang73ed2992021-09-15 11:38:23 +080043 ["True", "1", "False", "OFF", "N.A", "Default"],
44 ["False", "1", "False", "OFF", "N.A", "CoreIPC"],
45 ["False", "2", "False", "OFF", "N.A", "CoreIPCTfmLevel2"],
46 ["False", "3", "False", "OFF", "N.A", "CoreIPCTfmLevel3"],
47 ["True", "1", "False", "OFF", "profile_small", "DefaultProfileS"],
48 ["False", "2", "False", "OFF", "profile_medium", "DefaultProfileM"],
49 ["False", "3", "False", "OFF", "profile_large", "DefaultProfileL"],
50 ["True", "1", "True", "OFF", "N.A", "Regression"],
51 ["False", "1", "True", "OFF", "N.A", "RegressionIPC"],
52 ["False", "2", "True", "OFF", "N.A", "RegressionIPCTfmLevel2"],
53 ["False", "3", "True", "OFF", "N.A", "RegressionIPCTfmLevel3"],
54 ["True", "1", "True", "OFF", "profile_small", "RegressionProfileS"],
55 ["False", "2", "True", "OFF", "profile_medium", "RegressionProfileM"],
56 ["False", "3", "True", "OFF", "profile_large", "RegressionProfileL"],
57 ["True", "1", "False", "STORAGE", "N.A", "PsaApiTest (STORAGE)"],
58 ["True", "1", "False", "CRYPTO", "N.A", "PsaApiTest (Crypto)"],
59 ["True", "1", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTest (Attest)"],
60 ["True", "1", "False", "IPC", "N.A", "PsaApiTest (FF)"],
61 ["False", "1", "False", "STORAGE", "N.A", "PsaApiTestIPC (STORAGE)"],
62 ["False", "1", "False", "CRYPTO", "N.A", "PsaApiTestIPC (Crypto)"],
63 ["False", "1", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPC (Attest)"],
64 ["False", "1", "False", "IPC", "N.A", "PsaApiTestIPC (FF)"],
65 ["False", "2", "False", "STORAGE", "N.A", "PsaApiTestIPCTfmLevel2 (STORAGE)"],
66 ["False", "2", "False", "CRYPTO", "N.A", "PsaApiTestIPCTfmLevel2 (Crypto)"],
67 ["False", "2", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPCTfmLevel2 (Attest)"],
68 ["False", "2", "False", "IPC", "N.A", "PsaApiTestIPCTfmLevel2 (FF)"],
69 ["False", "3", "False", "STORAGE", "N.A", "PsaApiTestIPCTfmLevel3 (STORAGE)"],
70 ["False", "3", "False", "CRYPTO", "N.A", "PsaApiTestIPCTfmLevel3 (Crypto)"],
71 ["False", "3", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPCTfmLevel3 (Attest)"],
72 ["False", "3", "False", "IPC", "N.A", "PsaApiTestIPCTfmLevel3 (FF)"],
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +080073]
74
75cfgs = ["Default", "CoreIPC", "CoreIPCTfmLevel2", "CoreIPCTfmLevel3",
76 "Regression", "RegressionIPC",
77 "RegressionIPCTfmLevel2", "RegressionIPCTfmLevel3",
78 "DefaultProfileS", "RegressionProfileS",
79 "DefaultProfileM", "RegressionProfileM", "RegressionProfileM PSOFF",
Xinyu Zhang9b1aef92021-03-12 15:36:44 +080080 "DefaultProfileL", "RegressionProfileL",
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +080081 "PsaApiTest (Attest)", "PsaApiTestIPC (Attest)",
82 "PsaApiTestIPCTfmLevel2 (Attest)",
83 "PsaApiTest (Crypto)", "PsaApiTestIPC (Crypto)",
84 "PsaApiTestIPCTfmLevel2 (Crypto)",
Xinyu Zhang39acb412021-07-09 20:35:19 +080085 "PsaApiTest (STORAGE)", "PsaApiTestIPC (STORAGE)",
86 "PsaApiTestIPCTfmLevel2 (STORAGE)",
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +080087 "PsaApiTestIPC (FF)",
88 "PsaApiTestIPCTfmLevel2 (FF)",
Xinyu Zhang39acb412021-07-09 20:35:19 +080089 "PsaApiTestIPCTfmLevel3 (STORAGE)", "PsaApiTestIPCTfmLevel3 (Crypto)",
90 "PsaApiTestIPCTfmLevel3 (Attest)", "PsaApiTestIPCTfmLevel3 (FF)"]
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +080091
Xinyu Zhangda895572022-07-18 17:52:46 +080092cfgSkipFVP = [
Xinyu Zhangfb80b5d2022-07-26 15:42:26 +080093 "AN519_GCC_IPC_2_REG_Debug_BL2",
94 "AN519_GCC_IPC_2_REG_Debug_BL2_MEDIUM",
95 "AN519_GCC_IPC_2_REG_Debug_BL2_MEDIUM_PSOFF",
96 "AN519_ARMCLANG_IPC_2_REG_Debug_BL2",
97 "AN519_ARMCLANG_IPC_2_REG_Debug_BL2_MEDIUM",
98 "AN521_ARMCLANG_IPC_2_REG_Debug_BL2",
99 "AN521_ARMCLANG_IPC_2_REG_Debug_BL2_NSCE",
100 "AN521_ARMCLANG_IPC_2_REG_Debug_BL2_MEDIUM",
Xinyu Zhangda895572022-07-18 17:52:46 +0800101]
102
Xinyu Zhangaa3747f2020-12-24 16:27:06 +0800103@NonCPS
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800104def generateLavaParam(build_params) {
105 def params = []
Xinyu Zhang589fd052022-04-19 17:54:16 +0800106 params += string(name: "TARGET_PLATFORM", \
107 value: mapPlatform[build_params["TFM_PLATFORM"]])
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800108 params += string(name: "COMPILER", \
Xinyu Zhang433771e2022-04-01 16:49:17 +0800109 value: build_params["COMPILER"].split('_')[0])
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800110 params += string(name: "PSA_API_SUITE", \
111 value: mapTestPsaApi[build_params["TEST_PSA_API"]])
112
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800113 configName = "Config"
Xinyu Zhang73ed2992021-09-15 11:38:23 +0800114 config_params = [build_params["LIB_MODEL"], build_params["ISOLATION_LEVEL"], \
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800115 build_params["TEST_REGRESSION"], build_params["TEST_PSA_API"], \
116 build_params["PROFILE"]]
Xinyu Zhang7c8d3372021-12-22 11:15:42 +0800117 // Regression Test is enabled if CRYPTO is ON
118 if (build_params["EXTRA_PARAMS"] == "CRYPTO_ON") {
119 config_params[2] = "True"
120 }
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800121 for (config in mapConfigs) {
Xinyu Zhang3f7e2f52021-09-02 13:43:57 +0800122 if (config_params == config[0..4]) {
123 configName += config[5].replace(' (', '_').replace(')', '')
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800124 break
125 }
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800126 }
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800127 if (configName == "Config") {
128 configName = "ConfigDefault"
129 }
130 params += string(name: "PROJ_CONFIG", value: configName)
Xinyu Zhangaa3747f2020-12-24 16:27:06 +0800131 print("Params of ${configName} :")
132 print(config_params)
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800133 return params
134}
135
Xinyu Zhang0aced4c2021-09-03 17:06:21 +0800136def submit_lava_tests(config, results, build_res, params, params_collection) {
137 print("Doing LAVA stuff for ${build_res.getAbsoluteUrl()}")
138 params += generateLavaParam(params_collection)
139 params += string(name: 'BUILD_NUMBER', value: "${build_res.number}")
140 params += string(name: 'BUILD_URL', value: build_res.getAbsoluteUrl())
141 params += string(name: 'LAVA_URL', value: env.LAVA_URL)
Paul Sokolovskydaa430a2022-01-06 09:59:16 +0300142 params += string(name: 'CI_SCRIPTS_REPO', value: env.CI_SCRIPTS_REPO)
Xinyu Zhang0aced4c2021-09-03 17:06:21 +0800143 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
144 params += string(name: 'LAVA_CREDENTIALS', value: env.LAVA_CREDENTIALS)
145 params += string(name: 'CODE_COVERAGE_EN', value: env.CODE_COVERAGE_EN)
Xinyu Zhangda895572022-07-18 17:52:46 +0800146 // Workaround: Configs in cfgSkipFVP fail on FVP but pass on physical boards
147 if (params_collection['CONFIG_NAME'] in cfgSkipFVP) {
148 params += string(name: 'DEVICE_FILTER', value: "--physical-board-only")
149 } else {
150 params += string(name: 'DEVICE_FILTER', value: env.DEVICE_FILTER)
151 }
Xinyu Zhang0aced4c2021-09-03 17:06:21 +0800152 def lava_res = build(job: 'tf-m-lava-submit', parameters: params, propagate: false)
153 def lava_resubmitted = false
154 if (lava_res.result in failure_states) {
155 error("LAVA Create and Submit failed at ${lava_res.getAbsoluteUrl()}")
156 } else {
157 lava_des = lava_res.getDescription()
158 if (lava_des.contains(" Submitted twice!")) {
159 lava_resubmitted = true
160 lava_des = lava_des - " Submitted twice!"
161 }
162 results['lava_jobs'] += lava_des
163 }
164 links = "Build Config: ${config}\n"
165 links += "Build URL: ${build_res.getAbsoluteUrl()}\n"
166 links += "LAVA Submit: ${lava_res.getAbsoluteUrl()}"
167 if (lava_resubmitted) {
168 links += "\nLAVA Job Re-Submitted!"
169 }
170 print(links)
171}
172
Dean Birch62c4f082020-01-17 16:13:26 +0000173def listConfigs(ci_scripts_dir, config_list, filter_group) {
174 dir(ci_scripts_dir) {
175 echo "Obtaining list of configs."
Matthew Hartfb6fd362020-03-04 21:03:59 +0000176 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}"
Dean Birch62c4f082020-01-17 16:13:26 +0000177 def build_config_list_raw = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000178python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}
Dean Birch62c4f082020-01-17 16:13:26 +0000179""", returnStdout: true).trim()
180 def build_config_list = build_config_list_raw.tokenize('\n')
181 config_list.addAll(build_config_list)
182 }
183}
184
Matthew Hartfb6fd362020-03-04 21:03:59 +0000185def buildConfig(ci_scripts_dir, config, filter_group, results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000186 def params = []
Matthew Hartfb6fd362020-03-04 21:03:59 +0000187 def params_collection = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000188 def build_config_params
189 dir(ci_scripts_dir) {
190 echo "Obtaining build configuration for config ${config}"
Matthew Hartfb6fd362020-03-04 21:03:59 +0000191 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}"
Dean Birch62c4f082020-01-17 16:13:26 +0000192 build_config_params = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000193python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}
Dean Birch62c4f082020-01-17 16:13:26 +0000194""", returnStdout: true).trim()
195 }
196 def lines = build_config_params.tokenize('\n')
197 for (String line : lines) {
198 def key, value
199 (key, value) = line.tokenize('=')
200 params += string(name: key, value: value)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000201 params_collection[key] = value
Dean Birch62c4f082020-01-17 16:13:26 +0000202 }
203 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000204 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
205 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
206 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000207 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800208 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000209 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Karl Zhangf6f467e2020-07-10 16:24:45 +0800210 params += string(name: 'CODE_COVERAGE_EN', value: env.CODE_COVERAGE_EN)
Paul Sokolovskydaa430a2022-01-06 09:59:16 +0300211 params += string(name: 'CI_SCRIPTS_REPO', value: env.CI_SCRIPTS_REPO)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000212 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Leonardo Sandoval7090b2c2021-09-17 13:20:44 -0500213 params += string(name: 'MCUBOOT_REFSPEC', value: env.MCUBOOT_REFSPEC)
214 params += string(name: 'MCUBOOT_URL', value: env.MCUBOOT_URL)
215 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Paul Sokolovsky8d288712022-01-13 00:53:03 +0300216 params += string(name: 'MBEDTLS_URL', value: env.MBEDTLS_URL)
Leonardo Sandoval7090b2c2021-09-17 13:20:44 -0500217 params += string(name: 'TFM_TESTS_REFSPEC', value: env.TFM_TESTS_REFSPEC)
218 params += string(name: 'TFM_TESTS_URL', value: env.TFM_TESTS_URL)
219 params += string(name: 'PSA_ARCH_TESTS_VERSION', value: env.PSA_ARCH_TESTS_VERSION)
220 params += string(name: 'PSA_ARCH_TESTS_URL', value: env.PSA_ARCH_TESTS_URL)
221 params += string(name: 'SHARE_FOLDER', value: env.SHARE_FOLDER)
Hugo L'Hostise55a2752021-01-27 11:09:08 +0000222 if (env.JOB_NAME.equals("tf-m-nightly")) { //Setting the Memory footprint gathering.
223 params += string(name: 'SQUAD_CONFIGURATIONS', value: env.SQUAD_CONFIGURATIONS)
224 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000225 return { -> results
226 def build_res = build(job: 'tf-m-build-config', parameters: params, propagate: false)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000227 def build_url = build_res.getAbsoluteUrl()
Xinyu Zhang0aced4c2021-09-03 17:06:21 +0800228 results['builds'][build_res.number] = [build_res, config, params_collection]
229
Dean Bircha6ede7e2020-03-13 14:00:33 +0000230 print("${build_res.number}: ${config} ${build_res.result} ${build_url}")
Xinyu Zhangf2ba9112021-09-02 13:31:16 +0800231
232 // Filter out configs do not need LAVA tests
233
234 // Configs with build failure do not need LAVA tests
Xinyu Zhang6aa579a2022-04-20 11:36:27 +0800235 if (build_res.result in failure_states) {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000236 error("Build failed at ${build_url}")
Arthur She3c0dadd2021-11-18 21:17:48 -0800237 } else {
238 // Build successful
Xinyu Zhang6aa579a2022-04-20 11:36:27 +0800239 // Job tf-m-extra-build does not need LAVA tests
240 if (env.JOB_NAME.equals("tf-m-extra-build")) {
241 print("LAVA is not needed in tf-m-extra-build job.")
242 }
Arthur She87602dc2022-02-06 14:42:18 -0800243 // Submit test job for NXP LPCXpresso55S69 & Cypress PSoC64
Xinyu Zhang6aa579a2022-04-20 11:36:27 +0800244 else if (params_collection["TFM_PLATFORM"].contains("lpcxpresso55s69") || params_collection["TFM_PLATFORM"].contains("psoc64")) {
Arthur She3c0dadd2021-11-18 21:17:48 -0800245 submit_lava_tests(config, results, build_res, params, params_collection)
246 } else {
247 // Configs without BL2 do not need LAVA tests
248 if (params_collection["BL2"] == "False") {
249 print("LAVA is not needed for ${build_url}")
250 }
Arthur She3c0dadd2021-11-18 21:17:48 -0800251 // LAVA tests on MUSCA_B1 are not needed in per-patch job
252 else if (params_collection["TFM_PLATFORM"].contains("musca_b1") && \
253 env.JOB_NAME.equals("tf-m-build-and-test")) {
254 print("LAVA is not needed for ${build_url}")
255 }
Satish Kumar1cfdd912022-08-01 09:24:07 +0100256 // LAVA tests on Corstone1000 FPGA config is not supported
257 else if (params_collection["TFM_PLATFORM"].contains("corstone1000") && \
258 params_collection["EXTRA_PARAMS"].contains("FPGA")) {
259 print("LAVA is not needed for ${build_url}")
260 }
Arthur She3c0dadd2021-11-18 21:17:48 -0800261 // Submit LAVA tests
262 else {
263 submit_lava_tests(config, results, build_res, params, params_collection)
264 }
265 }
Dean Birch62c4f082020-01-17 16:13:26 +0000266 }
267 }
268}
269
Matthew Hart06340d72020-06-15 16:08:20 +0100270def buildDocs(results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000271 def params = []
272 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000273 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
274 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
275 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000276 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Dean Birch62c4f082020-01-17 16:13:26 +0000277 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Paul Sokolovskydaa430a2022-01-06 09:59:16 +0300278 params += string(name: 'CI_SCRIPTS_REPO', value: env.CI_SCRIPTS_REPO)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000279 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Leonardo Sandoval7090b2c2021-09-17 13:20:44 -0500280 params += string(name: 'SHARE_FOLDER', value: env.SHARE_FOLDER)
Matthew Hart06340d72020-06-15 16:08:20 +0100281 return { -> results
Dean Birch62c4f082020-01-17 16:13:26 +0000282 def res = build(job: 'tf-m-build-docs', parameters: params, propagate:false)
283 print("${res.number}: Docs ${res.result} ${res.getAbsoluteUrl()}")
Matthew Hart06340d72020-06-15 16:08:20 +0100284 results['docs'] = [res.number, res.result, params]
Dean Bircha6ede7e2020-03-13 14:00:33 +0000285 if (res.result in ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]) {
Dean Birch62c4f082020-01-17 16:13:26 +0000286 error("Build failed at ${res.getAbsoluteUrl()}")
287 }
288 }
289}
290
Xinyu Zhang38a18872020-11-23 16:45:28 +0800291def generateEmailBody(stage, failed_jobs) {
292 body = "Check console output at ${env.BUILD_URL} \n\n"
293
294 body += "Failed Jobs:\n"
295 failed_jobs.each { job ->
296 body += "${job.key} ${job.value}\n"
297 }
298
299 body += "\nFor detailed ${stage} results please refer to \
300 ${env.BUILD_URL}artifact/${stage}_results.csv \n"
301 return body
302}
303
304def emailNotification(results, stage, failed_jobs) {
Karl Zhang0413e972020-09-18 17:59:26 +0800305 script {
306 if (env.JOB_NAME.equals("tf-m-nightly") && !env.EMAIL_NOTIFICATION.equals('')) {
307 def result = "Fail."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800308 if (results == true) {
Karl Zhang0413e972020-09-18 17:59:26 +0800309 result = "Success."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800310 print("Skip sending as ${result} for ${stage}")
311 }
312 else {
313 emailext (
314 subject: ("Job ${env.JOB_NAME} ${stage} ${env.BUILD_NUMBER} ${result}"),
Xinyu Zhang38a18872020-11-23 16:45:28 +0800315 body: generateEmailBody(stage, failed_jobs),
Karl Zhang182ecdf2020-10-10 09:52:12 +0800316 to: "${EMAIL_NOTIFICATION}"
317 )
318 }
Karl Zhang0413e972020-09-18 17:59:26 +0800319 }
320 } /* script */
321}
322
Xinyu Zhang38a18872020-11-23 16:45:28 +0800323def filterFailedBuild(results) {
324 def failed_builds = [:]
325 results.each { result ->
326 if (result.value[0].getResult() == "FAILURE") {
327 failed_builds[result.value[1]] = result.value[0].getAbsoluteUrl()
328 }
329 }
330 return failed_builds
331}
332
333def filterFailedTest(string) {
334 def failed_tests = [:]
335 line = lineInString(string, "FAILURE_TESTS:")
Paul Sokolovskyc5cf9e62022-04-26 22:03:23 +0300336 if (line == null) {
337 return ["???"];
338 }
Xinyu Zhang38a18872020-11-23 16:45:28 +0800339 a = line.split(' ')
340 if (a.size() > 1) {
341 a = line.split(' ')[1..-1]
342 a.each { fail_test ->
343 config_link = fail_test.split(':')
344 failed_tests[config_link[0]] = config_link[1..-1].join(':')
345 }
346 }
347 return failed_tests
348}
349
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800350@NonCPS
351def generateCsvContent(results) {
352 def resultsParam = []
353 results.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800354 if (result.value[2]['BL2'] == "True") {
355 resultsParam.add([result.value[1], \
356 result.value[0].getResult(), \
357 result.value[2]['TFM_PLATFORM'], \
Xinyu Zhang433771e2022-04-01 16:49:17 +0800358 result.value[2]['COMPILER'].split('_')[0], \
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800359 result.value[2]['CMAKE_BUILD_TYPE'], \
360 result.value[2]['BL2'], \
Xinyu Zhang73ed2992021-09-15 11:38:23 +0800361 result.value[2]['LIB_MODEL'], \
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800362 result.value[2]['ISOLATION_LEVEL'], \
363 result.value[2]['TEST_REGRESSION'], \
364 result.value[2]['TEST_PSA_API'], \
Xinyu Zhang589fd052022-04-19 17:54:16 +0800365 result.value[2]['PROFILE']])
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800366 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800367 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800368 resultsParam.each { result ->
Xinyu Zhang433771e2022-04-01 16:49:17 +0800369 result[3] = result[3].split('_')[0]
Xinyu Zhangfb80b5d2022-07-26 15:42:26 +0800370 build_params = result[6..10]
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800371 configName = ""
372 for (map_cfg in mapConfigs) {
Xinyu Zhang3f7e2f52021-09-02 13:43:57 +0800373 if (build_params[0..4] == map_cfg[0..4]) {
374 configName = map_cfg[5]
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800375 break
376 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800377 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800378 if (configName == "") {
379 configName = "Default"
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800380 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800381 else if (configName == "RegressionProfileM") {
Xinyu Zhang3f7e2f52021-09-02 13:43:57 +0800382 if (build_params[5] == "OFF") {
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800383 configName = "RegressionProfileM PSOFF"
384 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800385 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800386 result.add(configName)
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800387 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800388 def csvContent = []
389 resultsParam.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800390 current_row = result[2..4]
391 cfgs.each {cfg ->
Xinyu Zhangfb80b5d2022-07-26 15:42:26 +0800392 if (cfg == result[11]) {
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800393 current_row.add(cfg)
394 current_row.add(result[1])
395 }
396 }
397 csvContent.add(current_row)
398 }
399 csvContent.sort{a,b -> a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2]}
400 build_summary = []
401 current_platform = ""
402 current_compiler = ""
403 current_build_type = ""
404 csvContent.each { build_cfg ->
405 if (current_platform != build_cfg[0] || \
406 current_compiler != build_cfg[1] || \
407 current_build_type != build_cfg[2]) {
408 current_platform = build_cfg[0]
409 current_compiler = build_cfg[1]
410 current_build_type = build_cfg[2]
411 csv_line = [current_platform, current_compiler, current_build_type]
412 cfgs.each {
413 csv_line.add("N.A.")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800414 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800415 build_summary.add(csv_line)
416 }
417 i = 0
418 cfgs.each { cfg ->
419 if (cfg == build_cfg[3]) {
420 build_summary[-1][3+i] = build_cfg[4]
421 }
422 i += 1
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800423 }
424 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800425 build_summary.add(0, ['Platform', 'Compiler', 'Cmake Build Type'])
426 build_summary[0] += cfgs
427 return build_summary
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800428}
429
430def generateBuildCsv(results) {
431 def csvContent = generateCsvContent(results)
432 node("master") {
433 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
434 archiveArtifacts 'build_results.csv'
435 }
436}
Dean Bircha6ede7e2020-03-13 14:00:33 +0000437
438def buildCsv(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000439 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000440 def csvContent = summary.getBuildCsv(results)
441 node("master") {
442 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
443 archiveArtifacts 'build_results.csv'
444 }
445}
446
447def writeSummary(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000448 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000449 def buildLinks = summary.getLinks(results)
450 node("master") {
451 writeFile file: "build_links.html", text: buildLinks
452 archiveArtifacts 'build_links.html'
453 }
454}
455
Matthew Hartfb6fd362020-03-04 21:03:59 +0000456def lineInString(string, match) {
457 def lines = string.split("\n")
458 def result = lines.findAll { it.contains(match) }
459 return result[0]
460}
461
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800462def showLinks(string) {
463 def lines = string.split("\n")
464 def result = lines.findAll { it.contains("Build Config: ")}
465 links = result.join("\n")
466 print(links)
467}
468
Matthew Hartfb6fd362020-03-04 21:03:59 +0000469def getResult(string, match) {
470 line = lineInString(string, match)
Dean Birch1d545c02020-05-29 14:09:21 +0100471 a = line.split(match)[1].split(' ')
472 score = a[0]
473 if (a.size() > 1)
474 {
475 fail_text = a[1..-1].join(" ")
476 return [score, fail_text]
477 }
478 return [score, ""]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000479}
480
481def submitJobsToList(results) {
482 def all_jobs = []
483 for (String result : results){
484 jobs_s = result.split('JOBS: ')
485 if (jobs_s.size() > 1) {
486 all_jobs += jobs_s[1]
487 }
488 }
489 return(all_jobs)
490}
491
Dean Birch62c4f082020-01-17 16:13:26 +0000492def configs = []
493def builds = [:]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000494def results = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000495
Xinyu Zhang4cdfd1b2021-05-21 15:10:49 +0800496timestamps {
497 node("docker-amd64-tf-m-bionic") {
498 stage("Init") {
499 cleanWs()
500 dir("tf-m-ci-scripts") {
501 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Xinyu Zhang8472b852021-09-04 00:13:34 +0800502 sh "git rev-parse --short HEAD"
Leonardo Sandoval7090b2c2021-09-17 13:20:44 -0500503 // Clone TF-M repositories so share folder can be reused by downstream jobs
504 sh "./clone.sh"
Xinyu Zhang4cdfd1b2021-05-21 15:10:49 +0800505 }
506 }
507 stage("Configs") {
508 // Populate configs
509 listConfigs('tf-m-ci-scripts', configs, env.FILTER_GROUP)
510 results['builds'] = [:]
511 results['lava_jobs'] = []
512 for (config in configs) {
513 builds[config] = buildConfig("tf-m-ci-scripts", config, env.FILTER_GROUP, results)
514 }
Xinyu Zhang351f14c2021-11-15 14:30:09 +0800515 if (!env.JOB_NAME.equals("tf-m-extra-build")) {
516 builds["docs"] = buildDocs(results)
517 }
Dean Birch62c4f082020-01-17 16:13:26 +0000518 }
519 }
Karl Zhangfec84102020-06-24 09:56:36 +0800520
Xinyu Zhang4cdfd1b2021-05-21 15:10:49 +0800521 stage("Builds") {
522 def verify = 1
Matthew Hartfb6fd362020-03-04 21:03:59 +0000523 def success = true
Matthew Hartfb6fd362020-03-04 21:03:59 +0000524 try {
Xinyu Zhang4cdfd1b2021-05-21 15:10:49 +0800525 parallel(builds)
526 } catch (Exception e) {
527 print(e)
528 manager.buildFailure()
529 verify = -1
530 success = false
531 } finally {
532 print("Verifying status")
533 def failed_builds = filterFailedBuild(results['builds'])
534 emailNotification(success, 'build', failed_builds)
535 g = new Gerrit()
536 g.verifyStatus(verify, 'tf-m-build', 'build')
537 print("Building CSV")
538 generateBuildCsv(results['builds'])
539 writeSummary(results['builds'])
540 }
541 }
542
543 node("docker-amd64-tf-m-bionic") {
544 stage("Tests") {
545 dir("tf-m-ci-scripts") {
546 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
547 }
548 def all_jobs = []
549 def success = true
550 print("Wait for LAVA results here...")
551 try {
552 all_jobs = submitJobsToList(results['lava_jobs'])
Paul Sokolovsky437bc422022-02-01 17:57:13 +0300553 output = ""
Xinyu Zhang4cdfd1b2021-05-21 15:10:49 +0800554 if (all_jobs.size() > 0) {
Paul Sokolovsky3d522f72022-04-13 11:17:00 +0300555 dir(".") {
Xinyu Zhang4cdfd1b2021-05-21 15:10:49 +0800556 withCredentials([usernamePassword(credentialsId: env.LAVA_CREDENTIALS, passwordVariable: 'LAVA_TOKEN', usernameVariable: 'LAVA_USER')]) {
Paul Sokolovsky3d522f72022-04-13 11:17:00 +0300557 output = sh(script: """./tf-m-ci-scripts/lava_helper/lava_wait_jobs.py --job-ids ${all_jobs.join(",")} \
Xinyu Zhang4cdfd1b2021-05-21 15:10:49 +0800558 --lava-url ${env.LAVA_URL} --lava-user ${LAVA_USER} --lava-token ${LAVA_TOKEN} \
Paul Sokolovsky3d522f72022-04-13 11:17:00 +0300559 --artifacts-path cfgs --lava-timeout 12000 \
Xinyu Zhang4cdfd1b2021-05-21 15:10:49 +0800560 """, returnStdout: true).trim()
Paul Sokolovsky1b024ac2022-02-01 22:26:23 +0300561 println("--- output from lava_wait_jobs.py ---")
562 println(output)
563 println("--- end of output from lava_wait_jobs.py ---")
Xinyu Zhang4cdfd1b2021-05-21 15:10:49 +0800564 showLinks(output)
565 archiveArtifacts artifacts: 'test_summary.*', allowEmptyArchive: true
566 archiveArtifacts artifacts: 'test_results.csv', allowEmptyArchive: true
567 g = new Gerrit()
568 def (boot_result, boot_output) = getResult(output, 'BOOT_RESULT: ')
569 if (boot_result) {
570 g.verifyStatus(boot_result, "lava_boot", "test")
571 }
572 def (test_result, test_output) = getResult(output, 'TEST_RESULT: ')
573 if (test_result) {
574 g.verifyStatus(test_result, "lava_test", "test")
575 }
576 if (boot_result.toInteger() < 1 || test_result.toInteger() < 1) {
Paul Sokolovsky84dd94f2022-01-27 22:08:56 +0300577 error("Marking job as failed due to failed boots: \"${boot_output}\" or tests: \"${test_output}\"")
Xinyu Zhang4cdfd1b2021-05-21 15:10:49 +0800578 }
Paul Sokolovsky0136de02022-04-19 20:21:47 +0300579
580 if (env.CODE_COVERAGE_EN == "TRUE") {
581 println("Producing merged report")
582 sh(script: """./tf-m-ci-scripts/lava_helper/codecov_merge.sh""")
583 archiveArtifacts artifacts: 'merged_report/**', allowEmptyArchive: true
584 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000585 }
586 }
587 }
Xinyu Zhang4cdfd1b2021-05-21 15:10:49 +0800588 else {
589 print("There were no LAVA jobs to test.")
590 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000591 }
Xinyu Zhang4cdfd1b2021-05-21 15:10:49 +0800592 catch (Exception e) {
593 print("ERROR: ${e}")
594 success = false
595 } finally {
Paul Sokolovsky3d522f72022-04-13 11:17:00 +0300596 archiveArtifacts artifacts: 'cfgs/**', allowEmptyArchive: true
Xinyu Zhang4cdfd1b2021-05-21 15:10:49 +0800597 if (all_jobs.size() > 0) {
598 emailNotification(success, 'test', filterFailedTest(output))
599 }
600 cleanWs()
601 if (!success) {
602 error("There was an Error waiting for LAVA jobs")
603 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000604 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000605 }
606 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000607}