blob: 92886a64f712f29cd5b5d3489bb806ab620f8c12 [file] [log] [blame]
Srikrishna Iyer09a81e92019-12-30 10:47:57 -08001# Copyright lowRISC contributors.
2# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3# SPDX-License-Identifier: Apache-2.0
Srikrishna Iyer09a81e92019-12-30 10:47:57 -08004
5import logging as log
6import pprint
Srikrishna Iyer09a81e92019-12-30 10:47:57 -08007import sys
8
Rupert Swarbrick6cc20112020-04-24 09:44:35 +01009from utils import VERBOSE
Srikrishna Iyer09a81e92019-12-30 10:47:57 -080010
11
12class Modes():
13 """
14 Abstraction for specifying collection of options called as 'modes'. This is
15 the base class which is extended for run_modes, build_modes, tests and regressions.
16 """
17 def self_str(self):
18 '''
19 This is used to construct the string representation of the entire class object.
20 '''
21 tname = ""
Rupert Swarbrick6cc20112020-04-24 09:44:35 +010022 if self.type != "":
23 tname = self.type + "_"
24 if self.mname != "":
25 tname += self.mname
Srikrishna Iyer09a81e92019-12-30 10:47:57 -080026 if log.getLogger().isEnabledFor(VERBOSE):
27 return "\n<---" + tname + ":\n" + pprint.pformat(self.__dict__) + \
28 "\n--->\n"
29 else:
30 return tname + ":" + self.name
31
32 def __str__(self):
33 return self.self_str()
34
35 def __repr__(self):
36 return self.self_str()
37
38 def __init__(self, mdict):
39 keys = mdict.keys()
40 attrs = self.__dict__.keys()
41
Rupert Swarbrick6cc20112020-04-24 09:44:35 +010042 if 'name' not in keys:
Srikrishna Iyer09a81e92019-12-30 10:47:57 -080043 log.error("Key \"name\" missing in mode %s", mdict)
44 sys.exit(1)
45
46 if not hasattr(self, "type"):
47 log.fatal("Key \"type\" is missing or invalid")
48 sys.exit(1)
49
Rupert Swarbrick6cc20112020-04-24 09:44:35 +010050 if not hasattr(self, "mname"):
51 self.mname = ""
Srikrishna Iyer09a81e92019-12-30 10:47:57 -080052
53 for key in keys:
54 if key not in attrs:
55 log.error("Key %s in %s is invalid", key, mdict)
56 sys.exit(1)
57 setattr(self, key, mdict[key])
58
59 def get_sub_modes(self):
60 sub_modes = []
61 if hasattr(self, "en_" + self.type + "_modes"):
62 sub_modes = getattr(self, "en_" + self.type + "_modes")
63 return sub_modes
64
65 def set_sub_modes(self, sub_modes):
66 setattr(self, "en_" + self.type + "_modes", sub_modes)
67
68 def merge_mode(self, mode):
69 '''
70 Merge a new mode with self.
71 Merge sub mode specified with 'en_*_modes with self.
72 '''
73
74 sub_modes = self.get_sub_modes()
75 is_sub_mode = mode.name in sub_modes
76
77 if not mode.name == self.name and not is_sub_mode:
78 return False
79
Srikrishna Iyer231d0d02020-08-06 17:08:22 -070080 # Merge attributes in self with attributes in mode arg, since they are
81 # the same mode but set in separate files, or a sub-mode.
82 for attr, self_attr_val in self.__dict__.items():
83 mode_attr_val = getattr(mode, attr, None)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -080084
Srikrishna Iyer231d0d02020-08-06 17:08:22 -070085 # If sub-mode, skip the name fields - they could differ.
86 if is_sub_mode and attr in ['name', 'mname']:
87 continue
88
89 # If mode's value is None, then nothing to do here.
90 if mode_attr_val is None:
91 continue
92
93 # If self value is None, then replace with mode's value.
94 if self_attr_val is None:
95 setattr(self, attr, mode_attr_val)
96 continue
97
98 # If they are equal, then nothing to do here.
99 if self_attr_val == mode_attr_val:
100 continue
101
102 # Extend if they are both lists.
103 if isinstance(self_attr_val, list):
104 assert isinstance(mode_attr_val, list)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800105 self_attr_val.extend(mode_attr_val)
Srikrishna Iyer231d0d02020-08-06 17:08:22 -0700106 continue
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800107
Srikrishna Iyer231d0d02020-08-06 17:08:22 -0700108 # If the current val is default, replace with new.
109 scalar_types = {str: "", int: -1}
110 default_val = scalar_types.get(type(self_attr_val))
111
112 if type(self_attr_val) in scalar_types.keys(
113 ) and self_attr_val == default_val:
114 setattr(self, attr, mode_attr_val)
115 continue
116
117 # Check if their types are compatible.
118 if type(self_attr_val) != type(mode_attr_val):
119 log.error(
120 "Mode %s cannot be merged into %s due to a conflict "
Weicai Yang79922802021-01-07 18:28:32 -0800121 "(type mismatch): %s: {%s(%s), %s(%s)}", mode.name,
122 self.name, attr, str(self_attr_val),
123 str(type(self_attr_val)), str(mode_attr_val),
124 str(type(mode_attr_val)))
Srikrishna Iyer231d0d02020-08-06 17:08:22 -0700125 sys.exit(1)
126
127 # Check if they are different non-default values.
128 if self_attr_val != default_val and mode_attr_val != default_val:
129 log.error(
130 "Mode %s cannot be merged into %s due to a conflict "
131 "(unable to pick one from different values): "
Weicai Yang79922802021-01-07 18:28:32 -0800132 "%s: {%s, %s}", mode.name, self.name, attr,
133 str(self_attr_val), str(mode_attr_val))
Srikrishna Iyer231d0d02020-08-06 17:08:22 -0700134 sys.exit(1)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800135
136 # Check newly appended sub_modes, remove 'self' and duplicates
137 sub_modes = self.get_sub_modes()
138
139 if sub_modes != []:
140 new_sub_modes = []
141 for sub_mode in sub_modes:
Rupert Swarbrick6cc20112020-04-24 09:44:35 +0100142 if self.name != sub_mode and sub_mode not in new_sub_modes:
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800143 new_sub_modes.append(sub_mode)
144 self.set_sub_modes(new_sub_modes)
145 return True
146
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800147 @staticmethod
148 def create_modes(ModeType, mdicts):
149 '''
150 Create modes of type ModeType from a given list of raw dicts
151 Process dependencies.
152 Return a list of modes objects.
153 '''
154 def merge_sub_modes(mode, parent, objs):
155 # Check if there are modes available to merge
156 sub_modes = mode.get_sub_modes()
Rupert Swarbrick6cc20112020-04-24 09:44:35 +0100157 if sub_modes == []:
158 return
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800159
160 # Set parent if it is None. If not, check cyclic dependency
161 if parent is None:
162 parent = mode
163 else:
164 if mode.name == parent.name:
165 log.error("Cyclic dependency when processing mode \"%s\"",
166 mode.name)
167 sys.exit(1)
168
169 for sub_mode in sub_modes:
170 # Find the sub_mode obj from str
171 found = False
172 for obj in objs:
173 if sub_mode == obj.name:
174 # First recursively merge the sub_modes
175 merge_sub_modes(obj, parent, objs)
176
177 # Now merge the sub mode with mode
178 mode.merge_mode(obj)
179 found = True
180 break
181 if not found:
182 log.error(
183 "Sub mode \"%s\" added to mode \"%s\" was not found!",
184 sub_mode, mode.name)
185 sys.exit(1)
186
187 modes_objs = []
188 # create a default mode if available
189 default_mode = ModeType.get_default_mode()
Rupert Swarbrick6cc20112020-04-24 09:44:35 +0100190 if default_mode is not None:
191 modes_objs.append(default_mode)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800192
193 # Process list of raw dicts that represent the modes
194 # Pass 1: Create unique set of modes by merging modes with the same name
195 for mdict in mdicts:
196 # Create a new item
197 new_mode_merged = False
198 new_mode = ModeType(mdict)
199 for mode in modes_objs:
200 # Merge new one with existing if available
201 if mode.name == new_mode.name:
202 mode.merge_mode(new_mode)
203 new_mode_merged = True
204 break
205
206 # Add the new mode to the list if not already appended
207 if not new_mode_merged:
208 modes_objs.append(new_mode)
209 ModeType.item_names.append(new_mode.name)
210
211 # Pass 2: Recursively expand sub modes within parent modes
212 for mode in modes_objs:
213 merge_sub_modes(mode, None, modes_objs)
214
215 # Return the list of objects
216 return modes_objs
217
218 @staticmethod
219 def get_default_mode(ModeType):
220 return None
221
222 @staticmethod
223 def find_mode(mode_name, modes):
224 '''
225 Given a mode_name in string, go through list of modes and return the mode with
226 the string that matches. Thrown an error and return None if nothing was found.
227 '''
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800228 for mode in modes:
229 if mode_name == mode.name:
230 return mode
231 return None
232
233 @staticmethod
234 def find_and_merge_modes(mode, mode_names, modes, merge_modes=True):
235 '''
236 '''
237 found_mode_objs = []
238 for mode_name in mode_names:
239 sub_mode = Modes.find_mode(mode_name, modes)
240 if sub_mode is not None:
241 found_mode_objs.append(sub_mode)
Rupert Swarbrick6cc20112020-04-24 09:44:35 +0100242 if merge_modes is True:
243 mode.merge_mode(sub_mode)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800244 else:
245 log.error("Mode \"%s\" enabled within mode \"%s\" not found!",
246 mode_name, mode.name)
247 sys.exit(1)
248 return found_mode_objs
249
250
251class BuildModes(Modes):
252 """
253 Build modes.
254 """
255
256 # Maintain a list of build_modes str
257 item_names = []
258
259 def __init__(self, bdict):
260 self.name = ""
261 self.type = "build"
Rupert Swarbrick6cc20112020-04-24 09:44:35 +0100262 if not hasattr(self, "mname"):
263 self.mname = "mode"
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800264 self.is_sim_mode = 0
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800265 self.pre_build_cmds = []
266 self.post_build_cmds = []
Srikrishna Iyer96a7ec22020-12-01 14:36:34 -0800267 self.en_build_modes = []
268 self.build_opts = []
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800269 self.pre_run_cmds = []
270 self.post_run_cmds = []
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800271 self.run_opts = []
Srikrishna Iyer96a7ec22020-12-01 14:36:34 -0800272 self.sw_images = []
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800273
274 super().__init__(bdict)
275 self.en_build_modes = list(set(self.en_build_modes))
276
277 @staticmethod
278 def get_default_mode():
279 return BuildModes({"name": "default"})
280
281
282class RunModes(Modes):
283 """
284 Run modes.
285 """
286
287 # Maintain a list of run_modes str
288 item_names = []
289
290 def __init__(self, rdict):
291 self.name = ""
292 self.type = "run"
Rupert Swarbrick6cc20112020-04-24 09:44:35 +0100293 if not hasattr(self, "mname"):
294 self.mname = "mode"
Rupert Swarbricke83b55e2020-05-12 11:44:04 +0100295 self.reseed = None
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800296 self.pre_run_cmds = []
297 self.post_run_cmds = []
Srikrishna Iyer96a7ec22020-12-01 14:36:34 -0800298 self.en_run_modes = []
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800299 self.run_opts = []
300 self.uvm_test = ""
301 self.uvm_test_seq = ""
302 self.build_mode = ""
Srikrishna Iyerde5efa02020-11-20 23:17:11 -0800303 self.sw_images = []
Srikrishna Iyer42d032f2020-03-04 23:55:44 -0800304 self.sw_build_device = ""
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800305
306 super().__init__(rdict)
307 self.en_run_modes = list(set(self.en_run_modes))
308
309 @staticmethod
310 def get_default_mode():
311 return None
312
313
314class Tests(RunModes):
315 """
316 Abstraction for tests. The RunModes abstraction can be reused here with a few
317 modifications.
318 """
319
320 # Maintain a list of tests str
321 item_names = []
322
323 # TODO: This info should be passed via hjson
324 defaults = {
Rupert Swarbricke83b55e2020-05-12 11:44:04 +0100325 "reseed": None,
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800326 "uvm_test": "",
327 "uvm_test_seq": "",
Srikrishna Iyer42d032f2020-03-04 23:55:44 -0800328 "build_mode": "",
Srikrishna Iyerde5efa02020-11-20 23:17:11 -0800329 "sw_images": [],
Srikrishna Iyer42d032f2020-03-04 23:55:44 -0800330 "sw_build_device": "",
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800331 }
332
333 def __init__(self, tdict):
Rupert Swarbrick6cc20112020-04-24 09:44:35 +0100334 if not hasattr(self, "mname"):
335 self.mname = "test"
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800336 super().__init__(tdict)
337
338 @staticmethod
339 def create_tests(tdicts, sim_cfg):
340 '''
341 Create Tests from a given list of raw dicts.
342 TODO: enhance the raw dict to include file scoped defaults.
343 Process enabled run modes and the set build mode.
344 Return a list of test objects.
345 '''
346 def get_pruned_en_run_modes(test_en_run_modes, global_en_run_modes):
347 pruned_en_run_modes = []
348 for test_en_run_mode in test_en_run_modes:
349 if test_en_run_mode not in global_en_run_modes:
350 pruned_en_run_modes.append(test_en_run_mode)
351 return pruned_en_run_modes
352
353 tests_objs = []
354 # Pass 1: Create unique set of tests by merging tests with the same name
355 for tdict in tdicts:
356 # Create a new item
357 new_test_merged = False
358 new_test = Tests(tdict)
359 for test in tests_objs:
360 # Merge new one with existing if available
361 if test.name == new_test.name:
362 test.merge_mode(new_test)
363 new_test_merged = True
364 break
365
366 # Add the new test to the list if not already appended
367 if not new_test_merged:
368 tests_objs.append(new_test)
369 Tests.item_names.append(new_test.name)
370
371 # Pass 2: Process dependencies
372 build_modes = []
373 if hasattr(sim_cfg, "build_modes"):
374 build_modes = getattr(sim_cfg, "build_modes")
375
376 run_modes = []
377 if hasattr(sim_cfg, "run_modes"):
378 run_modes = getattr(sim_cfg, "run_modes")
379
380 attrs = Tests.defaults
381 for test_obj in tests_objs:
382 # Unpack run_modes first
383 en_run_modes = get_pruned_en_run_modes(test_obj.en_run_modes,
384 sim_cfg.en_run_modes)
385 Modes.find_and_merge_modes(test_obj, en_run_modes, run_modes)
386
387 # Find and set the missing attributes from sim_cfg
388 # If not found in sim_cfg either, then throw a warning
389 # TODO: These should be file-scoped
390 for attr in attrs.keys():
391 # Check if attr value is default
392 val = getattr(test_obj, attr)
393 default_val = attrs[attr]
394 if val == default_val:
395 global_val = None
396 # Check if we can find a default in sim_cfg
397 if hasattr(sim_cfg, attr):
398 global_val = getattr(sim_cfg, attr)
399
400 if global_val is not None and global_val != default_val:
401 setattr(test_obj, attr, global_val)
402
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800403 # Unpack the build mode for this test
404 build_mode_objs = Modes.find_and_merge_modes(test_obj,
405 [test_obj.build_mode],
406 build_modes,
407 merge_modes=False)
408 test_obj.build_mode = build_mode_objs[0]
409
410 # Error if set build mode is actually a sim mode
411 if test_obj.build_mode.is_sim_mode is True:
412 log.error(
413 "Test \"%s\" uses build_mode %s which is actually a sim mode",
414 test_obj.name, test_obj.build_mode.name)
415 sys.exit(1)
416
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800417 # Merge build_mode's params with self
418 test_obj.pre_run_cmds.extend(test_obj.build_mode.pre_run_cmds)
419 test_obj.post_run_cmds.extend(test_obj.build_mode.post_run_cmds)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800420 test_obj.run_opts.extend(test_obj.build_mode.run_opts)
Srikrishna Iyer96a7ec22020-12-01 14:36:34 -0800421 test_obj.sw_images.extend(test_obj.build_mode.sw_images)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800422
423 # Return the list of tests
424 return tests_objs
425
426 @staticmethod
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800427 def merge_global_opts(tests, global_pre_build_cmds, global_post_build_cmds,
428 global_build_opts, global_pre_run_cmds,
Srikrishna Iyer96a7ec22020-12-01 14:36:34 -0800429 global_post_run_cmds, global_run_opts, global_sw_images):
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800430 processed_build_modes = []
431 for test in tests:
432 if test.build_mode.name not in processed_build_modes:
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800433 test.build_mode.pre_build_cmds.extend(global_pre_build_cmds)
434 test.build_mode.post_build_cmds.extend(global_post_build_cmds)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800435 test.build_mode.build_opts.extend(global_build_opts)
436 processed_build_modes.append(test.build_mode.name)
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800437 test.pre_run_cmds.extend(global_pre_run_cmds)
438 test.post_run_cmds.extend(global_post_run_cmds)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800439 test.run_opts.extend(global_run_opts)
Srikrishna Iyer96a7ec22020-12-01 14:36:34 -0800440 test.sw_images.extend(global_sw_images)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800441
442
443class Regressions(Modes):
444 """
445 Abstraction for test sets / regression sets.
446 """
447
448 # Maintain a list of tests str
449 item_names = []
450
451 # TODO: define __repr__ and __str__ to print list of tests if VERBOSE
452
453 def __init__(self, regdict):
454 self.name = ""
455 self.type = ""
Rupert Swarbrick6cc20112020-04-24 09:44:35 +0100456 if not hasattr(self, "mname"):
457 self.mname = "regression"
Srikrishna Iyer231d0d02020-08-06 17:08:22 -0700458
459 # The `tests` member is typically a list, but it defaults to None.
460 # There are 3 possible cases after all the HJson files are parsed, when
461 # this particular regression is supplied to be run:
462 #
463 # 1. `tests` == None: This is treated as "run ALL available tests".
464 # 2. `tests` == []: No available tests to run
465 # 3. `len(tests)` > 0: The provided set of tests are run.
Srikrishna Iyerfbbf6cb2020-08-05 23:00:51 -0700466 self.tests = None
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800467 self.test_names = []
Srikrishna Iyer231d0d02020-08-06 17:08:22 -0700468
469 self.reseed = None
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800470 self.excl_tests = [] # TODO: add support for this
471 self.en_sim_modes = []
472 self.en_run_modes = []
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800473 self.pre_build_cmds = []
474 self.post_build_cmds = []
475 self.pre_run_cmds = []
476 self.post_run_cmds = []
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800477 self.build_opts = []
478 self.run_opts = []
479 super().__init__(regdict)
480
481 @staticmethod
482 def create_regressions(regdicts, sim_cfg, tests):
483 '''
484 Create Test sets from a given list of raw dicts.
485 Return a list of test set objects.
486 '''
487
488 regressions_objs = []
489 # Pass 1: Create unique set of test sets by merging test sets with the same name
490 for regdict in regdicts:
491 # Create a new item
492 new_regression_merged = False
493 new_regression = Regressions(regdict)
494
495 # Check for name conflicts with tests before merging
496 if new_regression.name in Tests.item_names:
Srikrishna Iyerc93b4832020-08-06 17:54:16 -0700497 log.error(
498 "Test names and regression names are required to be unique. "
499 "The regression \"%s\" bears the same name with an existing test. ",
500 new_regression.name)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800501 sys.exit(1)
502
503 for regression in regressions_objs:
504 # Merge new one with existing if available
505 if regression.name == new_regression.name:
506 regression.merge_mode(new_regression)
507 new_regression_merged = True
508 break
509
510 # Add the new test to the list if not already appended
511 if not new_regression_merged:
512 regressions_objs.append(new_regression)
513 Regressions.item_names.append(new_regression.name)
514
515 # Pass 2: Process dependencies
516 build_modes = []
517 if hasattr(sim_cfg, "build_modes"):
518 build_modes = getattr(sim_cfg, "build_modes")
519
520 run_modes = []
521 if hasattr(sim_cfg, "run_modes"):
522 run_modes = getattr(sim_cfg, "run_modes")
523
524 for regression_obj in regressions_objs:
525 # Unpack the sim modes
526 found_sim_mode_objs = Modes.find_and_merge_modes(
527 regression_obj, regression_obj.en_sim_modes, build_modes,
528 False)
529
530 for sim_mode_obj in found_sim_mode_objs:
531 if sim_mode_obj.is_sim_mode == 0:
532 log.error(
533 "Enabled mode \"%s\" within the regression \"%s\" is not a sim mode",
534 sim_mode_obj.name, regression_obj.name)
535 sys.exit(1)
536
537 # Check if sim_mode_obj's sub-modes are a part of regressions's
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800538 # sim modes- if yes, then it will cause duplication of cmds &
539 # opts. Throw an error and exit.
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800540 for sim_mode_obj_sub in sim_mode_obj.en_build_modes:
541 if sim_mode_obj_sub in regression_obj.en_sim_modes:
Srikrishna Iyerc93b4832020-08-06 17:54:16 -0700542 log.error(
543 "Regression \"%s\" enables sim_modes \"%s\" and \"%s\". "
544 "The former is already a sub_mode of the latter.",
545 regression_obj.name, sim_mode_obj_sub,
546 sim_mode_obj.name)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800547 sys.exit(1)
548
549 # Check if sim_mode_obj is also passed on the command line, in
550 # which case, skip
551 if sim_mode_obj.name in sim_cfg.en_build_modes:
552 continue
553
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800554 # Merge the build and run cmds & opts from the sim modes
555 regression_obj.pre_build_cmds.extend(
556 sim_mode_obj.pre_build_cmds)
557 regression_obj.post_build_cmds.extend(
558 sim_mode_obj.post_build_cmds)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800559 regression_obj.build_opts.extend(sim_mode_obj.build_opts)
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800560 regression_obj.pre_run_cmds.extend(sim_mode_obj.pre_run_cmds)
561 regression_obj.post_run_cmds.extend(sim_mode_obj.post_run_cmds)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800562 regression_obj.run_opts.extend(sim_mode_obj.run_opts)
563
564 # Unpack the run_modes
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800565 # TODO: If there are other params other than run_opts throw an
566 # error and exit
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800567 found_run_mode_objs = Modes.find_and_merge_modes(
568 regression_obj, regression_obj.en_run_modes, run_modes, False)
569
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800570 # Only merge the pre_run_cmds, post_run_cmds & run_opts from the
571 # run_modes enabled
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800572 for run_mode_obj in found_run_mode_objs:
573 # Check if run_mode_obj is also passed on the command line, in
574 # which case, skip
575 if run_mode_obj.name in sim_cfg.en_run_modes:
576 continue
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800577 regression_obj.pre_run_cmds.extend(run_mode_obj.pre_run_cmds)
578 regression_obj.post_run_cmds.extend(run_mode_obj.post_run_cmds)
Rupert Swarbrick5dbaee72020-04-23 14:43:12 +0100579 regression_obj.run_opts.extend(run_mode_obj.run_opts)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800580
581 # Unpack tests
Srikrishna Iyer231d0d02020-08-06 17:08:22 -0700582 # If `tests` member resolves to None, then we add ALL available
583 # tests for running the regression.
Srikrishna Iyerfbbf6cb2020-08-05 23:00:51 -0700584 if regression_obj.tests is None:
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800585 log.log(VERBOSE,
586 "Unpacking all tests in scope for regression \"%s\"",
587 regression_obj.name)
588 regression_obj.tests = sim_cfg.tests
589 regression_obj.test_names = Tests.item_names
590
591 else:
592 tests_objs = []
593 regression_obj.test_names = regression_obj.tests
594 for test in regression_obj.tests:
595 test_obj = Modes.find_mode(test, sim_cfg.tests)
596 if test_obj is None:
597 log.error(
598 "Test \"%s\" added to regression \"%s\" not found!",
599 test, regression_obj.name)
Srikrishna Iyeraae92812020-07-01 00:24:46 -0700600 continue
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800601 tests_objs.append(test_obj)
602 regression_obj.tests = tests_objs
603
604 # Return the list of tests
605 return regressions_objs
606
607 def merge_regression_opts(self):
608 processed_build_modes = []
609 for test in self.tests:
610 if test.build_mode.name not in processed_build_modes:
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800611 test.build_mode.pre_build_cmds.extend(self.pre_build_cmds)
612 test.build_mode.post_build_cmds.extend(self.post_build_cmds)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800613 test.build_mode.build_opts.extend(self.build_opts)
614 processed_build_modes.append(test.build_mode.name)
Srikrishna Iyer6c531b02020-11-23 18:41:16 -0800615 test.pre_run_cmds.extend(self.pre_run_cmds)
616 test.post_run_cmds.extend(self.post_run_cmds)
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800617 test.run_opts.extend(self.run_opts)
618
619 # Override reseed if available.
Rupert Swarbricke83b55e2020-05-12 11:44:04 +0100620 if self.reseed is not None:
Srikrishna Iyer09a81e92019-12-30 10:47:57 -0800621 test.reseed = self.reseed