mirror of
https://github.com/stablyai/orca.git
synced 2026-10-07 00:02:29 +00:00
Index discovered test files once during shard selection validation (#24532)
Verified selection plans previously validated each selected filename with a scan of all discovered files. One per-call Set now handles membership checks. Exact source/discovery checks, nonempty selection, fallback to all tests, shard balancing and manifests remain intact.
This commit is contained in:
@@ -16,13 +16,14 @@ export default class TimingSequencer extends BaseSequencer {
|
||||
'utf8'
|
||||
)
|
||||
)
|
||||
const discovered = new Set(plan.files)
|
||||
if (
|
||||
plan.version !== 1 ||
|
||||
!plan.sourceSha ||
|
||||
plan.sourceSha !== process.env.ORCA_SHARD_SOURCE_SHA ||
|
||||
JSON.stringify([...plan.files].sort()) !== JSON.stringify(specs.map(key).sort()) ||
|
||||
!Array.isArray(plan.executionFiles) ||
|
||||
plan.executionFiles.some((file) => !plan.files.includes(file))
|
||||
plan.executionFiles.some((file) => !discovered.has(file))
|
||||
) {
|
||||
throw new Error('Selection provenance or discovery differs')
|
||||
}
|
||||
|
||||
@@ -6,39 +6,86 @@ import TimingSequencer from './ci-unit-sequencer.mjs'
|
||||
|
||||
let root
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks()
|
||||
vi.unstubAllEnvs()
|
||||
if (root) {
|
||||
rmSync(root, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
it.each(['valid', 'stale', 'missing-file', 'missing-artifact'])(
|
||||
'preserves complete shard coverage with %s planning evidence',
|
||||
async (kind) => {
|
||||
root = mkdtempSync(join(tmpdir(), 'unit-sequencer-'))
|
||||
const files = ['src/a.test.ts', 'src/b.test.ts', 'src/c.test.ts', 'src/d.test.ts']
|
||||
const plan = {
|
||||
version: 1,
|
||||
sourceSha: kind === 'stale' ? 'old' : 'current',
|
||||
files: kind === 'missing-file' ? files.slice(1) : files,
|
||||
executionFiles: files.slice(0, 2)
|
||||
}
|
||||
const planPath = join(root, 'selection.json')
|
||||
if (kind !== 'missing-artifact') {
|
||||
writeFileSync(planPath, JSON.stringify(plan))
|
||||
}
|
||||
vi.stubEnv('ORCA_UNIT_SELECTION_PLAN', planPath)
|
||||
vi.stubEnv('ORCA_SHARD_SOURCE_SHA', 'current')
|
||||
vi.stubEnv('ORCA_SHARD_MANIFEST', join(root, 'assignment.json'))
|
||||
const assigned = []
|
||||
for (const index of [1, 2]) {
|
||||
const sequencer = new TimingSequencer({ config: { root, shard: { index, count: 2 } } })
|
||||
const specs = files.map((file) => ({ moduleId: join(root, file) }))
|
||||
assigned.push(...(await sequencer.shard(specs)).map((spec) => spec.moduleId))
|
||||
}
|
||||
expect(assigned.sort()).toEqual(
|
||||
(kind === 'valid' ? files.slice(0, 2) : files).map((file) => join(root, file)).sort()
|
||||
)
|
||||
expect(new Set(assigned).size).toBe(assigned.length)
|
||||
it.each([
|
||||
'valid',
|
||||
'stale',
|
||||
'missing-file',
|
||||
'missing-artifact',
|
||||
'outside-selection',
|
||||
'empty-selection'
|
||||
])('preserves complete shard coverage with %s planning evidence', async (kind) => {
|
||||
root = mkdtempSync(join(tmpdir(), 'unit-sequencer-'))
|
||||
const files = ['src/a.test.ts', 'src/b.test.ts', 'src/c.test.ts', 'src/d.test.ts']
|
||||
const plan = {
|
||||
version: 1,
|
||||
sourceSha: kind === 'stale' ? 'old' : 'current',
|
||||
files: kind === 'missing-file' ? files.slice(1) : files,
|
||||
executionFiles:
|
||||
kind === 'outside-selection'
|
||||
? ['src/unknown.test.ts']
|
||||
: kind === 'empty-selection'
|
||||
? []
|
||||
: files.slice(0, 2)
|
||||
}
|
||||
)
|
||||
const planPath = join(root, 'selection.json')
|
||||
if (kind !== 'missing-artifact') {
|
||||
writeFileSync(planPath, JSON.stringify(plan))
|
||||
}
|
||||
vi.stubEnv('ORCA_UNIT_SELECTION_PLAN', planPath)
|
||||
vi.stubEnv('ORCA_SHARD_SOURCE_SHA', 'current')
|
||||
vi.stubEnv('ORCA_SHARD_MANIFEST', join(root, 'assignment.json'))
|
||||
const assigned = []
|
||||
for (const index of [1, 2]) {
|
||||
const sequencer = new TimingSequencer({ config: { root, shard: { index, count: 2 } } })
|
||||
const specs = files.map((file) => ({ moduleId: join(root, file) }))
|
||||
assigned.push(...(await sequencer.shard(specs)).map((spec) => spec.moduleId))
|
||||
}
|
||||
expect(assigned.sort()).toEqual(
|
||||
(kind === 'valid' ? files.slice(0, 2) : files).map((file) => join(root, file)).sort()
|
||||
)
|
||||
expect(new Set(assigned).size).toBe(assigned.length)
|
||||
})
|
||||
|
||||
it('validates a large selection without scanning the discovered array for each file', async () => {
|
||||
root = mkdtempSync(join(tmpdir(), 'unit-sequencer-scale-'))
|
||||
const files = Array.from({ length: 1600 }, (_, index) => `src/scale-${index}.test.ts`)
|
||||
const executionFiles = files.slice(800)
|
||||
const planPath = join(root, 'selection.json')
|
||||
writeFileSync(
|
||||
planPath,
|
||||
JSON.stringify({ version: 1, sourceSha: 'current', files, executionFiles })
|
||||
)
|
||||
vi.stubEnv('ORCA_UNIT_SELECTION_PLAN', planPath)
|
||||
vi.stubEnv('ORCA_SHARD_SOURCE_SHA', 'current')
|
||||
vi.stubEnv('ORCA_SHARD_MANIFEST', join(root, 'assignment.json'))
|
||||
const sequencer = new TimingSequencer({ config: { root, shard: { index: 1, count: 1 } } })
|
||||
const specs = files.map((file) => ({ moduleId: join(root, file) }))
|
||||
const includes = Array.prototype.includes
|
||||
let discoveredArrayScans = 0
|
||||
const scan = vi
|
||||
.spyOn(Array.prototype, 'includes')
|
||||
.mockImplementation(function (value, fromIndex) {
|
||||
if (
|
||||
this.length === files.length &&
|
||||
this[0] === files[0] &&
|
||||
typeof value === 'string' &&
|
||||
value.startsWith('src/scale-')
|
||||
) {
|
||||
discoveredArrayScans += 1
|
||||
}
|
||||
return includes.call(this, value, fromIndex)
|
||||
})
|
||||
const selected = await sequencer.shard(specs)
|
||||
scan.mockRestore()
|
||||
expect(selected.map((spec) => spec.moduleId).sort()).toEqual(
|
||||
executionFiles.map((file) => join(root, file)).sort()
|
||||
)
|
||||
expect(discoveredArrayScans).toBe(0)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user