From e9083cc9e3aacf765e2d00f1a62c38e17fa471e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iwo=20Strzebo=C5=84ski?= Date: Sun, 18 Oct 2026 13:35:10 +0000 Subject: [PATCH] Cover the camera path in the edge e2e test The camera work had unit tests on both ends and nothing exercising it against a real printer. This adds that, and it immediately earned its keep: it is the only test that covers `stream_base_url` surviving the hello, living on an in-memory connection, and coming back out of `GET /printers/:id/stream` - a path with no unit test behind it, because the connection map is not reachable without a socket. Verified against a live H2C: it reports a camera stream named after its own gateway id, and the endpoint answers `{"streamUrl":"http://e2e-gateway.invalid:1984","cameraId":"h2c"}`. Both halves are asserted, because "some printers have a stream and most do not" is the expected state rather than a defect. Only the X1/H2 class publishes an `rtsp_url` - confirmed at the network layer, where the H2C accepts TCP on 322 and a P1P refuses it and listens on 6000 - so the test also asserts that a printer without one is refused with a 404 that blames the printer's camera and not the gateway. A run where no printer has a camera still passes, but says so rather than claiming the path works. `CONTINUUM_STREAM_BASE_URL` is set to an unreachable name on purpose: nothing here plays video, and it only has to prove the value made the round trip. The gateway's go2rtc config is also pointed into the scratch directory now, so a run no longer writes `go2rtc.yaml` into the proxy checkout. --- scripts/e2e-edge.sh | 65 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/scripts/e2e-edge.sh b/scripts/e2e-edge.sh index c17d9e0..d8e960b 100755 --- a/scripts/e2e-edge.sh +++ b/scripts/e2e-edge.sh @@ -186,13 +186,19 @@ echo "==> starting the real continuum-proxy against it" # or cleanup kills only the wrapper and leaves an orphan reconnecting with a # stale token. An earlier version did exactly that, and the orphan then # reported a deleted farm's printers into the next run. +# STREAM_BASE_URL is deliberately set: it is what the gateway advertises in +# its hello and the only way GET /printers/:id/stream can answer 200, so +# leaving it unset would make the camera assertions below untestable rather +# than passing. It does not have to be reachable - nothing here plays video. +STREAM_BASE_URL="http://e2e-gateway.invalid:1984" env -C "$PROXY_DIR" \ CONTINUUM_GATEWAY_ID=e2e-gw \ CONTINUUM_FARM_ID="$FARM_ID" \ CONTINUUM_GATEWAY_TOKEN="$TOKEN" \ CONTINUUM_UPLINK_URL="ws://localhost:$PORT/ws/edge/v1" \ CONTINUUM_GO2RTC_BIN=/nonexistent-go2rtc \ - CONTINUUM_GO2RTC_CONFIG=./go2rtc.yaml \ + CONTINUUM_GO2RTC_CONFIG="$WORK/go2rtc.yaml" \ + CONTINUUM_STREAM_BASE_URL="$STREAM_BASE_URL" \ CONTINUUM_PRINTERS_PATH=printers.toml \ RUST_LOG=info \ "$PROXY_DIR/target/debug/continuum-proxy" > "$WORK/proxy.log" 2>&1 & @@ -277,6 +283,58 @@ else COMMAND_TESTED=yes fi +# --- 5b. the camera path --------------------------------------------------- + +# Only the X1/H2 class publishes an rtsp_url - confirmed at the network layer: +# the H2C accepts TCP on 322, a P1P refuses it and listens on 6000 instead. So +# "some printers have a stream and most do not" is the expected state, and both +# halves are asserted. A run where no printer has a camera still passes, but +# says so rather than claiming the path works. +echo "==> the camera path: what the gateway reported, and what the API answers" +WITH_CAMERA="$(psql_q "SELECT gateway_printer_id FROM printers + WHERE farm_id='$FARM_ID' AND camera_stream IS NOT NULL + ORDER BY gateway_printer_id LIMIT 1")" + +if [ -z "$WITH_CAMERA" ]; then + echo " SKIPPED: no printer reported a camera stream." + echo " Expected if only P1/A1-class printers are on: they publish no rtsp_url." +else + # The gateway sets camera_stream to its own printer id, so this also checks + # the two ends agree about the name a stream is served under. + STREAM_NAME="$(psql_q "SELECT camera_stream FROM printers + WHERE farm_id='$FARM_ID' AND gateway_printer_id='$WITH_CAMERA'")" + [ "$STREAM_NAME" = "$WITH_CAMERA" ] \ + || fail "camera_stream for '$WITH_CAMERA' is '$STREAM_NAME', expected its own gateway id" + ok "'$WITH_CAMERA' reported camera stream '$STREAM_NAME'" + + CAM_UUID="$(psql_q "SELECT id FROM printers + WHERE farm_id='$FARM_ID' AND gateway_printer_id='$WITH_CAMERA'")" + STREAM="$(curl -sf -H "$AUTH_HEADER" "$BASE/printers/$CAM_UUID/stream")" \ + || fail "GET /printers/$CAM_UUID/stream failed for a printer that has a camera" + echo "$STREAM" | grep -q "\"cameraId\":\"$WITH_CAMERA\"" \ + || fail "wrong cameraId: $STREAM" + # The farm's stream base URL has to survive the hello and come back out of + # an in-memory connection, which is the part with no unit test behind it. + echo "$STREAM" | grep -q "\"streamUrl\":\"$STREAM_BASE_URL\"" \ + || fail "streamUrl did not come back from the gateway's hello: $STREAM" + ok "GET .../stream: $STREAM" +fi + +# A printer with no camera must 404, and say which half is missing. This is +# the case a frontend hits for most of a mixed fleet, so it matters that it is +# a clean refusal rather than a 200 carrying nulls. +NO_CAMERA="$(psql_q "SELECT id FROM printers + WHERE farm_id='$FARM_ID' AND camera_stream IS NULL + AND gateway_printer_id IS NOT NULL LIMIT 1")" +if [ -n "$NO_CAMERA" ]; then + CODE="$(curl -s -o "$WORK/nocam.json" -w '%{http_code}' -H "$AUTH_HEADER" \ + "$BASE/printers/$NO_CAMERA/stream")" + [ "$CODE" = "404" ] || fail "expected 404 for a printer with no camera, got $CODE" + grep -q 'no camera' "$WORK/nocam.json" \ + || fail "the 404 should blame the printer's camera, not the gateway: $(cat "$WORK/nocam.json")" + ok "a printer with no camera is refused with 404, blaming the right half" +fi + # --- 6. the negative case -------------------------------------------------- echo "==> an unclaimed printer must be refused, not guessed at" @@ -292,6 +350,11 @@ ok "unclaimed printer refused with 409 PRINTER_UNREACHABLE" echo # Say what was actually exercised. Claiming commands work when the command test # was skipped is worse than not running it. +if [ -n "${WITH_CAMERA:-}" ]; then + echo " Camera path verified: '$WITH_CAMERA' reported a stream and the API served it." +else + echo " Camera path NOT verified: no printer on this LAN publishes an rtsp_url." +fi if [ "$COMMAND_TESTED" = yes ]; then echo "PASS - telemetry and commands both verified against a real database and real printers." else