Skip to content
File

Blob: src/workerd/api/node/tests/net-nodejs-test.js

javascript2017 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4//
5// Copyright Joyent, Inc. and other Node contributors.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a
8// copy of this software and associated documentation files (the
9// "Software"), to deal in the Software without restriction, including
10// without limitation the rights to use, copy, modify, merge, publish,
11// distribute, sublicense, and/or sell copies of the Software, and to permit
12// persons to whom the Software is furnished to do so, subject to the
13// following conditions:
14//
15// The above copyright notice and this permission notice shall be included
16// in all copies or substantial portions of the Software.
17//
18// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
21// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT ORs
23// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24// USE OR OTHER DEALINGS IN THE SOFTWARE.
25 
26import { fail, ok, strictEqual, deepStrictEqual, throws } from 'node:assert';
27import { mock } from 'node:test';
28import { once } from 'node:events';
29import * as net from 'node:net';
30import * as tls from 'node:tls';
31 
32export const checkPortsSetCorrectly = {
33 test(ctrl, env, ctx) {
34 const keys = [
35 'SIDECAR_HOSTNAME',
36 'SERVER_PORT',
37 'ECHO_SERVER_PORT',
38 'TIMEOUT_SERVER_PORT',
39 'END_SERVER_PORT',
40 'SERVER_THAT_DIES_PORT',
41 'RECONNECT_SERVER_PORT',
42 ];
43 for (const key of keys) {
44 strictEqual(typeof env[key], 'string');
45 ok(env[key].length > 0);
46 }
47 },
48};
49 
50// test/parallel/test-net-access-byteswritten.js
51export const testNetAccessBytesWritten = {
52 test() {
53 // Check that the bytesWritten getter doesn't crash if object isn't
54 // constructed.
55 strictEqual(net.Socket.prototype.bytesWritten, undefined);
56 strictEqual(
57 Object.getPrototypeOf(tls.TLSSocket).prototype.bytesWritten,
58 undefined
59 );
60 strictEqual(tls.TLSSocket.prototype.bytesWritten, undefined);
61 },
62};
63 
64// test/parallel/test-net-after-close.js
65export const testNetAfterClose = {
66 async test(ctrl, env, ctx) {
67 const { promise, resolve } = Promise.withResolvers();
68 const c = net.connect(Number(env.SERVER_PORT), env.SIDECAR_HOSTNAME);
69 c.resume();
70 c.on('close', () => resolve());
71 await promise;
72 
73 // Calling functions / accessing properties of a closed socket should not throw
74 c.setNoDelay();
75 c.setKeepAlive();
76 // eslint-disable-next-line @typescript-eslint/no-unused-expressions
77 c.bufferSize;
78 c.pause();
79 c.resume();
80 c.address();
81 // eslint-disable-next-line @typescript-eslint/no-unused-expressions
82 c.remoteAddress;
83 // eslint-disable-next-line @typescript-eslint/no-unused-expressions
84 c.remotePort;
85 },
86};
87 
88// test/parallel/test-net-allow-half-open.js
89export const testNetAllowHalfOpen = {
90 async test(ctrl, env, ctx) {
91 // Verify that the socket closes properly when the other end closes
92 // and allowHalfOpen is false.
93 
94 const { promise, resolve } = Promise.withResolvers();
95 const c = net.connect(Number(env.SERVER_PORT), env.SIDECAR_HOSTNAME);
96 strictEqual(c.allowHalfOpen, false);
97 c.resume();
98 
99 const endFn = mock.fn(() => {
100 queueMicrotask(() => {
101 ok(!c.destroyed);
102 });
103 });
104 const finishFn = mock.fn(() => {
105 ok(!c.destroyed);
106 });
107 const closeFn = mock.fn(resolve);
108 c.on('end', endFn);
109 
110 // Even tho we're not writing anything, since the socket receives a
111 // EOS and allowHalfOpen is false, the socket should close both the
112 // readable and writable sides, meaning we should definitely get a
113 // finish event.
114 c.on('finish', finishFn);
115 c.on('close', closeFn);
116 await promise;
117 strictEqual(endFn.mock.callCount(), 1);
118 strictEqual(finishFn.mock.callCount(), 1);
119 strictEqual(closeFn.mock.callCount(), 1);
120 },
121};
122 
123// test/parallel/test-net-better-error-messages-port-hostname.js
124export const testNetBetterErrorMessagesPortHostname = {
125 async test() {
126 // This is intentionally not a completely faithful reproduction of the
127 // original test, as we don't have the ability to mock DNS lookups.
128 const { promise, resolve, reject } = Promise.withResolvers();
129 const c = net.connect(0, 'invalid address');
130 c.on('connect', () => {
131 reject(new Error('should not connect'));
132 });
133 const errorFn = mock.fn((error) => {
134 // TODO(review): Currently our errors do not match the errors that
135 // Node.js produces. Do we need them to? Specifically, in a case like
136 // this, Node.js' error would have a meaningful `code` property along
137 // with `hostname` and `syscall` properties. We, instead, are passing
138 // along the underlying error returned from the internal Socket API.
139 try {
140 strictEqual(error.message, 'Specified address could not be parsed.');
141 } catch (err) {
142 console.log(err.message);
143 }
144 resolve();
145 });
146 c.on('error', errorFn);
147 await promise;
148 strictEqual(errorFn.mock.callCount(), 1);
149 },
150};
151 
152// test/parallel/test-net-binary.js
153export const testNetBinary = {
154 async test(ctrl, env, ctx) {
155 const { promise, resolve } = Promise.withResolvers();
156 
157 // Connect to the echo server
158 const c = net.connect(env.ECHO_SERVER_PORT, env.SIDECAR_HOSTNAME);
159 c.setEncoding('latin1');
160 let result = '';
161 c.on('data', (chunk) => {
162 result += chunk;
163 });
164 
165 let binaryString = '';
166 for (let i = 255; i >= 0; i--) {
167 c.write(String.fromCharCode(i), 'latin1');
168 binaryString += String.fromCharCode(i);
169 }
170 c.end();
171 c.on('close', () => {
172 resolve();
173 });
174 await promise;
175 strictEqual(result, binaryString);
176 },
177};
178 
179// test/parallel/test-net-buffersize.js
180export const testNetBuffersize = {
181 async test(ctrl, env, ctx) {
182 const { promise, resolve } = Promise.withResolvers();
183 const c = net.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME);
184 const finishFn = mock.fn(() => {
185 strictEqual(c.bufferSize, 0);
186 resolve();
187 });
188 c.on('finish', finishFn);
189 
190 strictEqual(c.bufferSize, 0);
191 c.write('a');
192 c.end();
193 strictEqual(c.bufferSize, 1);
194 await promise;
195 strictEqual(finishFn.mock.callCount(), 1);
196 },
197};
198 
199// test/parallel/test-net-bytes-read.js
200export const testNetBytesRead = {
201 async test(ctrl, env, ctx) {
202 const { promise, resolve } = Promise.withResolvers();
203 // Connect to the echo server
204 const c = net.connect(env.ECHO_SERVER_PORT, env.SIDECAR_HOSTNAME);
205 c.resume();
206 c.write('hello');
207 c.end();
208 const endFn = mock.fn(() => {
209 strictEqual(c.bytesRead, 5);
210 resolve();
211 });
212 c.on('end', endFn);
213 
214 await promise;
215 
216 strictEqual(endFn.mock.callCount(), 1);
217 },
218};
219 
220export const testNetBytesStats = {
221 async test(ctrl, env) {
222 // This is intentionally not a completely faithful reproduction of the
223 // original test which checks the bytesRead on the server side.
224 // Connect to the echo server
225 const { promise, resolve } = Promise.withResolvers();
226 const c = net.connect(env.ECHO_SERVER_PORT, env.SIDECAR_HOSTNAME);
227 let bytesDelivered = 0;
228 c.on('data', (chunk) => (bytesDelivered += chunk.byteLength));
229 c.write('hello');
230 c.end();
231 const endFn = mock.fn(() => {
232 strictEqual(c.bytesWritten, 0);
233 strictEqual(bytesDelivered, 5);
234 strictEqual(c.bytesRead, 5);
235 resolve();
236 });
237 c.on('end', endFn);
238 
239 await promise;
240 strictEqual(endFn.mock.callCount(), 1);
241 },
242};
243 
244// test/parallel/test-net-bytes-written-large.js
245const N = 10000000;
246export const testNetBytesWrittenLargeVariant1 = {
247 async test(ctrl, env, ctx) {
248 const { promise, resolve } = Promise.withResolvers();
249 const c = net.connect(env.ECHO_SERVER_PORT, env.SIDECAR_HOSTNAME);
250 c.resume();
251 
252 const writeFn = mock.fn(() => {
253 strictEqual(c.bytesWritten, N);
254 resolve();
255 });
256 
257 c.end(Buffer.alloc(N), writeFn);
258 
259 await promise;
260 },
261};
262 
263// test/parallel/test-net-can-reset-timeout.js
264export const testNetCanResetTimeout = {
265 async test(ctrl, env, ctx) {
266 const { promise, resolve } = Promise.withResolvers();
267 const c = net.connect(env.TIMEOUT_SERVER_PORT, env.SIDECAR_HOSTNAME);
268 const dataFn = mock.fn(() => {
269 c.end();
270 });
271 c.on('data', dataFn);
272 c.on('end', resolve);
273 
274 await promise;
275 
276 strictEqual(dataFn.mock.callCount(), 1);
277 },
278};
279 
280async function assertAbort(socket, testName) {
281 try {
282 await once(socket, 'close');
283 fail(`close ${testName} should have thrown`);
284 } catch (err) {
285 strictEqual(err.name, 'AbortError', err.message);
286 }
287}
288 
289// test/parallel/test-net-connect-abort-controller.js
290export const testNetConnectAbortControllerPostAbort = {
291 async test(ctrl, env, ctx) {
292 const ac = new AbortController();
293 const { signal } = ac;
294 const socket = net.connect({
295 host: env.SIDECAR_HOSTNAME,
296 port: env.SERVER_PORT,
297 signal,
298 });
299 ac.abort();
300 await assertAbort(socket, 'postAbort');
301 },
302};
303 
304export const testNetConnectAbortControllerPreAbort = {
305 async test(ctrl, env, ctx) {
306 const ac = new AbortController();
307 const { signal } = ac;
308 ac.abort();
309 const socket = net.connect({
310 host: env.SIDECAR_HOSTNAME,
311 port: env.SERVER_PORT,
312 signal,
313 });
314 await assertAbort(socket, 'preAbort');
315 },
316};
317 
318export const testNetConnectAbortControllerTickAbort = {
319 async test(ctrl, env, ctx) {
320 const ac = new AbortController();
321 const { signal } = ac;
322 queueMicrotask(() => ac.abort());
323 const socket = net.connect({
324 host: env.SIDECAR_HOSTNAME,
325 port: env.SERVER_PORT,
326 signal,
327 });
328 await assertAbort(socket, 'tickAbort');
329 },
330};
331 
332export const testNetConnectAbortControllerConstructor = {
333 async test() {
334 const ac = new AbortController();
335 const { signal } = ac;
336 ac.abort();
337 const socket = new net.Socket({ signal });
338 await assertAbort(socket, 'testConstructor');
339 },
340};
341 
342export const testNetConnectAbortControllerConstructorPost = {
343 async test() {
344 const ac = new AbortController();
345 const { signal } = ac;
346 const socket = new net.Socket({ signal });
347 ac.abort();
348 await assertAbort(socket, 'testConstructorPost');
349 },
350};
351 
352export const testNetConnectAbortControllerConstructorPostTick = {
353 async test() {
354 const ac = new AbortController();
355 const { signal } = ac;
356 queueMicrotask(() => ac.abort());
357 const socket = new net.Socket({ signal });
358 await assertAbort(socket, 'testConstructorPostTick');
359 },
360};
361 
362// test/parallel/test-net-connect-after-destroy.js
363export const testNetConnectAfterDestroy = {
364 async test() {
365 // Connect to something that we need to lookup, then delay
366 // the lookup so that the connect attempt happens after the
367 // destroy
368 const lookup = mock.fn((host, options, callback) => {
369 setTimeout(() => callback(null, 'localhost'), 100);
370 });
371 const c = net.connect({
372 port: 80,
373 host: 'example.org',
374 lookup,
375 });
376 c.on('connect', () => {
377 throw new Error('should not connect');
378 });
379 c.destroy();
380 strictEqual(c.destroyed, true);
381 strictEqual(lookup.mock.callCount(), 1);
382 },
383};
384 
385// test/parallel/test-net-connect-buffer.js
386export const testNetConnectBuffer = {
387 async test(ctrl, env, ctx) {
388 const { promise, resolve } = Promise.withResolvers();
389 const c = net.connect({
390 port: env.ECHO_SERVER_PORT,
391 host: env.SIDECAR_HOSTNAME,
392 highWaterMark: 0,
393 });
394 
395 strictEqual(c.pending, true);
396 strictEqual(c.connecting, true);
397 strictEqual(c.readyState, 'opening');
398 strictEqual(c.bytesWritten, 0);
399 
400 // Write a string that contains a multi-byte character sequence to test that
401 // `bytesWritten` is incremented with the # of bytes, not # of characters.
402 const a = "L'ร‰tat, c'est ";
403 const b = 'moi';
404 
405 let result = '';
406 c.setEncoding('utf8');
407 c.on('data', (chunk) => {
408 result += chunk;
409 });
410 const endFn = mock.fn(() => {
411 strictEqual(result, a + b);
412 });
413 c.on('end', endFn);
414 
415 const writeFn = mock.fn(() => {
416 strictEqual(c.pending, false);
417 strictEqual(c.connecting, false);
418 strictEqual(c.readyState, 'readOnly');
419 strictEqual(c.bytesWritten, Buffer.from(a + b).length);
420 });
421 c.write(a, writeFn);
422 
423 const closeFn = mock.fn(() => {
424 resolve();
425 });
426 c.on('close', closeFn);
427 
428 c.end(b);
429 
430 await promise;
431 strictEqual(closeFn.mock.callCount(), 1);
432 strictEqual(writeFn.mock.callCount(), 1);
433 strictEqual(endFn.mock.callCount(), 1);
434 },
435};
436 
437// test/parallel/test-net-connect-destroy.js
438export const testNetConnectDestroy = {
439 async test(ctrl, env, ctx) {
440 const { promise, resolve } = Promise.withResolvers();
441 const c = net.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME);
442 c.on('close', () => resolve());
443 c.destroy();
444 await promise;
445 },
446};
447 
448// test/parallel/test-net-connect-immediate-destroy.js
449export const testNetConnectImmediateDestroy = {
450 async test(ctrl, env, ctx) {
451 const connectFn = mock.fn();
452 const socket = net.connect(
453 env.SERVER_PORT,
454 env.SIDECAR_HOSTNAME,
455 connectFn
456 );
457 socket.destroy();
458 await Promise.resolve();
459 strictEqual(connectFn.mock.callCount(), 0);
460 },
461};
462 
463// test/parallel/test-net-connect-immediate-finish.js
464export const testNetConnectImmediateFinish = {
465 async text(ctrl, env, ctx) {
466 const { promise, resolve } = Promise.withResolvers();
467 const c = net.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME);
468 c.end();
469 c.on('finish', () => resolve());
470 await promise;
471 },
472};
473 
474// test/parallel/test-net-connect-keepalive.js
475// test/parallel/test-net-keepalive.js
476// We don't actually support keep alive so this test does
477// something different than the original Node.js test
478export const testNetConnectKeepAlive = {
479 async test() {
480 // We are not throwing on truthy keepAlive value for mysql/redis clients.
481 // throws(() => new net.Socket({ keepAlive: true }));
482 const c = new net.Socket();
483 c.setKeepAlive(false);
484 c.setKeepAlive(true);
485 // throws(() => c.setKeepAlive(true));
486 },
487};
488 
489// test/parallel/test-net-connect-memleak.js
490export const testNetConnectMemleak = {
491 async test(ctrl, env, ctx) {
492 const { promise, resolve } = Promise.withResolvers();
493 const connectFn = mock.fn(() => resolve());
494 const c = net.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME, connectFn);
495 c.emit('connect');
496 await promise;
497 strictEqual(connectFn.mock.callCount(), 1);
498 },
499};
500 
501// test/parallel/test-net-connect-no-arg.js
502export const testNetConnectNoArg = {
503 test() {
504 throws(() => net.connect(), {
505 code: 'ERR_MISSING_ARGS',
506 message: 'The "options" or "port" or "path" argument must be specified',
507 });
508 throws(() => new net.Socket().connect(), {
509 code: 'ERR_MISSING_ARGS',
510 message: 'The "options" or "port" or "path" argument must be specified',
511 });
512 throws(() => net.connect({}), {
513 code: 'ERR_MISSING_ARGS',
514 message: 'The "options" or "port" or "path" argument must be specified',
515 });
516 throws(() => new net.Socket().connect({}), {
517 code: 'ERR_MISSING_ARGS',
518 message: 'The "options" or "port" or "path" argument must be specified',
519 });
520 },
521};
522 
523// test/parallel/test-net-connect-options-allowhalfopen.js
524// Simplified version of the equivalent Node.js test
525export const testNetConnectOptionsAllowHalfOpen = {
526 async test(ctrl, env, ctx) {
527 const { promise, resolve, reject } = Promise.withResolvers();
528 const c = net.connect({
529 host: env.SIDECAR_HOSTNAME,
530 port: env.SERVER_PORT,
531 allowHalfOpen: true,
532 });
533 c.resume();
534 const writeFn = mock.fn(() => {
535 c.write('hello', (err) => {
536 if (err) reject(err);
537 resolve();
538 });
539 });
540 const endFn = mock.fn(() => {
541 strictEqual(c.readable, false);
542 strictEqual(c.writable, true);
543 queueMicrotask(writeFn);
544 });
545 c.on('end', endFn);
546 await promise;
547 },
548};
549 
550// test/parallel/test-net-connect-options-fd.js
551// We do not support the fd option so this test does something different
552// than the original Node.js test
553export const testNetConnectOptionsFd = {
554 async test() {
555 throws(() => new net.Socket({ fd: 42 }));
556 },
557};
558 
559// test/parallel/test-net-connect-options-invalid.js
560export const testNetConnectOptionsInvalid = {
561 test() {
562 ['objectMode', 'readableObjectMode', 'writableObjectMode'].forEach(
563 (invalidKey) => {
564 const option = {
565 port: 8080,
566 [invalidKey]: true,
567 };
568 const message = `The property 'options.${invalidKey}' is not supported. Received true`;
569 
570 throws(() => net.connect(option), {
571 code: 'ERR_INVALID_ARG_VALUE',
572 name: 'TypeError',
573 message: new RegExp(message),
574 });
575 }
576 );
577 },
578};
579 
580// test/parallel/test-net-connect-options-ipv6.js
581// TODO(soon): sidecar-supervisor assigns IPv4 addresses only. IPv6 support should be added.
582/*
583export const testNetConnectOptionsIpv6 = {
584 async test(ctrl, env, ctx) {
585 const { promise, resolve } = Promise.withResolvers();
586 const c = net.connect({ host: '::1', port: env.SERVER_PORT });
587 c.on('connect', () => resolve());
588 await promise;
589 },
590};
591*/
592 
593// test/parallel/test-net-connect-options-path.js
594// We do not support the path option so this test does something different
595// than the original Node.js test
596export const testNetConnectOptionsPath = {
597 async test() {
598 throws(() => net.connect({ path: '/tmp/sock' }));
599 },
600};
601 
602// test/parallel/test-net-connect-options-port.js
603// TODO(soon): Update this test.
604export const testNetConnectOptionsPort = {
605 async test() {
606 [true, false].forEach((port) => {
607 throws(() => net.connect(port), {
608 code: 'ERR_INVALID_ARG_TYPE',
609 name: 'TypeError',
610 });
611 });
612 [-1, 65537].forEach((port) => {
613 throws(() => net.connect(port), {
614 code: 'ERR_SOCKET_BAD_PORT',
615 });
616 });
617 },
618};
619 
620// test/parallel/test-net-connect-paused-connection.js
621// The original test is a bit different given that it uses unref to avoid
622// the paused connection from keeping the process alive. We don't have unref
623// so let's just make sure things clean up okay when the IoContext is destroyed.
624export const testNetConnectPausedConnection = {
625 test(ctrl, env, ctx) {
626 net.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME).pause();
627 },
628};
629 
630// test/parallel/test-net-connect-reset.js
631export const testNetConnectReset = {
632 async test() {
633 const { promise, resolve } = Promise.withResolvers();
634 const socket = new net.Socket();
635 socket.resetAndDestroy();
636 // Emit error if socket is not connecting/connected
637 socket.on('error', (err) => {
638 strictEqual(err.code, 'ERR_SOCKET_CLOSED');
639 strictEqual(err.name, 'Error');
640 resolve();
641 });
642 await promise;
643 },
644};
645 
646// test/parallel/test-net-dns-custom-lookup.js
647// test/parallel/test-net-dns-lookup.js
648export const testNetDnsCustomLookup = {
649 async test(ctrl, env, ctx) {
650 const { promise, resolve } = Promise.withResolvers();
651 const lookup = mock.fn((host, options, callback) => {
652 strictEqual(host, 'localhost');
653 strictEqual(options.family, 4);
654 queueMicrotask(() => callback(null, '127.0.0.1', 4));
655 });
656 const c = net.connect({
657 port: env.SERVER_PORT,
658 host: 'localhost',
659 lookup,
660 family: 4,
661 });
662 c.on('lookup', (err, ip, type) => {
663 strictEqual(err, null);
664 strictEqual(ip, '127.0.0.1');
665 strictEqual(type, 4);
666 resolve();
667 });
668 await promise;
669 strictEqual(lookup.mock.callCount(), 1);
670 },
671};
672 
673// test/parallel/test-net-dns-error.js
674// This test differs from original Node.js test since our error code for isValidHost
675// is different from Node.js.
676export const testNetDnsError = {
677 async test() {
678 const p1 = Promise.withResolvers();
679 const p2 = Promise.withResolvers();
680 const host = '*'.repeat(64);
681 const socket = net.connect(42, host, () =>
682 p1.reject(new Error('Should not have called'))
683 );
684 socket.on('error', function (err) {
685 strictEqual(err.name, 'TypeError');
686 strictEqual(
687 err.message,
688 'Specified address is empty string, contains unsupported characters or is too long.'
689 );
690 p1.resolve();
691 });
692 socket.on('lookup', function (err, ip, type) {
693 strictEqual(err.name, 'TypeError');
694 strictEqual(
695 err.message,
696 'Specified address is empty string, contains unsupported characters or is too long.'
697 );
698 strictEqual(ip, undefined);
699 strictEqual(type, undefined);
700 p2.resolve();
701 });
702 await Promise.all([p1, p2]);
703 },
704};
705 
706// test/parallel/test-net-dns-lookup-skip.js
707export const testNetDnsLookupSkip = {
708 async test(ctrl, env, ctx) {
709 const lookup = mock.fn();
710 [env.SIDECAR_HOSTNAME, '::1'].forEach((host) => {
711 net.connect({ host, port: env.SERVER_PORT, lookup }).destroy();
712 });
713 strictEqual(lookup.mock.callCount(), 0);
714 },
715};
716 
717// test/parallel/test-net-during-close.js
718export const testNetDuringClose = {
719 test(ctrl, env, ctx) {
720 const c = net.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME);
721 c.destroy();
722 // eslint-disable-next-line @typescript-eslint/no-unused-expressions
723 c.remoteAddress;
724 // eslint-disable-next-line @typescript-eslint/no-unused-expressions
725 c.remoteFamily;
726 // eslint-disable-next-line @typescript-eslint/no-unused-expressions
727 c.remotePort;
728 },
729};
730 
731// test/parallel/test-net-end-destroyed.js
732export const testNetEndDestroyed = {
733 async test(ctrl, env, ctx) {
734 const { promise, resolve } = Promise.withResolvers();
735 const c = net.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME);
736 c.resume();
737 
738 const endFn = mock.fn(() => {
739 strictEqual(c.destroyed, false);
740 resolve();
741 });
742 c.on('end', endFn);
743 await promise;
744 },
745};
746 
747// test/parallel/test-net-end-without-connect.js
748export const testNetEndWithoutConnect = {
749 async test() {
750 const { promise, resolve } = Promise.withResolvers();
751 const c = new net.Socket();
752 const endFn = mock.fn(() => {
753 strictEqual(c.writable, false);
754 resolve();
755 });
756 c.end(endFn);
757 await promise;
758 },
759};
760 
761// test/parallel/test-net-isip.js
762export const testNetIsIp = {
763 test() {
764 strictEqual(net.isIP('127.0.0.1'), 4);
765 strictEqual(net.isIP('x127.0.0.1'), 0);
766 strictEqual(net.isIP('example.com'), 0);
767 strictEqual(net.isIP('0000:0000:0000:0000:0000:0000:0000:0000'), 6);
768 strictEqual(net.isIP('0000:0000:0000:0000:0000:0000:0000:0000::0000'), 0);
769 strictEqual(net.isIP('1050:0:0:0:5:600:300c:326b'), 6);
770 strictEqual(net.isIP('2001:252:0:1::2008:6'), 6);
771 strictEqual(net.isIP('2001:dead:beef:1::2008:6'), 6);
772 strictEqual(net.isIP('2001::'), 6);
773 strictEqual(net.isIP('2001:dead::'), 6);
774 strictEqual(net.isIP('2001:dead:beef::'), 6);
775 strictEqual(net.isIP('2001:dead:beef:1::'), 6);
776 strictEqual(net.isIP('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 6);
777 strictEqual(net.isIP(':2001:252:0:1::2008:6:'), 0);
778 strictEqual(net.isIP(':2001:252:0:1::2008:6'), 0);
779 strictEqual(net.isIP('2001:252:0:1::2008:6:'), 0);
780 strictEqual(net.isIP('2001:252::1::2008:6'), 0);
781 strictEqual(net.isIP('::2001:252:1:2008:6'), 6);
782 strictEqual(net.isIP('::2001:252:1:1.1.1.1'), 6);
783 strictEqual(net.isIP('::2001:252:1:255.255.255.255'), 6);
784 strictEqual(net.isIP('::2001:252:1:255.255.255.255.76'), 0);
785 strictEqual(net.isIP('fe80::2008%eth0'), 6);
786 strictEqual(net.isIP('fe80::2008%eth0.0'), 6);
787 strictEqual(net.isIP('fe80::2008%eth0@1'), 0);
788 strictEqual(net.isIP('::anything'), 0);
789 strictEqual(net.isIP('::1'), 6);
790 strictEqual(net.isIP('::'), 6);
791 strictEqual(net.isIP('0000:0000:0000:0000:0000:0000:12345:0000'), 0);
792 strictEqual(net.isIP('0'), 0);
793 strictEqual(net.isIP(), 0);
794 strictEqual(net.isIP(''), 0);
795 strictEqual(net.isIP(null), 0);
796 strictEqual(net.isIP(123), 0);
797 strictEqual(net.isIP(true), 0);
798 strictEqual(net.isIP({}), 0);
799 strictEqual(
800 net.isIP({ toString: () => '::2001:252:1:255.255.255.255' }),
801 6
802 );
803 strictEqual(net.isIP({ toString: () => '127.0.0.1' }), 4);
804 strictEqual(net.isIP({ toString: () => 'bla' }), 0);
805 
806 strictEqual(net.isIPv4('127.0.0.1'), true);
807 strictEqual(net.isIPv4('example.com'), false);
808 strictEqual(net.isIPv4('2001:252:0:1::2008:6'), false);
809 strictEqual(net.isIPv4(), false);
810 strictEqual(net.isIPv4(''), false);
811 strictEqual(net.isIPv4(null), false);
812 strictEqual(net.isIPv4(123), false);
813 strictEqual(net.isIPv4(true), false);
814 strictEqual(net.isIPv4({}), false);
815 strictEqual(
816 net.isIPv4({ toString: () => '::2001:252:1:255.255.255.255' }),
817 false
818 );
819 strictEqual(net.isIPv4({ toString: () => '127.0.0.1' }), true);
820 strictEqual(net.isIPv4({ toString: () => 'bla' }), false);
821 
822 strictEqual(net.isIPv6('127.0.0.1'), false);
823 strictEqual(net.isIPv6('example.com'), false);
824 strictEqual(net.isIPv6('2001:252:0:1::2008:6'), true);
825 strictEqual(net.isIPv6(), false);
826 strictEqual(net.isIPv6(''), false);
827 strictEqual(net.isIPv6(null), false);
828 strictEqual(net.isIPv6(123), false);
829 strictEqual(net.isIPv6(true), false);
830 strictEqual(net.isIPv6({}), false);
831 strictEqual(
832 net.isIPv6({ toString: () => '::2001:252:1:255.255.255.255' }),
833 true
834 );
835 strictEqual(net.isIPv6({ toString: () => '127.0.0.1' }), false);
836 strictEqual(net.isIPv6({ toString: () => 'bla' }), false);
837 },
838};
839 
840// test/parallel/test-net-isipv4.js
841export const testNetIsIpv4 = {
842 test() {
843 const v4 = [
844 '0.0.0.0',
845 '8.8.8.8',
846 '127.0.0.1',
847 '100.100.100.100',
848 '192.168.0.1',
849 '18.101.25.153',
850 '123.23.34.2',
851 '172.26.168.134',
852 '212.58.241.131',
853 '128.0.0.0',
854 '23.71.254.72',
855 '223.255.255.255',
856 '192.0.2.235',
857 '99.198.122.146',
858 '46.51.197.88',
859 '173.194.34.134',
860 ];
861 
862 const v4not = [
863 '.100.100.100.100',
864 '100..100.100.100.',
865 '100.100.100.100.',
866 '999.999.999.999',
867 '256.256.256.256',
868 '256.100.100.100.100',
869 '123.123.123',
870 'http://123.123.123',
871 '1000.2.3.4',
872 '999.2.3.4',
873 '0000000192.168.0.200',
874 '192.168.0.2000000000',
875 ];
876 
877 for (const ip of v4) {
878 strictEqual(net.isIPv4(ip), true);
879 }
880 
881 for (const ip of v4not) {
882 strictEqual(net.isIPv4(ip), false);
883 }
884 },
885};
886 
887// test/parallel/test-net-isipv6.js
888export const testNetIsIpv6 = {
889 test() {
890 const v6 = [
891 '::',
892 '1::',
893 '::1',
894 '1::8',
895 '1::7:8',
896 '1:2:3:4:5:6:7:8',
897 '1:2:3:4:5:6::8',
898 '1:2:3:4:5:6:7::',
899 '1:2:3:4:5::7:8',
900 '1:2:3:4:5::8',
901 '1:2:3::8',
902 '1::4:5:6:7:8',
903 '1::6:7:8',
904 '1::3:4:5:6:7:8',
905 '1:2:3:4::6:7:8',
906 '1:2::4:5:6:7:8',
907 '::2:3:4:5:6:7:8',
908 '1:2::8',
909 '2001:0000:1234:0000:0000:C1C0:ABCD:0876',
910 '3ffe:0b00:0000:0000:0001:0000:0000:000a',
911 'FF02:0000:0000:0000:0000:0000:0000:0001',
912 '0000:0000:0000:0000:0000:0000:0000:0001',
913 '0000:0000:0000:0000:0000:0000:0000:0000',
914 '::ffff:192.168.1.26',
915 '2::10',
916 'ff02::1',
917 'fe80::',
918 '2002::',
919 '2001:db8::',
920 '2001:0db8:1234::',
921 '::ffff:0:0',
922 '::ffff:192.168.1.1',
923 '1:2:3:4::8',
924 '1::2:3:4:5:6:7',
925 '1::2:3:4:5:6',
926 '1::2:3:4:5',
927 '1::2:3:4',
928 '1::2:3',
929 '::2:3:4:5:6:7',
930 '::2:3:4:5:6',
931 '::2:3:4:5',
932 '::2:3:4',
933 '::2:3',
934 '::8',
935 '1:2:3:4:5:6::',
936 '1:2:3:4:5::',
937 '1:2:3:4::',
938 '1:2:3::',
939 '1:2::',
940 '1:2:3:4::7:8',
941 '1:2:3::7:8',
942 '1:2::7:8',
943 '1:2:3:4:5:6:1.2.3.4',
944 '1:2:3:4:5::1.2.3.4',
945 '1:2:3:4::1.2.3.4',
946 '1:2:3::1.2.3.4',
947 '1:2::1.2.3.4',
948 '1::1.2.3.4',
949 '1:2:3:4::5:1.2.3.4',
950 '1:2:3::5:1.2.3.4',
951 '1:2::5:1.2.3.4',
952 '1::5:1.2.3.4',
953 '1::5:11.22.33.44',
954 'fe80::217:f2ff:254.7.237.98',
955 'fe80::217:f2ff:fe07:ed62',
956 '2001:DB8:0:0:8:800:200C:417A',
957 'FF01:0:0:0:0:0:0:101',
958 '0:0:0:0:0:0:0:1',
959 '0:0:0:0:0:0:0:0',
960 '2001:DB8::8:800:200C:417A',
961 'FF01::101',
962 '0:0:0:0:0:0:13.1.68.3',
963 '0:0:0:0:0:FFFF:129.144.52.38',
964 '::13.1.68.3',
965 '::FFFF:129.144.52.38',
966 'fe80:0000:0000:0000:0204:61ff:fe9d:f156',
967 'fe80:0:0:0:204:61ff:fe9d:f156',
968 'fe80::204:61ff:fe9d:f156',
969 'fe80:0:0:0:204:61ff:254.157.241.86',
970 'fe80::204:61ff:254.157.241.86',
971 'fe80::1',
972 '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
973 '2001:db8:85a3:0:0:8a2e:370:7334',
974 '2001:db8:85a3::8a2e:370:7334',
975 '2001:0db8:0000:0000:0000:0000:1428:57ab',
976 '2001:0db8:0000:0000:0000::1428:57ab',
977 '2001:0db8:0:0:0:0:1428:57ab',
978 '2001:0db8:0:0::1428:57ab',
979 '2001:0db8::1428:57ab',
980 '2001:db8::1428:57ab',
981 '::ffff:12.34.56.78',
982 '::ffff:0c22:384e',
983 '2001:0db8:1234:0000:0000:0000:0000:0000',
984 '2001:0db8:1234:ffff:ffff:ffff:ffff:ffff',
985 '2001:db8:a::123',
986 '::ffff:192.0.2.128',
987 '::ffff:c000:280',
988 'a:b:c:d:e:f:f1:f2',
989 'a:b:c::d:e:f:f1',
990 'a:b:c::d:e:f',
991 'a:b:c::d:e',
992 'a:b:c::d',
993 '::a',
994 '::a:b:c',
995 '::a:b:c:d:e:f:f1',
996 'a::',
997 'a:b:c::',
998 'a:b:c:d:e:f:f1::',
999 'a:bb:ccc:dddd:000e:00f:0f::',
1000 '0:a:0:a:0:0:0:a',
1001 '0:a:0:0:a:0:0:a',
1002 '2001:db8:1:1:1:1:0:0',
1003 '2001:db8:1:1:1:0:0:0',
1004 '2001:db8:1:1:0:0:0:0',
1005 '2001:db8:1:0:0:0:0:0',
1006 '2001:db8:0:0:0:0:0:0',
1007 '2001:0:0:0:0:0:0:0',
1008 'A:BB:CCC:DDDD:000E:00F:0F::',
1009 '0:0:0:0:0:0:0:a',
1010 '0:0:0:0:a:0:0:0',
1011 '0:0:0:a:0:0:0:0',
1012 'a:0:0:a:0:0:a:a',
1013 'a:0:0:a:0:0:0:a',
1014 'a:0:0:0:a:0:0:a',
1015 'a:0:0:0:a:0:0:0',
1016 'a:0:0:0:0:0:0:0',
1017 'fe80::7:8%eth0',
1018 'fe80::7:8%1',
1019 ];
1020 
1021 const v6not = [
1022 '',
1023 '1:',
1024 ':1',
1025 '11:36:12',
1026 '02001:0000:1234:0000:0000:C1C0:ABCD:0876',
1027 '2001:0000:1234:0000:00001:C1C0:ABCD:0876',
1028 '2001:0000:1234: 0000:0000:C1C0:ABCD:0876',
1029 '2001:1:1:1:1:1:255Z255X255Y255',
1030 '3ffe:0b00:0000:0001:0000:0000:000a',
1031 'FF02:0000:0000:0000:0000:0000:0000:0000:0001',
1032 '3ffe:b00::1::a',
1033 '::1111:2222:3333:4444:5555:6666::',
1034 '1:2:3::4:5::7:8',
1035 '12345::6:7:8',
1036 '1::5:400.2.3.4',
1037 '1::5:260.2.3.4',
1038 '1::5:256.2.3.4',
1039 '1::5:1.256.3.4',
1040 '1::5:1.2.256.4',
1041 '1::5:1.2.3.256',
1042 '1::5:300.2.3.4',
1043 '1::5:1.300.3.4',
1044 '1::5:1.2.300.4',
1045 '1::5:1.2.3.300',
1046 '1::5:900.2.3.4',
1047 '1::5:1.900.3.4',
1048 '1::5:1.2.900.4',
1049 '1::5:1.2.3.900',
1050 '1::5:300.300.300.300',
1051 '1::5:3000.30.30.30',
1052 '1::400.2.3.4',
1053 '1::260.2.3.4',
1054 '1::256.2.3.4',
1055 '1::1.256.3.4',
1056 '1::1.2.256.4',
1057 '1::1.2.3.256',
1058 '1::300.2.3.4',
1059 '1::1.300.3.4',
1060 '1::1.2.300.4',
1061 '1::1.2.3.300',
1062 '1::900.2.3.4',
1063 '1::1.900.3.4',
1064 '1::1.2.900.4',
1065 '1::1.2.3.900',
1066 '1::300.300.300.300',
1067 '1::3000.30.30.30',
1068 '::400.2.3.4',
1069 '::260.2.3.4',
1070 '::256.2.3.4',
1071 '::1.256.3.4',
1072 '::1.2.256.4',
1073 '::1.2.3.256',
1074 '::300.2.3.4',
1075 '::1.300.3.4',
1076 '::1.2.300.4',
1077 '::1.2.3.300',
1078 '::900.2.3.4',
1079 '::1.900.3.4',
1080 '::1.2.900.4',
1081 '::1.2.3.900',
1082 '::300.300.300.300',
1083 '::3000.30.30.30',
1084 '2001:DB8:0:0:8:800:200C:417A:221',
1085 'FF01::101::2',
1086 '1111:2222:3333:4444::5555:',
1087 '1111:2222:3333::5555:',
1088 '1111:2222::5555:',
1089 '1111::5555:',
1090 '::5555:',
1091 ':::',
1092 '1111:',
1093 ':',
1094 ':1111:2222:3333:4444::5555',
1095 ':1111:2222:3333::5555',
1096 ':1111:2222::5555',
1097 ':1111::5555',
1098 ':::5555',
1099 '1.2.3.4:1111:2222:3333:4444::5555',
1100 '1.2.3.4:1111:2222:3333::5555',
1101 '1.2.3.4:1111:2222::5555',
1102 '1.2.3.4:1111::5555',
1103 '1.2.3.4::5555',
1104 '1.2.3.4::',
1105 'fe80:0000:0000:0000:0204:61ff:254.157.241.086',
1106 '123',
1107 'ldkfj',
1108 '2001::FFD3::57ab',
1109 '2001:db8:85a3::8a2e:37023:7334',
1110 '2001:db8:85a3::8a2e:370k:7334',
1111 '1:2:3:4:5:6:7:8:9',
1112 '1::2::3',
1113 '1:::3:4:5',
1114 '1:2:3::4:5:6:7:8:9',
1115 '::ffff:2.3.4',
1116 '::ffff:257.1.2.3',
1117 '::ffff:12345678901234567890.1.26',
1118 '2001:0000:1234:0000:0000:C1C0:ABCD:0876 0',
1119 '02001:0000:1234:0000:0000:C1C0:ABCD:0876',
1120 ];
1121 
1122 for (const ip of v6) {
1123 strictEqual(net.isIPv6(ip), true);
1124 }
1125 
1126 for (const ip of v6not) {
1127 strictEqual(net.isIPv6(ip), false);
1128 }
1129 },
1130};
1131 
1132// test/parallel/test-net-large-string.js
1133export const testNetLargeString = {
1134 async test(ctrl, env, ctx) {
1135 const { promise, resolve } = Promise.withResolvers();
1136 const c = net.connect(env.ECHO_SERVER_PORT, env.SIDECAR_HOSTNAME);
1137 let response = '';
1138 const size = 40 * 1024;
1139 const data = 'ใ‚'.repeat(size);
1140 c.setEncoding('utf8');
1141 c.on('data', (data) => (response += data));
1142 c.end(data);
1143 c.on('close', resolve);
1144 await promise;
1145 strictEqual(response.length, size);
1146 strictEqual(response, data);
1147 },
1148};
1149 
1150// test/parallel/test-net-local-address-port.js
1151// The localAddress information is a non-op in our implementation
1152export const testNetLocalAddressPort = {
1153 async test(ctrl, env, ctx) {
1154 const { promise, resolve } = Promise.withResolvers();
1155 const c = net.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME);
1156 c.on('connect', () => {
1157 strictEqual(c.localAddress, '0.0.0.0');
1158 strictEqual(c.localPort, 0);
1159 resolve();
1160 });
1161 await promise;
1162 },
1163};
1164 
1165// test/parallel/test-net-localerror.js
1166export const testNetLocalError = {
1167 async test() {
1168 const connect = (opts, code, type) => {
1169 throws(() => net.connect(opts), { code, name: type.name });
1170 };
1171 
1172 connect(
1173 {
1174 host: 'localhost',
1175 port: 0,
1176 localAddress: 'foobar',
1177 },
1178 'ERR_INVALID_IP_ADDRESS',
1179 TypeError
1180 );
1181 
1182 connect(
1183 {
1184 host: 'localhost',
1185 port: 0,
1186 localPort: 'foobar',
1187 },
1188 'ERR_INVALID_ARG_TYPE',
1189 TypeError
1190 );
1191 },
1192};
1193 
1194// test/parallel/test-net-onread-static-buffer.js
1195export const testNetOnReadStaticBuffer = {
1196 async test(ctrl, env, ctx) {
1197 const { promise, resolve } = Promise.withResolvers();
1198 const buffer = Buffer.alloc(1024);
1199 const fn = mock.fn((nread, buf) => {
1200 strictEqual(nread, 5);
1201 strictEqual(buf.buffer.byteLength, 1024);
1202 resolve();
1203 });
1204 const c = net.connect({
1205 port: env.ECHO_SERVER_PORT,
1206 host: env.SIDECAR_HOSTNAME,
1207 onread: {
1208 buffer,
1209 callback: fn,
1210 },
1211 });
1212 c.on('data', () => {
1213 throw new Error('Should not have failed');
1214 });
1215 c.write('hello');
1216 await promise;
1217 strictEqual(fn.mock.callCount(), 1);
1218 },
1219};
1220 
1221export const testNetReconnect = {
1222 async test(ctrl, env) {
1223 const { promise, resolve } = Promise.withResolvers();
1224 const N = 50;
1225 const client = net.connect(env.RECONNECT_SERVER_PORT, env.SIDECAR_HOSTNAME);
1226 
1227 client.setEncoding('UTF8');
1228 
1229 const onDataFn = mock.fn((chunk) => {
1230 strictEqual(chunk, 'hello\r\n');
1231 client.end();
1232 });
1233 client.on('data', onDataFn);
1234 
1235 const endFn = mock.fn(() => {});
1236 client.on('end', endFn);
1237 
1238 const closeFn = mock.fn((had_error) => {
1239 strictEqual(had_error, false);
1240 if (closeFn.mock.callCount() < N) {
1241 client.connect(env.RECONNECT_SERVER_PORT, env.SIDECAR_HOSTNAME); // reconnect
1242 } else {
1243 resolve();
1244 }
1245 });
1246 client.on('close', closeFn);
1247 
1248 await promise;
1249 strictEqual(closeFn.mock.callCount(), N + 1);
1250 strictEqual(onDataFn.mock.callCount(), N + 1);
1251 strictEqual(endFn.mock.callCount(), N + 1);
1252 },
1253};
1254 
1255// test/parallel/test-net-remote-address-port.js
1256// test/parallel/test-net-remote-address.js
1257export const testNetRemoteAddress = {
1258 async test(ctrl, env, ctx) {
1259 const { promise, resolve } = Promise.withResolvers();
1260 const c = net.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME);
1261 c.on('connect', () => {
1262 strictEqual(c.remoteAddress, env.SIDECAR_HOSTNAME);
1263 strictEqual(c.remotePort, parseInt(env.SERVER_PORT));
1264 resolve();
1265 });
1266 await promise;
1267 },
1268};
1269 
1270// // test/parallel/test-net-socket-byteswritten.js
1271export const testNetSocketBytesWritten = {
1272 async test(ctrl, env) {
1273 const { promise, resolve } = Promise.withResolvers();
1274 const socket = net.connect(env.END_SERVER_PORT, env.SIDECAR_HOSTNAME);
1275 
1276 // Cork the socket, then write twice; this should cause a writev, which
1277 // previously caused an err in the bytesWritten count.
1278 socket.cork();
1279 
1280 socket.write('one');
1281 socket.write(Buffer.from('twรธ', 'utf8'));
1282 
1283 socket.uncork();
1284 
1285 // one = 3 bytes, twรธ = 4 bytes
1286 strictEqual(socket.bytesWritten, 3 + 4);
1287 
1288 const connectFn = mock.fn(() => {
1289 strictEqual(socket.bytesWritten, 3 + 4);
1290 });
1291 socket.on('connect', connectFn);
1292 
1293 socket.on('end', function () {
1294 strictEqual(socket.bytesWritten, 3 + 4);
1295 resolve();
1296 });
1297 
1298 await promise;
1299 strictEqual(connectFn.mock.callCount(), 1);
1300 },
1301};
1302 
1303// test/parallel/test-net-socket-connect-invalid-autoselectfamily.js
1304export const testSocketConnectInvalidAutoselectFamily = {
1305 async test() {
1306 throws(
1307 () => {
1308 net.connect({ port: 8080, autoSelectFamily: 'INVALID' });
1309 },
1310 { code: 'ERR_INVALID_ARG_TYPE' }
1311 );
1312 },
1313};
1314 
1315// test/parallel/test-net-socket-connect-invalid-autoselectfamilyattempttimeout.js
1316export const testSocketConnectInvalidAutoselectFamilyTimeout = {
1317 async test() {
1318 for (const autoSelectFamilyAttemptTimeout of [-10, 0]) {
1319 throws(
1320 () => {
1321 net.connect({
1322 port: 8080,
1323 autoSelectFamily: true,
1324 autoSelectFamilyAttemptTimeout,
1325 });
1326 },
1327 { code: 'ERR_OUT_OF_RANGE' }
1328 );
1329 
1330 throws(
1331 () => {
1332 net.setDefaultAutoSelectFamilyAttemptTimeout(
1333 autoSelectFamilyAttemptTimeout
1334 );
1335 },
1336 { code: 'ERR_OUT_OF_RANGE' }
1337 );
1338 }
1339 
1340 // Check the default value of autoSelectFamilyAttemptTimeout is 10
1341 // if passed number is less than 10
1342 for (const autoSelectFamilyAttemptTimeout of [1, 9]) {
1343 net.setDefaultAutoSelectFamilyAttemptTimeout(
1344 autoSelectFamilyAttemptTimeout
1345 );
1346 strictEqual(net.getDefaultAutoSelectFamilyAttemptTimeout(), 10);
1347 }
1348 },
1349};
1350 
1351// test/parallel/test-net-socket-connect-without-cb.js
1352export const testNetSocketConnectWithoutCb = {
1353 async test(ctrl, env) {
1354 const { promise, resolve } = Promise.withResolvers();
1355 const client = new net.Socket();
1356 client.on('connect', resolve);
1357 client.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME);
1358 await promise;
1359 },
1360};
1361 
1362// test/parallel/test-net-socket-connecting.js
1363export const testNetSocketConnecting = {
1364 async test(ctrl, env) {
1365 const { promise, resolve } = Promise.withResolvers();
1366 const client = net.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME, () => {
1367 strictEqual(client.connecting, false);
1368 
1369 // Legacy getter
1370 strictEqual(client._connecting, false);
1371 resolve();
1372 });
1373 strictEqual(client.connecting, true);
1374 
1375 // Legacy getter
1376 strictEqual(client._connecting, true);
1377 await promise;
1378 },
1379};
1380 
1381// test/parallel/test-net-socket-destroy-send.js
1382export const testNetSocketDestroySend = {
1383 async test(ctrl, env) {
1384 const { promise, resolve, reject } = Promise.withResolvers();
1385 const conn = net.createConnection(env.SERVER_PORT, env.SIDECAR_HOSTNAME);
1386 
1387 conn.on('connect', function () {
1388 // Test destroy returns this, even on multiple calls when it short-circuits.
1389 strictEqual(conn, conn.destroy().destroy());
1390 conn.on('error', reject);
1391 
1392 conn.write(Buffer.from('kaboom'), (err) => {
1393 strictEqual(err.code, 'ERR_STREAM_DESTROYED');
1394 strictEqual(err.name, 'Error');
1395 strictEqual(
1396 err.message,
1397 'Cannot call write after a stream was destroyed'
1398 );
1399 resolve();
1400 });
1401 });
1402 
1403 await promise;
1404 },
1405};
1406 
1407// test/parallel/test-net-socket-end-callback.js
1408export const testNetSocketEndCallback = {
1409 async test(ctrl, env) {
1410 const { promise, resolve } = Promise.withResolvers();
1411 const connect = (...args) => {
1412 const socket = net.createConnection(
1413 env.SERVER_PORT,
1414 env.SIDECAR_HOSTNAME,
1415 () => {
1416 socket.end(...args);
1417 }
1418 );
1419 };
1420 
1421 let count = 0;
1422 const cb = mock.fn(() => {
1423 if (++count === 3) {
1424 resolve();
1425 }
1426 });
1427 
1428 connect(cb);
1429 connect('foo', cb);
1430 connect('foo', 'utf8', cb);
1431 await promise;
1432 strictEqual(cb.mock.callCount(), 3);
1433 },
1434};
1435 
1436// test/parallel/test-net-socket-no-halfopen-enforcer.js
1437export const testNetSocketNoHalfopenEnforcer = {
1438 async test() {
1439 const socket = new net.Socket({ allowHalfOpen: false });
1440 strictEqual(socket.listenerCount('end'), 1);
1441 },
1442};
1443 
1444// test/parallel/test-net-socket-ready-without-cb.js
1445export const testNetSocketReadyWithoutCb = {
1446 async test(ctrl, env) {
1447 const { promise, resolve } = Promise.withResolvers();
1448 const client = new net.Socket();
1449 client.on('ready', resolve);
1450 client.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME);
1451 await promise;
1452 },
1453};
1454 
1455// test/parallel/test-net-socket-reset-send.js
1456export const testNetSocketResetSend = {
1457 async test(ctrl, env) {
1458 const { promise, resolve, reject } = Promise.withResolvers();
1459 const conn = net.createConnection(env.SERVER_PORT, env.SIDECAR_HOSTNAME);
1460 conn.on('connect', () => {
1461 strictEqual(conn, conn.resetAndDestroy().destroy());
1462 conn.on('error', reject);
1463 
1464 conn.write(Buffer.from('fzfzfzfzfz'), (err) => {
1465 strictEqual(err.code, 'ERR_STREAM_DESTROYED');
1466 strictEqual(err.name, 'Error');
1467 strictEqual(
1468 err.message,
1469 'Cannot call write after a stream was destroyed'
1470 );
1471 resolve();
1472 });
1473 });
1474 await promise;
1475 },
1476};
1477 
1478// test/parallel/test-net-socket-timeout.js
1479export const testNetSocketTimeout = {
1480 async test(ctrl, env) {
1481 // Verify that invalid delays throw
1482 const s = new net.Socket();
1483 const nonNumericDelays = [
1484 '100',
1485 true,
1486 false,
1487 undefined,
1488 null,
1489 '',
1490 {},
1491 () => {},
1492 [],
1493 ];
1494 const badRangeDelays = [-0.001, -1, -Infinity, Infinity, NaN];
1495 const validDelays = [0, 0.001, 1, 1e6];
1496 const invalidCallbacks = [
1497 1,
1498 '100',
1499 true,
1500 false,
1501 null,
1502 {},
1503 [],
1504 Symbol('test'),
1505 ];
1506 
1507 for (let i = 0; i < nonNumericDelays.length; i++) {
1508 throws(
1509 () => {
1510 s.setTimeout(nonNumericDelays[i], () => {});
1511 },
1512 { code: 'ERR_INVALID_ARG_TYPE' },
1513 nonNumericDelays[i]
1514 );
1515 }
1516 
1517 for (let i = 0; i < badRangeDelays.length; i++) {
1518 throws(
1519 () => {
1520 s.setTimeout(badRangeDelays[i], () => {});
1521 },
1522 { code: 'ERR_OUT_OF_RANGE' },
1523 badRangeDelays[i]
1524 );
1525 }
1526 
1527 for (let i = 0; i < validDelays.length; i++) {
1528 s.setTimeout(validDelays[i], () => {});
1529 }
1530 
1531 for (let i = 0; i < invalidCallbacks.length; i++) {
1532 [0, 1].forEach((msec) =>
1533 throws(() => s.setTimeout(msec, invalidCallbacks[i]), {
1534 code: 'ERR_INVALID_ARG_TYPE',
1535 name: 'TypeError',
1536 })
1537 );
1538 }
1539 
1540 {
1541 const { promise, resolve, reject } = Promise.withResolvers();
1542 const socket = net.createConnection(
1543 env.SERVER_PORT,
1544 env.SIDECAR_HOSTNAME
1545 );
1546 strictEqual(
1547 socket.setTimeout(1, () => {
1548 socket.destroy();
1549 strictEqual(
1550 socket.setTimeout(1, () =>
1551 reject(new Error('Should not have called setTimeout callback'))
1552 ),
1553 socket
1554 );
1555 resolve();
1556 }),
1557 socket
1558 );
1559 await promise;
1560 }
1561 },
1562};
1563 
1564// test/parallel/test-net-socket-write-after-close.js
1565export const testNetSocketWriteAfterClose = {
1566 async test(ctrl, env) {
1567 {
1568 const { promise, resolve } = Promise.withResolvers();
1569 const client = net.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME, () => {
1570 client.on('error', (err) => {
1571 strictEqual(err.name, 'Error');
1572 // Node.js tests for a different error message.
1573 strictEqual(err.message, 'Socket is closed');
1574 strictEqual(err.code, 'ERR_SOCKET_CLOSED');
1575 resolve();
1576 });
1577 client._handle = null;
1578 client.write('foo');
1579 });
1580 await promise;
1581 }
1582 },
1583};
1584 
1585// test/parallel/test-net-socket-write-error.js
1586export const testNetSocketWriteError = {
1587 async test(ctrl, env) {
1588 const { promise, resolve, reject } = Promise.withResolvers();
1589 const client = net.createConnection(
1590 env.SERVER_PORT,
1591 env.SIDECAR_HOSTNAME,
1592 () => {
1593 client.on('error', reject);
1594 throws(
1595 () => {
1596 client.write(1337);
1597 },
1598 {
1599 code: 'ERR_INVALID_ARG_TYPE',
1600 name: 'TypeError',
1601 }
1602 );
1603 
1604 resolve();
1605 }
1606 );
1607 await promise;
1608 },
1609};
1610 
1611// test/parallel/test-net-sync-cork.js
1612export const testNetSyncCork = {
1613 async test(ctrl, env) {
1614 const N = 100;
1615 const buf = Buffer.alloc(2, 'a');
1616 
1617 const { promise, resolve } = Promise.withResolvers();
1618 const conn = net.connect(env.SERVER_PORT, env.SIDECAR_HOSTNAME);
1619 
1620 conn.on('connect', () => {
1621 let res = true;
1622 let i = 0;
1623 for (; i < N && res; i++) {
1624 conn.cork();
1625 conn.write(buf);
1626 res = conn.write(buf);
1627 conn.uncork();
1628 }
1629 strictEqual(i, N);
1630 resolve();
1631 });
1632 await promise;
1633 },
1634};
1635 
1636// test/parallel/test-net-timeout-no-handle.js
1637export const testNetTimeoutNoHandle = {
1638 async test() {
1639 const { promise, resolve, reject } = Promise.withResolvers();
1640 const socket = new net.Socket();
1641 socket.setTimeout(50);
1642 
1643 socket.on('timeout', () => {
1644 strictEqual(socket._handle, null);
1645 resolve();
1646 });
1647 
1648 socket.on('connect', reject);
1649 
1650 // Since the timeout is unrefed, the code will exit without this
1651 setTimeout(() => {}, 200);
1652 await promise;
1653 },
1654};
1655 
1656// test/parallel/test-net-writable.js
1657export const testNetWritable = {
1658 async test(ctrl, env) {
1659 const { promise, resolve } = Promise.withResolvers();
1660 const socket = net.connect(env.SERVER_THAT_DIES_PORT, env.SIDECAR_HOSTNAME);
1661 socket.on('end', () => {
1662 strictEqual(socket.writable, true);
1663 socket.write('hello world');
1664 resolve();
1665 });
1666 await promise;
1667 },
1668};
1669 
1670// test/parallel/test-net-write-arguments.js
1671export const testNetWriteArguments = {
1672 async test() {
1673 const socket = net.Stream({ highWaterMark: 0 });
1674 
1675 throws(
1676 () => {
1677 socket.write(null);
1678 },
1679 {
1680 code: 'ERR_STREAM_NULL_VALUES',
1681 name: 'TypeError',
1682 message: 'May not write null values to stream',
1683 }
1684 );
1685 
1686 [true, false, undefined, 1, 1.0, +Infinity, -Infinity, [], {}].forEach(
1687 (value) => {
1688 const socket = net.Stream({ highWaterMark: 0 });
1689 // We need to check the callback since 'error' will only
1690 // be emitted once per instance.
1691 throws(
1692 () => {
1693 socket.write(value);
1694 },
1695 {
1696 code: 'ERR_INVALID_ARG_TYPE',
1697 name: 'TypeError',
1698 }
1699 );
1700 }
1701 );
1702 },
1703};
1704 
1705// test/parallel/test-net-write-cb-on-destroy-before-connect.js
1706export const testNetWriteCbOnDestroyBefureConnected = {
1707 async test(ctrl, env) {
1708 const { promise, resolve } = Promise.withResolvers();
1709 const socket = new net.Socket();
1710 
1711 socket.on('connect', () => {
1712 throw new Error('Connect should not have been called');
1713 });
1714 
1715 socket.connect(Number(env.SERVER_PORT), env.SIDECAR_HOSTNAME);
1716 
1717 ok(socket.connecting);
1718 
1719 socket.write('foo', (err) => {
1720 strictEqual(err.code, 'ERR_SOCKET_CLOSED_BEFORE_CONNECTION');
1721 strictEqual(err.name, 'Error');
1722 resolve();
1723 });
1724 
1725 socket.destroy();
1726 await promise;
1727 },
1728};
1729 
1730// test/parallel/test-net-write-connect-write.js
1731export const testNetWriteConnectWrite = {
1732 async test(ctrl, env) {
1733 const { promise, resolve } = Promise.withResolvers();
1734 const conn = net.connect(env.ECHO_SERVER_PORT, env.SIDECAR_HOSTNAME);
1735 let received = '';
1736 
1737 conn.setEncoding('utf8');
1738 conn.on('connect', function () {
1739 conn.write(' after');
1740 });
1741 conn.on('data', function (buf) {
1742 received += buf;
1743 conn.end();
1744 });
1745 conn.write('before');
1746 
1747 conn.on('end', function () {
1748 strictEqual(received, 'before after');
1749 resolve();
1750 });
1751 await promise;
1752 },
1753};
1754 
1755export const testSocketAddress = {
1756 test() {
1757 // Test constructor with default options
1758 const addr1 = new net.SocketAddress();
1759 strictEqual(addr1.address, '127.0.0.1');
1760 strictEqual(addr1.port, 0);
1761 strictEqual(addr1.family, 'ipv4');
1762 strictEqual(addr1.flowlabel, 0);
1763 
1764 // Test constructor with IPv4 options
1765 const addr2 = new net.SocketAddress({
1766 address: '192.168.1.1',
1767 port: 8080,
1768 family: 'ipv4',
1769 });
1770 strictEqual(addr2.address, '192.168.1.1');
1771 strictEqual(addr2.port, 8080);
1772 strictEqual(addr2.family, 'ipv4');
1773 strictEqual(addr2.flowlabel, 0);
1774 
1775 // Test constructor with IPv6 options
1776 const addr3 = new net.SocketAddress({
1777 address: '::1',
1778 port: 3000,
1779 family: 'ipv6',
1780 flowlabel: 123,
1781 });
1782 strictEqual(addr3.address, '::1');
1783 strictEqual(addr3.port, 3000);
1784 strictEqual(addr3.family, 'ipv6');
1785 strictEqual(addr3.flowlabel, 123);
1786 
1787 // Test default IPv6 address
1788 const addr4 = new net.SocketAddress({ family: 'ipv6' });
1789 strictEqual(addr4.address, '::');
1790 strictEqual(addr4.family, 'ipv6');
1791 
1792 // Test toJSON method
1793 const addr5 = new net.SocketAddress({
1794 address: '10.0.0.1',
1795 port: 9000,
1796 family: 'ipv4',
1797 });
1798 const json = addr5.toJSON();
1799 strictEqual(json.address, '10.0.0.1');
1800 strictEqual(json.port, 9000);
1801 strictEqual(json.family, 'ipv4');
1802 strictEqual(json.flowlabel, 0);
1803 
1804 // Test isSocketAddress static method
1805 ok(net.SocketAddress.isSocketAddress(addr1));
1806 ok(net.SocketAddress.isSocketAddress(addr2));
1807 ok(!net.SocketAddress.isSocketAddress({}));
1808 ok(!net.SocketAddress.isSocketAddress(null));
1809 ok(!net.SocketAddress.isSocketAddress('string'));
1810 
1811 // Test parse static method with IPv4
1812 const parsed1 = net.SocketAddress.parse('192.168.1.100:8080');
1813 ok(parsed1);
1814 strictEqual(parsed1.address, '192.168.1.100');
1815 strictEqual(parsed1.port, 8080);
1816 strictEqual(parsed1.family, 'ipv4');
1817 
1818 // Test parse static method with IPv6
1819 const parsed2 = net.SocketAddress.parse('[::1]:3000');
1820 ok(parsed2);
1821 strictEqual(parsed2.address, '::1');
1822 strictEqual(parsed2.port, 3000);
1823 strictEqual(parsed2.family, 'ipv6');
1824 
1825 // Test parse with invalid input
1826 strictEqual(net.SocketAddress.parse('invalid'), undefined);
1827 strictEqual(net.SocketAddress.parse(''), undefined);
1828 
1829 // Test constructor validation - invalid family
1830 throws(() => new net.SocketAddress({ family: 'invalid' }), {
1831 code: 'ERR_INVALID_ARG_VALUE',
1832 });
1833 
1834 // Test constructor validation - invalid IPv4 address
1835 throws(
1836 () =>
1837 new net.SocketAddress({
1838 address: '300.300.300.300',
1839 family: 'ipv4',
1840 }),
1841 {
1842 code: 'ERR_INVALID_ADDRESS',
1843 }
1844 );
1845 
1846 // Test constructor validation - invalid IPv6 address
1847 throws(
1848 () =>
1849 new net.SocketAddress({
1850 address: 'invalid::ipv6',
1851 family: 'ipv6',
1852 }),
1853 {
1854 code: 'ERR_INVALID_ADDRESS',
1855 }
1856 );
1857 
1858 // Test constructor validation - invalid port
1859 throws(() => new net.SocketAddress({ port: -1 }), {
1860 code: 'ERR_SOCKET_BAD_PORT',
1861 });
1862 
1863 throws(() => new net.SocketAddress({ port: 65536 }), {
1864 code: 'ERR_SOCKET_BAD_PORT',
1865 });
1866 
1867 // Test family case insensitive
1868 const addr6 = new net.SocketAddress({ family: 'IPv4' });
1869 strictEqual(addr6.family, 'ipv4');
1870 
1871 const addr7 = new net.SocketAddress({ family: 'IPv6' });
1872 strictEqual(addr7.family, 'ipv6');
1873 
1874 // Test port type coercion
1875 const addr8 = new net.SocketAddress({ port: '8080' });
1876 console.log(typeof addr8.port);
1877 strictEqual(addr8.port, 8080);
1878 },
1879};
1880 
1881export const testBlockList = {
1882 test() {
1883 // Test BlockList constructor and static methods
1884 const bl = new net.BlockList();
1885 ok(net.BlockList.isBlockList(bl));
1886 ok(!net.BlockList.isBlockList({}));
1887 ok(!net.BlockList.isBlockList(null));
1888 
1889 // Test addAddress with IPv4
1890 bl.addAddress('192.168.1.1');
1891 bl.addAddress('10.0.0.1', 'ipv4');
1892 
1893 // Test check method with IPv4 addresses
1894 ok(bl.check('192.168.1.1'));
1895 ok(bl.check('10.0.0.1', 'ipv4'));
1896 ok(!bl.check('192.168.1.2'));
1897 ok(!bl.check('192.168.1.1', 'ipv6'));
1898 
1899 // Test addAddress with IPv6
1900 bl.addAddress('2001:db8::1', 'ipv6');
1901 ok(bl.check('2001:db8::1', 'ipv6'));
1902 ok(!bl.check('2001:db8::2', 'ipv6'));
1903 
1904 // Test addAddress with SocketAddress
1905 const addr1 = new net.SocketAddress({ address: '172.16.0.1', port: 80 });
1906 bl.addAddress(addr1);
1907 ok(bl.check(addr1));
1908 ok(bl.check('172.16.0.1'));
1909 
1910 // Test addRange with IPv4
1911 bl.addRange('192.168.2.1', '192.168.2.10');
1912 ok(bl.check('192.168.2.1'));
1913 ok(bl.check('192.168.2.5'));
1914 ok(bl.check('192.168.2.10'));
1915 ok(!bl.check('192.168.2.11'));
1916 ok(!bl.check('192.168.1.255'));
1917 
1918 // Test addRange with IPv6
1919 bl.addRange('2001:db8::10', '2001:db8::20', 'ipv6');
1920 ok(bl.check('2001:db8::15', 'ipv6'));
1921 ok(bl.check('2001:db8::10', 'ipv6'));
1922 ok(bl.check('2001:db8::20', 'ipv6'));
1923 ok(!bl.check('2001:db8::21', 'ipv6'));
1924 
1925 // Test addRange with SocketAddress
1926 const startAddr = new net.SocketAddress({
1927 address: '172.16.1.1',
1928 port: 80,
1929 });
1930 const endAddr = new net.SocketAddress({ address: '172.16.1.5', port: 80 });
1931 bl.addRange(startAddr, endAddr);
1932 ok(bl.check('172.16.1.3'));
1933 ok(!bl.check('172.16.1.6'));
1934 
1935 // Test addSubnet with IPv4
1936 bl.addSubnet('10.1.0.0', 24);
1937 ok(bl.check('10.1.0.1'));
1938 ok(bl.check('10.1.0.255'));
1939 ok(!bl.check('10.1.1.1'));
1940 
1941 // Test addSubnet with IPv6
1942 bl.addSubnet('2001:db8::', 32, 'ipv6');
1943 ok(bl.check('2001:db8::1', 'ipv6'));
1944 ok(bl.check('2001:db8:ffff::1', 'ipv6'));
1945 ok(!bl.check('2001:db9::1', 'ipv6'));
1946 
1947 // Test addSubnet with SocketAddress
1948 const subnetAddr = new net.SocketAddress({
1949 address: '172.17.0.0',
1950 port: 80,
1951 });
1952 bl.addSubnet(subnetAddr, 16);
1953 ok(bl.check('172.17.1.1'));
1954 ok(bl.check('172.17.255.255'));
1955 ok(!bl.check('172.18.0.1'));
1956 
1957 // Test rules getter
1958 const rules = bl.rules;
1959 ok(Array.isArray(rules));
1960 ok(rules.length > 0);
1961 ok(rules.some((rule) => rule.includes('Address: IPv4 192.168.1.1')));
1962 ok(
1963 rules.some((rule) =>
1964 rule.includes('Range: IPv4 192.168.2.1-192.168.2.10')
1965 )
1966 );
1967 ok(rules.some((rule) => rule.includes('Subnet: IPv4 10.1.0.0/24')));
1968 
1969 // Test toJSON
1970 const json = bl.toJSON();
1971 ok(Array.isArray(json));
1972 deepStrictEqual(json, rules);
1973 
1974 // Test fromJSON
1975 const bl2 = new net.BlockList();
1976 bl2.fromJSON(['Address: IPv4 203.0.113.1', 'Subnet: IPv4 198.51.100.0/24']);
1977 ok(bl2.check('203.0.113.1'));
1978 ok(bl2.check('198.51.100.100'));
1979 ok(!bl2.check('203.0.113.2'));
1980 
1981 // Test error cases
1982 throws(() => bl.addAddress(123), {
1983 code: 'ERR_INVALID_ARG_TYPE',
1984 });
1985 
1986 throws(() => bl.addAddress('invalid.ip'), {
1987 code: 'ERR_INVALID_IP_ADDRESS',
1988 });
1989 
1990 throws(() => bl.addAddress('192.168.1.1', 'invalid'), {
1991 code: 'ERR_INVALID_ARG_VALUE',
1992 });
1993 
1994 throws(() => bl.addRange('192.168.1.10', '192.168.1.1'), {
1995 code: 'ERR_INVALID_ARG_VALUE',
1996 });
1997 
1998 throws(() => bl.addSubnet('192.168.1.0', 33), {
1999 code: 'ERR_OUT_OF_RANGE',
2000 });
2001 
2002 throws(() => bl.addSubnet('192.168.1.0', -1), {
2003 code: 'ERR_OUT_OF_RANGE',
2004 });
2005 
2006 // Test IPv4-mapped IPv6 addresses
2007 bl.addAddress('192.168.10.1');
2008 ok(bl.check('::ffff:192.168.10.1', 'ipv6'));
2009 
2010 bl.addRange('192.168.11.1', '192.168.11.10');
2011 ok(bl.check('::ffff:192.168.11.5', 'ipv6'));
2012 
2013 bl.addSubnet('192.168.12.0', 24);
2014 ok(bl.check('::ffff:192.168.12.100', 'ipv6'));
2015 },
2016};