Skip to content

Commit 8d6ee2c

Browse files
committed
test: refactor net.connect port option test
1 parent b076cfa commit 8d6ee2c

File tree

2 files changed

+221
-127
lines changed

2 files changed

+221
-127
lines changed
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
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';
23+
const common = require('../common');
24+
const assert = require('assert');
25+
const dns = require('dns');
26+
const net = require('net');
27+
28+
// Test wrong type of ports
29+
{
30+
function portTypeError(opt) {
31+
const prefix = '"port" option should be a number or string: ';
32+
const cleaned = opt.replace(/[\\^$.*+?()[\]{}|=!<>:-]/g, '\\$&');
33+
return new RegExp(`^TypeError: ${prefix}${cleaned}$`);
34+
}
35+
36+
syncFailToConnect(true, portTypeError('true'));
37+
syncFailToConnect(false, portTypeError('false'));
38+
syncFailToConnect([], portTypeError(''), true);
39+
syncFailToConnect({}, portTypeError('[object Object]'), true);
40+
syncFailToConnect(null, portTypeError('null'));
41+
}
42+
43+
// Test out of range ports
44+
{
45+
function portRangeError(opt) {
46+
const prefix = '"port" option should be >= 0 and < 65536: ';
47+
const cleaned = opt.replace(/[\\^$.*+?()[\]{}|=!<>:-]/g, '\\$&');
48+
return new RegExp(`^RangeError: ${prefix}${cleaned}$`);
49+
}
50+
51+
syncFailToConnect('', portRangeError(''));
52+
syncFailToConnect(' ', portRangeError(' '));
53+
syncFailToConnect('0x', portRangeError('0x'), true);
54+
syncFailToConnect('-0x1', portRangeError('-0x1'), true);
55+
syncFailToConnect(NaN, portRangeError('NaN'));
56+
syncFailToConnect(Infinity, portRangeError('Infinity'));
57+
syncFailToConnect(-1, portRangeError('-1'));
58+
syncFailToConnect(65536, portRangeError('65536'));
59+
}
60+
61+
// Test invalid hints
62+
{
63+
const regexp = /^TypeError: Invalid argument: hints must use valid flags$/;
64+
// connect({hint}, cb) and connect({hint})
65+
const hints = (dns.ADDRCONFIG | dns.V4MAPPED) + 42;
66+
const hintOptBlocks = doConnect([{hints: hints}],
67+
() => common.mustNotCall());
68+
for (const block of hintOptBlocks) {
69+
assert.throws(block, regexp,
70+
`${block.name}({hints: ${hints})`);
71+
}
72+
}
73+
74+
// Test valid combinations of connect(port) and connect(port, host)
75+
{
76+
const expectedConnections = 72;
77+
let serverConnected = 0;
78+
79+
const server = net.createServer(common.mustCall(function(socket) {
80+
socket.end('ok');
81+
if (++serverConnected === expectedConnections) {
82+
server.close();
83+
}
84+
}, expectedConnections));
85+
86+
server.listen(0, 'localhost', common.mustCall(function() {
87+
const port = this.address().port;
88+
89+
// Total connections = 3 * 4(canConnect) * 6(doConnect) = 72
90+
canConnect(port);
91+
canConnect(port + '');
92+
canConnect('0x' + port.toString(16));
93+
}));
94+
95+
// Try connecting to random ports, but do so once the server is closed
96+
server.on('close', function() {
97+
asyncFailToConnect(0);
98+
asyncFailToConnect(/* undefined */);
99+
});
100+
}
101+
102+
function doConnect(args, getCb) {
103+
return [
104+
function createConnectionWithCb() {
105+
return net.createConnection.apply(net, args.concat(getCb()));
106+
},
107+
function createConnectionWithoutCb() {
108+
return net.createConnection.apply(net, args)
109+
.on('connect', getCb());
110+
},
111+
function connectWithCb() {
112+
return net.connect.apply(net, args.concat(getCb()));
113+
},
114+
function connectWithoutCb() {
115+
return net.connect.apply(net, args)
116+
.on('connect', getCb());
117+
},
118+
function socketConnectWithCb() {
119+
const socket = new net.Socket();
120+
return socket.connect.apply(socket, args.concat(getCb()));
121+
},
122+
function socketConnectWithoutCb() {
123+
const socket = new net.Socket();
124+
return socket.connect.apply(socket, args)
125+
.on('connect', getCb());
126+
}
127+
];
128+
}
129+
130+
function syncFailToConnect(port, regexp, optOnly) {
131+
if (!optOnly) {
132+
// connect(port, cb) and connect(port)
133+
const portArgBlocks = doConnect([port], () => common.mustNotCall());
134+
for (const block of portArgBlocks) {
135+
assert.throws(block, regexp, `${block.name}(${port})`);
136+
}
137+
138+
// connect(port, host, cb) and connect(port, host)
139+
const portHostArgBlocks = doConnect([port, 'localhost'],
140+
() => common.mustNotCall());
141+
for (const block of portHostArgBlocks) {
142+
assert.throws(block, regexp, `${block.name}(${port}, 'localhost')`);
143+
}
144+
}
145+
// connect({port}, cb) and connect({port})
146+
const portOptBlocks = doConnect([{port}],
147+
() => common.mustNotCall());
148+
for (const block of portOptBlocks) {
149+
assert.throws(block, regexp, `${block.name}({port: ${port}})`);
150+
}
151+
152+
// connect({port, host}, cb) and connect({port, host})
153+
const portHostOptBlocks = doConnect([{port: port, host: 'localhost'}],
154+
() => common.mustNotCall());
155+
for (const block of portHostOptBlocks) {
156+
assert.throws(block, regexp,
157+
`${block.name}({port: ${port}, host: 'localhost'})`);
158+
}
159+
}
160+
161+
function canConnect(port) {
162+
const noop = () => common.mustCall(function() {});
163+
// connect(port, cb) and connect(port)
164+
const portArgBlocks = doConnect([port], noop);
165+
for (const block of portArgBlocks) {
166+
assert.doesNotThrow(block, `${block.name}(${port})`);
167+
}
168+
169+
// connect(port, host, cb) and connect(port, host)
170+
const portHostArgBlocks = doConnect([port, 'localhost'], noop);
171+
for (const block of portHostArgBlocks) {
172+
assert.doesNotThrow(block, `${block.name}(${port})`);
173+
}
174+
175+
// connect({port}, cb) and connect({port})
176+
const portOptBlocks = doConnect([{port}], noop);
177+
for (const block of portOptBlocks) {
178+
assert.doesNotThrow(block, `${block.name}({port: ${port}})`);
179+
}
180+
181+
// connect({port, host}, cb) and connect({port, host})
182+
const portHostOptBlocks = doConnect([{port: port, host: 'localhost'}],
183+
noop);
184+
for (const block of portHostOptBlocks) {
185+
assert.doesNotThrow(block,
186+
`${block.name}({port: ${port}, host: 'localhost'})`);
187+
}
188+
}
189+
190+
function asyncFailToConnect(port) {
191+
const onError = () => common.mustCall(function(err) {
192+
const regexp = /^Error: connect (E\w+)(.+)$/;
193+
assert(regexp.test(err + ''), err + '');
194+
});
195+
196+
const dont = () => common.mustNotCall();
197+
// connect(port, cb) and connect(port)
198+
const portArgBlocks = doConnect([port], dont);
199+
for (const block of portArgBlocks) {
200+
assert.doesNotThrow(function() {
201+
block().on('error', onError());
202+
}, `${block.name}(${port})`);
203+
}
204+
205+
// connect({port}, cb) and connect({port})
206+
const portOptBlocks = doConnect([{port}], dont);
207+
for (const block of portOptBlocks) {
208+
assert.doesNotThrow(function() {
209+
block().on('error', onError());
210+
}, `${block.name}({port: ${port}})`);
211+
}
212+
213+
// connect({port, host}, cb) and connect({port, host})
214+
const portHostOptBlocks = doConnect([{port: port, host: 'localhost'}],
215+
dont);
216+
for (const block of portHostOptBlocks) {
217+
assert.doesNotThrow(function() {
218+
block().on('error', onError());
219+
}, `${block.name}({port: ${port}, host: 'localhost'})`);
220+
}
221+
}

test/parallel/test-net-create-connection.js

Lines changed: 0 additions & 127 deletions
This file was deleted.

0 commit comments

Comments
 (0)