class TestTestConfiguration(unittest.TestCase): """ Test the global test bench configuration """ def setUp(self): self.cfg = TestConfiguration() self.output_path = out() renew_path(self.output_path) def test_has_default_configuration(self): scope = create_scope("lib", "tb_entity") self.assertEqual(self.cfg.get_configurations(scope), [cfg()]) def test_set_generic(self): scope = create_scope("lib", "tb_entity") self.assertEqual(self.cfg.get_configurations(scope), [cfg()]) self.cfg.set_generic("global_generic", "global", scope=create_scope()) self.assertEqual(self.cfg.get_configurations(scope), [cfg(generics={"global_generic": "global"})]) self.cfg.set_generic("global_generic", "library", scope=create_scope("lib")) self.assertEqual(self.cfg.get_configurations(scope), [cfg(generics={"global_generic": "library"})]) self.cfg.set_generic("global_generic", "entity", scope=create_scope("lib", "tb_entity")) self.assertEqual(self.cfg.get_configurations(scope), [cfg(generics={"global_generic": "entity"})]) def test_set_pli(self): scope = create_scope("lib", "tb_entity") self.assertEqual(self.cfg.get_configurations(scope), [cfg("")]) self.cfg.set_pli(["libglobal.so"], scope=create_scope()) self.cfg.set_pli(["libfoo.so"], scope=create_scope("lib2")) self.assertEqual(self.cfg.get_configurations(scope), [cfg(pli=["libglobal.so"])]) self.cfg.set_pli(["libfoo.so"], scope=create_scope("lib")) self.assertEqual(self.cfg.get_configurations(scope), [cfg(pli=["libfoo.so"])]) self.cfg.set_pli(["libfoo2.so"], scope=create_scope("lib", "tb_entity")) self.assertEqual(self.cfg.get_configurations(scope), [cfg(pli=["libfoo2.so"])]) def test_add_config(self): for value in range(1, 3): self.cfg.add_config(scope=create_scope("lib", "tb_entity"), name="value=%i" % value, generics=dict(value=value, global_value="local value")) self.cfg.add_config(scope=create_scope("lib", "tb_entity", "configured test"), name="specific_test_config", generics=dict()) # Local value should take precedence self.cfg.set_generic("global_value", "global value") self.assertEqual(self.cfg.get_configurations(create_scope("lib", "tb_entity")), [cfg("value=1", generics={"value": 1, "global_value": "local value"}), cfg("value=2", generics={"value": 2, "global_value": "local value"})]) self.assertEqual(self.cfg.get_configurations(create_scope("lib", "tb_entity", "test")), [cfg("value=1", generics={"value": 1, "global_value": "local value"}), cfg("value=2", generics={"value": 2, "global_value": "local value"})]) self.assertEqual(self.cfg.get_configurations(create_scope("lib", "tb_entity", "configured test")), [cfg("specific_test_config", dict(global_value="global value"))]) def test_disable_ieee_warnings(self): lib_scope = create_scope("lib") ent_scope = create_scope("lib", "entity") self.assertEqual(self.cfg.get_configurations(lib_scope), [cfg(disable_ieee_warnings=False)]) self.assertEqual(self.cfg.get_configurations(ent_scope), [cfg(disable_ieee_warnings=False)]) self.cfg.disable_ieee_warnings(ent_scope) self.assertEqual(self.cfg.get_configurations(lib_scope), [cfg(disable_ieee_warnings=False)]) self.assertEqual(self.cfg.get_configurations(ent_scope), [cfg(disable_ieee_warnings=True)]) self.cfg.disable_ieee_warnings(lib_scope) self.assertEqual(self.cfg.get_configurations(lib_scope), [cfg(disable_ieee_warnings=True)]) self.assertEqual(self.cfg.get_configurations(ent_scope), [cfg(disable_ieee_warnings=True)]) def test_more_specific_configurations(self): self.cfg.set_generic("name", "value", scope=create_scope("lib", "entity3")) self.cfg.set_generic("name", "value", scope=create_scope("lib", "entity", "test")) self.cfg.disable_ieee_warnings(scope=create_scope("lib", "entity_ieee", "test")) self.cfg.add_config(name="name", generics=dict(), scope=create_scope("lib", "entity2", "test")) self.cfg.set_sim_option("vsim_extra_args", "", scope=create_scope("lib", "entity4", "test")) self.assertEqual(self.cfg.more_specific_configurations(create_scope("lib", "entity")), [create_scope("lib", "entity", "test")]) self.assertEqual(self.cfg.more_specific_configurations(create_scope("lib", "entity2")), [create_scope("lib", "entity2", "test")]) self.assertEqual(self.cfg.more_specific_configurations(create_scope("lib", "entity3")), []) self.assertEqual(self.cfg.more_specific_configurations(create_scope("lib", "entity4")), [create_scope("lib", "entity4", "test")]) self.assertEqual(self.cfg.more_specific_configurations(create_scope("lib", "entity_ieee")), [create_scope("lib", "entity_ieee", "test")]) def test_no_post_check_when_elaborate_only(self): self.cfg = TestConfiguration(elaborate_only=True) scope = create_scope("lib", "entity") def pre_config(): return True def post_check(): return True self.cfg.add_config(name="name", generics=dict(), pre_config=pre_config, post_check=post_check, scope=scope) self.assertEqual(self.cfg.get_configurations(scope), [cfg("name", pre_config=pre_config, elaborate_only=True)]) def test_config_with_post_check(self): scope = create_scope("lib", "entity") def post_check(): return True self.cfg.add_config(name="name", generics=dict(), post_check=post_check, scope=scope) self.assertEqual(self.cfg.get_configurations(scope), [cfg("name", post_check=post_check)]) def test_config_with_pre_config(self): scope = create_scope("lib", "entity") def pre_config(): return True self.cfg.add_config(name="name", generics=dict(), pre_config=pre_config, scope=scope) self.assertEqual(self.cfg.get_configurations(scope), [cfg("name", pre_config=pre_config)]) def test_sim_options(self): scope = create_scope("lib", "entity") sim_options = {"vsim_extra_args": "-voptargs=+acc"} for name, value in sim_options.items(): self.cfg.set_sim_option(name=name, value=value, scope=scope) self.assertEqual(self.cfg.get_configurations(create_scope("lib")), [cfg()]) self.assertEqual(self.cfg.get_configurations(scope), [cfg(sim_options=sim_options)]) self.assertEqual(self.cfg.get_configurations(create_scope("lib", "entity", "test")), [cfg(sim_options=sim_options)]) def test_fail_on_unknown_sim_option(self): self.assertRaises(ValueError, self.cfg.set_sim_option, "unknown", "value") def test_issue_65(self): self.cfg.set_generic(name="name", value=1, scope=create_scope()) self.cfg.set_sim_option(name="vsim_extra_args", value="-quiet", scope=create_scope()) @staticmethod def write_file(name, contents): with open(name, "w") as fwrite: fwrite.write(contents)
class TestTestConfiguration(unittest.TestCase): def setUp(self): self.cfg = TestConfiguration() self.output_path = out() if exists(self.output_path): rmtree(self.output_path) makedirs(self.output_path) def test_has_default_configuration(self): entity = EntityStub() entity.name = "tb_entity" entity.library_name = "lib" entity.architecture_names = {"arch" : out("arch.vhd")} entity.generic_names = [] self.assertEqual(self.cfg.get_configurations(entity, "arch"), [Configuration("lib.tb_entity")]) def test_set_generic(self): entity = EntityStub() entity.name = "tb_entity" entity.library_name = "lib" entity.architecture_names = {"arch" : out("arch.vhd")} entity.generic_names = ["global_generic"] self.assertEqual(self.cfg.get_configurations(entity, "arch"), [Configuration("lib.tb_entity")]) self.cfg.set_generic("global_generic", False, scope="") self.assertEqual(self.cfg.get_configurations(entity, "arch"), [Configuration("lib.tb_entity", generics={"global_generic" : False})]) self.cfg.set_generic("global_generic", True, scope="lib") self.cfg.set_generic("generic_not_present", True, scope="lib") self.assertEqual(self.cfg.get_configurations(entity, "arch"), [Configuration("lib.tb_entity", generics={"global_generic" : True})]) self.cfg.set_generic("global_generic", None, scope="lib.tb_entity") self.assertEqual(self.cfg.get_configurations(entity, "arch"), [Configuration("lib.tb_entity", generics={"global_generic" : None})]) def test_set_pli(self): entity = EntityStub() entity.name = "tb_entity" entity.library_name = "lib" entity.architecture_names = {"arch" : out("arch.vhd")} entity.generic_names = [] self.assertEqual(self.cfg.get_configurations(entity, "arch"), [Configuration("lib.tb_entity")]) self.cfg.set_pli(["libglobal.so"], scope="") self.cfg.set_pli(["libfoo.so"], scope="lib2") self.assertEqual(self.cfg.get_configurations(entity, "arch"), [Configuration("lib.tb_entity", pli=["libglobal.so"])]) self.cfg.set_pli(["libfoo.so"], scope="lib") self.assertEqual(self.cfg.get_configurations(entity, "arch"), [Configuration("lib.tb_entity", pli=["libfoo.so"])]) self.cfg.set_pli(["libfoo2.so"], scope="lib.tb_entity") self.assertEqual(self.cfg.get_configurations(entity, "arch"), [Configuration("lib.tb_entity", pli=["libfoo2.so"])]) def test_add_config(self): entity = EntityStub() entity.name = "tb_entity" entity.library_name = "lib" entity.architecture_names = {"arch" : out("arch.vhd")} entity.generic_names = ["value", "global_value"] for value in range(1, 3): self.cfg.add_config("lib.tb_entity", name="value=%i" % value, generics=dict(value=value, global_value="local value")) # Local value should take precedence self.cfg.set_generic("global_value", "global value") self.assertEqual(self.cfg.get_configurations(entity, "arch"), [Configuration("lib.tb_entity.value=1", generics={"value" : 1, "global_value" : "local value"}), Configuration("lib.tb_entity.value=2", generics={"value" : 2, "global_value" : "local value"})]) def write_file(self, name, contents): with open(name, "w") as fwrite: fwrite.write(contents)
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)
class TestTestConfiguration(unittest.TestCase): """ Test the global test bench configuration """ def setUp(self): self.cfg = TestConfiguration() self.output_path = out() renew_path(self.output_path) def test_has_default_configuration(self): scope = create_scope("lib", "tb_entity") self.assertEqual(self.cfg.get_configurations(scope), [cfg()]) def test_set_generic(self): scope = create_scope("lib", "tb_entity") self.assertEqual(self.cfg.get_configurations(scope), [cfg()]) self.cfg.set_generic("global_generic", "global", scope=create_scope()) self.assertEqual(self.cfg.get_configurations(scope), [cfg(generics={"global_generic": "global"})]) self.cfg.set_generic("global_generic", "library", scope=create_scope("lib")) self.assertEqual(self.cfg.get_configurations(scope), [cfg(generics={"global_generic": "library"})]) self.cfg.set_generic("global_generic", "entity", scope=create_scope("lib", "tb_entity")) self.assertEqual(self.cfg.get_configurations(scope), [cfg(generics={"global_generic": "entity"})]) def test_set_pli(self): scope = create_scope("lib", "tb_entity") self.assertEqual(self.cfg.get_configurations(scope), [cfg("")]) self.cfg.set_pli(["libglobal.so"], scope=create_scope()) self.cfg.set_pli(["libfoo.so"], scope=create_scope("lib2")) self.assertEqual(self.cfg.get_configurations(scope), [cfg(pli=["libglobal.so"])]) self.cfg.set_pli(["libfoo.so"], scope=create_scope("lib")) self.assertEqual(self.cfg.get_configurations(scope), [cfg(pli=["libfoo.so"])]) self.cfg.set_pli(["libfoo2.so"], scope=create_scope("lib", "tb_entity")) self.assertEqual(self.cfg.get_configurations(scope), [cfg(pli=["libfoo2.so"])]) def test_add_config(self): for value in range(1, 3): self.cfg.add_config(scope=create_scope("lib", "tb_entity"), name="value=%i" % value, generics=dict(value=value, global_value="local value")) self.cfg.add_config(scope=create_scope("lib", "tb_entity", "configured test"), name="specific_test_config", generics=dict()) # Local value should take precedence self.cfg.set_generic("global_value", "global value") self.assertEqual( self.cfg.get_configurations(create_scope("lib", "tb_entity")), [ cfg("value=1", generics={ "value": 1, "global_value": "local value" }), cfg("value=2", generics={ "value": 2, "global_value": "local value" }) ]) self.assertEqual( self.cfg.get_configurations( create_scope("lib", "tb_entity", "test")), [ cfg("value=1", generics={ "value": 1, "global_value": "local value" }), cfg("value=2", generics={ "value": 2, "global_value": "local value" }) ]) self.assertEqual( self.cfg.get_configurations( create_scope("lib", "tb_entity", "configured test")), [cfg("specific_test_config", dict(global_value="global value"))]) def test_disable_ieee_warnings(self): lib_scope = create_scope("lib") ent_scope = create_scope("lib", "entity") self.assertEqual(self.cfg.get_configurations(lib_scope), [cfg(disable_ieee_warnings=False)]) self.assertEqual(self.cfg.get_configurations(ent_scope), [cfg(disable_ieee_warnings=False)]) self.cfg.disable_ieee_warnings(ent_scope) self.assertEqual(self.cfg.get_configurations(lib_scope), [cfg(disable_ieee_warnings=False)]) self.assertEqual(self.cfg.get_configurations(ent_scope), [cfg(disable_ieee_warnings=True)]) self.cfg.disable_ieee_warnings(lib_scope) self.assertEqual(self.cfg.get_configurations(lib_scope), [cfg(disable_ieee_warnings=True)]) self.assertEqual(self.cfg.get_configurations(ent_scope), [cfg(disable_ieee_warnings=True)]) def test_more_specific_configurations(self): self.cfg.set_generic("name", "value", scope=create_scope("lib", "entity3")) self.cfg.set_generic("name", "value", scope=create_scope("lib", "entity", "test")) self.cfg.disable_ieee_warnings( scope=create_scope("lib", "entity_ieee", "test")) self.cfg.add_config(name="name", generics=dict(), scope=create_scope("lib", "entity2", "test")) self.cfg.set_sim_option("ghdl.flags", [], scope=create_scope("lib", "entity4", "test")) self.assertEqual( self.cfg.more_specific_configurations(create_scope( "lib", "entity")), [create_scope("lib", "entity", "test")]) self.assertEqual( self.cfg.more_specific_configurations( create_scope("lib", "entity2")), [create_scope("lib", "entity2", "test")]) self.assertEqual( self.cfg.more_specific_configurations( create_scope("lib", "entity3")), []) self.assertEqual( self.cfg.more_specific_configurations( create_scope("lib", "entity4")), [create_scope("lib", "entity4", "test")]) self.assertEqual( self.cfg.more_specific_configurations( create_scope("lib", "entity_ieee")), [create_scope("lib", "entity_ieee", "test")]) def test_config_with_post_check(self): scope = create_scope("lib", "entity") def post_check(): return True self.cfg.add_config(name="name", generics=dict(), post_check=post_check, scope=scope) self.assertEqual(self.cfg.get_configurations(scope), [cfg("name", post_check=post_check)]) def test_config_with_pre_config(self): scope = create_scope("lib", "entity") def pre_config(): return True self.cfg.add_config(name="name", generics=dict(), pre_config=pre_config, scope=scope) self.assertEqual(self.cfg.get_configurations(scope), [cfg("name", pre_config=pre_config)]) def test_sim_options(self): scope = create_scope("lib", "entity") sim_options = {"modelsim.vsim_flags": "-voptargs=+acc"} for name, value in sim_options.items(): self.cfg.set_sim_option(name=name, value=value, scope=scope) self.assertEqual(self.cfg.get_configurations(create_scope("lib")), [cfg()]) self.assertEqual(self.cfg.get_configurations(scope), [cfg(sim_options=sim_options)]) self.assertEqual( self.cfg.get_configurations(create_scope("lib", "entity", "test")), [cfg(sim_options=sim_options)]) def test_fail_on_unknown_sim_option(self): self.assertRaises(ValueError, self.cfg.set_sim_option, "unknown", "value") def test_issue_65(self): self.cfg.set_generic(name="name", value=1, scope=create_scope()) self.cfg.set_sim_option(name="modelsim.vsim_flags", value="-quiet", scope=create_scope()) @staticmethod def write_file(name, contents): with open(name, "w") as fwrite: fwrite.write(contents)
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)