1#!/usr/bin/env python3
2# Copyright (c) 2020 Intel Corporation
3#
4# SPDX-License-Identifier: Apache-2.0
5"""
6Tests for testinstance class
7"""
8
9import mmap
10import mock
11import os
12import pytest
13import sys
14
15from contextlib import nullcontext
16
17ZEPHYR_BASE = os.getenv('ZEPHYR_BASE')
18sys.path.insert(0, os.path.join(ZEPHYR_BASE, 'scripts', 'pylib', 'twister'))
19
20from twisterlib.testsuite import (
21    _find_src_dir_path,
22    _get_search_area_boundary,
23    find_c_files_in,
24    scan_file,
25    scan_testsuite_path,
26    ScanPathResult,
27    TestCase,
28    TestSuite
29)
30from twisterlib.error import TwisterException, TwisterRuntimeError
31
32
33TESTDATA_1 = [
34    (
35        ScanPathResult(
36            ['a', 'b'],
37            'Found a test that does not start with test_',
38            False,
39            False,
40            True,
41            ['feature_a', 'feature_b']
42        ),
43        ScanPathResult(
44            ['a', 'b'],
45            'Found a test that does not start with test_',
46            False,
47            False,
48            True,
49            ['feature_a', 'feature_b']
50        ),
51        True
52    ),
53#    (
54#        ScanPathResult(),
55#        ScanPathResult(),
56#        True
57#    ),
58    (
59        ScanPathResult(
60            ['a', 'b'],
61            'Found a test that does not start with test_',
62            False,
63            False,
64            True,
65            ['feature_a', 'feature_b']
66        ),
67        'I am not a ScanPathResult.',
68        False
69    ),
70#    (
71#        ScanPathResult(
72#            ['a', 'b'],
73#            'Found a test that does not start with test_',
74#            False,
75#            False,
76#            True,
77#            ['feature_a', 'feature_b']
78#        ),
79#        ScanPathResult(),
80#        False
81#    ),
82]
83
84
85@pytest.mark.parametrize(
86    'original, provided, expected',
87    TESTDATA_1,
88    ids=[
89        'identical',
90#        'empties',
91        'wrong type',
92#        'different with empty'
93    ]
94)
95def test_scanpathresults_dunders(original, provided, expected):
96    result = original == provided
97
98    assert result == expected
99
100TESTDATA_2 = [
101    (
102        os.path.join('testsuites', 'tests', 'test_ztest.c'),
103        ScanPathResult(
104            warnings=None,
105            matches=[
106                'a',
107                'c',
108                'unit_a',
109                'newline',
110                'test_test_aa',
111                'user',
112                'last'
113            ],
114            has_registered_test_suites=False,
115            has_run_registered_test_suites=False,
116            has_test_main=False,
117            ztest_suite_names = ['test_api']
118        )
119    ),
120    (
121        os.path.join('testsuites', 'tests', 'test_a', 'test_ztest_error.c'),
122        ScanPathResult(
123            warnings='Found a test that does not start with test_',
124            matches=['1a', '1c', '2a', '2b'],
125            has_registered_test_suites=False,
126            has_run_registered_test_suites=False,
127            has_test_main=True,
128            ztest_suite_names = ['feature1', 'feature2']
129        )
130    ),
131    (
132        os.path.join('testsuites', 'tests', 'test_a', 'test_ztest_error_1.c'),
133        ScanPathResult(
134            warnings='found invalid #ifdef, #endif in ztest_test_suite()',
135            matches=['unit_1a', 'unit_1b', 'Unit_1c'],
136            has_registered_test_suites=False,
137            has_run_registered_test_suites=False,
138            has_test_main=False,
139            ztest_suite_names = ['feature3']
140        )
141    ),
142    (
143        os.path.join(
144            'testsuites',
145            'tests',
146            'test_d',
147            'test_ztest_error_register_test_suite.c'
148        ),
149        ScanPathResult(
150            warnings=None,
151            matches=['unit_1a', 'unit_1b'],
152            has_registered_test_suites=True,
153            has_run_registered_test_suites=False,
154            has_test_main=False,
155            ztest_suite_names = ['feature4']
156        )
157    ),
158    (
159        os.path.join(
160            'testsuites',
161            'tests',
162            'test_e',
163            'test_ztest_new_suite.c'
164        ),
165        ScanPathResult(
166            warnings=None,
167            matches=['1a', '1b'],
168            has_registered_test_suites=False,
169            has_run_registered_test_suites=True,
170            has_test_main=False,
171            ztest_suite_names = ['feature5']
172        )
173    ),
174#    (
175#        os.path.join(
176#            'testsuites',
177#            'tests',
178#            'test_e',
179#            'test_ztest_no_suite.c'
180#        ),
181#        ScanPathResult(
182#            warnings=None,
183#            matches=None,
184#            has_registered_test_suites=False,
185#            has_run_registered_test_suites=False,
186#            has_test_main=False,
187#            ztest_suite_names = []
188#        )
189#    ),
190]
191
192
193@pytest.mark.parametrize(
194    'test_file, expected',
195    TESTDATA_2,
196    ids=[
197        'valid',
198        'test not starting with test_',
199        'invalid ifdef with test_main',
200        'registered testsuite',
201        'new testsuite with registered run',
202#        'empty testsuite'
203    ]
204)
205def test_scan_file(test_data, test_file, class_env, expected: ScanPathResult):
206    """
207    Testing scan_file method with different
208    ztest files for warnings and results
209    """
210
211    result: ScanPathResult = scan_file(os.path.join(test_data, test_file))
212
213    assert result == expected
214
215
216# Generate testcases depending on available mmap attributes
217TESTIDS_3 = []
218TESTDATA_3 = []
219
220try:
221    TESTDATA_3.append(
222        (
223            'nt',
224            {'access': mmap.ACCESS_READ}
225        )
226    )
227    TESTIDS_3.append('windows')
228except AttributeError:
229    pass
230
231try:
232    TESTDATA_3.append(
233        (
234            'posix',
235            {
236                'flags': mmap.MAP_PRIVATE,
237                'prot': mmap.PROT_READ,
238                'offset': 0
239            }
240        )
241    )
242    TESTIDS_3.append('linux')
243except AttributeError:
244    pass
245
246
247@pytest.mark.parametrize(
248    'os_name, expected',
249    TESTDATA_3,
250    ids=TESTIDS_3
251)
252def test_scan_file_mmap(os_name, expected):
253    class TestException(Exception):
254        pass
255
256    def assert_mmap(*args, **kwargs):
257        assert expected.items() <= kwargs.items()
258
259    # We do this to skip the rest of scan_file
260    def raise_exception(*args, **kwargs):
261        raise TestException('')
262
263    with mock.patch('mmap.mmap', mock.Mock(side_effect=assert_mmap)), \
264         mock.patch('builtins.open', mock.mock_open(read_data='dummy data')), \
265         mock.patch('os.name', os_name), \
266         mock.patch('contextlib.closing', raise_exception):
267        try:
268            scan_file('dummy/path')
269        except TestException:
270            assert True
271            return
272
273    assert False
274
275
276TESTDATA_4 = [
277    (
278        ZEPHYR_BASE,
279        '.',
280        'test_c',
281        'Tests should reference the category and subsystem' \
282        ' with a dot as a separator.'
283    ),
284    (
285        os.path.join(ZEPHYR_BASE, 'scripts', 'tests'),
286        '.',
287        '',
288        'Tests should reference the category and subsystem' \
289        ' with a dot as a separator.'),
290]
291
292
293@pytest.mark.parametrize(
294    'testsuite_root, workdir, name, exception',
295    TESTDATA_4
296)
297def test_get_unique_exception(testsuite_root, workdir, name, exception):
298    """
299    Test to check if tests reference the category and subsystem
300    with a dot as a separator
301    """
302
303    with pytest.raises(TwisterException):
304        unique = TestSuite(testsuite_root, workdir, name)
305        assert unique == exception
306
307
308TEST_DATA_REL_PATH = os.path.join(
309    'scripts',
310    'tests',
311    'twister',
312    'test_data',
313    'testsuites'
314)
315
316
317TESTDATA_5 = [
318    (
319        os.path.join(ZEPHYR_BASE, TEST_DATA_REL_PATH),
320        os.path.join(ZEPHYR_BASE, TEST_DATA_REL_PATH, 'tests', 'test_a'),
321        os.path.join(
322            os.sep,
323            TEST_DATA_REL_PATH,
324            'tests',
325            'test_a',
326            'test_a.check_1'
327        ),
328        os.path.join(
329            os.sep,
330            TEST_DATA_REL_PATH,
331            'tests',
332            'test_a',
333            'test_a.check_1'
334        ),
335    ),
336    (
337        ZEPHYR_BASE,
338        ZEPHYR_BASE,
339        'test_a.check_1',
340        'test_a.check_1'
341    ),
342    (
343        ZEPHYR_BASE,
344        os.path.join(
345            ZEPHYR_BASE,
346            TEST_DATA_REL_PATH,
347            'test_b'
348        ),
349        os.path.join(os.sep, TEST_DATA_REL_PATH, 'test_b', 'test_b.check_1'),
350        os.path.join(os.sep, TEST_DATA_REL_PATH, 'test_b', 'test_b.check_1')
351    ),
352    (
353        os.path.join(ZEPHYR_BASE, 'scripts', 'tests'),
354        os.path.join(ZEPHYR_BASE, 'scripts', 'tests'),
355        'test_b.check_1',
356        os.path.join('scripts', 'tests', 'test_b.check_1')
357    ),
358    (
359        ZEPHYR_BASE,
360        ZEPHYR_BASE,
361        'test_a.check_1.check_2',
362        'test_a.check_1.check_2'
363    ),
364]
365
366
367@pytest.mark.parametrize(
368    'testsuite_root, suite_path, name, expected',
369    TESTDATA_5
370)
371def test_get_unique(testsuite_root, suite_path, name, expected):
372    """
373    Test to check if the unique name is given
374    for each testsuite root and workdir
375    """
376
377    suite = TestSuite(testsuite_root, suite_path, name)
378    assert suite.name == expected
379
380
381TESTDATA_6 = [
382    (
383        b'/* dummy */\r\n    ztest_run_test_suite(feature)',
384        [
385            mock.Mock(
386                start=mock.Mock(return_value=0),
387                end=mock.Mock(return_value=0)
388            )
389        ],
390        False,
391        (0, 13)
392    ),
393    (
394        b'ztest_register_test_suite(featureX, NULL, ztest_unit_test(test_a));',
395        [
396            mock.Mock(
397                start=mock.Mock(return_value=0),
398                end=mock.Mock(return_value=26)
399            )
400        ],
401        True,
402        (26, 67)
403    ),
404    (
405        b'dummy text',
406        [
407            mock.Mock(
408                start=mock.Mock(return_value=0),
409                end=mock.Mock(return_value=0)
410            )
411        ],
412        False,
413        ValueError
414    )
415]
416
417@pytest.mark.parametrize(
418    'search_area, suite_regex_matches, is_registered_test_suite, expected',
419    TESTDATA_6,
420    ids=['run suite', 'registered suite', 'error']
421)
422def test_get_search_area_boundary(
423    search_area,
424    suite_regex_matches,
425    is_registered_test_suite,
426    expected
427):
428    with pytest.raises(expected) if \
429     isinstance(expected, type) and issubclass(expected, Exception) \
430     else nullcontext() as exception:
431        result = _get_search_area_boundary(
432            search_area,
433            suite_regex_matches,
434            is_registered_test_suite
435        )
436
437    if exception:
438        assert str(exception.value) == 'can\'t find ztest_run_test_suite'
439        return
440
441    assert result == expected
442
443
444TESTDATA_7 = [
445    (True, [os.path.join('', 'home', 'user', 'dummy_path', 'dummy.c'),
446            os.path.join('', 'home', 'user', 'dummy_path', 'dummy.cpp')]),
447    (False, [])
448]
449
450@pytest.mark.parametrize(
451    'isdir, expected',
452    TESTDATA_7,
453    ids=['valid', 'not a directory']
454)
455def test_find_c_files_in(isdir, expected):
456    old_dir = os.path.join('', 'home', 'user', 'dummy_base_dir')
457    new_path = os.path.join('', 'home', 'user', 'dummy_path')
458    cur_dir = old_dir
459
460    def mock_chdir(path, *args, **kwargs):
461        nonlocal cur_dir
462        cur_dir = path
463
464    # We simulate such a structure:
465    # <new_path>
466    # ┣ dummy.c
467    # ┣ wrong_dummy.h
468    # ┗ dummy_dir
469    #   ┣ dummy.cpp
470    #   ┗ wrong_dummy.hpp
471    # <old_dir>
472    # ┗ wrong_dummy.c
473    new_path_base = ['dummy.c', 'wrong_dummy.h']
474    new_path_subs = ['dummy.cpp', 'wrong_dummy.hpp']
475    old_dir_base = ['wrong_dummy.c']
476
477    def format_tester(fmt):
478        formats = [
479            {'name': 'subdirs', 'fmt': '**/*.'},
480            {'name': 'base', 'fmt': '*.'}
481        ]
482
483        for format in formats:
484            if fmt.startswith(format['fmt']):
485                return format['name'], fmt[len(format['fmt']):]
486
487        raise ValueError('This test wasn\'t designed for those globs.'
488                         ' Please fix the test before PR!')
489
490    def mock_glob(fmt, *args, **kwargs):
491        from_where, extension = format_tester(fmt)
492
493        if cur_dir == old_dir:
494            if from_where == 'subdirs':
495                return []
496            elif from_where == 'base':
497                return list(filter(lambda fn: fn.endswith(extension),
498                                   old_dir_base))
499            else:
500                return []
501        if cur_dir == new_path:
502            if from_where == 'subdirs':
503                return list(filter(lambda fn: fn.endswith(extension),
504                                   new_path_subs))
505            elif from_where == 'base':
506                return list(filter(lambda fn: fn.endswith(extension),
507                                   new_path_base))
508            else:
509                return []
510
511        raise ValueError('This test wasn\'t designed for those dirs.'
512                         'Please fix the test before PR!')
513
514    with mock.patch('os.path.isdir', return_value=isdir), \
515         mock.patch('os.getcwd', return_value=cur_dir), \
516         mock.patch('glob.glob', mock_glob), \
517         mock.patch('os.chdir', side_effect=mock_chdir) as chdir_mock:
518        filenames = find_c_files_in(new_path)
519
520    assert sorted(filenames) == sorted(expected)
521
522    assert chdir_mock.call_args is None or \
523           chdir_mock.call_args == mock.call(old_dir)
524
525
526TESTDATA_8 = [
527    (
528        os.path.join('dummy', 'path'),
529        ['testsuite_file_1', 'testsuite_file_2'],
530        ['src_dir_file_1', 'src_dir_file_2', 'src_dir_file_3'],
531        {'src_dir_file_1': 1000, 'src_dir_file_2': 2000, 'src_dir_file_3': 0},
532        {
533            'testsuite_file_1': ScanPathResult(
534                matches = ['test_a', 'b'],
535                warnings = 'dummy warning',
536                has_registered_test_suites = True,
537                has_run_registered_test_suites = True,
538                has_test_main = True,
539                ztest_suite_names = ['feature_a']
540            ),
541            'testsuite_file_2': ValueError,
542            'src_dir_file_1': ScanPathResult(
543                matches = ['test_b', 'a'],
544                warnings = None,
545                has_registered_test_suites = True,
546                has_run_registered_test_suites = True,
547                has_test_main = True,
548                ztest_suite_names = ['feature_b']
549            ),
550            'src_dir_file_2': ValueError,
551            'src_dir_file_3': ValueError,
552        },
553        [
554            'testsuite_file_2: can\'t find: dummy exception',
555            'testsuite_file_1: dummy warning',
556            'src_dir_file_2: error parsing source file: dummy exception',
557        ],
558        None,
559        (['a', 'b', 'test_a', 'test_b'], ['feature_a', 'feature_b'])
560    ),
561    (
562        os.path.join('dummy', 'path'),
563        [],
564        ['src_dir_file'],
565        {'src_dir_file': 1000},
566        {
567            'src_dir_file': ScanPathResult(
568                matches = ['test_b', 'a'],
569                warnings = None,
570                has_registered_test_suites = True,
571                has_run_registered_test_suites = False,
572                has_test_main = True,
573                ztest_suite_names = ['feature_b']
574            ),
575        },
576        [
577            'Found call to \'ztest_register_test_suite()\'' \
578            ' but no call to \'ztest_run_registered_test_suites()\''
579        ],
580        TwisterRuntimeError(
581            'Found call to \'ztest_register_test_suite()\'' \
582            ' but no call to \'ztest_run_registered_test_suites()\''
583        ),
584        None
585    ),
586    (
587        os.path.join('dummy', 'path'),
588        [],
589        ['src_dir_file'],
590        {'src_dir_file': 100},
591        {
592            'src_dir_file': ScanPathResult(
593                matches = ['test_b', 'a'],
594                warnings = 'dummy warning',
595                has_registered_test_suites = True,
596                has_run_registered_test_suites = True,
597                has_test_main = True,
598                ztest_suite_names = ['feature_b']
599            ),
600        },
601        ['src_dir_file: dummy warning'],
602        TwisterRuntimeError('src_dir_file: dummy warning'),
603        None
604    ),
605]
606
607
608@pytest.mark.parametrize(
609    'testsuite_path, testsuite_glob, src_dir_glob, sizes, scanpathresults,' \
610    ' expected_logs, expected_exception, expected',
611    TESTDATA_8,
612    ids=[
613        'valid',
614        'warning in src dir',
615        'register with run error',
616    ]
617)
618def test_scan_testsuite_path(
619    caplog,
620    testsuite_path,
621    testsuite_glob,
622    src_dir_glob,
623    sizes,
624    scanpathresults,
625    expected_logs,
626    expected_exception,
627    expected
628):
629    src_dir_path = os.path.join(testsuite_path, 'src')
630
631    def mock_fsdp(path, *args, **kwargs):
632        return src_dir_path
633
634    def mock_find(path, *args, **kwargs):
635        if path == src_dir_path:
636            return src_dir_glob
637        elif path == testsuite_path:
638            return testsuite_glob
639        else:
640            return []
641
642    def mock_sf(filename, *args, **kwargs):
643        if isinstance(scanpathresults[filename], type) and \
644           issubclass(scanpathresults[filename], Exception):
645            raise scanpathresults[filename]('dummy exception')
646        return scanpathresults[filename]
647
648    def mock_stat(filename, *args, **kwargs):
649        result = mock.Mock()
650        type(result).st_size = sizes[filename]
651
652        return result
653
654    with mock.patch('twisterlib.testsuite._find_src_dir_path', mock_fsdp), \
655         mock.patch('twisterlib.testsuite.find_c_files_in', mock_find), \
656         mock.patch('twisterlib.testsuite.scan_file', mock_sf), \
657         mock.patch('os.stat', mock_stat), \
658         pytest.raises(type(expected_exception)) if \
659          expected_exception else nullcontext() as exception:
660        result = scan_testsuite_path(testsuite_path)
661
662    assert all(
663        [expected_log in " ".join(caplog.text.split()) \
664         for expected_log in expected_logs]
665    )
666
667    if expected_exception:
668        assert str(expected_exception) == str(exception.value)
669        return
670
671    assert len(result[0]) == len(expected[0])
672    assert all(
673        [expected_subcase in result[0] for expected_subcase in expected[0]]
674    )
675    assert len(result[1]) == len(expected[1])
676    assert all(
677        [expected_subcase in result[1] for expected_subcase in expected[1]]
678    )
679
680
681TESTDATA_9 = [
682    ('dummy/path', 'dummy/path/src', 'dummy/path/src'),
683    ('dummy/path', 'dummy/src', 'dummy/src'),
684    ('dummy/path', 'another/path', '')
685]
686
687
688@pytest.mark.parametrize(
689    'test_dir_path, isdir_path, expected',
690    TESTDATA_9,
691    ids=['src here', 'src in parent', 'no path']
692)
693def test_find_src_dir_path(test_dir_path, isdir_path, expected):
694    def mock_isdir(path, *args, **kwargs):
695        return os.path.normpath(path) == isdir_path
696
697    with mock.patch('os.path.isdir', mock_isdir):
698        result = _find_src_dir_path(test_dir_path)
699
700    assert os.path.normpath(result) == expected or result == expected
701
702
703TEST_DATA_REL_PATH = os.path.join(
704    'scripts',
705    'tests',
706    'twister',
707    'test_data',
708    'testsuites'
709)
710
711
712TESTDATA_10 = [
713    (
714        ZEPHYR_BASE,
715        ZEPHYR_BASE,
716        'test_a.check_1',
717        {
718            'testcases': ['testcase1', 'testcase2']
719        },
720        ['subcase1', 'subcase2'],
721        ['testsuite_a', 'testsuite_b'],
722        [
723            ('test_a.check_1.testcase1', False),
724            ('test_a.check_1.testcase2', False)
725        ],
726    ),
727    (
728        ZEPHYR_BASE,
729        ZEPHYR_BASE,
730        'test_a.check_1',
731        {},
732        ['subcase_repeat', 'subcase_repeat', 'subcase_alone'],
733        ['testsuite_a'],
734        [
735            ('test_a.check_1.subcase_repeat', False),
736            ('test_a.check_1.subcase_alone', False)
737        ],
738    ),
739    (
740        ZEPHYR_BASE,
741        ZEPHYR_BASE,
742        'test_a.check_1',
743        {},
744        [],
745        ['testsuite_a', 'testsuite_a'],
746        [
747            ('test_a.check_1', True)
748        ],
749    ),
750]
751
752
753@pytest.mark.parametrize(
754    'testsuite_root, suite_path, name, data,' \
755    ' parsed_subcases, suite_names, expected',
756    TESTDATA_10,
757    ids=['data', 'subcases', 'empty']
758)
759def test_testsuite_add_subcases(
760    testsuite_root,
761    suite_path,
762    name,
763    data,
764    parsed_subcases,
765    suite_names,
766    expected
767):
768    """
769    Test to check if the unique name is given
770    for each testsuite root and workdir
771    """
772
773    suite = TestSuite(testsuite_root, suite_path, name)
774    suite.add_subcases(data, parsed_subcases, suite_names)
775
776    assert sorted(suite.ztest_suite_names) == sorted(suite_names)
777
778    assert len(suite.testcases) == len(expected)
779    for testcase in suite.testcases:
780        for expected_value in expected:
781            if expected_value[0] == testcase.name and \
782               expected_value[1] == testcase.freeform:
783                break
784        else:
785            assert False
786
787
788TESTDATA_11 = [
789#    (
790#        ZEPHYR_BASE,
791#        ZEPHYR_BASE,
792#        'test_a.check_1',
793#        {
794#            'testcases': ['testcase1', 'testcase2']
795#        },
796#        [],
797#    ),
798    (
799        ZEPHYR_BASE,
800        ZEPHYR_BASE,
801        'test_a.check_1',
802        {
803            'testcases': ['testcase1', 'testcase2'],
804            'harness': 'console',
805            'harness_config': { 'dummy': 'config' }
806        },
807        [
808            ('harness', 'console'),
809            ('harness_config', { 'dummy': 'config' })
810        ],
811    ),
812#    (
813#        ZEPHYR_BASE,
814#        ZEPHYR_BASE,
815#        'test_a.check_1',
816#        {
817#            'harness': 'console'
818#        },
819#        Exception,
820#    )
821]
822
823
824@pytest.mark.parametrize(
825    'testsuite_root, suite_path, name, data, expected',
826    TESTDATA_11,
827    ids=[
828#        'no harness',
829        'proper harness',
830#        'harness error'
831    ]
832)
833def test_testsuite_load(
834    testsuite_root,
835    suite_path,
836    name,
837    data,
838    expected
839):
840    suite = TestSuite(testsuite_root, suite_path, name)
841
842    with pytest.raises(expected) if \
843     isinstance(expected, type) and issubclass(expected, Exception) \
844     else nullcontext() as exception:
845        suite.load(data)
846
847    if exception:
848        assert str(exception.value) == 'Harness config error: console harness' \
849                                 ' defined without a configuration.'
850        return
851
852    for attr_name, value in expected:
853        assert getattr(suite, attr_name) == value
854
855
856def test_testcase_dunders():
857    case_lesser = TestCase(name='A lesser name')
858    case_greater = TestCase(name='a greater name')
859    case_greater.status = 'success'
860
861    assert case_lesser < case_greater
862    assert str(case_greater) == 'a greater name'
863    assert repr(case_greater) == '<TestCase a greater name with success>'
864
865
866TESTDATA_11 = [
867        (
868            ZEPHYR_BASE + '/scripts/tests/twister/test_data/testsuites',
869            ZEPHYR_BASE + '/scripts/tests/twister/test_data/testsuites/tests/test_a',
870            'test_a.check_1',
871            'test_a.check_1'
872        ),
873        (
874            ZEPHYR_BASE,
875            ZEPHYR_BASE,
876            'test_a.check_1',
877            'test_a.check_1'
878        ),
879        (
880            ZEPHYR_BASE,
881            ZEPHYR_BASE + '/scripts/tests/twister/test_data/testsuites/test_b',
882            'test_b.check_1',
883            'test_b.check_1'
884        ),
885        (
886            os.path.join(ZEPHYR_BASE, 'scripts/tests'),
887            os.path.join(ZEPHYR_BASE, 'scripts/tests'),
888            'test_b.check_1',
889            'test_b.check_1'
890        ),
891        (
892            ZEPHYR_BASE,
893            ZEPHYR_BASE,
894            'test_a.check_1.check_2',
895            'test_a.check_1.check_2'
896        ),
897]
898@pytest.mark.parametrize("testsuite_root, suite_path, name, expected", TESTDATA_11)
899def test_get_no_detailed_test_id(testsuite_root, suite_path, name, expected):
900    '''Test to check if the name without path is given for each testsuite'''
901    suite = TestSuite(testsuite_root, suite_path, name, detailed_test_id=False)
902    print(suite.name)
903    assert suite.name == expected
904