blob: 8c12dae2cdcdd1b72c5149feee4f54d7ddf8e42b [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()))))
84
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]
88
89 # Use the Build manager to calcuate the rejection list in the same
90 # manner.
91 rj = TFM_Build_Manager.generate_rejection_list(
92 build_cfg["seed_params"],
93 build_cfg["common_params"],
94 fvp_config_map.get_invalid()).keys()
95
96 # Remove every config that is included in the rejection.
97 # Ignore generated rejection configs that have not been set in the
98 # test map.
99 for name in rj:
100 name = name.lower()
101 try:
102 test_config_list.pop(test_config_list.index(name))
103 print("Rejecting config %s" % name)
104 except Exception as e:
105 print("Rejection ignored with exception:", e)
106 else:
107 print("Noting to do. Please provide a report or a config name to test")
108 sys.exit(1)
109
110 # Apply filters if specified by user
111 if user_args.build_armclang:
112 test_config_list = cfilter(test_config_list, "armclang")
113 elif user_args.build_gnuarm:
114 test_config_list = cfilter(test_config_list, "gnuarm")
115 elif user_args.filter:
116 test_config_list = cfilter(test_config_list, user_args.filter)
117 else:
118 pass
119
120 print("Working on Test list: \n%s" % "\n".join(sorted(test_config_list)))
121
122 if user_args.p_command:
123
124 for test_cfg in test_config_list:
125
126 test_cfg_obj = fvp_config_map.get_config_object(test_cfg)
127 _tmp_cfg = FastmodelWrapper(fvp_cfg=test_cfg_obj.get_config())
128
129 print("\nCommand line:")
130 print("")
131 _tmp_cfg.show_cmd()
132 print("\n")
133 sys.exit(0)
134
135 # Run tests
136 rep = []
137 test_count = 0
138 for test_cfg in test_config_list:
139
140 # Check if the config hardcoded binary path is same as the one
141 # in the build report. If not update the config
142 test_cfg_obj = fvp_config_map.get_config_object(test_cfg)
143
144 rep.append(FastmodelWrapper(
145 fvp_cfg=test_cfg_obj.get_config())
146 .start().block_wait().test().save_report().get_report())
147 test_count += 1
148 print("Testing progress:")
149 show_progress(test_count, len(test_config_list))
150
151 # Export the report in a file
152 if user_args.report:
153 f_report = {"report": {}, "_metadata_": {}}
154 f_report["report"] = {k["name"]: deepcopy(k) for k in rep}
155 save_json(user_args.report, f_report)
156
157 sl = [x["name"] for x in rep if x["success"] is True]
158 fl = [x["name"] for x in rep if x["success"] is False]
159
160 print("\n")
161
162 if sl:
163 print_test(t_list=sl, status="passed", tname="Tests")
164 if fl:
165 print_test(t_list=fl, status="failed", tname="Tests")
166 if user_args.eif:
167 sys.exit(1)
168
169
170def get_cmd_args():
171 """ Parse command line arguments """
172
173 # Parse command line arguments to override config
174 parser = argparse.ArgumentParser(description="TFM Fastmodel wrapper.")
175 parser.add_argument("-b", "--build_report",
176 dest="build_report",
177 action="store",
178 help="JSON file produced by build_helper (input)")
179 parser.add_argument("-a", "--build_all",
180 dest="build_all",
181 action="store_true",
182 help="If set build every configuration combination")
183 parser.add_argument("-e", "--error_if_failed",
184 dest="eif",
185 action="store_true",
186 help="If set will change the script exit code if one "
187 "or more tests fail")
188 parser.add_argument("-r", "--report",
189 dest="report",
190 action="store",
191 help="JSON file containing fastmodel report (output)")
192 parser.add_argument("-g", "--build_gnuarm",
193 dest="build_gnuarm",
194 action="store_true",
195 help="If set build every gnuarm configuration")
196 parser.add_argument("-c", "--build_armclang",
197 dest="build_armclang",
198 action="store_true",
199 help="If set build every armclang configuration")
200 parser.add_argument("-f", "--filter",
201 dest="filter",
202 action="store",
203 help="Only select configs that contain this string")
204 parser.add_argument("-l", "--list-configs",
205 dest="list_cfg",
206 action="store_true",
207 help="Print a list of the built-in configurations and"
208 "exit")
209 parser.add_argument("-s", "--single-config",
210 dest="single_cfg",
211 action="store",
212 help="Launch testing for a single built-in config, "
213 "picked by name")
214 parser.add_argument("-p", "--print-command",
215 dest="p_command",
216 action="store_true",
217 help="Print the FPV launch command to console & exit")
218 return parser.parse_args()
219
220
221if __name__ == "__main__":
222 main(get_cmd_args())