#!/bin/bash
# run_trim_test.sh
#
# PURPOSE:
# Run trim_excess_metadata.sh against the prepared lab environment on
# p4c-nyc-03 in three passes:
# 1. Dry run — preview only, no changes
# 2. Live run — execute all phases (no snap yet)
# 3. Snap run — same as live but also executes Phase 17 (p4 snap)
#
# After the snap run, this script prints the journal patch path and the
# exact commands needed to apply it and clean up orphaned archives.
#
# RUNS ON: p4c-bos-01 (as the perforce OS user)
#
# PREREQ: setup_lab.sh has already been run successfully.
#
# USAGE:
# cd /home/perforce/tem
# bash test/run_trim_test.sh
#
# Or with explicit tag:
# bash test/run_trim_test.sh [site_tag] (default: gf)
set -uo pipefail
# ---------------------------------------------------------------------------
# Configuration
# ---------------------------------------------------------------------------
SITE_TAG="${1:-gf}"
NYC03="p4c-nyc-03"
SDP_INSTANCE=1
TEM_DIR="/home/perforce/tem"
TRIM_SCRIPT="${TEM_DIR}/trim_excess_metadata.sh"
P4CONFIG_GF="${TEM_DIR}/.p4config.gf"
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
H1="============================================================"
H2="------------------------------------------------------------"
msg() { echo -e "$*"; }
hdr() { msg "\n${H1}\n$*\n${H2}"; }
step() { msg " --> $*"; }
ok() { msg " ✅ $*"; }
warn() { msg " ⚠️ $*"; }
fail() { msg " ❌ $*"; }
check_exit() {
local code="$1" label="$2" expected="${3:-0}"
if [[ "$code" -eq "$expected" ]]; then
ok "${label}: exit ${code} (expected)"
else
warn "${label}: exit ${code} (expected ${expected})"
fi
}
# ---------------------------------------------------------------------------
# Pre-flight
# ---------------------------------------------------------------------------
hdr "Pre-flight"
[[ -f "$TRIM_SCRIPT" ]] || { fail "Trim script not found: ${TRIM_SCRIPT}"; exit 1; }
[[ -f "$P4CONFIG_GF" ]] || { fail "P4CONFIG not found: ${P4CONFIG_GF} — run setup_lab.sh first"; exit 1; }
[[ -f "${TEM_DIR}/keep_users.gf.txt" ]] || { fail "keep_users.gf.txt not found — run setup_lab.sh first"; exit 1; }
[[ -f "${TEM_DIR}/keep_groups.gf.txt" ]] || { fail "keep_groups.gf.txt not found — run setup_lab.sh first"; exit 1; }
export P4CONFIG="$P4CONFIG_GF"
cd "$TEM_DIR"
step "Logging in to nyc-03 (using raw p4 login so ticket goes to .p4tickets) ..."
P4ADMIN_PASSWD="/p4/common/config/.p4passwd.p4_1.admin"
if [[ -f "$P4ADMIN_PASSWD" ]]; then
p4 login -a < "$P4ADMIN_PASSWD" 2>&1 | grep -E "logged in|Success|Error" || true
else
step "Warning: ${P4ADMIN_PASSWD} not found — you may need to log in manually."
fi
step "Verifying nyc-03 is a standalone commit server ..."
SERVER_INFO=$(p4 -ztag info -s 2>/dev/null)
SERVER_ID=$(echo "$SERVER_INFO" | awk '/^[.][.][.] ServerID / {print $3}')
SERVICES=$(echo "$SERVER_INFO" | awk '/^[.][.][.] serverServices /{print $3}')
P4ROOT=$(echo "$SERVER_INFO" | awk '/^[.][.][.] serverRoot / {print $3}')
if [[ "$SERVICES" != "standard" ]]; then
fail "nyc-03 services='${SERVICES}' — expected 'standard'. Run setup_lab.sh first."
exit 1
fi
ok "nyc-03: ServerID=${SERVER_ID}, Services=${SERVICES}, P4ROOT=${P4ROOT}"
# Show current state before trim
msg ""
step "Current depots on nyc-03:"
p4 depots 2>/dev/null | awk '{print " " $0}' || true
step "Current users on nyc-03:"
p4 users 2>/dev/null | awk '{print " " $0}' || true
# ---------------------------------------------------------------------------
# Pass 1: Dry run
# ---------------------------------------------------------------------------
hdr "Pass 1: Dry Run (no changes)"
DRY_LOG="${TEM_DIR}/test_dry_run.log"
msg "Log: ${DRY_LOG}"
bash "$TRIM_SCRIPT" "$SITE_TAG" 2>&1 | tee "$DRY_LOG"
DRY_EXIT="${PIPESTATUS[0]}"
check_exit "$DRY_EXIT" "Dry run" 0
# ---------------------------------------------------------------------------
# Pass 2: Live Run (no snap)
# ---------------------------------------------------------------------------
hdr "Pass 2: Live Run (-y, no snap)"
LIVE_LOG="${TEM_DIR}/test_live_run.log"
msg "Log: ${LIVE_LOG}"
bash "$TRIM_SCRIPT" "$SITE_TAG" -y 2>&1 | tee "$LIVE_LOG"
LIVE_EXIT="${PIPESTATUS[0]}"
# Exit 4 = shelved CL failures (expected: shelved CLs in filtered depots have
# no archive content to delete). 0 also acceptable if shelved CLs already gone.
if [[ "$LIVE_EXIT" -eq 0 || "$LIVE_EXIT" -eq 4 ]]; then
ok "Live run: exit ${LIVE_EXIT} (expected 0 or 4)"
else
warn "Live run: exit ${LIVE_EXIT} (expected 0 or 4)"
fi
# ---------------------------------------------------------------------------
# Pass 3: Snap Run (-y -snap)
# ---------------------------------------------------------------------------
hdr "Pass 3: Snap Run (-y -snap)"
SNAP_LOG="${TEM_DIR}/test_snap_run.log"
msg "Log: ${SNAP_LOG}"
bash "$TRIM_SCRIPT" "$SITE_TAG" -y -snap 2>&1 | tee "$SNAP_LOG"
SNAP_EXIT="${PIPESTATUS[0]}"
if [[ "$SNAP_EXIT" -eq 0 || "$SNAP_EXIT" -eq 4 ]]; then
ok "Snap run: exit ${SNAP_EXIT} (expected 0 or 4)"
else
warn "Snap run: exit ${SNAP_EXIT} (expected 0 or 4)"
fi
# ---------------------------------------------------------------------------
# Journal patch and cleanup instructions
# ---------------------------------------------------------------------------
hdr "Journal Patch: Apply Instructions"
# Find the most recent journal patch file generated by the trim script
JNL=$(ls -t "${TEM_DIR}"/trim_excess_metadata.*.jnl 2>/dev/null | head -1 || true)
if [[ -z "$JNL" ]]; then
msg "No journal patch file found. (All empty depots may have been deleted"
msg "via the front-door method — no patch needed.)"
else
ok "Journal patch file: ${JNL}"
msg ""
msg "The journal patch removes depot specs from db.domain for depots that"
msg "p4d refused to delete via the front-door method (e.g. because db.storage"
msg "entries remain from lazy copies into kept depot archives)."
msg ""
msg "To apply:"
msg ""
msg " 1. Copy patch to the p4d server (it must be on its local filesystem):"
msg " scp '${JNL}' perforce@${NYC03}:/tmp/"
msg ""
msg " 2. Stop p4d, apply, restart:"
msg " ssh perforce@${NYC03} \\"
msg " 'sudo systemctl stop p4d_${SDP_INSTANCE} && \\"
msg " p4d -r ${P4ROOT} -jr /tmp/$(basename "$JNL") && \\"
msg " sudo systemctl start p4d_${SDP_INSTANCE}'"
msg ""
msg " 3. Verify data integrity:"
msg " export P4CONFIG=${P4CONFIG_GF}"
msg " p4 verify //jam/... //pb/..."
msg ""
msg " 4. Delete orphaned archive directories (from Phase 18 output above)."
msg " Example (adjust to match Phase 18 output):"
msg " ssh perforce@${NYC03} 'rm -rf /p4/${SDP_INSTANCE}/depots/depot'"
fi
# ---------------------------------------------------------------------------
# Final verification
# ---------------------------------------------------------------------------
hdr "Final State Verification"
step "Waiting a moment for any service restart to settle ..."
sleep 3
step "Depots on nyc-03 after trim:"
p4 depots 2>/dev/null | awk '{print " " $0}' || true
step "Users on nyc-03 after trim:"
p4 users 2>/dev/null | awk '{print " " $0}' || true
step "Groups on nyc-03 after trim:"
p4 groups 2>/dev/null | awk '{print " " $0}' || true
step "Server specs on nyc-03 after trim:"
p4 servers 2>/dev/null | awk '{print " " $0}' || true
msg ""
msg "${H1}"
msg "Trim test run complete."
msg ""
msg "Expected outcomes (after journal patch applied):"
msg " Depots : jam, pb, Perforce (remote), spec, unload"
msg " Users : perforce only"
msg " Groups : testers only"
msg " Servers: p4d_commit_gf only"
msg " p4 verify //jam/... //pb/... — clean"
msg "${H1}"
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #2 | 32770 | C. Thomas Tyler |
Fix setup_lab.sh bugs G-J; fix run_trim_test.sh; Phase 17b validated setup_lab.sh bugs fixed: G. Phase 2 idempotency: use 'p4 server --exists -o' (plain -o always returns template) H. Phase 6: copy .md5 alongside .gz; rm -f before scp (read-only file on re-run) I. serverServices (not services) in p4 -ztag info output -- fix in setup_lab.sh + run_trim_test.sh J. Fresh ticket after standalone promotion: raw 'p4 login -a' with P4CONFIG=.p4config.gf Phase 17b test results (confirmed): - p4 storage -d only removes lbrRefCount=0 entries; all 5 depots had non-zero refcounts - Falls back to journal patch correctly for all 5 depots - @dv@ patch format (DOtype=0 placeholder) accepted by p4d -jr -- exit 0 - Post-patch: correct 5 depots remain; p4 verify clean (348+441 files) Co-authored-by: Copilot <[email protected]> |
||
| #1 | 32756 | C. Thomas Tyler |
Add test/ directory: setup and run scripts for trim_excess_metadata testing Captures the full Lab 0 -> trim-ready setup procedure as runnable scripts, making it easy for a future agent or human to reproduce the test environment from scratch. Files added: - test/README.md — full documentation: Battle School dependency, lab topology, what the test simulates (filtered-replication divestiture), lazy-copy leakage explanation, expected outcomes, gotchas - test/setup_lab.sh — orchestration script (runs on bos-01); adds gf site tag, runs mkrep.sh, adds RevisionDataFilter/ArchiveDataFilter, fixes service user password, rotates journal, creates filtered seed checkpoint, initialises nyc-03 as FFR replica, pulls archives via p4verify, promotes to standalone commit server, creates .p4config.gf / keep_users / keep_groups files - test/run_trim_test.sh — runs trim in 3 passes (dry, live, snap); prints journal patch apply commands and cleanup instructions Also updated: - ai/session_log_2026-06-16.md — added p4 snap / deep-rename context section Co-authored-by: Copilot <[email protected]> |