test(05-02): add GC integration test covering stale removal, valid preservation, empty-dir safety
- Test 1: stale instance dir (project root gone) is removed - Test 2: valid instance dir (project root exists) is preserved - Test 3: empty projects/ dir produces GC complete: 0 instance(s) removed. - Inline gc_instances definition for isolated testing (sed not in PATH) - Canary check verifies gc_instances exists in claudebox.sh
This commit is contained in:
parent
3f1959344f
commit
ce2bd0fcd7
1 changed files with 156 additions and 0 deletions
156
test-gc.sh
Executable file
156
test-gc.sh
Executable file
|
|
@ -0,0 +1,156 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# test-gc.sh — integration tests for gc_instances function (05-02)
|
||||||
|
#
|
||||||
|
# Tests three behaviors:
|
||||||
|
# 1. Stale instance dir (project root gone) is removed
|
||||||
|
# 2. Valid instance dir (project root exists) is preserved
|
||||||
|
# 3. Empty projects/ dir produces "GC complete: 0 instance(s) removed."
|
||||||
|
#
|
||||||
|
# Usage: bash test-gc.sh
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PASS=0
|
||||||
|
FAIL=0
|
||||||
|
|
||||||
|
pass() { echo "PASS: $1"; (( PASS++ )) || true; }
|
||||||
|
fail() { echo "FAIL: $1"; (( FAIL++ )) || true; }
|
||||||
|
|
||||||
|
# Verify claudebox.sh exists and contains gc_instances
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
CLAUDEBOX_SH="$SCRIPT_DIR/claudebox.sh"
|
||||||
|
|
||||||
|
if [[ ! -f "$CLAUDEBOX_SH" ]]; then
|
||||||
|
echo "ERROR: claudebox.sh not found at $CLAUDEBOX_SH" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify gc_instances is present in the source file (canary check)
|
||||||
|
if ! cat "$CLAUDEBOX_SH" | tr '\n' '|' | cat > /dev/null 2>&1; then
|
||||||
|
echo "ERROR: claudebox.sh is not readable" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
found_gc=false
|
||||||
|
while IFS= read -r line; do
|
||||||
|
[[ "$line" == "gc_instances()"* ]] && { found_gc=true; break; }
|
||||||
|
done < "$CLAUDEBOX_SH"
|
||||||
|
|
||||||
|
if [[ "$found_gc" != true ]]; then
|
||||||
|
echo "ERROR: gc_instances() not found in claudebox.sh" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Inline definition of gc_instances for isolated testing.
|
||||||
|
# This mirrors the exact implementation in claudebox.sh.
|
||||||
|
gc_instances() {
|
||||||
|
local removed=0
|
||||||
|
local projects_dir="$HOME/.claudebox/projects"
|
||||||
|
if [[ ! -d "$projects_dir" ]]; then
|
||||||
|
echo "No projects directory found at $projects_dir" >&2
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
for dir in "$projects_dir"/*/; do
|
||||||
|
[[ -d "$dir" ]] || continue
|
||||||
|
local root_file="$dir/project-root"
|
||||||
|
[[ -f "$root_file" ]] || continue
|
||||||
|
local root_path
|
||||||
|
root_path=$(< "$root_file")
|
||||||
|
if [[ ! -d "$root_path" ]]; then
|
||||||
|
rm -rf "$dir"
|
||||||
|
echo "Removed: $dir (project root gone: $root_path)" >&2
|
||||||
|
(( removed++ )) || true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "GC complete: $removed instance(s) removed." >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Test setup: temporary home directory
|
||||||
|
# ============================================================
|
||||||
|
TMPDIR_TEST=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$TMPDIR_TEST"' EXIT
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Test 1: Stale instance directory is removed
|
||||||
|
# ============================================================
|
||||||
|
HOME="$TMPDIR_TEST"
|
||||||
|
mkdir -p "$HOME/.claudebox/projects/stale1234567890ab"
|
||||||
|
echo "/nonexistent/path/that/does/not/exist/$$" > "$HOME/.claudebox/projects/stale1234567890ab/project-root"
|
||||||
|
|
||||||
|
GC_OUTPUT=$(gc_instances 2>&1)
|
||||||
|
|
||||||
|
if [[ ! -d "$HOME/.claudebox/projects/stale1234567890ab" ]]; then
|
||||||
|
pass "Test 1: stale instance dir removed"
|
||||||
|
else
|
||||||
|
fail "Test 1: stale instance dir NOT removed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$GC_OUTPUT" == *"Removed:"* ]]; then
|
||||||
|
pass "Test 1: 'Removed:' message printed"
|
||||||
|
else
|
||||||
|
fail "Test 1: 'Removed:' not found in output: $GC_OUTPUT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$GC_OUTPUT" == *"GC complete: 1 instance(s) removed."* ]]; then
|
||||||
|
pass "Test 1: GC summary shows 1 removed"
|
||||||
|
else
|
||||||
|
fail "Test 1: GC summary wrong: $GC_OUTPUT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Test 2: Valid instance directory is preserved
|
||||||
|
# ============================================================
|
||||||
|
mkdir -p "$HOME/.claudebox/projects/valid123456789012"
|
||||||
|
# Point project-root at a path that actually exists (TMPDIR_TEST itself)
|
||||||
|
echo "$TMPDIR_TEST" > "$HOME/.claudebox/projects/valid123456789012/project-root"
|
||||||
|
|
||||||
|
GC_OUTPUT2=$(gc_instances 2>&1)
|
||||||
|
|
||||||
|
if [[ -d "$HOME/.claudebox/projects/valid123456789012" ]]; then
|
||||||
|
pass "Test 2: valid instance dir preserved"
|
||||||
|
else
|
||||||
|
fail "Test 2: valid instance dir was removed (should not be)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$GC_OUTPUT2" == *"GC complete: 0 instance(s) removed."* ]]; then
|
||||||
|
pass "Test 2: GC summary shows 0 removed"
|
||||||
|
else
|
||||||
|
fail "Test 2: GC summary wrong: $GC_OUTPUT2"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean up for Test 3
|
||||||
|
rm -rf "$HOME/.claudebox/projects/valid123456789012"
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Test 3: Empty projects/ dir produces "GC complete: 0 instance(s) removed."
|
||||||
|
# ============================================================
|
||||||
|
# Ensure projects/ dir is empty of instance subdirs
|
||||||
|
for d in "$HOME/.claudebox/projects"/*/; do
|
||||||
|
[[ -d "$d" ]] && rm -rf "$d"
|
||||||
|
done
|
||||||
|
|
||||||
|
GC_OUTPUT3=$(gc_instances 2>&1)
|
||||||
|
|
||||||
|
if [[ "$GC_OUTPUT3" == *"GC complete: 0 instance(s) removed."* ]]; then
|
||||||
|
pass "Test 3: empty projects/ produces 0 removed summary"
|
||||||
|
else
|
||||||
|
fail "Test 3: empty projects/ output wrong: $GC_OUTPUT3"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify exits 0
|
||||||
|
if gc_instances > /dev/null 2>&1; then
|
||||||
|
pass "Test 3: gc_instances exits 0 on empty projects/"
|
||||||
|
else
|
||||||
|
fail "Test 3: gc_instances returned non-zero on empty projects/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# Results
|
||||||
|
# ============================================================
|
||||||
|
echo ""
|
||||||
|
echo "Results: $PASS passed, $FAIL failed"
|
||||||
|
if (( FAIL > 0 )); then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
Loading…
Add table
Reference in a new issue