llm-checker/tests/cpu-detector-windows-fallback.test.js
signerless a16254a541 fix(tests): make hardware/perf/cpu/ollama tests hermetic and deterministic
Four tests failed or flaked because they were coupled to the host
environment rather than testing the code under test:

- token-speed-estimation: asserted the host was an Apple M4 Pro Mac, so it
  could only pass on the author's machine. Now drives the estimators from a
  fixed M4 Pro hardware fixture — deterministic and host-independent.
- hardware-detector-regression: the "ignore remote display adapter" case
  mocked systeminformation but the Linux-only lspci augmentation still
  shelled out and leaked the host's real GPUs (3 found, 1 expected). Stub
  lspci so the case stays hermetic.
- cpu-detector-windows-fallback: read live os.cpus()[0].speed twice, so CPU
  frequency scaling made the exact-equality assertion flaky (5614 vs 5618).
  Pin os.cpus() to a stable snapshot for the case.
- ollama-client-speed-metrics: hard-failed when no local Ollama server was
  reachable. Skip cleanly (matching the existing no-models skip) so the
  suite is green in CI/dev environments without Ollama.

Also remove the accidentally committed .tmp-feature-check/ probe artifacts
and gitignore transient probe dirs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 20:28:33 +02:00

156 lines
5.7 KiB
JavaScript

const assert = require('assert');
const childProcess = require('child_process');
const os = require('os');
const CPUDetector = require('../src/hardware/backends/cpu-detector');
class MockWindowsCPUDetector extends CPUDetector {
constructor(handler) {
super();
this.handler = handler;
this.commands = [];
}
runCommand(command) {
this.commands.push(command);
return this.handler(command);
}
}
function withPlatform(platform, fn) {
const originalDescriptor = Object.getOwnPropertyDescriptor(process, 'platform');
Object.defineProperty(process, 'platform', { value: platform });
try {
return fn();
} finally {
Object.defineProperty(process, 'platform', originalDescriptor);
}
}
function testPhysicalCoresFallbackToCim() {
const detector = new MockWindowsCPUDetector((command) => {
if (command.startsWith('wmic')) {
throw new Error('wmic not found');
}
if (command.includes('Get-CimInstance Win32_Processor') && command.includes('NumberOfCores')) {
return '12\r\n';
}
throw new Error(`Unexpected command: ${command}`);
});
const physical = withPlatform('win32', () => detector.getPhysicalCores());
assert.strictEqual(physical, 12, `Expected PowerShell CIM fallback for physical cores, got ${physical}`);
assert(
detector.commands.some((cmd) => cmd.startsWith('wmic cpu get NumberOfCores')),
'Expected WMIC to be attempted first for physical cores'
);
assert(
detector.commands.some((cmd) => cmd.includes('Get-CimInstance Win32_Processor') && cmd.includes('NumberOfCores')),
'Expected Get-CimInstance fallback to be attempted for physical cores'
);
}
function testMaxClockFallbackToCim() {
const detector = new MockWindowsCPUDetector((command) => {
if (command.startsWith('wmic')) {
throw new Error('wmic not found');
}
if (command.includes('Get-CimInstance Win32_Processor') && command.includes('MaxClockSpeed')) {
return '5200\r\n';
}
throw new Error(`Unexpected command: ${command}`);
});
const maxClock = withPlatform('win32', () => detector.getMaxFrequency());
assert.strictEqual(maxClock, 5200, `Expected PowerShell CIM fallback for max clock speed, got ${maxClock}`);
assert(
detector.commands.some((cmd) => cmd.startsWith('wmic cpu get MaxClockSpeed')),
'Expected WMIC to be attempted first for max clock speed'
);
assert(
detector.commands.some((cmd) => cmd.includes('Get-CimInstance Win32_Processor') && cmd.includes('MaxClockSpeed')),
'Expected Get-CimInstance fallback to be attempted for max clock speed'
);
}
function testFallbackToNodeWhenWindowsCommandsUnavailable() {
const detector = new MockWindowsCPUDetector(() => {
throw new Error('command unavailable');
});
// Pin os.cpus() to a stable snapshot for the duration of this case. The Node
// fallback reads os.cpus()[0].speed, and reading the live value twice (once for
// the expectation, once inside the detector) is racy: CPU frequency scaling
// changes the reported clock between the two reads, which made this assertion
// flaky (e.g. 5614 vs 5618 MHz). Both reads now see identical values.
const originalCpus = os.cpus;
const fakeCpus = Array.from({ length: 8 }, () => ({ model: 'Mock CPU', speed: 3200 }));
os.cpus = () => fakeCpus.map((cpu) => ({ ...cpu }));
try {
const expectedCores = os.cpus().length;
const expectedSpeed = os.cpus()[0]?.speed || 0;
const result = withPlatform('win32', () => ({
physical: detector.getPhysicalCores(),
maxClock: detector.getMaxFrequency()
}));
assert.strictEqual(
result.physical,
expectedCores,
`Expected Node.js fallback core count (${expectedCores}), got ${result.physical}`
);
assert.strictEqual(
result.maxClock,
expectedSpeed,
`Expected Node.js fallback clock speed (${expectedSpeed}), got ${result.maxClock}`
);
} finally {
os.cpus = originalCpus;
}
}
function testWindowsCommandRunnerSuppressesWmicShellNoise() {
const originalSpawnSync = childProcess.spawnSync;
childProcess.spawnSync = (command, options) => {
assert.strictEqual(command, 'wmic cpu get NumberOfCores /value');
assert.strictEqual(options.shell, true, 'Expected Windows commands to run through a shell');
assert.strictEqual(options.windowsHide, true, 'Expected Windows shell windows to stay hidden');
assert.deepStrictEqual(options.stdio, ['ignore', 'pipe', 'pipe'], 'Expected stderr/stdout to be captured');
return {
status: 1,
stdout: '',
stderr: "'wmic' is not recognized as an internal or external command\r\n"
};
};
try {
const detector = new CPUDetector();
const result = withPlatform('win32', () => detector.queryWindowsNumeric(['wmic cpu get NumberOfCores /value']));
assert.strictEqual(result, null, 'Expected WMIC shell failures to be swallowed so fallback commands can continue');
} finally {
childProcess.spawnSync = originalSpawnSync;
}
}
function run() {
testPhysicalCoresFallbackToCim();
testMaxClockFallbackToCim();
testFallbackToNodeWhenWindowsCommandsUnavailable();
testWindowsCommandRunnerSuppressesWmicShellNoise();
console.log('cpu-detector-windows-fallback.test.js: OK');
}
if (require.main === module) {
try {
run();
} catch (error) {
console.error('cpu-detector-windows-fallback.test.js: FAILED');
console.error(error);
process.exit(1);
}
}
module.exports = { run };