Each file opened one or more Brainy instances (beforeEach, or a small per-test helper like migration-gate-family-scoped's module-level seed()) and never closed them. migration-gate-family-scoped.test.ts now tracks every brain seed() hands back in a describe-scoped array drained by afterEach, since the helper itself lives outside the describe block.
63 lines
2.5 KiB
TypeScript
63 lines
2.5 KiB
TypeScript
/**
|
|
* @module tests/unit/get-index-status-readiness
|
|
* @description Pattern-A / Finding 9: getIndexStatus reported `populated: size>0`
|
|
* and only `migrating`, so a native index that loaded its count but not its
|
|
* serving structure reported populated:true — a k8s readiness probe would 200 a
|
|
* brain that serves []. It now folds in the honest isReady() signal + the
|
|
* _indexRebuildFailed / _indexDegradedIds degraded states (mirroring
|
|
* validateIndexConsistency / checkHealth).
|
|
*/
|
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
|
import { Brainy, NounType } from '../../src/index.js'
|
|
|
|
describe('getIndexStatus honest readiness (Finding 9)', () => {
|
|
let brain: any
|
|
beforeEach(async () => {
|
|
process.env.BRAINY_DETERMINISTIC_EMBEDDINGS = 'true'
|
|
brain = new Brainy({ requireSubtype: false, storage: { type: 'memory' }, dimensions: 384 })
|
|
await brain.init()
|
|
await brain.add({ data: 'x', type: NounType.Concept })
|
|
await brain.flush()
|
|
})
|
|
|
|
afterEach(async () => {
|
|
await brain.close()
|
|
})
|
|
|
|
it('a not-ready provider makes populated honest (false) and exposes ready:false', async () => {
|
|
brain.index.isReady = () => false // count present, serving structure NOT loaded
|
|
const status = await brain.getIndexStatus()
|
|
expect(status.hnswIndex.populated).toBe(false)
|
|
expect(status.hnswIndex.ready).toBe(false)
|
|
delete brain.index.isReady
|
|
})
|
|
|
|
it('a ready provider reports populated:true + ready:true', async () => {
|
|
brain.index.isReady = () => true
|
|
const status = await brain.getIndexStatus()
|
|
expect(status.hnswIndex.populated).toBe(true)
|
|
expect(status.hnswIndex.ready).toBe(true)
|
|
delete brain.index.isReady
|
|
})
|
|
|
|
it('rebuildFailed / rebuildError surface the init-degraded state', async () => {
|
|
brain._indexRebuildFailed = new Error('boom')
|
|
const status = await brain.getIndexStatus()
|
|
expect(status.rebuildFailed).toBe(true)
|
|
expect(status.rebuildError).toBe('boom')
|
|
brain._indexRebuildFailed = null
|
|
})
|
|
|
|
it('degradedIds surfaces the adopt-forward degraded set', async () => {
|
|
brain._indexDegradedIds.add('00000000-0000-4000-8000-0000000000de')
|
|
const status = await brain.getIndexStatus()
|
|
expect(status.degradedIds).toBe(1)
|
|
brain._indexDegradedIds.clear()
|
|
})
|
|
|
|
it('a JS-baseline provider (no isReady) omits ready and falls back to size>0', async () => {
|
|
const status = await brain.getIndexStatus()
|
|
expect(status.hnswIndex.ready).toBeUndefined()
|
|
expect(status.hnswIndex.populated).toBe(brain.index.size() > 0)
|
|
})
|
|
})
|