blob: 1ff7f0bb8fd12ea19cd733d9f2bfa7665a7f272d [file] [log] [blame]
#!/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}'"