diff --git a/test/parallel/test-net-server-listen-handle.js b/test/parallel/test-net-server-listen-handle.js new file mode 100644 index 0000000000..8d25d88577 --- /dev/null +++ b/test/parallel/test-net-server-listen-handle.js @@ -0,0 +1,152 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); +const fs = require('fs'); +const uv = process.binding('uv'); +const TCP = process.binding('tcp_wrap').TCP; +const Pipe = process.binding('pipe_wrap').Pipe; + +common.refreshTmpDir(); + +function closeServer() { + return common.mustCall(function() { + this.close(); + }); +} + +// server.listen(pipe) creates a new pipe wrap, +// so server.close() doesn't actually unlink this existing pipe. +// It needs to be unlinked separately via handle.close() +function closePipeServer(handle) { + return common.mustCall(function() { + this.close(); + handle.close(); + }); +} + +let counter = 0; + +// Avoid conflict with listen-path +function randomPipePath() { + return common.PIPE + '-listen-handle-' + (counter++); +} + +function randomHandle(type) { + let handle, errno, handleName; + if (type === 'tcp') { + handle = new TCP(); + errno = handle.bind('0.0.0.0', 0); + handleName = 'arbitrary tcp port'; + } else { + const path = randomPipePath(); + handle = new Pipe(); + errno = handle.bind(path); + handleName = `pipe ${path}`; + } + + if (errno < 0) { // uv.errname requires err < 0 + assert(errno >= 0, `unable to bind ${handleName}: ${uv.errname(errno)}`); + } + if (!common.isWindows) { // fd doesn't work on windows + // err >= 0 but fd = -1, should not happen + assert.notStrictEqual(handle.fd, -1, + `Bound ${handleName} has fd -1 and errno ${errno}`); + } + return handle; +} + +// Not a public API, used by child_process +{ + // Test listen(tcp) + net.createServer() + .listen(randomHandle('tcp')) + .on('listening', closeServer()); + // Test listen(tcp, cb) + net.createServer() + .listen(randomHandle('tcp'), closeServer()); +} + +function randomPipes(number) { + const arr = []; + for (let i = 0; i < number; ++i) { + arr.push(randomHandle('pipe')); + } + return arr; +} + +// Not a public API, used by child_process +if (!common.isWindows) { // Windows doesn't support {fd: } + const handles = randomPipes(2); // generate pipes in advance + // Test listen(pipe) + net.createServer() + .listen(handles[0]) + .on('listening', closePipeServer(handles[0])); + // Test listen(pipe, cb) + net.createServer() + .listen(handles[1], closePipeServer(handles[1])); +} + +{ + // Test listen({handle: tcp}, cb) + net.createServer() + .listen({handle: randomHandle('tcp')}, closeServer()); + // Test listen({handle: tcp}) + net.createServer() + .listen({handle: randomHandle('tcp')}) + .on('listening', closeServer()); + // Test listen({_handle: tcp}, cb) + net.createServer() + .listen({_handle: randomHandle('tcp')}, closeServer()); + // Test listen({_handle: tcp}) + net.createServer() + .listen({_handle: randomHandle('tcp')}) + .on('listening', closeServer()); +} + +if (!common.isWindows) { // Windows doesn't support {fd: } + // Test listen({fd: tcp.fd}, cb) + net.createServer() + .listen({fd: randomHandle('tcp').fd}, closeServer()); + // Test listen({fd: tcp.fd}) + net.createServer() + .listen({fd: randomHandle('tcp').fd}) + .on('listening', closeServer()); +} + +if (!common.isWindows) { // Windows doesn't support {fd: } + const handles = randomPipes(6); // generate pipes in advance + // Test listen({handle: pipe}, cb) + net.createServer() + .listen({handle: handles[0]}, closePipeServer(handles[0])); + // Test listen({handle: pipe}) + net.createServer() + .listen({handle: handles[1]}) + .on('listening', closePipeServer(handles[1])); + // Test listen({_handle: pipe}, cb) + net.createServer() + .listen({_handle: handles[2]}, closePipeServer(handles[2])); + // Test listen({_handle: pipe}) + net.createServer() + .listen({_handle: handles[3]}) + .on('listening', closePipeServer(handles[3])); + // Test listen({fd: pipe.fd}, cb) + net.createServer() + .listen({fd: handles[4].fd}, closePipeServer(handles[4])); + // Test listen({fd: pipe.fd}) + net.createServer() + .listen({fd: handles[5].fd}) + .on('listening', closePipeServer(handles[5])); +} + +if (!common.isWindows) { // Windows doesn't support {fd: } + // Test invalid fd + const fd = fs.openSync(__filename, 'r'); + net.createServer() + .listen({fd: fd}, common.mustNotCall()) + .on('error', common.mustCall(function(err) { + assert.strictEqual(err + '', 'Error: listen EINVAL'); + this.close(); + })); +} diff --git a/test/parallel/test-net-server-listen-options.js b/test/parallel/test-net-server-listen-options.js index ed1d0dc894..494a331223 100644 --- a/test/parallel/test-net-server-listen-options.js +++ b/test/parallel/test-net-server-listen-options.js @@ -22,6 +22,11 @@ function listenError(literals, ...values) { net.createServer().listen().on('listening', common.mustCall(close)); // Test listen(cb) net.createServer().listen(common.mustCall(close)); + // Test listen(port) + net.createServer().listen(0).on('listening', common.mustCall(close)); + // Test listen({port}) + net.createServer().listen({port: 0}) + .on('listening', common.mustCall(close)); } // Test listen(port, cb) and listen({port: port}, cb) combinations diff --git a/test/parallel/test-net-server-listen-path.js b/test/parallel/test-net-server-listen-path.js new file mode 100644 index 0000000000..f9cc982a42 --- /dev/null +++ b/test/parallel/test-net-server-listen-path.js @@ -0,0 +1,49 @@ +'use strict'; + +const common = require('../common'); +const net = require('net'); + +common.refreshTmpDir(); + +function closeServer() { + return common.mustCall(function() { + this.close(); + }); +} + +let counter = 0; + +// Avoid conflict with listen-handle +function randomPipePath() { + return common.PIPE + '-listen-path-' + (counter++); +} + +// Test listen(path) +{ + const handlePath = randomPipePath(); + net.createServer() + .listen(handlePath) + .on('listening', closeServer()); +} + +// Test listen({path}) +{ + const handlePath = randomPipePath(); + net.createServer() + .listen({path: handlePath}) + .on('listening', closeServer()); +} + +// Test listen(path, cb) +{ + const handlePath = randomPipePath(); + net.createServer() + .listen(handlePath, closeServer()); +} + +// Test listen(path, cb) +{ + const handlePath = randomPipePath(); + net.createServer() + .listen({path: handlePath}, closeServer()); +}