diff options
| author | Stefan Boberg <[email protected]> | 2026-03-21 21:43:22 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2026-03-21 21:43:22 +0100 |
| commit | 14ca5b35d0fc477ba30f10b80f937b523fd7e930 (patch) | |
| tree | 8aab2acfec8be1af4bf0dffdb4badc3b64bf8385 /scripts/test_linux/block-clone-test.sh | |
| parent | fix null stats provider crash when build store is not configured (#875) (diff) | |
| download | zen-14ca5b35d0fc477ba30f10b80f937b523fd7e930.tar.xz zen-14ca5b35d0fc477ba30f10b80f937b523fd7e930.zip | |
Interprocess pipe support (for stdout/stderr capture) (#866)
- **RAII pipe handles for child process stdout/stderr capture**: `StdoutPipeHandles` is now a proper RAII type with automatic cleanup, move semantics, and partial close support. This makes it safe to use pipes for capturing child process output without risking handle/fd leaks.
- **Optional separate stderr pipe**: `CreateProcOptions` now accepts a `StderrPipe` field so callers can capture stdout and stderr independently. When null (default), stderr shares the stdout pipe as before.
- **LogStreamListener with pluggable handler**: The TCP log stream listener accepts connections from remote processes and delivers parsed log lines through a `LogStreamHandler` interface, set dynamically via `SetHandler()`. This allows any client to receive log messages without depending on a specific console implementation.
- **TcpLogStreamSink for zen::logging**: A logging sink that forwards log messages to a `LogStreamListener` over TCP, using the native `zen::logging::Sink` infrastructure with proper thread-safe synchronization.
- **Reliable child process exit codes on Linux**: `waitpid` result handling is fixed so `ProcessHandle::GetExitCode()` returns the real exit code. `ProcessHandle::Reset()` reaps zombies directly, replacing the global `IgnoreChildSignals()` which prevented exit code collection entirely. Also fixes a TOCTOU race in `ProcessHandle::Wait()` on Linux/Mac.
- **Pipe capture test suite**: Tests covering stdout/stderr capture via pipes (both shared and separate modes), RAII cleanup, move semantics, and exit code propagation using `zentest-appstub` as the child process.
- **Service command integration tests**: Shell-based integration tests for `zen service` covering the full lifecycle (install, status, start, stop, uninstall) on all three platforms — Linux (systemd), macOS (launchd), and Windows (SCM via PowerShell).
- **Test script reorganization**: Platform-specific test scripts moved from `scripts/test_scripts/` into `scripts/test_linux/`, `test_mac/`, and `test_windows/`.
Diffstat (limited to 'scripts/test_linux/block-clone-test.sh')
| -rwxr-xr-x | scripts/test_linux/block-clone-test.sh | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/scripts/test_linux/block-clone-test.sh b/scripts/test_linux/block-clone-test.sh new file mode 100755 index 000000000..0a74283f2 --- /dev/null +++ b/scripts/test_linux/block-clone-test.sh @@ -0,0 +1,143 @@ +#!/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_linux/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." |