Coverage for tsfpga/test/test_system_utils.py: 100%

105 statements  

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

8 

9import subprocess 

10from pathlib import Path 

11 

12import pytest 

13 

14from tsfpga.system_utils import ( 

15 create_directory, 

16 create_file, 

17 delete, 

18 file_is_in_directory, 

19 path_relative_to, 

20 prepend_file, 

21 read_file, 

22 read_last_lines_of_file, 

23 run_command, 

24) 

25 

26 

27def test_delete_files_and_folders(tmp_path): 

28 # Test deleting a file, with and without wait 

29 path = create_file(tmp_path / "temp.txt") 

30 assert path.exists() 

31 delete(path) 

32 assert not path.exists() 

33 

34 path = create_file(tmp_path / "temp.txt") 

35 assert path.exists() 

36 delete(path, wait_until_deleted=True) 

37 assert not path.exists() 

38 

39 # Test deleting a directory, with and without wait 

40 path = create_directory(tmp_path / "temp_dir") 

41 assert path.exists() 

42 delete(path) 

43 assert not path.exists() 

44 

45 path = create_directory(tmp_path / "temp_dir") 

46 assert path.exists() 

47 delete(path, wait_until_deleted=True) 

48 assert not path.exists() 

49 

50 

51def test_create_directory_plain(tmp_path): 

52 path = tmp_path / "temp_dir" 

53 assert not path.exists() 

54 

55 create_directory(path) 

56 assert path.exists() 

57 assert path.is_dir() 

58 

59 

60def test_create_directory_that_exists_without_empty(tmp_path): 

61 path = tmp_path / "temp_dir" 

62 sub_path = create_directory(path / "sub") 

63 

64 create_directory(path, empty=False) 

65 assert sub_path.exists() 

66 

67 

68def test_create_directory_that_exists_with_empty(tmp_path): 

69 path = tmp_path / "temp_dir" 

70 sub_path = create_directory(path / "sub") 

71 

72 create_directory(path) 

73 assert path.exists() 

74 assert not sub_path.exists() 

75 

76 

77def test_create_directory_without_empty_when_path_is_a_file(tmp_path): 

78 path = create_file(tmp_path / "file.txt", contents="data") 

79 

80 with pytest.raises(FileExistsError) as exception_info: 

81 create_directory(path, empty=False) 

82 assert str(exception_info.value) == f"Requested directory path already exists as a file: {path}" 

83 

84 assert read_file(path) == "data" 

85 

86 

87def test_file_is_in_directory(tmp_path): 

88 assert file_is_in_directory(tmp_path / "file.txt", [tmp_path]) 

89 assert not file_is_in_directory(tmp_path / "file.txt", [tmp_path / "sub"]) 

90 

91 assert file_is_in_directory( 

92 tmp_path / "sub" / "file.txt", [tmp_path / "sub", tmp_path / "sub2"] 

93 ) 

94 assert not file_is_in_directory(tmp_path / "file.txt", [tmp_path / "sub", tmp_path / "sub2"]) 

95 assert not file_is_in_directory( 

96 tmp_path / "sub" / "file.txt", [tmp_path / "sub2", tmp_path / "sub3"] 

97 ) 

98 

99 

100def test_path_relative_to(): 

101 this_file = Path(__file__) 

102 this_dir = this_file.parent 

103 parent = this_dir.parent 

104 

105 assert path_relative_to(this_file, this_dir) == Path(this_file.name) 

106 assert path_relative_to(this_file, parent) == Path(this_dir.name) / this_file.name 

107 assert ( 

108 path_relative_to(this_file, parent / "whatever") 

109 == Path("..") / this_dir.name / this_file.name 

110 ) 

111 

112 

113def test_read_last_lines_of_file_with_short_file(tmp_path): 

114 # A file that is smaller than the buffer size 

115 data = "a\nb\nc" 

116 file = create_file(tmp_path / "data.txt", contents=data) 

117 assert read_last_lines_of_file(file, num_lines=10) == data 

118 

119 

120def test_read_last_lines_of_file_with_long_file(tmp_path): 

121 # A file that is larger than the buffer size 

122 data_trash = (("a" * 700) + "\n") * 3000 

123 data_last_lines = (("b" * 700) + "\n") * 10 

124 file = create_file(tmp_path / "data.txt", contents=data_trash + data_last_lines) 

125 assert read_last_lines_of_file(file, num_lines=10) == data_last_lines 

126 

127 

128def test_read_last_lines_of_file_with_trailing_newlines(tmp_path): 

129 # A file that is smaller than the buffer size 

130 data = "a\nb\n\n \n\n" 

131 file = create_file(tmp_path / "data.txt", contents=data) 

132 assert read_last_lines_of_file(file, num_lines=10) == data 

133 

134 

135def test_read_last_lines_of_file_with_empty_file(tmp_path): 

136 data = "" 

137 file = create_file(tmp_path / "data.txt", contents=data) 

138 assert read_last_lines_of_file(file, num_lines=10) == data 

139 

140 data = "\n" 

141 file = create_file(tmp_path / "data.txt", contents=data) 

142 assert read_last_lines_of_file(file, num_lines=10) == data 

143 

144 

145def test_prepend_file(tmp_path): 

146 assert ( 

147 read_file( 

148 prepend_file( 

149 file_path=create_file(tmp_path / "data.txt", contents="data"), text="hello\nmy_" 

150 ) 

151 ) 

152 == "hello\nmy_data" 

153 ) 

154 

155 

156def test_prepend_file_with_empty_file(tmp_path): 

157 assert read_file(prepend_file(file_path=create_file(tmp_path / "data.txt"), text="a")) == "a" 

158 

159 

160def test_run_command_called_with_nonexisting_binary_should_raise_exception(): 

161 cmd = ["/apa/hest/zebra.exe", "foobar"] 

162 with pytest.raises(FileNotFoundError): 

163 run_command(cmd) 

164 

165 

166def test_run_command_with_non_zero_return_code_should_raise_exception(): 

167 cmd = ["ls", "/apa/hest/zebra"] 

168 with pytest.raises(subprocess.CalledProcessError): 

169 run_command(cmd) 

170 

171 

172def test_run_command_called_with_non_list_should_raise_exception(): 

173 cmd = ["ls", "-la"] 

174 run_command(cmd) 

175 

176 cmd = "ls -la" 

177 with pytest.raises(TypeError) as exception_info: 

178 run_command(cmd) 

179 assert str(exception_info.value).startswith("Must be called with a list") 

180 

181 

182def test_run_command_should_capture_output_as_strings(): 

183 this_dir = Path(__file__).parent.resolve() 

184 

185 cmd = ["ls", str(this_dir)] 

186 result = run_command(cmd, capture_output=True) 

187 

188 assert isinstance(result.stdout, str) 

189 assert isinstance(result.stderr, str) 

190 

191 assert result.stderr == "" 

192 

193 # Show that it is regular text with regular newlines. 

194 assert "\ntest_system_utils.py\n" in result.stdout 

195 assert "\ntest_ip_core_file.py\n" in result.stdout