#!/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)"