Skip to content

Commit 7080c8c

Browse files
committed
add test
1 parent 3dab395 commit 7080c8c

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Flags: --expose-gc --expose-internals
2+
'use strict';
3+
4+
const common = require('../common');
5+
const assert = require('assert');
6+
const {
7+
monitorEventLoopDelay,
8+
} = require('perf_hooks');
9+
const { sleep } = require('internal/util');
10+
11+
// Validate the native option type.
12+
{
13+
[null, 'a', 1, 0, {}, []].forEach((i) => {
14+
assert.throws(
15+
() => monitorEventLoopDelay({ native: i }),
16+
{
17+
name: 'TypeError',
18+
code: 'ERR_INVALID_ARG_TYPE',
19+
}
20+
);
21+
});
22+
}
23+
24+
// When native: true, resolution validation still runs.
25+
{
26+
[-1, 0].forEach((i) => {
27+
assert.throws(
28+
() => monitorEventLoopDelay({ native: true, resolution: i }),
29+
{
30+
name: 'RangeError',
31+
code: 'ERR_OUT_OF_RANGE',
32+
}
33+
);
34+
});
35+
}
36+
37+
// Basic enable/disable API works the same as the timer-based histogram.
38+
{
39+
const histogram = monitorEventLoopDelay({ native: true });
40+
assert(histogram);
41+
assert(histogram.enable());
42+
assert(!histogram.enable());
43+
histogram.reset();
44+
assert(histogram.disable());
45+
assert(!histogram.disable());
46+
}
47+
48+
// The native histogram records busy time per event loop iteration.
49+
//
50+
// The uv_check_t fires after each I/O poll phase. Each firing computes:
51+
// busy = (now - prev_check_time) - (idle_now - prev_idle_time)
52+
// where idle is time spent blocked in the I/O poll. Blocking synchronously
53+
// in a timer callback shows up as busy time in the subsequent check.
54+
//
55+
// Trace across iterations:
56+
// Iter 1 timers: tick(1) → sleep(50ms) → schedule tick for iter 2
57+
// Iter 1 check: CheckCB fires → prev_hrtime_ was 0, so just initializes state
58+
// Iter 2 timers: tick(2) → sleep(50ms) → schedule tick for iter 3
59+
// Iter 2 check: CheckCB fires → records ~50ms of busy time (count becomes 1)
60+
// Iter 3 timers: tick(3) → disable() + assertions (count >= 1)
61+
{
62+
const histogram = monitorEventLoopDelay({ native: true });
63+
histogram.enable();
64+
65+
let ticks = 0;
66+
function tick() {
67+
if (++ticks < 3) {
68+
sleep(50);
69+
setTimeout(tick, 0);
70+
} else {
71+
histogram.disable();
72+
assert(histogram.count > 0,
73+
`Expected samples to be recorded, got count=${histogram.count}`);
74+
assert(histogram.min > 0);
75+
assert(histogram.max > 0);
76+
assert(histogram.max >= histogram.min);
77+
assert(histogram.mean > 0);
78+
assert(histogram.percentiles.size > 0);
79+
for (let n = 1; n < 100; n += 0.1) {
80+
assert(histogram.percentile(n) >= 0);
81+
}
82+
83+
histogram.reset();
84+
assert.strictEqual(histogram.min, 9223372036854776000);
85+
assert.strictEqual(histogram.max, 0);
86+
assert(Number.isNaN(histogram.stddev));
87+
assert(Number.isNaN(histogram.mean));
88+
assert.strictEqual(histogram.percentiles.size, 1);
89+
}
90+
}
91+
92+
setTimeout(common.mustCall(tick), 0);
93+
}
94+
95+
// Make sure that the histogram instances can be garbage-collected without
96+
// and not just implicitly destroyed when the Environment is torn down.
97+
process.on('exit', global.gc);

0 commit comments

Comments
 (0)