Refactor test scripts into a single unified test file
This commit is contained in:
parent
9899387fe7
commit
9aeb676111
|
@ -5,4 +5,8 @@
|
||||||
/test/complex/
|
/test/complex/
|
||||||
/test/complex-extracted/
|
/test/complex-extracted/
|
||||||
/test/local/
|
/test/local/
|
||||||
/test/local-extracted/
|
/test/local-extracted/
|
||||||
|
/test/standard-test/
|
||||||
|
/test/standard-extracted/
|
||||||
|
/test/reference-extracted/
|
||||||
|
/test/*-checksums.txt
|
|
@ -37,4 +37,10 @@ COPY --from=builder /app/tarballer-freebsd /bin/
|
||||||
COPY --from=builder /app/tarballer-darwin /bin/
|
COPY --from=builder /app/tarballer-darwin /bin/
|
||||||
|
|
||||||
# Make binaries executable
|
# Make binaries executable
|
||||||
RUN chmod +x /bin/tarballer /bin/tarballer-freebsd /bin/tarballer-darwin
|
RUN chmod +x /bin/tarballer /bin/tarballer-freebsd /bin/tarballer-darwin
|
||||||
|
|
||||||
|
# Copy test script
|
||||||
|
COPY test/test.sh /bin/test.sh
|
||||||
|
|
||||||
|
# Make test script executable
|
||||||
|
RUN chmod +x /bin/test.sh
|
25
README.md
25
README.md
|
@ -9,6 +9,8 @@ A simple utility to create tarballs with a specific directory structure.
|
||||||
- Preserves file permissions and directory structure
|
- Preserves file permissions and directory structure
|
||||||
- Handles symbolic links correctly
|
- Handles symbolic links correctly
|
||||||
- Cross-platform compatibility (FreeBSD, macOS, Linux)
|
- Cross-platform compatibility (FreeBSD, macOS, Linux)
|
||||||
|
- Produces tarballs compatible with standard tar tools
|
||||||
|
- Verified data integrity with MD5 hash comparison
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
|
@ -25,17 +27,24 @@ This will create these binaries in the `./bin` directory:
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
You can run the included test to verify functionality:
|
You can run the included tests to verify functionality:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# Run the basic functionality test
|
||||||
docker compose up --build test
|
docker compose up --build test
|
||||||
|
|
||||||
|
# Run comparison test with standard tar tools
|
||||||
|
docker compose up --build tar-test
|
||||||
```
|
```
|
||||||
|
|
||||||
This will:
|
The tests will:
|
||||||
1. Create a test directory structure with nested directories and symlinks
|
1. Create test directory structures with nested directories and symlinks
|
||||||
2. Create a tarball from it
|
2. Create tarballs from them
|
||||||
3. Extract the tarball
|
3. Extract the tarballs using standard tools
|
||||||
4. Verify the contents and file structure, including symlinks
|
4. Verify the contents and file structure, including symlinks
|
||||||
|
5. Check that symlinks remain functional after extraction
|
||||||
|
6. Compare output with standard tar tools to ensure compatibility
|
||||||
|
7. Verify data integrity with MD5 hashing (original vs. extracted files)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -61,4 +70,8 @@ The usage is the same for all binaries:
|
||||||
./bin/tarballer-freebsd -source ./myproject -output release.tar.gz -prefix app
|
./bin/tarballer-freebsd -source ./myproject -output release.tar.gz -prefix app
|
||||||
```
|
```
|
||||||
|
|
||||||
When extracted, all files will be under the `app/` directory in the tarball.
|
When extracted, all files will be under the `app/` directory in the tarball and can be extracted with standard tools like:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tar -xzf release.tar.gz -C /path/to/extract
|
||||||
|
```
|
|
@ -1,5 +1,3 @@
|
||||||
version: '3'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
build:
|
build:
|
||||||
build:
|
build:
|
||||||
|
@ -20,56 +18,30 @@ services:
|
||||||
working_dir: /workdir
|
working_dir: /workdir
|
||||||
depends_on:
|
depends_on:
|
||||||
- build
|
- build
|
||||||
command: |
|
command: /bin/test.sh all
|
||||||
sh -c "# Clean up existing test directories
|
|
||||||
rm -rf /test/complex /test/complex-extracted &&
|
basic-test:
|
||||||
|
build:
|
||||||
# Create complex directory structure
|
context: .
|
||||||
mkdir -p /test/complex/dir1/subdir1/subsubdir1 &&
|
target: tester
|
||||||
mkdir -p /test/complex/dir1/subdir2 &&
|
volumes:
|
||||||
mkdir -p /test/complex/dir2/subdir1 &&
|
- ./bin:/output
|
||||||
|
- ./test:/test
|
||||||
# Create files at different levels
|
- .:/workdir
|
||||||
echo 'root level file' > /test/complex/rootfile.txt &&
|
working_dir: /workdir
|
||||||
echo 'level 1 file in dir1' > /test/complex/dir1/file1.txt &&
|
depends_on:
|
||||||
echo 'level 1 file in dir2' > /test/complex/dir2/file2.txt &&
|
- build
|
||||||
echo 'level 2 file in subdir1' > /test/complex/dir1/subdir1/file3.txt &&
|
command: /bin/test.sh basic
|
||||||
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 &&
|
tar-test:
|
||||||
|
build:
|
||||||
# Create a symbolic link with a relative path instead of absolute
|
context: .
|
||||||
cd /test/complex/dir2 && ln -s ../rootfile.txt symlink.txt && cd /workdir &&
|
target: tester
|
||||||
|
volumes:
|
||||||
# Print the original structure for reference
|
- ./bin:/output
|
||||||
echo '=== ORIGINAL DIRECTORY STRUCTURE ===' &&
|
- ./test:/test
|
||||||
find /test/complex -type f -o -type l | sort &&
|
- .:/workdir
|
||||||
|
working_dir: /workdir
|
||||||
# Create the tarball
|
depends_on:
|
||||||
/bin/tarballer -source /test/complex -output /workdir/complex.tar.gz -prefix complex-app &&
|
- build
|
||||||
|
command: /bin/test.sh tar
|
||||||
# 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 &&
|
|
||||||
|
|
||||||
# Verify file content matches
|
|
||||||
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 &&
|
|
||||||
|
|
||||||
echo 'All tests completed successfully!'"
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
fe910f3824aa56f69e6c5cfcaa617841 /test/complex-extracted/complex-app/dir1/file1.txt
|
||||||
|
65836cb8234924d22c1e383e4ddce797 /test/complex-extracted/complex-app/dir1/subdir1/file3.txt
|
||||||
|
03fc5818d2424dc1820fec5b6d3ba1ff /test/complex-extracted/complex-app/dir1/subdir1/subsubdir1/file5.txt
|
||||||
|
d4b7a1f50b3302d9523c0dba53f490fc /test/complex-extracted/complex-app/dir1/subdir2/file4.txt
|
||||||
|
604e0b2e70ef84a95fdc3dd6ca2d2d09 /test/complex-extracted/complex-app/dir2/file2.txt
|
||||||
|
788c8c79dbab5ef7507344254f0be0cb /test/complex-extracted/complex-app/rootfile.txt
|
|
@ -0,0 +1,6 @@
|
||||||
|
fe910f3824aa56f69e6c5cfcaa617841 /test/complex/dir1/file1.txt
|
||||||
|
65836cb8234924d22c1e383e4ddce797 /test/complex/dir1/subdir1/file3.txt
|
||||||
|
03fc5818d2424dc1820fec5b6d3ba1ff /test/complex/dir1/subdir1/subsubdir1/file5.txt
|
||||||
|
d4b7a1f50b3302d9523c0dba53f490fc /test/complex/dir1/subdir2/file4.txt
|
||||||
|
604e0b2e70ef84a95fdc3dd6ca2d2d09 /test/complex/dir2/file2.txt
|
||||||
|
788c8c79dbab5ef7507344254f0be0cb /test/complex/rootfile.txt
|
|
@ -0,0 +1,222 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Determine which test to run
|
||||||
|
TEST_TYPE=${1:-"all"}
|
||||||
|
|
||||||
|
run_basic_test() {
|
||||||
|
echo "=== RUNNING BASIC TEST ==="
|
||||||
|
|
||||||
|
# Clean up existing test directories
|
||||||
|
rm -rf /test/complex /test/complex-extracted
|
||||||
|
|
||||||
|
# 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 ==='
|
||||||
|
ORIG_HASHES=$(cat /test/complex-original-md5.txt | awk '{print $1}' | sort)
|
||||||
|
EXTR_HASHES=$(cat /test/complex-extracted-md5.txt | grep -v 'complex-app$' | awk '{print $1}' | sort)
|
||||||
|
|
||||||
|
if [ "$ORIG_HASHES" = "$EXTR_HASHES" ]; 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
|
||||||
|
|
||||||
|
# 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 ==='
|
||||||
|
|
||||||
|
# Extract just the hash part from each file
|
||||||
|
ORIG_HASHES=$(cat /test/original-checksums.txt | awk '{print $1}' | sort)
|
||||||
|
TARB_HASHES=$(cat /test/standard-checksums.txt | awk '{print $1}' | sort)
|
||||||
|
REF_HASHES=$(cat /test/reference-checksums.txt | awk '{print $1}' | sort)
|
||||||
|
|
||||||
|
# Compare original to tarballer extraction
|
||||||
|
if [ "$ORIG_HASHES" = "$TARB_HASHES" ]; then
|
||||||
|
echo 'SUCCESS: Tarballer extraction hashes match original files!'
|
||||||
|
else
|
||||||
|
echo 'ERROR: Hash mismatch detected between original and tarballer extraction!'
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Compare original to reference tar extraction
|
||||||
|
if [ "$ORIG_HASHES" = "$REF_HASHES" ]; then
|
||||||
|
echo 'SUCCESS: Reference tar extraction hashes match original files!'
|
||||||
|
else
|
||||||
|
echo 'ERROR: Hash mismatch detected between original and reference tar extraction!'
|
||||||
|
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
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
"tar")
|
||||||
|
run_tar_comparison_test
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
"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!"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "❌ SOME TESTS FAILED!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown test type: $TEST_TYPE"
|
||||||
|
echo "Usage: $0 [basic|tar|all]"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
Loading…
Reference in New Issue