test_sdp-mount-probe_1.sh #2

  • //
  • guest/
  • perforce_software/
  • sdp/
  • dev/
  • test/
  • bsw/
  • test_sdp-mount-probe_1.sh
  • View
  • Commits
  • Open Download .zip Download (7 KB)
#!/usr/bin/env bash
set -euo pipefail

# Tests SDP mount-point detection functions in utils.lib using tmpfs (no fstab edits).

declare -i ErrorCount=0
declare -i TestCount=0
declare -i PassCount=0
declare -i FailCount=0
declare ThisUser=

SDPBackupScript="/p4/common/bin/opt_perforce_sdp_backup.sh"

function msg() { printf '%b\n' "$*"; }
function errmsg() { printf '\nError: %s\n' "${1:-Unknown Error}"; ErrorCount=$((ErrorCount+1)); }
function bail() { errmsg "${1:-Unknown Error}"; exit "${ErrorCount}"; }
function record_ok()   { TestCount=$((TestCount+1)); PassCount=$((PassCount+1)); printf 'PASS: %s\n' "$1"; }
function record_fail() { TestCount=$((TestCount+1)); FailCount=$((FailCount+1)); printf 'FAIL: %s\n' "$1"; }

# shellcheck disable=SC1091
source /p4/common/lib/utils.lib

ThisUser=$(id -u -n)

[[ -r "$SDPBackupScript" ]] || bail "Missing expected SDP Backup Script: $SDPBackupScript"
[[ "$ThisUser" == root ]] || bail "Run as user 'root', not '$ThisUser'."

# Verify functions exist
for fn in get_mount_point find_p4depots_probe_path; do
   type -t "$fn" >/dev/null || { echo "FATAL: function '$fn' not found after sourcing $SDPBackupScript" >&2; exit 3; }
done

# --- Test bookkeeping ---------------------------------------------------------
PassCount=0
FailCount=0
TestCount=0

function assert_eq() {
   local got="$1" exp="$2" label="${3:-}"
   TestCount=$((TestCount+1))
   if [[ "$got" == "$exp" ]]; then
      PassCount=$((PassCount+1)); printf 'PASS: %s\n' "${label:-ok}"
   else
      FailCount=$((FailCount+1)); printf 'FAIL: %s\n  got: %s\n  exp: %s\n' "${label:-mismatch}" "$got" "$exp"
   fi
}

# --- Sandbox & cleanup --------------------------------------------------------
WORKDIR="$(mktemp -d -t sdp-mounttest.XXXXXXXX)"
TMPFILE=$(mktemp)
cleanup() {
   set +e
   # msg "Cleanup: Unmount everything under WORKDIR [$WORKDIR] (deepest-first)."
   if command -v findmnt >/dev/null 2>&1; then
      rm -f "$TMPFILE"
	  for mnt in $MNT_A $MNT_B; do
         if findmnt -Rno TARGET "$mnt" > /dev/null 2>&1; then
            echo "$mnt" >> "$TMPFILE"
	     fi
      done

	  # msg "Mounts Detected:\\n$(cat "$TMPFILE")\\n"
      while read -r mnt; do
         [[ -n "$mnt" ]] || continue
         umount "$mnt" >/dev/null 2>&1 || true
      done < "$TMPFILE"
   fi
   rm -rf "$WORKDIR"
}
trap cleanup EXIT INT TERM

SDPRoot="$WORKDIR/p4"
mkdir -p "$SDPRoot"

# Mount points for simulation
MNT_A="$WORKDIR/mntA"   # tmpfs
MNT_B="$WORKDIR/mntB"   # tmpfs
mkdir -p "$MNT_A" "$MNT_B"

# Mount tmpfs (no fstab)
mount -t tmpfs -o size=32M tmpfs "$MNT_A"
mount -t tmpfs -o size=32M tmpfs "$MNT_B"

# Ground truth via findmnt
expected_mp() { findmnt -no TARGET -T "$1"; }

# Helper: create an instance dir and selected links
mk_instance() {
  local inst="$1"; shift
  local base="$SDPRoot/$inst"
  mkdir -p "$base/bin"
  local kv
  for kv in "$@"; do
    local key="${kv%%=*}" val="${kv#*=}"
    case "$key" in
      depots)          ln -s "$val" "$base/depots" ;;
      cache)           ln -s "$val" "$base/cache" ;;
      checkpoints)     ln -s "$val" "$base/checkpoints" ;;
      checkpoints.*)   ln -s "$val" "$base/$key" ;;
      *) echo "FATAL: unknown mk_instance arg: $kv" >&2; exit 10 ;;
    esac
  done
}

