1 | 'use strict'
|
2 |
|
3 | const test = require('tap').test
|
4 | const async = require('async')
|
5 | const summary = require('summary')
|
6 | const endpoint = require('endpoint')
|
7 | const CollectAndRead = require('./collect-and-read.js')
|
8 |
|
9 | function diff (data) {
|
10 | const output = []
|
11 | let last = data[0]
|
12 | for (let i = 1; i < data.length; i++) {
|
13 | output.push(data[i] - last)
|
14 | last = data[i]
|
15 | }
|
16 | return output
|
17 | }
|
18 |
|
19 | test('cmd - collect - gc events', function (t) {
|
20 | const cmd = new CollectAndRead({}, '--expose-gc', '-e', `
|
21 | const t = [];
|
22 |
|
23 | const interval1 = setInterval(function () {
|
24 | for (let i = 0; i < 2000; i++) {
|
25 | t.push(new Date())
|
26 | }
|
27 | }, 20)
|
28 |
|
29 | const interval2 = setInterval(function () {
|
30 | for (let i = 0; i < 500; i++) {
|
31 | t.pop()
|
32 | }
|
33 | })
|
34 |
|
35 | setTimeout(function () {
|
36 | clearInterval(interval1)
|
37 | clearInterval(interval2)
|
38 | global.gc()
|
39 | }, 200)
|
40 | `)
|
41 |
|
42 | cmd.on('error', t.ifError.bind(t))
|
43 | cmd.on('ready', function () {
|
44 | async.parallel({
|
45 | traceEvent (done) {
|
46 | cmd.traceEvent.pipe(endpoint({ objectMode: true }, done))
|
47 | },
|
48 |
|
49 | processStat (done) {
|
50 | cmd.processStat.pipe(endpoint({ objectMode: true }, done))
|
51 | }
|
52 | }, function (err, output) {
|
53 | if (err) return t.ifError(err)
|
54 |
|
55 | const scavenge = output.traceEvent
|
56 | .filter((event) => event.name === 'V8.GCScavenger')
|
57 | const compactor = output.traceEvent
|
58 | .filter((event) => event.name === 'V8.GCCompactor')
|
59 |
|
60 | t.ok(scavenge.length >= 1)
|
61 | t.ok(scavenge[0].args.startTimestamp <= scavenge[0].args.endTimestamp)
|
62 | t.ok(Math.abs(scavenge[0].args.endTimestamp - Date.now()) < 10000)
|
63 | t.ok(Math.abs(scavenge[0].args.startTimestamp - Date.now()) < 10000)
|
64 |
|
65 | t.strictEqual(compactor.length, 1)
|
66 | t.ok(compactor[0].args.startTimestamp <= compactor[0].args.endTimestamp)
|
67 | t.ok(Math.abs(compactor[0].args.startTimestamp - Date.now()) < 10000)
|
68 | t.ok(Math.abs(compactor[0].args.endTimestamp - Date.now()) < 10000)
|
69 |
|
70 | t.end()
|
71 | })
|
72 | })
|
73 | })
|
74 |
|
75 | test('cmd - collect - data files have content', function (t) {
|
76 | const cmd = new CollectAndRead({}, '-e', 'setTimeout(() => {}, 1000)')
|
77 | cmd.on('error', t.ifError.bind(t))
|
78 | cmd.on('ready', function () {
|
79 | async.parallel({
|
80 | traceEvent (done) {
|
81 | cmd.traceEvent.pipe(endpoint({ objectMode: true }, done))
|
82 | },
|
83 |
|
84 | processStat (done) {
|
85 | cmd.processStat.pipe(endpoint({ objectMode: true }, done))
|
86 | }
|
87 | }, function (err, output) {
|
88 | if (err) return t.ifError(err)
|
89 |
|
90 |
|
91 | const sampleTimes = output.processStat.map((stat) => stat.timestamp)
|
92 | const timeSeperation = summary(diff(sampleTimes)).mean()
|
93 | t.ok(sampleTimes.length > 0, 'data is outputted')
|
94 | t.ok(Math.abs(timeSeperation - 10) < 20)
|
95 |
|
96 | t.end()
|
97 | })
|
98 | })
|
99 | })
|
100 |
|
101 | test('cmd - collect - startup delay is not included', function (t) {
|
102 | const cmd = new CollectAndRead({}, '-e', `
|
103 | for (const t = Date.now() + 100; t > Date.now();) {}
|
104 | setTimeout(() => {}, 100)
|
105 | `)
|
106 | cmd.on('error', t.ifError.bind(t))
|
107 | cmd.on('ready', function () {
|
108 | async.parallel({
|
109 | traceEvent (done) {
|
110 | cmd.traceEvent.pipe(endpoint({ objectMode: true }, done))
|
111 | },
|
112 |
|
113 | processStat (done) {
|
114 | cmd.processStat.pipe(endpoint({ objectMode: true }, done))
|
115 | }
|
116 | }, function (err, output) {
|
117 | if (err) return t.ifError(err)
|
118 |
|
119 | const delay = output.processStat.map((stat) => stat.delay)
|
120 | t.ok(delay[0] < 50)
|
121 | t.end()
|
122 | })
|
123 | })
|
124 | })
|