|
3 | 3 |
|
4 | 4 | const common = require('../common'); |
5 | 5 | const assert = require('assert'); |
6 | | -const os = require('os'); |
7 | 6 | const { |
8 | 7 | monitorEventLoopDelay, |
9 | 8 | } = require('perf_hooks'); |
@@ -52,59 +51,77 @@ const { sleep } = require('internal/util'); |
52 | 51 | } |
53 | 52 |
|
54 | 53 | { |
55 | | - const s390x = os.arch() === 's390x'; |
56 | 54 | const histogram = monitorEventLoopDelay({ resolution: 1 }); |
57 | 55 | histogram.enable(); |
58 | | - let m = 5; |
59 | | - if (s390x) { |
60 | | - m = m * 2; |
| 56 | + |
| 57 | + // Check if histogram has recorded valid samples (min > 0 indicates real delays measured) |
| 58 | + function hasValidSamples() { |
| 59 | + return histogram.count > 0 && histogram.min > 0 && histogram.max > 0; |
61 | 60 | } |
| 61 | + |
| 62 | + // Spin the event loop with blocking work to generate measurable delays. |
| 63 | + // Some configurations (s390x, sharedlibs) need more iterations. |
| 64 | + let spinsRemaining = 5; |
| 65 | + const maxRetries = 3; |
| 66 | + let retries = 0; |
| 67 | + |
62 | 68 | function spinAWhile() { |
63 | 69 | sleep(1000); |
64 | | - if (--m > 0) { |
| 70 | + if (--spinsRemaining > 0) { |
65 | 71 | setTimeout(spinAWhile, common.platformTimeout(500)); |
66 | 72 | } else { |
67 | | - // Give the histogram a chance to record final samples before disabling. |
68 | | - // This helps on slower systems where sampling may be delayed. |
69 | | - setImmediate(common.mustCall(() => { |
70 | | - histogram.disable(); |
71 | | - // The values are non-deterministic, so we just check that a value is |
72 | | - // present, as opposed to a specific value. |
73 | | - assert(histogram.count > 0, `Expected samples to be recorded, got count=${histogram.count}`); |
74 | | - assert(histogram.min > 0); |
75 | | - assert(histogram.max > 0); |
76 | | - assert(histogram.stddev > 0); |
77 | | - assert(histogram.mean > 0); |
78 | | - assert(histogram.percentiles.size > 0); |
79 | | - for (let n = 1; n < 100; n = n + 0.1) { |
80 | | - assert(histogram.percentile(n) >= 0); |
| 73 | + // Give the histogram a chance to record final samples before checking. |
| 74 | + setImmediate(() => { |
| 75 | + // If we don't have valid samples yet, retry with more spinning. |
| 76 | + // This handles slower configurations like sharedlibs builds. |
| 77 | + if (!hasValidSamples() && retries < maxRetries) { |
| 78 | + retries++; |
| 79 | + spinsRemaining = 5; |
| 80 | + setTimeout(spinAWhile, common.platformTimeout(500)); |
| 81 | + return; |
81 | 82 | } |
82 | | - histogram.reset(); |
83 | | - assert.strictEqual(histogram.min, 9223372036854776000); |
84 | | - assert.strictEqual(histogram.max, 0); |
85 | | - assert(Number.isNaN(histogram.stddev)); |
86 | | - assert(Number.isNaN(histogram.mean)); |
87 | | - assert.strictEqual(histogram.percentiles.size, 1); |
88 | 83 |
|
89 | | - ['a', false, {}, []].forEach((i) => { |
90 | | - assert.throws( |
91 | | - () => histogram.percentile(i), |
92 | | - { |
93 | | - name: 'TypeError', |
94 | | - code: 'ERR_INVALID_ARG_TYPE', |
95 | | - } |
96 | | - ); |
97 | | - }); |
98 | | - [-1, 0, 101, NaN].forEach((i) => { |
99 | | - assert.throws( |
100 | | - () => histogram.percentile(i), |
101 | | - { |
102 | | - name: 'RangeError', |
103 | | - code: 'ERR_OUT_OF_RANGE', |
104 | | - } |
105 | | - ); |
106 | | - }); |
107 | | - })); |
| 84 | + // Wrap final assertions in mustCall to ensure they run |
| 85 | + common.mustCall(() => { |
| 86 | + histogram.disable(); |
| 87 | + // The values are non-deterministic, so we just check that a value is |
| 88 | + // present, as opposed to a specific value. |
| 89 | + assert(histogram.count > 0, `Expected samples to be recorded, got count=${histogram.count}`); |
| 90 | + assert(histogram.min > 0, `Expected min > 0, got ${histogram.min}`); |
| 91 | + assert(histogram.max > 0); |
| 92 | + assert(histogram.stddev > 0); |
| 93 | + assert(histogram.mean > 0); |
| 94 | + assert(histogram.percentiles.size > 0); |
| 95 | + for (let n = 1; n < 100; n = n + 0.1) { |
| 96 | + assert(histogram.percentile(n) >= 0); |
| 97 | + } |
| 98 | + histogram.reset(); |
| 99 | + assert.strictEqual(histogram.min, 9223372036854776000); |
| 100 | + assert.strictEqual(histogram.max, 0); |
| 101 | + assert(Number.isNaN(histogram.stddev)); |
| 102 | + assert(Number.isNaN(histogram.mean)); |
| 103 | + assert.strictEqual(histogram.percentiles.size, 1); |
| 104 | + |
| 105 | + ['a', false, {}, []].forEach((i) => { |
| 106 | + assert.throws( |
| 107 | + () => histogram.percentile(i), |
| 108 | + { |
| 109 | + name: 'TypeError', |
| 110 | + code: 'ERR_INVALID_ARG_TYPE', |
| 111 | + } |
| 112 | + ); |
| 113 | + }); |
| 114 | + [-1, 0, 101, NaN].forEach((i) => { |
| 115 | + assert.throws( |
| 116 | + () => histogram.percentile(i), |
| 117 | + { |
| 118 | + name: 'RangeError', |
| 119 | + code: 'ERR_OUT_OF_RANGE', |
| 120 | + } |
| 121 | + ); |
| 122 | + }); |
| 123 | + })(); |
| 124 | + }); |
108 | 125 | } |
109 | 126 | } |
110 | 127 | spinAWhile(); |
|
0 commit comments