updates for testing

This commit is contained in:
Jacob Dubin
2026-04-14 20:36:07 -05:00
parent 8c58b895f6
commit d1672e1613
8 changed files with 385 additions and 0 deletions

View File

@@ -12,3 +12,11 @@ These scripts help exercise the new .NET hosted cloud locally.
Runs a small readiness checklist before the first physical Jibo test against the .NET cloud.
- `Import-WebSocketCaptureFixture.ps1`
Sanitizes an exported websocket capture fixture and copies it into the checked-in websocket fixture set.
- `start-dotnet-with-node-cert.sh`
Starts the .NET API on Linux using the same PEM certificate material already used by the Node server.
- `invoke-live-jibo-prep.sh`
Bash equivalent of the live-run prep checklist for Ubuntu.
- `get-websocket-capture-summary.sh`
Bash summary helper for captured websocket telemetry and exported fixtures.
- `import-websocket-capture-fixture.py`
Cross-platform import/sanitization helper for exported websocket fixtures.

View File

@@ -0,0 +1,48 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CAPTURE_DIRECTORY="${1:-${SCRIPT_DIR}/../../src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/bin/Debug/net10.0/captures/websocket}"
if [[ ! -d "${CAPTURE_DIRECTORY}" ]]; then
echo "No websocket capture directory found at ${CAPTURE_DIRECTORY}"
exit 0
fi
shopt -s nullglob
event_files=( "${CAPTURE_DIRECTORY}"/*.events.ndjson )
if [[ ${#event_files[@]} -eq 0 ]]; then
echo "No websocket telemetry event files found in ${CAPTURE_DIRECTORY}"
exit 0
fi
python3 - "$CAPTURE_DIRECTORY" "${event_files[@]}" <<'PY'
import collections
import json
import os
import sys
capture_dir = sys.argv[1]
event_files = sys.argv[2:]
counter = collections.Counter()
for path in event_files:
with open(path, "r", encoding="utf-8") as handle:
for line in handle:
line = line.strip()
if not line:
continue
payload = json.loads(line)
counter[payload.get("EventType", "unknown")] += 1
for key in sorted(counter):
print(f"{key}: {counter[key]}")
fixture_dir = os.path.join(capture_dir, "fixtures")
if os.path.isdir(fixture_dir):
print("")
print("Exported websocket fixtures:")
for name in sorted(os.listdir(fixture_dir)):
if name.endswith(".flow.json"):
print(f" - {name}")
PY

View File

@@ -0,0 +1,70 @@
#!/usr/bin/env python3
import argparse
import json
from pathlib import Path
def redact(value):
if value is None:
return None
if isinstance(value, str):
lowered = value.lower()
if "token" in lowered or "bearer" in lowered or "session" in lowered:
return "[redacted]"
return value
if isinstance(value, list):
return [redact(item) for item in value]
if isinstance(value, dict):
result = {}
for key, item in value.items():
lowered = key.lower()
if "token" in lowered or "authorization" in lowered:
result[key] = "[redacted]"
else:
result[key] = redact(item)
return result
return value
def main():
parser = argparse.ArgumentParser(description="Import and sanitize an exported websocket capture fixture.")
parser.add_argument("source_path")
parser.add_argument("fixture_name")
parser.add_argument(
"--destination-directory",
default=str(Path(__file__).resolve().parents[2] / "src" / "Jibo.Cloud" / "node" / "fixtures" / "websocket"),
)
parser.add_argument("--overwrite", action="store_true")
args = parser.parse_args()
source_path = Path(args.source_path).resolve()
destination_directory = Path(args.destination_directory).resolve()
destination_directory.mkdir(parents=True, exist_ok=True)
destination_path = destination_directory / f"{args.fixture_name}.flow.json"
if destination_path.exists() and not args.overwrite:
raise SystemExit(f"Destination fixture already exists: {destination_path}. Use --overwrite to replace it.")
with source_path.open("r", encoding="utf-8") as handle:
fixture = json.load(handle)
sanitized = redact(fixture)
sanitized["name"] = args.fixture_name
if "session" in sanitized and isinstance(sanitized["session"], dict):
sanitized["session"]["token"] = "[redacted]"
with destination_path.open("w", encoding="utf-8", newline="\n") as handle:
json.dump(sanitized, handle, indent=2)
handle.write("\n")
print("Imported sanitized websocket fixture:")
print(f" - source: {source_path}")
print(f" - destination: {destination_path}")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,37 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BASE_URL="${BASE_URL:-https://localhost:5001}"
CAPTURE_DIRECTORY="${CAPTURE_DIRECTORY:-${SCRIPT_DIR}/../../src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/bin/Debug/net10.0/captures/websocket}"
EXPECTED_HOSTS=(
"api.jibo.com"
"api-socket.jibo.com"
"neo-hub.jibo.com"
)
echo "OpenJibo live Jibo prep"
echo ""
echo "1. HTTP health check"
curl --silent --show-error --fail "${BASE_URL%/}/health" | python3 -m json.tool
echo ""
echo "2. Expected robot-facing hosts"
for host in "${EXPECTED_HOSTS[@]}"; do
echo " - ${host}"
done
echo ""
echo "3. Capture directory"
mkdir -p "${CAPTURE_DIRECTORY}"
echo " - ${CAPTURE_DIRECTORY}"
echo ""
echo "4. Live-run checklist"
echo " - keep the Ubuntu/Jibo routing setup in place"
echo " - keep the Node server available as a fallback"
echo " - point Jibo at the .NET server using the same controlled network settings"
echo " - perform one startup check, one chat turn, and one joke turn"
echo " - after the run, inspect capture output with scripts/cloud/get-websocket-capture-summary.sh"
echo " - import the best exported fixture with scripts/cloud/import-websocket-capture-fixture.py"

View File

@@ -0,0 +1,67 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
API_PROJECT="${REPO_ROOT}/src/Jibo.Cloud/dotnet/src/Jibo.Cloud.Api/Jibo.Cloud.Api.csproj"
CERT_PEM="${CERT_PEM:-${REPO_ROOT}/src/Jibo.Cloud/node/cert.pem}"
KEY_PEM="${KEY_PEM:-${REPO_ROOT}/src/Jibo.Cloud/node/key.pem}"
CHAIN_PEM="${CHAIN_PEM:-}"
PFX_OUT="${PFX_OUT:-${REPO_ROOT}/.tmp/openjibo-dev-cert.pfx}"
PFX_PASSWORD="${PFX_PASSWORD:-openjibo-dev-password}"
ASPNETCORE_URLS="${ASPNETCORE_URLS:-https://0.0.0.0:443;http://0.0.0.0:24605}"
DOTNET_ENVIRONMENT="${DOTNET_ENVIRONMENT:-Development}"
mkdir -p "$(dirname "${PFX_OUT}")"
if [[ ! -f "${CERT_PEM}" ]]; then
echo "Missing CERT_PEM: ${CERT_PEM}" >&2
exit 1
fi
if [[ ! -f "${KEY_PEM}" ]]; then
echo "Missing KEY_PEM: ${KEY_PEM}" >&2
exit 1
fi
OPENSSL_ARGS=(
pkcs12
-export
-out "${PFX_OUT}"
-inkey "${KEY_PEM}"
-in "${CERT_PEM}"
-passout "pass:${PFX_PASSWORD}"
)
if [[ -n "${CHAIN_PEM}" ]]; then
if [[ ! -f "${CHAIN_PEM}" ]]; then
echo "Missing CHAIN_PEM: ${CHAIN_PEM}" >&2
exit 1
fi
OPENSSL_ARGS+=( -certfile "${CHAIN_PEM}" )
fi
echo "Creating PFX for Kestrel"
echo " - cert: ${CERT_PEM}"
echo " - key: ${KEY_PEM}"
if [[ -n "${CHAIN_PEM}" ]]; then
echo " - chain: ${CHAIN_PEM}"
fi
echo " - pfx: ${PFX_OUT}"
openssl "${OPENSSL_ARGS[@]}"
export ASPNETCORE_URLS
export DOTNET_ENVIRONMENT
export ASPNETCORE_Kestrel__Certificates__Default__Path="${PFX_OUT}"
export ASPNETCORE_Kestrel__Certificates__Default__Password="${PFX_PASSWORD}"
echo ""
echo "Starting OpenJibo .NET cloud"
echo " - project: ${API_PROJECT}"
echo " - urls: ${ASPNETCORE_URLS}"
echo " - environment: ${DOTNET_ENVIRONMENT}"
cd "${REPO_ROOT}"
exec dotnet run --project "${API_PROJECT}" --no-launch-profile