• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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