blob: acb2d964e004b4ff27ab392fbac5353f6290e5ff [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
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +080013mapPlatform = ["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": "MUSCA_B1",
21 "musca_s1": "MUSCA_S1"]
22
23mapCompiler = ["toolchain_GNUARM.cmake": "GNUARM",
24 "toolchain_ARMCLANG.cmake": "ARMCLANG"]
25
26mapBL2 = ["True": "--bl2",
27 "False": ""]
28
29mapTestPsaApi = ["OFF": "",
30 "INTERNAL_TRUSTED_STORAGE": "ITS",
31 "PROTECTED_STORAGE": "PS",
32 "CRYPTO": "Crypto",
33 "INITIAL_ATTESTATION": "Attest",
34 "IPC": "FF"]
35
Xinyu Zhangdbfadae2020-12-07 14:42:59 +080036// BL2, NS, PSA_API, ISOLATION_LEVEL, TEST_REG, TEST_PSA_API, PROFILE, CONFIG_NAME
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +080037mapConfigs = [
38 ["True", "True", "False", "1", "False", "OFF", "N.A", "Default"],
39 ["True", "True", "True", "1", "False", "OFF", "N.A", "CoreIPC"],
40 ["True", "True", "True", "2", "False", "OFF", "N.A", "CoreIPCTfmLevel2"],
41 ["True", "True", "True", "3", "False", "OFF", "N.A", "CoreIPCTfmLevel3"],
42 ["True", "True", "False", "1", "False", "OFF", "profile_small", "DefaultProfileS"],
43 ["True", "True", "True", "2", "False", "OFF", "profile_medium", "DefaultProfileM"],
44 ["True", "True", "False", "1", "True", "OFF", "N.A", "Regression"],
45 ["True", "True", "True", "1", "True", "OFF", "N.A", "RegressionIPC"],
46 ["True", "True", "True", "2", "True", "OFF", "N.A", "RegressionIPCTfmLevel2"],
47 ["True", "True", "True", "3", "True", "OFF", "N.A", "RegressionIPCTfmLevel3"],
48 ["True", "True", "False", "1", "True", "OFF", "profile_small", "RegressionProfileS"],
49 ["True", "True", "True", "2", "True", "OFF", "profile_medium", "RegressionProfileM"],
50 ["True", "True", "False", "1", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTest (ITS)"],
51 ["True", "True", "False", "1", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTest (PS)"],
52 ["True", "True", "False", "1", "False", "CRYPTO", "N.A", "PsaApiTest (Crypto)"],
53 ["True", "True", "False", "1", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTest (Attest)"],
54 ["True", "True", "False", "1", "False", "IPC", "N.A", "PsaApiTest (FF)"],
55 ["True", "True", "True", "1", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTestIPC (ITS)"],
56 ["True", "True", "True", "1", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTestIPC (PS)"],
57 ["True", "True", "True", "1", "False", "CRYPTO", "N.A", "PsaApiTestIPC (Crypto)"],
58 ["True", "True", "True", "1", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPC (Attest)"],
59 ["True", "True", "True", "1", "False", "IPC", "N.A", "PsaApiTestIPC (FF)"],
60 ["True", "True", "True", "2", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel2 (ITS)"],
61 ["True", "True", "True", "2", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel2 (PS)"],
62 ["True", "True", "True", "2", "False", "CRYPTO", "N.A", "PsaApiTestIPCTfmLevel2 (Crypto)"],
63 ["True", "True", "True", "2", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPCTfmLevel2 (Attest)"],
64 ["True", "True", "True", "2", "False", "IPC", "N.A", "PsaApiTestIPCTfmLevel2 (FF)"],
65 ["True", "True", "True", "3", "False", "INTERNAL_TRUSTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel3 (ITS)"],
66 ["True", "True", "True", "3", "False", "PROTECTED_STORAGE", "N.A", "PsaApiTestIPCTfmLevel3 (PS)"],
67 ["True", "True", "True", "3", "False", "CRYPTO", "N.A", "PsaApiTestIPCTfmLevel3 (Crypto)"],
68 ["True", "True", "True", "3", "False", "INITIAL_ATTESTATION", "N.A", "PsaApiTestIPCTfmLevel3 (Attest)"],
69 ["True", "True", "True", "3", "False", "IPC", "N.A", "PsaApiTestIPCTfmLevel3 (FF)"],
70]
71
72cfgs = ["Default", "CoreIPC", "CoreIPCTfmLevel2", "CoreIPCTfmLevel3",
73 "Regression", "RegressionIPC",
74 "RegressionIPCTfmLevel2", "RegressionIPCTfmLevel3",
75 "DefaultProfileS", "RegressionProfileS",
76 "DefaultProfileM", "RegressionProfileM", "RegressionProfileM PSOFF",
77 "PsaApiTest (Attest)", "PsaApiTestIPC (Attest)",
78 "PsaApiTestIPCTfmLevel2 (Attest)",
79 "PsaApiTest (Crypto)", "PsaApiTestIPC (Crypto)",
80 "PsaApiTestIPCTfmLevel2 (Crypto)",
81 "PsaApiTest (PS)", "PsaApiTestIPC (PS)",
82 "PsaApiTestIPCTfmLevel2 (PS)",
83 "PsaApiTest (ITS)", "PsaApiTestIPC (ITS)",
84 "PsaApiTestIPCTfmLevel2 (ITS)",
85 "PsaApiTestIPC (FF)",
86 "PsaApiTestIPCTfmLevel2 (FF)",
87 "PsaApiTestIPCTfmLevel3 (ITS)", "PsaApiTestIPCTfmLevel3 (PS)",
88 "PsaApiTestIPCTfmLevel3 (Crypto)", "PsaApiTestIPCTfmLevel3 (Attest)",
89 "PsaApiTestIPCTfmLevel3 (FF)"]
90
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +080091def generateLavaParam(build_params) {
92 def params = []
93 params += string(name: "TARGET_PLATFORM", \
94 value: mapPlatform[build_params["TFM_PLATFORM"]])
95 params += string(name: "COMPILER", \
96 value: mapCompiler[build_params["TOOLCHAIN_FILE"]])
97 params += string(name: "PSA_API_SUITE", \
98 value: mapTestPsaApi[build_params["TEST_PSA_API"]])
99
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800100 configName = "Config"
101 config_params = [build_params["BL2"], build_params["NS"], \
102 build_params["PSA_API"], build_params["ISOLATION_LEVEL"], \
103 build_params["TEST_REGRESSION"], build_params["TEST_PSA_API"], \
104 build_params["PROFILE"]]
105 for (config in mapConfigs) {
106 if (config_params == config[0..6]) {
107 configName += config[7].split(' ')[0]
108 break
109 }
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800110 }
Xinyu Zhangdbfadae2020-12-07 14:42:59 +0800111 if (configName == "Config") {
112 configName = "ConfigDefault"
113 }
114 params += string(name: "PROJ_CONFIG", value: configName)
115
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800116 return params
117}
118
Dean Birch62c4f082020-01-17 16:13:26 +0000119def listConfigs(ci_scripts_dir, config_list, filter_group) {
120 dir(ci_scripts_dir) {
121 echo "Obtaining list of configs."
Matthew Hartfb6fd362020-03-04 21:03:59 +0000122 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}"
Dean Birch62c4f082020-01-17 16:13:26 +0000123 def build_config_list_raw = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000124python3 ./configs.py -g ${filter_group.replace(" ", " -g ")}
Dean Birch62c4f082020-01-17 16:13:26 +0000125""", returnStdout: true).trim()
126 def build_config_list = build_config_list_raw.tokenize('\n')
127 config_list.addAll(build_config_list)
128 }
129}
130
Matthew Hartfb6fd362020-03-04 21:03:59 +0000131def buildConfig(ci_scripts_dir, config, filter_group, results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000132 def params = []
Matthew Hartfb6fd362020-03-04 21:03:59 +0000133 def params_collection = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000134 def build_config_params
135 dir(ci_scripts_dir) {
136 echo "Obtaining build configuration for config ${config}"
Matthew Hartfb6fd362020-03-04 21:03:59 +0000137 echo "Running: python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}"
Dean Birch62c4f082020-01-17 16:13:26 +0000138 build_config_params = sh(script: """\
Matthew Hartfb6fd362020-03-04 21:03:59 +0000139python3 ./configs.py -g ${filter_group.replace(" ", " -g ")} ${config}
Dean Birch62c4f082020-01-17 16:13:26 +0000140""", returnStdout: true).trim()
141 }
142 def lines = build_config_params.tokenize('\n')
143 for (String line : lines) {
144 def key, value
145 (key, value) = line.tokenize('=')
146 params += string(name: key, value: value)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000147 params_collection[key] = value
Dean Birch62c4f082020-01-17 16:13:26 +0000148 }
149 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000150 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
151 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
152 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000153 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800154 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000155 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Karl Zhangf6f467e2020-07-10 16:24:45 +0800156 params += string(name: 'CODE_COVERAGE_EN', value: env.CODE_COVERAGE_EN)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000157 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000158 return { -> results
159 def build_res = build(job: 'tf-m-build-config', parameters: params, propagate: false)
160 def build_info = [build_res, config, params_collection]
161 results['builds'][build_res.number] = build_info
162 def build_url = build_res.getAbsoluteUrl()
163 print("${build_res.number}: ${config} ${build_res.result} ${build_url}")
164 failure_states = ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]
165 if (build_res.result in failure_states) {
166 error("Build failed at ${build_url}")
167 }
Karl Zhang2b10b342020-11-09 14:50:11 +0800168 else if (params_collection["NS"] == "False" || \
169 (params_collection["PROFILE"] == "profile_medium" && \
170 params_collection["PARTITION_PS"] == "OFF")) {
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800171 print("LAVA is not needed for ${build_url}")
172 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000173 else {
174 print("Doing LAVA stuff for ${build_url}")
Xinyu Zhang5c4bbca2020-09-24 16:36:03 +0800175 params += generateLavaParam(params_collection)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000176 params += string(name: 'BUILD_NUMBER', value: "${build_res.number}")
177 params += string(name: 'BUILD_URL', value: build_url)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000178 params += string(name: 'LAVA_URL', value: env.LAVA_URL)
Dean Birch956416f2020-08-12 10:36:16 +0100179 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
180 params += string(name: 'LAVA_CREDENTIALS', value: env.LAVA_CREDENTIALS)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000181 def lava_res = build(job: 'tf-m-lava-submit', parameters: params, propagate: false)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000182 if (lava_res.result in failure_states) {
183 error("LAVA Create and Submit failed at ${lava_res.getAbsoluteUrl()}")
184 }
185 else {
186 results['lava_jobs'] += lava_res.getDescription()
187 }
Dean Birch62c4f082020-01-17 16:13:26 +0000188 }
189 }
190}
191
Matthew Hart06340d72020-06-15 16:08:20 +0100192def buildDocs(results) {
Dean Birch62c4f082020-01-17 16:13:26 +0000193 def params = []
194 params += string(name: 'GERRIT_BRANCH', value: env.GERRIT_BRANCH)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000195 params += string(name: 'GERRIT_HOST', value: env.GERRIT_HOST)
196 params += string(name: 'GERRIT_CHANGE_NUMBER', value: env.GERRIT_CHANGE_NUMBER)
197 params += string(name: 'GERRIT_PATCHSET_REVISION', value: env.GERRIT_PATCHSET_REVISION)
Dean Birch62c4f082020-01-17 16:13:26 +0000198 params += string(name: 'GERRIT_REFSPEC', value: env.GERRIT_REFSPEC)
Karl Zhang02d30352020-08-20 13:48:52 +0800199 params += string(name: 'MBEDTLS_VERSION', value: env.MBEDTLS_VERSION)
Dean Birch62c4f082020-01-17 16:13:26 +0000200 params += string(name: 'CODE_REPO', value: env.CODE_REPO)
Colin Thorbinson58703db2020-11-24 12:02:19 +0000201 params += string(name: 'CI_SCRIPTS_BRANCH', value: env.CI_SCRIPTS_BRANCH)
Matthew Hart06340d72020-06-15 16:08:20 +0100202 return { -> results
Dean Birch62c4f082020-01-17 16:13:26 +0000203 def res = build(job: 'tf-m-build-docs', parameters: params, propagate:false)
204 print("${res.number}: Docs ${res.result} ${res.getAbsoluteUrl()}")
Matthew Hart06340d72020-06-15 16:08:20 +0100205 results['docs'] = [res.number, res.result, params]
Dean Bircha6ede7e2020-03-13 14:00:33 +0000206 if (res.result in ["FAILURE", "ABORTED", "UNSTABLE", "NOT_BUILT"]) {
Dean Birch62c4f082020-01-17 16:13:26 +0000207 error("Build failed at ${res.getAbsoluteUrl()}")
208 }
209 }
210}
211
Xinyu Zhang38a18872020-11-23 16:45:28 +0800212def generateEmailBody(stage, failed_jobs) {
213 body = "Check console output at ${env.BUILD_URL} \n\n"
214
215 body += "Failed Jobs:\n"
216 failed_jobs.each { job ->
217 body += "${job.key} ${job.value}\n"
218 }
219
220 body += "\nFor detailed ${stage} results please refer to \
221 ${env.BUILD_URL}artifact/${stage}_results.csv \n"
222 return body
223}
224
225def emailNotification(results, stage, failed_jobs) {
Karl Zhang0413e972020-09-18 17:59:26 +0800226 script {
227 if (env.JOB_NAME.equals("tf-m-nightly") && !env.EMAIL_NOTIFICATION.equals('')) {
228 def result = "Fail."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800229 if (results == true) {
Karl Zhang0413e972020-09-18 17:59:26 +0800230 result = "Success."
Karl Zhang182ecdf2020-10-10 09:52:12 +0800231 print("Skip sending as ${result} for ${stage}")
232 }
233 else {
234 emailext (
235 subject: ("Job ${env.JOB_NAME} ${stage} ${env.BUILD_NUMBER} ${result}"),
Xinyu Zhang38a18872020-11-23 16:45:28 +0800236 body: generateEmailBody(stage, failed_jobs),
Karl Zhang182ecdf2020-10-10 09:52:12 +0800237 to: "${EMAIL_NOTIFICATION}"
238 )
239 }
Karl Zhang0413e972020-09-18 17:59:26 +0800240 }
241 } /* script */
242}
243
Xinyu Zhang38a18872020-11-23 16:45:28 +0800244def filterFailedBuild(results) {
245 def failed_builds = [:]
246 results.each { result ->
247 if (result.value[0].getResult() == "FAILURE") {
248 failed_builds[result.value[1]] = result.value[0].getAbsoluteUrl()
249 }
250 }
251 return failed_builds
252}
253
254def filterFailedTest(string) {
255 def failed_tests = [:]
256 line = lineInString(string, "FAILURE_TESTS:")
257 a = line.split(' ')
258 if (a.size() > 1) {
259 a = line.split(' ')[1..-1]
260 a.each { fail_test ->
261 config_link = fail_test.split(':')
262 failed_tests[config_link[0]] = config_link[1..-1].join(':')
263 }
264 }
265 return failed_tests
266}
267
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800268@NonCPS
269def generateCsvContent(results) {
270 def resultsParam = []
271 results.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800272 if (result.value[2]['BL2'] == "True") {
273 resultsParam.add([result.value[1], \
274 result.value[0].getResult(), \
275 result.value[2]['TFM_PLATFORM'], \
276 result.value[2]['TOOLCHAIN_FILE'], \
277 result.value[2]['CMAKE_BUILD_TYPE'], \
278 result.value[2]['BL2'], \
279 result.value[2]['NS'], \
280 result.value[2]['PSA_API'], \
281 result.value[2]['ISOLATION_LEVEL'], \
282 result.value[2]['TEST_REGRESSION'], \
283 result.value[2]['TEST_PSA_API'], \
284 result.value[2]['PROFILE'], \
285 result.value[2]['PARTITION_PS'], \
286 result.value[2]['OTP']])
287 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800288 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800289 resultsParam.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800290 if (result[2] == 'musca_b1') {
291 if (result[13] != 'off') {
292 result[2] = 'musca_b1_OTP'
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800293 }
294 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800295 result[3] = mapCompiler[result[3]]
296 build_params = result[5..12]
297 configName = ""
298 for (map_cfg in mapConfigs) {
299 if (build_params[0..6] == map_cfg[0..6]) {
300 configName = map_cfg[7]
301 break
302 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800303 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800304 if (configName == "") {
305 configName = "Default"
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800306 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800307 else if (configName == "RegressionProfileM") {
308 if (build_params[7] == "OFF") {
309 configName = "RegressionProfileM PSOFF"
310 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800311 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800312 result.add(configName)
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800313 }
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800314 def csvContent = []
315 resultsParam.each { result ->
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800316 current_row = result[2..4]
317 cfgs.each {cfg ->
318 if (cfg == result[14]) {
319 current_row.add(cfg)
320 current_row.add(result[1])
321 }
322 }
323 csvContent.add(current_row)
324 }
325 csvContent.sort{a,b -> a[0] <=> b[0] ?: a[1] <=> b[1] ?: a[2] <=> b[2]}
326 build_summary = []
327 current_platform = ""
328 current_compiler = ""
329 current_build_type = ""
330 csvContent.each { build_cfg ->
331 if (current_platform != build_cfg[0] || \
332 current_compiler != build_cfg[1] || \
333 current_build_type != build_cfg[2]) {
334 current_platform = build_cfg[0]
335 current_compiler = build_cfg[1]
336 current_build_type = build_cfg[2]
337 csv_line = [current_platform, current_compiler, current_build_type]
338 cfgs.each {
339 csv_line.add("N.A.")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800340 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800341 build_summary.add(csv_line)
342 }
343 i = 0
344 cfgs.each { cfg ->
345 if (cfg == build_cfg[3]) {
346 build_summary[-1][3+i] = build_cfg[4]
347 }
348 i += 1
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800349 }
350 }
Xinyu Zhang4f2ef5a2020-11-09 18:11:43 +0800351 build_summary.add(0, ['Platform', 'Compiler', 'Cmake Build Type'])
352 build_summary[0] += cfgs
353 return build_summary
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800354}
355
356def generateBuildCsv(results) {
357 def csvContent = generateCsvContent(results)
358 node("master") {
359 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
360 archiveArtifacts 'build_results.csv'
361 }
362}
Dean Bircha6ede7e2020-03-13 14:00:33 +0000363
364def buildCsv(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000365 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000366 def csvContent = summary.getBuildCsv(results)
367 node("master") {
368 writeCSV file: 'build_results.csv', records: csvContent, format: CSVFormat.EXCEL
369 archiveArtifacts 'build_results.csv'
370 }
371}
372
373def writeSummary(results) {
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000374 def summary = new Summary();
Dean Bircha6ede7e2020-03-13 14:00:33 +0000375 def buildLinks = summary.getLinks(results)
376 node("master") {
377 writeFile file: "build_links.html", text: buildLinks
378 archiveArtifacts 'build_links.html'
379 }
380}
381
Matthew Hartfb6fd362020-03-04 21:03:59 +0000382def lineInString(string, match) {
383 def lines = string.split("\n")
384 def result = lines.findAll { it.contains(match) }
385 return result[0]
386}
387
388def getResult(string, match) {
389 line = lineInString(string, match)
Dean Birch1d545c02020-05-29 14:09:21 +0100390 a = line.split(match)[1].split(' ')
391 score = a[0]
392 if (a.size() > 1)
393 {
394 fail_text = a[1..-1].join(" ")
395 return [score, fail_text]
396 }
397 return [score, ""]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000398}
399
400def submitJobsToList(results) {
401 def all_jobs = []
402 for (String result : results){
403 jobs_s = result.split('JOBS: ')
404 if (jobs_s.size() > 1) {
405 all_jobs += jobs_s[1]
406 }
407 }
408 return(all_jobs)
409}
410
Dean Birch62c4f082020-01-17 16:13:26 +0000411def configs = []
412def builds = [:]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000413def results = [:]
Dean Birch62c4f082020-01-17 16:13:26 +0000414
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000415node("docker-amd64-tf-m-bionic") {
Dean Birch62c4f082020-01-17 16:13:26 +0000416 stage("Init") {
417 cleanWs()
418 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000419 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Birch62c4f082020-01-17 16:13:26 +0000420 }
421 }
422 stage("Configs") {
423 // Populate configs
424 listConfigs('tf-m-ci-scripts', configs, env.FILTER_GROUP)
Dean Bircha6ede7e2020-03-13 14:00:33 +0000425 results['builds'] = [:]
426 results['lava_jobs'] = []
Dean Birch62c4f082020-01-17 16:13:26 +0000427 for (config in configs) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000428 builds[config] = buildConfig("tf-m-ci-scripts", config, env.FILTER_GROUP, results)
Dean Birch62c4f082020-01-17 16:13:26 +0000429 }
Matthew Hart06340d72020-06-15 16:08:20 +0100430 builds["docs"] = buildDocs(results)
Dean Birch62c4f082020-01-17 16:13:26 +0000431 }
432}
Karl Zhangfec84102020-06-24 09:56:36 +0800433
Dean Birch62c4f082020-01-17 16:13:26 +0000434stage("Builds") {
435 def verify = 1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800436 def success = true
Dean Birch62c4f082020-01-17 16:13:26 +0000437 try {
438 parallel(builds)
439 } catch (Exception e) {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000440 print(e)
Dean Birch62c4f082020-01-17 16:13:26 +0000441 manager.buildFailure()
442 verify = -1
Karl Zhang182ecdf2020-10-10 09:52:12 +0800443 success = false
Dean Birch62c4f082020-01-17 16:13:26 +0000444 } finally {
Dean Bircha6ede7e2020-03-13 14:00:33 +0000445 print("Verifying status")
Xinyu Zhang38a18872020-11-23 16:45:28 +0800446 def failed_builds = filterFailedBuild(results['builds'])
447 emailNotification(success, 'build', failed_builds)
Dean Birchd0f9f8c2020-03-26 11:10:33 +0000448 g = new Gerrit()
449 g.verifyStatus(verify, 'tf-m-build', 'build')
Dean Bircha6ede7e2020-03-13 14:00:33 +0000450 print("Building CSV")
xinyu-tfmb4fc0412020-08-19 10:49:51 +0800451 generateBuildCsv(results['builds'])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000452 writeSummary(results['builds'])
Dean Birch62c4f082020-01-17 16:13:26 +0000453 }
454}
Matthew Hart06340d72020-06-15 16:08:20 +0100455
Benjamin Copelandbe53b032020-10-30 19:57:59 +0000456node("docker-amd64-tf-m-bionic") {
Matthew Hart06340d72020-06-15 16:08:20 +0100457 stage("Copy Docs") {
Karl Zhang32497972020-09-21 14:38:29 +0800458 if (env.JOB_NAME.equals("tf-m-build-and-test")) {
459 step([$class: 'CopyArtifact', projectName: 'tf-m-build-docs',
460 selector: specific("${results['docs'][0]}"), target: './docs/',
461 optional: true])
462 archiveArtifacts artifacts: 'docs/**', allowEmptyArchive: true
463 }
464 else {
465 print("No doc copy for job: ${env.JOB_NAME}")
466 }
Matthew Hart06340d72020-06-15 16:08:20 +0100467 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000468 stage("Tests") {
469 dir("tf-m-ci-scripts") {
Colin Thorbinson58703db2020-11-24 12:02:19 +0000470 checkout([$class: 'GitSCM', branches: [[name: '$CI_SCRIPTS_BRANCH']], userRemoteConfigs: [[credentialsId: 'GIT_SSH_KEY', url: '$CI_SCRIPTS_REPO']]])
Dean Bircha6ede7e2020-03-13 14:00:33 +0000471 }
Matthew Hartfb6fd362020-03-04 21:03:59 +0000472 def all_jobs = []
473 def success = true
Dean Bircha6ede7e2020-03-13 14:00:33 +0000474 print("Wait for LAVA results here...")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000475 try {
476 all_jobs = submitJobsToList(results['lava_jobs'])
477 if (all_jobs.size() > 0) {
478 dir("tf-m-ci-scripts") {
Dean Birch956416f2020-08-12 10:36:16 +0100479 withCredentials([usernamePassword(credentialsId: env.LAVA_CREDENTIALS, passwordVariable: 'LAVA_TOKEN', usernameVariable: 'LAVA_USER')]) {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000480 output = sh(script: """./lava_helper/lava_wait_jobs.py --job-ids ${all_jobs.join(",")} \
481 --lava-url ${env.LAVA_URL} --lava-user ${LAVA_USER} --lava-token ${LAVA_TOKEN} \
Matthew Hart05a59b52020-05-27 17:54:51 +0100482 --artifacts-path lava_artifacts --lava-timeout 7200 \
Matthew Hartfb6fd362020-03-04 21:03:59 +0000483 """, returnStdout: true).trim()
484 archiveArtifacts artifacts: 'test_summary.*', allowEmptyArchive: true
Xinyu Zhang1b8f5152020-11-13 16:10:58 +0800485 archiveArtifacts artifacts: 'test_results.csv', allowEmptyArchive: true
Matthew Hartfb6fd362020-03-04 21:03:59 +0000486 g = new Gerrit()
Dean Birch1d545c02020-05-29 14:09:21 +0100487 def (boot_result, boot_output) = getResult(output, 'BOOT_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000488 if (boot_result) {
489 g.verifyStatus(boot_result, "lava_boot", "test")
490 }
Dean Birch1d545c02020-05-29 14:09:21 +0100491 def (test_result, test_output) = getResult(output, 'TEST_RESULT: ')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000492 if (test_result) {
493 g.verifyStatus(test_result, "lava_test", "test")
494 }
495 if (boot_result.toInteger() < 1 || test_result.toInteger() < 1) {
Dean Birch1d545c02020-05-29 14:09:21 +0100496 error("Marking job as failed due to failed boots: ${boot_output} or tests: ${test_output}")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000497 }
498 }
499 }
500 }
501 else {
502 print("There were no LAVA jobs to test.")
503 }
504 }
505 catch (Exception e) {
506 print("ERROR: ${e}")
507 success = false
508 } finally {
509 archiveArtifacts artifacts: 'tf-m-ci-scripts/lava_artifacts/**', allowEmptyArchive: true
Xinyu Zhang38a18872020-11-23 16:45:28 +0800510 emailNotification(success, 'test', filterFailedTest(output))
Matthew Hartfb6fd362020-03-04 21:03:59 +0000511 cleanWs()
512 if (!success) {
513 error("There was an Error waiting for LAVA jobs")
514 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000515 }
516 }
Dean Bircha6ede7e2020-03-13 14:00:33 +0000517}