Coverage for tsfpga/test/test_build_project_list.py: 100%
101 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-21 20:51 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-02-21 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
11import pytest
13from tsfpga.build_project_list import BuildProjectList
14from tsfpga.module import BaseModule
15from tsfpga.system_utils import create_directory
16from tsfpga.vivado.project import BuildResult, VivadoProject
19@pytest.fixture
20def build_project_list_test():
21 class TestBuildProjectList:
22 @staticmethod
23 def _get_mocks(name, is_netlist_build):
24 project = MagicMock(spec=VivadoProject)
25 project.name = name
26 project.__str__.return_value = f"MockProject {name}"
27 project.is_netlist_build = is_netlist_build
29 module = MagicMock(spec=BaseModule)
30 module.name = name
31 module.get_build_projects.return_value = [project]
33 return module, project
35 def __init__(self):
36 self.module_one, self.project_one = self._get_mocks("one", False)
37 self.module_two, self.project_two = self._get_mocks("two", False)
39 self.module_three, self.project_three = self._get_mocks("three", True)
40 self.module_four, self.project_four = self._get_mocks("four", True)
42 self.modules = [self.module_one, self.module_two, self.module_three, self.module_four]
44 return TestBuildProjectList()
47def test_can_list_without_error(build_project_list_test):
48 list_str = str(BuildProjectList(build_project_list_test.modules, project_filters=[]))
49 assert "one" in list_str
50 assert "two" in list_str
53def test_project_filtering(build_project_list_test):
54 project_list = BuildProjectList(build_project_list_test.modules, project_filters=[])
55 assert len(project_list.projects) == 2
56 assert build_project_list_test.project_one in project_list.projects
57 assert build_project_list_test.project_two in project_list.projects
59 project_list = BuildProjectList(
60 build_project_list_test.modules, project_filters=["apa", "*ne", "three", "four"]
61 )
62 assert len(project_list.projects) == 1
63 assert build_project_list_test.project_one in project_list.projects
65 project_list = BuildProjectList(
66 build_project_list_test.modules, project_filters=["one", "one", "on*"]
67 )
68 assert len(project_list.projects) == 1
69 assert build_project_list_test.project_one in project_list.projects
71 project_list = BuildProjectList(
72 build_project_list_test.modules, project_filters=[], include_netlist_not_top_builds=True
73 )
74 assert len(project_list.projects) == 2
75 assert build_project_list_test.project_three in project_list.projects
76 assert build_project_list_test.project_four in project_list.projects
78 project_list = BuildProjectList(
79 build_project_list_test.modules,
80 include_netlist_not_top_builds=True,
81 project_filters=["apa", "one", "two", "thr*"],
82 )
83 assert len(project_list.projects) == 1
84 assert build_project_list_test.project_three in project_list.projects
87def test_create(build_project_list_test, tmp_path):
88 project_list = BuildProjectList(build_project_list_test.modules, project_filters=["one", "two"])
89 assert project_list.create(
90 projects_path=tmp_path / "projects_path",
91 num_parallel_builds=2,
92 ip_cache_path=tmp_path / "ip_cache_path",
93 )
95 build_project_list_test.project_one.create.assert_called_once_with(
96 project_path=tmp_path / "projects_path" / "one" / "project",
97 ip_cache_path=tmp_path / "ip_cache_path",
98 )
100 build_project_list_test.project_two.create.assert_called_once_with(
101 project_path=tmp_path / "projects_path" / "two" / "project",
102 ip_cache_path=tmp_path / "ip_cache_path",
103 )
105 build_project_list_test.project_three.create.assert_not_called()
106 build_project_list_test.project_four.create.assert_not_called()
109def test_create_unless_exists(build_project_list_test, tmp_path):
110 project_list = BuildProjectList(build_project_list_test.modules, project_filters=["one"])
111 assert project_list.create_unless_exists(
112 projects_path=tmp_path / "projects_path",
113 num_parallel_builds=2,
114 ip_cache_path=tmp_path / "ip_cache_path",
115 )
117 build_project_list_test.project_one.create.assert_called_once_with(
118 project_path=tmp_path / "projects_path" / "one" / "project",
119 ip_cache_path=tmp_path / "ip_cache_path",
120 )
122 # Create project file manually
123 create_directory(tmp_path / "projects_path" / "one" / "project")
124 (tmp_path / "projects_path" / "one" / "project" / "one.xpr").write_text("")
126 assert project_list.create_unless_exists(
127 projects_path=tmp_path / "projects_path",
128 num_parallel_builds=2,
129 ip_cache_path=tmp_path / "ip_cache_path",
130 )
132 # Still only called once after second create_unless_exists()
133 build_project_list_test.project_one.create.assert_called_once()
135 build_project_list_test.project_two.create.assert_not_called()
136 build_project_list_test.project_three.create.assert_not_called()
137 build_project_list_test.project_four.create.assert_not_called()
140def test_build(build_project_list_test, tmp_path):
141 project_list = BuildProjectList(build_project_list_test.modules, project_filters=["one"])
142 assert project_list.build(
143 projects_path=tmp_path / "projects_path",
144 num_parallel_builds=2,
145 num_threads_per_build=4,
146 other_build_argument=True,
147 )
149 build_project_list_test.project_one.build.assert_called_once_with(
150 project_path=tmp_path / "projects_path" / "one" / "project",
151 output_path=tmp_path / "projects_path" / "one",
152 num_threads=4,
153 other_build_argument=True,
154 )
157def test_build_fail_should_return_false(build_project_list_test, tmp_path):
158 project_list = BuildProjectList(build_project_list_test.modules, project_filters=["one"])
159 build_project_list_test.project_one.build.return_value = MagicMock(spec=BuildResult)
160 build_project_list_test.project_one.build.return_value.success = False
162 assert not project_list.build(
163 projects_path=tmp_path / "projects_path",
164 num_parallel_builds=2,
165 num_threads_per_build=4,
166 other_build_argument=True,
167 )
170def test_build_with_output_path(build_project_list_test, tmp_path):
171 project_list = BuildProjectList(build_project_list_test.modules, project_filters=["one"])
172 assert project_list.build(
173 projects_path=tmp_path / "projects_path",
174 num_parallel_builds=2,
175 num_threads_per_build=4,
176 output_path=tmp_path / "output_path",
177 )
179 build_project_list_test.project_one.build.assert_called_once_with(
180 project_path=tmp_path / "projects_path" / "one" / "project",
181 output_path=tmp_path / "output_path" / "one",
182 num_threads=4,
183 )
186def test_build_with_collect_artifacts(build_project_list_test, tmp_path):
187 project_list = BuildProjectList(build_project_list_test.modules, project_filters=["one"])
188 collect_artifacts = MagicMock()
189 assert project_list.build(
190 projects_path=tmp_path / "projects_path",
191 num_parallel_builds=2,
192 num_threads_per_build=4,
193 collect_artifacts=collect_artifacts,
194 )
196 collect_artifacts.assert_called_once_with(
197 project=build_project_list_test.project_one,
198 output_path=tmp_path / "projects_path" / "one",
199 )
202def test_build_with_collect_artifacts_and_output_path(build_project_list_test, tmp_path):
203 project_list = BuildProjectList(build_project_list_test.modules, project_filters=["one"])
204 collect_artifacts = MagicMock()
205 assert project_list.build(
206 projects_path=tmp_path / "projects_path",
207 num_parallel_builds=2,
208 num_threads_per_build=4,
209 output_path=tmp_path / "output_path",
210 collect_artifacts=collect_artifacts,
211 )
213 collect_artifacts.assert_called_once_with(
214 project=build_project_list_test.project_one,
215 output_path=tmp_path / "output_path" / "one",
216 )
219def test_build_with_collect_artifacts_return_false_should_fail_build(
220 build_project_list_test, tmp_path
221):
222 project_list = BuildProjectList(build_project_list_test.modules, project_filters=["one"])
223 collect_artifacts = MagicMock()
224 collect_artifacts.return_value = False
225 assert not project_list.build(
226 projects_path=tmp_path / "projects_path",
227 num_parallel_builds=2,
228 num_threads_per_build=4,
229 collect_artifacts=collect_artifacts,
230 )
233def test_open(build_project_list_test, tmp_path):
234 project_list = BuildProjectList(
235 build_project_list_test.modules, project_filters=[], include_netlist_not_top_builds=True
236 )
237 assert project_list.open(projects_path=tmp_path / "projects_path")
239 build_project_list_test.project_three.open.assert_called_once_with(
240 project_path=tmp_path / "projects_path" / "three" / "project"
241 )
242 build_project_list_test.project_four.open.assert_called_once_with(
243 project_path=tmp_path / "projects_path" / "four" / "project"
244 )
245 build_project_list_test.project_one.open.assert_not_called()
246 build_project_list_test.project_two.open.assert_not_called()