diff --git a/test/e2e.sh b/test/e2e.sh index 3327d67..c851c33 100755 --- a/test/e2e.sh +++ b/test/e2e.sh @@ -202,28 +202,32 @@ run_interactive_tests() { fi } -run_distro() { +run_host_interactive() { + info "Running interactive tests on host ($(uname -s))..." + if ! bash "${SCRIPT_DIR}/run-interactive.sh" 2>&1; then + return 1 + fi +} + +# Generic entry that times a named test phase and records results +run_distro_entry() { local distro="$1" + shift + # Remaining args are the function + args to run local start_time start_time="$(date +%s)" printf '\n%b══ %s ══%b\n' "$C_BOLD" "$distro" "$C_RESET" >&2 local status="PASS" - - if ! build_image "$distro"; then - status="FAIL (build)" - elif ! run_tests "$distro"; then - status="FAIL (bats)" - elif ! run_interactive_tests "$distro"; then - status="FAIL (interactive)" + if ! "$@"; then + status="FAIL" fi local end_time end_time="$(date +%s)" local duration=$(( end_time - start_time )) - # Append to results RESULTS_DISTROS="${RESULTS_DISTROS}${distro}\n" RESULTS_STATUS="${RESULTS_STATUS}${status}\n" RESULTS_DURATION="${RESULTS_DURATION}${duration}s\n" @@ -235,6 +239,24 @@ run_distro() { fi } +run_container_phases() { + local distro="$1" + if ! build_image "$distro"; then + return 1 + fi + if ! run_tests "$distro"; then + return 1 + fi + if ! run_interactive_tests "$distro"; then + return 1 + fi +} + +run_distro() { + local distro="$1" + run_distro_entry "$distro" run_container_phases "$distro" +} + # ------------------------------------------------------------------------------ # Summary # ------------------------------------------------------------------------------ @@ -282,6 +304,13 @@ main() { info "Using runtime: ${RUNTIME}" + # Run interactive tests on the host first (covers macOS ssh-keygen) + if command -v tmux >/dev/null 2>&1; then + run_distro_entry "host" run_host_interactive + else + info "tmux not found — skipping host interactive tests (install with: brew install tmux)" + fi + if [ -n "$TARGET_DISTRO" ]; then # Validate distro name local valid=false diff --git a/test/run-interactive.sh b/test/run-interactive.sh new file mode 100755 index 0000000..d88c5e2 --- /dev/null +++ b/test/run-interactive.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# Run interactive tmux tests on the host in an isolated HOME. +# Covers macOS ssh-keygen and platform-specific behavior that +# cannot be tested inside Linux containers. +# +# Requires: tmux, git, ssh-keygen + +set -o errexit +set -o nounset +set -o pipefail +IFS=$'\n\t' + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +readonly SCRIPT_DIR +REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" +readonly REPO_ROOT + +die() { + printf 'Error: %s\n' "$1" >&2 + exit 1 +} + +# Check dependencies +command -v tmux >/dev/null 2>&1 || die "tmux is required. Install with: brew install tmux" +command -v git >/dev/null 2>&1 || die "git is required" +command -v ssh-keygen >/dev/null 2>&1 || die "ssh-keygen is required" + +# Create isolated HOME +TEST_HOME="$(mktemp -d)" +trap 'rm -rf "$TEST_HOME"' EXIT + +# Set up the isolated environment +export HOME="$TEST_HOME" +export GIT_CONFIG_GLOBAL="${TEST_HOME}/.gitconfig" + +mkdir -p "${TEST_HOME}/.ssh" +mkdir -p "${TEST_HOME}/.config/git" + +# Copy the script into the test home (interactive helpers expect it at ~/git-harden.sh) +cp "${REPO_ROOT}/git-harden.sh" "${TEST_HOME}/git-harden.sh" + +# Copy interactive test scripts +cp -r "${SCRIPT_DIR}/interactive" "${TEST_HOME}/test-interactive" + +# Set up minimal git config +git config --global user.name "Test User" +git config --global user.email "test@example.com" + +printf '── Running interactive tests on host (%s) ──\n' "$(uname -s)" >&2 + +# Run the interactive tests +exec bash "${TEST_HOME}/test-interactive/run-all.sh"