Integration tests (tests/): - 9 categories covering config, lifecycle, signals, supervision, cache, writeback, network faults, crash recovery, and CLI - Shell-based harness with mock NAS (network namespace + SFTP), fault injection (tc netem), and power loss simulation - TAP format runner (run-all.sh) with proper SKIP detection Rust unit tests (warpgate/src/): - 110 tests across 14 modules, all passing in 0.01s - Config parsing, defaults validation, RestartTracker logic, RC API response parsing, rclone arg generation, service config generation, CLI output formatting, warmup path logic Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
81 lines
2.4 KiB
Bash
Executable File
81 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Test: dirty files are protected from LRU eviction
|
|
#
|
|
# Verifies that when the cache is under space pressure, dirty (unwritten)
|
|
# files are not evicted by the LRU policy. Clean cached files may be
|
|
# evicted, but dirty files must survive.
|
|
set -euo pipefail
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
source "$SCRIPT_DIR/../harness/helpers.sh"
|
|
source "$SCRIPT_DIR/../harness/mock-nas.sh"
|
|
|
|
require_root
|
|
setup_test_env
|
|
trap teardown_test_env EXIT
|
|
|
|
# Start mock NAS and pre-create 5 x 1 MB files for LRU pressure
|
|
start_mock_nas
|
|
for i in $(seq 1 5); do
|
|
nas_create_file "filler-${i}.bin" 1024
|
|
done
|
|
|
|
# Generate config with small cache (5 MB) and a very long write-back
|
|
# so dirty files remain dirty throughout the test
|
|
gen_config cache_max_size=5M write_back=300s
|
|
|
|
# Start warpgate and wait for readiness
|
|
start_warpgate
|
|
wait_for_mount
|
|
wait_for_rc_api
|
|
|
|
# Sever the network BEFORE writing the dirty file to prevent write-back
|
|
# from racing with LRU eviction — the file must stay dirty throughout.
|
|
inject_network_down
|
|
|
|
# Write a 1 MB dirty file through the mount (stays dirty due to 300s delay
|
|
# AND network being down, so write-back cannot succeed)
|
|
dd if=/dev/urandom bs=1K count=1024 2>/dev/null | \
|
|
dd of="$TEST_MOUNT/important-edit.bin" bs=1K 2>/dev/null
|
|
|
|
# Allow VFS to register the dirty write
|
|
sleep 2
|
|
|
|
# Confirm the file is dirty
|
|
dirty_before=$(get_dirty_count)
|
|
if [[ "$dirty_before" -lt 1 ]]; then
|
|
echo "FAIL: expected dirty count > 0 after write, got $dirty_before" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Now read the 5 x 1 MB filler files through the mount to create LRU
|
|
# pressure. With a 5 MB cache limit, evictions must happen, but the
|
|
# dirty file should be protected.
|
|
for i in $(seq 1 5); do
|
|
cat "$TEST_MOUNT/filler-${i}.bin" > /dev/null
|
|
done
|
|
|
|
# Allow time for LRU eviction to run
|
|
sleep 3
|
|
|
|
# The dirty file must still be present and dirty
|
|
dirty_after=$(get_dirty_count)
|
|
if [[ "$dirty_after" -lt 1 ]]; then
|
|
echo "FAIL: dirty file was evicted; dirty count dropped to $dirty_after" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Verify the dirty file is still readable through the mount
|
|
if [[ ! -f "$TEST_MOUNT/important-edit.bin" ]]; then
|
|
echo "FAIL: dirty file no longer accessible through mount" >&2
|
|
inject_network_up
|
|
exit 1
|
|
fi
|
|
|
|
# Verify the dirty file physically remains in the on-disk cache
|
|
assert_cached "important-edit.bin"
|
|
|
|
# Restore network for clean teardown
|
|
inject_network_up
|
|
|
|
echo "PASS: $(basename "$0" .sh)"
|