mirror of
https://github.com/stablyai/orca.git
synced 2026-10-09 00:02:39 +00:00
Run Node event-loop measurement after ordinary test suites (#26015)
This commit is contained in:
@@ -7,6 +7,9 @@ import { balanceFiles } from './ci-shard-assignment.mjs'
|
||||
import { discoverE2eFiles, planE2e } from './ci-e2e-shard-plan.mjs'
|
||||
import { parseTimingLog } from './ci-shard-timing-import.mjs'
|
||||
import TimingSequencer from './ci-unit-sequencer.mjs'
|
||||
import { UNIT_INCLUDE, UNIT_EXCLUDE } from './ci-unit-files.mjs'
|
||||
import { NODE_RUNTIME_INCLUDE } from './vitest-node-runtime-files.mjs'
|
||||
import { nodeRuntimePool } from './vitest-node-runtime-pool'
|
||||
|
||||
const directories = []
|
||||
afterEach(() => {
|
||||
@@ -60,10 +63,61 @@ describe('timing-weighted shard selection', () => {
|
||||
expect(new Set(selected)).toEqual(new Set(specs))
|
||||
})
|
||||
|
||||
it('wires a constructor into the opt-in Vitest config', async () => {
|
||||
it('keeps global sharding and runs the Node measurement after ordinary projects', async () => {
|
||||
vi.stubEnv('ORCA_BALANCE_UNIT_SHARDS', '1')
|
||||
const { default: config } = await import('../vitest.config')
|
||||
expect(config.test.sequence.sequencer).toBe(TimingSequencer)
|
||||
expect(config.test.maxWorkers).toBe(process.platform === 'win32' ? 4 : undefined)
|
||||
const measurementFile =
|
||||
'src/main/foreign-sqlite-readers/foreign-sqlite-reader-event-loop.test.ts'
|
||||
const projects = config.test.projects
|
||||
const measurement = projects.filter((project) => project.test.name === 'node-measurement')
|
||||
const ordinary = projects.filter((project) => project.test.name !== 'node-measurement')
|
||||
expect(measurement).toHaveLength(1)
|
||||
expect(ordinary).toHaveLength(process.versions.bun ? 2 : 1)
|
||||
expect(measurement[0].test).toMatchObject({
|
||||
include: [measurementFile],
|
||||
exclude: UNIT_EXCLUDE,
|
||||
maxWorkers: 1,
|
||||
sequence: { groupOrder: 2 },
|
||||
env: { ORCA_VITEST_RUNTIME: process.versions.bun ? 'node-runtime' : 'node' },
|
||||
pool: process.versions.bun ? 'node-runtime' : 'forks'
|
||||
})
|
||||
expect(measurement[0].test.poolRunner).toBe(process.versions.bun ? nodeRuntimePool : undefined)
|
||||
for (const project of ordinary) {
|
||||
expect(project.test.sequence.groupOrder).toBe(1)
|
||||
expect(project.test.exclude).toContain(measurementFile)
|
||||
}
|
||||
const ordinaryNode = ordinary.find((project) => project.test.name !== 'bun')
|
||||
expect(ordinaryNode.test.include).toEqual(
|
||||
process.versions.bun ? NODE_RUNTIME_INCLUDE : UNIT_INCLUDE
|
||||
)
|
||||
const ordinaryBun = ordinary.find((project) => project.test.name === 'bun')
|
||||
if (process.versions.bun) {
|
||||
expect(ordinaryBun.test.exclude).toEqual(
|
||||
expect.arrayContaining([...NODE_RUNTIME_INCLUDE, measurementFile])
|
||||
)
|
||||
}
|
||||
for (const project of projects) {
|
||||
expect(project.extends).toBe(false)
|
||||
expect(project.define).toEqual(config.define)
|
||||
expect(project.resolve).toEqual(config.resolve)
|
||||
expect(project.test.execArgv).toEqual(['--no-experimental-webstorage', '--expose-gc'])
|
||||
expect(project.test.setupFiles).toEqual([
|
||||
resolve('config/scripts/vitest-real-agent-home-write-guard.ts'),
|
||||
resolve('config/scripts/vitest-bun-node-builtins.ts'),
|
||||
resolve('config/scripts/happy-dom-offscreen-canvas.ts'),
|
||||
resolve('config/scripts/happy-dom-mutation-observer-retention.ts'),
|
||||
resolve('config/scripts/vitest-host-ports-setup.ts'),
|
||||
resolve('config/scripts/vitest-caller-identity-env-setup.ts')
|
||||
])
|
||||
expect(project.test).toMatchObject({
|
||||
environment: 'node',
|
||||
server: { deps: { inline: ['zod'] } },
|
||||
hookTimeout: 60_000,
|
||||
testTimeout: 30_000
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it('keeps nested/serial E2E files atomic and fails closed on discovery errors', () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { mkdtempSync, writeFileSync, rmSync } from 'node:fs'
|
||||
import { mkdtempSync, readFileSync, writeFileSync, rmSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { afterEach, expect, it, vi } from 'vitest'
|
||||
@@ -22,7 +22,12 @@ it.each([
|
||||
'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 files = [
|
||||
'src/main/foreign-sqlite-readers/foreign-sqlite-reader-event-loop.test.ts',
|
||||
'src/b.test.ts',
|
||||
'src/c.test.ts',
|
||||
'src/d.test.ts'
|
||||
]
|
||||
const plan = {
|
||||
version: 1,
|
||||
sourceSha: kind === 'stale' ? 'old' : 'current',
|
||||
@@ -44,8 +49,19 @@ it.each([
|
||||
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) }))
|
||||
const specs = files.map((file, position) => ({
|
||||
moduleId: join(root, file),
|
||||
project: {
|
||||
name: position === 0 ? 'node-measurement' : position % 2 ? 'bun' : 'node-runtime',
|
||||
config: { sequence: { groupOrder: position === 0 ? 2 : 1 }, isolate: true }
|
||||
}
|
||||
}))
|
||||
assigned.push(...(await sequencer.shard(specs)).map((spec) => spec.moduleId))
|
||||
const manifest = JSON.parse(readFileSync(join(root, 'assignment.json'), 'utf8'))
|
||||
expect(manifest.selectedShard).toBe(index)
|
||||
expect(manifest.shards.flatMap((shard) => shard.files).sort()).toEqual(
|
||||
(kind === 'valid' ? files.slice(0, 2) : files).toSorted()
|
||||
)
|
||||
}
|
||||
expect(assigned.sort()).toEqual(
|
||||
(kind === 'valid' ? files.slice(0, 2) : files).map((file) => join(root, file)).sort()
|
||||
|
||||
+42
-20
@@ -7,6 +7,7 @@ import { NODE_RUNTIME_INCLUDE } from './scripts/vitest-node-runtime-files.mjs'
|
||||
import { nodeRuntimePool } from './scripts/vitest-node-runtime-pool'
|
||||
|
||||
const balancedShards = process.env.ORCA_BALANCE_UNIT_SHARDS === '1'
|
||||
const measurementFile = 'src/main/foreign-sqlite-readers/foreign-sqlite-reader-event-loop.test.ts'
|
||||
const transforms = {
|
||||
define: { ORCA_FEATURE_WALL_ENABLED: 'true' },
|
||||
resolve: {
|
||||
@@ -39,28 +40,49 @@ const testOptions = {
|
||||
hookTimeout: 60_000,
|
||||
testTimeout: 30_000
|
||||
}
|
||||
const nodeProject = {
|
||||
extends: false,
|
||||
...transforms,
|
||||
test: {
|
||||
...testOptions,
|
||||
name: process.versions.bun ? 'node-runtime' : 'node',
|
||||
env: { ORCA_VITEST_RUNTIME: process.versions.bun ? 'node-runtime' : 'node' },
|
||||
include: process.versions.bun ? NODE_RUNTIME_INCLUDE : UNIT_INCLUDE,
|
||||
exclude: [...testOptions.exclude, measurementFile],
|
||||
sequence: { groupOrder: 1 },
|
||||
...(process.versions.bun
|
||||
? { pool: 'node-runtime', poolRunner: nodeRuntimePool }
|
||||
: { pool: 'forks' })
|
||||
}
|
||||
}
|
||||
const projects = [
|
||||
...(process.versions.bun
|
||||
? [
|
||||
{
|
||||
extends: false,
|
||||
...transforms,
|
||||
test: {
|
||||
...testOptions,
|
||||
name: 'bun',
|
||||
env: { ORCA_VITEST_RUNTIME: 'bun' },
|
||||
pool: 'forks',
|
||||
exclude: [...testOptions.exclude, ...NODE_RUNTIME_INCLUDE, measurementFile],
|
||||
sequence: { groupOrder: 1 }
|
||||
}
|
||||
}
|
||||
]
|
||||
: []),
|
||||
nodeProject,
|
||||
// Keep the event-loop measurement free of other suites without weakening its limits.
|
||||
{
|
||||
extends: false,
|
||||
...transforms,
|
||||
...nodeProject,
|
||||
test: {
|
||||
...testOptions,
|
||||
name: 'bun',
|
||||
env: { ORCA_VITEST_RUNTIME: 'bun' },
|
||||
pool: 'forks',
|
||||
exclude: [...testOptions.exclude, ...NODE_RUNTIME_INCLUDE]
|
||||
}
|
||||
},
|
||||
{
|
||||
extends: false,
|
||||
...transforms,
|
||||
test: {
|
||||
...testOptions,
|
||||
name: 'node-runtime',
|
||||
env: { ORCA_VITEST_RUNTIME: 'node-runtime' },
|
||||
include: NODE_RUNTIME_INCLUDE,
|
||||
pool: 'node-runtime',
|
||||
poolRunner: nodeRuntimePool
|
||||
...nodeProject.test,
|
||||
name: 'node-measurement',
|
||||
include: [measurementFile],
|
||||
exclude: testOptions.exclude,
|
||||
maxWorkers: 1,
|
||||
sequence: { groupOrder: 2 }
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -75,7 +97,7 @@ export default defineConfig({
|
||||
reporters: ['default', resolve('config/scripts/ci-unit-timing-reporter.mjs')]
|
||||
}
|
||||
: {}),
|
||||
...(process.versions.bun ? { projects } : {}),
|
||||
projects,
|
||||
...(process.platform === 'win32' ? { maxWorkers: 4 } : {})
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user