summaryrefslogtreecommitdiff
path: root/test/parallel/test-performance-function.js
diff options
context:
space:
mode:
authorJames M Snell <jasnell@gmail.com>2017-08-07 15:53:24 -0700
committerJames M Snell <jasnell@gmail.com>2017-08-23 16:00:09 -0700
commit67269fd7f33279699b1ae71225f3d738518c844c (patch)
tree22f6a615c02ccb93c69355d101db87f36f08cf06 /test/parallel/test-performance-function.js
parente007f66ae211192f385dc253bfa19a84e7fc649a (diff)
downloadandroid-node-v8-67269fd7f33279699b1ae71225f3d738518c844c.tar.gz
android-node-v8-67269fd7f33279699b1ae71225f3d738518c844c.tar.bz2
android-node-v8-67269fd7f33279699b1ae71225f3d738518c844c.zip
perf_hooks: implementation of the perf timing API
An initial implementation of the Performance Timing API for Node.js. This is the same Performance Timing API implemented by modern browsers with a number of Node.js specific properties. The User Timing mark() and measure() APIs are implemented, garbage collection timing, and node startup milestone timing. ```js const { performance } = require('perf_hooks'); performance.mark('A'); setTimeout(() => { performance.mark('B'); performance.measure('A to B', 'A', 'B'); const entry = performance.getEntriesByName('A to B', 'measure')[0]; console.log(entry.duration); }, 10000); ``` The implementation is at the native layer and makes use of uv_hrtime(). This should enable *eventual* integration with things like Tracing and Inspection. The implementation is extensible and should allow us to add new performance entry types as we go (e.g. for measuring i/o perf, etc). Documentation and a test are provided. PR-URL: https://github.com/nodejs/node/pull/14680 Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'test/parallel/test-performance-function.js')
-rw-r--r--test/parallel/test-performance-function.js93
1 files changed, 93 insertions, 0 deletions
diff --git a/test/parallel/test-performance-function.js b/test/parallel/test-performance-function.js
new file mode 100644
index 0000000000..8dd4d3004b
--- /dev/null
+++ b/test/parallel/test-performance-function.js
@@ -0,0 +1,93 @@
+'use strict';
+
+const common = require('../common');
+const assert = require('assert');
+
+const {
+ performance,
+ PerformanceObserver
+} = require('perf_hooks');
+
+{
+ // Intentional non-op. Do not wrap in common.mustCall();
+ const n = performance.timerify(() => {});
+ n();
+ const entries = performance.getEntriesByType('function');
+ assert.strictEqual(entries.length, 0);
+
+ const obs = new PerformanceObserver(common.mustCall((list) => {
+ const entries = list.getEntries();
+ const entry = entries[0];
+ assert(entry);
+ assert.strictEqual(entry.name, 'performance.timerify');
+ assert.strictEqual(entry.entryType, 'function');
+ assert.strictEqual(typeof entry.duration, 'number');
+ assert.strictEqual(typeof entry.startTime, 'number');
+ obs.disconnect();
+ performance.clearFunctions();
+ }));
+ obs.observe({ entryTypes: ['function'] });
+ n();
+}
+
+{
+ // If the error throws, the error should just be bubbled up and the
+ // performance timeline entry will not be reported.
+ const obs = new PerformanceObserver(common.mustNotCall());
+ obs.observe({ entryTypes: ['function'] });
+ const n = performance.timerify(() => {
+ throw new Error('test');
+ });
+ assert.throws(() => n(), /^Error: test$/);
+ const entries = performance.getEntriesByType('function');
+ assert.strictEqual(entries.length, 0);
+ obs.disconnect();
+}
+
+{
+ class N {}
+ const n = performance.timerify(N);
+ new n();
+ const entries = performance.getEntriesByType('function');
+ assert.strictEqual(entries.length, 0);
+
+ const obs = new PerformanceObserver(common.mustCall((list) => {
+ const entries = list.getEntries();
+ const entry = entries[0];
+ assert.strictEqual(entry[0], 1);
+ assert.strictEqual(entry[1], 'abc');
+ assert(entry);
+ assert.strictEqual(entry.name, 'N');
+ assert.strictEqual(entry.entryType, 'function');
+ assert.strictEqual(typeof entry.duration, 'number');
+ assert.strictEqual(typeof entry.startTime, 'number');
+ obs.disconnect();
+ performance.clearFunctions();
+ }));
+ obs.observe({ entryTypes: ['function'] });
+
+ new n(1, 'abc');
+}
+
+{
+ [1, {}, [], null, undefined, Infinity].forEach((i) => {
+ assert.throws(() => performance.timerify(i),
+ common.expectsError({
+ code: 'ERR_INVALID_ARG_TYPE',
+ type: TypeError,
+ message: 'The "fn" argument must be of type Function'
+ }));
+ });
+}
+
+// Function can only be wrapped once, also check length and name
+{
+ const m = (a, b = 1) => {};
+ const n = performance.timerify(m);
+ const o = performance.timerify(m);
+ const p = performance.timerify(n);
+ assert.strictEqual(n, o);
+ assert.strictEqual(n, p);
+ assert.strictEqual(n.length, m.length);
+ assert.strictEqual(n.name, 'timerified m');
+}