#!/usr/bin/env bash # Test block-clone functionality on temporary Btrfs and XFS loopback filesystems. # # Requires: root/sudo, btrfs-progs (mkfs.btrfs), xfsprogs (mkfs.xfs) # # Usage: # sudo ./scripts/test_scripts/block-clone-test.sh [path-to-zencore-test] # # If no path is given, defaults to build/linux/x86_64/debug/zencore-test # relative to the repository root. # # Options: # --btrfs-only Only test Btrfs # --xfs-only Only test XFS set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" TEST_BINARY="" RUN_BTRFS=true RUN_XFS=true for arg in "$@"; do case "$arg" in --btrfs-only) RUN_XFS=false ;; --xfs-only) RUN_BTRFS=false ;; *) TEST_BINARY="$arg" ;; esac done TEST_BINARY="${TEST_BINARY:-$REPO_ROOT/build/linux/x86_64/debug/zencore-test}" IMAGE_SIZE="512M" TEST_CASES="TryCloneFile,CopyFile.Clone,SupportsBlockRefCounting,CloneQueryInterface" # Track all temp files for cleanup CLEANUP_MOUNTS=() CLEANUP_DIRS=() CLEANUP_FILES=() cleanup() { local exit_code=$? set +e for mnt in "${CLEANUP_MOUNTS[@]}"; do if mountpoint -q "$mnt" 2>/dev/null; then umount "$mnt" fi done for dir in "${CLEANUP_DIRS[@]}"; do [ -d "$dir" ] && rmdir "$dir" done for f in "${CLEANUP_FILES[@]}"; do [ -f "$f" ] && rm -f "$f" done if [ $exit_code -ne 0 ]; then echo "FAILED (exit code $exit_code)" fi exit $exit_code } trap cleanup EXIT # --- Preflight checks --- if [ "$(id -u)" -ne 0 ]; then echo "error: this script must be run as root (for mount/umount)" >&2 exit 1 fi if [ ! -x "$TEST_BINARY" ]; then echo "error: test binary not found or not executable: $TEST_BINARY" >&2 echo "hint: build with 'xmake config -m debug && xmake build zencore-test'" >&2 exit 1 fi if $RUN_BTRFS && ! command -v mkfs.btrfs &>/dev/null; then echo "warning: mkfs.btrfs not found — install btrfs-progs to test Btrfs, skipping" >&2 RUN_BTRFS=false fi if $RUN_XFS && ! command -v mkfs.xfs &>/dev/null; then echo "warning: mkfs.xfs not found — install xfsprogs to test XFS, skipping" >&2 RUN_XFS=false fi if ! $RUN_BTRFS && ! $RUN_XFS; then echo "error: no filesystems to test" >&2 exit 1 fi # --- Helper to create, mount, and run tests on a loopback filesystem --- run_tests_on_fs() { local fs_type="$1" local mkfs_cmd="$2" echo "" echo "========================================" echo " Testing block-clone on $fs_type" echo "========================================" local image_path mount_path image_path="$(mktemp "/tmp/${fs_type}-clone-test-XXXXXX.img")" mount_path="$(mktemp -d "/tmp/${fs_type}-clone-mount-XXXXXX")" CLEANUP_FILES+=("$image_path") CLEANUP_DIRS+=("$mount_path") CLEANUP_MOUNTS+=("$mount_path") echo "Creating ${IMAGE_SIZE} ${fs_type} image at ${image_path} ..." truncate -s "$IMAGE_SIZE" "$image_path" $mkfs_cmd "$image_path" echo "Mounting at ${mount_path} ..." mount -o loop "$image_path" "$mount_path" chmod 777 "$mount_path" echo "Copying test binary ..." cp "$TEST_BINARY" "$mount_path/zencore-test" chmod +x "$mount_path/zencore-test" echo "Running tests ..." echo "---" "$mount_path/zencore-test" \ --test-suite="core.filesystem" \ --test-case="$TEST_CASES" echo "---" echo "$fs_type: all block-clone tests passed." } # --- Run --- if $RUN_BTRFS; then run_tests_on_fs "btrfs" "mkfs.btrfs -q" fi if $RUN_XFS; then run_tests_on_fs "xfs" "mkfs.xfs -q -m reflink=1" fi echo "" echo "All block-clone tests passed."