Files
shell/immich/test-immich-restore.sh
Peter Wood 58b5dea8b4 Refactor variable assignments and improve script readability in validate-plex-backups.sh and validate-plex-recovery.sh
- Changed inline variable assignments to separate declaration and assignment for clarity.
- Updated condition checks and log messages for better readability and consistency.
- Added a backup of validate-plex-recovery.sh for safety.
- Introduced a new script run-docker-tests.sh for testing setup in Docker containers.
- Enhanced ssh-login.sh to improve condition checks and logging functionality.
2025-06-05 17:14:02 -04:00

427 lines
13 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Immich Restore Script Test Suite
# This script tests the restoration functionality with mock data and validation
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Test configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEST_DIR="${SCRIPT_DIR}/test_data"
RESTORE_SCRIPT="${SCRIPT_DIR}/restore-immich.sh"
TEST_LOG="${SCRIPT_DIR}/../logs/immich-restore-test.log"
# Test counters
TESTS_RUN=0
TESTS_PASSED=0
TESTS_FAILED=0
# Create test directory
mkdir -p "$TEST_DIR"
mkdir -p "$(dirname "$TEST_LOG")"
# Logging function
log_test() {
local message="$1"
echo "$(date '+%Y-%m-%d %H:%M:%S') - TEST: $message" | tee -a "$TEST_LOG"
}
log_pass() {
local test_name="$1"
echo -e "${GREEN}✅ PASS${NC}: $test_name"
echo "$(date '+%Y-%m-%d %H:%M:%S') - PASS: $test_name" >> "$TEST_LOG"
TESTS_PASSED=$((TESTS_PASSED + 1))
}
log_fail() {
local test_name="$1"
local details="$2"
echo -e "${RED}❌ FAIL${NC}: $test_name"
[ -n "$details" ] && echo " Details: $details"
echo "$(date '+%Y-%m-%d %H:%M:%S') - FAIL: $test_name - $details" >> "$TEST_LOG"
TESTS_FAILED=$((TESTS_FAILED + 1))
}
log_info() {
local message="$1"
echo -e "${BLUE} INFO${NC}: $message"
}
# Test script existence and permissions
test_script_setup() {
TESTS_RUN=$((TESTS_RUN + 1))
log_test "Script Setup Validation"
if [ -f "$RESTORE_SCRIPT" ]; then
if [ -x "$RESTORE_SCRIPT" ]; then
log_pass "Script exists and is executable"
else
log_fail "Script exists but is not executable"
chmod +x "$RESTORE_SCRIPT"
log_info "Made script executable"
fi
else
log_fail "Restore script not found at $RESTORE_SCRIPT"
return 1
fi
}
# Test help functionality
test_help_functionality() {
TESTS_RUN=$((TESTS_RUN + 1))
log_test "Help Functionality"
local help_output
if help_output=$("$RESTORE_SCRIPT" --help 2>&1); then
if echo "$help_output" | grep -q "Usage:"; then
log_pass "Help command works and shows usage"
else
log_fail "Help command runs but doesn't show proper usage"
fi
else
log_fail "Help command failed to execute"
fi
}
# Create mock backup files
create_mock_backups() {
log_test "Creating mock backup files for testing"
# Create mock database backup (gzipped SQL)
local mock_db_backup="${TEST_DIR}/mock_immich_db_backup_20250603_120000.sql.gz"
echo "-- Mock Immich Database Backup
CREATE DATABASE IF NOT EXISTS immich;
USE immich;
CREATE TABLE IF NOT EXISTS test_table (id INT PRIMARY KEY, name VARCHAR(100));
INSERT INTO test_table VALUES (1, 'test_data');
-- End of mock backup" | gzip > "$mock_db_backup"
# Create mock uploads backup (tar.gz)
local mock_uploads_backup="${TEST_DIR}/mock_immich_uploads_20250603_120000.tar.gz"
mkdir -p "${TEST_DIR}/mock_uploads/upload"
mkdir -p "${TEST_DIR}/mock_uploads/thumbs"
echo "Mock photo data" > "${TEST_DIR}/mock_uploads/upload/photo1.jpg"
echo "Mock thumbnail data" > "${TEST_DIR}/mock_uploads/thumbs/thumb1.jpg"
tar -czf "$mock_uploads_backup" -C "${TEST_DIR}" mock_uploads
# Create corrupted backup files for testing
echo "corrupted data" > "${TEST_DIR}/corrupted_db.sql.gz"
echo "not a tar file" > "${TEST_DIR}/corrupted_uploads.tar.gz"
log_info "Mock backup files created"
return 0
}
# Test dry-run functionality
test_dry_run() {
TESTS_RUN=$((TESTS_RUN + 1))
log_test "Dry Run Functionality"
local mock_db_backup="${TEST_DIR}/mock_immich_db_backup_20250603_120000.sql.gz"
local mock_uploads_backup="${TEST_DIR}/mock_immich_uploads_20250603_120000.tar.gz"
local output
if output=$("$RESTORE_SCRIPT" --db-backup "$mock_db_backup" --uploads-backup "$mock_uploads_backup" --dry-run 2>&1); then
if echo "$output" | grep -q "DRY RUN MODE"; then
log_pass "Dry run mode works correctly"
else
log_fail "Dry run executed but didn't show proper dry run message"
fi
else
log_fail "Dry run command failed"
fi
}
# Test file validation
test_file_validation() {
TESTS_RUN=$((TESTS_RUN + 1))
log_test "Backup File Validation"
# Test with non-existent files
local output
if output=$("$RESTORE_SCRIPT" --db-backup "/nonexistent/file.sql.gz" --uploads-backup "/nonexistent/file.tar.gz" --dry-run 2>&1); then
log_fail "Script should fail with non-existent files but didn't"
else
if echo "$output" | grep -q "not found"; then
log_pass "File validation correctly detects missing files"
else
log_fail "Script failed but not with expected error message"
fi
fi
}
# Test corrupted file detection
test_corrupted_file_detection() {
TESTS_RUN=$((TESTS_RUN + 1))
log_test "Corrupted File Detection"
local corrupted_db="${TEST_DIR}/corrupted_db.sql.gz"
local corrupted_uploads="${TEST_DIR}/corrupted_uploads.tar.gz"
local output
if output=$("$RESTORE_SCRIPT" --db-backup "$corrupted_db" --uploads-backup "$corrupted_uploads" --dry-run 2>&1); then
log_fail "Script should detect corrupted files but didn't"
else
if echo "$output" | grep -q "corrupted"; then
log_pass "Corrupted file detection works"
else
log_fail "Script failed but not with corrupted file error"
fi
fi
}
# Test skip options
test_skip_options() {
TESTS_RUN=$((TESTS_RUN + 1))
log_test "Skip Options Functionality"
# Test skip-db option
local output
if output=$("$RESTORE_SCRIPT" --uploads-backup "${TEST_DIR}/mock_immich_uploads_20250603_120000.tar.gz" --skip-db --dry-run 2>&1); then
if echo "$output" | grep -q "Database backup: SKIPPED"; then
log_pass "Skip database option works"
else
log_fail "Skip database option doesn't show correct status"
fi
else
log_fail "Skip database option test failed"
fi
TESTS_RUN=$((TESTS_RUN + 1))
# Test skip-uploads option
if output=$("$RESTORE_SCRIPT" --db-backup "${TEST_DIR}/mock_immich_db_backup_20250603_120000.sql.gz" --skip-uploads --dry-run 2>&1); then
if echo "$output" | grep -q "Uploads backup: SKIPPED"; then
log_pass "Skip uploads option works"
else
log_fail "Skip uploads option doesn't show correct status"
fi
else
log_fail "Skip uploads option test failed"
fi
}
# Test environment variable validation
test_env_validation() {
TESTS_RUN=$((TESTS_RUN + 1))
log_test "Environment Variable Validation"
# Temporarily move .env file to test missing env
local env_file
env_file="$(dirname "$RESTORE_SCRIPT")/../.env"
if [ -f "$env_file" ]; then
mv "$env_file" "${env_file}.backup"
local output
if output=$("$RESTORE_SCRIPT" --help 2>&1); then
if echo "$output" | grep -q "Error.*env"; then
log_pass "Missing environment file detection works"
else
log_fail "Script should detect missing .env file"
fi
else
log_pass "Script correctly fails with missing .env file"
fi
# Restore .env file
mv "${env_file}.backup" "$env_file"
else
log_info "No .env file found to test with"
fi
}
# Test notification system (dry run)
test_notification_system() {
TESTS_RUN=$((TESTS_RUN + 1))
log_test "Notification System"
local mock_db_backup="${TEST_DIR}/mock_immich_db_backup_20250603_120000.sql.gz"
local mock_uploads_backup="${TEST_DIR}/mock_immich_uploads_20250603_120000.tar.gz"
# Set a test webhook URL temporarily
export WEBHOOK_URL="https://httpbin.org/post"
local output
if output=$("$RESTORE_SCRIPT" --db-backup "$mock_db_backup" --uploads-backup "$mock_uploads_backup" --dry-run 2>&1); then
if echo "$output" | grep -q "Immich Restore Started"; then
log_pass "Notification system appears to be working"
else
log_fail "Notification system not triggering properly"
fi
else
log_fail "Test with notifications failed"
fi
unset WEBHOOK_URL
}
# Test argument parsing
test_argument_parsing() {
TESTS_RUN=$((TESTS_RUN + 1))
log_test "Argument Parsing"
# Test unknown option
local output
if output=$("$RESTORE_SCRIPT" --unknown-option 2>&1); then
if echo "$output" | grep -q "Unknown option"; then
log_pass "Unknown option detection works"
else
log_fail "Unknown option should be detected"
fi
else
log_pass "Script correctly fails with unknown option"
fi
}
# Test logging functionality
test_logging() {
TESTS_RUN=$((TESTS_RUN + 1))
log_test "Logging Functionality"
local log_dir
log_dir="$(dirname "$RESTORE_SCRIPT")/../logs"
local restore_log="${log_dir}/immich-restore.log"
# Clear previous log entries
[ -f "$restore_log" ] && true > "$restore_log"
local mock_db_backup="${TEST_DIR}/mock_immich_db_backup_20250603_120000.sql.gz"
local mock_uploads_backup="${TEST_DIR}/mock_immich_uploads_20250603_120000.tar.gz"
"$RESTORE_SCRIPT" --db-backup "$mock_db_backup" --uploads-backup "$mock_uploads_backup" --dry-run >/dev/null 2>&1
if [ -f "$restore_log" ] && [ -s "$restore_log" ]; then
if grep -q "IMMICH RESTORATION STARTED" "$restore_log"; then
log_pass "Logging functionality works"
else
log_fail "Log file exists but doesn't contain expected content"
fi
else
log_fail "Log file not created or is empty"
fi
}
# Performance test with larger mock files
test_performance() {
TESTS_RUN=$((TESTS_RUN + 1))
log_test "Performance with Larger Files"
# Create a larger mock database backup
local large_db_backup="${TEST_DIR}/large_mock_db.sql.gz"
{
echo "-- Large Mock Database Backup"
for i in {1..1000}; do
echo "INSERT INTO test_table VALUES ($i, 'test_data_$i');"
done
echo "-- End of large mock backup"
} | gzip > "$large_db_backup"
# Create larger mock uploads
local large_uploads_backup="${TEST_DIR}/large_mock_uploads.tar.gz"
mkdir -p "${TEST_DIR}/large_mock_uploads"
for i in {1..50}; do
echo "Mock large file content $i" > "${TEST_DIR}/large_mock_uploads/file_$i.txt"
done
tar -czf "$large_uploads_backup" -C "${TEST_DIR}" large_mock_uploads
local start_time
start_time=$(date +%s)
local output
if output=$("$RESTORE_SCRIPT" --db-backup "$large_db_backup" --uploads-backup "$large_uploads_backup" --dry-run 2>&1); then
local end_time
end_time=$(date +%s)
local duration=$((end_time - start_time))
if [ $duration -lt 30 ]; then # Should complete dry run in under 30 seconds
log_pass "Performance test completed in ${duration}s"
else
log_fail "Performance test took too long: ${duration}s"
fi
else
log_fail "Performance test failed to execute"
fi
}
# Cleanup test data
cleanup_test_data() {
log_test "Cleaning up test data"
rm -rf "$TEST_DIR"
log_info "Test data cleaned up"
}
# Generate test report
generate_test_report() {
echo ""
echo "=================================================================="
echo -e "${BLUE}IMMICH RESTORE SCRIPT TEST REPORT${NC}"
echo "=================================================================="
echo "Test Date: $(date)"
echo "Script Tested: $RESTORE_SCRIPT"
echo ""
echo "Test Results:"
echo -e " Total Tests Run: ${BLUE}$TESTS_RUN${NC}"
echo -e " Tests Passed: ${GREEN}$TESTS_PASSED${NC}"
echo -e " Tests Failed: ${RED}$TESTS_FAILED${NC}"
echo ""
if [ $TESTS_FAILED -eq 0 ]; then
echo -e "${GREEN}✅ ALL TESTS PASSED${NC}"
echo "The restore script is ready for production use."
else
echo -e "${RED}❌ SOME TESTS FAILED${NC}"
echo "Please review the test log for details: $TEST_LOG"
fi
echo ""
echo "Test Log Location: $TEST_LOG"
echo "=================================================================="
}
# Main test execution
main() {
echo -e "${BLUE}Starting Immich Restore Script Test Suite${NC}"
echo "Test Directory: $TEST_DIR"
echo "Log File: $TEST_LOG"
echo ""
# Initialize test log
echo "=== Immich Restore Script Test Suite ===" > "$TEST_LOG"
echo "Started: $(date)" >> "$TEST_LOG"
echo "" >> "$TEST_LOG"
# Run all tests
test_script_setup
create_mock_backups
test_help_functionality
test_dry_run
test_file_validation
test_corrupted_file_detection
test_skip_options
test_env_validation
test_notification_system
test_argument_parsing
test_logging
test_performance
# Cleanup and report
cleanup_test_data
generate_test_report
# Exit with appropriate code
if [ $TESTS_FAILED -eq 0 ]; then
exit 0
else
exit 1
fi
}
# Run tests
main "$@"