test(broker): smoke test for hello + direct message flow
Some checks failed
CI / Tests / 🧪 Test (push) Has been cancelled
Some checks failed
CI / Tests / 🧪 Test (push) Has been cancelled
Adds scripts/{seed-test-mesh,peer-a,peer-b,smoke-test}.ts|.sh that
prove an end-to-end message flow works against a real Postgres:
- seed-test-mesh.ts creates user+mesh+2 members with deterministic
hex pubkeys ("aa..aa", "bb..bb"), writes seed JSON to stdout
- peer-a.ts sends hello then a direct "send" message to peer B's
pubkey with fake ciphertext "hello-from-a"
- peer-b.ts sends hello, waits up to 5s for a push, asserts
senderPubkey matches peer A, exits 0/1
- smoke-test.sh wires the three together
Verified flow: hello registers presence row → send queues into
mesh.message_queue → fanout matches connected peer by pubkey →
drainForMember joins on mesh.member for senderPubkey → push lands
with ciphertext + correct sender attribution.
Also fixes a date-serialization bug that blocked the first run:
applyPendingHookStatus used `sql${col} >= ${jsDate}` which passed
JS Date.toString() to Postgres (failed to parse). Replaced raw
sql`` template with typed gte/desc/isNotNull operators from
drizzle-orm. Same fix applied in sweepPendingStatuses.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
73
apps/broker/scripts/peer-a.ts
Normal file
73
apps/broker/scripts/peer-a.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env bun
|
||||
/**
|
||||
* Smoke-test peer A (sender).
|
||||
*
|
||||
* Reads the seed JSON from /tmp/smoke-seed.json, connects to the
|
||||
* broker, sends hello, then sends one direct message to peer B.
|
||||
* Exits after 5s whether or not it gets anything back.
|
||||
*/
|
||||
|
||||
import { readFileSync } from "node:fs";
|
||||
import WebSocket from "ws";
|
||||
|
||||
const seed = JSON.parse(readFileSync("/tmp/smoke-seed.json", "utf-8")) as {
|
||||
meshId: string;
|
||||
peerA: { memberId: string; pubkey: string };
|
||||
peerB: { memberId: string; pubkey: string };
|
||||
};
|
||||
|
||||
const BROKER = process.env.BROKER_WS_URL ?? "ws://localhost:7900/ws";
|
||||
const ws = new WebSocket(BROKER);
|
||||
|
||||
let helloAcked = false;
|
||||
|
||||
ws.on("open", () => {
|
||||
console.log("[peer-a] connected, sending hello");
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: "hello",
|
||||
meshId: seed.meshId,
|
||||
memberId: seed.peerA.memberId,
|
||||
pubkey: seed.peerA.pubkey,
|
||||
sessionId: "peer-a-session",
|
||||
pid: process.pid,
|
||||
cwd: "/tmp/peer-a",
|
||||
signature: "stub",
|
||||
nonce: "stub",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
ws.on("message", (raw) => {
|
||||
const msg = JSON.parse(raw.toString());
|
||||
console.log("[peer-a] recv:", JSON.stringify(msg));
|
||||
if (!helloAcked) {
|
||||
// Broker doesn't currently ack hello explicitly; first message we
|
||||
// get is a push OR error. Assume success and fire our send after
|
||||
// a short delay.
|
||||
}
|
||||
});
|
||||
|
||||
ws.on("error", (e) => console.error("[peer-a] error:", e.message));
|
||||
ws.on("close", () => console.log("[peer-a] closed"));
|
||||
|
||||
// After a short delay to let hello complete, send the test message.
|
||||
setTimeout(() => {
|
||||
console.log("[peer-a] sending direct message to peer-b");
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: "send",
|
||||
targetSpec: seed.peerB.pubkey,
|
||||
priority: "now",
|
||||
nonce: "fake-nonce-aaa",
|
||||
ciphertext: "hello-from-a",
|
||||
id: "msg-1",
|
||||
}),
|
||||
);
|
||||
}, 500);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log("[peer-a] done, closing");
|
||||
ws.close();
|
||||
process.exit(0);
|
||||
}, 5000);
|
||||
Reference in New Issue
Block a user