1// Flags: --expose-internals 2'use strict'; 3 4const common = require('../common'); 5const Countdown = require('../common/countdown'); 6const assert = require('assert'); 7const { inspect } = require('util'); 8const { internalBinding } = require('internal/test/binding'); 9const { 10 observerCounts: counts 11} = internalBinding('performance'); 12const { 13 performance, 14 PerformanceObserver, 15 constants 16} = require('perf_hooks'); 17 18const { 19 NODE_PERFORMANCE_ENTRY_TYPE_NODE, 20 NODE_PERFORMANCE_ENTRY_TYPE_MARK, 21 NODE_PERFORMANCE_ENTRY_TYPE_MEASURE, 22 NODE_PERFORMANCE_ENTRY_TYPE_GC, 23 NODE_PERFORMANCE_ENTRY_TYPE_FUNCTION, 24} = constants; 25 26assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_NODE], 0); 27assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_MARK], 0); 28assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_MEASURE], 0); 29assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_GC], 0); 30assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_FUNCTION], 0); 31 32{ 33 [1, null, undefined, {}, [], Infinity].forEach((i) => { 34 assert.throws( 35 () => new PerformanceObserver(i), 36 { 37 code: 'ERR_INVALID_CALLBACK', 38 name: 'TypeError', 39 message: `Callback must be a function. Received ${inspect(i)}` 40 } 41 ); 42 }); 43 const observer = new PerformanceObserver(common.mustNotCall()); 44 45 [1, null, undefined].forEach((input) => { 46 assert.throws( 47 () => observer.observe(input), 48 { 49 code: 'ERR_INVALID_ARG_TYPE', 50 name: 'TypeError', 51 message: 'The "options" argument must be of type object.' + 52 common.invalidArgTypeHelper(input) 53 }); 54 }); 55 56 [1, undefined, null, {}, Infinity].forEach((i) => { 57 assert.throws(() => observer.observe({ entryTypes: i }), 58 { 59 code: 'ERR_INVALID_OPT_VALUE', 60 name: 'TypeError', 61 message: `The value "${inspect(i)}" is invalid ` + 62 'for option "entryTypes"' 63 }); 64 }); 65 66 const obs = new PerformanceObserver(common.mustNotCall()); 67 obs.observe({ entryTypes: ['mark', 'mark'] }); 68 obs.disconnect(); 69 performance.mark('42'); 70 assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_MARK], 0); 71} 72 73// Test Non-Buffered 74{ 75 const observer = 76 new PerformanceObserver(common.mustCall(callback, 3)); 77 78 const countdown = 79 new Countdown(3, () => { 80 observer.disconnect(); 81 assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_MARK], 0); 82 }); 83 84 function callback(list, obs) { 85 assert.strictEqual(obs, observer); 86 const entries = list.getEntries(); 87 assert.strictEqual(entries.length, 1); 88 countdown.dec(); 89 } 90 assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_MARK], 0); 91 assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_NODE], 0); 92 observer.observe({ entryTypes: ['mark', 'node'] }); 93 assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_MARK], 1); 94 assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_NODE], 1); 95 performance.mark('test1'); 96 performance.mark('test2'); 97 performance.mark('test3'); 98} 99 100 101// Test Buffered 102{ 103 const observer = 104 new PerformanceObserver(common.mustCall(callback, 1)); 105 assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_MARK], 0); 106 107 function callback(list, obs) { 108 assert.strictEqual(obs, observer); 109 const entries = list.getEntries(); 110 assert.strictEqual(entries.length, 3); 111 observer.disconnect(); 112 assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_MARK], 0); 113 114 { 115 const entriesByName = list.getEntriesByName('test1'); 116 assert.strictEqual(entriesByName.length, 1); 117 assert.strictEqual(entriesByName[0].name, 'test1'); 118 assert.strictEqual(entriesByName[0].entryType, 'mark'); 119 } 120 121 { 122 const entriesByName = list.getEntriesByName('test1', 'mark'); 123 assert.strictEqual(entriesByName.length, 1); 124 assert.strictEqual(entriesByName[0].name, 'test1'); 125 assert.strictEqual(entriesByName[0].entryType, 'mark'); 126 } 127 128 { 129 const entriesByName = list.getEntriesByName('test1', 'measure'); 130 assert.strictEqual(entriesByName.length, 0); 131 } 132 133 { 134 const entriesByType = list.getEntriesByType('measure'); 135 assert.strictEqual(entriesByType.length, 1); 136 assert.strictEqual(entriesByType[0].name, 'test3'); 137 assert.strictEqual(entriesByType[0].entryType, 'measure'); 138 } 139 } 140 141 observer.observe({ entryTypes: ['mark', 'measure'], buffered: true }); 142 // Do this twice to make sure it doesn't throw 143 observer.observe({ entryTypes: ['mark', 'measure'], buffered: true }); 144 // Even tho we called twice, count should be 1 145 assert.strictEqual(counts[NODE_PERFORMANCE_ENTRY_TYPE_MARK], 1); 146 performance.mark('test1'); 147 performance.mark('test2'); 148 performance.measure('test3', 'test1', 'test2'); 149} 150