mirror of
https://github.com/got-feedBack/feedBack-desktop.git
synced 2026-08-11 03:09:56 +00:00
Clean release snapshot
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
// 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);
|
||||
Reference in New Issue
Block a user