74 lines
3.5 KiB
JavaScript
74 lines
3.5 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { mkdtemp } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import test from 'node:test'
|
|
import { ChannelStateStore, planDesiredState } from '../../control-plane/modules/updater/lib/channel-state.mjs'
|
|
|
|
const current = { dsh: '0.1.0-rc.7', environment: 'env-1', runtime: 'runtime-a' }
|
|
const supported = { dsh: '0.1.0-rc.7', environment: 'env-1' }
|
|
|
|
test('persists channel selection and retryable version or combination Holds', async () => {
|
|
const root = await mkdtemp(join(tmpdir(), 'dsh-channel-state-'))
|
|
const store = new ChannelStateStore(join(root, 'channel.json'), () => new Date('2026-08-19T00:00:00.000Z'))
|
|
assert.equal((await store.read()).updateChannel, 'stable')
|
|
await store.setChannel('experimental')
|
|
const version = await store.addHold({ type: 'version', dshVersion: '0.1.0-rc.8', reason: 'build failed' })
|
|
const combination = await store.addHold({
|
|
type: 'combination', dshVersion: '0.1.0-rc.9', environmentVersion: 'env-1', reason: 'health failed',
|
|
})
|
|
assert.deepEqual((await store.read()).holds.map(hold => hold.type), ['version', 'combination'])
|
|
await store.retry(version.id)
|
|
assert.deepEqual((await store.read()).holds.map(hold => hold.id), [combination.id])
|
|
})
|
|
|
|
test('plans Stable convergence before Experimental and freezes Ahead-of-Stable combinations', () => {
|
|
const local = { updateChannel: 'experimental', holds: [], experimentalBlocked: null }
|
|
assert.equal(planDesiredState({
|
|
local, current: { ...current, environment: 'env-old' }, supported,
|
|
upstream: { version: '0.1.0-rc.8' },
|
|
}).action, 'stable')
|
|
assert.equal(planDesiredState({
|
|
local, current: { ...current, dsh: '0.1.0-rc.8' }, supported,
|
|
upstream: { version: '0.1.0-rc.9' },
|
|
}).action, 'frozen')
|
|
assert.equal(planDesiredState({ local, current, supported, upstream: { version: '0.1.0-rc.8' } }).action, 'experimental')
|
|
assert.equal(planDesiredState({
|
|
local,
|
|
current: { ...current, authority: 'development', targetSequence: 0 },
|
|
supported, stableTargetSequence: 11,
|
|
upstream: { version: '0.1.0-rc.8' },
|
|
}).action, 'stable')
|
|
assert.equal(planDesiredState({
|
|
local,
|
|
current: { ...current, authority: 'stable', targetSequence: 11 },
|
|
supported, stableTargetSequence: 11,
|
|
upstream: { version: '0.1.0-rc.8' },
|
|
}).action, 'experimental')
|
|
})
|
|
|
|
test('suppresses only the held Experimental candidate and Environment combination', () => {
|
|
const local = {
|
|
updateChannel: 'experimental',
|
|
experimentalBlocked: null,
|
|
holds: [{
|
|
id: 'hold', type: 'combination', dshVersion: '0.1.0-rc.8', environmentVersion: 'env-1',
|
|
reason: 'incompatible', createdAt: '2026-08-19T00:00:00.000Z',
|
|
}],
|
|
}
|
|
const plan = planDesiredState({ local, current, supported, upstream: { version: '0.1.0-rc.8' } })
|
|
assert.equal(plan.action, 'held')
|
|
assert.equal(plan.hold.id, 'hold')
|
|
})
|
|
|
|
test('retries an Experimental Block independently of ordinary Holds', async () => {
|
|
const root = await mkdtemp(join(tmpdir(), 'dsh-channel-block-'))
|
|
const store = new ChannelStateStore(join(root, 'channel.json'), () => new Date('2026-08-19T00:00:00.000Z'))
|
|
const blocked = await store.block({
|
|
dshVersion: '0.1.0-rc.8', environmentVersion: 'env-2', reason: 'combination failed',
|
|
})
|
|
assert.equal((await store.read()).experimentalBlocked.id, blocked.experimentalBlocked.id)
|
|
await store.retry(blocked.experimentalBlocked.id)
|
|
assert.equal((await store.read()).experimentalBlocked, null)
|
|
})
|