blob: 4b27fa6564c334390ee5ec3f57277409ab02f7ba [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 Zhang28d61b42022-03-21 16:46:35 +08007 * Copyright (c) 2020-2022, 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
Matthew Hartfb6fd362020-03-04 21:03:59 +000024
25def get_artifact_url(artifact_store_url, params, filename):
Fathi Boudrae9accbc2020-11-25 10:32:31 +010026 platform = params["platform"]
27 if params["device_type"] == "fvp":
28 platform = "fvp"
29
Fathi Boudracaa90bd2020-12-04 22:00:14 +010030 url = "{}/artifact/trusted-firmware-m/build/bin/{}".format(artifact_store_url.rstrip("/"), filename)
Fathi Boudrae9accbc2020-11-25 10:32:31 +010031 return url
Matthew Hartfb6fd362020-03-04 21:03:59 +000032
33
34def get_recovery_url(recovery_store_url, recovery):
Dean Birch5d2dc572020-05-29 13:15:59 +010035 return "{}/{}".format(recovery_store_url.rstrip('/'), recovery)
Matthew Hartfb6fd362020-03-04 21:03:59 +000036
37
38def get_job_name(name, params, job):
39 return "{}_{}_{}_{}_{}_{}_{}_{}".format(
40 name,
41 job,
42 params["platform"],
43 params["build_no"],
44 params["compiler"],
45 params["build_type"],
46 params["boot_type"],
47 params["name"],
48 )
49
50
51def get_build_name(params):
52 return "{}_{}_{}_{}_{}".format(
53 params["platform"],
54 params["compiler"],
55 params["name"],
56 params["build_type"],
57 params["boot_type"],
58 )
59
60
Xinyu Zhangc918b6e2022-10-08 17:13:17 +080061def load_config_overrides(user_args, config_key):
62 """Load a configuration from multiple locations and override it with user provided
63 arguments"""
64
65 print("Using built-in config: %s" % config_key)
66 try:
67 config = lava_gen_config_map[config_key]
68 except KeyError:
69 print("No template found for config: %s" % config_key)
70 sys.exit(1)
71
72 config["build_no"] = user_args.build_no
73 config["artifact_store_url"] = user_args.jenkins_build_url
74
75 # Add the template folder
76 config["templ"] = os.path.join(user_args.template_dir, config["templ"])
77 return config
78
79
Matthew Hartfb6fd362020-03-04 21:03:59 +000080def generate_test_definitions(config, work_dir, user_args):
Fathi Boudra13b7eba2020-11-26 10:29:53 +010081 """Get a dictionary configuration and an existing jinja2 template to generate
82 a LAVA compatible yaml definition"""
Matthew Hartfb6fd362020-03-04 21:03:59 +000083
84 template_loader = FileSystemLoader(searchpath=work_dir)
85 template_env = Environment(loader=template_loader)
Dean Birch5d2dc572020-05-29 13:15:59 +010086 recovery_store_url = config.get('recovery_store_url', '')
Matthew Hartfb6fd362020-03-04 21:03:59 +000087 build_no = user_args.build_no
Dean Birch5d2dc572020-05-29 13:15:59 +010088 artifact_store_url = config["artifact_store_url"]
Matthew Hartfb6fd362020-03-04 21:03:59 +000089 template_file = config.pop("templ")
90
91 definitions = {}
92
93 for platform, recovery in config["platforms"].items():
94 if platform != user_args.platform:
95 continue
96 recovery_image_url = get_recovery_url(recovery_store_url, recovery)
97 for compiler in config["compilers"]:
98 if compiler != user_args.compiler:
99 continue
100 for build_type in config["build_types"]:
101 if build_type != user_args.build_type:
102 continue
103 for boot_type in config["boot_types"]:
104 bl2_string = "BL2" if user_args.bl2 else "NOBL2"
105 if boot_type != bl2_string:
106 continue
107 for test_name, test_dict in config["tests"].items():
108 if "Config{}".format(test_name) != user_args.proj_config:
109 continue
110 params = {
111 "device_type": config["device_type"],
112 "job_timeout": config["job_timeout"],
Fathi Boudra7454c552020-11-25 13:40:28 +0100113 "action_timeout": config.get("action_timeout", ''),
114 "monitor_timeout": config.get("monitor_timeout", ''),
115 "poweroff_timeout": config.get("poweroff_timeout", ''),
Matthew Hartfb6fd362020-03-04 21:03:59 +0000116 "compiler": compiler,
117 "build_type": build_type,
118 "build_no": build_no,
119 "boot_type": boot_type,
120 "name": test_name,
121 "test": test_dict,
122 "platform": platform,
123 "recovery_image_url": recovery_image_url,
124 "data_bin_offset": config.get('data_bin_offset', ''),
125 "docker_prefix": vars(user_args).get('docker_prefix', ''),
126 "license_variable": vars(user_args).get('license_variable', ''),
Leonardo Sandoval66386a22021-04-15 14:35:08 -0500127 "enable_code_coverage": user_args.enable_code_coverage == "TRUE",
128 "coverage_trace_plugin": coverage_trace_plugin,
Matthew Hartfb6fd362020-03-04 21:03:59 +0000129 "build_job_url": artifact_store_url,
Matthew Hart2c2688f2020-05-26 13:09:20 +0100130 "cpu0_baseline": config.get("cpu0_baseline", 0),
Paul Sokolovsky6302e1f2022-06-01 15:25:08 +0300131 "cpu0_initvtor_s": config.get("cpu0_initvtor_s", "0x10000000"),
132 "psa_api_suite": user_args.psa_suite,
Matthew Hartfb6fd362020-03-04 21:03:59 +0000133 }
Xinyu Zhang28d61b42022-03-21 16:46:35 +0800134 for binary_type, binary_name in config["binaries"].items():
135 params.update(
136 {
137 "{}_url".format(binary_type): get_artifact_url(
138 artifact_store_url,
139 params,
140 binary_name
141 )
142 }
143 )
Matthew Hartfb6fd362020-03-04 21:03:59 +0000144 params.update(
145 {
146 "job_name": get_job_name(
147 config["job_name"], params, user_args.jenkins_job,
148 ),
149 "build_name": get_build_name(params)
150 }
151 )
152
153 definition = template_env.get_template(template_file).render(
154 params
155 )
156 definitions.update({params["job_name"]: definition})
157 return definitions
158
159
160def generate_lava_job_defs(user_args, config):
Fathi Boudra13b7eba2020-11-26 10:29:53 +0100161 """Create a LAVA test job definition file"""
Matthew Hartfb6fd362020-03-04 21:03:59 +0000162
163 # Evaluate current directory
164 work_dir = os.path.abspath(os.path.dirname(__file__))
165
166 # If a single platform is requested and it exists in the platform
167 if user_args.platform and user_args.platform in config["platforms"]:
168 # Only test this platform
169 platform = user_args.platform
170 config["platforms"] = {platform: config["platforms"][platform]}
Fathi Boudra13b7eba2020-11-26 10:29:53 +0100171 # Generate the output definition
Matthew Hartfb6fd362020-03-04 21:03:59 +0000172 definitions = generate_test_definitions(config, work_dir, user_args)
Matthew Hartfb6fd362020-03-04 21:03:59 +0000173 # Write it into a file
174 out_dir = os.path.abspath(user_args.lava_def_output)
175 os.makedirs(out_dir, exist_ok=True)
176 for name, definition in definitions.items():
177 out_file = os.path.join(out_dir, "{}{}".format(name, ".yaml"))
178 with open(out_file, "w") as F:
179 F.write(definition)
180 print("Definition created at %s" % out_file)
181
182
183def main(user_args):
184 user_args.template_dir = "jinja2_templates"
Xinyu Zhangbe224f62021-02-03 17:57:38 +0800185 config_keys = list(lava_gen_config_map.keys())
186 if user_args.fvp_only:
Xinyu Zhangd7616fc2022-07-06 16:14:36 +0800187 config_keys = [key for key in config_keys if "fvp" in key]
Xinyu Zhang302b74d2021-11-03 14:53:44 +0800188 if user_args.physical_board_only:
Xinyu Zhangd7616fc2022-07-06 16:14:36 +0800189 config_keys = [key for key in config_keys
190 if "fvp" not in key and "qemu" not in key]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000191 if user_args.config_key:
192 config_keys = [user_args.config_key]
193 for config_key in config_keys:
194 config = load_config_overrides(user_args, config_key)
195 generate_lava_job_defs(user_args, config)
196
197
198def get_cmd_args():
Fathi Boudra13b7eba2020-11-26 10:29:53 +0100199 """Parse command line arguments"""
Matthew Hartfb6fd362020-03-04 21:03:59 +0000200
201 # Parse command line arguments to override config
202 parser = argparse.ArgumentParser(description="Lava Create Jobs")
203 cmdargs = parser.add_argument_group("Create LAVA Jobs")
Xinyu Zhang302b74d2021-11-03 14:53:44 +0800204 device_type = parser.add_mutually_exclusive_group()
Matthew Hartfb6fd362020-03-04 21:03:59 +0000205
206 # Configuration control
207 cmdargs.add_argument(
208 "--config-name",
209 dest="config_key",
210 action="store",
211 help="Select built-in configuration by name",
212 )
213 cmdargs.add_argument(
214 "--build-number",
215 dest="build_no",
216 action="store",
217 default="lastSuccessfulBuild",
218 help="JENKINS Build number selector. " "Default: lastSuccessfulBuild",
219 )
220 cmdargs.add_argument(
221 "--output-dir",
222 dest="lava_def_output",
223 action="store",
224 default="job_results",
225 help="Set LAVA compatible .yaml output file",
226 )
227 cmdargs.add_argument(
228 "--platform",
229 dest="platform",
230 action="store",
231 help="Override platform.Only the provided one " "will be tested",
232 )
233 cmdargs.add_argument(
234 "--compiler",
235 dest="compiler",
236 action="store",
237 help="Compiler to build definitions for",
238 )
239 cmdargs.add_argument(
240 "--jenkins-build-url",
241 dest="jenkins_build_url",
242 action="store",
243 help="Set the Jenkins URL",
244 )
245 cmdargs.add_argument(
246 "--jenkins-job",
247 dest="jenkins_job",
248 action="store",
249 default="tf-m-build-config",
250 help="Set the jenkins job name",
251 )
252 cmdargs.add_argument(
253 "--proj-config", dest="proj_config", action="store", help="Proj config"
254 )
255 cmdargs.add_argument(
256 "--build-type", dest="build_type", action="store", help="Build type"
257 )
258 cmdargs.add_argument(
259 "--docker-prefix", dest="docker_prefix", action="store", help="Prefix string for the FVP docker registry location"
260 )
261 cmdargs.add_argument(
262 "--license-variable", dest="license_variable", action="store", help="License string for Fastmodels"
263 )
Leonardo Sandoval66386a22021-04-15 14:35:08 -0500264 cmdargs.add_argument(
265 "--enable-code-coverage", dest="enable_code_coverage", action="store", default="FALSE", help="Enable trace-base code coverage"
266 )
Matthew Hartfb6fd362020-03-04 21:03:59 +0000267 cmdargs.add_argument("--bl2", dest="bl2", action="store_true", help="BL2")
Matthew Hart2c2688f2020-05-26 13:09:20 +0100268 cmdargs.add_argument(
269 "--psa-api-suite", dest="psa_suite", action="store", help="PSA API Suite name"
270 )
Matthew Hartfb6fd362020-03-04 21:03:59 +0000271
Xinyu Zhang302b74d2021-11-03 14:53:44 +0800272 device_type.add_argument(
273 "--fvp-only",
274 dest="fvp_only",
275 action="store_true",
276 help="Run test cases on FVP only",
277 )
278 device_type.add_argument(
279 "--physical-board-only",
280 dest="physical_board_only",
281 action="store_true",
282 help="Run test cases on physical boards only",
283 )
284
285 return parser.parse_args()
Matthew Hartfb6fd362020-03-04 21:03:59 +0000286
287if __name__ == "__main__":
288 main(get_cmd_args())