Coverage for tsfpga/vivado/test/test_ip_cores.py: 100%
93 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-01 20:51 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-01 20:51 +0000
1# --------------------------------------------------------------------------------------------------
2# Copyright (c) Lukas Vik. All rights reserved.
3#
4# This file is part of the tsfpga project, a project platform for modern FPGA development.
5# https://tsfpga.com
6# https://github.com/tsfpga/tsfpga
7# --------------------------------------------------------------------------------------------------
9from unittest.mock import MagicMock, patch
11import pytest
13from tsfpga.ip_core_file import IpCoreFile
14from tsfpga.module import BaseModule, get_modules
15from tsfpga.system_utils import create_file, delete
16from tsfpga.vivado.ip_cores import VivadoIpCores
19def test_get_ip_core_files_is_called_with_the_correct_arguments(tmp_path):
20 modules = [MagicMock(spec=BaseModule)]
22 with patch("tsfpga.vivado.ip_cores.VivadoIpCoreProject.create", autospec=True):
23 VivadoIpCores(modules, tmp_path, part_name="test_part")
25 modules[0].get_ip_core_files.assert_called_once_with(generics={}, part="test_part")
28def test_system_call_to_vivado_failing_should_raise_exception(tmp_path):
29 project = VivadoIpCores(modules=[], output_path=tmp_path, part_name="test_part")
31 with patch("tsfpga.vivado.ip_cores.VivadoIpCoreProject.create", autospec=True) as create:
32 create.return_value = False
34 with pytest.raises(RuntimeError) as exception_info:
35 project.create_vivado_project_if_needed()
37 assert str(exception_info.value) == "Failed to create Vivado IP core project"
40@pytest.fixture
41def ip_cores_test(tmp_path):
42 class IpCoresTest:
43 def __init__(self):
44 self.project_folder = tmp_path / "ip_project"
45 self.modules_folder = tmp_path / "modules"
47 self.apa_tcl = create_file(self.modules_folder / "apa" / "ip_cores" / "apa.tcl", "apa")
48 self.hest_tcl = create_file(
49 self.modules_folder / "hest" / "ip_cores" / "hest.tcl", "hest"
50 )
52 modules = get_modules(self.modules_folder)
53 self.vivado_ip_cores = VivadoIpCores(modules, self.project_folder, part_name="-")
55 # Create initial hash and (empty) compile order file
56 self.vivado_ip_cores._save_hash() # noqa: SLF001
57 self.create_compile_order_file()
59 def create_compile_order_file(self):
60 create_file(self.vivado_ip_cores.compile_order_file)
62 return IpCoresTest()
65@patch("tsfpga.vivado.ip_cores.VivadoIpCoreProject.create", autospec=True)
66def test_should_not_recreate(create, ip_cores_test):
67 assert not ip_cores_test.vivado_ip_cores.create_vivado_project_if_needed()
68 create.assert_not_called()
71@patch("tsfpga.vivado.ip_cores.VivadoIpCoreProject.create", autospec=True)
72def test_should_recreate_if_compile_order_file_is_missing(create, ip_cores_test):
73 delete(ip_cores_test.vivado_ip_cores.compile_order_file)
74 assert ip_cores_test.vivado_ip_cores.create_vivado_project_if_needed()
75 create.assert_called_once()
78@patch("tsfpga.vivado.ip_cores.VivadoIpCoreProject.create", autospec=True)
79def test_should_recreate_if_hash_file_is_missing(create, ip_cores_test):
80 delete(ip_cores_test.vivado_ip_cores._hash_file) # noqa: SLF001
81 assert ip_cores_test.vivado_ip_cores.create_vivado_project_if_needed()
82 create.assert_called_once()
85@patch("tsfpga.vivado.ip_cores.VivadoIpCoreProject.create", autospec=True)
86def test_should_not_recreate_if_nothing_is_changed(create, ip_cores_test):
87 # This test shows that the pattern used in the upcoming tests:
88 # change something -> get modules -> create new VivadoIpCores object
89 # should not result in a recreate unless we actually change something.
90 modules = get_modules(ip_cores_test.modules_folder)
91 vivado_ip_cores = VivadoIpCores(modules, ip_cores_test.project_folder, part_name="-")
93 assert not vivado_ip_cores.create_vivado_project_if_needed()
94 create.assert_not_called()
97@patch("tsfpga.vivado.ip_cores.VivadoIpCoreProject.create", autospec=True)
98def test_should_recreate_if_ip_core_file_is_added(create, ip_cores_test):
99 create_file(ip_cores_test.modules_folder / "zebra" / "ip_cores" / "zebra.tcl", "zebra")
100 modules = get_modules(ip_cores_test.modules_folder)
101 vivado_ip_cores = VivadoIpCores(modules, ip_cores_test.project_folder, part_name="-")
103 assert vivado_ip_cores.create_vivado_project_if_needed()
104 create.assert_called_once()
107@patch("tsfpga.vivado.ip_cores.VivadoIpCoreProject.create", autospec=True)
108def test_should_recreate_if_ip_core_file_is_removed(create, ip_cores_test):
109 delete(ip_cores_test.hest_tcl)
110 modules = get_modules(ip_cores_test.modules_folder)
111 vivado_ip_cores = VivadoIpCores(modules, ip_cores_test.project_folder, part_name="-")
113 assert vivado_ip_cores.create_vivado_project_if_needed()
114 create.assert_called_once()
117@patch("tsfpga.vivado.ip_cores.VivadoIpCoreProject.create", autospec=True)
118def test_should_recreate_if_ip_core_file_is_changed(create, ip_cores_test):
119 create_file(ip_cores_test.apa_tcl, "blaha blaha")
120 modules = get_modules(ip_cores_test.modules_folder)
121 vivado_ip_cores = VivadoIpCores(modules, ip_cores_test.project_folder, part_name="-")
123 assert vivado_ip_cores.create_vivado_project_if_needed()
124 create.assert_called_once()
127@patch("tsfpga.vivado.ip_cores.VivadoIpCoreProject.create", autospec=True)
128def test_ip_core_variables(create, ip_cores_test):
129 modules = [MagicMock(spec=BaseModule)]
131 modules[0].get_ip_core_files.return_value = [IpCoreFile(path=ip_cores_test.apa_tcl)]
133 vivado_ip_cores = VivadoIpCores(modules, ip_cores_test.project_folder, part_name="-")
135 assert vivado_ip_cores.create_vivado_project_if_needed()
136 assert create.call_count == 1
137 ip_cores_test.create_compile_order_file()
139 # Should not recreate until we change something
140 assert not vivado_ip_cores.create_vivado_project_if_needed()
141 assert create.call_count == 1
143 # Adding variables should recreate
144 modules[0].get_ip_core_files.return_value = [
145 IpCoreFile(path=ip_cores_test.apa_tcl, zz="123", aa="456")
146 ]
148 vivado_ip_cores = VivadoIpCores(modules, ip_cores_test.project_folder, part_name="-")
150 assert vivado_ip_cores.create_vivado_project_if_needed()
151 assert create.call_count == 2
152 ip_cores_test.create_compile_order_file()
154 # Changing order of variables should not recreate
155 modules[0].get_ip_core_files.return_value = [
156 IpCoreFile(path=ip_cores_test.apa_tcl, aa="456", zz="123")
157 ]
159 vivado_ip_cores = VivadoIpCores(modules, ip_cores_test.project_folder, part_name="-")
161 assert not vivado_ip_cores.create_vivado_project_if_needed()
162 assert create.call_count == 2