Skip to content

Commit 3855fe5

Browse files
committed
Add cleanup for root-owned files created by Docker containers
- Update Dockerfile run-tests script to clean up files before container exit - Add cleanup_root_files() function to all test runner scripts - Ensure cleanup only operates within git repository root for safety - Remove Python cache files, test artifacts, and temporary scripts - Use sudo when available to handle root-owned files on host system - Prevents permission issues when cleaning up test artifacts
1 parent 6807c2d commit 3855fe5

File tree

4 files changed

+188
-3
lines changed

4 files changed

+188
-3
lines changed

Dockerfile

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,17 @@ echo "Using Python: $(python3 --version)"\n\
4646
echo "Using Vim: $(vim --version | head -1)"\n\
4747
bash ./tests/test.sh\n\
4848
EXIT_CODE=$?\n\
49-
rm -f tests/.swo tests/.swp 2>&1 >/dev/null\n\
49+
# Cleanup files that might be created during tests\n\
50+
# Remove Vim swap files\n\
51+
find . -type f -name "*.swp" -o -name "*.swo" -o -name ".*.swp" -o -name ".*.swo" 2>/dev/null | xargs rm -f 2>/dev/null || true\n\
52+
# Remove temporary test scripts\n\
53+
rm -f .tmp_run_test_*.sh 2>/dev/null || true\n\
54+
# Remove Python cache files and directories\n\
55+
find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true\n\
56+
find . -type f -name "*.pyc" -o -name "*.pyo" 2>/dev/null | xargs rm -f 2>/dev/null || true\n\
57+
# Remove test artifacts\n\
58+
rm -rf test-logs results 2>/dev/null || true\n\
59+
rm -f test-results.json coverage.xml .coverage .coverage.* 2>/dev/null || true\n\
5060
exit $EXIT_CODE\n\
5161
' > /usr/local/bin/run-tests && \
5262
chmod +x /usr/local/bin/run-tests

scripts/user/run-tests-docker.sh

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,57 @@ YELLOW='\033[1;33m'
1010
BLUE='\033[0;34m'
1111
NC='\033[0m' # No Color
1212

13+
# Cleanup function to remove root-owned files created by Docker container
14+
# This function ensures cleanup only happens within the git repository root
15+
cleanup_root_files() {
16+
local provided_path="${1:-$(pwd)}"
17+
18+
# Find git root directory - this ensures we only operate within the project
19+
local git_root
20+
if ! git_root=$(cd "$provided_path" && git rev-parse --show-toplevel 2>/dev/null); then
21+
echo -e "${YELLOW}Warning: Not in a git repository, skipping cleanup${NC}" >&2
22+
return 0
23+
fi
24+
25+
# Normalize paths for comparison
26+
git_root=$(cd "$git_root" && pwd)
27+
local normalized_path=$(cd "$provided_path" && pwd)
28+
29+
# Safety check: ensure the provided path is within git root
30+
if [[ "$normalized_path" != "$git_root"* ]]; then
31+
echo -e "${RED}Error: Path '$normalized_path' is outside git root '$git_root', aborting cleanup${NC}" >&2
32+
return 1
33+
fi
34+
35+
# Use git root as the base for cleanup operations
36+
local project_root="$git_root"
37+
echo -e "${YELLOW}Cleaning up files created by Docker container in: $project_root${NC}"
38+
39+
# Find and remove root-owned files/directories that shouldn't persist
40+
# Use sudo if available, otherwise try without (may fail silently)
41+
if command -v sudo &> /dev/null; then
42+
# Remove Python cache files (only within git root)
43+
sudo find "$project_root" -type d -name "__pycache__" -user root -exec rm -rf {} + 2>/dev/null || true
44+
sudo find "$project_root" -type f \( -name "*.pyc" -o -name "*.pyo" \) -user root -delete 2>/dev/null || true
45+
46+
# Remove temporary test scripts (only within git root)
47+
sudo find "$project_root" -type f -name ".tmp_run_test_*.sh" -user root -delete 2>/dev/null || true
48+
49+
# Remove test artifacts (only within git root)
50+
sudo rm -rf "$project_root/test-logs" "$project_root/results" 2>/dev/null || true
51+
sudo rm -f "$project_root/test-results.json" "$project_root/coverage.xml" 2>/dev/null || true
52+
53+
# Remove Vim swap files (only within git root)
54+
sudo find "$project_root" -type f \( -name "*.swp" -o -name "*.swo" -o -name ".*.swp" -o -name ".*.swo" \) -user root -delete 2>/dev/null || true
55+
else
56+
# Without sudo, try to remove files we can access (only within git root)
57+
find "$project_root" -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
58+
find "$project_root" -type f \( -name "*.pyc" -o -name "*.pyo" -o -name ".tmp_run_test_*.sh" -o -name "*.swp" -o -name "*.swo" \) -delete 2>/dev/null || true
59+
rm -rf "$project_root/test-logs" "$project_root/results" 2>/dev/null || true
60+
rm -f "$project_root/test-results.json" "$project_root/coverage.xml" 2>/dev/null || true
61+
fi
62+
}
63+
1364
# Mapping of major.minor to full version
1465
declare -A PYTHON_VERSIONS
1566
PYTHON_VERSIONS["3.10"]="3.10.13"
@@ -70,10 +121,15 @@ docker compose build -q ${DOCKER_BUILD_ARGS[@]} python-mode-tests
70121

