Coverage for tsfpga/vivado/test/test_build_result_checker.py: 100%

88 statements  

« 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# -------------------------------------------------------------------------------------------------- 

8 

9import io 

10from unittest.mock import Mock, patch 

11 

12import pytest 

13 

14from tsfpga.vivado.build_result import BuildResult 

15from tsfpga.vivado.build_result_checker import ( 

16 DspBlocks, 

17 EqualTo, 

18 GreaterThan, 

19 LessThan, 

20 MaximumLogicLevel, 

21 Ramb, 

22 Ramb36, 

23 TotalLuts, 

24) 

25 

26 

27@patch("sys.stdout", new_callable=io.StringIO) 

28def test_size_checker_less_than_pass(mock_stdout): 

29 build_result = BuildResult(name="") 

30 build_result.synthesis_size = {"Total LUTs": 5} 

31 

32 assert TotalLuts(LessThan(10)).check(build_result) 

33 assert mock_stdout.getvalue() == "Result check passed for Total LUTs: 5 (< 10)\n" 

34 

35 

36@patch("sys.stdout", new_callable=io.StringIO) 

37def test_size_checker_less_than_fail(mock_stdout): 

38 build_result = BuildResult(name="") 

39 build_result.synthesis_size = {"Total LUTs": 5} 

40 

41 assert not TotalLuts(LessThan(5)).check(build_result) 

42 assert mock_stdout.getvalue() == "Result check failed for Total LUTs. Got 5, expected < 5.\n" 

43 

44 

45@patch("sys.stdout", new_callable=io.StringIO) 

46def test_size_checker_greater_than_pass(mock_stdout): 

47 build_result = BuildResult(name="") 

48 build_result.synthesis_size = {"Total LUTs": 5} 

49 

50 assert TotalLuts(GreaterThan(2)).check(build_result) 

51 assert mock_stdout.getvalue() == "Result check passed for Total LUTs: 5 (> 2)\n" 

52 

53 

54@patch("sys.stdout", new_callable=io.StringIO) 

55def test_size_checker_greater_than_fail(mock_stdout): 

56 build_result = BuildResult(name="") 

57 build_result.synthesis_size = {"Total LUTs": 5} 

58 

59 assert not TotalLuts(GreaterThan(5)).check(build_result) 

60 assert mock_stdout.getvalue() == "Result check failed for Total LUTs. Got 5, expected > 5.\n" 

61 

62 

63@patch("sys.stdout", new_callable=io.StringIO) 

64def test_size_checker_equal_to_pass(mock_stdout): 

65 build_result = BuildResult(name="") 

66 build_result.synthesis_size = {"RAMB36": 0, "Total LUTs": 5} 

67 

68 assert Ramb36(EqualTo(0)).check(build_result) 

69 assert TotalLuts(EqualTo(5)).check(build_result) 

70 

71 assert mock_stdout.getvalue() == ( 

72 "Result check passed for RAMB36: 0 (0)\nResult check passed for Total LUTs: 5 (5)\n" 

73 ) 

74 

75 

76@patch("sys.stdout", new_callable=io.StringIO) 

77def test_size_checker_equal_to_fail(mock_stdout): 

78 build_result = BuildResult(name="") 

79 build_result.synthesis_size = {"Total LUTs": 5} 

80 

81 assert not TotalLuts(EqualTo(50)).check(build_result) 

82 assert mock_stdout.getvalue() == "Result check failed for Total LUTs. Got 5, expected 50.\n" 

83 

84 

85def test_size_checker_dsp_blocks_has_two_names(): 

86 build_result = BuildResult(name="") 

87 

88 build_result.synthesis_size = {"DSP Blocks": 5} 

89 assert DspBlocks(EqualTo(5)).check(build_result) 

90 assert not DspBlocks(EqualTo(2)).check(build_result) 

91 

92 build_result.synthesis_size = {"DSP48 Blocks": 7} 

93 assert DspBlocks(EqualTo(7)).check(build_result) 

94 assert not DspBlocks(EqualTo(2)).check(build_result) 

95 

96 

97def test_size_checker_aggregated_ramb(): 

98 build_result = BuildResult(name="") 

99 

100 build_result.synthesis_size = {"RAMB18": 5, "RAMB36": 20} 

101 assert Ramb(EqualTo(22.5)).check(build_result) 

102 assert not Ramb(EqualTo(22)).check(build_result) 

103 

104 build_result.synthesis_size = {"RAMB18": 5, "RAMB36": 0} 

105 assert Ramb(EqualTo(2.5)).check(build_result) 

106 

107 build_result.synthesis_size = {"RAMB18": 0, "RAMB36": 20} 

108 assert Ramb(EqualTo(20)).check(build_result) 

109 

110 

111def test_size_checker_raises_exception_if_synthesis_size_is_not_set(): 

112 build_result = BuildResult(name="") 

113 build_result.synthesis_size = None 

114 

115 with pytest.raises(ValueError) as exception_info: 

116 assert Ramb36(EqualTo(0)).check(build_result) 

117 assert str(exception_info.value) == "Should only call after successful synthesis" 

118 

119 

120def test_size_checker_raises_exception_if_synthesis_size_does_not_have_requested_resource(): 

121 build_result = BuildResult(name="") 

122 build_result.synthesis_size = {"Total LUTs": 5} 

123 

124 with pytest.raises(ValueError) as exception_info: 

125 assert Ramb36(EqualTo(0)).check(build_result) 

126 assert ( 

127 str(exception_info.value) 

128 == 'Synthesis result size does not contain the requested resource: "RAMB36"' 

129 ) 

130 

131 

132@patch("sys.stdout", new_callable=io.StringIO) 

133def test_logic_level_checker_equal_to_pass(mock_stdout): 

134 build_result = Mock(spec=BuildResult) 

135 build_result.maximum_logic_level = 5 

136 

137 assert MaximumLogicLevel(EqualTo(5)).check(build_result) 

138 assert mock_stdout.getvalue() == "Result check passed for maximum logic level: 5 (5)\n" 

139 

140 

141@patch("sys.stdout", new_callable=io.StringIO) 

142def test_logic_level_checker_less_than_fail(mock_stdout): 

143 build_result = Mock(spec=BuildResult) 

144 build_result.maximum_logic_level = 11 

145 assert not MaximumLogicLevel(LessThan(7)).check(build_result) 

146 assert ( 

147 mock_stdout.getvalue() 

148 == "Result check failed for maximum logic level. Got 11, expected < 7.\n" 

149 ) 

150 

151 

152def test_logic_level_checker_raises_exception_if_logic_level_is_not_set(): 

153 build_result = BuildResult(name="") 

154 

155 with pytest.raises(ValueError) as exception_info: 

156 MaximumLogicLevel(LessThan(7)).check(build_result) 

157 assert str(exception_info.value) == "Should only call after successful synthesis"