Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

200 linesCodeBlameRaw
1// The platform usage report, from GraphQL answers as Cloudflare gives them,
2// without the network.
3
4import assert from "node:assert/strict";
5import { test } from "node:test";
6
7import {
8 DATASETS,
9 WATCHER_QUERIES,
10 assemble,
11 buildQuery,
12 format,
13 lastFullHour,
14 logsDataset,
15 parseArgs,
16 parseGroups,
17 snake,
18 verdict,
19 watcherQuery,
20 windows,
21} from "./platform-usage.mjs";
22
23const NOW = new Date("2026-10-08T15:30:00.000Z");
24const answer = (rows) => ({ data: { viewer: { accounts: [{ rows }] } } });
25const variantOf = (key, at = 0) => DATASETS.find((spec) => spec.key === key).variants[at];
26
27test("the windows are the UTC month so far and the last 24 hours", () => {
28 const [month, day] = windows(NOW);
29 assert.deepEqual(month, { key: "month_to_date", label: "Month to date (UTC)", start: "2026-10-01T00:00:00.000Z", end: "2026-10-08T15:30:00.000Z" });
30 assert.equal(day.key, "last_24h");
31 assert.equal(day.start, "2026-10-07T15:30:00.000Z");
32 assert.equal(day.end, NOW.toISOString());
33 // Just after midnight on the 1st, the month has only begun.
34 assert.equal(windows(new Date("2026-11-01T00:05:00Z"))[0].start, "2026-11-01T00:00:00.000Z");
35});
36
37test("a query asks for the variant's sums and dimensions under one alias", () => {
38 const query = buildQuery("kvOperationsAdaptiveGroups", variantOf("kv"));
39 assert.match(query, /rows: kvOperationsAdaptiveGroups\(limit: 10000, filter: \{ datetime_geq: \$start, datetime_leq: \$end \}\)/);
40 assert.match(query, /sum \{ requests \}/);
41 assert.match(query, /dimensions \{ namespaceId actionType \}/);
42 assert.match(query, /accounts\(filter: \{ accountTag: \$accountTag \}\)/);
43 const artifacts = buildQuery("artifactsEventsAdaptiveGroups", variantOf("artifacts"));
44 assert.match(artifacts, /\bcount\b/);
45 const minute = buildQuery("durableObjectsPeriodicGroups", variantOf("durable_objects_periodic", 2));
46 assert.match(minute, /datetimeMinute_geq: \$start, datetimeMinute_leq: \$end/);
47});
48
49test("Workers Logs are read from whichever dataset the schema has, or skipped", () => {
50 assert.equal(logsDataset(["workersInvocationsAdaptive", "workersObservabilityEventsAdaptiveGroups"]), "workersObservabilityEventsAdaptiveGroups");
51 assert.equal(logsDataset(["workersLogsSomethingGroups"]), "workersLogsSomethingGroups");
52 assert.equal(logsDataset(["workersInvocationsAdaptive", "kvOperationsAdaptiveGroups"]), null);
53});
54
55test("groups are summed per name, named from the listing, sorted largest first, with totals", () => {
56 const body = answer([
57 { sum: { rowsRead: 10, rowsWritten: 1, readQueries: 2, writeQueries: 1 }, dimensions: { databaseId: "aaa" } },
58 { sum: { rowsRead: 500, rowsWritten: 20, readQueries: 9, writeQueries: 3 }, dimensions: { databaseId: "bbb" } },
59 { sum: { rowsRead: 5, rowsWritten: 0, readQueries: 1, writeQueries: 0 }, dimensions: { databaseId: "aaa" } },
60 ]);
61 const parsed = parseGroups(body, variantOf("d1"), { bbb: "g1t-repos" });
62 assert.deepEqual(parsed.metrics, ["rows_read", "rows_written", "read_queries", "write_queries"]);
63 assert.deepEqual(
64 parsed.rows.map((row) => [row.name, row.rows_read]),
65 [
66 ["g1t-repos", 500],
67 ["aaa", 15],
68 ],
69 );
70 assert.deepEqual(parsed.totals, { rows_read: 515, rows_written: 21, read_queries: 12, write_queries: 4 });
71 const kv = parseGroups(
72 answer([
73 { sum: { requests: 3 }, dimensions: { namespaceId: "n1", actionType: "write" } },
74 { sum: { requests: 40 }, dimensions: { namespaceId: "n1", actionType: "read" } },
75 ]),
76 variantOf("kv"),
77 { n1: "SESSIONS" },
78 );
79 assert.deepEqual(
80 kv.rows.map((row) => row.name),
81 ["SESSIONS / read", "SESSIONS / write"],
82 );
83 assert.throws(() => parseGroups({ errors: [{ message: "unknown field cpuTimeUs" }] }, variantOf("workers")), /cpuTimeUs/);
84 assert.equal(snake("billableOperations"), "billable_operations");
85});
86
87test("a dataset that errors or is missing is a note, and the others still report", () => {
88 const windowList = windows(NOW);
89 const outcomes = {
90 month_to_date: {
91 workers: {
92 body: answer([{ sum: { requests: 7, errors: 0, cpuTimeUs: 1200 }, dimensions: { scriptName: "web" } }]),
93 variant: variantOf("workers"),
94 dataset: "workersInvocationsAdaptive",
95 },
96 d1: { body: { errors: [{ message: 'unknown field "readQueries"' }] }, variant: variantOf("d1"), dataset: "d1AnalyticsAdaptiveGroups" },
97 queues: { skipped: "queueMessageOperationsAdaptiveGroups is not in this account's schema" },
98 kv: { error: new Error("fetch failed") },
99 artifacts: {
100 body: answer([{ count: 4, sum: { durationMs: 80 }, dimensions: { repositoryNamespace: "g1t", eventType: "pull" } }]),
101 variant: variantOf("artifacts"),
102 dataset: "artifactsEventsAdaptiveGroups",
103 },
104 },
105 last_24h: {},
106 };
107 const report = assemble({ account: "acct", now: NOW, windowList, outcomes });
108 const month = report.windows[0];
109 assert.deepEqual(
110 month.datasets.map((set) => set.key),
111 ["workers", "artifacts"],
112 );
113 assert.equal(month.notes.length, 3);
114 assert.match(month.notes.join("\n"), /D1 rows.*readQueries/);
115 assert.match(month.notes.join("\n"), /not in this account's schema/);
116 assert.match(month.notes.join("\n"), /fetch failed/);
117 assert.deepEqual(report.windows[1].datasets, []);
118 const text = format(report, 10);
119 assert.match(text, /Workers invocations, by script/);
120 assert.match(text, /web\s+7\s+0\s+1,200/);
121 assert.match(text, /Notes:/);
122});
123
124test("the JSON report is one snake_case object with every row", () => {
125 const windowList = windows(NOW);
126 const rows = Array.from({ length: 15 }, (_, at) => ({ sum: { requests: at + 1 }, dimensions: { scriptName: `s${at}` } }));
127 const outcomes = {
128 month_to_date: { durable_objects: { body: answer(rows), variant: variantOf("durable_objects", 1), dataset: "durableObjectsInvocationsAdaptiveGroups" } },
129 last_24h: {},
130 };
131 const report = JSON.parse(JSON.stringify(assemble({ account: "acct", now: NOW, windowList, outcomes })));
132 assert.deepEqual(Object.keys(report), ["account", "generated_at", "windows"]);
133 assert.deepEqual(Object.keys(report.windows[0]), ["key", "label", "start", "end", "datasets", "notes", "errors"]);
134 const set = report.windows[0].datasets[0];
135 assert.deepEqual(Object.keys(set), ["key", "label", "dataset", "metrics", "rows", "totals"]);
136 assert.equal(set.rows.length, 15);
137 assert.equal(set.rows[0].name, "s14");
138 assert.equal(set.totals.requests, 120);
139 const keys = JSON.stringify(report)
140 .match(/"([^"]+)":/g)
141 .map((key) => key.slice(1, -2));
142 for (const key of keys) assert.match(key, /^[a-z0-9_]+$/, key);
143 // The tables show only the top.
144 assert.match(format(assemble({ account: "acct", now: NOW, windowList, outcomes }), 10), /\.\.\. and 5 more/);
145});
146
147test("the command line reads --json, --top and the account", () => {
148 assert.deepEqual(parseArgs(["--json", "--top", "3", "--account", "abc"], {}), { help: false, json: true, top: 3, account: "abc" });
149 assert.equal(parseArgs([], { CLOUDFLARE_ACCOUNT_ID: "env" }).account, "env");
150 assert.equal(parseArgs(["--help"], {}).help, true);
151 assert.equal(parseArgs([], {}).top, 10);
152});
153
154test("errors, fallbacks, failed watcher queries and an all-empty account fail the check", () => {
155 const windowList = windows(NOW);
156 const ok = {
157 month_to_date: {
158 workers: {
159 body: answer([{ sum: { requests: 7, errors: 0, cpuTimeUs: 1 }, dimensions: { scriptName: "web" } }]),
160 variant: variantOf("workers"),
161 dataset: "workersInvocationsAdaptive",
162 },
163 },
164 last_24h: {},
165 };
166 assert.deepEqual(verdict(assemble({ account: "acct", now: NOW, windowList, outcomes: ok }), { workers: { rows: 3 } }), []);
167 const broken = {
168 month_to_date: {
169 workers: { ...ok.month_to_date.workers, fellBack: 'unknown field "cpuTimeUs"' },
170 kv: { error: new Error("fetch failed") },
171 },
172 last_24h: {},
173 };
174 const problems = verdict(assemble({ account: "acct", now: NOW, windowList, outcomes: broken }), {
175 do_sql: { error: 'unknown field "rowsWritten"' },
176 d1: { rows: 2 },
177 });
178 assert.equal(problems.length, 3);
179 assert.match(problems.join("\n"), /fell back to fewer fields: unknown field "cpuTimeUs"/);
180 assert.match(problems.join("\n"), /fetch failed/);
181 assert.match(problems.join("\n"), /watcher query do_sql \(durableObjectsPeriodicGroups\): unknown field "rowsWritten"/);
182 const empty = { month_to_date: { workers: { body: answer([]), variant: variantOf("workers"), dataset: "workersInvocationsAdaptive" } }, last_24h: {} };
183 assert.match(
184 verdict(assemble({ account: "acct", now: NOW, windowList, outcomes: empty }), { kv: { rows: 0 } }).join("\n"),
185 /every dataset answered with no rows/,
186 );
187});
188
189test("the watcher queries are billing's, field for field, over the last full hour", async () => {
190 const { readFile } = await import("node:fs/promises");
191 const rust = await readFile(new URL("../../services/billing/src/platform.rs", import.meta.url), "utf8");
192 const theirs = [...rust.matchAll(/Query \{ key: "([^"]+)", dataset: "([^"]+)", select: "([^"]+)", dimensions: "([^"]+)", hour_filter: "([^"]+)" \}/g)].map(
193 ([, key, dataset, select, dimensions, hourFilter]) => ({ key, dataset, select, dimensions, hourFilter }),
194 );
195 assert.deepEqual(WATCHER_QUERIES, theirs);
196 assert.deepEqual(lastFullHour(NOW), { since: "2026-10-08T14:00:00Z", until: "2026-10-08T15:00:00Z" });
197 const d1 = watcherQuery(WATCHER_QUERIES.find((q) => q.key === "d1"));
198 assert.match(d1, /rows: d1AnalyticsAdaptiveGroups\(limit: 10000, filter: \{ datetimeHour_geq: \$since, datetimeHour_lt: \$until \}\)/);
199 assert.match(d1, /\$since: Time!/);
200});