1#!/usr/bin/env python3
2# Copyright (c) 2024 Intel Corporation
3#
4# SPDX-License-Identifier: Apache-2.0
5
6import importlib
7import json
8import os
9import sys
10from unittest import mock
11
12import pytest
13from conftest import TEST_DATA, ZEPHYR_BASE, testsuite_filename_mock
14from twisterlib.testplan import TestPlan
15
16
17class TestDummy:
18    TESTDATA_X = [
19        ("smoke", 5),
20        ("acceptance", 6),
21    ]
22
23    @classmethod
24    def setup_class(cls):
25        apath = os.path.join(ZEPHYR_BASE, "scripts", "twister")
26        cls.loader = importlib.machinery.SourceFileLoader("__main__", apath)
27        cls.spec = importlib.util.spec_from_loader(cls.loader.name, cls.loader)
28        cls.twister_module = importlib.util.module_from_spec(cls.spec)
29
30    @classmethod
31    def teardown_class(cls):
32        pass
33
34    @pytest.mark.parametrize(
35        "level, expected_tests", TESTDATA_X, ids=["smoke", "acceptance"]
36    )
37    @mock.patch.object(TestPlan, "TESTSUITE_FILENAME", testsuite_filename_mock)
38    def test_level(self, capfd, out_path, level, expected_tests):
39        # Select platforms used for the tests
40        test_platforms = ["qemu_x86", "frdm_k64f"]
41        # Select test root
42        path = os.path.join(TEST_DATA, "tests")
43        config_path = os.path.join(TEST_DATA, "test_config.yaml")
44
45        # Set flags for our Twister command as a list of strs
46        args = (
47            # Flags related to the generic test setup:
48            # * Control the level of detail in stdout/err
49            # * Establish the output directory
50            # * Select Zephyr tests to use
51            # * Control whether to only build or build and run aforementioned tests
52            ["-i", "--outdir", out_path, "-T", path, "-y"]
53            # Flags under test
54            + ["--level", level]
55            # Flags required for the test
56            + ["--test-config", config_path]
57            # Flags related to platform selection
58            + [
59                val
60                for pair in zip(["-p"] * len(test_platforms), test_platforms, strict=False)
61                for val in pair
62            ]
63        )
64
65        # First, provide the args variable as our Twister command line arguments.
66        # Then, catch the exit code in the sys_exit variable.
67        with mock.patch.object(sys, "argv", [sys.argv[0]] + args), pytest.raises(
68            SystemExit
69        ) as sys_exit:
70            # Execute the Twister call itself.
71            self.loader.exec_module(self.twister_module)
72
73        # Check whether the Twister call succeeded
74        assert str(sys_exit.value) == "0"
75
76        # Access to the test file output
77        with open(os.path.join(out_path, "testplan.json")) as f:
78            j = json.load(f)
79        filtered_j = [
80            (ts["platform"], ts["name"], tc["identifier"])
81            for ts in j["testsuites"]
82            for tc in ts["testcases"]
83            if "reason" not in tc
84        ]
85
86        # Read stdout and stderr to out and err variables respectively
87        out, err = capfd.readouterr()
88        # Rewrite the captured buffers to stdout and stderr so the user can still read them
89        sys.stdout.write(out)
90        sys.stderr.write(err)
91
92        # Test-relevant checks
93        assert expected_tests == len(filtered_j)
94