Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# -------------------------------------------------------------------------------------------------- 

2# Copyright (c) Lukas Vik. All rights reserved. 

3# 

4# This file is part of the tsfpga project. 

5# https://tsfpga.com 

6# https://gitlab.com/tsfpga/tsfpga 

7# -------------------------------------------------------------------------------------------------- 

8 

9import unittest 

10from unittest.mock import MagicMock 

11import pytest 

12 

13from tsfpga.build_project_list import BuildProjectList 

14from tsfpga.module import BaseModule 

15from tsfpga.system_utils import create_directory 

16from tsfpga.vivado.project import VivadoProject, BuildResult 

17 

18 

19# pylint: disable=too-many-instance-attributes 

20@pytest.mark.usefixtures("fixture_tmp_path") 

21class TestBuildProjectList(unittest.TestCase): 

22 

23 tmp_path = None 

24 

25 @staticmethod 

26 def _get_mocks(name, is_netlist_build): 

27 project = MagicMock(spec=VivadoProject) 

28 project.name = name 

29 project.__str__.return_value = f"MockProject {name}" 

30 project.is_netlist_build = is_netlist_build 

31 

32 module = MagicMock(spec=BaseModule) 

33 module.name = name 

34 module.get_build_projects.return_value = [project] 

35 

36 return module, project 

37 

38 def setUp(self): 

39 self.module_one, self.project_one = self._get_mocks("one", False) 

40 self.module_two, self.project_two = self._get_mocks("two", False) 

41 

42 self.module_three, self.project_three = self._get_mocks("three", True) 

43 self.module_four, self.project_four = self._get_mocks("four", True) 

44 

45 self.modules = [self.module_one, self.module_two, self.module_three, self.module_four] 

46 

47 def test_can_list_without_error(self): 

48 list_str = str(BuildProjectList(self.modules)) 

49 assert "one" in list_str 

50 assert "two" in list_str 

51 

52 def test_project_filtering(self): 

53 project_list = BuildProjectList(self.modules) 

54 assert len(project_list.projects) == 2 

55 assert self.project_one in project_list.projects 

56 assert self.project_two in project_list.projects 

57 

58 project_list = BuildProjectList( 

59 self.modules, project_filters=["apa", "*ne", "three", "four"] 

60 ) 

61 assert len(project_list.projects) == 1 

62 assert self.project_one in project_list.projects 

63 

64 project_list = BuildProjectList(self.modules, include_netlist_not_top_builds=True) 

65 assert len(project_list.projects) == 2 

66 assert self.project_three in project_list.projects 

67 assert self.project_four in project_list.projects 

68 

69 project_list = BuildProjectList( 

70 self.modules, 

71 include_netlist_not_top_builds=True, 

72 project_filters=["apa", "one", "two", "thr*"], 

73 ) 

74 assert len(project_list.projects) == 1 

75 assert self.project_three in project_list.projects 

76 

77 def test_create(self): 

78 project_list = BuildProjectList(self.modules, project_filters=["one", "two"]) 

79 assert project_list.create( 

80 projects_path=self.tmp_path / "projects_path", 

81 num_parallel_builds=2, 

82 ip_cache_path=self.tmp_path / "ip_cache_path", 

83 ) 

84 

85 self.project_one.create.assert_called_once_with( 

86 project_path=self.tmp_path / "projects_path" / "one" / "project", 

87 ip_cache_path=self.tmp_path / "ip_cache_path", 

88 ) 

89 

90 self.project_two.create.assert_called_once_with( 

91 project_path=self.tmp_path / "projects_path" / "two" / "project", 

92 ip_cache_path=self.tmp_path / "ip_cache_path", 

93 ) 

94 

95 self.project_three.create.assert_not_called() 

96 self.project_four.create.assert_not_called() 

97 

98 def test_create_unless_exists(self): 

99 project_list = BuildProjectList(self.modules, project_filters=["one"]) 

100 assert project_list.create_unless_exists( 

101 projects_path=self.tmp_path / "projects_path", 

102 num_parallel_builds=2, 

103 ip_cache_path=self.tmp_path / "ip_cache_path", 

104 ) 

105 

106 self.project_one.create.assert_called_once_with( 

107 project_path=self.tmp_path / "projects_path" / "one" / "project", 

108 ip_cache_path=self.tmp_path / "ip_cache_path", 

109 ) 

110 

111 # Create project file manually 

112 create_directory(self.tmp_path / "projects_path" / "one" / "project") 

113 (self.tmp_path / "projects_path" / "one" / "project" / "one.xpr").write_text("") 

