blob: 1fb9fd8f6d9c48e01e3d446fdb916b935c14d91f [file] [log] [blame]
Minos Galanakisea421232019-06-20 17:11:28 +01001#!/usr/bin/env python3
2
3""" fvp_dispatcher.py:
4
5 Fastmodel dispatcher takes an build report input from build_helper and
6 selects the appropriate tests, lauched in separate fastmodel Wrapper
7 instances """
8
9from __future__ import print_function
10
11__copyright__ = """
12/*
Karl Zhang08681e62020-10-30 13:56:03 +080013 * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
Minos Galanakisea421232019-06-20 17:11:28 +010014 *
15 * SPDX-License-Identifier: BSD-3-Clause
16 *
17 */
18 """
Karl Zhang08681e62020-10-30 13:56:03 +080019
20__author__ = "tf-m@lists.trustedfirmware.org"
Minos Galanakisea421232019-06-20 17:11:28 +010021__project__ = "Trusted Firmware-M Open CI"
Xinyu Zhang06286a92021-07-22 14:00:51 +080022__version__ = "1.4.0"
Minos Galanakisea421232019-06-20 17:11:28 +010023
24import os
25import sys
26import argparse
27from copy import deepcopy
28from fastmodel_dispatcher_configs import fvp_config_map
29
30try:
31 from tfm_ci_pylib.utils import load_json, print_test, save_json, \
32 show_progress
33 from tfm_ci_pylib.fastmodel_wrapper import FastmodelWrapper
34 from tfm_ci_pylib.tfm_build_manager import TFM_Build_Manager
35
36except ImportError:
37 dir_path = os.path.dirname(os.path.realpath(__file__))
38 sys.path.append(os.path.join(dir_path, "../"))
39 from tfm_ci_pylib.utils import load_json, print_test, save_json, \
40 show_progress
41 from tfm_ci_pylib.fastmodel_wrapper import FastmodelWrapper
42 from tfm_ci_pylib.tfm_build_manager import TFM_Build_Manager
43
44
45def cfilter(config_list, match):
46 """Filter a list of items in _text1_text2_ format and only include
47 results who contain the match term between two underscores """
48
49 # Ensure the match has the format of _text_
50 match = "_%s_" % match.strip("_")
51
52 return [n for n in config_list if match in n]
53
54
55def main(user_args):
56 """ Main logic """
57
58 test_config_list = None
59
60 if user_args.list_cfg:
61 print("Built-in configs:")
62 print("\n".join(fvp_config_map.list()))
63 sys.exit(0)
64 elif user_args.single_cfg:
65 try:
66 # Try to fetch the config to validate it exists
67 fvp_config_map.get_config(user_args.single_cfg)
68 test_config_list = [user_args.single_cfg]
69 except Exception as e:
70 print("Error: %s" % e)
71 sys.exit(1)
72 elif user_args.build_all:
73 test_config_list = fvp_config_map.list()
74 # If a build report is provided parse it
75 elif user_args.build_report:
76 build_report = load_json(user_args.build_report)
77
78 build_cfg = build_report["_metadata_"]["input_build_cfg"]
79
80 # build and test configs share common key name enties
81 config_list = list(map(str.lower,
82 (map(str, build_report["report"].keys()))))
Karl Zhangaff558a2020-05-15 14:28:23 +010083 print("zss config_list %s" % config_list)
Minos Galanakisea421232019-06-20 17:11:28 +010084
85 # Only choose the tests that have been defined in the map
86 test_config_list = [n for n in fvp_config_map.list()
87 if n in config_list]
Karl Zhangaff558a2020-05-15 14:28:23 +010088 print("zss test_config_list original %s" % test_config_list)
Minos Galanakisea421232019-06-20 17:11:28 +010089
90 # Use the Build manager to calcuate the rejection list in the same
91 # manner.
92 rj = TFM_Build_Manager.generate_rejection_list(
93 build_cfg["seed_params"],
94 build_cfg["common_params"],
95 fvp_config_map.get_invalid()).keys()
96
97 # Remove every config that is included in the rejection.
98 # Ignore generated rejection configs that have not been set in the
99 # test map.
100 for name in rj:
101 name = name.lower()
102 try:
103 test_config_list.pop(test_config_list.index(name))
104 print("Rejecting config %s" % name)
105 except Exception as e:
106 print("Rejection ignored with exception:", e)
107 else:
108 print("Noting to do. Please provide a report or a config name to test")
109 sys.exit(1)
110
111 # Apply filters if specified by user
112 if user_args.build_armclang:
113 test_config_list = cfilter(test_config_list, "armclang")
114 elif user_args.build_gnuarm:
115 test_config_list = cfilter(test_config_list, "gnuarm")
116 elif user_args.filter:
117 test_config_list = cfilter(test_config_list, user_args.filter)
118 else:
119 pass
120
Karl Zhangaff558a2020-05-15 14:28:23 +0100121# print("Working on Test list: \n%s" % "\n".join(sorted(test_config_list)))
122
Minos Galanakisea421232019-06-20 17:11:28 +0100123 if user_args.p_command:
124
125 for test_cfg in test_config_list:
126
127 test_cfg_obj = fvp_config_map.get_config_object(test_cfg)
Karl Zhangaff558a2020-05-15 14:28:23 +0100128
Minos Galanakisea421232019-06-20 17:11:28 +0100129 _tmp_cfg = FastmodelWrapper(fvp_cfg=test_cfg_obj.get_config())
130
131 print("\nCommand line:")
132 print("")
133 _tmp_cfg.show_cmd()
134 print("\n")
135 sys.exit(0)
136
137 # Run tests
138 rep = []
139 test_count = 0
Karl Zhangaff558a2020-05-15 14:28:23 +0100140# print("zss print_list list")
141# fvp_config_map.print_list()
142 print("zss test_config_list", test_config_list)
Minos Galanakisea421232019-06-20 17:11:28 +0100143 for test_cfg in test_config_list:
144
145 # Check if the config hardcoded binary path is same as the one
146 # in the build report. If not update the config
147 test_cfg_obj = fvp_config_map.get_config_object(test_cfg)
Karl Zhangaff558a2020-05-15 14:28:23 +0100148 print("+++test_cfg_obj %s\r\n %s\r\ntest_cfg %s" % (test_cfg_obj, test_cfg_obj.get_config(), test_cfg))
Minos Galanakisea421232019-06-20 17:11:28 +0100149
Karl Zhangaff558a2020-05-15 14:28:23 +0100150 print("---- test_cfg_obj.get_config()", test_cfg_obj.get_config())
Minos Galanakisea421232019-06-20 17:11:28 +0100151 rep.append(FastmodelWrapper(
152 fvp_cfg=test_cfg_obj.get_config())
153 .start().block_wait().test().save_report().get_report())
154 test_count += 1
155 print("Testing progress:")
156 show_progress(test_count, len(test_config_list))
157
158 # Export the report in a file
159 if user_args.report:
160 f_report = {"report": {}, "_metadata_": {}}
161 f_report["report"] = {k["name"]: deepcopy(k) for k in rep}
162 save_json(user_args.report, f_report)
163
164 sl = [x["name"] for x in rep if x["success"] is True]
165 fl = [x["name"] for x in rep if x["success"] is False]
166
167 print("\n")
168
169 if sl:
170 print_test(t_list=sl, status="passed", tname="Tests")
171 if fl:
172 print_test(t_list=fl, status="failed", tname="Tests")
173 if user_args.eif:
174 sys.exit(1)
175
176
177def get_cmd_args():
178 """ Parse command line arguments """
179
180 # Parse command line arguments to override config
181 parser = argparse.ArgumentParser(description="TFM Fastmodel wrapper.")
182 parser.add_argument("-b", "--build_report",
183 dest="build_report",
184 action="store",
185 help="JSON file produced by build_helper (input)")
186 parser.add_argument("-a", "--build_all",
187 dest="build_all",
188 action="store_true",
189 help="If set build every configuration combination")
190 parser.add_argument("-e", "--error_if_failed",
191 dest="eif",
192 action="store_true",
193 help="If set will change the script exit code if one "
194 "or more tests fail")
195 parser.add_argument("-r", "--report",
196 dest="report",
197 action="store",
198 help="JSON file containing fastmodel report (output)")
199 parser.add_argument("-g", "--build_gnuarm",
200 dest="build_gnuarm",
201 action="store_true",
202 help="If set build every gnuarm configuration")
203 parser.add_argument("-c", "--build_armclang",
204 dest="build_armclang",
205 action="store_true",
206 help="If set build every armclang configuration")
207 parser.add_argument("-f", "--filter",
208 dest="filter",
209 action="store",
210 help="Only select configs that contain this string")
211 parser.add_argument("-l", "--list-configs",
212 dest="list_cfg",
213 action="store_true",
214 help="Print a list of the built-in configurations and"
215 "exit")
216 parser.add_argument("-s", "--single-config",
217 dest="single_cfg",
218 action="store",
219 help="Launch testing for a single built-in config, "
220 "picked by name")
221 parser.add_argument("-p", "--print-command",
222 dest="p_command",
223 action="store_true",
Karl Zhangaff558a2020-05-15 14:28:23 +0100224 help="Print the FVP launch command to console & exit")
Minos Galanakisea421232019-06-20 17:11:28 +0100225 return parser.parse_args()
226
227
228if __name__ == "__main__":
229 main(get_cmd_args())