1'use strict'; 2 3const { mustCall } = require('../common'); 4 5const TIMEOUT = 10; 6const SPIN_DUR = 50; 7 8const assert = require('assert'); 9const { performance } = require('perf_hooks'); 10const { Worker, parentPort } = require('worker_threads'); 11 12const { nodeTiming, eventLoopUtilization } = performance; 13const elu = eventLoopUtilization(); 14 15// Take into account whether this test was started as a Worker. 16if (nodeTiming.loopStart === -1) { 17 assert.strictEqual(nodeTiming.idleTime, 0); 18 assert.deepStrictEqual(elu, { idle: 0, active: 0, utilization: 0 }); 19 assert.deepStrictEqual(eventLoopUtilization(elu), 20 { idle: 0, active: 0, utilization: 0 }); 21 assert.deepStrictEqual(eventLoopUtilization(elu, eventLoopUtilization()), 22 { idle: 0, active: 0, utilization: 0 }); 23} 24 25const nodeTimingProps = ['name', 'entryType', 'startTime', 'duration', 26 'nodeStart', 'v8Start', 'environment', 'loopStart', 27 'loopExit', 'bootstrapComplete', 'idleTime']; 28for (const p of nodeTimingProps) 29 assert.ok(typeof JSON.parse(JSON.stringify(nodeTiming))[p] === 30 typeof nodeTiming[p]); 31 32setTimeout(mustCall(function r() { 33 const elu1 = eventLoopUtilization(); 34 35 // Force idle time to accumulate before allowing test to continue. 36 if (elu1.idle <= 0) 37 return setTimeout(mustCall(r), 5); 38 39 const t = Date.now(); 40 while (Date.now() - t < SPIN_DUR) { } 41 42 const elu2 = eventLoopUtilization(elu1); 43 const elu3 = eventLoopUtilization(); 44 const elu4 = eventLoopUtilization(elu3, elu1); 45 46 assert.strictEqual(elu2.idle, 0); 47 assert.strictEqual(elu4.idle, 0); 48 assert.strictEqual(elu2.utilization, 1); 49 assert.strictEqual(elu4.utilization, 1); 50 assert.strictEqual(elu3.active - elu1.active, elu4.active); 51 assert.ok(elu2.active > SPIN_DUR - 10, `${elu2.active} <= ${SPIN_DUR - 10}`); 52 assert.ok(elu2.active < elu4.active, `${elu2.active} >= ${elu4.active}`); 53 assert.ok(elu3.active > elu2.active, `${elu3.active} <= ${elu2.active}`); 54 assert.ok(elu3.active > elu4.active, `${elu3.active} <= ${elu4.active}`); 55 56 setTimeout(mustCall(runIdleTimeTest), TIMEOUT); 57}), 5); 58 59function runIdleTimeTest() { 60 const idleTime = nodeTiming.idleTime; 61 const elu1 = eventLoopUtilization(); 62 const sum = elu1.idle + elu1.active; 63 64 assert.ok(sum >= elu1.idle && sum >= elu1.active, 65 `idle: ${elu1.idle} active: ${elu1.active} sum: ${sum}`); 66 assert.strictEqual(elu1.idle, idleTime); 67 assert.strictEqual(elu1.utilization, elu1.active / sum); 68 69 setTimeout(mustCall(runCalcTest), TIMEOUT, elu1); 70} 71 72function runCalcTest(elu1) { 73 const now = performance.now(); 74 const elu2 = eventLoopUtilization(); 75 const elu3 = eventLoopUtilization(elu2, elu1); 76 const active_delta = elu2.active - elu1.active; 77 const idle_delta = elu2.idle - elu1.idle; 78 79 assert.ok(elu2.idle >= 0, `${elu2.idle} < 0`); 80 assert.ok(elu2.active >= 0, `${elu2.active} < 0`); 81 assert.ok(elu3.idle >= 0, `${elu3.idle} < 0`); 82 assert.ok(elu3.active >= 0, `${elu3.active} < 0`); 83 assert.ok(elu2.idle + elu2.active > elu1.idle + elu1.active, 84 `${elu2.idle + elu2.active} <= ${elu1.idle + elu1.active}`); 85 assert.ok(elu2.idle + elu2.active >= now - nodeTiming.loopStart, 86 `${elu2.idle + elu2.active} < ${now - nodeTiming.loopStart}`); 87 assert.strictEqual(elu3.active, elu2.active - elu1.active); 88 assert.strictEqual(elu3.idle, elu2.idle - elu1.idle); 89 assert.strictEqual(elu3.utilization, 90 active_delta / (idle_delta + active_delta)); 91 92 setImmediate(mustCall(runWorkerTest)); 93} 94 95function runWorkerTest() { 96 // Use argv to detect whether we're running as a Worker called by this test 97 // vs. this test also being called as a Worker. 98 if (process.argv[2] === 'iamalive') { 99 parentPort.postMessage(JSON.stringify(eventLoopUtilization())); 100 return; 101 } 102 103 const elu1 = eventLoopUtilization(); 104 const worker = new Worker(__filename, { argv: [ 'iamalive' ] }); 105 106 worker.on('message', mustCall((msg) => { 107 const elu2 = eventLoopUtilization(elu1); 108 const data = JSON.parse(msg); 109 110 assert.ok(elu2.active + elu2.idle > data.active + data.idle, 111 `${elu2.active + elu2.idle} <= ${data.active + data.idle}`); 112 })); 113} 114