114 

115 assert project_list.create_unless_exists( 

116 projects_path=self.tmp_path / "projects_path", 

117 num_parallel_builds=2, 

118 ip_cache_path=self.tmp_path / "ip_cache_path", 

119 ) 

120 

121 # Still only called once after second create_unless_exists() 

122 self.project_one.create.assert_called_once() 

123 

124 self.project_two.create.assert_not_called() 

125 self.project_three.create.assert_not_called() 

126 self.project_four.create.assert_not_called() 

127 

128 def test_build(self): 

129 project_list = BuildProjectList(self.modules, project_filters=["one"]) 

130 assert project_list.build( 

131 projects_path=self.tmp_path / "projects_path", 

132 num_parallel_builds=2, 

133 num_threads_per_build=4, 

134 other_build_argument=True, 

135 ) 

136 

137 self.project_one.build.assert_called_once_with( 

138 project_path=self.tmp_path / "projects_path" / "one" / "project", 

139 output_path=self.tmp_path / "projects_path" / "one", 

140 num_threads=4, 

141 other_build_argument=True, 

142 ) 

143 

144 def test_build_fail_should_return_false(self): 

145 project_list = BuildProjectList(self.modules, project_filters=["one"]) 

146 self.project_one.build.return_value = MagicMock(spec=BuildResult) 

147 self.project_one.build.return_value.success = False 

148 

149 assert not project_list.build( 

150 projects_path=self.tmp_path / "projects_path", 

151 num_parallel_builds=2, 

152 num_threads_per_build=4, 

153 other_build_argument=True, 

154 ) 

155 

156 def test_build_with_output_path(self): 

157 project_list = BuildProjectList(self.modules, project_filters=["one"]) 

158 assert project_list.build( 

159 projects_path=self.tmp_path / "projects_path", 

160 num_parallel_builds=2, 

161 num_threads_per_build=4, 

162 output_path=self.tmp_path / "output_path", 

163 ) 

164 

165 self.project_one.build.assert_called_once_with( 

166 project_path=self.tmp_path / "projects_path" / "one" / "project", 

167 output_path=self.tmp_path / "output_path" / "one", 

168 num_threads=4, 

169 ) 

170 

171 def test_build_with_collect_artifacts(self): 

172 project_list = BuildProjectList(self.modules, project_filters=["one"]) 

173 collect_artifacts = MagicMock() 

174 assert project_list.build( 

175 projects_path=self.tmp_path / "projects_path", 

176 num_parallel_builds=2, 

177 num_threads_per_build=4, 

178 collect_artifacts=collect_artifacts, 

179 ) 

180 

181 collect_artifacts.assert_called_once_with( 

182 project=self.project_one, 

183 output_path=self.tmp_path / "projects_path" / "one", 

184 ) 

185 

186 def test_build_with_collect_artifacts_and_output_path(self): 

187 project_list = BuildProjectList(self.modules, project_filters=["one"]) 

188 collect_artifacts = MagicMock() 

189 assert project_list.build( 

190 projects_path=self.tmp_path / "projects_path", 

191 num_parallel_builds=2, 

192 num_threads_per_build=4, 

193 output_path=self.tmp_path / "output_path", 

194 collect_artifacts=collect_artifacts, 

195 ) 

196 

197 collect_artifacts.assert_called_once_with( 

198 project=self.project_one, output_path=self.tmp_path / "output_path" / "one" 

199 ) 

200 

201 def test_build_with_collect_artifacts_return_false_should_fail_build(self): 

202 project_list = BuildProjectList(self.modules, project_filters=["one"]) 

203 collect_artifacts = MagicMock() 

204 collect_artifacts.return_value = False 

205 assert not project_list.build( 

206 projects_path=self.tmp_path / "projects_path", 

207 num_parallel_builds=2, 

208 num_threads_per_build=4, 

209 collect_artifacts=collect_artifacts, 

210 ) 

211 

212 def test_open(self): 

213 project_list = BuildProjectList(self.modules, include_netlist_not_top_builds=True) 

214 assert project_list.open(projects_path=self.tmp_path / "projects_path") 

215 

216 self.project_three.open.assert_called_once_with( 

217 project_path=self.tmp_path / "projects_path" / "three" / "project" 

218 ) 

219 self.project_four.open.assert_called_once_with( 

220 project_path=self.tmp_path / "projects_path" / "four" / "project" 

221 ) 

222 self.project_one.open.assert_not_called() 

223 self.project_two.open.assert_not_called()