1'use strict'; 2 3const common = require('../common'); 4const assert = require('assert'); 5const { performance } = require('perf_hooks'); 6 7if (!common.isMainThread) 8 common.skip('bootstrapping workers works differently'); 9 10assert(performance); 11assert(performance.nodeTiming); 12assert.strictEqual(typeof performance.timeOrigin, 'number'); 13// Use a fairly large epsilon value, since we can only guarantee that the node 14// process started up in 15 seconds. 15assert(Math.abs(performance.timeOrigin - Date.now()) < 15000); 16 17const inited = performance.now(); 18assert(inited < 15000); 19 20{ 21 // Should work without throwing any errors 22 performance.mark('A'); 23 performance.clearMarks('A'); 24 25 performance.mark('B'); 26 performance.clearMarks(); 27} 28 29{ 30 performance.mark('A'); 31 [undefined, null, 'foo', 'initialize', 1].forEach((i) => { 32 performance.measure('test', i, 'A'); // Should not throw. 33 }); 34 35 [undefined, null, 'foo', 1].forEach((i) => { 36 assert.throws( 37 () => performance.measure('test', 'A', i), 38 { 39 code: 'ERR_INVALID_PERFORMANCE_MARK', 40 name: 'Error', 41 message: `The "${i}" performance mark has not been set` 42 }); 43 }); 44 45 performance.clearMarks(); 46} 47 48{ 49 performance.mark('A'); 50 setImmediate(() => { 51 performance.mark('B'); 52 performance.measure('foo', 'A', 'B'); 53 }); 54} 55 56assert.strictEqual(performance.nodeTiming.name, 'node'); 57assert.strictEqual(performance.nodeTiming.entryType, 'node'); 58 59const delay = 250; 60function checkNodeTiming(props) { 61 console.log(props); 62 63 for (const prop of Object.keys(props)) { 64 if (props[prop].around !== undefined) { 65 assert.strictEqual(typeof performance.nodeTiming[prop], 'number'); 66 const delta = performance.nodeTiming[prop] - props[prop].around; 67 assert( 68 Math.abs(delta) < (props[prop].delay || delay), 69 `${prop}: ${Math.abs(delta)} >= ${props[prop].delay || delay}` 70 ); 71 } else { 72 assert.strictEqual(performance.nodeTiming[prop], props[prop], 73 `mismatch for performance property ${prop}: ` + 74 `${performance.nodeTiming[prop]} vs ${props[prop]}`); 75 } 76 } 77} 78 79checkNodeTiming({ 80 name: 'node', 81 entryType: 'node', 82 startTime: 0, 83 duration: { around: performance.now() }, 84 nodeStart: { around: 0 }, 85 v8Start: { around: 0 }, 86 bootstrapComplete: { around: inited, delay: 2500 }, 87 environment: { around: 0 }, 88 loopStart: -1, 89 loopExit: -1 90}); 91 92setTimeout(() => { 93 checkNodeTiming({ 94 name: 'node', 95 entryType: 'node', 96 startTime: 0, 97 duration: { around: performance.now() }, 98 nodeStart: { around: 0 }, 99 v8Start: { around: 0 }, 100 bootstrapComplete: { around: inited, delay: 2500 }, 101 environment: { around: 0 }, 102 loopStart: { around: inited, delay: 2500 }, 103 loopExit: -1 104 }); 105}, 1000); 106 107process.on('exit', () => { 108 checkNodeTiming({ 109 name: 'node', 110 entryType: 'node', 111 startTime: 0, 112 duration: { around: performance.now() }, 113 nodeStart: { around: 0 }, 114 v8Start: { around: 0 }, 115 bootstrapComplete: { around: inited, delay: 2500 }, 116 environment: { around: 0 }, 117 loopStart: { around: inited, delay: 2500 }, 118 loopExit: { around: performance.now() } 119 }); 120}); 121