1#!/usr/bin/env python3
2# Copyright (c) 2023 Intel Corporation
3#
4# SPDX-License-Identifier: Apache-2.0
5
6'''Common fixtures for use in testing the twister tool.'''
7
8import logging
9import shutil
10from unittest import mock
11import os
12import pytest
13import sys
14
15logging.getLogger("twister").setLevel("DEBUG")  # requires for testing twister
16
17ZEPHYR_BASE = os.getenv('ZEPHYR_BASE')
18TEST_DATA = os.path.join(ZEPHYR_BASE, 'scripts', 'tests',
19                        'twister_blackbox', 'test_data')
20
21
22sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts/pylib/twister"))
23sys.path.insert(0, os.path.join(ZEPHYR_BASE, "scripts"))
24
25
26sample_filename_mock = mock.PropertyMock(return_value='test_sample.yaml')
27testsuite_filename_mock = mock.PropertyMock(return_value='test_data.yaml')
28sample_filename_mock = mock.PropertyMock(return_value='test_sample.yaml')
29
30def pytest_configure(config):
31    config.addinivalue_line("markers", "noclearlog: disable the clear_log autouse fixture")
32    config.addinivalue_line("markers", "noclearout: disable the provide_out autouse fixture")
33
34@pytest.fixture(name='zephyr_base')
35def zephyr_base_directory():
36    return ZEPHYR_BASE
37
38
39@pytest.fixture(name='zephyr_test_data')
40def zephyr_test_directory():
41    return TEST_DATA
42
43@pytest.fixture(autouse=True)
44def clear_log(request):
45    # As this fixture is autouse, one can use the pytest.mark.noclearlog decorator
46    # in order to be sure that this fixture's code will not fire.
47    if 'noclearlog' in request.keywords:
48        return
49
50    # clear_log is used by pytest fixture
51    # However, clear_log_in_test is prepared to be used directly in the code, wherever required
52    clear_log_in_test()
53
54def clear_log_in_test():
55    # Required to fix the pytest logging error
56    # See: https://github.com/pytest-dev/pytest/issues/5502
57    loggers = [logging.getLogger()] \
58            + list(logging.Logger.manager.loggerDict.values()) \
59            + [logging.getLogger(name) for \
60                                 name in logging.root.manager.loggerDict]
61    for logger in loggers:
62        handlers = getattr(logger, 'handlers', [])
63        for handler in handlers:
64            logger.removeHandler(handler)
65
66# This fixture provides blackbox tests with an `out_path` parameter
67# It should be used as the `-O` (`--out_dir`) parameter in blackbox tests
68# APPRECIATED: method of using this out_path wholly outside of test code
69@pytest.fixture(name='out_path', autouse=True)
70def provide_out(tmp_path, request):
71    # As this fixture is autouse, one can use the pytest.mark.noclearout decorator
72    # in order to be sure that this fixture's code will not fire.
73    # Most of the time, just omitting the `out_path` parameter is sufficient.
74    if 'noclearout' in request.keywords:
75        yield
76        return
77
78    # Before
79    out_container_path = tmp_path / 'blackbox-out-container'
80    out_container_path.mkdir()
81    out_path = os.path.join(out_container_path, "blackbox-out")
82
83    # Test
84    yield out_path
85
86    # After
87    # We're operating in temp, so it is not strictly necessary
88    # but the files can get large quickly as we do not need them after the test.
89    loggers = [logging.getLogger(name) for name in logging.root.manager.loggerDict]
90    for logg in loggers:
91        handls = logg.handlers[:]
92        for handl in handls:
93            logg.removeHandler(handl)
94            handl.close()
95    shutil.rmtree(out_container_path)
96