72 lines
2.1 KiB
TypeScript
72 lines
2.1 KiB
TypeScript
import { AuditLogger, MemoryAuditAdapter } from "@suaveplan/audit-logging";
|
|
import { describe, expect, it } from "@suaveplan/testing/runner";
|
|
import { Hono } from "hono";
|
|
import { createAuditMiddleware } from "../../src/middleware/audit-middleware.js";
|
|
import type { AuditPluginConfig } from "../../src/types/types.js";
|
|
|
|
const noopHostLogger = {
|
|
debug: () => undefined,
|
|
info: () => undefined,
|
|
warn: () => undefined,
|
|
error: () => undefined,
|
|
};
|
|
|
|
/**
|
|
* Deterministic Mulberry32 RNG so the test is reproducible across
|
|
* Bun + Node runtime engines.
|
|
*/
|
|
function mulberry32(seed: number): () => number {
|
|
let t = seed >>> 0;
|
|
return () => {
|
|
t = (t + 0x6d2b79f5) >>> 0;
|
|
let r = t;
|
|
r = Math.imul(r ^ (r >>> 15), r | 1);
|
|
r ^= r + Math.imul(r ^ (r >>> 7), r | 61);
|
|
return ((r ^ (r >>> 14)) >>> 0) / 4294967296;
|
|
};
|
|
}
|
|
|
|
describe("sampling integration", () => {
|
|
it("50% sample rate over 1000 requests sits in [400, 600] band", {
|
|
timeout: 30000,
|
|
}, async () => {
|
|
const storage = new MemoryAuditAdapter();
|
|
const logger = new AuditLogger({
|
|
storage,
|
|
secretKey: "x".repeat(32),
|
|
});
|
|
const config: AuditPluginConfig = {
|
|
sink: storage,
|
|
secretKey: "x".repeat(32),
|
|
samplingRate: 0.5,
|
|
excludePaths: [],
|
|
redactQueryParams: [],
|
|
redactHeaders: [],
|
|
redactBodyFields: [],
|
|
recordResponseSize: false,
|
|
recordRequestBody: false,
|
|
enableChainIntegrity: false,
|
|
rng: mulberry32(1234567),
|
|
};
|
|
|
|
const app = new Hono();
|
|
app.use(
|
|
"*",
|
|
createAuditMiddleware({
|
|
logger,
|
|
config,
|
|
hostLogger: noopHostLogger,
|
|
})
|
|
);
|
|
app.get("/x", (c) => c.text("ok"));
|
|
|
|
for (let i = 0; i < 1000; i += 1) {
|
|
await app.request(`/x?i=${i}`);
|
|
}
|
|
|
|
const count = storage.snapshot().length;
|
|
expect(count).toBeGreaterThanOrEqual(400);
|
|
expect(count).toBeLessThanOrEqual(600);
|
|
});
|
|
});
|