- Removed outdated tests for missing lines in core.py. - Added comprehensive tests for conflict resolution functionality, including various resolution strategies and edge cases. - Improved error handling tests for archive creation and extraction processes. - Enhanced unit tests for basic functionality and convenience functions with pytest markers. - Introduced tests for unique filename generation and conflict handling scenarios. - Added edge case tests for archive extraction and error conditions to improve overall test coverage.
262 lines
9.7 KiB
Python
262 lines
9.7 KiB
Python
"""Tests for tzst convenience functions."""
|
|
|
|
import pytest
|
|
|
|
from tzst import create_archive, extract_archive, list_archive
|
|
from tzst import test_archive as tzst_test_archive
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestConvenienceFunctions:
|
|
"""Test the convenience functions."""
|
|
|
|
def test_create_archive_function(self, sample_files, sample_archive_path):
|
|
"""Test create_archive function."""
|
|
file_paths = [f for f in sample_files if f.is_file()]
|
|
create_archive(sample_archive_path, file_paths)
|
|
|
|
assert sample_archive_path.exists()
|
|
|
|
# Verify contents
|
|
contents = list_archive(sample_archive_path)
|
|
assert len(contents) > 0
|
|
|
|
def test_extract_archive_function(
|
|
self, sample_files, sample_archive_path, temp_dir
|
|
):
|
|
"""Test extract_archive function."""
|
|
# Create archive first
|
|
file_paths = [f for f in sample_files if f.is_file()]
|
|
create_archive(sample_archive_path, file_paths)
|
|
|
|
# Extract
|
|
extract_dir = temp_dir / "extracted"
|
|
extract_archive(sample_archive_path, extract_dir)
|
|
|
|
# Verify extraction
|
|
assert extract_dir.exists()
|
|
extracted_files = list(extract_dir.rglob("*"))
|
|
assert len(extracted_files) > 0
|
|
|
|
def test_extract_archive_flat(self, sample_files, sample_archive_path, temp_dir):
|
|
"""Test flat extraction."""
|
|
# Create archive first
|
|
file_paths = [f for f in sample_files if f.is_file()]
|
|
create_archive(sample_archive_path, file_paths)
|
|
|
|
# Extract flat
|
|
extract_dir = temp_dir / "extracted_flat"
|
|
extract_archive(sample_archive_path, extract_dir, flatten=True)
|
|
|
|
# Verify flat extraction (no subdirectories)
|
|
assert extract_dir.exists()
|
|
extracted_files = [f for f in extract_dir.iterdir() if f.is_file()]
|
|
extracted_dirs = [d for d in extract_dir.iterdir() if d.is_dir()]
|
|
|
|
assert len(extracted_files) > 0
|
|
assert len(extracted_dirs) == 0 # Should be flat
|
|
|
|
def test_list_archive_function(self, sample_files, sample_archive_path):
|
|
"""Test list_archive function."""
|
|
# Create archive first
|
|
file_paths = [f for f in sample_files if f.is_file()]
|
|
create_archive(sample_archive_path, file_paths)
|
|
|
|
# List contents
|
|
contents = list_archive(sample_archive_path)
|
|
assert len(contents) > 0
|
|
|
|
# Test verbose listing
|
|
verbose_contents = list_archive(sample_archive_path, verbose=True)
|
|
assert len(verbose_contents) == len(contents)
|
|
assert "mode" in verbose_contents[0]
|
|
|
|
def test_test_archive_function(self, sample_files, sample_archive_path):
|
|
"""Test test_archive function."""
|
|
# Create archive first
|
|
file_paths = [f for f in sample_files if f.is_file()]
|
|
create_archive(sample_archive_path, file_paths)
|
|
|
|
# Test archive
|
|
assert tzst_test_archive(sample_archive_path) is True
|
|
|
|
# Test non-existent archive
|
|
fake_archive = sample_archive_path.parent / "fake.tzst"
|
|
assert tzst_test_archive(fake_archive) is False
|
|
|
|
def test_streaming_convenience_functions(
|
|
self, sample_files, sample_archive_path, temp_dir
|
|
):
|
|
"""Test convenience functions with streaming parameter."""
|
|
# Create archive first
|
|
file_paths = [f for f in sample_files if f.is_file()]
|
|
create_archive(sample_archive_path, file_paths)
|
|
|
|
# Test list_archive with streaming
|
|
contents_normal = list_archive(sample_archive_path, streaming=False)
|
|
contents_streaming = list_archive(sample_archive_path, streaming=True)
|
|
assert len(contents_normal) == len(contents_streaming)
|
|
|
|
# Test test_archive with streaming
|
|
assert tzst_test_archive(sample_archive_path, streaming=False) is True
|
|
assert tzst_test_archive(sample_archive_path, streaming=True) is True
|
|
|
|
# Test extract_archive with streaming
|
|
extract_dir_normal = temp_dir / "extract_normal"
|
|
extract_dir_streaming = temp_dir / "extract_streaming"
|
|
|
|
extract_archive(sample_archive_path, extract_dir_normal, streaming=False)
|
|
extract_archive(sample_archive_path, extract_dir_streaming, streaming=True)
|
|
|
|
assert extract_dir_normal.exists()
|
|
assert extract_dir_streaming.exists()
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestAtomicOperations:
|
|
"""Test atomic file operations."""
|
|
|
|
def test_atomic_file_operations(self, sample_files, temp_dir):
|
|
"""Test atomic file operations."""
|
|
archive_path = temp_dir / "atomic_test.tzst"
|
|
file_paths = [f for f in sample_files if f.is_file()]
|
|
|
|
# Test with atomic operations enabled
|
|
create_archive(archive_path, file_paths, use_temp_file=True)
|
|
assert archive_path.exists()
|
|
|
|
# Verify archive is valid
|
|
assert tzst_test_archive(archive_path) is True
|
|
|
|
def test_non_atomic_file_creation(self, sample_files, temp_dir):
|
|
"""Test that non-atomic creation also works."""
|
|
archive_path = temp_dir / "non_atomic_test.tzst"
|
|
file_paths = [f for f in sample_files if f.is_file()]
|
|
|
|
# Test with atomic operations disabled
|
|
create_archive(archive_path, file_paths, use_temp_file=False)
|
|
assert archive_path.exists()
|
|
|
|
# Verify archive is valid
|
|
assert tzst_test_archive(archive_path) is True
|
|
|
|
def test_atomic_cleanup_on_error(self, temp_dir):
|
|
"""Test that temporary files are cleaned up on errors."""
|
|
archive_path = temp_dir / "cleanup_test.tzst"
|
|
|
|
# Try to create archive with non-existent files
|
|
with pytest.raises(FileNotFoundError):
|
|
create_archive(archive_path, ["non_existent_file.txt"], use_temp_file=True)
|
|
|
|
# Archive should not exist
|
|
assert not archive_path.exists()
|
|
|
|
# No temporary files should be left behind
|
|
temp_files = list(temp_dir.glob(".cleanup_test.tzst.*"))
|
|
assert len(temp_files) == 0
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestCompressionLevels:
|
|
"""Test compression level validation and functionality."""
|
|
|
|
def test_compression_level_validation(self, sample_files, temp_dir):
|
|
"""Test compression level validation."""
|
|
file_paths = [f for f in sample_files if f.is_file()]
|
|
|
|
# Test valid compression levels
|
|
for level in [1, 3, 10, 22]:
|
|
archive_path = temp_dir / f"level_{level}.tzst"
|
|
create_archive(archive_path, file_paths, compression_level=level)
|
|
assert archive_path.exists()
|
|
assert tzst_test_archive(archive_path) is True
|
|
|
|
# Test invalid compression levels
|
|
for invalid_level in [0, 23, -1, 100]:
|
|
archive_path = temp_dir / f"invalid_{invalid_level}.tzst"
|
|
with pytest.raises(ValueError) as exc_info:
|
|
create_archive(
|
|
archive_path, file_paths, compression_level=invalid_level
|
|
)
|
|
|
|
assert "compression level" in str(exc_info.value).lower()
|
|
assert "1" in str(exc_info.value) and "22" in str(exc_info.value)
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestEdgeCaseCoverage:
|
|
"""Test edge cases to improve coverage."""
|
|
|
|
def test_empty_files_list(self, temp_dir):
|
|
"""Test create_archive with empty files list."""
|
|
archive_path = temp_dir / "empty.tzst"
|
|
|
|
# Should create an empty archive
|
|
create_archive(archive_path, [])
|
|
|
|
assert archive_path.exists()
|
|
contents = list_archive(archive_path)
|
|
assert len(contents) == 0
|
|
|
|
def test_create_archive_with_use_temp_file_false(self, temp_dir):
|
|
"""Test creating archive with use_temp_file=False."""
|
|
test_file = temp_dir / "test.txt"
|
|
test_file.write_text("test content")
|
|
archive_path = temp_dir / "test.tzst"
|
|
|
|
# Test non-atomic mode
|
|
create_archive(archive_path, [str(test_file)], use_temp_file=False)
|
|
|
|
assert archive_path.exists()
|
|
contents = list_archive(archive_path)
|
|
assert len(contents) == 1
|
|
|
|
def test_extract_archive_to_specific_path(self, temp_dir):
|
|
"""Test extracting archive to specific path."""
|
|
# Create test archive
|
|
test_file = temp_dir / "test.txt"
|
|
test_file.write_text("test content")
|
|
archive_path = temp_dir / "test.tzst"
|
|
create_archive(archive_path, [str(test_file)])
|
|
|
|
# Extract to specific directory
|
|
extract_dir = temp_dir / "extracted"
|
|
extract_archive(archive_path, extract_dir)
|
|
|
|
assert extract_dir.exists()
|
|
assert (extract_dir / "test.txt").exists()
|
|
assert (extract_dir / "test.txt").read_text() == "test content"
|
|
|
|
def test_list_archive_with_streaming(self, temp_dir):
|
|
"""Test listing archive with streaming mode."""
|
|
test_file = temp_dir / "test.txt"
|
|
test_file.write_text("test content")
|
|
archive_path = temp_dir / "test.tzst"
|
|
create_archive(archive_path, [str(test_file)])
|
|
|
|
# Test with streaming=True
|
|
contents = list_archive(archive_path, streaming=True)
|
|
assert len(contents) == 1
|
|
assert contents[0]["name"] == "test.txt"
|
|
|
|
def test_test_archive_success(self, temp_dir):
|
|
"""Test testing a valid archive."""
|
|
test_file = temp_dir / "test.txt"
|
|
test_file.write_text("test content")
|
|
archive_path = temp_dir / "test.tzst"
|
|
create_archive(archive_path, [str(test_file)])
|
|
|
|
# Test archive - should return True for valid archive
|
|
result = tzst_test_archive(archive_path)
|
|
assert result is True
|
|
|
|
def test_test_archive_failure(self, temp_dir):
|
|
"""Test testing an invalid archive."""
|
|
# Create a file that's not a valid archive
|
|
invalid_archive = temp_dir / "invalid.tzst"
|
|
invalid_archive.write_text("This is not a valid archive")
|
|
|
|
# Test archive - should return False for invalid archive
|
|
result = tzst_test_archive(invalid_archive)
|
|
assert result is False
|