sc-site-sync/test/runLivePull.sh
2026-10-19 01:25:16 -05:00

97 lines
3.7 KiB
Bash
Executable file

#!/usr/bin/env bash
# Live end-to-end PULL over real HTTP between two THROWAWAY SQLite instances.
# The SOURCE runs as a real `saltcorn serve` process; the TARGET is driven
# in-process and pulls the source's design state over the wire. Never touches
# Scott's instances or the shared plugins folder: all state, and the plugins folder
# the by-location install copies into, live in one mktemp dir (see testEnv.sh).
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
PLUGIN="$(dirname "$HERE")"
REPO="$(dirname "$PLUGIN")"
SC_BIN="$REPO/saltcorn/packages/saltcorn-cli/bin/saltcorn"
# shellcheck source=testEnv.sh
. "$HERE/testEnv.sh"
# SRC_PORT may be overridden; it must be free (never an existing instance's port).
SRC_PORT="${SRC_PORT:-3016}"
# One private state root per invocation, outside the plugin tree (see testEnv.sh).
STATE="$(make_state_dir site-sync-live)"
SRC_STATE="$STATE/src"
TGT_STATE="$STATE/tgt"
SRC_DB="$SRC_STATE/db.sqlite"
TGT_DB="$TGT_STATE/db.sqlite"
SHARED="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
NP="$REPO/saltcorn/node_modules"
UP_WAIT_SECONDS=60
ROUTE_GRACE_SECONDS=2
ENV_ID_RE='^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$'
SRC_PID=""
cleanup() {
if [ -n "$SRC_PID" ]; then
kill "$SRC_PID" 2>/dev/null || true
wait "$SRC_PID" 2>/dev/null || true
fi
rm -rf "$STATE"
}
trap cleanup EXIT
isolate_saltcorn_dirs "$STATE"
if (echo >"/dev/tcp/127.0.0.1/$SRC_PORT") 2>/dev/null; then
echo "FAILED: port $SRC_PORT is already in use (set SRC_PORT to a free port)"
exit 1
fi
mkdir -p "$SRC_STATE/files" "$TGT_STATE/files"
srcRun() { env SQLITE_FILEPATH="$SRC_DB" SALTCORN_FILE_STORE="$SRC_STATE/files" SALTCORN_SESSION_SECRET="live-src-secret" SALTCORN_NWORKERS=1 NODE_PATH="$NP" "$@"; }
tgtRun() { env SQLITE_FILEPATH="$TGT_DB" SALTCORN_FILE_STORE="$TGT_STATE/files" SALTCORN_SESSION_SECRET="live-tgt-secret" SALTCORN_NWORKERS=1 NODE_PATH="$NP" "$@"; }
# grep the ENV_ID marker so the plugin's own onLoad stdout log never pollutes it.
extractEnv() { grep -oE 'ENV_ID=[0-9a-f-]+' | tail -1 | cut -d= -f2; }
requireEnvId() {
if ! [[ "$2" =~ $ENV_ID_RE ]]; then
echo "FAILED: could not read the $1 env_id (got '$2')"
exit 1
fi
}
echo "# init schemas"
srcRun node "$SC_BIN" reset-schema --force >/dev/null
tgtRun node "$SC_BIN" reset-schema --force >/dev/null
echo "# bootstrap target + source, pair"
TGT_ENV="$(tgtRun node "$HERE/livePull.js" init-target | extractEnv)"
requireEnvId target "$TGT_ENV"
SRC_ENV="$(srcRun env TARGET_ENV="$TGT_ENV" SHARED="$SHARED" node "$HERE/livePull.js" init-source | extractEnv)"
requireEnvId source "$SRC_ENV"
tgtRun env SOURCE_ENV="$SRC_ENV" SOURCE_URL="http://127.0.0.1:$SRC_PORT" SHARED="$SHARED" node "$HERE/livePull.js" pair-target
echo " source env_id=$SRC_ENV"
echo " target env_id=$TGT_ENV"
echo "# start SOURCE server on :$SRC_PORT"
( cd "$SRC_STATE" && exec env SQLITE_FILEPATH="$SRC_DB" SALTCORN_FILE_STORE="$SRC_STATE/files" SALTCORN_SESSION_SECRET="live-src-secret" SALTCORN_NWORKERS=1 NODE_PATH="$NP" node "$SC_BIN" serve -p "$SRC_PORT" ) >"$SRC_STATE/serve.log" 2>&1 &
SRC_PID=$!
echo -n " waiting for :$SRC_PORT "
UP=0
for _ in $(seq 1 "$UP_WAIT_SECONDS"); do
if (echo >"/dev/tcp/127.0.0.1/$SRC_PORT") 2>/dev/null; then
UP=1
echo "up"
break
fi
echo -n "."
sleep 1
done
if [ "$UP" != "1" ]; then
echo " FAILED to come up; serve.log tail:"
tail -20 "$SRC_STATE/serve.log"
exit 1
fi
# small grace period for plugin route mounting
sleep "$ROUTE_GRACE_SECONDS"
echo "# DRIVE pull (target in-process -> source over HTTP)"
tgtRun env SOURCE_ENV="$SRC_ENV" SOURCE_URL="http://127.0.0.1:$SRC_PORT" node "$HERE/livePull.js" drive