blob: 9061a10d1f7adf8ccad628446158cdabcf0db304 [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)
Hugo L'Hostise55a2752021-01-27 11:09:08 +0000167 if (env.JOB_NAME.equals("tf-m-nightly")) { //Setting the Memory footprint gathering.
168 params += string(name: 'SQUAD_CONFIGURATIONS', value: env.SQUAD_CONFIGURATIONS)
169 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000170 return { -> results
171 def build_res = build(job: 'tf-m-build-config', parameters: params, propagate: false)
172 def build_info = [build_res, config, params_collection]
173 results['builds'][build_res.number] = build_info
174 def build_url = build_res.getAbsoluteUrl()
175 print("${build_res.number}: ${config} ${build_res.result} ${build_url}")
176 failure_states = ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]
177 if (build_res.result in failure_states) {
178 error("Build failed at ${build_url}")
179 }
Karl Zhang2b10b342020-11-09 14:50:11 +0800180 else if (params_collection["NS"] == "False" || \
Karl Zhang0b7bb4a2021-01-18 16:22:08 +0800181 (params_collection["TFM_PLATFORM"].contains("musca_b1") && \
182 env.JOB_NAME.equals("tf-m-build-and-test")) || \
Xinyu Zhang661a17a2021-01-05 19:24:40 +0800183 (params_collection["PROFILE"] == "profile_medium" && \
184 params_collection["PARTITION_PS"] == "OFF")) {
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800185 print("LAVA is not needed for ${build_url}")
186 }
Xinyu Zhang97114342021-01-21 14:08:03 +0800187 // Only submit LAVA test for a specified OTP enabled config in nightly or release job
188 else if (params_collection["OTP"] == "ENABLED" && \
189 params_collection["CONFIG_NAME"] != "MUSCA_B1_ARMCLANG_PSA_3_REG_Debug_OTP_BL2_NS") {
190 print("LAVA is not needed for ${build_url}")
191 }
192 else if (params_collection["CONFIG_NAME"] == "MUSCA_B1_ARMCLANG_PSA_3_REG_Debug_OTP_BL2_NS" && \
193 !(env.JOB_NAME.equals("tf-m-nightly") || env.JOB_NAME.equals("tf-m-release"))) {
194 print("LAVA is not needed for ${build_url}")
195 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000196 else {
197 print("Doing LAVA stuff for ${build_url}")
Xinyu Zhangaa3747f2020-12-24 16:27:06 +0800198 params += generateLavaParam(params_collection)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000199 params += string(name: 'BUILD_NUMBER', value: "${build_res.number}")
200 params += string(name: 'BUILD_URL', value: build_url)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000201 params += string(name: 'LAVA_URL', value: env.LAVA_URL)
Dean Birch956416f2020-08-12 10:36:16 +0100202 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
203 params += string(name: 'LAVA_CREDENTIALS', value: env.LAVA_CREDENTIALS)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000204 def lava_res = build(job: 'tf-m-lava-submit', parameters: params, propagate: false)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000205 if (lava_res.result in failure_states) {
206 error("LAVA Create and Submit failed at ${lava_res.getAbsoluteUrl()}")
207 }
208 else {
209 results['lava_jobs'] += lava_res.getDescription()
210 }
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800211 links = "Build Config: ${config}\n"
212 links += "Build URL: ${build_url}\n"
213 links += "LAVA Submit: ${lava_res.getAbsoluteUrl()}"
214 print(links)
Dean Birch62c4f082020-01-17 16:13:26 +0000215 }
216 }
217}
218
Matthew Hart06340d72020-06-15 16:08:20 +0100219def buildDocs(results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000220 def params = []
221 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000222 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
223 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
224 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000225 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800226 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000227 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000228 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Matthew Hart06340d72020-06-15 16:08:20 +0100229 return { -> results
Dean Birch62c4f082020-01-17 16:13:26 +0000230 def res = build(job: 'tf-m-build-docs', parameters: params, propagate:false)
231 print("${res.number}: Docs ${res.result} ${res.getAbsoluteUrl()}")
Matthew Hart06340d72020-06-15 16:08:20 +0100232 results['docs'] = [res.number, res.result, params]
Dean Bircha6ede7e2020-03-13 14:00:33 +0000233 if (res.result in ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]) {
Dean Birch62c4f082020-01-17 16:13:26 +0000234 error("Build failed at ${res.getAbsoluteUrl()}")
235 }
236 }
237}
238
Xinyu Zhang38a18872020-11-23 16:45:28 +0800239def generateEmailBody(stage, failed_jobs) {
240 body = "Check console output at ${env.BUILD_URL} \n\n"
241
242 body += "Failed Jobs:\n"
243 failed_jobs.each { job ->
244 body += "${job.key} ${job.value}\n"
245 }
246
247 body += "\nFor detailed ${stage} results please refer to \
248 ${env.BUILD_URL}artifact/${stage}_results.csv \n"
249 return body
250}
251
252def emailNotification(results, stage, failed_jobs) {
Karl Zhang0413e972020-09-18 17:59:26 +0800253 script {
254 if (env.JOB_NAME.equals("tf-m-nightly") && !env.EMAIL_NOTIFICATION.equals('')) {
255 def result = "Fail."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800256 if (results == true) {
Karl Zhang0413e972020-09-18 17:59:26 +0800257 result = "Success."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800258 print("Skip sending as ${result} for ${stage}")
259 }
260 else {
261 emailext (
262 subject: ("Job ${env.JOB_NAME} ${stage} ${env.BUILD_NUMBER} ${result}"),
Xinyu Zhang38a18872020-11-23 16:45:28 +0800263 body: generateEmailBody(stage, failed_jobs),
Karl Zhang182ecdf2020-10-10 09:52:12 +0800264 to: "${EMAIL_NOTIFICATION}"
265 )
266 }
Karl Zhang0413e972020-09-18 17:59:26 +0800267 }
268 } /* script */
269}
270
Xinyu Zhang38a18872020-11-23 16:45:28 +0800271def filterFailedBuild(results) {
272 def failed_builds = [:]
273 results.each { result ->
274 if (result.value[0].getResult() == "FAILURE") {
275 failed_builds[result.value[1]] = result.value[0].getAbsoluteUrl()
276 }
277 }
278 return failed_builds
279}
280
281def filterFailedTest(string) {
282 def failed_tests = [:]
283 line = lineInString(string, "FAILURE_TESTS:")
284 a = line.split(' ')
285 if (a.size() > 1) {
286 a = line.split(' ')[1..-1]
287 a.each { fail_test ->
288 config_link = fail_test.split(':')
289 failed_tests[config_link[0]] = config_link[1..-1].join(':')
290 }
291 }
292 return failed_tests
293}
294
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800295@NonCPS
296def generateCsvContent(results) {
297 def resultsParam = []
298 results.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800299 if (result.value[2]['BL2'] == "True") {
300 resultsParam.add([result.value[1], \
301 result.value[0].getResult(), \
302 result.value[2]['TFM_PLATFORM'], \
303 result.value[2]['TOOLCHAIN_FILE'], \
304 result.value[2]['CMAKE_BUILD_TYPE'], \
305 result.value[2]['BL2'], \
306 result.value[2]['NS'], \
307 result.value[2]['PSA_API'], \
308 result.value[2]['ISOLATION_LEVEL'], \
309 result.value[2]['TEST_REGRESSION'], \
310 result.value[2]['TEST_PSA_API'], \
311 result.value[2]['PROFILE'], \
312 result.value[2]['PARTITION_PS'], \
313 result.value[2]['OTP']])
314 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800315 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800316 resultsParam.each { result ->
Xinyu Zhang18a73542020-12-24 14:19:07 +0800317 if (result[2] == 'musca_b1/sse_200') {
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800318 if (result[13] != 'off') {
Xinyu Zhang18a73542020-12-24 14:19:07 +0800319 result[2] = 'musca_b1/sse_200_OTP'
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800320 }
321 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800322 result[3] = mapCompiler[result[3]]
323 build_params = result[5..12]
324 configName = ""
325 for (map_cfg in mapConfigs) {
326 if (build_params[0..6] == map_cfg[0..6]) {
327 configName = map_cfg[7]
328 break
329 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800330 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800331 if (configName == "") {
332 configName = "Default"
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800333 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800334 else if (configName == "RegressionProfileM") {
335 if (build_params[7] == "OFF") {
336 configName = "RegressionProfileM PSOFF"
337 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800338 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800339 result.add(configName)
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800340 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800341 def csvContent = []
342 resultsParam.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800343 current_row = result[2..4]
344 cfgs.each {cfg ->
345 if (cfg == result[14]) {
346 current_row.add(cfg)
347 current_row.add(result[1])
348 }
349 }
350 csvContent.add(current_row)
351 }
352 csvContent.sort{a,b -> a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2]}
353 build_summary = []
354 current_platform = ""
355 current_compiler = ""
356 current_build_type = ""
357 csvContent.each { build_cfg ->
358 if (current_platform != build_cfg[0] || \
359 current_compiler != build_cfg[1] || \
360 current_build_type != build_cfg[2]) {
361 current_platform = build_cfg[0]
362 current_compiler = build_cfg[1]
363 current_build_type = build_cfg[2]
364 csv_line = [current_platform, current_compiler, current_build_type]
365 cfgs.each {
366 csv_line.add("N.A.")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800367 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800368 build_summary.add(csv_line)
369 }
370 i = 0
371 cfgs.each { cfg ->
372 if (cfg == build_cfg[3]) {
373 build_summary[-1][3+i] = build_cfg[4]
374 }
375 i += 1
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800376 }
377 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800378 build_summary.add(0, ['Platform', 'Compiler', 'Cmake Build Type'])
379 build_summary[0] += cfgs
380 return build_summary
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800381}
382
383def generateBuildCsv(results) {
384 def csvContent = generateCsvContent(results)
385 node("master") {
386 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
387 archiveArtifacts 'build_results.csv'
388 }
389}
Dean Bircha6ede7e2020-03-13 14:00:33 +0000390
391def buildCsv(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000392 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000393 def csvContent = summary.getBuildCsv(results)
394 node("master") {
395 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
396 archiveArtifacts 'build_results.csv'
397 }
398}
399
400def writeSummary(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000401 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000402 def buildLinks = summary.getLinks(results)
403 node("master") {
404 writeFile file: "build_links.html", text: buildLinks
405 archiveArtifacts 'build_links.html'
406 }
407}
408
Matthew Hartfb6fd362020-03-04 21:03:59 +0000409def lineInString(string, match) {
410 def lines = string.split("\n")
411 def result = lines.findAll { it.contains(match) }
412 return result[0]
413}
414
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800415def showLinks(string) {
416 def lines = string.split("\n")
417 def result = lines.findAll { it.contains("Build Config: ")}
418 links = result.join("\n")
419 print(links)
420}
421
Matthew Hartfb6fd362020-03-04 21:03:59 +0000422def getResult(string, match) {
423 line = lineInString(string, match)
Dean Birch1d545c02020-05-29 14:09:21 +0100424 a = line.split(match)[1].split(' ')
425 score = a[0]
426 if (a.size() > 1)
427 {
428 fail_text = a[1..-1].join(" ")
429 return [score, fail_text]
430 }
431 return [score, ""]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000432}
433
434def submitJobsToList(results) {
435 def all_jobs = []
436 for (String result : results){
437 jobs_s = result.split('JOBS: ')
438 if (jobs_s.size() > 1) {
439 all_jobs += jobs_s[1]
440 }
441 }
442 return(all_jobs)
443}
444
Dean Birch62c4f082020-01-17 16:13:26 +0000445def configs = []
446def builds = [:]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000447def results = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000448
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000449node("docker-amd64-tf-m-bionic") {
Dean Birch62c4f082020-01-17 16:13:26 +0000450 stage("Init") {
451 cleanWs()
452 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000453 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Birch62c4f082020-01-17 16:13:26 +0000454 }
455 }
456 stage("Configs") {
457 // Populate configs
458 listConfigs('tf-m-ci-scripts', configs, env.FILTER_GROUP)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000459 results['builds'] = [:]
460 results['lava_jobs'] = []
Dean Birch62c4f082020-01-17 16:13:26 +0000461 for (config in configs) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000462 builds[config] = buildConfig("tf-m-ci-scripts", config, env.FILTER_GROUP, results)
Dean Birch62c4f082020-01-17 16:13:26 +0000463 }
Matthew Hart06340d72020-06-15 16:08:20 +0100464 builds["docs"] = buildDocs(results)
Dean Birch62c4f082020-01-17 16:13:26 +0000465 }
466}
Karl Zhangfec84102020-06-24 09:56:36 +0800467
Dean Birch62c4f082020-01-17 16:13:26 +0000468stage("Builds") {
469 def verify = 1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800470 def success = true
Dean Birch62c4f082020-01-17 16:13:26 +0000471 try {
472 parallel(builds)
473 } catch (Exception e) {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000474 print(e)
Dean Birch62c4f082020-01-17 16:13:26 +0000475 manager.buildFailure()
476 verify = -1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800477 success = false
Dean Birch62c4f082020-01-17 16:13:26 +0000478 } finally {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000479 print("Verifying status")
Xinyu Zhang38a18872020-11-23 16:45:28 +0800480 def failed_builds = filterFailedBuild(results['builds'])
481 emailNotification(success, 'build', failed_builds)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000482 g = new Gerrit()
483 g.verifyStatus(verify, 'tf-m-build', 'build')
Dean Bircha6ede7e2020-03-13 14:00:33 +0000484 print("Building CSV")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800485 generateBuildCsv(results['builds'])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000486 writeSummary(results['builds'])
Dean Birch62c4f082020-01-17 16:13:26 +0000487 }
488}
Matthew Hart06340d72020-06-15 16:08:20 +0100489
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000490node("docker-amd64-tf-m-bionic") {
Matthew Hart06340d72020-06-15 16:08:20 +0100491 stage("Copy Docs") {
Karl Zhang32497972020-09-21 14:38:29 +0800492 if (env.JOB_NAME.equals("tf-m-build-and-test")) {
493 step([$class: 'CopyArtifact', projectName: 'tf-m-build-docs',
494 selector: specific("${results['docs'][0]}"), target: './docs/',
495 optional: true])
496 archiveArtifacts artifacts: 'docs/**', allowEmptyArchive: true
497 }
498 else {
499 print("No doc copy for job: ${env.JOB_NAME}")
500 }
Matthew Hart06340d72020-06-15 16:08:20 +0100501 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000502 stage("Tests") {
503 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000504 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000505 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000506 def all_jobs = []
507 def success = true
Dean Bircha6ede7e2020-03-13 14:00:33 +0000508 print("Wait for LAVA results here...")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000509 try {
510 all_jobs = submitJobsToList(results['lava_jobs'])
511 if (all_jobs.size() > 0) {
512 dir("tf-m-ci-scripts") {
Dean Birch956416f2020-08-12 10:36:16 +0100513 withCredentials([usernamePassword(credentialsId: env.LAVA_CREDENTIALS, passwordVariable: 'LAVA_TOKEN', usernameVariable: 'LAVA_USER')]) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000514 output = sh(script: """./lava_helper/lava_wait_jobs.py --job-ids ${all_jobs.join(",")} \
515 --lava-url ${env.LAVA_URL} --lava-user ${LAVA_USER} --lava-token ${LAVA_TOKEN} \
Matthew Hart05a59b52020-05-27 17:54:51 +0100516 --artifacts-path lava_artifacts --lava-timeout 7200 \
Matthew Hartfb6fd362020-03-04 21:03:59 +0000517 """, returnStdout: true).trim()
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800518 showLinks(output)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000519 archiveArtifacts artifacts: 'test_summary.*', allowEmptyArchive: true
Xinyu Zhang1b8f5152020-11-13 16:10:58 +0800520 archiveArtifacts artifacts: 'test_results.csv', allowEmptyArchive: true
Matthew Hartfb6fd362020-03-04 21:03:59 +0000521 g = new Gerrit()
Dean Birch1d545c02020-05-29 14:09:21 +0100522 def (boot_result, boot_output) = getResult(output, 'BOOT_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000523 if (boot_result) {
524 g.verifyStatus(boot_result, "lava_boot", "test")
525 }
Dean Birch1d545c02020-05-29 14:09:21 +0100526 def (test_result, test_output) = getResult(output, 'TEST_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000527 if (test_result) {
528 g.verifyStatus(test_result, "lava_test", "test")
529 }
530 if (boot_result.toInteger() < 1 || test_result.toInteger() < 1) {
Dean Birch1d545c02020-05-29 14:09:21 +0100531 error("Marking job as failed due to failed boots: ${boot_output} or tests: ${test_output}")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000532 }
533 }
534 }
535 }
536 else {
537 print("There were no LAVA jobs to test.")
538 }
539 }
540 catch (Exception e) {
541 print("ERROR: ${e}")
542 success = false
543 } finally {
544 archiveArtifacts artifacts: 'tf-m-ci-scripts/lava_artifacts/**', allowEmptyArchive: true
Xinyu Zhang91609012020-12-09 17:35:49 +0800545 if (all_jobs.size() > 0) {
546 emailNotification(success, 'test', filterFailedTest(output))
547 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000548 cleanWs()
549 if (!success) {
550 error("There was an Error waiting for LAVA jobs")
551 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000552 }
553 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000554}