Files
OmniRoute/tests/unit/proxy-echo-ipv4-fallback-9694.test.ts
Praveen K Palaniswamy 65e81158ab fix(ollama): route models by advertised capability (#11088)
Landed with the design call resolved per the owner's pick — **option 1**: the synced store is now endpoint-agnostic (persistDiscoveredModels and managedModelImport no longer drop non-chat models at write time), and chat selectability moved to read time (auto-pool expansion in autoStrategy applies filterChatSelectableModels; the models-route projection already had its chatOnly filter). Your discovery test now passes end-to-end (3/3): /api/show capabilities persist per connection and image/embedding requests route through the advertising host.

Reconciliation notes: conflicted areas merged onto the current tip (adobe discovery import, requestedModel preflight signature, resolvedProvider fast-path coexists with the synced-route override — explicit resolution wins); carried base-red drains (#10055 memoization, #11071 test variants) dropped as already-landed; the managed-model-import exclusion test was propagated to the new contract (image/video models persist; the read filter still hides them from chat pickers — pinned by a new assertion). Full battery: 205/206 focused (the one red is a confirmed periodic-timer timing flake on the loaded devbox — 20/20 isolated), autoCombo vitest 30/30, combo suites 46/46, gates + typecheck clean.

Thank you @yourspraveen — the capability probe + routing design was right; it just needed the store contract opened up. Fixes #11087.
2026-08-23 11:45:01 -03:00

139 lines
4.9 KiB
TypeScript

/**
* #9694 — proxy "Test connection" false-negative on IPv4-only SOCKS5/SSH proxies.
*
* #1255 moved every egress probe to `api64.ipify.org`, which is IPv6-first, so a
* proxy with no IPv6 route has nothing to connect to and the probe hangs until the
* caller's deadline — a healthy proxy reported dead. Swapping the target to
* `api4.ipify.org` fixes that case and breaks #1255's.
*
* The probe now tries the targets in order inside the budget the caller already
* enforced. `api64` stays FIRST so a proxy with working IPv6 behaves exactly as it
* did after #1255 — including which of its addresses is reported, which matters
* because the egress IP is used as an identity to detect accounts sharing an address.
*/
import test from "node:test";
import assert from "node:assert/strict";
const {
probeEchoTargets,
resolveEgressEchoUrls,
splitEchoAttemptBudget,
EGRESS_ECHO_URL_DUAL,
EGRESS_ECHO_URL_V4,
EGRESS_ECHO_URL_ENV,
MIN_ECHO_ATTEMPT_MS,
} = await import("../../src/lib/proxyEchoTarget.ts");
test("#9694: the IPv6-first target is still tried first", () => {
assert.deepEqual(resolveEgressEchoUrls({}), [EGRESS_ECHO_URL_DUAL, EGRESS_ECHO_URL_V4]);
assert.equal(EGRESS_ECHO_URL_DUAL, "https://api64.ipify.org?format=json");
assert.equal(EGRESS_ECHO_URL_V4, "https://api4.ipify.org?format=json");
});
test("#9694: an operator override pins exactly one target", () => {
const env = { [EGRESS_ECHO_URL_ENV]: " https://echo.internal/ip " };
assert.deepEqual(resolveEgressEchoUrls(env), ["https://echo.internal/ip"]);
for (const blank of ["", " "]) {
assert.deepEqual(resolveEgressEchoUrls({ [EGRESS_ECHO_URL_ENV]: blank }), [
EGRESS_ECHO_URL_DUAL,
EGRESS_ECHO_URL_V4,
]);
}
});
test("#9694: attempts share the caller's budget instead of extending it", () => {
// The real call sites use 5s, 6s and 10s.
assert.deepEqual(splitEchoAttemptBudget(10000, 2), [5000, 5000]);
assert.deepEqual(splitEchoAttemptBudget(6000, 2), [3000, 3000]);
assert.deepEqual(splitEchoAttemptBudget(5000, 2), [2500, 2500]);
for (const total of [10000, 6000, 5000]) {
const budgets = splitEchoAttemptBudget(total, 2);
assert.ok(
budgets.reduce((a, b) => a + b, 0) <= total,
"the sum must never exceed the deadline the caller already enforced"
);
}
});
test("#9694: a budget too small to split is spent on one attempt, not two useless ones", () => {
assert.deepEqual(splitEchoAttemptBudget(MIN_ECHO_ATTEMPT_MS * 2 - 2, 2), [
MIN_ECHO_ATTEMPT_MS * 2 - 2,
]);
assert.deepEqual(splitEchoAttemptBudget(0, 2), []);
assert.deepEqual(splitEchoAttemptBudget(-1, 2), []);
assert.deepEqual(splitEchoAttemptBudget(10000, 0), []);
assert.deepEqual(splitEchoAttemptBudget(10000, 1), [10000]);
});
test("#9694: a reachable IPv6-first target is used and the IPv4 target is never touched", async () => {
const tried: string[] = [];
const outcome = await probeEchoTargets(
async (url) => {
tried.push(url);
return '{"ip":"2001:db8::1"}';
},
10000,
{}
);
assert.deepEqual(tried, [EGRESS_ECHO_URL_DUAL], "no extra request for a healthy IPv6 proxy");
assert.equal(outcome.url, EGRESS_ECHO_URL_DUAL);
assert.equal(outcome.result, '{"ip":"2001:db8::1"}');
});
test("#9694: an IPv4-only proxy reaches the IPv4 target and succeeds", async () => {
const tried: Array<{ url: string; timeoutMs: number }> = [];
const outcome = await probeEchoTargets(
async (url, timeoutMs) => {
tried.push({ url, timeoutMs });
// What an IPv4-only SOCKS5 tunnel does with an IPv6-first host: nothing,
// until the attempt budget aborts it.
if (url === EGRESS_ECHO_URL_DUAL) throw new Error("This operation was aborted");
return '{"ip":"203.0.113.7"}';
},
10000,
{}
);
assert.deepEqual(
tried.map((t) => t.url),
[EGRESS_ECHO_URL_DUAL, EGRESS_ECHO_URL_V4],
"the IPv6 attempt must not end the probe"
);
assert.deepEqual(
tried.map((t) => t.timeoutMs),
[5000, 5000],
"each attempt gets half of the caller's 10s budget"
);
assert.equal(outcome.url, EGRESS_ECHO_URL_V4);
assert.equal(outcome.result, '{"ip":"203.0.113.7"}');
});
test("#9694: a genuinely dead proxy still fails, with the last real error", async () => {
await assert.rejects(
() =>
probeEchoTargets(
async (url) => {
throw new Error(`ECONNREFUSED ${url}`);
},
10000,
{}
),
/ECONNREFUSED .*api4\.ipify\.org/,
"the surfaced error must describe a network failure, not internal bookkeeping"
);
});
test("#9694: an override that fails is not silently retried against ipify", async () => {
const tried: string[] = [];
await assert.rejects(() =>
probeEchoTargets(
async (url) => {
tried.push(url);
throw new Error("nope");
},
10000,
{ [EGRESS_ECHO_URL_ENV]: "https://echo.internal/ip" }
)
);
assert.deepEqual(tried, ["https://echo.internal/ip"]);
});