• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4if (!common.hasCrypto)
5  common.skip('missing crypto');
6const assert = require('assert');
7const h2 = require('http2');
8
9const { PerformanceObserver } = require('perf_hooks');
10
11const obs = new PerformanceObserver(common.mustCall((items) => {
12  const entry = items.getEntries()[0];
13  assert.strictEqual(entry.entryType, 'http2');
14  assert.strictEqual(typeof entry.startTime, 'number');
15  assert.strictEqual(typeof entry.duration, 'number');
16  switch (entry.name) {
17    case 'Http2Session':
18      assert.strictEqual(typeof entry.pingRTT, 'number');
19      assert.strictEqual(typeof entry.streamAverageDuration, 'number');
20      assert.strictEqual(typeof entry.streamCount, 'number');
21      assert.strictEqual(typeof entry.framesReceived, 'number');
22      assert.strictEqual(typeof entry.framesSent, 'number');
23      assert.strictEqual(typeof entry.bytesWritten, 'number');
24      assert.strictEqual(typeof entry.bytesRead, 'number');
25      assert.strictEqual(typeof entry.maxConcurrentStreams, 'number');
26      switch (entry.type) {
27        case 'server':
28          assert.strictEqual(entry.streamCount, 1);
29          assert(entry.framesReceived >= 3);
30          break;
31        case 'client':
32          assert.strictEqual(entry.streamCount, 1);
33          assert.strictEqual(entry.framesReceived, 7);
34          break;
35        default:
36          assert.fail('invalid Http2Session type');
37      }
38      break;
39    case 'Http2Stream':
40      assert.strictEqual(typeof entry.timeToFirstByte, 'number');
41      assert.strictEqual(typeof entry.timeToFirstByteSent, 'number');
42      assert.strictEqual(typeof entry.timeToFirstHeader, 'number');
43      assert.strictEqual(typeof entry.bytesWritten, 'number');
44      assert.strictEqual(typeof entry.bytesRead, 'number');
45      break;
46    default:
47      assert.fail('invalid entry name');
48  }
49}, 4));
50
51// Should throw if entryTypes are not valid
52{
53  const expectedError = { code: 'ERR_VALID_PERFORMANCE_ENTRY_TYPE' };
54  const wrongEntryTypes = { entryTypes: ['foo', 'bar', 'baz'] };
55  assert.throws(() => obs.observe(wrongEntryTypes), expectedError);
56}
57
58obs.observe({ entryTypes: ['http2'] });
59
60const body =
61  '<html><head></head><body><h1>this is some data</h2></body></html>';
62
63const server = h2.createServer();
64
65// We use the lower-level API here
66server.on('stream', common.mustCall(onStream));
67
68function onStream(stream, headers, flags) {
69  assert.strictEqual(headers[':scheme'], 'http');
70  assert.ok(headers[':authority']);
71  assert.strictEqual(headers[':method'], 'GET');
72  assert.strictEqual(flags, 5);
73  stream.respond({
74    'content-type': 'text/html',
75    ':status': 200
76  });
77  stream.write(body.slice(0, 20));
78  stream.end(body.slice(20));
79}
80
81server.on('session', common.mustCall((session) => {
82  session.ping(common.mustCall());
83}));
84
85server.listen(0);
86
87server.on('listening', common.mustCall(() => {
88
89  const client = h2.connect(`http://localhost:${server.address().port}`);
90
91  client.on('connect', common.mustCall(() => {
92    client.ping(common.mustCall());
93  }));
94
95  const req = client.request();
96
97  req.on('response', common.mustCall());
98
99  let data = '';
100  req.setEncoding('utf8');
101  req.on('data', (d) => data += d);
102  req.on('end', common.mustCall(() => {
103    assert.strictEqual(body, data);
104  }));
105  req.on('close', common.mustCall(() => {
106    client.close();
107    server.close();
108  }));
109
110}));
111