aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests/harness/search_connect_harness.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/tests/harness/search_connect_harness.mjs')
-rw-r--r--packages/meshbay-hub/tests/harness/search_connect_harness.mjs37
1 files changed, 32 insertions, 5 deletions
diff --git a/packages/meshbay-hub/tests/harness/search_connect_harness.mjs b/packages/meshbay-hub/tests/harness/search_connect_harness.mjs
index 60cea2ba..0c10a39d 100644
--- a/packages/meshbay-hub/tests/harness/search_connect_harness.mjs
+++ b/packages/meshbay-hub/tests/harness/search_connect_harness.mjs
@@ -26,6 +26,13 @@ const {
resolveAt = null,
// How many nodes the hub lists for the group.
nodes = 1,
+ // Which of them answer (resolveAt applies to these). null: all.
+ answering = null,
+ // Which of them this device refuses to reach on the local network. As
+ // measured on a Pixel: no progress, and connect() names the refusal only
+ // when ICE gives up, `refusedAt` ms in.
+ lanRefused = [],
+ refusedAt = 30000,
// How far to run the clock before giving up on the harness itself.
runUntil = 300000,
} = cfg;
@@ -65,11 +72,15 @@ async function run(until) {
// ── The environment ──────────────────────────────────────────────────────────
let closed = 0;
+const closedAt = [];
+const lateRefusals = [];
+let made = 0;
class FakeTransport {
constructor() {
this.onConnectProgress = null;
this.onNeedToken = null;
+ this.index = made++;
}
connect() {
@@ -83,14 +94,25 @@ class FakeTransport {
}
}, at);
}
- return new Promise((resolve) => {
- if (resolveAt !== null) {
+ return new Promise((resolve, reject) => {
+ if (lanRefused.includes(this.index)) {
+ setTimeout(() => {
+ const err = new Error('This device refused to reach the local network');
+ err.reason = 'local_network_blocked';
+ reject(err);
+ }, refusedAt);
+ return;
+ }
+ if (resolveAt !== null && (answering === null || answering.includes(this.index))) {
setTimeout(() => resolve({ ok: true, at: now - started }), resolveAt);
+ } else {
+ // The transport's own deadline for the channel: every connect() ends.
+ setTimeout(() => reject(new Error('DataChannel open timeout')), 30000);
}
});
}
- close() { closed += 1; }
+ close() { closed += 1; closedAt.push(now); }
}
globalThis.window = { MeshBayTransport: FakeTransport };
@@ -125,13 +147,18 @@ const connectToGroup = make(hubFetch, ensureFreshToken, globalThis.window);
// ── The scenario ─────────────────────────────────────────────────────────────
let outcome = null;
-connectToGroup('https://hub.example', 'g1', 'tok', null, 'alice', 'u1')
+connectToGroup('https://hub.example', 'g1', 'tok', null, 'alice', 'u1',
+ (groupId) => { lateRefusals.push({ groupId, at: now }); })
.then(() => { outcome = { result: 'connected', at: now }; })
- .catch((e) => { outcome = { result: 'failed', at: now, error: String(e.message) }; });
+ .catch((e) => {
+ outcome = { result: 'failed', at: now, error: String(e.message), reason: e.reason || null };
+ });
await run(runUntil);
console.log(JSON.stringify({
...(outcome || { result: 'still-waiting', at: now }),
closed,
+ closedAt,
+ lateRefusals,
}));