Skip to content

test(remote): add coverage for the remote gateway server - #288

Open
cyberspace-cs wants to merge 2 commits into
Tencent:mainfrom
cyberspace-cs:test/remote-gateway-coverage
Open

cyberspace-cs wants to merge 2 commits into
Tencent:mainfrom
cyberspace-cs:test/remote-gateway-coverage

Conversation

@cyberspace-cs

Copy link
Copy Markdown

Summary

The remote gateway module (crates/bsk-cli/src/daemon/remote/server.rs) was added in 0.3.0 with zero test coverage. This PR adds 6 tests covering its response helpers and the full request lifecycle over a real bound listener.

What's covered

Helper functions (pure):

  • response() emits JSON with cache-control: no-store and connection: close
  • denied() returns 401 with a structured {error: invalid_authorization} body
  • retry_response() sets retry-after alongside the status code

End-to-end integration tests (real bind() listener, driven with reqwest / tokio-tungstenite, using the existing isolated() lifecycle helper so parallel runs don't pollute each other's BSK_HOME):

  • remote_gateway_rejects_unauthenticated_requests — missing Origin, query-string requests, unknown paths, non-browser methods, missing/malformed Bearer credentials and non-JSON bodies all fail closed; the authorize endpoint rate limits per peer (429 + retry-after: 60)
  • remote_gateway_pairs_device_over_http — pairing exchange persists a durable device grant and returns a grant token
  • remote_gateway_upgrades_authorized_device — an authorized device with a matching bsk-auth. WebSocket subprotocol and the extension Origin upgrades to 101 and echoes the subprotocol

Verification

cargo test -p bsk --lib daemon::remote
14 passed; 0 failed

Full cargo test -p bsk --lib run: 334 passed; 2 failed — both failures are pre-existing Windows path assertions in skill_install::harness (they hard-code /home/user/.hermes/skills and are unrelated to this change).

cargo fmt --check clean.

The IPC protocol is JSON-RPC-style: a successful reply carries
"result" and a failed reply carries "error". Two defects made JSON
null a silent failure channel instead of a legal value.

1. Decoder (bsk-protocol): ResponseFrame::deserialize and the Frame
   visitor modelled the result field as Option<Value>, which serde
   collapses "result": null into the same None as a missing field.
   The daemon emits exactly that shape through its
   serde_json::to_value(..).unwrap_or(Value::Null) fallback, so a
   result serialisation failure surfaced on the CLI as a misleading
   "ambiguous response" / "expected result or error" decode error
   instead of a null result. Both deserializers now parse the raw
   value with #[serde(default, deserialize_with)] so an explicit
   null result decodes to Ok(Value::Null) while a missing field
   stays an error.

2. Daemon (bsk-cli): every serde_json::to_value(..).unwrap_or(Value::Null)
   site silently degraded a result serialisation failure (e.g. a
   payload nesting deeper than serde_json's recursion limit) to JSON
   null, hiding the real failure and colliding with legitimate null
   results. These now route through ok_value()/serialise_err()
   helpers that return a structured protocol_error instead, and the
   upload/download param staging paths return the same error rather
   than forwarding null params to the extension.

Adds unit tests on both sides: explicit-null decode for Frame and
ResponseFrame, serialise round-trip symmetry, missing-field
regression, and the daemon-side serialisation-failure path.
Adds 6 tests to crates/bsk-cli/src/daemon/remote/server.rs, the remote
gateway module introduced in 0.3.0 which previously had no test coverage:

- response_sets_json_no_store_headers_and_body: response() helper emits
  JSON with no-store cache-control and close connection semantics.
- denied_returns_401_with_error_body: authorization failure is 401 with
  a structured error body.
- retry_response_sets_retry_after: rate-limit responses carry retry-after.
- remote_gateway_rejects_unauthenticated_requests: end-to-end over a real
  bound listener - missing Origin, query strings, unknown paths,
  non-browser methods, missing/malformed Bearer credentials and
  non-JSON bodies all fail closed; the authorize endpoint rate limits
  per peer (429 + retry-after: 60).
- remote_gateway_pairs_device_over_http: pairing exchange persists a
  durable device grant and returns a grant token.
- remote_gateway_upgrades_authorized_device: an authorized device with a
  matching bsk-auth. WebSocket subprotocol and extension Origin upgrades
  to 101.

The integration tests bind a real listener and drive the gateway with
reqwest and tokio-tungstenite, using the existing isolated() lifecycle
helper so parallel test runs do not pollute each other's BSK_HOME.

cargo test -p bsk --lib daemon::remote: 14 passed, 0 failed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant