apt-tx/tests/error_scenarios.rs
robojerk 2daad2837d Major improvements: rollbacks, testing, docs, and code quality
- Fixed rollback implementation with two-phase approach (remove new, downgrade upgraded)
- Added explicit package tracking (newly_installed vs upgraded)
- Implemented graceful error handling with fail-fast approach
- Added comprehensive test suite (20 tests across 3 test files)
- Created centralized APT command execution module (apt_commands.rs)
- Added configuration system with dry-run, quiet, and APT options
- Reduced code duplication and improved maintainability
- Added extensive documentation (rollbacks.md, rollbacks-not-featured.md, ffi-bridge.md)
- Created configuration usage example
- Updated README with crate usage instructions
- All tests passing, clean compilation, production-ready
2025-09-13 11:21:35 -07:00

136 lines
4.4 KiB
Rust

//! Error scenario tests for APT wrapper
//!
//! These tests verify error handling in various failure conditions.
use apt_wrapper::{AptTransaction, init};
#[test]
fn test_invalid_package_names() {
let mut tx = AptTransaction::new().expect("Failed to create transaction");
// Test various invalid package names
let invalid_names = vec![
"", // Empty string
" ", // Whitespace only
"package-with-invalid-chars!@#", // Special characters
"very-long-package-name-that-is-unlikely-to-exist-and-should-fail-validation-123456789", // Too long
];
for invalid_name in invalid_names {
let result = tx.add_package(invalid_name);
assert!(result.is_err(), "Should fail for invalid package name: '{}'", invalid_name);
}
}
#[test]
fn test_nonexistent_packages() {
let mut tx = AptTransaction::new().expect("Failed to create transaction");
// Test packages that definitely don't exist
let nonexistent_packages = vec![
"this-package-definitely-does-not-exist-12345",
"another-nonexistent-package-67890",
"fake-package-name-xyz",
];
for package in nonexistent_packages {
let result = tx.add_package(package);
assert!(result.is_err(), "Should fail for nonexistent package: {}", package);
}
}
#[test]
fn test_transaction_error_recovery() {
let mut tx = AptTransaction::new().expect("Failed to create transaction");
// Add a valid package first
tx.add_package("apt").expect("Failed to add valid package");
assert_eq!(tx.packages().len(), 1);
// Try to add an invalid package
let result = tx.add_package("nonexistent-package-12345");
assert!(result.is_err());
// Transaction should still be valid with the good package
assert_eq!(tx.packages().len(), 1);
assert!(!tx.is_empty());
}
#[test]
fn test_rollback_empty_transaction() {
let tx = AptTransaction::new().expect("Failed to create transaction");
// Rollback of empty transaction should succeed
tx.rollback().expect("Rollback of empty transaction should succeed");
}
#[test]
fn test_rollback_without_commit() {
let mut tx = AptTransaction::new().expect("Failed to create transaction");
// Add packages but don't commit
tx.add_package("apt").expect("Failed to add package");
// Rollback should succeed (nothing to rollback)
tx.rollback().expect("Rollback without commit should succeed");
// Changed packages should be empty
assert!(tx.changed_packages().is_empty());
}
#[test]
fn test_duplicate_package_handling() {
let mut tx = AptTransaction::new().expect("Failed to create transaction");
// Add the same package twice
tx.add_package("apt").expect("Failed to add package first time");
tx.add_package("apt").expect("Failed to add package second time");
// Current implementation allows duplicates (this is expected behavior)
assert_eq!(tx.packages().len(), 2);
// Both instances should be the same package
assert_eq!(tx.packages()[0], "apt");
assert_eq!(tx.packages()[1], "apt");
}
#[test]
fn test_transaction_state_after_errors() {
let mut tx = AptTransaction::new().expect("Failed to create transaction");
// Add valid packages
tx.add_package("apt").expect("Failed to add apt");
tx.add_package("curl").expect("Failed to add curl");
// Try to add invalid package
let _ = tx.add_package("invalid-package-12345");
// Transaction should still be valid
assert_eq!(tx.packages().len(), 2);
assert!(!tx.is_empty());
// Resolve should still work
tx.resolve().expect("Resolve should work after error");
}
#[test]
fn test_error_messages_are_descriptive() {
let mut tx = AptTransaction::new().expect("Failed to create transaction");
// Test that error messages contain useful information
let result = tx.add_package("nonexistent-package-12345");
assert!(result.is_err());
let error_msg = format!("{}", result.unwrap_err());
assert!(error_msg.contains("Package not found") || error_msg.contains("nonexistent-package-12345"));
}
#[test]
fn test_initialization_error_handling() {
// This test verifies that init() handles errors gracefully
// In a real environment, this should work, but we test the error path
let result = init();
// We can't assert success since APT might not be available in test environment
// Just ensure it doesn't panic
let _ = result;
}