blob: 25e6eb66f7e083d280645a764bb1ecb9128fa9d4 [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" || \
Karl Zhang0b7bb4a2021-01-18 16:22:08 +0800173 (params_collection["TFM_PLATFORM"].contains("musca_b1") && \
174 env.JOB_NAME.equals("tf-m-build-and-test")) || \
Xinyu Zhang661a17a2021-01-05 19:24:40 +0800175 (params_collection["PROFILE"] == "profile_medium" && \
176 params_collection["PARTITION_PS"] == "OFF")) {
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800177 print("LAVA is not needed for ${build_url}")
178 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000179 else {
180 print("Doing LAVA stuff for ${build_url}")
Xinyu Zhangaa3747f2020-12-24 16:27:06 +0800181 params += generateLavaParam(params_collection)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000182 params += string(name: 'BUILD_NUMBER', value: "${build_res.number}")
183 params += string(name: 'BUILD_URL', value: build_url)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000184 params += string(name: 'LAVA_URL', value: env.LAVA_URL)
Dean Birch956416f2020-08-12 10:36:16 +0100185 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
186 params += string(name: 'LAVA_CREDENTIALS', value: env.LAVA_CREDENTIALS)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000187 def lava_res = build(job: 'tf-m-lava-submit', parameters: params, propagate: false)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000188 if (lava_res.result in failure_states) {
189 error("LAVA Create and Submit failed at ${lava_res.getAbsoluteUrl()}")
190 }
191 else {
192 results['lava_jobs'] += lava_res.getDescription()
193 }
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800194 links = "Build Config: ${config}\n"
195 links += "Build URL: ${build_url}\n"
196 links += "LAVA Submit: ${lava_res.getAbsoluteUrl()}"
197 print(links)
Dean Birch62c4f082020-01-17 16:13:26 +0000198 }
199 }
200}
201
Matthew Hart06340d72020-06-15 16:08:20 +0100202def buildDocs(results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000203 def params = []
204 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000205 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
206 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
207 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000208 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800209 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000210 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000211 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Matthew Hart06340d72020-06-15 16:08:20 +0100212 return { -> results
Dean Birch62c4f082020-01-17 16:13:26 +0000213 def res = build(job: 'tf-m-build-docs', parameters: params, propagate:false)
214 print("${res.number}: Docs ${res.result} ${res.getAbsoluteUrl()}")
Matthew Hart06340d72020-06-15 16:08:20 +0100215 results['docs'] = [res.number, res.result, params]
Dean Bircha6ede7e2020-03-13 14:00:33 +0000216 if (res.result in ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]) {
Dean Birch62c4f082020-01-17 16:13:26 +0000217 error("Build failed at ${res.getAbsoluteUrl()}")
218 }
219 }
220}
221
Xinyu Zhang38a18872020-11-23 16:45:28 +0800222def generateEmailBody(stage, failed_jobs) {
223 body = "Check console output at ${env.BUILD_URL} \n\n"
224
225 body += "Failed Jobs:\n"
226 failed_jobs.each { job ->
227 body += "${job.key} ${job.value}\n"
228 }
229
230 body += "\nFor detailed ${stage} results please refer to \
231 ${env.BUILD_URL}artifact/${stage}_results.csv \n"
232 return body
233}
234
235def emailNotification(results, stage, failed_jobs) {
Karl Zhang0413e972020-09-18 17:59:26 +0800236 script {
237 if (env.JOB_NAME.equals("tf-m-nightly") && !env.EMAIL_NOTIFICATION.equals('')) {
238 def result = "Fail."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800239 if (results == true) {
Karl Zhang0413e972020-09-18 17:59:26 +0800240 result = "Success."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800241 print("Skip sending as ${result} for ${stage}")
242 }
243 else {
244 emailext (
245 subject: ("Job ${env.JOB_NAME} ${stage} ${env.BUILD_NUMBER} ${result}"),
Xinyu Zhang38a18872020-11-23 16:45:28 +0800246 body: generateEmailBody(stage, failed_jobs),
Karl Zhang182ecdf2020-10-10 09:52:12 +0800247 to: "${EMAIL_NOTIFICATION}"
248 )
249 }
Karl Zhang0413e972020-09-18 17:59:26 +0800250 }
251 } /* script */
252}
253
Xinyu Zhang38a18872020-11-23 16:45:28 +0800254def filterFailedBuild(results) {
255 def failed_builds = [:]
256 results.each { result ->
257 if (result.value[0].getResult() == "FAILURE") {
258 failed_builds[result.value[1]] = result.value[0].getAbsoluteUrl()
259 }
260 }
261 return failed_builds
262}
263
264def filterFailedTest(string) {
265 def failed_tests = [:]
266 line = lineInString(string, "FAILURE_TESTS:")
267 a = line.split(' ')
268 if (a.size() > 1) {
269 a = line.split(' ')[1..-1]
270 a.each { fail_test ->
271 config_link = fail_test.split(':')
272 failed_tests[config_link[0]] = config_link[1..-1].join(':')
273 }
274 }
275 return failed_tests
276}
277
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800278@NonCPS
279def generateCsvContent(results) {
280 def resultsParam = []
281 results.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800282 if (result.value[2]['BL2'] == "True") {
283 resultsParam.add([result.value[1], \
284 result.value[0].getResult(), \
285 result.value[2]['TFM_PLATFORM'], \
286 result.value[2]['TOOLCHAIN_FILE'], \
287 result.value[2]['CMAKE_BUILD_TYPE'], \
288 result.value[2]['BL2'], \
289 result.value[2]['NS'], \
290 result.value[2]['PSA_API'], \
291 result.value[2]['ISOLATION_LEVEL'], \
292 result.value[2]['TEST_REGRESSION'], \
293 result.value[2]['TEST_PSA_API'], \
294 result.value[2]['PROFILE'], \
295 result.value[2]['PARTITION_PS'], \
296 result.value[2]['OTP']])
297 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800298 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800299 resultsParam.each { result ->
Xinyu Zhang18a73542020-12-24 14:19:07 +0800300 if (result[2] == 'musca_b1/sse_200') {
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800301 if (result[13] != 'off') {
Xinyu Zhang18a73542020-12-24 14:19:07 +0800302 result[2] = 'musca_b1/sse_200_OTP'
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800303 }
304 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800305 result[3] = mapCompiler[result[3]]
306 build_params = result[5..12]
307 configName = ""
308 for (map_cfg in mapConfigs) {
309 if (build_params[0..6] == map_cfg[0..6]) {
310 configName = map_cfg[7]
311 break
312 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800313 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800314 if (configName == "") {
315 configName = "Default"
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800316 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800317 else if (configName == "RegressionProfileM") {
318 if (build_params[7] == "OFF") {
319 configName = "RegressionProfileM PSOFF"
320 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800321 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800322 result.add(configName)
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800323 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800324 def csvContent = []
325 resultsParam.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800326 current_row = result[2..4]
327 cfgs.each {cfg ->
328 if (cfg == result[14]) {
329 current_row.add(cfg)
330 current_row.add(result[1])
331 }
332 }
333 csvContent.add(current_row)
334 }
335 csvContent.sort{a,b -> a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2]}
336 build_summary = []
337 current_platform = ""
338 current_compiler = ""
339 current_build_type = ""
340 csvContent.each { build_cfg ->
341 if (current_platform != build_cfg[0] || \
342 current_compiler != build_cfg[1] || \
343 current_build_type != build_cfg[2]) {
344 current_platform = build_cfg[0]
345 current_compiler = build_cfg[1]
346 current_build_type = build_cfg[2]
347 csv_line = [current_platform, current_compiler, current_build_type]
348 cfgs.each {
349 csv_line.add("N.A.")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800350 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800351 build_summary.add(csv_line)
352 }
353 i = 0
354 cfgs.each { cfg ->
355 if (cfg == build_cfg[3]) {
356 build_summary[-1][3+i] = build_cfg[4]
357 }
358 i += 1
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800359 }
360 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800361 build_summary.add(0, ['Platform', 'Compiler', 'Cmake Build Type'])
362 build_summary[0] += cfgs
363 return build_summary
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800364}
365
366def generateBuildCsv(results) {
367 def csvContent = generateCsvContent(results)
368 node("master") {
369 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
370 archiveArtifacts 'build_results.csv'
371 }
372}
Dean Bircha6ede7e2020-03-13 14:00:33 +0000373
374def buildCsv(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000375 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000376 def csvContent = summary.getBuildCsv(results)
377 node("master") {
378 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
379 archiveArtifacts 'build_results.csv'
380 }
381}
382
383def writeSummary(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000384 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000385 def buildLinks = summary.getLinks(results)
386 node("master") {
387 writeFile file: "build_links.html", text: buildLinks
388 archiveArtifacts 'build_links.html'
389 }
390}
391
Matthew Hartfb6fd362020-03-04 21:03:59 +0000392def lineInString(string, match) {
393 def lines = string.split("\n")
394 def result = lines.findAll { it.contains(match) }
395 return result[0]
396}
397
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800398def showLinks(string) {
399 def lines = string.split("\n")
400 def result = lines.findAll { it.contains("Build Config: ")}
401 links = result.join("\n")
402 print(links)
403}
404
Matthew Hartfb6fd362020-03-04 21:03:59 +0000405def getResult(string, match) {
406 line = lineInString(string, match)
Dean Birch1d545c02020-05-29 14:09:21 +0100407 a = line.split(match)[1].split(' ')
408 score = a[0]
409 if (a.size() > 1)
410 {
411 fail_text = a[1..-1].join(" ")
412 return [score, fail_text]
413 }
414 return [score, ""]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000415}
416
417def submitJobsToList(results) {
418 def all_jobs = []
419 for (String result : results){
420 jobs_s = result.split('JOBS: ')
421 if (jobs_s.size() > 1) {
422 all_jobs += jobs_s[1]
423 }
424 }
425 return(all_jobs)
426}
427
Dean Birch62c4f082020-01-17 16:13:26 +0000428def configs = []
429def builds = [:]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000430def results = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000431
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000432node("docker-amd64-tf-m-bionic") {
Dean Birch62c4f082020-01-17 16:13:26 +0000433 stage("Init") {
434 cleanWs()
435 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000436 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Birch62c4f082020-01-17 16:13:26 +0000437 }
438 }
439 stage("Configs") {
440 // Populate configs
441 listConfigs('tf-m-ci-scripts', configs, env.FILTER_GROUP)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000442 results['builds'] = [:]
443 results['lava_jobs'] = []
Dean Birch62c4f082020-01-17 16:13:26 +0000444 for (config in configs) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000445 builds[config] = buildConfig("tf-m-ci-scripts", config, env.FILTER_GROUP, results)
Dean Birch62c4f082020-01-17 16:13:26 +0000446 }
Matthew Hart06340d72020-06-15 16:08:20 +0100447 builds["docs"] = buildDocs(results)
Dean Birch62c4f082020-01-17 16:13:26 +0000448 }
449}
Karl Zhangfec84102020-06-24 09:56:36 +0800450
Dean Birch62c4f082020-01-17 16:13:26 +0000451stage("Builds") {
452 def verify = 1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800453 def success = true
Dean Birch62c4f082020-01-17 16:13:26 +0000454 try {
455 parallel(builds)
456 } catch (Exception e) {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000457 print(e)
Dean Birch62c4f082020-01-17 16:13:26 +0000458 manager.buildFailure()
459 verify = -1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800460 success = false
Dean Birch62c4f082020-01-17 16:13:26 +0000461 } finally {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000462 print("Verifying status")
Xinyu Zhang38a18872020-11-23 16:45:28 +0800463 def failed_builds = filterFailedBuild(results['builds'])
464 emailNotification(success, 'build', failed_builds)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000465 g = new Gerrit()
466 g.verifyStatus(verify, 'tf-m-build', 'build')
Dean Bircha6ede7e2020-03-13 14:00:33 +0000467 print("Building CSV")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800468 generateBuildCsv(results['builds'])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000469 writeSummary(results['builds'])
Dean Birch62c4f082020-01-17 16:13:26 +0000470 }
471}
Matthew Hart06340d72020-06-15 16:08:20 +0100472
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000473node("docker-amd64-tf-m-bionic") {
Matthew Hart06340d72020-06-15 16:08:20 +0100474 stage("Copy Docs") {
Karl Zhang32497972020-09-21 14:38:29 +0800475 if (env.JOB_NAME.equals("tf-m-build-and-test")) {
476 step([$class: 'CopyArtifact', projectName: 'tf-m-build-docs',
477 selector: specific("${results['docs'][0]}"), target: './docs/',
478 optional: true])
479 archiveArtifacts artifacts: 'docs/**', allowEmptyArchive: true
480 }
481 else {
482 print("No doc copy for job: ${env.JOB_NAME}")
483 }
Matthew Hart06340d72020-06-15 16:08:20 +0100484 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000485 stage("Tests") {
486 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000487 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000488 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000489 def all_jobs = []
490 def success = true
Dean Bircha6ede7e2020-03-13 14:00:33 +0000491 print("Wait for LAVA results here...")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000492 try {
493 all_jobs = submitJobsToList(results['lava_jobs'])
494 if (all_jobs.size() > 0) {
495 dir("tf-m-ci-scripts") {
Dean Birch956416f2020-08-12 10:36:16 +0100496 withCredentials([usernamePassword(credentialsId: env.LAVA_CREDENTIALS, passwordVariable: 'LAVA_TOKEN', usernameVariable: 'LAVA_USER')]) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000497 output = sh(script: """./lava_helper/lava_wait_jobs.py --job-ids ${all_jobs.join(",")} \
498 --lava-url ${env.LAVA_URL} --lava-user ${LAVA_USER} --lava-token ${LAVA_TOKEN} \
Matthew Hart05a59b52020-05-27 17:54:51 +0100499 --artifacts-path lava_artifacts --lava-timeout 7200 \
Matthew Hartfb6fd362020-03-04 21:03:59 +0000500 """, returnStdout: true).trim()
Xinyu Zhang97ee3fd2020-12-14 14:45:06 +0800501 showLinks(output)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000502 archiveArtifacts artifacts: 'test_summary.*', allowEmptyArchive: true
Xinyu Zhang1b8f5152020-11-13 16:10:58 +0800503 archiveArtifacts artifacts: 'test_results.csv', allowEmptyArchive: true
Matthew Hartfb6fd362020-03-04 21:03:59 +0000504 g = new Gerrit()
Dean Birch1d545c02020-05-29 14:09:21 +0100505 def (boot_result, boot_output) = getResult(output, 'BOOT_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000506 if (boot_result) {
507 g.verifyStatus(boot_result, "lava_boot", "test")
508 }
Dean Birch1d545c02020-05-29 14:09:21 +0100509 def (test_result, test_output) = getResult(output, 'TEST_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000510 if (test_result) {
511 g.verifyStatus(test_result, "lava_test", "test")
512 }
513 if (boot_result.toInteger() < 1 || test_result.toInteger() < 1) {
Dean Birch1d545c02020-05-29 14:09:21 +0100514 error("Marking job as failed due to failed boots: ${boot_output} or tests: ${test_output}")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000515 }
516 }
517 }
518 }
519 else {
520 print("There were no LAVA jobs to test.")
521 }
522 }
523 catch (Exception e) {
524 print("ERROR: ${e}")
525 success = false
526 } finally {
527 archiveArtifacts artifacts: 'tf-m-ci-scripts/lava_artifacts/**', allowEmptyArchive: true
Xinyu Zhang91609012020-12-09 17:35:49 +0800528 if (all_jobs.size() > 0) {
529 emailNotification(success, 'test', filterFailedTest(output))
530 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000531 cleanWs()
532 if (!success) {
533 error("There was an Error waiting for LAVA jobs")
534 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000535 }
536 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000537}