Add compression level validation to CLI

Introduced a `validate_compression_level` function to ensure compression levels are within the valid range (1-22). Updated CLI argument parsing to use this validation and added tests to verify valid, invalid, and non-numeric compression levels.
This commit is contained in:
xixu-me committed 2025-06-01 17:01:27 +08:00
1 parent 2a3ccefb21
commit 459b695af0
2 files changed
+104 -3

No files matched your search

+33 -3
View File
@@ -50,6 +50,31 @@ def format_size(size: int) -> str:
return f"{size_float:6.1f} PB"
def validate_compression_level(value: str) -> int:
"""Validate and return compression level.
Args:
value: String value from command line
Returns:
int: Valid compression level (1-22)
Raises:
argparse.ArgumentTypeError: If value is not a valid compression level
"""
try:
level = int(value)
if not 1 <= level <= 22:
raise argparse.ArgumentTypeError(
f"Invalid compression level: {level}. Must be between 1 and 22."
)
return level
except ValueError:
raise argparse.ArgumentTypeError(
f"Invalid compression level: '{value}'. Must be an integer between 1 and 22."
)
def cmd_add(args) -> int:
"""Command handler for creating/adding to archives.
@@ -511,9 +536,8 @@ Documentation:
"-l",
"--level",
dest="compression_level",
type=int,
type=validate_compression_level,
default=3,
choices=range(1, 23),
metavar="LEVEL",
help="Compression level (1-22, default: 3)",
)
@@ -628,6 +652,7 @@ def main(argv: list[str] | None = None) -> int:
int: Exit code for the program
- 0: Success
- 1: No command specified (help displayed)
- 2: Argument parsing error (invalid arguments)
- Other codes: Specific to individual command handlers
Note:
@@ -642,7 +667,12 @@ def main(argv: list[str] | None = None) -> int:
print()
parser = create_parser()
args = parser.parse_args(argv)
try:
args = parser.parse_args(argv)
except SystemExit as e:
# Handle argparse errors (invalid arguments, help, etc.)
return e.code if e.code is not None else 1
if not hasattr(args, "func"):
parser.print_help()
+71
View File
@@ -1033,3 +1033,74 @@ class TestCLIBoundaryConditions:
except OSError:
# Skip if filesystem doesn't support such long names
pytest.skip("Filesystem doesn't support long filenames")
class TestCompressionLevelValidation:
"""Test compression level validation in CLI."""
def test_valid_compression_levels(self, temp_dir):
"""Test that valid compression levels (1-22) work correctly."""
test_file = temp_dir / "test.txt"
test_file.write_text("Test content")
# Test boundary values and some middle values
valid_levels = [1, 2, 10, 22]
for level in valid_levels:
archive_path = temp_dir / f"test_level_{level}.tzst"
result = main(["a", str(archive_path), str(test_file), "-l", str(level)])
assert result == 0, f"Compression level {level} should be valid"
def test_invalid_compression_levels(self, temp_dir):
"""Test that invalid compression levels return proper error codes."""
test_file = temp_dir / "test.txt"
test_file.write_text("Test content")
archive_path = temp_dir / "test.tzst"
# Test invalid levels that should return exit code 2 (argparse error)
invalid_levels = [0, 23, 50, 100, -1, -10]
for level in invalid_levels:
result = main(["a", str(archive_path), str(test_file), "-l", str(level)])
assert result == 2, (
f"Invalid compression level {level} should return exit code 2"
)
def test_non_numeric_compression_levels(self, temp_dir):
"""Test that non-numeric compression levels return proper error codes."""
test_file = temp_dir / "test.txt"
test_file.write_text("Test content")
archive_path = temp_dir / "test.tzst"
# Test non-numeric values
invalid_values = ["abc", "1.5", "high", "max", ""]
for value in invalid_values:
result = main(["a", str(archive_path), str(test_file), "-l", value])
assert result == 2, (
f"Non-numeric compression level '{value}' should return exit code 2"
)
def test_compression_level_clamping(self, temp_dir):
"""Test compression level validation with extreme values."""
test_file = temp_dir / "test.txt"
test_file.write_text("Test content")
archive_path = temp_dir / "test.tzst"
# Test level 50 - should return argparse error code 2
result = main(["a", str(archive_path), str(test_file), "-l", "50"])
assert result == 2, "Compression level 50 should return exit code 2"
def test_extreme_compression_levels(self, temp_dir):
"""Test extreme compression level values."""
test_file = temp_dir / "test.txt"
test_file.write_text("Test content")
archive_path = temp_dir / "test.tzst"
# Test level 50 - should return argparse error code 2
result = main(["a", str(archive_path), str(test_file), "-l", "50"])
assert result == 2, "Extreme compression level 50 should return exit code 2"
# Test level 0 - should return argparse error code 2
result = main(["a", str(archive_path), str(test_file), "-l", "0"])
assert result == 2, "Extreme compression level 0 should return exit code 2"