summaryrefslogtreecommitdiff
path: root/test/async-hooks/test-writewrap.js
blob: 4f3455480ba84924cccb670c7a0fbb182d302be2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
'use strict';

const common = require('../common');
const assert = require('assert');
const initHooks = require('./init-hooks');
const { checkInvocations } = require('./hook-checks');
const net = require('net');

const hooks = initHooks();
hooks.enable();

//
// Creating server and listening on port
//
const server = net.createServer()
  .on('listening', common.mustCall(onlistening))
  .on('connection', common.mustCall(onconnection))
  .listen(0);

assert.strictEqual(hooks.activitiesOfTypes('WRITEWRAP').length, 0);

function onlistening() {
  assert.strictEqual(hooks.activitiesOfTypes('WRITEWRAP').length, 0);
  //
  // Creating client and connecting it to server
  //
  net
    .connect(server.address().port)
    .on('connect', common.mustCall(onconnect));

  assert.strictEqual(hooks.activitiesOfTypes('WRITEWRAP').length, 0);
}

function checkDestroyedWriteWraps(n, stage) {
  const as = hooks.activitiesOfTypes('WRITEWRAP');
  assert.strictEqual(as.length, n,
                     `${as.length} out of ${n} WRITEWRAPs when ${stage}`);

  function checkValidWriteWrap(w) {
    assert.strictEqual(w.type, 'WRITEWRAP');
    assert.strictEqual(typeof w.uid, 'number');
    assert.strictEqual(typeof w.triggerAsyncId, 'number');

    checkInvocations(w, { init: 1 }, `when ${stage}`);
  }
  as.forEach(checkValidWriteWrap);
}

function onconnection(conn) {
  conn.write('hi');  // Let the client know we're ready.
  conn.resume();
  //
  // Server received client connection
  //
  checkDestroyedWriteWraps(0, 'server got connection');
}

function onconnect() {
  //
  // Client connected to server
  //
  checkDestroyedWriteWraps(0, 'client connected');

  this.once('data', common.mustCall(ondata));
}

function ondata() {
  //
  // Writing data to client socket
  //
  const write = () => {
    let writeFinished = false;
    this.write('f'.repeat(1280000), () => {
      writeFinished = true;
    });
    process.nextTick(() => {
      if (writeFinished) {
        // Synchronous finish, write more data immediately.
        writeFinished = false;
        write();
      } else {
        // Asynchronous write; this is what we are here for.
        onafterwrite(this);
      }
    });
  };
  write();
}

function onafterwrite(self) {
  checkDestroyedWriteWraps(1, 'client destroyed');
  self.end();

  checkDestroyedWriteWraps(1, 'client destroyed');

  //
  // Closing server
  //
  server.close(common.mustCall(onserverClosed));
  checkDestroyedWriteWraps(1, 'server closing');
}

function onserverClosed() {
  checkDestroyedWriteWraps(1, 'server closed');
}

process.on('exit', onexit);

function onexit() {
  hooks.disable();
  hooks.sanityCheck('WRITEWRAP');
  checkDestroyedWriteWraps(1, 'process exits');
}