207 lines
6.9 KiB
Python
207 lines
6.9 KiB
Python
"""Unit tests for file integrity verification."""
|
|
|
|
import pytest
|
|
|
|
from src.infrastructure.security.file_integrity import (
|
|
FileIntegrityManager,
|
|
get_integrity_manager,
|
|
)
|
|
|
|
|
|
class TestFileIntegrityManager:
|
|
"""Test the FileIntegrityManager class."""
|
|
|
|
def test_calculate_checksum(self, tmp_path):
|
|
"""Test checksum calculation for a file."""
|
|
# Create a test file
|
|
test_file = tmp_path / "test.txt"
|
|
test_file.write_text("Hello, World!")
|
|
|
|
# Create integrity manager with temp checksum file
|
|
checksum_file = tmp_path / "checksums.json"
|
|
manager = FileIntegrityManager(checksum_file)
|
|
|
|
# Calculate checksum
|
|
checksum = manager.calculate_checksum(test_file)
|
|
|
|
# Verify checksum is a hex string
|
|
assert isinstance(checksum, str)
|
|
assert len(checksum) == 64 # SHA256 produces 64 hex chars
|
|
assert all(c in "0123456789abcdef" for c in checksum)
|
|
|
|
def test_calculate_checksum_nonexistent_file(self, tmp_path):
|
|
"""Test checksum calculation for nonexistent file."""
|
|
nonexistent = tmp_path / "nonexistent.txt"
|
|
checksum_file = tmp_path / "checksums.json"
|
|
manager = FileIntegrityManager(checksum_file)
|
|
|
|
with pytest.raises(FileNotFoundError):
|
|
manager.calculate_checksum(nonexistent)
|
|
|
|
def test_store_and_verify_checksum(self, tmp_path):
|
|
"""Test storing and verifying checksum."""
|
|
# Create test file
|
|
test_file = tmp_path / "test.txt"
|
|
test_file.write_text("Test content")
|
|
|
|
checksum_file = tmp_path / "checksums.json"
|
|
manager = FileIntegrityManager(checksum_file)
|
|
|
|
# Store checksum
|
|
stored_checksum = manager.store_checksum(test_file)
|
|
assert isinstance(stored_checksum, str)
|
|
|
|
# Verify checksum
|
|
assert manager.verify_checksum(test_file)
|
|
|
|
def test_verify_checksum_modified_file(self, tmp_path):
|
|
"""Test checksum verification fails for modified file."""
|
|
# Create test file
|
|
test_file = tmp_path / "test.txt"
|
|
test_file.write_text("Original content")
|
|
|
|
checksum_file = tmp_path / "checksums.json"
|
|
manager = FileIntegrityManager(checksum_file)
|
|
|
|
# Store checksum
|
|
manager.store_checksum(test_file)
|
|
|
|
# Modify file
|
|
test_file.write_text("Modified content")
|
|
|
|
# Verification should fail
|
|
assert not manager.verify_checksum(test_file)
|
|
|
|
def test_verify_checksum_with_expected_value(self, tmp_path):
|
|
"""Test checksum verification with expected value."""
|
|
test_file = tmp_path / "test.txt"
|
|
test_file.write_text("Known content")
|
|
|
|
checksum_file = tmp_path / "checksums.json"
|
|
manager = FileIntegrityManager(checksum_file)
|
|
|
|
# Calculate known checksum
|
|
expected = manager.calculate_checksum(test_file)
|
|
|
|
# Verify with expected checksum
|
|
assert manager.verify_checksum(test_file, expected)
|
|
|
|
# Verify with wrong checksum
|
|
wrong_checksum = "a" * 64
|
|
assert not manager.verify_checksum(test_file, wrong_checksum)
|
|
|
|
def test_has_checksum(self, tmp_path):
|
|
"""Test checking if checksum exists."""
|
|
test_file = tmp_path / "test.txt"
|
|
test_file.write_text("Content")
|
|
|
|
checksum_file = tmp_path / "checksums.json"
|
|
manager = FileIntegrityManager(checksum_file)
|
|
|
|
# Initially no checksum
|
|
assert not manager.has_checksum(test_file)
|
|
|
|
# Store checksum
|
|
manager.store_checksum(test_file)
|
|
|
|
# Now has checksum
|
|
assert manager.has_checksum(test_file)
|
|
|
|
def test_remove_checksum(self, tmp_path):
|
|
"""Test removing checksum."""
|
|
test_file = tmp_path / "test.txt"
|
|
test_file.write_text("Content")
|
|
|
|
checksum_file = tmp_path / "checksums.json"
|
|
manager = FileIntegrityManager(checksum_file)
|
|
|
|
# Store checksum
|
|
manager.store_checksum(test_file)
|
|
assert manager.has_checksum(test_file)
|
|
|
|
# Remove checksum
|
|
result = manager.remove_checksum(test_file)
|
|
assert result is True
|
|
assert not manager.has_checksum(test_file)
|
|
|
|
# Try to remove again
|
|
result = manager.remove_checksum(test_file)
|
|
assert result is False
|
|
|
|
def test_persistence(self, tmp_path):
|
|
"""Test that checksums persist across instances."""
|
|
test_file = tmp_path / "test.txt"
|
|
test_file.write_text("Persistent content")
|
|
|
|
checksum_file = tmp_path / "checksums.json"
|
|
|
|
# Store checksum in first instance
|
|
manager1 = FileIntegrityManager(checksum_file)
|
|
manager1.store_checksum(test_file)
|
|
|
|
# Load in second instance
|
|
manager2 = FileIntegrityManager(checksum_file)
|
|
assert manager2.has_checksum(test_file)
|
|
assert manager2.verify_checksum(test_file)
|
|
|
|
def test_get_integrity_manager_singleton(self):
|
|
"""Test that get_integrity_manager returns singleton."""
|
|
manager1 = get_integrity_manager()
|
|
manager2 = get_integrity_manager()
|
|
|
|
assert manager1 is manager2
|
|
|
|
def test_checksum_file_created_automatically(self, tmp_path):
|
|
"""Test that checksum file is created in data directory."""
|
|
test_file = tmp_path / "test.txt"
|
|
test_file.write_text("Content")
|
|
|
|
checksum_file = tmp_path / "checksums.json"
|
|
manager = FileIntegrityManager(checksum_file)
|
|
|
|
# Store checksum
|
|
manager.store_checksum(test_file)
|
|
|
|
# Verify checksum file was created
|
|
assert checksum_file.exists()
|
|
|
|
def test_unsupported_algorithm(self, tmp_path):
|
|
"""Test that unsupported hash algorithm raises error."""
|
|
test_file = tmp_path / "test.txt"
|
|
test_file.write_text("Content")
|
|
|
|
checksum_file = tmp_path / "checksums.json"
|
|
manager = FileIntegrityManager(checksum_file)
|
|
|
|
with pytest.raises(ValueError, match="Unsupported hash algorithm"):
|
|
manager.calculate_checksum(test_file, algorithm="invalid")
|
|
|
|
def test_corrupted_checksum_file(self, tmp_path):
|
|
"""Test handling of corrupted checksum file."""
|
|
test_file = tmp_path / "test.txt"
|
|
test_file.write_text("Content")
|
|
|
|
checksum_file = tmp_path / "checksums.json"
|
|
|
|
# Create corrupted checksum file
|
|
checksum_file.write_text("{ invalid json")
|
|
|
|
# Manager should handle gracefully
|
|
manager = FileIntegrityManager(checksum_file)
|
|
assert manager.checksums == {}
|
|
|
|
# Should be able to store new checksum
|
|
manager.store_checksum(test_file)
|
|
assert manager.has_checksum(test_file)
|
|
|
|
def test_verify_checksum_no_stored_checksum(self, tmp_path):
|
|
"""Test verification when no checksum is stored."""
|
|
test_file = tmp_path / "test.txt"
|
|
test_file.write_text("Content")
|
|
|
|
checksum_file = tmp_path / "checksums.json"
|
|
manager = FileIntegrityManager(checksum_file)
|
|
|
|
# Verification should return False
|
|
assert not manager.verify_checksum(test_file)
|