71122
echo -e "${YELLOW}Running python-mode tests with Python ${PYTHON_VERSION}...${NC}"
72123
# Run the tests with specific Python version
124+
TEST_EXIT_CODE=0
73125
if docker compose run --rm python-mode-tests; then
74126
echo -e "${GREEN}✓ All tests passed with Python ${PYTHON_VERSION}!${NC}"
75-
exit 0
76127
else
77128
echo -e "${RED}✗ Some tests failed with Python ${PYTHON_VERSION}. Check the output above for details.${NC}"
78-
exit 1
129+
TEST_EXIT_CODE=1
79130
fi
131+
132+
# Always cleanup root-owned files after Docker execution
133+
cleanup_root_files "$(pwd)"
134+
135+
exit $TEST_EXIT_CODE

scripts/user/run_tests.sh

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,61 @@ set -euo pipefail
66
cleanup() {
77
# Remove any leftover temporary test scripts
88
rm -f .tmp_run_test_*.sh
9+
# Cleanup root-owned files created by Docker container
10+
cleanup_root_files "$(pwd)"
911
}
12+
13+
# Cleanup function to remove root-owned files created by Docker container
14+
# This function ensures cleanup only happens within the git repository root
15+
cleanup_root_files() {
16+
local provided_path="${1:-$(pwd)}"
17+
18+
# Find git root directory - this ensures we only operate within the project
19+
local git_root
20+
if ! git_root=$(cd "$provided_path" && git rev-parse --show-toplevel 2>/dev/null); then
21+
log_warn "Not in a git repository, skipping cleanup"
22+
return 0
23+
fi
24+
25+
# Normalize paths for comparison
26+
git_root=$(cd "$git_root" && pwd)
27+
local normalized_path=$(cd "$provided_path" && pwd)
28+
29+
# Safety check: ensure the provided path is within git root
30+
if [[ "$normalized_path" != "$git_root"* ]]; then
31+
log_error "Path '$normalized_path' is outside git root '$git_root', aborting cleanup"
32+
return 1
33+
fi
34+
35+
# Use git root as the base for cleanup operations
36+
local project_root="$git_root"
37+
log_info "Cleaning up files created by Docker container in: $project_root"
38+
39+
# Find and remove root-owned files/directories that shouldn't persist
40+
# Use sudo if available, otherwise try without (may fail silently)
41+
if command -v sudo &> /dev/null; then
42+
# Remove Python cache files (only within git root)
43+
sudo find "$project_root" -type d -name "__pycache__" -user root -exec rm -rf {} + 2>/dev/null || true
44+
sudo find "$project_root" -type f \( -name "*.pyc" -o -name "*.pyo" \) -user root -delete 2>/dev/null || true
45+
46+
# Remove temporary test scripts (only within git root)
47+
sudo find "$project_root" -type f -name ".tmp_run_test_*.sh" -user root -delete 2>/dev/null || true
48+
49+
# Remove test artifacts (only within git root)
50+
sudo rm -rf "$project_root/test-logs" "$project_root/results" 2>/dev/null || true
51+
sudo rm -f "$project_root/test-results.json" "$project_root/coverage.xml" 2>/dev/null || true
52+
53+
# Remove Vim swap files (only within git root)
54+
sudo find "$project_root" -type f \( -name "*.swp" -o -name "*.swo" -o -name ".*.swp" -o -name ".*.swo" \) -user root -delete 2>/dev/null || true
55+
else
56+
# Without sudo, try to remove files we can access (only within git root)
57+
find "$project_root" -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
58+
find "$project_root" -type f \( -name "*.pyc" -o -name "*.pyo" -o -name ".tmp_run_test_*.sh" -o -name "*.swp" -o -name "*.swo" \) -delete 2>/dev/null || true
59+
rm -rf "$project_root/test-logs" "$project_root/results" 2>/dev/null || true
60+
rm -f "$project_root/test-results.json" "$project_root/coverage.xml" 2>/dev/null || true
61+
fi
62+
}
63+
1064
trap cleanup EXIT INT TERM
1165

1266
echo "⚡ Running Vader Test Suite (Final)..."
@@ -15,6 +69,7 @@ echo "⚡ Running Vader Test Suite (Final)..."
1569
RED='\033[0;31m'
1670
GREEN='\033[0;32m'
1771
BLUE='\033[0;34m'
72+
YELLOW='\033[1;33m'
1873
NC='\033[0m' # No Color
1974

