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(host, on_complete) {
28  const N = 100;
29  const DELAY = 1;
30  let count = 0;
31  let client_ended = false;
32
33  const server = net.createServer({ allowHalfOpen: true }, function(socket) {
34    socket.setEncoding('utf8');
35
36    socket.on('data', function(data) {
37      console.log(data);
38      assert.strictEqual(data, 'PING');
39      assert.strictEqual(socket.readyState, 'open');
40      assert.strictEqual(count <= N, true);
41      setTimeout(function() {
42        assert.strictEqual(socket.readyState, 'open');
43        socket.write('PONG');
44      }, DELAY);
45    });
46
47    socket.on('timeout', function() {
48      console.error('server-side timeout!!');
49      assert.strictEqual(false, true);
50    });
51
52    socket.on('end', function() {
53      console.log('server-side socket EOF');
54      assert.strictEqual(socket.readyState, 'writeOnly');
55      socket.end();
56    });
57
58    socket.on('close', function(had_error) {
59      console.log('server-side socket.end');
60      assert.strictEqual(had_error, false);
61      assert.strictEqual(socket.readyState, 'closed');
62      socket.server.close();
63    });
64  });
65
66  server.listen(0, host, common.mustCall(function() {
67    const client = net.createConnection(server.address().port, host);
68
69    client.setEncoding('utf8');
70
71    client.on('connect', function() {
72      assert.strictEqual(client.readyState, 'open');
73      client.write('PING');
74    });
75
76    client.on('data', function(data) {
77      console.log(data);
78      assert.strictEqual(data, 'PONG');
79      assert.strictEqual(client.readyState, 'open');
80
81      setTimeout(function() {
82        assert.strictEqual(client.readyState, 'open');
83        if (count++ < N) {
84          client.write('PING');
85        } else {
86          console.log('closing client');
87          client.end();
88          client_ended = true;
89        }
90      }, DELAY);
91    });
92
93    client.on('timeout', function() {
94      console.error('client-side timeout!!');
95      assert.strictEqual(false, true);
96    });
97
98    client.on('close', common.mustCall(function() {
99      console.log('client.end');
100      assert.strictEqual(count, N + 1);
101      assert.ok(client_ended);
102      if (on_complete) on_complete();
103    }));
104  }));
105}
106
107pingPongTest();
108