Files
OmniRoute/tests/unit/t14-proxy-fast-fail.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

105 lines
3.4 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import {
isProxyReachable,
getCachedProxyHealth,
invalidateProxyHealth,
__setProxyHealthTcpCheckForTesting,
} from "../../src/lib/proxyHealth.ts";
import { runWithProxyContext } from "../../open-sse/utils/proxyFetch.ts";
test("T14: isProxyReachable caches unreachable proxy result", async () => {
const proxyUrl = "http://127.0.0.1:1";
invalidateProxyHealth(proxyUrl);
const healthy = await isProxyReachable(proxyUrl, 120, 2_000);
assert.equal(healthy, false);
assert.equal(getCachedProxyHealth(proxyUrl), false);
});
test("#5109: concurrent proxy reachability checks share one TCP probe", async () => {
const proxyUrl = "http://127.0.0.1:1080";
invalidateProxyHealth(proxyUrl);
let probeCount = 0;
let releaseProbe!: (healthy: boolean) => void;
const probeStarted = new Promise<void>((resolve) => {
__setProxyHealthTcpCheckForTesting(async () => {
probeCount += 1;
resolve();
return new Promise<boolean>((resolveProbe) => {
releaseProbe = resolveProbe;
});
});
});
try {
const checks = Array.from({ length: 50 }, () => isProxyReachable(proxyUrl, 120, 2_000));
await probeStarted;
assert.equal(probeCount, 1, "concurrent requests must not fan out TCP health probes");
releaseProbe(true);
assert.deepEqual(
await Promise.all(checks),
Array.from({ length: 50 }, () => true)
);
assert.equal(getCachedProxyHealth(proxyUrl), true);
} finally {
__setProxyHealthTcpCheckForTesting(null);
invalidateProxyHealth(proxyUrl);
}
});
test("#5109: transient unreachable results use a short negative cache", async () => {
const proxyUrl = "http://127.0.0.1:1081";
invalidateProxyHealth(proxyUrl);
let probeCount = 0;
__setProxyHealthTcpCheckForTesting(async () => {
probeCount += 1;
return probeCount > 1;
});
try {
assert.equal(await isProxyReachable(proxyUrl, 120, 5), false);
assert.equal(getCachedProxyHealth(proxyUrl), false);
await new Promise((resolve) => setTimeout(resolve, 15));
assert.equal(await isProxyReachable(proxyUrl, 120, 5), true);
assert.equal(getCachedProxyHealth(proxyUrl), true);
assert.equal(probeCount, 2, "failed probes must not poison the proxy for 30 seconds");
} finally {
__setProxyHealthTcpCheckForTesting(null);
invalidateProxyHealth(proxyUrl);
}
});
test("T14: runWithProxyContext fails an in-flight request fast when the proxy is unreachable", async () => {
const proxyUrl = "http://127.0.0.1:1";
invalidateProxyHealth(proxyUrl);
// #9100: the T14 probe is now NON-BLOCKING — dispatch is optimistic and the
// probe aborts the request only while it is still in flight. To observe the
// fast-fail the callback must stay pending long enough for the probe to
// resolve (a callback that resolves instantly would simply win the race).
let executed = false;
let releaseRequest: () => void = () => {};
const gate = new Promise<void>((resolve) => {
releaseRequest = resolve;
});
const pending = runWithProxyContext(proxyUrl, async () => {
executed = true;
await gate; // stay in flight until the probe resolves unreachable
return "ok";
});
await assert.rejects(pending, (err) => (err as { code?: string })?.code === "PROXY_UNREACHABLE");
assert.equal(executed, true, "dispatch is optimistic; the request was started before the abort");
releaseRequest();
});