openvibers/openvibe.wiki Commits

The perf-budget test boots its server on its own PGlite directory (WIKI_PGLITE_DIR, a temp dir removed afterwards) with DATABASE_URL cleared: it used to fall back to the shared dev database data/pglite and migrate it. The exit wait is registered at spawn and raced against 12 s, so a server that crashed before the checks fails the test instead of ending it as a pass, and its database is removed only after it has exited. Found by the estate-wide floating-promise sweep; reviewed independently (its blocker, the exit wait, fixed here). npm test 32/32 test files passed.

OP OpenVibers committed 29 Sept 2026 · 186baef683 · 2 files, +23 −5


Changes

ddiff --git a/server/db.js b/server/db.js
iindex d154d4c..c49b07a 100644
---- a/server/db.js
++++ b/server/db.js
@@@ -22,7 +22,7 @@
* and wiki_event_outbox (openvibe-sdk/events PostgreSQL outbox).
*
* openDb(config) the serving handle: DATABASE_URL; in development without it, an embedded PGlite
-- * database in data/pglite (one process, nothing to install)
++ * database in data/pglite (WIKI_PGLITE_DIR overrides it; one process, nothing to install)
* migrate(config, {serving}) apply migrations/ with the owner role (DATABASE_DIRECT_URL), then close it
*/
const fs = require('fs');
@@@ -43,9 +43,10 @@ const DEV_PGLITE = path.join(__dirname, '..', 'data', 'pglite');
function openDb(config, { registry, log = console } = {}) {
if (!config.db.url) {
if (config.isProduction) throw new Error('DATABASE_URL is not set: production serves from PostgreSQL (OpenVibe.Host roles/data add-service.sh wiki)');
-- log.warn(`[Wiki] DATABASE_URL unset: embedded PGlite database in ${DEV_PGLITE} (development only, one process)`);
-- fs.mkdirSync(DEV_PGLITE, { recursive: true });
-- return createDb({ pglite: DEV_PGLITE, service: 'wiki', registry, log });
++ const dir = process.env.WIKI_PGLITE_DIR || DEV_PGLITE;
++ log.warn(`[Wiki] DATABASE_URL unset: embedded PGlite database in ${dir} (development only, one process)`);
++ fs.mkdirSync(dir, { recursive: true });
++ return createDb({ pglite: dir, service: 'wiki', registry, log });
}
return createDb({ url: config.db.url, service: 'wiki', registry, log });
}
ddiff --git a/test/perf-budget.test.js b/test/perf-budget.test.js
iindex d235cdf..161acf4 100644
---- a/test/perf-budget.test.js
++++ b/test/perf-budget.test.js
@@@ -4,7 +4,9 @@
// measurement; raising one is a decision to state in the commit.
// node test/perf-budget.test.js
const assert = require('assert');
++const fs = require('fs');
const net = require('net');
++const os = require('os');
const path = require('path');
const { spawn } = require('child_process');
const { measure, check, format } = require('openvibe-shared/perf-budget');
@@@ -24,14 +26,24 @@ const BUDGETS = {
const freePort = () => new Promise((resolve) => { const s = net.createServer(); s.listen(0, '127.0.0.1', () => { const { port } = s.address(); s.close(() => resolve(port)); }); });
(async () => {
++ // A fresh PGlite database of this run's own in a temp dir (server/db.js WIKI_PGLITE_DIR), never the shared
++ // data/pglite the dev server uses. DATABASE_URL/DATABASE_DIRECT_URL are cleared too, so an inherited one
++ // cannot point the child at a database other runs are using.
++ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'ov-wiki-budget-'));
const port = await freePort();
const child = spawn(process.execPath, [path.join(__dirname, '..', 'server', 'index.js')], {
cwd: path.join(__dirname, '..'),
-- env: { ...process.env, PORT: String(port), HOST: '127.0.0.1', NODE_ENV: 'test' },
++ env: {
++ ...process.env, PORT: String(port), HOST: '127.0.0.1', NODE_ENV: 'test',
++ WIKI_PGLITE_DIR: path.join(dir, 'pglite'), DATABASE_URL: '', DATABASE_DIRECT_URL: '',
++ },
stdio: ['ignore', 'ignore', 'pipe'],
});
let stderr = '';
child.stderr.on('data', (d) => { stderr = (stderr + d).slice(-2000); });
++ // Registered at spawn: a server that already crashed has exited before the finally below, and waiting on
++ // once('exit') then would never resolve (an unref'd timer does not hold the loop, so the test would end as a pass).
++ const exited = new Promise((resolve) => { child.once('exit', resolve); child.once('error', resolve); });
const base = `http://127.0.0.1:${port}`;
try {
let up = false;
@@@ -47,5 +59,10 @@ const freePort = () => new Promise((resolve) => { const s = net.createServer();
console.log('perf budget: all checks passed');
} finally {
child.kill();
++ // The server bounds its own shutdown at 10 s; wait for the real exit before removing its database.
++ let timer;
++ await Promise.race([exited, new Promise((resolve) => { timer = setTimeout(resolve, 12000); })]);
++ clearTimeout(timer);
++ fs.rmSync(dir, { recursive: true, force: true });
}
})().catch((err) => { console.error(err); process.exitCode = 1; });