1#!/usr/bin/env python3 2# Copyright (c) 2024 Intel Corporation 3# 4# SPDX-License-Identifier: Apache-2.0 5""" 6Blackbox tests for twister's command line functions related to disable features. 7""" 8 9import importlib 10import pytest 11from unittest import mock 12import os 13import sys 14import re 15 16# pylint: disable=no-name-in-module 17from conftest import ZEPHYR_BASE, TEST_DATA, testsuite_filename_mock 18from twisterlib.testplan import TestPlan 19 20 21@mock.patch.object(TestPlan, 'TESTSUITE_FILENAME', testsuite_filename_mock) 22class TestDisable: 23 TESTDATA_1 = [ 24 ( 25 os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), 26 ['qemu_x86'], 27 '--disable-suite-name-check', 28 [r"Expected suite names:\[['\w+'\[,\s]*\]", r"Detected suite names:\[['\w+'\[,\s]*\]"], 29 True 30 ), 31 ( 32 os.path.join(TEST_DATA, 'tests', 'dummy', 'agnostic'), 33 ['qemu_x86'], 34 '-v', 35 [r"Expected suite names:\[['(\w+)'[, ]*]+", r"Detected suite names:\[['(\w+)'[, ]*]+"], 36 False 37 ), 38 ] 39 TESTDATA_2 = [ 40 ( 41 os.path.join(TEST_DATA, 'tests', 'always_warning'), 42 ['qemu_x86'], 43 '--disable-warnings-as-errors', 44 '0' 45 ), 46 ( 47 os.path.join(TEST_DATA, 'tests', 'always_warning'), 48 ['qemu_x86'], 49 '-v', 50 '1' 51 ), 52 ] 53 54 55 @classmethod 56 def setup_class(cls): 57 apath = os.path.join(ZEPHYR_BASE, 'scripts', 'twister') 58 cls.loader = importlib.machinery.SourceFileLoader('__main__', apath) 59 cls.spec = importlib.util.spec_from_loader(cls.loader.name, cls.loader) 60 cls.twister_module = importlib.util.module_from_spec(cls.spec) 61 62 63 @classmethod 64 def teardown_class(cls): 65 pass 66 67 68 @pytest.mark.parametrize( 69 'test_path, test_platforms, flag, expected, expected_none', 70 TESTDATA_1, 71 ids=[ 72 'disable-suite-name-check', 73 'suite-name-check' 74 ], 75 ) 76 77 def test_disable_suite_name_check(self, capfd, out_path, test_path, test_platforms, flag, expected, expected_none): 78 args = ['-i', '--outdir', out_path, '-T', test_path] + \ 79 [flag] + \ 80 ['-vv', '-ll', 'DEBUG'] + \ 81 [val for pair in zip( 82 ['-p'] * len(test_platforms), test_platforms 83 ) for val in pair] 84 85 with mock.patch.object(sys, 'argv', [sys.argv[0]] + args), \ 86 pytest.raises(SystemExit) as sys_exit: 87 self.loader.exec_module(self.twister_module) 88 89 out, err = capfd.readouterr() 90 sys.stdout.write(out) 91 sys.stderr.write(err) 92 93 assert str(sys_exit.value) == '0' 94 if expected_none: 95 assert re.search(expected[0], err) is None, f"Not expected string in log: {expected[0]}" 96 assert re.search(expected[1], err) is None, f"Not expected: {expected[1]}" 97 else: 98 assert re.search(expected[0], err) is not None, f"Expected string in log: {expected[0]}" 99 assert re.search(expected[1], err) is not None, f"Expected string in log: {expected[1]}" 100 101 102 @pytest.mark.parametrize( 103 'test_path, test_platforms, flag, expected_exit_code', 104 TESTDATA_2, 105 ids=[ 106 'disable-warnings-as-errors', 107 'warnings-as-errors' 108 ], 109 ) 110 111 def test_disable_warnings_as_errors(self, capfd, out_path, test_path, test_platforms, flag, expected_exit_code): 112 args = ['-i', '--outdir', out_path, '-T', test_path] + \ 113 [flag] + \ 114 ['-vv'] + \ 115 ['--build-only'] + \ 116 [val for pair in zip( 117 ['-p'] * len(test_platforms), test_platforms 118 ) for val in pair] 119 120 with mock.patch.object(sys, 'argv', [sys.argv[0]] + args), \ 121 pytest.raises(SystemExit) as sys_exit: 122 self.loader.exec_module(self.twister_module) 123 124 out, err = capfd.readouterr() 125 sys.stdout.write(out) 126 sys.stderr.write(err) 127 128 assert str(sys_exit.value) == expected_exit_code, \ 129 f"Twister return not expected ({expected_exit_code}) exit code: ({sys_exit.value})" 130