1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-23 15:49:44 -05:00
denoland-deno/tests/node_compat/test/parallel/test-net-connect-options-fd.js

111 lines
3.8 KiB
JavaScript
Raw Normal View History

// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 20.11.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
// Flags: --expose-internals
'use strict';
const common = require('../common');
if (common.isWindows)
common.skip('Does not support wrapping sockets with fd on Windows');
const assert = require('assert');
const net = require('net');
const path = require('path');
const { internalBinding } = require('internal/test/binding');
const { Pipe, constants: PipeConstants } = internalBinding('pipe_wrap');
const tmpdir = require('../common/tmpdir');
tmpdir.refresh();
function testClients(getSocketOpt, getConnectOpt, getConnectCb) {
const cloneOptions = (index) =>
({ ...getSocketOpt(index), ...getConnectOpt(index) });
return [
net.connect(cloneOptions(0), getConnectCb(0)),
net.connect(cloneOptions(1))
.on('connect', getConnectCb(1)),
net.createConnection(cloneOptions(2), getConnectCb(2)),
net.createConnection(cloneOptions(3))
.on('connect', getConnectCb(3)),
new net.Socket(getSocketOpt(4)).connect(getConnectOpt(4), getConnectCb(4)),
new net.Socket(getSocketOpt(5)).connect(getConnectOpt(5))
.on('connect', getConnectCb(5)),
];
}
const CLIENT_VARIANTS = 6; // Same length as array above
const forAllClients = (cb) => common.mustCall(cb, CLIENT_VARIANTS);
// Test Pipe fd is wrapped correctly
{
// Use relative path to avoid hitting 108-char length limit
// for socket paths in libuv.
const prefix = path.relative('.', `${common.PIPE}-net-connect-options-fd`);
const serverPath = `${prefix}-server`;
let counter = 0;
let socketCounter = 0;
const handleMap = new Map();
const server = net.createServer()
.on('connection', forAllClients(function serverOnConnection(socket) {
let clientFd;
socket.on('data', common.mustCall(function(data) {
clientFd = data.toString();
console.error(`[Pipe]Received data from fd ${clientFd}`);
socket.end();
}));
socket.on('end', common.mustCall(function() {
counter++;
console.error(`[Pipe]Received end from fd ${clientFd}, total ${counter}`);
if (counter === CLIENT_VARIANTS) {
setTimeout(() => {
console.error(`[Pipe]Server closed by fd ${clientFd}`);
server.close();
}, 10);
}
}, 1));
}))
.on('close', function() {
setTimeout(() => {
for (const pair of handleMap) {
console.error(`[Pipe]Clean up handle with fd ${pair[1].fd}`);
pair[1].close(); // clean up handles
}
}, 10);
})
.on('error', function(err) {
console.error(err);
assert.fail(`[Pipe server]${err}`);
})
.listen({ path: serverPath }, common.mustCall(function serverOnListen() {
const getSocketOpt = (index) => {
const handle = new Pipe(PipeConstants.SOCKET);
const err = handle.bind(`${prefix}-client-${socketCounter++}`);
assert(err >= 0, String(err));
assert.notStrictEqual(handle.fd, -1);
handleMap.set(index, handle);
console.error(`[Pipe]Bound handle with Pipe ${handle.fd}`);
return { fd: handle.fd, readable: true, writable: true };
};
const getConnectOpt = () => ({
path: serverPath
});
const getConnectCb = (index) => common.mustCall(function clientOnConnect() {
// Test if it's wrapping an existing fd
assert(handleMap.has(index));
const oldHandle = handleMap.get(index);
assert.strictEqual(oldHandle.fd, this._handle.fd);
this.write(String(oldHandle.fd));
console.error(`[Pipe]Sending data through fd ${oldHandle.fd}`);
this.on('error', function(err) {
console.error(err);
assert.fail(`[Pipe Client]${err}`);
});
});
testClients(getSocketOpt, getConnectOpt, getConnectCb);
}));
}