openvibers/openvibe.host Commits
npm test no longer counts a skipped test as passed (roadmap WS-Q task 7; openvibe-shared/test-runner, Shared v1.25.0). test/run.js counted every file that exited 0 as passed, even one that had skipped part of its work. It is now the shared runner (same files, one at a time as before, 60 s timeout per file): a test prints "<label>: skipped (<why>)" for what it could not run, the same line scripts/release-acceptance.js reads, and that file is listed with ○ and its reasons and not counted as passed; --strict makes a skip fail the run. announce.test.js skipped its payload schema check without a word when the installed openvibe-contracts predates host.release.published@1; it now prints "announce payload schema: skipped (…)" then (the pinned 0.66.0 has the schema, so the check runs here). openvibe-shared is pinned at v1.25.0 (from v1.22.0; 1.23 and 1.24 add the web runtime, release-watch fixes and the readiness skip, and /api/ready answers as before because its db check really runs; README and STATUS.json follow). npm test (Node 22) 38/38.
Changes
@@@ -51,7 +51,7 @@ Stage A adds a few safety rules of its own:- OpenVibe.Contracts (`openvibe-contracts` v0.66.0; `host.*` capabilities and the `host` manifest were released in v0.24.0, and v0.32.0 adds the takedown routes to `host.site.manage`): service manifests (vhost rendering, snapshots, the first-party domain list), ids, problem+json, service-token verification, capability checks.- OpenVibe.Network (Stage B): SSO for the dashboard, the JWKS that verifies user and service tokens, client-credentials tokens for the outbox relay.- OpenVibe.Events (Stage B): `host.*` events through the `openvibe-sdk` v0.12.0 transactional outbox (openvibe-sdk/limits for the per-actor limits).--- `openvibe-shared` v1.22.0 (Stage B): shared chrome, legal pages, `/release.json`, `/metrics`, `/api/ready`.++- `openvibe-shared` v1.25.0 (Stage B): shared chrome, legal pages, `/release.json`, `/metrics`, `/api/ready`.- OpenVibe.Media: not yet. The roadmap stores artifacts "through Media where practical"; Stage B keeps them on local disk for now (see [Not done yet](#not-done-yet-stage-b)).## Capabilities@@@ -9,7 +9,7 @@"domain": "openvibe.host","tenantDomain": "*.openvibe.host","contracts": "openvibe-contracts v0.66.0",-- "packages": ["openvibe-contracts v0.66.0 (host.* capabilities and manifest released in v0.24.0; v0.32.0 adds the takedown routes to host.site.manage)", "openvibe-sdk v0.12.0", "openvibe-shared v1.22.0"],++ "packages": ["openvibe-contracts v0.66.0 (host.* capabilities and manifest released in v0.24.0; v0.32.0 adds the takedown routes to host.site.manage)", "openvibe-sdk v0.12.0", "openvibe-shared v1.25.0"],"capabilities": ["host.site.manage", "host.deploy.create", "host.domain.manage"],"capabilitiesRegistered": true,"serviceManifestRegistered": "host manifest v0.2.0 released (openvibe-contracts v0.24.0+), with the four host.* events",@@@ -18,7 +18,7 @@"express-rate-limit": "^7.5.0","openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.66.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.12.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.22.0"++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.25.0"},"bin": {"ovhost": "bin/ovhost"@@@ -1437,9 +1437,9 @@}},"node_modules/openvibe-shared": {-- "version": "1.22.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.22.0",-- "integrity": "sha512-FtqbR8h6YphOnJNqklJED3HyqvTwZJl58gyiZ3QgzmZtZcA16O2NMGq67O4p7grLojwaIG5DhXDMgmZcpScxJQ==",++ "version": "1.25.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.25.0",++ "integrity": "sha512-oqZ+PvljrWi8IEbtg6bDYai17ZV2sALFx/ezMptniELSr10TgFUiGUQt+b1IWwiHv0T2Y1U2iSrkirJxMNgjSw==","license": "MIT","dependencies": {"jsonwebtoken": "^9.0.0"@@@ -33,7 +33,7 @@"express-rate-limit": "^7.5.0","openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.66.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.12.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.22.0"++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.25.0"},"engines": {"node": ">=22.0.0"@@@ -17,7 +17,7 @@ const HOST_SECRET = `${SECRET}-host`;function payloadSchemaCheck(payload) {let known = true;try { contracts.schema('host.release.published'); } catch { known = false; }-- if (!known) return;++ if (!known) { console.log(`announce payload schema: skipped (installed openvibe-contracts ${require('openvibe-contracts/package.json').version} has no host.release.published)`); return; }const v = contracts.validate('host.release.published@1', payload);assert.ok(v.valid, JSON.stringify(v.errors));}@@@ -6,51 +6,10 @@** npm test # everything* npm test -- deploy certs # only files whose name contains one of the words++ * npm test -- --strict # a skipped test fails the run too++ *++ * A test that cannot run something here prints `<label>: skipped (<why>)`: that file is listed with++ * ○ and not counted as passed (openvibe-shared/test-runner).*/'use strict';--const { spawn } = require('child_process');--const fs = require('fs');--const path = require('path');----const filters = process.argv.slice(2).filter((a) => !a.startsWith('-'));--const files = fs.readdirSync(__dirname)-- .filter((f) => f.endsWith('.test.js'))-- .filter((f) => !filters.length || filters.some((w) => f.includes(w)))-- .sort();--const TIMEOUT_MS = 60000;----function runOne(file) {-- return new Promise((resolve) => {-- const started = Date.now();-- const child = spawn(process.execPath, [path.join(__dirname, file)], {-- cwd: path.join(__dirname, '..'),-- env: { ...process.env, NODE_ENV: 'test' },-- stdio: ['ignore', 'pipe', 'pipe'],-- });-- let output = '';-- child.stdout.on('data', (c) => { output += c; });-- child.stderr.on('data', (c) => { output += c; });-- const timer = setTimeout(() => { output += `\n[run] timed out after ${TIMEOUT_MS}ms`; child.kill('SIGKILL'); }, TIMEOUT_MS);-- child.on('close', (code, signal) => {-- clearTimeout(timer);-- resolve({ file, ok: code === 0, code: code ?? signal, ms: Date.now() - started, output });-- });-- });--}----(async () => {-- if (!files.length) { console.error('no test files matched'); process.exit(1); }-- const results = [];-- for (const f of files) {-- const r = await runOne(f);-- results.push(r);-- console.log(`${r.ok ? '✓' : '✗'} ${r.file.padEnd(32)} ${String(r.ms).padStart(6)}ms`);-- }-- const failed = results.filter((r) => !r.ok);-- for (const r of failed) {-- console.log(`\n── ${r.file} (exit ${r.code}) ──`);-- console.log(r.output.split('\n').slice(-60).join('\n'));-- }-- console.log(`\n${results.length - failed.length}/${results.length} test files passed`);-- process.exit(failed.length ? 1 : 0);--})();++require('openvibe-shared/test-runner').main({ dir: __dirname, timeoutMs: 60000, pad: 32, parallel: 1 });
@@ -51,7 +51,7 @@ Stage A adds a few safety rules of its own:
@@ -51,7 +51,7 @@ Stage A adds a few safety rules of its own:
- OpenVibe.Contracts (`openvibe-contracts` v0.66.0; `host.*` capabilities and the `host` manifest were released in v0.24.0, and v0.32.0 adds the takedown routes to `host.site.manage`): service manifests (vhost rendering, snapshots, the first-party domain list), ids, problem+json, service-token verification, capability checks.
- OpenVibe.Contracts (`openvibe-contracts` v0.66.0; `host.*` capabilities and the `host` manifest were released in v0.24.0, and v0.32.0 adds the takedown routes to `host.site.manage`): service manifests (vhost rendering, snapshots, the first-party domain list), ids, problem+json, service-token verification, capability checks.
- OpenVibe.Network (Stage B): SSO for the dashboard, the JWKS that verifies user and service tokens, client-credentials tokens for the outbox relay.
- OpenVibe.Network (Stage B): SSO for the dashboard, the JWKS that verifies user and service tokens, client-credentials tokens for the outbox relay.
- OpenVibe.Events (Stage B): `host.*` events through the `openvibe-sdk` v0.12.0 transactional outbox (openvibe-sdk/limits for the per-actor limits).
- OpenVibe.Events (Stage B): `host.*` events through the `openvibe-sdk` v0.12.0 transactional outbox (openvibe-sdk/limits for the per-actor limits).
-- `openvibe-shared` v1.22.0 (Stage B): shared chrome, legal pages, `/release.json`, `/metrics`, `/api/ready`.
+- `openvibe-shared` v1.25.0 (Stage B): shared chrome, legal pages, `/release.json`, `/metrics`, `/api/ready`.
- OpenVibe.Media: not yet. The roadmap stores artifacts "through Media where practical"; Stage B keeps them on local disk for now (see [Not done yet](#not-done-yet-stage-b)).
- OpenVibe.Media: not yet. The roadmap stores artifacts "through Media where practical"; Stage B keeps them on local disk for now (see [Not done yet](#not-done-yet-stage-b)).
## Capabilities
## Capabilities
@@ -9,7 +9,7 @@
@@ -9,7 +9,7 @@
"domain": "openvibe.host",
"domain": "openvibe.host",
"tenantDomain": "*.openvibe.host",
"tenantDomain": "*.openvibe.host",
"contracts": "openvibe-contracts v0.66.0",
"contracts": "openvibe-contracts v0.66.0",
- "packages": ["openvibe-contracts v0.66.0 (host.* capabilities and manifest released in v0.24.0; v0.32.0 adds the takedown routes to host.site.manage)", "openvibe-sdk v0.12.0", "openvibe-shared v1.22.0"],
+ "packages": ["openvibe-contracts v0.66.0 (host.* capabilities and manifest released in v0.24.0; v0.32.0 adds the takedown routes to host.site.manage)", "openvibe-sdk v0.12.0", "openvibe-shared v1.25.0"],
"capabilities": ["host.site.manage", "host.deploy.create", "host.domain.manage"],
"capabilities": ["host.site.manage", "host.deploy.create", "host.domain.manage"],
"capabilitiesRegistered": true,
"capabilitiesRegistered": true,
"serviceManifestRegistered": "host manifest v0.2.0 released (openvibe-contracts v0.24.0+), with the four host.* events",
"serviceManifestRegistered": "host manifest v0.2.0 released (openvibe-contracts v0.24.0+), with the four host.* events",
@@ -18,7 +18,7 @@
@@ -18,7 +18,7 @@
"express-rate-limit": "^7.5.0",
"express-rate-limit": "^7.5.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.66.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.66.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.12.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.12.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.22.0"
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.25.0"
},
},
"bin": {
"bin": {
"ovhost": "bin/ovhost"
"ovhost": "bin/ovhost"
@@ -1437,9 +1437,9 @@
@@ -1437,9 +1437,9 @@
}
}
},
},
"node_modules/openvibe-shared": {
"node_modules/openvibe-shared": {
- "version": "1.22.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.22.0",
- "integrity": "sha512-FtqbR8h6YphOnJNqklJED3HyqvTwZJl58gyiZ3QgzmZtZcA16O2NMGq67O4p7grLojwaIG5DhXDMgmZcpScxJQ==",
+ "version": "1.25.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.25.0",
+ "integrity": "sha512-oqZ+PvljrWi8IEbtg6bDYai17ZV2sALFx/ezMptniELSr10TgFUiGUQt+b1IWwiHv0T2Y1U2iSrkirJxMNgjSw==",
"license": "MIT",
"license": "MIT",
"dependencies": {
"dependencies": {
"jsonwebtoken": "^9.0.0"
"jsonwebtoken": "^9.0.0"
@@ -33,7 +33,7 @@
@@ -33,7 +33,7 @@
"express-rate-limit": "^7.5.0",
"express-rate-limit": "^7.5.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.66.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.66.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.12.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.12.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.22.0"
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.25.0"
},
},
"engines": {
"engines": {
"node": ">=22.0.0"
"node": ">=22.0.0"
@@ -17,7 +17,7 @@ const HOST_SECRET = `${SECRET}-host`;
@@ -17,7 +17,7 @@ const HOST_SECRET = `${SECRET}-host`;
function payloadSchemaCheck(payload) {
function payloadSchemaCheck(payload) {
let known = true;
let known = true;
try { contracts.schema('host.release.published'); } catch { known = false; }
try { contracts.schema('host.release.published'); } catch { known = false; }
- if (!known) return;
+ if (!known) { console.log(`announce payload schema: skipped (installed openvibe-contracts ${require('openvibe-contracts/package.json').version} has no host.release.published)`); return; }
const v = contracts.validate('host.release.published@1', payload);
const v = contracts.validate('host.release.published@1', payload);
assert.ok(v.valid, JSON.stringify(v.errors));
assert.ok(v.valid, JSON.stringify(v.errors));
}
}
@@ -6,51 +6,10 @@
@@ -6,51 +6,10 @@
*
*
* npm test # everything
* npm test # everything
* npm test -- deploy certs # only files whose name contains one of the words
* npm test -- deploy certs # only files whose name contains one of the words
+ * npm test -- --strict # a skipped test fails the run too
+ *
+ * A test that cannot run something here prints `<label>: skipped (<why>)`: that file is listed with
+ * ○ and not counted as passed (openvibe-shared/test-runner).
*/
*/
'use strict';
'use strict';
-const { spawn } = require('child_process');
-const fs = require('fs');
-const path = require('path');
-
-const filters = process.argv.slice(2).filter((a) => !a.startsWith('-'));
-const files = fs.readdirSync(__dirname)
- .filter((f) => f.endsWith('.test.js'))
- .filter((f) => !filters.length || filters.some((w) => f.includes(w)))
- .sort();
-const TIMEOUT_MS = 60000;
-
-function runOne(file) {
- return new Promise((resolve) => {
- const started = Date.now();
- const child = spawn(process.execPath, [path.join(__dirname, file)], {
- cwd: path.join(__dirname, '..'),
- env: { ...process.env, NODE_ENV: 'test' },
- stdio: ['ignore', 'pipe', 'pipe'],
- });
- let output = '';
- child.stdout.on('data', (c) => { output += c; });
- child.stderr.on('data', (c) => { output += c; });
- const timer = setTimeout(() => { output += `\n[run] timed out after ${TIMEOUT_MS}ms`; child.kill('SIGKILL'); }, TIMEOUT_MS);
- child.on('close', (code, signal) => {
- clearTimeout(timer);
- resolve({ file, ok: code === 0, code: code ?? signal, ms: Date.now() - started, output });
- });
- });
-}
-
-(async () => {
- if (!files.length) { console.error('no test files matched'); process.exit(1); }
- const results = [];
- for (const f of files) {
- const r = await runOne(f);
- results.push(r);
- console.log(`${r.ok ? '✓' : '✗'} ${r.file.padEnd(32)} ${String(r.ms).padStart(6)}ms`);
- }
- const failed = results.filter((r) => !r.ok);
- for (const r of failed) {
- console.log(`\n── ${r.file} (exit ${r.code}) ──`);
- console.log(r.output.split('\n').slice(-60).join('\n'));
- }
- console.log(`\n${results.length - failed.length}/${results.length} test files passed`);
- process.exit(failed.length ? 1 : 0);
-})();
+require('openvibe-shared/test-runner').main({ dir: __dirname, timeoutMs: 60000, pad: 32, parallel: 1 });