feat(devops): diagnose slow HK requests and dependency timings
This commit is contained in:
1 parent
3b76d063a6
commit
00e33623f7
42 files changed
+1335
-132
No files matched your search
@@ -53,6 +53,7 @@ export default async function DevOpsPage() {
|
||||
|
||||
const t = await getTranslations("pages.admin.devops");
|
||||
const data = await getDevOpsData();
|
||||
const performance = await getTranslations("pages.admin.performance");
|
||||
const installation = await getTranslations("pages.admin.installation");
|
||||
|
||||
return (
|
||||
@@ -63,6 +64,9 @@ export default async function DevOpsPage() {
|
||||
<Link href="/admin/devops/installation" className="btn btn-outline">
|
||||
{installation("title")}
|
||||
</Link>
|
||||
<Link href="/admin/devops/performance" className="btn btn-outline">
|
||||
{performance("title")}
|
||||
</Link>
|
||||
{/* Status cards */}
|
||||
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-5">
|
||||
<Card>
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import { createTranslator } from "next-intl";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { expect, it, vi } from "vitest";
|
||||
import messages from "@/messages/en.json";
|
||||
|
||||
const mocks = vi.hoisted(() => ({ read: vi.fn(), allowed: false }));
|
||||
vi.mock("@/lib/permissions", () => ({
|
||||
getAdminContext: async () => ({
|
||||
session: { user: { rank: 1 } },
|
||||
permissions: {},
|
||||
}),
|
||||
canAccess: () => mocks.allowed,
|
||||
PERMS: { DEVOPS_VIEW: "devops.view" },
|
||||
}));
|
||||
vi.mock("next/navigation", () => ({
|
||||
redirect: () => {
|
||||
throw new Error("redirect");
|
||||
},
|
||||
}));
|
||||
vi.mock("@/lib/performance-store", () => ({ readPerformance: mocks.read }));
|
||||
vi.mock("@/components/link", () => ({ default: () => null }));
|
||||
|
||||
vi.mock("next-intl/server", () => ({
|
||||
getTranslations: async () =>
|
||||
createTranslator({
|
||||
locale: "en",
|
||||
messages: messages.pages.admin.performance,
|
||||
}),
|
||||
}));
|
||||
|
||||
import Page from "./page";
|
||||
|
||||
it("rejects unauthorized users before reading timing records", async () => {
|
||||
await expect(Page({ searchParams: Promise.resolve({}) })).rejects.toThrow(
|
||||
"redirect",
|
||||
);
|
||||
expect(mocks.read).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("renders filtered slow records and explains incomplete streaming timings", async () => {
|
||||
mocks.allowed = true;
|
||||
const metrics = {
|
||||
durationMs: 1500,
|
||||
database: { count: 2, durationMs: 300, errors: 0 },
|
||||
external: { count: 1, durationMs: 400, errors: 1 },
|
||||
};
|
||||
mocks.read.mockResolvedValue({
|
||||
shared: false,
|
||||
samples: [
|
||||
{
|
||||
operationId: "slow-op",
|
||||
route: "/api/admin/studio",
|
||||
method: "GET",
|
||||
status: 200,
|
||||
at: 1000,
|
||||
streaming: true,
|
||||
metrics,
|
||||
},
|
||||
{
|
||||
operationId: "fast-op",
|
||||
route: "/api/admin/users",
|
||||
method: "GET",
|
||||
status: 200,
|
||||
at: 1001,
|
||||
streaming: false,
|
||||
metrics: { ...metrics, durationMs: 10 },
|
||||
},
|
||||
],
|
||||
});
|
||||
const html = renderToStaticMarkup(
|
||||
await Page({ searchParams: Promise.resolve({ slow: "1" }) }),
|
||||
);
|
||||
expect(html).toContain("slow-op");
|
||||
expect(html).not.toContain("fast-op");
|
||||
expect(html).toContain("Streaming response");
|
||||
expect(html).toContain("Local diagnostics");
|
||||
});
|
||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user