Skip to content

Commit df5044f

Browse files
authored
[Test] Stabilize message-translator tests on Node.js 26.4 (#1555)
The complex/primitive message-translator tests created a publisher and subscriber on one topic, published a single message, then spun. With volatile QoS that lone sample is only delivered if pub/sub discovery completes within the first DDS announcement window; when that window is missed, matching only recovers on the next full announcement cycle (~30s per case), making the CI suite appear to hang. Republish on a 100ms interval until the subscription receives the message, bounded to 55s so the timer self-cleans before the Mocha timeout, and clear the interval + destroy the node on both the success and failure paths. Fix: #1556
1 parent a6af64d commit df5044f

2 files changed

Lines changed: 75 additions & 4 deletions

File tree

test/test-message-translator-complex.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,16 +209,33 @@ describe('Rclnodejs message translation: complex types', function () {
209209
const MessageType = testData.pkg + '/msg/' + testData.type;
210210
const publisher = node.createPublisher(MessageType, topic);
211211
return new Promise((resolve, reject) => {
212+
let timer;
212213
const sub = node.createSubscription(MessageType, topic, (value) => {
213214
if (deepEqual(value, v)) {
215+
clearInterval(timer);
214216
node.destroy();
215217
resolve();
216218
} else {
219+
clearInterval(timer);
220+
node.destroy();
217221
console.log('got', value);
218222
console.log('expected', v);
219223
reject('case ' + i + '. Expected: ' + v + ', Got: ' + value);
220224
}
221225
});
226+
// Keep republishing until the subscription is matched and the
227+
// message is received; a single publish can be lost while pub/sub
228+
// discovery is still in progress.
229+
const start = Date.now();
230+
timer = setInterval(() => {
231+
if (Date.now() - start > 55 * 1000) {
232+
clearInterval(timer);
233+
node.destroy();
234+
reject('Timed out waiting for message');
235+
return;
236+
}
237+
publisher.publish(v);
238+
}, 100);
222239
publisher.publish(v);
223240
rclnodejs.spin(node);
224241
});

test/test-message-translator-primitive.js

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,18 +94,31 @@ describe('Rclnodejs message translation: primitive types', function () {
9494
const MessageType = 'std_msgs/msg/' + testData.type;
9595
const publisher = node.createPublisher(MessageType, topic);
9696
return new Promise((resolve, reject) => {
97+
let timer;
9798
const sub = node.createSubscription(MessageType, topic, (value) => {
9899
// For primitive types, msgs are defined as a single `.data` field
99100
if (value.data === v) {
101+
clearInterval(timer);
100102
node.destroy();
101103
resolve();
102104
} else {
105+
clearInterval(timer);
103106
node.destroy();
104107
reject(
105108
'case ' + i + '. Expected: ' + v + ', Got: ' + value.data
106109
);
107110
}
108111
});
112+
const start = Date.now();
113+
timer = setInterval(() => {
114+
if (Date.now() - start > 55 * 1000) {
115+
clearInterval(timer);
116+
node.destroy();
117+
reject('Timed out waiting for message');
118+
return;
119+
}
120+
publisher.publish(v);
121+
}, 100);
109122
publisher.publish(v); // Short-cut form of publishing primitive types
110123
rclnodejs.spin(node);
111124
});
@@ -119,18 +132,31 @@ describe('Rclnodejs message translation: primitive types', function () {
119132
const MessageType = 'std_msgs/msg/' + testData.type;
120133
const publisher = node.createPublisher(MessageType, topic);
121134
return new Promise((resolve, reject) => {
135+
let timer;
122136
const sub = node.createSubscription(MessageType, topic, (value) => {
123137
// For primitive types, msgs are defined as a single `.data` field
124138
if (value.data === v) {
139+
clearInterval(timer);
125140
node.destroy();
126141
resolve();
127142
} else {
143+
clearInterval(timer);
128144
node.destroy();
129145
reject(
130146
'case ' + i + '. Expected: ' + v + ', Got: ' + value.data
131147
);
132148
}
133149
});
150+
const start = Date.now();
151+
timer = setInterval(() => {
152+
if (Date.now() - start > 55 * 1000) {
153+
clearInterval(timer);
154+
node.destroy();
155+
reject('Timed out waiting for message');
156+
return;
157+
}
158+
publisher.publish({ data: v });
159+
}, 100);
134160
publisher.publish({ data: v }); // Ensure the original form of the message can be used
135161
rclnodejs.spin(node);
136162
});
@@ -221,27 +247,41 @@ describe('Rclnodejs message translation: primitive types array', function () {
221247
const MessageType = 'std_msgs/msg/' + testData.type;
222248
const publisher = node.createPublisher(MessageType, topic);
223249
return new Promise((resolve, reject) => {
250+
let timer;
224251
const sub = node.createSubscription(MessageType, topic, (value) => {
225252
// For primitive types, msgs are defined as a single `.data` field
226253
if (
227254
(isTypedArray(value.data) &&
228255
deepEqual(Array.from(value.data), testData.values)) ||
229256
deepEqual(value.data, testData.values)
230257
) {
258+
clearInterval(timer);
231259
node.destroy();
232260
resolve();
233261
} else {
262+
clearInterval(timer);
234263
node.destroy();
235264
reject('Expected: ' + testData.values + ', Got: ' + value.data);
236265
}
237266
});
238-
publisher.publish({
267+
const msg = {
239268
layout: {
240269
dim: [{ label: 'length', size: 0, stride: 0 }],
241270
data_offset: 0,
242271
},
243272
data: testData.values,
244-
});
273+
};
274+
const start = Date.now();
275+
timer = setInterval(() => {
276+
if (Date.now() - start > 55 * 1000) {
277+
clearInterval(timer);
278+
node.destroy();
279+
reject('Timed out waiting for message');
280+
return;
281+
}
282+
publisher.publish(msg);
283+
}, 100);
284+
publisher.publish(msg);
245285
rclnodejs.spin(node);
246286
});
247287
}
@@ -478,16 +518,19 @@ describe('Rclnodejs message translation: TypedArray large data', function () {
478518
const MessageType = 'std_msgs/msg/' + testData.type;
479519
const publisher = node.createPublisher(MessageType, topic);
480520
return new Promise((resolve, reject) => {
521+
let timer;
481522
const sub = node.createSubscription(MessageType, topic, (value) => {
482523
// For primitive types, msgs are defined as a single `.data` field
483524
if (
484525
(isTypedArray(value.data) &&
485526
deepEqual(Array.from(value.data), testData.values)) ||
486527
deepEqual(value.data, testData.values)
487528
) {
529+
clearInterval(timer);
488530
node.destroy();
489531
resolve();
490532
} else {
533+
clearInterval(timer);
491534
node.destroy();
492535
reject(
493536
'Expected: ' +
@@ -497,13 +540,24 @@ describe('Rclnodejs message translation: TypedArray large data', function () {
497540
);
498541
}
499542
});
500-
publisher.publish({
543+
const msg = {
501544
layout: {
502545
dim: [{ label: 'length', size: 0, stride: 0 }],
503546
data_offset: 0,
504547
},
505548
data: testData.values,
506-
});
549+
};
550+
const start = Date.now();
551+
timer = setInterval(() => {
552+
if (Date.now() - start > 55 * 1000) {
553+
clearInterval(timer);
554+
node.destroy();
555+
reject('Timed out waiting for message');
556+
return;
557+
}
558+
publisher.publish(msg);
559+
}, 100);
560+
publisher.publish(msg);
507561
rclnodejs.spin(node);
508562
});
509563
}

0 commit comments

Comments
 (0)