1
0
Fork 0
collect/test.sh
Andrew Tomaka 814e0650de Fix test suite cleanup to handle failures and interruptions
Add proper cleanup handling using bash trap to ensure test artifacts
are removed regardless of how the test script exits.

Changes:
- Add cleanup() function to remove all test artifacts
- Set trap to call cleanup on EXIT (success, failure, or interruption)
- Remove redundant manual cleanup since trap handles it automatically
- Add error suppression to prevent cleanup failures

This fixes the defect where test artifacts would remain if a test failed
or the script was interrupted before reaching the manual cleanup section.
2025-06-12 22:15:27 -04:00

237 lines
No EOL
9.1 KiB
Bash
Executable file

#!/bin/bash
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Test counter
TESTS_PASSED=0
TESTS_FAILED=0
# Cleanup function
cleanup() {
echo -e "\n${YELLOW}Cleaning up test artifacts...${NC}"
rm -rf test test-*.tgz test-*.zip collect /tmp/test_output.txt 2>/dev/null || true
echo -e "${GREEN}Cleanup completed.${NC}"
}
# Set trap to cleanup on script exit (success, failure, or interruption)
trap cleanup EXIT
# Function to run a test
run_test() {
local test_name="$1"
local command="$2"
local expected_exit_code="${3:-0}"
echo -n "Testing $test_name... "
# Run command and capture exit code
set +e
eval "$command" > /tmp/test_output.txt 2>&1
local exit_code=$?
set -e
if [ $exit_code -eq $expected_exit_code ]; then
echo -e "${GREEN}PASSED${NC}"
((TESTS_PASSED++))
return 0
else
echo -e "${RED}FAILED${NC}"
echo " Expected exit code: $expected_exit_code, got: $exit_code"
echo " Output:"
cat /tmp/test_output.txt | sed 's/^/ /'
((TESTS_FAILED++))
return 1
fi
}
# Function to verify archive contents
verify_archive_contents() {
local archive="$1"
local expected_files="$2"
echo -n " Verifying contents of $archive... "
if [[ "$archive" == *.tgz || "$archive" == *.tar.gz ]]; then
actual_files=$(tar -tzf "$archive" | sort | tr '\n' ' ' | sed 's/ $//')
elif [[ "$archive" == *.zip ]]; then
actual_files=$(unzip -l "$archive" | grep -v "Archive:" | grep -v "Length" | grep -v -- "--------" | grep -v "files" | awk '{print $4}' | grep -v '^$' | sort | tr '\n' ' ' | sed 's/ $//')
else
echo -e "${RED}Unknown archive format${NC}"
return 1
fi
expected_sorted=$(echo "$expected_files" | tr ' ' '\n' | sort | tr '\n' ' ' | sed 's/ $//')
if [ "$actual_files" = "$expected_sorted" ]; then
echo -e "${GREEN}OK${NC}"
return 0
else
echo -e "${RED}FAILED${NC}"
echo " Expected: $expected_sorted"
echo " Got: $actual_files"
return 1
fi
}
echo -e "${YELLOW}=== Collect CLI Test Suite ===${NC}\n"
# Clean up any previous test artifacts
echo "Cleaning up previous test artifacts..."
rm -rf test test-*.tgz test-*.zip collect
# Build the tool
echo "Building collect tool..."
if ! go build -o collect; then
echo -e "${RED}Failed to build collect tool${NC}"
exit 1
fi
echo -e "${GREEN}Build successful${NC}\n"
# Create test directory structure
echo "Setting up test environment..."
mkdir -p test/subdir/aet-bin test/subdir/aet-config test/other test/deep/nested/aet-tools
echo "test config" > test/.mise.toml
echo "another config" > test/subdir/.mise.toml
echo "binary" > test/subdir/aet-bin/tool
echo "config" > test/subdir/aet-config/settings.conf
echo "other file" > test/other/file.txt
echo "deep tool" > test/deep/nested/aet-tools/deep.sh
echo "not in aet dir" > test/deep/nested/regular.txt
echo -e "${GREEN}Test environment ready${NC}\n"
# Test 1: Name matching with tar.gz
run_test "name matching (.mise.toml) with tar.gz" \
"./collect --name .mise.toml test/ test-name.tgz"
verify_archive_contents "test-name.tgz" ".mise.toml subdir/.mise.toml"
# Test 2: Pattern matching with zip
run_test "pattern matching (aet-*) with zip" \
"./collect --match 'aet-*' test/ test-pattern.zip"
verify_archive_contents "test-pattern.zip" "subdir/aet-bin/tool subdir/aet-config/settings.conf deep/nested/aet-tools/deep.sh"
# Test 3: Pattern matching with tgz
run_test "pattern matching (aet-*) with tgz" \
"./collect --match 'aet-*' test/ test-pattern.tgz"
verify_archive_contents "test-pattern.tgz" "deep/nested/aet-tools/deep.sh subdir/aet-bin/tool subdir/aet-config/settings.conf"
# Test 4: No files found (should exit with code 1)
run_test "no files found error" \
"./collect --name nonexistent.file test/ test-empty.zip" 1
# Test 5: Invalid arguments - no flags
run_test "invalid arguments - no flags" \
"./collect test/ output.zip" 3
# Test 6: Invalid arguments - no positional args
run_test "invalid arguments - no positional args" \
"./collect --name .mise.toml" 3
# Test 7: Invalid arguments - missing output file
run_test "invalid arguments - missing output file" \
"./collect --name .mise.toml test/" 3
# Test 8: Invalid archive format
run_test "invalid archive format" \
"./collect --name .mise.toml test/ output.txt" 3
# Test 9: Non-existent source directory
run_test "non-existent source directory" \
"./collect --name .mise.toml nonexistent/ output.zip" 2
# Test 10: Help flag
run_test "help flag output" \
"./collect --help" 0
# Test 11: Name matching with subdirectory pattern
echo "subdir config" > test/subdir/aet-bin/.mise.toml
run_test "name matching finds files in pattern dirs too" \
"./collect --name .mise.toml test/ test-name-all.tgz"
verify_archive_contents "test-name-all.tgz" ".mise.toml subdir/.mise.toml subdir/aet-bin/.mise.toml"
# Test 12: Multiple name flags
echo "readme" > test/README.md
echo "makefile" > test/Makefile
echo "another makefile" > test/subdir/Makefile
run_test "multiple name flags" \
"./collect --name .mise.toml --name README.md --name Makefile test/ test-multi-name.tgz"
verify_archive_contents "test-multi-name.tgz" ".mise.toml Makefile README.md subdir/.mise.toml subdir/Makefile subdir/aet-bin/.mise.toml"
# Test 13: Multiple match flags
mkdir -p test/prefix-one test/prefix-two test/other-prefix
echo "file1" > test/prefix-one/data.txt
echo "file2" > test/prefix-two/config.yml
echo "file3" > test/other-prefix/info.log
run_test "multiple match flags" \
"./collect --match 'prefix-*' --match 'aet-*' test/ test-multi-match.tgz"
verify_archive_contents "test-multi-match.tgz" "deep/nested/aet-tools/deep.sh prefix-one/data.txt prefix-two/config.yml subdir/aet-bin/.mise.toml subdir/aet-bin/tool subdir/aet-config/settings.conf"
# Test 14: Combined name and match flags
run_test "combined name and match flags" \
"./collect --name .mise.toml --match 'aet-*' --name README.md test/ test-combined.tgz"
verify_archive_contents "test-combined.tgz" ".mise.toml README.md deep/nested/aet-tools/deep.sh subdir/.mise.toml subdir/aet-bin/.mise.toml subdir/aet-bin/tool subdir/aet-config/settings.conf"
# Test 15: Include directory filter - simple path
mkdir -p test/src test/docs test/examples
echo "source file" > test/src/main.go
echo "doc file" > test/docs/README.md
echo "example file" > test/examples/demo.txt
run_test "include directory - simple path" \
"./collect --include-dir src --name 'main.go' test/ test-include-simple.tgz"
verify_archive_contents "test-include-simple.tgz" "src/main.go"
# Test 16: Include directory filter - glob pattern
mkdir -p test/project-one/src test/project-two/src test/other/src
echo "p1 source" > test/project-one/src/app.go
echo "p2 source" > test/project-two/src/lib.go
echo "other source" > test/other/src/util.go
run_test "include directory - glob pattern" \
"./collect --include-dir 'project-*' --name 'app.go' --name 'lib.go' test/ test-include-glob.tgz"
verify_archive_contents "test-include-glob.tgz" "project-one/src/app.go project-two/src/lib.go"
# Test 17: Exclude directory filter - simple path
run_test "exclude directory - simple path" \
"./collect --exclude-dir docs --name 'README.md' test/ test-exclude-simple.tgz"
verify_archive_contents "test-exclude-simple.tgz" "README.md"
# Test 18: Exclude directory filter - glob pattern
mkdir -p test/temp-cache test/temp-logs test/important
echo "cache file" > test/temp-cache/data.txt
echo "log file" > test/temp-logs/app.log
echo "important file" > test/important/config.txt
run_test "exclude directory - glob pattern" \
"./collect --exclude-dir 'temp-*' --name 'data.txt' --name 'config.txt' --name 'demo.txt' test/ test-exclude-glob.tgz"
verify_archive_contents "test-exclude-glob.tgz" "examples/demo.txt important/config.txt prefix-one/data.txt"
# Test 19: Multiple include directories
run_test "multiple include directories" \
"./collect --include-dir src --include-dir docs --name 'main.go' --name 'README.md' test/ test-multi-include.tgz"
verify_archive_contents "test-multi-include.tgz" "docs/README.md src/main.go"
# Test 20: Multiple exclude directories
run_test "multiple exclude directories" \
"./collect --exclude-dir 'temp-*' --exclude-dir examples --name 'data.txt' --name 'config.txt' test/ test-multi-exclude.tgz"
verify_archive_contents "test-multi-exclude.tgz" "important/config.txt prefix-one/data.txt"
# Test 21: Combined include and exclude (include takes precedence in overlaps)
run_test "combined include and exclude filters" \
"./collect --include-dir 'project-*' --exclude-dir 'project-two' --name 'app.go' --name 'lib.go' test/ test-include-exclude.tgz"
verify_archive_contents "test-include-exclude.tgz" "project-one/src/app.go"
# Summary
echo -e "\n${YELLOW}=== Test Summary ===${NC}"
echo -e "Tests passed: ${GREEN}$TESTS_PASSED${NC}"
echo -e "Tests failed: ${RED}$TESTS_FAILED${NC}"
if [ $TESTS_FAILED -eq 0 ]; then
echo -e "\n${GREEN}All tests passed!${NC}"
exit 0
else
echo -e "\n${RED}Some tests failed!${NC}"
exit 1
fi