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
« 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# --------------------------------------------------------------------------------------------------
9import subprocess
10from pathlib import Path
12import pytest
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)
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()
34 path = create_file(tmp_path / "temp.txt")
35 assert path.exists()
36 delete(path, wait_until_deleted=True)
37 assert not path.exists()
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()
45 path = create_directory(tmp_path / "temp_dir")
46 assert path.exists()
47 delete(path, wait_until_deleted=True)
48 assert not path.exists()
51def test_create_directory_plain(tmp_path):
52 path = tmp_path / "temp_dir"
53 assert not path.exists()
55 create_directory(path)
56 assert path.exists()
57 assert path.is_dir()
60def test_create_directory_that_exists_without_empty(tmp_path):
61 path = tmp_path / "temp_dir"
62 sub_path = create_directory(path / "sub")
64 create_directory(path, empty=False)
65 assert sub_path.exists()
68def test_create_directory_that_exists_with_empty(tmp_path):
69 path = tmp_path / "temp_dir"
70 sub_path = create_directory(path / "sub")
72 create_directory(path)
73 assert path.exists()
74 assert not sub_path.exists()
77def test_create_directory_without_empty_when_path_is_a_file(tmp_path):
78 path = create_file(tmp_path / "file.txt", contents="data")
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}"
84 assert read_file(path) == "data"
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"])
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 )
100def test_path_relative_to():
101 this_file = Path(__file__)
102 this_dir = this_file.parent
103 parent = this_dir.parent
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 )
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
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
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
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
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
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 )
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"
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)
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)
172def test_run_command_called_with_non_list_should_raise_exception():
173 cmd = ["ls", "-la"]
174 run_command(cmd)
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")
182def test_run_command_should_capture_output_as_strings():
183 this_dir = Path(__file__).parent.resolve()
185 cmd = ["ls", str(this_dir)]
186 result = run_command(cmd, capture_output=True)
188 assert isinstance(result.stdout, str)
189 assert isinstance(result.stderr, str)
191 assert result.stderr == ""
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