blob: 71baa3f13fa29ae534588c228557fccad0e3affb [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/*
7 * Copyright (c) 2020, Arm Limited. All rights reserved.
8 *
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 Boudra83e4f292020-12-04 22:33:40 +010056 # FIXME: temporary workaround until we switch all platforms artifacts
57 # to use the same location (new build system)
58 url = "{}/artifact/trusted-firmware-m/build".format(artifact_store_url.rstrip("/"))
59 if platform.lower().startswith("musca"):
60 url = "{}/bin/{}".format(url, filename)
61 else:
62 url = "{}/install/outputs/{}/{}".format(url, platform, filename)
Fathi Boudrae9accbc2020-11-25 10:32:31 +010063 return url
Matthew Hartfb6fd362020-03-04 21:03:59 +000064
65
66def get_recovery_url(recovery_store_url, recovery):
Dean Birch5d2dc572020-05-29 13:15:59 +010067 return "{}/{}".format(recovery_store_url.rstrip('/'), recovery)
Matthew Hartfb6fd362020-03-04 21:03:59 +000068
69
70def get_job_name(name, params, job):
71 return "{}_{}_{}_{}_{}_{}_{}_{}".format(
72 name,
73 job,
74 params["platform"],
75 params["build_no"],
76 params["compiler"],
77 params["build_type"],
78 params["boot_type"],
79 params["name"],
80 )
81
82
83def get_build_name(params):
84 return "{}_{}_{}_{}_{}".format(
85 params["platform"],
86 params["compiler"],
87 params["name"],
88 params["build_type"],
89 params["boot_type"],
90 )
91
92
93def generate_test_definitions(config, work_dir, user_args):
Fathi Boudra13b7eba2020-11-26 10:29:53 +010094 """Get a dictionary configuration and an existing jinja2 template to generate
95 a LAVA compatible yaml definition"""
Matthew Hartfb6fd362020-03-04 21:03:59 +000096
97 template_loader = FileSystemLoader(searchpath=work_dir)
98 template_env = Environment(loader=template_loader)
Dean Birch5d2dc572020-05-29 13:15:59 +010099 recovery_store_url = config.get('recovery_store_url', '')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000100 build_no = user_args.build_no
Dean Birch5d2dc572020-05-29 13:15:59 +0100101 artifact_store_url = config["artifact_store_url"]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000102 template_file = config.pop("templ")
103
104 definitions = {}
105
106 for platform, recovery in config["platforms"].items():
107 if platform != user_args.platform:
108 continue
109 recovery_image_url = get_recovery_url(recovery_store_url, recovery)
110 for compiler in config["compilers"]:
111 if compiler != user_args.compiler:
112 continue
113 for build_type in config["build_types"]:
114 if build_type != user_args.build_type:
115 continue
116 for boot_type in config["boot_types"]:
117 bl2_string = "BL2" if user_args.bl2 else "NOBL2"
118 if boot_type != bl2_string:
119 continue
120 for test_name, test_dict in config["tests"].items():
121 if "Config{}".format(test_name) != user_args.proj_config:
122 continue
123 params = {
124 "device_type": config["device_type"],
125 "job_timeout": config["job_timeout"],
Fathi Boudra7454c552020-11-25 13:40:28 +0100126 "action_timeout": config.get("action_timeout", ''),
127 "monitor_timeout": config.get("monitor_timeout", ''),
128 "poweroff_timeout": config.get("poweroff_timeout", ''),
Matthew Hartfb6fd362020-03-04 21:03:59 +0000129 "compiler": compiler,
130 "build_type": build_type,
131 "build_no": build_no,
132 "boot_type": boot_type,
133 "name": test_name,
134 "test": test_dict,
135 "platform": platform,
136 "recovery_image_url": recovery_image_url,
137 "data_bin_offset": config.get('data_bin_offset', ''),
138 "docker_prefix": vars(user_args).get('docker_prefix', ''),
139 "license_variable": vars(user_args).get('license_variable', ''),
140 "build_job_url": artifact_store_url,
Matthew Hart2c2688f2020-05-26 13:09:20 +0100141 "cpu0_baseline": config.get("cpu0_baseline", 0),
142 "cpu0_initvtor_s": config.get("cpu0_initvtor_s", "0x10000000")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000143 }
144 params.update(
145 {
146 "firmware_url": get_artifact_url(
147 artifact_store_url,
148 params,
Fathi Boudra7454c552020-11-25 13:40:28 +0100149 test_dict.get("binaries").get("firmware"),
Matthew Hartfb6fd362020-03-04 21:03:59 +0000150 ),
Fathi Boudra7454c552020-11-25 13:40:28 +0100151 }
152 )
153 params.update(
154 {
Matthew Hartfb6fd362020-03-04 21:03:59 +0000155 "bootloader_url": get_artifact_url(
156 artifact_store_url,
157 params,
Fathi Boudra7454c552020-11-25 13:40:28 +0100158 test_dict.get("binaries").get("bootloader"),
Matthew Hartfb6fd362020-03-04 21:03:59 +0000159 ),
160 }
161 )
162 params.update(
163 {
164 "job_name": get_job_name(
165 config["job_name"], params, user_args.jenkins_job,
166 ),
167 "build_name": get_build_name(params)
168 }
169 )
170
171 definition = template_env.get_template(template_file).render(
172 params
173 )
174 definitions.update({params["job_name"]: definition})
175 return definitions
176
177
178def generate_lava_job_defs(user_args, config):
Fathi Boudra13b7eba2020-11-26 10:29:53 +0100179 """Create a LAVA test job definition file"""
Matthew Hartfb6fd362020-03-04 21:03:59 +0000180
181 # Evaluate current directory
182 work_dir = os.path.abspath(os.path.dirname(__file__))
183
184 # If a single platform is requested and it exists in the platform
185 if user_args.platform and user_args.platform in config["platforms"]:
186 # Only test this platform
187 platform = user_args.platform
188 config["platforms"] = {platform: config["platforms"][platform]}
Fathi Boudra13b7eba2020-11-26 10:29:53 +0100189 # Generate the output definition
Matthew Hartfb6fd362020-03-04 21:03:59 +0000190 definitions = generate_test_definitions(config, work_dir, user_args)
191
192 # Write it into a file
193 out_dir = os.path.abspath(user_args.lava_def_output)
194 os.makedirs(out_dir, exist_ok=True)
195 for name, definition in definitions.items():
196 out_file = os.path.join(out_dir, "{}{}".format(name, ".yaml"))
197 with open(out_file, "w") as F:
198 F.write(definition)
199 print("Definition created at %s" % out_file)
200
201
202def main(user_args):
203 user_args.template_dir = "jinja2_templates"
204 config_keys = lava_gen_config_map.keys()
205 if user_args.config_key:
206 config_keys = [user_args.config_key]
207 for config_key in config_keys:
208 config = load_config_overrides(user_args, config_key)
209 generate_lava_job_defs(user_args, config)
210
211
212def get_cmd_args():
Fathi Boudra13b7eba2020-11-26 10:29:53 +0100213 """Parse command line arguments"""
Matthew Hartfb6fd362020-03-04 21:03:59 +0000214
215 # Parse command line arguments to override config
216 parser = argparse.ArgumentParser(description="Lava Create Jobs")
217 cmdargs = parser.add_argument_group("Create LAVA Jobs")
218
219 # Configuration control
220 cmdargs.add_argument(
221 "--config-name",
222 dest="config_key",
223 action="store",
224 help="Select built-in configuration by name",
225 )
226 cmdargs.add_argument(
227 "--build-number",
228 dest="build_no",
229 action="store",
230 default="lastSuccessfulBuild",
231 help="JENKINS Build number selector. " "Default: lastSuccessfulBuild",
232 )
233 cmdargs.add_argument(
234 "--output-dir",
235 dest="lava_def_output",
236 action="store",
237 default="job_results",
238 help="Set LAVA compatible .yaml output file",
239 )
240 cmdargs.add_argument(
241 "--platform",
242 dest="platform",
243 action="store",
244 help="Override platform.Only the provided one " "will be tested",
245 )
246 cmdargs.add_argument(
247 "--compiler",
248 dest="compiler",
249 action="store",
250 help="Compiler to build definitions for",
251 )
252 cmdargs.add_argument(
253 "--jenkins-build-url",
254 dest="jenkins_build_url",
255 action="store",
256 help="Set the Jenkins URL",
257 )
258 cmdargs.add_argument(
259 "--jenkins-job",
260 dest="jenkins_job",
261 action="store",
262 default="tf-m-build-config",
263 help="Set the jenkins job name",
264 )
265 cmdargs.add_argument(
266 "--proj-config", dest="proj_config", action="store", help="Proj config"
267 )
268 cmdargs.add_argument(
269 "--build-type", dest="build_type", action="store", help="Build type"
270 )
271 cmdargs.add_argument(
272 "--docker-prefix", dest="docker_prefix", action="store", help="Prefix string for the FVP docker registry location"
273 )
274 cmdargs.add_argument(
275 "--license-variable", dest="license_variable", action="store", help="License string for Fastmodels"
276 )
277 cmdargs.add_argument("--bl2", dest="bl2", action="store_true", help="BL2")
Matthew Hart2c2688f2020-05-26 13:09:20 +0100278 cmdargs.add_argument(
279 "--psa-api-suite", dest="psa_suite", action="store", help="PSA API Suite name"
280 )
Matthew Hartfb6fd362020-03-04 21:03:59 +0000281 return parser.parse_args()
282
283
284if __name__ == "__main__":
285 main(get_cmd_args())