2075
log_info() {
@@ -29,6 +84,10 @@ log_error() {
2984
echo -e "${RED}[ERROR]${NC} $*"
3085
}
3186

87+
log_warn() {
88+
echo -e "${YELLOW}[WARN]${NC} $*"
89+
}
90+
3291
# Find test files
3392
TEST_FILES=()
3493
if [[ -d "tests/vader" ]]; then
@@ -218,6 +277,9 @@ EOFSCRIPT
218277
# Cleanup temporary files
219278
rm -f "$TEMP_SCRIPT" ".tmp_run_test_${test_name}.sh"
220279

280+
# Cleanup root-owned files after each Docker execution
281+
cleanup_root_files "$(pwd)"
282+
221283
# Check if docker command timed out or failed
222284
if [ "$DOCKER_EXIT_CODE" -eq 124 ]; then
223285
log_error "Test timed out: $test_name (exceeded 120s timeout)"
@@ -303,6 +365,9 @@ log_info "Total tests: ${#TEST_FILES[@]}"
303365
log_info "Passed: ${#PASSED_TESTS[@]}"
304366
log_info "Failed: ${#FAILED_TESTS[@]}"
305367

368+
# Final cleanup before exit
369+
cleanup_root_files "$(pwd)"
370+
306371
if [[ ${#FAILED_TESTS[@]} -gt 0 ]]; then
307372
echo
308373
log_error "Failed tests:"

scripts/user/test-all-python-versions.sh

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,57 @@ YELLOW='\033[1;33m'
1010
BLUE='\033[0;34m'
1111
NC='\033[0m' # No Color
1212

13+
# Cleanup function to remove root-owned files created by Docker container
14+
# This function ensures cleanup only happens within the git repository root
15+
cleanup_root_files() {
16+
local provided_path="${1:-$(pwd)}"
17+
18+
# Find git root directory - this ensures we only operate within the project
19+
local git_root
20+
if ! git_root=$(cd "$provided_path" && git rev-parse --show-toplevel 2>/dev/null); then
21+
echo -e "${YELLOW}Warning: Not in a git repository, skipping cleanup${NC}" >&2
22+
return 0
23+
fi
24+
25+
# Normalize paths for comparison
26+
git_root=$(cd "$git_root" && pwd)
27+
local normalized_path=$(cd "$provided_path" && pwd)
28+
29+
# Safety check: ensure the provided path is within git root
30+
if [[ "$normalized_path" != "$git_root"* ]]; then
31+
echo -e "${RED}Error: Path '$normalized_path' is outside git root '$git_root', aborting cleanup${NC}" >&2
32+
return 1
33+
fi
34+
35+
# Use git root as the base for cleanup operations
36+
local project_root="$git_root"
37+
echo -e "${YELLOW}Cleaning up files created by Docker container in: $project_root${NC}"
38+
39+
# Find and remove root-owned files/directories that shouldn't persist
40+
# Use sudo if available, otherwise try without (may fail silently)
41+
if command -v sudo &> /dev/null; then
42+
# Remove Python cache files (only within git root)
43+
sudo find "$project_root" -type d -name "__pycache__" -user root -exec rm -rf {} + 2>/dev/null || true
44+
sudo find "$project_root" -type f \( -name "*.pyc" -o -name "*.pyo" \) -user root -delete 2>/dev/null || true
45+
46+
# Remove temporary test scripts (only within git root)
47+
sudo find "$project_root" -type f -name ".tmp_run_test_*.sh" -user root -delete 2>/dev/null || true
48+
49+
# Remove test artifacts (only within git root)
50+
sudo rm -rf "$project_root/test-logs" "$project_root/results" 2>/dev/null || true
51+
sudo rm -f "$project_root/test-results.json" "$project_root/coverage.xml" 2>/dev/null || true
52+
53+
# Remove Vim swap files (only within git root)
54+
sudo find "$project_root" -type f \( -name "*.swp" -o -name "*.swo" -o -name ".*.swp" -o -name ".*.swo" \) -user root -delete 2>/dev/null || true
55+
else
56+
# Without sudo, try to remove files we can access (only within git root)
57+
find "$project_root" -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
58+
find "$project_root" -type f \( -name "*.pyc" -o -name "*.pyo" -o -name ".tmp_run_test_*.sh" -o -name "*.swp" -o -name "*.swo" \) -delete 2>/dev/null || true
59+
rm -rf "$project_root/test-logs" "$project_root/results" 2>/dev/null || true
60+
rm -f "$project_root/test-results.json" "$project_root/coverage.xml" 2>/dev/null || true
61+
fi
62+
}
63+
1364
# Mapping of major.minor to full version (same as run-tests-docker.sh in user folder)
1465
declare -A PYTHON_VERSIONS
1566
PYTHON_VERSIONS["3.10"]="3.10.13"
@@ -46,6 +97,9 @@ for short_version in "${!PYTHON_VERSIONS[@]}"; do
4697
echo ""
4798
done
4899

100+
# Cleanup root-owned files after all tests
101+
cleanup_root_files "$(pwd)"
102+
49103
# Summary
50104
echo -e "${YELLOW}========================================${NC}"
51105
echo -e "${YELLOW}TEST SUMMARY${NC}"

0 commit comments

Comments
 (0)