#!/bin/sh # Determine which test to run TEST_TYPE=${1:-"all"} # Set to 1 to keep temporary files, 0 to clean them up KEEP_TEMP_FILES=${2:-0} cleanup_files() { if [ "$KEEP_TEMP_FILES" -eq 0 ]; then echo "=== CLEANING UP TEMPORARY FILES ===" rm -rf /test/complex /test/complex-extracted rm -f /test/complex-original-md5.txt /test/complex-extracted-md5.txt rm -rf /test/standard-test /test/standard-extracted /test/reference-extracted rm -f /test/original-checksums.txt /test/standard-checksums.txt /test/reference-checksums.txt rm -f /workdir/complex.tar.gz /workdir/standard.tar.gz /workdir/reference.tar.gz echo "Temporary files cleaned up" else echo "Keeping temporary files for inspection" fi } run_basic_test() { echo "=== RUNNING BASIC TEST ===" # Clean up existing test directories rm -rf /test/complex /test/complex-extracted rm -f /test/complex-original-md5.txt /test/complex-extracted-md5.txt # Create complex directory structure mkdir -p /test/complex/dir1/subdir1/subsubdir1 mkdir -p /test/complex/dir1/subdir2 mkdir -p /test/complex/dir2/subdir1 # Create files at different levels echo 'root level file' > /test/complex/rootfile.txt echo 'level 1 file in dir1' > /test/complex/dir1/file1.txt echo 'level 1 file in dir2' > /test/complex/dir2/file2.txt echo 'level 2 file in subdir1' > /test/complex/dir1/subdir1/file3.txt echo 'level 2 file in subdir2' > /test/complex/dir1/subdir2/file4.txt echo 'level 3 file in subsubdir1' > /test/complex/dir1/subdir1/subsubdir1/file5.txt # Create a symbolic link with a relative path instead of absolute cd /test/complex/dir2 && ln -s ../rootfile.txt symlink.txt && cd /workdir # Calculate MD5 hashes of original files for verification find /test/complex -type f | sort | xargs md5sum > /test/complex-original-md5.txt # Print the original structure for reference echo '=== ORIGINAL DIRECTORY STRUCTURE ===' find /test/complex -type f -o -type l | sort # Create the tarball /bin/tarballer -source /test/complex -output /workdir/complex.tar.gz -prefix complex-app # Extract the tarball mkdir -p /test/complex-extracted tar -xzf /workdir/complex.tar.gz -C /test/complex-extracted # Verify the extracted structure echo '=== EXTRACTED DIRECTORY STRUCTURE ===' find /test/complex-extracted -type f -o -type l | sort # Calculate MD5 hashes of extracted files find /test/complex-extracted -type f | sort | xargs md5sum > /test/complex-extracted-md5.txt # Compare file content echo '=== VERIFYING FILE CONTENTS ===' cat /test/complex/rootfile.txt echo ' <-- Original: rootfile.txt' cat /test/complex-extracted/complex-app/rootfile.txt echo ' <-- Extracted: rootfile.txt' cat /test/complex/dir1/subdir1/subsubdir1/file5.txt echo ' <-- Original: deep nested file5.txt' cat /test/complex-extracted/complex-app/dir1/subdir1/subsubdir1/file5.txt echo ' <-- Extracted: deep nested file5.txt' # Test symlink echo '=== TESTING SYMLINK ===' ls -la /test/complex/dir2/symlink.txt ls -la /test/complex-extracted/complex-app/dir2/symlink.txt # Verify MD5 hashes echo '=== MD5 HASH VERIFICATION ===' echo 'Original file hashes:' cat /test/complex-original-md5.txt echo 'Extracted file hashes:' cat /test/complex-extracted-md5.txt # Verify hash comparison echo '=== COMPARING FILE HASHES ===' # Extract just file paths from original hashes ORIG_FILES=$(cat /test/complex-original-md5.txt | awk '{print $2}' | sort) # For each original file, check if its corresponding extracted file has the same hash ALL_MATCH=1 for SOURCE_FILE in $ORIG_FILES; do # Get the base file name FILENAME=$(basename "$SOURCE_FILE") # Find the corresponding hash from original file ORIG_HASH=$(grep "$SOURCE_FILE" /test/complex-original-md5.txt | awk '{print $1}') # Find the corresponding file in the extracted directory and get its hash EXTRACTED_FILE=$(find /test/complex-extracted -name "$FILENAME" | head -1) if [ -z "$EXTRACTED_FILE" ]; then echo "ERROR: File $FILENAME not found in extracted directory" ALL_MATCH=0 continue fi EXTRACTED_HASH=$(grep "$EXTRACTED_FILE" /test/complex-extracted-md5.txt | awk '{print $1}') if [ "$ORIG_HASH" != "$EXTRACTED_HASH" ]; then echo "ERROR: Hash mismatch for $FILENAME: original=$ORIG_HASH extracted=$EXTRACTED_HASH" ALL_MATCH=0 fi done if [ "$ALL_MATCH" -eq 1 ]; then echo 'SUCCESS: All file hashes match between original and extracted files!' else echo 'ERROR: Hash mismatch detected!' return 1 fi echo 'Basic test completed successfully!' return 0 } run_tar_comparison_test() { echo "=== RUNNING TAR COMPARISON TEST ===" # Clean up test directories rm -rf /test/standard-test /test/standard-extracted /test/reference-extracted rm -f /test/original-checksums.txt /test/standard-checksums.txt /test/reference-checksums.txt # Create a diverse test directory structure mkdir -p /test/standard-test/config/settings mkdir -p /test/standard-test/data/user/documents mkdir -p /test/standard-test/data/user/pictures mkdir -p /test/standard-test/logs # Create various file types echo '{"app": "tarballer", "version": "1.0"}' > /test/standard-test/config/settings/app.json echo 'debug=true' > /test/standard-test/config/settings/debug.conf dd if=/dev/urandom bs=1K count=10 of=/test/standard-test/data/user/documents/binary.dat 2>/dev/null echo 'Test log entry 1' > /test/standard-test/logs/app.log echo 'Test log entry 2' >> /test/standard-test/logs/app.log # Create symlinks ln -s ../config/settings/app.json /test/standard-test/data/config-link.json ln -s ../../logs/app.log /test/standard-test/data/user/log-link.txt # Store MD5 hashes of original files for comparison find /test/standard-test -type f | sort | xargs md5sum > /test/original-checksums.txt # Create tarball using our utility /bin/tarballer -source /test/standard-test -output /workdir/standard.tar.gz -prefix app # Create a reference tarball using standard tar for comparison tar -czf /workdir/reference.tar.gz -C /test/standard-test --transform 's,^./,app/,' . echo '=== TARBALLER OUTPUT ===' mkdir -p /test/standard-extracted tar -xzf /workdir/standard.tar.gz -C /test/standard-extracted find /test/standard-extracted -type f -o -type l | sort # Extract reference tarball echo '=== REFERENCE TAR OUTPUT ===' mkdir -p /test/reference-extracted tar -xzf /workdir/reference.tar.gz -C /test/reference-extracted find /test/reference-extracted -type f -o -type l | sort # Verify checksums match for all extracted files echo '=== CHECKSUMS OF EXTRACTED FILES ===' find /test/standard-extracted -type f | sort | xargs md5sum > /test/standard-checksums.txt find /test/reference-extracted -type f | sort | xargs md5sum > /test/reference-checksums.txt echo 'ORIGINAL FILE CHECKSUMS:' cat /test/original-checksums.txt echo 'TARBALLER EXTRACTED CHECKSUMS:' cat /test/standard-checksums.txt echo 'REFERENCE TAR EXTRACTED CHECKSUMS:' cat /test/reference-checksums.txt # Compare MD5 checksums systematically echo '=== SYSTEMATIC MD5 COMPARISON ===' # Compare original files to tarballer extraction MATCH_COUNT=0 EXPECTED_COUNT=$(cat /test/original-checksums.txt | wc -l) # For each original file, find its corresponding extracted file and compare hashes while read -r line; do ORIG_HASH=$(echo "$line" | awk '{print $1}') ORIG_FILE=$(echo "$line" | awk '{print $2}') FILENAME=$(basename "$ORIG_FILE") # Find the corresponding file in the extracted directory EXTRACTED_FILE=$(find /test/standard-extracted -name "$FILENAME" | grep -v ".md5-manifest.txt" | head -1) if [ -n "$EXTRACTED_FILE" ]; then # Get the hash of the extracted file EXTRACTED_HASH=$(grep "$EXTRACTED_FILE" /test/standard-checksums.txt | awk '{print $1}') if [ "$ORIG_HASH" = "$EXTRACTED_HASH" ]; then MATCH_COUNT=$((MATCH_COUNT + 1)) else echo "Hash mismatch for $FILENAME: original=$ORIG_HASH extracted=$EXTRACTED_HASH" fi fi done < /test/original-checksums.txt if [ "$MATCH_COUNT" -eq "$EXPECTED_COUNT" ]; then echo 'SUCCESS: Tarballer extraction hashes match original files!' else echo "ERROR: Hash mismatch detected! Matched $MATCH_COUNT of $EXPECTED_COUNT files." return 1 fi # Similar check for reference tar extraction MATCH_COUNT=0 while read -r line; do ORIG_HASH=$(echo "$line" | awk '{print $1}') ORIG_FILE=$(echo "$line" | awk '{print $2}') FILENAME=$(basename "$ORIG_FILE") # Find the corresponding file in the extracted directory EXTRACTED_FILE=$(find /test/reference-extracted -name "$FILENAME" | head -1) if [ -n "$EXTRACTED_FILE" ]; then # Get the hash of the extracted file EXTRACTED_HASH=$(grep "$EXTRACTED_FILE" /test/reference-checksums.txt | awk '{print $1}') if [ "$ORIG_HASH" = "$EXTRACTED_HASH" ]; then MATCH_COUNT=$((MATCH_COUNT + 1)) else echo "Hash mismatch for $FILENAME: original=$ORIG_HASH reference=$EXTRACTED_HASH" fi fi done < /test/original-checksums.txt if [ "$MATCH_COUNT" -eq "$EXPECTED_COUNT" ]; then echo 'SUCCESS: Reference tar extraction hashes match original files!' else echo "ERROR: Hash mismatch detected! Matched $MATCH_COUNT of $EXPECTED_COUNT files." return 1 fi echo '=== VERIFYING SYMLINKS ===' echo 'ORIGINAL SYMLINKS:' find /test/standard-test -type l -exec ls -la {} \; echo 'EXTRACTED SYMLINKS:' find /test/standard-extracted -type l -exec ls -la {} \; # Compare file counts to ensure all files were extracted echo '=== FILE COUNT COMPARISON ===' echo -n 'Original files: ' && find /test/standard-test -type f | wc -l echo -n 'Extracted files: ' && find /test/standard-extracted -type f | wc -l # Test symlink functionality echo '=== TESTING SYMLINK CONTENT ===' echo 'Original linked content:' cat /test/standard-test/data/config-link.json echo 'Extracted linked content:' cat /test/standard-extracted/app/data/config-link.json echo 'Tar comparison test completed successfully!' return 0 } # Main script execution case "$TEST_TYPE" in "basic") run_basic_test RESULT=$? [ "$RESULT" -eq 0 ] && cleanup_files exit $RESULT ;; "tar") run_tar_comparison_test RESULT=$? [ "$RESULT" -eq 0 ] && cleanup_files exit $RESULT ;; "all") echo "=== RUNNING ALL TESTS ===" run_basic_test BASIC_RESULT=$? run_tar_comparison_test TAR_RESULT=$? if [ $BASIC_RESULT -eq 0 ] && [ $TAR_RESULT -eq 0 ]; then echo "✅ ALL TESTS PASSED SUCCESSFULLY!" cleanup_files exit 0 else echo "❌ SOME TESTS FAILED!" exit 1 fi ;; "clean") cleanup_files exit 0 ;; *) echo "Unknown test type: $TEST_TYPE" echo "Usage: $0 [basic|tar|all|clean] [keep_temp_files]" echo " keep_temp_files: 0 (clean up, default) or 1 (keep temp files)" exit 1 ;; esac