← back to Dw Vendor Microsites

lib/smoke-local.sh

72 lines

#!/usr/bin/env bash
# smoke-local.sh <viewer_dir> <jsonl> <fieldmap> <expected_count>
#
# Boots `node server.js <port> <jsonl> <fieldmap>` on an OS-assigned port, then asserts:
#   - GET /                 -> 200
#   - GET /api/skus         -> 200 and `all` == expected_count (== table row count)
#   - GET /api/facets       -> 200 and at least one facet non-empty
#   - GET /api/config       -> 200 with a title
# Prints a JSON verdict and exits 0 on PASS, non-zero on FAIL. Always kills the node.
set -euo pipefail

VDIR="${1:?usage: smoke-local.sh <viewer_dir> <jsonl> <fieldmap> <expected_count>}"
JSONL="${2:?missing jsonl}"
FIELDMAP="${3:?missing fieldmap}"
EXPECT="${4:?missing expected_count}"

PORT=$(python3 -c "import socket;s=socket.socket();s.bind(('127.0.0.1',0));print(s.getsockname()[1]);s.close()")

node "$VDIR/server.js" "$PORT" "$JSONL" "$FIELDMAP" >/tmp/smoke-$PORT.log 2>&1 &
NODE_PID=$!
trap 'kill $NODE_PID 2>/dev/null || true' EXIT

# wait for boot (max 8s)
for i in $(seq 1 40); do
  if curl -s -o /dev/null "http://127.0.0.1:$PORT/api/config" 2>/dev/null; then break; fi
  sleep 0.2
done

python3 - "$PORT" "$EXPECT" <<'PY'
import sys, json, urllib.request
port = sys.argv[1]; expect = int(sys.argv[2])
base = f"http://127.0.0.1:{port}"
def get(p):
    with urllib.request.urlopen(base+p, timeout=8) as r:
        return r.status, r.read().decode()

res = {"port": port, "checks": {}, "status": "PASS"}
def fail(msg):
    res["status"]="FAIL"; res.setdefault("errors",[]).append(msg)

try:
    s,_ = get("/"); res["checks"]["root"]=s
    if s!=200: fail(f"root {s}")
except Exception as e: fail(f"root err {e}")

try:
    s,b = get("/api/config"); res["checks"]["config"]=s
    c=json.loads(b)
    if s!=200 or not c.get("title"): fail("config no title")
    res["title"]=c.get("title"); res["samples_only"]=c.get("samples_only")
except Exception as e: fail(f"config err {e}")

try:
    s,b = get("/api/skus?limit=1"); res["checks"]["skus"]=s
    d=json.loads(b); allc=d.get("all")
    res["sku_all"]=allc
    if s!=200: fail(f"skus {s}")
    if allc!=expect: fail(f"count mismatch all={allc} expect={expect}")
except Exception as e: fail(f"skus err {e}")

try:
    s,b = get("/api/facets"); res["checks"]["facets"]=s
    d=json.loads(b); f=d.get("facets",{})
    nonempty = any(len(v)>0 for v in f.values())
    res["facets_nonempty"]=nonempty
    if s!=200 or not nonempty: fail("facets empty")
except Exception as e: fail(f"facets err {e}")

print(json.dumps(res))
sys.exit(0 if res["status"]=="PASS" else 1)
PY