11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst { mustCall } = require('../common');
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst TIMEOUT = 10;
61cb0ef41Sopenharmony_ciconst SPIN_DUR = 50;
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ciconst assert = require('assert');
91cb0ef41Sopenharmony_ciconst { performance } = require('perf_hooks');
101cb0ef41Sopenharmony_ciconst { Worker, parentPort } = require('worker_threads');
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ciconst { nodeTiming, eventLoopUtilization } = performance;
131cb0ef41Sopenharmony_ciconst elu = eventLoopUtilization();
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci// Take into account whether this test was started as a Worker.
161cb0ef41Sopenharmony_ciif (nodeTiming.loopStart === -1) {
171cb0ef41Sopenharmony_ci  assert.strictEqual(nodeTiming.idleTime, 0);
181cb0ef41Sopenharmony_ci  assert.deepStrictEqual(elu, { idle: 0, active: 0, utilization: 0 });
191cb0ef41Sopenharmony_ci  assert.deepStrictEqual(eventLoopUtilization(elu),
201cb0ef41Sopenharmony_ci                         { idle: 0, active: 0, utilization: 0 });
211cb0ef41Sopenharmony_ci  assert.deepStrictEqual(eventLoopUtilization(elu, eventLoopUtilization()),
221cb0ef41Sopenharmony_ci                         { idle: 0, active: 0, utilization: 0 });
231cb0ef41Sopenharmony_ci}
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ciconst nodeTimingProps = ['name', 'entryType', 'startTime', 'duration',
261cb0ef41Sopenharmony_ci                         'nodeStart', 'v8Start', 'environment', 'loopStart',
271cb0ef41Sopenharmony_ci                         'loopExit', 'bootstrapComplete', 'idleTime'];
281cb0ef41Sopenharmony_cifor (const p of nodeTimingProps)
291cb0ef41Sopenharmony_ci  assert.ok(typeof JSON.parse(JSON.stringify(nodeTiming))[p] ===
301cb0ef41Sopenharmony_ci    typeof nodeTiming[p]);
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_cisetTimeout(mustCall(function r() {
331cb0ef41Sopenharmony_ci  const elu1 = eventLoopUtilization();
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  // Force idle time to accumulate before allowing test to continue.
361cb0ef41Sopenharmony_ci  if (elu1.idle <= 0)
371cb0ef41Sopenharmony_ci    return setTimeout(mustCall(r), 5);
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  const t = Date.now();
401cb0ef41Sopenharmony_ci  while (Date.now() - t < SPIN_DUR);
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  const elu2 = eventLoopUtilization(elu1);
431cb0ef41Sopenharmony_ci  const elu3 = eventLoopUtilization();
441cb0ef41Sopenharmony_ci  const elu4 = eventLoopUtilization(elu3, elu1);
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  assert.strictEqual(elu2.idle, 0);
471cb0ef41Sopenharmony_ci  assert.strictEqual(elu4.idle, 0);
481cb0ef41Sopenharmony_ci  assert.strictEqual(elu2.utilization, 1);
491cb0ef41Sopenharmony_ci  assert.strictEqual(elu4.utilization, 1);
501cb0ef41Sopenharmony_ci  assert.strictEqual(elu3.active - elu1.active, elu4.active);
511cb0ef41Sopenharmony_ci  assert.ok(elu2.active > SPIN_DUR - 10, `${elu2.active} <= ${SPIN_DUR - 10}`);
521cb0ef41Sopenharmony_ci  assert.ok(elu2.active < elu4.active, `${elu2.active} >= ${elu4.active}`);
531cb0ef41Sopenharmony_ci  assert.ok(elu3.active > elu2.active, `${elu3.active} <= ${elu2.active}`);
541cb0ef41Sopenharmony_ci  assert.ok(elu3.active > elu4.active, `${elu3.active} <= ${elu4.active}`);
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  setTimeout(mustCall(runIdleTimeTest), TIMEOUT);
571cb0ef41Sopenharmony_ci}), 5);
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_cifunction runIdleTimeTest() {
601cb0ef41Sopenharmony_ci  const idleTime = nodeTiming.idleTime;
611cb0ef41Sopenharmony_ci  const elu1 = eventLoopUtilization();
621cb0ef41Sopenharmony_ci  const sum = elu1.idle + elu1.active;
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  assert.ok(sum >= elu1.idle && sum >= elu1.active,
651cb0ef41Sopenharmony_ci            `idle: ${elu1.idle}  active: ${elu1.active}  sum: ${sum}`);
661cb0ef41Sopenharmony_ci  assert.strictEqual(elu1.idle, idleTime);
671cb0ef41Sopenharmony_ci  assert.strictEqual(elu1.utilization, elu1.active / sum);
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  setTimeout(mustCall(runCalcTest), TIMEOUT, elu1);
701cb0ef41Sopenharmony_ci}
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_cifunction runCalcTest(elu1) {
731cb0ef41Sopenharmony_ci  const now = performance.now();
741cb0ef41Sopenharmony_ci  const elu2 = eventLoopUtilization();
751cb0ef41Sopenharmony_ci  const elu3 = eventLoopUtilization(elu2, elu1);
761cb0ef41Sopenharmony_ci  const active_delta = elu2.active - elu1.active;
771cb0ef41Sopenharmony_ci  const idle_delta = elu2.idle - elu1.idle;
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci  assert.ok(elu2.idle >= 0, `${elu2.idle} < 0`);
801cb0ef41Sopenharmony_ci  assert.ok(elu2.active >= 0, `${elu2.active} < 0`);
811cb0ef41Sopenharmony_ci  assert.ok(elu3.idle >= 0, `${elu3.idle} < 0`);
821cb0ef41Sopenharmony_ci  assert.ok(elu3.active >= 0, `${elu3.active} < 0`);
831cb0ef41Sopenharmony_ci  assert.ok(elu2.idle + elu2.active > elu1.idle + elu1.active,
841cb0ef41Sopenharmony_ci            `${elu2.idle + elu2.active} <= ${elu1.idle + elu1.active}`);
851cb0ef41Sopenharmony_ci  assert.ok(elu2.idle + elu2.active >= now - nodeTiming.loopStart,
861cb0ef41Sopenharmony_ci            `${elu2.idle + elu2.active} < ${now - nodeTiming.loopStart}`);
871cb0ef41Sopenharmony_ci  assert.strictEqual(elu3.active, elu2.active - elu1.active);
881cb0ef41Sopenharmony_ci  assert.strictEqual(elu3.idle, elu2.idle - elu1.idle);
891cb0ef41Sopenharmony_ci  assert.strictEqual(elu3.utilization,
901cb0ef41Sopenharmony_ci                     active_delta / (idle_delta + active_delta));
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci  setImmediate(mustCall(runWorkerTest));
931cb0ef41Sopenharmony_ci}
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_cifunction runWorkerTest() {
961cb0ef41Sopenharmony_ci  // Use argv to detect whether we're running as a Worker called by this test
971cb0ef41Sopenharmony_ci  // vs. this test also being called as a Worker.
981cb0ef41Sopenharmony_ci  if (process.argv[2] === 'iamalive') {
991cb0ef41Sopenharmony_ci    parentPort.postMessage(JSON.stringify(eventLoopUtilization()));
1001cb0ef41Sopenharmony_ci    return;
1011cb0ef41Sopenharmony_ci  }
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci  const elu1 = eventLoopUtilization();
1041cb0ef41Sopenharmony_ci  const worker = new Worker(__filename, { argv: [ 'iamalive' ] });
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci  worker.on('message', mustCall((msg) => {
1071cb0ef41Sopenharmony_ci    const elu2 = eventLoopUtilization(elu1);
1081cb0ef41Sopenharmony_ci    const data = JSON.parse(msg);
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci    assert.ok(elu2.active + elu2.idle > data.active + data.idle,
1111cb0ef41Sopenharmony_ci              `${elu2.active + elu2.idle} <= ${data.active + data.idle}`);
1121cb0ef41Sopenharmony_ci  }));
1131cb0ef41Sopenharmony_ci}
114