From dfc7860ab1f947e37ed09b1860ad5ea90cefb8ef Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Fri, 9 Aug 2024 17:17:40 -0400 Subject: [PATCH] twister: rework board handling We now use hwmv2 to list boards instead of relying on twister specific config files. One yaml files (twister.yaml for now) will have all the data needed for all possible targets and variations of a board reusing most of the data where possible and variations can override the top level data. Twister keeps track of 'aliases' of boards and identifies that for example native_sim is the same as native_sim/native, so either names will be possible in both test yaml files or on the command line, however, the reporting will always use the full name, so no there is no confusion about what is being tested/built. Signed-off-by: Anas Nashif --- ...xaemv8a_fvp_base_revc_2xaemv8a_smp_ns.yaml | 2 +- .../pylib/twister/twisterlib/config_parser.py | 4 +- scripts/pylib/twister/twisterlib/platform.py | 73 +++-- .../pylib/twister/twisterlib/testinstance.py | 19 +- scripts/pylib/twister/twisterlib/testplan.py | 254 +++++++++++------- .../pylib/twister/twisterlib/twister_main.py | 2 +- scripts/schemas/twister/platform-schema.yaml | 207 +++++++------- tests/arch/arm64/arm64_smc_call/testcase.yaml | 2 +- 8 files changed, 326 insertions(+), 237 deletions(-) diff --git a/boards/arm/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a_fvp_base_revc_2xaemv8a_smp_ns.yaml b/boards/arm/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a_fvp_base_revc_2xaemv8a_smp_ns.yaml index e64ed9f8e7c..f7ef5f7e24a 100644 --- a/boards/arm/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a_fvp_base_revc_2xaemv8a_smp_ns.yaml +++ b/boards/arm/fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a_fvp_base_revc_2xaemv8a_smp_ns.yaml @@ -1,7 +1,7 @@ # Copyright (c) 2022 Arm Limited (or its affiliates). All rights reserved. # SPDX-License-Identifier: Apache-2.0 -identifier: fvp_base_revc_2xaemv8a//smp/ns +identifier: fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a/smp/ns name: FVP Emulation FVP_Base_RevC-2xAEMvA (SMP) arch: arm64 type: sim diff --git a/scripts/pylib/twister/twisterlib/config_parser.py b/scripts/pylib/twister/twisterlib/config_parser.py index 10a31613459..c777059ad86 100644 --- a/scripts/pylib/twister/twisterlib/config_parser.py +++ b/scripts/pylib/twister/twisterlib/config_parser.py @@ -93,12 +93,14 @@ class TwisterConfigParser: self.common = {} def load(self): - self.data = scl.yaml_load_verify(self.filename, self.schema) + data = scl.yaml_load_verify(self.filename, self.schema) + self.data = data if 'tests' in self.data: self.scenarios = self.data['tests'] if 'common' in self.data: self.common = self.data['common'] + return data def _cast_value(self, value, typestr): if isinstance(value, str): diff --git a/scripts/pylib/twister/twisterlib/platform.py b/scripts/pylib/twister/twisterlib/platform.py index 6429907928f..03281ed3b2f 100644 --- a/scripts/pylib/twister/twisterlib/platform.py +++ b/scripts/pylib/twister/twisterlib/platform.py @@ -6,8 +6,11 @@ import os import scl -from twisterlib.config_parser import TwisterConfigParser from twisterlib.environment import ZEPHYR_BASE +import logging + +logger = logging.getLogger('twister') +logger.setLevel(logging.DEBUG) class Platform: """Class representing metadata for a particular platform @@ -23,6 +26,7 @@ class Platform: """ self.name = "" + self.aliases = [] self.normalized_name = "" # if sysbuild to be used by default on a given platform self.sysbuild = False @@ -38,7 +42,7 @@ class Platform: self.flash = 512 self.supported = set() - self.arch = "" + self.arch = None self.vendor = "" self.tier = -1 self.type = "na" @@ -50,41 +54,58 @@ class Platform: self.filter_data = dict() self.uart = "" self.resc = "" + self.qualifier = None - def load(self, platform_file): - scp = TwisterConfigParser(platform_file, self.platform_schema) - scp.load() - data = scp.data + def load(self, board, target, aliases, data): + """Load the platform data from the board data and target data + board: the board object as per the zephyr build system + target: the target name of the board as per the zephyr build system + aliases: list of aliases for the target + data: the data from the twister.yaml file for the target + """ + self.name = target + self.aliases = aliases + + # Get data for various targets and use the main board data as a + # defauly. Individual variant information will replace the default data + # provded in the main twister configuration for this board. + variants = data.get("variants", {}) + variant_data = {} + for alias in aliases: + variant_data = variants.get(alias, {}) + if variant_data: + break - self.name = data['identifier'] self.normalized_name = self.name.replace("/", "_") - self.sysbuild = data.get("sysbuild", False) - self.twister = data.get("twister", True) + self.sysbuild = variant_data.get("sysbuild", data.get("sysbuild", self.sysbuild)) + self.twister = variant_data.get("twister", data.get("twister", self.twister)) + # if no RAM size is specified by the board, take a default of 128K - self.ram = data.get("ram", 128) - testing = data.get("testing", {}) - self.timeout_multiplier = testing.get("timeout_multiplier", 1.0) - self.ignore_tags = testing.get("ignore_tags", []) - self.only_tags = testing.get("only_tags", []) - self.default = testing.get("default", False) + self.ram = variant_data.get("ram", data.get("ram", self.ram)) + # if no flash size is specified by the board, take a default of 512K + self.flash = variant_data.get("flash", data.get("flash", self.flash)) + + testing = variant_data.get("testing", data.get("testing", {})) + self.timeout_multiplier = testing.get("timeout_multiplier", self.timeout_multiplier) + self.ignore_tags = testing.get("ignore_tags", self.ignore_tags) + self.only_tags = testing.get("only_tags", self.only_tags) + self.default = testing.get("default", self.default) self.binaries = testing.get("binaries", []) renode = testing.get("renode", {}) self.uart = renode.get("uart", "") self.resc = renode.get("resc", "") - # if no flash size is specified by the board, take a default of 512K - self.flash = data.get("flash", 512) self.supported = set() - for supp_feature in data.get("supported", []): + for supp_feature in variant_data.get("supported", data.get("supported", [])): for item in supp_feature.split(":"): self.supported.add(item) - self.arch = data['arch'] - self.vendor = data.get('vendor', '') - self.tier = data.get("tier", -1) - self.type = data.get('type', "na") - self.simulation = data.get('simulation', "na") - self.simulation_exec = data.get('simulation_exec') - self.supported_toolchains = data.get("toolchain", []) + self.arch = variant_data.get('arch', data.get('arch', self.arch)) + self.vendor = board.vendor + self.tier = variant_data.get("tier", data.get("tier", self.tier)) + self.type = variant_data.get('type', data.get('type', self.type)) + self.simulation = variant_data.get('simulation', data.get('simulation', self.simulation)) + self.simulation_exec = variant_data.get('simulation_exec', data.get('simulation_exec', self.simulation_exec)) + self.supported_toolchains = variant_data.get("toolchain", data.get("toolchain", [])) if self.supported_toolchains is None: self.supported_toolchains = [] @@ -111,7 +132,7 @@ class Platform: if toolchain not in self.supported_toolchains: self.supported_toolchains.append(toolchain) - self.env = data.get("env", []) + self.env = variant_data.get("env", data.get("env", [])) self.env_satisfied = True for env in self.env: if not os.environ.get(env, None): diff --git a/scripts/pylib/twister/twisterlib/testinstance.py b/scripts/pylib/twister/twisterlib/testinstance.py index 16586a7a20e..64ca808a314 100644 --- a/scripts/pylib/twister/twisterlib/testinstance.py +++ b/scripts/pylib/twister/twisterlib/testinstance.py @@ -241,7 +241,14 @@ class TestInstance: self.handler = handler # Global testsuite parameters - def check_runnable(self, enable_slow=False, filter='buildable', fixtures=[], hardware_map=None): + def check_runnable(self, + options, + hardware_map=None): + + enable_slow = options.enable_slow + filter = options.filter + fixtures = options.fixture + device_testing = options.device_testing if os.name == 'nt': # running on simulators is currently supported only for QEMU on Windows @@ -264,8 +271,7 @@ class TestInstance: target_ready = bool(self.testsuite.type == "unit" or \ self.platform.type == "native" or \ (self.platform.simulation in SUPPORTED_SIMS and \ - self.platform.simulation not in self.testsuite.simulation_exclude) or \ - filter == 'runnable') + self.platform.simulation not in self.testsuite.simulation_exclude) or device_testing) # check if test is runnable in pytest if self.testsuite.harness == 'pytest': @@ -317,9 +323,10 @@ class TestInstance: content = "\n".join(new_config_list) if enable_coverage: - if platform.name in coverage_platform: - content = content + "\nCONFIG_COVERAGE=y" - content = content + "\nCONFIG_COVERAGE_DUMP=y" + for cp in coverage_platform: + if cp in platform.aliases: + content = content + "\nCONFIG_COVERAGE=y" + content = content + "\nCONFIG_COVERAGE_DUMP=y" if enable_asan: if platform.type == "native": diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 360040490de..8731522c21e 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -182,6 +182,7 @@ class TestPlan: if self.options.test: self.run_individual_testsuite = self.options.test + self.add_configurations() num = self.add_testsuites(testsuite_filter=self.run_individual_testsuite) if num == 0: raise TwisterRuntimeError("No test cases found at the specified location...") @@ -192,9 +193,7 @@ class TestPlan: self.scenarios.append(ts.id) self.report_duplicates() - self.parse_configuration(config_file=self.env.test_config) - self.add_configurations() if self.load_errors: raise TwisterRuntimeError("Errors while loading configurations") @@ -398,8 +397,13 @@ class TestPlan: sys.stdout.write(what + "\n") sys.stdout.flush() + def find_twister_data(self, board_data_list, board_aliases): + """Find the twister data for a board in the list of board data based on the aliases""" + for board_data in board_data_list: + if board_data.get('identifier') in board_aliases: + return board_data + def add_configurations(self): - board_dirs = set() # Create a list of board roots as defined by the build system in general # Note, internally in twister a board root includes the `boards` folder # but in Zephyr build system, the board root is without the `boards` in folder path. @@ -407,82 +411,91 @@ class TestPlan: lb_args = Namespace(arch_roots=self.env.arch_roots, soc_roots=self.env.soc_roots, board_roots=board_roots, board=None, board_dir=None) - v1_boards = list_boards.find_boards(lb_args) - v2_dirs = list_boards.find_v2_board_dirs(lb_args) - for b in v1_boards: - board_dirs.add(b.dir) - board_dirs.update(v2_dirs) - logger.debug("Reading platform configuration files under %s..." % self.env.board_roots) - + known_boards = list_boards.find_v2_boards(lb_args) + bdirs = {} platform_config = self.test_config.get('platforms', {}) - for folder in board_dirs: - for file in glob.glob(os.path.join(folder, "*.yaml")): - # If the user set a platform filter, we can, if no other option would increase - # the allowed platform pool, save on time by not loading YAMLs of any boards - # that do not start with the required names. - if self.options.platform and \ - not self.options.all and \ - not self.options.integration and \ - not any([ - os.path.basename(file).startswith( - re.split('[/@]', p)[0] - ) for p in self.options.platform - ]): - continue - try: - platform = Platform() - platform.load(file) - if platform.name in [p.name for p in self.platforms]: - logger.error(f"Duplicate platform {platform.name} in {file}") - raise Exception(f"Duplicate platform identifier {platform.name} found") - if not platform.twister: + # helper function to initialize and add platforms + def init_and_add_platforms(data, board, target, qualifier, aliases): + platform = Platform() + if not new_config_found: + data = self.find_twister_data(bdirs[board.dir], aliases) + if not data: + return + platform.load(board, target, aliases, data) + platform.qualifier = qualifier + if platform.name in [p.name for p in self.platforms]: + logger.error(f"Duplicate platform {platform.name} in {board.dir}") + raise Exception(f"Duplicate platform identifier {platform.name} found") + if not platform.twister: + return + logger.debug(f"Adding platform {platform.name} with aliases {platform.aliases}") + self.platforms.append(platform) + + for board in known_boards: + new_config_found = False + # don't load the same board data twice + if not bdirs.get(board.dir): + datas = [] + for file in glob.glob(os.path.join(board.dir, "*.yaml")): + if os.path.basename(file) == "twister.yaml": continue - - self.platforms.append(platform) - if not platform_config.get('override_default_platforms', False): - if platform.default: - self.default_platforms.append(platform.name) - else: - if platform.name in platform_config.get('default_platforms', []): - logger.debug(f"adding {platform.name} to default platforms") - self.default_platforms.append(platform.name) - - # support board@revision - # if there is already an existed _.yaml, then use it to - # load platform directly, otherwise, iterate the directory to - # get all valid board revision based on each _.conf. - if '@' not in platform.name: - tmp_dir = os.listdir(os.path.dirname(file)) - for item in tmp_dir: - # Need to make sure the revision matches - # the permitted patterns as described in - # cmake/modules/extensions.cmake. - revision_patterns = ["[A-Z]", - "[0-9]+", - "(0|[1-9][0-9]*)(_[0-9]+){0,2}"] - - for pattern in revision_patterns: - result = re.match(f"{platform.name}_(?P{pattern})\\.conf", item) - if result: - revision = result.group("revision") - yaml_file = f"{platform.name}_{revision}.yaml" - if yaml_file not in tmp_dir: - platform_revision = copy.deepcopy(platform) - revision = revision.replace("_", ".") - platform_revision.name = f"{platform.name}@{revision}" - platform_revision.normalized_name = platform_revision.name.replace("/", "_") - platform_revision.default = False - self.platforms.append(platform_revision) - - break - - - except RuntimeError as e: - logger.error("E: %s: can't load: %s" % (file, e)) + try: + scp = TwisterConfigParser(file, Platform.platform_schema) + sdata = scp.load() + datas.append(sdata) + except Exception as e: + logger.error(f"Error loading {file}: {e!r}") + self.load_errors += 1 + continue + bdirs[board.dir] = datas + data = {} + if os.path.exists(board.dir / 'twister.yaml'): + try: + scp = TwisterConfigParser(board.dir / 'twister.yaml', Platform.platform_schema) + data = scp.load() + except Exception as e: + logger.error(f"Error loading {board.dir / 'twister.yaml'}: {e!r}") self.load_errors += 1 + continue + new_config_found = True - self.platform_names = [p.name for p in self.platforms] + + + for qual in list_boards.board_v2_qualifiers(board): + + if board.revisions: + for rev in board.revisions: + target = f"{board.name}@{rev.name}/{qual}" + aliases = [target] + target_no_rev = f"{board.name}/{qual}" + if rev.name == board.revision_default: + aliases.append(target_no_rev) + if '/' not in qual and len(board.socs) == 1: + if rev.name == board.revision_default: + aliases.append(f"{board.name}") + aliases.append(f"{board.name}@{rev.name}") + + init_and_add_platforms(data, board, target, qual, aliases) + else: + target = f"{board.name}/{qual}" + aliases = [target] + if '/' not in qual and len(board.socs) == 1: + aliases.append(board.name) + init_and_add_platforms(data, board, target, qual, aliases) + + for platform in self.platforms: + if not platform_config.get('override_default_platforms', False): + if platform.default: + self.default_platforms.append(platform.name) + #logger.debug(f"adding {platform.name} to default platforms") + continue + for pp in platform_config.get('default_platforms', []): + if pp in platform.aliases: + logger.debug(f"adding {platform.name} to default platforms (override mode)") + self.default_platforms.append(platform.name) + + self.platform_names = [a for p in self.platforms for a in p.aliases] def get_all_tests(self): testcases = [] @@ -550,6 +563,30 @@ class TestPlan: for name in parsed_data.scenarios.keys(): suite_dict = parsed_data.get_scenario(name) suite = TestSuite(root, suite_path, name, data=suite_dict, detailed_test_id=self.options.detailed_test_id) + + # convert to fully qualified names + _integration = [] + _platform_allow = [] + _platform_exclude = [] + for _ip in suite.integration_platforms: + if _ip in self.platform_names: + _integration.append(self.get_platform(_ip).name) + else: + logger.error(f"Platform {_ip} not found in the list of platforms") + suite.integration_platforms = _integration + for _pe in suite.platform_exclude: + if _pe in self.platform_names: + _platform_exclude.append(self.get_platform(_pe).name) + else: + logger.error(f"Platform {_pe} not found in the list of platforms") + suite.platform_exclude = _platform_exclude + for _pa in suite.platform_allow: + if _pa in self.platform_names: + _platform_allow.append(self.get_platform(_pa).name) + else: + logger.error(f"Platform {_pa} not found in the list of platforms") + suite.platform_allow = _platform_allow + if suite.harness in ['ztest', 'test']: if subcases is None: # scan it only once per testsuite @@ -575,7 +612,7 @@ class TestPlan: def get_platform(self, name): selected_platform = None for platform in self.platforms: - if platform.name == name: + if name in platform.aliases: selected_platform = platform break return selected_platform @@ -608,13 +645,10 @@ class TestPlan: instance.run_id = ts.get("run_id") if self.options.device_testing: - tfilter = 'runnable' - else: - tfilter = 'buildable' + self.options.filter = 'runnable' + instance.run = instance.check_runnable( - self.options.enable_slow, - tfilter, - self.options.fixture, + self.options, self.hwm ) @@ -660,14 +694,24 @@ class TestPlan: if tc.get('log'): case.output = tc.get('log') - - instance.create_overlay(platform, self.options.enable_asan, self.options.enable_ubsan, self.options.enable_coverage, self.options.coverage_platform) + instance.create_overlay(platform, + self.options.enable_asan, + self.options.enable_ubsan, + self.options.enable_coverage, + self.options.coverage_platform + ) instance_list.append(instance) self.add_instances(instance_list) except FileNotFoundError as e: logger.error(f"{e}") return 1 + def check_platform(self, platform, platform_list): + for p in platform_list: + if p in platform.aliases: + return True + return False + def apply_filters(self, **kwargs): toolchain = self.env.toolchain @@ -709,8 +753,16 @@ class TestPlan: elif vendor_filter: vendor_platforms = True + _platforms = [] if platform_filter: + logger.debug(f"Checking platform filter: {platform_filter}") + # find in aliases and rename self.verify_platforms_existence(platform_filter, f"platform_filter") + for pf in platform_filter: + logger.debug(f"Checking platform in filter: {pf}") + if pf in self.platform_names: + _platforms.append(self.get_platform(pf).name) + platform_filter = _platforms platforms = list(filter(lambda p: p.name in platform_filter, self.platforms)) elif emu_filter: platforms = list(filter(lambda p: p.simulation != 'na', self.platforms)) @@ -776,19 +828,12 @@ class TestPlan: instance_list = [] for plat in platform_scope: instance = TestInstance(ts, plat, self.env.outdir) - if runnable: - tfilter = 'runnable' - else: - tfilter = 'buildable' - instance.run = instance.check_runnable( - self.options.enable_slow, - tfilter, - self.options.fixture, + self.options, self.hwm ) - if not force_platform and plat.name in exclude_platform: + if not force_platform and self.check_platform(plat,exclude_platform): instance.add_filter("Platform is excluded on command line.", Filters.CMD_LINE) if (plat.arch == "unit") != (ts.type == "unit"): @@ -961,13 +1006,13 @@ class TestPlan: keyed_test = keyed_tests.get(test_keys) if keyed_test is not None: plat_key = {key_field: getattr(keyed_test['plat'], key_field) for key_field in key_fields} - instance.add_filter(f"Already covered for key {tuple(key)} by platform {keyed_test['plat'].name} having key {plat_key}", Filters.PLATFORM_KEY) + instance.add_filter(f"Already covered for key {key} by platform {keyed_test['plat'].name} having key {plat_key}", Filters.PLATFORM_KEY) else: - # do not add a platform to keyed tests if previously filtered + # do not add a platform to keyed tests if previously + # filtered + if not instance.filters: keyed_tests[test_keys] = {'plat': plat, 'ts': ts} - else: - instance.add_filter(f"Excluded platform missing key fields demanded by test {key_fields}", Filters.PLATFORM) # if nothing stopped us until now, it means this configuration # needs to be added. @@ -981,11 +1026,11 @@ class TestPlan: # take all default platforms if default_platforms and not ts.build_on_all and not integration: if ts.platform_allow: - a = set(self.default_platforms) - b = set(ts.platform_allow) - c = a.intersection(b) - if c: - aa = list(filter(lambda ts: ts.platform.name in c, instance_list)) + _default_p = set(self.default_platforms) + _platform_allow = set(ts.platform_allow) + _intersection = _default_p.intersection(_platform_allow) + if _intersection: + aa = list(filter(lambda _scenario: _scenario.platform.name in _intersection, instance_list)) self.add_instances(aa) else: self.add_instances(instance_list) @@ -1011,7 +1056,11 @@ class TestPlan: self.add_instances(instance_list) for _, case in self.instances.items(): - case.create_overlay(case.platform, self.options.enable_asan, self.options.enable_ubsan, self.options.enable_coverage, self.options.coverage_platform) + case.create_overlay(case.platform, + self.options.enable_asan, + self.options.enable_ubsan, + self.options.enable_coverage, + self.options.coverage_platform) self.selected_platforms = set(p.platform.name for p in self.instances.values()) @@ -1105,3 +1154,4 @@ def change_skip_to_error_if_integration(options, instance): return instance.status = TwisterStatus.ERROR instance.reason += " but is one of the integration platforms" + logger.debug(f"Changing status of {instance.name} to ERROR because it is an integration platform") diff --git a/scripts/pylib/twister/twisterlib/twister_main.py b/scripts/pylib/twister/twisterlib/twister_main.py index 55398be8cc0..f5ee03b808a 100644 --- a/scripts/pylib/twister/twisterlib/twister_main.py +++ b/scripts/pylib/twister/twisterlib/twister_main.py @@ -139,7 +139,7 @@ def main(options: argparse.Namespace, default_options: argparse.Namespace): for i in tplan.instances.values(): if i.status == TwisterStatus.FILTER: - if options.platform and i.platform.name not in options.platform: + if options.platform and not tplan.check_platform(i.platform, options.platform): continue logger.debug( "{:<25} {:<50} {}SKIPPED{}: {}".format( diff --git a/scripts/schemas/twister/platform-schema.yaml b/scripts/schemas/twister/platform-schema.yaml index c651f83c3e3..a8771404b02 100644 --- a/scripts/schemas/twister/platform-schema.yaml +++ b/scripts/schemas/twister/platform-schema.yaml @@ -9,103 +9,112 @@ # The original spec comes from Zephyr's twister script # -type: map -mapping: - "identifier": - type: str - "maintainers": - type: seq - seq: - - type: str - "name": - type: str - "type": - type: str - enum: ["mcu", "qemu", "sim", "unit", "native"] - "simulation": - type: str - enum: - [ - "qemu", - "simics", - "xt-sim", - "renode", - "nsim", - "mdb-nsim", - "tsim", - "armfvp", - "native", - "custom", - ] - "simulation_exec": - type: str - "arch": - type: str - enum: - [ - # architectures - "arc", - "arm", - "arm64", - "mips", - "nios2", - "posix", - "riscv", - "sparc", - "x86", - "xtensa", +schema;platform-schema: + type: map + mapping: + "variants": + type: map + matching-rule: "any" + mapping: + regex;(([a-zA-Z0-9_]+)): + include: platform-schema + "identifier": + type: str + "maintainers": + type: seq + seq: + - type: str + "name": + type: str + "type": + type: str + enum: ["mcu", "qemu", "sim", "unit", "native"] + "simulation": + type: str + enum: + [ + "qemu", + "simics", + "xt-sim", + "renode", + "nsim", + "mdb-nsim", + "tsim", + "armfvp", + "native", + "custom", + ] + "simulation_exec": + type: str + "arch": + type: str + enum: + [ + # architectures + "arc", + "arm", + "arm64", + "mips", + "nios2", + "posix", + "riscv", + "sparc", + "x86", + "xtensa", - # unit testing - "unit", - ] - "vendor": - type: str - "tier": - type: int - "toolchain": - type: seq - seq: - - type: str - "sysbuild": - type: bool - "env": - type: seq - seq: - - type: str - "ram": - type: int - "flash": - type: int - "twister": - type: bool - "supported": - type: seq - seq: - - type: str - "testing": - type: map - mapping: - "timeout_multiplier": - type: number - required: false - "default": - type: bool - "binaries": - type: seq - seq: - - type: str - "only_tags": - type: seq - seq: - - type: str - "ignore_tags": - type: seq - seq: - - type: str - "renode": - type: map - mapping: - "uart": - type: str - "resc": - type: str + # unit testing + "unit", + ] + "vendor": + type: str + "tier": + type: int + "toolchain": + type: seq + seq: + - type: str + "sysbuild": + type: bool + "env": + type: seq + seq: + - type: str + "ram": + type: int + "flash": + type: int + "twister": + type: bool + "supported": + type: seq + seq: + - type: str + "testing": + type: map + mapping: + "timeout_multiplier": + type: number + required: false + "default": + type: bool + "binaries": + type: seq + seq: + - type: str + "only_tags": + type: seq + seq: + - type: str + "ignore_tags": + type: seq + seq: + - type: str + "renode": + type: map + mapping: + "uart": + type: str + "resc": + type: str + +include: platform-schema diff --git a/tests/arch/arm64/arm64_smc_call/testcase.yaml b/tests/arch/arm64/arm64_smc_call/testcase.yaml index 763192878e6..eb424fe1a52 100644 --- a/tests/arch/arm64/arm64_smc_call/testcase.yaml +++ b/tests/arch/arm64/arm64_smc_call/testcase.yaml @@ -1,6 +1,6 @@ tests: arch.arm64.smc_call.smc: - platform_allow: fvp_base_revc_2xaemv8a//smp/ns + platform_allow: fvp_base_revc_2xaemv8a/fvp_base_revc_2xaemv8a/smp/ns tags: - arm - smc