* test(ci): give the Windows OEM process-read test the PowerShell cold-start watchdog
The runner's first Windows PowerShell 5.1 start has reached 48 s on packaged CI; the
test's 30 s cap failed package (windows) 7 times in ~1,000 runs. Match the 75 s
watchdog nsis-process-check already uses for the same cold start.
Co-Authored-By: Claude <noreply@anthropic.com>
* test(ci): keep the OEM marker alive past a cold read, and bound the PowerShell read
A blocking spawnSync can't be interrupted by the test timeout, and the marker child
exited at 30 s, so a 48 s cold read could miss it. The reader now has its own 60 s bound.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(bench): keep idle-CPU cleanup running when the final process read fails
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(bench): kill the app tree when the final process read fails
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix(bench): make the idle-CPU benchmark run and report CPU on Windows
Three independent Windows defects in the idle-CPU benchmark (its report is
what Windows performance work would cite):
- `buildAppIfNeeded` spawned `npx`, which is `npx.cmd` on Windows, so
execFileSync failed with ENOENT before any sampling. Build through
`config/scripts/run-electron-vite-build.mjs` instead — the repo's own
Windows-safe wrapper, which also runs the boot-graph verification.
- `readWindowsProcesses` returned `cpuTimeSeconds: null`, so the sampler's
per-process CPU delta (idle-cpu-process-sampling.mjs:198) fell back to
the hardcoded `percentCpu: 0` and every CPU KPI in the report was zero.
Read `UserModeTime`/`KernelModeTime` from `Win32_Process` (100 ns units)
and keep `null` when a host does not return them.
Measured on Windows, same options before and after the CPU fix:
| class | mean CPU before | mean CPU after |
| --- | ---: | ---: |
| renderer | 0 | 2.20 |
| gpu | 0 | 2.08 |
| utility | 0 | 0.11 |
| agent-or-node | 0 | 0.06 |
| total | 0 | 4.51 (p95 8.40) |
RSS is unchanged (934 MiB -> 937 MiB), so only the CPU reporting changed.
Refs #25235
* fix(bench): reject a missing Win32_Process time instead of reading it as zero
Review follow-up (CodeRabbit). `Number(null)` is `0`, which is also a real
counter value, so an absent `UserModeTime`/`KernelModeTime` passed the
finite check and the sampler would report a kernel-only delta instead of
taking the fallback. Require an actual number from the CIM payload.
Verified on Windows that the real payload still reports CPU once the check
is tight: total mean 4.40%, p95 14.48%, renderer 3.51%.
* test(bench): cover the Windows CIM CPU time mapping
The mapping was only reachable through Get-CimInstance, so no test ran it.
Lift it into cimCpuSeconds and assert the 100ns-to-seconds sum plus the
missing / string / non-finite cases that must stay null.
* fix(bench): read the Windows process table as UTF-8 so JSON.parse survives
PowerShell writes to a redirected stdout in the OEM code page (437 here),
which best-fits characters such as U+2022 and U+2192 in any running
process's command line to raw 0x07 / 0x1A bytes. ConvertTo-Json had left
them unescaped because they are not control characters in UTF-16, so the
sampler's JSON.parse failed with "Bad control character in string literal"
whenever such a process happened to be alive -- hence intermittent.
Set [Console]::OutputEncoding to UTF-8, as the app's own CIM scan does,
and cover it with a Windows-only test that fails without the fix.
Fixes#25236
* fix(bench): pass the local runtime to fetchRepos in the idle-CPU fixture
fetchRepos now requires a runtimeEnvironmentId, so the fixture's bare call
threw "Cannot read properties of undefined (reading 'runtimeEnvironmentId')"
before sampling on every platform. null selects this app's own catalog, as
the e2e helpers already do.
* ci(bench): run the Windows process-table test in the Windows lane
The UTF-8 regression test self-skips off win32, so it must be registered in
both Windows lists or it runs on no machine.
---------
Co-authored-by: Paolo <paovalletta@hotmail.it>
Co-authored-by: Orca Worker <orca-worker@localhost>
Splits run-idle-cpu-benchmark.mjs into a scale fixture, an in-page timing
probe, and process sampling, and records a measured origin/main baseline so
the agent-status batching slice has an auditable before.
The agent-status write workload is not included: it needs setAgentStatuses,
so it lands with the store slice.