mock has been available in Python standard lib since Python 3.3, remove the unnecessary dependency to `mock` pip package. Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
495 lines
12 KiB
Python
495 lines
12 KiB
Python
#!/usr/bin/env python3
|
|
# Copyright (c) 2023 Intel Corporation
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
'''
|
|
This test file contains tests for platform.py module of twister
|
|
'''
|
|
import sys
|
|
import os
|
|
from unittest import mock
|
|
import pytest
|
|
|
|
from contextlib import nullcontext
|
|
from pykwalify.errors import SchemaError
|
|
|
|
ZEPHYR_BASE = os.getenv("ZEPHYR_BASE")
|
|
sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/twister"))
|
|
|
|
from twisterlib.platform import Platform, Simulator, generate_platforms
|
|
|
|
|
|
TESTDATA_1 = [
|
|
(
|
|
"""\
|
|
identifier: dummy empty
|
|
arch: arc
|
|
""",
|
|
{
|
|
'name': 'dummy empty',
|
|
'arch': 'arc',
|
|
'twister': True,
|
|
'ram': 128,
|
|
'timeout_multiplier': 1.0,
|
|
'ignore_tags': [],
|
|
'only_tags': [],
|
|
'default': False,
|
|
'binaries': [],
|
|
'flash': 512,
|
|
'supported': set(),
|
|
'vendor': '',
|
|
'tier': -1,
|
|
'type': 'na',
|
|
'simulators': [],
|
|
'supported_toolchains': [],
|
|
'env': [],
|
|
'env_satisfied': True
|
|
},
|
|
'<dummy empty on arc>'
|
|
),
|
|
(
|
|
"""\
|
|
identifier: dummy full
|
|
arch: riscv
|
|
twister: true
|
|
ram: 1024
|
|
testing:
|
|
timeout_multiplier: 2.0
|
|
ignore_tags:
|
|
- tag1
|
|
- tag2
|
|
only_tags:
|
|
- tag3
|
|
default: true
|
|
binaries:
|
|
- dummy.exe
|
|
- dummy.bin
|
|
flash: 4096
|
|
supported:
|
|
- ble
|
|
- netif:openthread
|
|
- gpio
|
|
vendor: vendor1
|
|
tier: 1
|
|
type: unit
|
|
simulation:
|
|
- name: nsim
|
|
exec: nsimdrv
|
|
toolchain:
|
|
- zephyr
|
|
- llvm
|
|
env:
|
|
- dummynonexistentvar
|
|
""",
|
|
{
|
|
'name': 'dummy full',
|
|
'arch': 'riscv',
|
|
'twister': True,
|
|
'ram': 1024,
|
|
'timeout_multiplier': 2.0,
|
|
'ignore_tags': ['tag1', 'tag2'],
|
|
'only_tags': ['tag3'],
|
|
'default': True,
|
|
'binaries': ['dummy.exe', 'dummy.bin'],
|
|
'flash': 4096,
|
|
'supported': set(['ble', 'netif', 'openthread', 'gpio']),
|
|
'vendor': 'vendor1',
|
|
'tier': 1,
|
|
'type': 'unit',
|
|
'simulators': [Simulator({'name': 'nsim', 'exec': 'nsimdrv'})],
|
|
'supported_toolchains': ['zephyr', 'llvm', 'cross-compile'],
|
|
'env': ['dummynonexistentvar'],
|
|
'env_satisfied': False
|
|
},
|
|
'<dummy full on riscv>'
|
|
),
|
|
]
|
|
|
|
# This test is disabled because the Platform loading was changed significantly.
|
|
# The test should be updated to reflect the new implementation.
|
|
|
|
@pytest.mark.parametrize(
|
|
'platform_text, expected_data, expected_repr',
|
|
TESTDATA_1,
|
|
ids=['almost empty specification', 'full specification']
|
|
)
|
|
def xtest_platform_load(platform_text, expected_data, expected_repr):
|
|
platform = Platform()
|
|
|
|
with mock.patch('builtins.open', mock.mock_open(read_data=platform_text)):
|
|
platform.load('dummy.yaml')
|
|
|
|
for k, v in expected_data.items():
|
|
if not hasattr(platform, k):
|
|
assert False, f'No key {k} in platform {platform}'
|
|
att = getattr(platform, k)
|
|
if isinstance(v, list) and not isinstance(att, list):
|
|
assert False, f'Value mismatch in key {k} in platform {platform}'
|
|
if isinstance(v, list):
|
|
assert sorted(att) == sorted(v)
|
|
else:
|
|
assert att == v
|
|
|
|
assert platform.__repr__() == expected_repr
|
|
|
|
|
|
TESTDATA_2 = [
|
|
(
|
|
['m0'],
|
|
None,
|
|
{
|
|
'p1e1/s1', 'p1e2/s1', 'p2/s1', 'p3@A/s2/c1', 'p3@B/s2/c1',
|
|
},
|
|
),
|
|
(
|
|
['m0', 'm1'],
|
|
None,
|
|
{
|
|
'p1e1/s1', 'p1e2/s1', 'p2/s1', 'p3@A/s2/c1', 'p3@B/s2/c1',
|
|
'p1e1/s1/v1', 'p1e1/s1/v2', 'p1e2/s1/v1', 'p2/s1/v1',
|
|
},
|
|
),
|
|
(
|
|
['m0', 'm1', 'm2'],
|
|
None,
|
|
{
|
|
'p1e1/s1', 'p1e2/s1', 'p2/s1', 'p3@A/s2/c1', 'p3@B/s2/c1',
|
|
'p1e1/s1/v1', 'p1e1/s1/v2', 'p1e2/s1/v1', 'p2/s1/v1',
|
|
'p3@A/s2/c2', 'p3@B/s2/c2', 'p4/s1',
|
|
},
|
|
),
|
|
(
|
|
['m0', 'm3'],
|
|
Exception("Duplicate platform identifier p1e1/s1 found"),
|
|
None,
|
|
),
|
|
(
|
|
['m0', 'm1', 'm4'],
|
|
Exception("Duplicate platform identifier p1e2/s1/v1 found"),
|
|
None,
|
|
),
|
|
(
|
|
['m0', 'm5'],
|
|
SchemaError(), # Unknown message as this is raised externally
|
|
None,
|
|
),
|
|
]
|
|
|
|
@pytest.mark.parametrize(
|
|
'roots, expected_exception, expected_platform_names',
|
|
TESTDATA_2,
|
|
ids=[
|
|
'default board root',
|
|
'1 extra board root',
|
|
'2 extra board roots',
|
|
'1 extra board root, duplicate platform',
|
|
'2 extra board roots, duplicate platform',
|
|
'1 extra board root, malformed yaml',
|
|
]
|
|
)
|
|
def test_generate_platforms(
|
|
tmp_path,
|
|
roots,
|
|
expected_exception,
|
|
expected_platform_names,
|
|
):
|
|
tmp_files = {
|
|
'm0/boards/zephyr/p1/board.yml': """\
|
|
boards:
|
|
- name: p1e1
|
|
vendor: zephyr
|
|
socs:
|
|
- name: s1
|
|
- name: p1e2
|
|
vendor: zephyr
|
|
socs:
|
|
- name: s1
|
|
""",
|
|
'm0/boards/zephyr/p1/twister.yaml': """\
|
|
type: native
|
|
arch: x86
|
|
variants:
|
|
p1e1:
|
|
twister: False
|
|
p1e2:
|
|
sysbuild: True
|
|
""",
|
|
'm0/boards/zephyr/p2/board.yml': """\
|
|
boards:
|
|
- name: p2
|
|
vendor: zephyr
|
|
socs:
|
|
- name: s1
|
|
""",
|
|
'm0/boards/zephyr/p2/p2.yaml': """\
|
|
identifier: p2/s1
|
|
type: sim
|
|
arch: x86
|
|
vendor: vendor2
|
|
testing:
|
|
default: True
|
|
""",
|
|
'm0/boards/arm/p3/board.yml': """\
|
|
board:
|
|
name: p3
|
|
vendor: arm
|
|
revision:
|
|
format: letter
|
|
default: "A"
|
|
revisions:
|
|
- name: "A"
|
|
- name: "B"
|
|
socs:
|
|
- name: s2
|
|
""",
|
|
'm0/boards/arm/p3/twister.yaml': """\
|
|
type: unit
|
|
arch: arm
|
|
vendor: vendor3
|
|
sysbuild: True
|
|
variants:
|
|
p3/s2/c1:
|
|
testing:
|
|
timeout_multiplier: 2.71828
|
|
p3@B/s2/c1:
|
|
testing:
|
|
timeout_multiplier: 3.14159
|
|
""",
|
|
'm0/soc/zephyr/soc.yml': """\
|
|
family:
|
|
- name: zephyr
|
|
series:
|
|
- name: zephyr_testing
|
|
socs:
|
|
- name: s1
|
|
- name: s2
|
|
cpuclusters:
|
|
- name: c1
|
|
""",
|
|
'm1/boards/zephyr/p1e1/board.yml': """\
|
|
board:
|
|
extend: p1e1
|
|
variants:
|
|
- name: v1
|
|
qualifier: s1
|
|
- name: v2
|
|
qualifier: s1
|
|
""",
|
|
'm1/boards/zephyr/p1e1/twister.yaml': """\
|
|
variants:
|
|
p1e1/s1/v1:
|
|
testing:
|
|
default: True
|
|
""",
|
|
'm1/boards/zephyr/p1e2/board.yml': """\
|
|
board:
|
|
extend: p1e2
|
|
variants:
|
|
- name: v1
|
|
qualifier: s1
|
|
""",
|
|
'm1/boards/zephyr/p2/board.yml': """\
|
|
board:
|
|
extend: p2
|
|
variants:
|
|
- name: v1
|
|
qualifier: s1
|
|
""",
|
|
'm1/boards/zephyr/p2/p2_s1_v1.yaml': """\
|
|
identifier: p2/s1/v1
|
|
""",
|
|
'm2/boards/misc/board.yml': """\
|
|
boards:
|
|
- extend: p3
|
|
- name: p4
|
|
vendor: misc
|
|
socs:
|
|
- name: s1
|
|
""",
|
|
'm2/boards/misc/twister.yaml': """\
|
|
type: qemu
|
|
arch: riscv
|
|
vendor: vendor4
|
|
simulation:
|
|
- name: qemu
|
|
variants:
|
|
p3@A/s2/c2:
|
|
sysbuild: False
|
|
""",
|
|
'm2/soc/zephyr/soc.yml': """\
|
|
socs:
|
|
- extend: s2
|
|
cpuclusters:
|
|
- name: c2
|
|
""",
|
|
'm3/boards/zephyr/p1e1/board.yml': """\
|
|
board:
|
|
extend: p1e1
|
|
""",
|
|
'm3/boards/zephyr/p1e1/twister.yaml': """\
|
|
variants:
|
|
p1e1/s1:
|
|
name: Duplicate Platform
|
|
""",
|
|
'm4/boards/zephyr/p1e2/board.yml': """\
|
|
board:
|
|
extend: p2
|
|
""",
|
|
'm4/boards/zephyr/p1e2/p1e2_s1_v1.yaml': """\
|
|
identifier: p1e2/s1/v1
|
|
""",
|
|
'm5/boards/zephyr/p2/p2-2.yaml': """\
|
|
testing:
|
|
ć#@%!#!#^#@%@:1.0
|
|
identifier: p2_2
|
|
type: sim
|
|
arch: x86
|
|
vendor: vendor2
|
|
""",
|
|
'm5/boards/zephyr/p2/board.yml': """\
|
|
board:
|
|
extend: p2
|
|
""",
|
|
}
|
|
|
|
for filename, content in tmp_files.items():
|
|
(tmp_path / filename).parent.mkdir(parents=True, exist_ok=True)
|
|
(tmp_path / filename).write_text(content)
|
|
|
|
roots = list(map(tmp_path.joinpath, roots))
|
|
with pytest.raises(type(expected_exception)) if \
|
|
expected_exception else nullcontext() as exception:
|
|
platforms = list(generate_platforms(board_roots=roots, soc_roots=roots, arch_roots=roots))
|
|
|
|
if expected_exception:
|
|
if expected_exception.args:
|
|
assert str(expected_exception) == str(exception.value)
|
|
return
|
|
|
|
platform_names = {platform.name for platform in platforms}
|
|
assert len(platforms) == len(platform_names)
|
|
assert platform_names == expected_platform_names
|
|
|
|
expected_data = {
|
|
'p1e1/s1': {
|
|
'aliases': ['p1e1/s1', 'p1e1'],
|
|
# m0/boards/zephyr/p1/board.yml
|
|
'vendor': 'zephyr',
|
|
# m0/boards/zephyr/p1/twister.yaml (base + variant)
|
|
'twister': False,
|
|
'arch': 'x86',
|
|
'type': 'native',
|
|
},
|
|
'p1e2/s1': {
|
|
'aliases': ['p1e2/s1', 'p1e2'],
|
|
# m0/boards/zephyr/p1/board.yml
|
|
'vendor': 'zephyr',
|
|
# m0/boards/zephyr/p1/twister.yaml (base + variant)
|
|
'sysbuild': True,
|
|
'arch': 'x86',
|
|
'type': 'native',
|
|
},
|
|
'p1e1/s1/v1': {
|
|
'aliases': ['p1e1/s1/v1'],
|
|
# m0/boards/zephyr/p1/board.yml
|
|
'vendor': 'zephyr',
|
|
# m0/boards/zephyr/p1/twister.yaml (base)
|
|
# m1/boards/zephyr/p1e1/twister.yaml (variant)
|
|
'default': True,
|
|
'arch': 'x86',
|
|
'type': 'native',
|
|
},
|
|
'p1e1/s1/v2': {
|
|
'aliases': ['p1e1/s1/v2'],
|
|
# m0/boards/zephyr/p1/board.yml
|
|
'vendor': 'zephyr',
|
|
# m0/boards/zephyr/p1/twister.yaml (base)
|
|
'arch': 'x86',
|
|
'type': 'native',
|
|
},
|
|
'p1e2/s1/v1': {
|
|
'aliases': ['p1e2/s1/v1'],
|
|
# m0/boards/zephyr/p1/board.yml
|
|
'vendor': 'zephyr',
|
|
# m0/boards/zephyr/p1/twister.yaml (base)
|
|
'arch': 'x86',
|
|
'type': 'native',
|
|
},
|
|
'p2/s1': {
|
|
'aliases': ['p2/s1', 'p2'],
|
|
# m0/boards/zephyr/p2/board.yml
|
|
'vendor': 'zephyr',
|
|
# m0/boards/zephyr/p2/p2.yaml
|
|
'default': True,
|
|
'arch': 'x86',
|
|
'type': 'sim',
|
|
},
|
|
'p2/s1/v1': {
|
|
'aliases': ['p2/s1/v1'],
|
|
# m0/boards/zephyr/p2/board.yml
|
|
'vendor': 'zephyr',
|
|
# m1/boards/zephyr/p2/p2_s1_v1.yaml
|
|
},
|
|
'p3@A/s2/c1': {
|
|
'aliases': ['p3@A/s2/c1', 'p3/s2/c1'],
|
|
# m0/boards/arm/p3/board.yml
|
|
'vendor': 'arm',
|
|
# m0/boards/arm/p3/twister.yaml (base + variant)
|
|
'sysbuild': True,
|
|
'timeout_multiplier': 2.71828,
|
|
'arch': 'arm',
|
|
'type': 'unit',
|
|
},
|
|
'p3@B/s2/c1': {
|
|
'aliases': ['p3@B/s2/c1'],
|
|
# m0/boards/arm/p3/board.yml
|
|
'vendor': 'arm',
|
|
# m0/boards/arm/p3/twister.yaml (base + variant)
|
|
'sysbuild': True,
|
|
'timeout_multiplier': 3.14159,
|
|
'arch': 'arm',
|
|
'type': 'unit',
|
|
},
|
|
'p3@A/s2/c2': {
|
|
'aliases': ['p3@A/s2/c2', 'p3/s2/c2'],
|
|
# m0/boards/arm/p3/board.yml
|
|
'vendor': 'arm',
|
|
# m0/boards/arm/p3/twister.yaml (base)
|
|
# m2/boards/misc/twister.yaml (variant)
|
|
'sysbuild': False,
|
|
'arch': 'arm',
|
|
'type': 'unit',
|
|
},
|
|
'p3@B/s2/c2': {
|
|
'aliases': ['p3@B/s2/c2'],
|
|
# m0/boards/arm/p3/board.yml
|
|
'vendor': 'arm',
|
|
# m0/boards/arm/p3/twister.yaml (base)
|
|
'sysbuild': True,
|
|
'arch': 'arm',
|
|
'type': 'unit',
|
|
},
|
|
'p4/s1': {
|
|
'aliases': ['p4/s1', 'p4'],
|
|
# m2/boards/misc/board.yml
|
|
'vendor': 'misc',
|
|
# m2/boards/misc/twister.yaml (base)
|
|
'arch': 'riscv',
|
|
'type': 'qemu',
|
|
'simulators': [Simulator({'name': 'qemu'})],
|
|
'simulation': 'qemu',
|
|
},
|
|
}
|
|
|
|
init_platform = Platform()
|
|
for platform in platforms:
|
|
expected_platform_data = expected_data[platform.name]
|
|
for attr, default in vars(init_platform).items():
|
|
if attr in {'name', 'normalized_name', 'supported_toolchains'}:
|
|
continue
|
|
expected = expected_platform_data.get(attr, default)
|
|
actual = getattr(platform, attr, None)
|
|
assert expected == actual, \
|
|
f"expected '{platform}.{attr}' to be '{expected}', was '{actual}'"
|