blob: 6095d8e5df036d2ce6d1d5060d21d5c24f4295ae [file] [log] [blame]
Dean Birch62c4f082020-01-17 16:13:26 +00001#!/usr/bin/env groovy
2//-------------------------------------------------------------------------------
3// Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
4//
5// SPDX-License-Identifier: BSD-3-Clause
6//
7//-------------------------------------------------------------------------------
8
Dean Birchd0f9f8c2020-03-26 11:10:33 +00009@Library('trustedfirmware') _
10import org.trustedfirmware.Gerrit
11import org.trustedfirmware.Summary
Dean Bircha6ede7e2020-03-13 14:00:33 +000012
Mark Horvath8d281cd2020-12-07 15:20:26 +010013mapPlatform = ["cypress/psoc64": "psoc64",
14 "mps2/an519": "AN519",
15 "mps2/an521": "AN521",
16 "mps2/an539": "AN539",
17 "mps2/sse-200_aws": "SSE-200_AWS",
18 "mps3/an524": "AN524",
19 "musca_a": "MUSCA_A",
20 "musca_b1/sse_200": "MUSCA_B1",
21 "musca_b1/secure_enclave": "MUSCA_B1_SE",
22 "musca_s1": "MUSCA_S1"]
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +080023
24mapCompiler = ["toolchain_GNUARM.cmake": "GNUARM",
25 "toolchain_ARMCLANG.cmake": "ARMCLANG"]
26
27mapBL2 = ["True": "--bl2",
28 "False": ""]
29
30mapTestPsaApi = ["OFF": "",
31 "INTERNAL_TRUSTED_STORAGE": "ITS",
32 "PROTECTED_STORAGE": "PS",
33 "CRYPTO": "Crypto",
34 "INITIAL_ATTESTATION": "Attest",
35 "IPC": "FF"]
36
Xinyu Zhangdbfadae2020-12-07 14:42:59 +080037// BL2, NS, PSA_API, ISOLATION_LEVEL, TEST_REG, TEST_PSA_API, PROFILE, CONFIG_NAME
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +080038mapConfigs = [
39 ["True", "True", "False", "1", "False", "OFF", "N.A", "Default"],
40 ["True", "True", "True", "1", "False", "OFF", "N.A", "CoreIPC"],
41 ["True", "True", "True", "2", "False", "OFF", "N.A", "CoreIPCTfmLevel2"],
42 ["True", "True", "True", "3", "False", "OFF", "N.A", "CoreIPCTfmLevel3"],
43 ["True", "True", "False", "1", "False", "OFF", "profile_small", "DefaultProfileS"],
44 ["True", "True", "True", "2", "False", "OFF", "profile_medium", "DefaultProfileM"],
45 ["True", "True", "False", "1", "True", "OFF", "N.A", "Regression"],
46 ["True", "True", "True", "1", "True", "OFF", "N.A", "RegressionIPC"],
47 ["True", "True", "True", "2", "True", "OFF", "N.A", "RegressionIPCTfmLevel2"],
48 ["True", "True", "True", "3", "True", "OFF", "N.A", "RegressionIPCTfmLevel3"],
49 ["True", "True", "False", "1", "True", "OFF", "profile_small", "RegressionProfileS"],
50 ["True", "True", "True", "2", "True", "OFF", "profile_medium", "RegressionProfileM"],
51 ["True", "True", "False", "1", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTest (ITS)"],
52 ["True", "True", "False", "1", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTest (PS)"],
53 ["True", "True", "False", "1", "False", "CRYPTO", "N.A", "PsaApiTest (Crypto)"],
54 ["True", "True", "False", "1", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTest (Attest)"],
55 ["True", "True", "False", "1", "False", "IPC", "N.A", "PsaApiTest (FF)"],
56 ["True", "True", "True", "1", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTestIPC (ITS)"],
57 ["True", "True", "True", "1", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTestIPC (PS)"],
58 ["True", "True", "True", "1", "False", "CRYPTO", "N.A", "PsaApiTestIPC (Crypto)"],
59 ["True", "True", "True", "1", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPC (Attest)"],
60 ["True", "True", "True", "1", "False", "IPC", "N.A", "PsaApiTestIPC (FF)"],
61 ["True", "True", "True", "2", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel2 (ITS)"],
62 ["True", "True", "True", "2", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel2 (PS)"],
63 ["True", "True", "True", "2", "False", "CRYPTO", "N.A", "PsaApiTestIPCTfmLevel2 (Crypto)"],
64 ["True", "True", "True", "2", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPCTfmLevel2 (Attest)"],
65 ["True", "True", "True", "2", "False", "IPC", "N.A", "PsaApiTestIPCTfmLevel2 (FF)"],
66 ["True", "True", "True", "3", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel3 (ITS)"],
67 ["True", "True", "True", "3", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel3 (PS)"],
68 ["True", "True", "True", "3", "False", "CRYPTO", "N.A", "PsaApiTestIPCTfmLevel3 (Crypto)"],
69 ["True", "True", "True", "3", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPCTfmLevel3 (Attest)"],
70 ["True", "True", "True", "3", "False", "IPC", "N.A", "PsaApiTestIPCTfmLevel3 (FF)"],
71]
72
73cfgs = ["Default", "CoreIPC", "CoreIPCTfmLevel2", "CoreIPCTfmLevel3",
74 "Regression", "RegressionIPC",
75 "RegressionIPCTfmLevel2", "RegressionIPCTfmLevel3",
76 "DefaultProfileS", "RegressionProfileS",
77 "DefaultProfileM", "RegressionProfileM", "RegressionProfileM PSOFF",
78 "PsaApiTest (Attest)", "PsaApiTestIPC (Attest)",
79 "PsaApiTestIPCTfmLevel2 (Attest)",
80 "PsaApiTest (Crypto)", "PsaApiTestIPC (Crypto)",
81 "PsaApiTestIPCTfmLevel2 (Crypto)",
82 "PsaApiTest (PS)", "PsaApiTestIPC (PS)",
83 "PsaApiTestIPCTfmLevel2 (PS)",
84 "PsaApiTest (ITS)", "PsaApiTestIPC (ITS)",
85 "PsaApiTestIPCTfmLevel2 (ITS)",
86 "PsaApiTestIPC (FF)",
87 "PsaApiTestIPCTfmLevel2 (FF)",
88 "PsaApiTestIPCTfmLevel3 (ITS)", "PsaApiTestIPCTfmLevel3 (PS)",
89 "PsaApiTestIPCTfmLevel3 (Crypto)", "PsaApiTestIPCTfmLevel3 (Attest)",
90 "PsaApiTestIPCTfmLevel3 (FF)"]
91
Xinyu Zhangaa3747f2020-12-24 16:27:06 +080092@NonCPS
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +080093def generateLavaParam(build_params) {
94 def params = []
95 params += string(name: "TARGET_PLATFORM", \
96 value: mapPlatform[build_params["TFM_PLATFORM"]])
97 params += string(name: "COMPILER", \
98 value: mapCompiler[build_params["TOOLCHAIN_FILE"]])
99 params += string(name: "PSA_API_SUITE", \
100 value: mapTestPsaApi[build_params["TEST_PSA_API"]])
101
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800102 configName = "Config"
103 config_params = [build_params["BL2"], build_params["NS"], \
104 build_params["PSA_API"], build_params["ISOLATION_LEVEL"], \
105 build_params["TEST_REGRESSION"], build_params["TEST_PSA_API"], \
106 build_params["PROFILE"]]
107 for (config in mapConfigs) {
108 if (config_params == config[0..6]) {
Xinyu Zhangfc1bacd2020-12-24 15:26:35 +0800109 configName += config[7].replace(' (', '_').replace(')', '')
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800110 break
111 }
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800112 }
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800113 if (configName == "Config") {
114 configName = "ConfigDefault"
115 }
116 params += string(name: "PROJ_CONFIG", value: configName)
Xinyu Zhangaa3747f2020-12-24 16:27:06 +0800117 print("Params of ${configName} :")
118 print(config_params)
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800119 return params
120}
121
Dean Birch62c4f082020-01-17 16:13:26 +0000122def listConfigs(ci_scripts_dir, config_list, filter_group) {
123 dir(ci_scripts_dir) {
124 echo "Obtaining list of configs."
Matthew Hartfb6fd362020-03-04 21:03:59 +0000125 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}"
Dean Birch62c4f082020-01-17 16:13:26 +0000126 def build_config_list_raw = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000127python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}
Dean Birch62c4f082020-01-17 16:13:26 +0000128""", returnStdout: true).trim()
129 def build_config_list = build_config_list_raw.tokenize('\n')
130 config_list.addAll(build_config_list)
131 }
132}
133
Matthew Hartfb6fd362020-03-04 21:03:59 +0000134def buildConfig(ci_scripts_dir, config, filter_group, results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000135 def params = []
Matthew Hartfb6fd362020-03-04 21:03:59 +0000136 def params_collection = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000137 def build_config_params
138 dir(ci_scripts_dir) {
139 echo "Obtaining build configuration for config ${config}"
Matthew Hartfb6fd362020-03-04 21:03:59 +0000140 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}"
Dean Birch62c4f082020-01-17 16:13:26 +0000141 build_config_params = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000142python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}
Dean Birch62c4f082020-01-17 16:13:26 +0000143""", returnStdout: true).trim()
144 }
145 def lines = build_config_params.tokenize('\n')
146 for (String line : lines) {
147 def key, value
148 (key, value) = line.tokenize('=')
149 params += string(name: key, value: value)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000150 params_collection[key] = value
Dean Birch62c4f082020-01-17 16:13:26 +0000151 }
152 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000153 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
154 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
155 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000156 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800157 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000158 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Karl Zhangf6f467e2020-07-10 16:24:45 +0800159 params += string(name: 'CODE_COVERAGE_EN', value: env.CODE_COVERAGE_EN)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000160 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000161 return { -> results
162 def build_res = build(job: 'tf-m-build-config', parameters: params, propagate: false)
163 def build_info = [build_res, config, params_collection]
164 results['builds'][build_res.number] = build_info
165 def build_url = build_res.getAbsoluteUrl()
166 print("${build_res.number}: ${config} ${build_res.result} ${build_url}")
167 failure_states = ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]
168 if (build_res.result in failure_states) {
169 error("Build failed at ${build_url}")
170 }
Karl Zhang2b10b342020-11-09 14:50:11 +0800171 else if (params_collection["NS"] == "False" || \
Xinyu Zhang661a17a2021-01-05 19:24:40 +0800172 params_collection["OTP"] == "ENABLED" || \
173 (params_collection["PROFILE"] == "profile_medium" && \
174 params_collection["PARTITION_PS"] == "OFF")) {
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800175 print("LAVA is not needed for ${build_url}")
176 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000177 else {
178 print("Doing LAVA stuff for ${build_url}")
Xinyu Zhangaa3747f2020-12-24 16:27:06 +0800179 params += generateLavaParam(params_collection)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000180 params += string(name: 'BUILD_NUMBER', value: "${build_res.number}")
181 params += string(name: 'BUILD_URL', value: build_url)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000182 params += string(name: 'LAVA_URL', value: env.LAVA_URL)
Dean Birch956416f2020-08-12 10:36:16 +0100183 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
184 params += string(name: 'LAVA_CREDENTIALS', value: env.LAVA_CREDENTIALS)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000185 def lava_res = build(job: 'tf-m-lava-submit', parameters: params, propagate: false)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000186 if (lava_res.result in failure_states) {
187 error("LAVA Create and Submit failed at ${lava_res.getAbsoluteUrl()}")
188 }
189 else {
190 results['lava_jobs'] += lava_res.getDescription()
191 }
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800192 links = "Build Config: ${config}\n"
193 links += "Build URL: ${build_url}\n"
194 links += "LAVA Submit: ${lava_res.getAbsoluteUrl()}"
195 print(links)
Dean Birch62c4f082020-01-17 16:13:26 +0000196 }
197 }
198}
199
Matthew Hart06340d72020-06-15 16:08:20 +0100200def buildDocs(results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000201 def params = []
202 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000203 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
204 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
205 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000206 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800207 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000208 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000209 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Matthew Hart06340d72020-06-15 16:08:20 +0100210 return { -> results
Dean Birch62c4f082020-01-17 16:13:26 +0000211 def res = build(job: 'tf-m-build-docs', parameters: params, propagate:false)
212 print("${res.number}: Docs ${res.result} ${res.getAbsoluteUrl()}")
Matthew Hart06340d72020-06-15 16:08:20 +0100213 results['docs'] = [res.number, res.result, params]
Dean Bircha6ede7e2020-03-13 14:00:33 +0000214 if (res.result in ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]) {
Dean Birch62c4f082020-01-17 16:13:26 +0000215 error("Build failed at ${res.getAbsoluteUrl()}")
216 }
217 }
218}
219
Xinyu Zhang38a18872020-11-23 16:45:28 +0800220def generateEmailBody(stage, failed_jobs) {
221 body = "Check console output at ${env.BUILD_URL} \n\n"
222
223 body += "Failed Jobs:\n"
224 failed_jobs.each { job ->
225 body += "${job.key} ${job.value}\n"
226 }
227
228 body += "\nFor detailed ${stage} results please refer to \
229 ${env.BUILD_URL}artifact/${stage}_results.csv \n"
230 return body
231}
232
233def emailNotification(results, stage, failed_jobs) {
Karl Zhang0413e972020-09-18 17:59:26 +0800234 script {
235 if (env.JOB_NAME.equals("tf-m-nightly") && !env.EMAIL_NOTIFICATION.equals('')) {
236 def result = "Fail."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800237 if (results == true) {
Karl Zhang0413e972020-09-18 17:59:26 +0800238 result = "Success."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800239 print("Skip sending as ${result} for ${stage}")
240 }
241 else {
242 emailext (
243 subject: ("Job ${env.JOB_NAME} ${stage} ${env.BUILD_NUMBER} ${result}"),
Xinyu Zhang38a18872020-11-23 16:45:28 +0800244 body: generateEmailBody(stage, failed_jobs),
Karl Zhang182ecdf2020-10-10 09:52:12 +0800245 to: "${EMAIL_NOTIFICATION}"
246 )
247 }
Karl Zhang0413e972020-09-18 17:59:26 +0800248 }
249 } /* script */
250}
251
Xinyu Zhang38a18872020-11-23 16:45:28 +0800252def filterFailedBuild(results) {
253 def failed_builds = [:]
254 results.each { result ->
255 if (result.value[0].getResult() == "FAILURE") {
256 failed_builds[result.value[1]] = result.value[0].getAbsoluteUrl()
257 }
258 }
259 return failed_builds
260}
261
262def filterFailedTest(string) {
263 def failed_tests = [:]
264 line = lineInString(string, "FAILURE_TESTS:")
265 a = line.split(' ')
266 if (a.size() > 1) {
267 a = line.split(' ')[1..-1]
268 a.each { fail_test ->
269 config_link = fail_test.split(':')
270 failed_tests[config_link[0]] = config_link[1..-1].join(':')
271 }
272 }
273 return failed_tests
274}
275
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800276@NonCPS
277def generateCsvContent(results) {
278 def resultsParam = []
279 results.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800280 if (result.value[2]['BL2'] == "True") {
281 resultsParam.add([result.value[1], \
282 result.value[0].getResult(), \
283 result.value[2]['TFM_PLATFORM'], \
284 result.value[2]['TOOLCHAIN_FILE'], \
285 result.value[2]['CMAKE_BUILD_TYPE'], \
286 result.value[2]['BL2'], \
287 result.value[2]['NS'], \
288 result.value[2]['PSA_API'], \
289 result.value[2]['ISOLATION_LEVEL'], \
290 result.value[2]['TEST_REGRESSION'], \
291 result.value[2]['TEST_PSA_API'], \
292 result.value[2]['PROFILE'], \
293 result.value[2]['PARTITION_PS'], \
294 result.value[2]['OTP']])
295 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800296 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800297 resultsParam.each { result ->
Xinyu Zhang18a73542020-12-24 14:19:07 +0800298 if (result[2] == 'musca_b1/sse_200') {
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800299 if (result[13] != 'off') {
Xinyu Zhang18a73542020-12-24 14:19:07 +0800300 result[2] = 'musca_b1/sse_200_OTP'
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800301 }
302 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800303 result[3] = mapCompiler[result[3]]
304 build_params = result[5..12]
305 configName = ""
306 for (map_cfg in mapConfigs) {
307 if (build_params[0..6] == map_cfg[0..6]) {
308 configName = map_cfg[7]
309 break
310 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800311 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800312 if (configName == "") {
313 configName = "Default"
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800314 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800315 else if (configName == "RegressionProfileM") {
316 if (build_params[7] == "OFF") {
317 configName = "RegressionProfileM PSOFF"
318 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800319 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800320 result.add(configName)
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800321 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800322 def csvContent = []
323 resultsParam.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800324 current_row = result[2..4]
325 cfgs.each {cfg ->
326 if (cfg == result[14]) {
327 current_row.add(cfg)
328 current_row.add(result[1])
329 }
330 }
331 csvContent.add(current_row)
332 }
333 csvContent.sort{a,b -> a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2]}
334 build_summary = []
335 current_platform = ""
336 current_compiler = ""
337 current_build_type = ""
338 csvContent.each { build_cfg ->
339 if (current_platform != build_cfg[0] || \
340 current_compiler != build_cfg[1] || \
341 current_build_type != build_cfg[2]) {
342 current_platform = build_cfg[0]
343 current_compiler = build_cfg[1]
344 current_build_type = build_cfg[2]
345 csv_line = [current_platform, current_compiler, current_build_type]
346 cfgs.each {
347 csv_line.add("N.A.")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800348 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800349 build_summary.add(csv_line)
350 }
351 i = 0
352 cfgs.each { cfg ->
353 if (cfg == build_cfg[3]) {
354 build_summary[-1][3+i] = build_cfg[4]
355 }
356 i += 1
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800357 }
358 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800359 build_summary.add(0, ['Platform', 'Compiler', 'Cmake Build Type'])
360 build_summary[0] += cfgs
361 return build_summary
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800362}
363
364def generateBuildCsv(results) {
365 def csvContent = generateCsvContent(results)
366 node("master") {
367 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
368 archiveArtifacts 'build_results.csv'
369 }
370}
Dean Bircha6ede7e2020-03-13 14:00:33 +0000371
372def buildCsv(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000373 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000374 def csvContent = summary.getBuildCsv(results)
375 node("master") {
376 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
377 archiveArtifacts 'build_results.csv'
378 }
379}
380
381def writeSummary(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000382 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000383 def buildLinks = summary.getLinks(results)
384 node("master") {
385 writeFile file: "build_links.html", text: buildLinks
386 archiveArtifacts 'build_links.html'
387 }
388}
389
Matthew Hartfb6fd362020-03-04 21:03:59 +0000390def lineInString(string, match) {
391 def lines = string.split("\n")
392 def result = lines.findAll { it.contains(match) }
393 return result[0]
394}
395
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800396def showLinks(string) {
397 def lines = string.split("\n")
398 def result = lines.findAll { it.contains("Build Config: ")}
399 links = result.join("\n")
400 print(links)
401}
402
Matthew Hartfb6fd362020-03-04 21:03:59 +0000403def getResult(string, match) {
404 line = lineInString(string, match)
Dean Birch1d545c02020-05-29 14:09:21 +0100405 a = line.split(match)[1].split(' ')
406 score = a[0]
407 if (a.size() > 1)
408 {
409 fail_text = a[1..-1].join(" ")
410 return [score, fail_text]
411 }
412 return [score, ""]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000413}
414
415def submitJobsToList(results) {
416 def all_jobs = []
417 for (String result : results){
418 jobs_s = result.split('JOBS: ')
419 if (jobs_s.size() > 1) {
420 all_jobs += jobs_s[1]
421 }
422 }
423 return(all_jobs)
424}
425
Dean Birch62c4f082020-01-17 16:13:26 +0000426def configs = []
427def builds = [:]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000428def results = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000429
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000430node("docker-amd64-tf-m-bionic") {
Dean Birch62c4f082020-01-17 16:13:26 +0000431 stage("Init") {
432 cleanWs()
433 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000434 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Birch62c4f082020-01-17 16:13:26 +0000435 }
436 }
437 stage("Configs") {
438 // Populate configs
439 listConfigs('tf-m-ci-scripts', configs, env.FILTER_GROUP)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000440 results['builds'] = [:]
441 results['lava_jobs'] = []
Dean Birch62c4f082020-01-17 16:13:26 +0000442 for (config in configs) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000443 builds[config] = buildConfig("tf-m-ci-scripts", config, env.FILTER_GROUP, results)
Dean Birch62c4f082020-01-17 16:13:26 +0000444 }
Matthew Hart06340d72020-06-15 16:08:20 +0100445 builds["docs"] = buildDocs(results)
Dean Birch62c4f082020-01-17 16:13:26 +0000446 }
447}
Karl Zhangfec84102020-06-24 09:56:36 +0800448
Dean Birch62c4f082020-01-17 16:13:26 +0000449stage("Builds") {
450 def verify = 1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800451 def success = true
Dean Birch62c4f082020-01-17 16:13:26 +0000452 try {
453 parallel(builds)
454 } catch (Exception e) {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000455 print(e)
Dean Birch62c4f082020-01-17 16:13:26 +0000456 manager.buildFailure()
457 verify = -1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800458 success = false
Dean Birch62c4f082020-01-17 16:13:26 +0000459 } finally {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000460 print("Verifying status")
Xinyu Zhang38a18872020-11-23 16:45:28 +0800461 def failed_builds = filterFailedBuild(results['builds'])
462 emailNotification(success, 'build', failed_builds)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000463 g = new Gerrit()
464 g.verifyStatus(verify, 'tf-m-build', 'build')
Dean Bircha6ede7e2020-03-13 14:00:33 +0000465 print("Building CSV")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800466 generateBuildCsv(results['builds'])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000467 writeSummary(results['builds'])
Dean Birch62c4f082020-01-17 16:13:26 +0000468 }
469}
Matthew Hart06340d72020-06-15 16:08:20 +0100470
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000471node("docker-amd64-tf-m-bionic") {
Matthew Hart06340d72020-06-15 16:08:20 +0100472 stage("Copy Docs") {
Karl Zhang32497972020-09-21 14:38:29 +0800473 if (env.JOB_NAME.equals("tf-m-build-and-test")) {
474 step([$class: 'CopyArtifact', projectName: 'tf-m-build-docs',
475 selector: specific("${results['docs'][0]}"), target: './docs/',
476 optional: true])
477 archiveArtifacts artifacts: 'docs/**', allowEmptyArchive: true
478 }
479 else {
480 print("No doc copy for job: ${env.JOB_NAME}")
481 }
Matthew Hart06340d72020-06-15 16:08:20 +0100482 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000483 stage("Tests") {
484 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000485 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000486 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000487 def all_jobs = []
488 def success = true
Dean Bircha6ede7e2020-03-13 14:00:33 +0000489 print("Wait for LAVA results here...")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000490 try {
491 all_jobs = submitJobsToList(results['lava_jobs'])
492 if (all_jobs.size() > 0) {
493 dir("tf-m-ci-scripts") {
Dean Birch956416f2020-08-12 10:36:16 +0100494 withCredentials([usernamePassword(credentialsId: env.LAVA_CREDENTIALS, passwordVariable: 'LAVA_TOKEN', usernameVariable: 'LAVA_USER')]) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000495 output = sh(script: """./lava_helper/lava_wait_jobs.py --job-ids ${all_jobs.join(",")} \
496 --lava-url ${env.LAVA_URL} --lava-user ${LAVA_USER} --lava-token ${LAVA_TOKEN} \
Matthew Hart05a59b52020-05-27 17:54:51 +0100497 --artifacts-path lava_artifacts --lava-timeout 7200 \
Matthew Hartfb6fd362020-03-04 21:03:59 +0000498 """, returnStdout: true).trim()
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800499 showLinks(output)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000500 archiveArtifacts artifacts: 'test_summary.*', allowEmptyArchive: true
Xinyu Zhang1b8f5152020-11-13 16:10:58 +0800501 archiveArtifacts artifacts: 'test_results.csv', allowEmptyArchive: true
Matthew Hartfb6fd362020-03-04 21:03:59 +0000502 g = new Gerrit()
Dean Birch1d545c02020-05-29 14:09:21 +0100503 def (boot_result, boot_output) = getResult(output, 'BOOT_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000504 if (boot_result) {
505 g.verifyStatus(boot_result, "lava_boot", "test")
506 }
Dean Birch1d545c02020-05-29 14:09:21 +0100507 def (test_result, test_output) = getResult(output, 'TEST_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000508 if (test_result) {
509 g.verifyStatus(test_result, "lava_test", "test")
510 }
511 if (boot_result.toInteger() < 1 || test_result.toInteger() < 1) {
Dean Birch1d545c02020-05-29 14:09:21 +0100512 error("Marking job as failed due to failed boots: ${boot_output} or tests: ${test_output}")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000513 }
514 }
515 }
516 }
517 else {
518 print("There were no LAVA jobs to test.")
519 }
520 }
521 catch (Exception e) {
522 print("ERROR: ${e}")
523 success = false
524 } finally {
525 archiveArtifacts artifacts: 'tf-m-ci-scripts/lava_artifacts/**', allowEmptyArchive: true
Xinyu Zhang91609012020-12-09 17:35:49 +0800526 if (all_jobs.size() > 0) {
527 emailNotification(success, 'test', filterFailedTest(output))
528 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000529 cleanWs()
530 if (!success) {
531 error("There was an Error waiting for LAVA jobs")
532 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000533 }
534 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000535}