openvibers/openvibe.bot Commits
Bump openvibe-shared v2.2.0 → v2.5.0 (#12)
Changes
@@@ -16,7 +16,7 @@"jsonwebtoken": "^9.0.2","openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.85.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.2.0",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.5.0","pg": "^8.23.0","ws": "^8.18.0"},@@@ -889,12 +889,15 @@}},"node_modules/openvibe-shared": {-- "version": "2.2.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.2.0",-- "integrity": "sha512-1q+iUuUxzPeylTYmithW4jR++Jccvn5GEOrB1B3D18Dgn6OXQhPpvhPQAa1D1k1p+dWIa1/SmggyJwSGFnTNtw==",++ "version": "2.5.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.5.0",++ "integrity": "sha512-fHuUS6SXM7ezatfAyqLm1V8B6puV9YXSnz6aG6XQbWx28qghRCCHeUF3lr4nxiCGdn9SyikYtIyLGL5r1ycp9Q==","license": "MIT","dependencies": {"jsonwebtoken": "^9.0.0"++ },++ "bin": {++ "openvibe-build-assets": "scripts/build-assets.js"}},"node_modules/parseurl": {@@@ -28,7 +28,7 @@"jsonwebtoken": "^9.0.2","openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.85.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.2.0",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.5.0","pg": "^8.23.0","ws": "^8.18.0"},@@@ -94,17 +94,18 @@ const { boot, check, done } = require('./helpers/app');const { robot, pairing } = await t.robot(alex, { limits: { max_command_ms: 200 } });const { dev } = await pairOverWs(robot.id, pairing.code);const op = await ownerJoined(robot.id);-- const before = Date.now() + t.clock.offset;op.send({ type: 'command', id: 'd1', kind: 'drive', value: { throttle: 1, steer: 0 }, ms: 5000 });const c1 = await dev.waitFor((m) => m.type === 'command' && m.ref === 'd1');-- const d1 = c1.deadline_ms - before;-- assert.ok(d1 > 100 && d1 <= 200 + 60, `capped to <=200 (was ${d1})`);++ // Both fields are stamped by the server, so a loaded client cannot inflate the span; a client-side++ // Date.now() would add the send/schedule delay and make this flaky on a busy machine.++ const d1 = c1.deadline_ms - c1.ts;++ assert.ok(d1 > 100 && d1 <= 200, `capped to <=200 (was ${d1})`);dev.send({ type: 'ack', id: c1.id });await op.waitFor((m) => m.type === 'command_result' && m.id === 'd1');-- const before2 = Date.now() + t.clock.offset;op.send({ type: 'command', id: 'd2', kind: 'drive', value: { throttle: 1, steer: 0 }, ms: 100 });const c2 = await dev.waitFor((m) => m.type === 'command' && m.ref === 'd2');-- assert.ok(c2.deadline_ms - before2 <= 100 + 60, `a shorter request is honoured (was ${c2.deadline_ms - before2})`);++ const d2 = c2.deadline_ms - c2.ts;++ assert.ok(d2 > 0 && d2 <= 100, `a shorter request is honoured (was ${d2})`);dev.send({ type: 'ack', id: c2.id });op.close(); dev.close();});@@@ -74,12 +74,16 @@ async function boot(opts = {}) {return { status: res.status, headers: res.headers, json, text };}++ // The test host runs many jobs at once, so a socket's connect or a small frame can be delayed by++ // seconds even when the server is healthy; wait long enough that only a real hang fails a test.++ const SOCKET_WAIT_MS = 20000;++/** A WebSocket client to /device or /control. waitFor(pred) resolves the first matching frame. */function ws(p, { headers = {} } = {}) {return new Promise((resolve, reject) => {const socket = new WebSocket(`${base.replace('http', 'ws')}${p}`, { headers });const client = { ws: socket, messages: [], ended: false, waiters: [], closeCode: null };-- const timer = setTimeout(() => reject(new Error(`ws open timeout on ${p}`)), 4000);++ const timer = setTimeout(() => reject(new Error(`ws open timeout on ${p}`)), SOCKET_WAIT_MS);socket.on('message', (raw) => {let m; try { m = JSON.parse(raw.toString()); } catch { return; }client.messages.push(m);@@@ -89,7 +93,7 @@ async function boot(opts = {}) {socket.on('error', () => { /* close follows */ });socket.on('open', () => { clearTimeout(timer); resolve(client); });client.send = (o) => socket.send(JSON.stringify(o));-- client.waitFor = (pred, ms = 4000) => new Promise((ok, fail) => {++ client.waitFor = (pred, ms = SOCKET_WAIT_MS) => new Promise((ok, fail) => {const hit = client.messages.find(pred);if (hit) return ok(hit);if (client.ended) return ok(null);@@@ -97,7 +101,7 @@ async function boot(opts = {}) {client.waiters.push(w);setTimeout(() => { client.waiters = client.waiters.filter((x) => x !== w); fail(new Error(`waitFor timed out; got ${JSON.stringify(client.messages.map((m) => m.type))}`)); }, ms).unref();});-- client.waitForClose = (ms = 4000) => new Promise((ok) => {++ client.waitForClose = (ms = SOCKET_WAIT_MS) => new Promise((ok) => {if (client.ended) return ok(client.closeCode);client.onClose = (code) => ok(code);setTimeout(() => ok(null), ms).unref();@@@ -9,4 +9,6 @@* npm test -- profiles pairing # only files whose name contains one of the words*/'use strict';--require('openvibe-shared/test-runner').main({ dir: __dirname, timeoutMs: 60000, pad: 28, parallel: 1 });++// A file's wall timeout is generous: the test host is shared with other jobs, so a healthy file can take++// several times its usual time. Files still run one at a time (parallel: 1) to keep the host's load down.++require('openvibe-shared/test-runner').main({ dir: __dirname, timeoutMs: 180000, pad: 28, parallel: 1 });
@@ -16,7 +16,7 @@
@@ -16,7 +16,7 @@
"jsonwebtoken": "^9.0.2",
"jsonwebtoken": "^9.0.2",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.85.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.85.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.2.0",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.5.0",
"pg": "^8.23.0",
"pg": "^8.23.0",
"ws": "^8.18.0"
"ws": "^8.18.0"
},
},
@@ -889,12 +889,15 @@
@@ -889,12 +889,15 @@
}
}
},
},
"node_modules/openvibe-shared": {
"node_modules/openvibe-shared": {
- "version": "2.2.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.2.0",
- "integrity": "sha512-1q+iUuUxzPeylTYmithW4jR++Jccvn5GEOrB1B3D18Dgn6OXQhPpvhPQAa1D1k1p+dWIa1/SmggyJwSGFnTNtw==",
+ "version": "2.5.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.5.0",
+ "integrity": "sha512-fHuUS6SXM7ezatfAyqLm1V8B6puV9YXSnz6aG6XQbWx28qghRCCHeUF3lr4nxiCGdn9SyikYtIyLGL5r1ycp9Q==",
"license": "MIT",
"license": "MIT",
"dependencies": {
"dependencies": {
"jsonwebtoken": "^9.0.0"
"jsonwebtoken": "^9.0.0"
+ },
+ "bin": {
+ "openvibe-build-assets": "scripts/build-assets.js"
}
}
},
},
"node_modules/parseurl": {
"node_modules/parseurl": {
@@ -28,7 +28,7 @@
@@ -28,7 +28,7 @@
"jsonwebtoken": "^9.0.2",
"jsonwebtoken": "^9.0.2",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.85.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.85.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.26.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.2.0",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v2.5.0",
"pg": "^8.23.0",
"pg": "^8.23.0",
"ws": "^8.18.0"
"ws": "^8.18.0"
},
},
@@ -94,17 +94,18 @@ const { boot, check, done } = require('./helpers/app');
@@ -94,17 +94,18 @@ const { boot, check, done } = require('./helpers/app');
const { robot, pairing } = await t.robot(alex, { limits: { max_command_ms: 200 } });
const { robot, pairing } = await t.robot(alex, { limits: { max_command_ms: 200 } });
const { dev } = await pairOverWs(robot.id, pairing.code);
const { dev } = await pairOverWs(robot.id, pairing.code);
const op = await ownerJoined(robot.id);
const op = await ownerJoined(robot.id);
- const before = Date.now() + t.clock.offset;
op.send({ type: 'command', id: 'd1', kind: 'drive', value: { throttle: 1, steer: 0 }, ms: 5000 });
op.send({ type: 'command', id: 'd1', kind: 'drive', value: { throttle: 1, steer: 0 }, ms: 5000 });
const c1 = await dev.waitFor((m) => m.type === 'command' && m.ref === 'd1');
const c1 = await dev.waitFor((m) => m.type === 'command' && m.ref === 'd1');
- const d1 = c1.deadline_ms - before;
- assert.ok(d1 > 100 && d1 <= 200 + 60, `capped to <=200 (was ${d1})`);
+ // Both fields are stamped by the server, so a loaded client cannot inflate the span; a client-side
+ // Date.now() would add the send/schedule delay and make this flaky on a busy machine.
+ const d1 = c1.deadline_ms - c1.ts;
+ assert.ok(d1 > 100 && d1 <= 200, `capped to <=200 (was ${d1})`);
dev.send({ type: 'ack', id: c1.id });
dev.send({ type: 'ack', id: c1.id });
await op.waitFor((m) => m.type === 'command_result' && m.id === 'd1');
await op.waitFor((m) => m.type === 'command_result' && m.id === 'd1');
- const before2 = Date.now() + t.clock.offset;
op.send({ type: 'command', id: 'd2', kind: 'drive', value: { throttle: 1, steer: 0 }, ms: 100 });
op.send({ type: 'command', id: 'd2', kind: 'drive', value: { throttle: 1, steer: 0 }, ms: 100 });
const c2 = await dev.waitFor((m) => m.type === 'command' && m.ref === 'd2');
const c2 = await dev.waitFor((m) => m.type === 'command' && m.ref === 'd2');
- assert.ok(c2.deadline_ms - before2 <= 100 + 60, `a shorter request is honoured (was ${c2.deadline_ms - before2})`);
+ const d2 = c2.deadline_ms - c2.ts;
+ assert.ok(d2 > 0 && d2 <= 100, `a shorter request is honoured (was ${d2})`);
dev.send({ type: 'ack', id: c2.id });
dev.send({ type: 'ack', id: c2.id });
op.close(); dev.close();
op.close(); dev.close();
});
});
@@ -74,12 +74,16 @@ async function boot(opts = {}) {
@@ -74,12 +74,16 @@ async function boot(opts = {}) {
return { status: res.status, headers: res.headers, json, text };
return { status: res.status, headers: res.headers, json, text };
}
}
+ // The test host runs many jobs at once, so a socket's connect or a small frame can be delayed by
+ // seconds even when the server is healthy; wait long enough that only a real hang fails a test.
+ const SOCKET_WAIT_MS = 20000;
+
/** A WebSocket client to /device or /control. waitFor(pred) resolves the first matching frame. */
/** A WebSocket client to /device or /control. waitFor(pred) resolves the first matching frame. */
function ws(p, { headers = {} } = {}) {
function ws(p, { headers = {} } = {}) {
return new Promise((resolve, reject) => {
return new Promise((resolve, reject) => {
const socket = new WebSocket(`${base.replace('http', 'ws')}${p}`, { headers });
const socket = new WebSocket(`${base.replace('http', 'ws')}${p}`, { headers });
const client = { ws: socket, messages: [], ended: false, waiters: [], closeCode: null };
const client = { ws: socket, messages: [], ended: false, waiters: [], closeCode: null };
- const timer = setTimeout(() => reject(new Error(`ws open timeout on ${p}`)), 4000);
+ const timer = setTimeout(() => reject(new Error(`ws open timeout on ${p}`)), SOCKET_WAIT_MS);
socket.on('message', (raw) => {
socket.on('message', (raw) => {
let m; try { m = JSON.parse(raw.toString()); } catch { return; }
let m; try { m = JSON.parse(raw.toString()); } catch { return; }
client.messages.push(m);
client.messages.push(m);
@@ -89,7 +93,7 @@ async function boot(opts = {}) {
@@ -89,7 +93,7 @@ async function boot(opts = {}) {
socket.on('error', () => { /* close follows */ });
socket.on('error', () => { /* close follows */ });
socket.on('open', () => { clearTimeout(timer); resolve(client); });
socket.on('open', () => { clearTimeout(timer); resolve(client); });
client.send = (o) => socket.send(JSON.stringify(o));
client.send = (o) => socket.send(JSON.stringify(o));
- client.waitFor = (pred, ms = 4000) => new Promise((ok, fail) => {
+ client.waitFor = (pred, ms = SOCKET_WAIT_MS) => new Promise((ok, fail) => {
const hit = client.messages.find(pred);
const hit = client.messages.find(pred);
if (hit) return ok(hit);
if (hit) return ok(hit);
if (client.ended) return ok(null);
if (client.ended) return ok(null);
@@ -97,7 +101,7 @@ async function boot(opts = {}) {
@@ -97,7 +101,7 @@ async function boot(opts = {}) {
client.waiters.push(w);
client.waiters.push(w);
setTimeout(() => { client.waiters = client.waiters.filter((x) => x !== w); fail(new Error(`waitFor timed out; got ${JSON.stringify(client.messages.map((m) => m.type))}`)); }, ms).unref();
setTimeout(() => { client.waiters = client.waiters.filter((x) => x !== w); fail(new Error(`waitFor timed out; got ${JSON.stringify(client.messages.map((m) => m.type))}`)); }, ms).unref();
});
});
- client.waitForClose = (ms = 4000) => new Promise((ok) => {
+ client.waitForClose = (ms = SOCKET_WAIT_MS) => new Promise((ok) => {
if (client.ended) return ok(client.closeCode);
if (client.ended) return ok(client.closeCode);
client.onClose = (code) => ok(code);
client.onClose = (code) => ok(code);
setTimeout(() => ok(null), ms).unref();
setTimeout(() => ok(null), ms).unref();
@@ -9,4 +9,6 @@
@@ -9,4 +9,6 @@
* npm test -- profiles pairing # only files whose name contains one of the words
* npm test -- profiles pairing # only files whose name contains one of the words
*/
*/
'use strict';
'use strict';
-require('openvibe-shared/test-runner').main({ dir: __dirname, timeoutMs: 60000, pad: 28, parallel: 1 });
+// A file's wall timeout is generous: the test host is shared with other jobs, so a healthy file can take
+// several times its usual time. Files still run one at a time (parallel: 1) to keep the host's load down.
+require('openvibe-shared/test-runner').main({ dir: __dirname, timeoutMs: 180000, pad: 28, parallel: 1 });