Skip to content

Commit c040df1

Browse files
committed
test: avoid timer race in event loop delay test
An expired timer can run before the first complete event loop iteration, disabling the histogram before it records any samples. Drive a known number of iterations with setImmediate before checking the histograms, and share the chain between resolution variants. Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com> Assisted-by: codex:gpt-5.6-sol
1 parent 9024119 commit c040df1

1 file changed

Lines changed: 38 additions & 47 deletions

File tree

test/sequential/test-performance-eventloopdelay.js

Lines changed: 38 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@ const {
99
} = require('perf_hooks');
1010
const { sleep } = require('internal/util');
1111

12+
function runEventLoopIterations(iterations, callback) {
13+
let remaining = iterations;
14+
function tick() {
15+
if (--remaining > 0) {
16+
setImmediate(tick);
17+
} else {
18+
callback();
19+
}
20+
}
21+
setImmediate(tick);
22+
}
23+
1224
{
1325
const histogram = monitorEventLoopDelay();
1426
assert(histogram);
@@ -125,12 +137,16 @@ const { sleep } = require('internal/util');
125137
}
126138

127139
{
140+
const iterations = 10;
128141
const histogram = monitorEventLoopDelay({ samplePerIteration: true });
129142
histogram.enable();
130-
setTimeout(common.mustCall(() => {
143+
runEventLoopIterations(iterations, common.mustCall(() => {
131144
histogram.disable();
132-
assert(histogram.count > 0,
133-
`Expected samples to be recorded, got count=${histogram.count}`);
145+
assert(
146+
histogram.count >= iterations - 1,
147+
`Expected at least ${iterations - 1} samples for ${iterations} iterations, ` +
148+
`got ${histogram.count}`
149+
);
134150
assert(histogram.min > 0);
135151
assert(histogram.max > 0);
136152
assert(histogram.mean > 0);
@@ -146,7 +162,7 @@ const { sleep } = require('internal/util');
146162
assert(Number.isNaN(histogram.mean));
147163
assert(Number.isNaN(histogram.stddev));
148164
assert.strictEqual(histogram.percentiles.size, 1);
149-
}), common.platformTimeout(20));
165+
}));
150166
}
151167

152168
{
@@ -158,65 +174,40 @@ const { sleep } = require('internal/util');
158174
assert.strictEqual(histogram.disable(), false); // Already disabled, no-op
159175
// Re-enabling after disable should work
160176
assert.strictEqual(histogram.enable(), true);
161-
setTimeout(common.mustCall(() => {
177+
runEventLoopIterations(10, common.mustCall(() => {
162178
histogram.disable();
163179
assert(histogram.count > 0,
164180
`Expected samples after re-enable, got count=${histogram.count}`);
165-
}), common.platformTimeout(20));
181+
}));
166182
}
167183

168184
{
169185
// Verify that samplePerIteration records exactly one sample per event loop iteration.
170-
const N = 10;
186+
// It should do so independently of the timer resolution used by the legacy
187+
// monitorEventLoopDelay path.
188+
const iterations = 10;
171189
const histogram = monitorEventLoopDelay({ samplePerIteration: true });
172-
histogram.enable();
173-
174-
let iterations = 0;
175-
const verify = common.mustCall(() => {
176-
histogram.disable();
177-
assert(
178-
histogram.count >= N - 1,
179-
`Expected at least ${N - 1} samples for ${N} iterations, got ${histogram.count}`
180-
);
181-
});
182-
183-
function tick() {
184-
if (++iterations < N) {
185-
setImmediate(tick);
186-
} else {
187-
verify();
188-
}
189-
}
190-
setImmediate(tick);
191-
}
192-
193-
{
194-
// samplePerIteration should sample per event loop iteration, independent of
195-
// the timer resolution used by the legacy monitorEventLoopDelay path.
196-
const N = 10;
197-
const histogram = monitorEventLoopDelay({
190+
const largeResolutionHistogram = monitorEventLoopDelay({
198191
samplePerIteration: true,
199192
resolution: 60 * 1000,
200193
});
201194
histogram.enable();
195+
largeResolutionHistogram.enable();
202196

203-
let iterations = 0;
204-
const verify = common.mustCall(() => {
197+
runEventLoopIterations(iterations, common.mustCall(() => {
205198
histogram.disable();
199+
largeResolutionHistogram.disable();
206200
assert(
207-
histogram.count >= N - 1,
208-
`Expected samples despite large resolution, got count=${histogram.count}`
201+
histogram.count >= iterations - 1,
202+
`Expected at least ${iterations - 1} samples for ${iterations} iterations, ` +
203+
`got ${histogram.count}`
209204
);
210-
});
211-
212-
function tick() {
213-
if (++iterations < N) {
214-
setImmediate(tick);
215-
} else {
216-
verify();
217-
}
218-
}
219-
setImmediate(tick);
205+
assert(
206+
largeResolutionHistogram.count >= iterations - 1,
207+
`Expected samples despite large resolution, ` +
208+
`got count=${largeResolutionHistogram.count}`
209+
);
210+
}));
220211
}
221212

222213
// Make sure that the histogram instances can be garbage-collected without

0 commit comments

Comments
 (0)