feat: add CI deployment and live progress
This commit is contained in:
@@ -2,6 +2,7 @@ import { describe, expect, test } from "bun:test";
|
||||
import {
|
||||
MemoryOperationStore,
|
||||
MemoryWorkspaceLeaseProvider,
|
||||
MAX_OPERATION_EVENTS,
|
||||
OperationConflictError,
|
||||
OperationValidationError,
|
||||
recoverStaleOperations,
|
||||
@@ -153,6 +154,58 @@ describe("operation store", () => {
|
||||
).rejects.toBeInstanceOf(OperationValidationError);
|
||||
});
|
||||
|
||||
test("persists monotonic bounded progress events with cursors", async () => {
|
||||
const store = new MemoryOperationStore(undefined, () => "event-operation");
|
||||
const operation = await store.create({
|
||||
workspaceId: "demo",
|
||||
action: "resources.apply",
|
||||
idempotencyKey: "events",
|
||||
});
|
||||
await store.emit(operation.metadata.name, {
|
||||
resource: { apiVersion: "v1", kind: "Secret", name: "credentials" },
|
||||
phase: "apply",
|
||||
state: "started",
|
||||
});
|
||||
const complete = await store.emit(operation.metadata.name, {
|
||||
resource: { apiVersion: "v1", kind: "Secret", name: "credentials" },
|
||||
phase: "apply",
|
||||
state: "succeeded",
|
||||
});
|
||||
expect(complete.sequence).toBe(2);
|
||||
expect(await store.events(operation.metadata.name, 1)).toMatchObject({
|
||||
items: [expect.objectContaining({ sequence: 2 })],
|
||||
retainedFirstSequence: 1,
|
||||
cursorGap: false,
|
||||
});
|
||||
await store.transition(operation.metadata.name, "running");
|
||||
await store.transition(operation.metadata.name, "succeeded");
|
||||
expect(await store.events(operation.metadata.name, 1)).toMatchObject({
|
||||
items: [expect.objectContaining({ sequence: 2 })],
|
||||
retainedFirstSequence: 1,
|
||||
cursorGap: false,
|
||||
});
|
||||
await expect(
|
||||
store.events(operation.metadata.name, -1),
|
||||
).rejects.toBeInstanceOf(OperationValidationError);
|
||||
for (let index = 0; index < MAX_OPERATION_EVENTS; index++) {
|
||||
await store.emit(operation.metadata.name, {
|
||||
resource: { apiVersion: "v1", kind: "Service", name: `web-${index}` },
|
||||
phase: "apply",
|
||||
state: "succeeded",
|
||||
});
|
||||
}
|
||||
const bounded = await store.events(operation.metadata.name);
|
||||
expect(bounded.items).toHaveLength(MAX_OPERATION_EVENTS);
|
||||
expect(bounded.items[0]?.sequence).toBe(3);
|
||||
expect(bounded).toMatchObject({
|
||||
retainedFirstSequence: 3,
|
||||
cursorGap: true,
|
||||
});
|
||||
expect(await store.events(operation.metadata.name, 2)).toMatchObject({
|
||||
cursorGap: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("provides exclusive, renewable per-workspace leases", async () => {
|
||||
let now = 0;
|
||||
const leases = new MemoryWorkspaceLeaseProvider(() => now);
|
||||
|
||||
Reference in New Issue
Block a user