1#!/usr/bin/env python3
2# Copyright (c) 2020 Intel Corporation
3# Copyright (c) 2024 Arm Limited (or its affiliates). All rights reserved.
4#
5# SPDX-License-Identifier: Apache-2.0
6"""
7This test file contains foundational testcases for Twister tool
8"""
9
10import os
11import sys
12import mock
13import pytest
14
15from pathlib import Path
16
17ZEPHYR_BASE = os.getenv("ZEPHYR_BASE")
18sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/twister"))
19
20import scl
21from twisterlib.error import ConfigurationError
22from twisterlib.testplan import TwisterConfigParser
23
24def test_yamlload():
25    """ Test to check if loading the non-existent files raises the errors """
26    filename = 'testcase_nc.yaml'
27    with pytest.raises(FileNotFoundError):
28        scl.yaml_load(filename)
29
30
31@pytest.mark.parametrize("filename, schema",
32                         [("testsuite_correct_schema.yaml", "testsuite-schema.yaml"),
33                          ("platform_correct_schema.yaml", "platform-schema.yaml")])
34def test_correct_schema(filename, schema, test_data):
35    """ Test to validate the testsuite schema"""
36    filename = test_data + filename
37    schema = scl.yaml_load(ZEPHYR_BASE +'/scripts/schemas/twister//' + schema)
38    data = TwisterConfigParser(filename, schema)
39    data.load()
40    assert data
41
42
43@pytest.mark.parametrize("filename, schema",
44                         [("testsuite_incorrect_schema.yaml", "testsuite-schema.yaml"),
45                          ("platform_incorrect_schema.yaml", "platform-schema.yaml")])
46def test_incorrect_schema(filename, schema, test_data):
47    """ Test to validate the exception is raised for incorrect testsuite schema"""
48    filename = test_data + filename
49    schema = scl.yaml_load(ZEPHYR_BASE +'/scripts/schemas/twister//' + schema)
50    with pytest.raises(Exception) as exception:
51        scl.yaml_load_verify(filename, schema)
52        assert str(exception.value) == "Schema validation failed"
53
54def test_testsuite_config_files():
55    """ Test to validate conf and overlay files are extracted properly """
56    filename = Path(ZEPHYR_BASE) / "scripts/tests/twister/test_data/test_data_with_deprecation_warnings.yaml"
57    schema = scl.yaml_load(Path(ZEPHYR_BASE) / "scripts/schemas/twister/testsuite-schema.yaml")
58    data = TwisterConfigParser(filename, schema)
59    data.load()
60
61    with mock.patch('warnings.warn') as warn_mock:
62        # Load and validate the specific scenario from testcases.yaml
63        scenario = data.get_scenario("test_config.main")
64        assert scenario
65
66        # CONF_FILE, DTC_OVERLAY_FILE, OVERLAY_CONFIG fields should be stripped out
67        # of extra_args. Other fields should remain untouched.
68        warn_mock.assert_called_once_with(
69            "Do not specify CONF_FILE, OVERLAY_CONFIG, or DTC_OVERLAY_FILE in extra_args."
70            " This feature is deprecated and will soon result in an error."
71            " Use extra_conf_files, extra_overlay_confs"
72            " or extra_dtc_overlay_files YAML fields instead",
73            DeprecationWarning,
74            stacklevel=2
75        )
76
77    assert scenario["extra_args"] == ["UNRELATED1=abc", "UNRELATED2=xyz"]
78
79    # Check that all conf files have been assembled in the correct order
80    assert ";".join(scenario["extra_conf_files"]) == \
81        "conf1;conf2;conf3;conf4;conf5;conf6;conf7;conf8"
82
83    # Check that all DTC overlay files have been assembled in the correct order
84    assert ";".join(scenario["extra_dtc_overlay_files"]) == \
85        "overlay1;overlay2;overlay3;overlay4;overlay5;overlay6;overlay7;overlay8"
86
87    # Check that all overlay conf files have been assembled in the correct order
88    assert scenario["extra_overlay_confs"] == \
89        ["oc1.conf", "oc2.conf", "oc3.conf", "oc4.conf"]
90
91    # Check extra kconfig statements, too
92    assert scenario["extra_configs"] == ["CONFIG_FOO=y"]
93
94def test_configuration_error():
95    """Test to validate that the ConfigurationError is raisable without further errors.
96
97    It ought to have an str with a path, colon and a message as its only args entry.
98    """
99    filename = Path(ZEPHYR_BASE) / "scripts/tests/twister/test_twister.py"
100
101    with pytest.raises(ConfigurationError) as exception:
102        raise ConfigurationError(filename, "Dummy message.")
103
104    assert len(exception.value.args) == 1
105    assert exception.value.args[0] == str(filename) + ": " + "Dummy message."
106