mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-05 16:10:43 +00:00
96 lines
4.0 KiB
JavaScript
96 lines
4.0 KiB
JavaScript
import {
|
|
digest,
|
|
integer,
|
|
inventory,
|
|
key,
|
|
partition,
|
|
shardIndex,
|
|
verifyFiles,
|
|
} from "./partition.mjs";
|
|
|
|
export function validateReports(reports, expected) {
|
|
const count = integer(expected.count, "Shard count");
|
|
const files = inventory(expected.files);
|
|
const allocation = partition(files, count, expected.timings);
|
|
const seen = new Set();
|
|
const completed = [];
|
|
for (const { metadata: report, blob } of reports) {
|
|
if (!report || report.schema !== 1) throw new Error("Invalid shard metadata schema");
|
|
const index = shardIndex(report.index, count);
|
|
if (seen.has(index)) throw new Error(`Duplicate shard ${index}`);
|
|
seen.add(index);
|
|
for (const field of ["sha", "runId", "configDigest", "environmentDigest", "node", "vitest"]) {
|
|
if (report[field] !== expected[field]) throw new Error(`Shard ${index} has wrong ${field}`);
|
|
}
|
|
const attempt = integer(report.attempt, "Artifact attempt");
|
|
if (attempt > expected.attempt) throw new Error(`Shard ${index} is from a future attempt`);
|
|
if (report.count !== count) throw new Error(`Shard ${index} has wrong shard count`);
|
|
if (report.reason !== "passed" || report.hasCoverage !== true) {
|
|
throw new Error(`Shard ${index} did not complete with coverage`);
|
|
}
|
|
if (!blob?.length || digest(blob) !== report.blobDigest)
|
|
throw new Error(`Corrupt blob for shard ${index}`);
|
|
verifyFiles(report.manifest, files, `Shard ${index} discovery`);
|
|
if (report.manifestDigest !== digest(JSON.stringify(inventory(report.manifest)))) {
|
|
throw new Error(`Corrupt manifest for shard ${index}`);
|
|
}
|
|
verifyFiles(report.files, allocation[index - 1], `Shard ${index} results`);
|
|
for (const file of report.files) {
|
|
if (!["passed", "skipped"].includes(file.state) || !Array.isArray(file.tests)) {
|
|
throw new Error(`Incomplete file: ${key(file)}`);
|
|
}
|
|
if (file.state === "passed" && !file.tests.length)
|
|
throw new Error(`Empty file: ${key(file)}`);
|
|
if (!Array.isArray(file.collected)) throw new Error(`Missing collection: ${key(file)}`);
|
|
const collected = new Map(file.collected.map((test) => [test.id, test]));
|
|
if (collected.size !== file.collected.length || collected.size !== file.tests.length) {
|
|
throw new Error(`Incomplete test collection: ${key(file)}`);
|
|
}
|
|
const testIds = new Set();
|
|
for (const test of file.tests) {
|
|
if (typeof test.id !== "string" || !test.id || testIds.has(test.id)) {
|
|
throw new Error(`Duplicate or invalid test identity: ${key(file)}`);
|
|
}
|
|
testIds.add(test.id);
|
|
const initial = collected.get(test.id);
|
|
if (
|
|
!initial ||
|
|
initial.name !== test.name ||
|
|
!["run", "skip", "todo"].includes(initial.mode) ||
|
|
(["skip", "todo"].includes(initial.mode) && test.state !== "skipped")
|
|
) {
|
|
throw new Error(`Changed test collection: ${key(file)} ${test.name}`);
|
|
}
|
|
if (
|
|
typeof test.name !== "string" ||
|
|
!["run", "skip", "todo"].includes(test.mode) ||
|
|
!["passed", "skipped"].includes(test.state)
|
|
) {
|
|
throw new Error(`Incomplete test: ${key(file)} ${test.name}`);
|
|
}
|
|
if (["skip", "todo"].includes(test.mode) && test.state !== "skipped") {
|
|
throw new Error(`Invalid test disposition: ${key(file)} ${test.name}`);
|
|
}
|
|
}
|
|
}
|
|
completed.push(...report.files);
|
|
}
|
|
if (seen.size !== count) {
|
|
throw new Error(
|
|
`Missing shards: expected ${count}, received ${seen.size}; artifacts may have expired, rerun all jobs`,
|
|
);
|
|
}
|
|
verifyFiles(completed, files, "Complete suite");
|
|
return {
|
|
files: completed.length,
|
|
tests: completed.reduce((total, file) => total + file.tests.length, 0),
|
|
dispositions: completed
|
|
.flatMap((file) => file.tests)
|
|
.reduce((totals, test) => {
|
|
const status = test.mode === "todo" ? "todo" : test.state;
|
|
totals[status] = (totals[status] || 0) + 1;
|
|
return totals;
|
|
}, {}),
|
|
};
|
|
}
|