tarballer/test/test.sh

368 lines
13 KiB
Bash
Executable File

#!/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}
# Function to generate a random file with predictable size
generate_random_file() {
local OUTPUT=$1
local SIZE=$2
dd if=/dev/urandom bs=1 count=$SIZE of="$OUTPUT" 2>/dev/null
}
# Generate random string (for file contents)
generate_random_string() {
local LENGTH=$1
tr -dc A-Za-z0-9 </dev/urandom | head -c $LENGTH
}
cleanup_files() {
if [ "$KEEP_TEMP_FILES" -eq 0 ]; then
echo "=== CLEANING UP TEMPORARY FILES ==="
rm -rf /tmp/complex /tmp/complex-extracted
rm -f /tmp/complex-original-md5.txt /tmp/complex-extracted-md5.txt
rm -rf /tmp/standard-test /tmp/standard-extracted /tmp/reference-extracted
rm -f /tmp/original-checksums.txt /tmp/standard-checksums.txt /tmp/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 /tmp/complex /tmp/complex-extracted
rm -f /tmp/complex-original-md5.txt /tmp/complex-extracted-md5.txt
# Create complex directory structure
mkdir -p /tmp/complex/dir1/subdir1/subsubdir1
mkdir -p /tmp/complex/dir1/subdir2
mkdir -p /tmp/complex/dir2/subdir1
# Create files at different levels with random content
echo "root level file ($(generate_random_string 8))" > /tmp/complex/rootfile.txt
echo "level 1 file in dir1 ($(generate_random_string 12))" > /tmp/complex/dir1/file1.txt
echo "level 1 file in dir2 ($(generate_random_string 16))" > /tmp/complex/dir2/file2.txt
echo "level 2 file in subdir1 ($(generate_random_string 10))" > /tmp/complex/dir1/subdir1/file3.txt
echo "level 2 file in subdir2 ($(generate_random_string 14))" > /tmp/complex/dir1/subdir2/file4.txt
echo "level 3 file in subsubdir1 ($(generate_random_string 20))" > /tmp/complex/dir1/subdir1/subsubdir1/file5.txt
# Add random binary files of different sizes
generate_random_file "/tmp/complex/random_binary_small.bin" 512
generate_random_file "/tmp/complex/dir1/random_binary_medium.bin" 2048
generate_random_file "/tmp/complex/dir2/random_binary_large.bin" 8192
# Create a symbolic link with a relative path instead of absolute
cd /tmp/complex/dir2 && ln -s ../rootfile.txt symlink.txt && cd /workdir
# Calculate MD5 hashes of original files for verification
find /tmp/complex -type f | sort | xargs md5sum > /tmp/complex-original-md5.txt
# Print the original structure for reference
echo '=== ORIGINAL DIRECTORY STRUCTURE ==='
find /tmp/complex -type f -o -type l | sort
# Create the tarball
/bin/tarballer -source /tmp/complex -output /workdir/complex.tar.gz -prefix complex-app
# Extract the tarball
mkdir -p /tmp/complex-extracted
tar -xzf /workdir/complex.tar.gz -C /tmp/complex-extracted
# Verify the extracted structure
echo '=== EXTRACTED DIRECTORY STRUCTURE ==='
find /tmp/complex-extracted -type f -o -type l | sort
# Calculate MD5 hashes of extracted files
find /tmp/complex-extracted -type f | sort | xargs md5sum > /tmp/complex-extracted-md5.txt
# Compare file content
echo '=== VERIFYING FILE CONTENTS ==='
cat /tmp/complex/rootfile.txt
echo ' <-- Original: rootfile.txt'
cat /tmp/complex-extracted/complex-app/rootfile.txt
echo ' <-- Extracted: rootfile.txt'
cat /tmp/complex/dir1/subdir1/subsubdir1/file5.txt
echo ' <-- Original: deep nested file5.txt'
cat /tmp/complex-extracted/complex-app/dir1/subdir1/subsubdir1/file5.txt
echo ' <-- Extracted: deep nested file5.txt'
# Verify binary file MD5 hashes specifically
echo '=== VERIFYING BINARY FILE MD5 HASHES ==='
md5sum /tmp/complex/random_binary_small.bin
md5sum /tmp/complex-extracted/complex-app/random_binary_small.bin
md5sum /tmp/complex/dir1/random_binary_medium.bin
md5sum /tmp/complex-extracted/complex-app/dir1/random_binary_medium.bin
md5sum /tmp/complex/dir2/random_binary_large.bin
md5sum /tmp/complex-extracted/complex-app/dir2/random_binary_large.bin
# Test symlink
echo '=== TESTING SYMLINK ==='
ls -la /tmp/complex/dir2/symlink.txt
ls -la /tmp/complex-extracted/complex-app/dir2/symlink.txt
# Verify MD5 hashes
echo '=== MD5 HASH VERIFICATION ==='
echo 'Original file hashes:'
cat /tmp/complex-original-md5.txt
echo 'Extracted file hashes:'
cat /tmp/complex-extracted-md5.txt
# Verify hash comparison
echo '=== COMPARING FILE HASHES ==='
# Extract just file paths from original hashes
ORIG_FILES=$(cat /tmp/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" /tmp/complex-original-md5.txt | awk '{print $1}')
# Find the corresponding file in the extracted directory and get its hash
EXTRACTED_FILE=$(find /tmp/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" /tmp/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 /tmp/standard-test /tmp/standard-extracted /tmp/reference-extracted
rm -f /tmp/original-checksums.txt /tmp/standard-checksums.txt /tmp/reference-checksums.txt
# Create a diverse test directory structure
mkdir -p /tmp/standard-test/config/settings
mkdir -p /tmp/standard-test/data/user/documents
mkdir -p /tmp/standard-test/data/user/pictures
mkdir -p /tmp/standard-test/logs
# Create various file types with random content
echo "{\"app\": \"tarballer\", \"version\": \"1.0\", \"random_data\": \"$(generate_random_string 32)\"}" > /tmp/standard-test/config/settings/app.json
echo "debug=true\nlog_level=$(generate_random_string 5)\ndate_format=\"$(generate_random_string 8)\"" > /tmp/standard-test/config/settings/debug.conf
# Create binary files of different sizes
generate_random_file "/tmp/standard-test/data/user/documents/binary.dat" 10240
generate_random_file "/tmp/standard-test/data/user/pictures/image1.raw" 5120
generate_random_file "/tmp/standard-test/data/user/pictures/image2.raw" 7168
# Create log files with random entries
echo "Test log entry 1 - $(generate_random_string 16)" > /tmp/standard-test/logs/app.log
echo "Test log entry 2 - $(generate_random_string 24)" >> /tmp/standard-test/logs/app.log
echo "Test log entry 3 - $(generate_random_string 20)" >> /tmp/standard-test/logs/app.log
# Create text file with random data
generate_random_string 1024 > /tmp/standard-test/data/user/documents/text_file.txt
# Create config file with mixed content
cat << EOF > /tmp/standard-test/config/mixed_content.conf
# Configuration file with mixed content
SERVER_NAME=$(generate_random_string 12)
PORT=8080
MAX_CONNECTIONS=100
TIMEOUT=30
RANDOM_SEED=$(generate_random_string 64)
EOF
# Create symlinks
ln -s ../config/settings/app.json /tmp/standard-test/data/config-link.json
ln -s ../../logs/app.log /tmp/standard-test/data/user/log-link.txt
# Store MD5 hashes of original files for comparison
find /tmp/standard-test -type f | sort | xargs md5sum > /tmp/original-checksums.txt
# Create tarball using our utility
/bin/tarballer -source /tmp/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 /tmp/standard-test --transform 's,^./,app/,' .
echo '=== TARBALLER OUTPUT ==='
mkdir -p /tmp/standard-extracted
tar -xzf /workdir/standard.tar.gz -C /tmp/standard-extracted
find /tmp/standard-extracted -type f -o -type l | sort
# Extract reference tarball
echo '=== REFERENCE TAR OUTPUT ==='
mkdir -p /tmp/reference-extracted
tar -xzf /workdir/reference.tar.gz -C /tmp/reference-extracted
find /tmp/reference-extracted -type f -o -type l | sort
# Verify checksums match for all extracted files
echo '=== CHECKSUMS OF EXTRACTED FILES ==='
find /tmp/standard-extracted -type f | sort | xargs md5sum > /tmp/standard-checksums.txt
find /tmp/reference-extracted -type f | sort | xargs md5sum > /tmp/reference-checksums.txt
echo 'ORIGINAL FILE CHECKSUMS:'
cat /tmp/original-checksums.txt
echo 'TARBALLER EXTRACTED CHECKSUMS:'
cat /tmp/standard-checksums.txt
echo 'REFERENCE TAR EXTRACTED CHECKSUMS:'
cat /tmp/reference-checksums.txt
# Compare MD5 checksums systematically
echo '=== SYSTEMATIC MD5 COMPARISON ==='
# Compare original files to tarballer extraction
MATCH_COUNT=0
EXPECTED_COUNT=$(cat /tmp/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 /tmp/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" /tmp/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 < /tmp/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 /tmp/reference-extracted -name "$FILENAME" | head -1)
if [ -n "$EXTRACTED_FILE" ]; then
# Get the hash of the extracted file
EXTRACTED_HASH=$(grep "$EXTRACTED_FILE" /tmp/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 < /tmp/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 /tmp/standard-test -type l -exec ls -la {} \;
echo 'EXTRACTED SYMLINKS:'
find /tmp/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 /tmp/standard-test -type f | wc -l
echo -n 'Extracted files: ' && find /tmp/standard-extracted -type f | wc -l
# Test symlink functionality
echo '=== TESTING SYMLINK CONTENT ==='
echo 'Original linked content:'
cat /tmp/standard-test/data/config-link.json
echo 'Extracted linked content:'
cat /tmp/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