Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
d2f5242
ci: add a non-blocking Windows job for the oracle framework and gap CLI
KyleAMathews Nov 13, 2026
0fc897b
ci(windows): diagnostic split of the fast suites, fixture package.json
KyleAMathews Nov 13, 2026
72b9495
ci(windows): diagnostic replay, error-log dump, and discovered-config…
KyleAMathews Nov 13, 2026
dacfb88
fix(oracle-gaps): one path rule for Windows, and shell-aware replay l…
KyleAMathews Nov 13, 2026
8d96432
test: portable npm spawns, a segment rule for production files, nativ…
KyleAMathews Nov 13, 2026
ef9205d
ci(windows): sharded Windows jobs in place of the diagnostic ones
KyleAMathews Nov 13, 2026
8d2d037
fix(oracle-gaps): give TypeScript and the owner map one spelling of a…
KyleAMathews Nov 13, 2026
29c6959
ci(windows): P10 done-line, refusal, early-stop, and per-shell replay…
KyleAMathews Nov 13, 2026
00456e7
fix(oracle-gaps): oracles read the platform's replay lines, and scrat…
KyleAMathews Nov 13, 2026
f79aae7
fix(windows): forward-slash report paths, cmd quotes, six shards, and…
KyleAMathews Nov 13, 2026
8697227
fix(oracle-gaps): keys and report paths are forward-slash in the CLI …
KyleAMathews Nov 13, 2026
0c9f38d
ci(windows): the replay witness runs after a failed stop witness
KyleAMathews Nov 13, 2026
dc71773
ci(windows): print the replay output the witness reads (diagnostic)
KyleAMathews Nov 13, 2026
b8b48d7
ci(windows): the replay fixture declares its fixed seed
KyleAMathews Nov 13, 2026
00a2740
Merge remote-tracking branch 'origin/main' into ci/windows
KyleAMathews Nov 13, 2026
c1c34d2
fix(windows): the stop law on win32, the stop hook, the argv cap, and…
KyleAMathews Nov 13, 2026
ee1a5fd
fix(oracle-gaps): the temporary directory's real path for state, sock…
KyleAMathews Nov 13, 2026
70b118d
fix(oracle-gaps): the e2e fixture's temporary directory by its native…
KyleAMathews Nov 13, 2026
ebc39e6
ci(windows): split the blocking Windows jobs from the non-blocking on…
KyleAMathews Nov 13, 2026
318e95e
fix(oracle-gaps): the static oracle's temp directory by its native re…
KyleAMathews Nov 13, 2026
d0ea5af
fix(oracle-gaps): the e2e driver names a scratch path in both spellin…
KyleAMathews Nov 13, 2026
09df6bb
fix(oracle-gaps): mutants' owner files are forward-slash in the e2e d…
KyleAMathews Nov 13, 2026
50b4ab5
fix(windows): stop witness, replay quoting by the shells' grammar, an…
KyleAMathews Nov 14, 2026
b904d57
fix(oracle-gaps): path-spelling oracle generates win32 separators and…
KyleAMathews Nov 14, 2026
de8a373
fix(oracle-gaps): event-triggered stop, derived hostile names, and th…
KyleAMathews Nov 14, 2026
63bf49e
fix(oracle-gaps): constructed tests keep their names (classify reach)
KyleAMathews Nov 14, 2026
c3ed569
Merge remote-tracking branch 'origin/ci/windows' into ci/windows-stat…
KyleAMathews Nov 14, 2026
2b7b7f3
fix(windows): Rerun cmd lines, ! as no-form, separators by platform, …
KyleAMathews Nov 14, 2026
abc8b45
fix(windows): the witness feeds PowerShell its line on stdin, not as …
KyleAMathews Nov 14, 2026
69c82eb
diagnostic: the replay witness reports the shell's own error for a li…
KyleAMathews Nov 14, 2026
0772447
fix(windows): the -t argument never carries a shell-hostile character…
KyleAMathews Nov 14, 2026
ae44184
Revert "diagnostic: the replay witness reports the shell's own error …
KyleAMathews Nov 14, 2026
0f49e3e
Merge remote-tracking branch 'origin/ci/windows' into ci/windows-stat…
KyleAMathews Nov 14, 2026
9698922
fix(windows): cmd env rule, exact witness matching, set-line readers,…
KyleAMathews Nov 14, 2026
257a5b0
fix(windows): the replay witness counts each printed line once, and r…
KyleAMathews Nov 14, 2026
0c42c33
fix(windows): the replay witness pairs each printed line with its cmd…
KyleAMathews Nov 14, 2026
08f028d
fix(windows): restore the replay witness's helpers that the pairing r…
KyleAMathews Nov 14, 2026
bd208ac
fix(windows): a Rerun line counts only for its own failing fixed unit…
KyleAMathews Nov 14, 2026
3b97795
fix(windows): the witness reads a fixed unit's FAIL line (`fixed seed…
KyleAMathews Nov 14, 2026
7d46701
fix(windows): the Rerun name check ignores vitest's colors
KyleAMathews Nov 14, 2026
2ee903a
Merge remote-tracking branch 'origin/ci/windows' into ci/windows-stat…
KyleAMathews Nov 14, 2026
5186cd5
Merge remote-tracking branch 'origin/main' into ci/windows-static-e2e
KyleAMathews Nov 14, 2026
f4bc85c
fix(oracle-gaps): the e2e replay check reads and runs the PowerShell …
KyleAMathews Nov 14, 2026
dd3347a
test(oracle-gaps): the greppable-stream breach names the stdout's gap…
KyleAMathews Nov 14, 2026
8721946
test(oracle-gaps): the greppable-stream breach names the stderr's gap…
KyleAMathews Nov 14, 2026
f00c2c7
fix(oracle-gaps): invalidate a patched file by its forward-slash path…
KyleAMathews Nov 14, 2026
b6085b8
fix(oracle-gaps): the CLI-directory reach state compares paths in one…
KyleAMathews Nov 14, 2026
0f9c1a5
fix(oracle-gaps): the static driver names the package in both path sp…
KyleAMathews Nov 14, 2026
957a060
ci: the Windows static oracle job blocks the preview
KyleAMathews Nov 14, 2026
8fb0b00
fix(oracle-gaps): the daemon pause and win32 stops do not need signal…
KyleAMathews Nov 14, 2026
7efe175
fix(oracle-gaps): the abort run is POSIX only; the Windows end-to-end…
KyleAMathews Nov 14, 2026
9b22c71
test(oracle-gaps): the idle profile records which condition blocked t…
KyleAMathews Nov 14, 2026
495b281
fix(oracle-gaps): the abort state is reachable on every platform again
KyleAMathews Nov 14, 2026
5d97ae8
chore(oracle-gaps): temporary daemon-history profile on Linux and Win…
KyleAMathews Nov 14, 2026
887dfe3
chore(oracle-gaps): probe the daemon-history job's startup and gap ti…
KyleAMathews Nov 14, 2026
144bc06
chore(oracle-gaps): time ps in the temporary profile job
KyleAMathews Nov 14, 2026
d0cd4fe
chore(oracle-gaps): probe ps without timeout and tolerate probe failures
KyleAMathews Nov 14, 2026
79f421e
chore(oracle-gaps): remove the temporary daemon-history profile
KyleAMathews Nov 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,11 @@ jobs:
- test-oracle-gaps-fast
- test-oracle-gaps-end-to-end
- test-vitest-5
# The blocking Windows jobs (the non-blocking static and e2e jobs are not
# a dependency until they are green).
# The blocking Windows jobs (the non-blocking end-to-end job is not a
# dependency until it is green).
- windows-unit
- windows-gap-classify
- windows-gap-oracles
- windows-gap-cli
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -223,10 +224,6 @@ jobs:
windows-gap-oracles:
name: Windows gap report static oracle (${{ matrix.shard }}/6)
runs-on: windows-latest
# Not blocking yet: these suites fail on Windows, tracked by class in
# https://github.com/TanStack/oracles/issues/72. Remove this line when they
# are green.
continue-on-error: true
timeout-minutes: 20
strategy:
fail-fast: false
Expand Down Expand Up @@ -287,7 +284,8 @@ jobs:
working-directory: packages/oracles
env:
SHARD: ${{ matrix.shard }}
run: pnpm exec vitest --run --config oracle-gaps/vitest.config.mjs gap-report-oracle -t "$(node scripts/pr-shards.mjs pattern oracle-gaps-fixed-seed-windows "$SHARD")"
# The verbose reporter prints each test with its duration, which sizes the shards.
run: pnpm exec vitest --run --reporter=verbose --config oracle-gaps/vitest.config.mjs gap-report-oracle -t "$(node scripts/pr-shards.mjs pattern oracle-gaps-fixed-seed-windows "$SHARD")"
windows-gap-cli:
name: Windows gap CLI on a fixture
runs-on: windows-latest
Expand Down
35 changes: 27 additions & 8 deletions packages/oracles/oracle-gaps/capture-setup.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -953,23 +953,29 @@ if (state.capture || idleProfile) {
let since
let last
let longest = 0
// Profiling only: how many samples each condition blocked the idle clock.
let blocked = new Map()
// The test whose samples are being recorded (profiling).
let key
let use = realUse()
let reported = false
beforeEach(() => {
if (continuing) return
baseTimers = timersListed(process.getActiveResourcesInfo())
since = undefined
longest = 0
blocked = new Map()
sawIo = false
})
beforeEach((context) => {
if (continuing) return
key = testKey(context.task)
context.onTestFinished(() => {
baseTimers = undefined
if (idleProfile)
appendFileSync(
idleProfile,
`${JSON.stringify({ key: testKey(context.task), longest })}\n`,
`${JSON.stringify({ key: testKey(context.task), longest, blocked: Object.fromEntries(blocked) })}\n`,
)
})
})
Expand All @@ -988,14 +994,27 @@ if (state.capture || idleProfile) {
// a timeout at the limit anyway (a collection's five-minute GC timer).
const horizon = now + (state.idleHorizonMs ?? Infinity)
const timerDue = [...pending.values()].some((due) => due <= horizon)
if (
late ||
io ||
used.utilization > 0.05 ||
timerDue ||
timersListed(kinds) > baseTimers
) {
const blocker = late
? `late`
: io
? `io ${kinds.filter((kind) => !quiet.has(kind)).join(`,`)}`
: used.utilization > 0.05
? `busy`
: timerDue
? `timer due`
: timersListed(kinds) > baseTimers
? `timers listed`
: undefined
// Each sample of a copy that can be cut off is written as it happens, so
// a copy the watchdog kills keeps its samples (profiling).
if (idleProfile && state.idleMs)
appendFileSync(
idleProfile,
`${JSON.stringify({ sample: blocker ?? `idle`, key, at: Math.round(now) })}\n`,
)
if (blocker !== undefined) {
since = undefined
if (idleProfile) blocked.set(blocker, (blocked.get(blocker) ?? 0) + 1)
return
}
since ??= now
Expand Down
4 changes: 2 additions & 2 deletions packages/oracles/oracle-gaps/check.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ export default async (env) => {
for (const path of paths) {
const hash = servedHash(path, index)
if (served.get(path) === hash) continue
context.invalidateFile(path)
context.invalidateFile(posix(path))
served.set(path, hash)
}
}
Expand Down Expand Up @@ -1457,7 +1457,7 @@ export default async (env) => {
const hash = started.get(path) ?? now
const read = served.get(path) ?? hash
// The context may hold other text than the path's text now.
if (read !== now || hash !== now) context.invalidateFile(path)
if (read !== now || hash !== now) context.invalidateFile(posix(path))
if (hash !== now) stable = false
served.set(path, now)
return [path, hash]
Expand Down
17 changes: 17 additions & 0 deletions packages/oracles/oracle-gaps/daemon.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import { spawn } from 'node:child_process'
import { randomUUID } from 'node:crypto'
import {
existsSync,
linkSync,
mkdirSync,
openSync,
Expand Down Expand Up @@ -370,6 +371,22 @@ async function serve(pkg) {
stderr.push(`${line}\n`),
)
await store.flush()
// A test-only pause (ORACLE_GAPS_TEST_PAUSE_AT=daemon-reply, as
// ORACLE_GAPS_TEST_STOP): the check is done and its reply is held,
// so the CLI waits as it would for a daemon that is slow and dies.
// The pause is marked in the check's output directory, with this
// daemon's pid, for the oracle to kill it by (no signal pauses a
// process on win32).
// Once: a daemon that the CLI restarts after this one died inherits the
// variable, and must answer, or the CLI waits as long as the run allows.
const mark = join(options.out, `paused`)
if (
process.env.ORACLE_GAPS_TEST_PAUSE_AT === `daemon-reply` &&
!existsSync(mark)
) {
writeFileSync(mark, `${process.pid}`)
await new Promise(() => {})
}
} catch (error) {
failed = sent(error)
}
Expand Down
Loading
Loading