示例#1
0
 def _create_tests(self, simulator_if):
     scanner = TestScanner(simulator_if,
                           self._configuration,
                           elaborate_only=self._elaborate_only)
     test_list = scanner.from_project(self._project, entity_filter=self._tb_filter)
     test_list.keep_matches(self._test_filter)
     return test_list
示例#2
0
 def _create_tests(self, simulator_if):
     scanner = TestScanner(simulator_if,
                           self._configuration,
                           elaborate_only=self._elaborate_only)
     test_list = scanner.from_project(self._project,
                                      entity_filter=self._tb_filter)
     test_list.keep_matches(self._test_filter)
     return test_list
示例#3
0
文件: ui.py 项目: varunnagpaal/vunit
 def _create_tests(self, simulator_if):
     """
     Create the test suites by scanning the project
     """
     scanner = TestScanner(simulator_if,
                           self._configuration)
     test_list = scanner.from_project(self._project, entity_filter=self._tb_filter)
     test_list.keep_matches(self._test_filter)
     return test_list
示例#4
0
    def setUp(self):
        self.simulator_if = 'simulator_if'
        self.test_scanner = TestScanner(self.simulator_if, TestConfiguration())

        self.output_path = join(dirname(__file__), "test_scanner_out")

        if exists(self.output_path):
            rmtree(self.output_path)
        makedirs(self.output_path)
示例#5
0
文件: ui.py 项目: jcparrad/vunit
    def _create_tests(self, simulator_if):
        """
        Create the test suites by scanning the project
        """
        scanner = TestScanner(simulator_if,
                              self._configuration)
        test_list = scanner.from_project(self._project, entity_filter=self._tb_filter)

        if test_list.num_tests() == 0:
            LOGGER.warning("Test scanner found no test benches using current filter rule:\n%s",
                           self._tb_filter.__doc__)

        test_list.keep_matches(self._test_filter)
        return test_list
示例#6
0
    def _create_tests(self, simulator_if):
        """
        Create the test suites by scanning the project
        """
        scanner = TestScanner(simulator_if,
                              self._configuration,
                              elaborate_only=self._elaborate_only)
        test_list = scanner.from_project(self._project, entity_filter=self._tb_filter)

        if test_list.num_tests() == 0:
            LOGGER.warning("Test scanner found no test benches using current filter rule:\n%s",
                           self._tb_filter.__doc__)

        test_list.keep_matches(self._test_filter)
        return test_list
示例#7
0
 def helper(config_name, suffix):
     """
     Add config with name and check that the test has the given suffix
     """
     project = ProjectStub()
     lib = project.add_library("lib")
     lib.add_entity("tb_entity",
                    generic_names=["runner_cfg"])
     self.configuration = TestConfiguration()
     self.test_scanner = TestScanner(self.simulator_if, self.configuration)
     self.configuration.add_config(scope=create_scope("lib", "tb_entity"),
                                   name=config_name,
                                   generics=dict())
     tests = self.test_scanner.from_project(project)
     self.assert_has_tests(tests,
                           ["lib.tb_entity" + suffix])
