blob: f922a738b546b212a8f05b898f1bee7e304fba56 [file] [log] [blame]
Matthew Hartfb6fd362020-03-04 21:03:59 +00001#!/usr/bin/env python3
2
3from __future__ import print_function
4
5__copyright__ = """
6/*
Xinyu Zhangbe224f62021-02-03 17:57:38 +08007 * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
Matthew Hartfb6fd362020-03-04 21:03:59 +00008 *
9 * SPDX-License-Identifier: BSD-3-Clause
10 *
11 */
12 """
13
14"""
Fathi Boudra13b7eba2020-11-26 10:29:53 +010015Script to create LAVA definitions from a single tf-m-build-config Jenkins Job
Matthew Hartfb6fd362020-03-04 21:03:59 +000016"""
17
18import os
19import sys
Matthew Hartfb6fd362020-03-04 21:03:59 +000020import argparse
Matthew Hartfb6fd362020-03-04 21:03:59 +000021from jinja2 import Environment, FileSystemLoader
22from lava_helper_configs import *
23
24try:
25 from tfm_ci_pylib.lava_rpc_connector import LAVA_RPC_connector
26except ImportError:
27 dir_path = os.path.dirname(os.path.realpath(__file__))
28 sys.path.append(os.path.join(dir_path, "../"))
29 from tfm_ci_pylib.lava_rpc_connector import LAVA_RPC_connector
30
31
32def load_config_overrides(user_args, config_key):
Fathi Boudra13b7eba2020-11-26 10:29:53 +010033 """Load a configuration from multiple locations and override it with user provided
34 arguments"""
Matthew Hartfb6fd362020-03-04 21:03:59 +000035
36 print("Using built-in config: %s" % config_key)
37 try:
38 config = lava_gen_config_map[config_key]
39 except KeyError:
40 print("No template found for config: %s" % config_key)
41 sys.exit(1)
42
43 config["build_no"] = user_args.build_no
Dean Birch5d2dc572020-05-29 13:15:59 +010044 config["artifact_store_url"] = user_args.jenkins_build_url
Matthew Hartfb6fd362020-03-04 21:03:59 +000045
Fathi Boudra13b7eba2020-11-26 10:29:53 +010046 # Add the template folder
Matthew Hartfb6fd362020-03-04 21:03:59 +000047 config["templ"] = os.path.join(user_args.template_dir, config["templ"])
48 return config
49
50
51def get_artifact_url(artifact_store_url, params, filename):
Fathi Boudrae9accbc2020-11-25 10:32:31 +010052 platform = params["platform"]
53 if params["device_type"] == "fvp":
54 platform = "fvp"
55
Fathi Boudracaa90bd2020-12-04 22:00:14 +010056 url = "{}/artifact/trusted-firmware-m/build/bin/{}".format(artifact_store_url.rstrip("/"), filename)
Fathi Boudrae9accbc2020-11-25 10:32:31 +010057 return url
Matthew Hartfb6fd362020-03-04 21:03:59 +000058
59
60def get_recovery_url(recovery_store_url, recovery):
Dean Birch5d2dc572020-05-29 13:15:59 +010061 return "{}/{}".format(recovery_store_url.rstrip('/'), recovery)
Matthew Hartfb6fd362020-03-04 21:03:59 +000062
63
64def get_job_name(name, params, job):
65 return "{}_{}_{}_{}_{}_{}_{}_{}".format(
66 name,
67 job,
68 params["platform"],
69 params["build_no"],
70 params["compiler"],
71 params["build_type"],
72 params["boot_type"],
73 params["name"],
74 )
75
76
77def get_build_name(params):
78 return "{}_{}_{}_{}_{}".format(
79 params["platform"],
80 params["compiler"],
81 params["name"],
82 params["build_type"],
83 params["boot_type"],
84 )
85
86
87def generate_test_definitions(config, work_dir, user_args):
Fathi Boudra13b7eba2020-11-26 10:29:53 +010088 """Get a dictionary configuration and an existing jinja2 template to generate
89 a LAVA compatible yaml definition"""
Matthew Hartfb6fd362020-03-04 21:03:59 +000090
91 template_loader = FileSystemLoader(searchpath=work_dir)
92 template_env = Environment(loader=template_loader)
Dean Birch5d2dc572020-05-29 13:15:59 +010093 recovery_store_url = config.get('recovery_store_url', '')
Matthew Hartfb6fd362020-03-04 21:03:59 +000094 build_no = user_args.build_no
Dean Birch5d2dc572020-05-29 13:15:59 +010095 artifact_store_url = config["artifact_store_url"]
Matthew Hartfb6fd362020-03-04 21:03:59 +000096 template_file = config.pop("templ")
97
98 definitions = {}
99
100 for platform, recovery in config["platforms"].items():
101 if platform != user_args.platform:
102 continue
103 recovery_image_url = get_recovery_url(recovery_store_url, recovery)
104 for compiler in config["compilers"]:
105 if compiler != user_args.compiler:
106 continue
107 for build_type in config["build_types"]:
108 if build_type != user_args.build_type:
109 continue
110 for boot_type in config["boot_types"]:
111 bl2_string = "BL2" if user_args.bl2 else "NOBL2"
112 if boot_type != bl2_string:
113 continue
114 for test_name, test_dict in config["tests"].items():
115 if "Config{}".format(test_name) != user_args.proj_config:
116 continue
117 params = {
118 "device_type": config["device_type"],
119 "job_timeout": config["job_timeout"],
Fathi Boudra7454c552020-11-25 13:40:28 +0100120 "action_timeout": config.get("action_timeout", ''),
121 "monitor_timeout": config.get("monitor_timeout", ''),
122 "poweroff_timeout": config.get("poweroff_timeout", ''),
Matthew Hartfb6fd362020-03-04 21:03:59 +0000123 "compiler": compiler,
124 "build_type": build_type,
125 "build_no": build_no,
126 "boot_type": boot_type,
127 "name": test_name,
128 "test": test_dict,
129 "platform": platform,
130 "recovery_image_url": recovery_image_url,
131 "data_bin_offset": config.get('data_bin_offset', ''),
132 "docker_prefix": vars(user_args).get('docker_prefix', ''),
133 "license_variable": vars(user_args).get('license_variable', ''),
Leonardo Sandoval66386a22021-04-15 14:35:08 -0500134 "enable_code_coverage": user_args.enable_code_coverage == "TRUE",
135 "coverage_trace_plugin": coverage_trace_plugin,
Matthew Hartfb6fd362020-03-04 21:03:59 +0000136 "build_job_url": artifact_store_url,
Matthew Hart2c2688f2020-05-26 13:09:20 +0100137 "cpu0_baseline": config.get("cpu0_baseline", 0),
138 "cpu0_initvtor_s": config.get("cpu0_initvtor_s", "0x10000000")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000139 }
140 params.update(
141 {
142 "firmware_url": get_artifact_url(
143 artifact_store_url,
144 params,
Fathi Boudra7454c552020-11-25 13:40:28 +0100145 test_dict.get("binaries").get("firmware"),
Matthew Hartfb6fd362020-03-04 21:03:59 +0000146 ),
Arthur She07c91b52021-07-15 15:03:10 -0700147 "tarball_url": get_artifact_url(
148 artifact_store_url,
149 params,
150 test_dict.get("binaries").get("tarball"),
151 ),
Arthur She87602dc2022-02-06 14:42:18 -0800152 "spe_url": get_artifact_url(
153 artifact_store_url,
154 params,
155 test_dict.get("binaries").get("spe_image"),
156 ),
157 "nspe_url": get_artifact_url(
158 artifact_store_url,
159 params,
160 test_dict.get("binaries").get("nspe_image"),
161 ),
Fathi Boudra7454c552020-11-25 13:40:28 +0100162 }
163 )
164 params.update(
165 {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000166 "bootloader_url": get_artifact_url(
167 artifact_store_url,
168 params,
Fathi Boudra7454c552020-11-25 13:40:28 +0100169 test_dict.get("binaries").get("bootloader"),
Matthew Hartfb6fd362020-03-04 21:03:59 +0000170 ),
171 }
172 )
173 params.update(
174 {
175 "job_name": get_job_name(
176 config["job_name"], params, user_args.jenkins_job,
177 ),
178 "build_name": get_build_name(params)
179 }
180 )
181
182 definition = template_env.get_template(template_file).render(
183 params
184 )
185 definitions.update({params["job_name"]: definition})
186 return definitions
187
188
189def generate_lava_job_defs(user_args, config):
Fathi Boudra13b7eba2020-11-26 10:29:53 +0100190 """Create a LAVA test job definition file"""
Matthew Hartfb6fd362020-03-04 21:03:59 +0000191
192 # Evaluate current directory
193 work_dir = os.path.abspath(os.path.dirname(__file__))
194
195 # If a single platform is requested and it exists in the platform
196 if user_args.platform and user_args.platform in config["platforms"]:
197 # Only test this platform
198 platform = user_args.platform
199 config["platforms"] = {platform: config["platforms"][platform]}
Fathi Boudra13b7eba2020-11-26 10:29:53 +0100200 # Generate the output definition
Matthew Hartfb6fd362020-03-04 21:03:59 +0000201 definitions = generate_test_definitions(config, work_dir, user_args)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000202 # Write it into a file
203 out_dir = os.path.abspath(user_args.lava_def_output)
204 os.makedirs(out_dir, exist_ok=True)
205 for name, definition in definitions.items():
206 out_file = os.path.join(out_dir, "{}{}".format(name, ".yaml"))
207 with open(out_file, "w") as F:
208 F.write(definition)
209 print("Definition created at %s" % out_file)
210
211
212def main(user_args):
213 user_args.template_dir = "jinja2_templates"
Xinyu Zhangbe224f62021-02-03 17:57:38 +0800214 config_keys = list(lava_gen_config_map.keys())
215 if user_args.fvp_only:
216 for key in config_keys:
217 if "fvp" not in key:
218 config_keys.remove(key)
Xinyu Zhang302b74d2021-11-03 14:53:44 +0800219 if user_args.physical_board_only:
220 for key in config_keys:
221 if "fvp" in key or "qemu" in key:
222 config_keys.remove(key)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000223 if user_args.config_key:
224 config_keys = [user_args.config_key]
225 for config_key in config_keys:
226 config = load_config_overrides(user_args, config_key)
227 generate_lava_job_defs(user_args, config)
228
229
230def get_cmd_args():
Fathi Boudra13b7eba2020-11-26 10:29:53 +0100231 """Parse command line arguments"""
Matthew Hartfb6fd362020-03-04 21:03:59 +0000232
233 # Parse command line arguments to override config
234 parser = argparse.ArgumentParser(description="Lava Create Jobs")
235 cmdargs = parser.add_argument_group("Create LAVA Jobs")
Xinyu Zhang302b74d2021-11-03 14:53:44 +0800236 device_type = parser.add_mutually_exclusive_group()
Matthew Hartfb6fd362020-03-04 21:03:59 +0000237
238 # Configuration control
239 cmdargs.add_argument(
240 "--config-name",
241 dest="config_key",
242 action="store",
243 help="Select built-in configuration by name",
244 )
245 cmdargs.add_argument(
246 "--build-number",
247 dest="build_no",
248 action="store",
249 default="lastSuccessfulBuild",
250 help="JENKINS Build number selector. " "Default: lastSuccessfulBuild",
251 )
252 cmdargs.add_argument(
253 "--output-dir",
254 dest="lava_def_output",
255 action="store",
256 default="job_results",
257 help="Set LAVA compatible .yaml output file",
258 )
259 cmdargs.add_argument(
260 "--platform",
261 dest="platform",
262 action="store",
263 help="Override platform.Only the provided one " "will be tested",
264 )
265 cmdargs.add_argument(
266 "--compiler",
267 dest="compiler",
268 action="store",
269 help="Compiler to build definitions for",
270 )
271 cmdargs.add_argument(
272 "--jenkins-build-url",
273 dest="jenkins_build_url",
274 action="store",
275 help="Set the Jenkins URL",
276 )
277 cmdargs.add_argument(
278 "--jenkins-job",
279 dest="jenkins_job",
280 action="store",
281 default="tf-m-build-config",
282 help="Set the jenkins job name",
283 )
284 cmdargs.add_argument(
285 "--proj-config", dest="proj_config", action="store", help="Proj config"
286 )
287 cmdargs.add_argument(
288 "--build-type", dest="build_type", action="store", help="Build type"
289 )
290 cmdargs.add_argument(
291 "--docker-prefix", dest="docker_prefix", action="store", help="Prefix string for the FVP docker registry location"
292 )
293 cmdargs.add_argument(
294 "--license-variable", dest="license_variable", action="store", help="License string for Fastmodels"
295 )
Leonardo Sandoval66386a22021-04-15 14:35:08 -0500296 cmdargs.add_argument(
297 "--enable-code-coverage", dest="enable_code_coverage", action="store", default="FALSE", help="Enable trace-base code coverage"
298 )
Matthew Hartfb6fd362020-03-04 21:03:59 +0000299 cmdargs.add_argument("--bl2", dest="bl2", action="store_true", help="BL2")
Matthew Hart2c2688f2020-05-26 13:09:20 +0100300 cmdargs.add_argument(
301 "--psa-api-suite", dest="psa_suite", action="store", help="PSA API Suite name"
302 )
Matthew Hartfb6fd362020-03-04 21:03:59 +0000303
Xinyu Zhang302b74d2021-11-03 14:53:44 +0800304 device_type.add_argument(
305 "--fvp-only",
306 dest="fvp_only",
307 action="store_true",
308 help="Run test cases on FVP only",
309 )
310 device_type.add_argument(
311 "--physical-board-only",
312 dest="physical_board_only",
313 action="store_true",
314 help="Run test cases on physical boards only",
315 )
316
317 return parser.parse_args()
Matthew Hartfb6fd362020-03-04 21:03:59 +0000318
319if __name__ == "__main__":
320 main(get_cmd_args())