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