mirror of
https://github.com/got-feedBack/feedBack-desktop.git
synced 2026-07-21 20:31:28 +00:00
130 lines
5.7 KiB
JavaScript
130 lines
5.7 KiB
JavaScript
// Smoke-test harness for the Windows VST sandbox path. Loads the addon,
|
|
// spawns the sandbox subprocess for Guitar Rig 6, opens its editor, then
|
|
// closes and shuts down cleanly. Used by clean-rerun.cmd on the test VM.
|
|
//
|
|
// Run from the repo root: `node scripts/dev/load-gr6.js > load-gr6-sandbox.log`.
|
|
// The Guitar Rig 6 path is hardcoded to its standard Win11 install location;
|
|
// adjust the GR6 path below if your install differs.
|
|
'use strict';
|
|
const path = require('path');
|
|
const addonPath = path.join(process.cwd(), 'build', 'Release', 'slopsmith_audio.node');
|
|
console.log('[test] loading addon from', addonPath);
|
|
const addon = require(addonPath);
|
|
console.log('[test] addon loaded; methods:', Object.keys(addon).slice(0, 10).join(', '), '...');
|
|
|
|
// Global watchdog — best-effort coverage for *asynchronous* hang paths
|
|
// (event-loop livelocks, setTimeout-stacked cleanup). loadVST is now a
|
|
// Napi::AsyncWorker, so the libuv event loop continues to fire timers
|
|
// while the load runs on a worker thread; this watchdog can pre-empt
|
|
// a hung async load. addon.shutdown still parks the event loop
|
|
// synchronously inside dispatchOnMessageThread, so if shutdown itself
|
|
// hangs the timer callback never fires — a proper supervisor-process
|
|
// + SIGKILL watchdog belongs in the CI harness (test-suite follow-up).
|
|
//
|
|
// The timer callback hard-exits — do NOT call addon.shutdown() here,
|
|
// it would block on the same dispatchOnMessageThread the addon is
|
|
// already stuck in and deadlock the process.
|
|
const WATCHDOG_MS = 60000;
|
|
const watchdog = setTimeout(() => {
|
|
console.error(`[test] FATAL: watchdog tripped after ${WATCHDOG_MS} ms (async hang)`);
|
|
process.exit(1);
|
|
}, WATCHDOG_MS);
|
|
|
|
function failExit(msg) {
|
|
if (msg) console.log('[test] FAIL:', msg);
|
|
// addon.shutdown blocks on dispatchOnMessageThread (up to 15s) if
|
|
// JUCE init partially succeeded; an init-failure path that triggered
|
|
// *because* the message thread never came up would then time out
|
|
// before the process exits. Cap with a hard process.exit timer so a
|
|
// hung shutdown can't extend the failure window beyond 3s.
|
|
const hardKill = setTimeout(() => {
|
|
console.error('[test] FAIL: addon.shutdown hung, force-exiting');
|
|
process.exit(2);
|
|
}, 3000);
|
|
hardKill.unref();
|
|
try { addon.shutdown(); } catch (_) {}
|
|
try { clearTimeout(watchdog); } catch (_) {}
|
|
try { clearTimeout(hardKill); } catch (_) {}
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log('[test] addon.init()');
|
|
try {
|
|
addon.init();
|
|
} catch (e) {
|
|
failExit('EXCEPTION on init: ' + e.message);
|
|
}
|
|
|
|
setTimeout(async () => {
|
|
// Allow override for CI / dev machines whose VST3 layout differs from
|
|
// the standard "C:\Program Files\Common Files\VST3" install location.
|
|
// The default Native Instruments install ships "Guitar Rig 6.vst3";
|
|
// some installer versions or FX-only variants land as
|
|
// "Guitar Rig 6 FX.vst3". Try both before giving up.
|
|
const fs = require('fs');
|
|
const candidates = process.env.GR6_PATH
|
|
? [process.env.GR6_PATH]
|
|
: [
|
|
// NI's own installer drops into a vendor subdir; this is the
|
|
// most common default on a fresh GR6 install.
|
|
'C:\\Program Files\\Native Instruments\\VST3\\Guitar Rig 6.vst3',
|
|
'C:\\Program Files\\Native Instruments\\VST3\\Guitar Rig 6 FX.vst3',
|
|
// Some installs (and the existing CI fixture VM) drop into the
|
|
// shared Common Files VST3 dir; keep these as fallbacks so the
|
|
// existing smoke harness doesn't have to flip overnight.
|
|
'C:\\Program Files\\Common Files\\VST3\\Guitar Rig 6.vst3',
|
|
'C:\\Program Files\\Common Files\\VST3\\Guitar Rig 6 FX.vst3',
|
|
];
|
|
const gr6 = candidates.find(p => { try { return fs.existsSync(p); } catch (_) { return false; } });
|
|
if (!gr6) {
|
|
console.error('[test] FATAL: no Guitar Rig 6 install found at any of:');
|
|
for (const p of candidates) console.error(' - ' + p);
|
|
console.error('Set GR6_PATH to override (e.g. GR6_PATH="C:\\path\\to\\Guitar Rig 6.vst3" node scripts\\dev\\load-gr6.js).');
|
|
try { addon.shutdown(); } catch (_) {}
|
|
clearTimeout(watchdog);
|
|
process.exit(2);
|
|
return;
|
|
}
|
|
console.log('[test] calling addon.loadVST(' + gr6 + ')');
|
|
let slot;
|
|
try {
|
|
// addon.loadVST is now a Promise<number> (Napi::AsyncWorker); await
|
|
// it. The enclosing setTimeout callback was made async above.
|
|
slot = await addon.loadVST(gr6);
|
|
console.log('[test] loadVST returned slot:', slot);
|
|
} catch (e) {
|
|
failExit('EXCEPTION on loadVST: ' + e.message);
|
|
return;
|
|
}
|
|
|
|
if (!Number.isInteger(slot) || slot < 0) {
|
|
failExit('loadVST returned invalid slot: ' + String(slot));
|
|
return;
|
|
}
|
|
|
|
setTimeout(() => {
|
|
console.log('[test] calling addon.openPluginEditor(' + slot + ')');
|
|
let ok = false;
|
|
try {
|
|
ok = addon.openPluginEditor(slot);
|
|
console.log('[test] openPluginEditor returned:', ok);
|
|
} catch (e) {
|
|
failExit('EXCEPTION on openPluginEditor: ' + e.message);
|
|
return;
|
|
}
|
|
if (!ok) {
|
|
try { addon.closePluginEditor(slot); } catch (_) {}
|
|
failExit('openPluginEditor returned false');
|
|
return;
|
|
}
|
|
console.log('[test] sleeping 5s for editor creation + potential crash...');
|
|
setTimeout(() => {
|
|
console.log('[test] still alive after editor wait; closing');
|
|
try { addon.closePluginEditor(slot); } catch (e) {}
|
|
try { addon.shutdown(); } catch (e) {}
|
|
clearTimeout(watchdog);
|
|
setTimeout(() => process.exit(0), 1000);
|
|
}, 5000);
|
|
}, 1500);
|
|
}, 2000);
|