Files
orca/config/scripts/windows-native-benchmark-observer.mjs
T
Neil f23fa8ca76 Prepare Windows natives with scoped compiler settings and measure servicing (#28881)
* Scope Windows native compiler setup and measure ARM inbox preparation

* Add a controlled Windows native preparation comparison

* Test native preparation through an injected process runner

* Guard reviewed Windows native batch runners
2026-10-14 18:18:24 -07:00

119 lines
4.1 KiB
JavaScript

import assert from 'node:assert/strict'
import { createHash } from 'node:crypto'
import { writeFileSync } from 'node:fs'
import { createRequire } from 'node:module'
import { basename } from 'node:path'
import { performance } from 'node:perf_hooks'
export const compilerEnvironmentKey =
/^(PATH|INCLUDE|LIB|LIBPATH|VCINSTALLDIR|VSINSTALLDIR|VisualStudioVersion|VSCMD_.+|VCTools.+|WindowsSDK.+|UniversalCRT.+|UCRTVersion)$/i
export const hash = (value) => createHash('sha256').update(value).digest('hex')
export function environmentReceipt(environment) {
const entries = Object.entries(environment)
.filter(([, value]) => value !== undefined)
.map(([name, value]) => [name.toLowerCase(), String(value)])
.sort(([left], [right]) => left.localeCompare(right))
assert.equal(
new Set(entries.map(([name]) => name)).size,
entries.length,
'Duplicate environment keys'
)
return {
hash: hash(JSON.stringify(entries)),
versions: Object.fromEntries(
entries.filter(
([name, value]) =>
/^(visualstudioversion|vscmd_ver|windowssdkversion|vctoolsversion|vscmd_arg_tgt_arch)$/.test(
name
) && /^(?:[\d.]+\\?|x64|amd64|arm64)$/.test(value)
)
),
compiler: Object.fromEntries(
entries
.filter(([name]) => compilerEnvironmentKey.test(name))
.map(([name, value]) => [name, hash(value)])
)
}
}
export function changedEnvironmentNames(before, after) {
const normalize = (environment) =>
new Map(Object.entries(environment).map(([name, value]) => [name.toLowerCase(), value]))
const original = normalize(before)
const prepared = normalize(after)
return [...new Set([...original.keys(), ...prepared.keys()])]
.filter((name) => original.get(name) !== prepared.get(name))
.sort()
}
export function processPhase(spec) {
const name = basename(spec.program).toLowerCase()
if (name === 'vswhere.exe') {
return 'discovery'
}
if (name === 'capture-windows-native-environment.cmd') {
return 'capture'
}
if (spec.args?.some((arg) => arg.endsWith('ensure-native-runtime.mjs'))) {
return spec.args.includes('--check-only') ? 'probe' : 'preparation'
}
return spec.args?.includes('rebuild') ? 'addon-build' : 'other'
}
export function installNativeBenchmarkObserver(api, output, environment = process.env) {
const original = api.runProcessSync
const parent = environmentReceipt(environment)
const receipt = { parentBefore: parent, parentAfter: parent, calls: [] }
writeFileSync(output, `${JSON.stringify(receipt, null, 2)}\n`)
api.runProcessSync = (spec) => {
const startedAt = new Date().toISOString()
const start = performance.now()
const childEnvironment = spec.env ?? environment
const call = {
phase: processPhase(spec),
program: basename(spec.program),
args: spec.args,
startedAt,
environment: environmentReceipt(childEnvironment),
changedNames: changedEnvironmentNames(environment, childEnvironment)
}
try {
const result = original(spec)
Object.assign(call, {
code: result.code,
timedOut: result.timedOut,
outputTruncated: result.outputTruncated,
stdoutSha256: hash(result.stdout ?? ''),
stderrSha256: hash(result.stderr ?? ''),
stdoutBytes: Buffer.byteLength(result.stdout ?? ''),
stderrBytes: Buffer.byteLength(result.stderr ?? '')
})
return result
} catch (error) {
call.error = error.message
throw error
} finally {
call.durationMs = performance.now() - start
call.finishedAt = new Date().toISOString()
receipt.calls.push(call)
receipt.parentAfter = environmentReceipt(environment)
assert.equal(
receipt.parentAfter.hash,
parent.hash,
'Compiler setup changed its parent environment'
)
writeFileSync(output, `${JSON.stringify(receipt, null, 2)}\n`)
}
}
return receipt
}
if (process.env.ORCA_NATIVE_BENCHMARK_TRACE) {
const require = createRequire(import.meta.url)
installNativeBenchmarkObserver(
require('@orca/process-host'),
process.env.ORCA_NATIVE_BENCHMARK_TRACE
)
}