From c44ceeec78eb24d85f95e7cbc79381fda6a742a1 Mon Sep 17 00:00:00 2001 From: Minggang Wang Date: Mon, 29 Jun 2026 16:12:45 +0800 Subject: [PATCH 1/3] [Test] Stabilize message-translator tests on Node.js 26.4 --- test/test-message-translator-complex.js | 6 ++++++ test/test-message-translator-primitive.js | 26 +++++++++++++++++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/test/test-message-translator-complex.js b/test/test-message-translator-complex.js index 69e10745..32c6cfb3 100644 --- a/test/test-message-translator-complex.js +++ b/test/test-message-translator-complex.js @@ -209,8 +209,10 @@ describe('Rclnodejs message translation: complex types', function () { const MessageType = testData.pkg + '/msg/' + testData.type; const publisher = node.createPublisher(MessageType, topic); return new Promise((resolve, reject) => { + let timer; const sub = node.createSubscription(MessageType, topic, (value) => { if (deepEqual(value, v)) { + clearInterval(timer); node.destroy(); resolve(); } else { @@ -219,6 +221,10 @@ describe('Rclnodejs message translation: complex types', function () { reject('case ' + i + '. Expected: ' + v + ', Got: ' + value); } }); + // Keep republishing until the subscription is matched and the + // message is received; a single publish can be lost while pub/sub + // discovery is still in progress. + timer = setInterval(() => publisher.publish(v), 100); publisher.publish(v); rclnodejs.spin(node); }); diff --git a/test/test-message-translator-primitive.js b/test/test-message-translator-primitive.js index 1163c3f4..816f91b2 100644 --- a/test/test-message-translator-primitive.js +++ b/test/test-message-translator-primitive.js @@ -94,18 +94,22 @@ describe('Rclnodejs message translation: primitive types', function () { const MessageType = 'std_msgs/msg/' + testData.type; const publisher = node.createPublisher(MessageType, topic); return new Promise((resolve, reject) => { + let timer; const sub = node.createSubscription(MessageType, topic, (value) => { // For primitive types, msgs are defined as a single `.data` field if (value.data === v) { + clearInterval(timer); node.destroy(); resolve(); } else { + clearInterval(timer); node.destroy(); reject( 'case ' + i + '. Expected: ' + v + ', Got: ' + value.data ); } }); + timer = setInterval(() => publisher.publish(v), 100); publisher.publish(v); // Short-cut form of publishing primitive types rclnodejs.spin(node); }); @@ -119,18 +123,22 @@ describe('Rclnodejs message translation: primitive types', function () { const MessageType = 'std_msgs/msg/' + testData.type; const publisher = node.createPublisher(MessageType, topic); return new Promise((resolve, reject) => { + let timer; const sub = node.createSubscription(MessageType, topic, (value) => { // For primitive types, msgs are defined as a single `.data` field if (value.data === v) { + clearInterval(timer); node.destroy(); resolve(); } else { + clearInterval(timer); node.destroy(); reject( 'case ' + i + '. Expected: ' + v + ', Got: ' + value.data ); } }); + timer = setInterval(() => publisher.publish({ data: v }), 100); publisher.publish({ data: v }); // Ensure the original form of the message can be used rclnodejs.spin(node); }); @@ -221,6 +229,7 @@ describe('Rclnodejs message translation: primitive types array', function () { const MessageType = 'std_msgs/msg/' + testData.type; const publisher = node.createPublisher(MessageType, topic); return new Promise((resolve, reject) => { + let timer; const sub = node.createSubscription(MessageType, topic, (value) => { // For primitive types, msgs are defined as a single `.data` field if ( @@ -228,20 +237,24 @@ describe('Rclnodejs message translation: primitive types array', function () { deepEqual(Array.from(value.data), testData.values)) || deepEqual(value.data, testData.values) ) { + clearInterval(timer); node.destroy(); resolve(); } else { + clearInterval(timer); node.destroy(); reject('Expected: ' + testData.values + ', Got: ' + value.data); } }); - publisher.publish({ + const msg = { layout: { dim: [{ label: 'length', size: 0, stride: 0 }], data_offset: 0, }, data: testData.values, - }); + }; + timer = setInterval(() => publisher.publish(msg), 100); + publisher.publish(msg); rclnodejs.spin(node); }); } @@ -478,6 +491,7 @@ describe('Rclnodejs message translation: TypedArray large data', function () { const MessageType = 'std_msgs/msg/' + testData.type; const publisher = node.createPublisher(MessageType, topic); return new Promise((resolve, reject) => { + let timer; const sub = node.createSubscription(MessageType, topic, (value) => { // For primitive types, msgs are defined as a single `.data` field if ( @@ -485,9 +499,11 @@ describe('Rclnodejs message translation: TypedArray large data', function () { deepEqual(Array.from(value.data), testData.values)) || deepEqual(value.data, testData.values) ) { + clearInterval(timer); node.destroy(); resolve(); } else { + clearInterval(timer); node.destroy(); reject( 'Expected: ' + @@ -497,13 +513,15 @@ describe('Rclnodejs message translation: TypedArray large data', function () { ); } }); - publisher.publish({ + const msg = { layout: { dim: [{ label: 'length', size: 0, stride: 0 }], data_offset: 0, }, data: testData.values, - }); + }; + timer = setInterval(() => publisher.publish(msg), 100); + publisher.publish(msg); rclnodejs.spin(node); }); } From 70e530916dd270148b9acc71ba3e34e6544b0353 Mon Sep 17 00:00:00 2001 From: Minggang Wang Date: Mon, 29 Jun 2026 16:26:26 +0800 Subject: [PATCH 2/3] Address comments --- test/test-message-translator-complex.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test-message-translator-complex.js b/test/test-message-translator-complex.js index 32c6cfb3..61038b11 100644 --- a/test/test-message-translator-complex.js +++ b/test/test-message-translator-complex.js @@ -216,6 +216,8 @@ describe('Rclnodejs message translation: complex types', function () { node.destroy(); resolve(); } else { + clearInterval(timer); + node.destroy(); console.log('got', value); console.log('expected', v); reject('case ' + i + '. Expected: ' + v + ', Got: ' + value); From da8a308eab7b10756edcb71455d8d1307ce05bbc Mon Sep 17 00:00:00 2001 From: Minggang Wang Date: Mon, 29 Jun 2026 16:42:59 +0800 Subject: [PATCH 3/3] Address comments --- test/test-message-translator-complex.js | 11 +++++- test/test-message-translator-primitive.js | 44 ++++++++++++++++++++--- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/test/test-message-translator-complex.js b/test/test-message-translator-complex.js index 61038b11..b688f92d 100644 --- a/test/test-message-translator-complex.js +++ b/test/test-message-translator-complex.js @@ -226,7 +226,16 @@ describe('Rclnodejs message translation: complex types', function () { // Keep republishing until the subscription is matched and the // message is received; a single publish can be lost while pub/sub // discovery is still in progress. - timer = setInterval(() => publisher.publish(v), 100); + const start = Date.now(); + timer = setInterval(() => { + if (Date.now() - start > 55 * 1000) { + clearInterval(timer); + node.destroy(); + reject('Timed out waiting for message'); + return; + } + publisher.publish(v); + }, 100); publisher.publish(v); rclnodejs.spin(node); }); diff --git a/test/test-message-translator-primitive.js b/test/test-message-translator-primitive.js index 816f91b2..7a3932ab 100644 --- a/test/test-message-translator-primitive.js +++ b/test/test-message-translator-primitive.js @@ -109,7 +109,16 @@ describe('Rclnodejs message translation: primitive types', function () { ); } }); - timer = setInterval(() => publisher.publish(v), 100); + const start = Date.now(); + timer = setInterval(() => { + if (Date.now() - start > 55 * 1000) { + clearInterval(timer); + node.destroy(); + reject('Timed out waiting for message'); + return; + } + publisher.publish(v); + }, 100); publisher.publish(v); // Short-cut form of publishing primitive types rclnodejs.spin(node); }); @@ -138,7 +147,16 @@ describe('Rclnodejs message translation: primitive types', function () { ); } }); - timer = setInterval(() => publisher.publish({ data: v }), 100); + const start = Date.now(); + timer = setInterval(() => { + if (Date.now() - start > 55 * 1000) { + clearInterval(timer); + node.destroy(); + reject('Timed out waiting for message'); + return; + } + publisher.publish({ data: v }); + }, 100); publisher.publish({ data: v }); // Ensure the original form of the message can be used rclnodejs.spin(node); }); @@ -253,7 +271,16 @@ describe('Rclnodejs message translation: primitive types array', function () { }, data: testData.values, }; - timer = setInterval(() => publisher.publish(msg), 100); + const start = Date.now(); + timer = setInterval(() => { + if (Date.now() - start > 55 * 1000) { + clearInterval(timer); + node.destroy(); + reject('Timed out waiting for message'); + return; + } + publisher.publish(msg); + }, 100); publisher.publish(msg); rclnodejs.spin(node); }); @@ -520,7 +547,16 @@ describe('Rclnodejs message translation: TypedArray large data', function () { }, data: testData.values, }; - timer = setInterval(() => publisher.publish(msg), 100); + const start = Date.now(); + timer = setInterval(() => { + if (Date.now() - start > 55 * 1000) { + clearInterval(timer); + node.destroy(); + reject('Timed out waiting for message'); + return; + } + publisher.publish(msg); + }, 100); publisher.publish(msg); rclnodejs.spin(node); });