• 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.mustCall(function(err, connections) {
43        assert.ifError(err);
44        assert.strictEqual(connections, 1);
45      }))
46    );
47
48    socket.setNoDelay();
49    socket.timeout = 0;
50
51    socket.setEncoding('utf8');
52    socket.on('data', common.mustCall(function(data) {
53      // Since we never queue data (we're always waiting for the PING
54      // before sending a pong) the writeQueueSize should always be less
55      // than one message.
56      assert.ok(socket.bufferSize >= 0 && socket.bufferSize <= 4);
57
58      assert.strictEqual(socket.writable, true);
59      assert.strictEqual(socket.readable, true);
60      assert.ok(count <= N);
61      assert.strictEqual(data, 'PING');
62
63      socket.write('PONG', common.mustCall(function() {
64        sentPongs++;
65      }));
66    }, N + 1));
67
68    socket.on('end', common.mustCall(function() {
69      assert.strictEqual(socket.allowHalfOpen, true);
70      assert.strictEqual(socket.writable, true); // Because allowHalfOpen
71      assert.strictEqual(socket.readable, false);
72      socket.end();
73    }));
74
75    socket.on('error', common.mustNotCall());
76
77    socket.on('close', common.mustCall(function() {
78      assert.strictEqual(socket.writable, false);
79      assert.strictEqual(socket.readable, false);
80      socket.server.close();
81    }));
82  }
83
84
85  server.listen(port, host, common.mustCall(function() {
86    if (this.address().port)
87      port = this.address().port;
88
89    const client = net.createConnection(port, host);
90
91    client.setEncoding('ascii');
92    client.on('connect', common.mustCall(function() {
93      assert.strictEqual(client.readable, true);
94      assert.strictEqual(client.writable, true);
95      client.write('PING');
96    }));
97
98    client.on('data', common.mustCall(function(data) {
99      assert.strictEqual(data, 'PONG');
100      count += 1;
101
102      if (sent_final_ping) {
103        assert.strictEqual(client.writable, false);
104        assert.strictEqual(client.readable, true);
105        return;
106      }
107      assert.strictEqual(client.writable, true);
108      assert.strictEqual(client.readable, true);
109
110      if (count < N) {
111        client.write('PING');
112      } else {
113        sent_final_ping = true;
114        client.write('PING');
115        client.end();
116      }
117    }, N + 1));
118
119    client.on('close', common.mustCall(function() {
120      assert.strictEqual(count, N + 1);
121      assert.strictEqual(sentPongs, N + 1);
122      assert.strictEqual(sent_final_ping, true);
123    }));
124
125    client.on('error', common.mustNotCall());
126  }));
127}
128
129/* All are run at once, so run on different ports */
130const tmpdir = require('../common/tmpdir');
131tmpdir.refresh();
132pingPongTest(common.PIPE);
133pingPongTest(0);
134pingPongTest(0, 'localhost');
135if (common.hasIPv6)
136  pingPongTest(0, '::1');
137