• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright Joyent, Inc. and other Node contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to permit
8// persons to whom the Software is furnished to do so, subject to the
9// following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22'use strict';
23const common = require('../common');
24const assert = require('assert');
25const net = require('net');
26
27function pingPongTest(port, host) {
28  const N = 1000;
29  let count = 0;
30  let sentPongs = 0;
31  let sent_final_ping = false;
32
33  const server = net.createServer(
34    { allowHalfOpen: true },
35    common.mustCall(onSocket)
36  );
37
38  function onSocket(socket) {
39    assert.strictEqual(socket.server, server);
40    assert.strictEqual(
41      server,
42      server.getConnections(common.mustSucceed((connections) => {
43        assert.strictEqual(connections, 1);
44      }))
45    );
46
47    socket.setNoDelay();
48    socket.timeout = 0;
49
50    socket.setEncoding('utf8');
51    socket.on('data', common.mustCall(function(data) {
52      // Since we never queue data (we're always waiting for the PING
53      // before sending a pong) the writeQueueSize should always be less
54      // than one message.
55      assert.ok(socket.bufferSize >= 0 && socket.bufferSize <= 4);
56
57      assert.strictEqual(socket.writable, true);
58      assert.strictEqual(socket.readable, true);
59      assert.ok(count <= N);
60      assert.strictEqual(data, 'PING');
61
62      socket.write('PONG', common.mustCall(function() {
63        sentPongs++;
64      }));
65    }, N + 1));
66
67    socket.on('end', common.mustCall(function() {
68      assert.strictEqual(socket.allowHalfOpen, true);
69      assert.strictEqual(socket.writable, true); // Because allowHalfOpen
70      assert.strictEqual(socket.readable, false);
71      socket.end();
72    }));
73
74    socket.on('error', common.mustNotCall());
75
76    socket.on('close', common.mustCall(function() {
77      assert.strictEqual(socket.writable, false);
78      assert.strictEqual(socket.readable, false);
79      socket.server.close();
80    }));
81  }
82
83
84  server.listen(port, host, common.mustCall(function() {
85    if (this.address().port)
86      port = this.address().port;
87
88    const client = net.createConnection(port, host);
89
90    client.setEncoding('ascii');
91    client.on('connect', common.mustCall(function() {
92      assert.strictEqual(client.readable, true);
93      assert.strictEqual(client.writable, true);
94      client.write('PING');
95    }));
96
97    client.on('data', common.mustCall(function(data) {
98      assert.strictEqual(data, 'PONG');
99      count += 1;
100
101      if (sent_final_ping) {
102        assert.strictEqual(client.writable, false);
103        assert.strictEqual(client.readable, true);
104        return;
105      }
106      assert.strictEqual(client.writable, true);
107      assert.strictEqual(client.readable, true);
108
109      if (count < N) {
110        client.write('PING');
111      } else {
112        sent_final_ping = true;
113        client.write('PING');
114        client.end();
115      }
116    }, N + 1));
117
118    client.on('close', common.mustCall(function() {
119      assert.strictEqual(count, N + 1);
120      assert.strictEqual(sentPongs, N + 1);
121      assert.strictEqual(sent_final_ping, true);
122    }));
123
124    client.on('error', common.mustNotCall());
125  }));
126}
127
128/* All are run at once, so run on different ports */
129const tmpdir = require('../common/tmpdir');
130tmpdir.refresh();
131pingPongTest(common.PIPE);
132pingPongTest(0);
133pingPongTest(0, 'localhost');
134if (common.hasIPv6)
135  pingPongTest(0, '::1');
136