assembly of ingest pipeline
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
import { Effect, Either } from "effect"
|
||||
import { describe, expect, it } from "vitest"
|
||||
|
||||
import {
|
||||
type IngestUpstreamSnapshot,
|
||||
makeAstNodeKind,
|
||||
makeNormalizedHash,
|
||||
makeRawHash,
|
||||
makeRunIdentity,
|
||||
makeShapeHash,
|
||||
makeSnapshotIdentity,
|
||||
makeTaintedBundleInput,
|
||||
makeTaintedBundleLocation,
|
||||
makeTrustedCanonicalProjectionPath,
|
||||
makeTrustedManifestPath,
|
||||
makeTrustedSegmentsPath,
|
||||
makeTrustedSummaryPath,
|
||||
makeVerifiedPreviousRunManifest,
|
||||
} from "../src/domain/models/IngestSnapshot.js"
|
||||
import {
|
||||
apply,
|
||||
decide,
|
||||
makeAwaitingSnapshotSelection,
|
||||
validatePreviousRunManifest,
|
||||
} from "../src/policies/decideSnapshotIngest.js"
|
||||
import { workflow } from "../src/workflows/ingestSnapshot.js"
|
||||
|
||||
const makeCommand = (
|
||||
overrides: Partial<IngestUpstreamSnapshot> = {},
|
||||
): IngestUpstreamSnapshot => ({
|
||||
SnapshotIdentity: makeSnapshotIdentity("snapshot-001"),
|
||||
BundleInput: makeTaintedBundleInput(
|
||||
makeTaintedBundleLocation("/tmp/bundle.js"),
|
||||
),
|
||||
SnapshotMetadata: null,
|
||||
PreviousRunManifest: null,
|
||||
...overrides,
|
||||
})
|
||||
|
||||
describe("ingestSnapshot workflow", () => {
|
||||
it("ingests a deterministic bundle snapshot", async () => {
|
||||
const event = await Effect.runPromise(workflow(makeCommand()))
|
||||
|
||||
expect(event._tag).toBe("UpstreamSnapshotIngested")
|
||||
expect(event.payload.RunManifest.RunIdentity).toBe(makeRunIdentity("run:snapshot-001"))
|
||||
expect(event.payload.RunManifest.ManifestPath).toBe(
|
||||
makeTrustedManifestPath("runs/run:snapshot-001/manifest.json"),
|
||||
)
|
||||
expect(event.payload.SegmentRecords).toHaveLength(1)
|
||||
})
|
||||
|
||||
it("hard-stops when the bundle location is not parseable", () => {
|
||||
const result = decide(
|
||||
makeAwaitingSnapshotSelection(),
|
||||
makeCommand({
|
||||
BundleInput: makeTaintedBundleInput(makeTaintedBundleLocation("not-a-path")),
|
||||
}),
|
||||
)
|
||||
|
||||
expect(Either.isLeft(result)).toBe(true)
|
||||
if (Either.isLeft(result)) {
|
||||
expect(result.left.payload.Reason).toBe("BundleNotParseable")
|
||||
}
|
||||
})
|
||||
|
||||
it("applies the ingested event into SnapshotIngested state", () => {
|
||||
const result = decide(makeAwaitingSnapshotSelection(), makeCommand())
|
||||
expect(Either.isRight(result)).toBe(true)
|
||||
if (Either.isRight(result)) {
|
||||
const nextState = apply(makeAwaitingSnapshotSelection(), result.right)
|
||||
expect(nextState._tag).toBe("SnapshotIngested")
|
||||
if (nextState._tag === "SnapshotIngested") {
|
||||
expect(nextState.RunManifest.CanonicalProjectionPath).toBe(
|
||||
makeTrustedCanonicalProjectionPath("runs/run:snapshot-001/canonical.ts"),
|
||||
)
|
||||
expect(nextState.SummaryPath).toBe(
|
||||
makeTrustedSummaryPath("runs/run:snapshot-001/summary.json"),
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it("accepts a verified previous run manifest", () => {
|
||||
const result = validatePreviousRunManifest({
|
||||
RunIdentity: makeRunIdentity("run:previous"),
|
||||
SnapshotIdentity: makeSnapshotIdentity("snapshot-000"),
|
||||
ManifestPath: makeTrustedManifestPath("runs/run:previous/manifest.json"),
|
||||
SegmentsPath: makeTrustedSegmentsPath("runs/run:previous/segments.json"),
|
||||
CanonicalProjectionPath: makeTrustedCanonicalProjectionPath(
|
||||
"runs/run:previous/canonical.ts",
|
||||
),
|
||||
SummaryPath: makeTrustedSummaryPath("runs/run:previous/summary.json"),
|
||||
})
|
||||
|
||||
expect(Either.isRight(result)).toBe(true)
|
||||
})
|
||||
|
||||
it("preserves segment evidence when a previous manifest is present", async () => {
|
||||
const event = await Effect.runPromise(
|
||||
workflow(
|
||||
makeCommand({
|
||||
PreviousRunManifest: makeVerifiedPreviousRunManifest({
|
||||
RunIdentity: makeRunIdentity("run:previous"),
|
||||
SnapshotIdentity: makeSnapshotIdentity("snapshot-000"),
|
||||
ManifestPath: makeTrustedManifestPath("runs/run:previous/manifest.json"),
|
||||
SegmentsPath: makeTrustedSegmentsPath("runs/run:previous/segments.json"),
|
||||
CanonicalProjectionPath: makeTrustedCanonicalProjectionPath(
|
||||
"runs/run:previous/canonical.ts",
|
||||
),
|
||||
SummaryPath: makeTrustedSummaryPath("runs/run:previous/summary.json"),
|
||||
}),
|
||||
}),
|
||||
),
|
||||
)
|
||||
|
||||
expect(event.payload.SegmentRecords[0]).toMatchObject({
|
||||
SegmentId: "snapshot-001:root",
|
||||
AstNodeKind: makeAstNodeKind("Program"),
|
||||
Hashes: {
|
||||
RawHash: makeRawHash("raw:snapshot-001"),
|
||||
NormalizedHash: makeNormalizedHash("normalized:snapshot-001"),
|
||||
ShapeHash: makeShapeHash("shape:snapshot-001"),
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user