118 lines
4.0 KiB
Python
118 lines
4.0 KiB
Python
|
|
"""Tests for Container class.
|
||
|
|
|
||
|
|
Note: These tests require udisks2 to be installed and running.
|
||
|
|
They actually mount/unmount images, so they're integration tests.
|
||
|
|
"""
|
||
|
|
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
from src.core.container import Container, ContainerError
|
||
|
|
from src.core.image_manager import create_sparse_image
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.fixture
|
||
|
|
def vault_image(tmp_path: Path) -> Path:
|
||
|
|
"""Create a temporary vault image for testing."""
|
||
|
|
image_path = tmp_path / "test.vault"
|
||
|
|
create_sparse_image(image_path, size_mb=10)
|
||
|
|
return image_path
|
||
|
|
|
||
|
|
|
||
|
|
class TestContainer:
|
||
|
|
"""Tests for Container class."""
|
||
|
|
|
||
|
|
@pytest.mark.integration
|
||
|
|
def test_mount_and_unmount(self, vault_image: Path) -> None:
|
||
|
|
"""Test mounting and unmounting a vault image."""
|
||
|
|
container = Container(vault_image)
|
||
|
|
|
||
|
|
# Mount
|
||
|
|
mount_point = container.mount()
|
||
|
|
assert container.is_mounted()
|
||
|
|
assert mount_point.exists()
|
||
|
|
assert mount_point.is_dir()
|
||
|
|
|
||
|
|
# Should be able to write files
|
||
|
|
test_file = mount_point / "test.txt"
|
||
|
|
test_file.write_text("Hello, Vault!")
|
||
|
|
assert test_file.exists()
|
||
|
|
|
||
|
|
# Unmount
|
||
|
|
container.unmount()
|
||
|
|
assert not container.is_mounted()
|
||
|
|
|
||
|
|
@pytest.mark.integration
|
||
|
|
def test_context_manager(self, vault_image: Path) -> None:
|
||
|
|
"""Test using container as context manager."""
|
||
|
|
with Container(vault_image) as container:
|
||
|
|
assert container.is_mounted()
|
||
|
|
mount_point = container.mount_point
|
||
|
|
assert mount_point is not None
|
||
|
|
assert mount_point.exists()
|
||
|
|
|
||
|
|
# Should be unmounted after context exits
|
||
|
|
assert not container.is_mounted()
|
||
|
|
|
||
|
|
@pytest.mark.integration
|
||
|
|
def test_mount_creates_vault_directory(self, vault_image: Path) -> None:
|
||
|
|
"""Test that .vault directory can be created in mounted image."""
|
||
|
|
with Container(vault_image) as container:
|
||
|
|
vault_dir = container.mount_point / ".vault" # type: ignore
|
||
|
|
vault_dir.mkdir()
|
||
|
|
assert vault_dir.exists()
|
||
|
|
|
||
|
|
# Create manifest file
|
||
|
|
manifest = vault_dir / "manifest.json"
|
||
|
|
manifest.write_text('{"test": true}')
|
||
|
|
assert manifest.exists()
|
||
|
|
|
||
|
|
@pytest.mark.integration
|
||
|
|
def test_mount_already_mounted(self, vault_image: Path) -> None:
|
||
|
|
"""Test that mounting already mounted container fails."""
|
||
|
|
container = Container(vault_image)
|
||
|
|
container.mount()
|
||
|
|
|
||
|
|
try:
|
||
|
|
with pytest.raises(ContainerError, match="already mounted"):
|
||
|
|
container.mount()
|
||
|
|
finally:
|
||
|
|
container.unmount()
|
||
|
|
|
||
|
|
def test_mount_nonexistent_image(self, tmp_path: Path) -> None:
|
||
|
|
"""Test that mounting nonexistent image fails."""
|
||
|
|
container = Container(tmp_path / "nonexistent.vault")
|
||
|
|
|
||
|
|
with pytest.raises(ContainerError, match="not found"):
|
||
|
|
container.mount()
|
||
|
|
|
||
|
|
def test_is_mounted_initially_false(self, vault_image: Path) -> None:
|
||
|
|
"""Test that container is not mounted initially."""
|
||
|
|
container = Container(vault_image)
|
||
|
|
assert not container.is_mounted()
|
||
|
|
|
||
|
|
@pytest.mark.integration
|
||
|
|
def test_unmount_not_mounted(self, vault_image: Path) -> None:
|
||
|
|
"""Test that unmounting not mounted container is safe."""
|
||
|
|
container = Container(vault_image)
|
||
|
|
|
||
|
|
# Should not raise
|
||
|
|
container.unmount()
|
||
|
|
|
||
|
|
@pytest.mark.integration
|
||
|
|
def test_data_persists_after_remount(self, vault_image: Path) -> None:
|
||
|
|
"""Test that data persists after unmount and remount."""
|
||
|
|
test_content = "Persistent data test"
|
||
|
|
|
||
|
|
# Write data
|
||
|
|
with Container(vault_image) as container:
|
||
|
|
test_file = container.mount_point / "persistent.txt" # type: ignore
|
||
|
|
test_file.write_text(test_content)
|
||
|
|
|
||
|
|
# Read data after remount
|
||
|
|
with Container(vault_image) as container:
|
||
|
|
test_file = container.mount_point / "persistent.txt" # type: ignore
|
||
|
|
assert test_file.exists()
|
||
|
|
assert test_file.read_text() == test_content
|