blob: 4d971bc5ddb615af9d97a57765d3a6c4bee298b2 [file] [log] [blame]
Dean Birch62c4f082020-01-17 16:13:26 +00001#!/usr/bin/env groovy
2//-------------------------------------------------------------------------------
Xinyu Zhang97114342021-01-21 14:08:03 +08003// Copyright (c) 2020-2021, 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
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 = []
Xinyu Zhang97114342021-01-21 14:08:03 +080095 if (build_params["TFM_PLATFORM"] == "musca_b1/sse_200" && \
96 build_params["OTP"] == "ENABLED") {
97 params += string(name: "TARGET_PLATFORM", value: "MUSCA_B1_OTP")
98 }
99 else {
100 params += string(name: "TARGET_PLATFORM", \
101 value: mapPlatform[build_params["TFM_PLATFORM"]])
102 }
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800103 params += string(name: "COMPILER", \
104 value: mapCompiler[build_params["TOOLCHAIN_FILE"]])
105 params += string(name: "PSA_API_SUITE", \
106 value: mapTestPsaApi[build_params["TEST_PSA_API"]])
107
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800108 configName = "Config"
109 config_params = [build_params["BL2"], build_params["NS"], \
110 build_params["PSA_API"], build_params["ISOLATION_LEVEL"], \
111 build_params["TEST_REGRESSION"], build_params["TEST_PSA_API"], \
112 build_params["PROFILE"]]
113 for (config in mapConfigs) {
114 if (config_params == config[0..6]) {
Xinyu Zhangfc1bacd2020-12-24 15:26:35 +0800115 configName += config[7].replace(' (', '_').replace(')', '')
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800116 break
117 }
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800118 }
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800119 if (configName == "Config") {
120 configName = "ConfigDefault"
121 }
122 params += string(name: "PROJ_CONFIG", value: configName)
Xinyu Zhangaa3747f2020-12-24 16:27:06 +0800123 print("Params of ${configName} :")
124 print(config_params)
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800125 return params
126}
127
Dean Birch62c4f082020-01-17 16:13:26 +0000128def listConfigs(ci_scripts_dir, config_list, filter_group) {
129 dir(ci_scripts_dir) {
130 echo "Obtaining list of configs."
Matthew Hartfb6fd362020-03-04 21:03:59 +0000131 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}"
Dean Birch62c4f082020-01-17 16:13:26 +0000132 def build_config_list_raw = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000133python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}
Dean Birch62c4f082020-01-17 16:13:26 +0000134""", returnStdout: true).trim()
135 def build_config_list = build_config_list_raw.tokenize('\n')
136 config_list.addAll(build_config_list)
137 }
138}
139
Matthew Hartfb6fd362020-03-04 21:03:59 +0000140def buildConfig(ci_scripts_dir, config, filter_group, results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000141 def params = []
Matthew Hartfb6fd362020-03-04 21:03:59 +0000142 def params_collection = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000143 def build_config_params
144 dir(ci_scripts_dir) {
145 echo "Obtaining build configuration for config ${config}"
Matthew Hartfb6fd362020-03-04 21:03:59 +0000146 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}"
Dean Birch62c4f082020-01-17 16:13:26 +0000147 build_config_params = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000148python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}
Dean Birch62c4f082020-01-17 16:13:26 +0000149""", returnStdout: true).trim()
150 }
151 def lines = build_config_params.tokenize('\n')
152 for (String line : lines) {
153 def key, value
154 (key, value) = line.tokenize('=')
155 params += string(name: key, value: value)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000156 params_collection[key] = value
Dean Birch62c4f082020-01-17 16:13:26 +0000157 }
158 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000159 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
160 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
161 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000162 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800163 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000164 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Karl Zhangf6f467e2020-07-10 16:24:45 +0800165 params += string(name: 'CODE_COVERAGE_EN', value: env.CODE_COVERAGE_EN)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000166 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000167 return { -> results
168 def build_res = build(job: 'tf-m-build-config', parameters: params, propagate: false)
169 def build_info = [build_res, config, params_collection]
170 results['builds'][build_res.number] = build_info
171 def build_url = build_res.getAbsoluteUrl()
172 print("${build_res.number}: ${config} ${build_res.result} ${build_url}")
173 failure_states = ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]
174 if (build_res.result in failure_states) {
175 error("Build failed at ${build_url}")
176 }
Karl Zhang2b10b342020-11-09 14:50:11 +0800177 else if (params_collection["NS"] == "False" || \
Karl Zhang0b7bb4a2021-01-18 16:22:08 +0800178 (params_collection["TFM_PLATFORM"].contains("musca_b1") && \
179 env.JOB_NAME.equals("tf-m-build-and-test")) || \
Xinyu Zhang661a17a2021-01-05 19:24:40 +0800180 (params_collection["PROFILE"] == "profile_medium" && \
181 params_collection["PARTITION_PS"] == "OFF")) {
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800182 print("LAVA is not needed for ${build_url}")
183 }
Xinyu Zhang97114342021-01-21 14:08:03 +0800184 // Only submit LAVA test for a specified OTP enabled config in nightly or release job
185 else if (params_collection["OTP"] == "ENABLED" && \
186 params_collection["CONFIG_NAME"] != "MUSCA_B1_ARMCLANG_PSA_3_REG_Debug_OTP_BL2_NS") {
187 print("LAVA is not needed for ${build_url}")
188 }
189 else if (params_collection["CONFIG_NAME"] == "MUSCA_B1_ARMCLANG_PSA_3_REG_Debug_OTP_BL2_NS" && \
190 !(env.JOB_NAME.equals("tf-m-nightly") || env.JOB_NAME.equals("tf-m-release"))) {
191 print("LAVA is not needed for ${build_url}")
192 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000193 else {
194 print("Doing LAVA stuff for ${build_url}")
Xinyu Zhangaa3747f2020-12-24 16:27:06 +0800195 params += generateLavaParam(params_collection)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000196 params += string(name: 'BUILD_NUMBER', value: "${build_res.number}")
197 params += string(name: 'BUILD_URL', value: build_url)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000198 params += string(name: 'LAVA_URL', value: env.LAVA_URL)
Dean Birch956416f2020-08-12 10:36:16 +0100199 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
200 params += string(name: 'LAVA_CREDENTIALS', value: env.LAVA_CREDENTIALS)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000201 def lava_res = build(job: 'tf-m-lava-submit', parameters: params, propagate: false)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000202 if (lava_res.result in failure_states) {
203 error("LAVA Create and Submit failed at ${lava_res.getAbsoluteUrl()}")
204 }
205 else {
206 results['lava_jobs'] += lava_res.getDescription()
207 }
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800208 links = "Build Config: ${config}\n"
209 links += "Build URL: ${build_url}\n"
210 links += "LAVA Submit: ${lava_res.getAbsoluteUrl()}"
211 print(links)
Dean Birch62c4f082020-01-17 16:13:26 +0000212 }
213 }
214}
215
Matthew Hart06340d72020-06-15 16:08:20 +0100216def buildDocs(results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000217 def params = []
218 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000219 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
220 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
221 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000222 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800223 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000224 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000225 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Matthew Hart06340d72020-06-15 16:08:20 +0100226 return { -> results
Dean Birch62c4f082020-01-17 16:13:26 +0000227 def res = build(job: 'tf-m-build-docs', parameters: params, propagate:false)
228 print("${res.number}: Docs ${res.result} ${res.getAbsoluteUrl()}")
Matthew Hart06340d72020-06-15 16:08:20 +0100229 results['docs'] = [res.number, res.result, params]
Dean Bircha6ede7e2020-03-13 14:00:33 +0000230 if (res.result in ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]) {
Dean Birch62c4f082020-01-17 16:13:26 +0000231 error("Build failed at ${res.getAbsoluteUrl()}")
232 }
233 }
234}
235
Xinyu Zhang38a18872020-11-23 16:45:28 +0800236def generateEmailBody(stage, failed_jobs) {
237 body = "Check console output at ${env.BUILD_URL} \n\n"
238
239 body += "Failed Jobs:\n"
240 failed_jobs.each { job ->
241 body += "${job.key} ${job.value}\n"
242 }
243
244 body += "\nFor detailed ${stage} results please refer to \
245 ${env.BUILD_URL}artifact/${stage}_results.csv \n"
246 return body
247}
248
249def emailNotification(results, stage, failed_jobs) {
Karl Zhang0413e972020-09-18 17:59:26 +0800250 script {
251 if (env.JOB_NAME.equals("tf-m-nightly") && !env.EMAIL_NOTIFICATION.equals('')) {
252 def result = "Fail."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800253 if (results == true) {
Karl Zhang0413e972020-09-18 17:59:26 +0800254 result = "Success."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800255 print("Skip sending as ${result} for ${stage}")
256 }
257 else {
258 emailext (
259 subject: ("Job ${env.JOB_NAME} ${stage} ${env.BUILD_NUMBER} ${result}"),
Xinyu Zhang38a18872020-11-23 16:45:28 +0800260 body: generateEmailBody(stage, failed_jobs),
Karl Zhang182ecdf2020-10-10 09:52:12 +0800261 to: "${EMAIL_NOTIFICATION}"
262 )
263 }
Karl Zhang0413e972020-09-18 17:59:26 +0800264 }
265 } /* script */
266}
267
Xinyu Zhang38a18872020-11-23 16:45:28 +0800268def filterFailedBuild(results) {
269 def failed_builds = [:]
270 results.each { result ->
271 if (result.value[0].getResult() == "FAILURE") {
272 failed_builds[result.value[1]] = result.value[0].getAbsoluteUrl()
273 }
274 }
275 return failed_builds
276}
277
278def filterFailedTest(string) {
279 def failed_tests = [:]
280 line = lineInString(string, "FAILURE_TESTS:")
281 a = line.split(' ')
282 if (a.size() > 1) {
283 a = line.split(' ')[1..-1]
284 a.each { fail_test ->
285 config_link = fail_test.split(':')
286 failed_tests[config_link[0]] = config_link[1..-1].join(':')
287 }
288 }
289 return failed_tests
290}
291
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800292@NonCPS
293def generateCsvContent(results) {
294 def resultsParam = []
295 results.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800296 if (result.value[2]['BL2'] == "True") {
297 resultsParam.add([result.value[1], \
298 result.value[0].getResult(), \
299 result.value[2]['TFM_PLATFORM'], \
300 result.value[2]['TOOLCHAIN_FILE'], \
301 result.value[2]['CMAKE_BUILD_TYPE'], \
302 result.value[2]['BL2'], \
303 result.value[2]['NS'], \
304 result.value[2]['PSA_API'], \
305 result.value[2]['ISOLATION_LEVEL'], \
306 result.value[2]['TEST_REGRESSION'], \
307 result.value[2]['TEST_PSA_API'], \
308 result.value[2]['PROFILE'], \
309 result.value[2]['PARTITION_PS'], \
310 result.value[2]['OTP']])
311 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800312 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800313 resultsParam.each { result ->
Xinyu Zhang18a73542020-12-24 14:19:07 +0800314 if (result[2] == 'musca_b1/sse_200') {
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800315 if (result[13] != 'off') {
Xinyu Zhang18a73542020-12-24 14:19:07 +0800316 result[2] = 'musca_b1/sse_200_OTP'
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800317 }
318 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800319 result[3] = mapCompiler[result[3]]
320 build_params = result[5..12]
321 configName = ""
322 for (map_cfg in mapConfigs) {
323 if (build_params[0..6] == map_cfg[0..6]) {
324 configName = map_cfg[7]
325 break
326 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800327 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800328 if (configName == "") {
329 configName = "Default"
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800330 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800331 else if (configName == "RegressionProfileM") {
332 if (build_params[7] == "OFF") {
333 configName = "RegressionProfileM PSOFF"
334 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800335 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800336 result.add(configName)
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800337 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800338 def csvContent = []
339 resultsParam.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800340 current_row = result[2..4]
341 cfgs.each {cfg ->
342 if (cfg == result[14]) {
343 current_row.add(cfg)
344 current_row.add(result[1])
345 }
346 }
347 csvContent.add(current_row)
348 }
349 csvContent.sort{a,b -> a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2]}
350 build_summary = []
351 current_platform = ""
352 current_compiler = ""
353 current_build_type = ""
354 csvContent.each { build_cfg ->
355 if (current_platform != build_cfg[0] || \
356 current_compiler != build_cfg[1] || \
357 current_build_type != build_cfg[2]) {
358 current_platform = build_cfg[0]
359 current_compiler = build_cfg[1]
360 current_build_type = build_cfg[2]
361 csv_line = [current_platform, current_compiler, current_build_type]
362 cfgs.each {
363 csv_line.add("N.A.")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800364 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800365 build_summary.add(csv_line)
366 }
367 i = 0
368 cfgs.each { cfg ->
369 if (cfg == build_cfg[3]) {
370 build_summary[-1][3+i] = build_cfg[4]
371 }
372 i += 1
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800373 }
374 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800375 build_summary.add(0, ['Platform', 'Compiler', 'Cmake Build Type'])
376 build_summary[0] += cfgs
377 return build_summary
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800378}
379
380def generateBuildCsv(results) {
381 def csvContent = generateCsvContent(results)
382 node("master") {
383 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
384 archiveArtifacts 'build_results.csv'
385 }
386}
Dean Bircha6ede7e2020-03-13 14:00:33 +0000387
388def buildCsv(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000389 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000390 def csvContent = summary.getBuildCsv(results)
391 node("master") {
392 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
393 archiveArtifacts 'build_results.csv'
394 }
395}
396
397def writeSummary(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000398 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000399 def buildLinks = summary.getLinks(results)
400 node("master") {
401 writeFile file: "build_links.html", text: buildLinks
402 archiveArtifacts 'build_links.html'
403 }
404}
405
Matthew Hartfb6fd362020-03-04 21:03:59 +0000406def lineInString(string, match) {
407 def lines = string.split("\n")
408 def result = lines.findAll { it.contains(match) }
409 return result[0]
410}
411
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800412def showLinks(string) {
413 def lines = string.split("\n")
414 def result = lines.findAll { it.contains("Build Config: ")}
415 links = result.join("\n")
416 print(links)
417}
418
Matthew Hartfb6fd362020-03-04 21:03:59 +0000419def getResult(string, match) {
420 line = lineInString(string, match)
Dean Birch1d545c02020-05-29 14:09:21 +0100421 a = line.split(match)[1].split(' ')
422 score = a[0]
423 if (a.size() > 1)
424 {
425 fail_text = a[1..-1].join(" ")
426 return [score, fail_text]
427 }
428 return [score, ""]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000429}
430
431def submitJobsToList(results) {
432 def all_jobs = []
433 for (String result : results){
434 jobs_s = result.split('JOBS: ')
435 if (jobs_s.size() > 1) {
436 all_jobs += jobs_s[1]
437 }
438 }
439 return(all_jobs)
440}
441
Dean Birch62c4f082020-01-17 16:13:26 +0000442def configs = []
443def builds = [:]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000444def results = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000445
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000446node("docker-amd64-tf-m-bionic") {
Dean Birch62c4f082020-01-17 16:13:26 +0000447 stage("Init") {
448 cleanWs()
449 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000450 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Birch62c4f082020-01-17 16:13:26 +0000451 }
452 }
453 stage("Configs") {
454 // Populate configs
455 listConfigs('tf-m-ci-scripts', configs, env.FILTER_GROUP)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000456 results['builds'] = [:]
457 results['lava_jobs'] = []
Dean Birch62c4f082020-01-17 16:13:26 +0000458 for (config in configs) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000459 builds[config] = buildConfig("tf-m-ci-scripts", config, env.FILTER_GROUP, results)
Dean Birch62c4f082020-01-17 16:13:26 +0000460 }
Matthew Hart06340d72020-06-15 16:08:20 +0100461 builds["docs"] = buildDocs(results)
Dean Birch62c4f082020-01-17 16:13:26 +0000462 }
463}
Karl Zhangfec84102020-06-24 09:56:36 +0800464
Dean Birch62c4f082020-01-17 16:13:26 +0000465stage("Builds") {
466 def verify = 1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800467 def success = true
Dean Birch62c4f082020-01-17 16:13:26 +0000468 try {
469 parallel(builds)
470 } catch (Exception e) {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000471 print(e)
Dean Birch62c4f082020-01-17 16:13:26 +0000472 manager.buildFailure()
473 verify = -1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800474 success = false
Dean Birch62c4f082020-01-17 16:13:26 +0000475 } finally {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000476 print("Verifying status")
Xinyu Zhang38a18872020-11-23 16:45:28 +0800477 def failed_builds = filterFailedBuild(results['builds'])
478 emailNotification(success, 'build', failed_builds)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000479 g = new Gerrit()
480 g.verifyStatus(verify, 'tf-m-build', 'build')
Dean Bircha6ede7e2020-03-13 14:00:33 +0000481 print("Building CSV")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800482 generateBuildCsv(results['builds'])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000483 writeSummary(results['builds'])
Dean Birch62c4f082020-01-17 16:13:26 +0000484 }
485}
Matthew Hart06340d72020-06-15 16:08:20 +0100486
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000487node("docker-amd64-tf-m-bionic") {
Matthew Hart06340d72020-06-15 16:08:20 +0100488 stage("Copy Docs") {
Karl Zhang32497972020-09-21 14:38:29 +0800489 if (env.JOB_NAME.equals("tf-m-build-and-test")) {
490 step([$class: 'CopyArtifact', projectName: 'tf-m-build-docs',
491 selector: specific("${results['docs'][0]}"), target: './docs/',
492 optional: true])
493 archiveArtifacts artifacts: 'docs/**', allowEmptyArchive: true
494 }
495 else {
496 print("No doc copy for job: ${env.JOB_NAME}")
497 }
Matthew Hart06340d72020-06-15 16:08:20 +0100498 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000499 stage("Tests") {
500 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000501 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000502 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000503 def all_jobs = []
504 def success = true
Dean Bircha6ede7e2020-03-13 14:00:33 +0000505 print("Wait for LAVA results here...")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000506 try {
507 all_jobs = submitJobsToList(results['lava_jobs'])
508 if (all_jobs.size() > 0) {
509 dir("tf-m-ci-scripts") {
Dean Birch956416f2020-08-12 10:36:16 +0100510 withCredentials([usernamePassword(credentialsId: env.LAVA_CREDENTIALS, passwordVariable: 'LAVA_TOKEN', usernameVariable: 'LAVA_USER')]) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000511 output = sh(script: """./lava_helper/lava_wait_jobs.py --job-ids ${all_jobs.join(",")} \
512 --lava-url ${env.LAVA_URL} --lava-user ${LAVA_USER} --lava-token ${LAVA_TOKEN} \
Matthew Hart05a59b52020-05-27 17:54:51 +0100513 --artifacts-path lava_artifacts --lava-timeout 7200 \
Matthew Hartfb6fd362020-03-04 21:03:59 +0000514 """, returnStdout: true).trim()
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800515 showLinks(output)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000516 archiveArtifacts artifacts: 'test_summary.*', allowEmptyArchive: true
Xinyu Zhang1b8f5152020-11-13 16:10:58 +0800517 archiveArtifacts artifacts: 'test_results.csv', allowEmptyArchive: true
Matthew Hartfb6fd362020-03-04 21:03:59 +0000518 g = new Gerrit()
Dean Birch1d545c02020-05-29 14:09:21 +0100519 def (boot_result, boot_output) = getResult(output, 'BOOT_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000520 if (boot_result) {
521 g.verifyStatus(boot_result, "lava_boot", "test")
522 }
Dean Birch1d545c02020-05-29 14:09:21 +0100523 def (test_result, test_output) = getResult(output, 'TEST_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000524 if (test_result) {
525 g.verifyStatus(test_result, "lava_test", "test")
526 }
527 if (boot_result.toInteger() < 1 || test_result.toInteger() < 1) {
Dean Birch1d545c02020-05-29 14:09:21 +0100528 error("Marking job as failed due to failed boots: ${boot_output} or tests: ${test_output}")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000529 }
530 }
531 }
532 }
533 else {
534 print("There were no LAVA jobs to test.")
535 }
536 }
537 catch (Exception e) {
538 print("ERROR: ${e}")
539 success = false
540 } finally {
541 archiveArtifacts artifacts: 'tf-m-ci-scripts/lava_artifacts/**', allowEmptyArchive: true
Xinyu Zhang91609012020-12-09 17:35:49 +0800542 if (all_jobs.size() > 0) {
543 emailNotification(success, 'test', filterFailedTest(output))
544 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000545 cleanWs()
546 if (!success) {
547 error("There was an Error waiting for LAVA jobs")
548 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000549 }
550 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000551}