Files
orca/tests/e2e/cross-version-wire/orchestration-delivery-downgrade.unit.test.ts
Jinwoo Hong 3ab2a1b91c refactor(orchestration): derive delivery eligibility from messages (#19837)
* fix(orchestration): retire read deliveries and clarify mailbox recovery

* fix(orchestration): simplify delivery recovery and update nudge contracts

* test: align orchestration check help expectation

* refactor(orchestration): derive delivery eligibility from messages

* fix(orchestration): validate live consumers and simplify batch revocation

* refactor(orchestration): keep deliveries.status and derive eligibility without a column drop

The outstanding_deliveries view now reads status = 'outstanding' plus unread
membership, so v41 only drops uniqueness from idx_deliveries_one_outstanding
and adds the view and trigger. Older binaries can still open the database.
Removes the column-drop migration, the v40 test fixture and hasColumn guards,
the fenced skew probe, and the unrelated nudge-text change.

* docs(orchestration): drop delivery storage reference

The compatibility caveat it existed to explain no longer applies; the view
and index comments carry the remaining rationale.

* docs: revert unrelated formatter churn

* test(orchestration): verify historical database downgrade round trip
2026-09-13 23:24:04 -04:00

69 lines
2.9 KiB
TypeScript

import { mkdtempSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { expect, test } from 'vitest'
import { OrchestrationDb } from '../../../src/main/runtime/orchestration/db'
import { importReleaseCheckoutModule, materializeReleaseCheckout } from './release-checkout'
// Pin the last pre-v41 implementation: this contract specifically exercises status-only readers.
const PRE_V41 = 'aac38d698ff75ac4c8658addab48ef5a83617619'
test('pre-v41 code opens, acknowledges and writes a v41 database, then current code reopens it', async () => {
const checkout = await materializeReleaseCheckout(PRE_V41)
const baseline = await importReleaseCheckoutModule(
checkout,
'src/main/runtime/orchestration/db.ts'
)
const OldDb = baseline.OrchestrationDb as typeof OrchestrationDb
const directory = mkdtempSync(join(tmpdir(), 'orca-delivery-downgrade-'))
const path = join(directory, 'orchestration.db')
let db: OrchestrationDb | undefined
try {
db = new OldDb(path)
expect(db.db.pragma('user_version', { simple: true })).toBe(40)
const run = db.createRun({
objective: 'downgrade round trip',
coordinatorHandle: 'coord',
coordinatorPaneKey: 'tab:11111111-1111-4111-8111-111111111111'
})
const params = { runId: run.id, consumerGeneration: run.consumer_generation }
const insert = (subject: string) =>
db!.insertMessage({
runId: run.id,
from: 'worker',
to: `run:${run.id}`,
subject
})
const oldMessage = insert('obsolete heartbeat')
const oldBatch = db.getOrCreateRunDelivery(params)!
db.close()
db = new OrchestrationDb(path)
db.markAsRead([oldMessage.id])
const completion = insert('completion')
const currentBatch = db.getOrCreateRunDelivery(params)!
expect(currentBatch.messages.map((message) => message.id)).toEqual([completion.id])
expect(currentBatch.delivery.id).not.toBe(oldBatch.delivery.id)
db.close()
db = new OldDb(path)
expect(db.db.pragma('user_version', { simple: true })).toBe(41)
// Old readers retain their original replay semantics, but can acknowledge either stored batch.
db.acknowledgeRunDelivery({ ...params, deliveryId: oldBatch.delivery.id })
expect(db.getOrCreateRunDelivery(params)?.delivery.id).toBe(currentBatch.delivery.id)
db.acknowledgeRunDelivery({ ...params, deliveryId: currentBatch.delivery.id })
const next = insert('written after downgrade')
const nextBatch = db.getOrCreateRunDelivery(params)!
expect(nextBatch.messages.map((message) => message.id)).toEqual([next.id])
db.close()
db = new OrchestrationDb(path)
expect(db.getOrCreateRunDelivery(params)?.delivery.id).toBe(nextBatch.delivery.id)
db.acknowledgeRunDelivery({ ...params, deliveryId: nextBatch.delivery.id })
expect(db.getOrCreateRunDelivery(params)).toBeUndefined()
} finally {
db?.close()
rmSync(directory, { recursive: true, force: true })
}
})