# Build scenarios
echo "Building scenarios under: $WORKDIR"

# Instance "1": server w/ depots on MNT_A (mounted)
mk_instance "1" "depots=$MNT_A"

# Instance "px": proxy w/ cache on MNT_B (mounted)
mk_instance "px" "cache=$MNT_B"

# Instance "2": checkpoints.* variant on regular dir (not a mount)
CP_DIR="$WORKDIR/cpdir"; mkdir -p "$CP_DIR"
mk_instance "2" "checkpoints.aa=$CP_DIR"

# Instance "zzz": depots on regular dir (not a mount)
DEPOTS_NM="$WORKDIR/depots_nm"; mkdir -p "$DEPOTS_NM"
mk_instance "zzz" "depots=$DEPOTS_NM"

echo
echo "Running tests..."

# T1: No instance arg -> prefer '1' among many, resolve depots -> MNT_A
if probe=$(find_p4depots_probe_path "$SDPRoot"); then
   if [[ "${probe: -1}" == "/" ]]; then
      record_ok "T1: probe has trailing slash"
   else
      record_fail "T1: probe missing trailing slash"
   fi
   if mp=$(get_mount_point "$probe"); then
      exp=$(expected_mp "$MNT_A")
      assert_eq "$mp" "$exp" "T1: prefer '1' -> MNT_A"
   else
    record_fail "T1: get_mount_point failed"
   fi
else
   record_fail "T1: probe failed"
fi

# T2: Explicit instance 'px' (proxy) -> cache -> MNT_B
if probe=$(find_p4depots_probe_path "$SDPRoot" "px"); then
   if [[ "${probe: -1}" == "/" ]]; then
      record_ok "T2: probe has trailing slash"
   else
      record_fail "T2: probe missing trailing slash"
   fi

   if mp=$(get_mount_point "$probe"); then
      exp=$(expected_mp "$MNT_B")
      assert_eq "$mp" "$exp" "T2: proxy cache -> MNT_B"
   else
      record_fail "T2: get_mount_point failed"
   fi
else
   record_fail "T2: probe failed"
fi

# T3: checkpoints.* variant on instance '2' (not mounted)
if probe=$(find_p4depots_probe_path "$SDPRoot" "2"); then
  if mp=$(get_mount_point "$probe"); then
    exp=$(expected_mp "$CP_DIR")
    assert_eq "$mp" "$exp" "T3: checkpoints.* resolves correctly"
  else
    record_fail "T3: get_mount_point failed"
  fi
else
  record_fail "T3: probe failed"
fi

# T4: depots on non-mounted dir (instance 'zzz')
if probe=$(find_p4depots_probe_path "$SDPRoot" "zzz"); then
  if mp=$(get_mount_point "$probe"); then
    exp=$(expected_mp "$DEPOTS_NM")
    assert_eq "$mp" "$exp" "T4: depots non-mounted resolves to base mount"
  else
    record_fail "T4: get_mount_point failed"
  fi
else
  record_fail "T4: probe failed"
fi

# T5: Error when instance exists but has no depots/cache/checkpoints*
mkdir -p "$SDPRoot/empty/bin"
if probe=$(find_p4depots_probe_path "$SDPRoot" "empty"); then
   record_fail "T5: expected failure but got probe: $probe"
else
   record_ok "T5: expected failure occurred (no depots/cache/checkpoints*)"
fi

# T6: Error when SDPRoot has no instances
EMPTYROOT="$WORKDIR/emptyroot"; mkdir -p "$EMPTYROOT"
if probe=$(find_p4depots_probe_path "$EMPTYROOT"); then
   record_fail "T6: expected failure with empty SDPRoot but got probe: $probe"
else
   record_ok "T6: expected failure with empty SDPRoot"
fi

# T7: Trailing slash check (explicit '1')
if probe=$(find_p4depots_probe_path "$SDPRoot" "1"); then
   if [[ "${probe: -1}" == "/" ]]; then
      record_ok "T7: trailing slash present"
   else
      record_fail "T7: trailing slash missing"
   fi
else
   record_fail "T7: probe failed"
fi

msg "\\n--------------------------------------------
Total tests:  $TestCount
Passed:       $PassCount
Failed:       $FailCount"

if [[ "$FailCount" -eq 0 ]]; then
   msg "PASS: ALL TESTS PASSED"
else
   msg "FAIL: Some tests did not pass."
fi

# Change User Description Committed
#2 31886 C. Thomas Tyler Refactoring non-trivial functions into a library utils.lib.

Added test script.
#1 31883 C. Thomas Tyler Enhanced backup script to be all-inclusive.
Added first cut at a test script.