blob: a22f7c9e293dbe8e00aaed879eb895de93eaa805 [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"""
15Script for create LAVA definitions from a single tf-m-build-config
16jenkins Job.
17"""
18
19import os
20import sys
Matthew Hartfb6fd362020-03-04 21:03:59 +000021import argparse
Matthew Hartfb6fd362020-03-04 21:03:59 +000022from jinja2 import Environment, FileSystemLoader
23from lava_helper_configs import *
24
25try:
26 from tfm_ci_pylib.lava_rpc_connector import LAVA_RPC_connector
27except ImportError:
28 dir_path = os.path.dirname(os.path.realpath(__file__))
29 sys.path.append(os.path.join(dir_path, "../"))
30 from tfm_ci_pylib.lava_rpc_connector import LAVA_RPC_connector
31
32
33def load_config_overrides(user_args, config_key):
34 """ Load a configuration from multiple locations and override it with
35 user provided arguements """
36
37 print("Using built-in config: %s" % config_key)
38 try:
39 config = lava_gen_config_map[config_key]
40 except KeyError:
41 print("No template found for config: %s" % config_key)
42 sys.exit(1)
43
44 config["build_no"] = user_args.build_no
Dean Birch5d2dc572020-05-29 13:15:59 +010045 config["artifact_store_url"] = user_args.jenkins_build_url
Matthew Hartfb6fd362020-03-04 21:03:59 +000046
47 # Add the template folder
48 config["templ"] = os.path.join(user_args.template_dir, config["templ"])
49 return config
50
51
52def get_artifact_url(artifact_store_url, params, filename):
Fathi Boudrae9accbc2020-11-25 10:32:31 +010053 platform = params["platform"]
54 if params["device_type"] == "fvp":
55 platform = "fvp"
56
57 # FIXME: temporary workaround until we switch all platforms artifacts
58 # to use the same location (new build system)
59 url = "{}/artifact/trusted-firmware-m/build".format(artifact_store_url.rstrip("/"))
60 if platform.lower().startswith("musca"):
61 url = "{}/bin/{}".format(url, filename)
62 else:
63 url = "{}/install/outputs/{}/{}".format(url, platform, filename)
64 return url
Matthew Hartfb6fd362020-03-04 21:03:59 +000065
66
67def get_recovery_url(recovery_store_url, recovery):
Dean Birch5d2dc572020-05-29 13:15:59 +010068 return "{}/{}".format(recovery_store_url.rstrip('/'), recovery)
Matthew Hartfb6fd362020-03-04 21:03:59 +000069
70
71def get_job_name(name, params, job):
72 return "{}_{}_{}_{}_{}_{}_{}_{}".format(
73 name,
74 job,
75 params["platform"],
76 params["build_no"],
77 params["compiler"],
78 params["build_type"],
79 params["boot_type"],
80 params["name"],
81 )
82
83
84def get_build_name(params):
85 return "{}_{}_{}_{}_{}".format(
86 params["platform"],
87 params["compiler"],
88 params["name"],
89 params["build_type"],
90 params["boot_type"],
91 )
92
93
94def generate_test_definitions(config, work_dir, user_args):
95 """ Get a dictionary configuration, and an existing jinja2 template
96 and generate a LAVA compatbile yaml definition """
97
98 template_loader = FileSystemLoader(searchpath=work_dir)
99 template_env = Environment(loader=template_loader)
Dean Birch5d2dc572020-05-29 13:15:59 +0100100 recovery_store_url = config.get('recovery_store_url', '')
Matthew Hartfb6fd362020-03-04 21:03:59 +0000101 build_no = user_args.build_no
Dean Birch5d2dc572020-05-29 13:15:59 +0100102 artifact_store_url = config["artifact_store_url"]
Matthew Hartfb6fd362020-03-04 21:03:59 +0000103 template_file = config.pop("templ")
104
105 definitions = {}
106
107 for platform, recovery in config["platforms"].items():
108 if platform != user_args.platform:
109 continue
110 recovery_image_url = get_recovery_url(recovery_store_url, recovery)
111 for compiler in config["compilers"]:
112 if compiler != user_args.compiler:
113 continue
114 for build_type in config["build_types"]:
115 if build_type != user_args.build_type:
116 continue
117 for boot_type in config["boot_types"]:
118 bl2_string = "BL2" if user_args.bl2 else "NOBL2"
119 if boot_type != bl2_string:
120 continue
121 for test_name, test_dict in config["tests"].items():
122 if "Config{}".format(test_name) != user_args.proj_config:
123 continue
124 params = {
125 "device_type": config["device_type"],
126 "job_timeout": config["job_timeout"],
127 "action_timeout": config["action_timeout"],
128 "monitor_timeout": config["monitor_timeout"],
129 "poweroff_timeout": config["poweroff_timeout"],
130 "compiler": compiler,
131 "build_type": build_type,
132 "build_no": build_no,
133 "boot_type": boot_type,
134 "name": test_name,
135 "test": test_dict,
136 "platform": platform,
137 "recovery_image_url": recovery_image_url,
138 "data_bin_offset": config.get('data_bin_offset', ''),
139 "docker_prefix": vars(user_args).get('docker_prefix', ''),
140 "license_variable": vars(user_args).get('license_variable', ''),
141 "build_job_url": artifact_store_url,
Matthew Hart2c2688f2020-05-26 13:09:20 +0100142 "cpu0_baseline": config.get("cpu0_baseline", 0),
143 "cpu0_initvtor_s": config.get("cpu0_initvtor_s", "0x10000000")
Matthew Hartfb6fd362020-03-04 21:03:59 +0000144 }
145 params.update(
146 {
147 "firmware_url": get_artifact_url(
148 artifact_store_url,
149 params,
150 test_dict["binaries"]["firmware"],
151 ),
152 "bootloader_url": get_artifact_url(
153 artifact_store_url,
154 params,
155 test_dict["binaries"]["bootloader"],
156 ),
157 }
158 )
159 params.update(
160 {
161 "job_name": get_job_name(
162 config["job_name"], params, user_args.jenkins_job,
163 ),
164 "build_name": get_build_name(params)
165 }
166 )
167
168 definition = template_env.get_template(template_file).render(
169 params
170 )
171 definitions.update({params["job_name"]: definition})
172 return definitions
173
174
175def generate_lava_job_defs(user_args, config):
176 """ Create a LAVA test job definition file """
177
178 # Evaluate current directory
179 work_dir = os.path.abspath(os.path.dirname(__file__))
180
181 # If a single platform is requested and it exists in the platform
182 if user_args.platform and user_args.platform in config["platforms"]:
183 # Only test this platform
184 platform = user_args.platform
185 config["platforms"] = {platform: config["platforms"][platform]}
Matthew Hartfb6fd362020-03-04 21:03:59 +0000186 # Generate the ouptut definition
187 definitions = generate_test_definitions(config, work_dir, user_args)
188
189 # Write it into a file
190 out_dir = os.path.abspath(user_args.lava_def_output)
191 os.makedirs(out_dir, exist_ok=True)
192 for name, definition in definitions.items():
193 out_file = os.path.join(out_dir, "{}{}".format(name, ".yaml"))
194 with open(out_file, "w") as F:
195 F.write(definition)
196 print("Definition created at %s" % out_file)
197
198
199def main(user_args):
200 user_args.template_dir = "jinja2_templates"
201 config_keys = lava_gen_config_map.keys()
202 if user_args.config_key:
203 config_keys = [user_args.config_key]
204 for config_key in config_keys:
205 config = load_config_overrides(user_args, config_key)
206 generate_lava_job_defs(user_args, config)
207
208
209def get_cmd_args():
210 """ Parse command line arguments """
211
212 # Parse command line arguments to override config
213 parser = argparse.ArgumentParser(description="Lava Create Jobs")
214 cmdargs = parser.add_argument_group("Create LAVA Jobs")
215
216 # Configuration control
217 cmdargs.add_argument(
218 "--config-name",
219 dest="config_key",
220 action="store",
221 help="Select built-in configuration by name",
222 )
223 cmdargs.add_argument(
224 "--build-number",
225 dest="build_no",
226 action="store",
227 default="lastSuccessfulBuild",
228 help="JENKINS Build number selector. " "Default: lastSuccessfulBuild",
229 )
230 cmdargs.add_argument(
231 "--output-dir",
232 dest="lava_def_output",
233 action="store",
234 default="job_results",
235 help="Set LAVA compatible .yaml output file",
236 )
237 cmdargs.add_argument(
238 "--platform",
239 dest="platform",
240 action="store",
241 help="Override platform.Only the provided one " "will be tested",
242 )
243 cmdargs.add_argument(
244 "--compiler",
245 dest="compiler",
246 action="store",
247 help="Compiler to build definitions for",
248 )
249 cmdargs.add_argument(
250 "--jenkins-build-url",
251 dest="jenkins_build_url",
252 action="store",
253 help="Set the Jenkins URL",
254 )
255 cmdargs.add_argument(
256 "--jenkins-job",
257 dest="jenkins_job",
258 action="store",
259 default="tf-m-build-config",
260 help="Set the jenkins job name",
261 )
262 cmdargs.add_argument(
263 "--proj-config", dest="proj_config", action="store", help="Proj config"
264 )
265 cmdargs.add_argument(
266 "--build-type", dest="build_type", action="store", help="Build type"
267 )
268 cmdargs.add_argument(
269 "--docker-prefix", dest="docker_prefix", action="store", help="Prefix string for the FVP docker registry location"
270 )
271 cmdargs.add_argument(
272 "--license-variable", dest="license_variable", action="store", help="License string for Fastmodels"
273 )
274 cmdargs.add_argument("--bl2", dest="bl2", action="store_true", help="BL2")
Matthew Hart2c2688f2020-05-26 13:09:20 +0100275 cmdargs.add_argument(
276 "--psa-api-suite", dest="psa_suite", action="store", help="PSA API Suite name"
277 )
Matthew Hartfb6fd362020-03-04 21:03:59 +0000278 return parser.parse_args()
279
280
281if __name__ == "__main__":
282 main(get_cmd_args())