Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion tests/e2e/src/cases/background-health-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,10 @@ describe("background health e2e", () => {
},
});

app = await spawnApp();
// The admin listener is off; `admin` here is used only for
// listModelStatuses, which reads GET /status/models on the metrics
// listener. Resources are seeded straight to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/src/cases/cache-ttl-eviction-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,8 @@ describe("cache TTL eviction e2e: entry expires after ttl_seconds", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
// No admin listener: every resource here is seeded straight to etcd.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand Down
28 changes: 21 additions & 7 deletions tests/e2e/src/cases/cooldown-contract-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -74,7 +74,9 @@ describe("cooldown contract (H1) — 401 cools down despite being non-retryable"
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -225,7 +227,9 @@ describe("cooldown contract (M1) — 429 cools down even when retry_on_429=false
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -378,7 +382,9 @@ describe("cooldown contract (H2) — Retry-After header from upstream drives TTL
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -516,7 +522,9 @@ describe("filter contract (H3) — all candidates unhealthy returns 503", () =>
errorBody: { error: { message: "all-down B", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -646,7 +654,9 @@ describe("filter contract (H3 escape hatch) — try_anyway sends to known-bad",
errorBody: { error: { message: "still down", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -765,7 +775,9 @@ describe("cooldown observability — a cooldown transition emits aisix_deploymen
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -958,7 +970,9 @@ describe("cooldown observability — the state gauge follows a target back into
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
31 changes: 17 additions & 14 deletions tests/e2e/src/cases/datadog-exporter-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,8 +3,8 @@ import { createServer, type IncomingMessage, type Server } from "node:http";
import { gunzipSync } from "node:zlib";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
pickFreePort,
spawnApp,
startOpenAiUpstream,
Expand DownExpand Up@@ -126,19 +126,19 @@ async function startMockDatadog(): Promise<MockDatadog> {
};
}

async function seedRouting(admin: AdminClient, upstream: OpenAiUpstream, model: string) {
const pk = await admin.createProviderKey({
async function seedRouting(seed: SeedClient, upstream: OpenAiUpstream, model: string) {
const pk = await seed.createProviderKey({
display_name: `${model}-pk`,
secret: PROVIDER_SECRET,
api_base: `${upstream.baseUrl}/v1`,
});
await admin.createModel({
await seed.createModel({
display_name: model,
provider: "openai",
model_name: "gpt-4o-mini",
provider_key_id: pk.id,
});
await admin.createApiKey({
await seed.createApiKey({
key_hash: CALLER_KEY_HASH,
allowed_models: [model],
});
Expand DownExpand Up@@ -184,12 +184,14 @@ function asRecord(log: unknown): Record<string, unknown> {

describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog", () => {
let etcdReachable = false;
let etcd: EtcdClient | undefined;
let upstream: OpenAiUpstream | undefined;
let dd: MockDatadog | undefined;
const apps: SpawnedApp[] = [];

beforeAll(async () => {
etcdReachable = await new EtcdClient().ping();
etcd = new EtcdClient();
etcdReachable = await etcd.ping();
if (!etcdReachable) return;
// Plant the response token in the mock upstream's assistant content so the
// content-capture test can search for it in the `full` log body.
Expand DownExpand Up@@ -226,15 +228,15 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
return;
}
const app = await spawnApp({
admin: false,
// The API key rides the DP's own env, never the kine config.
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
// Deliberately seeds via the Admin API: deprecation-window coverage.
const admin = new AdminClient(app.adminUrl, app.adminKey);
await admin.createObservabilityExporter({
const seed = new SeedClient(etcd!, app.etcdPrefix);
await seed.createObservabilityExporter({
name: "mock-datadog",
enabled: true,
kind: "datadog",
Expand All@@ -245,7 +247,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
// Default privacy posture: operational metadata only, never content.
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-exporter-model");
await seedRouting(seed, upstream, "datadog-exporter-model");

await waitConfigPropagation(async () => {
try {
Expand DownExpand Up@@ -315,15 +317,16 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
const ddFull = await startMockDatadog();
const ddMeta = await startMockDatadog();
const app = await spawnApp({
admin: false,
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
try {
const admin = new AdminClient(app.adminUrl, app.adminKey);
const seed = new SeedClient(etcd!, app.etcdPrefix);
// Two exporters on the same DP: one captures content, one does not.
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-full",
enabled: true,
kind: "datadog",
Expand All@@ -332,7 +335,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "full",
});
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-meta",
enabled: true,
kind: "datadog",
Expand All@@ -341,7 +344,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-content-model");
await seedRouting(seed, upstream, "datadog-content-model");

await waitConfigPropagation(async () => {
try {
Expand Down
44 changes: 19 additions & 25 deletions tests/e2e/src/cases/guardrail-disabled-bypass-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,6 @@ import { createHash } from "node:crypto";
import OpenAI, { APIError } from "openai";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
spawnApp,
Expand DownExpand Up@@ -49,7 +48,6 @@ const FORBIDDEN_WORD = "supersecret";
describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
let app: SpawnedApp | undefined;
let upstream: OpenAiUpstream | undefined;
let admin: AdminClient | undefined;
let seed: SeedClient | undefined;
let etcdReachable = false;

Expand All@@ -59,8 +57,9 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
admin = new AdminClient(app.adminUrl, app.adminKey);
// No admin listener: resources are seeded to etcd and load-state is
// read from the metrics/status listener.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand DownExpand Up@@ -113,33 +112,28 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
// Readiness probe — two gates so the test cannot pass
// vacuously.
//
// Gate A: confirm the Guardrail row IS in the snapshot. Without
// this, the "forbidden literal arrives at upstream" assertion
// below would also pass if the rule simply hadn't propagated
// yet — indistinguishable from a real `enabled:false` bypass.
// Reading admin /v1/guardrails via the typed JSON helper is
// the cheapest way to verify the resource exists in the store
// the snapshot is built from.
// Gate A: confirm the Guardrail row IS in the applied snapshot.
// Without this, the "forbidden literal arrives at upstream"
// assertion below would also pass if the rule simply hadn't
// propagated yet — indistinguishable from a real `enabled:false`
// bypass. `/status/config`'s `resource_counts` reflects what the
// DP has LOADED (not merely what was written to etcd), served on
// the metrics listener — the admin-off equivalent of the old
// admin `/v1/guardrails` read.
//
// Gate B: confirm Model + ApiKey + ProviderKey are loaded by
// driving a benign chat completion through the proxy. A 200
// response means the dispatcher is ready.
await waitConfigPropagation(async () => {
try {
const list = (await admin!.json(
"GET",
"/admin/v1/guardrails",
)) as unknown as Array<Record<string, unknown>>;
const hasRule = list.some((entry) => {
// Admin list endpoints variably return bare values or
// {value: ...} wrappers; handle either shape generically.
const inner = (entry?.value ?? entry) as Record<
string,
unknown
>;
return inner?.name === "gr-disabled-keyword";
});
if (!hasRule) return false;
const res = await fetch(`${app!.metricsUrl}/status/config`);
if (!res.ok) return false;
const cfg = (await res.json()) as {
applied?: { resource_counts?: Record<string, number> };
};
if ((cfg.applied?.resource_counts?.guardrails ?? 0) < 1) {
return false;
}
await client.chat.completions.create({
model: "gr-disabled-model",
messages: [{ role: "user", content: "ready-probe" }],
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion tests/e2e/src/cases/background-health-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,10 @@ describe("background health e2e", () => {
},
});

app = await spawnApp();
// The admin listener is off; `admin` here is used only for
// listModelStatuses, which reads GET /status/models on the metrics
// listener. Resources are seeded straight to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/src/cases/cache-ttl-eviction-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,8 @@ describe("cache TTL eviction e2e: entry expires after ttl_seconds", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
// No admin listener: every resource here is seeded straight to etcd.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand Down
28 changes: 21 additions & 7 deletions tests/e2e/src/cases/cooldown-contract-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -74,7 +74,9 @@ describe("cooldown contract (H1) — 401 cools down despite being non-retryable"
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -225,7 +227,9 @@ describe("cooldown contract (M1) — 429 cools down even when retry_on_429=false
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -378,7 +382,9 @@ describe("cooldown contract (H2) — Retry-After header from upstream drives TTL
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -516,7 +522,9 @@ describe("filter contract (H3) — all candidates unhealthy returns 503", () =>
errorBody: { error: { message: "all-down B", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -646,7 +654,9 @@ describe("filter contract (H3 escape hatch) — try_anyway sends to known-bad",
errorBody: { error: { message: "still down", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -765,7 +775,9 @@ describe("cooldown observability — a cooldown transition emits aisix_deploymen
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -958,7 +970,9 @@ describe("cooldown observability — the state gauge follows a target back into
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
31 changes: 17 additions & 14 deletions tests/e2e/src/cases/datadog-exporter-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,8 +3,8 @@ import { createServer, type IncomingMessage, type Server } from "node:http";
import { gunzipSync } from "node:zlib";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
pickFreePort,
spawnApp,
startOpenAiUpstream,
Expand DownExpand Up@@ -126,19 +126,19 @@ async function startMockDatadog(): Promise<MockDatadog> {
};
}

async function seedRouting(admin: AdminClient, upstream: OpenAiUpstream, model: string) {
const pk = await admin.createProviderKey({
async function seedRouting(seed: SeedClient, upstream: OpenAiUpstream, model: string) {
const pk = await seed.createProviderKey({
display_name: `${model}-pk`,
secret: PROVIDER_SECRET,
api_base: `${upstream.baseUrl}/v1`,
});
await admin.createModel({
await seed.createModel({
display_name: model,
provider: "openai",
model_name: "gpt-4o-mini",
provider_key_id: pk.id,
});
await admin.createApiKey({
await seed.createApiKey({
key_hash: CALLER_KEY_HASH,
allowed_models: [model],
});
Expand DownExpand Up@@ -184,12 +184,14 @@ function asRecord(log: unknown): Record<string, unknown> {

describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog", () => {
let etcdReachable = false;
let etcd: EtcdClient | undefined;
let upstream: OpenAiUpstream | undefined;
let dd: MockDatadog | undefined;
const apps: SpawnedApp[] = [];

beforeAll(async () => {
etcdReachable = await new EtcdClient().ping();
etcd = new EtcdClient();
etcdReachable = await etcd.ping();
if (!etcdReachable) return;
// Plant the response token in the mock upstream's assistant content so the
// content-capture test can search for it in the `full` log body.
Expand DownExpand Up@@ -226,15 +228,15 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
return;
}
const app = await spawnApp({
admin: false,
// The API key rides the DP's own env, never the kine config.
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
// Deliberately seeds via the Admin API: deprecation-window coverage.
const admin = new AdminClient(app.adminUrl, app.adminKey);
await admin.createObservabilityExporter({
const seed = new SeedClient(etcd!, app.etcdPrefix);
await seed.createObservabilityExporter({
name: "mock-datadog",
enabled: true,
kind: "datadog",
Expand All@@ -245,7 +247,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
// Default privacy posture: operational metadata only, never content.
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-exporter-model");
await seedRouting(seed, upstream, "datadog-exporter-model");

await waitConfigPropagation(async () => {
try {
Expand DownExpand Up@@ -315,15 +317,16 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
const ddFull = await startMockDatadog();
const ddMeta = await startMockDatadog();
const app = await spawnApp({
admin: false,
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
try {
const admin = new AdminClient(app.adminUrl, app.adminKey);
const seed = new SeedClient(etcd!, app.etcdPrefix);
// Two exporters on the same DP: one captures content, one does not.
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-full",
enabled: true,
kind: "datadog",
Expand All@@ -332,7 +335,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "full",
});
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-meta",
enabled: true,
kind: "datadog",
Expand All@@ -341,7 +344,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-content-model");
await seedRouting(seed, upstream, "datadog-content-model");

await waitConfigPropagation(async () => {
try {
Expand Down
44 changes: 19 additions & 25 deletions tests/e2e/src/cases/guardrail-disabled-bypass-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,6 @@ import { createHash } from "node:crypto";
import OpenAI, { APIError } from "openai";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
spawnApp,
Expand DownExpand Up@@ -49,7 +48,6 @@ const FORBIDDEN_WORD = "supersecret";
describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
let app: SpawnedApp | undefined;
let upstream: OpenAiUpstream | undefined;
let admin: AdminClient | undefined;
let seed: SeedClient | undefined;
let etcdReachable = false;

Expand All@@ -59,8 +57,9 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
admin = new AdminClient(app.adminUrl, app.adminKey);
// No admin listener: resources are seeded to etcd and load-state is
// read from the metrics/status listener.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand DownExpand Up@@ -113,33 +112,28 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
// Readiness probe — two gates so the test cannot pass
// vacuously.
//
// Gate A: confirm the Guardrail row IS in the snapshot. Without
// this, the "forbidden literal arrives at upstream" assertion
// below would also pass if the rule simply hadn't propagated
// yet — indistinguishable from a real `enabled:false` bypass.
// Reading admin /v1/guardrails via the typed JSON helper is
// the cheapest way to verify the resource exists in the store
// the snapshot is built from.
// Gate A: confirm the Guardrail row IS in the applied snapshot.
// Without this, the "forbidden literal arrives at upstream"
// assertion below would also pass if the rule simply hadn't
// propagated yet — indistinguishable from a real `enabled:false`
// bypass. `/status/config`'s `resource_counts` reflects what the
// DP has LOADED (not merely what was written to etcd), served on
// the metrics listener — the admin-off equivalent of the old
// admin `/v1/guardrails` read.
//
// Gate B: confirm Model + ApiKey + ProviderKey are loaded by
// driving a benign chat completion through the proxy. A 200
// response means the dispatcher is ready.
await waitConfigPropagation(async () => {
try {
const list = (await admin!.json(
"GET",
"/admin/v1/guardrails",
)) as unknown as Array<Record<string, unknown>>;
const hasRule = list.some((entry) => {
// Admin list endpoints variably return bare values or
// {value: ...} wrappers; handle either shape generically.
const inner = (entry?.value ?? entry) as Record<
string,
unknown
>;
return inner?.name === "gr-disabled-keyword";
});
if (!hasRule) return false;
const res = await fetch(`${app!.metricsUrl}/status/config`);
if (!res.ok) return false;
const cfg = (await res.json()) as {
applied?: { resource_counts?: Record<string, number> };
};
if ((cfg.applied?.resource_counts?.guardrails ?? 0) < 1) {
return false;
}
await client.chat.completions.create({
model: "gr-disabled-model",
messages: [{ role: "user", content: "ready-probe" }],
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion tests/e2e/src/cases/background-health-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,10 @@ describe("background health e2e", () => {
},
});

app = await spawnApp();
// The admin listener is off; `admin` here is used only for
// listModelStatuses, which reads GET /status/models on the metrics
// listener. Resources are seeded straight to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/src/cases/cache-ttl-eviction-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,8 @@ describe("cache TTL eviction e2e: entry expires after ttl_seconds", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
// No admin listener: every resource here is seeded straight to etcd.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand Down
28 changes: 21 additions & 7 deletions tests/e2e/src/cases/cooldown-contract-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -74,7 +74,9 @@ describe("cooldown contract (H1) — 401 cools down despite being non-retryable"
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -225,7 +227,9 @@ describe("cooldown contract (M1) — 429 cools down even when retry_on_429=false
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -378,7 +382,9 @@ describe("cooldown contract (H2) — Retry-After header from upstream drives TTL
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -516,7 +522,9 @@ describe("filter contract (H3) — all candidates unhealthy returns 503", () =>
errorBody: { error: { message: "all-down B", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -646,7 +654,9 @@ describe("filter contract (H3 escape hatch) — try_anyway sends to known-bad",
errorBody: { error: { message: "still down", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -765,7 +775,9 @@ describe("cooldown observability — a cooldown transition emits aisix_deploymen
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -958,7 +970,9 @@ describe("cooldown observability — the state gauge follows a target back into
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
31 changes: 17 additions & 14 deletions tests/e2e/src/cases/datadog-exporter-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,8 +3,8 @@ import { createServer, type IncomingMessage, type Server } from "node:http";
import { gunzipSync } from "node:zlib";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
pickFreePort,
spawnApp,
startOpenAiUpstream,
Expand DownExpand Up@@ -126,19 +126,19 @@ async function startMockDatadog(): Promise<MockDatadog> {
};
}

async function seedRouting(admin: AdminClient, upstream: OpenAiUpstream, model: string) {
const pk = await admin.createProviderKey({
async function seedRouting(seed: SeedClient, upstream: OpenAiUpstream, model: string) {
const pk = await seed.createProviderKey({
display_name: `${model}-pk`,
secret: PROVIDER_SECRET,
api_base: `${upstream.baseUrl}/v1`,
});
await admin.createModel({
await seed.createModel({
display_name: model,
provider: "openai",
model_name: "gpt-4o-mini",
provider_key_id: pk.id,
});
await admin.createApiKey({
await seed.createApiKey({
key_hash: CALLER_KEY_HASH,
allowed_models: [model],
});
Expand DownExpand Up@@ -184,12 +184,14 @@ function asRecord(log: unknown): Record<string, unknown> {

describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog", () => {
let etcdReachable = false;
let etcd: EtcdClient | undefined;
let upstream: OpenAiUpstream | undefined;
let dd: MockDatadog | undefined;
const apps: SpawnedApp[] = [];

beforeAll(async () => {
etcdReachable = await new EtcdClient().ping();
etcd = new EtcdClient();
etcdReachable = await etcd.ping();
if (!etcdReachable) return;
// Plant the response token in the mock upstream's assistant content so the
// content-capture test can search for it in the `full` log body.
Expand DownExpand Up@@ -226,15 +228,15 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
return;
}
const app = await spawnApp({
admin: false,
// The API key rides the DP's own env, never the kine config.
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
// Deliberately seeds via the Admin API: deprecation-window coverage.
const admin = new AdminClient(app.adminUrl, app.adminKey);
await admin.createObservabilityExporter({
const seed = new SeedClient(etcd!, app.etcdPrefix);
await seed.createObservabilityExporter({
name: "mock-datadog",
enabled: true,
kind: "datadog",
Expand All@@ -245,7 +247,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
// Default privacy posture: operational metadata only, never content.
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-exporter-model");
await seedRouting(seed, upstream, "datadog-exporter-model");

await waitConfigPropagation(async () => {
try {
Expand DownExpand Up@@ -315,15 +317,16 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
const ddFull = await startMockDatadog();
const ddMeta = await startMockDatadog();
const app = await spawnApp({
admin: false,
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
try {
const admin = new AdminClient(app.adminUrl, app.adminKey);
const seed = new SeedClient(etcd!, app.etcdPrefix);
// Two exporters on the same DP: one captures content, one does not.
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-full",
enabled: true,
kind: "datadog",
Expand All@@ -332,7 +335,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "full",
});
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-meta",
enabled: true,
kind: "datadog",
Expand All@@ -341,7 +344,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-content-model");
await seedRouting(seed, upstream, "datadog-content-model");

await waitConfigPropagation(async () => {
try {
Expand Down
44 changes: 19 additions & 25 deletions tests/e2e/src/cases/guardrail-disabled-bypass-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,6 @@ import { createHash } from "node:crypto";
import OpenAI, { APIError } from "openai";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
spawnApp,
Expand DownExpand Up@@ -49,7 +48,6 @@ const FORBIDDEN_WORD = "supersecret";
describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
let app: SpawnedApp | undefined;
let upstream: OpenAiUpstream | undefined;
let admin: AdminClient | undefined;
let seed: SeedClient | undefined;
let etcdReachable = false;

Expand All@@ -59,8 +57,9 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
admin = new AdminClient(app.adminUrl, app.adminKey);
// No admin listener: resources are seeded to etcd and load-state is
// read from the metrics/status listener.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand DownExpand Up@@ -113,33 +112,28 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
// Readiness probe — two gates so the test cannot pass
// vacuously.
//
// Gate A: confirm the Guardrail row IS in the snapshot. Without
// this, the "forbidden literal arrives at upstream" assertion
// below would also pass if the rule simply hadn't propagated
// yet — indistinguishable from a real `enabled:false` bypass.
// Reading admin /v1/guardrails via the typed JSON helper is
// the cheapest way to verify the resource exists in the store
// the snapshot is built from.
// Gate A: confirm the Guardrail row IS in the applied snapshot.
// Without this, the "forbidden literal arrives at upstream"
// assertion below would also pass if the rule simply hadn't
// propagated yet — indistinguishable from a real `enabled:false`
// bypass. `/status/config`'s `resource_counts` reflects what the
// DP has LOADED (not merely what was written to etcd), served on
// the metrics listener — the admin-off equivalent of the old
// admin `/v1/guardrails` read.
//
// Gate B: confirm Model + ApiKey + ProviderKey are loaded by
// driving a benign chat completion through the proxy. A 200
// response means the dispatcher is ready.
await waitConfigPropagation(async () => {
try {
const list = (await admin!.json(
"GET",
"/admin/v1/guardrails",
)) as unknown as Array<Record<string, unknown>>;
const hasRule = list.some((entry) => {
// Admin list endpoints variably return bare values or
// {value: ...} wrappers; handle either shape generically.
const inner = (entry?.value ?? entry) as Record<
string,
unknown
>;
return inner?.name === "gr-disabled-keyword";
});
if (!hasRule) return false;
const res = await fetch(`${app!.metricsUrl}/status/config`);
if (!res.ok) return false;
const cfg = (await res.json()) as {
applied?: { resource_counts?: Record<string, number> };
};
if ((cfg.applied?.resource_counts?.guardrails ?? 0) < 1) {
return false;
}
await client.chat.completions.create({
model: "gr-disabled-model",
messages: [{ role: "user", content: "ready-probe" }],
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion tests/e2e/src/cases/background-health-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,10 @@ describe("background health e2e", () => {
},
});

app = await spawnApp();
// The admin listener is off; `admin` here is used only for
// listModelStatuses, which reads GET /status/models on the metrics
// listener. Resources are seeded straight to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/src/cases/cache-ttl-eviction-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,8 @@ describe("cache TTL eviction e2e: entry expires after ttl_seconds", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
// No admin listener: every resource here is seeded straight to etcd.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand Down
28 changes: 21 additions & 7 deletions tests/e2e/src/cases/cooldown-contract-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -74,7 +74,9 @@ describe("cooldown contract (H1) — 401 cools down despite being non-retryable"
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -225,7 +227,9 @@ describe("cooldown contract (M1) — 429 cools down even when retry_on_429=false
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -378,7 +382,9 @@ describe("cooldown contract (H2) — Retry-After header from upstream drives TTL
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -516,7 +522,9 @@ describe("filter contract (H3) — all candidates unhealthy returns 503", () =>
errorBody: { error: { message: "all-down B", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -646,7 +654,9 @@ describe("filter contract (H3 escape hatch) — try_anyway sends to known-bad",
errorBody: { error: { message: "still down", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -765,7 +775,9 @@ describe("cooldown observability — a cooldown transition emits aisix_deploymen
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -958,7 +970,9 @@ describe("cooldown observability — the state gauge follows a target back into
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
31 changes: 17 additions & 14 deletions tests/e2e/src/cases/datadog-exporter-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,8 +3,8 @@ import { createServer, type IncomingMessage, type Server } from "node:http";
import { gunzipSync } from "node:zlib";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
pickFreePort,
spawnApp,
startOpenAiUpstream,
Expand DownExpand Up@@ -126,19 +126,19 @@ async function startMockDatadog(): Promise<MockDatadog> {
};
}

async function seedRouting(admin: AdminClient, upstream: OpenAiUpstream, model: string) {
const pk = await admin.createProviderKey({
async function seedRouting(seed: SeedClient, upstream: OpenAiUpstream, model: string) {
const pk = await seed.createProviderKey({
display_name: `${model}-pk`,
secret: PROVIDER_SECRET,
api_base: `${upstream.baseUrl}/v1`,
});
await admin.createModel({
await seed.createModel({
display_name: model,
provider: "openai",
model_name: "gpt-4o-mini",
provider_key_id: pk.id,
});
await admin.createApiKey({
await seed.createApiKey({
key_hash: CALLER_KEY_HASH,
allowed_models: [model],
});
Expand DownExpand Up@@ -184,12 +184,14 @@ function asRecord(log: unknown): Record<string, unknown> {

describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog", () => {
let etcdReachable = false;
let etcd: EtcdClient | undefined;
let upstream: OpenAiUpstream | undefined;
let dd: MockDatadog | undefined;
const apps: SpawnedApp[] = [];

beforeAll(async () => {
etcdReachable = await new EtcdClient().ping();
etcd = new EtcdClient();
etcdReachable = await etcd.ping();
if (!etcdReachable) return;
// Plant the response token in the mock upstream's assistant content so the
// content-capture test can search for it in the `full` log body.
Expand DownExpand Up@@ -226,15 +228,15 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
return;
}
const app = await spawnApp({
admin: false,
// The API key rides the DP's own env, never the kine config.
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
// Deliberately seeds via the Admin API: deprecation-window coverage.
const admin = new AdminClient(app.adminUrl, app.adminKey);
await admin.createObservabilityExporter({
const seed = new SeedClient(etcd!, app.etcdPrefix);
await seed.createObservabilityExporter({
name: "mock-datadog",
enabled: true,
kind: "datadog",
Expand All@@ -245,7 +247,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
// Default privacy posture: operational metadata only, never content.
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-exporter-model");
await seedRouting(seed, upstream, "datadog-exporter-model");

await waitConfigPropagation(async () => {
try {
Expand DownExpand Up@@ -315,15 +317,16 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
const ddFull = await startMockDatadog();
const ddMeta = await startMockDatadog();
const app = await spawnApp({
admin: false,
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
try {
const admin = new AdminClient(app.adminUrl, app.adminKey);
const seed = new SeedClient(etcd!, app.etcdPrefix);
// Two exporters on the same DP: one captures content, one does not.
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-full",
enabled: true,
kind: "datadog",
Expand All@@ -332,7 +335,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "full",
});
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-meta",
enabled: true,
kind: "datadog",
Expand All@@ -341,7 +344,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-content-model");
await seedRouting(seed, upstream, "datadog-content-model");

await waitConfigPropagation(async () => {
try {
Expand Down
44 changes: 19 additions & 25 deletions tests/e2e/src/cases/guardrail-disabled-bypass-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,6 @@ import { createHash } from "node:crypto";
import OpenAI, { APIError } from "openai";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
spawnApp,
Expand DownExpand Up@@ -49,7 +48,6 @@ const FORBIDDEN_WORD = "supersecret";
describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
let app: SpawnedApp | undefined;
let upstream: OpenAiUpstream | undefined;
let admin: AdminClient | undefined;
let seed: SeedClient | undefined;
let etcdReachable = false;

Expand All@@ -59,8 +57,9 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
admin = new AdminClient(app.adminUrl, app.adminKey);
// No admin listener: resources are seeded to etcd and load-state is
// read from the metrics/status listener.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand DownExpand Up@@ -113,33 +112,28 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
// Readiness probe — two gates so the test cannot pass
// vacuously.
//
// Gate A: confirm the Guardrail row IS in the snapshot. Without
// this, the "forbidden literal arrives at upstream" assertion
// below would also pass if the rule simply hadn't propagated
// yet — indistinguishable from a real `enabled:false` bypass.
// Reading admin /v1/guardrails via the typed JSON helper is
// the cheapest way to verify the resource exists in the store
// the snapshot is built from.
// Gate A: confirm the Guardrail row IS in the applied snapshot.
// Without this, the "forbidden literal arrives at upstream"
// assertion below would also pass if the rule simply hadn't
// propagated yet — indistinguishable from a real `enabled:false`
// bypass. `/status/config`'s `resource_counts` reflects what the
// DP has LOADED (not merely what was written to etcd), served on
// the metrics listener — the admin-off equivalent of the old
// admin `/v1/guardrails` read.
//
// Gate B: confirm Model + ApiKey + ProviderKey are loaded by
// driving a benign chat completion through the proxy. A 200
// response means the dispatcher is ready.
await waitConfigPropagation(async () => {
try {
const list = (await admin!.json(
"GET",
"/admin/v1/guardrails",
)) as unknown as Array<Record<string, unknown>>;
const hasRule = list.some((entry) => {
// Admin list endpoints variably return bare values or
// {value: ...} wrappers; handle either shape generically.
const inner = (entry?.value ?? entry) as Record<
string,
unknown
>;
return inner?.name === "gr-disabled-keyword";
});
if (!hasRule) return false;
const res = await fetch(`${app!.metricsUrl}/status/config`);
if (!res.ok) return false;
const cfg = (await res.json()) as {
applied?: { resource_counts?: Record<string, number> };
};
if ((cfg.applied?.resource_counts?.guardrails ?? 0) < 1) {
return false;
}
await client.chat.completions.create({
model: "gr-disabled-model",
messages: [{ role: "user", content: "ready-probe" }],
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion tests/e2e/src/cases/background-health-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,10 @@ describe("background health e2e", () => {
},
});

app = await spawnApp();
// The admin listener is off; `admin` here is used only for
// listModelStatuses, which reads GET /status/models on the metrics
// listener. Resources are seeded straight to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/src/cases/cache-ttl-eviction-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,8 @@ describe("cache TTL eviction e2e: entry expires after ttl_seconds", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
// No admin listener: every resource here is seeded straight to etcd.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand Down
28 changes: 21 additions & 7 deletions tests/e2e/src/cases/cooldown-contract-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -74,7 +74,9 @@ describe("cooldown contract (H1) — 401 cools down despite being non-retryable"
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -225,7 +227,9 @@ describe("cooldown contract (M1) — 429 cools down even when retry_on_429=false
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -378,7 +382,9 @@ describe("cooldown contract (H2) — Retry-After header from upstream drives TTL
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -516,7 +522,9 @@ describe("filter contract (H3) — all candidates unhealthy returns 503", () =>
errorBody: { error: { message: "all-down B", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -646,7 +654,9 @@ describe("filter contract (H3 escape hatch) — try_anyway sends to known-bad",
errorBody: { error: { message: "still down", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -765,7 +775,9 @@ describe("cooldown observability — a cooldown transition emits aisix_deploymen
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -958,7 +970,9 @@ describe("cooldown observability — the state gauge follows a target back into
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
31 changes: 17 additions & 14 deletions tests/e2e/src/cases/datadog-exporter-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,8 +3,8 @@ import { createServer, type IncomingMessage, type Server } from "node:http";
import { gunzipSync } from "node:zlib";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
pickFreePort,
spawnApp,
startOpenAiUpstream,
Expand DownExpand Up@@ -126,19 +126,19 @@ async function startMockDatadog(): Promise<MockDatadog> {
};
}

async function seedRouting(admin: AdminClient, upstream: OpenAiUpstream, model: string) {
const pk = await admin.createProviderKey({
async function seedRouting(seed: SeedClient, upstream: OpenAiUpstream, model: string) {
const pk = await seed.createProviderKey({
display_name: `${model}-pk`,
secret: PROVIDER_SECRET,
api_base: `${upstream.baseUrl}/v1`,
});
await admin.createModel({
await seed.createModel({
display_name: model,
provider: "openai",
model_name: "gpt-4o-mini",
provider_key_id: pk.id,
});
await admin.createApiKey({
await seed.createApiKey({
key_hash: CALLER_KEY_HASH,
allowed_models: [model],
});
Expand DownExpand Up@@ -184,12 +184,14 @@ function asRecord(log: unknown): Record<string, unknown> {

describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog", () => {
let etcdReachable = false;
let etcd: EtcdClient | undefined;
let upstream: OpenAiUpstream | undefined;
let dd: MockDatadog | undefined;
const apps: SpawnedApp[] = [];

beforeAll(async () => {
etcdReachable = await new EtcdClient().ping();
etcd = new EtcdClient();
etcdReachable = await etcd.ping();
if (!etcdReachable) return;
// Plant the response token in the mock upstream's assistant content so the
// content-capture test can search for it in the `full` log body.
Expand DownExpand Up@@ -226,15 +228,15 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
return;
}
const app = await spawnApp({
admin: false,
// The API key rides the DP's own env, never the kine config.
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
// Deliberately seeds via the Admin API: deprecation-window coverage.
const admin = new AdminClient(app.adminUrl, app.adminKey);
await admin.createObservabilityExporter({
const seed = new SeedClient(etcd!, app.etcdPrefix);
await seed.createObservabilityExporter({
name: "mock-datadog",
enabled: true,
kind: "datadog",
Expand All@@ -245,7 +247,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
// Default privacy posture: operational metadata only, never content.
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-exporter-model");
await seedRouting(seed, upstream, "datadog-exporter-model");

await waitConfigPropagation(async () => {
try {
Expand DownExpand Up@@ -315,15 +317,16 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
const ddFull = await startMockDatadog();
const ddMeta = await startMockDatadog();
const app = await spawnApp({
admin: false,
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
try {
const admin = new AdminClient(app.adminUrl, app.adminKey);
const seed = new SeedClient(etcd!, app.etcdPrefix);
// Two exporters on the same DP: one captures content, one does not.
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-full",
enabled: true,
kind: "datadog",
Expand All@@ -332,7 +335,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "full",
});
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-meta",
enabled: true,
kind: "datadog",
Expand All@@ -341,7 +344,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-content-model");
await seedRouting(seed, upstream, "datadog-content-model");

await waitConfigPropagation(async () => {
try {
Expand Down
44 changes: 19 additions & 25 deletions tests/e2e/src/cases/guardrail-disabled-bypass-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,6 @@ import { createHash } from "node:crypto";
import OpenAI, { APIError } from "openai";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
spawnApp,
Expand DownExpand Up@@ -49,7 +48,6 @@ const FORBIDDEN_WORD = "supersecret";
describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
let app: SpawnedApp | undefined;
let upstream: OpenAiUpstream | undefined;
let admin: AdminClient | undefined;
let seed: SeedClient | undefined;
let etcdReachable = false;

Expand All@@ -59,8 +57,9 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
admin = new AdminClient(app.adminUrl, app.adminKey);
// No admin listener: resources are seeded to etcd and load-state is
// read from the metrics/status listener.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand DownExpand Up@@ -113,33 +112,28 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
// Readiness probe — two gates so the test cannot pass
// vacuously.
//
// Gate A: confirm the Guardrail row IS in the snapshot. Without
// this, the "forbidden literal arrives at upstream" assertion
// below would also pass if the rule simply hadn't propagated
// yet — indistinguishable from a real `enabled:false` bypass.
// Reading admin /v1/guardrails via the typed JSON helper is
// the cheapest way to verify the resource exists in the store
// the snapshot is built from.
// Gate A: confirm the Guardrail row IS in the applied snapshot.
// Without this, the "forbidden literal arrives at upstream"
// assertion below would also pass if the rule simply hadn't
// propagated yet — indistinguishable from a real `enabled:false`
// bypass. `/status/config`'s `resource_counts` reflects what the
// DP has LOADED (not merely what was written to etcd), served on
// the metrics listener — the admin-off equivalent of the old
// admin `/v1/guardrails` read.
//
// Gate B: confirm Model + ApiKey + ProviderKey are loaded by
// driving a benign chat completion through the proxy. A 200
// response means the dispatcher is ready.
await waitConfigPropagation(async () => {
try {
const list = (await admin!.json(
"GET",
"/admin/v1/guardrails",
)) as unknown as Array<Record<string, unknown>>;
const hasRule = list.some((entry) => {
// Admin list endpoints variably return bare values or
// {value: ...} wrappers; handle either shape generically.
const inner = (entry?.value ?? entry) as Record<
string,
unknown
>;
return inner?.name === "gr-disabled-keyword";
});
if (!hasRule) return false;
const res = await fetch(`${app!.metricsUrl}/status/config`);
if (!res.ok) return false;
const cfg = (await res.json()) as {
applied?: { resource_counts?: Record<string, number> };
};
if ((cfg.applied?.resource_counts?.guardrails ?? 0) < 1) {
return false;
}
await client.chat.completions.create({
model: "gr-disabled-model",
messages: [{ role: "user", content: "ready-probe" }],
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion tests/e2e/src/cases/background-health-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,10 @@ describe("background health e2e", () => {
},
});

app = await spawnApp();
// The admin listener is off; `admin` here is used only for
// listModelStatuses, which reads GET /status/models on the metrics
// listener. Resources are seeded straight to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/src/cases/cache-ttl-eviction-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,8 @@ describe("cache TTL eviction e2e: entry expires after ttl_seconds", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
// No admin listener: every resource here is seeded straight to etcd.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand Down
28 changes: 21 additions & 7 deletions tests/e2e/src/cases/cooldown-contract-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -74,7 +74,9 @@ describe("cooldown contract (H1) — 401 cools down despite being non-retryable"
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -225,7 +227,9 @@ describe("cooldown contract (M1) — 429 cools down even when retry_on_429=false
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -378,7 +382,9 @@ describe("cooldown contract (H2) — Retry-After header from upstream drives TTL
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -516,7 +522,9 @@ describe("filter contract (H3) — all candidates unhealthy returns 503", () =>
errorBody: { error: { message: "all-down B", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -646,7 +654,9 @@ describe("filter contract (H3 escape hatch) — try_anyway sends to known-bad",
errorBody: { error: { message: "still down", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -765,7 +775,9 @@ describe("cooldown observability — a cooldown transition emits aisix_deploymen
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -958,7 +970,9 @@ describe("cooldown observability — the state gauge follows a target back into
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
31 changes: 17 additions & 14 deletions tests/e2e/src/cases/datadog-exporter-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,8 +3,8 @@ import { createServer, type IncomingMessage, type Server } from "node:http";
import { gunzipSync } from "node:zlib";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
pickFreePort,
spawnApp,
startOpenAiUpstream,
Expand DownExpand Up@@ -126,19 +126,19 @@ async function startMockDatadog(): Promise<MockDatadog> {
};
}

async function seedRouting(admin: AdminClient, upstream: OpenAiUpstream, model: string) {
const pk = await admin.createProviderKey({
async function seedRouting(seed: SeedClient, upstream: OpenAiUpstream, model: string) {
const pk = await seed.createProviderKey({
display_name: `${model}-pk`,
secret: PROVIDER_SECRET,
api_base: `${upstream.baseUrl}/v1`,
});
await admin.createModel({
await seed.createModel({
display_name: model,
provider: "openai",
model_name: "gpt-4o-mini",
provider_key_id: pk.id,
});
await admin.createApiKey({
await seed.createApiKey({
key_hash: CALLER_KEY_HASH,
allowed_models: [model],
});
Expand DownExpand Up@@ -184,12 +184,14 @@ function asRecord(log: unknown): Record<string, unknown> {

describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog", () => {
let etcdReachable = false;
let etcd: EtcdClient | undefined;
let upstream: OpenAiUpstream | undefined;
let dd: MockDatadog | undefined;
const apps: SpawnedApp[] = [];

beforeAll(async () => {
etcdReachable = await new EtcdClient().ping();
etcd = new EtcdClient();
etcdReachable = await etcd.ping();
if (!etcdReachable) return;
// Plant the response token in the mock upstream's assistant content so the
// content-capture test can search for it in the `full` log body.
Expand DownExpand Up@@ -226,15 +228,15 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
return;
}
const app = await spawnApp({
admin: false,
// The API key rides the DP's own env, never the kine config.
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
// Deliberately seeds via the Admin API: deprecation-window coverage.
const admin = new AdminClient(app.adminUrl, app.adminKey);
await admin.createObservabilityExporter({
const seed = new SeedClient(etcd!, app.etcdPrefix);
await seed.createObservabilityExporter({
name: "mock-datadog",
enabled: true,
kind: "datadog",
Expand All@@ -245,7 +247,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
// Default privacy posture: operational metadata only, never content.
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-exporter-model");
await seedRouting(seed, upstream, "datadog-exporter-model");

await waitConfigPropagation(async () => {
try {
Expand DownExpand Up@@ -315,15 +317,16 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
const ddFull = await startMockDatadog();
const ddMeta = await startMockDatadog();
const app = await spawnApp({
admin: false,
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
try {
const admin = new AdminClient(app.adminUrl, app.adminKey);
const seed = new SeedClient(etcd!, app.etcdPrefix);
// Two exporters on the same DP: one captures content, one does not.
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-full",
enabled: true,
kind: "datadog",
Expand All@@ -332,7 +335,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "full",
});
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-meta",
enabled: true,
kind: "datadog",
Expand All@@ -341,7 +344,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-content-model");
await seedRouting(seed, upstream, "datadog-content-model");

await waitConfigPropagation(async () => {
try {
Expand Down
44 changes: 19 additions & 25 deletions tests/e2e/src/cases/guardrail-disabled-bypass-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,6 @@ import { createHash } from "node:crypto";
import OpenAI, { APIError } from "openai";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
spawnApp,
Expand DownExpand Up@@ -49,7 +48,6 @@ const FORBIDDEN_WORD = "supersecret";
describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
let app: SpawnedApp | undefined;
let upstream: OpenAiUpstream | undefined;
let admin: AdminClient | undefined;
let seed: SeedClient | undefined;
let etcdReachable = false;

Expand All@@ -59,8 +57,9 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
admin = new AdminClient(app.adminUrl, app.adminKey);
// No admin listener: resources are seeded to etcd and load-state is
// read from the metrics/status listener.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand DownExpand Up@@ -113,33 +112,28 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
// Readiness probe — two gates so the test cannot pass
// vacuously.
//
// Gate A: confirm the Guardrail row IS in the snapshot. Without
// this, the "forbidden literal arrives at upstream" assertion
// below would also pass if the rule simply hadn't propagated
// yet — indistinguishable from a real `enabled:false` bypass.
// Reading admin /v1/guardrails via the typed JSON helper is
// the cheapest way to verify the resource exists in the store
// the snapshot is built from.
// Gate A: confirm the Guardrail row IS in the applied snapshot.
// Without this, the "forbidden literal arrives at upstream"
// assertion below would also pass if the rule simply hadn't
// propagated yet — indistinguishable from a real `enabled:false`
// bypass. `/status/config`'s `resource_counts` reflects what the
// DP has LOADED (not merely what was written to etcd), served on
// the metrics listener — the admin-off equivalent of the old
// admin `/v1/guardrails` read.
//
// Gate B: confirm Model + ApiKey + ProviderKey are loaded by
// driving a benign chat completion through the proxy. A 200
// response means the dispatcher is ready.
await waitConfigPropagation(async () => {
try {
const list = (await admin!.json(
"GET",
"/admin/v1/guardrails",
)) as unknown as Array<Record<string, unknown>>;
const hasRule = list.some((entry) => {
// Admin list endpoints variably return bare values or
// {value: ...} wrappers; handle either shape generically.
const inner = (entry?.value ?? entry) as Record<
string,
unknown
>;
return inner?.name === "gr-disabled-keyword";
});
if (!hasRule) return false;
const res = await fetch(`${app!.metricsUrl}/status/config`);
if (!res.ok) return false;
const cfg = (await res.json()) as {
applied?: { resource_counts?: Record<string, number> };
};
if ((cfg.applied?.resource_counts?.guardrails ?? 0) < 1) {
return false;
}
await client.chat.completions.create({
model: "gr-disabled-model",
messages: [{ role: "user", content: "ready-probe" }],
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion tests/e2e/src/cases/background-health-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,10 @@ describe("background health e2e", () => {
},
});

app = await spawnApp();
// The admin listener is off; `admin` here is used only for
// listModelStatuses, which reads GET /status/models on the metrics
// listener. Resources are seeded straight to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/src/cases/cache-ttl-eviction-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,8 @@ describe("cache TTL eviction e2e: entry expires after ttl_seconds", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
// No admin listener: every resource here is seeded straight to etcd.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand Down
28 changes: 21 additions & 7 deletions tests/e2e/src/cases/cooldown-contract-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -74,7 +74,9 @@ describe("cooldown contract (H1) — 401 cools down despite being non-retryable"
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -225,7 +227,9 @@ describe("cooldown contract (M1) — 429 cools down even when retry_on_429=false
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -378,7 +382,9 @@ describe("cooldown contract (H2) — Retry-After header from upstream drives TTL
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -516,7 +522,9 @@ describe("filter contract (H3) — all candidates unhealthy returns 503", () =>
errorBody: { error: { message: "all-down B", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -646,7 +654,9 @@ describe("filter contract (H3 escape hatch) — try_anyway sends to known-bad",
errorBody: { error: { message: "still down", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -765,7 +775,9 @@ describe("cooldown observability — a cooldown transition emits aisix_deploymen
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -958,7 +970,9 @@ describe("cooldown observability — the state gauge follows a target back into
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
31 changes: 17 additions & 14 deletions tests/e2e/src/cases/datadog-exporter-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,8 +3,8 @@ import { createServer, type IncomingMessage, type Server } from "node:http";
import { gunzipSync } from "node:zlib";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
pickFreePort,
spawnApp,
startOpenAiUpstream,
Expand DownExpand Up@@ -126,19 +126,19 @@ async function startMockDatadog(): Promise<MockDatadog> {
};
}

async function seedRouting(admin: AdminClient, upstream: OpenAiUpstream, model: string) {
const pk = await admin.createProviderKey({
async function seedRouting(seed: SeedClient, upstream: OpenAiUpstream, model: string) {
const pk = await seed.createProviderKey({
display_name: `${model}-pk`,
secret: PROVIDER_SECRET,
api_base: `${upstream.baseUrl}/v1`,
});
await admin.createModel({
await seed.createModel({
display_name: model,
provider: "openai",
model_name: "gpt-4o-mini",
provider_key_id: pk.id,
});
await admin.createApiKey({
await seed.createApiKey({
key_hash: CALLER_KEY_HASH,
allowed_models: [model],
});
Expand DownExpand Up@@ -184,12 +184,14 @@ function asRecord(log: unknown): Record<string, unknown> {

describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog", () => {
let etcdReachable = false;
let etcd: EtcdClient | undefined;
let upstream: OpenAiUpstream | undefined;
let dd: MockDatadog | undefined;
const apps: SpawnedApp[] = [];

beforeAll(async () => {
etcdReachable = await new EtcdClient().ping();
etcd = new EtcdClient();
etcdReachable = await etcd.ping();
if (!etcdReachable) return;
// Plant the response token in the mock upstream's assistant content so the
// content-capture test can search for it in the `full` log body.
Expand DownExpand Up@@ -226,15 +228,15 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
return;
}
const app = await spawnApp({
admin: false,
// The API key rides the DP's own env, never the kine config.
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
// Deliberately seeds via the Admin API: deprecation-window coverage.
const admin = new AdminClient(app.adminUrl, app.adminKey);
await admin.createObservabilityExporter({
const seed = new SeedClient(etcd!, app.etcdPrefix);
await seed.createObservabilityExporter({
name: "mock-datadog",
enabled: true,
kind: "datadog",
Expand All@@ -245,7 +247,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
// Default privacy posture: operational metadata only, never content.
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-exporter-model");
await seedRouting(seed, upstream, "datadog-exporter-model");

await waitConfigPropagation(async () => {
try {
Expand DownExpand Up@@ -315,15 +317,16 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
const ddFull = await startMockDatadog();
const ddMeta = await startMockDatadog();
const app = await spawnApp({
admin: false,
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
try {
const admin = new AdminClient(app.adminUrl, app.adminKey);
const seed = new SeedClient(etcd!, app.etcdPrefix);
// Two exporters on the same DP: one captures content, one does not.
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-full",
enabled: true,
kind: "datadog",
Expand All@@ -332,7 +335,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "full",
});
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-meta",
enabled: true,
kind: "datadog",
Expand All@@ -341,7 +344,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-content-model");
await seedRouting(seed, upstream, "datadog-content-model");

await waitConfigPropagation(async () => {
try {
Expand Down
44 changes: 19 additions & 25 deletions tests/e2e/src/cases/guardrail-disabled-bypass-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,6 @@ import { createHash } from "node:crypto";
import OpenAI, { APIError } from "openai";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
spawnApp,
Expand DownExpand Up@@ -49,7 +48,6 @@ const FORBIDDEN_WORD = "supersecret";
describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
let app: SpawnedApp | undefined;
let upstream: OpenAiUpstream | undefined;
let admin: AdminClient | undefined;
let seed: SeedClient | undefined;
let etcdReachable = false;

Expand All@@ -59,8 +57,9 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
admin = new AdminClient(app.adminUrl, app.adminKey);
// No admin listener: resources are seeded to etcd and load-state is
// read from the metrics/status listener.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand DownExpand Up@@ -113,33 +112,28 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
// Readiness probe — two gates so the test cannot pass
// vacuously.
//
// Gate A: confirm the Guardrail row IS in the snapshot. Without
// this, the "forbidden literal arrives at upstream" assertion
// below would also pass if the rule simply hadn't propagated
// yet — indistinguishable from a real `enabled:false` bypass.
// Reading admin /v1/guardrails via the typed JSON helper is
// the cheapest way to verify the resource exists in the store
// the snapshot is built from.
// Gate A: confirm the Guardrail row IS in the applied snapshot.
// Without this, the "forbidden literal arrives at upstream"
// assertion below would also pass if the rule simply hadn't
// propagated yet — indistinguishable from a real `enabled:false`
// bypass. `/status/config`'s `resource_counts` reflects what the
// DP has LOADED (not merely what was written to etcd), served on
// the metrics listener — the admin-off equivalent of the old
// admin `/v1/guardrails` read.
//
// Gate B: confirm Model + ApiKey + ProviderKey are loaded by
// driving a benign chat completion through the proxy. A 200
// response means the dispatcher is ready.
await waitConfigPropagation(async () => {
try {
const list = (await admin!.json(
"GET",
"/admin/v1/guardrails",
)) as unknown as Array<Record<string, unknown>>;
const hasRule = list.some((entry) => {
// Admin list endpoints variably return bare values or
// {value: ...} wrappers; handle either shape generically.
const inner = (entry?.value ?? entry) as Record<
string,
unknown
>;
return inner?.name === "gr-disabled-keyword";
});
if (!hasRule) return false;
const res = await fetch(`${app!.metricsUrl}/status/config`);
if (!res.ok) return false;
const cfg = (await res.json()) as {
applied?: { resource_counts?: Record<string, number> };
};
if ((cfg.applied?.resource_counts?.guardrails ?? 0) < 1) {
return false;
}
await client.chat.completions.create({
model: "gr-disabled-model",
messages: [{ role: "user", content: "ready-probe" }],
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion tests/e2e/src/cases/background-health-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,10 @@ describe("background health e2e", () => {
},
});

app = await spawnApp();
// The admin listener is off; `admin` here is used only for
// listModelStatuses, which reads GET /status/models on the metrics
// listener. Resources are seeded straight to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
3 changes: 2 additions & 1 deletion tests/e2e/src/cases/cache-ttl-eviction-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,7 +57,8 @@ describe("cache TTL eviction e2e: entry expires after ttl_seconds", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
// No admin listener: every resource here is seeded straight to etcd.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand Down
28 changes: 21 additions & 7 deletions tests/e2e/src/cases/cooldown-contract-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -74,7 +74,9 @@ describe("cooldown contract (H1) — 401 cools down despite being non-retryable"
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -225,7 +227,9 @@ describe("cooldown contract (M1) — 429 cools down even when retry_on_429=false
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -378,7 +382,9 @@ describe("cooldown contract (H2) — Retry-After header from upstream drives TTL
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -516,7 +522,9 @@ describe("filter contract (H3) — all candidates unhealthy returns 503", () =>
errorBody: { error: { message: "all-down B", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -646,7 +654,9 @@ describe("filter contract (H3 escape hatch) — try_anyway sends to known-bad",
errorBody: { error: { message: "still down", type: "server_error" } },
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -765,7 +775,9 @@ describe("cooldown observability — a cooldown transition emits aisix_deploymen
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand DownExpand Up@@ -958,7 +970,9 @@ describe("cooldown observability — the state gauge follows a target back into
},
});

app = await spawnApp();
// Admin listener off; `admin` reads only /status/models on the metrics
// listener, and every resource is seeded to etcd via `seed`.
app = await spawnApp({ admin: false });
admin = new AdminClient(app.adminUrl, app.adminKey, app.metricsUrl);
seed = new SeedClient(etcd, app.etcdPrefix);

Expand Down
31 changes: 17 additions & 14 deletions tests/e2e/src/cases/datadog-exporter-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,8 +3,8 @@ import { createServer, type IncomingMessage, type Server } from "node:http";
import { gunzipSync } from "node:zlib";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
pickFreePort,
spawnApp,
startOpenAiUpstream,
Expand DownExpand Up@@ -126,19 +126,19 @@ async function startMockDatadog(): Promise<MockDatadog> {
};
}

async function seedRouting(admin: AdminClient, upstream: OpenAiUpstream, model: string) {
const pk = await admin.createProviderKey({
async function seedRouting(seed: SeedClient, upstream: OpenAiUpstream, model: string) {
const pk = await seed.createProviderKey({
display_name: `${model}-pk`,
secret: PROVIDER_SECRET,
api_base: `${upstream.baseUrl}/v1`,
});
await admin.createModel({
await seed.createModel({
display_name: model,
provider: "openai",
model_name: "gpt-4o-mini",
provider_key_id: pk.id,
});
await admin.createApiKey({
await seed.createApiKey({
key_hash: CALLER_KEY_HASH,
allowed_models: [model],
});
Expand DownExpand Up@@ -184,12 +184,14 @@ function asRecord(log: unknown): Record<string, unknown> {

describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog", () => {
let etcdReachable = false;
let etcd: EtcdClient | undefined;
let upstream: OpenAiUpstream | undefined;
let dd: MockDatadog | undefined;
const apps: SpawnedApp[] = [];

beforeAll(async () => {
etcdReachable = await new EtcdClient().ping();
etcd = new EtcdClient();
etcdReachable = await etcd.ping();
if (!etcdReachable) return;
// Plant the response token in the mock upstream's assistant content so the
// content-capture test can search for it in the `full` log body.
Expand DownExpand Up@@ -226,15 +228,15 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
return;
}
const app = await spawnApp({
admin: false,
// The API key rides the DP's own env, never the kine config.
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
// Deliberately seeds via the Admin API: deprecation-window coverage.
const admin = new AdminClient(app.adminUrl, app.adminKey);
await admin.createObservabilityExporter({
const seed = new SeedClient(etcd!, app.etcdPrefix);
await seed.createObservabilityExporter({
name: "mock-datadog",
enabled: true,
kind: "datadog",
Expand All@@ -245,7 +247,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
// Default privacy posture: operational metadata only, never content.
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-exporter-model");
await seedRouting(seed, upstream, "datadog-exporter-model");

await waitConfigPropagation(async () => {
try {
Expand DownExpand Up@@ -315,15 +317,16 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
const ddFull = await startMockDatadog();
const ddMeta = await startMockDatadog();
const app = await spawnApp({
admin: false,
extraEnv: {
[`DD_CRED_${CREDENTIAL_REF.toUpperCase()}_API_KEY`]: DD_API_KEY,
},
});
apps.push(app);
try {
const admin = new AdminClient(app.adminUrl, app.adminKey);
const seed = new SeedClient(etcd!, app.etcdPrefix);
// Two exporters on the same DP: one captures content, one does not.
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-full",
enabled: true,
kind: "datadog",
Expand All@@ -332,7 +335,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "full",
});
await admin.createObservabilityExporter({
await seed.createObservabilityExporter({
name: "datadog-meta",
enabled: true,
kind: "datadog",
Expand All@@ -341,7 +344,7 @@ describe("datadog exporter e2e (#688): DP delivers a gzip JSON intake to Datadog
service: DD_SERVICE,
content_mode: "metadata_only",
});
await seedRouting(admin, upstream, "datadog-content-model");
await seedRouting(seed, upstream, "datadog-content-model");

await waitConfigPropagation(async () => {
try {
Expand Down
44 changes: 19 additions & 25 deletions tests/e2e/src/cases/guardrail-disabled-bypass-e2e.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,6 @@ import { createHash } from "node:crypto";
import OpenAI, { APIError } from "openai";
import { afterAll, beforeAll, describe, expect, test } from "vitest";
import {
AdminClient,
EtcdClient,
SeedClient,
spawnApp,
Expand DownExpand Up@@ -49,7 +48,6 @@ const FORBIDDEN_WORD = "supersecret";
describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
let app: SpawnedApp | undefined;
let upstream: OpenAiUpstream | undefined;
let admin: AdminClient | undefined;
let seed: SeedClient | undefined;
let etcdReachable = false;

Expand All@@ -59,8 +57,9 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
if (!etcdReachable) return;

upstream = await startOpenAiUpstream();
app = await spawnApp();
admin = new AdminClient(app.adminUrl, app.adminKey);
// No admin listener: resources are seeded to etcd and load-state is
// read from the metrics/status listener.
app = await spawnApp({ admin: false });
seed = new SeedClient(etcd, app.etcdPrefix);

const pk = await seed.createProviderKey({
Expand DownExpand Up@@ -113,33 +112,28 @@ describe("guardrail disabled-bypass e2e: enabled:false → no block", () => {
// Readiness probe — two gates so the test cannot pass
// vacuously.
//
// Gate A: confirm the Guardrail row IS in the snapshot. Without
// this, the "forbidden literal arrives at upstream" assertion
// below would also pass if the rule simply hadn't propagated
// yet — indistinguishable from a real `enabled:false` bypass.
// Reading admin /v1/guardrails via the typed JSON helper is
// the cheapest way to verify the resource exists in the store
// the snapshot is built from.
// Gate A: confirm the Guardrail row IS in the applied snapshot.
// Without this, the "forbidden literal arrives at upstream"
// assertion below would also pass if the rule simply hadn't
// propagated yet — indistinguishable from a real `enabled:false`
// bypass. `/status/config`'s `resource_counts` reflects what the
// DP has LOADED (not merely what was written to etcd), served on
// the metrics listener — the admin-off equivalent of the old
// admin `/v1/guardrails` read.
//
// Gate B: confirm Model + ApiKey + ProviderKey are loaded by
// driving a benign chat completion through the proxy. A 200
// response means the dispatcher is ready.
await waitConfigPropagation(async () => {
try {
const list = (await admin!.json(
"GET",
"/admin/v1/guardrails",
)) as unknown as Array<Record<string, unknown>>;
const hasRule = list.some((entry) => {
// Admin list endpoints variably return bare values or
// {value: ...} wrappers; handle either shape generically.
const inner = (entry?.value ?? entry) as Record<
string,
unknown
>;
return inner?.name === "gr-disabled-keyword";
});
if (!hasRule) return false;
const res = await fetch(`${app!.metricsUrl}/status/config`);
if (!res.ok) return false;
const cfg = (await res.json()) as {
applied?: { resource_counts?: Record<string, number> };
};
if ((cfg.applied?.resource_counts?.guardrails ?? 0) < 1) {
return false;
}
await client.chat.completions.create({
model: "gr-disabled-model",
messages: [{ role: "user", content: "ready-probe" }],
Expand Down
Loading
Loading