particle-os-tools/test-advanced-composefs.sh

603 lines
No EOL
20 KiB
Bash

#!/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 "$@"