blob: 9d215c73821ec6952d5e2ad6537083acf700a1c7 [file] [log] [blame]
Dean Birch62c4f082020-01-17 16:13:26 +00001#!/usr/bin/env groovy
2//-------------------------------------------------------------------------------
3// Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
4//
5// SPDX-License-Identifier: BSD-3-Clause
6//
7//-------------------------------------------------------------------------------
8
Dean Birchd0f9f8c2020-03-26 11:10:33 +00009@Library('trustedfirmware') _
10import org.trustedfirmware.Gerrit
11import org.trustedfirmware.Summary
Dean Bircha6ede7e2020-03-13 14:00:33 +000012
Mark Horvath8d281cd2020-12-07 15:20:26 +010013mapPlatform = ["cypress/psoc64": "psoc64",
14 "mps2/an519": "AN519",
15 "mps2/an521": "AN521",
16 "mps2/an539": "AN539",
17 "mps2/sse-200_aws": "SSE-200_AWS",
18 "mps3/an524": "AN524",
19 "musca_a": "MUSCA_A",
20 "musca_b1/sse_200": "MUSCA_B1",
21 "musca_b1/secure_enclave": "MUSCA_B1_SE",
22 "musca_s1": "MUSCA_S1"]
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +080023
24mapCompiler = ["toolchain_GNUARM.cmake": "GNUARM",
25 "toolchain_ARMCLANG.cmake": "ARMCLANG"]
26
27mapBL2 = ["True": "--bl2",
28 "False": ""]
29
30mapTestPsaApi = ["OFF": "",
31 "INTERNAL_TRUSTED_STORAGE": "ITS",
32 "PROTECTED_STORAGE": "PS",
33 "CRYPTO": "Crypto",
34 "INITIAL_ATTESTATION": "Attest",
35 "IPC": "FF"]
36
Xinyu Zhangdbfadae2020-12-07 14:42:59 +080037// BL2, NS, PSA_API, ISOLATION_LEVEL, TEST_REG, TEST_PSA_API, PROFILE, CONFIG_NAME
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +080038mapConfigs = [
39 ["True", "True", "False", "1", "False", "OFF", "N.A", "Default"],
40 ["True", "True", "True", "1", "False", "OFF", "N.A", "CoreIPC"],
41 ["True", "True", "True", "2", "False", "OFF", "N.A", "CoreIPCTfmLevel2"],
42 ["True", "True", "True", "3", "False", "OFF", "N.A", "CoreIPCTfmLevel3"],
43 ["True", "True", "False", "1", "False", "OFF", "profile_small", "DefaultProfileS"],
44 ["True", "True", "True", "2", "False", "OFF", "profile_medium", "DefaultProfileM"],
45 ["True", "True", "False", "1", "True", "OFF", "N.A", "Regression"],
46 ["True", "True", "True", "1", "True", "OFF", "N.A", "RegressionIPC"],
47 ["True", "True", "True", "2", "True", "OFF", "N.A", "RegressionIPCTfmLevel2"],
48 ["True", "True", "True", "3", "True", "OFF", "N.A", "RegressionIPCTfmLevel3"],
49 ["True", "True", "False", "1", "True", "OFF", "profile_small", "RegressionProfileS"],
50 ["True", "True", "True", "2", "True", "OFF", "profile_medium", "RegressionProfileM"],
51 ["True", "True", "False", "1", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTest (ITS)"],
52 ["True", "True", "False", "1", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTest (PS)"],
53 ["True", "True", "False", "1", "False", "CRYPTO", "N.A", "PsaApiTest (Crypto)"],
54 ["True", "True", "False", "1", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTest (Attest)"],
55 ["True", "True", "False", "1", "False", "IPC", "N.A", "PsaApiTest (FF)"],
56 ["True", "True", "True", "1", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTestIPC (ITS)"],
57 ["True", "True", "True", "1", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTestIPC (PS)"],
58 ["True", "True", "True", "1", "False", "CRYPTO", "N.A", "PsaApiTestIPC (Crypto)"],
59 ["True", "True", "True", "1", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPC (Attest)"],
60 ["True", "True", "True", "1", "False", "IPC", "N.A", "PsaApiTestIPC (FF)"],
61 ["True", "True", "True", "2", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel2 (ITS)"],
62 ["True", "True", "True", "2", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel2 (PS)"],
63 ["True", "True", "True", "2", "False", "CRYPTO", "N.A", "PsaApiTestIPCTfmLevel2 (Crypto)"],
64 ["True", "True", "True", "2", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPCTfmLevel2 (Attest)"],
65 ["True", "True", "True", "2", "False", "IPC", "N.A", "PsaApiTestIPCTfmLevel2 (FF)"],
66 ["True", "True", "True", "3", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel3 (ITS)"],
67 ["True", "True", "True", "3", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel3 (PS)"],
68 ["True", "True", "True", "3", "False", "CRYPTO", "N.A", "PsaApiTestIPCTfmLevel3 (Crypto)"],
69 ["True", "True", "True", "3", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPCTfmLevel3 (Attest)"],
70 ["True", "True", "True", "3", "False", "IPC", "N.A", "PsaApiTestIPCTfmLevel3 (FF)"],
71]
72
73cfgs = ["Default", "CoreIPC", "CoreIPCTfmLevel2", "CoreIPCTfmLevel3",
74 "Regression", "RegressionIPC",
75 "RegressionIPCTfmLevel2", "RegressionIPCTfmLevel3",
76 "DefaultProfileS", "RegressionProfileS",
77 "DefaultProfileM", "RegressionProfileM", "RegressionProfileM PSOFF",
78 "PsaApiTest (Attest)", "PsaApiTestIPC (Attest)",
79 "PsaApiTestIPCTfmLevel2 (Attest)",
80 "PsaApiTest (Crypto)", "PsaApiTestIPC (Crypto)",
81 "PsaApiTestIPCTfmLevel2 (Crypto)",
82 "PsaApiTest (PS)", "PsaApiTestIPC (PS)",
83 "PsaApiTestIPCTfmLevel2 (PS)",
84 "PsaApiTest (ITS)", "PsaApiTestIPC (ITS)",
85 "PsaApiTestIPCTfmLevel2 (ITS)",
86 "PsaApiTestIPC (FF)",
87 "PsaApiTestIPCTfmLevel2 (FF)",
88 "PsaApiTestIPCTfmLevel3 (ITS)", "PsaApiTestIPCTfmLevel3 (PS)",
89 "PsaApiTestIPCTfmLevel3 (Crypto)", "PsaApiTestIPCTfmLevel3 (Attest)",
90 "PsaApiTestIPCTfmLevel3 (FF)"]
91
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +080092def generateLavaParam(build_params) {
93 def params = []
94 params += string(name: "TARGET_PLATFORM", \
95 value: mapPlatform[build_params["TFM_PLATFORM"]])
96 params += string(name: "COMPILER", \
97 value: mapCompiler[build_params["TOOLCHAIN_FILE"]])
98 params += string(name: "PSA_API_SUITE", \
99 value: mapTestPsaApi[build_params["TEST_PSA_API"]])
100
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800101 configName = "Config"
102 config_params = [build_params["BL2"], build_params["NS"], \
103 build_params["PSA_API"], build_params["ISOLATION_LEVEL"], \
104 build_params["TEST_REGRESSION"], build_params["TEST_PSA_API"], \
105 build_params["PROFILE"]]
106 for (config in mapConfigs) {
107 if (config_params == config[0..6]) {
108 configName += config[7].split(' ')[0]
109 break
110 }
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800111 }
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800112 if (configName == "Config") {
113 configName = "ConfigDefault"
114 }
115 params += string(name: "PROJ_CONFIG", value: configName)
116
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800117 return params
118}
119
Dean Birch62c4f082020-01-17 16:13:26 +0000120def listConfigs(ci_scripts_dir, config_list, filter_group) {
121 dir(ci_scripts_dir) {
122 echo "Obtaining list of configs."
Matthew Hartfb6fd362020-03-04 21:03:59 +0000123 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}"
Dean Birch62c4f082020-01-17 16:13:26 +0000124 def build_config_list_raw = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000125python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}
Dean Birch62c4f082020-01-17 16:13:26 +0000126""", returnStdout: true).trim()
127 def build_config_list = build_config_list_raw.tokenize('\n')
128 config_list.addAll(build_config_list)
129 }
130}
131
Matthew Hartfb6fd362020-03-04 21:03:59 +0000132def buildConfig(ci_scripts_dir, config, filter_group, results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000133 def params = []
Matthew Hartfb6fd362020-03-04 21:03:59 +0000134 def params_collection = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000135 def build_config_params
136 dir(ci_scripts_dir) {
137 echo "Obtaining build configuration for config ${config}"
Matthew Hartfb6fd362020-03-04 21:03:59 +0000138 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}"
Dean Birch62c4f082020-01-17 16:13:26 +0000139 build_config_params = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000140python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}
Dean Birch62c4f082020-01-17 16:13:26 +0000141""", returnStdout: true).trim()
142 }
143 def lines = build_config_params.tokenize('\n')
144 for (String line : lines) {
145 def key, value
146 (key, value) = line.tokenize('=')
147 params += string(name: key, value: value)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000148 params_collection[key] = value
Dean Birch62c4f082020-01-17 16:13:26 +0000149 }
150 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000151 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
152 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
153 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000154 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800155 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000156 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Karl Zhangf6f467e2020-07-10 16:24:45 +0800157 params += string(name: 'CODE_COVERAGE_EN', value: env.CODE_COVERAGE_EN)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000158 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000159 return { -> results
160 def build_res = build(job: 'tf-m-build-config', parameters: params, propagate: false)
161 def build_info = [build_res, config, params_collection]
162 results['builds'][build_res.number] = build_info
163 def build_url = build_res.getAbsoluteUrl()
164 print("${build_res.number}: ${config} ${build_res.result} ${build_url}")
165 failure_states = ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]
166 if (build_res.result in failure_states) {
167 error("Build failed at ${build_url}")
168 }
Karl Zhang2b10b342020-11-09 14:50:11 +0800169 else if (params_collection["NS"] == "False" || \
170 (params_collection["PROFILE"] == "profile_medium" && \
171 params_collection["PARTITION_PS"] == "OFF")) {
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800172 print("LAVA is not needed for ${build_url}")
173 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000174 else {
175 print("Doing LAVA stuff for ${build_url}")
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800176 params += generateLavaParam(params_collection)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000177 params += string(name: 'BUILD_NUMBER', value: "${build_res.number}")
178 params += string(name: 'BUILD_URL', value: build_url)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000179 params += string(name: 'LAVA_URL', value: env.LAVA_URL)
Dean Birch956416f2020-08-12 10:36:16 +0100180 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
181 params += string(name: 'LAVA_CREDENTIALS', value: env.LAVA_CREDENTIALS)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000182 def lava_res = build(job: 'tf-m-lava-submit', parameters: params, propagate: false)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000183 if (lava_res.result in failure_states) {
184 error("LAVA Create and Submit failed at ${lava_res.getAbsoluteUrl()}")
185 }
186 else {
187 results['lava_jobs'] += lava_res.getDescription()
188 }
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800189 links = "Build Config: ${config}\n"
190 links += "Build URL: ${build_url}\n"
191 links += "LAVA Submit: ${lava_res.getAbsoluteUrl()}"
192 print(links)
Dean Birch62c4f082020-01-17 16:13:26 +0000193 }
194 }
195}
196
Matthew Hart06340d72020-06-15 16:08:20 +0100197def buildDocs(results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000198 def params = []
199 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000200 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
201 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
202 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000203 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800204 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000205 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000206 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Matthew Hart06340d72020-06-15 16:08:20 +0100207 return { -> results
Dean Birch62c4f082020-01-17 16:13:26 +0000208 def res = build(job: 'tf-m-build-docs', parameters: params, propagate:false)
209 print("${res.number}: Docs ${res.result} ${res.getAbsoluteUrl()}")
Matthew Hart06340d72020-06-15 16:08:20 +0100210 results['docs'] = [res.number, res.result, params]
Dean Bircha6ede7e2020-03-13 14:00:33 +0000211 if (res.result in ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]) {
Dean Birch62c4f082020-01-17 16:13:26 +0000212 error("Build failed at ${res.getAbsoluteUrl()}")
213 }
214 }
215}
216
Xinyu Zhang38a18872020-11-23 16:45:28 +0800217def generateEmailBody(stage, failed_jobs) {
218 body = "Check console output at ${env.BUILD_URL} \n\n"
219
220 body += "Failed Jobs:\n"
221 failed_jobs.each { job ->
222 body += "${job.key} ${job.value}\n"
223 }
224
225 body += "\nFor detailed ${stage} results please refer to \
226 ${env.BUILD_URL}artifact/${stage}_results.csv \n"
227 return body
228}
229
230def emailNotification(results, stage, failed_jobs) {
Karl Zhang0413e972020-09-18 17:59:26 +0800231 script {
232 if (env.JOB_NAME.equals("tf-m-nightly") && !env.EMAIL_NOTIFICATION.equals('')) {
233 def result = "Fail."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800234 if (results == true) {
Karl Zhang0413e972020-09-18 17:59:26 +0800235 result = "Success."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800236 print("Skip sending as ${result} for ${stage}")
237 }
238 else {
239 emailext (
240 subject: ("Job ${env.JOB_NAME} ${stage} ${env.BUILD_NUMBER} ${result}"),
Xinyu Zhang38a18872020-11-23 16:45:28 +0800241 body: generateEmailBody(stage, failed_jobs),
Karl Zhang182ecdf2020-10-10 09:52:12 +0800242 to: "${EMAIL_NOTIFICATION}"
243 )
244 }
Karl Zhang0413e972020-09-18 17:59:26 +0800245 }
246 } /* script */
247}
248
Xinyu Zhang38a18872020-11-23 16:45:28 +0800249def filterFailedBuild(results) {
250 def failed_builds = [:]
251 results.each { result ->
252 if (result.value[0].getResult() == "FAILURE") {
253 failed_builds[result.value[1]] = result.value[0].getAbsoluteUrl()
254 }
255 }
256 return failed_builds
257}
258
259def filterFailedTest(string) {
260 def failed_tests = [:]
261 line = lineInString(string, "FAILURE_TESTS:")
262 a = line.split(' ')
263 if (a.size() > 1) {
264 a = line.split(' ')[1..-1]
265 a.each { fail_test ->
266 config_link = fail_test.split(':')
267 failed_tests[config_link[0]] = config_link[1..-1].join(':')
268 }
269 }
270 return failed_tests
271}
272
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800273@NonCPS
274def generateCsvContent(results) {
275 def resultsParam = []
276 results.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800277 if (result.value[2]['BL2'] == "True") {
278 resultsParam.add([result.value[1], \
279 result.value[0].getResult(), \
280 result.value[2]['TFM_PLATFORM'], \
281 result.value[2]['TOOLCHAIN_FILE'], \
282 result.value[2]['CMAKE_BUILD_TYPE'], \
283 result.value[2]['BL2'], \
284 result.value[2]['NS'], \
285 result.value[2]['PSA_API'], \
286 result.value[2]['ISOLATION_LEVEL'], \
287 result.value[2]['TEST_REGRESSION'], \
288 result.value[2]['TEST_PSA_API'], \
289 result.value[2]['PROFILE'], \
290 result.value[2]['PARTITION_PS'], \
291 result.value[2]['OTP']])
292 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800293 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800294 resultsParam.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800295 if (result[2] == 'musca_b1') {
296 if (result[13] != 'off') {
297 result[2] = 'musca_b1_OTP'
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800298 }
299 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800300 result[3] = mapCompiler[result[3]]
301 build_params = result[5..12]
302 configName = ""
303 for (map_cfg in mapConfigs) {
304 if (build_params[0..6] == map_cfg[0..6]) {
305 configName = map_cfg[7]
306 break
307 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800308 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800309 if (configName == "") {
310 configName = "Default"
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800311 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800312 else if (configName == "RegressionProfileM") {
313 if (build_params[7] == "OFF") {
314 configName = "RegressionProfileM PSOFF"
315 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800316 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800317 result.add(configName)
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800318 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800319 def csvContent = []
320 resultsParam.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800321 current_row = result[2..4]
322 cfgs.each {cfg ->
323 if (cfg == result[14]) {
324 current_row.add(cfg)
325 current_row.add(result[1])
326 }
327 }
328 csvContent.add(current_row)
329 }
330 csvContent.sort{a,b -> a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2]}
331 build_summary = []
332 current_platform = ""
333 current_compiler = ""
334 current_build_type = ""
335 csvContent.each { build_cfg ->
336 if (current_platform != build_cfg[0] || \
337 current_compiler != build_cfg[1] || \
338 current_build_type != build_cfg[2]) {
339 current_platform = build_cfg[0]
340 current_compiler = build_cfg[1]
341 current_build_type = build_cfg[2]
342 csv_line = [current_platform, current_compiler, current_build_type]
343 cfgs.each {
344 csv_line.add("N.A.")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800345 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800346 build_summary.add(csv_line)
347 }
348 i = 0
349 cfgs.each { cfg ->
350 if (cfg == build_cfg[3]) {
351 build_summary[-1][3+i] = build_cfg[4]
352 }
353 i += 1
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800354 }
355 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800356 build_summary.add(0, ['Platform', 'Compiler', 'Cmake Build Type'])
357 build_summary[0] += cfgs
358 return build_summary
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800359}
360
361def generateBuildCsv(results) {
362 def csvContent = generateCsvContent(results)
363 node("master") {
364 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
365 archiveArtifacts 'build_results.csv'
366 }
367}
Dean Bircha6ede7e2020-03-13 14:00:33 +0000368
369def buildCsv(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000370 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000371 def csvContent = summary.getBuildCsv(results)
372 node("master") {
373 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
374 archiveArtifacts 'build_results.csv'
375 }
376}
377
378def writeSummary(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000379 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000380 def buildLinks = summary.getLinks(results)
381 node("master") {
382 writeFile file: "build_links.html", text: buildLinks
383 archiveArtifacts 'build_links.html'
384 }
385}
386
Matthew Hartfb6fd362020-03-04 21:03:59 +0000387def lineInString(string, match) {
388 def lines = string.split("\n")
389 def result = lines.findAll { it.contains(match) }
390 return result[0]
391}
392
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800393def showLinks(string) {
394 def lines = string.split("\n")
395 def result = lines.findAll { it.contains("Build Config: ")}
396 links = result.join("\n")
397 print(links)
398}
399
Matthew Hartfb6fd362020-03-04 21:03:59 +0000400def getResult(string, match) {
401 line = lineInString(string, match)
Dean Birch1d545c02020-05-29 14:09:21 +0100402 a = line.split(match)[1].split(' ')
403 score = a[0]
404 if (a.size() > 1)
405 {
406 fail_text = a[1..-1].join(" ")
407 return [score, fail_text]
408 }
409 return [score, ""]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000410}
411
412def submitJobsToList(results) {
413 def all_jobs = []
414 for (String result : results){
415 jobs_s = result.split('JOBS: ')
416 if (jobs_s.size() > 1) {
417 all_jobs += jobs_s[1]
418 }
419 }
420 return(all_jobs)
421}
422
Dean Birch62c4f082020-01-17 16:13:26 +0000423def configs = []
424def builds = [:]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000425def results = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000426
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000427node("docker-amd64-tf-m-bionic") {
Dean Birch62c4f082020-01-17 16:13:26 +0000428 stage("Init") {
429 cleanWs()
430 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000431 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Birch62c4f082020-01-17 16:13:26 +0000432 }
433 }
434 stage("Configs") {
435 // Populate configs
436 listConfigs('tf-m-ci-scripts', configs, env.FILTER_GROUP)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000437 results['builds'] = [:]
438 results['lava_jobs'] = []
Dean Birch62c4f082020-01-17 16:13:26 +0000439 for (config in configs) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000440 builds[config] = buildConfig("tf-m-ci-scripts", config, env.FILTER_GROUP, results)
Dean Birch62c4f082020-01-17 16:13:26 +0000441 }
Matthew Hart06340d72020-06-15 16:08:20 +0100442 builds["docs"] = buildDocs(results)
Dean Birch62c4f082020-01-17 16:13:26 +0000443 }
444}
Karl Zhangfec84102020-06-24 09:56:36 +0800445
Dean Birch62c4f082020-01-17 16:13:26 +0000446stage("Builds") {
447 def verify = 1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800448 def success = true
Dean Birch62c4f082020-01-17 16:13:26 +0000449 try {
450 parallel(builds)
451 } catch (Exception e) {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000452 print(e)
Dean Birch62c4f082020-01-17 16:13:26 +0000453 manager.buildFailure()
454 verify = -1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800455 success = false
Dean Birch62c4f082020-01-17 16:13:26 +0000456 } finally {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000457 print("Verifying status")
Xinyu Zhang38a18872020-11-23 16:45:28 +0800458 def failed_builds = filterFailedBuild(results['builds'])
459 emailNotification(success, 'build', failed_builds)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000460 g = new Gerrit()
461 g.verifyStatus(verify, 'tf-m-build', 'build')
Dean Bircha6ede7e2020-03-13 14:00:33 +0000462 print("Building CSV")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800463 generateBuildCsv(results['builds'])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000464 writeSummary(results['builds'])
Dean Birch62c4f082020-01-17 16:13:26 +0000465 }
466}
Matthew Hart06340d72020-06-15 16:08:20 +0100467
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000468node("docker-amd64-tf-m-bionic") {
Matthew Hart06340d72020-06-15 16:08:20 +0100469 stage("Copy Docs") {
Karl Zhang32497972020-09-21 14:38:29 +0800470 if (env.JOB_NAME.equals("tf-m-build-and-test")) {
471 step([$class: 'CopyArtifact', projectName: 'tf-m-build-docs',
472 selector: specific("${results['docs'][0]}"), target: './docs/',
473 optional: true])
474 archiveArtifacts artifacts: 'docs/**', allowEmptyArchive: true
475 }
476 else {
477 print("No doc copy for job: ${env.JOB_NAME}")
478 }
Matthew Hart06340d72020-06-15 16:08:20 +0100479 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000480 stage("Tests") {
481 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000482 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000483 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000484 def all_jobs = []
485 def success = true
Dean Bircha6ede7e2020-03-13 14:00:33 +0000486 print("Wait for LAVA results here...")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000487 try {
488 all_jobs = submitJobsToList(results['lava_jobs'])
489 if (all_jobs.size() > 0) {
490 dir("tf-m-ci-scripts") {
Dean Birch956416f2020-08-12 10:36:16 +0100491 withCredentials([usernamePassword(credentialsId: env.LAVA_CREDENTIALS, passwordVariable: 'LAVA_TOKEN', usernameVariable: 'LAVA_USER')]) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000492 output = sh(script: """./lava_helper/lava_wait_jobs.py --job-ids ${all_jobs.join(",")} \
493 --lava-url ${env.LAVA_URL} --lava-user ${LAVA_USER} --lava-token ${LAVA_TOKEN} \
Matthew Hart05a59b52020-05-27 17:54:51 +0100494 --artifacts-path lava_artifacts --lava-timeout 7200 \
Matthew Hartfb6fd362020-03-04 21:03:59 +0000495 """, returnStdout: true).trim()
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800496 showLinks(output)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000497 archiveArtifacts artifacts: 'test_summary.*', allowEmptyArchive: true
Xinyu Zhang1b8f5152020-11-13 16:10:58 +0800498 archiveArtifacts artifacts: 'test_results.csv', allowEmptyArchive: true
Matthew Hartfb6fd362020-03-04 21:03:59 +0000499 g = new Gerrit()
Dean Birch1d545c02020-05-29 14:09:21 +0100500 def (boot_result, boot_output) = getResult(output, 'BOOT_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000501 if (boot_result) {
502 g.verifyStatus(boot_result, "lava_boot", "test")
503 }
Dean Birch1d545c02020-05-29 14:09:21 +0100504 def (test_result, test_output) = getResult(output, 'TEST_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000505 if (test_result) {
506 g.verifyStatus(test_result, "lava_test", "test")
507 }
508 if (boot_result.toInteger() < 1 || test_result.toInteger() < 1) {
Dean Birch1d545c02020-05-29 14:09:21 +0100509 error("Marking job as failed due to failed boots: ${boot_output} or tests: ${test_output}")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000510 }
511 }
512 }
513 }
514 else {
515 print("There were no LAVA jobs to test.")
516 }
517 }
518 catch (Exception e) {
519 print("ERROR: ${e}")
520 success = false
521 } finally {
522 archiveArtifacts artifacts: 'tf-m-ci-scripts/lava_artifacts/**', allowEmptyArchive: true
Xinyu Zhang91609012020-12-09 17:35:49 +0800523 if (all_jobs.size() > 0) {
524 emailNotification(success, 'test', filterFailedTest(output))
525 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000526 cleanWs()
527 if (!success) {
528 error("There was an Error waiting for LAVA jobs")
529 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000530 }
531 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000532}