summaryrefslogtreecommitdiff
path: root/zephyr/zmake/tests/test_project.py
blob: 5d6fd0b5ed1143076656665e0e126d8c91b2fb48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# Copyright 2021 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import hypothesis
import hypothesis.strategies as st
import pathlib
import pytest
import string
import tempfile

import zmake.modules
import zmake.project


board_names = st.text(alphabet=set(string.ascii_lowercase) | {'_'},
                      min_size=1)
sets_of_board_names = st.lists(st.lists(board_names, unique=True))


class TemporaryProject(tempfile.TemporaryDirectory):
    """A temporary project wrapper.

    Args:
        config: The config dictionary to be used with the project.
    """
    def __init__(self, config):
        self.config = config
        super().__init__()

    def __enter__(self):
        project_path = pathlib.Path(super().__enter__())
        return zmake.project.Project(project_path, config_dict=self.config)


@hypothesis.given(sets_of_board_names)
@hypothesis.settings(deadline=None)
def test_find_dts_overlays(modules):
    """Test the functionality of find_dts_overlays with multiple
    modules, each with sets of board names."""

    # Recursive function to wind up all the temporary directories and
    # call the actual test.
    def setup_modules_and_dispatch(modules, test_fn, module_list=()):
        if modules:
            boards = modules[0]
            with tempfile.TemporaryDirectory() as modpath:
                modpath = pathlib.Path(modpath)
                for board in boards:
                    dts_path = zmake.project.module_dts_overlay_name(
                        modpath, board)
                    dts_path.parent.mkdir(parents=True, exist_ok=True)
                    dts_path.touch()
                setup_modules_and_dispatch(
                    modules[1:], test_fn, module_list=module_list + (modpath,))
        else:
            test_fn(module_list)

    # The actual test case, once temp modules have been setup.
    def testcase(module_paths):
        # Maps board_name→overlay_files
        board_file_mapping = {}
        for modpath, board_list in zip(module_paths, modules):
            for board in board_list:
                file_name = zmake.project.module_dts_overlay_name(
                    modpath, board)
                files = board_file_mapping.get(board, set())
                board_file_mapping[board] = files | {file_name}

        for board, expected_dts_files in board_file_mapping.items():
            with TemporaryProject(
                {'board': board,
                 'toolchain': 'foo',
                 'output-type': 'elf',
                 'supported-zephyr-versions': ['v2.4']}) as project:
                config = project.find_dts_overlays(
                    dict(enumerate(module_paths)))

                actual_dts_files = set(
                    config.cmake_defs.get('DTC_OVERLAY_FILE', '').split(';'))

                assert actual_dts_files == set(map(str, expected_dts_files))

    setup_modules_and_dispatch(modules, testcase)


module_lists = st.lists(st.one_of(*map(st.just, zmake.modules.known_modules)),
                        unique=True)


@hypothesis.given(module_lists)
@hypothesis.settings(deadline=None)
def test_prune_modules(modules):
    """Test the Project.prune_modules method in the usual case (all
    modules available)."""
    module_paths = {
        name: pathlib.Path('/fake/module/path', name)
        for name in zmake.modules.known_modules
    }

    with TemporaryProject(
        {'board': 'native_posix',
         'toolchain': 'coreboot-sdk',
         'output-type': 'elf',
         'supported-zephyr-versions': ['v2.5'],
         'modules': modules}) as project:
        assert set(project.prune_modules(module_paths)) == set(modules)


def test_prune_modules_unavailable():
    """The Project.prune_modules method should raise a KeyError when
    not all modules are available."""

    # Missing 'cmsis'
    module_paths = {
        'hal_stm32': pathlib.Path('/mod/halstm'),
    }

    with TemporaryProject(
        {'board': 'native_posix',
         'toolchain': 'coreboot-sdk',
         'output-type': 'elf',
         'supported-zephyr-versions': ['v2.5'],
         'modules': ['hal_stm32', 'cmsis']}) as project:
        with pytest.raises(KeyError):
            project.prune_modules(module_paths)