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