#!/bin/bash # Test script for apt-layer Advanced ComposeFS Features # Validates the Phase 2.3 implementation: Advanced ComposeFS Features set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Test counters TOTAL_TESTS=0 PASSED_TESTS=0 FAILED_TESTS=0 # Test logging functions log_test() { echo -e "${BLUE}[TEST]${NC} $1" } log_pass() { echo -e "${GREEN}[PASS]${NC} $1" ((PASSED_TESTS++)) } log_fail() { echo -e "${RED}[FAIL]${NC} $1" ((FAILED_TESTS++)) } log_info() { echo -e "${YELLOW}[INFO]${NC} $1" } # Test summary print_summary() { echo "" echo "==========================================" echo "ADVANCED COMPOSEFS FEATURES TEST SUMMARY" echo "==========================================" echo "Total Tests: $TOTAL_TESTS" echo "Passed: $PASSED_TESTS" echo "Failed: $FAILED_TESTS" echo "Success Rate: $((PASSED_TESTS * 100 / TOTAL_TESTS))%" echo "==========================================" if [[ $FAILED_TESTS -eq 0 ]]; then echo -e "${GREEN}All tests passed! Advanced ComposeFS features are working correctly.${NC}" exit 0 else echo -e "${RED}Some tests failed. Please review the output above.${NC}" exit 1 fi } # Cleanup function cleanup() { log_info "Cleaning up test artifacts..." # Unmount any test mounts for mount_point in /tmp/apt-layer-advanced-test-*; do if [[ -d "$mount_point" ]] && mountpoint -q "$mount_point" 2>/dev/null; then umount "$mount_point" 2>/dev/null || true rmdir "$mount_point" 2>/dev/null || true fi done # Remove test files rm -rf /tmp/apt-layer-advanced-test-* } # Setup test environment setup_test_env() { log_info "Setting up advanced test environment..." # Create test directories mkdir -p /tmp/apt-layer-advanced-test-source1 mkdir -p /tmp/apt-layer-advanced-test-source2 mkdir -p /tmp/apt-layer-advanced-test-source3 mkdir -p /tmp/apt-layer-advanced-test-layers mkdir -p /tmp/apt-layer-advanced-test-mounts # Create test source content with duplicates echo "Common file content" > /tmp/apt-layer-advanced-test-source1/common.txt echo "Source 1 unique" > /tmp/apt-layer-advanced-test-source1/unique1.txt echo "Common file content" > /tmp/apt-layer-advanced-test-source1/duplicate.txt echo "Common file content" > /tmp/apt-layer-advanced-test-source2/common.txt echo "Source 2 unique" > /tmp/apt-layer-advanced-test-source2/unique2.txt echo "Common file content" > /tmp/apt-layer-advanced-test-source2/duplicate.txt echo "Source 3 unique" > /tmp/apt-layer-advanced-test-source3/unique3.txt echo "Common file content" > /tmp/apt-layer-advanced-test-source3/duplicate.txt # Create subdirectories mkdir -p /tmp/apt-layer-advanced-test-source1/subdir echo "Subdir file" > /tmp/apt-layer-advanced-test-source1/subdir/file.txt mkdir -p /tmp/apt-layer-advanced-test-source2/subdir echo "Subdir file" > /tmp/apt-layer-advanced-test-source2/subdir/file.txt log_info "Advanced test environment setup completed" } # Test 1: Multi-layer composition test_multi_layer_composition() { ((TOTAL_TESTS++)) log_test "Testing multi-layer composition..." # Create base layers local source1="/tmp/apt-layer-advanced-test-source1" local source2="/tmp/apt-layer-advanced-test-source2" local source3="/tmp/apt-layer-advanced-test-source3" local layer1="/tmp/apt-layer-advanced-test-layers/layer1.composefs" local layer2="/tmp/apt-layer-advanced-test-layers/layer2.composefs" local layer3="/tmp/apt-layer-advanced-test-layers/layer3.composefs" local composed="/tmp/apt-layer-advanced-test-layers/multi-composed.composefs" # Create individual layers if ! apt-layer composefs create "$source1" "$layer1" "layer1"; then log_fail "Failed to create layer1" return 1 fi if ! apt-layer composefs create "$source2" "$layer2" "layer2"; then log_fail "Failed to create layer2" return 1 fi if ! apt-layer composefs create "$source3" "$layer3" "layer3"; then log_fail "Failed to create layer3" return 1 fi # Compose multiple layers if ! apt-layer composefs multi-compose "$layer1" "$layer2" "$layer3" "$composed"; then log_fail "Multi-layer composition failed" return 1 fi # Validate composed layer if ! apt-layer composefs validate "$composed"; then log_fail "Composed layer validation failed" return 1 fi # Test mounting composed layer local mount_point="/tmp/apt-layer-advanced-test-mounts/multi-composed" if ! apt-layer composefs mount "$composed" "$mount_point"; then log_fail "Failed to mount composed layer" return 1 fi # Check if files from all layers are present if [[ ! -f "$mount_point/common.txt" ]]; then log_fail "Common file not found in composed layer" return 1 fi if [[ ! -f "$mount_point/unique1.txt" ]]; then log_fail "Unique1 file not found in composed layer" return 1 fi if [[ ! -f "$mount_point/unique2.txt" ]]; then log_fail "Unique2 file not found in composed layer" return 1 fi if [[ ! -f "$mount_point/unique3.txt" ]]; then log_fail "Unique3 file not found in composed layer" return 1 fi # Unmount apt-layer composefs unmount "$mount_point" log_pass "Multi-layer composition test passed" return 0 } # Test 2: Layer deduplication test_layer_deduplication() { ((TOTAL_TESTS++)) log_test "Testing layer deduplication..." local input_layer="/tmp/apt-layer-advanced-test-layers/multi-composed.composefs" local dedup_layer="/tmp/apt-layer-advanced-test-layers/deduplicated.composefs" # Create input layer if it doesn't exist if [[ ! -f "$input_layer" ]]; then log_info "Creating input layer for deduplication test..." local source1="/tmp/apt-layer-advanced-test-source1" local source2="/tmp/apt-layer-advanced-test-source2" local layer1="/tmp/apt-layer-advanced-test-layers/layer1.composefs" local layer2="/tmp/apt-layer-advanced-test-layers/layer2.composefs" apt-layer composefs create "$source1" "$layer1" "layer1" apt-layer composefs create "$source2" "$layer2" "layer2" apt-layer composefs multi-compose "$layer1" "$layer2" "$input_layer" fi # Deduplicate layer if ! apt-layer composefs deduplicate "$input_layer" "$dedup_layer" "content-hash"; then log_fail "Layer deduplication failed" return 1 fi # Validate deduplicated layer if ! apt-layer composefs validate "$dedup_layer"; then log_fail "Deduplicated layer validation failed" return 1 fi # Check if deduplicated layer is smaller or same size local original_size local dedup_size original_size=$(stat -c%s "$input_layer") dedup_size=$(stat -c%s "$dedup_layer") if [[ $dedup_size -gt $original_size ]]; then log_fail "Deduplicated layer is larger than original" return 1 fi log_pass "Layer deduplication test passed" return 0 } # Test 3: Layer compression test_layer_compression() { ((TOTAL_TESTS++)) log_test "Testing layer compression..." local input_layer="/tmp/apt-layer-advanced-test-layers/deduplicated.composefs" local compressed_gzip="/tmp/apt-layer-advanced-test-layers/compressed-gzip.composefs.gz" local compressed_zstd="/tmp/apt-layer-advanced-test-layers/compressed-zstd.composefs.zst" # Create input layer if it doesn't exist if [[ ! -f "$input_layer" ]]; then log_info "Creating input layer for compression test..." local source1="/tmp/apt-layer-advanced-test-source1" local layer1="/tmp/apt-layer-advanced-test-layers/layer1.composefs" apt-layer composefs create "$source1" "$layer1" "layer1" apt-layer composefs deduplicate "$layer1" "$input_layer" "content-hash" fi # Test gzip compression if ! apt-layer composefs compress "$input_layer" "$compressed_gzip" "gzip" "6"; then log_fail "Gzip compression failed" return 1 fi # Test zstd compression (if available) if command -v zstd &> /dev/null; then if ! apt-layer composefs compress "$input_layer" "$compressed_zstd" "zstd" "3"; then log_fail "Zstd compression failed" return 1 fi # Check compression ratios local original_size local gzip_size local zstd_size original_size=$(stat -c%s "$input_layer") gzip_size=$(stat -c%s "$compressed_gzip") zstd_size=$(stat -c%s "$compressed_zstd") log_info "Compression results:" log_info " Original: $((original_size / 1024)) KB" log_info " Gzip: $((gzip_size / 1024)) KB" log_info " Zstd: $((zstd_size / 1024)) KB" else log_info "Zstd not available, skipping zstd compression test" fi log_pass "Layer compression test passed" return 0 } # Test 4: Layer benchmarking test_layer_benchmarking() { ((TOTAL_TESTS++)) log_test "Testing layer benchmarking..." local layer_path="/tmp/apt-layer-advanced-test-layers/deduplicated.composefs" local benchmark_file="/tmp/apt-layer-advanced-test-layers/benchmark-report.txt" # Create layer if it doesn't exist if [[ ! -f "$layer_path" ]]; then log_info "Creating layer for benchmarking test..." local source1="/tmp/apt-layer-advanced-test-source1" local layer1="/tmp/apt-layer-advanced-test-layers/layer1.composefs" apt-layer composefs create "$source1" "$layer1" "layer1" apt-layer composefs deduplicate "$layer1" "$layer_path" "content-hash" fi # Run benchmark if ! apt-layer composefs benchmark "$layer_path" "$benchmark_file"; then log_fail "Layer benchmarking failed" return 1 fi # Check if benchmark file was created if [[ ! -f "$benchmark_file" ]]; then log_fail "Benchmark report file not created" return 1 fi # Check if benchmark file has content local file_size file_size=$(stat -c%s "$benchmark_file" 2>/dev/null || echo "0") if [[ $file_size -eq 0 ]]; then log_fail "Benchmark report file is empty" return 1 fi log_pass "Layer benchmarking test passed" return 0 } # Test 5: Enhanced metadata handling test_enhanced_metadata() { ((TOTAL_TESTS++)) log_test "Testing enhanced metadata handling..." local source_dir="/tmp/apt-layer-advanced-test-source1" local json_metadata="/tmp/apt-layer-advanced-test-layers/metadata.json" local yaml_metadata="/tmp/apt-layer-advanced-test-layers/metadata.yaml" # Test JSON metadata if ! apt-layer composefs enhanced-metadata "$source_dir" "$json_metadata" "json"; then log_fail "JSON metadata generation failed" return 1 fi # Test YAML metadata if ! apt-layer composefs enhanced-metadata "$source_dir" "$yaml_metadata" "yaml"; then log_fail "YAML metadata generation failed" return 1 fi # Validate JSON metadata if ! command -v jq &> /dev/null; then log_info "jq not available, skipping JSON validation" else if ! jq empty "$json_metadata" 2>/dev/null; then log_fail "Invalid JSON metadata" return 1 fi # Check required fields if ! jq -e '.metadata_version' "$json_metadata" >/dev/null 2>&1; then log_fail "Missing metadata_version in JSON" return 1 fi if ! jq -e '.file_statistics.total_files' "$json_metadata" >/dev/null 2>&1; then log_fail "Missing file_statistics in JSON" return 1 fi fi # Check if metadata files have content local json_size local yaml_size json_size=$(stat -c%s "$json_metadata" 2>/dev/null || echo "0") yaml_size=$(stat -c%s "$yaml_metadata" 2>/dev/null || echo "0") if [[ $json_size -eq 0 ]]; then log_fail "JSON metadata file is empty" return 1 fi if [[ $yaml_size -eq 0 ]]; then log_fail "YAML metadata file is empty" return 1 fi log_pass "Enhanced metadata handling test passed" return 0 } # Test 6: Layer relationship tracking test_layer_relationships() { ((TOTAL_TESTS++)) log_test "Testing layer relationship tracking..." local layer1="/tmp/apt-layer-advanced-test-layers/layer1.composefs" local layer2="/tmp/apt-layer-advanced-test-layers/layer2.composefs" local composed="/tmp/apt-layer-advanced-test-layers/multi-composed.composefs" local relationship_file="/tmp/apt-layer-advanced-test-layers/relationships.json" # Create layers if they don't exist if [[ ! -f "$layer1" ]]; then local source1="/tmp/apt-layer-advanced-test-source1" apt-layer composefs create "$source1" "$layer1" "layer1" fi if [[ ! -f "$layer2" ]]; then local source2="/tmp/apt-layer-advanced-test-source2" apt-layer composefs create "$source2" "$layer2" "layer2" fi if [[ ! -f "$composed" ]]; then apt-layer composefs multi-compose "$layer1" "$layer2" "$composed" fi # Track relationships if ! apt-layer composefs track-relationships "$composed" "$relationship_file" "$layer1" "$layer2"; then log_fail "Layer relationship tracking failed" return 1 fi # Check if relationship file was created if [[ ! -f "$relationship_file" ]]; then log_fail "Relationship file not created" return 1 fi # Validate relationship file (basic check) if ! command -v jq &> /dev/null; then log_info "jq not available, skipping relationship validation" else if ! jq empty "$relationship_file" 2>/dev/null; then log_fail "Invalid relationship JSON" return 1 fi # Check required fields if ! jq -e '.layer_id' "$relationship_file" >/dev/null 2>&1; then log_fail "Missing layer_id in relationship file" return 1 fi if ! jq -e '.parent_layers' "$relationship_file" >/dev/null 2>&1; then log_fail "Missing parent_layers in relationship file" return 1 fi fi log_pass "Layer relationship tracking test passed" return 0 } # Test 7: Advanced conflict resolution test_advanced_conflict_resolution() { ((TOTAL_TESTS++)) log_test "Testing advanced conflict resolution..." # Create conflicting layers local conflict_source1="/tmp/apt-layer-advanced-test-conflict1" local conflict_source2="/tmp/apt-layer-advanced-test-conflict2" local conflict_layer1="/tmp/apt-layer-advanced-test-layers/conflict1.composefs" local conflict_layer2="/tmp/apt-layer-advanced-test-layers/conflict2.composefs" local resolved_layer="/tmp/apt-layer-advanced-test-layers/resolved.composefs" local conflict_report="/tmp/apt-layer-advanced-test-layers/conflict-report.txt" # Create conflicting sources mkdir -p "$conflict_source1" "$conflict_source2" echo "Version 1 of conflicting file" > "$conflict_source1/conflict.txt" echo "Version 2 of conflicting file" > "$conflict_source2/conflict.txt" echo "Unique to source 1" > "$conflict_source1/unique1.txt" echo "Unique to source 2" > "$conflict_source2/unique2.txt" # Create layers if ! apt-layer composefs create "$conflict_source1" "$conflict_layer1" "conflict1"; then log_fail "Failed to create conflict layer 1" return 1 fi if ! apt-layer composefs create "$conflict_source2" "$conflict_layer2" "conflict2"; then log_fail "Failed to create conflict layer 2" return 1 fi # Resolve conflicts if ! apt-layer composefs resolve-conflicts "$conflict_layer1" "$conflict_layer2" "$resolved_layer" "$conflict_report"; then log_fail "Conflict resolution failed" return 1 fi # Check if conflict report was created if [[ ! -f "$conflict_report" ]]; then log_fail "Conflict report not created" return 1 fi # Validate resolved layer if ! apt-layer composefs validate "$resolved_layer"; then log_fail "Resolved layer validation failed" return 1 fi # Test mounting resolved layer local mount_point="/tmp/apt-layer-advanced-test-mounts/resolved" if ! apt-layer composefs mount "$resolved_layer" "$mount_point"; then log_fail "Failed to mount resolved layer" return 1 fi # Check if files are present if [[ ! -f "$mount_point/conflict.txt" ]]; then log_fail "Conflicting file not found in resolved layer" return 1 fi if [[ ! -f "$mount_point/unique1.txt" ]]; then log_fail "Unique1 file not found in resolved layer" return 1 fi if [[ ! -f "$mount_point/unique2.txt" ]]; then log_fail "Unique2 file not found in resolved layer" return 1 fi # Unmount apt-layer composefs unmount "$mount_point" log_pass "Advanced conflict resolution test passed" return 0 } # Test 8: Performance testing test_performance_features() { ((TOTAL_TESTS++)) log_test "Testing performance features..." local layer_path="/tmp/apt-layer-advanced-test-layers/deduplicated.composefs" local benchmark_file="/tmp/apt-layer-advanced-test-layers/performance-benchmark.txt" # Create layer if it doesn't exist if [[ ! -f "$layer_path" ]]; then log_info "Creating layer for performance test..." local source1="/tmp/apt-layer-advanced-test-source1" local layer1="/tmp/apt-layer-advanced-test-layers/layer1.composefs" apt-layer composefs create "$source1" "$layer1" "layer1" apt-layer composefs deduplicate "$layer1" "$layer_path" "content-hash" fi # Run performance benchmark local start_time local end_time local benchmark_time start_time=$(date +%s.%N) if ! apt-layer composefs benchmark "$layer_path" "$benchmark_file"; then log_fail "Performance benchmarking failed" return 1 fi end_time=$(date +%s.%N) benchmark_time=$(echo "$end_time - $start_time" | bc -l 2>/dev/null || echo "0") log_info "Benchmark execution time: ${benchmark_time}s" # Check if benchmark completed within reasonable time (30 seconds) if [[ $(echo "$benchmark_time > 30" | bc -l 2>/dev/null || echo "0") -eq 1 ]]; then log_fail "Benchmark took too long: ${benchmark_time}s" return 1 fi log_pass "Performance features test passed" return 0 } # Main test execution main() { echo "==========================================" echo "apt-layer ADVANCED COMPOSEFS FEATURES TEST" echo "==========================================" echo "Testing Phase 2.3: Advanced ComposeFS Features" echo "==========================================" echo "" # Setup test environment setup_test_env # Run tests test_multi_layer_composition test_layer_deduplication test_layer_compression test_layer_benchmarking test_enhanced_metadata test_layer_relationships test_advanced_conflict_resolution test_performance_features # Print summary print_summary } # Cleanup on exit trap cleanup EXIT # Run main function main "$@"