Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | |
| 3 | from __future__ import print_function |
| 4 | |
| 5 | __copyright__ = """ |
| 6 | /* |
Gergely Korcsák | ac2d0f0 | 2024-05-28 08:23:04 +0200 | [diff] [blame] | 7 | * Copyright (c) 2020-2024, Arm Limited. All rights reserved. |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 8 | * |
| 9 | * SPDX-License-Identifier: BSD-3-Clause |
| 10 | * |
| 11 | */ |
| 12 | """ |
| 13 | |
| 14 | """ |
Fathi Boudra | 13b7eba | 2020-11-26 10:29:53 +0100 | [diff] [blame] | 15 | Script to create LAVA definitions from a single tf-m-build-config Jenkins Job |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 16 | """ |
| 17 | |
| 18 | import os |
| 19 | import sys |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 20 | import argparse |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 21 | from jinja2 import Environment, FileSystemLoader |
| 22 | from lava_helper_configs import * |
| 23 | |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 24 | |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 25 | def get_recovery_url(recovery_store_url, recovery): |
Dean Birch | 5d2dc57 | 2020-05-29 13:15:59 +0100 | [diff] [blame] | 26 | return "{}/{}".format(recovery_store_url.rstrip('/'), recovery) |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 27 | |
| 28 | |
Xinyu Zhang | c918b6e | 2022-10-08 17:13:17 +0800 | [diff] [blame] | 29 | def load_config_overrides(user_args, config_key): |
| 30 | """Load a configuration from multiple locations and override it with user provided |
| 31 | arguments""" |
| 32 | |
| 33 | print("Using built-in config: %s" % config_key) |
| 34 | try: |
Xinyu Zhang | 426c725 | 2023-10-12 17:43:53 +0800 | [diff] [blame] | 35 | config = lava_gen_config_map_bl2[config_key] if os.getenv("BL2") == "True" \ |
| 36 | else lava_gen_config_map_nobl2[config_key] |
Xinyu Zhang | c918b6e | 2022-10-08 17:13:17 +0800 | [diff] [blame] | 37 | except KeyError: |
| 38 | print("No template found for config: %s" % config_key) |
| 39 | sys.exit(1) |
| 40 | |
Xinyu Zhang | c918b6e | 2022-10-08 17:13:17 +0800 | [diff] [blame] | 41 | # Add the template folder |
| 42 | config["templ"] = os.path.join(user_args.template_dir, config["templ"]) |
| 43 | return config |
| 44 | |
| 45 | |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 46 | def generate_test_definitions(config, work_dir, user_args): |
Fathi Boudra | 13b7eba | 2020-11-26 10:29:53 +0100 | [diff] [blame] | 47 | """Get a dictionary configuration and an existing jinja2 template to generate |
| 48 | a LAVA compatible yaml definition""" |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 49 | |
| 50 | template_loader = FileSystemLoader(searchpath=work_dir) |
| 51 | template_env = Environment(loader=template_loader) |
Dean Birch | 5d2dc57 | 2020-05-29 13:15:59 +0100 | [diff] [blame] | 52 | recovery_store_url = config.get('recovery_store_url', '') |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 53 | template_file = config.pop("templ") |
| 54 | |
| 55 | definitions = {} |
| 56 | |
| 57 | for platform, recovery in config["platforms"].items(): |
Xinyu Zhang | 22a1275 | 2022-10-10 17:21:21 +0800 | [diff] [blame] | 58 | if platform != os.getenv('TFM_PLATFORM'): |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 59 | continue |
| 60 | recovery_image_url = get_recovery_url(recovery_store_url, recovery) |
Xinyu Zhang | 3235538 | 2023-04-25 17:49:06 +0800 | [diff] [blame] | 61 | if os.getenv("TEST_PSA_API") != "OFF": |
Xinyu Zhang | 22a1275 | 2022-10-10 17:21:21 +0800 | [diff] [blame] | 62 | monitor_name = "arch_tests" |
Xinyu Zhang | 3235538 | 2023-04-25 17:49:06 +0800 | [diff] [blame] | 63 | elif os.getenv("TEST_REGRESSION") == "OFF": |
Xinyu Zhang | 22a1275 | 2022-10-10 17:21:21 +0800 | [diff] [blame] | 64 | monitor_name = "no_reg_tests" |
Xinyu Zhang | 3235538 | 2023-04-25 17:49:06 +0800 | [diff] [blame] | 65 | else: |
| 66 | monitor_name = "reg_tests" |
Xinyu Zhang | 22a1275 | 2022-10-10 17:21:21 +0800 | [diff] [blame] | 67 | params = { |
| 68 | "job_name": "{}_{}_{}".format(os.getenv('CONFIG_NAME'), os.getenv("BUILD_NUMBER"), config["device_type"]), |
| 69 | "build_name": os.getenv('CONFIG_NAME'), |
| 70 | "device_type": config["device_type"], |
| 71 | "job_timeout": config["job_timeout"], |
Benjamin Copeland | 3573aba | 2025-01-14 22:34:41 +0000 | [diff] [blame] | 72 | "notification_email": config.get("notification_email", ''), |
Xinyu Zhang | 22a1275 | 2022-10-10 17:21:21 +0800 | [diff] [blame] | 73 | "action_timeout": config.get("action_timeout", ''), |
| 74 | "monitor_timeout": config.get("monitor_timeout", ''), |
| 75 | "poweroff_timeout": config.get("poweroff_timeout", ''), |
| 76 | "build_no": os.getenv("BUILD_NUMBER"), |
| 77 | "name": monitor_name, |
| 78 | "monitors": config['monitors'].get(monitor_name, []), |
| 79 | "platform": platform, |
| 80 | "recovery_image_url": recovery_image_url, |
Xinyu Zhang | 22a1275 | 2022-10-10 17:21:21 +0800 | [diff] [blame] | 81 | "docker_prefix": vars(user_args).get('docker_prefix', ''), |
| 82 | "license_variable": vars(user_args).get('license_variable', ''), |
| 83 | "enable_code_coverage": user_args.enable_code_coverage == "TRUE", |
| 84 | "coverage_trace_plugin": coverage_trace_plugin, |
Paul Sokolovsky | f08e08e | 2024-07-02 18:59:43 +0300 | [diff] [blame] | 85 | "build_job_url": os.getenv("BUILD_URL"), |
Xinyu Zhang | 22a1275 | 2022-10-10 17:21:21 +0800 | [diff] [blame] | 86 | "cpu0_baseline": config.get("cpu0_baseline", 0), |
| 87 | "cpu0_initvtor_s": config.get("cpu0_initvtor_s", "0x10000000"), |
| 88 | "psa_api_suite": os.getenv("TEST_PSA_API") if os.getenv("TEST_PSA_API") == "IPC" else "", |
Gergely Korcsák | ac2d0f0 | 2024-05-28 08:23:04 +0200 | [diff] [blame] | 89 | "binaries": config.get('binaries', []), |
Nicola Mazzucato | e12c1b5 | 2024-12-16 09:56:26 +0000 | [diff] [blame] | 90 | "data_url_prefix": "{}/artifact/ci_build".format(os.getenv("BUILD_URL")), |
| 91 | "build_type": os.getenv("CMAKE_BUILD_TYPE"), |
Xinyu Zhang | 22a1275 | 2022-10-10 17:21:21 +0800 | [diff] [blame] | 92 | } |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 93 | |
Xinyu Zhang | 22a1275 | 2022-10-10 17:21:21 +0800 | [diff] [blame] | 94 | if len(params["monitors"]) == 0: |
| 95 | break |
| 96 | |
| 97 | definition = template_env.get_template(template_file).render( |
| 98 | params |
| 99 | ) |
| 100 | definitions.update({params["job_name"]: definition}) |
| 101 | |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 102 | return definitions |
| 103 | |
| 104 | |
| 105 | def generate_lava_job_defs(user_args, config): |
Fathi Boudra | 13b7eba | 2020-11-26 10:29:53 +0100 | [diff] [blame] | 106 | """Create a LAVA test job definition file""" |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 107 | |
| 108 | # Evaluate current directory |
| 109 | work_dir = os.path.abspath(os.path.dirname(__file__)) |
| 110 | |
Xinyu Zhang | 22a1275 | 2022-10-10 17:21:21 +0800 | [diff] [blame] | 111 | # If platform exists in the LAVA platforms |
| 112 | if os.getenv("TFM_PLATFORM") in config["platforms"]: |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 113 | # Only test this platform |
Xinyu Zhang | 22a1275 | 2022-10-10 17:21:21 +0800 | [diff] [blame] | 114 | platform = os.getenv("TFM_PLATFORM") |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 115 | config["platforms"] = {platform: config["platforms"][platform]} |
Fathi Boudra | 13b7eba | 2020-11-26 10:29:53 +0100 | [diff] [blame] | 116 | # Generate the output definition |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 117 | definitions = generate_test_definitions(config, work_dir, user_args) |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 118 | # Write it into a file |
| 119 | out_dir = os.path.abspath(user_args.lava_def_output) |
| 120 | os.makedirs(out_dir, exist_ok=True) |
| 121 | for name, definition in definitions.items(): |
| 122 | out_file = os.path.join(out_dir, "{}{}".format(name, ".yaml")) |
| 123 | with open(out_file, "w") as F: |
| 124 | F.write(definition) |
| 125 | print("Definition created at %s" % out_file) |
| 126 | |
| 127 | |
| 128 | def main(user_args): |
| 129 | user_args.template_dir = "jinja2_templates" |
Xinyu Zhang | 426c725 | 2023-10-12 17:43:53 +0800 | [diff] [blame] | 130 | config_keys = list(lava_gen_config_map_bl2.keys()) if os.getenv("BL2") == "True" \ |
| 131 | else list(lava_gen_config_map_nobl2.keys()) |
Xinyu Zhang | be224f6 | 2021-02-03 17:57:38 +0800 | [diff] [blame] | 132 | if user_args.fvp_only: |
Xinyu Zhang | d7616fc | 2022-07-06 16:14:36 +0800 | [diff] [blame] | 133 | config_keys = [key for key in config_keys if "fvp" in key] |
Xinyu Zhang | 302b74d | 2021-11-03 14:53:44 +0800 | [diff] [blame] | 134 | if user_args.physical_board_only: |
Xinyu Zhang | d7616fc | 2022-07-06 16:14:36 +0800 | [diff] [blame] | 135 | config_keys = [key for key in config_keys |
| 136 | if "fvp" not in key and "qemu" not in key] |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 137 | if user_args.config_key: |
| 138 | config_keys = [user_args.config_key] |
| 139 | for config_key in config_keys: |
| 140 | config = load_config_overrides(user_args, config_key) |
| 141 | generate_lava_job_defs(user_args, config) |
| 142 | |
| 143 | |
| 144 | def get_cmd_args(): |
Fathi Boudra | 13b7eba | 2020-11-26 10:29:53 +0100 | [diff] [blame] | 145 | """Parse command line arguments""" |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 146 | |
| 147 | # Parse command line arguments to override config |
| 148 | parser = argparse.ArgumentParser(description="Lava Create Jobs") |
| 149 | cmdargs = parser.add_argument_group("Create LAVA Jobs") |
Xinyu Zhang | 302b74d | 2021-11-03 14:53:44 +0800 | [diff] [blame] | 150 | device_type = parser.add_mutually_exclusive_group() |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 151 | |
| 152 | # Configuration control |
| 153 | cmdargs.add_argument( |
| 154 | "--config-name", |
| 155 | dest="config_key", |
| 156 | action="store", |
| 157 | help="Select built-in configuration by name", |
| 158 | ) |
| 159 | cmdargs.add_argument( |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 160 | "--output-dir", |
| 161 | dest="lava_def_output", |
| 162 | action="store", |
| 163 | default="job_results", |
| 164 | help="Set LAVA compatible .yaml output file", |
| 165 | ) |
| 166 | cmdargs.add_argument( |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 167 | "--jenkins-build-url", |
| 168 | dest="jenkins_build_url", |
| 169 | action="store", |
| 170 | help="Set the Jenkins URL", |
| 171 | ) |
| 172 | cmdargs.add_argument( |
| 173 | "--jenkins-job", |
| 174 | dest="jenkins_job", |
| 175 | action="store", |
| 176 | default="tf-m-build-config", |
| 177 | help="Set the jenkins job name", |
| 178 | ) |
| 179 | cmdargs.add_argument( |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 180 | "--docker-prefix", dest="docker_prefix", action="store", help="Prefix string for the FVP docker registry location" |
| 181 | ) |
| 182 | cmdargs.add_argument( |
| 183 | "--license-variable", dest="license_variable", action="store", help="License string for Fastmodels" |
| 184 | ) |
Leonardo Sandoval | 66386a2 | 2021-04-15 14:35:08 -0500 | [diff] [blame] | 185 | cmdargs.add_argument( |
| 186 | "--enable-code-coverage", dest="enable_code_coverage", action="store", default="FALSE", help="Enable trace-base code coverage" |
| 187 | ) |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 188 | |
Xinyu Zhang | 302b74d | 2021-11-03 14:53:44 +0800 | [diff] [blame] | 189 | device_type.add_argument( |
| 190 | "--fvp-only", |
| 191 | dest="fvp_only", |
| 192 | action="store_true", |
| 193 | help="Run test cases on FVP only", |
| 194 | ) |
| 195 | device_type.add_argument( |
| 196 | "--physical-board-only", |
| 197 | dest="physical_board_only", |
| 198 | action="store_true", |
| 199 | help="Run test cases on physical boards only", |
| 200 | ) |
| 201 | |
| 202 | return parser.parse_args() |
Matthew Hart | fb6fd36 | 2020-03-04 21:03:59 +0000 | [diff] [blame] | 203 | |
| 204 | if __name__ == "__main__": |
| 205 | main(get_cmd_args()) |