|
1 | 1 | """Tests for the platform utility functions.""" |
2 | 2 |
|
3 | 3 | import math |
| 4 | +import tempfile |
| 5 | +from pathlib import Path |
4 | 6 |
|
5 | 7 | import pytest |
6 | 8 |
|
7 | 9 | from aignostics.platform import mime_type_to_file_ending |
8 | | -from aignostics.platform._utils import convert_to_json_serializable |
| 10 | +from aignostics.platform._utils import calculate_file_crc32c, convert_to_json_serializable |
9 | 11 |
|
10 | 12 |
|
11 | 13 | class TestConvertToJsonSerializable: |
@@ -239,3 +241,105 @@ def test_unknown_mime_type_raises_error(record_property) -> None: |
239 | 241 | record_property("tested-item-id", "SPEC-PLATFORM-SERVICE") |
240 | 242 | with pytest.raises(ValueError, match="Unknown mime type: application/unknown"): |
241 | 243 | mime_type_to_file_ending("application/unknown") |
| 244 | + |
| 245 | + |
| 246 | +class TestCalculateFileCrc32c: |
| 247 | + """Tests for the calculate_file_crc32c function.""" |
| 248 | + |
| 249 | + @pytest.mark.unit |
| 250 | + @staticmethod |
| 251 | + def test_calculate_crc32c_small_file(record_property) -> None: |
| 252 | + """Test CRC32C calculation for a small file. |
| 253 | +
|
| 254 | + This test verifies that the calculate_file_crc32c function correctly |
| 255 | + calculates the CRC32C checksum for a small file that fits in a single chunk. |
| 256 | + """ |
| 257 | + record_property("tested-item-id", "SPEC-PLATFORM-SERVICE") |
| 258 | + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as temp_file: |
| 259 | + temp_path = Path(temp_file.name) |
| 260 | + temp_file.write(b"Hello, World!") |
| 261 | + |
| 262 | + try: |
| 263 | + checksum = calculate_file_crc32c(temp_path) |
| 264 | + # Verify it returns a base64-encoded string |
| 265 | + assert isinstance(checksum, str) |
| 266 | + assert len(checksum) > 0 |
| 267 | + # The checksum for "Hello, World!" should be consistent |
| 268 | + assert checksum == "TVUQaA==" |
| 269 | + finally: |
| 270 | + temp_path.unlink() |
| 271 | + |
| 272 | + @pytest.mark.unit |
| 273 | + @staticmethod |
| 274 | + def test_calculate_crc32c_large_file(record_property) -> None: |
| 275 | + """Test CRC32C calculation for a large file with multiple chunks. |
| 276 | +
|
| 277 | + This test verifies that the calculate_file_crc32c function correctly |
| 278 | + calculates the CRC32C checksum for a file larger than 8MB, ensuring |
| 279 | + the continue statement (line 187) is executed multiple times. |
| 280 | + """ |
| 281 | + record_property("tested-item-id", "SPEC-PLATFORM-SERVICE") |
| 282 | + # Create a file larger than EIGHT_MB (8,388,608 bytes) |
| 283 | + # Use 10MB to ensure multiple chunks |
| 284 | + file_size = 10 * 1024 * 1024 # 10 MB |
| 285 | + chunk_data = b"A" * (1024 * 1024) # 1 MB chunks |
| 286 | + |
| 287 | + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as temp_file: |
| 288 | + temp_path = Path(temp_file.name) |
| 289 | + for _ in range(10): # Write 10 chunks of 1MB each |
| 290 | + temp_file.write(chunk_data) |
| 291 | + |
| 292 | + try: |
| 293 | + checksum = calculate_file_crc32c(temp_path) |
| 294 | + # Verify it returns a base64-encoded string |
| 295 | + assert isinstance(checksum, str) |
| 296 | + assert len(checksum) > 0 |
| 297 | + # Verify file size is as expected |
| 298 | + assert temp_path.stat().st_size == file_size |
| 299 | + finally: |
| 300 | + temp_path.unlink() |
| 301 | + |
| 302 | + @pytest.mark.unit |
| 303 | + @staticmethod |
| 304 | + def test_calculate_crc32c_empty_file(record_property) -> None: |
| 305 | + """Test CRC32C calculation for an empty file. |
| 306 | +
|
| 307 | + This test verifies that the calculate_file_crc32c function correctly |
| 308 | + handles empty files. |
| 309 | + """ |
| 310 | + record_property("tested-item-id", "SPEC-PLATFORM-SERVICE") |
| 311 | + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as temp_file: |
| 312 | + temp_path = Path(temp_file.name) |
| 313 | + # Don't write anything, leave file empty |
| 314 | + |
| 315 | + try: |
| 316 | + checksum = calculate_file_crc32c(temp_path) |
| 317 | + # Verify it returns a base64-encoded string |
| 318 | + assert isinstance(checksum, str) |
| 319 | + assert len(checksum) > 0 |
| 320 | + # Empty file CRC32C checksum |
| 321 | + assert checksum == "AAAAAA==" |
| 322 | + finally: |
| 323 | + temp_path.unlink() |
| 324 | + |
| 325 | + @pytest.mark.unit |
| 326 | + @staticmethod |
| 327 | + def test_calculate_crc32c_deterministic(record_property) -> None: |
| 328 | + """Test that CRC32C calculation is deterministic. |
| 329 | +
|
| 330 | + This test verifies that calculating the checksum multiple times for |
| 331 | + the same file produces the same result. |
| 332 | + """ |
| 333 | + record_property("tested-item-id", "SPEC-PLATFORM-SERVICE") |
| 334 | + test_data = b"Test data for deterministic checksum verification" |
| 335 | + |
| 336 | + with tempfile.NamedTemporaryFile(mode="wb", delete=False) as temp_file: |
| 337 | + temp_path = Path(temp_file.name) |
| 338 | + temp_file.write(test_data) |
| 339 | + |
| 340 | + try: |
| 341 | + checksum1 = calculate_file_crc32c(temp_path) |
| 342 | + checksum2 = calculate_file_crc32c(temp_path) |
| 343 | + assert checksum1 == checksum2 |
| 344 | + finally: |
| 345 | + temp_path.unlink() |
0 commit comments