示例#8
0
class TestTestScanner(unittest.TestCase):

    def setUp(self):
        self.simulator_if = 'simulator_if'
        self.test_scanner = TestScanner(self.simulator_if, TestConfiguration())

        self.output_path = join(dirname(__file__), "test_scanner_out")

        if exists(self.output_path):
            rmtree(self.output_path)
        makedirs(self.output_path)

    def tearDown(self):
        if exists(self.output_path):
            rmtree(self.output_path)

    def write_file(self, name, contents):
        with open(name, "w") as fwrite:
            fwrite.write(contents)

    def test_that_no_tests_are_created(self):
        project = ProjectStub()
        tests = self.test_scanner.from_project(project)
        self.assertEqual(len(tests), 0)

    def test_that_single_test_is_created(self):
        project = ProjectStub()
        work = project.add_library("work")
        work.add_entity("tb_entity", out("tb_entity.vhd"),
                        {"arch" : out("arch.vhd")})
        self.write_file(out("arch.vhd"), "")
        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests,
                              ["work.tb_entity"])

    def test_that_tests_are_filtered(self):
        project = ProjectStub()
        work = project.add_library("work")

        work.add_entity("tb_entity", out("tb_entity.vhd"),
                        {"arch" : out("arch1.vhd")})
        self.write_file(out("arch1.vhd"), "")

        work.add_entity("tb_entity2", out("path", "tb_entity2.vhd"),
                        {"arch" : out("arch2.vhd")})
        self.write_file(out("arch2.vhd"), "")

        work.add_entity("entity2", out("entity2.vhd"),
                        {"arch" : ""})

        work.add_entity("entity_tb", out("entity_tb.vhd"),
                        {"arch" : out("entity_tb.vhd")})
        self.write_file(out("entity_tb.vhd"), "")

        tests = self.test_scanner.from_project(project, entity_filter=tb_filter)
        self.assert_has_tests(tests,
                              ["work.tb_entity",
                               "work.tb_entity2",
                               "work.entity_tb"])

    def test_that_two_tests_are_created(self):
        project = ProjectStub()
        work = project.add_library("work")
        work.add_entity("tb_entity", out("tb_entity.vhd"),
                        {"arch1" : out("arch1.vhd"),
                         "arch2" : out("arch2.vhd")})
        self.write_file(out("arch1.vhd"), "")
        self.write_file(out("arch2.vhd"), "")

        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests,
                              ["work.tb_entity.arch1",
                               "work.tb_entity.arch2"])

    def test_create_tests_with_runner_cfg_generic(self):
        project = ProjectStub()
        work = project.add_library("work")
        work.add_entity("tb_entity", out("tb_entity.vhd"),
                        {"arch" : out("entity_arch.vhd")},
                        ["runner_cfg"])

        self.write_file(out("entity_arch.vhd"),
'''
if run("Test_1")
--if run("Test_2")
if run("Test_3")
''')

        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests,
                              ["work.tb_entity.Test_1",
                               "work.tb_entity.Test_3"])

    @mock.patch("vunit.test_scanner.logger")
    def test_duplicate_tests_cause_error(self, mock_logger):
        project = ProjectStub()
        work = project.add_library("work")
        work.add_entity("tb_entity", out("tb_entity.vhd"),
                        {"arch" : out("entity_arch.vhd")},
                        ["runner_cfg"])

        self.write_file(out("entity_arch.vhd"),
'''
if run("Test_1")
--if run("Test_1")
if run("Test_3")
if run("Test_2")
if run("Test_3")
if run("Test_3")
if run("Test_2")
''')

        self.assertRaises(TestScannerError, self.test_scanner.from_project, project)

        error_calls = mock_logger.error.call_args_list
        self.assertEqual(len(error_calls), 2)
        self.assertTrue("Test_3" in str(error_calls[0]))
        self.assertTrue(out("entity_arch.vhd") in error_calls[0][0][0])

        self.assertTrue("Test_2" in str(error_calls[1]))
        self.assertTrue(out("entity_arch.vhd") in error_calls[1][0][0])


    def test_create_default_test_with_runner_cfg_generic(self):
        project = ProjectStub()
        work = project.add_library("work")
        work.add_entity("tb_entity", out("tb_entity.vhd"),
                        {"arch" : out("entity_arch.vhd")},
                        ["runner_cfg"])

        self.write_file(out("entity_arch.vhd"), '')

        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests,
                              ["work.tb_entity"])

    def test_that_pragma_run_in_same_simulation_works(self):
        project = ProjectStub()
        work = project.add_library("work")
        work.add_entity("tb_entity", out("tb_entity.vhd"),
                        {"arch" : out("entity_arch.vhd")},
                        ["runner_cfg"])

        self.write_file(out("entity_arch.vhd"),
'''
-- vunit_pragma run_all_in_same_sim
if run("Test_1")
if run("Test_2")
--if run("Test_3")
''')

        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests,
                              [("work.tb_entity", ("Test_1", "Test_2"))])


    def assertCountEqual(self, values1, values2):
        # Python 2.7 compatability
        self.assertEqual(sorted(values1), sorted(values2))

    def assert_has_tests(self, test_list, tests):
        self.assertEqual(len(test_list), len(tests))
        for t1, t2 in zip(test_list, tests):
            if type(t2) is tuple:
                name, test_cases = t2
                self.assertEqual(t1.name, name)
                self.assertEqual(t1._test_cases, list(test_cases))
            else:
                self.assertEqual(t1.name, t2)
