Initial Commit
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import type { Meter, MeterProvider } from "@opentelemetry/api";
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import {
|
||||
createRateLimitInstruments,
|
||||
RATE_LIMIT_COUNTER_NAMES,
|
||||
} from "./instruments.js";
|
||||
|
||||
interface RecordedCounter {
|
||||
readonly name: string;
|
||||
readonly addCalls: {
|
||||
value: number;
|
||||
attributes?: Readonly<Record<string, unknown>>;
|
||||
}[];
|
||||
}
|
||||
|
||||
function fakeProvider(): {
|
||||
provider: MeterProvider;
|
||||
counters: RecordedCounter[];
|
||||
} {
|
||||
const counters: RecordedCounter[] = [];
|
||||
const provider: MeterProvider = {
|
||||
getMeter(_name: string): Meter {
|
||||
const meter: Meter = {
|
||||
createCounter(n: string) {
|
||||
const r: RecordedCounter = { name: n, addCalls: [] };
|
||||
counters.push(r);
|
||||
return {
|
||||
add(
|
||||
v: number,
|
||||
attrs?: Readonly<Record<string, unknown>>
|
||||
) {
|
||||
r.addCalls.push({ value: v, attributes: attrs });
|
||||
},
|
||||
} as ReturnType<Meter["createCounter"]>;
|
||||
},
|
||||
createUpDownCounter() {
|
||||
throw new Error("not used");
|
||||
},
|
||||
createHistogram() {
|
||||
throw new Error("not used");
|
||||
},
|
||||
createObservableCounter() {
|
||||
throw new Error("not used");
|
||||
},
|
||||
createObservableGauge() {
|
||||
throw new Error("not used");
|
||||
},
|
||||
createObservableUpDownCounter() {
|
||||
throw new Error("not used");
|
||||
},
|
||||
addBatchObservableCallback() {
|
||||
/* noop */
|
||||
},
|
||||
removeBatchObservableCallback() {
|
||||
/* noop */
|
||||
},
|
||||
} as Meter;
|
||||
return meter;
|
||||
},
|
||||
};
|
||||
return { provider, counters };
|
||||
}
|
||||
|
||||
describe("instruments", () => {
|
||||
it("creates the rate-limit exceeded counter", { timeout: 5000 }, () => {
|
||||
const { provider, counters } = fakeProvider();
|
||||
const inst = createRateLimitInstruments({ meterProvider: provider });
|
||||
expect(counters.map((c) => c.name)).toEqual([
|
||||
"api.rate_limit.exceeded_total",
|
||||
]);
|
||||
inst.counters["api.rate_limit.exceeded_total"].add(1, {
|
||||
plugin: "p",
|
||||
route: "GET /",
|
||||
key_kind: "principal",
|
||||
});
|
||||
expect(counters[0]!.addCalls).toHaveLength(1);
|
||||
expect(counters[0]!.addCalls[0]!.attributes).toEqual({
|
||||
plugin: "p",
|
||||
route: "GET /",
|
||||
key_kind: "principal",
|
||||
});
|
||||
});
|
||||
|
||||
it("falls back to global meter-provider when none supplied", {
|
||||
timeout: 5000,
|
||||
}, () => {
|
||||
const inst = createRateLimitInstruments();
|
||||
// Global no-op provider returns no-op counters; .add must not throw.
|
||||
expect(() =>
|
||||
inst.counters["api.rate_limit.exceeded_total"].add(1, {})
|
||||
).not.toThrow();
|
||||
});
|
||||
|
||||
it("exposes the full counter-name tuple", { timeout: 5000 }, () => {
|
||||
expect(RATE_LIMIT_COUNTER_NAMES).toEqual([
|
||||
"api.rate_limit.exceeded_total",
|
||||
]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user