示例#9
0
 def setUp(self):
     self.simulator_if = 'simulator_if'
     self.configuration = TestConfiguration()
     self.test_scanner = TestScanner(self.simulator_if, self.configuration)
     self.output_path = join(dirname(__file__), "test_scanner_out")
     renew_path(self.output_path)
示例#10
0
class TestTestScanner(unittest.TestCase):
    """
    Tests the test scanner
    """

    def setUp(self):
        self.simulator_if = 'simulator_if'
        self.configuration = TestConfiguration()
        self.test_scanner = TestScanner(self.simulator_if, self.configuration)
        self.output_path = join(dirname(__file__), "test_scanner_out")
        renew_path(self.output_path)

    def tearDown(self):
        if exists(self.output_path):
            rmtree(self.output_path)

    def test_that_no_tests_are_created(self):
        project = ProjectStub()
        tests = self.test_scanner.from_project(project)
        self.assertEqual(len(tests), 0)

    def test_that_single_vhdl_test_is_created(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        ent = lib.add_entity("tb_entity")
        ent.set_contents("")
        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests, ["lib.tb_entity"])

    def test_that_single_verilog_test_is_created(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        module = lib.add_module("tb_module")
        module.set_contents("")
        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests, ["lib.tb_module"])

    def test_that_tests_are_filtered(self):
        project = ProjectStub()
        lib = project.add_library("lib")

        tb1 = lib.add_entity("tb_entity")
        tb1.set_contents("")

        tb2 = lib.add_entity("tb_entity2")
        tb2.set_contents("")

        ent = lib.add_entity("entity_tb")
        ent.set_contents("")

        ent2 = lib.add_entity("entity2")
        ent2.set_contents("")

        tests = self.test_scanner.from_project(project, entity_filter=tb_filter)
        self.assert_has_tests(tests,
                              ["lib.entity_tb",
                               "lib.tb_entity",
                               "lib.tb_entity2"])

    def test_that_two_tests_are_created_from_two_architectures(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        ent = lib.add_entity("tb_entity")
        ent.set_contents("")

        arch2 = ent.add_architecture("arch2")
        arch2.set_contents("")

        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests,
                              ["lib.tb_entity.arch",
                               "lib.tb_entity.arch2"])

    def test_create_tests_with_runner_cfg_generic(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        ent = lib.add_entity("tb_entity",
                             generic_names=["runner_cfg"])

        ent.set_contents('''\
if run("Test_1")
--if run("Test_2")
if run("Test_3")
''')

        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests,
                              ["lib.tb_entity.Test_1",
                               "lib.tb_entity.Test_3"])

    @mock.patch("vunit.test_scanner.LOGGER")
    def test_duplicate_tests_cause_error(self, mock_logger):
        project = ProjectStub()
        lib = project.add_library("lib")
        ent = lib.add_entity("tb_entity",
                             generic_names=["runner_cfg"])

        ent.set_contents('''\
if run("Test_1")
--if run("Test_1")
if run("Test_3")
if run("Test_2")
if run("Test_3")
if run("Test_3")
if run("Test_2")
''')

        self.assertRaises(TestScannerError, self.test_scanner.from_project, project)

        error_calls = mock_logger.error.call_args_list
        self.assertEqual(len(error_calls), 2)
        call0_args = error_calls[0][0]
        self.assertIn("Test_3", call0_args)
        self.assertIn(ent.file_name, call0_args)

        call1_args = error_calls[1][0]
        self.assertIn("Test_2", call1_args)
        self.assertIn(ent.file_name, call1_args)

    @mock.patch("vunit.test_scanner.LOGGER")
    def test_warning_on_configuration_of_non_existent_test(self, mock_logger):
        project = ProjectStub()
        lib = project.add_library("lib")
        ent = lib.add_entity("tb_entity",
                             generic_names=["runner_cfg", "name"])

        ent.set_contents('if run("Test")')

        test_scope = create_scope("lib", "tb_entity", "Test")
        self.configuration.set_generic("name", "value",
                                       scope=test_scope)

        test_1_scope = create_scope("lib", "tb_entity", "No test 1")
        self.configuration.add_config(scope=test_1_scope,
                                      name="",
                                      generics=dict())

        test_2_scope = create_scope("lib", "tb_entity", "No test 2")
        self.configuration.set_generic("name", "value",
                                       scope=test_2_scope)

        tests = self.test_scanner.from_project(project)

        warning_calls = mock_logger.warning.call_args_list
        self.assertEqual(len(warning_calls), 2)
        call_args0 = warning_calls[0][0]
        call_args1 = warning_calls[1][0]
        self.assertIn(dotjoin(*test_1_scope), call_args0)
        self.assertIn(dotjoin(*test_2_scope), call_args1)
        self.assert_has_tests(tests,
                              ["lib.tb_entity.Test"])

    @mock.patch("vunit.test_scanner.LOGGER")
    def test_warning_on_configuration_of_individual_test_with_same_sim(self, mock_logger):
        project = ProjectStub()
        lib = project.add_library("lib")
        ent = lib.add_entity("tb_entity",
                             generic_names=["runner_cfg"])

        ent.set_contents('''\
if run("Test 1")
if run("Test 2")
-- vunit_pragma run_all_in_same_sim
''')

        test_scope = create_scope("lib", "tb_entity", "Test 1")
        self.configuration.set_generic("name", "value", scope=test_scope)
        tests = self.test_scanner.from_project(project)

        warning_calls = mock_logger.warning.call_args_list
        self.assertEqual(len(warning_calls), 1)
        call_args = warning_calls[0][0]
        self.assertIn(1, call_args)
        self.assertIn("lib.tb_entity", call_args)
        self.assert_has_tests(tests,
                              [("lib.tb_entity", ("lib.tb_entity.Test 1", "lib.tb_entity.Test 2"))])

    def test_create_default_test_with_runner_cfg_generic(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        ent = lib.add_entity("tb_entity",
                             generic_names=["runner_cfg"])

        ent.set_contents('')

        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests,
                              ["lib.tb_entity"])

    def test_that_pragma_run_in_same_simulation_works(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        ent = lib.add_entity("tb_entity",
                             generic_names=["runner_cfg"])

        ent.set_contents('''\
-- vunit_pragma run_all_in_same_sim
if run("Test_1")
if run("Test_2")
--if run("Test_3")
''')

        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests,
                              [("lib.tb_entity", ("lib.tb_entity.Test_1", "lib.tb_entity.Test_2"))])

    def test_adds_tb_path_generic(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        with_path = lib.add_entity("tb_entity_with_tb_path",
                                   generic_names=["tb_path"])
        with_path.set_contents("")

        without_path = lib.add_entity("tb_entity_without_tb_path")
        without_path.set_contents("")

        tests = self.test_scanner.from_project(project)

        with_path_generics = find_generics(tests, "lib.tb_entity_with_tb_path")
        without_path_generics = find_generics(tests, "lib.tb_entity_without_tb_path")
        self.assertEqual(with_path_generics["tb_path"], (out() + "/").replace("\\", "/"))
        self.assertNotIn("tb_path", without_path_generics)

    @mock.patch("vunit.test_scanner.LOGGER")
    def test_warning_on_non_overrriden_tb_path(self, mock_logger):
        project = ProjectStub()
        lib = project.add_library("lib")

        ent = lib.add_entity("tb_entity",
                             generic_names=["tb_path"])
        ent.set_contents("")

        tb_path_non_overriden_value = "foo"
        self.configuration.set_generic("tb_path", tb_path_non_overriden_value)
        tests = self.test_scanner.from_project(project)

        warning_calls = mock_logger.warning.call_args_list
        tb_path_value = (out() + "/").replace("\\", "/")
        self.assertEqual(len(warning_calls), 1)
        call_args = warning_calls[0][0]
        self.assertIn("lib.tb_entity", call_args)
        self.assertIn(tb_path_non_overriden_value, call_args)
        self.assertIn(tb_path_value, call_args)
        generics = find_generics(tests, "lib.tb_entity")
        self.assertEqual(generics["tb_path"], tb_path_value)

    @mock.patch("vunit.test_scanner.LOGGER")
    def test_warning_on_setting_missing_generic(self, mock_logger):
        project = ProjectStub()
        lib = project.add_library("lib")

        ent = lib.add_entity("tb_entity",
                             generic_names=[""])
        ent.set_contents("")
        self.configuration.set_generic("name123", "value123")
        self.test_scanner.from_project(project)
        warning_calls = mock_logger.warning.call_args_list
        self.assertEqual(len(warning_calls), 1)
        call_args = warning_calls[0][0]
        self.assertIn("lib", call_args)
        self.assertIn("tb_entity", call_args)
        self.assertIn("name123", call_args)
        self.assertIn("value123", call_args)

    def assert_has_tests(self, test_list, tests):
        """
        Asser that the test_list contains tests.
        A test can be either a string to represent a single test or a
        tuple to represent multiple tests within a test suite.
        """
        self.assertEqual(len(test_list), len(tests))
        for test1, test2 in zip(test_list, tests):
            if isinstance(test2, tuple):
                name, test_cases = test2
                self.assertEqual(test1.name, name)
                self.assertEqual(test1.test_cases, list(test_cases))
            else:
                self.assertEqual(test1.name, test2)
示例#11
0
 def setUp(self):
     self.simulator_if = 'simulator_if'
     self.configuration = TestConfiguration()
     self.test_scanner = TestScanner(self.simulator_if, self.configuration)
     self.output_path = join(dirname(__file__), "test_scanner_out")
     renew_path(self.output_path)
示例#12
0
class TestTestScanner(unittest.TestCase):
    """
    Tests the test scanner
    """

    def setUp(self):
        self.simulator_if = 'simulator_if'
        self.configuration = TestConfiguration()
        self.test_scanner = TestScanner(self.simulator_if, self.configuration)
        self.output_path = join(dirname(__file__), "test_scanner_out")
        renew_path(self.output_path)

    def tearDown(self):
        if exists(self.output_path):
            rmtree(self.output_path)

    def test_that_no_tests_are_created(self):
        project = ProjectStub()
        tests = self.test_scanner.from_project(project)
        self.assertEqual(len(tests), 0)

    def test_that_single_vhdl_test_is_created(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        lib.add_entity("tb_entity")
        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests, ["lib.tb_entity.all"])

    def test_that_single_verilog_test_is_created(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        lib.add_module("tb_module")
        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests, ["lib.tb_module.all"])

    def test_runner_cfg_creates_tests_from_entity(self):
        project = ProjectStub()
        lib = project.add_library("lib")

        lib.add_entity("entity_ok", generic_names=["runner_cfg"])
        lib.add_entity("entity_not_ok")

        tests = self.test_scanner.from_project(project, entity_filter=tb_filter)
        self.assert_has_tests(tests,
                              ["lib.entity_ok.all"])

    def test_runner_cfg_creates_tests_from_module(self):
        project = ProjectStub()
        lib = project.add_library("lib")

        lib.add_module("module_ok", generic_names=["runner_cfg"])
        lib.add_module("module_not_ok")

        tests = self.test_scanner.from_project(project, entity_filter=tb_filter)
        self.assert_has_tests(tests,
                              ["lib.module_ok.all"])

    def test_warning_on_missing_runner_cfg_when_matching_tb_pattern(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        module = lib.add_module("tb_module_not_ok")

        with mock.patch("vunit.test_scanner.LOGGER", autospec=True) as logger:
            tests = self.test_scanner.from_project(project, entity_filter=tb_filter)
            logger.warning.assert_has_calls([
                mock.call('%s %s matches testbench name regex %s '
                          'but has no %s runner_cfg and will therefore not be run.\n'
                          'in file %s',
                          'Module',
                          'tb_module_not_ok',
                          '(tb_.*)|(.*_tb)',
                          'parameter',
                          module.file_name)])
        self.assert_has_tests(tests, [])

    def test_warning_on_runner_cfg_but_not_matching_tb_pattern(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        entity = lib.add_entity("entity_ok_but_warning", generic_names=["runner_cfg"])

        with mock.patch("vunit.test_scanner.LOGGER", autospec=True) as logger:
            tests = self.test_scanner.from_project(project, entity_filter=tb_filter)
            logger.warning.assert_has_calls([
                mock.call('%s %s has runner_cfg %s but the file name and the %s name does not match regex %s\n'
                          'in file %s',
                          'Entity',
                          'entity_ok_but_warning',
                          'generic',
                          'entity',
                          '(tb_.*)|(.*_tb)',
                          entity.file_name)])
        self.assert_has_tests(tests, ["lib.entity_ok_but_warning.all"])

    def test_that_two_tests_are_created_from_two_architectures(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        ent = lib.add_entity("tb_entity")
        ent.add_architecture("arch2")

        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests,
                              ["lib.tb_entity.arch.all",
                               "lib.tb_entity.arch2.all"])

    def test_create_tests_with_runner_cfg_generic(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        lib.add_entity("tb_entity",
                       generic_names=["runner_cfg"],
                       contents='''\
if run("Test_1")
--if run("Test_2")
if run("Test_3")
''')

        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests,
                              ["lib.tb_entity.Test_1",
                               "lib.tb_entity.Test_3"])

    @mock.patch("vunit.test_scanner.LOGGER")
    def test_duplicate_tests_cause_error(self, mock_logger):
        project = ProjectStub()
        lib = project.add_library("lib")
        ent = lib.add_entity("tb_entity",
                             generic_names=["runner_cfg"],
                             contents='''\
if run("Test_1")
--if run("Test_1")
if run("Test_3")
if run("Test_2")
if run("Test_3")
if run("Test_3")
if run("Test_2")
''')

        self.assertRaises(TestScannerError, self.test_scanner.from_project, project)

        error_calls = mock_logger.error.call_args_list
        self.assertEqual(len(error_calls), 2)
        call0_args = error_calls[0][0]
        self.assertIn("Test_3", call0_args)
        self.assertIn(ent.file_name, call0_args)

        call1_args = error_calls[1][0]
        self.assertIn("Test_2", call1_args)
        self.assertIn(ent.file_name, call1_args)

    @mock.patch("vunit.test_scanner.LOGGER")
    def test_warning_on_configuration_of_non_existent_test(self, mock_logger):
        project = ProjectStub()
        lib = project.add_library("lib")
        lib.add_entity("tb_entity",
                       generic_names=["runner_cfg", "name"],
                       contents='if run("Test")')

        test_scope = create_scope("lib", "tb_entity", "Test")
        self.configuration.set_generic("name", "value",
                                       scope=test_scope)

        test_1_scope = create_scope("lib", "tb_entity", "No test 1")
        self.configuration.add_config(scope=test_1_scope,
                                      name="",
                                      generics=dict())

        test_2_scope = create_scope("lib", "tb_entity", "No test 2")
        self.configuration.set_generic("name", "value",
                                       scope=test_2_scope)

        tests = self.test_scanner.from_project(project)

        warning_calls = mock_logger.warning.call_args_list
        self.assertEqual(len(warning_calls), 2)
        call_args0 = warning_calls[0][0]
        call_args1 = warning_calls[1][0]
        self.assertIn(dotjoin(*test_1_scope), call_args0)
        self.assertIn(dotjoin(*test_2_scope), call_args1)
        self.assert_has_tests(tests,
                              ["lib.tb_entity.Test"])

    @mock.patch("vunit.test_scanner.LOGGER")
    def test_warning_on_configuration_of_individual_test_with_same_sim(self, mock_logger):
        project = ProjectStub()
        lib = project.add_library("lib")
        lib.add_entity("tb_entity",
                       generic_names=["runner_cfg"],
                       contents='''\
if run("Test 1")
if run("Test 2")
-- vunit_pragma run_all_in_same_sim
''')

        test_scope = create_scope("lib", "tb_entity", "Test 1")
        self.configuration.set_generic("name", "value", scope=test_scope)
        tests = self.test_scanner.from_project(project)

        warning_calls = mock_logger.warning.call_args_list
        self.assertEqual(len(warning_calls), 1)
        call_args = warning_calls[0][0]
        self.assertIn(1, call_args)
        self.assertIn("lib.tb_entity", call_args)
        self.assert_has_tests(tests,
                              [("lib.tb_entity", ("lib.tb_entity.Test 1", "lib.tb_entity.Test 2"))])

    def test_create_default_test_with_runner_cfg_generic(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        lib.add_entity("tb_entity",
                       generic_names=["runner_cfg"])

        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests,
                              ["lib.tb_entity.all"])

    def test_does_not_add_all_suffix_with_named_configurations(self):

        def helper(config_name, suffix):
            """
            Add config with name and check that the test has the given suffix
            """
            project = ProjectStub()
            lib = project.add_library("lib")
            lib.add_entity("tb_entity",
                           generic_names=["runner_cfg"])
            self.configuration = TestConfiguration()
            self.test_scanner = TestScanner(self.simulator_if, self.configuration)
            self.configuration.add_config(scope=create_scope("lib", "tb_entity"),
                                          name=config_name,
                                          generics=dict())
            tests = self.test_scanner.from_project(project)
            self.assert_has_tests(tests,
                                  ["lib.tb_entity" + suffix])
        helper("config", ".config")
        helper("", ".all")
        helper(None, ".all")

    def test_that_pragma_run_in_same_simulation_works(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        lib.add_entity("tb_entity",
                       generic_names=["runner_cfg"],
                       contents='''\
-- vunit_pragma run_all_in_same_sim
if run("Test_1")
if run("Test_2")
--if run("Test_3")
''')

        tests = self.test_scanner.from_project(project)
        self.assert_has_tests(tests,
                              [("lib.tb_entity", ("lib.tb_entity.Test_1", "lib.tb_entity.Test_2"))])

    def test_adds_tb_path_generic(self):
        project = ProjectStub()
        lib = project.add_library("lib")
        lib.add_entity("tb_entity_with_tb_path",
                       generic_names=["tb_path"])

        lib.add_entity("tb_entity_without_tb_path")

        tests = self.test_scanner.from_project(project)

        with_path_generics = find_generics(tests, "lib.tb_entity_with_tb_path.all")
        without_path_generics = find_generics(tests, "lib.tb_entity_without_tb_path.all")
        self.assertEqual(with_path_generics["tb_path"], (out() + "/").replace("\\", "/"))
        self.assertNotIn("tb_path", without_path_generics)

    @mock.patch("vunit.test_scanner.LOGGER")
    def test_warning_on_non_overrriden_tb_path(self, mock_logger):
        project = ProjectStub()
        lib = project.add_library("lib")

        lib.add_entity("tb_entity",
                       generic_names=["tb_path"])

        tb_path_non_overriden_value = "foo"
        self.configuration.set_generic("tb_path", tb_path_non_overriden_value)
        tests = self.test_scanner.from_project(project)

        warning_calls = mock_logger.warning.call_args_list
        tb_path_value = (out() + "/").replace("\\", "/")
        self.assertEqual(len(warning_calls), 1)
        call_args = warning_calls[0][0]
        self.assertIn("lib.tb_entity", call_args)
        self.assertIn(tb_path_non_overriden_value, call_args)
        self.assertIn(tb_path_value, call_args)
        generics = find_generics(tests, "lib.tb_entity.all")
        self.assertEqual(generics["tb_path"], tb_path_value)

    @mock.patch("vunit.test_scanner.LOGGER")
    def test_warning_on_setting_missing_generic(self, mock_logger):
        project = ProjectStub()
        lib = project.add_library("lib")

        lib.add_entity("tb_entity",
                       generic_names=[""])
        self.configuration.set_generic("name123", "value123")
        self.test_scanner.from_project(project)
        warning_calls = mock_logger.warning.call_args_list
        self.assertEqual(len(warning_calls), 1)
        call_args = warning_calls[0][0]
        self.assertIn("lib", call_args)
        self.assertIn("tb_entity", call_args)
        self.assertIn("name123", call_args)
        self.assertIn("value123", call_args)

    def assert_has_tests(self, test_list, tests):
        """
        Asser that the test_list contains tests.
        A test can be either a string to represent a single test or a
        tuple to represent multiple tests within a test suite.
        """
        self.assertEqual(len(test_list), len(tests))
        for test1, test2 in zip(test_list, sorted(tests)):
            if isinstance(test2, tuple):
                name, test_cases = test2
                self.assertEqual(test1.name, name)
                self.assertEqual(test1.test_cases, list(test_cases))
            else:
                self.assertEqual(test1.name, test2)