diff --git a/tests/node_compat/config.jsonc b/tests/node_compat/config.jsonc index 5acbd25dc3..04cb4e6e2d 100644 --- a/tests/node_compat/config.jsonc +++ b/tests/node_compat/config.jsonc @@ -122,6 +122,16 @@ "sequential": ["test-child-process-exit.js"] }, "tests": { + "abort": [ + "test-addon-uv-handle-leak.js" + ], + "benchmark": [ + "test-benchmark-async-hooks.js", + "test-benchmark-http.js", + "test-benchmark-http2.js", + "test-benchmark-tls.js", + "test-benchmark-worker.js" + ], "common": [ "child_process.js", "countdown.js", @@ -133,6 +143,13 @@ "internet.js", "tmpdir.js" ], + "es-module": [ + "test-cjs-prototype-pollution.js", + "test-esm-dynamic-import-mutating-fs.js", + "test-esm-loader-cache-clearing.js", + "test-esm-windows.js", + "test-vm-compile-function-lineoffset.js" + ], "fixtures": [ "a.js", "child_process_should_emit_error.js", @@ -161,12 +178,29 @@ // "test-dns.js", "test-http-https-default-ports.js" ], + "message": [ + "eval_messages.js", + "max_tick_depth.js", + "stdin_messages.js", + "util_inspect_error.js" + ], "parallel": [ + "test-arm-math-illegal-instruction.js", "test-assert-async.js", "test-assert-fail.js", "test-assert-strict-exists.js", "test-assert.js", + "test-async-hooks-run-in-async-scope-caught-exception.js", + "test-async-hooks-run-in-async-scope-this-arg.js", + "test-async-local-storage-bind.js", + "test-async-local-storage-contexts.js", + "test-async-local-storage-deep-stack.js", + "test-async-local-storage-http-multiclients.js", + "test-async-local-storage-snapshot.js", + "test-atomics-wake.js", "test-bad-unicode.js", + "test-beforeexit-event-exit.js", + "test-blob-buffer-too-large.js", "test-blocklist.js", "test-btoa-atob.js", "test-buffer-alloc.js", @@ -202,6 +236,7 @@ "test-buffer-readint.js", "test-buffer-readuint.js", "test-buffer-safe-unsafe.js", + "test-buffer-sharedarraybuffer.js", "test-buffer-slice.js", "test-buffer-slow.js", "test-buffer-swap.js", @@ -209,6 +244,7 @@ "test-buffer-tostring-range.js", "test-buffer-tostring-rangeerror.js", "test-buffer-tostring.js", + "test-buffer-write.js", "test-buffer-writedouble.js", "test-buffer-writefloat.js", "test-buffer-writeint.js", @@ -237,8 +273,10 @@ "test-child-process-execfilesync-maxbuf.js", "test-child-process-execsync-maxbuf.js", "test-child-process-flush-stdio.js", + "test-child-process-fork3.js", "test-child-process-ipc-next-tick.js", "test-child-process-kill.js", + "test-child-process-send-type-error.js", "test-child-process-set-blocking.js", "test-child-process-spawn-args.js", "test-child-process-spawn-event.js", @@ -246,49 +284,140 @@ "test-child-process-spawnsync-maxbuf.js", "test-child-process-spawnsync-validation-errors.js", "test-child-process-spawnsync.js", - // TODO(crowlKats): socket is not yet polyfilled - // "test-client-request-destroy.js", + "test-child-process-stdin-ipc.js", + "test-child-process-stdio-overlapped.js", + "test-client-request-destroy.js", + "test-cluster-uncaught-exception.js", + "test-console-assign-undefined.js", "test-console-async-write-error.js", + "test-console-formatTime.js", "test-console-group.js", "test-console-log-stdio-broken-dest.js", "test-console-log-throw-primitive.js", "test-console-no-swallow-stack-overflow.js", + "test-console-not-call-toString.js", + "test-console-self-assign.js", "test-console-sync-write-error.js", "test-console-table.js", "test-console-tty-colors.js", + "test-crypto-dh-errors.js", + "test-crypto-dh-odd-key.js", "test-crypto-dh-shared.js", "test-crypto-dh.js", + "test-crypto-domain.js", + "test-crypto-from-binary.js", "test-crypto-hash.js", "test-crypto-hkdf.js", "test-crypto-hmac.js", + "test-crypto-keygen-dh-classic.js", + "test-crypto-keygen-duplicate-deprecated-option.js", + "test-crypto-keygen-empty-passphrase-no-error.js", + "test-crypto-keygen-key-objects.js", + "test-crypto-keygen-missing-oid.js", + "test-crypto-keygen-non-standard-public-exponent.js", + "test-crypto-keygen-rfc8017-9-1.js", + "test-crypto-keygen-rfc8017-a-2-3.js", + "test-crypto-lazy-transform-writable.js", + "test-crypto-no-algorithm.js", + "test-crypto-op-during-process-exit.js", + "test-crypto-padding-aes256.js", "test-crypto-pbkdf2.js", "test-crypto-prime.js", + "test-crypto-psychic-signatures.js", + "test-crypto-publicDecrypt-fails-first-time.js", + "test-crypto-randomfillsync-regression.js", + "test-crypto-scrypt.js", "test-crypto-secret-keygen.js", "test-crypto-stream.js", + "test-crypto-subtle-zero-length.js", "test-crypto-update-encoding.js", "test-crypto-x509.js", + "test-dgram-address.js", + "test-dgram-bind-default-address.js", + "test-dgram-bind-error-repeat.js", + "test-dgram-bind.js", + "test-dgram-bytes-length.js", "test-dgram-close-during-bind.js", + "test-dgram-close-in-listening.js", + "test-dgram-close-is-not-callback.js", "test-dgram-close-signal.js", + "test-dgram-close.js", + "test-dgram-connect-send-callback-buffer-length.js", + "test-dgram-connect-send-callback-buffer.js", + "test-dgram-connect-send-callback-multi-buffer.js", + "test-dgram-connect-send-default-host.js", + "test-dgram-connect-send-empty-array.js", + "test-dgram-connect-send-empty-buffer.js", + "test-dgram-connect-send-empty-packet.js", + "test-dgram-connect-send-multi-buffer-copy.js", + "test-dgram-connect-send-multi-string-array.js", + "test-dgram-connect.js", + "test-dgram-createSocket-type.js", + "test-dgram-error-message-address.js", + "test-dgram-implicit-bind.js", + "test-dgram-listen-after-bind.js", + "test-dgram-msgsize.js", + "test-dgram-oob-buffer.js", + "test-dgram-recv-error.js", + "test-dgram-ref.js", + "test-dgram-send-bad-arguments.js", + "test-dgram-send-callback-buffer-empty-address.js", + "test-dgram-send-callback-buffer-length-empty-address.js", + "test-dgram-send-callback-buffer-length.js", + "test-dgram-send-callback-buffer.js", + "test-dgram-send-callback-multi-buffer-empty-address.js", + "test-dgram-send-callback-multi-buffer.js", + "test-dgram-send-callback-recursive.js", + "test-dgram-send-default-host.js", + "test-dgram-send-empty-array.js", + "test-dgram-send-empty-buffer.js", + "test-dgram-send-empty-packet.js", + "test-dgram-send-error.js", + "test-dgram-send-invalid-msg-type.js", + "test-dgram-send-multi-buffer-copy.js", + "test-dgram-send-multi-string-array.js", + "test-dgram-udp4.js", + "test-dgram-udp6-send-default-host.js", + "test-dgram-unref.js", + "test-diagnostics-channel-bind-store.js", "test-diagnostics-channel-has-subscribers.js", "test-diagnostics-channel-net.js", "test-diagnostics-channel-object-channel-pub-sub.js", "test-diagnostics-channel-pub-sub.js", + "test-diagnostics-channel-safe-subscriber-errors.js", "test-diagnostics-channel-symbol-named.js", "test-diagnostics-channel-sync-unsubscribe.js", "test-diagnostics-channel-tracing-channel-args-types.js", + "test-diagnostics-channel-tracing-channel-async-error.js", + "test-diagnostics-channel-tracing-channel-async.js", "test-diagnostics-channel-tracing-channel-callback-run-stores.js", "test-diagnostics-channel-tracing-channel-promise-run-stores.js", + "test-diagnostics-channel-tracing-channel-run-stores.js", "test-diagnostics-channel-tracing-channel-sync-error.js", "test-diagnostics-channel-tracing-channel-sync.js", "test-diagnostics-channel-udp.js", "test-dns-lookup.js", "test-dns-memory-error.js", + "test-dns-multi-channel.js", "test-dns-promises-exists.js", "test-dns-resolvens-typeerror.js", "test-dns-setservers-type-check.js", + "test-domain-crypto.js", + "test-domain-ee-error-listener.js", + "test-domain-nested-throw.js", + "test-domain-nested.js", + "test-domain-stack.js", + "test-domain-top-level-error-handler-clears-stack.js", + "test-dsa-fips-invalid-key.js", + "test-env-newprotomethod-remove-unnecessary-prototypes.js", + "test-error-aggregateTwoErrors.js", + "test-error-prepare-stack-trace.js", + "test-errors-aborterror.js", "test-eval-strict-referenceerror.js", "test-eval.js", + "test-event-capture-rejections.js", "test-event-emitter-add-listeners.js", + "test-event-emitter-check-listener-leaks.js", "test-event-emitter-emit-context.js", "test-event-emitter-error-monitor.js", "test-event-emitter-errors.js", @@ -297,6 +426,9 @@ "test-event-emitter-listener-count.js", "test-event-emitter-listeners-side-effects.js", "test-event-emitter-listeners.js", + "test-event-emitter-max-listeners-warning-for-null.js", + "test-event-emitter-max-listeners-warning-for-symbol.js", + "test-event-emitter-max-listeners-warning.js", "test-event-emitter-max-listeners.js", "test-event-emitter-method-names.js", "test-event-emitter-modify-in-emit.js", @@ -315,6 +447,7 @@ "test-events-once.js", "test-events-uncaught-exception-stack.js", "test-eventtarget-brandcheck.js", + "test-eventtarget-once-twice.js", "test-exception-handler.js", "test-exception-handler2.js", "test-file-read-noexist.js", @@ -325,28 +458,42 @@ "test-fs-access.js", "test-fs-append-file-sync.js", "test-fs-append-file.js", + "test-fs-buffertype-writesync.js", "test-fs-chmod-mask.js", "test-fs-chmod.js", "test-fs-chown-type-check.js", + "test-fs-close.js", + "test-fs-constants.js", "test-fs-copyfile.js", "test-fs-empty-readStream.js", + "test-fs-fmap.js", "test-fs-lchown.js", + "test-fs-long-path.js", "test-fs-mkdir.js", + "test-fs-non-number-arguments-throw.js", "test-fs-open-flags.js", "test-fs-open-mode-mask.js", "test-fs-open-no-close.js", "test-fs-open-numeric-flags.js", "test-fs-open.js", "test-fs-opendir.js", + "test-fs-promises-exists.js", "test-fs-promises-file-handle-stat.js", + "test-fs-promises-file-handle-write.js", + "test-fs-promises-readfile-empty.js", + "test-fs-promises-readfile-with-fd.js", "test-fs-promises-writefile-with-fd.js", + "test-fs-read-file-sync-hostname.js", + "test-fs-read-file-sync.js", "test-fs-read-stream-autoClose.js", "test-fs-read-stream-concurrent-reads.js", "test-fs-read-stream-double-close.js", "test-fs-read-stream-encoding.js", + "test-fs-read-stream-fd-leak.js", "test-fs-read-stream-fd.js", "test-fs-read-stream-inherit.js", "test-fs-read-stream-patch-open.js", + "test-fs-read-stream-pos.js", "test-fs-read-stream-resume.js", "test-fs-read-stream-throw-type-error.js", "test-fs-read-stream.js", @@ -356,8 +503,12 @@ "test-fs-readdir-stack-overflow.js", "test-fs-readdir.js", "test-fs-readfile-empty.js", + "test-fs-readfile-unlink.js", + "test-fs-readfile-zero-byte-liar.js", + "test-fs-readfilesync-enoent.js", "test-fs-readv-sync.js", "test-fs-readv.js", + "test-fs-ready-event-stream.js", "test-fs-realpath-native.js", "test-fs-rmdir-recursive-sync-warns-not-found.js", "test-fs-rmdir-recursive-sync-warns-on-file.js", @@ -367,33 +518,122 @@ "test-fs-rmdir-recursive-warns-on-file.js", "test-fs-rmdir-recursive.js", "test-fs-rmdir-type-check.js", + "test-fs-sir-writes-alot.js", + "test-fs-stream-construct-compat-error-read.js", + "test-fs-stream-construct-compat-graceful-fs.js", + "test-fs-stream-construct-compat-old-node.js", + "test-fs-stream-destroy-emit-error.js", + "test-fs-stream-double-close.js", + "test-fs-stream-fs-options.js", + "test-fs-stream-options.js", + "test-fs-symlink-dir-junction-relative.js", + "test-fs-timestamp-parsing-error.js", + "test-fs-truncate-clear-file-zero.js", + "test-fs-util-validateoffsetlength.js", + "test-fs-utimes-y2K38.js", "test-fs-utimes.js", + "test-fs-watch-file-enoent-after-deletion.js", + "test-fs-watch-recursive-add-file-with-url.js", + "test-fs-watch-recursive-add-file.js", + "test-fs-watch-recursive-add-folder.js", + "test-fs-watch-recursive-update-file.js", "test-fs-watchfile.js", "test-fs-write-buffer.js", "test-fs-write-file-buffer.js", "test-fs-write-file-invalid-path.js", "test-fs-write-file-sync.js", "test-fs-write-file.js", + "test-fs-write-negativeoffset.js", "test-fs-write-no-fd.js", "test-fs-write-stream-autoclose-option.js", "test-fs-write-stream-close-without-callback.js", "test-fs-write-stream-double-close.js", + "test-fs-write-stream-encoding.js", "test-fs-write-stream-end.js", "test-fs-write-stream-fs.js", + "test-fs-write-stream-patch-open.js", "test-fs-write-stream-throw-type-error.js", "test-fs-write-stream.js", "test-fs-write-sync.js", "test-fs-write.js", "test-fs-writev-sync.js", + "test-fs-writev.js", + "test-global-domexception.js", + "test-global-encoder.js", + "test-global-webcrypto.js", + "test-global-webstreams.js", "test-handle-wrap-close-abort.js", + "test-http-abort-before-end.js", + "test-http-addrequest-localaddress.js", + "test-http-agent-false.js", "test-http-agent-getname.js", + "test-http-agent-keepalive-delay.js", + "test-http-agent-maxtotalsockets.js", + "test-http-agent-no-protocol.js", + "test-http-agent-null.js", + "test-http-allow-req-after-204-res.js", + "test-http-bind-twice.js", + "test-http-buffer-sanity.js", + "test-http-chunked-smuggling.js", + "test-http-chunked.js", + "test-http-client-abort2.js", + "test-http-client-check-http-token.js", + "test-http-client-close-with-default-agent.js", + "test-http-client-default-headers-exist.js", + "test-http-client-defaults.js", + "test-http-client-encoding.js", "test-http-client-get-url.js", + "test-http-client-headers-array.js", + "test-http-client-invalid-path.js", + "test-http-client-keep-alive-hint.js", + "test-http-client-race-2.js", + "test-http-client-race.js", "test-http-client-read-in-error.js", + "test-http-client-reject-unexpected-agent.js", + "test-http-client-timeout-connect-listener.js", + "test-http-client-timeout-with-data.js", + "test-http-client-unescaped-path.js", + "test-http-client-upload-buf.js", + "test-http-client-upload.js", // TODO(lev): ClientRequest.socket is not polyfilled so this test keeps // failing //"test-http-client-set-timeout.js", + "test-http-common.js", + "test-http-contentLength0.js", + "test-http-correct-hostname.js", + "test-http-date-header.js", + "test-http-decoded-auth.js", + "test-http-default-encoding.js", + "test-http-dump-req-when-res-ends.js", + "test-http-end-throw-socket-handling.js", + "test-http-eof-on-connect.js", + "test-http-extra-response.js", + "test-http-flush-headers.js", + "test-http-full-response.js", + "test-http-head-request.js", + "test-http-head-response-has-no-body-end-implicit-headers.js", + "test-http-head-response-has-no-body-end.js", + "test-http-head-response-has-no-body.js", + "test-http-head-throw-on-response-body-write.js", + "test-http-header-obstext.js", + "test-http-header-owstext.js", + "test-http-header-read.js", "test-http-header-validators.js", + "test-http-hex-write.js", + "test-http-highwatermark.js", + "test-http-host-headers.js", + "test-http-hostname-typechecking.js", + "test-http-incoming-message-destroy.js", + "test-http-invalid-path-chars.js", + "test-http-invalidheaderfield.js", + "test-http-invalidheaderfield2.js", + "test-http-keep-alive-timeout-custom.js", + "test-http-listening.js", + "test-http-localaddress-bind-error.js", "test-http-localaddress.js", + "test-http-methods.js", + "test-http-outgoing-end-types.js", + "test-http-outgoing-finished.js", // TODO(bartlomieju): temporarily disabled while we iterate on the HTTP client // "test-http-outgoing-buffer.js", "test-http-outgoing-internal-headernames-getter.js", @@ -403,53 +643,186 @@ // "test-http-outgoing-message-inheritance.js", "test-http-outgoing-renderHeaders.js", "test-http-outgoing-settimeout.js", + "test-http-outgoing-write-types.js", + "test-http-parser-free.js", + "test-http-pause-no-dump.js", + "test-http-pause-resume-one-end.js", + "test-http-pause.js", + "test-http-pipe-fs.js", + "test-http-pipeline-requests-connection-leak.js", + "test-http-proxy.js", + "test-http-readable-data-event.js", + "test-http-request-arguments.js", + "test-http-request-dont-override-options.js", + "test-http-request-end-twice.js", + "test-http-request-end.js", + "test-http-request-invalid-method-error.js", + "test-http-request-large-payload.js", + "test-http-request-methods.js", + "test-http-res-write-end-dont-take-array.js", + "test-http-response-multiheaders.js", + "test-http-response-readable.js", + "test-http-response-writehead-returns-this.js", + "test-http-server-delete-parser.js", + "test-http-server-write-after-end.js", + "test-http-server-write-end-after-end.js", + "test-http-set-cookies.js", + "test-http-set-header-chain.js", + "test-http-status-code.js", + "test-http-status-reason-invalid-chars.js", + "test-http-uncaught-from-request-callback.js", + "test-http-url.parse-auth.js", + "test-http-url.parse-basic.js", "test-http-url.parse-https.request.js", "test-http-url.parse-only-support-http-https-protocol.js", + "test-http-url.parse-path.js", + "test-http-url.parse-post.js", + "test-http-url.parse-search.js", + "test-http-wget.js", + "test-http-write-empty-string.js", + "test-http-zerolengthbuffer.js", + "test-http2-client-request-listeners-warning.js", + "test-http2-compat-expect-handling.js", + "test-http2-compat-socket-set.js", + "test-http2-connect-options.js", + "test-http2-date-header.js", + "test-http2-dont-override.js", + "test-http2-endafterheaders.js", + "test-http2-methods.js", + "test-http2-request-response-proto.js", + "test-http2-respond-file-204.js", + "test-http2-respond-file-compat.js", + "test-http2-session-timeout.js", + "test-http2-socket-proxy.js", + "test-http2-status-code-invalid.js", + "test-http2-status-code.js", + "test-http2-stream-removelisteners-after-close.js", + "test-http2-write-empty-string.js", + "test-https-client-renegotiation-limit.js", + "test-https-connecting-to-http.js", + "test-https-foafssl.js", + "test-https-localaddress-bind-error.js", + "test-https-localaddress.js", + "test-icu-data-dir.js", + "test-icu-env.js", + "test-icu-stringwidth.js", "test-icu-transcode.js", + "test-inspector-stops-no-file.js", + "test-instanceof.js", + "test-internal-fs.js", + "test-internal-util-normalizeencoding.js", + "test-kill-segfault-freebsd.js", + "test-listen-fd-detached-inherit.js", + "test-listen-fd-detached.js", + "test-memory-usage-emfile.js", + "test-memory-usage.js", + "test-messagechannel.js", + "test-microtask-queue-integration.js", + "test-microtask-queue-run-immediate.js", + "test-microtask-queue-run.js", + "test-module-cache.js", + "test-module-circular-symlinks.js", + "test-module-isBuiltin.js", + "test-module-multi-extensions.js", + "test-module-nodemodulepaths.js", + "test-module-readonly.js", + "test-module-relative-lookup.js", "test-net-access-byteswritten.js", + "test-net-after-close.js", "test-net-autoselectfamily.js", "test-net-better-error-messages-listen-path.js", + "test-net-better-error-messages-listen.js", "test-net-better-error-messages-path.js", "test-net-better-error-messages-port-hostname.js", + "test-net-bind-twice.js", + "test-net-buffersize.js", + "test-net-bytes-written-large.js", + "test-net-can-reset-timeout.js", "test-net-connect-after-destroy.js", + "test-net-connect-call-socket-connect.js", "test-net-connect-destroy.js", "test-net-connect-immediate-destroy.js", "test-net-connect-immediate-finish.js", "test-net-connect-no-arg.js", + "test-net-connect-options-fd.js", + "test-net-connect-options-ipv6.js", + "test-net-connect-options-port.js", + "test-net-connect-paused-connection.js", + "test-net-dns-custom-lookup.js", "test-net-dns-error.js", + "test-net-dns-lookup-skip.js", + "test-net-dns-lookup.js", "test-net-during-close.js", + "test-net-eaddrinuse.js", "test-net-end-close.js", "test-net-end-without-connect.js", + "test-net-error-twice.js", "test-net-isip.js", "test-net-isipv4.js", "test-net-isipv6.js", + "test-net-keepalive.js", + "test-net-listen-after-destroying-stdin.js", "test-net-listen-close-server-callback-is-not-function.js", "test-net-listen-close-server.js", + "test-net-listen-error.js", "test-net-listen-invalid-port.js", "test-net-listening.js", + "test-net-local-address-port.js", "test-net-localerror.js", "test-net-options-lookup.js", + "test-net-pause-resume-connecting.js", + "test-net-persistent-keepalive.js", + "test-net-persistent-nodelay.js", + "test-net-persistent-ref-unref.js", "test-net-pipe-connect-errors.js", + "test-net-reconnect.js", + "test-net-remote-address-port.js", + "test-net-remote-address.js", + "test-net-server-capture-rejection.js", + "test-net-server-close.js", "test-net-server-listen-options-signal.js", "test-net-server-listen-options.js", "test-net-server-listen-path.js", "test-net-server-listen-remove-callback.js", "test-net-server-options.js", + "test-net-server-pause-on-connect.js", "test-net-server-unref-persistent.js", "test-net-server-unref.js", + "test-net-settimeout.js", + "test-net-socket-close-after-end.js", + "test-net-socket-connect-invalid-autoselectfamily.js", + "test-net-socket-connect-without-cb.js", + "test-net-socket-connecting.js", + "test-net-socket-destroy-send.js", "test-net-socket-destroy-twice.js", + "test-net-socket-end-before-connect.js", + "test-net-socket-end-callback.js", "test-net-socket-no-halfopen-enforcer.js", + "test-net-socket-ready-without-cb.js", "test-net-socket-setnodelay.js", + "test-net-socket-timeout-unref.js", + "test-net-socket-write-after-close.js", + "test-net-socket-write-error.js", + "test-net-sync-cork.js", "test-net-timeout-no-handle.js", + "test-net-writable.js", "test-net-write-arguments.js", + "test-net-write-connect-write.js", + "test-net-write-fully-async-buffer.js", + "test-net-write-fully-async-hex-string.js", + "test-net-write-slow.js", "test-next-tick-doesnt-hang.js", + "test-next-tick-domain.js", + "test-next-tick-errors.js", "test-next-tick-fixed-queue-regression.js", "test-next-tick-intentional-starvation.js", "test-next-tick-ordering.js", "test-next-tick-ordering2.js", "test-next-tick-when-exiting.js", "test-next-tick.js", + "test-no-node-snapshot.js", "test-nodeeventtarget.js", + "test-os-homedir-no-envvar.js", "test-os.js", "test-outgoing-message-destroy.js", "test-outgoing-message-pipe.js", @@ -468,15 +841,35 @@ "test-path-win32-exists.js", "test-path-zero-length-strings.js", "test-path.js", + "test-perf-gc-crash.js", + "test-performanceobserver-gc.js", + "test-pipe-return-val.js", + "test-pipe-writev.js", + "test-process-abort.js", + "test-process-argv-0.js", "test-process-beforeexit.js", "test-process-binding-internalbinding-allowlist.js", + "test-process-binding.js", + "test-process-dlopen-undefined-exports.js", + "test-process-domain-segfault.js", + "test-process-emitwarning.js", "test-process-env-allowed-flags.js", + "test-process-env-delete.js", + "test-process-env-windows-error-reset.js", "test-process-exit-from-before-exit.js", "test-process-exit-handler.js", "test-process-exit-recursive.js", "test-process-exit.js", + "test-process-getgroups.js", + "test-process-hrtime-bigint.js", "test-process-kill-pid.js", + "test-process-next-tick.js", + "test-process-no-deprecation.js", + "test-process-ppid.js", + "test-process-really-exit.js", "test-process-uptime.js", + "test-process-warning.js", + "test-promise-handled-rejection-no-warning.js", "test-promise-unhandled-silent.js", "test-promise-unhandled-throw-handler.js", "test-punycode.js", @@ -484,6 +877,14 @@ "test-querystring-maxKeys-non-finite.js", "test-querystring-multichar-separator.js", "test-querystring.js", + "test-readable-from-iterator-closing.js", + "test-readable-from.js", + "test-readable-large-hwm.js", + "test-readable-single-end.js", + "test-readline-async-iterators-destroy.js", + "test-readline-async-iterators.js", + "test-readline-carriage-return-between-chunks.js", + "test-readline-csi.js", "test-readline-emit-keypress-events.js", "test-readline-interface-escapecodetimeout.js", "test-readline-keys.js", @@ -492,7 +893,31 @@ "test-readline-set-raw-mode.js", "test-readline-undefined-columns.js", "test-readline.js", + "test-ref-unref-return.js", + "test-regression-object-prototype.js", + "test-require-invalid-package.js", + "test-require-long-path.js", + "test-require-nul.js", + "test-require-process.js", + "test-signal-handler-remove-on-exit.js", + "test-signal-handler.js", + "test-socket-address.js", + "test-socket-write-after-fin-error.js", + "test-source-map-enable.js", + "test-spawn-cmd-named-pipe.js", "test-stdin-from-file-spawn.js", + "test-stdin-hang.js", + "test-stdin-pipe-large.js", + "test-stdin-pipe-resume.js", + "test-stdin-script-child-option.js", + "test-stdio-pipe-access.js", + "test-stdio-pipe-redirect.js", + "test-stdio-pipe-stderr.js", + "test-stdio-undestroy.js", + "test-stdout-cannot-be-closed-child-process-pipe.js", + "test-stdout-pipeline-destroy.js", + "test-stdout-stderr-reading.js", + "test-stdout-stderr-write.js", "test-stream-add-abort-signal.js", "test-stream-aliases-legacy.js", "test-stream-auto-destroy.js", @@ -500,22 +925,30 @@ "test-stream-backpressure.js", "test-stream-big-packet.js", "test-stream-big-push.js", + "test-stream-catch-rejections.js", "test-stream-construct.js", + "test-stream-decoder-objectmode.js", "test-stream-destroy-event-order.js", "test-stream-duplex-destroy.js", "test-stream-duplex-end.js", "test-stream-duplex-from.js", "test-stream-duplex-props.js", "test-stream-duplex-readable-end.js", + "test-stream-duplex-readable-writable.js", "test-stream-duplex-writable-finished.js", "test-stream-duplex.js", + "test-stream-end-of-streams.js", "test-stream-end-paused.js", "test-stream-error-once.js", "test-stream-events-prepend.js", + "test-stream-filter.js", + "test-stream-flatMap.js", + "test-stream-forEach.js", "test-stream-inheritance.js", "test-stream-ispaused.js", "test-stream-objectmode-undefined.js", "test-stream-once-readable-pipe.js", + "test-stream-passthrough-drain.js", "test-stream-pipe-after-end.js", "test-stream-pipe-await-drain-manual-resume.js", "test-stream-pipe-await-drain-push-while-write.js", @@ -523,6 +956,7 @@ "test-stream-pipe-cleanup-pause.js", "test-stream-pipe-cleanup.js", "test-stream-pipe-error-handling.js", + "test-stream-pipe-error-unhandled.js", "test-stream-pipe-event.js", "test-stream-pipe-flow-after-unpipe.js", "test-stream-pipe-flow.js", @@ -533,8 +967,12 @@ "test-stream-pipe-unpipe-streams.js", "test-stream-pipe-without-listenerCount.js", "test-stream-pipeline-async-iterator.js", + "test-stream-pipeline-duplex.js", + "test-stream-pipeline-listeners.js", "test-stream-pipeline-queued-end-in-destroy.js", + "test-stream-pipeline-uncaught.js", "test-stream-pipeline-with-empty-string.js", + "test-stream-push-order.js", "test-stream-push-strings.js", "test-stream-readable-aborted.js", "test-stream-readable-add-chunk-during-data.js", @@ -566,15 +1004,21 @@ "test-stream-readable-resumeScheduled.js", "test-stream-readable-setEncoding-existing-buffers.js", "test-stream-readable-setEncoding-null.js", + "test-stream-readable-strategy-option.js", + "test-stream-readable-unpipe-resume.js", "test-stream-readable-unshift.js", "test-stream-readable-with-unimplemented-_read.js", "test-stream-readableListening-state.js", + "test-stream-reduce.js", + "test-stream-toArray.js", + "test-stream-toWeb-allows-server-response.js", "test-stream-transform-callback-twice.js", "test-stream-transform-constructor-set-methods.js", "test-stream-transform-destroy.js", "test-stream-transform-final-sync.js", "test-stream-transform-final.js", "test-stream-transform-flush-data.js", + "test-stream-transform-hwm0.js", "test-stream-transform-objectmode-falsey-value.js", "test-stream-transform-split-highwatermark.js", "test-stream-transform-split-objectmode.js", @@ -589,6 +1033,7 @@ "test-stream-writable-decoded-encoding.js", "test-stream-writable-destroy.js", "test-stream-writable-end-cb-error.js", + "test-stream-writable-end-cb-uncaught.js", "test-stream-writable-end-multiple.js", "test-stream-writable-ended-state.js", "test-stream-writable-final-async.js", @@ -616,6 +1061,7 @@ "test-stream2-basic.js", "test-stream2-compatibility.js", "test-stream2-decode-partial.js", + "test-stream2-finish-pipe-error.js", "test-stream2-finish-pipe.js", "test-stream2-large-read-stall.js", "test-stream2-objects.js", @@ -638,24 +1084,60 @@ "test-stream3-cork-end.js", "test-stream3-cork-uncork.js", "test-stream3-pause-then-read.js", + "test-stream3-pipeline-async-iterator.js", "test-streams-highwatermark.js", "test-string-decoder.js", + "test-stringbytes-external.js", + "test-sync-fileread.js", + "test-sys.js", + "test-tick-processor-arguments.js", "test-timers-api-refs.js", "test-timers-args.js", "test-timers-clear-null-does-not-throw-error.js", "test-timers-clear-object-does-not-throw-error.js", "test-timers-clear-timeout-interval-equivalent.js", + "test-timers-clearImmediate-als.js", "test-timers-clearImmediate.js", + "test-timers-immediate-queue.js", + "test-timers-immediate.js", "test-timers-interval-throw.js", "test-timers-non-integer-delay.js", + "test-timers-refresh-in-callback.js", "test-timers-refresh.js", "test-timers-same-timeout-wrong-list-deleted.js", + "test-timers-setimmediate-infinite-loop.js", + "test-timers-socket-timeout-removes-other-socket-unref-timer.js", "test-timers-timeout-with-non-integer.js", "test-timers-uncaught-exception.js", "test-timers-unref-throw-then-ref.js", + "test-timers-unref.js", + "test-timers-unrefd-interval-still-fires.js", + "test-timers-unrefed-in-beforeexit.js", + "test-timers-unrefed-in-callback.js", "test-timers-user-call.js", "test-timers-zero-timeout.js", + "test-timers.js", + "test-tls-alert-handling.js", + "test-tls-alert.js", + "test-tls-client-renegotiation-limit.js", + "test-tls-dhe.js", + "test-tls-ecdh-auto.js", + "test-tls-ecdh-multiple.js", + "test-tls-ecdh.js", + "test-tls-enable-trace-cli.js", + "test-tls-enable-trace.js", + "test-tls-env-extra-ca-no-crypto.js", + "test-tls-ocsp-callback.js", + "test-tls-psk-server.js", + "test-tls-securepair-server.js", + "test-tls-server-verify.js", + "test-tls-session-cache.js", + "test-tls-set-ciphers.js", + "test-tls-transport-destroy-after-own-gc.js", + "test-trace-events-async-hooks-dynamic.js", + "test-trace-events-async-hooks-worker.js", "test-tty-stdin-end.js", + "test-tz-version.js", "test-url-domain-ascii-unicode.js", "test-url-fileurltopath.js", "test-url-format-invalid-input.js", @@ -666,19 +1148,31 @@ "test-url-pathtofileurl.js", "test-url-relative.js", "test-url-urltooptions.js", + "test-utf8-scripts.js", "test-util-deprecate-invalid-code.js", "test-util-deprecate.js", "test-util-format.js", "test-util-inherits.js", + "test-util-inspect-getters-accessing-this.js", "test-util-inspect-long-running.js", "test-util-inspect-namespace.js", "test-util-inspect-proxy.js", "test-util-inspect.js", "test-util-isDeepStrictEqual.js", + "test-util-primordial-monkeypatching.js", "test-util-promisify.js", "test-util-types-exists.js", "test-util-types.js", "test-util.js", + "test-uv-binding-constant.js", + "test-uv-unmapped-exception.js", + "test-v8-coverage.js", + "test-v8-deserialize-buffer.js", + "test-v8-flag-pool-size-0.js", + "test-v8-global-setter.js", + "test-v8-stop-coverage.js", + "test-v8-take-coverage-noop.js", + "test-v8-take-coverage.js", "test-vm-access-process-env.js", "test-vm-attributes-property-not-on-sandbox.js", "test-vm-codegen.js", @@ -723,28 +1217,39 @@ "test-vm-timeout-escape-promise-2.js", "test-vm-timeout-escape-promise.js", "test-vm-timeout.js", + "test-weakref.js", + "test-webcrypto-encrypt-decrypt.js", "test-webcrypto-sign-verify.js", + "test-websocket.js", + "test-webstream-string-tag.js", "test-whatwg-encoding-custom-api-basics.js", "test-whatwg-encoding-custom-textdecoder-ignorebom.js", "test-whatwg-encoding-custom-textdecoder-streaming.js", "test-whatwg-events-add-event-listener-options-passive.js", "test-whatwg-events-add-event-listener-options-signal.js", "test-whatwg-events-customevent.js", + "test-whatwg-readablebytestreambyob.js", "test-whatwg-url-custom-deepequal.js", "test-whatwg-url-custom-global.js", "test-whatwg-url-custom-href-side-effect.js", "test-whatwg-url-custom-tostringtag.js", "test-whatwg-url-override-hostname.js", "test-whatwg-url-properties.js", + "test-worker-cleanexit-with-js.js", "test-worker-message-port-infinite-message-loop.js", "test-worker-message-port-multiple-sharedarraybuffers.js", "test-worker-message-port-receive-message.js", + "test-worker-on-process-exit.js", + "test-worker-ref-onexit.js", + "test-worker-terminate-unrefed.js", "test-zlib-close-after-error.js", "test-zlib-close-after-write.js", "test-zlib-convenience-methods.js", + "test-zlib-create-raw.js", "test-zlib-deflate-raw-inherits.js", "test-zlib-destroy-pipe.js", "test-zlib-empty-buffer.js", + "test-zlib-flush-write-sync-interleaved.js", "test-zlib-from-string.js", "test-zlib-invalid-input.js", "test-zlib-no-stream.js", @@ -762,14 +1267,41 @@ "console-dumb-tty.js", "no_dropped_stdio.js", "no_interleaved_stdio.js", + "test-set-raw-mode-reset-process-exit.js", + "test-set-raw-mode-reset.js", "test-tty-color-support-warning-2.js", "test-tty-color-support-warning.js", + "test-tty-stdin-call-end.js", "test-tty-stdin-end.js", "test-tty-stdout-end.js" ], - "pummel": [], + "pummel": [ + "test-crypto-dh-hash.js", + "test-crypto-timing-safe-equal-benchmarks.js", + "test-dh-regr.js", + "test-fs-largefile.js", + "test-fs-readfile-tostring-fail.js", + "test-fs-watch-system-limit.js", + "test-heapsnapshot-near-heap-limit-big.js", + "test-net-many-clients.js", + "test-net-pingpong-delay.js", + "test-process-cpuUsage.js", + "test-stream-pipe-multi.js" + ], "sequential": [ - "test-child-process-exit.js" + "test-buffer-creation-regression.js", + "test-child-process-exit.js", + "test-http-server-keep-alive-timeout-slow-server.js", + "test-net-better-error-messages-port.js", + "test-net-connect-handle-econnrefused.js", + "test-net-connect-local-error.js", + "test-net-reconnect-error.js", + "test-net-response-size.js", + "test-net-server-bind.js", + "test-tls-lookup.js", + "test-tls-psk-client.js", + "test-tls-securepair-client.js", + "test-tls-session-timeout.js" ] }, "windowsIgnore": { diff --git a/tests/node_compat/runner/TODO.md b/tests/node_compat/runner/TODO.md index 116226d8a0..f6393a5e1f 100644 --- a/tests/node_compat/runner/TODO.md +++ b/tests/node_compat/runner/TODO.md @@ -1,7 +1,7 @@ # Remaining Node Tests -595 tests out of 3681 have been ported from Node 20.11.1 (16.16% ported, 83.94% remaining). +1120 tests out of 3681 have been ported from Node 20.11.1 (30.43% ported, 69.68% remaining). NOTE: This file should not be manually edited. Please edit `tests/node_compat/config.json` and run `deno task setup` in `tests/node_compat/runner` dir instead. @@ -9,7 +9,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [abort/test-abort-fatal-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/abort/test-abort-fatal-error.js) - [abort/test-abort-uncaught-exception.js](https://github.com/nodejs/node/tree/v20.11.1/test/abort/test-abort-uncaught-exception.js) - [abort/test-addon-register-signal-handler.js](https://github.com/nodejs/node/tree/v20.11.1/test/abort/test-addon-register-signal-handler.js) -- [abort/test-addon-uv-handle-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/abort/test-addon-uv-handle-leak.js) - [abort/test-http-parser-consume.js](https://github.com/nodejs/node/tree/v20.11.1/test/abort/test-http-parser-consume.js) - [abort/test-process-abort-exitcode.js](https://github.com/nodejs/node/tree/v20.11.1/test/abort/test-process-abort-exitcode.js) - [abort/test-signal-handler.js](https://github.com/nodejs/node/tree/v20.11.1/test/abort/test-signal-handler.js) @@ -17,7 +16,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [abort/test-zlib-invalid-internals-usage.js](https://github.com/nodejs/node/tree/v20.11.1/test/abort/test-zlib-invalid-internals-usage.js) - [benchmark/test-bechmark-readline.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-bechmark-readline.js) - [benchmark/test-benchmark-assert.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-assert.js) -- [benchmark/test-benchmark-async-hooks.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-async-hooks.js) - [benchmark/test-benchmark-blob.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-blob.js) - [benchmark/test-benchmark-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-buffer.js) - [benchmark/test-benchmark-child-process.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-child-process.js) @@ -30,8 +28,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [benchmark/test-benchmark-esm.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-esm.js) - [benchmark/test-benchmark-events.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-events.js) - [benchmark/test-benchmark-fs.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-fs.js) -- [benchmark/test-benchmark-http.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-http.js) -- [benchmark/test-benchmark-http2.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-http2.js) - [benchmark/test-benchmark-mime.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-mime.js) - [benchmark/test-benchmark-misc.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-misc.js) - [benchmark/test-benchmark-module.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-module.js) @@ -45,19 +41,16 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [benchmark/test-benchmark-streams.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-streams.js) - [benchmark/test-benchmark-string_decoder.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-string_decoder.js) - [benchmark/test-benchmark-timers.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-timers.js) -- [benchmark/test-benchmark-tls.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-tls.js) - [benchmark/test-benchmark-url.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-url.js) - [benchmark/test-benchmark-util.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-util.js) - [benchmark/test-benchmark-v8.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-v8.js) - [benchmark/test-benchmark-validators.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-validators.js) - [benchmark/test-benchmark-vm.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-vm.js) - [benchmark/test-benchmark-webstreams.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-webstreams.js) -- [benchmark/test-benchmark-worker.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-worker.js) - [benchmark/test-benchmark-zlib.js](https://github.com/nodejs/node/tree/v20.11.1/test/benchmark/test-benchmark-zlib.js) - [es-module/test-cjs-esm-warn.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-cjs-esm-warn.js) - [es-module/test-cjs-legacyMainResolve-permission.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-cjs-legacyMainResolve-permission.js) - [es-module/test-cjs-legacyMainResolve.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-cjs-legacyMainResolve.js) -- [es-module/test-cjs-prototype-pollution.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-cjs-prototype-pollution.js) - [es-module/test-dynamic-import-script-lifetime.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-dynamic-import-script-lifetime.js) - [es-module/test-esm-assertionless-json-import.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-assertionless-json-import.js) - [es-module/test-esm-cjs-builtins.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-cjs-builtins.js) @@ -66,7 +59,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [es-module/test-esm-data-urls.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-data-urls.js) - [es-module/test-esm-dynamic-import-attribute.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-dynamic-import-attribute.js) - [es-module/test-esm-dynamic-import-commonjs.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-dynamic-import-commonjs.js) -- [es-module/test-esm-dynamic-import-mutating-fs.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-dynamic-import-mutating-fs.js) - [es-module/test-esm-dynamic-import.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-dynamic-import.js) - [es-module/test-esm-encoded-path-native.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-encoded-path-native.js) - [es-module/test-esm-error-cache.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-error-cache.js) @@ -74,7 +66,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [es-module/test-esm-import-attributes-validation.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-import-attributes-validation.js) - [es-module/test-esm-invalid-data-urls.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-invalid-data-urls.js) - [es-module/test-esm-invalid-pjson.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-invalid-pjson.js) -- [es-module/test-esm-loader-cache-clearing.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-loader-cache-clearing.js) - [es-module/test-esm-loader-modulemap.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-loader-modulemap.js) - [es-module/test-esm-loader-search.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-loader-search.js) - [es-module/test-esm-named-exports.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-named-exports.js) @@ -89,10 +80,8 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [es-module/test-esm-undefined-cjs-global-like-variables.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-undefined-cjs-global-like-variables.js) - [es-module/test-esm-unknown-extension.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-unknown-extension.js) - [es-module/test-esm-url-extname.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-url-extname.js) -- [es-module/test-esm-windows.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-esm-windows.js) - [es-module/test-loaders-hidden-from-users.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-loaders-hidden-from-users.js) - [es-module/test-vm-compile-function-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-vm-compile-function-leak.js) -- [es-module/test-vm-compile-function-lineoffset.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-vm-compile-function-lineoffset.js) - [es-module/test-vm-contextified-script-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-vm-contextified-script-leak.js) - [es-module/test-vm-source-text-module-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-vm-source-text-module-leak.js) - [es-module/test-vm-synthetic-module-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/es-module/test-vm-synthetic-module-leak.js) @@ -147,19 +136,14 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [known_issues/test-vm-timeout-escape-nexttick.js](https://github.com/nodejs/node/tree/v20.11.1/test/known_issues/test-vm-timeout-escape-nexttick.js) - [known_issues/test-vm-timeout-escape-queuemicrotask.js](https://github.com/nodejs/node/tree/v20.11.1/test/known_issues/test-vm-timeout-escape-queuemicrotask.js) - [message/assert_throws_stack.js](https://github.com/nodejs/node/tree/v20.11.1/test/message/assert_throws_stack.js) -- [message/eval_messages.js](https://github.com/nodejs/node/tree/v20.11.1/test/message/eval_messages.js) - [message/internal_assert.js](https://github.com/nodejs/node/tree/v20.11.1/test/message/internal_assert.js) - [message/internal_assert_fail.js](https://github.com/nodejs/node/tree/v20.11.1/test/message/internal_assert_fail.js) -- [message/max_tick_depth.js](https://github.com/nodejs/node/tree/v20.11.1/test/message/max_tick_depth.js) - [message/nexttick_throw.js](https://github.com/nodejs/node/tree/v20.11.1/test/message/nexttick_throw.js) -- [message/stdin_messages.js](https://github.com/nodejs/node/tree/v20.11.1/test/message/stdin_messages.js) - [message/util-inspect-error-cause.js](https://github.com/nodejs/node/tree/v20.11.1/test/message/util-inspect-error-cause.js) -- [message/util_inspect_error.js](https://github.com/nodejs/node/tree/v20.11.1/test/message/util_inspect_error.js) - [parallel/test-abortcontroller.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-abortcontroller.js) - [parallel/test-aborted-util.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-aborted-util.js) - [parallel/test-abortsignal-cloneable.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-abortsignal-cloneable.js) - [parallel/test-accessor-properties.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-accessor-properties.js) -- [parallel/test-arm-math-illegal-instruction.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-arm-math-illegal-instruction.js) - [parallel/test-assert-builtins-not-read-from-filesystem.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-assert-builtins-not-read-from-filesystem.js) - [parallel/test-assert-calltracker-calls.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-assert-calltracker-calls.js) - [parallel/test-assert-calltracker-getCalls.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-assert-calltracker-getCalls.js) @@ -196,20 +180,13 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-async-hooks-promise-triggerid.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-hooks-promise-triggerid.js) - [parallel/test-async-hooks-promise.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-hooks-promise.js) - [parallel/test-async-hooks-recursive-stack-runInAsyncScope.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-hooks-recursive-stack-runInAsyncScope.js) -- [parallel/test-async-hooks-run-in-async-scope-caught-exception.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-hooks-run-in-async-scope-caught-exception.js) -- [parallel/test-async-hooks-run-in-async-scope-this-arg.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-hooks-run-in-async-scope-this-arg.js) - [parallel/test-async-hooks-top-level-clearimmediate.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-hooks-top-level-clearimmediate.js) - [parallel/test-async-hooks-vm-gc.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-hooks-vm-gc.js) - [parallel/test-async-hooks-worker-asyncfn-terminate-1.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-hooks-worker-asyncfn-terminate-1.js) - [parallel/test-async-hooks-worker-asyncfn-terminate-2.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-hooks-worker-asyncfn-terminate-2.js) - [parallel/test-async-hooks-worker-asyncfn-terminate-3.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-hooks-worker-asyncfn-terminate-3.js) - [parallel/test-async-hooks-worker-asyncfn-terminate-4.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-hooks-worker-asyncfn-terminate-4.js) -- [parallel/test-async-local-storage-bind.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-local-storage-bind.js) -- [parallel/test-async-local-storage-contexts.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-local-storage-contexts.js) -- [parallel/test-async-local-storage-deep-stack.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-local-storage-deep-stack.js) - [parallel/test-async-local-storage-exit-does-not-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-local-storage-exit-does-not-leak.js) -- [parallel/test-async-local-storage-http-multiclients.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-local-storage-http-multiclients.js) -- [parallel/test-async-local-storage-snapshot.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-local-storage-snapshot.js) - [parallel/test-async-wrap-constructor.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-wrap-constructor.js) - [parallel/test-async-wrap-destroyid.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-wrap-destroyid.js) - [parallel/test-async-wrap-pop-id-during-load.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-wrap-pop-id-during-load.js) @@ -218,12 +195,9 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-async-wrap-trigger-id.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-wrap-trigger-id.js) - [parallel/test-async-wrap-uncaughtexception.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-async-wrap-uncaughtexception.js) - [parallel/test-asyncresource-bind.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-asyncresource-bind.js) -- [parallel/test-atomics-wake.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-atomics-wake.js) - [parallel/test-bash-completion.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-bash-completion.js) -- [parallel/test-beforeexit-event-exit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-beforeexit-event-exit.js) - [parallel/test-benchmark-cli.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-benchmark-cli.js) - [parallel/test-binding-constants.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-binding-constants.js) -- [parallel/test-blob-buffer-too-large.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-blob-buffer-too-large.js) - [parallel/test-blob-createobjecturl.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-blob-createobjecturl.js) - [parallel/test-blob-file-backed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-blob-file-backed.js) - [parallel/test-blob.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-blob.js) @@ -241,8 +215,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-buffer-pool-untransferable.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-buffer-pool-untransferable.js) - [parallel/test-buffer-prototype-inspect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-buffer-prototype-inspect.js) - [parallel/test-buffer-set-inspect-max-bytes.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-buffer-set-inspect-max-bytes.js) -- [parallel/test-buffer-sharedarraybuffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-buffer-sharedarraybuffer.js) -- [parallel/test-buffer-write.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-buffer-write.js) - [parallel/test-c-ares.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-c-ares.js) - [parallel/test-child-process-advanced-serialization-largebuffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-advanced-serialization-largebuffer.js) - [parallel/test-child-process-advanced-serialization.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-advanced-serialization.js) @@ -283,7 +255,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-child-process-fork-stdio.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-fork-stdio.js) - [parallel/test-child-process-fork-timeout-kill-signal.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-fork-timeout-kill-signal.js) - [parallel/test-child-process-fork.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-fork.js) -- [parallel/test-child-process-fork3.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-fork3.js) - [parallel/test-child-process-http-socket-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-http-socket-leak.js) - [parallel/test-child-process-internal.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-internal.js) - [parallel/test-child-process-ipc.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-ipc.js) @@ -296,7 +267,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-child-process-send-cb.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-send-cb.js) - [parallel/test-child-process-send-keep-open.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-send-keep-open.js) - [parallel/test-child-process-send-returns-boolean.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-send-returns-boolean.js) -- [parallel/test-child-process-send-type-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-send-type-error.js) - [parallel/test-child-process-send-utf8.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-send-utf8.js) - [parallel/test-child-process-server-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-server-close.js) - [parallel/test-child-process-silent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-silent.js) @@ -311,12 +281,10 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-child-process-spawnsync-kill-signal.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-spawnsync-kill-signal.js) - [parallel/test-child-process-spawnsync-shell.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-spawnsync-shell.js) - [parallel/test-child-process-spawnsync-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-spawnsync-timeout.js) -- [parallel/test-child-process-stdin-ipc.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-stdin-ipc.js) - [parallel/test-child-process-stdin.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-stdin.js) - [parallel/test-child-process-stdio-big-write-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-stdio-big-write-end.js) - [parallel/test-child-process-stdio-inherit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-stdio-inherit.js) - [parallel/test-child-process-stdio-merge-stdouts-into-cat.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-stdio-merge-stdouts-into-cat.js) -- [parallel/test-child-process-stdio-overlapped.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-stdio-overlapped.js) - [parallel/test-child-process-stdio-reuse-readable-stdio.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-stdio-reuse-readable-stdio.js) - [parallel/test-child-process-stdio.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-stdio.js) - [parallel/test-child-process-stdout-flush-exit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-child-process-stdout-flush-exit.js) @@ -338,7 +306,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-cli-syntax-eval.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-cli-syntax-eval.js) - [parallel/test-cli-syntax-piped-bad.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-cli-syntax-piped-bad.js) - [parallel/test-cli-syntax-piped-good.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-cli-syntax-piped-good.js) -- [parallel/test-client-request-destroy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-client-request-destroy.js) - [parallel/test-cluster-accept-fail.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-cluster-accept-fail.js) - [parallel/test-cluster-advanced-serialization.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-cluster-advanced-serialization.js) - [parallel/test-cluster-basic.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-cluster-basic.js) @@ -403,7 +370,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-cluster-shared-handle-bind-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-cluster-shared-handle-bind-error.js) - [parallel/test-cluster-shared-handle-bind-privileged-port.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-cluster-shared-handle-bind-privileged-port.js) - [parallel/test-cluster-shared-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-cluster-shared-leak.js) -- [parallel/test-cluster-uncaught-exception.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-cluster-uncaught-exception.js) - [parallel/test-cluster-worker-constructor.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-cluster-worker-constructor.js) - [parallel/test-cluster-worker-death.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-cluster-worker-death.js) - [parallel/test-cluster-worker-destroy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-cluster-worker-destroy.js) @@ -426,15 +392,11 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-common-gc.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-common-gc.js) - [parallel/test-common-must-not-call.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-common-must-not-call.js) - [parallel/test-common.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-common.js) -- [parallel/test-console-assign-undefined.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-console-assign-undefined.js) - [parallel/test-console-clear.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-console-clear.js) - [parallel/test-console-count.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-console-count.js) -- [parallel/test-console-formatTime.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-console-formatTime.js) - [parallel/test-console-instance.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-console-instance.js) - [parallel/test-console-issue-43095.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-console-issue-43095.js) - [parallel/test-console-methods.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-console-methods.js) -- [parallel/test-console-not-call-toString.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-console-not-call-toString.js) -- [parallel/test-console-self-assign.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-console-self-assign.js) - [parallel/test-console-stdio-setters.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-console-stdio-setters.js) - [parallel/test-console.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-console.js) - [parallel/test-constants.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-constants.js) @@ -451,22 +413,18 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-crypto-des3-wrap.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-des3-wrap.js) - [parallel/test-crypto-dh-constructor.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-dh-constructor.js) - [parallel/test-crypto-dh-curves.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-dh-curves.js) -- [parallel/test-crypto-dh-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-dh-errors.js) - [parallel/test-crypto-dh-generate-keys.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-dh-generate-keys.js) - [parallel/test-crypto-dh-group-setters.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-dh-group-setters.js) - [parallel/test-crypto-dh-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-dh-leak.js) - [parallel/test-crypto-dh-modp2-views.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-dh-modp2-views.js) - [parallel/test-crypto-dh-modp2.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-dh-modp2.js) -- [parallel/test-crypto-dh-odd-key.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-dh-odd-key.js) - [parallel/test-crypto-dh-padding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-dh-padding.js) - [parallel/test-crypto-dh-stateless.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-dh-stateless.js) -- [parallel/test-crypto-domain.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-domain.js) - [parallel/test-crypto-domains.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-domains.js) - [parallel/test-crypto-ecb.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-ecb.js) - [parallel/test-crypto-ecdh-convert-key.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-ecdh-convert-key.js) - [parallel/test-crypto-encoding-validation-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-encoding-validation-error.js) - [parallel/test-crypto-fips.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-fips.js) -- [parallel/test-crypto-from-binary.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-from-binary.js) - [parallel/test-crypto-getcipherinfo.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-getcipherinfo.js) - [parallel/test-crypto-hash-stream-pipe.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-hash-stream-pipe.js) - [parallel/test-crypto-key-objects-messageport.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-key-objects-messageport.js) @@ -487,41 +445,24 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-crypto-keygen-async-rsa.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-async-rsa.js) - [parallel/test-crypto-keygen-bit-length.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-bit-length.js) - [parallel/test-crypto-keygen-deprecation.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-deprecation.js) -- [parallel/test-crypto-keygen-dh-classic.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-dh-classic.js) -- [parallel/test-crypto-keygen-duplicate-deprecated-option.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-duplicate-deprecated-option.js) - [parallel/test-crypto-keygen-eddsa.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-eddsa.js) -- [parallel/test-crypto-keygen-empty-passphrase-no-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-empty-passphrase-no-error.js) - [parallel/test-crypto-keygen-empty-passphrase-no-prompt.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-empty-passphrase-no-prompt.js) - [parallel/test-crypto-keygen-invalid-parameter-encoding-dsa.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-invalid-parameter-encoding-dsa.js) - [parallel/test-crypto-keygen-invalid-parameter-encoding-ec.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-invalid-parameter-encoding-ec.js) - [parallel/test-crypto-keygen-key-object-without-encoding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-key-object-without-encoding.js) -- [parallel/test-crypto-keygen-key-objects.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-key-objects.js) -- [parallel/test-crypto-keygen-missing-oid.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-missing-oid.js) - [parallel/test-crypto-keygen-no-rsassa-pss-params.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-no-rsassa-pss-params.js) -- [parallel/test-crypto-keygen-non-standard-public-exponent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-non-standard-public-exponent.js) - [parallel/test-crypto-keygen-promisify.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-promisify.js) -- [parallel/test-crypto-keygen-rfc8017-9-1.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-rfc8017-9-1.js) -- [parallel/test-crypto-keygen-rfc8017-a-2-3.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-rfc8017-a-2-3.js) - [parallel/test-crypto-keygen-rsa-pss.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-rsa-pss.js) - [parallel/test-crypto-keygen-sync.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen-sync.js) - [parallel/test-crypto-keygen.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-keygen.js) -- [parallel/test-crypto-lazy-transform-writable.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-lazy-transform-writable.js) -- [parallel/test-crypto-no-algorithm.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-no-algorithm.js) -- [parallel/test-crypto-op-during-process-exit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-op-during-process-exit.js) -- [parallel/test-crypto-padding-aes256.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-padding-aes256.js) - [parallel/test-crypto-padding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-padding.js) - [parallel/test-crypto-private-decrypt-gh32240.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-private-decrypt-gh32240.js) -- [parallel/test-crypto-psychic-signatures.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-psychic-signatures.js) -- [parallel/test-crypto-publicDecrypt-fails-first-time.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-publicDecrypt-fails-first-time.js) - [parallel/test-crypto-random.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-random.js) -- [parallel/test-crypto-randomfillsync-regression.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-randomfillsync-regression.js) - [parallel/test-crypto-randomuuid.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-randomuuid.js) - [parallel/test-crypto-rsa-dsa-revert.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-rsa-dsa-revert.js) - [parallel/test-crypto-rsa-dsa.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-rsa-dsa.js) -- [parallel/test-crypto-scrypt.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-scrypt.js) - [parallel/test-crypto-secure-heap.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-secure-heap.js) - [parallel/test-crypto-sign-verify.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-sign-verify.js) -- [parallel/test-crypto-subtle-zero-length.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-subtle-zero-length.js) - [parallel/test-crypto-verify-failure.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-verify-failure.js) - [parallel/test-crypto-webcrypto-aes-decrypt-tag-too-small.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-webcrypto-aes-decrypt-tag-too-small.js) - [parallel/test-crypto-worker-thread.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-crypto-worker-thread.js) @@ -557,84 +498,34 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-debugger-websocket-secret-mismatch.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-debugger-websocket-secret-mismatch.js) - [parallel/test-delayed-require.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-delayed-require.js) - [parallel/test-dgram-abort-closed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-abort-closed.js) -- [parallel/test-dgram-address.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-address.js) -- [parallel/test-dgram-bind-default-address.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-bind-default-address.js) -- [parallel/test-dgram-bind-error-repeat.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-bind-error-repeat.js) - [parallel/test-dgram-bind-fd-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-bind-fd-error.js) - [parallel/test-dgram-bind-fd.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-bind-fd.js) -- [parallel/test-dgram-bind.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-bind.js) -- [parallel/test-dgram-bytes-length.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-bytes-length.js) -- [parallel/test-dgram-close-in-listening.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-close-in-listening.js) -- [parallel/test-dgram-close-is-not-callback.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-close-is-not-callback.js) -- [parallel/test-dgram-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-close.js) - [parallel/test-dgram-cluster-bind-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-cluster-bind-error.js) - [parallel/test-dgram-cluster-close-during-bind.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-cluster-close-during-bind.js) - [parallel/test-dgram-cluster-close-in-listening.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-cluster-close-in-listening.js) -- [parallel/test-dgram-connect-send-callback-buffer-length.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-connect-send-callback-buffer-length.js) -- [parallel/test-dgram-connect-send-callback-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-connect-send-callback-buffer.js) -- [parallel/test-dgram-connect-send-callback-multi-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-connect-send-callback-multi-buffer.js) -- [parallel/test-dgram-connect-send-default-host.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-connect-send-default-host.js) -- [parallel/test-dgram-connect-send-empty-array.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-connect-send-empty-array.js) -- [parallel/test-dgram-connect-send-empty-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-connect-send-empty-buffer.js) -- [parallel/test-dgram-connect-send-empty-packet.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-connect-send-empty-packet.js) -- [parallel/test-dgram-connect-send-multi-buffer-copy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-connect-send-multi-buffer-copy.js) -- [parallel/test-dgram-connect-send-multi-string-array.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-connect-send-multi-string-array.js) -- [parallel/test-dgram-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-connect.js) - [parallel/test-dgram-create-socket-handle-fd.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-create-socket-handle-fd.js) - [parallel/test-dgram-create-socket-handle.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-create-socket-handle.js) -- [parallel/test-dgram-createSocket-type.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-createSocket-type.js) - [parallel/test-dgram-custom-lookup.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-custom-lookup.js) - [parallel/test-dgram-deprecation-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-deprecation-error.js) -- [parallel/test-dgram-error-message-address.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-error-message-address.js) - [parallel/test-dgram-exclusive-implicit-bind.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-exclusive-implicit-bind.js) -- [parallel/test-dgram-implicit-bind.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-implicit-bind.js) - [parallel/test-dgram-ipv6only.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-ipv6only.js) -- [parallel/test-dgram-listen-after-bind.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-listen-after-bind.js) - [parallel/test-dgram-membership.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-membership.js) -- [parallel/test-dgram-msgsize.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-msgsize.js) - [parallel/test-dgram-multicast-loopback.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-multicast-loopback.js) - [parallel/test-dgram-multicast-set-interface.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-multicast-set-interface.js) - [parallel/test-dgram-multicast-setTTL.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-multicast-setTTL.js) -- [parallel/test-dgram-oob-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-oob-buffer.js) -- [parallel/test-dgram-recv-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-recv-error.js) -- [parallel/test-dgram-ref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-ref.js) - [parallel/test-dgram-send-address-types.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-address-types.js) -- [parallel/test-dgram-send-bad-arguments.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-bad-arguments.js) -- [parallel/test-dgram-send-callback-buffer-empty-address.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-callback-buffer-empty-address.js) -- [parallel/test-dgram-send-callback-buffer-length-empty-address.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-callback-buffer-length-empty-address.js) -- [parallel/test-dgram-send-callback-buffer-length.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-callback-buffer-length.js) -- [parallel/test-dgram-send-callback-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-callback-buffer.js) -- [parallel/test-dgram-send-callback-multi-buffer-empty-address.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-callback-multi-buffer-empty-address.js) -- [parallel/test-dgram-send-callback-multi-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-callback-multi-buffer.js) -- [parallel/test-dgram-send-callback-recursive.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-callback-recursive.js) - [parallel/test-dgram-send-cb-quelches-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-cb-quelches-error.js) -- [parallel/test-dgram-send-default-host.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-default-host.js) -- [parallel/test-dgram-send-empty-array.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-empty-array.js) -- [parallel/test-dgram-send-empty-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-empty-buffer.js) -- [parallel/test-dgram-send-empty-packet.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-empty-packet.js) -- [parallel/test-dgram-send-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-error.js) -- [parallel/test-dgram-send-invalid-msg-type.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-invalid-msg-type.js) -- [parallel/test-dgram-send-multi-buffer-copy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-multi-buffer-copy.js) -- [parallel/test-dgram-send-multi-string-array.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-multi-string-array.js) - [parallel/test-dgram-send-queue-info.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-send-queue-info.js) - [parallel/test-dgram-sendto.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-sendto.js) - [parallel/test-dgram-setBroadcast.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-setBroadcast.js) - [parallel/test-dgram-setTTL.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-setTTL.js) - [parallel/test-dgram-socket-buffer-size.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-socket-buffer-size.js) -- [parallel/test-dgram-udp4.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-udp4.js) - [parallel/test-dgram-udp6-link-local-address.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-udp6-link-local-address.js) -- [parallel/test-dgram-udp6-send-default-host.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-udp6-send-default-host.js) - [parallel/test-dgram-unref-in-cluster.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-unref-in-cluster.js) -- [parallel/test-dgram-unref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dgram-unref.js) -- [parallel/test-diagnostics-channel-bind-store.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-diagnostics-channel-bind-store.js) - [parallel/test-diagnostics-channel-http-server-start.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-diagnostics-channel-http-server-start.js) - [parallel/test-diagnostics-channel-http.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-diagnostics-channel-http.js) - [parallel/test-diagnostics-channel-memory-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-diagnostics-channel-memory-leak.js) - [parallel/test-diagnostics-channel-process.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-diagnostics-channel-process.js) -- [parallel/test-diagnostics-channel-safe-subscriber-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-diagnostics-channel-safe-subscriber-errors.js) -- [parallel/test-diagnostics-channel-tracing-channel-async-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-diagnostics-channel-tracing-channel-async-error.js) -- [parallel/test-diagnostics-channel-tracing-channel-async.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-diagnostics-channel-tracing-channel-async.js) -- [parallel/test-diagnostics-channel-tracing-channel-run-stores.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-diagnostics-channel-tracing-channel-run-stores.js) - [parallel/test-diagnostics-channel-worker-threads.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-diagnostics-channel-worker-threads.js) - [parallel/test-directory-import.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-directory-import.js) - [parallel/test-disable-proto-delete.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-disable-proto-delete.js) @@ -650,7 +541,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-dns-lookup-promises.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dns-lookup-promises.js) - [parallel/test-dns-lookupService-promises.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dns-lookupService-promises.js) - [parallel/test-dns-lookupService.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dns-lookupService.js) -- [parallel/test-dns-multi-channel.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dns-multi-channel.js) - [parallel/test-dns-perf_hooks.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dns-perf_hooks.js) - [parallel/test-dns-resolve-promises.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dns-resolve-promises.js) - [parallel/test-dns-resolveany-bad-ancount.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dns-resolveany-bad-ancount.js) @@ -663,9 +553,7 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-domain-add-remove.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-add-remove.js) - [parallel/test-domain-async-id-map-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-async-id-map-leak.js) - [parallel/test-domain-bind-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-bind-timeout.js) -- [parallel/test-domain-crypto.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-crypto.js) - [parallel/test-domain-dep0097.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-dep0097.js) -- [parallel/test-domain-ee-error-listener.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-ee-error-listener.js) - [parallel/test-domain-ee-implicit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-ee-implicit.js) - [parallel/test-domain-ee.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-ee.js) - [parallel/test-domain-emit-error-handler-stack.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-emit-error-handler-stack.js) @@ -680,8 +568,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-domain-load-after-set-uncaught-exception-capture.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-load-after-set-uncaught-exception-capture.js) - [parallel/test-domain-multi.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-multi.js) - [parallel/test-domain-multiple-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-multiple-errors.js) -- [parallel/test-domain-nested-throw.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-nested-throw.js) -- [parallel/test-domain-nested.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-nested.js) - [parallel/test-domain-nexttick.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-nexttick.js) - [parallel/test-domain-no-error-handler-abort-on-uncaught-0.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-no-error-handler-abort-on-uncaught-0.js) - [parallel/test-domain-no-error-handler-abort-on-uncaught-1.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-no-error-handler-abort-on-uncaught-1.js) @@ -698,13 +584,11 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-domain-safe-exit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-safe-exit.js) - [parallel/test-domain-set-uncaught-exception-capture-after-load.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-set-uncaught-exception-capture-after-load.js) - [parallel/test-domain-stack-empty-in-process-uncaughtexception.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-stack-empty-in-process-uncaughtexception.js) -- [parallel/test-domain-stack.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-stack.js) - [parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-throw-error-then-throw-from-uncaught-exception-handler.js) - [parallel/test-domain-thrown-error-handler-stack.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-thrown-error-handler-stack.js) - [parallel/test-domain-timer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-timer.js) - [parallel/test-domain-timers-uncaught-exception.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-timers-uncaught-exception.js) - [parallel/test-domain-timers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-timers.js) -- [parallel/test-domain-top-level-error-handler-clears-stack.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-top-level-error-handler-clears-stack.js) - [parallel/test-domain-top-level-error-handler-throw.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-top-level-error-handler-throw.js) - [parallel/test-domain-uncaught-exception.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-uncaught-exception.js) - [parallel/test-domain-vm-promise-isolation.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-domain-vm-promise-isolation.js) @@ -715,18 +599,13 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-dotenv.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dotenv.js) - [parallel/test-double-tls-client.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-double-tls-client.js) - [parallel/test-double-tls-server.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-double-tls-server.js) -- [parallel/test-dsa-fips-invalid-key.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dsa-fips-invalid-key.js) - [parallel/test-dummy-stdio.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-dummy-stdio.js) - [parallel/test-emit-after-uncaught-exception.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-emit-after-uncaught-exception.js) -- [parallel/test-env-newprotomethod-remove-unnecessary-prototypes.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-env-newprotomethod-remove-unnecessary-prototypes.js) - [parallel/test-env-var-no-warnings.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-env-var-no-warnings.js) - [parallel/test-err-name-deprecation.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-err-name-deprecation.js) -- [parallel/test-error-aggregateTwoErrors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-error-aggregateTwoErrors.js) - [parallel/test-error-format-list.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-error-format-list.js) -- [parallel/test-error-prepare-stack-trace.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-error-prepare-stack-trace.js) - [parallel/test-error-reporting.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-error-reporting.js) - [parallel/test-error-serdes.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-error-serdes.js) -- [parallel/test-errors-aborterror.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-errors-aborterror.js) - [parallel/test-errors-systemerror-frozen-intrinsics.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-errors-systemerror-frozen-intrinsics.js) - [parallel/test-errors-systemerror-stackTraceLimit-custom-setter.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-errors-systemerror-stackTraceLimit-custom-setter.js) - [parallel/test-errors-systemerror-stackTraceLimit-deleted-and-Error-sealed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-errors-systemerror-stackTraceLimit-deleted-and-Error-sealed.js) @@ -757,11 +636,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-eslint-require-common-first.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-eslint-require-common-first.js) - [parallel/test-eslint-required-modules.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-eslint-required-modules.js) - [parallel/test-eval-disallow-code-generation-from-strings.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-eval-disallow-code-generation-from-strings.js) -- [parallel/test-event-capture-rejections.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-event-capture-rejections.js) -- [parallel/test-event-emitter-check-listener-leaks.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-event-emitter-check-listener-leaks.js) -- [parallel/test-event-emitter-max-listeners-warning-for-null.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-event-emitter-max-listeners-warning-for-null.js) -- [parallel/test-event-emitter-max-listeners-warning-for-symbol.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-event-emitter-max-listeners-warning-for-symbol.js) -- [parallel/test-event-emitter-max-listeners-warning.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-event-emitter-max-listeners-warning.js) - [parallel/test-event-target.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-event-target.js) - [parallel/test-eventemitter-asyncresource.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-eventemitter-asyncresource.js) - [parallel/test-events-customevent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-events-customevent.js) @@ -769,7 +643,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-events-listener-count-with-listener.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-events-listener-count-with-listener.js) - [parallel/test-events-static-geteventlisteners.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-events-static-geteventlisteners.js) - [parallel/test-eventtarget-memoryleakwarning.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-eventtarget-memoryleakwarning.js) -- [parallel/test-eventtarget-once-twice.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-eventtarget-once-twice.js) - [parallel/test-eventtarget.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-eventtarget.js) - [parallel/test-experimental-shared-value-conveyor.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-experimental-shared-value-conveyor.js) - [parallel/test-file-validate-mode-flag.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-file-validate-mode-flag.js) @@ -784,10 +657,7 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-fs-append-file-flush.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-append-file-flush.js) - [parallel/test-fs-assert-encoding-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-assert-encoding-error.js) - [parallel/test-fs-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-buffer.js) -- [parallel/test-fs-buffertype-writesync.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-buffertype-writesync.js) - [parallel/test-fs-close-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-close-errors.js) -- [parallel/test-fs-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-close.js) -- [parallel/test-fs-constants.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-constants.js) - [parallel/test-fs-copyfile-respect-permissions.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-copyfile-respect-permissions.js) - [parallel/test-fs-error-messages.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-error-messages.js) - [parallel/test-fs-exists.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-exists.js) @@ -796,11 +666,9 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-fs-fchown.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-fchown.js) - [parallel/test-fs-filehandle-use-after-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-filehandle-use-after-close.js) - [parallel/test-fs-filehandle.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-filehandle.js) -- [parallel/test-fs-fmap.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-fmap.js) - [parallel/test-fs-fsync.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-fsync.js) - [parallel/test-fs-lchmod.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-lchmod.js) - [parallel/test-fs-link.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-link.js) -- [parallel/test-fs-long-path.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-long-path.js) - [parallel/test-fs-make-callback.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-make-callback.js) - [parallel/test-fs-makeStatsCallback.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-makeStatsCallback.js) - [parallel/test-fs-mkdir-mode-mask.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-mkdir-mode-mask.js) @@ -808,10 +676,8 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-fs-mkdir-rmdir.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-mkdir-rmdir.js) - [parallel/test-fs-mkdtemp-prefix-check.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-mkdtemp-prefix-check.js) - [parallel/test-fs-mkdtemp.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-mkdtemp.js) -- [parallel/test-fs-non-number-arguments-throw.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-non-number-arguments-throw.js) - [parallel/test-fs-null-bytes.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-null-bytes.js) - [parallel/test-fs-options-immutable.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-options-immutable.js) -- [parallel/test-fs-promises-exists.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-exists.js) - [parallel/test-fs-promises-file-handle-aggregate-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-file-handle-aggregate-errors.js) - [parallel/test-fs-promises-file-handle-append-file.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-file-handle-append-file.js) - [parallel/test-fs-promises-file-handle-chmod.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-file-handle-chmod.js) @@ -825,10 +691,7 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-fs-promises-file-handle-stream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-file-handle-stream.js) - [parallel/test-fs-promises-file-handle-sync.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-file-handle-sync.js) - [parallel/test-fs-promises-file-handle-truncate.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-file-handle-truncate.js) -- [parallel/test-fs-promises-file-handle-write.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-file-handle-write.js) - [parallel/test-fs-promises-file-handle-writeFile.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-file-handle-writeFile.js) -- [parallel/test-fs-promises-readfile-empty.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-readfile-empty.js) -- [parallel/test-fs-promises-readfile-with-fd.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-readfile-with-fd.js) - [parallel/test-fs-promises-readfile.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-readfile.js) - [parallel/test-fs-promises-watch.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-watch.js) - [parallel/test-fs-promises-write-optional-params.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promises-write-optional-params.js) @@ -838,15 +701,11 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-fs-promisified.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-promisified.js) - [parallel/test-fs-read-empty-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-read-empty-buffer.js) - [parallel/test-fs-read-file-assert-encoding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-read-file-assert-encoding.js) -- [parallel/test-fs-read-file-sync-hostname.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-read-file-sync-hostname.js) -- [parallel/test-fs-read-file-sync.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-read-file-sync.js) - [parallel/test-fs-read-offset-null.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-read-offset-null.js) - [parallel/test-fs-read-optional-params.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-read-optional-params.js) - [parallel/test-fs-read-promises-optional-params.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-read-promises-optional-params.js) - [parallel/test-fs-read-stream-err.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-read-stream-err.js) -- [parallel/test-fs-read-stream-fd-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-read-stream-fd-leak.js) - [parallel/test-fs-read-stream-file-handle.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-read-stream-file-handle.js) -- [parallel/test-fs-read-stream-pos.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-read-stream-pos.js) - [parallel/test-fs-readSync-optional-params.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readSync-optional-params.js) - [parallel/test-fs-readdir-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readdir-buffer.js) - [parallel/test-fs-readdir-types.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readdir-types.js) @@ -856,64 +715,42 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-fs-readfile-flags.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readfile-flags.js) - [parallel/test-fs-readfile-pipe-large.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readfile-pipe-large.js) - [parallel/test-fs-readfile-pipe.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readfile-pipe.js) -- [parallel/test-fs-readfile-unlink.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readfile-unlink.js) -- [parallel/test-fs-readfile-zero-byte-liar.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readfile-zero-byte-liar.js) - [parallel/test-fs-readfile.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readfile.js) -- [parallel/test-fs-readfilesync-enoent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readfilesync-enoent.js) - [parallel/test-fs-readfilesync-pipe-large.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readfilesync-pipe-large.js) - [parallel/test-fs-readlink-type-check.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readlink-type-check.js) - [parallel/test-fs-readv-promises.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readv-promises.js) - [parallel/test-fs-readv-promisify.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-readv-promisify.js) -- [parallel/test-fs-ready-event-stream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-ready-event-stream.js) - [parallel/test-fs-realpath-buffer-encoding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-realpath-buffer-encoding.js) - [parallel/test-fs-realpath-on-substed-drive.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-realpath-on-substed-drive.js) - [parallel/test-fs-realpath-pipe.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-realpath-pipe.js) - [parallel/test-fs-realpath.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-realpath.js) - [parallel/test-fs-rename-type-check.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-rename-type-check.js) - [parallel/test-fs-rm.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-rm.js) -- [parallel/test-fs-sir-writes-alot.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-sir-writes-alot.js) - [parallel/test-fs-stat-bigint.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-stat-bigint.js) - [parallel/test-fs-stat.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-stat.js) - [parallel/test-fs-statfs.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-statfs.js) -- [parallel/test-fs-stream-construct-compat-error-read.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-stream-construct-compat-error-read.js) - [parallel/test-fs-stream-construct-compat-error-write.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-stream-construct-compat-error-write.js) -- [parallel/test-fs-stream-construct-compat-graceful-fs.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-stream-construct-compat-graceful-fs.js) -- [parallel/test-fs-stream-construct-compat-old-node.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-stream-construct-compat-old-node.js) -- [parallel/test-fs-stream-destroy-emit-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-stream-destroy-emit-error.js) -- [parallel/test-fs-stream-double-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-stream-double-close.js) -- [parallel/test-fs-stream-fs-options.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-stream-fs-options.js) -- [parallel/test-fs-stream-options.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-stream-options.js) - [parallel/test-fs-symlink-buffer-path.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-symlink-buffer-path.js) -- [parallel/test-fs-symlink-dir-junction-relative.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-symlink-dir-junction-relative.js) - [parallel/test-fs-symlink-dir-junction.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-symlink-dir-junction.js) - [parallel/test-fs-symlink-dir.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-symlink-dir.js) - [parallel/test-fs-symlink-longpath.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-symlink-longpath.js) - [parallel/test-fs-symlink.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-symlink.js) - [parallel/test-fs-sync-fd-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-sync-fd-leak.js) - [parallel/test-fs-syncwritestream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-syncwritestream.js) -- [parallel/test-fs-timestamp-parsing-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-timestamp-parsing-error.js) -- [parallel/test-fs-truncate-clear-file-zero.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-truncate-clear-file-zero.js) - [parallel/test-fs-truncate-fd.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-truncate-fd.js) - [parallel/test-fs-truncate-sync.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-truncate-sync.js) - [parallel/test-fs-truncate.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-truncate.js) - [parallel/test-fs-unlink-type-check.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-unlink-type-check.js) -- [parallel/test-fs-util-validateoffsetlength.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-util-validateoffsetlength.js) - [parallel/test-fs-utils-get-dirents.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-utils-get-dirents.js) -- [parallel/test-fs-utimes-y2K38.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-utimes-y2K38.js) - [parallel/test-fs-watch-abort-signal.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-abort-signal.js) - [parallel/test-fs-watch-close-when-destroyed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-close-when-destroyed.js) - [parallel/test-fs-watch-encoding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-encoding.js) - [parallel/test-fs-watch-enoent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-enoent.js) -- [parallel/test-fs-watch-file-enoent-after-deletion.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-file-enoent-after-deletion.js) - [parallel/test-fs-watch-recursive-add-file-to-existing-subfolder.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-recursive-add-file-to-existing-subfolder.js) - [parallel/test-fs-watch-recursive-add-file-to-new-folder.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-recursive-add-file-to-new-folder.js) -- [parallel/test-fs-watch-recursive-add-file-with-url.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-recursive-add-file-with-url.js) -- [parallel/test-fs-watch-recursive-add-file.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-recursive-add-file.js) -- [parallel/test-fs-watch-recursive-add-folder.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-recursive-add-folder.js) - [parallel/test-fs-watch-recursive-assert-leaks.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-recursive-assert-leaks.js) - [parallel/test-fs-watch-recursive-promise.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-recursive-promise.js) - [parallel/test-fs-watch-recursive-symlink.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-recursive-symlink.js) -- [parallel/test-fs-watch-recursive-update-file.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-recursive-update-file.js) - [parallel/test-fs-watch-recursive-validate.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-recursive-validate.js) - [parallel/test-fs-watch-recursive-watch-file.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-recursive-watch-file.js) - [parallel/test-fs-watch-ref-unref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-watch-ref-unref.js) @@ -926,34 +763,26 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-fs-write-buffer-large.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-buffer-large.js) - [parallel/test-fs-write-file-flush.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-file-flush.js) - [parallel/test-fs-write-file-typedarrays.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-file-typedarrays.js) -- [parallel/test-fs-write-negativeoffset.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-negativeoffset.js) - [parallel/test-fs-write-optional-params.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-optional-params.js) - [parallel/test-fs-write-reuse-callback.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-reuse-callback.js) - [parallel/test-fs-write-sigxfsz.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-sigxfsz.js) - [parallel/test-fs-write-stream-change-open.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-stream-change-open.js) -- [parallel/test-fs-write-stream-encoding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-stream-encoding.js) - [parallel/test-fs-write-stream-err.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-stream-err.js) - [parallel/test-fs-write-stream-file-handle-2.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-stream-file-handle-2.js) - [parallel/test-fs-write-stream-file-handle.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-stream-file-handle.js) - [parallel/test-fs-write-stream-flush.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-stream-flush.js) -- [parallel/test-fs-write-stream-patch-open.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-stream-patch-open.js) - [parallel/test-fs-write-sync-optional-params.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-write-sync-optional-params.js) - [parallel/test-fs-writefile-with-fd.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-writefile-with-fd.js) - [parallel/test-fs-writev-promises.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-writev-promises.js) -- [parallel/test-fs-writev.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-fs-writev.js) - [parallel/test-gc-http-client-connaborted.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-gc-http-client-connaborted.js) - [parallel/test-gc-net-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-gc-net-timeout.js) - [parallel/test-gc-tls-external-memory.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-gc-tls-external-memory.js) - [parallel/test-global-console-exists.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-global-console-exists.js) - [parallel/test-global-customevent-disabled.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-global-customevent-disabled.js) - [parallel/test-global-customevent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-global-customevent.js) -- [parallel/test-global-domexception.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-global-domexception.js) -- [parallel/test-global-encoder.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-global-encoder.js) - [parallel/test-global-setters.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-global-setters.js) - [parallel/test-global-webcrypto-classes.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-global-webcrypto-classes.js) - [parallel/test-global-webcrypto-disbled.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-global-webcrypto-disbled.js) -- [parallel/test-global-webcrypto.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-global-webcrypto.js) -- [parallel/test-global-webstreams.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-global-webstreams.js) - [parallel/test-global.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-global.js) - [parallel/test-h2-large-header-cause-client-to-hangup.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-h2-large-header-cause-client-to-hangup.js) - [parallel/test-handle-wrap-hasref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-handle-wrap-hasref.js) @@ -973,26 +802,19 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-heapsnapshot-near-heap-limit-worker.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-heapsnapshot-near-heap-limit-worker.js) - [parallel/test-http-1.0-keep-alive.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-1.0-keep-alive.js) - [parallel/test-http-1.0.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-1.0.js) -- [parallel/test-http-abort-before-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-abort-before-end.js) - [parallel/test-http-abort-client.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-abort-client.js) - [parallel/test-http-abort-queued.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-abort-queued.js) - [parallel/test-http-abort-stream-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-abort-stream-end.js) - [parallel/test-http-aborted.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-aborted.js) -- [parallel/test-http-addrequest-localaddress.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-addrequest-localaddress.js) - [parallel/test-http-after-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-after-connect.js) - [parallel/test-http-agent-abort-controller.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-abort-controller.js) - [parallel/test-http-agent-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-close.js) - [parallel/test-http-agent-destroyed-socket.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-destroyed-socket.js) - [parallel/test-http-agent-domain-reused-gc.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-domain-reused-gc.js) - [parallel/test-http-agent-error-on-idle.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-error-on-idle.js) -- [parallel/test-http-agent-false.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-false.js) -- [parallel/test-http-agent-keepalive-delay.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-keepalive-delay.js) - [parallel/test-http-agent-keepalive.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-keepalive.js) - [parallel/test-http-agent-maxsockets-respected.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-maxsockets-respected.js) - [parallel/test-http-agent-maxsockets.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-maxsockets.js) -- [parallel/test-http-agent-maxtotalsockets.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-maxtotalsockets.js) -- [parallel/test-http-agent-no-protocol.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-no-protocol.js) -- [parallel/test-http-agent-null.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-null.js) - [parallel/test-http-agent-remove.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-remove.js) - [parallel/test-http-agent-reuse-drained-socket-only.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-reuse-drained-socket-only.js) - [parallel/test-http-agent-scheduling.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-scheduling.js) @@ -1002,19 +824,14 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http-agent-uninitialized.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent-uninitialized.js) - [parallel/test-http-agent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-agent.js) - [parallel/test-http-allow-content-length-304.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-allow-content-length-304.js) -- [parallel/test-http-allow-req-after-204-res.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-allow-req-after-204-res.js) - [parallel/test-http-automatic-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-automatic-headers.js) - [parallel/test-http-autoselectfamily.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-autoselectfamily.js) -- [parallel/test-http-bind-twice.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-bind-twice.js) - [parallel/test-http-blank-header.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-blank-header.js) -- [parallel/test-http-buffer-sanity.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-buffer-sanity.js) - [parallel/test-http-byteswritten.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-byteswritten.js) - [parallel/test-http-catch-uncaughtexception.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-catch-uncaughtexception.js) - [parallel/test-http-chunk-extensions-limit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-chunk-extensions-limit.js) - [parallel/test-http-chunk-problem.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-chunk-problem.js) - [parallel/test-http-chunked-304.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-chunked-304.js) -- [parallel/test-http-chunked-smuggling.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-chunked-smuggling.js) -- [parallel/test-http-chunked.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-chunked.js) - [parallel/test-http-client-abort-destroy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-abort-destroy.js) - [parallel/test-http-client-abort-event.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-abort-event.js) - [parallel/test-http-client-abort-keep-alive-destroy-res.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-abort-keep-alive-destroy-res.js) @@ -1024,36 +841,24 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http-client-abort-response-event.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-abort-response-event.js) - [parallel/test-http-client-abort-unix-socket.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-abort-unix-socket.js) - [parallel/test-http-client-abort.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-abort.js) -- [parallel/test-http-client-abort2.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-abort2.js) - [parallel/test-http-client-abort3.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-abort3.js) - [parallel/test-http-client-aborted-event.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-aborted-event.js) - [parallel/test-http-client-agent-abort-close-event.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-agent-abort-close-event.js) - [parallel/test-http-client-agent-end-close-event.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-agent-end-close-event.js) - [parallel/test-http-client-agent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-agent.js) -- [parallel/test-http-client-check-http-token.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-check-http-token.js) - [parallel/test-http-client-close-event.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-close-event.js) -- [parallel/test-http-client-close-with-default-agent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-close-with-default-agent.js) -- [parallel/test-http-client-default-headers-exist.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-default-headers-exist.js) -- [parallel/test-http-client-defaults.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-defaults.js) -- [parallel/test-http-client-encoding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-encoding.js) - [parallel/test-http-client-error-rawbytes.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-error-rawbytes.js) - [parallel/test-http-client-finished.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-finished.js) -- [parallel/test-http-client-headers-array.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-headers-array.js) - [parallel/test-http-client-headers-host-array.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-headers-host-array.js) - [parallel/test-http-client-immediate-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-immediate-error.js) - [parallel/test-http-client-incomingmessage-destroy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-incomingmessage-destroy.js) -- [parallel/test-http-client-invalid-path.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-invalid-path.js) -- [parallel/test-http-client-keep-alive-hint.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-keep-alive-hint.js) - [parallel/test-http-client-keep-alive-release-before-finish.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-keep-alive-release-before-finish.js) - [parallel/test-http-client-override-global-agent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-override-global-agent.js) - [parallel/test-http-client-parse-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-parse-error.js) - [parallel/test-http-client-pipe-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-pipe-end.js) -- [parallel/test-http-client-race-2.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-race-2.js) -- [parallel/test-http-client-race.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-race.js) - [parallel/test-http-client-readable.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-readable.js) - [parallel/test-http-client-reject-chunked-with-content-length.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-reject-chunked-with-content-length.js) - [parallel/test-http-client-reject-cr-no-lf.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-reject-cr-no-lf.js) -- [parallel/test-http-client-reject-unexpected-agent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-reject-unexpected-agent.js) - [parallel/test-http-client-req-error-dont-double-fire.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-req-error-dont-double-fire.js) - [parallel/test-http-client-request-options.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-request-options.js) - [parallel/test-http-client-res-destroyed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-res-destroyed.js) @@ -1063,97 +868,60 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http-client-set-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-set-timeout.js) - [parallel/test-http-client-spurious-aborted.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-spurious-aborted.js) - [parallel/test-http-client-timeout-agent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-timeout-agent.js) -- [parallel/test-http-client-timeout-connect-listener.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-timeout-connect-listener.js) - [parallel/test-http-client-timeout-event.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-timeout-event.js) - [parallel/test-http-client-timeout-on-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-timeout-on-connect.js) - [parallel/test-http-client-timeout-option-listeners.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-timeout-option-listeners.js) - [parallel/test-http-client-timeout-option-with-agent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-timeout-option-with-agent.js) - [parallel/test-http-client-timeout-option.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-timeout-option.js) -- [parallel/test-http-client-timeout-with-data.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-timeout-with-data.js) - [parallel/test-http-client-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-timeout.js) -- [parallel/test-http-client-unescaped-path.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-unescaped-path.js) -- [parallel/test-http-client-upload-buf.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-upload-buf.js) -- [parallel/test-http-client-upload.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-client-upload.js) -- [parallel/test-http-common.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-common.js) - [parallel/test-http-conn-reset.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-conn-reset.js) - [parallel/test-http-connect-req-res.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-connect-req-res.js) - [parallel/test-http-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-connect.js) - [parallel/test-http-content-length-mismatch.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-content-length-mismatch.js) - [parallel/test-http-content-length.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-content-length.js) -- [parallel/test-http-contentLength0.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-contentLength0.js) -- [parallel/test-http-correct-hostname.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-correct-hostname.js) - [parallel/test-http-createConnection.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-createConnection.js) -- [parallel/test-http-date-header.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-date-header.js) - [parallel/test-http-debug.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-debug.js) -- [parallel/test-http-decoded-auth.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-decoded-auth.js) -- [parallel/test-http-default-encoding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-default-encoding.js) - [parallel/test-http-default-port.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-default-port.js) - [parallel/test-http-destroyed-socket-write2.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-destroyed-socket-write2.js) - [parallel/test-http-dns-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-dns-error.js) - [parallel/test-http-double-content-length.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-double-content-length.js) -- [parallel/test-http-dump-req-when-res-ends.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-dump-req-when-res-ends.js) - [parallel/test-http-early-hints-invalid-argument.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-early-hints-invalid-argument.js) - [parallel/test-http-early-hints.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-early-hints.js) -- [parallel/test-http-end-throw-socket-handling.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-end-throw-socket-handling.js) -- [parallel/test-http-eof-on-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-eof-on-connect.js) - [parallel/test-http-exceptions.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-exceptions.js) - [parallel/test-http-expect-continue.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-expect-continue.js) - [parallel/test-http-expect-handling.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-expect-handling.js) -- [parallel/test-http-extra-response.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-extra-response.js) -- [parallel/test-http-flush-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-flush-headers.js) - [parallel/test-http-flush-response-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-flush-response-headers.js) -- [parallel/test-http-full-response.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-full-response.js) - [parallel/test-http-generic-streams.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-generic-streams.js) - [parallel/test-http-get-pipeline-problem.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-get-pipeline-problem.js) -- [parallel/test-http-head-request.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-head-request.js) -- [parallel/test-http-head-response-has-no-body-end-implicit-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-head-response-has-no-body-end-implicit-headers.js) -- [parallel/test-http-head-response-has-no-body-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-head-response-has-no-body-end.js) -- [parallel/test-http-head-response-has-no-body.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-head-response-has-no-body.js) -- [parallel/test-http-head-throw-on-response-body-write.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-head-throw-on-response-body-write.js) - [parallel/test-http-header-badrequest.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-header-badrequest.js) -- [parallel/test-http-header-obstext.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-header-obstext.js) - [parallel/test-http-header-overflow.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-header-overflow.js) -- [parallel/test-http-header-owstext.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-header-owstext.js) -- [parallel/test-http-header-read.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-header-read.js) -- [parallel/test-http-hex-write.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-hex-write.js) -- [parallel/test-http-highwatermark.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-highwatermark.js) - [parallel/test-http-host-header-ipv6-fail.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-host-header-ipv6-fail.js) -- [parallel/test-http-host-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-host-headers.js) -- [parallel/test-http-hostname-typechecking.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-hostname-typechecking.js) - [parallel/test-http-incoming-matchKnownFields.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-incoming-matchKnownFields.js) - [parallel/test-http-incoming-message-connection-setter.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-incoming-message-connection-setter.js) -- [parallel/test-http-incoming-message-destroy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-incoming-message-destroy.js) - [parallel/test-http-incoming-message-options.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-incoming-message-options.js) - [parallel/test-http-incoming-pipelined-socket-destroy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-incoming-pipelined-socket-destroy.js) - [parallel/test-http-information-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-information-headers.js) - [parallel/test-http-information-processing.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-information-processing.js) - [parallel/test-http-insecure-parser-per-stream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-insecure-parser-per-stream.js) - [parallel/test-http-insecure-parser.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-insecure-parser.js) -- [parallel/test-http-invalid-path-chars.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-invalid-path-chars.js) - [parallel/test-http-invalid-te.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-invalid-te.js) - [parallel/test-http-invalid-urls.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-invalid-urls.js) -- [parallel/test-http-invalidheaderfield.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-invalidheaderfield.js) -- [parallel/test-http-invalidheaderfield2.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-invalidheaderfield2.js) - [parallel/test-http-keep-alive-close-on-header.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-keep-alive-close-on-header.js) - [parallel/test-http-keep-alive-drop-requests.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-keep-alive-drop-requests.js) - [parallel/test-http-keep-alive-max-requests.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-keep-alive-max-requests.js) - [parallel/test-http-keep-alive-pipeline-max-requests.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-keep-alive-pipeline-max-requests.js) -- [parallel/test-http-keep-alive-timeout-custom.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-keep-alive-timeout-custom.js) - [parallel/test-http-keep-alive-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-keep-alive-timeout.js) - [parallel/test-http-keep-alive.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-keep-alive.js) - [parallel/test-http-keepalive-client.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-keepalive-client.js) - [parallel/test-http-keepalive-free.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-keepalive-free.js) - [parallel/test-http-keepalive-override.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-keepalive-override.js) - [parallel/test-http-keepalive-request.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-keepalive-request.js) -- [parallel/test-http-listening.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-listening.js) -- [parallel/test-http-localaddress-bind-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-localaddress-bind-error.js) - [parallel/test-http-malformed-request.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-malformed-request.js) - [parallel/test-http-many-ended-pipelines.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-many-ended-pipelines.js) - [parallel/test-http-max-header-size-per-stream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-max-header-size-per-stream.js) - [parallel/test-http-max-header-size.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-max-header-size.js) - [parallel/test-http-max-headers-count.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-max-headers-count.js) - [parallel/test-http-max-http-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-max-http-headers.js) -- [parallel/test-http-methods.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-methods.js) - [parallel/test-http-missing-header-separator-cr.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-missing-header-separator-cr.js) - [parallel/test-http-missing-header-separator-lf.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-missing-header-separator-lf.js) - [parallel/test-http-multi-line-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-multi-line-headers.js) @@ -1167,10 +935,8 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http-outgoing-destroyed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-destroyed.js) - [parallel/test-http-outgoing-end-cork.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-end-cork.js) - [parallel/test-http-outgoing-end-multiple.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-end-multiple.js) -- [parallel/test-http-outgoing-end-types.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-end-types.js) - [parallel/test-http-outgoing-finish-writable.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-finish-writable.js) - [parallel/test-http-outgoing-finish.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-finish.js) -- [parallel/test-http-outgoing-finished.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-finished.js) - [parallel/test-http-outgoing-first-chunk-singlebyte-encoding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-first-chunk-singlebyte-encoding.js) - [parallel/test-http-outgoing-message-capture-rejection.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-message-capture-rejection.js) - [parallel/test-http-outgoing-message-inheritance.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-message-inheritance.js) @@ -1178,58 +944,38 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http-outgoing-properties.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-properties.js) - [parallel/test-http-outgoing-proto.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-proto.js) - [parallel/test-http-outgoing-writableFinished.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-writableFinished.js) -- [parallel/test-http-outgoing-write-types.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-outgoing-write-types.js) - [parallel/test-http-parser-bad-ref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-parser-bad-ref.js) - [parallel/test-http-parser-finish-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-parser-finish-error.js) -- [parallel/test-http-parser-free.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-parser-free.js) - [parallel/test-http-parser-freed-before-upgrade.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-parser-freed-before-upgrade.js) - [parallel/test-http-parser-lazy-loaded.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-parser-lazy-loaded.js) - [parallel/test-http-parser-memory-retention.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-parser-memory-retention.js) - [parallel/test-http-parser-multiple-execute.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-parser-multiple-execute.js) - [parallel/test-http-parser-timeout-reset.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-parser-timeout-reset.js) - [parallel/test-http-parser.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-parser.js) -- [parallel/test-http-pause-no-dump.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-pause-no-dump.js) -- [parallel/test-http-pause-resume-one-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-pause-resume-one-end.js) -- [parallel/test-http-pause.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-pause.js) - [parallel/test-http-perf_hooks.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-perf_hooks.js) -- [parallel/test-http-pipe-fs.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-pipe-fs.js) - [parallel/test-http-pipeline-assertionerror-finish.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-pipeline-assertionerror-finish.js) - [parallel/test-http-pipeline-flood.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-pipeline-flood.js) -- [parallel/test-http-pipeline-requests-connection-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-pipeline-requests-connection-leak.js) - [parallel/test-http-pipeline-socket-parser-typeerror.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-pipeline-socket-parser-typeerror.js) -- [parallel/test-http-proxy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-proxy.js) - [parallel/test-http-raw-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-raw-headers.js) -- [parallel/test-http-readable-data-event.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-readable-data-event.js) - [parallel/test-http-remove-connection-header-persists-connection.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-remove-connection-header-persists-connection.js) - [parallel/test-http-remove-header-stays-removed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-remove-header-stays-removed.js) - [parallel/test-http-req-close-robust-from-tampering.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-req-close-robust-from-tampering.js) - [parallel/test-http-req-res-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-req-res-close.js) - [parallel/test-http-request-agent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-request-agent.js) -- [parallel/test-http-request-arguments.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-request-arguments.js) -- [parallel/test-http-request-dont-override-options.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-request-dont-override-options.js) -- [parallel/test-http-request-end-twice.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-request-end-twice.js) -- [parallel/test-http-request-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-request-end.js) - [parallel/test-http-request-host-header.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-request-host-header.js) -- [parallel/test-http-request-invalid-method-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-request-invalid-method-error.js) - [parallel/test-http-request-join-authorization-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-request-join-authorization-headers.js) -- [parallel/test-http-request-large-payload.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-request-large-payload.js) -- [parallel/test-http-request-methods.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-request-methods.js) - [parallel/test-http-request-smuggling-content-length.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-request-smuggling-content-length.js) - [parallel/test-http-res-write-after-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-res-write-after-end.js) -- [parallel/test-http-res-write-end-dont-take-array.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-res-write-end-dont-take-array.js) - [parallel/test-http-response-add-header-after-sent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-response-add-header-after-sent.js) - [parallel/test-http-response-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-response-close.js) - [parallel/test-http-response-cork.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-response-cork.js) - [parallel/test-http-response-multi-content-length.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-response-multi-content-length.js) -- [parallel/test-http-response-multiheaders.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-response-multiheaders.js) - [parallel/test-http-response-no-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-response-no-headers.js) -- [parallel/test-http-response-readable.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-response-readable.js) - [parallel/test-http-response-remove-header-after-sent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-response-remove-header-after-sent.js) - [parallel/test-http-response-setheaders.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-response-setheaders.js) - [parallel/test-http-response-splitting.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-response-splitting.js) - [parallel/test-http-response-status-message.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-response-status-message.js) - [parallel/test-http-response-statuscode.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-response-statuscode.js) -- [parallel/test-http-response-writehead-returns-this.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-response-writehead-returns-this.js) - [parallel/test-http-same-map.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-same-map.js) - [parallel/test-http-server-async-dispose.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-async-dispose.js) - [parallel/test-http-server-capture-rejections.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-capture-rejections.js) @@ -1242,7 +988,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http-server-connections-checking-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-connections-checking-leak.js) - [parallel/test-http-server-consumed-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-consumed-timeout.js) - [parallel/test-http-server-de-chunked-trailer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-de-chunked-trailer.js) -- [parallel/test-http-server-delete-parser.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-delete-parser.js) - [parallel/test-http-server-destroy-socket-on-client-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-destroy-socket-on-client-error.js) - [parallel/test-http-server-headers-timeout-delayed-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-headers-timeout-delayed-headers.js) - [parallel/test-http-server-headers-timeout-interrupted-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-headers-timeout-interrupted-headers.js) @@ -1275,11 +1020,7 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http-server-timeouts-validation.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-timeouts-validation.js) - [parallel/test-http-server-unconsume-consume.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-unconsume-consume.js) - [parallel/test-http-server-unconsume.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-unconsume.js) -- [parallel/test-http-server-write-after-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-write-after-end.js) -- [parallel/test-http-server-write-end-after-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server-write-end-after-end.js) - [parallel/test-http-server.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-server.js) -- [parallel/test-http-set-cookies.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-set-cookies.js) -- [parallel/test-http-set-header-chain.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-set-header-chain.js) - [parallel/test-http-set-max-idle-http-parser.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-set-max-idle-http-parser.js) - [parallel/test-http-set-timeout-server.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-set-timeout-server.js) - [parallel/test-http-set-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-set-timeout.js) @@ -1287,16 +1028,13 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http-should-keep-alive.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-should-keep-alive.js) - [parallel/test-http-socket-encoding-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-socket-encoding-error.js) - [parallel/test-http-socket-error-listeners.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-socket-error-listeners.js) -- [parallel/test-http-status-code.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-status-code.js) - [parallel/test-http-status-message.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-status-message.js) -- [parallel/test-http-status-reason-invalid-chars.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-status-reason-invalid-chars.js) - [parallel/test-http-sync-write-error-during-continue.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-sync-write-error-during-continue.js) - [parallel/test-http-timeout-client-warning.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-timeout-client-warning.js) - [parallel/test-http-timeout-overflow.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-timeout-overflow.js) - [parallel/test-http-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-timeout.js) - [parallel/test-http-transfer-encoding-repeated-chunked.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-transfer-encoding-repeated-chunked.js) - [parallel/test-http-transfer-encoding-smuggling.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-transfer-encoding-smuggling.js) -- [parallel/test-http-uncaught-from-request-callback.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-uncaught-from-request-callback.js) - [parallel/test-http-unix-socket-keep-alive.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-unix-socket-keep-alive.js) - [parallel/test-http-unix-socket.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-unix-socket.js) - [parallel/test-http-upgrade-advertise.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-upgrade-advertise.js) @@ -1308,19 +1046,11 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http-upgrade-server.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-upgrade-server.js) - [parallel/test-http-upgrade-server2.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-upgrade-server2.js) - [parallel/test-http-url.parse-auth-with-header-in-request.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-url.parse-auth-with-header-in-request.js) -- [parallel/test-http-url.parse-auth.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-url.parse-auth.js) -- [parallel/test-http-url.parse-basic.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-url.parse-basic.js) -- [parallel/test-http-url.parse-path.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-url.parse-path.js) -- [parallel/test-http-url.parse-post.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-url.parse-post.js) -- [parallel/test-http-url.parse-search.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-url.parse-search.js) -- [parallel/test-http-wget.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-wget.js) - [parallel/test-http-writable-true-after-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-writable-true-after-close.js) - [parallel/test-http-write-callbacks.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-write-callbacks.js) -- [parallel/test-http-write-empty-string.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-write-empty-string.js) - [parallel/test-http-write-head-2.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-write-head-2.js) - [parallel/test-http-write-head.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-write-head.js) - [parallel/test-http-zero-length-write.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-zero-length-write.js) -- [parallel/test-http-zerolengthbuffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http-zerolengthbuffer.js) - [parallel/test-http.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http.js) - [parallel/test-http2-altsvc.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-altsvc.js) - [parallel/test-http2-autoselect-protocol.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-autoselect-protocol.js) @@ -1340,7 +1070,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http2-client-port-80.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-client-port-80.js) - [parallel/test-http2-client-priority-before-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-client-priority-before-connect.js) - [parallel/test-http2-client-promisify-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-client-promisify-connect.js) -- [parallel/test-http2-client-request-listeners-warning.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-client-request-listeners-warning.js) - [parallel/test-http2-client-request-options-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-client-request-options-errors.js) - [parallel/test-http2-client-rststream-before-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-client-rststream-before-connect.js) - [parallel/test-http2-client-set-priority.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-client-set-priority.js) @@ -1361,7 +1090,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http2-compat-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-errors.js) - [parallel/test-http2-compat-expect-continue-check.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-expect-continue-check.js) - [parallel/test-http2-compat-expect-continue.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-expect-continue.js) -- [parallel/test-http2-compat-expect-handling.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-expect-handling.js) - [parallel/test-http2-compat-method-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-method-connect.js) - [parallel/test-http2-compat-serverrequest-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-serverrequest-end.js) - [parallel/test-http2-compat-serverrequest-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-serverrequest-headers.js) @@ -1394,7 +1122,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http2-compat-serverresponse.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-serverresponse.js) - [parallel/test-http2-compat-short-stream-client-server.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-short-stream-client-server.js) - [parallel/test-http2-compat-socket-destroy-delayed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-socket-destroy-delayed.js) -- [parallel/test-http2-compat-socket-set.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-socket-set.js) - [parallel/test-http2-compat-socket.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-socket.js) - [parallel/test-http2-compat-write-early-hints-invalid-argument-type.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-write-early-hints-invalid-argument-type.js) - [parallel/test-http2-compat-write-early-hints-invalid-argument-value.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-compat-write-early-hints-invalid-argument-value.js) @@ -1403,7 +1130,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http2-connect-method-extended-cant-turn-off.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-connect-method-extended-cant-turn-off.js) - [parallel/test-http2-connect-method-extended.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-connect-method-extended.js) - [parallel/test-http2-connect-method.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-connect-method.js) -- [parallel/test-http2-connect-options.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-connect-options.js) - [parallel/test-http2-connect-tls-with-delay.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-connect-tls-with-delay.js) - [parallel/test-http2-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-connect.js) - [parallel/test-http2-cookies.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-cookies.js) @@ -1413,13 +1139,10 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http2-createsecureserver-options.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-createsecureserver-options.js) - [parallel/test-http2-createserver-options.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-createserver-options.js) - [parallel/test-http2-createwritereq.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-createwritereq.js) -- [parallel/test-http2-date-header.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-date-header.js) - [parallel/test-http2-debug.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-debug.js) - [parallel/test-http2-destroy-after-write.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-destroy-after-write.js) - [parallel/test-http2-dont-lose-data.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-dont-lose-data.js) -- [parallel/test-http2-dont-override.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-dont-override.js) - [parallel/test-http2-empty-frame-without-eof.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-empty-frame-without-eof.js) -- [parallel/test-http2-endafterheaders.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-endafterheaders.js) - [parallel/test-http2-error-order.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-error-order.js) - [parallel/test-http2-exceeds-server-trailer-size.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-exceeds-server-trailer-size.js) - [parallel/test-http2-forget-closed-streams.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-forget-closed-streams.js) @@ -1446,7 +1169,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http2-max-invalid-frames.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-max-invalid-frames.js) - [parallel/test-http2-max-session-memory-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-max-session-memory-leak.js) - [parallel/test-http2-max-settings.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-max-settings.js) -- [parallel/test-http2-methods.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-methods.js) - [parallel/test-http2-misbehaving-flow-control-paused.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-misbehaving-flow-control-paused.js) - [parallel/test-http2-misbehaving-flow-control.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-misbehaving-flow-control.js) - [parallel/test-http2-misbehaving-multiplex.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-misbehaving-multiplex.js) @@ -1479,15 +1201,12 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http2-propagate-session-destroy-code.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-propagate-session-destroy-code.js) - [parallel/test-http2-removed-header-stays-removed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-removed-header-stays-removed.js) - [parallel/test-http2-request-remove-connect-listener.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-request-remove-connect-listener.js) -- [parallel/test-http2-request-response-proto.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-request-response-proto.js) - [parallel/test-http2-res-corked.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-res-corked.js) - [parallel/test-http2-res-writable-properties.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-res-writable-properties.js) - [parallel/test-http2-reset-flood.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-reset-flood.js) - [parallel/test-http2-respond-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-respond-errors.js) -- [parallel/test-http2-respond-file-204.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-respond-file-204.js) - [parallel/test-http2-respond-file-304.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-respond-file-304.js) - [parallel/test-http2-respond-file-404.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-respond-file-404.js) -- [parallel/test-http2-respond-file-compat.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-respond-file-compat.js) - [parallel/test-http2-respond-file-error-dir.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-respond-file-error-dir.js) - [parallel/test-http2-respond-file-error-pipe-offset.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-respond-file-error-pipe-offset.js) - [parallel/test-http2-respond-file-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-respond-file-errors.js) @@ -1535,19 +1254,14 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http2-session-gc-while-write-scheduled.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-session-gc-while-write-scheduled.js) - [parallel/test-http2-session-settings.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-session-settings.js) - [parallel/test-http2-session-stream-state.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-session-stream-state.js) -- [parallel/test-http2-session-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-session-timeout.js) - [parallel/test-http2-session-unref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-session-unref.js) - [parallel/test-http2-settings-unsolicited-ack.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-settings-unsolicited-ack.js) - [parallel/test-http2-short-stream-client-server.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-short-stream-client-server.js) - [parallel/test-http2-single-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-single-headers.js) - [parallel/test-http2-socket-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-socket-close.js) - [parallel/test-http2-socket-proxy-handler-for-has.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-socket-proxy-handler-for-has.js) -- [parallel/test-http2-socket-proxy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-socket-proxy.js) -- [parallel/test-http2-status-code-invalid.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-status-code-invalid.js) -- [parallel/test-http2-status-code.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-status-code.js) - [parallel/test-http2-stream-client.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-stream-client.js) - [parallel/test-http2-stream-destroy-event-order.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-stream-destroy-event-order.js) -- [parallel/test-http2-stream-removelisteners-after-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-stream-removelisteners-after-close.js) - [parallel/test-http2-timeouts.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-timeouts.js) - [parallel/test-http2-tls-disconnect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-tls-disconnect.js) - [parallel/test-http2-too-large-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-too-large-headers.js) @@ -1565,7 +1279,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-http2-util-update-options-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-util-update-options-buffer.js) - [parallel/test-http2-window-size.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-window-size.js) - [parallel/test-http2-write-callbacks.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-write-callbacks.js) -- [parallel/test-http2-write-empty-string.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-write-empty-string.js) - [parallel/test-http2-write-finishes-after-stream-destroy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-write-finishes-after-stream-destroy.js) - [parallel/test-http2-zero-length-header.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-zero-length-header.js) - [parallel/test-http2-zero-length-write.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-http2-zero-length-write.js) @@ -1592,20 +1305,15 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-https-client-get-url.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-client-get-url.js) - [parallel/test-https-client-override-global-agent.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-client-override-global-agent.js) - [parallel/test-https-client-reject.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-client-reject.js) -- [parallel/test-https-client-renegotiation-limit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-client-renegotiation-limit.js) - [parallel/test-https-client-resume.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-client-resume.js) - [parallel/test-https-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-close.js) - [parallel/test-https-connect-address-family.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-connect-address-family.js) -- [parallel/test-https-connecting-to-http.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-connecting-to-http.js) - [parallel/test-https-drain.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-drain.js) - [parallel/test-https-eof-for-eom.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-eof-for-eom.js) -- [parallel/test-https-foafssl.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-foafssl.js) - [parallel/test-https-host-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-host-headers.js) - [parallel/test-https-hwm.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-hwm.js) - [parallel/test-https-insecure-parse-per-stream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-insecure-parse-per-stream.js) - [parallel/test-https-keep-alive-drop-requests.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-keep-alive-drop-requests.js) -- [parallel/test-https-localaddress-bind-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-localaddress-bind-error.js) -- [parallel/test-https-localaddress.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-localaddress.js) - [parallel/test-https-max-header-size-per-stream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-max-header-size-per-stream.js) - [parallel/test-https-max-headers-count.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-max-headers-count.js) - [parallel/test-https-options-boolean-check.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-options-boolean-check.js) @@ -1631,11 +1339,8 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-https-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-timeout.js) - [parallel/test-https-truncate.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-truncate.js) - [parallel/test-https-unix-socket-self-signed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-https-unix-socket-self-signed.js) -- [parallel/test-icu-data-dir.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-icu-data-dir.js) -- [parallel/test-icu-env.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-icu-env.js) - [parallel/test-icu-minimum-version.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-icu-minimum-version.js) - [parallel/test-icu-punycode.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-icu-punycode.js) -- [parallel/test-icu-stringwidth.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-icu-stringwidth.js) - [parallel/test-inspect-address-in-use.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-inspect-address-in-use.js) - [parallel/test-inspect-async-hook-setup-at-inspect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-inspect-async-hook-setup-at-inspect.js) - [parallel/test-inspect-publish-uid.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-inspect-publish-uid.js) @@ -1685,7 +1390,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-inspector-runtime-evaluate-with-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-inspector-runtime-evaluate-with-timeout.js) - [parallel/test-inspector-scriptparsed-context.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-inspector-scriptparsed-context.js) - [parallel/test-inspector-stop-profile-after-done.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-inspector-stop-profile-after-done.js) -- [parallel/test-inspector-stops-no-file.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-inspector-stops-no-file.js) - [parallel/test-inspector-stress-http.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-inspector-stress-http.js) - [parallel/test-inspector-tracing-domain.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-inspector-tracing-domain.js) - [parallel/test-inspector-vm-global-accessors-getter-sideeffect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-inspector-vm-global-accessors-getter-sideeffect.js) @@ -1694,12 +1398,10 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-inspector-waiting-for-disconnect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-inspector-waiting-for-disconnect.js) - [parallel/test-inspector-workers-flat-list.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-inspector-workers-flat-list.js) - [parallel/test-inspector.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-inspector.js) -- [parallel/test-instanceof.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-instanceof.js) - [parallel/test-internal-assert.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-assert.js) - [parallel/test-internal-error-original-names.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-error-original-names.js) - [parallel/test-internal-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-errors.js) - [parallel/test-internal-fs-syncwritestream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-fs-syncwritestream.js) -- [parallel/test-internal-fs.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-fs.js) - [parallel/test-internal-iterable-weak-map.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-iterable-weak-map.js) - [parallel/test-internal-module-require.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-module-require.js) - [parallel/test-internal-module-wrap.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-module-wrap.js) @@ -1711,7 +1413,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-internal-util-classwrapper.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-util-classwrapper.js) - [parallel/test-internal-util-decorate-error-stack.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-util-decorate-error-stack.js) - [parallel/test-internal-util-helpers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-util-helpers.js) -- [parallel/test-internal-util-normalizeencoding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-util-normalizeencoding.js) - [parallel/test-internal-util-objects.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-util-objects.js) - [parallel/test-internal-util-weakreference.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-util-weakreference.js) - [parallel/test-internal-validators-validateoneof.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-internal-validators-validateoneof.js) @@ -1720,171 +1421,102 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-intl-v8BreakIterator.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-intl-v8BreakIterator.js) - [parallel/test-intl.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-intl.js) - [parallel/test-js-stream-call-properties.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-js-stream-call-properties.js) -- [parallel/test-kill-segfault-freebsd.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-kill-segfault-freebsd.js) - [parallel/test-listen-fd-cluster.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-listen-fd-cluster.js) -- [parallel/test-listen-fd-detached-inherit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-listen-fd-detached-inherit.js) -- [parallel/test-listen-fd-detached.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-listen-fd-detached.js) - [parallel/test-listen-fd-ebadf.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-listen-fd-ebadf.js) - [parallel/test-listen-fd-server.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-listen-fd-server.js) - [parallel/test-macos-app-sandbox.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-macos-app-sandbox.js) - [parallel/test-math-random.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-math-random.js) -- [parallel/test-memory-usage-emfile.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-memory-usage-emfile.js) -- [parallel/test-memory-usage.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-memory-usage.js) -- [parallel/test-messagechannel.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-messagechannel.js) - [parallel/test-messageevent-brandcheck.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-messageevent-brandcheck.js) - [parallel/test-messageport-hasref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-messageport-hasref.js) - [parallel/test-messaging-maketransferable.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-messaging-maketransferable.js) -- [parallel/test-microtask-queue-integration.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-microtask-queue-integration.js) -- [parallel/test-microtask-queue-run-immediate.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-microtask-queue-run-immediate.js) -- [parallel/test-microtask-queue-run.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-microtask-queue-run.js) - [parallel/test-mime-api.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-mime-api.js) - [parallel/test-mime-whatwg.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-mime-whatwg.js) - [parallel/test-module-binding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-binding.js) - [parallel/test-module-builtin.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-builtin.js) -- [parallel/test-module-cache.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-cache.js) - [parallel/test-module-children.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-children.js) - [parallel/test-module-circular-dependency-warning.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-circular-dependency-warning.js) -- [parallel/test-module-circular-symlinks.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-circular-symlinks.js) - [parallel/test-module-create-require.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-create-require.js) - [parallel/test-module-globalpaths-nodepath.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-globalpaths-nodepath.js) -- [parallel/test-module-isBuiltin.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-isBuiltin.js) - [parallel/test-module-loading-deprecated.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-loading-deprecated.js) - [parallel/test-module-loading-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-loading-error.js) - [parallel/test-module-loading-globalpaths.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-loading-globalpaths.js) - [parallel/test-module-main-extension-lookup.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-main-extension-lookup.js) - [parallel/test-module-main-fail.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-main-fail.js) - [parallel/test-module-main-preserve-symlinks-fail.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-main-preserve-symlinks-fail.js) -- [parallel/test-module-multi-extensions.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-multi-extensions.js) -- [parallel/test-module-nodemodulepaths.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-nodemodulepaths.js) - [parallel/test-module-parent-deprecation.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-parent-deprecation.js) - [parallel/test-module-parent-setter-deprecation.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-parent-setter-deprecation.js) - [parallel/test-module-prototype-mutation.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-prototype-mutation.js) -- [parallel/test-module-readonly.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-readonly.js) -- [parallel/test-module-relative-lookup.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-relative-lookup.js) - [parallel/test-module-run-main-monkey-patch.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-run-main-monkey-patch.js) - [parallel/test-module-stat.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-stat.js) - [parallel/test-module-symlinked-peer-modules.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-symlinked-peer-modules.js) - [parallel/test-module-version.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-version.js) - [parallel/test-module-wrap.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-wrap.js) - [parallel/test-module-wrapper.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-module-wrapper.js) -- [parallel/test-net-after-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-after-close.js) - [parallel/test-net-allow-half-open.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-allow-half-open.js) - [parallel/test-net-autoselectfamily-commandline-option.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-autoselectfamily-commandline-option.js) - [parallel/test-net-autoselectfamily-default.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-autoselectfamily-default.js) - [parallel/test-net-autoselectfamily-ipv4first.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-autoselectfamily-ipv4first.js) -- [parallel/test-net-better-error-messages-listen.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-better-error-messages-listen.js) - [parallel/test-net-binary.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-binary.js) -- [parallel/test-net-bind-twice.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-bind-twice.js) -- [parallel/test-net-buffersize.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-buffersize.js) - [parallel/test-net-bytes-read.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-bytes-read.js) - [parallel/test-net-bytes-stats.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-bytes-stats.js) -- [parallel/test-net-bytes-written-large.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-bytes-written-large.js) -- [parallel/test-net-can-reset-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-can-reset-timeout.js) - [parallel/test-net-child-process-connect-reset.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-child-process-connect-reset.js) - [parallel/test-net-client-bind-twice.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-client-bind-twice.js) - [parallel/test-net-connect-abort-controller.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-abort-controller.js) - [parallel/test-net-connect-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-buffer.js) - [parallel/test-net-connect-buffer2.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-buffer2.js) -- [parallel/test-net-connect-call-socket-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-call-socket-connect.js) - [parallel/test-net-connect-keepalive.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-keepalive.js) - [parallel/test-net-connect-memleak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-memleak.js) - [parallel/test-net-connect-nodelay.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-nodelay.js) - [parallel/test-net-connect-options-allowhalfopen.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-options-allowhalfopen.js) -- [parallel/test-net-connect-options-fd.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-options-fd.js) - [parallel/test-net-connect-options-invalid.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-options-invalid.js) -- [parallel/test-net-connect-options-ipv6.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-options-ipv6.js) - [parallel/test-net-connect-options-path.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-options-path.js) -- [parallel/test-net-connect-options-port.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-options-port.js) -- [parallel/test-net-connect-paused-connection.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-paused-connection.js) - [parallel/test-net-connect-reset-after-destroy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-reset-after-destroy.js) - [parallel/test-net-connect-reset-before-connected.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-reset-before-connected.js) - [parallel/test-net-connect-reset-until-connected.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-reset-until-connected.js) - [parallel/test-net-connect-reset.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-connect-reset.js) - [parallel/test-net-deprecated-setsimultaneousaccepts.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-deprecated-setsimultaneousaccepts.js) -- [parallel/test-net-dns-custom-lookup.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-dns-custom-lookup.js) -- [parallel/test-net-dns-lookup-skip.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-dns-lookup-skip.js) -- [parallel/test-net-dns-lookup.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-dns-lookup.js) -- [parallel/test-net-eaddrinuse.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-eaddrinuse.js) - [parallel/test-net-end-destroyed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-end-destroyed.js) -- [parallel/test-net-error-twice.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-error-twice.js) -- [parallel/test-net-keepalive.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-keepalive.js) - [parallel/test-net-large-string.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-large-string.js) -- [parallel/test-net-listen-after-destroying-stdin.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-listen-after-destroying-stdin.js) -- [parallel/test-net-listen-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-listen-error.js) - [parallel/test-net-listen-exclusive-random-ports.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-listen-exclusive-random-ports.js) - [parallel/test-net-listen-fd0.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-listen-fd0.js) - [parallel/test-net-listen-ipv6only.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-listen-ipv6only.js) -- [parallel/test-net-local-address-port.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-local-address-port.js) - [parallel/test-net-normalize-args.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-normalize-args.js) - [parallel/test-net-onread-static-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-onread-static-buffer.js) -- [parallel/test-net-pause-resume-connecting.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-pause-resume-connecting.js) - [parallel/test-net-perf_hooks.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-perf_hooks.js) -- [parallel/test-net-persistent-keepalive.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-persistent-keepalive.js) -- [parallel/test-net-persistent-nodelay.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-persistent-nodelay.js) -- [parallel/test-net-persistent-ref-unref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-persistent-ref-unref.js) - [parallel/test-net-pingpong.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-pingpong.js) -- [parallel/test-net-reconnect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-reconnect.js) -- [parallel/test-net-remote-address-port.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-remote-address-port.js) -- [parallel/test-net-remote-address.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-remote-address.js) - [parallel/test-net-server-call-listen-multiple-times.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-server-call-listen-multiple-times.js) -- [parallel/test-net-server-capture-rejection.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-server-capture-rejection.js) -- [parallel/test-net-server-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-server-close.js) - [parallel/test-net-server-drop-connections.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-server-drop-connections.js) - [parallel/test-net-server-keepalive.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-server-keepalive.js) - [parallel/test-net-server-listen-handle.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-server-listen-handle.js) - [parallel/test-net-server-max-connections-close-makes-more-available.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-server-max-connections-close-makes-more-available.js) - [parallel/test-net-server-max-connections.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-server-max-connections.js) - [parallel/test-net-server-nodelay.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-server-nodelay.js) -- [parallel/test-net-server-pause-on-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-server-pause-on-connect.js) - [parallel/test-net-server-reset.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-server-reset.js) - [parallel/test-net-server-simultaneous-accepts-produce-warning-once.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-server-simultaneous-accepts-produce-warning-once.js) - [parallel/test-net-server-try-ports.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-server-try-ports.js) -- [parallel/test-net-settimeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-settimeout.js) - [parallel/test-net-socket-byteswritten.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-byteswritten.js) -- [parallel/test-net-socket-close-after-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-close-after-end.js) -- [parallel/test-net-socket-connect-invalid-autoselectfamily.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-connect-invalid-autoselectfamily.js) - [parallel/test-net-socket-connect-invalid-autoselectfamilyattempttimeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-connect-invalid-autoselectfamilyattempttimeout.js) -- [parallel/test-net-socket-connect-without-cb.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-connect-without-cb.js) -- [parallel/test-net-socket-connecting.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-connecting.js) - [parallel/test-net-socket-constructor.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-constructor.js) -- [parallel/test-net-socket-destroy-send.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-destroy-send.js) -- [parallel/test-net-socket-end-before-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-end-before-connect.js) -- [parallel/test-net-socket-end-callback.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-end-callback.js) - [parallel/test-net-socket-local-address.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-local-address.js) -- [parallel/test-net-socket-ready-without-cb.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-ready-without-cb.js) - [parallel/test-net-socket-reset-send.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-reset-send.js) - [parallel/test-net-socket-reset-twice.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-reset-twice.js) -- [parallel/test-net-socket-timeout-unref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-timeout-unref.js) - [parallel/test-net-socket-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-timeout.js) -- [parallel/test-net-socket-write-after-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-write-after-close.js) -- [parallel/test-net-socket-write-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-socket-write-error.js) - [parallel/test-net-stream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-stream.js) -- [parallel/test-net-sync-cork.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-sync-cork.js) - [parallel/test-net-throttle.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-throttle.js) -- [parallel/test-net-writable.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-writable.js) - [parallel/test-net-write-after-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-write-after-close.js) - [parallel/test-net-write-after-end-nt.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-write-after-end-nt.js) - [parallel/test-net-write-cb-on-destroy-before-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-write-cb-on-destroy-before-connect.js) -- [parallel/test-net-write-connect-write.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-write-connect-write.js) -- [parallel/test-net-write-fully-async-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-write-fully-async-buffer.js) -- [parallel/test-net-write-fully-async-hex-string.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-write-fully-async-hex-string.js) -- [parallel/test-net-write-slow.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-net-write-slow.js) -- [parallel/test-next-tick-domain.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-next-tick-domain.js) -- [parallel/test-next-tick-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-next-tick-errors.js) - [parallel/test-no-addons-resolution-condition.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-no-addons-resolution-condition.js) -- [parallel/test-no-node-snapshot.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-no-node-snapshot.js) - [parallel/test-npm-install.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-npm-install.js) - [parallel/test-npm-version.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-npm-version.js) - [parallel/test-openssl-ca-options.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-openssl-ca-options.js) - [parallel/test-options-binding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-options-binding.js) - [parallel/test-os-checked-function.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-os-checked-function.js) - [parallel/test-os-eol.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-os-eol.js) -- [parallel/test-os-homedir-no-envvar.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-os-homedir-no-envvar.js) - [parallel/test-os-process-priority.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-os-process-priority.js) - [parallel/test-os-userinfo-handles-getter-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-os-userinfo-handles-getter-errors.js) - [parallel/test-path-posix-relative-on-windows.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-path-posix-relative-on-windows.js) - [parallel/test-pending-deprecation.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-pending-deprecation.js) -- [parallel/test-perf-gc-crash.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-perf-gc-crash.js) - [parallel/test-perf-hooks-histogram.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-perf-hooks-histogram.js) - [parallel/test-perf-hooks-resourcetiming.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-perf-hooks-resourcetiming.js) - [parallel/test-perf-hooks-usertiming.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-perf-hooks-usertiming.js) @@ -1898,7 +1530,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-performance-nodetiming.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-performance-nodetiming.js) - [parallel/test-performance-resourcetimingbufferfull.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-performance-resourcetimingbufferfull.js) - [parallel/test-performance-resourcetimingbuffersize.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-performance-resourcetimingbuffersize.js) -- [parallel/test-performanceobserver-gc.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-performanceobserver-gc.js) - [parallel/test-performanceobserver.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-performanceobserver.js) - [parallel/test-permission-allow-child-process-cli.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-permission-allow-child-process-cli.js) - [parallel/test-permission-allow-worker-cli.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-permission-allow-worker-cli.js) @@ -1927,10 +1558,8 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-pipe-file-to-http.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-pipe-file-to-http.js) - [parallel/test-pipe-head.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-pipe-head.js) - [parallel/test-pipe-outgoing-message-data-emitted-after-ended.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-pipe-outgoing-message-data-emitted-after-ended.js) -- [parallel/test-pipe-return-val.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-pipe-return-val.js) - [parallel/test-pipe-stream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-pipe-stream.js) - [parallel/test-pipe-unref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-pipe-unref.js) -- [parallel/test-pipe-writev.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-pipe-writev.js) - [parallel/test-policy-crypto-default-encoding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-policy-crypto-default-encoding.js) - [parallel/test-policy-crypto-hash-tampering.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-policy-crypto-hash-tampering.js) - [parallel/test-policy-dependencies.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-policy-dependencies.js) @@ -1950,12 +1579,9 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-primordials-promise.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-primordials-promise.js) - [parallel/test-primordials-regexp.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-primordials-regexp.js) - [parallel/test-priority-queue.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-priority-queue.js) -- [parallel/test-process-abort.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-abort.js) -- [parallel/test-process-argv-0.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-argv-0.js) - [parallel/test-process-assert.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-assert.js) - [parallel/test-process-beforeexit-throw-exit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-beforeexit-throw-exit.js) - [parallel/test-process-binding-util.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-binding-util.js) -- [parallel/test-process-binding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-binding.js) - [parallel/test-process-chdir-errormessage.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-chdir-errormessage.js) - [parallel/test-process-chdir.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-chdir.js) - [parallel/test-process-config.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-config.js) @@ -1963,19 +1589,14 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-process-constrained-memory.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-constrained-memory.js) - [parallel/test-process-cpuUsage.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-cpuUsage.js) - [parallel/test-process-dlopen-error-message-crash.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-dlopen-error-message-crash.js) -- [parallel/test-process-dlopen-undefined-exports.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-dlopen-undefined-exports.js) -- [parallel/test-process-domain-segfault.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-domain-segfault.js) - [parallel/test-process-emit-warning-from-native.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-emit-warning-from-native.js) - [parallel/test-process-emit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-emit.js) -- [parallel/test-process-emitwarning.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-emitwarning.js) - [parallel/test-process-env-allowed-flags-are-documented.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-env-allowed-flags-are-documented.js) -- [parallel/test-process-env-delete.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-env-delete.js) - [parallel/test-process-env-deprecation.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-env-deprecation.js) - [parallel/test-process-env-ignore-getter-setter.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-env-ignore-getter-setter.js) - [parallel/test-process-env-sideeffects.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-env-sideeffects.js) - [parallel/test-process-env-symbols.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-env-symbols.js) - [parallel/test-process-env-tz.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-env-tz.js) -- [parallel/test-process-env-windows-error-reset.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-env-windows-error-reset.js) - [parallel/test-process-env.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-env.js) - [parallel/test-process-euid-egid.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-euid-egid.js) - [parallel/test-process-exception-capture-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-exception-capture-errors.js) @@ -1997,17 +1618,11 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-process-getactiveresources-track-multiple-timers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-getactiveresources-track-multiple-timers.js) - [parallel/test-process-getactiveresources-track-timer-lifetime.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-getactiveresources-track-timer-lifetime.js) - [parallel/test-process-getactiveresources.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-getactiveresources.js) -- [parallel/test-process-getgroups.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-getgroups.js) -- [parallel/test-process-hrtime-bigint.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-hrtime-bigint.js) - [parallel/test-process-hrtime.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-hrtime.js) - [parallel/test-process-initgroups.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-initgroups.js) - [parallel/test-process-kill-null.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-kill-null.js) -- [parallel/test-process-next-tick.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-next-tick.js) -- [parallel/test-process-no-deprecation.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-no-deprecation.js) -- [parallel/test-process-ppid.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-ppid.js) - [parallel/test-process-prototype.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-prototype.js) - [parallel/test-process-raw-debug.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-raw-debug.js) -- [parallel/test-process-really-exit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-really-exit.js) - [parallel/test-process-redirect-warnings-env.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-redirect-warnings-env.js) - [parallel/test-process-redirect-warnings.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-redirect-warnings.js) - [parallel/test-process-release.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-release.js) @@ -2021,8 +1636,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-process-umask.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-umask.js) - [parallel/test-process-uncaught-exception-monitor.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-uncaught-exception-monitor.js) - [parallel/test-process-versions.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-versions.js) -- [parallel/test-process-warning.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-process-warning.js) -- [parallel/test-promise-handled-rejection-no-warning.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-promise-handled-rejection-no-warning.js) - [parallel/test-promise-hook-create-hook.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-promise-hook-create-hook.js) - [parallel/test-promise-hook-exceptions.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-promise-hook-exceptions.js) - [parallel/test-promise-hook-on-after.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-promise-hook-on-after.js) @@ -2044,16 +1657,8 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-promises-warning-on-unhandled-rejection.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-promises-warning-on-unhandled-rejection.js) - [parallel/test-queue-microtask-uncaught-asynchooks.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-queue-microtask-uncaught-asynchooks.js) - [parallel/test-queue-microtask.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-queue-microtask.js) -- [parallel/test-readable-from-iterator-closing.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readable-from-iterator-closing.js) - [parallel/test-readable-from-web-enqueue-then-close.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readable-from-web-enqueue-then-close.js) -- [parallel/test-readable-from.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readable-from.js) -- [parallel/test-readable-large-hwm.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readable-large-hwm.js) -- [parallel/test-readable-single-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readable-single-end.js) - [parallel/test-readline-async-iterators-backpressure.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readline-async-iterators-backpressure.js) -- [parallel/test-readline-async-iterators-destroy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readline-async-iterators-destroy.js) -- [parallel/test-readline-async-iterators.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readline-async-iterators.js) -- [parallel/test-readline-carriage-return-between-chunks.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readline-carriage-return-between-chunks.js) -- [parallel/test-readline-csi.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readline-csi.js) - [parallel/test-readline-input-onerror.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readline-input-onerror.js) - [parallel/test-readline-interface-no-trailing-newline.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readline-interface-no-trailing-newline.js) - [parallel/test-readline-interface-recursive-writes.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readline-interface-recursive-writes.js) @@ -2061,8 +1666,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-readline-promises-interface.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readline-promises-interface.js) - [parallel/test-readline-promises-tab-complete.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readline-promises-tab-complete.js) - [parallel/test-readline-tab-complete.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-readline-tab-complete.js) -- [parallel/test-ref-unref-return.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-ref-unref-return.js) -- [parallel/test-regression-object-prototype.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-regression-object-prototype.js) - [parallel/test-release-changelog.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-release-changelog.js) - [parallel/test-release-npm.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-release-npm.js) - [parallel/test-repl-array-prototype-tempering.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-repl-array-prototype-tempering.js) @@ -2150,13 +1753,9 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-require-extensions-same-filename-as-dir-trailing-slash.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-require-extensions-same-filename-as-dir-trailing-slash.js) - [parallel/test-require-extensions-same-filename-as-dir.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-require-extensions-same-filename-as-dir.js) - [parallel/test-require-invalid-main-no-exports.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-require-invalid-main-no-exports.js) -- [parallel/test-require-invalid-package.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-require-invalid-package.js) - [parallel/test-require-json.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-require-json.js) -- [parallel/test-require-long-path.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-require-long-path.js) - [parallel/test-require-mjs.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-require-mjs.js) - [parallel/test-require-node-prefix.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-require-node-prefix.js) -- [parallel/test-require-nul.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-require-nul.js) -- [parallel/test-require-process.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-require-process.js) - [parallel/test-require-resolve.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-require-resolve.js) - [parallel/test-require-symlink.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-require-symlink.js) - [parallel/test-require-unicode.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-require-unicode.js) @@ -2197,8 +1796,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-shadow-realm.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-shadow-realm.js) - [parallel/test-sigint-infinite-loop.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-sigint-infinite-loop.js) - [parallel/test-signal-args.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-signal-args.js) -- [parallel/test-signal-handler-remove-on-exit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-signal-handler-remove-on-exit.js) -- [parallel/test-signal-handler.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-signal-handler.js) - [parallel/test-signal-safety.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-signal-safety.js) - [parallel/test-signal-unregister.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-signal-unregister.js) - [parallel/test-single-executable-blob-config-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-single-executable-blob-config-errors.js) @@ -2224,113 +1821,68 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-snapshot-warning.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-snapshot-warning.js) - [parallel/test-snapshot-weak-reference.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-snapshot-weak-reference.js) - [parallel/test-snapshot-worker.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-snapshot-worker.js) -- [parallel/test-socket-address.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-socket-address.js) - [parallel/test-socket-options-invalid.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-socket-options-invalid.js) -- [parallel/test-socket-write-after-fin-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-socket-write-after-fin-error.js) - [parallel/test-socket-write-after-fin.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-socket-write-after-fin.js) - [parallel/test-socket-writes-before-passed-to-tls-socket.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-socket-writes-before-passed-to-tls-socket.js) - [parallel/test-socketaddress.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-socketaddress.js) - [parallel/test-source-map-api.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-source-map-api.js) -- [parallel/test-source-map-enable.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-source-map-enable.js) -- [parallel/test-spawn-cmd-named-pipe.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-spawn-cmd-named-pipe.js) - [parallel/test-stack-size-limit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stack-size-limit.js) - [parallel/test-startup-empty-regexp-statics.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-startup-empty-regexp-statics.js) - [parallel/test-startup-large-pages.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-startup-large-pages.js) - [parallel/test-stdin-child-proc.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdin-child-proc.js) - [parallel/test-stdin-from-file.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdin-from-file.js) -- [parallel/test-stdin-hang.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdin-hang.js) - [parallel/test-stdin-pause-resume-sync.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdin-pause-resume-sync.js) - [parallel/test-stdin-pause-resume.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdin-pause-resume.js) -- [parallel/test-stdin-pipe-large.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdin-pipe-large.js) -- [parallel/test-stdin-pipe-resume.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdin-pipe-resume.js) - [parallel/test-stdin-resume-pause.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdin-resume-pause.js) -- [parallel/test-stdin-script-child-option.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdin-script-child-option.js) - [parallel/test-stdin-script-child.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdin-script-child.js) - [parallel/test-stdio-closed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdio-closed.js) -- [parallel/test-stdio-pipe-access.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdio-pipe-access.js) -- [parallel/test-stdio-pipe-redirect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdio-pipe-redirect.js) -- [parallel/test-stdio-pipe-stderr.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdio-pipe-stderr.js) -- [parallel/test-stdio-undestroy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdio-undestroy.js) -- [parallel/test-stdout-cannot-be-closed-child-process-pipe.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdout-cannot-be-closed-child-process-pipe.js) - [parallel/test-stdout-close-catch.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdout-close-catch.js) - [parallel/test-stdout-close-unref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdout-close-unref.js) -- [parallel/test-stdout-pipeline-destroy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdout-pipeline-destroy.js) -- [parallel/test-stdout-stderr-reading.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdout-stderr-reading.js) -- [parallel/test-stdout-stderr-write.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdout-stderr-write.js) - [parallel/test-stdout-to-file.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stdout-to-file.js) - [parallel/test-strace-openat-openssl.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-strace-openat-openssl.js) - [parallel/test-stream-base-prototype-accessors-enumerability.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-base-prototype-accessors-enumerability.js) - [parallel/test-stream-base-typechecking.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-base-typechecking.js) -- [parallel/test-stream-catch-rejections.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-catch-rejections.js) - [parallel/test-stream-compose-operator.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-compose-operator.js) - [parallel/test-stream-compose.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-compose.js) - [parallel/test-stream-consumers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-consumers.js) -- [parallel/test-stream-decoder-objectmode.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-decoder-objectmode.js) - [parallel/test-stream-destroy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-destroy.js) - [parallel/test-stream-drop-take.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-drop-take.js) -- [parallel/test-stream-duplex-readable-writable.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-duplex-readable-writable.js) -- [parallel/test-stream-end-of-streams.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-end-of-streams.js) -- [parallel/test-stream-filter.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-filter.js) - [parallel/test-stream-finished.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-finished.js) -- [parallel/test-stream-flatMap.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-flatMap.js) -- [parallel/test-stream-forEach.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-forEach.js) - [parallel/test-stream-map.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-map.js) -- [parallel/test-stream-passthrough-drain.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-passthrough-drain.js) - [parallel/test-stream-pipe-deadlock.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-pipe-deadlock.js) -- [parallel/test-stream-pipe-error-unhandled.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-pipe-error-unhandled.js) -- [parallel/test-stream-pipeline-duplex.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-pipeline-duplex.js) - [parallel/test-stream-pipeline-http2.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-pipeline-http2.js) -- [parallel/test-stream-pipeline-listeners.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-pipeline-listeners.js) - [parallel/test-stream-pipeline-process.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-pipeline-process.js) -- [parallel/test-stream-pipeline-uncaught.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-pipeline-uncaught.js) - [parallel/test-stream-pipeline.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-pipeline.js) - [parallel/test-stream-preprocess.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-preprocess.js) - [parallel/test-stream-promises.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-promises.js) -- [parallel/test-stream-push-order.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-push-order.js) - [parallel/test-stream-readable-async-iterators.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-readable-async-iterators.js) - [parallel/test-stream-readable-default-encoding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-readable-default-encoding.js) - [parallel/test-stream-readable-dispose.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-readable-dispose.js) -- [parallel/test-stream-readable-strategy-option.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-readable-strategy-option.js) -- [parallel/test-stream-readable-unpipe-resume.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-readable-unpipe-resume.js) -- [parallel/test-stream-reduce.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-reduce.js) - [parallel/test-stream-set-default-hwm.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-set-default-hwm.js) -- [parallel/test-stream-toArray.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-toArray.js) -- [parallel/test-stream-toWeb-allows-server-response.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-toWeb-allows-server-response.js) -- [parallel/test-stream-transform-hwm0.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-transform-hwm0.js) - [parallel/test-stream-wrap-drain.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-wrap-drain.js) - [parallel/test-stream-wrap-encoding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-wrap-encoding.js) - [parallel/test-stream-wrap.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-wrap.js) -- [parallel/test-stream-writable-end-cb-uncaught.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-writable-end-cb-uncaught.js) - [parallel/test-stream-writable-samecb-singletick.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream-writable-samecb-singletick.js) -- [parallel/test-stream2-finish-pipe-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream2-finish-pipe-error.js) - [parallel/test-stream2-httpclient-response-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream2-httpclient-response-end.js) -- [parallel/test-stream3-pipeline-async-iterator.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stream3-pipeline-async-iterator.js) - [parallel/test-string-decoder-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-string-decoder-end.js) - [parallel/test-string-decoder-fuzz.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-string-decoder-fuzz.js) -- [parallel/test-stringbytes-external.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-stringbytes-external.js) - [parallel/test-structuredClone-global.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-structuredClone-global.js) -- [parallel/test-sync-fileread.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-sync-fileread.js) - [parallel/test-sync-io-option.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-sync-io-option.js) -- [parallel/test-sys.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-sys.js) - [parallel/test-tcp-wrap-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tcp-wrap-connect.js) - [parallel/test-tcp-wrap-listen.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tcp-wrap-listen.js) - [parallel/test-tcp-wrap.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tcp-wrap.js) -- [parallel/test-tick-processor-arguments.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tick-processor-arguments.js) - [parallel/test-tick-processor-version-check.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tick-processor-version-check.js) - [parallel/test-timer-immediate.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timer-immediate.js) - [parallel/test-timers-active.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-active.js) -- [parallel/test-timers-clearImmediate-als.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-clearImmediate-als.js) - [parallel/test-timers-destroyed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-destroyed.js) - [parallel/test-timers-dispose.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-dispose.js) - [parallel/test-timers-enroll-invalid-msecs.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-enroll-invalid-msecs.js) - [parallel/test-timers-enroll-second-time.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-enroll-second-time.js) - [parallel/test-timers-immediate-promisified.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-immediate-promisified.js) - [parallel/test-timers-immediate-queue-throw.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-immediate-queue-throw.js) -- [parallel/test-timers-immediate-queue.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-immediate-queue.js) - [parallel/test-timers-immediate-unref-nested-once.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-immediate-unref-nested-once.js) - [parallel/test-timers-immediate-unref-simple.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-immediate-unref-simple.js) - [parallel/test-timers-immediate-unref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-immediate-unref.js) -- [parallel/test-timers-immediate.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-immediate.js) - [parallel/test-timers-interval-promisified.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-interval-promisified.js) - [parallel/test-timers-linked-list.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-linked-list.js) - [parallel/test-timers-max-duration-warning.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-max-duration-warning.js) @@ -2339,10 +1891,7 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-timers-now.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-now.js) - [parallel/test-timers-ordering.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-ordering.js) - [parallel/test-timers-promises-scheduler.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-promises-scheduler.js) -- [parallel/test-timers-refresh-in-callback.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-refresh-in-callback.js) - [parallel/test-timers-reset-process-domain-on-throw.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-reset-process-domain-on-throw.js) -- [parallel/test-timers-setimmediate-infinite-loop.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-setimmediate-infinite-loop.js) -- [parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js) - [parallel/test-timers-this.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-this.js) - [parallel/test-timers-throw-when-cb-not-function.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-throw-when-cb-not-function.js) - [parallel/test-timers-timeout-promisified.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-timeout-promisified.js) @@ -2352,16 +1901,9 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-timers-unref-active.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-unref-active.js) - [parallel/test-timers-unref-remove-other-unref-timers-only-one-fires.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-unref-remove-other-unref-timers-only-one-fires.js) - [parallel/test-timers-unref-remove-other-unref-timers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-unref-remove-other-unref-timers.js) -- [parallel/test-timers-unref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-unref.js) -- [parallel/test-timers-unrefd-interval-still-fires.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-unrefd-interval-still-fires.js) -- [parallel/test-timers-unrefed-in-beforeexit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-unrefed-in-beforeexit.js) -- [parallel/test-timers-unrefed-in-callback.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers-unrefed-in-callback.js) -- [parallel/test-timers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-timers.js) - [parallel/test-tls-0-dns-altname.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-0-dns-altname.js) - [parallel/test-tls-add-context.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-add-context.js) - [parallel/test-tls-addca.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-addca.js) -- [parallel/test-tls-alert-handling.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-alert-handling.js) -- [parallel/test-tls-alert.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-alert.js) - [parallel/test-tls-alpn-server-client.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-alpn-server-client.js) - [parallel/test-tls-async-cb-after-socket-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-async-cb-after-socket-end.js) - [parallel/test-tls-basic-validations.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-basic-validations.js) @@ -2391,7 +1933,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-tls-client-reject-12.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-client-reject-12.js) - [parallel/test-tls-client-reject.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-client-reject.js) - [parallel/test-tls-client-renegotiation-13.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-client-renegotiation-13.js) -- [parallel/test-tls-client-renegotiation-limit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-client-renegotiation-limit.js) - [parallel/test-tls-client-resume-12.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-client-resume-12.js) - [parallel/test-tls-client-resume.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-client-resume.js) - [parallel/test-tls-client-verify.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-client-verify.js) @@ -2419,19 +1960,12 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-tls-destroy-stream-12.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-destroy-stream-12.js) - [parallel/test-tls-destroy-stream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-destroy-stream.js) - [parallel/test-tls-destroy-whilst-write.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-destroy-whilst-write.js) -- [parallel/test-tls-dhe.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-dhe.js) - [parallel/test-tls-disable-renegotiation.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-disable-renegotiation.js) -- [parallel/test-tls-ecdh-auto.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-ecdh-auto.js) -- [parallel/test-tls-ecdh-multiple.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-ecdh-multiple.js) -- [parallel/test-tls-ecdh.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-ecdh.js) - [parallel/test-tls-econnreset.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-econnreset.js) - [parallel/test-tls-empty-sni-context.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-empty-sni-context.js) - [parallel/test-tls-enable-keylog-cli.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-enable-keylog-cli.js) -- [parallel/test-tls-enable-trace-cli.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-enable-trace-cli.js) -- [parallel/test-tls-enable-trace.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-enable-trace.js) - [parallel/test-tls-env-bad-extra-ca.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-env-bad-extra-ca.js) - [parallel/test-tls-env-extra-ca-file-load.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-env-extra-ca-file-load.js) -- [parallel/test-tls-env-extra-ca-no-crypto.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-env-extra-ca-no-crypto.js) - [parallel/test-tls-env-extra-ca.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-env-extra-ca.js) - [parallel/test-tls-error-servername.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-error-servername.js) - [parallel/test-tls-exportkeyingmaterial.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-exportkeyingmaterial.js) @@ -2473,7 +2007,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-tls-no-rsa-key.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-no-rsa-key.js) - [parallel/test-tls-no-sslv23.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-no-sslv23.js) - [parallel/test-tls-no-sslv3.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-no-sslv3.js) -- [parallel/test-tls-ocsp-callback.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-ocsp-callback.js) - [parallel/test-tls-on-empty-socket.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-on-empty-socket.js) - [parallel/test-tls-onread-static-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-onread-static-buffer.js) - [parallel/test-tls-options-boolean-check.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-options-boolean-check.js) @@ -2486,7 +2019,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-tls-pfx-authorizationerror.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-pfx-authorizationerror.js) - [parallel/test-tls-psk-circuit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-psk-circuit.js) - [parallel/test-tls-psk-errors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-psk-errors.js) -- [parallel/test-tls-psk-server.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-psk-server.js) - [parallel/test-tls-reduced-SECLEVEL-in-cipher.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-reduced-SECLEVEL-in-cipher.js) - [parallel/test-tls-reinitialize-listeners.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-reinitialize-listeners.js) - [parallel/test-tls-request-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-request-timeout.js) @@ -2497,16 +2029,12 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-tls-secure-session.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-secure-session.js) - [parallel/test-tls-securepair-fiftharg.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-securepair-fiftharg.js) - [parallel/test-tls-securepair-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-securepair-leak.js) -- [parallel/test-tls-securepair-server.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-securepair-server.js) - [parallel/test-tls-server-capture-rejection.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-server-capture-rejection.js) - [parallel/test-tls-server-connection-server.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-server-connection-server.js) - [parallel/test-tls-server-failed-handshake-emits-clienterror.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-server-failed-handshake-emits-clienterror.js) - [parallel/test-tls-server-parent-constructor-options.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-server-parent-constructor-options.js) - [parallel/test-tls-server-setoptions-clientcertengine.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-server-setoptions-clientcertengine.js) -- [parallel/test-tls-server-verify.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-server-verify.js) -- [parallel/test-tls-session-cache.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-session-cache.js) - [parallel/test-tls-set-ciphers-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-set-ciphers-error.js) -- [parallel/test-tls-set-ciphers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-set-ciphers.js) - [parallel/test-tls-set-encoding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-set-encoding.js) - [parallel/test-tls-set-secure-context.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-set-secure-context.js) - [parallel/test-tls-set-sigalgs.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-set-sigalgs.js) @@ -2533,7 +2061,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-tls-tlswrap-segfault-2.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-tlswrap-segfault-2.js) - [parallel/test-tls-tlswrap-segfault.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-tlswrap-segfault.js) - [parallel/test-tls-translate-peer-certificate.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-translate-peer-certificate.js) -- [parallel/test-tls-transport-destroy-after-own-gc.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-transport-destroy-after-own-gc.js) - [parallel/test-tls-use-after-free-regression.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-use-after-free-regression.js) - [parallel/test-tls-wrap-econnreset-localaddress.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-wrap-econnreset-localaddress.js) - [parallel/test-tls-wrap-econnreset-pipe.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tls-wrap-econnreset-pipe.js) @@ -2550,8 +2077,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-trace-events-all.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-trace-events-all.js) - [parallel/test-trace-events-api-worker-disabled.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-trace-events-api-worker-disabled.js) - [parallel/test-trace-events-api.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-trace-events-api.js) -- [parallel/test-trace-events-async-hooks-dynamic.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-trace-events-async-hooks-dynamic.js) -- [parallel/test-trace-events-async-hooks-worker.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-trace-events-async-hooks-worker.js) - [parallel/test-trace-events-async-hooks.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-trace-events-async-hooks.js) - [parallel/test-trace-events-binding.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-trace-events-binding.js) - [parallel/test-trace-events-bootstrap.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-trace-events-bootstrap.js) @@ -2580,7 +2105,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-tty-stdin-pipe.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tty-stdin-pipe.js) - [parallel/test-ttywrap-invalid-fd.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-ttywrap-invalid-fd.js) - [parallel/test-ttywrap-stack.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-ttywrap-stack.js) -- [parallel/test-tz-version.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-tz-version.js) - [parallel/test-unhandled-exception-rethrow-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-unhandled-exception-rethrow-error.js) - [parallel/test-unhandled-exception-with-worker-inuse.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-unhandled-exception-with-worker-inuse.js) - [parallel/test-unicode-node-options.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-unicode-node-options.js) @@ -2588,36 +2112,24 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-url-is-url.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-url-is-url.js) - [parallel/test-url-null-char.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-url-null-char.js) - [parallel/test-url-parse-format.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-url-parse-format.js) -- [parallel/test-utf8-scripts.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-utf8-scripts.js) - [parallel/test-util-callbackify.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-util-callbackify.js) - [parallel/test-util-emit-experimental-warning.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-util-emit-experimental-warning.js) -- [parallel/test-util-inspect-getters-accessing-this.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-util-inspect-getters-accessing-this.js) - [parallel/test-util-internal.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-util-internal.js) - [parallel/test-util-log.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-util-log.js) -- [parallel/test-util-primordial-monkeypatching.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-util-primordial-monkeypatching.js) - [parallel/test-util-sigint-watchdog.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-util-sigint-watchdog.js) - [parallel/test-util-sleep.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-util-sleep.js) -- [parallel/test-uv-binding-constant.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-uv-binding-constant.js) - [parallel/test-uv-errmap.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-uv-errmap.js) - [parallel/test-uv-errno.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-uv-errno.js) -- [parallel/test-uv-unmapped-exception.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-uv-unmapped-exception.js) - [parallel/test-v8-collect-gc-profile-exit-before-stop.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-collect-gc-profile-exit-before-stop.js) - [parallel/test-v8-collect-gc-profile-in-worker.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-collect-gc-profile-in-worker.js) - [parallel/test-v8-collect-gc-profile.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-collect-gc-profile.js) -- [parallel/test-v8-coverage.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-coverage.js) -- [parallel/test-v8-deserialize-buffer.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-deserialize-buffer.js) -- [parallel/test-v8-flag-pool-size-0.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-flag-pool-size-0.js) - [parallel/test-v8-flag-type-check.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-flag-type-check.js) - [parallel/test-v8-flags.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-flags.js) - [parallel/test-v8-getheapsnapshot-twice.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-getheapsnapshot-twice.js) -- [parallel/test-v8-global-setter.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-global-setter.js) - [parallel/test-v8-serdes.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-serdes.js) - [parallel/test-v8-serialize-leak.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-serialize-leak.js) - [parallel/test-v8-startup-snapshot-api.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-startup-snapshot-api.js) - [parallel/test-v8-stats.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-stats.js) -- [parallel/test-v8-stop-coverage.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-stop-coverage.js) -- [parallel/test-v8-take-coverage-noop.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-take-coverage-noop.js) -- [parallel/test-v8-take-coverage.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-take-coverage.js) - [parallel/test-v8-version-tag.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-v8-version-tag.js) - [parallel/test-validators.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-validators.js) - [parallel/test-vfs.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-vfs.js) @@ -2651,7 +2163,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-vm-timeout-escape-promise-module.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-vm-timeout-escape-promise-module.js) - [parallel/test-warn-sigprof.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-warn-sigprof.js) - [parallel/test-warn-stream-wrap.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-warn-stream-wrap.js) -- [parallel/test-weakref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-weakref.js) - [parallel/test-webcrypto-constructors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webcrypto-constructors.js) - [parallel/test-webcrypto-cryptokey-workers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webcrypto-cryptokey-workers.js) - [parallel/test-webcrypto-derivebits-cfrg.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webcrypto-derivebits-cfrg.js) @@ -2664,7 +2175,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-webcrypto-digest.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webcrypto-digest.js) - [parallel/test-webcrypto-encrypt-decrypt-aes.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webcrypto-encrypt-decrypt-aes.js) - [parallel/test-webcrypto-encrypt-decrypt-rsa.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webcrypto-encrypt-decrypt-rsa.js) -- [parallel/test-webcrypto-encrypt-decrypt.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webcrypto-encrypt-decrypt.js) - [parallel/test-webcrypto-export-import-cfrg.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webcrypto-export-import-cfrg.js) - [parallel/test-webcrypto-export-import-ec.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webcrypto-export-import-ec.js) - [parallel/test-webcrypto-export-import-rsa.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webcrypto-export-import-rsa.js) @@ -2679,10 +2189,8 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-webcrypto-util.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webcrypto-util.js) - [parallel/test-webcrypto-webidl.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webcrypto-webidl.js) - [parallel/test-webcrypto-wrap-unwrap.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webcrypto-wrap-unwrap.js) -- [parallel/test-websocket.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-websocket.js) - [parallel/test-webstream-encoding-inspect.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webstream-encoding-inspect.js) - [parallel/test-webstream-readablestream-pipeto.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webstream-readablestream-pipeto.js) -- [parallel/test-webstream-string-tag.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webstream-string-tag.js) - [parallel/test-webstreams-abort-controller.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webstreams-abort-controller.js) - [parallel/test-webstreams-compose.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webstreams-compose.js) - [parallel/test-webstreams-finished.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-webstreams-finished.js) @@ -2699,7 +2207,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-whatwg-events-eventtarget-this-of-listener.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-whatwg-events-eventtarget-this-of-listener.js) - [parallel/test-whatwg-readablebytestream-bad-buffers-and-views.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-whatwg-readablebytestream-bad-buffers-and-views.js) - [parallel/test-whatwg-readablebytestream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-whatwg-readablebytestream.js) -- [parallel/test-whatwg-readablebytestreambyob.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-whatwg-readablebytestreambyob.js) - [parallel/test-whatwg-readablestream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-whatwg-readablestream.js) - [parallel/test-whatwg-transformstream.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-whatwg-transformstream.js) - [parallel/test-whatwg-url-canparse.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-whatwg-url-canparse.js) @@ -2746,7 +2253,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-worker-broadcastchannel-wpt.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-broadcastchannel-wpt.js) - [parallel/test-worker-broadcastchannel.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-broadcastchannel.js) - [parallel/test-worker-cjs-workerdata.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-cjs-workerdata.js) -- [parallel/test-worker-cleanexit-with-js.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-cleanexit-with-js.js) - [parallel/test-worker-cleanexit-with-moduleload.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-cleanexit-with-moduleload.js) - [parallel/test-worker-cleanup-handles.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-cleanup-handles.js) - [parallel/test-worker-console-listeners.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-console-listeners.js) @@ -2817,7 +2323,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-worker-no-sab.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-no-sab.js) - [parallel/test-worker-no-stdin-stdout-interaction.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-no-stdin-stdout-interaction.js) - [parallel/test-worker-non-fatal-uncaught-exception.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-non-fatal-uncaught-exception.js) -- [parallel/test-worker-on-process-exit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-on-process-exit.js) - [parallel/test-worker-onmessage-not-a-function.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-onmessage-not-a-function.js) - [parallel/test-worker-onmessage.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-onmessage.js) - [parallel/test-worker-parent-port-ref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-parent-port-ref.js) @@ -2826,7 +2331,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-worker-process-env-shared.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-process-env-shared.js) - [parallel/test-worker-process-env.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-process-env.js) - [parallel/test-worker-process-exit-async-module.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-process-exit-async-module.js) -- [parallel/test-worker-ref-onexit.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-ref-onexit.js) - [parallel/test-worker-ref.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-ref.js) - [parallel/test-worker-relative-path-double-dot.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-relative-path-double-dot.js) - [parallel/test-worker-relative-path.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-relative-path.js) @@ -2846,7 +2350,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-worker-terminate-ref-public-port.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-terminate-ref-public-port.js) - [parallel/test-worker-terminate-source-map.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-terminate-source-map.js) - [parallel/test-worker-terminate-timers.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-terminate-timers.js) -- [parallel/test-worker-terminate-unrefed.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-terminate-unrefed.js) - [parallel/test-worker-track-unmanaged-fds.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-track-unmanaged-fds.js) - [parallel/test-worker-type-check.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-type-check.js) - [parallel/test-worker-uncaught-exception-async.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-worker-uncaught-exception-async.js) @@ -2874,7 +2377,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-zlib-bytes-read.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-bytes-read.js) - [parallel/test-zlib-close-in-ondata.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-close-in-ondata.js) - [parallel/test-zlib-const.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-const.js) -- [parallel/test-zlib-create-raw.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-create-raw.js) - [parallel/test-zlib-deflate-constructors.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-deflate-constructors.js) - [parallel/test-zlib-destroy.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-destroy.js) - [parallel/test-zlib-dictionary-fail.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-dictionary-fail.js) @@ -2883,7 +2385,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [parallel/test-zlib-flush-drain-longblock.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-flush-drain-longblock.js) - [parallel/test-zlib-flush-drain.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-flush-drain.js) - [parallel/test-zlib-flush-flags.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-flush-flags.js) -- [parallel/test-zlib-flush-write-sync-interleaved.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-flush-write-sync-interleaved.js) - [parallel/test-zlib-flush.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-flush.js) - [parallel/test-zlib-from-concatenated-gzip.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-from-concatenated-gzip.js) - [parallel/test-zlib-from-gzip-with-trailing-garbage.js](https://github.com/nodejs/node/tree/v20.11.1/test/parallel/test-zlib-from-gzip-with-trailing-garbage.js) @@ -2912,9 +2413,7 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [pseudo-tty/test-handle-wrap-hasref-tty.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-handle-wrap-hasref-tty.js) - [pseudo-tty/test-readable-tty-keepalive.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-readable-tty-keepalive.js) - [pseudo-tty/test-repl-external-module.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-repl-external-module.js) -- [pseudo-tty/test-set-raw-mode-reset-process-exit.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-set-raw-mode-reset-process-exit.js) - [pseudo-tty/test-set-raw-mode-reset-signal.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-set-raw-mode-reset-signal.js) -- [pseudo-tty/test-set-raw-mode-reset.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-set-raw-mode-reset.js) - [pseudo-tty/test-stderr-stdout-handle-sigwinch.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-stderr-stdout-handle-sigwinch.js) - [pseudo-tty/test-stdin-write.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-stdin-write.js) - [pseudo-tty/test-stdout-read.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-stdout-read.js) @@ -2923,22 +2422,15 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [pseudo-tty/test-trace-sigint.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-trace-sigint.js) - [pseudo-tty/test-tty-color-support.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-tty-color-support.js) - [pseudo-tty/test-tty-isatty.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-tty-isatty.js) -- [pseudo-tty/test-tty-stdin-call-end.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-tty-stdin-call-end.js) - [pseudo-tty/test-tty-stdout-resize.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-tty-stdout-resize.js) - [pseudo-tty/test-tty-stream-constructors.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-tty-stream-constructors.js) - [pseudo-tty/test-tty-window-size.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-tty-window-size.js) - [pseudo-tty/test-tty-wrap.js](https://github.com/nodejs/node/tree/v20.11.1/test/pseudo-tty/test-tty-wrap.js) - [pummel/test-child-process-spawn-loop.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-child-process-spawn-loop.js) -- [pummel/test-crypto-dh-hash.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-crypto-dh-hash.js) - [pummel/test-crypto-dh-keys.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-crypto-dh-keys.js) -- [pummel/test-crypto-timing-safe-equal-benchmarks.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-crypto-timing-safe-equal-benchmarks.js) -- [pummel/test-dh-regr.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-dh-regr.js) -- [pummel/test-fs-largefile.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-fs-largefile.js) -- [pummel/test-fs-readfile-tostring-fail.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-fs-readfile-tostring-fail.js) - [pummel/test-fs-watch-file-slow.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-fs-watch-file-slow.js) - [pummel/test-fs-watch-file.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-fs-watch-file.js) - [pummel/test-fs-watch-non-recursive.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-fs-watch-non-recursive.js) -- [pummel/test-fs-watch-system-limit.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-fs-watch-system-limit.js) - [pummel/test-hash-seed.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-hash-seed.js) - [pummel/test-heapdump-dns.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-heapdump-dns.js) - [pummel/test-heapdump-env.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-heapdump-env.js) @@ -2949,7 +2441,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [pummel/test-heapdump-tls.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-heapdump-tls.js) - [pummel/test-heapdump-worker.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-heapdump-worker.js) - [pummel/test-heapdump-zlib.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-heapdump-zlib.js) -- [pummel/test-heapsnapshot-near-heap-limit-big.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-heapsnapshot-near-heap-limit-big.js) - [pummel/test-heapsnapshot-near-heap-limit-bounded.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-heapsnapshot-near-heap-limit-bounded.js) - [pummel/test-heapsnapshot-near-heap-limit-by-api.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-heapsnapshot-near-heap-limit-by-api.js) - [pummel/test-heapsnapshot-near-heap-limit.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-heapsnapshot-near-heap-limit.js) @@ -2958,9 +2449,7 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [pummel/test-https-large-response.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-https-large-response.js) - [pummel/test-https-no-reader.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-https-no-reader.js) - [pummel/test-keep-alive.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-keep-alive.js) -- [pummel/test-net-many-clients.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-net-many-clients.js) - [pummel/test-net-pause.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-net-pause.js) -- [pummel/test-net-pingpong-delay.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-net-pingpong-delay.js) - [pummel/test-net-pingpong.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-net-pingpong.js) - [pummel/test-net-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-net-timeout.js) - [pummel/test-net-timeout2.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-net-timeout2.js) @@ -2973,10 +2462,8 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [pummel/test-policy-integrity-worker-commonjs.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-policy-integrity-worker-commonjs.js) - [pummel/test-policy-integrity-worker-module.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-policy-integrity-worker-module.js) - [pummel/test-policy-integrity-worker-no-package-json.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-policy-integrity-worker-no-package-json.js) -- [pummel/test-process-cpuUsage.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-process-cpuUsage.js) - [pummel/test-process-hrtime.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-process-hrtime.js) - [pummel/test-regress-GH-892.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-regress-GH-892.js) -- [pummel/test-stream-pipe-multi.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-stream-pipe-multi.js) - [pummel/test-timers.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-timers.js) - [pummel/test-tls-server-large-request.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-tls-server-large-request.js) - [pummel/test-tls-throttle.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-tls-throttle.js) @@ -2986,7 +2473,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [pummel/test-webcrypto-derivebits-pbkdf2.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-webcrypto-derivebits-pbkdf2.js) - [pummel/test-worker-take-heapsnapshot.js](https://github.com/nodejs/node/tree/v20.11.1/test/pummel/test-worker-take-heapsnapshot.js) - [sequential/test-async-wrap-getasyncid.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-async-wrap-getasyncid.js) -- [sequential/test-buffer-creation-regression.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-buffer-creation-regression.js) - [sequential/test-child-process-emfile.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-child-process-emfile.js) - [sequential/test-child-process-execsync.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-child-process-execsync.js) - [sequential/test-child-process-pass-fd.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-child-process-pass-fd.js) @@ -3038,7 +2524,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [sequential/test-http-max-sockets.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-http-max-sockets.js) - [sequential/test-http-regr-gh-2928.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-http-regr-gh-2928.js) - [sequential/test-http-server-keep-alive-timeout-slow-client-headers.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-http-server-keep-alive-timeout-slow-client-headers.js) -- [sequential/test-http-server-keep-alive-timeout-slow-server.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-http-server-keep-alive-timeout-slow-server.js) - [sequential/test-http2-large-file.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-http2-large-file.js) - [sequential/test-http2-max-session-memory.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-http2-max-session-memory.js) - [sequential/test-http2-ping-flood.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-http2-ping-flood.js) @@ -3051,16 +2536,10 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [sequential/test-inspector-port-cluster.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-inspector-port-cluster.js) - [sequential/test-module-loading.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-module-loading.js) - [sequential/test-net-GH-5504.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-net-GH-5504.js) -- [sequential/test-net-better-error-messages-port.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-net-better-error-messages-port.js) - [sequential/test-net-connect-econnrefused.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-net-connect-econnrefused.js) -- [sequential/test-net-connect-handle-econnrefused.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-net-connect-handle-econnrefused.js) -- [sequential/test-net-connect-local-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-net-connect-local-error.js) - [sequential/test-net-listen-shared-ports.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-net-listen-shared-ports.js) - [sequential/test-net-localport.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-net-localport.js) -- [sequential/test-net-reconnect-error.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-net-reconnect-error.js) -- [sequential/test-net-response-size.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-net-response-size.js) - [sequential/test-net-server-address.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-net-server-address.js) -- [sequential/test-net-server-bind.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-net-server-bind.js) - [sequential/test-next-tick-error-spin.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-next-tick-error-spin.js) - [sequential/test-perf-hooks.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-perf-hooks.js) - [sequential/test-performance-eventloopdelay.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-performance-eventloopdelay.js) @@ -3081,10 +2560,6 @@ NOTE: This file should not be manually edited. Please edit `tests/node_compat/co - [sequential/test-timers-block-eventloop.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-timers-block-eventloop.js) - [sequential/test-timers-set-interval-excludes-callback-duration.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-timers-set-interval-excludes-callback-duration.js) - [sequential/test-tls-connect.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-tls-connect.js) -- [sequential/test-tls-lookup.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-tls-lookup.js) -- [sequential/test-tls-psk-client.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-tls-psk-client.js) -- [sequential/test-tls-securepair-client.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-tls-securepair-client.js) -- [sequential/test-tls-session-timeout.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-tls-session-timeout.js) - [sequential/test-util-debug.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-util-debug.js) - [sequential/test-vm-break-on-sigint.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-vm-break-on-sigint.js) - [sequential/test-vm-timeout-escape-promise-module-2.js](https://github.com/nodejs/node/tree/v20.11.1/test/sequential/test-vm-timeout-escape-promise-module-2.js) diff --git a/tests/node_compat/test/abort/test-addon-uv-handle-leak.js b/tests/node_compat/test/abort/test-addon-uv-handle-leak.js new file mode 100644 index 0000000000..618eea481d --- /dev/null +++ b/tests/node_compat/test/abort/test-addon-uv-handle-leak.js @@ -0,0 +1,143 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); +const cp = require('child_process'); +const { spawnSync } = require('child_process'); + +// This is a sibling test to test/addons/uv-handle-leak. + +const bindingPath = path.resolve( + __dirname, '..', 'addons', 'uv-handle-leak', 'build', + `${common.buildType}/binding.node`); + +if (!fs.existsSync(bindingPath)) + common.skip('binding not built yet'); + +if (process.argv[2] === 'child') { + + const { Worker } = require('worker_threads'); + + // The worker thread loads and then unloads `bindingPath`. Because of this the + // symbols in `bindingPath` are lost when the worker thread quits, but the + // number of open handles in the worker thread's event loop is assessed in the + // main thread afterwards, and the names of the callbacks associated with the + // open handles is retrieved at that time as well. Thus, we require + // `bindingPath` here so that the symbols and their names survive the life + // cycle of the worker thread. + require(bindingPath); + + new Worker(` + const binding = require(${JSON.stringify(bindingPath)}); + + binding.leakHandle(); + binding.leakHandle(0); + binding.leakHandle(0x42); + `, { eval: true }); +} else { + const child = cp.spawnSync(process.execPath, [__filename, 'child']); + const stderr = child.stderr.toString(); + + assert.strictEqual(child.stdout.toString(), ''); + + const lines = stderr.split('\n'); + + let state = 'initial'; + + // Parse output that is formatted like this: + + // uv loop at [0x559b65ed5770] has open handles: + // [0x7f2de0018430] timer (active) + // Close callback: 0x7f2df31de220 CloseCallback(uv_handle_s*) [...] + // Data: 0x7f2df33df140 example_instance [...] + // (First field): 0x7f2df33dedc0 vtable for ExampleOwnerClass [...] + // [0x7f2de000b870] timer + // Close callback: 0x7f2df31de220 CloseCallback(uv_handle_s*) [...] + // Data: (nil) + // [0x7f2de000b910] timer + // Close callback: 0x7f2df31de220 CloseCallback(uv_handle_s*) [...] + // Data: 0x42 + // uv loop at [0x559b65ed5770] has 3 open handles in total + + function isGlibc() { + try { + const lddOut = spawnSync('ldd', [process.execPath]).stdout; + const libcInfo = lddOut.toString().split('\n').map( + (line) => line.match(/libc\.so.+=>\s*(\S+)\s/)).filter((info) => info); + if (libcInfo.length === 0) + return false; + const nmOut = spawnSync('nm', ['-D', libcInfo[0][1]]).stdout; + if (/gnu_get_libc_version/.test(nmOut)) + return true; + } catch { + return false; + } + } + + + if (!(common.isFreeBSD || + common.isAIX || + common.isIBMi || + (common.isLinux && !isGlibc()) || + common.isWindows)) { + assert(stderr.includes('ExampleOwnerClass'), stderr); + assert(stderr.includes('CloseCallback'), stderr); + assert(stderr.includes('example_instance'), stderr); + } + + while (lines.length > 0) { + const line = lines.shift().trim(); + if (line.length === 0) { + continue; // Skip empty lines. + } + + switch (state) { + case 'initial': + assert.match(line, /^uv loop at \[.+\] has open handles:$/); + state = 'handle-start'; + break; + case 'handle-start': + if (/^uv loop at \[.+\] has \d+ open handles in total$/.test(line)) { + state = 'source-line'; + break; + } + assert.match(line, /^\[.+\] timer( \(active\))?$/); + state = 'close-callback'; + break; + case 'close-callback': + assert.match(line, /^Close callback:/); + state = 'data'; + break; + case 'data': + assert.match(line, /^Data: .+$/); + state = 'maybe-first-field'; + break; + case 'maybe-first-field': + if (!/^\(First field\)/.test(line)) { + lines.unshift(line); + } + state = 'handle-start'; + break; + case 'source-line': + assert.match(line, /CheckedUvLoopClose/); + state = 'assertion-failure'; + break; + case 'assertion-failure': + assert.match(line, /Assertion failed:/); + state = 'done'; + break; + case 'done': + break; + } + } + + assert.strictEqual(state, 'done'); +} diff --git a/tests/node_compat/test/benchmark/test-benchmark-async-hooks.js b/tests/node_compat/test/benchmark/test-benchmark-async-hooks.js new file mode 100644 index 0000000000..282d1b2fcf --- /dev/null +++ b/tests/node_compat/test/benchmark/test-benchmark-async-hooks.js @@ -0,0 +1,20 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.enoughTestMem) + common.skip('Insufficient memory for async_hooks benchmark test'); + +const runBenchmark = require('../common/benchmark'); + +runBenchmark('async_hooks'); diff --git a/tests/node_compat/test/benchmark/test-benchmark-http.js b/tests/node_compat/test/benchmark/test-benchmark-http.js new file mode 100644 index 0000000000..ee54b6ba37 --- /dev/null +++ b/tests/node_compat/test/benchmark/test-benchmark-http.js @@ -0,0 +1,21 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +if (!common.enoughTestMem) + common.skip('Insufficient memory for HTTP benchmark test'); + +// Because the http benchmarks use hardcoded ports, this should be in sequential +// rather than parallel to make sure it does not conflict with tests that choose +// random available ports. + +const runBenchmark = require('../common/benchmark'); + +runBenchmark('http', { NODEJS_BENCHMARK_ZERO_ALLOWED: 1 }); diff --git a/tests/node_compat/test/benchmark/test-benchmark-http2.js b/tests/node_compat/test/benchmark/test-benchmark-http2.js new file mode 100644 index 0000000000..d880132577 --- /dev/null +++ b/tests/node_compat/test/benchmark/test-benchmark-http2.js @@ -0,0 +1,23 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.enoughTestMem) + common.skip('Insufficient memory for HTTP/2 benchmark test'); + +// Because the http benchmarks use hardcoded ports, this should be in sequential +// rather than parallel to make sure it does not conflict with tests that choose +// random available ports. + +const runBenchmark = require('../common/benchmark'); + +runBenchmark('http2', { NODEJS_BENCHMARK_ZERO_ALLOWED: 1 }); diff --git a/tests/node_compat/test/benchmark/test-benchmark-tls.js b/tests/node_compat/test/benchmark/test-benchmark-tls.js new file mode 100644 index 0000000000..ae97d09872 --- /dev/null +++ b/tests/node_compat/test/benchmark/test-benchmark-tls.js @@ -0,0 +1,24 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.enoughTestMem) + common.skip('Insufficient memory for TLS benchmark test'); + +// Because the TLS benchmarks use hardcoded ports, this should be in sequential +// rather than parallel to make sure it does not conflict with tests that choose +// random available ports. + +const runBenchmark = require('../common/benchmark'); + +runBenchmark('tls', { NODEJS_BENCHMARK_ZERO_ALLOWED: 1 }); diff --git a/tests/node_compat/test/benchmark/test-benchmark-worker.js b/tests/node_compat/test/benchmark/test-benchmark-worker.js new file mode 100644 index 0000000000..ef65c9cc21 --- /dev/null +++ b/tests/node_compat/test/benchmark/test-benchmark-worker.js @@ -0,0 +1,21 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +if (!common.enoughTestMem) + common.skip('Insufficient memory for Worker benchmark test'); + +// Because the worker benchmarks can run on different threads, +// this should be in sequential rather than parallel to make sure +// it does not conflict with tests that choose random available ports. + +const runBenchmark = require('../common/benchmark'); + +runBenchmark('worker', { NODEJS_BENCHMARK_ZERO_ALLOWED: 1 }); diff --git a/tests/node_compat/test/es-module/test-cjs-prototype-pollution.js b/tests/node_compat/test/es-module/test-cjs-prototype-pollution.js new file mode 100644 index 0000000000..8859653f49 --- /dev/null +++ b/tests/node_compat/test/es-module/test-cjs-prototype-pollution.js @@ -0,0 +1,19 @@ +// 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. + +'use strict'; + +const { mustNotCall, mustCall } = require('../common'); + +Object.defineProperties(Object.prototype, { + then: { + set: mustNotCall('set %Object.prototype%.then'), + get: mustNotCall('get %Object.prototype%.then'), + }, +}); + +import('data:text/javascript,').then(mustCall()); diff --git a/tests/node_compat/test/es-module/test-esm-dynamic-import-mutating-fs.js b/tests/node_compat/test/es-module/test-esm-dynamic-import-mutating-fs.js new file mode 100644 index 0000000000..7e5050a87d --- /dev/null +++ b/tests/node_compat/test/es-module/test-esm-dynamic-import-mutating-fs.js @@ -0,0 +1,29 @@ +// 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. + +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); + +const assert = require('node:assert'); +const fs = require('node:fs/promises'); + +tmpdir.refresh(); +const target = tmpdir.fileURL(`${Math.random()}.mjs`); + +(async () => { + + await assert.rejects(import(target), { code: 'ERR_MODULE_NOT_FOUND' }); + + await fs.writeFile(target, 'export default "actual target"\n'); + + const moduleRecord = await import(target); + + await fs.rm(target); + + assert.strictEqual(await import(target), moduleRecord); +})().then(common.mustCall()); diff --git a/tests/node_compat/test/es-module/test-esm-loader-cache-clearing.js b/tests/node_compat/test/es-module/test-esm-loader-cache-clearing.js new file mode 100644 index 0000000000..0f511fc867 --- /dev/null +++ b/tests/node_compat/test/es-module/test-esm-loader-cache-clearing.js @@ -0,0 +1,17 @@ +// 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. + +'use strict'; +require('../common'); + +const { cache } = require; + +Object.keys(cache).forEach((key) => { + delete cache[key]; +}); +// Require the same module again triggers the crash +require('../common'); diff --git a/tests/node_compat/test/es-module/test-esm-windows.js b/tests/node_compat/test/es-module/test-esm-windows.js new file mode 100644 index 0000000000..9150dbc1d9 --- /dev/null +++ b/tests/node_compat/test/es-module/test-esm-windows.js @@ -0,0 +1,54 @@ +// 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. + +'use strict'; + +// This test ensures that JavaScript file that includes +// a reserved Windows word can be loaded as ESM module + +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs').promises; +const path = require('path'); + +const imp = (file) => { + return import(path.relative(__dirname, file).replace(/\\/g, '/')); +}; + +(async () => { + tmpdir.refresh(); + const rel = (file) => tmpdir.resolve(file); + + { // Load a single script + const file = rel('con.mjs'); + await fs.writeFile(file, 'export default "ok"'); + assert.strictEqual((await imp(file)).default, 'ok'); + await fs.unlink(file); + } + + { // Load a module + const entry = rel('entry.mjs'); + const nmDir = rel('node_modules'); + const mDir = rel('node_modules/con'); + const pkg = rel('node_modules/con/package.json'); + const script = rel('node_modules/con/index.mjs'); + + await fs.writeFile(entry, 'export {default} from "con"'); + await fs.mkdir(nmDir); + await fs.mkdir(mDir); + await fs.writeFile(pkg, '{"main":"index.mjs"}'); + await fs.writeFile(script, 'export default "ok"'); + + assert.strictEqual((await imp(entry)).default, 'ok'); + await fs.unlink(script); + await fs.unlink(pkg); + await fs.rmdir(mDir); + await fs.rmdir(nmDir); + await fs.unlink(entry); + } +})().then(common.mustCall()); diff --git a/tests/node_compat/test/es-module/test-vm-compile-function-lineoffset.js b/tests/node_compat/test/es-module/test-vm-compile-function-lineoffset.js new file mode 100644 index 0000000000..d287a3afb6 --- /dev/null +++ b/tests/node_compat/test/es-module/test-vm-compile-function-lineoffset.js @@ -0,0 +1,41 @@ +// 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. + +'use strict'; + +require('../common'); + +const assert = require('assert'); +const { compileFunction } = require('node:vm'); + +const min = -2147483648; +const max = 2147483647; + +compileFunction('', [], { lineOffset: min, columnOffset: min }); +compileFunction('', [], { lineOffset: max, columnOffset: max }); + +assert.throws( + () => { + compileFunction('', [], { lineOffset: min - 1, columnOffset: max }); + }, + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: /The value of "options\.lineOffset" is out of range/, + } +); + +assert.throws( + () => { + compileFunction('', [], { lineOffset: min, columnOffset: min - 1 }); + }, + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: /The value of "options\.columnOffset" is out of range/, + } +); diff --git a/tests/node_compat/test/message/eval_messages.js b/tests/node_compat/test/message/eval_messages.js new file mode 100644 index 0000000000..c8e41c9109 --- /dev/null +++ b/tests/node_compat/test/message/eval_messages.js @@ -0,0 +1,60 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +require('../common'); + +const spawn = require('child_process').spawn; + +function run(cmd, strict, cb) { + const args = []; + if (strict) args.push('--use_strict'); + args.push('-pe', cmd); + const child = spawn(process.execPath, args); + child.stdout.pipe(process.stdout); + child.stderr.pipe(process.stdout); + child.on('close', cb); +} + +const queue = + [ 'with(this){__filename}', + '42', + 'throw new Error("hello")', + 'var x = 100; y = x;', + 'var ______________________________________________; throw 10' ]; + +function go() { + const c = queue.shift(); + if (!c) return console.log('done'); + run(c, false, function() { + run(c, true, go); + }); +} + +go(); diff --git a/tests/node_compat/test/message/max_tick_depth.js b/tests/node_compat/test/message/max_tick_depth.js new file mode 100644 index 0000000000..5a2afb5967 --- /dev/null +++ b/tests/node_compat/test/message/max_tick_depth.js @@ -0,0 +1,38 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); + +process.maxTickDepth = 10; +let i = 20; +process.nextTick(function f() { + console.error(`tick ${i}`); + if (i-- > 0) + process.nextTick(f); +}); diff --git a/tests/node_compat/test/message/stdin_messages.js b/tests/node_compat/test/message/stdin_messages.js new file mode 100644 index 0000000000..15911b6999 --- /dev/null +++ b/tests/node_compat/test/message/stdin_messages.js @@ -0,0 +1,61 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +require('../common'); + +const spawn = require('child_process').spawn; + +function run(cmd, strict, cb) { + const args = []; + if (strict) args.push('--use_strict'); + args.push('-p'); + const child = spawn(process.execPath, args); + child.stdout.pipe(process.stdout); + child.stderr.pipe(process.stdout); + child.stdin.end(cmd); + child.on('close', cb); +} + +const queue = + [ 'with(this){__filename}', + '42', + 'throw new Error("hello")', + 'let x = 100; y = x;', + 'let ______________________________________________; throw 10' ]; + +function go() { + const c = queue.shift(); + if (!c) return console.log('done'); + run(c, false, function() { + run(c, true, go); + }); +} + +go(); diff --git a/tests/node_compat/test/message/util_inspect_error.js b/tests/node_compat/test/message/util_inspect_error.js new file mode 100644 index 0000000000..d3aad09fcd --- /dev/null +++ b/tests/node_compat/test/message/util_inspect_error.js @@ -0,0 +1,19 @@ +// 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. + +'use strict'; + +require('../common'); +const util = require('util'); + +const err = new Error('foo\nbar'); + +console.log(util.inspect({ err, nested: { err } }, { compact: true })); +console.log(util.inspect({ err, nested: { err } }, { compact: false })); + +err.foo = 'bar'; +console.log(util.inspect(err, { compact: true, breakLength: 5 })); diff --git a/tests/node_compat/test/parallel/test-arm-math-illegal-instruction.js b/tests/node_compat/test/parallel/test-arm-math-illegal-instruction.js new file mode 100644 index 0000000000..9eccee9887 --- /dev/null +++ b/tests/node_compat/test/parallel/test-arm-math-illegal-instruction.js @@ -0,0 +1,22 @@ +// 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. + +'use strict'; +require('../common'); + +// This test ensures Math functions don't fail with an "illegal instruction" +// error on ARM devices (primarily on the Raspberry Pi 1) +// See https://github.com/nodejs/node/issues/1376 +// and https://code.google.com/p/v8/issues/detail?id=4019 + +// Iterate over all Math functions +Object.getOwnPropertyNames(Math).forEach((functionName) => { + if (!/[A-Z]/.test(functionName)) { + // The function names don't have capital letters. + Math[functionName](-0.5); + } +}); diff --git a/tests/node_compat/test/parallel/test-async-hooks-run-in-async-scope-caught-exception.js b/tests/node_compat/test/parallel/test-async-hooks-run-in-async-scope-caught-exception.js new file mode 100644 index 0000000000..17e1e35a87 --- /dev/null +++ b/tests/node_compat/test/parallel/test-async-hooks-run-in-async-scope-caught-exception.js @@ -0,0 +1,18 @@ +// 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. + +'use strict'; + +require('../common'); +const { AsyncResource } = require('async_hooks'); + +try { + new AsyncResource('foo').runInAsyncScope(() => { throw new Error('bar'); }); +} catch { + // Continue regardless of error. +} +// Should abort (fail the case) if async id is not matching. diff --git a/tests/node_compat/test/parallel/test-async-hooks-run-in-async-scope-this-arg.js b/tests/node_compat/test/parallel/test-async-hooks-run-in-async-scope-this-arg.js new file mode 100644 index 0000000000..f6886347fb --- /dev/null +++ b/tests/node_compat/test/parallel/test-async-hooks-run-in-async-scope-this-arg.js @@ -0,0 +1,24 @@ +// 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. + +'use strict'; + +// Test that passing thisArg to runInAsyncScope() works. + +const common = require('../common'); +const assert = require('assert'); +const { AsyncResource } = require('async_hooks'); + +const thisArg = {}; + +const res = new AsyncResource('fhqwhgads'); + +function callback() { + assert.strictEqual(this, thisArg); +} + +res.runInAsyncScope(common.mustCall(callback), thisArg); diff --git a/tests/node_compat/test/parallel/test-async-local-storage-bind.js b/tests/node_compat/test/parallel/test-async-local-storage-bind.js new file mode 100644 index 0000000000..2036c47aa9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-async-local-storage-bind.js @@ -0,0 +1,24 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { AsyncLocalStorage } = require('async_hooks'); + +[1, false, '', {}, []].forEach((i) => { + assert.throws(() => AsyncLocalStorage.bind(i), { + code: 'ERR_INVALID_ARG_TYPE' + }); +}); + +const fn = common.mustCall(AsyncLocalStorage.bind(() => 123)); +assert.strictEqual(fn(), 123); + +const fn2 = AsyncLocalStorage.bind(common.mustCall((arg) => assert.strictEqual(arg, 'test'))); +fn2('test'); diff --git a/tests/node_compat/test/parallel/test-async-local-storage-contexts.js b/tests/node_compat/test/parallel/test-async-local-storage-contexts.js new file mode 100644 index 0000000000..de31622c14 --- /dev/null +++ b/tests/node_compat/test/parallel/test-async-local-storage-contexts.js @@ -0,0 +1,42 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const vm = require('vm'); +const { AsyncLocalStorage } = require('async_hooks'); + +// Regression test for https://github.com/nodejs/node/issues/38781 + +const context = vm.createContext({ + AsyncLocalStorage, + assert +}); + +vm.runInContext(` + const storage = new AsyncLocalStorage() + async function test() { + return storage.run({ test: 'vm' }, async () => { + assert.strictEqual(storage.getStore().test, 'vm'); + await 42; + assert.strictEqual(storage.getStore().test, 'vm'); + }); + } + test() +`, context); + +const storage = new AsyncLocalStorage(); +async function test() { + return storage.run({ test: 'main context' }, async () => { + assert.strictEqual(storage.getStore().test, 'main context'); + await 42; + assert.strictEqual(storage.getStore().test, 'main context'); + }); +} +test(); diff --git a/tests/node_compat/test/parallel/test-async-local-storage-deep-stack.js b/tests/node_compat/test/parallel/test-async-local-storage-deep-stack.js new file mode 100644 index 0000000000..ee51af0eab --- /dev/null +++ b/tests/node_compat/test/parallel/test-async-local-storage-deep-stack.js @@ -0,0 +1,22 @@ +// 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. + +'use strict'; +const common = require('../common'); +const { AsyncLocalStorage } = require('async_hooks'); + +// Regression test for: https://github.com/nodejs/node/issues/34556 + +const als = new AsyncLocalStorage(); + +const done = common.mustCall(); + +function run(count) { + if (count !== 0) return als.run({}, run, --count); + done(); +} +run(1000); diff --git a/tests/node_compat/test/parallel/test-async-local-storage-http-multiclients.js b/tests/node_compat/test/parallel/test-async-local-storage-http-multiclients.js new file mode 100644 index 0000000000..44e07f4c6b --- /dev/null +++ b/tests/node_compat/test/parallel/test-async-local-storage-http-multiclients.js @@ -0,0 +1,72 @@ +// 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. + +'use strict'; +const common = require('../common'); +const Countdown = require('../common/countdown'); +const assert = require('assert'); +const { AsyncLocalStorage } = require('async_hooks'); +const http = require('http'); +const cls = new AsyncLocalStorage(); +const NUM_CLIENTS = 10; + +// Run multiple clients that receive data from a server +// in multiple chunks, in a single non-closure function. +// Use the AsyncLocalStorage (ALS) APIs to maintain the context +// and data download. Make sure that individual clients +// receive their respective data, with no conflicts. + +// Set up a server that sends large buffers of data, filled +// with cardinal numbers, increasing per request +let index = 0; +const server = http.createServer((q, r) => { + // Send a large chunk as response, otherwise the data + // may be sent in a single chunk, and the callback in the + // client may be called only once, defeating the purpose of test + r.end((index++ % 10).toString().repeat(1024 * 1024)); +}); + +const countdown = new Countdown(NUM_CLIENTS, () => { + server.close(); +}); + +server.listen(0, common.mustCall(() => { + for (let i = 0; i < NUM_CLIENTS; i++) { + cls.run(new Map(), common.mustCall(() => { + const options = { port: server.address().port }; + const req = http.get(options, common.mustCall((res) => { + const store = cls.getStore(); + store.set('data', ''); + + // Make ondata and onend non-closure + // functions and fully dependent on ALS + res.setEncoding('utf8'); + res.on('data', ondata); + res.on('end', common.mustCall(onend)); + })); + req.end(); + })); + } +})); + +// Accumulate the current data chunk with the store data +function ondata(d) { + const store = cls.getStore(); + assert.notStrictEqual(store, undefined); + let chunk = store.get('data'); + chunk += d; + store.set('data', chunk); +} + +// Retrieve the store data, and test for homogeneity +function onend() { + const store = cls.getStore(); + assert.notStrictEqual(store, undefined); + const data = store.get('data'); + assert.strictEqual(data, data[0].repeat(data.length)); + countdown.dec(); +} diff --git a/tests/node_compat/test/parallel/test-async-local-storage-snapshot.js b/tests/node_compat/test/parallel/test-async-local-storage-snapshot.js new file mode 100644 index 0000000000..70fd7aa1c7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-async-local-storage-snapshot.js @@ -0,0 +1,23 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { strictEqual } = require('assert'); +const { AsyncLocalStorage } = require('async_hooks'); + +const asyncLocalStorage = new AsyncLocalStorage(); +const runInAsyncScope = + asyncLocalStorage.run(123, common.mustCall(() => AsyncLocalStorage.snapshot())); +const result = + asyncLocalStorage.run(321, common.mustCall(() => { + return runInAsyncScope(() => { + return asyncLocalStorage.getStore(); + }); + })); +strictEqual(result, 123); diff --git a/tests/node_compat/test/parallel/test-atomics-wake.js b/tests/node_compat/test/parallel/test-atomics-wake.js new file mode 100644 index 0000000000..c7a4eca36a --- /dev/null +++ b/tests/node_compat/test/parallel/test-atomics-wake.js @@ -0,0 +1,14 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +// https://github.com/nodejs/node/issues/21219 +assert.strictEqual(Atomics.wake, undefined); diff --git a/tests/node_compat/test/parallel/test-beforeexit-event-exit.js b/tests/node_compat/test/parallel/test-beforeexit-event-exit.js new file mode 100644 index 0000000000..ef8963abf5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-beforeexit-event-exit.js @@ -0,0 +1,34 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const { mustNotCall } = require('../common'); + +process.on('beforeExit', mustNotCall('exit should not allow this to occur')); + +process.exit(); diff --git a/tests/node_compat/test/parallel/test-blob-buffer-too-large.js b/tests/node_compat/test/parallel/test-blob-buffer-too-large.js new file mode 100644 index 0000000000..8ae291fda2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-blob-buffer-too-large.js @@ -0,0 +1,31 @@ +// 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: --no-warnings +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { Blob, kMaxLength } = require('buffer'); + +if (common.isFreeBSD) + common.skip('Oversized buffer make the FreeBSD CI runner crash'); + +try { + new Blob([new Uint8Array(kMaxLength), [1]]); +} catch (e) { + if ( + e.message === 'Array buffer allocation failed' || + e.message === `Invalid typed array length: ${kMaxLength}` + ) { + common.skip( + 'Insufficient memory on this platform for oversized buffer test.' + ); + } else { + assert.strictEqual(e.code, 'ERR_BUFFER_TOO_LARGE'); + } +} diff --git a/tests/node_compat/test/parallel/test-buffer-sharedarraybuffer.js b/tests/node_compat/test/parallel/test-buffer-sharedarraybuffer.js new file mode 100644 index 0000000000..a7e8f03d92 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-sharedarraybuffer.js @@ -0,0 +1,34 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +const sab = new SharedArrayBuffer(24); +const arr1 = new Uint16Array(sab); +const arr2 = new Uint16Array(12); +arr2[0] = 5000; +arr1[0] = 5000; +arr1[1] = 4000; +arr2[1] = 4000; + +const arr_buf = Buffer.from(arr1.buffer); +const ar_buf = Buffer.from(arr2.buffer); + +assert.deepStrictEqual(arr_buf, ar_buf); + +arr1[1] = 6000; +arr2[1] = 6000; + +assert.deepStrictEqual(arr_buf, ar_buf); + +// Checks for calling Buffer.byteLength on a SharedArrayBuffer. +assert.strictEqual(Buffer.byteLength(sab), sab.byteLength); + +Buffer.from({ buffer: sab }); // Should not throw. diff --git a/tests/node_compat/test/parallel/test-buffer-write.js b/tests/node_compat/test/parallel/test-buffer-write.js new file mode 100644 index 0000000000..672d5d0bc2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-buffer-write.js @@ -0,0 +1,115 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +[-1, 10].forEach((offset) => { + assert.throws( + () => Buffer.alloc(9).write('foo', offset), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0 && <= 9. Received ${offset}` + } + ); +}); + +const resultMap = new Map([ + ['utf8', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], + ['ucs2', Buffer.from([102, 0, 111, 0, 111, 0, 0, 0, 0])], + ['ascii', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], + ['latin1', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], + ['binary', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], + ['utf16le', Buffer.from([102, 0, 111, 0, 111, 0, 0, 0, 0])], + ['base64', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], + ['base64url', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], + ['hex', Buffer.from([102, 111, 111, 0, 0, 0, 0, 0, 0])], +]); + +// utf8, ucs2, ascii, latin1, utf16le +const encodings = ['utf8', 'utf-8', 'ucs2', 'ucs-2', 'ascii', 'latin1', + 'binary', 'utf16le', 'utf-16le']; + +encodings + .reduce((es, e) => es.concat(e, e.toUpperCase()), []) + .forEach((encoding) => { + const buf = Buffer.alloc(9); + const len = Buffer.byteLength('foo', encoding); + assert.strictEqual(buf.write('foo', 0, len, encoding), len); + + if (encoding.includes('-')) + encoding = encoding.replace('-', ''); + + assert.deepStrictEqual(buf, resultMap.get(encoding.toLowerCase())); + }); + +// base64 +['base64', 'BASE64', 'base64url', 'BASE64URL'].forEach((encoding) => { + const buf = Buffer.alloc(9); + const len = Buffer.byteLength('Zm9v', encoding); + + assert.strictEqual(buf.write('Zm9v', 0, len, encoding), len); + assert.deepStrictEqual(buf, resultMap.get(encoding.toLowerCase())); +}); + +// hex +['hex', 'HEX'].forEach((encoding) => { + const buf = Buffer.alloc(9); + const len = Buffer.byteLength('666f6f', encoding); + + assert.strictEqual(buf.write('666f6f', 0, len, encoding), len); + assert.deepStrictEqual(buf, resultMap.get(encoding.toLowerCase())); +}); + +// Invalid encodings +for (let i = 1; i < 10; i++) { + const encoding = String(i).repeat(i); + const error = common.expectsError({ + code: 'ERR_UNKNOWN_ENCODING', + name: 'TypeError', + message: `Unknown encoding: ${encoding}` + }); + + assert.ok(!Buffer.isEncoding(encoding)); + assert.throws(() => Buffer.alloc(9).write('foo', encoding), error); +} + +// UCS-2 overflow CVE-2018-12115 +for (let i = 1; i < 4; i++) { + // Allocate two Buffers sequentially off the pool. Run more than once in case + // we hit the end of the pool and don't get sequential allocations + const x = Buffer.allocUnsafe(4).fill(0); + const y = Buffer.allocUnsafe(4).fill(1); + // Should not write anything, pos 3 doesn't have enough room for a 16-bit char + assert.strictEqual(x.write('ыыыыыы', 3, 'ucs2'), 0); + // CVE-2018-12115 experienced via buffer overrun to next block in the pool + assert.strictEqual(Buffer.compare(y, Buffer.alloc(4, 1)), 0); +} + +// Should not write any data when there is no space for 16-bit chars +const z = Buffer.alloc(4, 0); +assert.strictEqual(z.write('\u0001', 3, 'ucs2'), 0); +assert.strictEqual(Buffer.compare(z, Buffer.alloc(4, 0)), 0); +// Make sure longer strings are written up to the buffer end. +assert.strictEqual(z.write('abcd', 2), 2); +assert.deepStrictEqual([...z], [0, 0, 0x61, 0x62]); + +// Large overrun could corrupt the process +assert.strictEqual(Buffer.alloc(4) + .write('ыыыыыы'.repeat(100), 3, 'utf16le'), 0); + +{ + // .write() does not affect the byte after the written-to slice of the Buffer. + // Refs: https://github.com/nodejs/node/issues/26422 + const buf = Buffer.alloc(8); + assert.strictEqual(buf.write('ыы', 1, 'utf16le'), 4); + assert.deepStrictEqual([...buf], [0, 0x4b, 0x04, 0x4b, 0x04, 0, 0, 0]); +} diff --git a/tests/node_compat/test/parallel/test-child-process-fork3.js b/tests/node_compat/test/parallel/test-child-process-fork3.js new file mode 100644 index 0000000000..cda9098a3b --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-fork3.js @@ -0,0 +1,34 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const child_process = require('child_process'); +const fixtures = require('../common/fixtures'); + +child_process.fork(fixtures.path('empty.js')); // should not hang diff --git a/tests/node_compat/test/parallel/test-child-process-send-type-error.js b/tests/node_compat/test/parallel/test-child-process-send-type-error.js new file mode 100644 index 0000000000..0ee7a8c9c3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-send-type-error.js @@ -0,0 +1,36 @@ +// 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. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const cp = require('child_process'); + +function fail(proc, args) { + assert.throws(() => { + proc.send.apply(proc, args); + }, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); +} + +let target = process; + +if (process.argv[2] !== 'child') { + target = cp.fork(__filename, ['child']); + target.on('exit', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + })); +} + +fail(target, ['msg', null, null]); +fail(target, ['msg', null, '']); +fail(target, ['msg', null, 'foo']); +fail(target, ['msg', null, 0]); +fail(target, ['msg', null, NaN]); +fail(target, ['msg', null, 1]); +fail(target, ['msg', null, null, common.mustNotCall()]); diff --git a/tests/node_compat/test/parallel/test-child-process-stdin-ipc.js b/tests/node_compat/test/parallel/test-child-process-stdin-ipc.js new file mode 100644 index 0000000000..46bfdc7be6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-stdin-ipc.js @@ -0,0 +1,47 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const spawn = require('child_process').spawn; + +if (process.argv[2] === 'child') { + // Just reference stdin, it should start it + process.stdin; // eslint-disable-line no-unused-expressions + return; +} + +const proc = spawn(process.execPath, [__filename, 'child'], { + stdio: ['ipc', 'inherit', 'inherit'] +}); + +proc.on('exit', common.mustCall(function(code) { + assert.strictEqual(code, 0); +})); diff --git a/tests/node_compat/test/parallel/test-child-process-stdio-overlapped.js b/tests/node_compat/test/parallel/test-child-process-stdio-overlapped.js new file mode 100644 index 0000000000..9ee17df49f --- /dev/null +++ b/tests/node_compat/test/parallel/test-child-process-stdio-overlapped.js @@ -0,0 +1,86 @@ +// 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. + +// Test for "overlapped" stdio option. This test uses the "overlapped-checker" +// helper program which basically a specialized echo program. +// +// The test has two goals: +// +// - Verify that overlapped I/O works on windows. The test program will deadlock +// if stdin doesn't have the FILE_FLAG_OVERLAPPED flag set on startup (see +// test/overlapped-checker/main_win.c for more details). +// - Verify that "overlapped" stdio option works transparently as a pipe (on +// unix/windows) +// +// This is how the test works: +// +// - This script assumes only numeric strings are written to the test program +// stdout. +// - The test program will be spawned with "overlapped" set on stdin and "pipe" +// set on stdout/stderr and at startup writes a number to its stdout +// - When this script receives some data, it will parse the number, add 50 and +// write to the test program's stdin. +// - The test program will then echo the number back to us which will repeat the +// cycle until the number reaches 200, at which point we send the "exit" +// string, which causes the test program to exit. +// - Extra assertion: Every time the test program writes a string to its stdout, +// it will write the number of bytes written to stderr. +// - If overlapped I/O is not setup correctly, this test is going to hang. +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const child_process = require('child_process'); + +const exeExtension = process.platform === 'win32' ? '.exe' : ''; +const exe = 'overlapped-checker' + exeExtension; +const exePath = path.join(path.dirname(process.execPath), exe); + +if (!require('fs').existsSync(exePath)) { + common.skip(exe + ' binary is not available'); +} + +const child = child_process.spawn(exePath, [], { + stdio: ['overlapped', 'pipe', 'pipe'] +}); + +child.stdin.setEncoding('utf8'); +child.stdout.setEncoding('utf8'); +child.stderr.setEncoding('utf8'); + +function writeNext(n) { + child.stdin.write((n + 50).toString()); +} + +child.stdout.on('data', (s) => { + const n = Number(s); + if (n >= 200) { + child.stdin.write('exit'); + return; + } + writeNext(n); +}); + +let stderr = ''; +child.stderr.on('data', (s) => { + stderr += s; +}); + +child.stderr.on('end', common.mustCall(() => { + // This is the sequence of numbers sent to us: + // - 0 (1 byte written) + // - 50 (2 bytes written) + // - 100 (3 bytes written) + // - 150 (3 bytes written) + // - 200 (3 bytes written) + assert.strictEqual(stderr, '12333'); +})); + +child.on('exit', common.mustCall((status) => { + // The test program will return the number of writes as status code. + assert.strictEqual(status, 0); +})); diff --git a/tests/node_compat/test/parallel/test-client-request-destroy.js b/tests/node_compat/test/parallel/test-client-request-destroy.js new file mode 100644 index 0000000000..dabdb8c4d3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-client-request-destroy.js @@ -0,0 +1,20 @@ +// 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. + +'use strict'; + +// Test that http.ClientRequest,prototype.destroy() returns `this`. +require('../common'); + +const assert = require('assert'); +const http = require('http'); +const clientRequest = new http.ClientRequest({ createConnection: () => {} }); + +assert.strictEqual(clientRequest.destroyed, false); +assert.strictEqual(clientRequest.destroy(), clientRequest); +assert.strictEqual(clientRequest.destroyed, true); +assert.strictEqual(clientRequest.destroy(), clientRequest); diff --git a/tests/node_compat/test/parallel/test-cluster-uncaught-exception.js b/tests/node_compat/test/parallel/test-cluster-uncaught-exception.js new file mode 100644 index 0000000000..96a5d26186 --- /dev/null +++ b/tests/node_compat/test/parallel/test-cluster-uncaught-exception.js @@ -0,0 +1,56 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// Installing a custom uncaughtException handler should override the default +// one that the cluster module installs. +// https://github.com/joyent/node/issues/2556 + +const common = require('../common'); +const assert = require('assert'); +const cluster = require('cluster'); +const fork = require('child_process').fork; + +const MAGIC_EXIT_CODE = 42; + +const isTestRunner = process.argv[2] !== 'child'; + +if (isTestRunner) { + const primary = fork(__filename, ['child']); + primary.on('exit', common.mustCall((code) => { + assert.strictEqual(code, MAGIC_EXIT_CODE); + })); +} else if (cluster.isPrimary) { + process.on('uncaughtException', common.mustCall(() => { + process.nextTick(() => process.exit(MAGIC_EXIT_CODE)); + })); + cluster.fork(); + throw new Error('kill primary'); +} else { // worker + process.exit(); +} diff --git a/tests/node_compat/test/parallel/test-console-assign-undefined.js b/tests/node_compat/test/parallel/test-console-assign-undefined.js new file mode 100644 index 0000000000..f19fb5c1f7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-console-assign-undefined.js @@ -0,0 +1,35 @@ +// 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. + +'use strict'; + +// Patch global.console before importing modules that may modify the console +// object. + +const tmp = global.console; +global.console = 42; + +require('../common'); +const assert = require('assert'); + +// Originally the console had a getter. Test twice to verify it had no side +// effect. +assert.strictEqual(global.console, 42); +assert.strictEqual(global.console, 42); + +assert.throws( + () => console.log('foo'), + { name: 'TypeError' } +); + +global.console = 1; +assert.strictEqual(global.console, 1); +assert.strictEqual(console, 1); + +// Reset the console +global.console = tmp; +console.log('foo'); diff --git a/tests/node_compat/test/parallel/test-console-formatTime.js b/tests/node_compat/test/parallel/test-console-formatTime.js new file mode 100644 index 0000000000..3ab6e9ca8a --- /dev/null +++ b/tests/node_compat/test/parallel/test-console-formatTime.js @@ -0,0 +1,21 @@ +// 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. + +'use strict'; +// Flags: --expose-internals +require('../common'); +const { formatTime } = require('internal/console/constructor'); +const assert = require('assert'); + +assert.strictEqual(formatTime(100.0096), '100.01ms'); +assert.strictEqual(formatTime(100.0115), '100.011ms'); +assert.strictEqual(formatTime(1500.04), '1.500s'); +assert.strictEqual(formatTime(1000.056), '1.000s'); +assert.strictEqual(formatTime(60300.3), '1:00.300 (m:ss.mmm)'); +assert.strictEqual(formatTime(4000457.4), '1:06:40.457 (h:mm:ss.mmm)'); +assert.strictEqual(formatTime(3601310.4), '1:00:01.310 (h:mm:ss.mmm)'); +assert.strictEqual(formatTime(3213601017.6), '892:40:01.018 (h:mm:ss.mmm)'); diff --git a/tests/node_compat/test/parallel/test-console-not-call-toString.js b/tests/node_compat/test/parallel/test-console-not-call-toString.js new file mode 100644 index 0000000000..fd7416dc2d --- /dev/null +++ b/tests/node_compat/test/parallel/test-console-not-call-toString.js @@ -0,0 +1,41 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +function func() {} +let toStringCalled = false; +func.toString = function() { + toStringCalled = true; +}; + +require('util').inspect(func); + +assert.ok(!toStringCalled); diff --git a/tests/node_compat/test/parallel/test-console-self-assign.js b/tests/node_compat/test/parallel/test-console-self-assign.js new file mode 100644 index 0000000000..780bbfa81c --- /dev/null +++ b/tests/node_compat/test/parallel/test-console-self-assign.js @@ -0,0 +1,13 @@ +// 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. + +'use strict'; + +require('../common'); + +// Assigning to itself should not throw. +global.console = global.console; // eslint-disable-line no-self-assign diff --git a/tests/node_compat/test/parallel/test-crypto-dh-errors.js b/tests/node_compat/test/parallel/test-crypto-dh-errors.js new file mode 100644 index 0000000000..73224a715c --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-dh-errors.js @@ -0,0 +1,118 @@ +// 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. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); + +// https://github.com/nodejs/node/issues/32738 +// XXX(bnoordhuis) validateInt32() throwing ERR_OUT_OF_RANGE and RangeError +// instead of ERR_INVALID_ARG_TYPE and TypeError is questionable, IMO. +assert.throws(() => crypto.createDiffieHellman(13.37), { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "sizeOrKey" is out of range. ' + + 'It must be an integer. Received 13.37', +}); + +assert.throws(() => crypto.createDiffieHellman('abcdef', 13.37), { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "generator" is out of range. ' + + 'It must be an integer. Received 13.37', +}); + +for (const bits of [-1, 0, 1]) { + if (common.hasOpenSSL3) { + assert.throws(() => crypto.createDiffieHellman(bits), { + code: 'ERR_OSSL_DH_MODULUS_TOO_SMALL', + name: 'Error', + message: /modulus too small/, + }); + } else { + assert.throws(() => crypto.createDiffieHellman(bits), { + code: 'ERR_OSSL_BN_BITS_TOO_SMALL', + name: 'Error', + message: /bits too small/, + }); + } +} + +for (const g of [-1, 1]) { + const ex = { + code: 'ERR_OSSL_DH_BAD_GENERATOR', + name: 'Error', + message: /bad generator/, + }; + assert.throws(() => crypto.createDiffieHellman('abcdef', g), ex); + assert.throws(() => crypto.createDiffieHellman('abcdef', 'hex', g), ex); +} + +for (const g of [Buffer.from([]), + Buffer.from([0]), + Buffer.from([1])]) { + const ex = { + code: 'ERR_OSSL_DH_BAD_GENERATOR', + name: 'Error', + message: /bad generator/, + }; + assert.throws(() => crypto.createDiffieHellman('abcdef', g), ex); + assert.throws(() => crypto.createDiffieHellman('abcdef', 'hex', g), ex); +} + +[ + [0x1, 0x2], + () => { }, + /abc/, + {}, +].forEach((input) => { + assert.throws( + () => crypto.createDiffieHellman(input), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + } + ); +}); + +// Invalid test: curve argument is undefined +assert.throws( + () => crypto.createECDH(), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "curve" argument must be of type string. ' + + 'Received undefined' + }); + +assert.throws( + function() { + crypto.getDiffieHellman('unknown-group'); + }, + { + name: 'Error', + code: 'ERR_CRYPTO_UNKNOWN_DH_GROUP', + message: 'Unknown DH group' + }, + 'crypto.getDiffieHellman(\'unknown-group\') ' + + 'failed to throw the expected error.' +); + +assert.throws( + () => crypto.createDiffieHellman('', true), + { + code: 'ERR_INVALID_ARG_TYPE' + } +); +[true, Symbol(), {}, () => {}, []].forEach((generator) => assert.throws( + () => crypto.createDiffieHellman('', 'base64', generator), + { code: 'ERR_INVALID_ARG_TYPE' } +)); diff --git a/tests/node_compat/test/parallel/test-crypto-dh-odd-key.js b/tests/node_compat/test/parallel/test-crypto-dh-odd-key.js new file mode 100644 index 0000000000..ba5e64f945 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-dh-odd-key.js @@ -0,0 +1,50 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); + +function test() { + const odd = Buffer.alloc(39, 'A'); + + const c = crypto.createDiffieHellman(common.hasOpenSSL3 ? 1024 : 32); + c.setPrivateKey(odd); + c.generateKeys(); +} + +// FIPS requires a length of at least 1024 +if (!common.hasFipsCrypto) { + test(); +} else { + assert.throws(function() { test(); }, /key size too small/); +} diff --git a/tests/node_compat/test/parallel/test-crypto-domain.js b/tests/node_compat/test/parallel/test-crypto-domain.js new file mode 100644 index 0000000000..e0a7c7f11e --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-domain.js @@ -0,0 +1,56 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); +const domain = require('domain'); + +const test = (fn) => { + const ex = new Error('BAM'); + const d = domain.create(); + d.on('error', common.mustCall(function(err) { + assert.strictEqual(err, ex); + })); + const cb = common.mustCall(function() { + throw ex; + }); + d.run(cb); +}; + +test(function(cb) { + crypto.pbkdf2('password', 'salt', 1, 8, cb); +}); + +test(function(cb) { + crypto.randomBytes(32, cb); +}); diff --git a/tests/node_compat/test/parallel/test-crypto-from-binary.js b/tests/node_compat/test/parallel/test-crypto-from-binary.js new file mode 100644 index 0000000000..f1eee30a96 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-from-binary.js @@ -0,0 +1,72 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// This is the same as test/simple/test-crypto, but from before the shift +// to use buffers by default. + + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); + +const EXTERN_APEX = 0xFBEE9; + +// Manually controlled string for checking binary output +let ucs2_control = 'a\u0000'; + +// Grow the strings to proper length +while (ucs2_control.length <= EXTERN_APEX) { + ucs2_control = ucs2_control.repeat(2); +} + + +// Check resultant buffer and output string +const b = Buffer.from(ucs2_control + ucs2_control, 'ucs2'); + +// +// Test updating from birant data +// +{ + const datum1 = b.slice(700000); + const hash1_converted = crypto.createHash('sha1') + .update(datum1.toString('base64'), 'base64') + .digest('hex'); + const hash1_direct = crypto.createHash('sha1').update(datum1).digest('hex'); + assert.strictEqual(hash1_direct, hash1_converted); + + const datum2 = b; + const hash2_converted = crypto.createHash('sha1') + .update(datum2.toString('base64'), 'base64') + .digest('hex'); + const hash2_direct = crypto.createHash('sha1').update(datum2).digest('hex'); + assert.strictEqual(hash2_direct, hash2_converted); +} diff --git a/tests/node_compat/test/parallel/test-crypto-keygen-dh-classic.js b/tests/node_compat/test/parallel/test-crypto-keygen-dh-classic.js new file mode 100644 index 0000000000..172a91470d --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-keygen-dh-classic.js @@ -0,0 +1,30 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const { + generateKeyPair, +} = require('crypto'); + +// Test classic Diffie-Hellman key generation. +{ + generateKeyPair('dh', { + primeLength: 512 + }, common.mustSucceed((publicKey, privateKey) => { + assert.strictEqual(publicKey.type, 'public'); + assert.strictEqual(publicKey.asymmetricKeyType, 'dh'); + + assert.strictEqual(privateKey.type, 'private'); + assert.strictEqual(privateKey.asymmetricKeyType, 'dh'); + })); +} diff --git a/tests/node_compat/test/parallel/test-crypto-keygen-duplicate-deprecated-option.js b/tests/node_compat/test/parallel/test-crypto-keygen-duplicate-deprecated-option.js new file mode 100644 index 0000000000..300c8d893d --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-keygen-duplicate-deprecated-option.js @@ -0,0 +1,50 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const { + generateKeyPair, +} = require('crypto'); + +// This test makes sure deprecated and new options may be used +// simultaneously so long as they're identical values. +{ + generateKeyPair('rsa-pss', { + modulusLength: 512, + saltLength: 16, + hash: 'sha256', + hashAlgorithm: 'sha256', + mgf1Hash: 'sha256', + mgf1HashAlgorithm: 'sha256' + }, common.mustSucceed((publicKey, privateKey) => { + assert.strictEqual(publicKey.type, 'public'); + assert.strictEqual(publicKey.asymmetricKeyType, 'rsa-pss'); + assert.deepStrictEqual(publicKey.asymmetricKeyDetails, { + modulusLength: 512, + publicExponent: 65537n, + hashAlgorithm: 'sha256', + mgf1HashAlgorithm: 'sha256', + saltLength: 16 + }); + + assert.strictEqual(privateKey.type, 'private'); + assert.strictEqual(privateKey.asymmetricKeyType, 'rsa-pss'); + assert.deepStrictEqual(privateKey.asymmetricKeyDetails, { + modulusLength: 512, + publicExponent: 65537n, + hashAlgorithm: 'sha256', + mgf1HashAlgorithm: 'sha256', + saltLength: 16 + }); + })); +} diff --git a/tests/node_compat/test/parallel/test-crypto-keygen-empty-passphrase-no-error.js b/tests/node_compat/test/parallel/test-crypto-keygen-empty-passphrase-no-error.js new file mode 100644 index 0000000000..ad6f10931c --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-keygen-empty-passphrase-no-error.js @@ -0,0 +1,36 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const { + generateKeyPair, +} = require('crypto'); + +// Passing an empty passphrase string should not throw ERR_OSSL_CRYPTO_MALLOC_FAILURE even on OpenSSL 3. +// Regression test for https://github.com/nodejs/node/issues/41428. +generateKeyPair('rsa', { + modulusLength: 1024, + publicKeyEncoding: { + type: 'spki', + format: 'pem' + }, + privateKeyEncoding: { + type: 'pkcs8', + format: 'pem', + cipher: 'aes-256-cbc', + passphrase: '' + } +}, common.mustSucceed((publicKey, privateKey) => { + assert.strictEqual(typeof publicKey, 'string'); + assert.strictEqual(typeof privateKey, 'string'); +})); diff --git a/tests/node_compat/test/parallel/test-crypto-keygen-key-objects.js b/tests/node_compat/test/parallel/test-crypto-keygen-key-objects.js new file mode 100644 index 0000000000..e0dba54297 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-keygen-key-objects.js @@ -0,0 +1,40 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const { + generateKeyPairSync, +} = require('crypto'); + +// Test sync key generation with key objects. +{ + const { publicKey, privateKey } = generateKeyPairSync('rsa', { + modulusLength: 512 + }); + + assert.strictEqual(typeof publicKey, 'object'); + assert.strictEqual(publicKey.type, 'public'); + assert.strictEqual(publicKey.asymmetricKeyType, 'rsa'); + assert.deepStrictEqual(publicKey.asymmetricKeyDetails, { + modulusLength: 512, + publicExponent: 65537n + }); + + assert.strictEqual(typeof privateKey, 'object'); + assert.strictEqual(privateKey.type, 'private'); + assert.strictEqual(privateKey.asymmetricKeyType, 'rsa'); + assert.deepStrictEqual(privateKey.asymmetricKeyDetails, { + modulusLength: 512, + publicExponent: 65537n + }); +} diff --git a/tests/node_compat/test/parallel/test-crypto-keygen-missing-oid.js b/tests/node_compat/test/parallel/test-crypto-keygen-missing-oid.js new file mode 100644 index 0000000000..0d7e0cb693 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-keygen-missing-oid.js @@ -0,0 +1,50 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const { + generateKeyPair, + generateKeyPairSync, + getCurves, +} = require('crypto'); + +// This test creates EC key pairs on curves without associated OIDs. +// Specifying a key encoding should not crash. +{ + if (process.versions.openssl >= '1.1.1i') { + for (const namedCurve of ['Oakley-EC2N-3', 'Oakley-EC2N-4']) { + if (!getCurves().includes(namedCurve)) + continue; + + const expectedErrorCode = + common.hasOpenSSL3 ? 'ERR_OSSL_MISSING_OID' : 'ERR_OSSL_EC_MISSING_OID'; + const params = { + namedCurve, + publicKeyEncoding: { + format: 'der', + type: 'spki' + } + }; + + assert.throws(() => { + generateKeyPairSync('ec', params); + }, { + code: expectedErrorCode + }); + + generateKeyPair('ec', params, common.mustCall((err) => { + assert.strictEqual(err.code, expectedErrorCode); + })); + } + } +} diff --git a/tests/node_compat/test/parallel/test-crypto-keygen-non-standard-public-exponent.js b/tests/node_compat/test/parallel/test-crypto-keygen-non-standard-public-exponent.js new file mode 100644 index 0000000000..b769bb2437 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-keygen-non-standard-public-exponent.js @@ -0,0 +1,42 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const { + generateKeyPairSync, +} = require('crypto'); + +// Test sync key generation with key objects with a non-standard +// publicExponent +{ + const { publicKey, privateKey } = generateKeyPairSync('rsa', { + publicExponent: 3, + modulusLength: 512 + }); + + assert.strictEqual(typeof publicKey, 'object'); + assert.strictEqual(publicKey.type, 'public'); + assert.strictEqual(publicKey.asymmetricKeyType, 'rsa'); + assert.deepStrictEqual(publicKey.asymmetricKeyDetails, { + modulusLength: 512, + publicExponent: 3n + }); + + assert.strictEqual(typeof privateKey, 'object'); + assert.strictEqual(privateKey.type, 'private'); + assert.strictEqual(privateKey.asymmetricKeyType, 'rsa'); + assert.deepStrictEqual(privateKey.asymmetricKeyDetails, { + modulusLength: 512, + publicExponent: 3n + }); +} diff --git a/tests/node_compat/test/parallel/test-crypto-keygen-rfc8017-9-1.js b/tests/node_compat/test/parallel/test-crypto-keygen-rfc8017-9-1.js new file mode 100644 index 0000000000..2019f03f6a --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-keygen-rfc8017-9-1.js @@ -0,0 +1,39 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const { + generateKeyPair, +} = require('crypto'); + +// RFC 8017, 9.1.: "Assuming that the mask generation function is based on a +// hash function, it is RECOMMENDED that the hash function be the same as the +// one that is applied to the message." +{ + + generateKeyPair('rsa-pss', { + modulusLength: 512, + hashAlgorithm: 'sha256', + saltLength: 16 + }, common.mustSucceed((publicKey, privateKey) => { + const expectedKeyDetails = { + modulusLength: 512, + publicExponent: 65537n, + hashAlgorithm: 'sha256', + mgf1HashAlgorithm: 'sha256', + saltLength: 16 + }; + assert.deepStrictEqual(publicKey.asymmetricKeyDetails, expectedKeyDetails); + assert.deepStrictEqual(privateKey.asymmetricKeyDetails, expectedKeyDetails); + })); +} diff --git a/tests/node_compat/test/parallel/test-crypto-keygen-rfc8017-a-2-3.js b/tests/node_compat/test/parallel/test-crypto-keygen-rfc8017-a-2-3.js new file mode 100644 index 0000000000..fe732269a3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-keygen-rfc8017-a-2-3.js @@ -0,0 +1,53 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const { + generateKeyPair, +} = require('crypto'); + +// RFC 8017, A.2.3.: "For a given hashAlgorithm, the default value of +// saltLength is the octet length of the hash value." +{ + generateKeyPair('rsa-pss', { + modulusLength: 512, + hashAlgorithm: 'sha512' + }, common.mustSucceed((publicKey, privateKey) => { + const expectedKeyDetails = { + modulusLength: 512, + publicExponent: 65537n, + hashAlgorithm: 'sha512', + mgf1HashAlgorithm: 'sha512', + saltLength: 64 + }; + assert.deepStrictEqual(publicKey.asymmetricKeyDetails, expectedKeyDetails); + assert.deepStrictEqual(privateKey.asymmetricKeyDetails, expectedKeyDetails); + })); + + // It is still possible to explicitly set saltLength to 0. + generateKeyPair('rsa-pss', { + modulusLength: 512, + hashAlgorithm: 'sha512', + saltLength: 0 + }, common.mustSucceed((publicKey, privateKey) => { + const expectedKeyDetails = { + modulusLength: 512, + publicExponent: 65537n, + hashAlgorithm: 'sha512', + mgf1HashAlgorithm: 'sha512', + saltLength: 0 + }; + assert.deepStrictEqual(publicKey.asymmetricKeyDetails, expectedKeyDetails); + assert.deepStrictEqual(privateKey.asymmetricKeyDetails, expectedKeyDetails); + })); +} diff --git a/tests/node_compat/test/parallel/test-crypto-lazy-transform-writable.js b/tests/node_compat/test/parallel/test-crypto-lazy-transform-writable.js new file mode 100644 index 0000000000..af0cf7d688 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-lazy-transform-writable.js @@ -0,0 +1,43 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); +const Stream = require('stream'); + +const hasher1 = crypto.createHash('sha256'); +const hasher2 = crypto.createHash('sha256'); + +// Calculate the expected result. +hasher1.write(Buffer.from('hello world')); +hasher1.end(); + +const expected = hasher1.read().toString('hex'); + +class OldStream extends Stream { + constructor() { + super(); + this.readable = true; + } +} + +const stream = new OldStream(); + +stream.pipe(hasher2).on('finish', common.mustCall(function() { + const hash = hasher2.read().toString('hex'); + assert.strictEqual(hash, expected); +})); + +stream.emit('data', Buffer.from('hello')); +stream.emit('data', Buffer.from(' world')); +stream.emit('end'); diff --git a/tests/node_compat/test/parallel/test-crypto-no-algorithm.js b/tests/node_compat/test/parallel/test-crypto-no-algorithm.js new file mode 100644 index 0000000000..32265ae8e5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-no-algorithm.js @@ -0,0 +1,45 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.hasOpenSSL3) + common.skip('this test requires OpenSSL 3.x'); + +const assert = require('node:assert/strict'); +const crypto = require('node:crypto'); + +if (common.isMainThread) { + // TODO(richardlau): Decide if `crypto.setFips` should error if the + // provider named "fips" is not available. + crypto.setFips(1); + crypto.randomBytes(20, common.mustCall((err) => { + // crypto.randomBytes should either succeed or fail but not hang. + if (err) { + assert.match(err.message, /digital envelope routines::unsupported/); + const expected = /random number generator::unable to fetch drbg/; + assert(err.opensslErrorStack.some((msg) => expected.test(msg)), + `did not find ${expected} in ${err.opensslErrorStack}`); + } + })); +} + +{ + // Startup test. Should not hang. + const { path } = require('../common/fixtures'); + const { spawnSync } = require('node:child_process'); + const baseConf = path('openssl3-conf', 'base_only.cnf'); + const cp = spawnSync(process.execPath, + [ `--openssl-config=${baseConf}`, '-p', '"hello"' ], + { encoding: 'utf8' }); + assert(common.nodeProcessAborted(cp.status, cp.signal), + `process did not abort, code:${cp.status} signal:${cp.signal}`); +} diff --git a/tests/node_compat/test/parallel/test-crypto-op-during-process-exit.js b/tests/node_compat/test/parallel/test-crypto-op-during-process-exit.js new file mode 100644 index 0000000000..2c75cbfcb7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-op-during-process-exit.js @@ -0,0 +1,35 @@ +// 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. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) { common.skip('missing crypto'); } +const assert = require('assert'); +const { generateKeyPair } = require('crypto'); + +if (common.isWindows) { + // Remove this conditional once the libuv change is in Node.js. + common.skip('crashing due to https://github.com/libuv/libuv/pull/2983'); +} + +// Regression test for a race condition: process.exit() might lead to OpenSSL +// cleaning up state from the exit() call via calling its destructor, but +// running OpenSSL operations on another thread might lead to them attempting +// to initialize OpenSSL, leading to a crash. +// This test crashed consistently on x64 Linux on Node v14.9.0. + +generateKeyPair('rsa', { + modulusLength: 2048, + privateKeyEncoding: { + type: 'pkcs1', + format: 'pem' + } +}, (err/* , publicKey, privateKey */) => { + assert.ifError(err); +}); + +setTimeout(() => process.exit(), common.platformTimeout(10)); diff --git a/tests/node_compat/test/parallel/test-crypto-padding-aes256.js b/tests/node_compat/test/parallel/test-crypto-padding-aes256.js new file mode 100644 index 0000000000..812755a95c --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-padding-aes256.js @@ -0,0 +1,67 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); + +const iv = Buffer.from('00000000000000000000000000000000', 'hex'); +const key = Buffer.from('0123456789abcdef0123456789abcdef' + + '0123456789abcdef0123456789abcdef', 'hex'); + +function encrypt(val, pad) { + const c = crypto.createCipheriv('aes256', key, iv); + c.setAutoPadding(pad); + return c.update(val, 'utf8', 'latin1') + c.final('latin1'); +} + +function decrypt(val, pad) { + const c = crypto.createDecipheriv('aes256', key, iv); + c.setAutoPadding(pad); + return c.update(val, 'latin1', 'utf8') + c.final('utf8'); +} + +// echo 0123456789abcdef0123456789abcdef \ +// | openssl enc -e -aes256 -nopad -K -iv \ +// | openssl enc -d -aes256 -nopad -K -iv +let plaintext = '0123456789abcdef0123456789abcdef'; // Multiple of block size +let encrypted = encrypt(plaintext, false); +let decrypted = decrypt(encrypted, false); +assert.strictEqual(decrypted, plaintext); + +// echo 0123456789abcdef0123456789abcde \ +// | openssl enc -e -aes256 -K -iv \ +// | openssl enc -d -aes256 -K -iv +plaintext = '0123456789abcdef0123456789abcde'; // not a multiple +encrypted = encrypt(plaintext, true); +decrypted = decrypt(encrypted, true); +assert.strictEqual(decrypted, plaintext); diff --git a/tests/node_compat/test/parallel/test-crypto-psychic-signatures.js b/tests/node_compat/test/parallel/test-crypto-psychic-signatures.js new file mode 100644 index 0000000000..f24d2d8b36 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-psychic-signatures.js @@ -0,0 +1,107 @@ +// 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. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); + +const crypto = require('crypto'); + +// Tests for CVE-2022-21449 +// https://neilmadden.blog/2022/04/19/psychic-signatures-in-java/ +// Dubbed "Psychic Signatures", these signatures bypassed the ECDSA signature +// verification implementation in Java in 15, 16, 17, and 18. OpenSSL is not +// (and was not) vulnerable so these are a precaution. + +const vectors = { + 'ieee-p1363': [ + Buffer.from('0000000000000000000000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000', 'hex'), + Buffer.from('ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551' + + 'ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551', 'hex'), + ], + 'der': [ + Buffer.from('3046022100' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '022100' + + '0000000000000000000000000000000000000000000000000000000000000000', 'hex'), + Buffer.from('3046022100' + + 'ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551' + + '022100' + + 'ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551', 'hex'), + ], +}; + +const keyPair = crypto.generateKeyPairSync('ec', { + namedCurve: 'P-256', + publicKeyEncoding: { + format: 'der', + type: 'spki' + }, +}); + +const data = Buffer.from('Hello!'); + +for (const [encoding, signatures] of Object.entries(vectors)) { + for (const signature of signatures) { + const key = { + key: keyPair.publicKey, + format: 'der', + type: 'spki', + dsaEncoding: encoding, + }; + + // one-shot sync + assert.strictEqual( + crypto.verify( + 'sha256', + data, + key, + signature, + ), + false, + ); + + // one-shot async + crypto.verify( + 'sha256', + data, + key, + signature, + common.mustSucceed((verified) => assert.strictEqual(verified, false)), + ); + + // stream + assert.strictEqual( + crypto.createVerify('sha256') + .update(data) + .verify(key, signature), + false, + ); + + // webcrypto + globalThis.crypto.subtle.importKey( + 'spki', + keyPair.publicKey, + { name: 'ECDSA', namedCurve: 'P-256' }, + false, + ['verify'], + ).then((publicKey) => { + return globalThis.crypto.subtle.verify( + { name: 'ECDSA', hash: 'SHA-256' }, + publicKey, + signature, + data, + ); + }).then(common.mustCall((verified) => { + assert.strictEqual(verified, false); + })); + } +} diff --git a/tests/node_compat/test/parallel/test-crypto-publicDecrypt-fails-first-time.js b/tests/node_compat/test/parallel/test-crypto-publicDecrypt-fails-first-time.js new file mode 100644 index 0000000000..3248788592 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-publicDecrypt-fails-first-time.js @@ -0,0 +1,48 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// Test for https://github.com/nodejs/node/issues/40814 + +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.hasOpenSSL3) + common.skip('only openssl3'); // https://github.com/nodejs/node/pull/42793#issuecomment-1107491901 + +const assert = require('assert'); +const crypto = require('crypto'); + +const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', { + modulusLength: 2048, + publicKeyEncoding: { + type: 'spki', + format: 'pem' + }, + privateKeyEncoding: { + type: 'pkcs8', + format: 'pem', + cipher: 'aes-128-ecb', + passphrase: 'abcdef' + } +}); +assert.notStrictEqual(privateKey.toString(), ''); + +const msg = 'The quick brown fox jumps over the lazy dog'; + +const encryptedString = crypto.privateEncrypt({ + key: privateKey, + passphrase: 'abcdef' +}, Buffer.from(msg)).toString('base64'); +const decryptedString = crypto.publicDecrypt(publicKey, Buffer.from(encryptedString, 'base64')).toString(); +console.log(`Encrypted: ${encryptedString}`); +console.log(`Decrypted: ${decryptedString}`); + +assert.notStrictEqual(encryptedString, ''); +assert.strictEqual(decryptedString, msg); diff --git a/tests/node_compat/test/parallel/test-crypto-randomfillsync-regression.js b/tests/node_compat/test/parallel/test-crypto-randomfillsync-regression.js new file mode 100644 index 0000000000..e81ec39272 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-randomfillsync-regression.js @@ -0,0 +1,25 @@ +// 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. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const { randomFillSync } = require('crypto'); +const { notStrictEqual } = require('assert'); + +const ab = new ArrayBuffer(20); +const buf = Buffer.from(ab, 10); + +const before = buf.toString('hex'); + +randomFillSync(buf); + +const after = buf.toString('hex'); + +notStrictEqual(before, after); diff --git a/tests/node_compat/test/parallel/test-crypto-scrypt.js b/tests/node_compat/test/parallel/test-crypto-scrypt.js new file mode 100644 index 0000000000..427e22537c --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-scrypt.js @@ -0,0 +1,266 @@ +// 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.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); + +const { internalBinding } = require('internal/test/binding'); +if (typeof internalBinding('crypto').ScryptJob !== 'function') + common.skip('no scrypt support'); + +const good = [ + // Zero-length key is legal, functions as a parameter validation check. + { + pass: '', + salt: '', + keylen: 0, + N: 16, + p: 1, + r: 1, + expected: '', + }, + // Test vectors from https://tools.ietf.org/html/rfc7914#page-13 that + // should pass. Note that the test vector with N=1048576 is omitted + // because it takes too long to complete and uses over 1 GiB of memory. + { + pass: '', + salt: '', + keylen: 64, + N: 16, + p: 1, + r: 1, + expected: + '77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442' + + 'fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906', + }, + { + pass: 'password', + salt: 'NaCl', + keylen: 64, + N: 1024, + p: 16, + r: 8, + expected: + 'fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b373162' + + '2eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640', + }, + { + pass: 'pleaseletmein', + salt: 'SodiumChloride', + keylen: 64, + N: 16384, + p: 1, + r: 8, + expected: + '7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2' + + 'd5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887', + }, + { + pass: '', + salt: '', + keylen: 64, + cost: 16, + parallelization: 1, + blockSize: 1, + expected: + '77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442' + + 'fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906', + }, + { + pass: 'password', + salt: 'NaCl', + keylen: 64, + cost: 1024, + parallelization: 16, + blockSize: 8, + expected: + 'fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b373162' + + '2eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640', + }, + { + pass: 'pleaseletmein', + salt: 'SodiumChloride', + keylen: 64, + cost: 16384, + parallelization: 1, + blockSize: 8, + expected: + '7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2' + + 'd5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887', + }, +]; + +// Test vectors that should fail. +const bad = [ + { N: 1, p: 1, r: 1 }, // N < 2 + { N: 3, p: 1, r: 1 }, // Not power of 2. + { N: 1, cost: 1 }, // Both N and cost + { p: 1, parallelization: 1 }, // Both p and parallelization + { r: 1, blockSize: 1 }, // Both r and blocksize +]; + +// Test vectors where 128*N*r exceeds maxmem. +const toobig = [ + { N: 2 ** 16, p: 1, r: 1 }, // N >= 2**(r*16) + { N: 2, p: 2 ** 30, r: 1 }, // p > (2**30-1)/r + { N: 2 ** 20, p: 1, r: 8 }, + { N: 2 ** 10, p: 1, r: 8, maxmem: 2 ** 20 }, +]; + +const badargs = [ + { + args: [], + expected: { code: 'ERR_INVALID_ARG_TYPE', message: /"password"/ }, + }, + { + args: [null], + expected: { code: 'ERR_INVALID_ARG_TYPE', message: /"password"/ }, + }, + { + args: [''], + expected: { code: 'ERR_INVALID_ARG_TYPE', message: /"salt"/ }, + }, + { + args: ['', null], + expected: { code: 'ERR_INVALID_ARG_TYPE', message: /"salt"/ }, + }, + { + args: ['', ''], + expected: { code: 'ERR_INVALID_ARG_TYPE', message: /"keylen"/ }, + }, + { + args: ['', '', null], + expected: { code: 'ERR_INVALID_ARG_TYPE', message: /"keylen"/ }, + }, + { + args: ['', '', .42], + expected: { code: 'ERR_OUT_OF_RANGE', message: /"keylen"/ }, + }, + { + args: ['', '', -42], + expected: { code: 'ERR_OUT_OF_RANGE', message: /"keylen"/ }, + }, + { + args: ['', '', 2 ** 31], + expected: { code: 'ERR_OUT_OF_RANGE', message: /"keylen"/ }, + }, + { + args: ['', '', 2147485780], + expected: { code: 'ERR_OUT_OF_RANGE', message: /"keylen"/ }, + }, + { + args: ['', '', 2 ** 32], + expected: { code: 'ERR_OUT_OF_RANGE', message: /"keylen"/ }, + }, +]; + +for (const options of good) { + const { pass, salt, keylen, expected } = options; + const actual = crypto.scryptSync(pass, salt, keylen, options); + assert.strictEqual(actual.toString('hex'), expected); + crypto.scrypt(pass, salt, keylen, options, common.mustSucceed((actual) => { + assert.strictEqual(actual.toString('hex'), expected); + })); +} + +for (const options of bad) { + const expected = { + message: /Invalid scrypt param/, + }; + assert.throws(() => crypto.scrypt('pass', 'salt', 1, options, () => {}), + expected); + assert.throws(() => crypto.scryptSync('pass', 'salt', 1, options), + expected); +} + +for (const options of toobig) { + const expected = { + message: /Invalid scrypt param/ + }; + assert.throws(() => crypto.scrypt('pass', 'salt', 1, options, () => {}), + expected); + assert.throws(() => crypto.scryptSync('pass', 'salt', 1, options), + expected); +} + +{ + const defaults = { N: 16384, p: 1, r: 8 }; + const expected = crypto.scryptSync('pass', 'salt', 1, defaults); + const actual = crypto.scryptSync('pass', 'salt', 1); + assert.deepStrictEqual(actual.toString('hex'), expected.toString('hex')); + crypto.scrypt('pass', 'salt', 1, common.mustSucceed((actual) => { + assert.deepStrictEqual(actual.toString('hex'), expected.toString('hex')); + })); +} + +for (const { args, expected } of badargs) { + assert.throws(() => crypto.scrypt(...args), expected); + assert.throws(() => crypto.scryptSync(...args), expected); +} + +{ + const expected = { code: 'ERR_INVALID_ARG_TYPE' }; + assert.throws(() => crypto.scrypt('', '', 42, null), expected); + assert.throws(() => crypto.scrypt('', '', 42, {}, null), expected); + assert.throws(() => crypto.scrypt('', '', 42, {}), expected); + assert.throws(() => crypto.scrypt('', '', 42, {}, {}), expected); +} + +{ + // Values for maxmem that do not fit in 32 bits but that are still safe + // integers should be allowed. + crypto.scrypt('', '', 4, { maxmem: 2 ** 52 }, + common.mustSucceed((actual) => { + assert.strictEqual(actual.toString('hex'), 'd72c87d0'); + })); + + // Values that exceed Number.isSafeInteger should not be allowed. + assert.throws(() => crypto.scryptSync('', '', 0, { maxmem: 2 ** 53 }), { + code: 'ERR_OUT_OF_RANGE' + }); +} + +{ + // Regression test for https://github.com/nodejs/node/issues/28836. + + function testParameter(name, value) { + let accessCount = 0; + + // Find out how often the value is accessed. + crypto.scryptSync('', '', 1, { + get [name]() { + accessCount++; + return value; + } + }); + + // Try to crash the process on the last access. + assert.throws(() => { + crypto.scryptSync('', '', 1, { + get [name]() { + if (--accessCount === 0) + return ''; + return value; + } + }); + }, { + code: 'ERR_INVALID_ARG_TYPE' + }); + } + + [ + ['N', 16384], ['cost', 16384], + ['r', 8], ['blockSize', 8], + ['p', 1], ['parallelization', 1], + ].forEach((arg) => testParameter(...arg)); +} diff --git a/tests/node_compat/test/parallel/test-crypto-subtle-zero-length.js b/tests/node_compat/test/parallel/test-crypto-subtle-zero-length.js new file mode 100644 index 0000000000..7aa73660a5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-crypto-subtle-zero-length.js @@ -0,0 +1,46 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const { subtle } = globalThis.crypto; + +(async () => { + const k = await subtle.importKey( + 'raw', + new Uint8Array(32), + { name: 'AES-GCM' }, + false, + [ 'encrypt', 'decrypt' ]); + assert(k instanceof CryptoKey); + + const e = await subtle.encrypt({ + name: 'AES-GCM', + iv: new Uint8Array(12), + }, k, new Uint8Array(0)); + assert(e instanceof ArrayBuffer); + assert.deepStrictEqual( + Buffer.from(e), + Buffer.from([ + 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, + 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b ])); + + const v = await subtle.decrypt({ + name: 'AES-GCM', + iv: new Uint8Array(12), + }, k, e); + assert(v instanceof ArrayBuffer); + assert.strictEqual(v.byteLength, 0); +})().then(common.mustCall()).catch((e) => { + assert.ifError(e); +}); diff --git a/tests/node_compat/test/parallel/test-dgram-address.js b/tests/node_compat/test/parallel/test-dgram-address.js new file mode 100644 index 0000000000..63e7c9e1ac --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-address.js @@ -0,0 +1,88 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +{ + // IPv4 Test + const socket = dgram.createSocket('udp4'); + + socket.on('listening', common.mustCall(() => { + const address = socket.address(); + + assert.strictEqual(address.address, common.localhostIPv4); + assert.strictEqual(typeof address.port, 'number'); + assert.ok(isFinite(address.port)); + assert.ok(address.port > 0); + assert.strictEqual(address.family, 'IPv4'); + socket.close(); + })); + + socket.on('error', (err) => { + socket.close(); + assert.fail(`Unexpected error on udp4 socket. ${err.toString()}`); + }); + + socket.bind(0, common.localhostIPv4); +} + +if (common.hasIPv6) { + // IPv6 Test + const socket = dgram.createSocket('udp6'); + const localhost = '::1'; + + socket.on('listening', common.mustCall(() => { + const address = socket.address(); + + assert.strictEqual(address.address, localhost); + assert.strictEqual(typeof address.port, 'number'); + assert.ok(isFinite(address.port)); + assert.ok(address.port > 0); + assert.strictEqual(address.family, 'IPv6'); + socket.close(); + })); + + socket.on('error', (err) => { + socket.close(); + assert.fail(`Unexpected error on udp6 socket. ${err.toString()}`); + }); + + socket.bind(0, localhost); +} + +{ + // Verify that address() throws if the socket is not bound. + const socket = dgram.createSocket('udp4'); + + assert.throws(() => { + socket.address(); + }, /^Error: getsockname EBADF$/); +} diff --git a/tests/node_compat/test/parallel/test-dgram-bind-default-address.js b/tests/node_compat/test/parallel/test-dgram-bind-default-address.js new file mode 100644 index 0000000000..ec3ab66a20 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-bind-default-address.js @@ -0,0 +1,60 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +// Skip test in FreeBSD jails since 0.0.0.0 will resolve to default interface +if (common.inFreeBSDJail) + common.skip('In a FreeBSD jail'); + +const assert = require('assert'); +const dgram = require('dgram'); + +dgram.createSocket('udp4').bind(0, common.mustCall(function() { + assert.strictEqual(typeof this.address().port, 'number'); + assert.ok(isFinite(this.address().port)); + assert.ok(this.address().port > 0); + assert.strictEqual(this.address().address, '0.0.0.0'); + this.close(); +})); + +if (!common.hasIPv6) { + common.printSkipMessage('udp6 part of test, because no IPv6 support'); + return; +} + +dgram.createSocket('udp6').bind(0, common.mustCall(function() { + assert.strictEqual(typeof this.address().port, 'number'); + assert.ok(isFinite(this.address().port)); + assert.ok(this.address().port > 0); + let address = this.address().address; + if (address === '::ffff:0.0.0.0') + address = '::'; + assert.strictEqual(address, '::'); + this.close(); +})); diff --git a/tests/node_compat/test/parallel/test-dgram-bind-error-repeat.js b/tests/node_compat/test/parallel/test-dgram-bind-error-repeat.js new file mode 100644 index 0000000000..d03b133bf4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-bind-error-repeat.js @@ -0,0 +1,34 @@ +// 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. + +'use strict'; +const common = require('../common'); +const dgram = require('dgram'); + +// Regression test for https://github.com/nodejs/node/issues/30209 +// No warning should be emitted when re-trying `.bind()` on UDP sockets +// repeatedly. + +process.on('warning', common.mustNotCall()); + +const reservePortSocket = dgram.createSocket('udp4'); +reservePortSocket.bind(() => { + const { port } = reservePortSocket.address(); + + const newSocket = dgram.createSocket('udp4'); + + let errors = 0; + newSocket.on('error', common.mustCall(() => { + if (++errors < 20) { + newSocket.bind(port, common.mustNotCall()); + } else { + newSocket.close(); + reservePortSocket.close(); + } + }, 20)); + newSocket.bind(port, common.mustNotCall()); +}); diff --git a/tests/node_compat/test/parallel/test-dgram-bind.js b/tests/node_compat/test/parallel/test-dgram-bind.js new file mode 100644 index 0000000000..010d795f83 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-bind.js @@ -0,0 +1,50 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const socket = dgram.createSocket('udp4'); + +socket.on('listening', common.mustCall(() => { + assert.throws(() => { + socket.bind(); + }, { + code: 'ERR_SOCKET_ALREADY_BOUND', + name: 'Error', + message: /^Socket is already bound$/ + }); + + socket.close(); +})); + +const result = socket.bind(); // Should not throw. + +assert.strictEqual(result, socket); // Should have returned itself. diff --git a/tests/node_compat/test/parallel/test-dgram-bytes-length.js b/tests/node_compat/test/parallel/test-dgram-bytes-length.js new file mode 100644 index 0000000000..df2a960803 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-bytes-length.js @@ -0,0 +1,46 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const message = Buffer.from('Some bytes'); +const client = dgram.createSocket('udp4'); +client.send( + message, + 0, + message.length, + 41234, + 'localhost', + function(err, bytes) { + assert.strictEqual(bytes, message.length); + client.close(); + } +); diff --git a/tests/node_compat/test/parallel/test-dgram-close-in-listening.js b/tests/node_compat/test/parallel/test-dgram-close-in-listening.js new file mode 100644 index 0000000000..fc0827d86f --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-close-in-listening.js @@ -0,0 +1,33 @@ +// 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. + +'use strict'; +// Ensure that if a dgram socket is closed before the sendQueue is drained +// will not crash + +const common = require('../common'); +const dgram = require('dgram'); + +const buf = Buffer.alloc(1024, 42); + +const socket = dgram.createSocket('udp4'); + +socket.on('listening', function() { + socket.close(); +}); + +// Get a random port for send +const portGetter = dgram.createSocket('udp4') + .bind(0, 'localhost', common.mustCall(() => { + // Adds a listener to 'listening' to send the data when + // the socket is available + socket.send(buf, 0, buf.length, + portGetter.address().port, + portGetter.address().address); + + portGetter.close(); + })); diff --git a/tests/node_compat/test/parallel/test-dgram-close-is-not-callback.js b/tests/node_compat/test/parallel/test-dgram-close-is-not-callback.js new file mode 100644 index 0000000000..6af6dcf956 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-close-is-not-callback.js @@ -0,0 +1,28 @@ +// 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. + +'use strict'; +const common = require('../common'); +const dgram = require('dgram'); + +const buf = Buffer.alloc(1024, 42); + +const socket = dgram.createSocket('udp4'); + +// Get a random port for send +const portGetter = dgram.createSocket('udp4') + .bind(0, 'localhost', common.mustCall(() => { + socket.send(buf, 0, buf.length, + portGetter.address().port, + portGetter.address().address); + + // If close callback is not function, ignore the argument. + socket.close('bad argument'); + portGetter.close(); + + socket.on('close', common.mustCall()); + })); diff --git a/tests/node_compat/test/parallel/test-dgram-close.js b/tests/node_compat/test/parallel/test-dgram-close.js new file mode 100644 index 0000000000..0bd7e78d10 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-close.js @@ -0,0 +1,63 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Flags: --expose-internals +'use strict'; +// Ensure that if a dgram socket is closed before the DNS lookup completes, it +// won't crash. + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); +const { kStateSymbol } = require('internal/dgram'); + +const buf = Buffer.alloc(1024, 42); + +let socket = dgram.createSocket('udp4'); +const { handle } = socket[kStateSymbol]; + +// Get a random port for send +const portGetter = dgram.createSocket('udp4') + .bind(0, 'localhost', common.mustCall(() => { + socket.send(buf, 0, buf.length, + portGetter.address().port, + portGetter.address().address); + + assert.strictEqual(socket.close(common.mustCall()), socket); + socket.on('close', common.mustCall()); + socket = null; + + // Verify that accessing handle after closure doesn't throw + setImmediate(function() { + setImmediate(function() { + console.log('Handle fd is: ', handle.fd); + }); + }); + + portGetter.close(); + })); diff --git a/tests/node_compat/test/parallel/test-dgram-connect-send-callback-buffer-length.js b/tests/node_compat/test/parallel/test-dgram-connect-send-callback-buffer-length.js new file mode 100644 index 0000000000..aa8e32eecc --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-connect-send-callback-buffer-length.js @@ -0,0 +1,30 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +const dgram = require('dgram'); +const client = dgram.createSocket('udp4'); + +const buf = Buffer.allocUnsafe(256); +const offset = 20; +const len = buf.length - offset; + +const messageSent = common.mustSucceed(function messageSent(bytes) { + assert.notStrictEqual(bytes, buf.length); + assert.strictEqual(bytes, buf.length - offset); + client.close(); +}); + +client.bind(0, common.mustCall(() => { + client.connect(client.address().port, common.mustCall(() => { + client.send(buf, offset, len, messageSent); + })); +})); diff --git a/tests/node_compat/test/parallel/test-dgram-connect-send-callback-buffer.js b/tests/node_compat/test/parallel/test-dgram-connect-send-callback-buffer.js new file mode 100644 index 0000000000..19e01d6af8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-connect-send-callback-buffer.js @@ -0,0 +1,27 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +const buf = Buffer.allocUnsafe(256); + +const onMessage = common.mustSucceed((bytes) => { + assert.strictEqual(bytes, buf.length); + client.close(); +}); + +client.bind(0, common.mustCall(() => { + client.connect(client.address().port, common.mustCall(() => { + client.send(buf, onMessage); + })); +})); diff --git a/tests/node_compat/test/parallel/test-dgram-connect-send-callback-multi-buffer.js b/tests/node_compat/test/parallel/test-dgram-connect-send-callback-multi-buffer.js new file mode 100644 index 0000000000..4f0a19ceab --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-connect-send-callback-multi-buffer.js @@ -0,0 +1,36 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +const messageSent = common.mustCall((err, bytes) => { + assert.strictEqual(bytes, buf1.length + buf2.length); +}); + +const buf1 = Buffer.alloc(256, 'x'); +const buf2 = Buffer.alloc(256, 'y'); + +client.on('listening', common.mustCall(() => { + const port = client.address().port; + client.connect(port, common.mustCall(() => { + client.send([buf1, buf2], messageSent); + })); +})); + +client.on('message', common.mustCall((buf, info) => { + const expected = Buffer.concat([buf1, buf2]); + assert.ok(buf.equals(expected), 'message was received correctly'); + client.close(); +})); + +client.bind(0); diff --git a/tests/node_compat/test/parallel/test-dgram-connect-send-default-host.js b/tests/node_compat/test/parallel/test-dgram-connect-send-default-host.js new file mode 100644 index 0000000000..7ca49680d6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-connect-send-default-host.js @@ -0,0 +1,55 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); +const server = dgram.createSocket('udp4'); + +const toSend = [Buffer.alloc(256, 'x'), + Buffer.alloc(256, 'y'), + Buffer.alloc(256, 'z'), + 'hello']; + +const received = []; + +server.on('listening', common.mustCall(() => { + const port = server.address().port; + client.connect(port, (err) => { + assert.ifError(err); + client.send(toSend[0], 0, toSend[0].length); + client.send(toSend[1]); + client.send([toSend[2]]); + client.send(toSend[3], 0, toSend[3].length); + + client.send(new Uint8Array(toSend[0]), 0, toSend[0].length); + client.send(new Uint8Array(toSend[1])); + client.send([new Uint8Array(toSend[2])]); + client.send(new Uint8Array(Buffer.from(toSend[3])), + 0, toSend[3].length); + }); +})); + +server.on('message', common.mustCall((buf, info) => { + received.push(buf.toString()); + + if (received.length === toSend.length * 2) { + // The replies may arrive out of order -> sort them before checking. + received.sort(); + + const expected = toSend.concat(toSend).map(String).sort(); + assert.deepStrictEqual(received, expected); + client.close(); + server.close(); + } +}, toSend.length * 2)); + +server.bind(0); diff --git a/tests/node_compat/test/parallel/test-dgram-connect-send-empty-array.js b/tests/node_compat/test/parallel/test-dgram-connect-send-empty-array.js new file mode 100644 index 0000000000..a47645c104 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-connect-send-empty-array.js @@ -0,0 +1,29 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +client.on('message', common.mustCall((buf, info) => { + const expected = Buffer.alloc(0); + assert.ok(buf.equals(expected), `Expected empty message but got ${buf}`); + client.close(); +})); + +client.on('listening', common.mustCall(() => { + client.connect(client.address().port, + common.localhostIPv4, + common.mustCall(() => client.send([]))); +})); + +client.bind(0); diff --git a/tests/node_compat/test/parallel/test-dgram-connect-send-empty-buffer.js b/tests/node_compat/test/parallel/test-dgram-connect-send-empty-buffer.js new file mode 100644 index 0000000000..17e10aa804 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-connect-send-empty-buffer.js @@ -0,0 +1,27 @@ +// 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. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +client.bind(0, common.mustCall(function() { + const port = this.address().port; + client.connect(port, common.mustCall(() => { + const buf = Buffer.alloc(0); + client.send(buf, 0, 0, common.mustSucceed()); + })); + + client.on('message', common.mustCall((buffer) => { + assert.strictEqual(buffer.length, 0); + client.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-dgram-connect-send-empty-packet.js b/tests/node_compat/test/parallel/test-dgram-connect-send-empty-packet.js new file mode 100644 index 0000000000..8c4d52af82 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-connect-send-empty-packet.js @@ -0,0 +1,35 @@ +// 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. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +client.bind(0, common.mustCall(function() { + client.connect(client.address().port, common.mustCall(() => { + client.on('message', common.mustCall(callback)); + const buf = Buffer.alloc(1); + + const interval = setInterval(function() { + client.send(buf, 0, 0, common.mustCall(callback)); + }, 10); + + function callback(firstArg) { + // If client.send() callback, firstArg should be null. + // If client.on('message') listener, firstArg should be a 0-length buffer. + if (firstArg instanceof Buffer) { + assert.strictEqual(firstArg.length, 0); + clearInterval(interval); + client.close(); + } + } + })); +})); diff --git a/tests/node_compat/test/parallel/test-dgram-connect-send-multi-buffer-copy.js b/tests/node_compat/test/parallel/test-dgram-connect-send-multi-buffer-copy.js new file mode 100644 index 0000000000..e561ffbdca --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-connect-send-multi-buffer-copy.js @@ -0,0 +1,36 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +const onMessage = common.mustCall(common.mustSucceed((bytes) => { + assert.strictEqual(bytes, buf1.length + buf2.length); +})); + +const buf1 = Buffer.alloc(256, 'x'); +const buf2 = Buffer.alloc(256, 'y'); + +client.on('listening', common.mustCall(function() { + const toSend = [buf1, buf2]; + client.connect(client.address().port, common.mustCall(() => { + client.send(toSend, onMessage); + })); +})); + +client.on('message', common.mustCall(function onMessage(buf, info) { + const expected = Buffer.concat([buf1, buf2]); + assert.ok(buf.equals(expected), 'message was received correctly'); + client.close(); +})); + +client.bind(0); diff --git a/tests/node_compat/test/parallel/test-dgram-connect-send-multi-string-array.js b/tests/node_compat/test/parallel/test-dgram-connect-send-multi-string-array.js new file mode 100644 index 0000000000..9f94a59b3c --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-connect-send-multi-string-array.js @@ -0,0 +1,24 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); +const socket = dgram.createSocket('udp4'); +const data = ['foo', 'bar', 'baz']; + +socket.on('message', common.mustCall((msg, rinfo) => { + socket.close(); + assert.deepStrictEqual(msg.toString(), data.join('')); +})); + +socket.bind(0, () => { + socket.connect(socket.address().port, common.mustCall(() => { + socket.send(data); + })); +}); diff --git a/tests/node_compat/test/parallel/test-dgram-connect.js b/tests/node_compat/test/parallel/test-dgram-connect.js new file mode 100644 index 0000000000..d6c2df6f46 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-connect.js @@ -0,0 +1,73 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const PORT = 12345; + +const client = dgram.createSocket('udp4'); +client.connect(PORT, common.mustCall(() => { + const remoteAddr = client.remoteAddress(); + assert.strictEqual(remoteAddr.port, PORT); + assert.throws(() => { + client.connect(PORT, common.mustNotCall()); + }, { + name: 'Error', + message: 'Already connected', + code: 'ERR_SOCKET_DGRAM_IS_CONNECTED' + }); + + client.disconnect(); + assert.throws(() => { + client.disconnect(); + }, { + name: 'Error', + message: 'Not connected', + code: 'ERR_SOCKET_DGRAM_NOT_CONNECTED' + }); + + assert.throws(() => { + client.remoteAddress(); + }, { + name: 'Error', + message: 'Not connected', + code: 'ERR_SOCKET_DGRAM_NOT_CONNECTED' + }); + + client.once('connect', common.mustCall(() => client.close())); + client.connect(PORT); +})); + +assert.throws(() => { + client.connect(PORT); +}, { + name: 'Error', + message: 'Already connected', + code: 'ERR_SOCKET_DGRAM_IS_CONNECTED' +}); + +assert.throws(() => { + client.disconnect(); +}, { + name: 'Error', + message: 'Not connected', + code: 'ERR_SOCKET_DGRAM_NOT_CONNECTED' +}); + +[ 0, null, 78960, undefined ].forEach((port) => { + assert.throws(() => { + client.connect(port); + }, { + name: 'RangeError', + message: /^Port should be > 0 and < 65536/, + code: 'ERR_SOCKET_BAD_PORT' + }); +}); diff --git a/tests/node_compat/test/parallel/test-dgram-createSocket-type.js b/tests/node_compat/test/parallel/test-dgram-createSocket-type.js new file mode 100644 index 0000000000..78f77b5544 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-createSocket-type.js @@ -0,0 +1,68 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); +const invalidTypes = [ + 'test', + ['udp4'], + new String('udp4'), + 1, + {}, + true, + false, + null, + undefined, +]; +const validTypes = [ + 'udp4', + 'udp6', + { type: 'udp4' }, + { type: 'udp6' }, +]; +const errMessage = /^Bad socket type specified\. Valid types are: udp4, udp6$/; + +// Error must be thrown with invalid types +invalidTypes.forEach((invalidType) => { + assert.throws(() => { + dgram.createSocket(invalidType); + }, { + code: 'ERR_SOCKET_BAD_TYPE', + name: 'TypeError', + message: errMessage + }); +}); + +// Error must not be thrown with valid types +validTypes.forEach((validType) => { + const socket = dgram.createSocket(validType); + socket.close(); +}); + +// Ensure buffer sizes can be set +{ + const socket = dgram.createSocket({ + type: 'udp4', + recvBufferSize: 10000, + sendBufferSize: 15000 + }); + + socket.bind(common.mustCall(() => { + // note: linux will double the buffer size + assert.ok(socket.getRecvBufferSize() === 10000 || + socket.getRecvBufferSize() === 20000, + 'SO_RCVBUF not 10000 or 20000, ' + + `was ${socket.getRecvBufferSize()}`); + assert.ok(socket.getSendBufferSize() === 15000 || + socket.getSendBufferSize() === 30000, + 'SO_SNDBUF not 15000 or 30000, ' + + `was ${socket.getRecvBufferSize()}`); + socket.close(); + })); +} diff --git a/tests/node_compat/test/parallel/test-dgram-error-message-address.js b/tests/node_compat/test/parallel/test-dgram-error-message-address.js new file mode 100644 index 0000000000..b8fab2d3cb --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-error-message-address.js @@ -0,0 +1,64 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +// IPv4 Test +const socket_ipv4 = dgram.createSocket('udp4'); + +socket_ipv4.on('listening', common.mustNotCall()); + +socket_ipv4.on('error', common.mustCall(function(e) { + assert.strictEqual(e.port, undefined); + assert.strictEqual(e.message, 'bind EADDRNOTAVAIL 1.1.1.1'); + assert.strictEqual(e.address, '1.1.1.1'); + assert.strictEqual(e.code, 'EADDRNOTAVAIL'); + socket_ipv4.close(); +})); + +socket_ipv4.bind(0, '1.1.1.1'); + +// IPv6 Test +const socket_ipv6 = dgram.createSocket('udp6'); + +socket_ipv6.on('listening', common.mustNotCall()); + +socket_ipv6.on('error', common.mustCall(function(e) { + // EAFNOSUPPORT or EPROTONOSUPPORT means IPv6 is disabled on this system. + const allowed = ['EADDRNOTAVAIL', 'EAFNOSUPPORT', 'EPROTONOSUPPORT']; + assert(allowed.includes(e.code), `'${e.code}' was not one of ${allowed}.`); + assert.strictEqual(e.port, undefined); + assert.strictEqual(e.message, `bind ${e.code} 111::1`); + assert.strictEqual(e.address, '111::1'); + socket_ipv6.close(); +})); + +socket_ipv6.bind(0, '111::1'); diff --git a/tests/node_compat/test/parallel/test-dgram-implicit-bind.js b/tests/node_compat/test/parallel/test-dgram-implicit-bind.js new file mode 100644 index 0000000000..dfafc2d1ac --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-implicit-bind.js @@ -0,0 +1,53 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const dgram = require('dgram'); + +const source = dgram.createSocket('udp4'); +const target = dgram.createSocket('udp4'); +let messages = 0; + +target.on('message', common.mustCall(function(buf) { + if (buf.toString() === 'abc') ++messages; + if (buf.toString() === 'def') ++messages; + if (messages === 2) { + source.close(); + target.close(); + } +}, 2)); + +target.on('listening', common.mustCall(function() { + // Second .send() call should not throw a bind error. + const port = this.address().port; + source.send(Buffer.from('abc'), 0, 3, port, '127.0.0.1'); + source.send(Buffer.from('def'), 0, 3, port, '127.0.0.1'); +})); + +target.bind(0); diff --git a/tests/node_compat/test/parallel/test-dgram-listen-after-bind.js b/tests/node_compat/test/parallel/test-dgram-listen-after-bind.js new file mode 100644 index 0000000000..7cfdd824ea --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-listen-after-bind.js @@ -0,0 +1,52 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const socket = dgram.createSocket('udp4'); + +socket.bind(); + +let fired = false; +const timer = setTimeout(() => { + socket.close(); +}, 100); + +socket.on('listening', common.mustCall(() => { + clearTimeout(timer); + fired = true; + socket.close(); +})); + +socket.on('close', common.mustCall(() => { + assert(fired, 'listening should fire after bind'); +})); diff --git a/tests/node_compat/test/parallel/test-dgram-msgsize.js b/tests/node_compat/test/parallel/test-dgram-msgsize.js new file mode 100644 index 0000000000..81754f6650 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-msgsize.js @@ -0,0 +1,46 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +// Send a too big datagram. The destination doesn't matter because it's +// not supposed to get sent out anyway. +const buf = Buffer.allocUnsafe(256 * 1024); +const sock = dgram.createSocket('udp4'); +sock.send(buf, 0, buf.length, 12345, '127.0.0.1', common.mustCall(cb)); +function cb(err) { + assert(err instanceof Error); + assert.strictEqual(err.code, 'EMSGSIZE'); + assert.strictEqual(err.address, '127.0.0.1'); + assert.strictEqual(err.port, 12345); + assert.strictEqual(err.message, 'send EMSGSIZE 127.0.0.1:12345'); + sock.close(); +} diff --git a/tests/node_compat/test/parallel/test-dgram-oob-buffer.js b/tests/node_compat/test/parallel/test-dgram-oob-buffer.js new file mode 100644 index 0000000000..af9629c3ac --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-oob-buffer.js @@ -0,0 +1,52 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// Some operating systems report errors when an UDP message is sent to an +// unreachable host. This error can be reported by sendto() and even by +// recvfrom(). Node should not propagate this error to the user. + +const common = require('../common'); +const dgram = require('dgram'); + +const socket = dgram.createSocket('udp4'); +const buf = Buffer.from([1, 2, 3, 4]); +const portGetter = dgram.createSocket('udp4') + .bind(0, 'localhost', common.mustCall(() => { + const { address, port } = portGetter.address(); + portGetter.close(common.mustCall(() => { + socket.send(buf, 0, 0, port, address, common.mustNotCall()); + socket.send(buf, 0, 4, port, address, common.mustNotCall()); + socket.send(buf, 1, 3, port, address, common.mustNotCall()); + socket.send(buf, 3, 1, port, address, common.mustNotCall()); + // Since length of zero means nothing, don't error despite OOB. + socket.send(buf, 4, 0, port, address, common.mustNotCall()); + + socket.close(); + })); + })); diff --git a/tests/node_compat/test/parallel/test-dgram-recv-error.js b/tests/node_compat/test/parallel/test-dgram-recv-error.js new file mode 100644 index 0000000000..3bbdb300aa --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-recv-error.js @@ -0,0 +1,26 @@ +// 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'); +const assert = require('assert'); +const dgram = require('dgram'); +const { kStateSymbol } = require('internal/dgram'); +const s = dgram.createSocket('udp4'); +const { handle } = s[kStateSymbol]; + +s.on('error', common.mustCall((err) => { + s.close(); + + // Don't check the full error message, as the errno is not important here. + assert.match(String(err), /^Error: recvmsg/); + assert.strictEqual(err.syscall, 'recvmsg'); +})); + +s.on('message', common.mustNotCall('no message should be received.')); +s.bind(common.mustCall(() => handle.onmessage(-1, handle, null, null))); diff --git a/tests/node_compat/test/parallel/test-dgram-ref.js b/tests/node_compat/test/parallel/test-dgram-ref.js new file mode 100644 index 0000000000..7cd9200955 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-ref.js @@ -0,0 +1,42 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const dgram = require('dgram'); + +// Should not hang, see https://github.com/nodejs/node-v0.x-archive/issues/1282 +dgram.createSocket('udp4'); +dgram.createSocket('udp6'); + +{ + // Test the case of ref()'ing a socket with no handle. + const s = dgram.createSocket('udp4'); + + s.close(common.mustCall(() => s.ref())); +} diff --git a/tests/node_compat/test/parallel/test-dgram-send-bad-arguments.js b/tests/node_compat/test/parallel/test-dgram-send-bad-arguments.js new file mode 100644 index 0000000000..a99f359663 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-bad-arguments.js @@ -0,0 +1,162 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const buf = Buffer.from('test'); +const host = '127.0.0.1'; +const sock = dgram.createSocket('udp4'); + +function checkArgs(connected) { + // First argument should be a buffer. + assert.throws( + () => { sock.send(); }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "buffer" argument must be of type string or an instance ' + + 'of Buffer, TypedArray, or DataView. Received undefined' + } + ); + + // send(buf, offset, length, port, host) + if (connected) { + assert.throws( + () => { sock.send(buf, 1, 1, -1, host); }, + { + code: 'ERR_SOCKET_DGRAM_IS_CONNECTED', + name: 'Error', + message: 'Already connected' + } + ); + + assert.throws( + () => { sock.send(buf, 1, 1, 0, host); }, + { + code: 'ERR_SOCKET_DGRAM_IS_CONNECTED', + name: 'Error', + message: 'Already connected' + } + ); + + assert.throws( + () => { sock.send(buf, 1, 1, 65536, host); }, + { + code: 'ERR_SOCKET_DGRAM_IS_CONNECTED', + name: 'Error', + message: 'Already connected' + } + ); + + assert.throws( + () => { sock.send(buf, 1234, '127.0.0.1', common.mustNotCall()); }, + { + code: 'ERR_SOCKET_DGRAM_IS_CONNECTED', + name: 'Error', + message: 'Already connected' + } + ); + + const longArray = [1, 2, 3, 4, 5, 6, 7, 8]; + for (const input of ['hello', + Buffer.from('hello'), + Buffer.from('hello world').subarray(0, 5), + Buffer.from('hello world').subarray(4, 9), + Buffer.from('hello world').subarray(6), + new Uint8Array([1, 2, 3, 4, 5]), + new Uint8Array(longArray).subarray(0, 5), + new Uint8Array(longArray).subarray(2, 7), + new Uint8Array(longArray).subarray(3), + new DataView(new ArrayBuffer(5), 0), + new DataView(new ArrayBuffer(6), 1), + new DataView(new ArrayBuffer(7), 1, 5)]) { + assert.throws( + () => { sock.send(input, 6, 0); }, + { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: '"offset" is outside of buffer bounds', + } + ); + + assert.throws( + () => { sock.send(input, 0, 6); }, + { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: '"length" is outside of buffer bounds', + } + ); + + assert.throws( + () => { sock.send(input, 3, 4); }, + { + code: 'ERR_BUFFER_OUT_OF_BOUNDS', + name: 'RangeError', + message: '"length" is outside of buffer bounds', + } + ); + } + } else { + assert.throws(() => { sock.send(buf, 1, 1, -1, host); }, RangeError); + assert.throws(() => { sock.send(buf, 1, 1, 0, host); }, RangeError); + assert.throws(() => { sock.send(buf, 1, 1, 65536, host); }, RangeError); + } + + // send(buf, port, host) + assert.throws( + () => { sock.send(23, 12345, host); }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "buffer" argument must be of type string or an instance ' + + 'of Buffer, TypedArray, or DataView. Received type number (23)' + } + ); + + // send([buf1, ..], port, host) + assert.throws( + () => { sock.send([buf, 23], 12345, host); }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "buffer list arguments" argument must be of type string ' + + 'or an instance of Buffer, TypedArray, or DataView. ' + + 'Received an instance of Array' + } + ); +} + +checkArgs(); +sock.connect(12345, common.mustCall(() => { + checkArgs(true); + sock.close(); +})); diff --git a/tests/node_compat/test/parallel/test-dgram-send-callback-buffer-empty-address.js b/tests/node_compat/test/parallel/test-dgram-send-callback-buffer-empty-address.js new file mode 100644 index 0000000000..c9b8d08f03 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-callback-buffer-empty-address.js @@ -0,0 +1,23 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +const buf = Buffer.alloc(256, 'x'); + +const onMessage = common.mustSucceed((bytes) => { + assert.strictEqual(bytes, buf.length); + client.close(); +}); + +client.bind(0, () => client.send(buf, client.address().port, onMessage)); diff --git a/tests/node_compat/test/parallel/test-dgram-send-callback-buffer-length-empty-address.js b/tests/node_compat/test/parallel/test-dgram-send-callback-buffer-length-empty-address.js new file mode 100644 index 0000000000..aeab74b411 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-callback-buffer-length-empty-address.js @@ -0,0 +1,28 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +const dgram = require('dgram'); +const client = dgram.createSocket('udp4'); + +const buf = Buffer.alloc(256, 'x'); +const offset = 20; +const len = buf.length - offset; + +const onMessage = common.mustSucceed(function messageSent(bytes) { + assert.notStrictEqual(bytes, buf.length); + assert.strictEqual(bytes, buf.length - offset); + client.close(); +}); + +client.bind(0, () => client.send(buf, offset, len, + client.address().port, + onMessage)); diff --git a/tests/node_compat/test/parallel/test-dgram-send-callback-buffer-length.js b/tests/node_compat/test/parallel/test-dgram-send-callback-buffer-length.js new file mode 100644 index 0000000000..decb1388e5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-callback-buffer-length.js @@ -0,0 +1,50 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +const dgram = require('dgram'); +const client = dgram.createSocket('udp4'); + +const buf = Buffer.allocUnsafe(256); +const offset = 20; +const len = buf.length - offset; + +const messageSent = common.mustSucceed(function messageSent(bytes) { + assert.notStrictEqual(bytes, buf.length); + assert.strictEqual(bytes, buf.length - offset); + client.close(); +}); + +client.bind(0, () => client.send(buf, offset, len, + client.address().port, + '127.0.0.1', + messageSent)); diff --git a/tests/node_compat/test/parallel/test-dgram-send-callback-buffer.js b/tests/node_compat/test/parallel/test-dgram-send-callback-buffer.js new file mode 100644 index 0000000000..73593844db --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-callback-buffer.js @@ -0,0 +1,26 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +const buf = Buffer.allocUnsafe(256); + +const onMessage = common.mustSucceed((bytes) => { + assert.strictEqual(bytes, buf.length); + client.close(); +}); + +client.bind(0, () => client.send(buf, + client.address().port, + common.localhostIPv4, + onMessage)); diff --git a/tests/node_compat/test/parallel/test-dgram-send-callback-multi-buffer-empty-address.js b/tests/node_compat/test/parallel/test-dgram-send-callback-multi-buffer-empty-address.js new file mode 100644 index 0000000000..4a9d80eb57 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-callback-multi-buffer-empty-address.js @@ -0,0 +1,34 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +const messageSent = common.mustSucceed(function messageSent(bytes) { + assert.strictEqual(bytes, buf1.length + buf2.length); +}); + +const buf1 = Buffer.alloc(256, 'x'); +const buf2 = Buffer.alloc(256, 'y'); + +client.on('listening', function() { + const port = this.address().port; + client.send([buf1, buf2], port, messageSent); +}); + +client.on('message', common.mustCall(function onMessage(buf) { + const expected = Buffer.concat([buf1, buf2]); + assert.ok(buf.equals(expected), 'message was received correctly'); + client.close(); +})); + +client.bind(0); diff --git a/tests/node_compat/test/parallel/test-dgram-send-callback-multi-buffer.js b/tests/node_compat/test/parallel/test-dgram-send-callback-multi-buffer.js new file mode 100644 index 0000000000..b775978be5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-callback-multi-buffer.js @@ -0,0 +1,34 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +const messageSent = common.mustCall((err, bytes) => { + assert.strictEqual(bytes, buf1.length + buf2.length); +}); + +const buf1 = Buffer.alloc(256, 'x'); +const buf2 = Buffer.alloc(256, 'y'); + +client.on('listening', () => { + const port = client.address().port; + client.send([buf1, buf2], port, common.localhostIPv4, messageSent); +}); + +client.on('message', common.mustCall((buf, info) => { + const expected = Buffer.concat([buf1, buf2]); + assert.ok(buf.equals(expected), 'message was received correctly'); + client.close(); +})); + +client.bind(0); diff --git a/tests/node_compat/test/parallel/test-dgram-send-callback-recursive.js b/tests/node_compat/test/parallel/test-dgram-send-callback-recursive.js new file mode 100644 index 0000000000..27579516c8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-callback-recursive.js @@ -0,0 +1,50 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const dgram = require('dgram'); +const client = dgram.createSocket('udp4'); +const chunk = 'abc'; +let received = 0; +let sent = 0; +const limit = 10; +let async = false; +let port; + +function onsend() { + if (sent++ < limit) { + client.send(chunk, 0, chunk.length, port, common.localhostIPv4, onsend); + } else { + assert.strictEqual(async, true); + } +} + +client.on('listening', function() { + port = this.address().port; + + process.nextTick(() => { + async = true; + }); + + onsend(); +}); + +client.on('message', (buf, info) => { + received++; + if (received === limit) { + client.close(); + } +}); + +client.on('close', common.mustCall(function() { + assert.strictEqual(received, limit); +})); + +client.bind(0); diff --git a/tests/node_compat/test/parallel/test-dgram-send-default-host.js b/tests/node_compat/test/parallel/test-dgram-send-default-host.js new file mode 100644 index 0000000000..989dca888b --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-default-host.js @@ -0,0 +1,79 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +const toSend = [Buffer.alloc(256, 'x'), + Buffer.alloc(256, 'y'), + Buffer.alloc(256, 'z'), + 'hello']; + +const received = []; +let totalBytesSent = 0; +let totalBytesReceived = 0; +const arrayBufferViewsCount = common.getArrayBufferViews( + Buffer.from('') +).length; + +client.on('listening', common.mustCall(() => { + const port = client.address().port; + + client.send(toSend[0], 0, toSend[0].length, port); + client.send(toSend[1], port); + client.send([toSend[2]], port); + client.send(toSend[3], 0, toSend[3].length, port); + + totalBytesSent += toSend.map((buf) => buf.length) + .reduce((a, b) => a + b, 0); + + for (const msgBuf of common.getArrayBufferViews(toSend[0])) { + client.send(msgBuf, 0, msgBuf.byteLength, port); + totalBytesSent += msgBuf.byteLength; + } + for (const msgBuf of common.getArrayBufferViews(toSend[1])) { + client.send(msgBuf, port); + totalBytesSent += msgBuf.byteLength; + } + for (const msgBuf of common.getArrayBufferViews(toSend[2])) { + client.send([msgBuf], port); + totalBytesSent += msgBuf.byteLength; + } +})); + +client.on('message', common.mustCall((buf, info) => { + received.push(buf.toString()); + totalBytesReceived += info.size; + + if (totalBytesReceived === totalBytesSent) { + client.close(); + } + // For every buffer in `toSend`, we send the raw Buffer, + // as well as every TypedArray in getArrayBufferViews() +}, toSend.length + (toSend.length - 1) * arrayBufferViewsCount)); + +client.on('close', common.mustCall((buf, info) => { + // The replies may arrive out of order -> sort them before checking. + received.sort(); + + const repeated = [...toSend]; + for (let i = 0; i < arrayBufferViewsCount; i++) { + repeated.push(...toSend.slice(0, 3)); + } + + assert.strictEqual(totalBytesSent, totalBytesReceived); + + const expected = repeated.map(String).sort(); + assert.deepStrictEqual(received, expected); +})); + +client.bind(0); diff --git a/tests/node_compat/test/parallel/test-dgram-send-empty-array.js b/tests/node_compat/test/parallel/test-dgram-send-empty-array.js new file mode 100644 index 0000000000..cf2508d9ca --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-empty-array.js @@ -0,0 +1,32 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +let interval; + +client.on('message', common.mustCall(function onMessage(buf, info) { + const expected = Buffer.alloc(0); + assert.ok(buf.equals(expected), `Expected empty message but got ${buf}`); + clearInterval(interval); + client.close(); +})); + +client.on('listening', common.mustCall(function() { + interval = setInterval(function() { + client.send([], client.address().port, common.localhostIPv4); + }, 10); +})); + +client.bind(0); diff --git a/tests/node_compat/test/parallel/test-dgram-send-empty-buffer.js b/tests/node_compat/test/parallel/test-dgram-send-empty-buffer.js new file mode 100644 index 0000000000..de5101cbd2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-empty-buffer.js @@ -0,0 +1,50 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +client.bind(0, common.mustCall(function() { + const port = this.address().port; + + client.on('message', common.mustCall(function onMessage(buffer) { + assert.strictEqual(buffer.length, 0); + clearInterval(interval); + client.close(); + })); + + const buf = Buffer.alloc(0); + const interval = setInterval(function() { + client.send(buf, 0, 0, port, '127.0.0.1', common.mustCall()); + }, 10); +})); diff --git a/tests/node_compat/test/parallel/test-dgram-send-empty-packet.js b/tests/node_compat/test/parallel/test-dgram-send-empty-packet.js new file mode 100644 index 0000000000..01f7a459ce --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-empty-packet.js @@ -0,0 +1,36 @@ +// 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. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +client.bind(0, common.mustCall(function() { + + client.on('message', common.mustCall(callback)); + + const port = this.address().port; + const buf = Buffer.alloc(1); + + const interval = setInterval(function() { + client.send(buf, 0, 0, port, '127.0.0.1', common.mustCall(callback)); + }, 10); + + function callback(firstArg) { + // If client.send() callback, firstArg should be null. + // If client.on('message') listener, firstArg should be a 0-length buffer. + if (firstArg instanceof Buffer) { + assert.strictEqual(firstArg.length, 0); + clearInterval(interval); + client.close(); + } + } +})); diff --git a/tests/node_compat/test/parallel/test-dgram-send-error.js b/tests/node_compat/test/parallel/test-dgram-send-error.js new file mode 100644 index 0000000000..8b0887e349 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-error.js @@ -0,0 +1,77 @@ +// 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'); +const assert = require('assert'); +const dgram = require('dgram'); +const { internalBinding } = require('internal/test/binding'); +const { UV_UNKNOWN } = internalBinding('uv'); +const { getSystemErrorName } = require('util'); +const { kStateSymbol } = require('internal/dgram'); +const mockError = new Error('mock DNS error'); + +function getSocket(callback) { + const socket = dgram.createSocket('udp4'); + + socket.on('message', common.mustNotCall('Should not receive any messages.')); + socket.bind(common.mustCall(() => { + socket[kStateSymbol].handle.lookup = function(address, callback) { + process.nextTick(callback, mockError); + }; + + callback(socket); + })); + return socket; +} + +getSocket((socket) => { + socket.on('error', common.mustCall((err) => { + socket.close(); + assert.strictEqual(err, mockError); + })); + + socket.send('foo', socket.address().port, 'localhost'); +}); + +getSocket((socket) => { + const callback = common.mustCall((err) => { + socket.close(); + assert.strictEqual(err, mockError); + }); + + socket.send('foo', socket.address().port, 'localhost', callback); +}); + +{ + const socket = dgram.createSocket('udp4'); + + socket.on('message', common.mustNotCall('Should not receive any messages.')); + + socket.bind(common.mustCall(() => { + const port = socket.address().port; + const callback = common.mustCall((err) => { + socket.close(); + assert.strictEqual(err.code, 'UNKNOWN'); + assert.strictEqual(getSystemErrorName(err.errno), 'UNKNOWN'); + assert.strictEqual(err.syscall, 'send'); + assert.strictEqual(err.address, common.localhostIPv4); + assert.strictEqual(err.port, port); + assert.strictEqual( + err.message, + `${err.syscall} ${err.code} ${err.address}:${err.port}` + ); + }); + + socket[kStateSymbol].handle.send = function() { + return UV_UNKNOWN; + }; + + socket.send('foo', port, common.localhostIPv4, callback); + })); +} diff --git a/tests/node_compat/test/parallel/test-dgram-send-invalid-msg-type.js b/tests/node_compat/test/parallel/test-dgram-send-invalid-msg-type.js new file mode 100644 index 0000000000..7fbe1730a4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-invalid-msg-type.js @@ -0,0 +1,43 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); + +// This test ensures that a TypeError is raised when the argument to `send()` +// or `sendto()` is anything but a Buffer. +// https://github.com/nodejs/node-v0.x-archive/issues/4496 + +const assert = require('assert'); +const dgram = require('dgram'); + +// Should throw but not crash. +const socket = dgram.createSocket('udp4'); +assert.throws(function() { socket.send(true, 0, 1, 1, 'host'); }, TypeError); +assert.throws(function() { socket.sendto(5, 0, 1, 1, 'host'); }, TypeError); +socket.close(); diff --git a/tests/node_compat/test/parallel/test-dgram-send-multi-buffer-copy.js b/tests/node_compat/test/parallel/test-dgram-send-multi-buffer-copy.js new file mode 100644 index 0000000000..bb5217de71 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-multi-buffer-copy.js @@ -0,0 +1,35 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp4'); + +const onMessage = common.mustCall(function(err, bytes) { + assert.strictEqual(bytes, buf1.length + buf2.length); +}); + +const buf1 = Buffer.alloc(256, 'x'); +const buf2 = Buffer.alloc(256, 'y'); + +client.on('listening', function() { + const toSend = [buf1, buf2]; + client.send(toSend, this.address().port, common.localhostIPv4, onMessage); + toSend.splice(0, 2); +}); + +client.on('message', common.mustCall(function onMessage(buf, info) { + const expected = Buffer.concat([buf1, buf2]); + assert.ok(buf.equals(expected), 'message was received correctly'); + client.close(); +})); + +client.bind(0); diff --git a/tests/node_compat/test/parallel/test-dgram-send-multi-string-array.js b/tests/node_compat/test/parallel/test-dgram-send-multi-string-array.js new file mode 100644 index 0000000000..ae77a421ed --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-send-multi-string-array.js @@ -0,0 +1,20 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); +const socket = dgram.createSocket('udp4'); +const data = ['foo', 'bar', 'baz']; + +socket.on('message', common.mustCall((msg, rinfo) => { + socket.close(); + assert.deepStrictEqual(msg.toString(), data.join('')); +})); + +socket.bind(() => socket.send(data, socket.address().port, 'localhost')); diff --git a/tests/node_compat/test/parallel/test-dgram-udp4.js b/tests/node_compat/test/parallel/test-dgram-udp4.js new file mode 100644 index 0000000000..f477746a0d --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-udp4.js @@ -0,0 +1,59 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); +const message_to_send = 'A message to send'; + +const server = dgram.createSocket('udp4'); +server.on('message', common.mustCall((msg, rinfo) => { + assert.strictEqual(rinfo.address, common.localhostIPv4); + assert.strictEqual(msg.toString(), message_to_send.toString()); + server.send(msg, 0, msg.length, rinfo.port, rinfo.address); +})); +server.on('listening', common.mustCall(() => { + const client = dgram.createSocket('udp4'); + const port = server.address().port; + client.on('message', common.mustCall((msg, rinfo) => { + assert.strictEqual(rinfo.address, common.localhostIPv4); + assert.strictEqual(rinfo.port, port); + assert.strictEqual(msg.toString(), message_to_send.toString()); + client.close(); + server.close(); + })); + client.send(message_to_send, + 0, + message_to_send.length, + port, + 'localhost'); + client.on('close', common.mustCall()); +})); +server.on('close', common.mustCall()); +server.bind(0); diff --git a/tests/node_compat/test/parallel/test-dgram-udp6-send-default-host.js b/tests/node_compat/test/parallel/test-dgram-udp6-send-default-host.js new file mode 100644 index 0000000000..039df7615b --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-udp6-send-default-host.js @@ -0,0 +1,83 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasIPv6) + common.skip('no IPv6 support'); + +const assert = require('assert'); +const dgram = require('dgram'); + +const client = dgram.createSocket('udp6'); + +const toSend = [Buffer.alloc(256, 'x'), + Buffer.alloc(256, 'y'), + Buffer.alloc(256, 'z'), + 'hello']; + +const received = []; +let totalBytesSent = 0; +let totalBytesReceived = 0; +const arrayBufferViewLength = common.getArrayBufferViews( + Buffer.from('') +).length; + +client.on('listening', common.mustCall(() => { + const port = client.address().port; + + client.send(toSend[0], 0, toSend[0].length, port); + client.send(toSend[1], port); + client.send([toSend[2]], port); + client.send(toSend[3], 0, toSend[3].length, port); + + totalBytesSent += toSend.map((buf) => buf.length) + .reduce((a, b) => a + b, 0); + + for (const msgBuf of common.getArrayBufferViews(toSend[0])) { + client.send(msgBuf, 0, msgBuf.byteLength, port); + totalBytesSent += msgBuf.byteLength; + } + for (const msgBuf of common.getArrayBufferViews(toSend[1])) { + client.send(msgBuf, port); + totalBytesSent += msgBuf.byteLength; + } + for (const msgBuf of common.getArrayBufferViews(toSend[2])) { + client.send([msgBuf], port); + totalBytesSent += msgBuf.byteLength; + } +})); + +client.on('message', common.mustCall((buf, info) => { + received.push(buf.toString()); + totalBytesReceived += info.size; + + if (totalBytesReceived === totalBytesSent) { + client.close(); + } + // For every buffer in `toSend`, we send the raw Buffer, + // as well as every TypedArray in getArrayBufferViews() +}, toSend.length + (toSend.length - 1) * arrayBufferViewLength)); + +client.on('close', common.mustCall((buf, info) => { + // The replies may arrive out of order -> sort them before checking. + received.sort(); + + const repeated = [...toSend]; + for (let i = 0; i < arrayBufferViewLength; i++) { + // We get arrayBufferViews only for toSend[0..2]. + repeated.push(...toSend.slice(0, 3)); + } + + assert.strictEqual(totalBytesSent, totalBytesReceived); + + const expected = repeated.map(String).sort(); + assert.deepStrictEqual(received, expected); +})); + +client.bind(0); diff --git a/tests/node_compat/test/parallel/test-dgram-unref.js b/tests/node_compat/test/parallel/test-dgram-unref.js new file mode 100644 index 0000000000..282c3ec3be --- /dev/null +++ b/tests/node_compat/test/parallel/test-dgram-unref.js @@ -0,0 +1,47 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const dgram = require('dgram'); + +{ + // Test the case of unref()'ing a socket with a handle. + const s = dgram.createSocket('udp4'); + s.bind(); + s.unref(); +} + +{ + // Test the case of unref()'ing a socket with no handle. + const s = dgram.createSocket('udp4'); + + s.close(common.mustCall(() => s.unref())); +} + +setTimeout(common.mustNotCall(), 1000).unref(); diff --git a/tests/node_compat/test/parallel/test-diagnostics-channel-bind-store.js b/tests/node_compat/test/parallel/test-diagnostics-channel-bind-store.js new file mode 100644 index 0000000000..823c5bb63c --- /dev/null +++ b/tests/node_compat/test/parallel/test-diagnostics-channel-bind-store.js @@ -0,0 +1,115 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const dc = require('diagnostics_channel'); +const { AsyncLocalStorage } = require('async_hooks'); + +let n = 0; +const thisArg = new Date(); +const inputs = [ + { foo: 'bar' }, + { baz: 'buz' }, +]; + +const channel = dc.channel('test'); + +// Bind a storage directly to published data +const store1 = new AsyncLocalStorage(); +channel.bindStore(store1); +let store1bound = true; + +// Bind a store with transformation of published data +const store2 = new AsyncLocalStorage(); +channel.bindStore(store2, common.mustCall((data) => { + assert.strictEqual(data, inputs[n]); + return { data }; +}, 4)); + +// Regular subscribers should see publishes from runStores calls +channel.subscribe(common.mustCall((data) => { + if (store1bound) { + assert.deepStrictEqual(data, store1.getStore()); + } + assert.deepStrictEqual({ data }, store2.getStore()); + assert.strictEqual(data, inputs[n]); +}, 4)); + +// Verify stores are empty before run +assert.strictEqual(store1.getStore(), undefined); +assert.strictEqual(store2.getStore(), undefined); + +channel.runStores(inputs[n], common.mustCall(function(a, b) { + // Verify this and argument forwarding + assert.strictEqual(this, thisArg); + assert.strictEqual(a, 1); + assert.strictEqual(b, 2); + + // Verify store 1 state matches input + assert.strictEqual(store1.getStore(), inputs[n]); + + // Verify store 2 state has expected transformation + assert.deepStrictEqual(store2.getStore(), { data: inputs[n] }); + + // Should support nested contexts + n++; + channel.runStores(inputs[n], common.mustCall(function() { + // Verify this and argument forwarding + assert.strictEqual(this, undefined); + + // Verify store 1 state matches input + assert.strictEqual(store1.getStore(), inputs[n]); + + // Verify store 2 state has expected transformation + assert.deepStrictEqual(store2.getStore(), { data: inputs[n] }); + })); + n--; + + // Verify store 1 state matches input + assert.strictEqual(store1.getStore(), inputs[n]); + + // Verify store 2 state has expected transformation + assert.deepStrictEqual(store2.getStore(), { data: inputs[n] }); +}), thisArg, 1, 2); + +// Verify stores are empty after run +assert.strictEqual(store1.getStore(), undefined); +assert.strictEqual(store2.getStore(), undefined); + +// Verify unbinding works +assert.ok(channel.unbindStore(store1)); +store1bound = false; + +// Verify unbinding a store that is not bound returns false +assert.ok(!channel.unbindStore(store1)); + +n++; +channel.runStores(inputs[n], common.mustCall(() => { + // Verify after unbinding store 1 will remain undefined + assert.strictEqual(store1.getStore(), undefined); + + // Verify still bound store 2 receives expected data + assert.deepStrictEqual(store2.getStore(), { data: inputs[n] }); +})); + +// Contain transformer errors and emit on next tick +const fail = new Error('fail'); +channel.bindStore(store1, () => { + throw fail; +}); + +let calledRunStores = false; +process.once('uncaughtException', common.mustCall((err) => { + assert.strictEqual(calledRunStores, true); + assert.strictEqual(err, fail); +})); + +channel.runStores(inputs[n], common.mustCall()); +calledRunStores = true; diff --git a/tests/node_compat/test/parallel/test-diagnostics-channel-safe-subscriber-errors.js b/tests/node_compat/test/parallel/test-diagnostics-channel-safe-subscriber-errors.js new file mode 100644 index 0000000000..62a4edafdf --- /dev/null +++ b/tests/node_compat/test/parallel/test-diagnostics-channel-safe-subscriber-errors.js @@ -0,0 +1,36 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const dc = require('diagnostics_channel'); +const assert = require('assert'); + +const input = { + foo: 'bar' +}; + +const channel = dc.channel('fail'); + +const error = new Error('nope'); + +process.on('uncaughtException', common.mustCall((err) => { + assert.strictEqual(err, error); +})); + +channel.subscribe(common.mustCall((message, name) => { + throw error; +})); + +// The failing subscriber should not stop subsequent subscribers from running +channel.subscribe(common.mustCall()); + +// Publish should continue without throwing +const fn = common.mustCall(); +channel.publish(input); +fn(); diff --git a/tests/node_compat/test/parallel/test-diagnostics-channel-tracing-channel-async-error.js b/tests/node_compat/test/parallel/test-diagnostics-channel-tracing-channel-async-error.js new file mode 100644 index 0000000000..fa48387a26 --- /dev/null +++ b/tests/node_compat/test/parallel/test-diagnostics-channel-tracing-channel-async-error.js @@ -0,0 +1,53 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const dc = require('diagnostics_channel'); +const assert = require('assert'); + +const channel = dc.tracingChannel('test'); + +const expectedError = new Error('test'); +const input = { foo: 'bar' }; +const thisArg = { baz: 'buz' }; + +function check(found) { + assert.deepStrictEqual(found, input); +} + +const handlers = { + start: common.mustCall(check, 2), + end: common.mustCall(check, 2), + asyncStart: common.mustCall(check, 2), + asyncEnd: common.mustCall(check, 2), + error: common.mustCall((found) => { + check(found); + assert.deepStrictEqual(found.error, expectedError); + }, 2) +}; + +channel.subscribe(handlers); + +channel.traceCallback(function(cb, err) { + assert.deepStrictEqual(this, thisArg); + setImmediate(cb, err); +}, 0, input, thisArg, common.mustCall((err, res) => { + assert.strictEqual(err, expectedError); + assert.strictEqual(res, undefined); +}), expectedError); + +channel.tracePromise(function(value) { + assert.deepStrictEqual(this, thisArg); + return Promise.reject(value); +}, input, thisArg, expectedError).then( + common.mustNotCall(), + common.mustCall((value) => { + assert.deepStrictEqual(value, expectedError); + }) +); diff --git a/tests/node_compat/test/parallel/test-diagnostics-channel-tracing-channel-async.js b/tests/node_compat/test/parallel/test-diagnostics-channel-tracing-channel-async.js new file mode 100644 index 0000000000..25c67f77ce --- /dev/null +++ b/tests/node_compat/test/parallel/test-diagnostics-channel-tracing-channel-async.js @@ -0,0 +1,67 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const dc = require('diagnostics_channel'); +const assert = require('assert'); + +const channel = dc.tracingChannel('test'); + +const expectedResult = { foo: 'bar' }; +const input = { foo: 'bar' }; +const thisArg = { baz: 'buz' }; + +function check(found) { + assert.deepStrictEqual(found, input); +} + +const handlers = { + start: common.mustCall(check, 2), + end: common.mustCall(check, 2), + asyncStart: common.mustCall((found) => { + check(found); + assert.strictEqual(found.error, undefined); + assert.deepStrictEqual(found.result, expectedResult); + }, 2), + asyncEnd: common.mustCall((found) => { + check(found); + assert.strictEqual(found.error, undefined); + assert.deepStrictEqual(found.result, expectedResult); + }, 2), + error: common.mustNotCall() +}; + +channel.subscribe(handlers); + +channel.traceCallback(function(cb, err, res) { + assert.deepStrictEqual(this, thisArg); + setImmediate(cb, err, res); +}, 0, input, thisArg, common.mustCall((err, res) => { + assert.strictEqual(err, null); + assert.deepStrictEqual(res, expectedResult); +}), null, expectedResult); + +channel.tracePromise(function(value) { + assert.deepStrictEqual(this, thisArg); + return Promise.resolve(value); +}, input, thisArg, expectedResult).then( + common.mustCall((value) => { + assert.deepStrictEqual(value, expectedResult); + }), + common.mustNotCall() +); + +let failed = false; +try { + channel.traceCallback(common.mustNotCall(), 0, input, thisArg, 1, 2, 3); +} catch (err) { + assert.ok(/"callback" argument must be of type function/.test(err.message)); + failed = true; +} +assert.strictEqual(failed, true); diff --git a/tests/node_compat/test/parallel/test-diagnostics-channel-tracing-channel-run-stores.js b/tests/node_compat/test/parallel/test-diagnostics-channel-tracing-channel-run-stores.js new file mode 100644 index 0000000000..8efaaf4e27 --- /dev/null +++ b/tests/node_compat/test/parallel/test-diagnostics-channel-tracing-channel-run-stores.js @@ -0,0 +1,28 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { AsyncLocalStorage } = require('async_hooks'); +const dc = require('diagnostics_channel'); +const assert = require('assert'); + +const channel = dc.tracingChannel('test'); +const store = new AsyncLocalStorage(); + +const context = { foo: 'bar' }; + +channel.start.bindStore(store, common.mustCall(() => { + return context; +})); + +assert.strictEqual(store.getStore(), undefined); +channel.traceSync(common.mustCall(() => { + assert.deepStrictEqual(store.getStore(), context); +})); +assert.strictEqual(store.getStore(), undefined); diff --git a/tests/node_compat/test/parallel/test-dns-multi-channel.js b/tests/node_compat/test/parallel/test-dns-multi-channel.js new file mode 100644 index 0000000000..708b49648f --- /dev/null +++ b/tests/node_compat/test/parallel/test-dns-multi-channel.js @@ -0,0 +1,59 @@ +// 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. + +'use strict'; +const common = require('../common'); +const dnstools = require('../common/dns'); +const { Resolver } = require('dns'); +const assert = require('assert'); +const dgram = require('dgram'); + +const servers = [ + { + socket: dgram.createSocket('udp4'), + reply: { type: 'A', address: '1.2.3.4', ttl: 123, domain: 'example.org' } + }, + { + socket: dgram.createSocket('udp4'), + reply: { type: 'A', address: '5.6.7.8', ttl: 123, domain: 'example.org' } + }, +]; + +let waiting = servers.length; +for (const { socket, reply } of servers) { + socket.on('message', common.mustCall((msg, { address, port }) => { + const parsed = dnstools.parseDNSPacket(msg); + const domain = parsed.questions[0].domain; + assert.strictEqual(domain, 'example.org'); + + socket.send(dnstools.writeDNSPacket({ + id: parsed.id, + questions: parsed.questions, + answers: [reply], + }), port, address); + })); + + socket.bind(0, common.mustCall(() => { + if (--waiting === 0) ready(); + })); +} + + +function ready() { + const resolvers = servers.map((server) => ({ + server, + resolver: new Resolver() + })); + + for (const { server: { socket, reply }, resolver } of resolvers) { + resolver.setServers([`127.0.0.1:${socket.address().port}`]); + resolver.resolve4('example.org', common.mustSucceed((res) => { + assert.deepStrictEqual(res, [reply.address]); + socket.close(); + })); + } +} diff --git a/tests/node_compat/test/parallel/test-domain-crypto.js b/tests/node_compat/test/parallel/test-domain-crypto.js new file mode 100644 index 0000000000..1d289eea6c --- /dev/null +++ b/tests/node_compat/test/parallel/test-domain-crypto.js @@ -0,0 +1,50 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('node compiled without OpenSSL.'); + +const crypto = require('crypto'); + +// Pollution of global is intentional as part of test. +common.allowGlobals(require('domain')); +// See https://github.com/nodejs/node/commit/d1eff9ab +global.domain = require('domain'); + +// Should not throw a 'TypeError: undefined is not a function' exception +crypto.randomBytes(8); +crypto.randomBytes(8, common.mustSucceed()); +const buf = Buffer.alloc(8); +crypto.randomFillSync(buf); +crypto.pseudoRandomBytes(8); +crypto.pseudoRandomBytes(8, common.mustSucceed()); +crypto.pbkdf2('password', 'salt', 8, 8, 'sha1', common.mustSucceed()); diff --git a/tests/node_compat/test/parallel/test-domain-ee-error-listener.js b/tests/node_compat/test/parallel/test-domain-ee-error-listener.js new file mode 100644 index 0000000000..a89345fafe --- /dev/null +++ b/tests/node_compat/test/parallel/test-domain-ee-error-listener.js @@ -0,0 +1,27 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const domain = require('domain').create(); +const EventEmitter = require('events'); + +domain.on('error', common.mustNotCall()); + +const ee = new EventEmitter(); + +const plainObject = { justAn: 'object' }; +ee.once('error', common.mustCall((err) => { + assert.deepStrictEqual(err, plainObject); +})); +ee.emit('error', plainObject); + +const err = new Error('test error'); +ee.once('error', common.expectsError(err)); +ee.emit('error', err); diff --git a/tests/node_compat/test/parallel/test-domain-nested-throw.js b/tests/node_compat/test/parallel/test-domain-nested-throw.js new file mode 100644 index 0000000000..fa8d5763c2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-domain-nested-throw.js @@ -0,0 +1,108 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const domain = require('domain'); + +if (process.argv[2] !== 'child') { + parent(); + return; +} + +function parent() { + const node = process.execPath; + const spawn = require('child_process').spawn; + const opt = { stdio: 'inherit' }; + const child = spawn(node, [__filename, 'child'], opt); + child.on('exit', function(c) { + assert(!c); + console.log('ok'); + }); +} + +let gotDomain1Error = false; +let gotDomain2Error = false; + +let threw1 = false; +let threw2 = false; + +function throw1() { + threw1 = true; + throw new Error('handled by domain1'); +} + +function throw2() { + threw2 = true; + throw new Error('handled by domain2'); +} + +function inner(throw1, throw2) { + const domain1 = domain.createDomain(); + + domain1.on('error', function(err) { + if (gotDomain1Error) { + console.error('got domain 1 twice'); + process.exit(1); + } + gotDomain1Error = true; + throw2(); + }); + + domain1.run(function() { + throw1(); + }); +} + +function outer() { + const domain2 = domain.createDomain(); + + domain2.on('error', function(err) { + if (gotDomain2Error) { + console.error('got domain 2 twice'); + process.exit(1); + } + gotDomain2Error = true; + }); + + domain2.run(function() { + inner(throw1, throw2); + }); +} + +process.on('exit', function() { + assert(gotDomain1Error); + assert(gotDomain2Error); + assert(threw1); + assert(threw2); + console.log('ok'); +}); + +outer(); diff --git a/tests/node_compat/test/parallel/test-domain-nested.js b/tests/node_compat/test/parallel/test-domain-nested.js new file mode 100644 index 0000000000..8bffb960c2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-domain-nested.js @@ -0,0 +1,50 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// Make sure that the nested domains don't cause the domain stack to grow + +require('../common'); +const assert = require('assert'); +const domain = require('domain'); + +process.on('exit', function(c) { + assert.strictEqual(domain._stack.length, 0); +}); + +domain.create().run(function() { + domain.create().run(function() { + domain.create().run(function() { + domain.create().on('error', function(e) { + // Don't need to do anything here + }).run(function() { + throw new Error('died'); + }); + }); + }); +}); diff --git a/tests/node_compat/test/parallel/test-domain-stack.js b/tests/node_compat/test/parallel/test-domain-stack.js new file mode 100644 index 0000000000..b7399ff296 --- /dev/null +++ b/tests/node_compat/test/parallel/test-domain-stack.js @@ -0,0 +1,55 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// Make sure that the domain stack doesn't get out of hand. + +require('../common'); +const domain = require('domain'); + +const a = domain.create(); +a.name = 'a'; + +a.on('error', function() { + if (domain._stack.length > 5) { + console.error('leaking!', domain._stack); + process.exit(1); + } +}); + +const foo = a.bind(function() { + throw new Error('error from foo'); +}); + +for (let i = 0; i < 1000; i++) { + process.nextTick(foo); +} + +process.on('exit', function(c) { + if (!c) console.log('ok'); +}); diff --git a/tests/node_compat/test/parallel/test-domain-top-level-error-handler-clears-stack.js b/tests/node_compat/test/parallel/test-domain-top-level-error-handler-clears-stack.js new file mode 100644 index 0000000000..718159c0f4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-domain-top-level-error-handler-clears-stack.js @@ -0,0 +1,38 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const domain = require('domain'); + +// Make sure that the domains stack is cleared after a top-level domain +// error handler exited gracefully. +const d = domain.create(); + +d.on('error', common.mustCall(() => { + // Scheduling a callback with process.nextTick _could_ enter a _new_ domain, + // but domain's error handlers are called outside of their domain's context. + // So there should _no_ domain on the domains stack if the domains stack was + // cleared properly when the domain error handler was called. + process.nextTick(() => { + if (domain._stack.length !== 0) { + // Do not use assert to perform this test: this callback runs in a + // different callstack as the original process._fatalException that + // handled the original error, thus throwing here would trigger another + // call to process._fatalException, and so on recursively and + // indefinitely. + console.error('domains stack length should be 0, but instead is:', + domain._stack.length); + process.exit(1); + } + }); +})); + +d.run(() => { + throw new Error('Error from domain'); +}); diff --git a/tests/node_compat/test/parallel/test-dsa-fips-invalid-key.js b/tests/node_compat/test/parallel/test-dsa-fips-invalid-key.js new file mode 100644 index 0000000000..90a41e2568 --- /dev/null +++ b/tests/node_compat/test/parallel/test-dsa-fips-invalid-key.js @@ -0,0 +1,26 @@ +// 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. + +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); + +if (!common.hasFipsCrypto) + common.skip('node compiled without FIPS OpenSSL.'); + +const assert = require('assert'); +const crypto = require('crypto'); + +const input = 'hello'; + +const dsapri = fixtures.readKey('dsa_private_1025.pem'); +const sign = crypto.createSign('SHA1'); +sign.update(input); + +assert.throws(function() { + sign.sign(dsapri); +}, /PEM_read_bio_PrivateKey failed/); diff --git a/tests/node_compat/test/parallel/test-env-newprotomethod-remove-unnecessary-prototypes.js b/tests/node_compat/test/parallel/test-env-newprotomethod-remove-unnecessary-prototypes.js new file mode 100644 index 0000000000..bded14a407 --- /dev/null +++ b/tests/node_compat/test/parallel/test-env-newprotomethod-remove-unnecessary-prototypes.js @@ -0,0 +1,26 @@ +// 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'; +require('../common'); + +// This test ensures that unnecessary prototypes are no longer +// being generated by node::NewFunctionTemplate. + +const assert = require('assert'); +const { internalBinding } = require('internal/test/binding'); +[ + internalBinding('udp_wrap').UDP.prototype.bind6, + internalBinding('tcp_wrap').TCP.prototype.bind6, + internalBinding('udp_wrap').UDP.prototype.send6, + internalBinding('tcp_wrap').TCP.prototype.bind, + internalBinding('udp_wrap').UDP.prototype.close, + internalBinding('tcp_wrap').TCP.prototype.open, +].forEach((binding, i) => { + assert.strictEqual('prototype' in binding, false, `Test ${i} failed`); +}); diff --git a/tests/node_compat/test/parallel/test-error-aggregateTwoErrors.js b/tests/node_compat/test/parallel/test-error-aggregateTwoErrors.js new file mode 100644 index 0000000000..1ae41a0c12 --- /dev/null +++ b/tests/node_compat/test/parallel/test-error-aggregateTwoErrors.js @@ -0,0 +1,66 @@ +// 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'; + +require('../common'); +const assert = require('assert'); +const { aggregateTwoErrors } = require('internal/errors'); + +assert.strictEqual(aggregateTwoErrors(null, null), null); + +{ + const err = new Error(); + assert.strictEqual(aggregateTwoErrors(null, err), err); +} + +{ + const err = new Error(); + assert.strictEqual(aggregateTwoErrors(err, null), err); +} + +{ + const err0 = new Error('original'); + const err1 = new Error('second error'); + + err0.code = 'ERR0'; + err1.code = 'ERR1'; + + const chainedError = aggregateTwoErrors(err1, err0); + assert.strictEqual(chainedError.message, err0.message); + assert.strictEqual(chainedError.code, err0.code); + assert.deepStrictEqual(chainedError.errors, [err0, err1]); +} + +{ + const err0 = new Error('original'); + const err1 = new Error('second error'); + const err2 = new Error('third error'); + + err0.code = 'ERR0'; + err1.code = 'ERR1'; + err2.code = 'ERR2'; + + const chainedError = aggregateTwoErrors(err2, aggregateTwoErrors(err1, err0)); + assert.strictEqual(chainedError.message, err0.message); + assert.strictEqual(chainedError.code, err0.code); + assert.deepStrictEqual(chainedError.errors, [err0, err1, err2]); +} + +{ + const err0 = new Error('original'); + const err1 = new Error('second error'); + + err0.code = 'ERR0'; + err1.code = 'ERR1'; + + const chainedError = aggregateTwoErrors(null, aggregateTwoErrors(err1, err0)); + assert.strictEqual(chainedError.message, err0.message); + assert.strictEqual(chainedError.code, err0.code); + assert.deepStrictEqual(chainedError.errors, [err0, err1]); +} diff --git a/tests/node_compat/test/parallel/test-error-prepare-stack-trace.js b/tests/node_compat/test/parallel/test-error-prepare-stack-trace.js new file mode 100644 index 0000000000..ede87825cb --- /dev/null +++ b/tests/node_compat/test/parallel/test-error-prepare-stack-trace.js @@ -0,0 +1,26 @@ +// 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: --enable-source-maps +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Error.prepareStackTrace() can be overridden with source maps enabled. +{ + let prepareCalled = false; + Error.prepareStackTrace = (_error, trace) => { + prepareCalled = true; + }; + try { + throw new Error('foo'); + } catch (err) { + err.stack; // eslint-disable-line no-unused-expressions + } + assert(prepareCalled); +} diff --git a/tests/node_compat/test/parallel/test-errors-aborterror.js b/tests/node_compat/test/parallel/test-errors-aborterror.js new file mode 100644 index 0000000000..38c4df0873 --- /dev/null +++ b/tests/node_compat/test/parallel/test-errors-aborterror.js @@ -0,0 +1,38 @@ +// 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'; + +require('../common'); +const { + strictEqual, + throws, +} = require('assert'); +const { AbortError } = require('internal/errors'); + +{ + const err = new AbortError(); + strictEqual(err.message, 'The operation was aborted'); + strictEqual(err.cause, undefined); +} + +{ + const cause = new Error('boom'); + const err = new AbortError('bang', { cause }); + strictEqual(err.message, 'bang'); + strictEqual(err.cause, cause); +} + +{ + throws(() => new AbortError('', false), { + code: 'ERR_INVALID_ARG_TYPE' + }); + throws(() => new AbortError('', ''), { + code: 'ERR_INVALID_ARG_TYPE' + }); +} diff --git a/tests/node_compat/test/parallel/test-event-capture-rejections.js b/tests/node_compat/test/parallel/test-event-capture-rejections.js new file mode 100644 index 0000000000..ae34d26b49 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-capture-rejections.js @@ -0,0 +1,327 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { EventEmitter, captureRejectionSymbol } = require('events'); +const { inherits } = require('util'); + +// Inherits from EE without a call to the +// parent constructor. +function NoConstructor() { +} + +// captureRejections param validation +{ + [1, [], function() {}, {}, Infinity, Math.PI, 'meow'].forEach((arg) => { + assert.throws( + () => new EventEmitter({ captureRejections: arg }), + { + name: 'TypeError', + code: 'ERR_INVALID_ARG_TYPE', + message: 'The "options.captureRejections" property must be of type boolean.' + + common.invalidArgTypeHelper(arg), + } + ); + }); +} + +inherits(NoConstructor, EventEmitter); + +function captureRejections() { + const ee = new EventEmitter({ captureRejections: true }); + const _err = new Error('kaboom'); + ee.on('something', common.mustCall(async (value) => { + throw _err; + })); + + ee.on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + process.nextTick(captureRejectionsTwoHandlers); + })); + + ee.emit('something'); +} + +function captureRejectionsTwoHandlers() { + const ee = new EventEmitter({ captureRejections: true }); + const _err = new Error('kaboom'); + + ee.on('something', common.mustCall(async (value) => { + throw _err; + })); + + // throw twice + ee.on('something', common.mustCall(async (value) => { + throw _err; + })); + + let count = 0; + + ee.on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + if (++count === 2) { + process.nextTick(defaultValue); + } + }, 2)); + + ee.emit('something'); +} + +function defaultValue() { + const ee = new EventEmitter(); + const _err = new Error('kaboom'); + ee.on('something', common.mustCall(async (value) => { + throw _err; + })); + + process.removeAllListeners('unhandledRejection'); + + process.once('unhandledRejection', common.mustCall((err) => { + // restore default + process.on('unhandledRejection', (err) => { throw err; }); + + assert.strictEqual(err, _err); + process.nextTick(globalSetting); + })); + + ee.emit('something'); +} + +function globalSetting() { + assert.strictEqual(EventEmitter.captureRejections, false); + EventEmitter.captureRejections = true; + const ee = new EventEmitter(); + const _err = new Error('kaboom'); + ee.on('something', common.mustCall(async (value) => { + throw _err; + })); + + ee.on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + + // restore default + EventEmitter.captureRejections = false; + process.nextTick(configurable); + })); + + ee.emit('something'); +} + +// We need to be able to configure this for streams, as we would +// like to call destroy(err) there. +function configurable() { + const ee = new EventEmitter({ captureRejections: true }); + const _err = new Error('kaboom'); + ee.on('something', common.mustCall(async (...args) => { + assert.deepStrictEqual(args, [42, 'foobar']); + throw _err; + })); + + assert.strictEqual(captureRejectionSymbol, Symbol.for('nodejs.rejection')); + + ee[captureRejectionSymbol] = common.mustCall((err, type, ...args) => { + assert.strictEqual(err, _err); + assert.strictEqual(type, 'something'); + assert.deepStrictEqual(args, [42, 'foobar']); + process.nextTick(globalSettingNoConstructor); + }); + + ee.emit('something', 42, 'foobar'); +} + +function globalSettingNoConstructor() { + assert.strictEqual(EventEmitter.captureRejections, false); + EventEmitter.captureRejections = true; + const ee = new NoConstructor(); + const _err = new Error('kaboom'); + ee.on('something', common.mustCall(async (value) => { + throw _err; + })); + + ee.on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + + // restore default + EventEmitter.captureRejections = false; + process.nextTick(thenable); + })); + + ee.emit('something'); +} + +function thenable() { + const ee = new EventEmitter({ captureRejections: true }); + const _err = new Error('kaboom'); + ee.on('something', common.mustCall((value) => { + const obj = {}; + + Object.defineProperty(obj, 'then', { + get: common.mustCall(() => { + return common.mustCall((resolved, rejected) => { + assert.strictEqual(resolved, undefined); + rejected(_err); + }); + }, 1), // Only 1 call for Promises/A+ compat. + }); + + return obj; + })); + + ee.on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + process.nextTick(avoidLoopOnRejection); + })); + + ee.emit('something'); +} + +function avoidLoopOnRejection() { + const ee = new EventEmitter({ captureRejections: true }); + const _err1 = new Error('kaboom'); + const _err2 = new Error('kaboom2'); + ee.on('something', common.mustCall(async (value) => { + throw _err1; + })); + + ee[captureRejectionSymbol] = common.mustCall(async (err) => { + assert.strictEqual(err, _err1); + throw _err2; + }); + + process.removeAllListeners('unhandledRejection'); + + process.once('unhandledRejection', common.mustCall((err) => { + // restore default + process.on('unhandledRejection', (err) => { throw err; }); + + assert.strictEqual(err, _err2); + process.nextTick(avoidLoopOnError); + })); + + ee.emit('something'); +} + +function avoidLoopOnError() { + const ee = new EventEmitter({ captureRejections: true }); + const _err1 = new Error('kaboom'); + const _err2 = new Error('kaboom2'); + ee.on('something', common.mustCall(async (value) => { + throw _err1; + })); + + ee.on('error', common.mustCall(async (err) => { + assert.strictEqual(err, _err1); + throw _err2; + })); + + process.removeAllListeners('unhandledRejection'); + + process.once('unhandledRejection', common.mustCall((err) => { + // restore default + process.on('unhandledRejection', (err) => { throw err; }); + + assert.strictEqual(err, _err2); + process.nextTick(thenableThatThrows); + })); + + ee.emit('something'); +} + +function thenableThatThrows() { + const ee = new EventEmitter({ captureRejections: true }); + const _err = new Error('kaboom'); + ee.on('something', common.mustCall((value) => { + const obj = {}; + + Object.defineProperty(obj, 'then', { + get: common.mustCall(() => { + throw _err; + }, 1), // Only 1 call for Promises/A+ compat. + }); + + return obj; + })); + + ee.on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + process.nextTick(resetCaptureOnThrowInError); + })); + + ee.emit('something'); +} + +function resetCaptureOnThrowInError() { + const ee = new EventEmitter({ captureRejections: true }); + ee.on('something', common.mustCall(async (value) => { + throw new Error('kaboom'); + })); + + ee.once('error', common.mustCall((err) => { + throw err; + })); + + process.removeAllListeners('uncaughtException'); + + process.once('uncaughtException', common.mustCall((err) => { + process.nextTick(next); + })); + + ee.emit('something'); + + function next() { + process.on('uncaughtException', common.mustNotCall()); + + const _err = new Error('kaboom2'); + ee.on('something2', common.mustCall(async (value) => { + throw _err; + })); + + ee.on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + + process.removeAllListeners('uncaughtException'); + + // restore default + process.on('uncaughtException', (err) => { throw err; }); + + process.nextTick(argValidation); + })); + + ee.emit('something2'); + } +} + +function argValidation() { + + function testType(obj) { + const received = obj.constructor.name !== 'Number' ? + `an instance of ${obj.constructor.name}` : + `type number (${obj})`; + + assert.throws(() => new EventEmitter({ captureRejections: obj }), { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "options.captureRejections" property must be of type ' + + `boolean. Received ${received}`, + }); + + assert.throws(() => EventEmitter.captureRejections = obj, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "EventEmitter.captureRejections" property must be of ' + + `type boolean. Received ${received}`, + }); + } + + testType([]); + testType({ hello: 42 }); + testType(42); +} + +captureRejections(); diff --git a/tests/node_compat/test/parallel/test-event-emitter-check-listener-leaks.js b/tests/node_compat/test/parallel/test-event-emitter-check-listener-leaks.js new file mode 100644 index 0000000000..3233ca06a6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-check-listener-leaks.js @@ -0,0 +1,110 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const events = require('events'); + +// default +{ + const e = new events.EventEmitter(); + + for (let i = 0; i < 10; i++) { + e.on('default', common.mustNotCall()); + } + assert.ok(!Object.hasOwn(e._events.default, 'warned')); + e.on('default', common.mustNotCall()); + assert.ok(e._events.default.warned); + + // symbol + const symbol = Symbol('symbol'); + e.setMaxListeners(1); + e.on(symbol, common.mustNotCall()); + assert.ok(!Object.hasOwn(e._events[symbol], 'warned')); + e.on(symbol, common.mustNotCall()); + assert.ok(Object.hasOwn(e._events[symbol], 'warned')); + + // specific + e.setMaxListeners(5); + for (let i = 0; i < 5; i++) { + e.on('specific', common.mustNotCall()); + } + assert.ok(!Object.hasOwn(e._events.specific, 'warned')); + e.on('specific', common.mustNotCall()); + assert.ok(e._events.specific.warned); + + // only one + e.setMaxListeners(1); + e.on('only one', common.mustNotCall()); + assert.ok(!Object.hasOwn(e._events['only one'], 'warned')); + e.on('only one', common.mustNotCall()); + assert.ok(Object.hasOwn(e._events['only one'], 'warned')); + + // unlimited + e.setMaxListeners(0); + for (let i = 0; i < 1000; i++) { + e.on('unlimited', common.mustNotCall()); + } + assert.ok(!Object.hasOwn(e._events.unlimited, 'warned')); +} + +// process-wide +{ + events.EventEmitter.defaultMaxListeners = 42; + const e = new events.EventEmitter(); + + for (let i = 0; i < 42; ++i) { + e.on('fortytwo', common.mustNotCall()); + } + assert.ok(!Object.hasOwn(e._events.fortytwo, 'warned')); + e.on('fortytwo', common.mustNotCall()); + assert.ok(Object.hasOwn(e._events.fortytwo, 'warned')); + delete e._events.fortytwo.warned; + + events.EventEmitter.defaultMaxListeners = 44; + e.on('fortytwo', common.mustNotCall()); + assert.ok(!Object.hasOwn(e._events.fortytwo, 'warned')); + e.on('fortytwo', common.mustNotCall()); + assert.ok(Object.hasOwn(e._events.fortytwo, 'warned')); +} + +// But _maxListeners still has precedence over defaultMaxListeners +{ + events.EventEmitter.defaultMaxListeners = 42; + const e = new events.EventEmitter(); + e.setMaxListeners(1); + e.on('uno', common.mustNotCall()); + assert.ok(!Object.hasOwn(e._events.uno, 'warned')); + e.on('uno', common.mustNotCall()); + assert.ok(Object.hasOwn(e._events.uno, 'warned')); + + // chainable + assert.strictEqual(e, e.setMaxListeners(1)); +} diff --git a/tests/node_compat/test/parallel/test-event-emitter-max-listeners-warning-for-null.js b/tests/node_compat/test/parallel/test-event-emitter-max-listeners-warning-for-null.js new file mode 100644 index 0000000000..1e3435ef39 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-max-listeners-warning-for-null.js @@ -0,0 +1,30 @@ +// 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: --no-warnings +// The flag suppresses stderr output but the warning event will still emit +'use strict'; + +const common = require('../common'); +const events = require('events'); +const assert = require('assert'); + +const e = new events.EventEmitter(); +e.setMaxListeners(1); + +process.on('warning', common.mustCall((warning) => { + assert.ok(warning instanceof Error); + assert.strictEqual(warning.name, 'MaxListenersExceededWarning'); + assert.strictEqual(warning.emitter, e); + assert.strictEqual(warning.count, 2); + assert.strictEqual(warning.type, null); + assert.ok(warning.message.includes( + '2 null listeners added to [EventEmitter].')); +})); + +e.on(null, () => {}); +e.on(null, () => {}); diff --git a/tests/node_compat/test/parallel/test-event-emitter-max-listeners-warning-for-symbol.js b/tests/node_compat/test/parallel/test-event-emitter-max-listeners-warning-for-symbol.js new file mode 100644 index 0000000000..113fba229c --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-max-listeners-warning-for-symbol.js @@ -0,0 +1,32 @@ +// 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: --no-warnings +// The flag suppresses stderr output but the warning event will still emit +'use strict'; + +const common = require('../common'); +const events = require('events'); +const assert = require('assert'); + +const symbol = Symbol('symbol'); + +const e = new events.EventEmitter(); +e.setMaxListeners(1); + +process.on('warning', common.mustCall((warning) => { + assert.ok(warning instanceof Error); + assert.strictEqual(warning.name, 'MaxListenersExceededWarning'); + assert.strictEqual(warning.emitter, e); + assert.strictEqual(warning.count, 2); + assert.strictEqual(warning.type, symbol); + assert.ok(warning.message.includes( + '2 Symbol(symbol) listeners added to [EventEmitter].')); +})); + +e.on(symbol, () => {}); +e.on(symbol, () => {}); diff --git a/tests/node_compat/test/parallel/test-event-emitter-max-listeners-warning.js b/tests/node_compat/test/parallel/test-event-emitter-max-listeners-warning.js new file mode 100644 index 0000000000..69977a9679 --- /dev/null +++ b/tests/node_compat/test/parallel/test-event-emitter-max-listeners-warning.js @@ -0,0 +1,38 @@ +// 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: --no-warnings +// The flag suppresses stderr output but the warning event will still emit +'use strict'; + +const common = require('../common'); +const events = require('events'); +const assert = require('assert'); + +class FakeInput extends events.EventEmitter { + resume() {} + pause() {} + write() {} + end() {} +} + +const e = new FakeInput(); +e.setMaxListeners(1); + +process.on('warning', common.mustCall((warning) => { + assert.ok(warning instanceof Error); + assert.strictEqual(warning.name, 'MaxListenersExceededWarning'); + assert.strictEqual(warning.emitter, e); + assert.strictEqual(warning.count, 2); + assert.strictEqual(warning.type, 'event-type'); + assert.ok(warning.message.includes( + '2 event-type listeners added to [FakeInput].')); +})); + +e.on('event-type', () => {}); +e.on('event-type', () => {}); // Trigger warning. +e.on('event-type', () => {}); // Verify that warning is emitted only once. diff --git a/tests/node_compat/test/parallel/test-eventtarget-once-twice.js b/tests/node_compat/test/parallel/test-eventtarget-once-twice.js new file mode 100644 index 0000000000..82877c7987 --- /dev/null +++ b/tests/node_compat/test/parallel/test-eventtarget-once-twice.js @@ -0,0 +1,21 @@ +// 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. + +'use strict'; +const common = require('../common'); +const { once } = require('events'); + +const et = new EventTarget(); +(async function() { + await once(et, 'foo'); + await once(et, 'foo'); +})().then(common.mustCall()); + +et.dispatchEvent(new Event('foo')); +setImmediate(() => { + et.dispatchEvent(new Event('foo')); +}); diff --git a/tests/node_compat/test/parallel/test-fs-buffertype-writesync.js b/tests/node_compat/test/parallel/test-fs-buffertype-writesync.js new file mode 100644 index 0000000000..f2e8c97ee7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-buffertype-writesync.js @@ -0,0 +1,23 @@ +// 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. + +'use strict'; +require('../common'); + +// This test ensures that writeSync throws for invalid data input. + +const assert = require('assert'); +const fs = require('fs'); + +[ + true, false, 0, 1, Infinity, () => {}, {}, [], undefined, null, +].forEach((value) => { + assert.throws( + () => fs.writeSync(1, value), + { message: /"buffer"/, code: 'ERR_INVALID_ARG_TYPE' } + ); +}); diff --git a/tests/node_compat/test/parallel/test-fs-close.js b/tests/node_compat/test/parallel/test-fs-close.js new file mode 100644 index 0000000000..1efb90ecd3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-close.js @@ -0,0 +1,19 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +const assert = require('assert'); +const fs = require('fs'); + +const fd = fs.openSync(__filename, 'r'); + +fs.close(fd, common.mustCall(function(...args) { + assert.deepStrictEqual(args, [null]); +})); diff --git a/tests/node_compat/test/parallel/test-fs-constants.js b/tests/node_compat/test/parallel/test-fs-constants.js new file mode 100644 index 0000000000..f6599ae859 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-constants.js @@ -0,0 +1,15 @@ +// 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. + +'use strict'; +require('../common'); +const fs = require('fs'); +const assert = require('assert'); + +// Check if the two constants accepted by chmod() on Windows are defined. +assert.notStrictEqual(fs.constants.S_IRUSR, undefined); +assert.notStrictEqual(fs.constants.S_IWUSR, undefined); diff --git a/tests/node_compat/test/parallel/test-fs-fmap.js b/tests/node_compat/test/parallel/test-fs-fmap.js new file mode 100644 index 0000000000..728cdc8c54 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-fmap.js @@ -0,0 +1,35 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const fs = require('fs'); + +const { + O_CREAT = 0, + O_RDONLY = 0, + O_TRUNC = 0, + O_WRONLY = 0, + UV_FS_O_FILEMAP = 0 +} = fs.constants; + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +// Run this test on all platforms. While UV_FS_O_FILEMAP is only available on +// Windows, it should be silently ignored on other platforms. + +const filename = tmpdir.resolve('fmap.txt'); +const text = 'Memory File Mapping Test'; + +const mw = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY; +const mr = UV_FS_O_FILEMAP | O_RDONLY; + +fs.writeFileSync(filename, text, { flag: mw }); +const r1 = fs.readFileSync(filename, { encoding: 'utf8', flag: mr }); +assert.strictEqual(r1, text); diff --git a/tests/node_compat/test/parallel/test-fs-long-path.js b/tests/node_compat/test/parallel/test-fs-long-path.js new file mode 100644 index 0000000000..9b818cb75b --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-long-path.js @@ -0,0 +1,56 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.isWindows) + common.skip('this test is Windows-specific.'); + +const fs = require('fs'); +const path = require('path'); + +const tmpdir = require('../common/tmpdir'); + +// Make a path that will be at least 260 chars long. +const fileNameLen = Math.max(260 - tmpdir.path.length - 1, 1); +const fileName = tmpdir.resolve('x'.repeat(fileNameLen)); +const fullPath = path.resolve(fileName); + +tmpdir.refresh(); + +console.log({ + filenameLength: fileName.length, + fullPathLength: fullPath.length +}); + +fs.writeFile(fullPath, 'ok', common.mustSucceed(() => { + fs.stat(fullPath, common.mustSucceed()); + + // Tests https://github.com/nodejs/node/issues/39721 + fs.realpath.native(fullPath, common.mustSucceed()); +})); diff --git a/tests/node_compat/test/parallel/test-fs-non-number-arguments-throw.js b/tests/node_compat/test/parallel/test-fs-non-number-arguments-throw.js new file mode 100644 index 0000000000..404ef6c298 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-non-number-arguments-throw.js @@ -0,0 +1,54 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const tmpdir = require('../common/tmpdir'); +const tempFile = tmpdir.resolve('fs-non-number-arguments-throw'); + +tmpdir.refresh(); +fs.writeFileSync(tempFile, 'abc\ndef'); + +// A sanity check when using numbers instead of strings +const sanity = 'def'; +const saneEmitter = fs.createReadStream(tempFile, { start: 4, end: 6 }); + +assert.throws( + () => { + fs.createReadStream(tempFile, { start: '4', end: 6 }); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + +assert.throws( + () => { + fs.createReadStream(tempFile, { start: 4, end: '6' }); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + +assert.throws( + () => { + fs.createWriteStream(tempFile, { start: '4' }); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + +saneEmitter.on('data', common.mustCall(function(data) { + assert.strictEqual( + sanity, data.toString('utf8'), + `read ${data.toString('utf8')} instead of ${sanity}`); +})); diff --git a/tests/node_compat/test/parallel/test-fs-promises-exists.js b/tests/node_compat/test/parallel/test-fs-promises-exists.js new file mode 100644 index 0000000000..1455047175 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-promises-exists.js @@ -0,0 +1,16 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const fsPromises = require('fs/promises'); + +assert.strictEqual(fsPromises, fs.promises); +assert.strictEqual(fsPromises.constants, fs.constants); diff --git a/tests/node_compat/test/parallel/test-fs-promises-file-handle-write.js b/tests/node_compat/test/parallel/test-fs-promises-file-handle-write.js new file mode 100644 index 0000000000..994ce4ee6d --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-promises-file-handle-write.js @@ -0,0 +1,84 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +// The following tests validate base functionality for the fs.promises +// FileHandle.write method. + +const fs = require('fs'); +const { open } = fs.promises; +const path = require('path'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const tmpDir = tmpdir.path; + +tmpdir.refresh(); + +async function validateWrite() { + const filePathForHandle = path.resolve(tmpDir, 'tmp-write.txt'); + const fileHandle = await open(filePathForHandle, 'w+'); + const buffer = Buffer.from('Hello world'.repeat(100), 'utf8'); + + await fileHandle.write(buffer, 0, buffer.length); + const readFileData = fs.readFileSync(filePathForHandle); + assert.deepStrictEqual(buffer, readFileData); + + await fileHandle.close(); +} + +async function validateEmptyWrite() { + const filePathForHandle = path.resolve(tmpDir, 'tmp-empty-write.txt'); + const fileHandle = await open(filePathForHandle, 'w+'); + const buffer = Buffer.from(''); // empty buffer + + await fileHandle.write(buffer, 0, buffer.length); + const readFileData = fs.readFileSync(filePathForHandle); + assert.deepStrictEqual(buffer, readFileData); + + await fileHandle.close(); +} + +async function validateNonUint8ArrayWrite() { + const filePathForHandle = path.resolve(tmpDir, 'tmp-data-write.txt'); + const fileHandle = await open(filePathForHandle, 'w+'); + const buffer = Buffer.from('Hello world', 'utf8').toString('base64'); + + await fileHandle.write(buffer, 0, buffer.length); + const readFileData = fs.readFileSync(filePathForHandle); + assert.deepStrictEqual(Buffer.from(buffer, 'utf8'), readFileData); + + await fileHandle.close(); +} + +async function validateNonStringValuesWrite() { + const filePathForHandle = path.resolve(tmpDir, 'tmp-non-string-write.txt'); + const fileHandle = await open(filePathForHandle, 'w+'); + const nonStringValues = [ + 123, {}, new Map(), null, undefined, 0n, () => {}, Symbol(), true, + new String('notPrimitive'), + { toString() { return 'amObject'; } }, + { [Symbol.toPrimitive]: (hint) => 'amObject' }, + ]; + for (const nonStringValue of nonStringValues) { + await assert.rejects( + fileHandle.write(nonStringValue), + { message: /"buffer"/, code: 'ERR_INVALID_ARG_TYPE' } + ); + } + + await fileHandle.close(); +} + +Promise.all([ + validateWrite(), + validateEmptyWrite(), + validateNonUint8ArrayWrite(), + validateNonStringValuesWrite(), +]).then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-fs-promises-readfile-empty.js b/tests/node_compat/test/parallel/test-fs-promises-readfile-empty.js new file mode 100644 index 0000000000..3a72b0c6e6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-promises-readfile-empty.js @@ -0,0 +1,24 @@ +// 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. + +'use strict'; +require('../common'); + +const assert = require('assert'); +const { promises: fs } = require('fs'); +const fixtures = require('../common/fixtures'); + +const fn = fixtures.path('empty.txt'); + +fs.readFile(fn) + .then(assert.ok); + +fs.readFile(fn, 'utf8') + .then(assert.strictEqual.bind(this, '')); + +fs.readFile(fn, { encoding: 'utf8' }) + .then(assert.strictEqual.bind(this, '')); diff --git a/tests/node_compat/test/parallel/test-fs-promises-readfile-with-fd.js b/tests/node_compat/test/parallel/test-fs-promises-readfile-with-fd.js new file mode 100644 index 0000000000..f5a0199d93 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-promises-readfile-with-fd.js @@ -0,0 +1,41 @@ +// 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. + +'use strict'; + +// This test makes sure that `readFile()` always reads from the current +// position of the file, instead of reading from the beginning of the file. + +const common = require('../common'); +const assert = require('assert'); +const { writeFileSync } = require('fs'); +const { open } = require('fs').promises; + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const fn = tmpdir.resolve('test.txt'); +writeFileSync(fn, 'Hello World'); + +async function readFileTest() { + const handle = await open(fn, 'r'); + + /* Read only five bytes, so that the position moves to five. */ + const buf = Buffer.alloc(5); + const { bytesRead } = await handle.read(buf, 0, 5, null); + assert.strictEqual(bytesRead, 5); + assert.strictEqual(buf.toString(), 'Hello'); + + /* readFile() should read from position five, instead of zero. */ + assert.strictEqual((await handle.readFile()).toString(), ' World'); + + await handle.close(); +} + + +readFileTest() + .then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-fs-read-file-sync-hostname.js b/tests/node_compat/test/parallel/test-fs-read-file-sync-hostname.js new file mode 100644 index 0000000000..104f1c2b92 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-file-sync-hostname.js @@ -0,0 +1,40 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.isLinux) + common.skip('Test is linux specific.'); + +const assert = require('assert'); +const fs = require('fs'); + +// Test to make sure reading a file under the /proc directory works. See: +// https://groups.google.com/forum/#!topic/nodejs-dev/rxZ_RoH1Gn0 +const hostname = fs.readFileSync('/proc/sys/kernel/hostname'); +assert.ok(hostname.length > 0); diff --git a/tests/node_compat/test/parallel/test-fs-read-file-sync.js b/tests/node_compat/test/parallel/test-fs-read-file-sync.js new file mode 100644 index 0000000000..ae50907fd8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-file-sync.js @@ -0,0 +1,41 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const fixtures = require('../common/fixtures'); + +const fn = fixtures.path('elipses.txt'); + +const s = fs.readFileSync(fn, 'utf8'); +for (let i = 0; i < s.length; i++) { + assert.strictEqual(s[i], '\u2026'); +} +assert.strictEqual(s.length, 10000); diff --git a/tests/node_compat/test/parallel/test-fs-read-stream-fd-leak.js b/tests/node_compat/test/parallel/test-fs-read-stream-fd-leak.js new file mode 100644 index 0000000000..88025721ca --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-stream-fd-leak.js @@ -0,0 +1,69 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const fixtures = require('../common/fixtures'); + +let openCount = 0; +const _fsopen = fs.open; +const _fsclose = fs.close; + +const loopCount = 50; +const totalCheck = 50; +const emptyTxt = fixtures.path('empty.txt'); + +fs.open = function() { + openCount++; + return _fsopen.apply(null, arguments); +}; + +fs.close = function() { + openCount--; + return _fsclose.apply(null, arguments); +}; + +function testLeak(endFn, callback) { + console.log(`testing for leaks from fs.createReadStream().${endFn}()...`); + + let i = 0; + let check = 0; + + function checkFunction() { + if (openCount !== 0 && check < totalCheck) { + check++; + setTimeout(checkFunction, 100); + return; + } + + assert.strictEqual( + openCount, + 0, + `no leaked file descriptors using ${endFn}() (got ${openCount})` + ); + + openCount = 0; + callback && setTimeout(callback, 100); + } + + setInterval(function() { + const s = fs.createReadStream(emptyTxt); + s[endFn](); + + if (++i === loopCount) { + clearTimeout(this); + setTimeout(checkFunction, 100); + } + }, 2); +} + +testLeak('close', function() { + testLeak('destroy'); +}); diff --git a/tests/node_compat/test/parallel/test-fs-read-stream-pos.js b/tests/node_compat/test/parallel/test-fs-read-stream-pos.js new file mode 100644 index 0000000000..58a79794e1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-read-stream-pos.js @@ -0,0 +1,89 @@ +// 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. + +'use strict'; + +// Refs: https://github.com/nodejs/node/issues/33940 + +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const fs = require('fs'); +const assert = require('assert'); + +tmpdir.refresh(); + +const file = tmpdir.resolve('read_stream_pos_test.txt'); + +fs.writeFileSync(file, ''); + +let counter = 0; + +const writeInterval = setInterval(() => { + counter = counter + 1; + const line = `hello at ${counter}\n`; + fs.writeFileSync(file, line, { flag: 'a' }); +}, 1); + +const hwm = 10; +let bufs = []; +let isLow = false; +let cur = 0; +let stream; + +const readInterval = setInterval(() => { + if (stream) return; + + stream = fs.createReadStream(file, { + highWaterMark: hwm, + start: cur + }); + stream.on('data', common.mustCallAtLeast((chunk) => { + cur += chunk.length; + bufs.push(chunk); + if (isLow) { + const brokenLines = Buffer.concat(bufs).toString() + .split('\n') + .filter((line) => { + const s = 'hello at'.slice(0, line.length); + if (line && !line.startsWith(s)) { + return true; + } + return false; + }); + assert.strictEqual(brokenLines.length, 0); + exitTest(); + return; + } + if (chunk.length !== hwm) { + isLow = true; + } + })); + stream.on('end', () => { + stream = null; + isLow = false; + bufs = []; + }); +}, 10); + +// Time longer than 90 seconds to exit safely +const endTimer = setTimeout(() => { + exitTest(); +}, 90000); + +const exitTest = () => { + clearInterval(readInterval); + clearInterval(writeInterval); + clearTimeout(endTimer); + if (stream && !stream.destroyed) { + stream.on('close', () => { + process.exit(); + }); + stream.destroy(); + } else { + process.exit(); + } +}; diff --git a/tests/node_compat/test/parallel/test-fs-readfile-unlink.js b/tests/node_compat/test/parallel/test-fs-readfile-unlink.js new file mode 100644 index 0000000000..e9e4b67b17 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-readfile-unlink.js @@ -0,0 +1,53 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +// Test that unlink succeeds immediately after readFile completes. + +const assert = require('assert'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); + +const fileName = tmpdir.resolve('test.bin'); +const buf = Buffer.alloc(512 * 1024, 42); + +tmpdir.refresh(); + +fs.writeFileSync(fileName, buf); + +fs.readFile(fileName, common.mustSucceed((data) => { + assert.strictEqual(data.length, buf.length); + assert.strictEqual(buf[0], 42); + + // Unlink should not throw. This is part of the test. It used to throw on + // Windows due to a bug. + fs.unlinkSync(fileName); +})); diff --git a/tests/node_compat/test/parallel/test-fs-readfile-zero-byte-liar.js b/tests/node_compat/test/parallel/test-fs-readfile-zero-byte-liar.js new file mode 100644 index 0000000000..e2481554c6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-readfile-zero-byte-liar.js @@ -0,0 +1,62 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +// Test that readFile works even when stat returns size 0. + +const assert = require('assert'); +const fs = require('fs'); + +const dataExpected = fs.readFileSync(__filename, 'utf8'); + +// Sometimes stat returns size=0, but it's a lie. +fs._fstat = fs.fstat; +fs._fstatSync = fs.fstatSync; + +fs.fstat = (fd, cb) => { + fs._fstat(fd, (er, st) => { + if (er) return cb(er); + st.size = 0; + return cb(er, st); + }); +}; + +fs.fstatSync = (fd) => { + const st = fs._fstatSync(fd); + st.size = 0; + return st; +}; + +const d = fs.readFileSync(__filename, 'utf8'); +assert.strictEqual(d, dataExpected); + +fs.readFile(__filename, 'utf8', common.mustCall((er, d) => { + assert.strictEqual(d, dataExpected); +})); diff --git a/tests/node_compat/test/parallel/test-fs-readfilesync-enoent.js b/tests/node_compat/test/parallel/test-fs-readfilesync-enoent.js new file mode 100644 index 0000000000..ba888cee5a --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-readfilesync-enoent.js @@ -0,0 +1,39 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// This test is only relevant on Windows. +if (!common.isWindows) + common.skip('Windows specific test.'); + +// This test ensures fs.realpathSync works on properly on Windows without +// throwing ENOENT when the path involves a fileserver. +// https://github.com/nodejs/node-v0.x-archive/issues/3542 + +const assert = require('assert'); +const fs = require('fs'); +const os = require('os'); +const path = require('path'); + +function test(p) { + const result = fs.realpathSync(p); + assert.strictEqual(result.toLowerCase(), path.resolve(p).toLowerCase()); + + fs.realpath(p, common.mustSucceed((result) => { + assert.strictEqual(result.toLowerCase(), path.resolve(p).toLowerCase()); + })); +} + +test(`//${os.hostname()}/c$/Windows/System32`); +test(`//${os.hostname()}/c$/Windows`); +test(`//${os.hostname()}/c$/`); +test(`\\\\${os.hostname()}\\c$\\`); +test('C:\\'); +test('C:'); +test(process.env.windir); diff --git a/tests/node_compat/test/parallel/test-fs-ready-event-stream.js b/tests/node_compat/test/parallel/test-fs-ready-event-stream.js new file mode 100644 index 0000000000..12f1b04443 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-ready-event-stream.js @@ -0,0 +1,27 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const tmpdir = require('../common/tmpdir'); + +const readStream = fs.createReadStream(__filename); +assert.strictEqual(readStream.pending, true); +readStream.on('ready', common.mustCall(() => { + assert.strictEqual(readStream.pending, false); +})); + +const writeFile = tmpdir.resolve('write-fsreadyevent.txt'); +tmpdir.refresh(); +const writeStream = fs.createWriteStream(writeFile, { autoClose: true }); +assert.strictEqual(writeStream.pending, true); +writeStream.on('ready', common.mustCall(() => { + assert.strictEqual(writeStream.pending, false); + writeStream.end(); +})); diff --git a/tests/node_compat/test/parallel/test-fs-sir-writes-alot.js b/tests/node_compat/test/parallel/test-fs-sir-writes-alot.js new file mode 100644 index 0000000000..4cf0fbe4e8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-sir-writes-alot.js @@ -0,0 +1,77 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const fs = require('fs'); +const assert = require('assert'); + +const tmpdir = require('../common/tmpdir'); + +const filename = tmpdir.resolve('out.txt'); + +tmpdir.refresh(); + +const fd = fs.openSync(filename, 'w'); + +const line = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n'; + +const N = 10240; +let complete = 0; + +for (let i = 0; i < N; i++) { + // Create a new buffer for each write. Before the write is actually + // executed by the thread pool, the buffer will be collected. + const buffer = Buffer.from(line); + fs.write(fd, buffer, 0, buffer.length, null, function(er, written) { + complete++; + if (complete === N) { + fs.closeSync(fd); + const s = fs.createReadStream(filename); + s.on('data', testBuffer); + } + }); +} + +let bytesChecked = 0; + +function testBuffer(b) { + for (let i = 0; i < b.length; i++) { + bytesChecked++; + if (b[i] !== 'a'.charCodeAt(0) && b[i] !== '\n'.charCodeAt(0)) { + throw new Error(`invalid char ${i},${b[i]}`); + } + } +} + +process.on('exit', function() { + // Probably some of the writes are going to overlap, so we can't assume + // that we get (N * line.length). Let's just make sure we've checked a + // few... + assert.ok(bytesChecked > 1000); +}); diff --git a/tests/node_compat/test/parallel/test-fs-stream-construct-compat-error-read.js b/tests/node_compat/test/parallel/test-fs-stream-construct-compat-error-read.js new file mode 100644 index 0000000000..210217ca17 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-stream-construct-compat-error-read.js @@ -0,0 +1,39 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const fs = require('fs'); +const assert = require('assert'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +{ + // Compat error. + + function ReadStream(...args) { + fs.ReadStream.call(this, ...args); + } + Object.setPrototypeOf(ReadStream.prototype, fs.ReadStream.prototype); + Object.setPrototypeOf(ReadStream, fs.ReadStream); + + ReadStream.prototype.open = common.mustCall(function ReadStream$open() { + const that = this; + fs.open(that.path, that.flags, that.mode, (err, fd) => { + that.emit('error', err); + }); + }); + + const r = new ReadStream('/doesnotexist', { emitClose: true }) + .on('error', common.mustCall((err) => { + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(r.destroyed, true); + r.on('close', common.mustCall()); + })); +} diff --git a/tests/node_compat/test/parallel/test-fs-stream-construct-compat-graceful-fs.js b/tests/node_compat/test/parallel/test-fs-stream-construct-compat-graceful-fs.js new file mode 100644 index 0000000000..7df6566f83 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-stream-construct-compat-graceful-fs.js @@ -0,0 +1,77 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const fs = require('fs'); +const assert = require('assert'); +const fixtures = require('../common/fixtures'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +{ + // Compat with graceful-fs. + + function ReadStream(...args) { + fs.ReadStream.call(this, ...args); + } + Object.setPrototypeOf(ReadStream.prototype, fs.ReadStream.prototype); + Object.setPrototypeOf(ReadStream, fs.ReadStream); + + ReadStream.prototype.open = common.mustCall(function ReadStream$open() { + const that = this; + fs.open(that.path, that.flags, that.mode, (err, fd) => { + if (err) { + if (that.autoClose) + that.destroy(); + + that.emit('error', err); + } else { + that.fd = fd; + that.emit('open', fd); + that.read(); + } + }); + }); + + const r = new ReadStream(fixtures.path('x.txt')) + .on('open', common.mustCall((fd) => { + assert.strictEqual(fd, r.fd); + r.destroy(); + })); +} + +{ + // Compat with graceful-fs. + + function WriteStream(...args) { + fs.WriteStream.call(this, ...args); + } + Object.setPrototypeOf(WriteStream.prototype, fs.WriteStream.prototype); + Object.setPrototypeOf(WriteStream, fs.WriteStream); + + WriteStream.prototype.open = common.mustCall(function WriteStream$open() { + const that = this; + fs.open(that.path, that.flags, that.mode, function(err, fd) { + if (err) { + that.destroy(); + that.emit('error', err); + } else { + that.fd = fd; + that.emit('open', fd); + } + }); + }); + + const w = new WriteStream(`${tmpdir.path}/dummy`) + .on('open', common.mustCall((fd) => { + assert.strictEqual(fd, w.fd); + w.destroy(); + })); +} diff --git a/tests/node_compat/test/parallel/test-fs-stream-construct-compat-old-node.js b/tests/node_compat/test/parallel/test-fs-stream-construct-compat-old-node.js new file mode 100644 index 0000000000..12ff3984b9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-stream-construct-compat-old-node.js @@ -0,0 +1,104 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const fs = require('fs'); +const assert = require('assert'); +const fixtures = require('../common/fixtures'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +{ + // Compat with old node. + + function ReadStream(...args) { + fs.ReadStream.call(this, ...args); + } + Object.setPrototypeOf(ReadStream.prototype, fs.ReadStream.prototype); + Object.setPrototypeOf(ReadStream, fs.ReadStream); + + ReadStream.prototype.open = common.mustCall(function() { + fs.open(this.path, this.flags, this.mode, (er, fd) => { + if (er) { + if (this.autoClose) { + this.destroy(); + } + this.emit('error', er); + return; + } + + this.fd = fd; + this.emit('open', fd); + this.emit('ready'); + }); + }); + + let readyCalled = false; + let ticked = false; + const r = new ReadStream(fixtures.path('x.txt')) + .on('ready', common.mustCall(() => { + readyCalled = true; + // Make sure 'ready' is emitted in same tick as 'open'. + assert.strictEqual(ticked, false); + })) + .on('error', common.mustNotCall()) + .on('open', common.mustCall((fd) => { + process.nextTick(() => { + ticked = true; + r.destroy(); + }); + assert.strictEqual(readyCalled, false); + assert.strictEqual(fd, r.fd); + })); +} + +{ + // Compat with old node. + + function WriteStream(...args) { + fs.WriteStream.call(this, ...args); + } + Object.setPrototypeOf(WriteStream.prototype, fs.WriteStream.prototype); + Object.setPrototypeOf(WriteStream, fs.WriteStream); + + WriteStream.prototype.open = common.mustCall(function() { + fs.open(this.path, this.flags, this.mode, (er, fd) => { + if (er) { + if (this.autoClose) { + this.destroy(); + } + this.emit('error', er); + return; + } + + this.fd = fd; + this.emit('open', fd); + this.emit('ready'); + }); + }); + + let readyCalled = false; + let ticked = false; + const w = new WriteStream(`${tmpdir.path}/dummy`) + .on('ready', common.mustCall(() => { + readyCalled = true; + // Make sure 'ready' is emitted in same tick as 'open'. + assert.strictEqual(ticked, false); + })) + .on('error', common.mustNotCall()) + .on('open', common.mustCall((fd) => { + process.nextTick(() => { + ticked = true; + w.destroy(); + }); + assert.strictEqual(readyCalled, false); + assert.strictEqual(fd, w.fd); + })); +} diff --git a/tests/node_compat/test/parallel/test-fs-stream-destroy-emit-error.js b/tests/node_compat/test/parallel/test-fs-stream-destroy-emit-error.js new file mode 100644 index 0000000000..1a3008895f --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-stream-destroy-emit-error.js @@ -0,0 +1,50 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +{ + const stream = fs.createReadStream(__filename); + stream.on('close', common.mustCall()); + test(stream); +} + +{ + const stream = fs.createWriteStream(`${tmpdir.path}/dummy`); + stream.on('close', common.mustCall()); + test(stream); +} + +{ + const stream = fs.createReadStream(__filename, { emitClose: true }); + stream.on('close', common.mustCall()); + test(stream); +} + +{ + const stream = fs.createWriteStream(`${tmpdir.path}/dummy2`, + { emitClose: true }); + stream.on('close', common.mustCall()); + test(stream); +} + + +function test(stream) { + const err = new Error('DESTROYED'); + stream.on('open', function() { + stream.destroy(err); + }); + stream.on('error', common.mustCall(function(err_) { + assert.strictEqual(err_, err); + })); +} diff --git a/tests/node_compat/test/parallel/test-fs-stream-double-close.js b/tests/node_compat/test/parallel/test-fs-stream-double-close.js new file mode 100644 index 0000000000..01894e2602 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-stream-double-close.js @@ -0,0 +1,61 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +test1(fs.createReadStream(__filename)); +test2(fs.createReadStream(__filename)); +test3(fs.createReadStream(__filename)); + +test1(fs.createWriteStream(`${tmpdir.path}/dummy1`)); +test2(fs.createWriteStream(`${tmpdir.path}/dummy2`)); +test3(fs.createWriteStream(`${tmpdir.path}/dummy3`)); + +function test1(stream) { + stream.destroy(); + stream.destroy(); +} + +function test2(stream) { + stream.destroy(); + stream.on('open', common.mustCall(function(fd) { + stream.destroy(); + })); +} + +function test3(stream) { + stream.on('open', common.mustCall(function(fd) { + stream.destroy(); + stream.destroy(); + })); +} diff --git a/tests/node_compat/test/parallel/test-fs-stream-fs-options.js b/tests/node_compat/test/parallel/test-fs-stream-fs-options.js new file mode 100644 index 0000000000..3740962b7a --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-stream-fs-options.js @@ -0,0 +1,79 @@ +// 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. + +'use strict'; + +require('../common'); +const fixtures = require('../common/fixtures'); +const fs = require('fs'); +const assert = require('assert'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const streamOpts = ['open', 'close']; +const writeStreamOptions = [...streamOpts, 'write']; +const readStreamOptions = [...streamOpts, 'read']; +const originalFs = { fs }; + +{ + const file = tmpdir.resolve('write-end-test0.txt'); + + writeStreamOptions.forEach((fn) => { + const overrideFs = Object.assign({}, originalFs.fs, { [fn]: null }); + if (fn === 'write') overrideFs.writev = null; + + const opts = { + fs: overrideFs + }; + assert.throws( + () => fs.createWriteStream(file, opts), { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: `The "options.fs.${fn}" property must be of type function. ` + + 'Received null' + }, + `createWriteStream options.fs.${fn} should throw if isn't a function` + ); + }); +} + +{ + const file = tmpdir.resolve('write-end-test0.txt'); + const overrideFs = Object.assign({}, originalFs.fs, { writev: 'not a fn' }); + const opts = { + fs: overrideFs + }; + assert.throws( + () => fs.createWriteStream(file, opts), { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "options.fs.writev" property must be of type function. ' + + 'Received type string (\'not a fn\')' + }, + 'createWriteStream options.fs.writev should throw if isn\'t a function' + ); +} + +{ + const file = fixtures.path('x.txt'); + readStreamOptions.forEach((fn) => { + const overrideFs = Object.assign({}, originalFs.fs, { [fn]: null }); + const opts = { + fs: overrideFs + }; + assert.throws( + () => fs.createReadStream(file, opts), { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: `The "options.fs.${fn}" property must be of type function. ` + + 'Received null' + }, + `createReadStream options.fs.${fn} should throw if isn't a function` + ); + }); +} diff --git a/tests/node_compat/test/parallel/test-fs-stream-options.js b/tests/node_compat/test/parallel/test-fs-stream-options.js new file mode 100644 index 0000000000..1733d19193 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-stream-options.js @@ -0,0 +1,56 @@ +// 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. + +'use strict'; +const { mustNotMutateObjectDeep } = require('../common'); + +const assert = require('assert'); +const fs = require('fs'); + +{ + const fd = 'k'; + + assert.throws( + () => { + fs.createReadStream(null, mustNotMutateObjectDeep({ fd })); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + }); + + assert.throws( + () => { + fs.createWriteStream(null, mustNotMutateObjectDeep({ fd })); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + }); +} + +{ + const path = 46; + + assert.throws( + () => { + fs.createReadStream(path); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + }); + + assert.throws( + () => { + fs.createWriteStream(path); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + }); +} diff --git a/tests/node_compat/test/parallel/test-fs-symlink-dir-junction-relative.js b/tests/node_compat/test/parallel/test-fs-symlink-dir-junction-relative.js new file mode 100644 index 0000000000..90487f51f5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-symlink-dir-junction-relative.js @@ -0,0 +1,65 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// Test creating and resolving relative junction or symbolic link + +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); + +const linkPath1 = tmpdir.resolve('junction1'); +const linkPath2 = tmpdir.resolve('junction2'); +const linkTarget = fixtures.fixturesDir; +const linkData = fixtures.fixturesDir; + +tmpdir.refresh(); + +// Test fs.symlink() +fs.symlink(linkData, linkPath1, 'junction', common.mustSucceed(() => { + verifyLink(linkPath1); +})); + +// Test fs.symlinkSync() +fs.symlinkSync(linkData, linkPath2, 'junction'); +verifyLink(linkPath2); + +function verifyLink(linkPath) { + const stats = fs.lstatSync(linkPath); + assert.ok(stats.isSymbolicLink()); + + const data1 = fs.readFileSync(`${linkPath}/x.txt`, 'ascii'); + const data2 = fs.readFileSync(`${linkTarget}/x.txt`, 'ascii'); + assert.strictEqual(data1, data2); + + // Clean up. + fs.unlinkSync(linkPath); +} diff --git a/tests/node_compat/test/parallel/test-fs-timestamp-parsing-error.js b/tests/node_compat/test/parallel/test-fs-timestamp-parsing-error.js new file mode 100644 index 0000000000..1319f998b9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-timestamp-parsing-error.js @@ -0,0 +1,36 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const fs = require('fs'); + +for (const input of [Infinity, -Infinity, NaN]) { + assert.throws( + () => { + fs._toUnixTimestamp(input); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); +} + +assert.throws( + () => { + fs._toUnixTimestamp({}); + }, + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + +const okInputs = [1, -1, '1', '-1', Date.now()]; +for (const input of okInputs) { + fs._toUnixTimestamp(input); +} diff --git a/tests/node_compat/test/parallel/test-fs-truncate-clear-file-zero.js b/tests/node_compat/test/parallel/test-fs-truncate-clear-file-zero.js new file mode 100644 index 0000000000..0dc50ef563 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-truncate-clear-file-zero.js @@ -0,0 +1,63 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); + +// This test ensures that `fs.truncate` opens the file with `r+` and not `w`, +// which had earlier resulted in the target file's content getting zeroed out. +// https://github.com/nodejs/node-v0.x-archive/issues/6233 + +const assert = require('assert'); +const fs = require('fs'); + +const filename = `${tmpdir.path}/truncate-file.txt`; + +tmpdir.refresh(); + +// Synchronous test. +{ + fs.writeFileSync(filename, '0123456789'); + assert.strictEqual(fs.readFileSync(filename).toString(), '0123456789'); + fs.truncateSync(filename, 5); + assert.strictEqual(fs.readFileSync(filename).toString(), '01234'); +} + +// Asynchronous test. +{ + fs.writeFileSync(filename, '0123456789'); + assert.strictEqual(fs.readFileSync(filename).toString(), '0123456789'); + fs.truncate( + filename, + 5, + common.mustSucceed(() => { + assert.strictEqual(fs.readFileSync(filename).toString(), '01234'); + }) + ); +} diff --git a/tests/node_compat/test/parallel/test-fs-util-validateoffsetlength.js b/tests/node_compat/test/parallel/test-fs-util-validateoffsetlength.js new file mode 100644 index 0000000000..7186df4071 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-util-validateoffsetlength.js @@ -0,0 +1,94 @@ +// 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'); + +const assert = require('assert'); +const { + validateOffsetLengthRead, + validateOffsetLengthWrite, +} = require('internal/fs/utils'); + +{ + const offset = -1; + assert.throws( + () => validateOffsetLengthRead(offset, 0, 0), + common.expectsError({ + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be >= 0. Received ${offset}` + }) + ); +} + +{ + const length = -1; + assert.throws( + () => validateOffsetLengthRead(0, length, 0), + common.expectsError({ + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "length" is out of range. ' + + `It must be >= 0. Received ${length}` + }) + ); +} + +{ + const offset = 1; + const length = 1; + const byteLength = offset + length - 1; + assert.throws( + () => validateOffsetLengthRead(offset, length, byteLength), + common.expectsError({ + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "length" is out of range. ' + + `It must be <= ${byteLength - offset}. Received ${length}` + }) + ); +} + +// Most platforms don't allow reads or writes >= 2 GiB. +// See https://github.com/libuv/libuv/pull/1501. +const kIoMaxLength = 2 ** 31 - 1; + +// RangeError when offset > byteLength +{ + const offset = 100; + const length = 100; + const byteLength = 50; + assert.throws( + () => validateOffsetLengthWrite(offset, length, byteLength), + common.expectsError({ + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "offset" is out of range. ' + + `It must be <= ${byteLength}. Received ${offset}` + }) + ); +} + +// RangeError when byteLength < kIoMaxLength, and length > byteLength - offset. +{ + const offset = kIoMaxLength - 150; + const length = 200; + const byteLength = kIoMaxLength - 100; + assert.throws( + () => validateOffsetLengthWrite(offset, length, byteLength), + common.expectsError({ + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + message: 'The value of "length" is out of range. ' + + `It must be <= ${byteLength - offset}. Received ${length}` + }) + ); +} diff --git a/tests/node_compat/test/parallel/test-fs-utimes-y2K38.js b/tests/node_compat/test/parallel/test-fs-utimes-y2K38.js new file mode 100644 index 0000000000..381b46b1fb --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-utimes-y2K38.js @@ -0,0 +1,73 @@ +// 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. + +'use strict'; +const common = require('../common'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const assert = require('assert'); +const fs = require('fs'); + +// Check for Y2K38 support. For Windows, assume it's there. Windows +// doesn't have `touch` and `date -r` which are used in the check for support. +if (!common.isWindows) { + const testFilePath = `${tmpdir.path}/y2k38-test`; + const testFileDate = '204001020304'; + const { spawnSync } = require('child_process'); + const touchResult = spawnSync('touch', + ['-t', testFileDate, testFilePath], + { encoding: 'utf8' }); + if (touchResult.status !== 0) { + common.skip('File system appears to lack Y2K38 support (touch failed)'); + } + + // On some file systems that lack Y2K38 support, `touch` will succeed but + // the time will be incorrect. + const dateResult = spawnSync('date', + ['-r', testFilePath, '+%Y%m%d%H%M'], + { encoding: 'utf8' }); + if (dateResult.status === 0) { + if (dateResult.stdout.trim() !== testFileDate) { + common.skip('File system appears to lack Y2k38 support (date failed)'); + } + } else { + // On some platforms `date` may not support the `-r` option. Usually + // this will result in a non-zero status and usage information printed. + // In this case optimistically proceed -- the earlier `touch` succeeded + // but validation that the file has the correct time is not easily possible. + assert.match(dateResult.stderr, /[Uu]sage:/); + } +} + +// Ref: https://github.com/nodejs/node/issues/13255 +const path = `${tmpdir.path}/test-utimes-precision`; +fs.writeFileSync(path, ''); + +const Y2K38_mtime = 2 ** 31; +fs.utimesSync(path, Y2K38_mtime, Y2K38_mtime); +const Y2K38_stats = fs.statSync(path); +assert.strictEqual(Y2K38_stats.mtime.getTime() / 1000, Y2K38_mtime); + +if (common.isWindows) { + // This value would get converted to (double)1713037251359.9998 + const truncate_mtime = 1713037251360; + fs.utimesSync(path, truncate_mtime / 1000, truncate_mtime / 1000); + const truncate_stats = fs.statSync(path); + assert.strictEqual(truncate_stats.mtime.getTime(), truncate_mtime); + + // test Y2K38 for windows + // This value if treaded as a `signed long` gets converted to -2135622133469. + // POSIX systems stores timestamps in {long t_sec, long t_usec}. + // NTFS stores times in nanoseconds in a single `uint64_t`, so when libuv + // calculates (long)`uv_timespec_t.tv_sec` we get 2's complement. + const overflow_mtime = 2159345162531; + fs.utimesSync(path, overflow_mtime / 1000, overflow_mtime / 1000); + const overflow_stats = fs.statSync(path); + assert.strictEqual(overflow_stats.mtime.getTime(), overflow_mtime); +} diff --git a/tests/node_compat/test/parallel/test-fs-watch-file-enoent-after-deletion.js b/tests/node_compat/test/parallel/test-fs-watch-file-enoent-after-deletion.js new file mode 100644 index 0000000000..5b4c892d00 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-watch-file-enoent-after-deletion.js @@ -0,0 +1,54 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +// Make sure the deletion event gets reported in the following scenario: +// 1. Watch a file. +// 2. The initial stat() goes okay. +// 3. Something deletes the watched file. +// 4. The second stat() fails with ENOENT. + +// The second stat() translates into the first 'change' event but a logic error +// stopped it from getting emitted. +// https://github.com/nodejs/node-v0.x-archive/issues/4027 + +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const filename = tmpdir.resolve('watched'); +fs.writeFileSync(filename, 'quis custodiet ipsos custodes'); + +fs.watchFile(filename, { interval: 50 }, common.mustCall(function(curr, prev) { + fs.unwatchFile(filename); +})); + +fs.unlinkSync(filename); diff --git a/tests/node_compat/test/parallel/test-fs-watch-recursive-add-file-with-url.js b/tests/node_compat/test/parallel/test-fs-watch-recursive-add-file-with-url.js new file mode 100644 index 0000000000..eb79cc85a9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-watch-recursive-add-file-with-url.js @@ -0,0 +1,59 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { setTimeout } = require('timers/promises'); + +if (common.isIBMi) + common.skip('IBMi does not support `fs.watch()`'); + +// fs-watch on folders have limited capability in AIX. +// The testcase makes use of folder watching, and causes +// hang. This behavior is documented. Skip this for AIX. + +if (common.isAIX) + common.skip('folder watch capability is limited in AIX.'); + +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); +const { pathToFileURL } = require('url'); + +const tmpdir = require('../common/tmpdir'); +const testDir = tmpdir.path; +tmpdir.refresh(); + +(async () => { + // Add a file to already watching folder, and use URL as the path + + const rootDirectory = fs.mkdtempSync(testDir + path.sep); + const testDirectory = path.join(rootDirectory, 'test-5'); + fs.mkdirSync(testDirectory); + + const filePath = path.join(testDirectory, 'file-8.txt'); + const url = pathToFileURL(testDirectory); + + const watcher = fs.watch(url, { recursive: true }); + let watcherClosed = false; + watcher.on('change', function(event, filename) { + assert.strictEqual(event, 'rename'); + + if (filename === path.basename(filePath)) { + watcher.close(); + watcherClosed = true; + } + }); + + await setTimeout(common.platformTimeout(100)); + fs.writeFileSync(filePath, 'world'); + + process.on('exit', function() { + assert(watcherClosed, 'watcher Object was not closed'); + }); +})().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-fs-watch-recursive-add-file.js b/tests/node_compat/test/parallel/test-fs-watch-recursive-add-file.js new file mode 100644 index 0000000000..d572026da5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-watch-recursive-add-file.js @@ -0,0 +1,57 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { setTimeout } = require('timers/promises'); + +if (common.isIBMi) + common.skip('IBMi does not support `fs.watch()`'); + +// fs-watch on folders have limited capability in AIX. +// The testcase makes use of folder watching, and causes +// hang. This behavior is documented. Skip this for AIX. + +if (common.isAIX) + common.skip('folder watch capability is limited in AIX.'); + +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +const testDir = tmpdir.path; +tmpdir.refresh(); + +(async () => { + // Add a file to already watching folder + + const rootDirectory = fs.mkdtempSync(testDir + path.sep); + const testDirectory = path.join(rootDirectory, 'test-1'); + fs.mkdirSync(testDirectory); + + const testFile = path.join(testDirectory, 'file-1.txt'); + + const watcher = fs.watch(testDirectory, { recursive: true }); + let watcherClosed = false; + watcher.on('change', function(event, filename) { + assert.strictEqual(event, 'rename'); + + if (filename === path.basename(testFile)) { + watcher.close(); + watcherClosed = true; + } + }); + + await setTimeout(common.platformTimeout(100)); + fs.writeFileSync(testFile, 'world'); + + process.once('exit', function() { + assert(watcherClosed, 'watcher Object was not closed'); + }); +})().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-fs-watch-recursive-add-folder.js b/tests/node_compat/test/parallel/test-fs-watch-recursive-add-folder.js new file mode 100644 index 0000000000..46345443c5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-watch-recursive-add-folder.js @@ -0,0 +1,57 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { setTimeout } = require('timers/promises'); + +if (common.isIBMi) + common.skip('IBMi does not support `fs.watch()`'); + +// fs-watch on folders have limited capability in AIX. +// The testcase makes use of folder watching, and causes +// hang. This behavior is documented. Skip this for AIX. + +if (common.isAIX) + common.skip('folder watch capability is limited in AIX.'); + +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +const testDir = tmpdir.path; +tmpdir.refresh(); + +(async () => { + // Add a folder to already watching folder + + const rootDirectory = fs.mkdtempSync(testDir + path.sep); + const testDirectory = path.join(rootDirectory, 'test-2'); + fs.mkdirSync(testDirectory); + + const testFile = path.join(testDirectory, 'folder-2'); + + const watcher = fs.watch(testDirectory, { recursive: true }); + let watcherClosed = false; + watcher.on('change', function(event, filename) { + assert.strictEqual(event, 'rename'); + + if (filename === path.basename(testFile)) { + watcher.close(); + watcherClosed = true; + } + }); + + await setTimeout(common.platformTimeout(100)); + fs.mkdirSync(testFile); + + process.once('exit', function() { + assert(watcherClosed, 'watcher Object was not closed'); + }); +})().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-fs-watch-recursive-update-file.js b/tests/node_compat/test/parallel/test-fs-watch-recursive-update-file.js new file mode 100644 index 0000000000..185db0d645 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-watch-recursive-update-file.js @@ -0,0 +1,59 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { setTimeout } = require('timers/promises'); + +if (common.isIBMi) + common.skip('IBMi does not support `fs.watch()`'); + +// fs-watch on folders have limited capability in AIX. +// The testcase makes use of folder watching, and causes +// hang. This behavior is documented. Skip this for AIX. + +if (common.isAIX) + common.skip('folder watch capability is limited in AIX.'); + +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +const testDir = tmpdir.path; +tmpdir.refresh(); + +(async () => { + // Watch a folder and update an already existing file in it. + + const rootDirectory = fs.mkdtempSync(testDir + path.sep); + const testDirectory = path.join(rootDirectory, 'test-0'); + fs.mkdirSync(testDirectory); + + const testFile = path.join(testDirectory, 'file-1.txt'); + fs.writeFileSync(testFile, 'hello'); + + const watcher = fs.watch(testDirectory, { recursive: true }); + let watcherClosed = false; + watcher.on('change', common.mustCallAtLeast(function(event, filename) { + // Libuv inconsistenly emits a rename event for the file we are watching + assert.ok(event === 'change' || event === 'rename'); + + if (filename === path.basename(testFile)) { + watcher.close(); + watcherClosed = true; + } + })); + + await setTimeout(common.platformTimeout(100)); + fs.writeFileSync(testFile, 'hello'); + + process.once('exit', function() { + assert(watcherClosed, 'watcher Object was not closed'); + }); +})().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-fs-write-negativeoffset.js b/tests/node_compat/test/parallel/test-fs-write-negativeoffset.js new file mode 100644 index 0000000000..101b6ecc3b --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-negativeoffset.js @@ -0,0 +1,58 @@ +// 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. + +'use strict'; + +// Tests that passing a negative offset does not crash the process + +const common = require('../common'); + +const { + closeSync, + open, + write, + writeSync, +} = require('fs'); + +const assert = require('assert'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const filename = tmpdir.resolve('test.txt'); + +open(filename, 'w+', common.mustSucceed((fd) => { + assert.throws(() => { + write(fd, Buffer.alloc(0), -1, common.mustNotCall()); + }, { + code: 'ERR_OUT_OF_RANGE', + }); + assert.throws(() => { + writeSync(fd, Buffer.alloc(0), -1); + }, { + code: 'ERR_OUT_OF_RANGE', + }); + closeSync(fd); +})); + +const filename2 = tmpdir.resolve('test2.txt'); + +// Make sure negative length's don't cause aborts either + +open(filename2, 'w+', common.mustSucceed((fd) => { + assert.throws(() => { + write(fd, Buffer.alloc(0), 0, -1, common.mustNotCall()); + }, { + code: 'ERR_OUT_OF_RANGE', + }); + assert.throws(() => { + writeSync(fd, Buffer.alloc(0), 0, -1); + }, { + code: 'ERR_OUT_OF_RANGE', + }); + closeSync(fd); +})); diff --git a/tests/node_compat/test/parallel/test-fs-write-stream-encoding.js b/tests/node_compat/test/parallel/test-fs-write-stream-encoding.js new file mode 100644 index 0000000000..85f63bd7e9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-stream-encoding.js @@ -0,0 +1,42 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const fixtures = require('../common/fixtures'); +const fs = require('fs'); +const stream = require('stream'); +const tmpdir = require('../common/tmpdir'); +const firstEncoding = 'base64'; +const secondEncoding = 'latin1'; + +const examplePath = fixtures.path('x.txt'); +const dummyPath = tmpdir.resolve('x.txt'); + +tmpdir.refresh(); + +const exampleReadStream = fs.createReadStream(examplePath, { + encoding: firstEncoding +}); + +const dummyWriteStream = fs.createWriteStream(dummyPath, { + encoding: firstEncoding +}); + +exampleReadStream.pipe(dummyWriteStream).on('finish', function() { + const assertWriteStream = new stream.Writable({ + write: function(chunk, enc, next) { + const expected = Buffer.from('xyz\n'); + assert(chunk.equals(expected)); + } + }); + assertWriteStream.setDefaultEncoding(secondEncoding); + fs.createReadStream(dummyPath, { + encoding: secondEncoding + }).pipe(assertWriteStream); +}); diff --git a/tests/node_compat/test/parallel/test-fs-write-stream-patch-open.js b/tests/node_compat/test/parallel/test-fs-write-stream-patch-open.js new file mode 100644 index 0000000000..8f9b15c59c --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-write-stream-patch-open.js @@ -0,0 +1,43 @@ +// 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. + +'use strict'; +const common = require('../common'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); + +// Run in a child process because 'out' is opened twice, blocking the tmpdir +// and preventing cleanup. +if (process.argv[2] !== 'child') { + // Parent + const assert = require('assert'); + const { fork } = require('child_process'); + tmpdir.refresh(); + + // Run test + const child = fork(__filename, ['child'], { stdio: 'inherit' }); + child.on('exit', common.mustCall(function(code) { + assert.strictEqual(code, 0); + })); + + return; +} + +// Child + +common.expectWarning( + 'DeprecationWarning', + 'WriteStream.prototype.open() is deprecated', 'DEP0135'); +const s = fs.createWriteStream(`${tmpdir.path}/out`); +s.open(); + +process.nextTick(() => { + // Allow overriding open(). + fs.WriteStream.prototype.open = common.mustCall(); + fs.createWriteStream('asd'); +}); diff --git a/tests/node_compat/test/parallel/test-fs-writev.js b/tests/node_compat/test/parallel/test-fs-writev.js new file mode 100644 index 0000000000..2212aa65f4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-fs-writev.js @@ -0,0 +1,113 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const tmpdir = require('../common/tmpdir'); + +tmpdir.refresh(); + +const expected = 'ümlaut. Лорем 運務ホソモ指及 आपको करने विकास 紙読決多密所 أضف'; + +const getFileName = (i) => tmpdir.resolve(`writev_${i}.txt`); + +/** + * Testing with a array of buffers input + */ + +// fs.writev with array of buffers with all parameters +{ + const filename = getFileName(1); + const fd = fs.openSync(filename, 'w'); + + const buffer = Buffer.from(expected); + const bufferArr = [buffer, buffer]; + + const done = common.mustSucceed((written, buffers) => { + assert.deepStrictEqual(bufferArr, buffers); + const expectedLength = bufferArr.length * buffer.byteLength; + assert.deepStrictEqual(written, expectedLength); + fs.closeSync(fd); + + assert(Buffer.concat(bufferArr).equals(fs.readFileSync(filename))); + }); + + fs.writev(fd, bufferArr, null, done); +} + +// fs.writev with array of buffers without position +{ + const filename = getFileName(2); + const fd = fs.openSync(filename, 'w'); + + const buffer = Buffer.from(expected); + const bufferArr = [buffer, buffer]; + + const done = common.mustSucceed((written, buffers) => { + assert.deepStrictEqual(bufferArr, buffers); + + const expectedLength = bufferArr.length * buffer.byteLength; + assert.deepStrictEqual(written, expectedLength); + fs.closeSync(fd); + + assert(Buffer.concat(bufferArr).equals(fs.readFileSync(filename))); + }); + + fs.writev(fd, bufferArr, done); +} + + +// fs.writev with empty array of buffers +{ + const filename = getFileName(3); + const fd = fs.openSync(filename, 'w'); + const bufferArr = []; + let afterSyncCall = false; + + const done = common.mustSucceed((written, buffers) => { + assert.strictEqual(buffers.length, 0); + assert.strictEqual(written, 0); + assert(afterSyncCall); + fs.closeSync(fd); + }); + + fs.writev(fd, bufferArr, done); + afterSyncCall = true; +} + +/** + * Testing with wrong input types + */ +{ + const filename = getFileName(4); + const fd = fs.openSync(filename, 'w'); + + [false, 'test', {}, [{}], ['sdf'], null, undefined].forEach((i) => { + assert.throws( + () => fs.writev(fd, i, null, common.mustNotCall()), { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); + }); + + fs.closeSync(fd); +} + +// fs.writev with wrong fd types +[false, 'test', {}, [{}], null, undefined].forEach((i) => { + assert.throws( + () => fs.writev(i, common.mustNotCall()), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + } + ); +}); diff --git a/tests/node_compat/test/parallel/test-global-domexception.js b/tests/node_compat/test/parallel/test-global-domexception.js new file mode 100644 index 0000000000..1b88a08916 --- /dev/null +++ b/tests/node_compat/test/parallel/test-global-domexception.js @@ -0,0 +1,18 @@ +// 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. + +'use strict'; + +require('../common'); + +const assert = require('assert'); + +assert.strictEqual(typeof DOMException, 'function'); + +assert.throws(() => { + atob('我要抛错!'); +}, DOMException); diff --git a/tests/node_compat/test/parallel/test-global-encoder.js b/tests/node_compat/test/parallel/test-global-encoder.js new file mode 100644 index 0000000000..4a2db0d2f3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-global-encoder.js @@ -0,0 +1,15 @@ +// 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. + +'use strict'; + +require('../common'); +const { strictEqual } = require('assert'); +const util = require('util'); + +strictEqual(TextDecoder, util.TextDecoder); +strictEqual(TextEncoder, util.TextEncoder); diff --git a/tests/node_compat/test/parallel/test-global-webcrypto.js b/tests/node_compat/test/parallel/test-global-webcrypto.js new file mode 100644 index 0000000000..b2074cf8bf --- /dev/null +++ b/tests/node_compat/test/parallel/test-global-webcrypto.js @@ -0,0 +1,20 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); + +/* eslint-disable no-restricted-syntax */ +assert.strictEqual(globalThis.crypto, crypto.webcrypto); +assert.strictEqual(Crypto, crypto.webcrypto.constructor); +assert.strictEqual(SubtleCrypto, crypto.webcrypto.subtle.constructor); diff --git a/tests/node_compat/test/parallel/test-global-webstreams.js b/tests/node_compat/test/parallel/test-global-webstreams.js new file mode 100644 index 0000000000..ae61fbe9fb --- /dev/null +++ b/tests/node_compat/test/parallel/test-global-webstreams.js @@ -0,0 +1,31 @@ +// 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. + +'use strict'; + +require('../common'); + +const assert = require('assert'); +const webstreams = require('stream/web'); + +assert.strictEqual(ReadableStream, webstreams.ReadableStream); +assert.strictEqual(ReadableStreamDefaultReader, webstreams.ReadableStreamDefaultReader); +assert.strictEqual(ReadableStreamBYOBReader, webstreams.ReadableStreamBYOBReader); +assert.strictEqual(ReadableStreamBYOBRequest, webstreams.ReadableStreamBYOBRequest); +assert.strictEqual(ReadableByteStreamController, webstreams.ReadableByteStreamController); +assert.strictEqual(ReadableStreamDefaultController, webstreams.ReadableStreamDefaultController); +assert.strictEqual(TransformStream, webstreams.TransformStream); +assert.strictEqual(TransformStreamDefaultController, webstreams.TransformStreamDefaultController); +assert.strictEqual(WritableStream, webstreams.WritableStream); +assert.strictEqual(WritableStreamDefaultWriter, webstreams.WritableStreamDefaultWriter); +assert.strictEqual(WritableStreamDefaultController, webstreams.WritableStreamDefaultController); +assert.strictEqual(ByteLengthQueuingStrategy, webstreams.ByteLengthQueuingStrategy); +assert.strictEqual(CountQueuingStrategy, webstreams.CountQueuingStrategy); +assert.strictEqual(TextEncoderStream, webstreams.TextEncoderStream); +assert.strictEqual(TextDecoderStream, webstreams.TextDecoderStream); +assert.strictEqual(CompressionStream, webstreams.CompressionStream); +assert.strictEqual(DecompressionStream, webstreams.DecompressionStream); diff --git a/tests/node_compat/test/parallel/test-http-abort-before-end.js b/tests/node_compat/test/parallel/test-http-abort-before-end.js new file mode 100644 index 0000000000..f144dff65d --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-abort-before-end.js @@ -0,0 +1,50 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const http = require('http'); + +const server = http.createServer(common.mustNotCall()); + +server.listen(0, common.mustCall(() => { + const req = http.request({ + method: 'GET', + host: '127.0.0.1', + port: server.address().port + }); + + req.on('abort', common.mustCall(() => { + server.close(); + })); + + req.on('error', common.mustNotCall()); + + req.abort(); + req.end(); +})); diff --git a/tests/node_compat/test/parallel/test-http-addrequest-localaddress.js b/tests/node_compat/test/parallel/test-http-addrequest-localaddress.js new file mode 100644 index 0000000000..7f4cbc3f31 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-addrequest-localaddress.js @@ -0,0 +1,44 @@ +// 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. + +'use strict'; +require('../common'); + +// This test ensures that `addRequest`'s Legacy API accepts `localAddress` +// correctly instead of accepting `path`. +// https://github.com/nodejs/node/issues/5051 + +const assert = require('assert'); +const agent = require('http').globalAgent; + +// Small stub just so we can call addRequest directly +const req = { + getHeader: () => {} +}; + +agent.maxSockets = 0; + +// `localAddress` is used when naming requests / sockets while using the Legacy +// API. Port 8080 is hardcoded since this does not create a network connection. +agent.addRequest(req, 'localhost', 8080, '127.0.0.1'); +assert.strictEqual(Object.keys(agent.requests).length, 1); +assert.strictEqual( + Object.keys(agent.requests)[0], + 'localhost:8080:127.0.0.1'); + +// `path` is *not* used when naming requests / sockets. +// Port 8080 is hardcoded since this does not create a network connection +agent.addRequest(req, { + host: 'localhost', + port: 8080, + localAddress: '127.0.0.1', + path: '/foo' +}); +assert.strictEqual(Object.keys(agent.requests).length, 1); +assert.strictEqual( + Object.keys(agent.requests)[0], + 'localhost:8080:127.0.0.1'); diff --git a/tests/node_compat/test/parallel/test-http-agent-false.js b/tests/node_compat/test/parallel/test-http-agent-false.js new file mode 100644 index 0000000000..60dc16d9b0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-agent-false.js @@ -0,0 +1,53 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const http = require('http'); + +// Sending `agent: false` when `port: null` is also passed in (i.e. the result +// of a `url.parse()` call with the default port used, 80 or 443), should not +// result in an assertion error... +const opts = { + host: '127.0.0.1', + port: null, + path: '/', + method: 'GET', + agent: false +}; + +// We just want an "error" (no local HTTP server on port 80) or "response" +// to happen (user happens ot have HTTP server running on port 80). +// As long as the process doesn't crash from a C++ assertion then we're good. +const req = http.request(opts); + +// Will be called by either the response event or error event, not both +const oneResponse = common.mustCall(); +req.on('response', oneResponse); +req.on('error', oneResponse); +req.end(); diff --git a/tests/node_compat/test/parallel/test-http-agent-keepalive-delay.js b/tests/node_compat/test/parallel/test-http-agent-keepalive-delay.js new file mode 100644 index 0000000000..7cc6120d73 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-agent-keepalive-delay.js @@ -0,0 +1,43 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const { Agent } = require('_http_agent'); + +const agent = new Agent({ + keepAlive: true, + keepAliveMsecs: 1000, +}); + +const server = http.createServer(common.mustCall((req, res) => { + res.end('ok'); +})); + +server.listen(0, common.mustCall(() => { + const createConnection = agent.createConnection; + agent.createConnection = (options, ...args) => { + assert.strictEqual(options.keepAlive, true); + assert.strictEqual(options.keepAliveInitialDelay, agent.keepAliveMsecs); + return createConnection.call(agent, options, ...args); + }; + http.get({ + host: 'localhost', + port: server.address().port, + agent: agent, + path: '/' + }, common.mustCall((res) => { + // for emit end event + res.on('data', () => {}); + res.on('end', () => { + server.close(); + }); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-agent-maxtotalsockets.js b/tests/node_compat/test/parallel/test-http-agent-maxtotalsockets.js new file mode 100644 index 0000000000..ee7e2bb5d5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-agent-maxtotalsockets.js @@ -0,0 +1,118 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const Countdown = require('../common/countdown'); + +assert.throws(() => new http.Agent({ + maxTotalSockets: 'test', +}), { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "maxTotalSockets" argument must be of type number. ' + + "Received type string ('test')", +}); + +[-1, 0, NaN].forEach((item) => { + assert.throws(() => new http.Agent({ + maxTotalSockets: item, + }), { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError', + }); +}); + +assert.ok(new http.Agent({ + maxTotalSockets: Infinity, +})); + +function start(param = {}) { + const { maxTotalSockets, maxSockets } = param; + + const agent = new http.Agent({ + keepAlive: true, + keepAliveMsecs: 1000, + maxTotalSockets, + maxSockets, + maxFreeSockets: 3 + }); + + const server = http.createServer(common.mustCall((req, res) => { + res.end('hello world'); + }, 6)); + const server2 = http.createServer(common.mustCall((req, res) => { + res.end('hello world'); + }, 6)); + + server.keepAliveTimeout = 0; + server2.keepAliveTimeout = 0; + + const countdown = new Countdown(12, () => { + assert.strictEqual(getRequestCount(), 0); + agent.destroy(); + server.close(); + server2.close(); + }); + + function handler(s) { + for (let i = 0; i < 6; i++) { + http.get({ + host: 'localhost', + port: s.address().port, + agent, + path: `/${i}`, + }, common.mustCall((res) => { + assert.strictEqual(res.statusCode, 200); + res.resume(); + res.on('end', common.mustCall(() => { + for (const key of Object.keys(agent.sockets)) { + assert(agent.sockets[key].length <= maxSockets); + } + assert(getTotalSocketsCount() <= maxTotalSockets); + countdown.dec(); + })); + })); + } + } + + function getTotalSocketsCount() { + let num = 0; + for (const key of Object.keys(agent.sockets)) { + num += agent.sockets[key].length; + } + return num; + } + + function getRequestCount() { + let num = 0; + for (const key of Object.keys(agent.requests)) { + num += agent.requests[key].length; + } + return num; + } + + server.listen(0, common.mustCall(() => handler(server))); + server2.listen(0, common.mustCall(() => handler(server2))); +} + +// If maxTotalSockets is larger than maxSockets, +// then the origin check will be skipped +// when the socket is removed. +[{ + maxTotalSockets: 2, + maxSockets: 3, +}, { + maxTotalSockets: 3, + maxSockets: 2, +}, { + maxTotalSockets: 2, + maxSockets: 2, +}].forEach(start); diff --git a/tests/node_compat/test/parallel/test-http-agent-no-protocol.js b/tests/node_compat/test/parallel/test-http-agent-no-protocol.js new file mode 100644 index 0000000000..58a43792a9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-agent-no-protocol.js @@ -0,0 +1,48 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const http = require('http'); +const url = require('url'); + +const server = http.createServer(common.mustCall((req, res) => { + res.end(); +})).listen(0, '127.0.0.1', common.mustCall(() => { + const opts = url.parse(`http://127.0.0.1:${server.address().port}/`); + + // Remove the `protocol` field… the `http` module should fall back + // to "http:", as defined by the global, default `http.Agent` instance. + opts.agent = new http.Agent(); + opts.agent.protocol = null; + + http.get(opts, common.mustCall((res) => { + res.resume(); + server.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-agent-null.js b/tests/node_compat/test/parallel/test-http-agent-null.js new file mode 100644 index 0000000000..7619be7ecd --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-agent-null.js @@ -0,0 +1,44 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const http = require('http'); + +const server = http.createServer(common.mustCall((req, res) => { + res.end(); +})).listen(0, common.mustCall(() => { + const options = { + agent: null, + port: server.address().port + }; + http.get(options, common.mustCall((res) => { + res.resume(); + server.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-allow-req-after-204-res.js b/tests/node_compat/test/parallel/test-http-allow-req-after-204-res.js new file mode 100644 index 0000000000..04d2560a44 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-allow-req-after-204-res.js @@ -0,0 +1,68 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const http = require('http'); +const assert = require('assert'); +const Countdown = require('../common/countdown'); + +// first 204 or 304 works, subsequent anything fails +const codes = [204, 200]; + +const countdown = new Countdown(codes.length, () => server.close()); + +const server = http.createServer(common.mustCall((req, res) => { + const code = codes.shift(); + assert.strictEqual(typeof code, 'number'); + assert.ok(code > 0); + res.writeHead(code, {}); + res.end(); +}, codes.length)); + +function nextRequest() { + + const request = http.get({ + port: server.address().port, + path: '/' + }, common.mustCall((response) => { + response.on('end', common.mustCall(() => { + if (countdown.dec()) { + // throws error: + nextRequest(); + // TODO: investigate why this does not work fine even though it should. + // works just fine: + // process.nextTick(nextRequest); + } + })); + response.resume(); + })); + request.end(); +} + +server.listen(0, nextRequest); diff --git a/tests/node_compat/test/parallel/test-http-bind-twice.js b/tests/node_compat/test/parallel/test-http-bind-twice.js new file mode 100644 index 0000000000..6ec3d20708 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-bind-twice.js @@ -0,0 +1,43 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const server1 = http.createServer(common.mustNotCall()); +server1.listen(0, '127.0.0.1', common.mustCall(function() { + const server2 = http.createServer(common.mustNotCall()); + server2.listen(this.address().port, '127.0.0.1', common.mustNotCall()); + + server2.on('error', common.mustCall(function(e) { + assert.strictEqual(e.code, 'EADDRINUSE'); + server1.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-buffer-sanity.js b/tests/node_compat/test/parallel/test-http-buffer-sanity.js new file mode 100644 index 0000000000..b9b5832be0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-buffer-sanity.js @@ -0,0 +1,78 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const bufferSize = 5 * 1024 * 1024; +let measuredSize = 0; + +const buffer = Buffer.allocUnsafe(bufferSize); +for (let i = 0; i < buffer.length; i++) { + buffer[i] = i % 256; +} + +const server = http.Server(function(req, res) { + server.close(); + + let i = 0; + + req.on('data', (d) => { + measuredSize += d.length; + for (let j = 0; j < d.length; j++) { + assert.strictEqual(d[j], buffer[i]); + i++; + } + }); + + req.on('end', common.mustCall(() => { + assert.strictEqual(measuredSize, bufferSize); + res.writeHead(200); + res.write('thanks'); + res.end(); + })); +}); + +server.listen(0, common.mustCall(() => { + const req = http.request({ + port: server.address().port, + method: 'POST', + path: '/', + headers: { 'content-length': buffer.length } + }, common.mustCall((res) => { + res.setEncoding('utf8'); + let data = ''; + res.on('data', (chunk) => data += chunk); + res.on('end', common.mustCall(() => { + assert.strictEqual(data, 'thanks'); + })); + })); + req.end(buffer); +})); diff --git a/tests/node_compat/test/parallel/test-http-chunked-smuggling.js b/tests/node_compat/test/parallel/test-http-chunked-smuggling.js new file mode 100644 index 0000000000..ef85d16798 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-chunked-smuggling.js @@ -0,0 +1,50 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const http = require('http'); +const net = require('net'); +const assert = require('assert'); + +// Verify that invalid chunk extensions cannot be used to perform HTTP request +// smuggling attacks. + +const server = http.createServer(common.mustCall((request, response) => { + assert.notStrictEqual(request.url, '/admin'); + response.end('hello world'); +}), 1); + +server.listen(0, common.mustCall(start)); + +function start() { + const sock = net.connect(server.address().port); + + sock.write('' + + 'GET / HTTP/1.1\r\n' + + 'Host: localhost:8080\r\n' + + 'Transfer-Encoding: chunked\r\n' + + '\r\n' + + '2;\n' + + 'xx\r\n' + + '4c\r\n' + + '0\r\n' + + '\r\n' + + 'GET /admin HTTP/1.1\r\n' + + 'Host: localhost:8080\r\n' + + 'Transfer-Encoding: chunked\r\n' + + '\r\n' + + '0\r\n' + + '\r\n' + ); + + sock.resume(); + sock.on('end', common.mustCall(function() { + server.close(); + })); +} diff --git a/tests/node_compat/test/parallel/test-http-chunked.js b/tests/node_compat/test/parallel/test-http-chunked.js new file mode 100644 index 0000000000..13a7c62b95 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-chunked.js @@ -0,0 +1,63 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const UTF8_STRING = '南越国是前203年至前111年存在于岭南地区的一个国家,' + + '国都位于番禺,疆域包括今天中国的广东、广西两省区的大部份地区,福建省、湖南、' + + '贵州、云南的一小部份地区和越南的北部。南越国是秦朝灭亡后,' + + '由南海郡尉赵佗于前203年起兵兼并桂林郡和象郡后建立。前196年和前179年,' + + '南越国曾先后两次名义上臣属于西汉,成为西汉的“外臣”。前112年,' + + '南越国末代君主赵建德与西汉发生战争,被汉武帝于前111年所灭。' + + '南越国共存在93年,历经五代君主。南越国是岭南地区的第一个有记载的政权国家,' + + '采用封建制和郡县制并存的制度,它的建立保证了秦末乱世岭南地区社会秩序的稳定,' + + '有效的改善了岭南地区落后的政治、经济现状。'; + +const server = http.createServer(common.mustCall((req, res) => { + res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf8' }); + res.end(UTF8_STRING, 'utf8'); +})); +server.listen(0, common.mustCall(() => { + let data = ''; + http.get({ + path: '/', + host: 'localhost', + port: server.address().port + }, common.mustCall((x) => { + x.setEncoding('utf8'); + x.on('data', (c) => data += c); + x.on('end', common.mustCall(() => { + assert.strictEqual(typeof data, 'string'); + assert.strictEqual(UTF8_STRING, data); + server.close(); + })); + })).end(); +})); diff --git a/tests/node_compat/test/parallel/test-http-client-abort2.js b/tests/node_compat/test/parallel/test-http-client-abort2.js new file mode 100644 index 0000000000..f179e49514 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-abort2.js @@ -0,0 +1,45 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const http = require('http'); + +const server = http.createServer(common.mustCall((req, res) => { + res.end('Hello'); +})); + +server.listen(0, common.mustCall(() => { + const options = { port: server.address().port }; + const req = http.get(options, common.mustCall((res) => { + res.on('data', (data) => { + req.abort(); + server.close(); + }); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-client-check-http-token.js b/tests/node_compat/test/parallel/test-http-client-check-http-token.js new file mode 100644 index 0000000000..2457523b21 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-check-http-token.js @@ -0,0 +1,41 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const Countdown = require('../common/countdown'); + +const expectedSuccesses = [undefined, null, 'GET', 'post']; +const expectedFails = [-1, 1, 0, {}, true, false, [], Symbol()]; + +const countdown = + new Countdown(expectedSuccesses.length, + common.mustCall(() => server.close())); + +const server = http.createServer(common.mustCall((req, res) => { + res.end(); + countdown.dec(); +}, expectedSuccesses.length)); + +server.listen(0, common.mustCall(() => { + expectedFails.forEach((method) => { + assert.throws(() => { + http.request({ method, path: '/' }, common.mustNotCall()); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "options.method" property must be of type string.' + + common.invalidArgTypeHelper(method) + }); + }); + + expectedSuccesses.forEach((method) => { + http.request({ method, port: server.address().port }).end(); + }); +})); diff --git a/tests/node_compat/test/parallel/test-http-client-close-with-default-agent.js b/tests/node_compat/test/parallel/test-http-client-close-with-default-agent.js new file mode 100644 index 0000000000..67c2ae6156 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-close-with-default-agent.js @@ -0,0 +1,30 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const server = http.createServer(function(req, res) { + res.writeHead(200); + res.end(); +}); + +server.listen(0, common.mustCall(() => { + const req = http.get({ port: server.address().port }, (res) => { + assert.strictEqual(res.statusCode, 200); + res.resume(); + server.close(); + }); + + req.end(); +})); + +// This timer should never go off as the server will close the socket +setTimeout(common.mustNotCall(), common.platformTimeout(1000)).unref(); diff --git a/tests/node_compat/test/parallel/test-http-client-default-headers-exist.js b/tests/node_compat/test/parallel/test-http-client-default-headers-exist.js new file mode 100644 index 0000000000..883154db3d --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-default-headers-exist.js @@ -0,0 +1,77 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const { once } = require('events'); + +const expectedHeaders = { + 'DELETE': ['host', 'connection'], + 'GET': ['host', 'connection'], + 'HEAD': ['host', 'connection'], + 'OPTIONS': ['host', 'connection'], + 'POST': ['host', 'connection', 'content-length'], + 'PUT': ['host', 'connection', 'content-length'], + 'TRACE': ['host', 'connection'] +}; + +const expectedMethods = Object.keys(expectedHeaders); + +const server = http.createServer(common.mustCall((req, res) => { + res.end(); + + assert(Object.hasOwn(expectedHeaders, req.method), + `${req.method} was an unexpected method`); + + const requestHeaders = Object.keys(req.headers); + requestHeaders.forEach((header) => { + assert.ok( + expectedHeaders[req.method].includes(header.toLowerCase()), + `${header} should not exist for method ${req.method}` + ); + }); + + assert.strictEqual( + requestHeaders.length, + expectedHeaders[req.method].length, + `some headers were missing for method: ${req.method}` + ); +}, expectedMethods.length)); + +server.listen(0, common.mustCall(() => { + Promise.all(expectedMethods.map(async (method) => { + const request = http.request({ + method: method, + port: server.address().port + }).end(); + return once(request, 'response'); + })).then(common.mustCall(() => { server.close(); })); +})); diff --git a/tests/node_compat/test/parallel/test-http-client-defaults.js b/tests/node_compat/test/parallel/test-http-client-defaults.js new file mode 100644 index 0000000000..815dd60c0d --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-defaults.js @@ -0,0 +1,30 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const ClientRequest = require('http').ClientRequest; + +{ + const req = new ClientRequest({ createConnection: () => {} }); + assert.strictEqual(req.path, '/'); + assert.strictEqual(req.method, 'GET'); +} + +{ + const req = new ClientRequest({ method: '', createConnection: () => {} }); + assert.strictEqual(req.path, '/'); + assert.strictEqual(req.method, 'GET'); +} + +{ + const req = new ClientRequest({ path: '', createConnection: () => {} }); + assert.strictEqual(req.path, '/'); + assert.strictEqual(req.method, 'GET'); +} diff --git a/tests/node_compat/test/parallel/test-http-client-encoding.js b/tests/node_compat/test/parallel/test-http-client-encoding.js new file mode 100644 index 0000000000..3003bdf6e0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-encoding.js @@ -0,0 +1,46 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const server = http.createServer((req, res) => { + res.end('ok'); + server.close(); +}).listen(0, common.mustCall(() => { + http.request({ + port: server.address().port, + encoding: 'utf8' + }, common.mustCall((res) => { + let data = ''; + res.on('data', (chunk) => data += chunk); + res.on('end', common.mustCall(() => assert.strictEqual(data, 'ok'))); + })).end(); +})); diff --git a/tests/node_compat/test/parallel/test-http-client-headers-array.js b/tests/node_compat/test/parallel/test-http-client-headers-array.js new file mode 100644 index 0000000000..9558d22f6a --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-headers-array.js @@ -0,0 +1,77 @@ +// 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. + +'use strict'; + +require('../common'); + +const assert = require('assert'); +const http = require('http'); + +function execute(options) { + http.createServer(function(req, res) { + const expectHeaders = { + 'x-foo': 'boom', + 'cookie': 'a=1; b=2; c=3', + 'connection': 'keep-alive', + 'host': 'example.com', + }; + + // no Host header when you set headers an array + if (!Array.isArray(options.headers)) { + expectHeaders.host = `localhost:${this.address().port}`; + } + + // no Authorization header when you set headers an array + if (options.auth && !Array.isArray(options.headers)) { + expectHeaders.authorization = + `Basic ${Buffer.from(options.auth).toString('base64')}`; + } + + this.close(); + + assert.deepStrictEqual(req.headers, expectHeaders); + + res.writeHead(200, { 'Connection': 'close' }); + res.end(); + }).listen(0, function() { + options = Object.assign(options, { + port: this.address().port, + path: '/' + }); + const req = http.request(options); + req.end(); + }); +} + +// Should be the same except for implicit Host header on the first two +execute({ headers: { 'x-foo': 'boom', 'cookie': 'a=1; b=2; c=3' } }); +execute({ headers: { 'x-foo': 'boom', 'cookie': [ 'a=1', 'b=2', 'c=3' ] } }); +execute({ headers: [ + [ 'x-foo', 'boom' ], + [ 'cookie', 'a=1; b=2; c=3' ], + [ 'Host', 'example.com' ], +] }); +execute({ headers: [ + [ 'x-foo', 'boom' ], + [ 'cookie', [ 'a=1', 'b=2', 'c=3' ]], + [ 'Host', 'example.com' ], +] }); +execute({ headers: [ + [ 'x-foo', 'boom' ], [ 'cookie', 'a=1' ], + [ 'cookie', 'b=2' ], [ 'cookie', 'c=3' ], + [ 'Host', 'example.com'], +] }); + +// Authorization and Host header both missing from the second +execute({ auth: 'foo:bar', headers: + { 'x-foo': 'boom', 'cookie': 'a=1; b=2; c=3' } }); +execute({ auth: 'foo:bar', headers: [ + [ 'x-foo', 'boom' ], [ 'cookie', 'a=1' ], + [ 'cookie', 'b=2' ], [ 'cookie', 'c=3'], + [ 'Host', 'example.com'], +] }); diff --git a/tests/node_compat/test/parallel/test-http-client-invalid-path.js b/tests/node_compat/test/parallel/test-http-client-invalid-path.js new file mode 100644 index 0000000000..096d767498 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-invalid-path.js @@ -0,0 +1,20 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); + +assert.throws(() => { + http.request({ + path: '/thisisinvalid\uffe2' + }).end(); +}, { + code: 'ERR_UNESCAPED_CHARACTERS', + name: 'TypeError' +}); diff --git a/tests/node_compat/test/parallel/test-http-client-keep-alive-hint.js b/tests/node_compat/test/parallel/test-http-client-keep-alive-hint.js new file mode 100644 index 0000000000..91141329e0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-keep-alive-hint.js @@ -0,0 +1,34 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const server = http.createServer( + { keepAliveTimeout: common.platformTimeout(60000) }, + function(req, res) { + req.resume(); + res.writeHead(200, { 'Connection': 'keep-alive', 'Keep-Alive': 'timeout=1' }); + res.end('FOO'); + } +); + +server.listen(0, common.mustCall(() => { + http.get({ port: server.address().port }, (res) => { + assert.strictEqual(res.statusCode, 200); + + res.resume(); + server.close(); + }); +})); + + +// This timer should never go off as the agent will parse the hint and terminate earlier +setTimeout(common.mustNotCall(), common.platformTimeout(3000)).unref(); diff --git a/tests/node_compat/test/parallel/test-http-client-race-2.js b/tests/node_compat/test/parallel/test-http-client-race-2.js new file mode 100644 index 0000000000..09e77070fd --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-race-2.js @@ -0,0 +1,119 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +// +// Slight variation on test-http-client-race to test for another race +// condition involving the parsers FreeList used internally by http.Client. +// + +const body1_s = '1111111111111111'; +const body2_s = '22222'; +const body3_s = '3333333333333333333'; + +const server = http.createServer(function(req, res) { + const pathname = url.parse(req.url).pathname; + + let body; + switch (pathname) { + case '/1': body = body1_s; break; + case '/2': body = body2_s; break; + default: body = body3_s; + } + + res.writeHead(200, { + 'Content-Type': 'text/plain', + 'Content-Length': body.length + }); + res.end(body); +}); +server.listen(0); + +let body1 = ''; +let body2 = ''; +let body3 = ''; + +server.on('listening', function() { + // + // Client #1 is assigned Parser #1 + // + const req1 = http.get({ port: this.address().port, path: '/1' }); + req1.on('response', function(res1) { + res1.setEncoding('utf8'); + + res1.on('data', function(chunk) { + body1 += chunk; + }); + + res1.on('end', function() { + // + // Delay execution a little to allow the 'close' event to be processed + // (required to trigger this bug!) + // + setTimeout(function() { + // + // The bug would introduce itself here: Client #2 would be allocated the + // parser that previously belonged to Client #1. But we're not finished + // with Client #1 yet! + // + // At this point, the bug would manifest itself and crash because the + // internal state of the parser was no longer valid for use by Client #1 + // + const req2 = http.get({ port: server.address().port, path: '/2' }); + req2.on('response', function(res2) { + res2.setEncoding('utf8'); + res2.on('data', function(chunk) { body2 += chunk; }); + res2.on('end', function() { + + // + // Just to be really sure we've covered all our bases, execute a + // request using client2. + // + const req3 = http.get({ port: server.address().port, path: '/3' }); + req3.on('response', function(res3) { + res3.setEncoding('utf8'); + res3.on('data', function(chunk) { body3 += chunk; }); + res3.on('end', function() { server.close(); }); + }); + }); + }); + }, 500); + }); + }); +}); + +process.on('exit', function() { + assert.strictEqual(body1_s, body1); + assert.strictEqual(body2_s, body2); + assert.strictEqual(body3_s, body3); +}); diff --git a/tests/node_compat/test/parallel/test-http-client-race.js b/tests/node_compat/test/parallel/test-http-client-race.js new file mode 100644 index 0000000000..0dff9ce830 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-race.js @@ -0,0 +1,76 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +const body1_s = '1111111111111111'; +const body2_s = '22222'; + +const server = http.createServer(function(req, res) { + const body = url.parse(req.url).pathname === '/1' ? body1_s : body2_s; + res.writeHead(200, { + 'Content-Type': 'text/plain', + 'Content-Length': body.length + }); + res.end(body); +}); +server.listen(0); + +let body1 = ''; +let body2 = ''; + +server.on('listening', function() { + const req1 = http.request({ port: this.address().port, path: '/1' }); + req1.end(); + req1.on('response', function(res1) { + res1.setEncoding('utf8'); + + res1.on('data', function(chunk) { + body1 += chunk; + }); + + res1.on('end', function() { + const req2 = http.request({ port: server.address().port, path: '/2' }); + req2.end(); + req2.on('response', function(res2) { + res2.setEncoding('utf8'); + res2.on('data', function(chunk) { body2 += chunk; }); + res2.on('end', function() { server.close(); }); + }); + }); + }); +}); + +process.on('exit', function() { + assert.strictEqual(body1_s, body1); + assert.strictEqual(body2_s, body2); +}); diff --git a/tests/node_compat/test/parallel/test-http-client-reject-unexpected-agent.js b/tests/node_compat/test/parallel/test-http-client-reject-unexpected-agent.js new file mode 100644 index 0000000000..4bfd4210a9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-reject-unexpected-agent.js @@ -0,0 +1,76 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const baseOptions = { + method: 'GET', + port: undefined, + host: common.localhostIPv4, +}; + +const failingAgentOptions = [ + true, + 'agent', + {}, + 1, + () => null, + Symbol(), +]; + +const acceptableAgentOptions = [ + false, + undefined, + null, + new http.Agent(), +]; + +const server = http.createServer((req, res) => { + res.end('hello'); +}); + +let numberOfResponses = 0; + +function createRequest(agent) { + const options = Object.assign(baseOptions, { agent }); + const request = http.request(options); + request.end(); + request.on('response', common.mustCall(() => { + numberOfResponses++; + if (numberOfResponses === acceptableAgentOptions.length) { + server.close(); + } + })); +} + +server.listen(0, baseOptions.host, common.mustCall(function() { + baseOptions.port = this.address().port; + + failingAgentOptions.forEach((agent) => { + assert.throws( + () => createRequest(agent), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "options.agent" property must be one of Agent-like ' + + 'Object, undefined, or false.' + + common.invalidArgTypeHelper(agent) + } + ); + }); + + acceptableAgentOptions.forEach((agent) => { + createRequest(agent); + }); +})); + +process.on('exit', () => { + assert.strictEqual(numberOfResponses, acceptableAgentOptions.length); +}); diff --git a/tests/node_compat/test/parallel/test-http-client-timeout-connect-listener.js b/tests/node_compat/test/parallel/test-http-client-timeout-connect-listener.js new file mode 100644 index 0000000000..c151d16556 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-timeout-connect-listener.js @@ -0,0 +1,49 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// This test ensures that `ClientRequest.prototype.setTimeout()` does +// not add a listener for the `'connect'` event to the socket if the +// socket is already connected. + +const assert = require('assert'); +const http = require('http'); + +// Maximum allowed value for timeouts. +const timeout = 2 ** 31 - 1; + +const server = http.createServer((req, res) => { + res.end(); +}); + +server.listen(0, common.mustCall(() => { + const agent = new http.Agent({ keepAlive: true, maxSockets: 1 }); + const options = { port: server.address().port, agent: agent }; + + doRequest(options, common.mustCall(() => { + const req = doRequest(options, common.mustCall(() => { + agent.destroy(); + server.close(); + })); + + req.on('socket', common.mustCall((socket) => { + assert.strictEqual(socket.listenerCount('connect'), 0); + })); + })); +})); + +function doRequest(options, callback) { + const req = http.get(options, (res) => { + res.on('end', callback); + res.resume(); + }); + + req.setTimeout(timeout); + return req; +} diff --git a/tests/node_compat/test/parallel/test-http-client-timeout-with-data.js b/tests/node_compat/test/parallel/test-http-client-timeout-with-data.js new file mode 100644 index 0000000000..9e0f521b2e --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-timeout-with-data.js @@ -0,0 +1,70 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +let nchunks = 0; + +const options = { + method: 'GET', + port: undefined, + host: '127.0.0.1', + path: '/' +}; + +const server = http.createServer(function(req, res) { + res.writeHead(200, { 'Content-Length': '2' }); + res.write('*'); + server.once('timeout', common.mustCall(function() { res.end('*'); })); +}); + +server.listen(0, options.host, function() { + options.port = this.address().port; + const req = http.request(options, onresponse); + req.end(); + + function onresponse(res) { + req.setTimeout(50, common.mustCall(function() { + assert.strictEqual(nchunks, 1); // Should have received the first chunk + server.emit('timeout'); + })); + + res.on('data', common.mustCall(function(data) { + assert.strictEqual(String(data), '*'); + nchunks++; + }, 2)); + + res.on('end', common.mustCall(function() { + assert.strictEqual(nchunks, 2); + server.close(); + })); + } +}); diff --git a/tests/node_compat/test/parallel/test-http-client-unescaped-path.js b/tests/node_compat/test/parallel/test-http-client-unescaped-path.js new file mode 100644 index 0000000000..6ae8106390 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-unescaped-path.js @@ -0,0 +1,44 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +for (let i = 0; i <= 32; i += 1) { + const path = `bad${String.fromCharCode(i)}path`; + assert.throws( + () => http.get({ path }, common.mustNotCall()), + { + code: 'ERR_UNESCAPED_CHARACTERS', + name: 'TypeError', + message: 'Request path contains unescaped characters' + } + ); +} diff --git a/tests/node_compat/test/parallel/test-http-client-upload-buf.js b/tests/node_compat/test/parallel/test-http-client-upload-buf.js new file mode 100644 index 0000000000..a8299363fc --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-upload-buf.js @@ -0,0 +1,71 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const N = 1024; + +const server = http.createServer(common.mustCall(function(req, res) { + assert.strictEqual(req.method, 'POST'); + let bytesReceived = 0; + + req.on('data', function(chunk) { + bytesReceived += chunk.length; + }); + + req.on('end', common.mustCall(function() { + assert.strictEqual(N, bytesReceived); + console.log('request complete from server'); + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write('hello\n'); + res.end(); + })); +})); +server.listen(0); + +server.on('listening', common.mustCall(function() { + const req = http.request({ + port: this.address().port, + method: 'POST', + path: '/' + }, common.mustCall(function(res) { + res.setEncoding('utf8'); + res.on('data', function(chunk) { + console.log(chunk); + }); + res.on('end', common.mustCall(function() { + server.close(); + })); + })); + + req.write(Buffer.allocUnsafe(N)); + req.end(); +})); diff --git a/tests/node_compat/test/parallel/test-http-client-upload.js b/tests/node_compat/test/parallel/test-http-client-upload.js new file mode 100644 index 0000000000..4501c1e5fe --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-client-upload.js @@ -0,0 +1,74 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const server = http.createServer(common.mustCall(function(req, res) { + assert.strictEqual(req.method, 'POST'); + req.setEncoding('utf8'); + + let sent_body = ''; + + req.on('data', function(chunk) { + console.log(`server got: ${JSON.stringify(chunk)}`); + sent_body += chunk; + }); + + req.on('end', common.mustCall(function() { + assert.strictEqual(sent_body, '1\n2\n3\n'); + console.log('request complete from server'); + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write('hello\n'); + res.end(); + })); +})); +server.listen(0); + +server.on('listening', common.mustCall(function() { + const req = http.request({ + port: this.address().port, + method: 'POST', + path: '/' + }, common.mustCall(function(res) { + res.setEncoding('utf8'); + res.on('data', function(chunk) { + console.log(chunk); + }); + res.on('end', common.mustCall(function() { + server.close(); + })); + })); + + req.write('1\n'); + req.write('2\n'); + req.write('3\n'); + req.end(); +})); diff --git a/tests/node_compat/test/parallel/test-http-common.js b/tests/node_compat/test/parallel/test-http-common.js new file mode 100644 index 0000000000..ce900ea72b --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-common.js @@ -0,0 +1,40 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const httpCommon = require('_http_common'); +const checkIsHttpToken = httpCommon._checkIsHttpToken; +const checkInvalidHeaderChar = httpCommon._checkInvalidHeaderChar; + +// checkIsHttpToken +assert(checkIsHttpToken('t')); +assert(checkIsHttpToken('tt')); +assert(checkIsHttpToken('ttt')); +assert(checkIsHttpToken('tttt')); +assert(checkIsHttpToken('ttttt')); + +assert.strictEqual(checkIsHttpToken(''), false); +assert.strictEqual(checkIsHttpToken(' '), false); +assert.strictEqual(checkIsHttpToken('あ'), false); +assert.strictEqual(checkIsHttpToken('あa'), false); +assert.strictEqual(checkIsHttpToken('aaaaあaaaa'), false); + +// checkInvalidHeaderChar +assert(checkInvalidHeaderChar('あ')); +assert(checkInvalidHeaderChar('aaaaあaaaa')); + +assert.strictEqual(checkInvalidHeaderChar(''), false); +assert.strictEqual(checkInvalidHeaderChar(1), false); +assert.strictEqual(checkInvalidHeaderChar(' '), false); +assert.strictEqual(checkInvalidHeaderChar(false), false); +assert.strictEqual(checkInvalidHeaderChar('t'), false); +assert.strictEqual(checkInvalidHeaderChar('tt'), false); +assert.strictEqual(checkInvalidHeaderChar('ttt'), false); +assert.strictEqual(checkInvalidHeaderChar('tttt'), false); +assert.strictEqual(checkInvalidHeaderChar('ttttt'), false); diff --git a/tests/node_compat/test/parallel/test-http-contentLength0.js b/tests/node_compat/test/parallel/test-http-contentLength0.js new file mode 100644 index 0000000000..8a0dc19ff3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-contentLength0.js @@ -0,0 +1,51 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const http = require('http'); + +// Simple test of Node's HTTP Client choking on a response +// with a 'Content-Length: 0 ' response header. +// I.E. a space character after the 'Content-Length' throws an `error` event. + + +const s = http.createServer(function(req, res) { + res.writeHead(200, { 'Content-Length': '0 ' }); + res.end(); +}); +s.listen(0, function() { + + const request = http.request({ port: this.address().port }, (response) => { + console.log(`STATUS: ${response.statusCode}`); + s.close(); + response.resume(); + }); + + request.end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-correct-hostname.js b/tests/node_compat/test/parallel/test-http-correct-hostname.js new file mode 100644 index 0000000000..a38d57f03d --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-correct-hostname.js @@ -0,0 +1,35 @@ +// 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. + +/* eslint-disable node-core/crypto-check */ +// Flags: --expose-internals +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +const { kOutHeaders } = require('internal/http'); + +const http = require('http'); +const modules = { http }; + +if (common.hasCrypto) { + const https = require('https'); + modules.https = https; +} + +Object.keys(modules).forEach((module) => { + const doNotCall = common.mustNotCall( + `${module}.request should not connect to ${module}://example.com%60x.example.com` + ); + const req = modules[module].request(`${module}://example.com%60x.example.com`, doNotCall); + assert.deepStrictEqual(req[kOutHeaders].host, [ + 'Host', + 'example.com`x.example.com', + ]); + req.abort(); +}); diff --git a/tests/node_compat/test/parallel/test-http-date-header.js b/tests/node_compat/test/parallel/test-http-date-header.js new file mode 100644 index 0000000000..4299a6848a --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-date-header.js @@ -0,0 +1,62 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); + +const testResBody = 'other stuff!\n'; + +const server = http.createServer((req, res) => { + assert.ok(!('date' in req.headers), + 'Request headers contained a Date.'); + res.writeHead(200, { + 'Content-Type': 'text/plain' + }); + res.end(testResBody); +}); +server.listen(0); + + +server.addListener('listening', () => { + const options = { + port: server.address().port, + path: '/', + method: 'GET' + }; + const req = http.request(options, (res) => { + assert.ok('date' in res.headers, + 'Response headers didn\'t contain a Date.'); + res.addListener('end', () => { + server.close(); + }); + res.resume(); + }); + req.end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-decoded-auth.js b/tests/node_compat/test/parallel/test-http-decoded-auth.js new file mode 100644 index 0000000000..a0d2eb953e --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-decoded-auth.js @@ -0,0 +1,55 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); + +const testCases = [ + { + username: 'test@test"', + password: '123456^', + expected: 'dGVzdEB0ZXN0IjoxMjM0NTZe' + }, + { + username: 'test%40test', + password: '123456', + expected: 'dGVzdEB0ZXN0OjEyMzQ1Ng==' + }, + { + username: 'not%3Agood', + password: 'god', + expected: 'bm90Omdvb2Q6Z29k' + }, + { + username: 'not%22good', + password: 'g%5Eod', + expected: 'bm90Imdvb2Q6Z15vZA==' + }, + { + username: 'test1234::::', + password: 'mypass', + expected: 'dGVzdDEyMzQ6Ojo6Om15cGFzcw==' + }, +]; + +for (const testCase of testCases) { + const server = http.createServer(function(request, response) { + // The correct authorization header is be passed + assert.strictEqual(request.headers.authorization, `Basic ${testCase.expected}`); + response.writeHead(200, {}); + response.end('ok'); + server.close(); + }); + + server.listen(0, function() { + // make the request + const url = new URL(`http://${testCase.username}:${testCase.password}@localhost:${this.address().port}`); + http.request(url).end(); + }); +} diff --git a/tests/node_compat/test/parallel/test-http-default-encoding.js b/tests/node_compat/test/parallel/test-http-default-encoding.js new file mode 100644 index 0000000000..a87831c632 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-default-encoding.js @@ -0,0 +1,65 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); + +const expected = 'This is a unicode text: سلام'; +let result = ''; + +const server = http.Server((req, res) => { + req.setEncoding('utf8'); + req.on('data', (chunk) => { + result += chunk; + }).on('end', () => { + res.writeHead(200); + res.end('hello world\n'); + server.close(); + }); + +}); + +server.listen(0, function() { + http.request({ + port: this.address().port, + path: '/', + method: 'POST' + }, (res) => { + console.log(res.statusCode); + res.resume(); + }).on('error', (e) => { + console.log(e.message); + process.exit(1); + }).end(expected); +}); + +process.on('exit', () => { + assert.strictEqual(result, expected); +}); diff --git a/tests/node_compat/test/parallel/test-http-dump-req-when-res-ends.js b/tests/node_compat/test/parallel/test-http-dump-req-when-res-ends.js new file mode 100644 index 0000000000..3b94250f5a --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-dump-req-when-res-ends.js @@ -0,0 +1,73 @@ +// 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. + +'use strict'; + +const { mustCall } = require('../common'); + +const fs = require('fs'); +const http = require('http'); +const { strictEqual } = require('assert'); + +const server = http.createServer(mustCall(function(req, res) { + strictEqual(req.socket.listenerCount('data'), 1); + req.socket.once('data', mustCall(function() { + // Ensure that a chunk of data is received before calling `res.end()`. + res.end('hello world'); + })); + // This checks if the request gets dumped + // resume will be triggered by res.end(). + req.on('resume', mustCall(function() { + // There is no 'data' event handler anymore + // it gets automatically removed when dumping the request. + strictEqual(req.listenerCount('data'), 0); + req.on('data', mustCall()); + })); + + // We explicitly pause the stream + // so that the following on('data') does not cause + // a resume. + req.pause(); + req.on('data', function() {}); + + // Start sending the response. + res.flushHeaders(); +})); + +server.listen(0, mustCall(function() { + const req = http.request({ + method: 'POST', + port: server.address().port + }); + + // Send the http request without waiting + // for the body. + req.flushHeaders(); + + req.on('response', mustCall(function(res) { + // Pipe the body as soon as we get the headers of the + // response back. + fs.createReadStream(__filename).pipe(req); + + res.resume(); + + // On some platforms the `'end'` event might not be emitted because the + // socket could be destroyed by the other peer while data is still being + // sent. In this case the 'aborted'` event is emitted instead of `'end'`. + // `'close'` is used here because it is always emitted and does not + // invalidate the test. + res.on('close', function() { + server.close(); + }); + })); + + req.on('error', function() { + // An error can happen if there is some data still + // being sent, as the other side is calling .destroy() + // this is safe to ignore. + }); +})); diff --git a/tests/node_compat/test/parallel/test-http-end-throw-socket-handling.js b/tests/node_compat/test/parallel/test-http-end-throw-socket-handling.js new file mode 100644 index 0000000000..2e963648e8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-end-throw-socket-handling.js @@ -0,0 +1,60 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const Countdown = require('../common/countdown'); + +// Make sure that throwing in 'end' handler doesn't lock +// up the socket forever. +// +// This is NOT a good way to handle errors in general, but all +// the same, we should not be so brittle and easily broken. + +const http = require('http'); +const countdown = new Countdown(10, () => server.close()); + +const server = http.createServer((req, res) => { + countdown.dec(); + res.end('ok'); +}); + +server.listen(0, common.mustCall(() => { + for (let i = 0; i < 10; i++) { + const options = { port: server.address().port }; + const req = http.request(options, (res) => { + res.resume(); + res.on('end', common.mustCall(() => { + throw new Error('gleep glorp'); + })); + }); + req.end(); + } +})); + +process.on('uncaughtException', common.mustCall(10)); diff --git a/tests/node_compat/test/parallel/test-http-eof-on-connect.js b/tests/node_compat/test/parallel/test-http-eof-on-connect.js new file mode 100644 index 0000000000..7a682a03c0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-eof-on-connect.js @@ -0,0 +1,48 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +const common = require('../common'); +const net = require('net'); +const http = require('http'); + +// This is a regression test for https://github.com/joyent/node/issues/44 +// It is separate from test-http-malformed-request.js because it is only +// reproducible on the first packet on the first connection to a server. + +const server = http.createServer(common.mustNotCall()); +server.listen(0); + +server.on('listening', function() { + net.createConnection(this.address().port).on('connect', function() { + this.destroy(); + }).on('close', function() { + server.close(); + }); +}); diff --git a/tests/node_compat/test/parallel/test-http-extra-response.js b/tests/node_compat/test/parallel/test-http-extra-response.js new file mode 100644 index 0000000000..5d2ba9d36f --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-extra-response.js @@ -0,0 +1,87 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const net = require('net'); + +// If an HTTP server is broken and sends data after the end of the response, +// node should ignore it and drop the connection. +// Demos this bug: https://github.com/joyent/node/issues/680 + +const body = 'hello world\r\n'; +const fullResponse = + 'HTTP/1.1 500 Internal Server Error\r\n' + + `Content-Length: ${body.length}\r\n` + + 'Content-Type: text/plain\r\n' + + 'Date: Fri + 18 Feb 2011 06:22:45 GMT\r\n' + + 'Host: 10.20.149.2\r\n' + + 'Access-Control-Allow-Credentials: true\r\n' + + 'Server: badly broken/0.1 (OS NAME)\r\n' + + '\r\n' + + body; + +const server = net.createServer(function(socket) { + let postBody = ''; + + socket.setEncoding('utf8'); + + socket.on('data', function(chunk) { + postBody += chunk; + + if (postBody.includes('\r\n')) { + socket.write(fullResponse); + socket.end(fullResponse); + } + }); + + socket.on('error', function(err) { + assert.strictEqual(err.code, 'ECONNRESET'); + }); +}); + + +server.listen(0, common.mustCall(function() { + http.get({ port: this.address().port }, common.mustCall(function(res) { + let buffer = ''; + console.log(`Got res code: ${res.statusCode}`); + + res.setEncoding('utf8'); + res.on('data', function(chunk) { + buffer += chunk; + }); + + res.on('end', common.mustCall(function() { + console.log(`Response ended, read ${buffer.length} bytes`); + assert.strictEqual(body, buffer); + server.close(); + })); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-flush-headers.js b/tests/node_compat/test/parallel/test-http-flush-headers.js new file mode 100644 index 0000000000..5b5fe34199 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-flush-headers.js @@ -0,0 +1,27 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); + +const server = http.createServer(); +server.on('request', function(req, res) { + assert.strictEqual(req.headers.foo, 'bar'); + res.end('ok'); + server.close(); +}); +server.listen(0, '127.0.0.1', function() { + const req = http.request({ + method: 'GET', + host: '127.0.0.1', + port: this.address().port, + }); + req.setHeader('foo', 'bar'); + req.flushHeaders(); +}); diff --git a/tests/node_compat/test/parallel/test-http-full-response.js b/tests/node_compat/test/parallel/test-http-full-response.js new file mode 100644 index 0000000000..cef22c7c80 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-full-response.js @@ -0,0 +1,88 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +// This test requires the program 'ab' +const http = require('http'); +const exec = require('child_process').exec; + +const bodyLength = 12345; + +const body = 'c'.repeat(bodyLength); + +const server = http.createServer(function(req, res) { + res.writeHead(200, { + 'Content-Length': bodyLength, + 'Content-Type': 'text/plain' + }); + res.end(body); +}); + +function runAb(opts, callback) { + const command = `ab ${opts} http://127.0.0.1:${server.address().port}/`; + exec(command, function(err, stdout, stderr) { + if (err) { + if (/ab|apr/i.test(stderr)) { + common.printSkipMessage(`problem spawning \`ab\`.\n${stderr}`); + process.reallyExit(0); + } + throw err; + } + + let m = /Document Length:\s*(\d+) bytes/i.exec(stdout); + const documentLength = parseInt(m[1]); + + m = /Complete requests:\s*(\d+)/i.exec(stdout); + const completeRequests = parseInt(m[1]); + + m = /HTML transferred:\s*(\d+) bytes/i.exec(stdout); + const htmlTransferred = parseInt(m[1]); + + assert.strictEqual(bodyLength, documentLength); + assert.strictEqual(completeRequests * documentLength, htmlTransferred); + + if (callback) callback(); + }); +} + +server.listen(0, common.mustCall(function() { + runAb('-c 1 -n 10', common.mustCall(function() { + console.log('-c 1 -n 10 okay'); + + runAb('-c 1 -n 100', common.mustCall(function() { + console.log('-c 1 -n 100 okay'); + + runAb('-c 1 -n 1000', common.mustCall(function() { + console.log('-c 1 -n 1000 okay'); + server.close(); + })); + })); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-head-request.js b/tests/node_compat/test/parallel/test-http-head-request.js new file mode 100644 index 0000000000..fe3cc09ed1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-head-request.js @@ -0,0 +1,64 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const http = require('http'); + +const body = 'hello world\n'; + +function test(headers) { + const server = http.createServer(function(req, res) { + console.error('req: %s headers: %j', req.method, headers); + res.writeHead(200, headers); + res.end(); + server.close(); + }); + + server.listen(0, common.mustCall(function() { + const request = http.request({ + port: this.address().port, + method: 'HEAD', + path: '/' + }, common.mustCall(function(response) { + console.error('response start'); + response.on('end', common.mustCall(function() { + console.error('response end'); + })); + response.resume(); + })); + request.end(); + })); +} + +test({ + 'Transfer-Encoding': 'chunked' +}); +test({ + 'Content-Length': body.length +}); diff --git a/tests/node_compat/test/parallel/test-http-head-response-has-no-body-end-implicit-headers.js b/tests/node_compat/test/parallel/test-http-head-response-has-no-body-end-implicit-headers.js new file mode 100644 index 0000000000..514fb4584b --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-head-response-has-no-body-end-implicit-headers.js @@ -0,0 +1,34 @@ +// 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. + +'use strict'; +const common = require('../common'); +const http = require('http'); + +// This test is to make sure that when the HTTP server +// responds to a HEAD request with data to res.end, +// it does not send any body but the response is sent +// anyway. + +const server = http.createServer(function(req, res) { + res.end('FAIL'); // broken: sends FAIL from hot path. +}); +server.listen(0); + +server.on('listening', common.mustCall(function() { + const req = http.request({ + port: this.address().port, + method: 'HEAD', + path: '/' + }, common.mustCall(function(res) { + res.on('end', common.mustCall(function() { + server.close(); + })); + res.resume(); + })); + req.end(); +})); diff --git a/tests/node_compat/test/parallel/test-http-head-response-has-no-body-end.js b/tests/node_compat/test/parallel/test-http-head-response-has-no-body-end.js new file mode 100644 index 0000000000..9b831751a8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-head-response-has-no-body-end.js @@ -0,0 +1,55 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const http = require('http'); + +// This test is to make sure that when the HTTP server +// responds to a HEAD request with data to res.end, +// it does not send any body. + +const server = http.createServer(function(req, res) { + res.writeHead(200); + res.end('FAIL'); // broken: sends FAIL from hot path. +}); +server.listen(0); + +server.on('listening', common.mustCall(function() { + const req = http.request({ + port: this.address().port, + method: 'HEAD', + path: '/' + }, common.mustCall(function(res) { + res.on('end', common.mustCall(function() { + server.close(); + })); + res.resume(); + })); + req.end(); +})); diff --git a/tests/node_compat/test/parallel/test-http-head-response-has-no-body.js b/tests/node_compat/test/parallel/test-http-head-response-has-no-body.js new file mode 100644 index 0000000000..334c89193d --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-head-response-has-no-body.js @@ -0,0 +1,55 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const http = require('http'); + +// This test is to make sure that when the HTTP server +// responds to a HEAD request, it does not send any body. +// In this case it was sending '0\r\n\r\n' + +const server = http.createServer(function(req, res) { + res.writeHead(200); // broken: defaults to TE chunked + res.end(); +}); +server.listen(0); + +server.on('listening', common.mustCall(function() { + const req = http.request({ + port: this.address().port, + method: 'HEAD', + path: '/' + }, common.mustCall(function(res) { + res.on('end', common.mustCall(function() { + server.close(); + })); + res.resume(); + })); + req.end(); +})); diff --git a/tests/node_compat/test/parallel/test-http-head-throw-on-response-body-write.js b/tests/node_compat/test/parallel/test-http-head-throw-on-response-body-write.js new file mode 100644 index 0000000000..237cc1d891 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-head-throw-on-response-body-write.js @@ -0,0 +1,109 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +{ + const server = http.createServer((req, res) => { + res.writeHead(200); + res.end('this is content'); + }); + server.listen(0); + + server.on('listening', common.mustCall(function() { + const req = http.request({ + port: this.address().port, + method: 'HEAD', + path: '/' + }, common.mustCall((res) => { + res.resume(); + res.on('end', common.mustCall(function() { + server.close(); + })); + })); + req.end(); + })); +} + +{ + const server = http.createServer({ + rejectNonStandardBodyWrites: true, + }, (req, res) => { + res.writeHead(204); + assert.throws(() => { + res.write('this is content'); + }, { + code: 'ERR_HTTP_BODY_NOT_ALLOWED', + name: 'Error', + message: 'Adding content for this request method or response status is not allowed.' + }); + res.end(); + }); + server.listen(0); + + server.on('listening', common.mustCall(function() { + const req = http.request({ + port: this.address().port, + method: 'GET', + path: '/' + }, common.mustCall((res) => { + res.resume(); + res.on('end', common.mustCall(function() { + server.close(); + })); + })); + req.end(); + })); +} + +{ + const server = http.createServer({ + rejectNonStandardBodyWrites: false, + }, (req, res) => { + res.writeHead(200); + res.end('this is content'); + }); + server.listen(0); + + server.on('listening', common.mustCall(function() { + const req = http.request({ + port: this.address().port, + method: 'HEAD', + path: '/' + }, common.mustCall((res) => { + res.resume(); + res.on('end', common.mustCall(function() { + server.close(); + })); + })); + req.end(); + })); +} diff --git a/tests/node_compat/test/parallel/test-http-header-obstext.js b/tests/node_compat/test/parallel/test-http-header-obstext.js new file mode 100644 index 0000000000..acdcef81ad --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-header-obstext.js @@ -0,0 +1,28 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// This test ensures that the http-parser can handle UTF-8 characters +// in the http header. + +const http = require('http'); +const assert = require('assert'); + +const server = http.createServer(common.mustCall((req, res) => { + res.end('ok'); +})); +server.listen(0, () => { + http.get({ + port: server.address().port, + headers: { 'Test': 'Düsseldorf' } + }, common.mustCall((res) => { + assert.strictEqual(res.statusCode, 200); + server.close(); + })); +}); diff --git a/tests/node_compat/test/parallel/test-http-header-owstext.js b/tests/node_compat/test/parallel/test-http-header-owstext.js new file mode 100644 index 0000000000..488f14d026 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-header-owstext.js @@ -0,0 +1,56 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// This test ensures that the http-parser strips leading and trailing OWS from +// header values. It sends the header values in chunks to force the parser to +// build the string up through multiple calls to on_header_value(). + +const assert = require('assert'); +const http = require('http'); +const net = require('net'); + +function check(hdr, snd, rcv) { + const server = http.createServer(common.mustCall((req, res) => { + assert.strictEqual(req.headers[hdr], rcv); + req.pipe(res); + })); + + server.listen(0, common.mustCall(function() { + const client = net.connect(this.address().port, start); + function start() { + client.write('GET / HTTP/1.1\r\n' + hdr + ':', drain); + } + + function drain() { + if (snd.length === 0) { + return client.write('\r\nConnection: close\r\n\r\n'); + } + client.write(snd.shift(), drain); + } + + const bufs = []; + client.on('data', function(chunk) { + bufs.push(chunk); + }); + client.on('end', common.mustCall(function() { + const head = Buffer.concat(bufs) + .toString('latin1') + .split('\r\n')[0]; + assert.strictEqual(head, 'HTTP/1.1 200 OK'); + server.close(); + })); + })); +} + +check('host', [' \t foo.com\t'], 'foo.com'); +check('host', [' \t foo\tcom\t'], 'foo\tcom'); +check('host', [' \t', ' ', ' foo.com\t', '\t '], 'foo.com'); +check('host', [' \t', ' \t'.repeat(100), '\t '], ''); +check('host', [' \t', ' - - - - ', '\t '], '- - - -'); diff --git a/tests/node_compat/test/parallel/test-http-header-read.js b/tests/node_compat/test/parallel/test-http-header-read.js new file mode 100644 index 0000000000..cc57cc7a9e --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-header-read.js @@ -0,0 +1,59 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); + +// Verify that ServerResponse.getHeader() works correctly even after +// the response header has been sent. Issue 752 on github. + +const s = http.createServer(function(req, res) { + const contentType = 'Content-Type'; + const plain = 'text/plain'; + res.setHeader(contentType, plain); + assert.ok(!res.headersSent); + res.writeHead(200); + assert.ok(res.headersSent); + res.end('hello world\n'); + // This checks that after the headers have been sent, getHeader works + // and does not throw an exception (Issue 752) + assert.strictEqual(plain, res.getHeader(contentType)); +}); + +s.listen(0, runTest); + +function runTest() { + http.get({ port: this.address().port }, function(response) { + response.on('end', function() { + s.close(); + }); + response.resume(); + }); +} diff --git a/tests/node_compat/test/parallel/test-http-hex-write.js b/tests/node_compat/test/parallel/test-http-hex-write.js new file mode 100644 index 0000000000..d855676ced --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-hex-write.js @@ -0,0 +1,56 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const http = require('http'); + +const expect = 'hex\nutf8\n'; + +http.createServer(function(q, s) { + s.setHeader('content-length', expect.length); + s.write('6865780a', 'hex'); + s.write('utf8\n'); + s.end(); + this.close(); +}).listen(0, common.mustCall(function() { + http.request({ port: this.address().port }) + .on('response', common.mustCall(function(res) { + let data = ''; + + res.setEncoding('ascii'); + res.on('data', function(c) { + data += c; + }); + res.on('end', common.mustCall(function() { + assert.strictEqual(data, expect); + })); + })).end(); +})); diff --git a/tests/node_compat/test/parallel/test-http-highwatermark.js b/tests/node_compat/test/parallel/test-http-highwatermark.js new file mode 100644 index 0000000000..52d892f246 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-highwatermark.js @@ -0,0 +1,59 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); +const http = require('http'); + +// These test cases to check socketOnDrain where needPause becomes false. +// When send large response enough to exceed highWaterMark, it expect the socket +// to be paused and res.write would be failed. +// And it should be resumed when outgoingData falls below highWaterMark. + +let requestReceived = 0; + +const server = http.createServer(function(req, res) { + const id = ++requestReceived; + const enoughToDrain = req.connection.writableHighWaterMark; + const body = 'x'.repeat(enoughToDrain * 100); + + if (id === 1) { + // Case of needParse = false + req.connection.once('pause', common.mustCall(() => { + assert(req.connection._paused, '_paused must be true because it exceeds' + + 'highWaterMark by second request'); + })); + } else { + // Case of needParse = true + const resume = req.connection.parser.resume.bind(req.connection.parser); + req.connection.parser.resume = common.mustCall((...args) => { + const paused = req.connection._paused; + assert(!paused, '_paused must be false because it become false by ' + + 'socketOnDrain when outgoingData falls below ' + + 'highWaterMark'); + return resume(...args); + }); + } + assert(!res.write(body), 'res.write must return false because it will ' + + 'exceed highWaterMark on this call'); + res.end(); +}).on('listening', () => { + const c = net.createConnection(server.address().port, () => { + c.write('GET / HTTP/1.1\r\n\r\n'); + c.write('GET / HTTP/1.1\r\n\r\n', + () => setImmediate(() => c.resume())); + c.end(); + }); + + c.on('end', () => { + server.close(); + }); +}); + +server.listen(0); diff --git a/tests/node_compat/test/parallel/test-http-host-headers.js b/tests/node_compat/test/parallel/test-http-host-headers.js new file mode 100644 index 0000000000..e3de017967 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-host-headers.js @@ -0,0 +1,103 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const http = require('http'); +const assert = require('assert'); +const httpServer = http.createServer(reqHandler); + +function reqHandler(req, res) { + if (req.url === '/setHostFalse5') { + assert.strictEqual(req.headers.host, undefined); + } else { + assert.strictEqual( + req.headers.host, `localhost:${this.address().port}`, + `Wrong host header for req[${req.url}]: ${req.headers.host}`); + } + res.writeHead(200, {}); + res.end('ok'); +} + +testHttp(); + +function testHttp() { + + let counter = 0; + + function cb(res) { + counter--; + if (counter === 0) { + httpServer.close(); + } + res.resume(); + } + + httpServer.listen(0, (er) => { + assert.ifError(er); + http.get({ + method: 'GET', + path: `/${counter++}`, + host: 'localhost', + port: httpServer.address().port, + rejectUnauthorized: false + }, cb).on('error', common.mustNotCall()); + + http.request({ + method: 'GET', + path: `/${counter++}`, + host: 'localhost', + port: httpServer.address().port, + rejectUnauthorized: false + }, cb).on('error', common.mustNotCall()).end(); + + http.request({ + method: 'POST', + path: `/${counter++}`, + host: 'localhost', + port: httpServer.address().port, + rejectUnauthorized: false + }, cb).on('error', common.mustNotCall()).end(); + + http.request({ + method: 'PUT', + path: `/${counter++}`, + host: 'localhost', + port: httpServer.address().port, + rejectUnauthorized: false + }, cb).on('error', common.mustNotCall()).end(); + + http.request({ + method: 'DELETE', + path: `/${counter++}`, + host: 'localhost', + port: httpServer.address().port, + rejectUnauthorized: false + }, cb).on('error', common.mustNotCall()).end(); + }); +} diff --git a/tests/node_compat/test/parallel/test-http-hostname-typechecking.js b/tests/node_compat/test/parallel/test-http-hostname-typechecking.js new file mode 100644 index 0000000000..e42384504b --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-hostname-typechecking.js @@ -0,0 +1,49 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +// All of these values should cause http.request() to throw synchronously +// when passed as the value of either options.hostname or options.host +const vals = [{}, [], NaN, Infinity, -Infinity, true, false, 1, 0, new Date()]; + +vals.forEach((v) => { + const received = common.invalidArgTypeHelper(v); + assert.throws( + () => http.request({ hostname: v }), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "options.hostname" property must be of ' + + 'type string or one of undefined or null.' + + received + } + ); + + assert.throws( + () => http.request({ host: v }), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + message: 'The "options.host" property must be of ' + + 'type string or one of undefined or null.' + + received + } + ); +}); + +// These values are OK and should not throw synchronously. +// Only testing for 'hostname' validation so ignore connection errors. +const dontCare = () => {}; +['', undefined, null].forEach((v) => { + http.request({ hostname: v }).on('error', dontCare).end(); + http.request({ host: v }).on('error', dontCare).end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-incoming-message-destroy.js b/tests/node_compat/test/parallel/test-http-incoming-message-destroy.js new file mode 100644 index 0000000000..0c41570d9a --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-incoming-message-destroy.js @@ -0,0 +1,17 @@ +// 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. + +'use strict'; + +// Test that http.IncomingMessage,prototype.destroy() returns `this`. +require('../common'); + +const assert = require('assert'); +const http = require('http'); +const incomingMessage = new http.IncomingMessage(); + +assert.strictEqual(incomingMessage.destroy(), incomingMessage); diff --git a/tests/node_compat/test/parallel/test-http-invalid-path-chars.js b/tests/node_compat/test/parallel/test-http-invalid-path-chars.js new file mode 100644 index 0000000000..be037050d5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-invalid-path-chars.js @@ -0,0 +1,27 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const http = require('http'); + +const theExperimentallyDeterminedNumber = 39; + +for (let i = 0; i <= theExperimentallyDeterminedNumber; i++) { + const prefix = 'a'.repeat(i); + for (let i = 0; i <= 32; i++) { + assert.throws(() => { + http.request({ path: prefix + String.fromCodePoint(i) }, assert.fail); + }, { + code: 'ERR_UNESCAPED_CHARACTERS', + name: 'TypeError', + message: 'Request path contains unescaped characters' + }); + } +} diff --git a/tests/node_compat/test/parallel/test-http-invalidheaderfield.js b/tests/node_compat/test/parallel/test-http-invalidheaderfield.js new file mode 100644 index 0000000000..93d8d99f88 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-invalidheaderfield.js @@ -0,0 +1,59 @@ +// 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. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const EventEmitter = require('events'); +const http = require('http'); + +const ee = new EventEmitter(); +let count = 3; + +const server = http.createServer(function(req, res) { + res.setHeader('testing_123', 123); + assert.throws(function() { + res.setHeader('testing 123', 123); + }, TypeError); + res.end(''); +}); +server.listen(0, function() { + + http.get({ port: this.address().port }, function() { + ee.emit('done'); + }); + + assert.throws( + function() { + const options = { + port: server.address().port, + headers: { 'testing 123': 123 } + }; + http.get(options, common.mustNotCall()); + }, + function(err) { + ee.emit('done'); + if (err instanceof TypeError) return true; + } + ); + + // Should not throw. + const options = { + port: server.address().port, + headers: { 'testing_123': 123 } + }; + http.get(options, function() { + ee.emit('done'); + }); +}); + +ee.on('done', function() { + if (--count === 0) { + server.close(); + } +}); diff --git a/tests/node_compat/test/parallel/test-http-invalidheaderfield2.js b/tests/node_compat/test/parallel/test-http-invalidheaderfield2.js new file mode 100644 index 0000000000..e6c0f976b6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-invalidheaderfield2.js @@ -0,0 +1,95 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const inspect = require('util').inspect; +const { _checkIsHttpToken, _checkInvalidHeaderChar } = require('_http_common'); + +// Good header field names +[ + 'TCN', + 'ETag', + 'date', + 'alt-svc', + 'Content-Type', + '0', + 'Set-Cookie2', + 'Set_Cookie', + 'foo`bar^', + 'foo|bar', + '~foobar', + 'FooBar!', + '#Foo', + '$et-Cookie', + '%%Test%%', + 'Test&123', + 'It\'s_fun', + '2*3', + '4+2', + '3.14159265359', +].forEach(function(str) { + assert.strictEqual( + _checkIsHttpToken(str), true, + `_checkIsHttpToken(${inspect(str)}) unexpectedly failed`); +}); +// Bad header field names +[ + ':', + '@@', + '中文呢', // unicode + '((((())))', + ':alternate-protocol', + 'alternate-protocol:', + 'foo\nbar', + 'foo\rbar', + 'foo\r\nbar', + 'foo\x00bar', + '\x7FMe!', + '{Start', + '(Start', + '[Start', + 'End}', + 'End)', + 'End]', + '"Quote"', + 'This,That', +].forEach(function(str) { + assert.strictEqual( + _checkIsHttpToken(str), false, + `_checkIsHttpToken(${inspect(str)}) unexpectedly succeeded`); +}); + + +// Good header field values +[ + 'foo bar', + 'foo\tbar', + '0123456789ABCdef', + '!@#$%^&*()-_=+\\;\':"[]{}<>,./?|~`', +].forEach(function(str) { + assert.strictEqual( + _checkInvalidHeaderChar(str), false, + `_checkInvalidHeaderChar(${inspect(str)}) unexpectedly failed`); +}); + +// Bad header field values +[ + 'foo\rbar', + 'foo\nbar', + 'foo\r\nbar', + '中文呢', // unicode + '\x7FMe!', + 'Testing 123\x00', + 'foo\vbar', + 'Ding!\x07', +].forEach(function(str) { + assert.strictEqual( + _checkInvalidHeaderChar(str), true, + `_checkInvalidHeaderChar(${inspect(str)}) unexpectedly succeeded`); +}); diff --git a/tests/node_compat/test/parallel/test-http-keep-alive-timeout-custom.js b/tests/node_compat/test/parallel/test-http-keep-alive-timeout-custom.js new file mode 100644 index 0000000000..eb48c8c0bd --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-keep-alive-timeout-custom.js @@ -0,0 +1,38 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const http = require('http'); +const assert = require('assert'); + +const server = http.createServer(common.mustCall((req, res) => { + const body = 'hello world\n'; + + res.writeHead(200, { + 'Content-Length': body.length, + 'Keep-Alive': 'timeout=50' + }); + res.write(body); + res.end(); +})); +server.keepAliveTimeout = 12010; + +const agent = new http.Agent({ maxSockets: 1, keepAlive: true }); + +server.listen(0, common.mustCall(function() { + http.get({ + path: '/', port: this.address().port, agent: agent + }, common.mustCall((response) => { + response.resume(); + assert.strictEqual( + response.headers['keep-alive'], 'timeout=50'); + server.close(); + agent.destroy(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-listening.js b/tests/node_compat/test/parallel/test-http-listening.js new file mode 100644 index 0000000000..9963e377b5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-listening.js @@ -0,0 +1,23 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const server = http.createServer(); + +assert.strictEqual(server.listening, false); + +server.listen(0, common.mustCall(() => { + assert.strictEqual(server.listening, true); + + server.close(common.mustCall(() => { + assert.strictEqual(server.listening, false); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-localaddress-bind-error.js b/tests/node_compat/test/parallel/test-http-localaddress-bind-error.js new file mode 100644 index 0000000000..d951652e1b --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-localaddress-bind-error.js @@ -0,0 +1,59 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const invalidLocalAddress = '1.2.3.4'; + +const server = http.createServer(function(req, res) { + console.log(`Connect from: ${req.connection.remoteAddress}`); + + req.on('end', function() { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end(`You are from: ${req.connection.remoteAddress}`); + }); + req.resume(); +}); + +server.listen(0, '127.0.0.1', common.mustCall(function() { + http.request({ + host: 'localhost', + port: this.address().port, + path: '/', + method: 'GET', + localAddress: invalidLocalAddress + }, function(res) { + assert.fail('unexpectedly got response from server'); + }).on('error', common.mustCall(function(e) { + console.log(`client got error: ${e.message}`); + server.close(); + })).end(); +})); diff --git a/tests/node_compat/test/parallel/test-http-methods.js b/tests/node_compat/test/parallel/test-http-methods.js new file mode 100644 index 0000000000..163fb571dd --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-methods.js @@ -0,0 +1,74 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); + +// This test ensures all http methods from HTTP parser are exposed +// to http library + +const methods = [ + 'ACL', + 'BIND', + 'CHECKOUT', + 'CONNECT', + 'COPY', + 'DELETE', + 'GET', + 'HEAD', + 'LINK', + 'LOCK', + 'M-SEARCH', + 'MERGE', + 'MKACTIVITY', + 'MKCALENDAR', + 'MKCOL', + 'MOVE', + 'NOTIFY', + 'OPTIONS', + 'PATCH', + 'POST', + 'PROPFIND', + 'PROPPATCH', + 'PURGE', + 'PUT', + 'REBIND', + 'REPORT', + 'SEARCH', + 'SOURCE', + 'SUBSCRIBE', + 'TRACE', + 'UNBIND', + 'UNLINK', + 'UNLOCK', + 'UNSUBSCRIBE', +]; + +assert.deepStrictEqual(http.METHODS, methods.sort()); diff --git a/tests/node_compat/test/parallel/test-http-outgoing-end-types.js b/tests/node_compat/test/parallel/test-http-outgoing-end-types.js new file mode 100644 index 0000000000..30e466c4a8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-outgoing-end-types.js @@ -0,0 +1,25 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const httpServer = http.createServer(common.mustCall(function(req, res) { + httpServer.close(); + assert.throws(() => { + res.end(['Throws.']); + }, { + code: 'ERR_INVALID_ARG_TYPE' + }); + res.end(); +})); + +httpServer.listen(0, common.mustCall(function() { + http.get({ port: this.address().port }); +})); diff --git a/tests/node_compat/test/parallel/test-http-outgoing-finished.js b/tests/node_compat/test/parallel/test-http-outgoing-finished.js new file mode 100644 index 0000000000..543f4d7c6d --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-outgoing-finished.js @@ -0,0 +1,39 @@ +// 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. + +'use strict'; +const common = require('../common'); +const { finished } = require('stream'); + +const http = require('http'); +const assert = require('assert'); + +const server = http.createServer(function(req, res) { + let closed = false; + res + .on('close', common.mustCall(() => { + closed = true; + finished(res, common.mustCall(() => { + server.close(); + })); + })) + .end(); + finished(res, common.mustCall(() => { + assert.strictEqual(closed, true); + })); + +}).listen(0, function() { + http + .request({ + port: this.address().port, + method: 'GET' + }) + .on('response', function(res) { + res.resume(); + }) + .end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-outgoing-write-types.js b/tests/node_compat/test/parallel/test-http-outgoing-write-types.js new file mode 100644 index 0000000000..101f70581c --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-outgoing-write-types.js @@ -0,0 +1,31 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const httpServer = http.createServer(common.mustCall(function(req, res) { + httpServer.close(); + assert.throws(() => { + res.write(['Throws.']); + }, { + code: 'ERR_INVALID_ARG_TYPE' + }); + // should not throw + res.write('1a2b3c'); + // should not throw + res.write(new Uint8Array(1024)); + // should not throw + res.write(Buffer.from('1'.repeat(1024))); + res.end(); +})); + +httpServer.listen(0, common.mustCall(function() { + http.get({ port: this.address().port }); +})); diff --git a/tests/node_compat/test/parallel/test-http-parser-free.js b/tests/node_compat/test/parallel/test-http-parser-free.js new file mode 100644 index 0000000000..d1fe71e254 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-parser-free.js @@ -0,0 +1,59 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const Countdown = require('../common/countdown'); +const N = 100; + +const server = http.createServer(function(req, res) { + res.end('Hello'); +}); + +const countdown = new Countdown(N, () => server.close()); + +server.listen(0, function() { + http.globalAgent.maxSockets = 1; + let parser; + for (let i = 0; i < N; ++i) { + (function makeRequest(i) { + const req = http.get({ port: server.address().port }, function(res) { + if (!parser) { + parser = req.parser; + } else { + assert.strictEqual(req.parser, parser); + } + + countdown.dec(); + res.resume(); + }); + })(i); + } +}); diff --git a/tests/node_compat/test/parallel/test-http-pause-no-dump.js b/tests/node_compat/test/parallel/test-http-pause-no-dump.js new file mode 100644 index 0000000000..0e9fb6605d --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-pause-no-dump.js @@ -0,0 +1,40 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const server = http.createServer(common.mustCall(function(req, res) { + req.once('data', common.mustCall(() => { + req.pause(); + res.writeHead(200); + res.end(); + res.on('finish', common.mustCall(() => { + assert(!req._dumped); + })); + })); +})); +server.listen(0); + +server.on('listening', common.mustCall(function() { + const req = http.request({ + port: this.address().port, + method: 'POST', + path: '/' + }, common.mustCall(function(res) { + assert.strictEqual(res.statusCode, 200); + res.resume(); + res.on('end', common.mustCall(() => { + server.close(); + })); + })); + + req.end(Buffer.allocUnsafe(1024)); +})); diff --git a/tests/node_compat/test/parallel/test-http-pause-resume-one-end.js b/tests/node_compat/test/parallel/test-http-pause-resume-one-end.js new file mode 100644 index 0000000000..c7b0126e62 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-pause-resume-one-end.js @@ -0,0 +1,62 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const http = require('http'); +const assert = require('assert'); + +const server = http.Server(function(req, res) { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('Hello World\n'); + server.close(); +}); + +server.listen(0, common.mustCall(function() { + const opts = { + port: this.address().port, + headers: { connection: 'close' } + }; + + http.get(opts, common.mustCall(function(res) { + res.on('data', common.mustCall(function() { + res.pause(); + setImmediate(function() { + res.resume(); + }); + })); + + res.on('end', common.mustCall(() => { + assert.strictEqual(res.destroyed, false); + })); + assert.strictEqual(res.destroyed, false); + res.on('close', common.mustCall(() => { + assert.strictEqual(res.destroyed, true); + })); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-pause.js b/tests/node_compat/test/parallel/test-http-pause.js new file mode 100644 index 0000000000..a9e377de90 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-pause.js @@ -0,0 +1,85 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); + +const expectedServer = 'Request Body from Client'; +let resultServer = ''; +const expectedClient = 'Response Body from Server'; +let resultClient = ''; + +const server = http.createServer((req, res) => { + console.error('pause server request'); + req.pause(); + setTimeout(() => { + console.error('resume server request'); + req.resume(); + req.setEncoding('utf8'); + req.on('data', (chunk) => { + resultServer += chunk; + }); + req.on('end', () => { + console.error(resultServer); + res.writeHead(200); + res.end(expectedClient); + }); + }, 100); +}); + +server.listen(0, function() { + // Anonymous function rather than arrow function to test `this` value. + assert.strictEqual(this, server); + const req = http.request({ + port: this.address().port, + path: '/', + method: 'POST' + }, (res) => { + console.error('pause client response'); + res.pause(); + setTimeout(() => { + console.error('resume client response'); + res.resume(); + res.on('data', (chunk) => { + resultClient += chunk; + }); + res.on('end', () => { + console.error(resultClient); + server.close(); + }); + }, 100); + }); + req.end(expectedServer); +}); + +process.on('exit', () => { + assert.strictEqual(resultServer, expectedServer); + assert.strictEqual(resultClient, expectedClient); +}); diff --git a/tests/node_compat/test/parallel/test-http-pipe-fs.js b/tests/node_compat/test/parallel/test-http-pipe-fs.js new file mode 100644 index 0000000000..3fcd2e1f2c --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-pipe-fs.js @@ -0,0 +1,72 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const http = require('http'); +const fs = require('fs'); +const Countdown = require('../common/countdown'); +const NUMBER_OF_STREAMS = 2; + +const countdown = new Countdown(NUMBER_OF_STREAMS, () => server.close()); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const file = tmpdir.resolve('http-pipe-fs-test.txt'); + +const server = http.createServer(common.mustCall(function(req, res) { + const stream = fs.createWriteStream(file); + req.pipe(stream); + stream.on('close', function() { + res.writeHead(200); + res.end(); + }); +}, 2)).listen(0, function() { + http.globalAgent.maxSockets = 1; + + for (let i = 0; i < NUMBER_OF_STREAMS; ++i) { + const req = http.request({ + port: server.address().port, + method: 'POST', + headers: { + 'Content-Length': 5 + } + }, function(res) { + res.on('end', function() { + console.error(`res${i + 1} end`); + countdown.dec(); + }); + res.resume(); + }); + req.on('socket', function(s) { + console.error(`req${i + 1} start`); + }); + req.end('12345'); + } +}); diff --git a/tests/node_compat/test/parallel/test-http-pipeline-requests-connection-leak.js b/tests/node_compat/test/parallel/test-http-pipeline-requests-connection-leak.js new file mode 100644 index 0000000000..3a5498113b --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-pipeline-requests-connection-leak.js @@ -0,0 +1,41 @@ +// 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. + +'use strict'; +require('../common'); +const Countdown = require('../common/countdown'); + +// This test ensures Node.js doesn't behave erratically when receiving pipelined +// requests +// https://github.com/nodejs/node/issues/3332 + +const http = require('http'); +const net = require('net'); + +const big = Buffer.alloc(16 * 1024, 'A'); + +const COUNT = 1e4; + +const countdown = new Countdown(COUNT, () => { + server.close(); + client.end(); +}); + +let client; +const server = http + .createServer(function(req, res) { + res.end(big, function() { + countdown.dec(); + }); + }) + .listen(0, function() { + const req = 'GET / HTTP/1.1\r\nHost: example.com\r\n\r\n'.repeat(COUNT); + client = net.connect(this.address().port, function() { + client.write(req); + }); + client.resume(); + }); diff --git a/tests/node_compat/test/parallel/test-http-proxy.js b/tests/node_compat/test/parallel/test-http-proxy.js new file mode 100644 index 0000000000..a457275239 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-proxy.js @@ -0,0 +1,114 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +const cookies = [ + 'session_token=; path=/; expires=Sun, 15-Sep-2030 13:48:52 GMT', + 'prefers_open_id=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT', +]; + +const headers = { 'content-type': 'text/plain', + 'set-cookie': cookies, + 'hello': 'world' }; + +const backend = http.createServer(function(req, res) { + console.error('backend request'); + res.writeHead(200, headers); + res.write('hello world\n'); + res.end(); +}); + +const proxy = http.createServer(function(req, res) { + console.error(`proxy req headers: ${JSON.stringify(req.headers)}`); + http.get({ + port: backend.address().port, + path: url.parse(req.url).pathname + }, function(proxy_res) { + + console.error(`proxy res headers: ${JSON.stringify(proxy_res.headers)}`); + + assert.strictEqual(proxy_res.headers.hello, 'world'); + assert.strictEqual(proxy_res.headers['content-type'], 'text/plain'); + assert.deepStrictEqual(proxy_res.headers['set-cookie'], cookies); + + res.writeHead(proxy_res.statusCode, proxy_res.headers); + + proxy_res.on('data', function(chunk) { + res.write(chunk); + }); + + proxy_res.on('end', function() { + res.end(); + console.error('proxy res'); + }); + }); +}); + +let body = ''; + +let nlistening = 0; +function startReq() { + nlistening++; + if (nlistening < 2) return; + + http.get({ + port: proxy.address().port, + path: '/test' + }, function(res) { + console.error('got res'); + assert.strictEqual(res.statusCode, 200); + + assert.strictEqual(res.headers.hello, 'world'); + assert.strictEqual(res.headers['content-type'], 'text/plain'); + assert.deepStrictEqual(res.headers['set-cookie'], cookies); + + res.setEncoding('utf8'); + res.on('data', function(chunk) { body += chunk; }); + res.on('end', function() { + proxy.close(); + backend.close(); + console.error('closed both'); + }); + }); + console.error('client req'); +} + +console.error('listen proxy'); +proxy.listen(0, startReq); + +console.error('listen backend'); +backend.listen(0, startReq); + +process.on('exit', function() { + assert.strictEqual(body, 'hello world\n'); +}); diff --git a/tests/node_compat/test/parallel/test-http-readable-data-event.js b/tests/node_compat/test/parallel/test-http-readable-data-event.js new file mode 100644 index 0000000000..6c91ebe526 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-readable-data-event.js @@ -0,0 +1,65 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const helloWorld = 'Hello World!'; +const helloAgainLater = 'Hello again later!'; + +let next = null; + +const server = http.createServer((req, res) => { + res.writeHead(200, { + 'Content-Length': `${(helloWorld.length + helloAgainLater.length)}` + }); + + // We need to make sure the data is flushed + // before writing again + next = () => { + res.end(helloAgainLater); + next = () => { }; + }; + + res.write(helloWorld); +}).listen(0, function() { + const opts = { + hostname: 'localhost', + port: server.address().port, + path: '/' + }; + + const expectedData = [helloWorld, helloAgainLater]; + const expectedRead = [helloWorld, null, helloAgainLater, null, null]; + + const req = http.request(opts, (res) => { + res.on('error', common.mustNotCall()); + + res.on('readable', common.mustCall(() => { + let data; + + do { + data = res.read(); + assert.strictEqual(data, expectedRead.shift()); + next(); + } while (data !== null); + }, 3)); + + res.setEncoding('utf8'); + res.on('data', common.mustCall((data) => { + assert.strictEqual(data, expectedData.shift()); + }, 2)); + + res.on('end', common.mustCall(() => { + server.close(); + })); + }); + + req.end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-request-arguments.js b/tests/node_compat/test/parallel/test-http-request-arguments.js new file mode 100644 index 0000000000..d15bfc40ea --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-request-arguments.js @@ -0,0 +1,35 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +// Test providing both a url and options, with the options partially +// replacing address and port portions of the URL provided. +{ + const server = http.createServer( + common.mustCall((req, res) => { + assert.strictEqual(req.url, '/testpath'); + res.end(); + server.close(); + }) + ); + server.listen( + 0, + common.mustCall(() => { + http.get( + 'http://example.com/testpath', + { hostname: 'localhost', port: server.address().port }, + common.mustCall((res) => { + res.resume(); + }) + ); + }) + ); +} diff --git a/tests/node_compat/test/parallel/test-http-request-dont-override-options.js b/tests/node_compat/test/parallel/test-http-request-dont-override-options.js new file mode 100644 index 0000000000..caa87bd953 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-request-dont-override-options.js @@ -0,0 +1,47 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + + +const server = http.createServer(common.mustCall(function(req, res) { + res.writeHead(200); + res.end('ok'); +})); + +server.listen(0, function() { + const agent = new http.Agent(); + agent.defaultPort = this.address().port; + + // Options marked as explicitly undefined for readability + // in this test, they should STAY undefined as options should not + // be mutable / modified + const options = { + host: undefined, + hostname: common.localhostIPv4, + port: undefined, + defaultPort: undefined, + path: undefined, + method: undefined, + agent: agent + }; + + http.request(options, function(res) { + res.resume(); + server.close(); + assert.strictEqual(options.host, undefined); + assert.strictEqual(options.hostname, common.localhostIPv4); + assert.strictEqual(options.port, undefined); + assert.strictEqual(options.defaultPort, undefined); + assert.strictEqual(options.path, undefined); + assert.strictEqual(options.method, undefined); + }).end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-request-end-twice.js b/tests/node_compat/test/parallel/test-http-request-end-twice.js new file mode 100644 index 0000000000..34c3aee390 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-request-end-twice.js @@ -0,0 +1,46 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); + +const server = http.Server(function(req, res) { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('hello world\n'); +}); +server.listen(0, function() { + const req = http.get({ port: this.address().port }, function(res) { + res.on('end', function() { + assert.strictEqual(req.end(), req); + server.close(); + }); + res.resume(); + }); +}); diff --git a/tests/node_compat/test/parallel/test-http-request-end.js b/tests/node_compat/test/parallel/test-http-request-end.js new file mode 100644 index 0000000000..4c71cd1432 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-request-end.js @@ -0,0 +1,69 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); + +const expected = 'Post Body For Test'; + +const server = http.Server(function(req, res) { + let result = ''; + + req.setEncoding('utf8'); + req.on('data', function(chunk) { + result += chunk; + }); + + req.on('end', function() { + assert.strictEqual(result, expected); + res.writeHead(200); + res.end('hello world\n'); + server.close(); + }); + +}); + +server.listen(0, function() { + const req = http.request({ + port: this.address().port, + path: '/', + method: 'POST' + }, function(res) { + console.log(res.statusCode); + res.resume(); + }).on('error', function(e) { + console.log(e.message); + process.exit(1); + }); + + const result = req.end(expected); + + assert.strictEqual(req, result); +}); diff --git a/tests/node_compat/test/parallel/test-http-request-invalid-method-error.js b/tests/node_compat/test/parallel/test-http-request-invalid-method-error.js new file mode 100644 index 0000000000..570966056e --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-request-invalid-method-error.js @@ -0,0 +1,20 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); + +assert.throws( + () => http.request({ method: '\0' }), + { + code: 'ERR_INVALID_HTTP_TOKEN', + name: 'TypeError', + message: 'Method must be a valid HTTP token ["\u0000"]' + } +); diff --git a/tests/node_compat/test/parallel/test-http-request-large-payload.js b/tests/node_compat/test/parallel/test-http-request-large-payload.js new file mode 100644 index 0000000000..80e36297eb --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-request-large-payload.js @@ -0,0 +1,33 @@ +// 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. + +'use strict'; +require('../common'); + +// This test ensures Node.js doesn't throw an error when making requests with +// the payload 16kb or more in size. +// https://github.com/nodejs/node/issues/2821 + +const http = require('http'); + +const server = http.createServer(function(req, res) { + res.writeHead(200); + res.end(); + + server.close(); +}); + +server.listen(0, function() { + const req = http.request({ + method: 'POST', + port: this.address().port + }); + + const payload = Buffer.alloc(16390, 'Й'); + req.write(payload); + req.end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-request-methods.js b/tests/node_compat/test/parallel/test-http-request-methods.js new file mode 100644 index 0000000000..69fb7aa5b1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-request-methods.js @@ -0,0 +1,72 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); +const http = require('http'); + +// Test that the DELETE, PATCH and PURGE verbs get passed through correctly + +['DELETE', 'PATCH', 'PURGE'].forEach(function(method, index) { + const server = http.createServer(common.mustCall(function(req, res) { + assert.strictEqual(req.method, method); + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write('hello '); + res.write('world\n'); + res.end(); + })); + server.listen(0); + + server.on('listening', common.mustCall(function() { + const c = net.createConnection(this.address().port); + let server_response = ''; + + c.setEncoding('utf8'); + + c.on('connect', function() { + c.write(`${method} / HTTP/1.0\r\n\r\n`); + }); + + c.on('data', function(chunk) { + console.log(chunk); + server_response += chunk; + }); + + c.on('end', common.mustCall(function() { + const m = server_response.split('\r\n\r\n'); + assert.strictEqual(m[1], 'hello world\n'); + c.end(); + })); + + c.on('close', function() { + server.close(); + }); + })); +}); diff --git a/tests/node_compat/test/parallel/test-http-res-write-end-dont-take-array.js b/tests/node_compat/test/parallel/test-http-res-write-end-dont-take-array.js new file mode 100644 index 0000000000..8d99963823 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-res-write-end-dont-take-array.js @@ -0,0 +1,80 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const server = http.createServer(); + +server.once('request', common.mustCall((req, res) => { + server.on('request', common.mustCall((req, res) => { + res.end(Buffer.from('asdf')); + })); + // `res.write()` should accept `string`. + res.write('string'); + // `res.write()` should accept `buffer`. + res.write(Buffer.from('asdf')); + + const expectedError = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + }; + + // `res.write()` should not accept an Array. + assert.throws( + () => { + res.write(['array']); + }, + expectedError + ); + + // `res.end()` should not accept an Array. + assert.throws( + () => { + res.end(['moo']); + }, + expectedError + ); + + // `res.end()` should accept `string`. + res.end('string'); +})); + +server.listen(0, function() { + // Just make a request, other tests handle responses. + http.get({ port: this.address().port }, (res) => { + res.resume(); + // Do it again to test .end(Buffer); + http.get({ port: server.address().port }, (res) => { + res.resume(); + server.close(); + }); + }); +}); diff --git a/tests/node_compat/test/parallel/test-http-response-multiheaders.js b/tests/node_compat/test/parallel/test-http-response-multiheaders.js new file mode 100644 index 0000000000..27bfbcdca5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-response-multiheaders.js @@ -0,0 +1,78 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const http = require('http'); +const assert = require('assert'); +const Countdown = require('../common/countdown'); + +// Test that certain response header fields do not repeat. +// 'content-length' should also be in this list but it is +// handled differently because multiple content-lengths are +// an error (see test-http-response-multi-content-length.js). +const norepeat = [ + 'content-type', + 'user-agent', + 'referer', + 'host', + 'authorization', + 'proxy-authorization', + 'if-modified-since', + 'if-unmodified-since', + 'from', + 'location', + 'max-forwards', + 'retry-after', + 'etag', + 'last-modified', + 'server', + 'age', + 'expires', +]; +const runCount = 2; + +const server = http.createServer(function(req, res) { + const num = req.headers['x-num']; + if (num === '1') { + for (const name of norepeat) { + res.setHeader(name, ['A', 'B']); + } + res.setHeader('X-A', ['A', 'B']); + } else if (num === '2') { + const headers = {}; + for (const name of norepeat) { + headers[name] = ['A', 'B']; + } + headers['X-A'] = ['A', 'B']; + res.writeHead(200, headers); + } + res.end('ok'); +}); + +server.listen(0, common.mustCall(function() { + const countdown = new Countdown(runCount, () => server.close()); + for (let n = 1; n <= runCount; n++) { + // This runs twice, the first time, the server will use + // setHeader, the second time it uses writeHead. The + // result on the client side should be the same in + // either case -- only the first instance of the header + // value should be reported for the header fields listed + // in the norepeat array. + http.get( + { port: this.address().port, headers: { 'x-num': n } }, + common.mustCall(function(res) { + countdown.dec(); + for (const name of norepeat) { + assert.strictEqual(res.headers[name], 'A'); + } + assert.strictEqual(res.headers['x-a'], 'A, B'); + }) + ); + } +})); diff --git a/tests/node_compat/test/parallel/test-http-response-readable.js b/tests/node_compat/test/parallel/test-http-response-readable.js new file mode 100644 index 0000000000..3d2ca1a859 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-response-readable.js @@ -0,0 +1,48 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); + +const testServer = new http.Server(function(req, res) { + res.writeHead(200); + res.end('Hello world'); +}); + +testServer.listen(0, function() { + http.get({ port: this.address().port }, function(res) { + assert.strictEqual(res.readable, true); + res.on('end', function() { + assert.strictEqual(res.readable, false); + testServer.close(); + }); + res.resume(); + }); +}); diff --git a/tests/node_compat/test/parallel/test-http-response-writehead-returns-this.js b/tests/node_compat/test/parallel/test-http-response-writehead-returns-this.js new file mode 100644 index 0000000000..a9796890f4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-response-writehead-returns-this.js @@ -0,0 +1,29 @@ +// 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. + +'use strict'; +require('../common'); +const http = require('http'); +const assert = require('assert'); + +const server = http.createServer((req, res) => { + res.writeHead(200, { 'a-header': 'a-header-value' }).end('abc'); +}); + +server.listen(0, () => { + http.get({ port: server.address().port }, (res) => { + assert.strictEqual(res.headers['a-header'], 'a-header-value'); + + const chunks = []; + + res.on('data', (chunk) => chunks.push(chunk)); + res.on('end', () => { + assert.strictEqual(Buffer.concat(chunks).toString(), 'abc'); + server.close(); + }); + }); +}); diff --git a/tests/node_compat/test/parallel/test-http-server-delete-parser.js b/tests/node_compat/test/parallel/test-http-server-delete-parser.js new file mode 100644 index 0000000000..fbb242366f --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-server-delete-parser.js @@ -0,0 +1,31 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +const http = require('http'); + +const server = http.createServer(common.mustCall((req, res) => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write('okay', common.mustCall(() => { + delete res.socket.parser; + })); + res.end(); +})); + +server.listen(0, '127.0.0.1', common.mustCall(() => { + const req = http.request({ + port: server.address().port, + host: '127.0.0.1', + method: 'GET', + }); + req.end(); +})); + +server.unref(); diff --git a/tests/node_compat/test/parallel/test-http-server-write-after-end.js b/tests/node_compat/test/parallel/test-http-server-write-after-end.js new file mode 100644 index 0000000000..c7e0cb48eb --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-server-write-after-end.js @@ -0,0 +1,36 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const http = require('http'); + +// Fix for https://github.com/nodejs/node/issues/14368 + +const server = http.createServer(handle); + +function handle(req, res) { + res.on('error', common.mustNotCall()); + + res.write('hello'); + res.end(); + + setImmediate(common.mustCall(() => { + res.write('world', common.mustCall((err) => { + common.expectsError({ + code: 'ERR_STREAM_WRITE_AFTER_END', + name: 'Error' + })(err); + server.close(); + })); + })); +} + +server.listen(0, common.mustCall(() => { + http.get(`http://localhost:${server.address().port}`); +})); diff --git a/tests/node_compat/test/parallel/test-http-server-write-end-after-end.js b/tests/node_compat/test/parallel/test-http-server-write-end-after-end.js new file mode 100644 index 0000000000..eb05ea93cc --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-server-write-end-after-end.js @@ -0,0 +1,38 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const http = require('http'); + +const server = http.createServer(handle); + +function handle(req, res) { + res.on('error', common.mustNotCall()); + + res.write('hello'); + res.end(); + + setImmediate(common.mustCall(() => { + res.end('world'); + process.nextTick(() => { + server.close(); + }); + res.write('world', common.mustCall((err) => { + common.expectsError({ + code: 'ERR_STREAM_WRITE_AFTER_END', + name: 'Error' + })(err); + server.close(); + })); + })); +} + +server.listen(0, common.mustCall(() => { + http.get(`http://localhost:${server.address().port}`); +})); diff --git a/tests/node_compat/test/parallel/test-http-set-cookies.js b/tests/node_compat/test/parallel/test-http-set-cookies.js new file mode 100644 index 0000000000..d8c7627b7a --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-set-cookies.js @@ -0,0 +1,84 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const Countdown = require('../common/countdown'); + +const countdown = new Countdown(2, () => server.close()); +const server = http.createServer(function(req, res) { + if (req.url === '/one') { + res.writeHead(200, [['set-cookie', 'A'], + ['content-type', 'text/plain']]); + res.end('one\n'); + } else { + res.writeHead(200, [['set-cookie', 'A'], + ['set-cookie', 'B'], + ['content-type', 'text/plain']]); + res.end('two\n'); + } +}); +server.listen(0); + +server.on('listening', function() { + // + // one set-cookie header + // + http.get({ port: this.address().port, path: '/one' }, function(res) { + // set-cookie headers are always return in an array. + // even if there is only one. + assert.deepStrictEqual(res.headers['set-cookie'], ['A']); + assert.strictEqual(res.headers['content-type'], 'text/plain'); + + res.on('data', function(chunk) { + console.log(chunk.toString()); + }); + + res.on('end', function() { + countdown.dec(); + }); + }); + + // Two set-cookie headers + + http.get({ port: this.address().port, path: '/two' }, function(res) { + assert.deepStrictEqual(res.headers['set-cookie'], ['A', 'B']); + assert.strictEqual(res.headers['content-type'], 'text/plain'); + + res.on('data', function(chunk) { + console.log(chunk.toString()); + }); + + res.on('end', function() { + countdown.dec(); + }); + }); + +}); diff --git a/tests/node_compat/test/parallel/test-http-set-header-chain.js b/tests/node_compat/test/parallel/test-http-set-header-chain.js new file mode 100644 index 0000000000..80f59711ae --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-set-header-chain.js @@ -0,0 +1,36 @@ +// 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. + +'use strict'; +const common = require('../common'); +const http = require('http'); +const assert = require('assert'); +const expected = { + '__proto__': null, + 'testheader1': 'foo', + 'testheader2': 'bar', + 'testheader3': 'xyz' +}; +const server = http.createServer(common.mustCall((req, res) => { + let retval = res.setHeader('testheader1', 'foo'); + + // Test that the setHeader returns the same response object. + assert.strictEqual(retval, res); + + retval = res.setHeader('testheader2', 'bar').setHeader('testheader3', 'xyz'); + // Test that chaining works for setHeader. + assert.deepStrictEqual(res.getHeaders(), expected); + res.end('ok'); +})); +server.listen(0, () => { + http.get({ port: server.address().port }, common.mustCall((res) => { + res.on('data', () => {}); + res.on('end', common.mustCall(() => { + server.close(); + })); + })); +}); diff --git a/tests/node_compat/test/parallel/test-http-status-code.js b/tests/node_compat/test/parallel/test-http-status-code.js new file mode 100644 index 0000000000..7880864006 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-status-code.js @@ -0,0 +1,65 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const Countdown = require('../common/countdown'); + +// Simple test of Node's HTTP ServerResponse.statusCode +// ServerResponse.prototype.statusCode + +const tests = [200, 202, 300, 404, 451, 500]; +let test; +const countdown = new Countdown(tests.length, () => s.close()); + +const s = http.createServer(function(req, res) { + res.writeHead(test, { 'Content-Type': 'text/plain' }); + console.log(`--\nserver: statusCode after writeHead: ${res.statusCode}`); + assert.strictEqual(res.statusCode, test); + res.end('hello world\n'); +}); + +s.listen(0, nextTest); + + +function nextTest() { + test = tests.shift(); + + http.get({ port: s.address().port }, function(response) { + console.log(`client: expected status: ${test}`); + console.log(`client: statusCode: ${response.statusCode}`); + assert.strictEqual(response.statusCode, test); + response.on('end', function() { + if (countdown.dec()) + nextTest(); + }); + response.resume(); + }); +} diff --git a/tests/node_compat/test/parallel/test-http-status-reason-invalid-chars.js b/tests/node_compat/test/parallel/test-http-status-reason-invalid-chars.js new file mode 100644 index 0000000000..cdf36c7cf6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-status-reason-invalid-chars.js @@ -0,0 +1,54 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const Countdown = require('../common/countdown'); + +function explicit(req, res) { + assert.throws(() => { + res.writeHead(200, 'OK\r\nContent-Type: text/html\r\n'); + }, /Invalid character in statusMessage/); + + assert.throws(() => { + res.writeHead(200, 'OK\u010D\u010AContent-Type: gotcha\r\n'); + }, /Invalid character in statusMessage/); + + res.statusMessage = 'OK'; + res.end(); +} + +function implicit(req, res) { + assert.throws(() => { + res.statusMessage = 'OK\r\nContent-Type: text/html\r\n'; + res.writeHead(200); + }, /Invalid character in statusMessage/); + res.statusMessage = 'OK'; + res.end(); +} + +const server = http.createServer((req, res) => { + if (req.url === '/explicit') { + explicit(req, res); + } else { + implicit(req, res); + } +}).listen(0, common.mustCall(() => { + const hostname = 'localhost'; + const countdown = new Countdown(2, () => server.close()); + const url = `http://${hostname}:${server.address().port}`; + const check = common.mustCall((res) => { + assert.notStrictEqual(res.headers['content-type'], 'text/html'); + assert.notStrictEqual(res.headers['content-type'], 'gotcha'); + countdown.dec(); + }, 2); + http.get(`${url}/explicit`, check).end(); + http.get(`${url}/implicit`, check).end(); +})); diff --git a/tests/node_compat/test/parallel/test-http-uncaught-from-request-callback.js b/tests/node_compat/test/parallel/test-http-uncaught-from-request-callback.js new file mode 100644 index 0000000000..32185e57dc --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-uncaught-from-request-callback.js @@ -0,0 +1,36 @@ +// 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. + +'use strict'; +const common = require('../common'); +const asyncHooks = require('async_hooks'); +const http = require('http'); + +// Regression test for https://github.com/nodejs/node/issues/31796 + +asyncHooks.createHook({ + after: () => {} +}).enable(); + + +process.once('uncaughtException', common.mustCall(() => { + server.close(); +})); + +const server = http.createServer(common.mustCall((request, response) => { + response.writeHead(200, { 'Content-Type': 'text/plain' }); + response.end(); +})); + +server.listen(0, common.mustCall(() => { + http.get({ + host: 'localhost', + port: server.address().port + }, common.mustCall(() => { + throw new Error('whoah'); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-url.parse-auth.js b/tests/node_compat/test/parallel/test-http-url.parse-auth.js new file mode 100644 index 0000000000..9c80578338 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-url.parse-auth.js @@ -0,0 +1,55 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +function check(request) { + // The correct authorization header is be passed + assert.strictEqual(request.headers.authorization, 'Basic dXNlcjpwYXNzOg=='); +} + +const server = http.createServer(function(request, response) { + // Run the check function + check(request); + response.writeHead(200, {}); + response.end('ok'); + server.close(); +}); + +server.listen(0, function() { + const port = this.address().port; + // username = "user", password = "pass:" + const testURL = url.parse(`http://user:pass%3A@localhost:${port}`); + + // make the request + http.request(testURL).end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-url.parse-basic.js b/tests/node_compat/test/parallel/test-http-url.parse-basic.js new file mode 100644 index 0000000000..62fa40431f --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-url.parse-basic.js @@ -0,0 +1,65 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +let testURL; + +// Make sure the basics work +function check(request) { + // Default method should still be 'GET' + assert.strictEqual(request.method, 'GET'); + // There are no URL params, so you should not see any + assert.strictEqual(request.url, '/'); + // The host header should use the url.parse.hostname + assert.strictEqual(request.headers.host, + `${testURL.hostname}:${testURL.port}`); +} + +const server = http.createServer(function(request, response) { + // Run the check function + check(request); + response.writeHead(200, {}); + response.end('ok'); + server.close(); +}); + +server.listen(0, function() { + testURL = url.parse(`http://localhost:${this.address().port}`); + + // make the request + const clientRequest = http.request(testURL); + // Since there is a little magic with the agent + // make sure that an http request uses the http.Agent + assert.ok(clientRequest.agent instanceof http.Agent); + clientRequest.end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-url.parse-path.js b/tests/node_compat/test/parallel/test-http-url.parse-path.js new file mode 100644 index 0000000000..1fb44adf62 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-url.parse-path.js @@ -0,0 +1,53 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +function check(request) { + // A path should come over + assert.strictEqual(request.url, '/asdf'); +} + +const server = http.createServer(function(request, response) { + // Run the check function + check(request); + response.writeHead(200, {}); + response.end('ok'); + server.close(); +}); + +server.listen(0, function() { + const testURL = url.parse(`http://localhost:${this.address().port}/asdf`); + + // make the request + http.request(testURL).end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-url.parse-post.js b/tests/node_compat/test/parallel/test-http-url.parse-post.js new file mode 100644 index 0000000000..1756191379 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-url.parse-post.js @@ -0,0 +1,61 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +let testURL; + +function check(request) { + // url.parse should not mess with the method + assert.strictEqual(request.method, 'POST'); + // Everything else should be right + assert.strictEqual(request.url, '/asdf?qwer=zxcv'); + // The host header should use the url.parse.hostname + assert.strictEqual(request.headers.host, + `${testURL.hostname}:${testURL.port}`); +} + +const server = http.createServer(function(request, response) { + // Run the check function + check(request); + response.writeHead(200, {}); + response.end('ok'); + server.close(); +}); + +server.listen(0, function() { + testURL = url.parse(`http://localhost:${this.address().port}/asdf?qwer=zxcv`); + testURL.method = 'POST'; + + // make the request + http.request(testURL).end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-url.parse-search.js b/tests/node_compat/test/parallel/test-http-url.parse-search.js new file mode 100644 index 0000000000..181e1a1fdc --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-url.parse-search.js @@ -0,0 +1,54 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const http = require('http'); +const url = require('url'); + +function check(request) { + // A path should come over with params + assert.strictEqual(request.url, '/asdf?qwer=zxcv'); +} + +const server = http.createServer(function(request, response) { + // Run the check function + check(request); + response.writeHead(200, {}); + response.end('ok'); + server.close(); +}); + +server.listen(0, function() { + const port = this.address().port; + const testURL = url.parse(`http://localhost:${port}/asdf?qwer=zxcv`); + + // make the request + http.request(testURL).end(); +}); diff --git a/tests/node_compat/test/parallel/test-http-wget.js b/tests/node_compat/test/parallel/test-http-wget.js new file mode 100644 index 0000000000..ea31a22acb --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-wget.js @@ -0,0 +1,85 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); +const http = require('http'); + +// `wget` sends an HTTP/1.0 request with Connection: Keep-Alive +// +// Sending back a chunked response to an HTTP/1.0 client would be wrong, +// so what has to happen in this case is that the connection is closed +// by the server after the entity body if the Content-Length was not +// sent. +// +// If the Content-Length was sent, we can probably safely honor the +// keep-alive request, even though HTTP 1.0 doesn't say that the +// connection can be kept open. Presumably any client sending this +// header knows that it is extending HTTP/1.0 and can handle the +// response. We don't test that here however, just that if the +// content-length is not provided, that the connection is in fact +// closed. + +const server = http.createServer((req, res) => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write('hello '); + res.write('world\n'); + res.end(); +}); +server.listen(0); + +server.on('listening', common.mustCall(() => { + const c = net.createConnection(server.address().port); + let server_response = ''; + + c.setEncoding('utf8'); + + c.on('connect', () => { + c.write('GET / HTTP/1.0\r\n' + + 'Connection: Keep-Alive\r\n\r\n'); + }); + + c.on('data', (chunk) => { + console.log(chunk); + server_response += chunk; + }); + + c.on('end', common.mustCall(() => { + const m = server_response.split('\r\n\r\n'); + assert.strictEqual(m[1], 'hello world\n'); + console.log('got end'); + c.end(); + })); + + c.on('close', common.mustCall(() => { + console.log('got close'); + server.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-write-empty-string.js b/tests/node_compat/test/parallel/test-http-write-empty-string.js new file mode 100644 index 0000000000..362a2a5cbf --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-write-empty-string.js @@ -0,0 +1,61 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const http = require('http'); + +const server = http.createServer(function(request, response) { + console.log(`responding to ${request.url}`); + + response.writeHead(200, { 'Content-Type': 'text/plain' }); + response.write('1\n'); + response.write(''); + response.write('2\n'); + response.write(''); + response.end('3\n'); + + this.close(); +}); + +server.listen(0, common.mustCall(() => { + http.get({ port: server.address().port }, common.mustCall((res) => { + let response = ''; + + assert.strictEqual(res.statusCode, 200); + res.setEncoding('ascii'); + res.on('data', (chunk) => { + response += chunk; + }); + res.on('end', common.mustCall(() => { + assert.strictEqual(response, '1\n2\n3\n'); + })); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http-zerolengthbuffer.js b/tests/node_compat/test/parallel/test-http-zerolengthbuffer.js new file mode 100644 index 0000000000..ff41874fa6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http-zerolengthbuffer.js @@ -0,0 +1,30 @@ +// 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. + +'use strict'; +// Serving up a zero-length buffer should work. + +const common = require('../common'); +const http = require('http'); + +const server = http.createServer((req, res) => { + const buffer = Buffer.alloc(0); + res.writeHead(200, { 'Content-Type': 'text/html', + 'Content-Length': buffer.length }); + res.end(buffer); +}); + +server.listen(0, common.mustCall(() => { + http.get({ port: server.address().port }, common.mustCall((res) => { + + res.on('data', common.mustNotCall()); + + res.on('end', (d) => { + server.close(); + }); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http2-client-request-listeners-warning.js b/tests/node_compat/test/parallel/test-http2-client-request-listeners-warning.js new file mode 100644 index 0000000000..0d1f5e07a8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-client-request-listeners-warning.js @@ -0,0 +1,48 @@ +// 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. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const http2 = require('http2'); +const EventEmitter = require('events'); + +// This test ensures that a MaxListenersExceededWarning isn't emitted if +// more than EventEmitter.defaultMaxListeners requests are started on a +// ClientHttp2Session before it has finished connecting. + +process.on('warning', common.mustNotCall('A warning was emitted')); + +const server = http2.createServer(); +server.on('stream', (stream) => { + stream.respond(); + stream.end(); +}); + +server.listen(common.mustCall(() => { + const client = http2.connect(`http://localhost:${server.address().port}`); + + function request() { + return new Promise((resolve, reject) => { + const stream = client.request(); + stream.on('error', reject); + stream.on('response', resolve); + stream.end(); + }); + } + + const requests = []; + for (let i = 0; i < EventEmitter.defaultMaxListeners + 1; i++) { + requests.push(request()); + } + + Promise.all(requests).then(common.mustCall()).finally(common.mustCall(() => { + server.close(); + client.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http2-compat-expect-handling.js b/tests/node_compat/test/parallel/test-http2-compat-expect-handling.js new file mode 100644 index 0000000000..074c76680a --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-compat-expect-handling.js @@ -0,0 +1,52 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); + +const expectValue = 'meoww'; + +const server = http2.createServer(common.mustNotCall()); + +server.once('checkExpectation', common.mustCall((req, res) => { + assert.strictEqual(req.headers.expect, expectValue); + res.statusCode = 417; + res.end(); +})); + +server.listen(0, common.mustCall(() => nextTest(2))); + +function nextTest(testsToRun) { + if (!testsToRun) { + return server.close(); + } + + const port = server.address().port; + const client = http2.connect(`http://localhost:${port}`); + const req = client.request({ + ':path': '/', + ':method': 'GET', + ':scheme': 'http', + ':authority': `localhost:${port}`, + 'expect': expectValue + }); + + req.on('response', common.mustCall((headers) => { + assert.strictEqual(headers[':status'], 417); + req.resume(); + })); + + req.on('end', common.mustCall(() => { + client.close(); + nextTest(testsToRun - 1); + })); +} diff --git a/tests/node_compat/test/parallel/test-http2-compat-socket-set.js b/tests/node_compat/test/parallel/test-http2-compat-socket-set.js new file mode 100644 index 0000000000..1346226863 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-compat-socket-set.js @@ -0,0 +1,104 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const h2 = require('http2'); + +// Tests behavior of the proxied socket in Http2ServerRequest +// & Http2ServerResponse - specifically property setters + +const errMsg = { + code: 'ERR_HTTP2_NO_SOCKET_MANIPULATION', + name: 'Error', + message: 'HTTP/2 sockets should not be directly manipulated ' + + '(e.g. read and written)' +}; + +const server = h2.createServer(); + +server.on('request', common.mustCall(function(request, response) { + const noop = () => {}; + + assert.strictEqual(request.stream.destroyed, false); + request.socket.destroyed = true; + assert.strictEqual(request.stream.destroyed, true); + request.socket.destroyed = false; + + assert.strictEqual(request.stream.readable, true); + request.socket.readable = false; + assert.strictEqual(request.stream.readable, false); + + assert.strictEqual(request.stream.writable, true); + request.socket.writable = false; + assert.strictEqual(request.stream.writable, false); + + const realOn = request.stream.on; + request.socket.on = noop; + assert.strictEqual(request.stream.on, noop); + request.stream.on = realOn; + + const realOnce = request.stream.once; + request.socket.once = noop; + assert.strictEqual(request.stream.once, noop); + request.stream.once = realOnce; + + const realEnd = request.stream.end; + request.socket.end = noop; + assert.strictEqual(request.stream.end, noop); + request.socket.end = common.mustCall(); + request.socket.end(); + request.stream.end = realEnd; + + const realEmit = request.stream.emit; + request.socket.emit = noop; + assert.strictEqual(request.stream.emit, noop); + request.stream.emit = realEmit; + + const realDestroy = request.stream.destroy; + request.socket.destroy = noop; + assert.strictEqual(request.stream.destroy, noop); + request.stream.destroy = realDestroy; + + request.socket.setTimeout = noop; + assert.strictEqual(request.stream.session.setTimeout, noop); + + assert.strictEqual(request.stream.session.socket._isProcessing, undefined); + request.socket._isProcessing = true; + assert.strictEqual(request.stream.session.socket._isProcessing, true); + + assert.throws(() => request.socket.read = noop, errMsg); + assert.throws(() => request.socket.write = noop, errMsg); + assert.throws(() => request.socket.pause = noop, errMsg); + assert.throws(() => request.socket.resume = noop, errMsg); + + response.stream.destroy(); +})); + +server.listen(0, common.mustCall(function() { + const port = server.address().port; + const url = `http://localhost:${port}`; + const client = h2.connect(url, common.mustCall(function() { + const headers = { + ':path': '/', + ':method': 'GET', + ':scheme': 'http', + ':authority': `localhost:${port}` + }; + const request = client.request(headers); + request.on('end', common.mustCall(() => { + client.close(); + server.close(); + })); + request.end(); + request.resume(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http2-connect-options.js b/tests/node_compat/test/parallel/test-http2-connect-options.js new file mode 100644 index 0000000000..fa9272ff33 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-connect-options.js @@ -0,0 +1,48 @@ +// 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.hasCrypto) + common.skip('missing crypto'); + +if (!common.hasMultiLocalhost()) + common.skip('platform-specific test.'); + +const http2 = require('http2'); +const assert = require('assert'); + +const server = http2.createServer((req, res) => { + console.log(`Connect from: ${req.connection.remoteAddress}`); + assert.strictEqual(req.connection.remoteAddress, '127.0.0.2'); + + req.on('end', common.mustCall(() => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end(`You are from: ${req.connection.remoteAddress}`); + })); + req.resume(); +}); + +server.listen(0, '127.0.0.1', common.mustCall(() => { + const options = { localAddress: '127.0.0.2', family: 4 }; + + const client = http2.connect( + 'http://localhost:' + server.address().port, + options + ); + const req = client.request({ + ':path': '/' + }); + req.on('data', () => req.resume()); + req.on('end', common.mustCall(function() { + client.close(); + req.close(); + server.close(); + })); + req.end(); +})); diff --git a/tests/node_compat/test/parallel/test-http2-date-header.js b/tests/node_compat/test/parallel/test-http2-date-header.js new file mode 100644 index 0000000000..0a8b9c9df3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-date-header.js @@ -0,0 +1,36 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); + +const server = http2.createServer(); + +server.on('stream', common.mustCall((stream) => { + // Date header is defaulted + stream.respond(); + stream.end(); +})); + +server.listen(0, common.mustCall(() => { + const client = http2.connect(`http://localhost:${server.address().port}`); + const req = client.request(); + req.on('response', common.mustCall((headers) => { + // The date header must be set to a non-invalid value + assert.notStrictEqual((new Date()).toString(), 'Invalid Date'); + })); + req.resume(); + req.on('end', common.mustCall(() => { + server.close(); + client.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http2-dont-override.js b/tests/node_compat/test/parallel/test-http2-dont-override.js new file mode 100644 index 0000000000..c14863be39 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-dont-override.js @@ -0,0 +1,56 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); + +const options = {}; + +const server = http2.createServer(options); + +// Options are defaulted but the options are not modified +assert.deepStrictEqual(Object.keys(options), []); + +server.on('stream', common.mustCall((stream) => { + const headers = {}; + const options = {}; + stream.respond(headers, options); + + // The headers are defaulted but the original object is not modified + assert.deepStrictEqual(Object.keys(headers), []); + + // Options are defaulted but the original object is not modified + assert.deepStrictEqual(Object.keys(options), []); + + stream.end(); +})); + +server.listen(0, common.mustCall(() => { + const client = http2.connect(`http://localhost:${server.address().port}`); + + const headers = {}; + const options = {}; + + const req = client.request(headers, options); + + // The headers are defaulted but the original object is not modified + assert.deepStrictEqual(Object.keys(headers), []); + + // Options are defaulted but the original object is not modified + assert.deepStrictEqual(Object.keys(options), []); + + req.resume(); + req.on('end', common.mustCall(() => { + server.close(); + client.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http2-endafterheaders.js b/tests/node_compat/test/parallel/test-http2-endafterheaders.js new file mode 100644 index 0000000000..c1f9f0a553 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-endafterheaders.js @@ -0,0 +1,57 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); +const Countdown = require('../common/countdown'); + +const server = http2.createServer(); +server.on('stream', common.mustCall((stream, headers) => { + const check = headers[':method'] === 'GET'; + assert.strictEqual(stream.endAfterHeaders, check); + stream.on('data', common.mustNotCall()); + stream.on('end', common.mustCall()); + stream.respond(); + stream.end('ok'); +}, 2)); + +const countdown = new Countdown(2, () => server.close()); + +server.listen(0, common.mustCall(() => { + { + const client = http2.connect(`http://localhost:${server.address().port}`); + const req = client.request(); + + req.resume(); + req.on('response', common.mustCall(() => { + assert.strictEqual(req.endAfterHeaders, false); + })); + req.on('end', common.mustCall(() => { + client.close(); + countdown.dec(); + })); + } + { + const client = http2.connect(`http://localhost:${server.address().port}`); + const req = client.request({ ':method': 'POST' }); + + req.resume(); + req.end(); + req.on('response', common.mustCall(() => { + assert.strictEqual(req.endAfterHeaders, false); + })); + req.on('end', common.mustCall(() => { + client.close(); + countdown.dec(); + })); + } +})); diff --git a/tests/node_compat/test/parallel/test-http2-methods.js b/tests/node_compat/test/parallel/test-http2-methods.js new file mode 100644 index 0000000000..b1597f8c03 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-methods.js @@ -0,0 +1,56 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const h2 = require('http2'); + +const server = h2.createServer(); + +const methods = ['GET', 'POST', 'PATCH', 'FOO', 'A_B_C']; +let expected = methods.length; + +// We use the lower-level API here +server.on('stream', common.mustCall(onStream, expected)); + +function onStream(stream, headers, flags) { + const method = headers[':method']; + assert.notStrictEqual(method, undefined); + assert(methods.includes(method), `method ${method} not included`); + stream.respond({ + 'content-type': 'text/html', + ':status': 200 + }); + stream.end('hello world'); +} + +server.listen(0); + +server.on('listening', common.mustCall(() => { + + const client = h2.connect(`http://localhost:${server.address().port}`); + + const headers = { ':path': '/' }; + + methods.forEach((method) => { + headers[':method'] = method; + const req = client.request(headers); + req.on('response', common.mustCall()); + req.resume(); + req.on('end', common.mustCall(() => { + if (--expected === 0) { + server.close(); + client.close(); + } + })); + req.end(); + }); +})); diff --git a/tests/node_compat/test/parallel/test-http2-request-response-proto.js b/tests/node_compat/test/parallel/test-http2-request-response-proto.js new file mode 100644 index 0000000000..8f34cbc339 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-request-response-proto.js @@ -0,0 +1,25 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); + +const { + Http2ServerRequest, + Http2ServerResponse, +} = http2; + +const protoRequest = { __proto__: Http2ServerRequest.prototype }; +const protoResponse = { __proto__: Http2ServerResponse.prototype }; + +assert.strictEqual(protoRequest instanceof Http2ServerRequest, true); +assert.strictEqual(protoResponse instanceof Http2ServerResponse, true); diff --git a/tests/node_compat/test/parallel/test-http2-respond-file-204.js b/tests/node_compat/test/parallel/test-http2-respond-file-204.js new file mode 100644 index 0000000000..f0a87337dc --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-respond-file-204.js @@ -0,0 +1,49 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const http2 = require('http2'); + +const { + HTTP2_HEADER_CONTENT_TYPE, + HTTP2_HEADER_STATUS +} = http2.constants; + +const fname = fixtures.path('elipses.txt'); + +const server = http2.createServer(); +server.on('stream', (stream) => { + assert.throws(() => { + stream.respondWithFile(fname, { + [HTTP2_HEADER_STATUS]: 204, + [HTTP2_HEADER_CONTENT_TYPE]: 'text/plain' + }); + }, { + code: 'ERR_HTTP2_PAYLOAD_FORBIDDEN', + name: 'Error', + message: 'Responses with 204 status must not have a payload' + }); + stream.respond({}); + stream.end(); +}); +server.listen(0, () => { + const client = http2.connect(`http://localhost:${server.address().port}`); + const req = client.request(); + req.on('response', common.mustCall()); + req.on('data', common.mustNotCall()); + req.on('end', common.mustCall(() => { + client.close(); + server.close(); + })); + req.end(); +}); diff --git a/tests/node_compat/test/parallel/test-http2-respond-file-compat.js b/tests/node_compat/test/parallel/test-http2-respond-file-compat.js new file mode 100644 index 0000000000..e8c78ce3ab --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-respond-file-compat.js @@ -0,0 +1,31 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const http2 = require('http2'); +const fixtures = require('../common/fixtures'); + +const fname = fixtures.path('elipses.txt'); + +const server = http2.createServer(common.mustCall((request, response) => { + response.stream.respondWithFile(fname); +})); +server.listen(0, () => { + const client = http2.connect(`http://localhost:${server.address().port}`); + const req = client.request(); + req.on('response', common.mustCall()); + req.on('end', common.mustCall(() => { + client.close(); + server.close(); + })); + req.end(); + req.resume(); +}); diff --git a/tests/node_compat/test/parallel/test-http2-session-timeout.js b/tests/node_compat/test/parallel/test-http2-session-timeout.js new file mode 100644 index 0000000000..84c549aa96 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-session-timeout.js @@ -0,0 +1,71 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); +const hrtime = process.hrtime.bigint; +const NS_PER_MS = 1_000_000n; + +let requests = 0; +const mustNotCall = () => { + assert.fail(`Timeout after ${requests} request(s)`); +}; + +const server = http2.createServer(); +// Disable server timeout until first request. We will set the timeout based on +// how long the first request takes. +server.timeout = 0n; + +server.on('request', (req, res) => res.end()); +server.on('timeout', mustNotCall); + +server.listen(0, common.mustCall(() => { + const port = server.address().port; + + const url = `http://localhost:${port}`; + const client = http2.connect(url); + let startTime = hrtime(); + makeReq(); + + function makeReq() { + const request = client.request({ + ':path': '/foobar', + ':method': 'GET', + ':scheme': 'http', + ':authority': `localhost:${port}`, + }); + request.resume(); + request.end(); + + requests += 1; + + request.on('end', () => { + const diff = hrtime() - startTime; + const milliseconds = diff / NS_PER_MS; + if (server.timeout === 0n) { + // Set the timeout now. First connection will take significantly longer + // than subsequent connections, so using the duration of the first + // connection as the timeout should be robust. Double it anyway for good + // measure. + server.timeout = milliseconds * 2n; + startTime = hrtime(); + makeReq(); + } else if (milliseconds < server.timeout * 2n) { + makeReq(); + } else { + server.removeListener('timeout', mustNotCall); + server.close(); + client.close(); + } + }); + } +})); diff --git a/tests/node_compat/test/parallel/test-http2-socket-proxy.js b/tests/node_compat/test/parallel/test-http2-socket-proxy.js new file mode 100644 index 0000000000..c24ca29982 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-socket-proxy.js @@ -0,0 +1,133 @@ +// 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.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const h2 = require('http2'); +const net = require('net'); +const util = require('util'); + +const { kTimeout } = require('internal/timers'); + +// Tests behavior of the proxied socket on Http2Session + +const errMsg = { + code: 'ERR_HTTP2_NO_SOCKET_MANIPULATION', + name: 'Error', + message: 'HTTP/2 sockets should not be directly manipulated ' + + '(e.g. read and written)' +}; + +const server = h2.createServer(); + +server.on('stream', common.mustCall(function(stream, headers) { + const socket = stream.session.socket; + const session = stream.session; + + assert.ok(socket instanceof net.Socket); + + assert.strictEqual(socket.writable, true); + assert.strictEqual(socket.readable, true); + assert.strictEqual(typeof socket.address(), 'object'); + + socket.setTimeout(987); + assert.strictEqual(session[kTimeout]._idleTimeout, 987); + + // The indentation is corrected depending on the depth. + let inspectedTimeout = util.inspect(session[kTimeout]); + assert(inspectedTimeout.includes(' _idlePrev: [TimersList]')); + assert(inspectedTimeout.includes(' _idleNext: [TimersList]')); + assert(!inspectedTimeout.includes(' _idleNext: [TimersList]')); + + inspectedTimeout = util.inspect([ session[kTimeout] ]); + assert(inspectedTimeout.includes(' _idlePrev: [TimersList]')); + assert(inspectedTimeout.includes(' _idleNext: [TimersList]')); + assert(!inspectedTimeout.includes(' _idleNext: [TimersList]')); + + const inspectedTimersList = util.inspect([[ session[kTimeout]._idlePrev ]]); + assert(inspectedTimersList.includes(' _idlePrev: [Timeout]')); + assert(inspectedTimersList.includes(' _idleNext: [Timeout]')); + assert(!inspectedTimersList.includes(' _idleNext: [Timeout]')); + + assert.throws(() => socket.destroy, errMsg); + assert.throws(() => socket.emit, errMsg); + assert.throws(() => socket.end, errMsg); + assert.throws(() => socket.pause, errMsg); + assert.throws(() => socket.read, errMsg); + assert.throws(() => socket.resume, errMsg); + assert.throws(() => socket.write, errMsg); + assert.throws(() => socket.setEncoding, errMsg); + assert.throws(() => socket.setKeepAlive, errMsg); + assert.throws(() => socket.setNoDelay, errMsg); + + assert.throws(() => (socket.destroy = undefined), errMsg); + assert.throws(() => (socket.emit = undefined), errMsg); + assert.throws(() => (socket.end = undefined), errMsg); + assert.throws(() => (socket.pause = undefined), errMsg); + assert.throws(() => (socket.read = undefined), errMsg); + assert.throws(() => (socket.resume = undefined), errMsg); + assert.throws(() => (socket.write = undefined), errMsg); + assert.throws(() => (socket.setEncoding = undefined), errMsg); + assert.throws(() => (socket.setKeepAlive = undefined), errMsg); + assert.throws(() => (socket.setNoDelay = undefined), errMsg); + + // Resetting the socket listeners to their own value should not throw. + socket.on = socket.on; // eslint-disable-line no-self-assign + socket.once = socket.once; // eslint-disable-line no-self-assign + + socket.unref(); + assert.strictEqual(socket._handle.hasRef(), false); + socket.ref(); + assert.strictEqual(socket._handle.hasRef(), true); + + stream.respond(); + + socket.writable = true; + socket.readable = true; + assert.strictEqual(socket.writable, true); + assert.strictEqual(socket.readable, true); + socket.writable = false; + socket.readable = false; + assert.strictEqual(socket.writable, false); + assert.strictEqual(socket.readable, false); + + stream.end(); + + // Setting socket properties sets the session properties correctly. + const fn = () => {}; + socket.setTimeout = fn; + assert.strictEqual(session.setTimeout, fn); + + socket.ref = fn; + assert.strictEqual(session.ref, fn); + + socket.unref = fn; + assert.strictEqual(session.unref, fn); + + stream.session.on('close', common.mustCall(() => { + assert.strictEqual(session.socket, undefined); + })); +})); + +server.listen(0, common.mustCall(function() { + const port = server.address().port; + const url = `http://localhost:${port}`; + const client = h2.connect(url, common.mustCall(() => { + const request = client.request(); + request.on('end', common.mustCall(() => { + client.close(); + server.close(); + })); + request.resume(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http2-status-code-invalid.js b/tests/node_compat/test/parallel/test-http2-status-code-invalid.js new file mode 100644 index 0000000000..3a5e46af84 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-status-code-invalid.js @@ -0,0 +1,48 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); + +const server = http2.createServer(); + +function expectsError(code) { + return common.expectsError({ + code: 'ERR_HTTP2_STATUS_INVALID', + name: 'RangeError', + message: `Invalid status code: ${code}` + }); +} + +server.on('stream', common.mustCall((stream) => { + + // Anything lower than 100 and greater than 599 is rejected + [ 99, 700, 1000 ].forEach((i) => { + assert.throws(() => stream.respond({ ':status': i }), expectsError(i)); + }); + + stream.respond(); + stream.end(); +})); + +server.listen(0, common.mustCall(() => { + const client = http2.connect(`http://localhost:${server.address().port}`); + const req = client.request(); + req.on('response', common.mustCall((headers) => { + assert.strictEqual(headers[':status'], 200); + })); + req.resume(); + req.on('end', common.mustCall(() => { + server.close(); + client.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-http2-status-code.js b/tests/node_compat/test/parallel/test-http2-status-code.js new file mode 100644 index 0000000000..4af94b0cb7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-status-code.js @@ -0,0 +1,48 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); + +const codes = [ 200, 202, 300, 400, 404, 451, 500 ]; +let test = 0; + +const server = http2.createServer(); + +server.on('stream', common.mustCall((stream) => { + const status = codes[test++]; + stream.respond({ ':status': status }, { endStream: true }); +}, 7)); + +server.listen(0, common.mustCall(() => { + const client = http2.connect(`http://localhost:${server.address().port}`); + + let remaining = codes.length; + function maybeClose() { + if (--remaining === 0) { + client.close(); + server.close(); + } + } + + function doTest(expected) { + const req = client.request(); + req.on('response', common.mustCall((headers) => { + assert.strictEqual(headers[':status'], expected); + })); + req.resume(); + req.on('end', common.mustCall(maybeClose)); + } + + for (let n = 0; n < codes.length; n++) + doTest(codes[n]); +})); diff --git a/tests/node_compat/test/parallel/test-http2-stream-removelisteners-after-close.js b/tests/node_compat/test/parallel/test-http2-stream-removelisteners-after-close.js new file mode 100644 index 0000000000..e528dc2670 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-stream-removelisteners-after-close.js @@ -0,0 +1,38 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const http2 = require('http2'); + +// Regression test for https://github.com/nodejs/node/issues/29457: +// HTTP/2 stream event listeners can be added and removed after the +// session has been destroyed. + +const server = http2.createServer((req, res) => { + res.end('Hi!\n'); +}); + +server.listen(0, common.mustCall(() => { + const client = http2.connect(`http://localhost:${server.address().port}`); + const headers = { ':path': '/' }; + const req = client.request(headers); + + req.on('close', common.mustCall(() => { + req.removeAllListeners(); + req.on('priority', common.mustNotCall()); + server.close(); + })); + + req.on('priority', common.mustNotCall()); + req.on('error', common.mustCall()); + + client.destroy(); +})); diff --git a/tests/node_compat/test/parallel/test-http2-write-empty-string.js b/tests/node_compat/test/parallel/test-http2-write-empty-string.js new file mode 100644 index 0000000000..aea523d5d5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-http2-write-empty-string.js @@ -0,0 +1,48 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); + +const server = http2.createServer(function(request, response) { + response.writeHead(200, { 'Content-Type': 'text/plain' }); + response.write('1\n'); + response.write(''); + response.write('2\n'); + response.write(''); + response.end('3\n'); + + this.close(); +}); + +server.listen(0, common.mustCall(function() { + const client = http2.connect(`http://localhost:${this.address().port}`); + const headers = { ':path': '/' }; + const req = client.request(headers).setEncoding('ascii'); + + let res = ''; + + req.on('response', common.mustCall(function(headers) { + assert.strictEqual(headers[':status'], 200); + })); + + req.on('data', (chunk) => { + res += chunk; + }); + + req.on('end', common.mustCall(function() { + assert.strictEqual(res, '1\n2\n3\n'); + client.close(); + })); + + req.end(); +})); diff --git a/tests/node_compat/test/parallel/test-https-client-renegotiation-limit.js b/tests/node_compat/test/parallel/test-https-client-renegotiation-limit.js new file mode 100644 index 0000000000..a612de29a6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-https-client-renegotiation-limit.js @@ -0,0 +1,118 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.opensslCli) + common.skip('node compiled without OpenSSL CLI.'); + +const assert = require('assert'); +const tls = require('tls'); +const https = require('https'); +const fixtures = require('../common/fixtures'); + +// Renegotiation as a protocol feature was dropped after TLS1.2. +tls.DEFAULT_MAX_VERSION = 'TLSv1.2'; + +// Renegotiation limits to test +const LIMITS = [0, 1, 2, 3, 5, 10, 16]; + +{ + let n = 0; + function next() { + if (n >= LIMITS.length) return; + tls.CLIENT_RENEG_LIMIT = LIMITS[n++]; + test(next); + } + next(); +} + +function test(next) { + const options = { + cert: fixtures.readKey('rsa_cert.crt'), + key: fixtures.readKey('rsa_private.pem'), + }; + + const server = https.createServer(options, (req, res) => { + const conn = req.connection; + conn.on('error', (err) => { + console.error(`Caught exception: ${err}`); + assert.match(err.message, /TLS session renegotiation attack/); + conn.destroy(); + }); + res.end('ok'); + }); + + server.listen(0, () => { + const agent = https.Agent({ + keepAlive: true, + }); + + let client; + let renegs = 0; + + const options = { + rejectUnauthorized: false, + agent, + }; + + const { port } = server.address(); + + https.get(`https://localhost:${port}/`, options, (res) => { + client = res.socket; + + client.on('close', (hadErr) => { + assert.strictEqual(hadErr, false); + assert.strictEqual(renegs, tls.CLIENT_RENEG_LIMIT + 1); + server.close(); + process.nextTick(next); + }); + + client.on('error', (err) => { + console.log('CLIENT ERR', err); + throw err; + }); + + spam(); + + // Simulate renegotiation attack + function spam() { + client.renegotiate({}, (err) => { + assert.ifError(err); + assert.ok(renegs <= tls.CLIENT_RENEG_LIMIT); + setImmediate(spam); + }); + renegs++; + } + }); + + }); +} diff --git a/tests/node_compat/test/parallel/test-https-connecting-to-http.js b/tests/node_compat/test/parallel/test-https-connecting-to-http.js new file mode 100644 index 0000000000..ecb049fba2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-https-connecting-to-http.js @@ -0,0 +1,47 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// This tests the situation where you try to connect a https client +// to an http server. You should get an error and exit. +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const http = require('http'); +const https = require('https'); +const server = http.createServer(common.mustNotCall()); + +server.listen(0, common.mustCall(function() { + const req = https.get({ port: this.address().port }, common.mustNotCall()); + + req.on('error', common.mustCall(function(e) { + console.log('Got expected error: ', e.message); + server.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-https-foafssl.js b/tests/node_compat/test/parallel/test-https-foafssl.js new file mode 100644 index 0000000000..faa5376f01 --- /dev/null +++ b/tests/node_compat/test/parallel/test-https-foafssl.js @@ -0,0 +1,96 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.opensslCli) + common.skip('node compiled without OpenSSL CLI.'); + +const assert = require('assert'); +const fixtures = require('../common/fixtures'); +const https = require('https'); +const spawn = require('child_process').spawn; + +const options = { + key: fixtures.readKey('rsa_private.pem'), + cert: fixtures.readKey('rsa_cert.crt'), + requestCert: true, + rejectUnauthorized: false +}; + +const webIdUrl = 'URI:http://example.com/#me'; +const modulus = fixtures.readKey('rsa_cert_foafssl_b.modulus', 'ascii').replace(/\n/g, ''); +const exponent = fixtures.readKey('rsa_cert_foafssl_b.exponent', 'ascii').replace(/\n/g, ''); + +const CRLF = '\r\n'; +const body = 'hello world\n'; +let cert; + +const server = https.createServer(options, common.mustCall(function(req, res) { + console.log('got request'); + + cert = req.connection.getPeerCertificate(); + + assert.strictEqual(cert.subjectaltname, webIdUrl); + assert.strictEqual(cert.exponent, exponent); + assert.strictEqual(cert.modulus, modulus); + res.writeHead(200, { 'content-type': 'text/plain' }); + res.end(body, () => { console.log('stream finished'); }); + console.log('sent response'); +})); + +server.listen(0, function() { + const args = ['s_client', + '-quiet', + '-connect', `127.0.0.1:${this.address().port}`, + '-cert', fixtures.path('keys/rsa_cert_foafssl_b.crt'), + '-key', fixtures.path('keys/rsa_private_b.pem')]; + + const client = spawn(common.opensslCli, args); + + client.stdout.on('data', function(data) { + console.log('response received'); + const message = data.toString(); + const contents = message.split(CRLF + CRLF).pop(); + assert.strictEqual(body, contents); + server.close((e) => { + assert.ifError(e); + console.log('server closed'); + }); + console.log('server.close() called'); + }); + + client.stdin.write('GET /\n\n'); + + client.on('error', function(error) { + throw error; + }); +}); diff --git a/tests/node_compat/test/parallel/test-https-localaddress-bind-error.js b/tests/node_compat/test/parallel/test-https-localaddress-bind-error.js new file mode 100644 index 0000000000..304f0b2857 --- /dev/null +++ b/tests/node_compat/test/parallel/test-https-localaddress-bind-error.js @@ -0,0 +1,69 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const https = require('https'); + +const fixtures = require('../common/fixtures'); + +const options = { + key: fixtures.readKey('agent1-key.pem'), + cert: fixtures.readKey('agent1-cert.pem') +}; + +const invalidLocalAddress = '1.2.3.4'; + +const server = https.createServer(options, function(req, res) { + console.log(`Connect from: ${req.connection.remoteAddress}`); + + req.on('end', function() { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end(`You are from: ${req.connection.remoteAddress}`); + }); + req.resume(); +}); + +server.listen(0, '127.0.0.1', common.mustCall(function() { + https.request({ + host: 'localhost', + port: this.address().port, + path: '/', + method: 'GET', + localAddress: invalidLocalAddress + }, function(res) { + assert.fail('unexpectedly got response from server'); + }).on('error', common.mustCall(function(e) { + console.log(`client got error: ${e.message}`); + server.close(); + })).end(); +})); diff --git a/tests/node_compat/test/parallel/test-https-localaddress.js b/tests/node_compat/test/parallel/test-https-localaddress.js new file mode 100644 index 0000000000..a988c94a38 --- /dev/null +++ b/tests/node_compat/test/parallel/test-https-localaddress.js @@ -0,0 +1,76 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Flags: --expose-internals +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.hasMultiLocalhost()) + common.skip('platform-specific test.'); + +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const https = require('https'); + +const options = { + key: fixtures.readKey('agent1-key.pem'), + cert: fixtures.readKey('agent1-cert.pem') +}; + +const server = https.createServer(options, function(req, res) { + console.log(`Connect from: ${req.connection.remoteAddress}`); + assert.strictEqual(req.connection.remoteAddress, '127.0.0.2'); + + req.on('end', function() { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end(`You are from: ${req.connection.remoteAddress}`); + }); + req.resume(); +}); + +server.listen(0, '127.0.0.1', function() { + const options = { + host: 'localhost', + port: this.address().port, + family: 4, + path: '/', + method: 'GET', + localAddress: '127.0.0.2', + rejectUnauthorized: false + }; + + const req = https.request(options, function(res) { + res.on('end', function() { + server.close(); + }); + res.resume(); + }); + req.end(); +}); diff --git a/tests/node_compat/test/parallel/test-icu-data-dir.js b/tests/node_compat/test/parallel/test-icu-data-dir.js new file mode 100644 index 0000000000..5054de86ef --- /dev/null +++ b/tests/node_compat/test/parallel/test-icu-data-dir.js @@ -0,0 +1,40 @@ +// 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'); +const { spawnSyncAndExit } = require('../common/child_process'); +const { internalBinding } = require('internal/test/binding'); + +const { hasSmallICU } = internalBinding('config'); +if (!(common.hasIntl && hasSmallICU)) + common.skip('missing Intl'); + +{ + spawnSyncAndExit( + process.execPath, + ['--icu-data-dir=/', '-e', '0'], + { + status: 9, + signal: null, + stderr: /Could not initialize ICU/ + }); +} + +{ + const env = { ...process.env, NODE_ICU_DATA: '/' }; + spawnSyncAndExit( + process.execPath, + ['-e', '0'], + { env }, + { + status: 9, + signal: null, + stderr: /Could not initialize ICU/ + }); +} diff --git a/tests/node_compat/test/parallel/test-icu-env.js b/tests/node_compat/test/parallel/test-icu-env.js new file mode 100644 index 0000000000..4a9545d2ca --- /dev/null +++ b/tests/node_compat/test/parallel/test-icu-env.js @@ -0,0 +1,295 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { execFileSync } = require('child_process'); + +// system-icu should not be tested +const hasBuiltinICU = process.config.variables.icu_gyp_path === 'tools/icu/icu-generic.gyp'; +if (!hasBuiltinICU) + common.skip('system ICU'); + +// small-icu doesn't support non-English locales +const hasFullICU = (() => { + try { + const january = new Date(9e8); + const spanish = new Intl.DateTimeFormat('es', { month: 'long' }); + return spanish.format(january) === 'enero'; + } catch { + return false; + } +})(); +if (!hasFullICU) + common.skip('small ICU'); + +const icuVersionMajor = Number(process.config.variables.icu_ver_major ?? 0); +if (icuVersionMajor < 71) + common.skip('ICU too old'); + + +function runEnvOutside(addEnv, code, ...args) { + return execFileSync( + process.execPath, + ['-e', `process.stdout.write(String(${code}));`], + { env: { ...process.env, ...addEnv }, encoding: 'utf8' } + ); +} + +function runEnvInside(addEnv, func, ...args) { + Object.assign(process.env, addEnv); // side effects! + return func(...args); +} + +function isPack(array) { + const firstItem = array[0]; + return array.every((item) => item === firstItem); +} + +function isSet(array) { + const deduped = new Set(array); + return array.length === deduped.size; +} + + +const localesISO639 = [ + 'eng', 'cmn', 'hin', 'spa', + 'fra', 'arb', 'ben', 'rus', + 'por', 'urd', 'ind', 'deu', + 'jpn', 'pcm', 'mar', 'tel', +]; + +const locales = [ + 'en', 'zh', 'hi', 'es', + 'fr', 'ar', 'bn', 'ru', + 'pt', 'ur', 'id', 'de', + 'ja', 'pcm', 'mr', 'te', +]; + +// These must not overlap +const zones = [ + 'America/New_York', + 'UTC', + 'Asia/Irkutsk', + 'Australia/North', + 'Antarctica/South_Pole', +]; + + +assert.deepStrictEqual(Intl.getCanonicalLocales(localesISO639), locales); + + +// On some platforms these keep original locale (for example, 'January') +const enero = runEnvOutside( + { LANG: 'es' }, + 'new Intl.DateTimeFormat(undefined, { month: "long" } ).format(new Date(9e8))' +); +const janvier = runEnvOutside( + { LANG: 'fr' }, + 'new Intl.DateTimeFormat(undefined, { month: "long" } ).format(new Date(9e8))' +); +const isMockable = enero !== janvier; + +// Tests with mocked env +if (isMockable) { + assert.strictEqual( + isSet(zones.map((TZ) => runEnvOutside({ TZ }, 'new Date(333333333333).toString()'))), + true + ); + assert.strictEqual( + isSet(zones.map((TZ) => runEnvOutside({ TZ }, 'new Date(333333333333).toLocaleString()'))), + true + ); + assert.deepStrictEqual( + locales.map((LANG) => runEnvOutside({ LANG, TZ: 'Europe/Zurich' }, 'new Date(333333333333).toString()')), + [ + 'Fri Jul 25 1980 01:35:33 GMT+0100 (Central European Standard Time)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (中欧标准时间)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (मध्य यूरोपीय मानक समय)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (hora estándar de Europa central)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (heure normale d’Europe centrale)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (توقيت وسط أوروبا الرسمي)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (মধ্য ইউরোপীয় মানক সময়)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (Центральная Европа, стандартное время)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (Horário Padrão da Europa Central)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (وسطی یورپ کا معیاری وقت)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (Waktu Standar Eropa Tengah)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (Mitteleuropäische Normalzeit)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (中央ヨーロッパ標準時)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (Mídúl Yúrop Fíksd Taim)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (मध्‍य युरोपियन प्रमाण वेळ)', + 'Fri Jul 25 1980 01:35:33 GMT+0100 (సెంట్రల్ యూరోపియన్ ప్రామాణిక సమయం)', + ] + ); + assert.deepStrictEqual( + locales.map((LANG) => runEnvOutside({ LANG, TZ: 'Europe/Zurich' }, 'new Date(333333333333).toLocaleString()')), + [ + '7/25/1980, 1:35:33 AM', + '1980/7/25 01:35:33', + '25/7/1980, 1:35:33 am', + '25/7/1980, 1:35:33', + '25/07/1980 01:35:33', + '٢٥‏/٧‏/١٩٨٠، ١:٣٥:٣٣ ص', + '২৫/৭/১৯৮০, ১:৩৫:৩৩ AM', + '25.07.1980, 01:35:33', + '25/07/1980, 01:35:33', + '25/7/1980، 1:35:33 AM', + '25/7/1980, 01.35.33', + '25.7.1980, 01:35:33', + '1980/7/25 1:35:33', + '25/7/1980 01:35:33', + '२५/७/१९८०, १:३५:३३ AM', + '25/7/1980 1:35:33 AM', + ] + ); + assert.strictEqual( + runEnvOutside({ LANG: 'en' }, '["z", "ä"].sort(new Intl.Collator().compare)'), + 'ä,z' + ); + assert.strictEqual( + runEnvOutside({ LANG: 'sv' }, '["z", "ä"].sort(new Intl.Collator().compare)'), + 'z,ä' + ); + assert.deepStrictEqual( + locales.map( + (LANG) => runEnvOutside({ LANG, TZ: 'Europe/Zurich' }, 'new Intl.DateTimeFormat().format(333333333333)') + ), + [ + '7/25/1980', '1980/7/25', + '25/7/1980', '25/7/1980', + '25/07/1980', '٢٥‏/٧‏/١٩٨٠', + '২৫/৭/১৯৮০', '25.07.1980', + '25/07/1980', '25/7/1980', + '25/7/1980', '25.7.1980', + '1980/7/25', '25/7/1980', + '२५/७/१९८०', '25/7/1980', + ] + ); + assert.deepStrictEqual( + locales.map((LANG) => runEnvOutside({ LANG }, 'new Intl.DisplayNames(undefined, { type: "region" }).of("CH")')), + [ + 'Switzerland', '瑞士', + 'स्विट्ज़रलैंड', 'Suiza', + 'Suisse', 'سويسرا', + 'সুইজারল্যান্ড', 'Швейцария', + 'Suíça', 'سوئٹزر لینڈ', + 'Swiss', 'Schweiz', + 'スイス', 'Swítsaland', + 'स्वित्झर्लंड', 'స్విట్జర్లాండ్', + ] + ); + assert.deepStrictEqual( + locales.map((LANG) => runEnvOutside({ LANG }, 'new Intl.NumberFormat().format(275760.913)')), + [ + '275,760.913', '275,760.913', + '2,75,760.913', '275.760,913', + '275 760,913', '٢٧٥٬٧٦٠٫٩١٣', + '২,৭৫,৭৬০.৯১৩', '275 760,913', + '275.760,913', '275,760.913', + '275.760,913', '275.760,913', + '275,760.913', '275,760.913', + '२,७५,७६०.९१३', '2,75,760.913', + ] + ); + assert.deepStrictEqual( + locales.map((LANG) => runEnvOutside({ LANG }, 'new Intl.PluralRules().select(0)')), + [ + 'other', 'other', 'one', 'other', + 'one', 'zero', 'one', 'many', + 'one', 'other', 'other', 'other', + 'other', 'one', 'other', 'other', + ] + ); + assert.deepStrictEqual( + locales.map((LANG) => runEnvOutside({ LANG }, 'new Intl.RelativeTimeFormat().format(-586920.617, "hour")')), + [ + '586,920.617 hours ago', + '586,920.617小时前', + '5,86,920.617 घंटे पहले', + 'hace 586.920,617 horas', + 'il y a 586 920,617 heures', + 'قبل ٥٨٦٬٩٢٠٫٦١٧ ساعة', + '৫,৮৬,৯২০.৬১৭ ঘন্টা আগে', + '586 920,617 часа назад', + 'há 586.920,617 horas', + '586,920.617 گھنٹے پہلے', + '586.920,617 jam yang lalu', + 'vor 586.920,617 Stunden', + '586,920.617 時間前', + '586,920.617 áwa wé dọ́n pas', + '५,८६,९२०.६१७ तासांपूर्वी', + '5,86,920.617 గంటల క్రితం', + ] + ); +} + + +// Tests with process.env mutated inside +{ + // process.env.TZ is not intercepted in Workers + if (common.isMainThread) { + assert.strictEqual( + isSet(zones.map((TZ) => runEnvInside({ TZ }, () => new Date(333333333333).toString()))), + true + ); + assert.strictEqual( + isSet(zones.map((TZ) => runEnvInside({ TZ }, () => new Date(333333333333).toLocaleString()))), + true + ); + } else { + assert.strictEqual( + isPack(zones.map((TZ) => runEnvInside({ TZ }, () => new Date(333333333333).toString()))), + true + ); + assert.strictEqual( + isPack(zones.map((TZ) => runEnvInside({ TZ }, () => new Date(333333333333).toLocaleString()))), + true + ); + } + + assert.strictEqual( + isPack(locales.map((LANG) => runEnvInside({ LANG, TZ: 'Europe/Zurich' }, () => new Date(333333333333).toString()))), + true + ); + assert.strictEqual( + isPack(locales.map( + (LANG) => runEnvInside({ LANG, TZ: 'Europe/Zurich' }, () => new Date(333333333333).toLocaleString()) + )), + true + ); + assert.deepStrictEqual( + runEnvInside({ LANG: 'en' }, () => ['z', 'ä'].sort(new Intl.Collator().compare)), + runEnvInside({ LANG: 'sv' }, () => ['z', 'ä'].sort(new Intl.Collator().compare)) + ); + assert.strictEqual( + isPack(locales.map( + (LANG) => runEnvInside({ LANG, TZ: 'Europe/Zurich' }, () => new Intl.DateTimeFormat().format(333333333333)) + )), + true + ); + assert.strictEqual( + isPack(locales.map( + (LANG) => runEnvInside({ LANG }, () => new Intl.DisplayNames(undefined, { type: 'region' }).of('CH')) + )), + true + ); + assert.strictEqual( + isPack(locales.map((LANG) => runEnvInside({ LANG }, () => new Intl.NumberFormat().format(275760.913)))), + true + ); + assert.strictEqual( + isPack(locales.map((LANG) => runEnvInside({ LANG }, () => new Intl.PluralRules().select(0)))), + true + ); + assert.strictEqual( + isPack(locales.map( + (LANG) => runEnvInside({ LANG }, () => new Intl.RelativeTimeFormat().format(-586920.617, 'hour')) + )), + true + ); +} diff --git a/tests/node_compat/test/parallel/test-icu-stringwidth.js b/tests/node_compat/test/parallel/test-icu-stringwidth.js new file mode 100644 index 0000000000..3e3c1f0c31 --- /dev/null +++ b/tests/node_compat/test/parallel/test-icu-stringwidth.js @@ -0,0 +1,102 @@ +// 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'); + +const assert = require('assert'); +const { getStringWidth } = require('internal/util/inspect'); + +// Test column width + +// Ll (Lowercase Letter): LATIN SMALL LETTER A +assert.strictEqual(getStringWidth('a'), 1); +assert.strictEqual(getStringWidth(String.fromCharCode(0x0061)), 1); +// Lo (Other Letter) +assert.strictEqual(getStringWidth('丁'), 2); +assert.strictEqual(getStringWidth(String.fromCharCode(0x4E01)), 2); +// Surrogate pairs +assert.strictEqual(getStringWidth('\ud83d\udc78\ud83c\udfff'), 4); +assert.strictEqual(getStringWidth('👅'), 2); +// Cs (Surrogate): High Surrogate +assert.strictEqual(getStringWidth('\ud83d'), 1); +// Cs (Surrogate): Low Surrogate +assert.strictEqual(getStringWidth('\udc78'), 1); +// Cc (Control): NULL +assert.strictEqual(getStringWidth('\u0000'), 0); +// Cc (Control): BELL +assert.strictEqual(getStringWidth(String.fromCharCode(0x0007)), 0); +// Cc (Control): LINE FEED +assert.strictEqual(getStringWidth('\n'), 0); +// Cf (Format): SOFT HYPHEN +assert.strictEqual(getStringWidth(String.fromCharCode(0x00AD)), 1); +// Cf (Format): LEFT-TO-RIGHT MARK +// Cf (Format): RIGHT-TO-LEFT MARK +assert.strictEqual(getStringWidth('\u200Ef\u200F'), 1); +// Cn (Unassigned): Not a character +assert.strictEqual(getStringWidth(String.fromCharCode(0x10FFEF)), 1); +// Cn (Unassigned): Not a character (but in a CJK range) +assert.strictEqual(getStringWidth(String.fromCharCode(0x3FFEF)), 1); +// Mn (Nonspacing Mark): COMBINING ACUTE ACCENT +assert.strictEqual(getStringWidth(String.fromCharCode(0x0301)), 0); +// Mc (Spacing Mark): BALINESE ADEG ADEG +// Chosen as its Canonical_Combining_Class is not 0, but is not a 0-width +// character. +assert.strictEqual(getStringWidth(String.fromCharCode(0x1B44)), 1); +// Me (Enclosing Mark): COMBINING ENCLOSING CIRCLE +assert.strictEqual(getStringWidth(String.fromCharCode(0x20DD)), 0); + +// The following is an emoji sequence with ZWJ (zero-width-joiner). In some +// implementations, it is represented as a single glyph, in other +// implementations as a sequence of individual glyphs. By default, each +// component will be counted individually, since not a lot of systems support +// these fully. +// See https://www.unicode.org/reports/tr51/tr51-16.html#Emoji_ZWJ_Sequences +assert.strictEqual(getStringWidth('👩‍👩‍👧‍👧'), 8); +// TODO(BridgeAR): This should have a width of two and six. The heart contains +// the \uFE0F variation selector that indicates that it should be displayed as +// emoji instead of as text. Emojis are all full width characters when not being +// rendered as text. +// https://en.wikipedia.org/wiki/Variation_Selectors_(Unicode_block) +assert.strictEqual(getStringWidth('❤️'), 1); +assert.strictEqual(getStringWidth('👩‍❤️‍👩'), 5); +// The length of one is correct. It is an emoji treated as text. +assert.strictEqual(getStringWidth('❤'), 1); + +// By default, unicode characters whose width is considered ambiguous will +// be considered half-width. For these characters, getStringWidth will return +// 1. In some contexts, however, it is more appropriate to consider them full +// width. By default, the algorithm will assume half width. +assert.strictEqual(getStringWidth('\u01d4'), 1); + +// Control chars and combining chars are zero +assert.strictEqual(getStringWidth('\u200E\n\u220A\u20D2'), 1); + +// Test that the fast path for ASCII characters yields results consistent +// with the 'slow' path. +for (let i = 0; i < 256; i++) { + const char = String.fromCharCode(i); + assert.strictEqual( + getStringWidth(char + '🎉'), + getStringWidth(char) + 2); + + if (i < 32 || (i >= 127 && i < 160)) { // Control character + assert.strictEqual(getStringWidth(char), 0); + } else { // Regular ASCII character + assert.strictEqual(getStringWidth(char), 1); + } +} + +if (common.hasIntl) { + const a = '한글'.normalize('NFD'); // 한글 + const b = '한글'.normalize('NFC'); // 한글 + assert.strictEqual(a.length, 6); + assert.strictEqual(b.length, 2); + assert.strictEqual(getStringWidth(a), 4); + assert.strictEqual(getStringWidth(b), 4); +} diff --git a/tests/node_compat/test/parallel/test-inspector-stops-no-file.js b/tests/node_compat/test/parallel/test-inspector-stops-no-file.js new file mode 100644 index 0000000000..0eea1e3b16 --- /dev/null +++ b/tests/node_compat/test/parallel/test-inspector-stops-no-file.js @@ -0,0 +1,23 @@ +// 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. + +'use strict'; +require('../common'); + +const spawn = require('child_process').spawn; + +const child = spawn(process.execPath, + [ '--inspect', 'no-such-script.js' ], + { 'stdio': 'inherit' }); + +function signalHandler() { + child.kill(); + process.exit(1); +} + +process.on('SIGINT', signalHandler); +process.on('SIGTERM', signalHandler); diff --git a/tests/node_compat/test/parallel/test-instanceof.js b/tests/node_compat/test/parallel/test-instanceof.js new file mode 100644 index 0000000000..2d81c1cf15 --- /dev/null +++ b/tests/node_compat/test/parallel/test-instanceof.js @@ -0,0 +1,18 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); + + +// Regression test for instanceof, see +// https://github.com/nodejs/node/issues/7592 +const F = () => {}; +F.prototype = {}; +assert({ __proto__: F.prototype } instanceof F); diff --git a/tests/node_compat/test/parallel/test-internal-fs.js b/tests/node_compat/test/parallel/test-internal-fs.js new file mode 100644 index 0000000000..b0abd04e9b --- /dev/null +++ b/tests/node_compat/test/parallel/test-internal-fs.js @@ -0,0 +1,60 @@ +// 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'; + +require('../common'); +const assert = require('assert'); +const fs = require('internal/fs/utils'); + +// Valid encodings and no args should not throw. +fs.assertEncoding(); +fs.assertEncoding('utf8'); + +assert.throws( + () => fs.assertEncoding('foo'), + { code: 'ERR_INVALID_ARG_VALUE', name: 'TypeError' } +); + +// Test junction symlinks +{ + const pathString = 'c:\\test1'; + const linkPathString = '\\test2'; + + const preprocessSymlinkDestination = fs.preprocessSymlinkDestination( + pathString, + 'junction', + linkPathString + ); + + if (process.platform === 'win32') { + assert.match(preprocessSymlinkDestination, /^\\\\\?\\/); + } else { + assert.strictEqual(preprocessSymlinkDestination, pathString); + } +} + +// Test none junction symlinks +{ + const pathString = 'c:\\test1'; + const linkPathString = '\\test2'; + + const preprocessSymlinkDestination = fs.preprocessSymlinkDestination( + pathString, + undefined, + linkPathString + ); + + if (process.platform === 'win32') { + // There should not be any forward slashes + assert.strictEqual( + /\//.test(preprocessSymlinkDestination), false); + } else { + assert.strictEqual(preprocessSymlinkDestination, pathString); + } +} diff --git a/tests/node_compat/test/parallel/test-internal-util-normalizeencoding.js b/tests/node_compat/test/parallel/test-internal-util-normalizeencoding.js new file mode 100644 index 0000000000..9a85f6192e --- /dev/null +++ b/tests/node_compat/test/parallel/test-internal-util-normalizeencoding.js @@ -0,0 +1,62 @@ +// 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'; + +require('../common'); +const assert = require('assert'); +const util = require('internal/util'); + +const tests = [ + [undefined, 'utf8'], + [null, 'utf8'], + ['', 'utf8'], + ['utf8', 'utf8'], + ['utf-8', 'utf8'], + ['UTF-8', 'utf8'], + ['UTF8', 'utf8'], + ['Utf8', 'utf8'], + ['uTf-8', 'utf8'], + ['utF-8', 'utf8'], + ['ucs2', 'utf16le'], + ['UCS2', 'utf16le'], + ['UcS2', 'utf16le'], + ['ucs-2', 'utf16le'], + ['UCS-2', 'utf16le'], + ['UcS-2', 'utf16le'], + ['utf16le', 'utf16le'], + ['utf-16le', 'utf16le'], + ['UTF-16LE', 'utf16le'], + ['UTF16LE', 'utf16le'], + ['binary', 'latin1'], + ['BINARY', 'latin1'], + ['latin1', 'latin1'], + ['LaTiN1', 'latin1'], + ['base64', 'base64'], + ['BASE64', 'base64'], + ['Base64', 'base64'], + ['base64url', 'base64url'], + ['BASE64url', 'base64url'], + ['Base64url', 'base64url'], + ['hex', 'hex'], + ['HEX', 'hex'], + ['ASCII', 'ascii'], + ['AsCii', 'ascii'], + ['foo', undefined], + [1, undefined], + [false, undefined], + [NaN, undefined], + [0, undefined], + [[], undefined], + [{}, undefined], +]; + +tests.forEach((e, i) => { + const res = util.normalizeEncoding(e[0]); + assert.strictEqual(res, e[1], `#${i} failed: expected ${e[1]}, got ${res}`); +}); diff --git a/tests/node_compat/test/parallel/test-kill-segfault-freebsd.js b/tests/node_compat/test/parallel/test-kill-segfault-freebsd.js new file mode 100644 index 0000000000..b42901a322 --- /dev/null +++ b/tests/node_compat/test/parallel/test-kill-segfault-freebsd.js @@ -0,0 +1,26 @@ +// 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. + +'use strict'; +require('../common'); + +// This test ensures Node.js doesn't crash on hitting Ctrl+C in order to +// terminate the currently running process (especially on FreeBSD). +// https://github.com/nodejs/node-v0.x-archive/issues/9326 + +const assert = require('assert'); +const child_process = require('child_process'); + +// NOTE: Was crashing on FreeBSD +const cp = child_process.spawn(process.execPath, [ + '-e', + 'process.kill(process.pid, "SIGINT")', +]); + +cp.on('exit', function(code) { + assert.notStrictEqual(code, 0); +}); diff --git a/tests/node_compat/test/parallel/test-listen-fd-detached-inherit.js b/tests/node_compat/test/parallel/test-listen-fd-detached-inherit.js new file mode 100644 index 0000000000..60ef9ac4b5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-listen-fd-detached-inherit.js @@ -0,0 +1,125 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (common.isWindows) + common.skip('This test is disabled on windows.'); + +const assert = require('assert'); +const http = require('http'); +const net = require('net'); +const spawn = require('child_process').spawn; + +switch (process.argv[2]) { + case 'child': return child(); + case 'parent': return parent(); + default: return test(); +} + +// Spawn the parent, and listen for it to tell us the pid of the child. +// WARNING: This is an example of listening on some arbitrary FD number +// that has already been bound elsewhere in advance. However, binding +// server handles to stdio fd's is NOT a good or reliable way to do +// concurrency in HTTP servers! Use the cluster module, or if you want +// a more low-level approach, use child process IPC manually. +function test() { + const parent = spawn(process.execPath, [__filename, 'parent'], { + stdio: [ 0, 'pipe', 2 ] + }); + let json = ''; + parent.stdout.on('data', function(c) { + json += c.toString(); + if (json.includes('\n')) next(); + }); + function next() { + console.error('output from parent = %s', json); + const child = JSON.parse(json); + // Now make sure that we can request to the subprocess, then kill it. + http.get({ + server: 'localhost', + port: child.port, + path: '/', + }).on('response', function(res) { + let s = ''; + res.on('data', function(c) { + s += c.toString(); + }); + res.on('end', function() { + // Kill the subprocess before we start doing asserts. + // It's really annoying when tests leave orphans! + process.kill(child.pid, 'SIGKILL'); + try { + parent.kill(); + } catch { + // Continue regardless of error. + } + + assert.strictEqual(s, 'hello from child\n'); + assert.strictEqual(res.statusCode, 200); + }); + }); + } +} + +// Listen on port, and then pass the handle to the detached child. +// Then output the child's pid, and immediately exit. +function parent() { + const server = net.createServer(function(conn) { + conn.end('HTTP/1.1 403 Forbidden\r\n\r\nI got problems.\r\n'); + throw new Error('Should not see connections on parent'); + }).listen(0, function() { + console.error('server listening on %d', this.address().port); + + const child = spawn(process.execPath, [__filename, 'child'], { + stdio: [ 0, 1, 2, server._handle ], + detached: true + }); + + console.log('%j\n', { pid: child.pid, port: this.address().port }); + + // Now close the parent, so that the child is the only thing + // referencing that handle. Note that connections will still + // be accepted, because the child has the fd open, but the parent + // will exit gracefully. + server.close(); + child.unref(); + }); +} + +// Run as a child of the parent() mode. +function child() { + // Start a server on fd=3 + http.createServer(function(req, res) { + console.error('request on child'); + console.error('%s %s', req.method, req.url, req.headers); + res.end('hello from child\n'); + }).listen({ fd: 3 }, function() { + console.error('child listening on fd=3'); + }); +} diff --git a/tests/node_compat/test/parallel/test-listen-fd-detached.js b/tests/node_compat/test/parallel/test-listen-fd-detached.js new file mode 100644 index 0000000000..2bef173a2f --- /dev/null +++ b/tests/node_compat/test/parallel/test-listen-fd-detached.js @@ -0,0 +1,122 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (common.isWindows) + common.skip('This test is disabled on windows.'); + +const assert = require('assert'); +const http = require('http'); +const net = require('net'); +const spawn = require('child_process').spawn; + +switch (process.argv[2]) { + case 'child': return child(); + case 'parent': return parent(); + default: return test(); +} + +// Spawn the parent, and listen for it to tell us the pid of the child. +// WARNING: This is an example of listening on some arbitrary FD number +// that has already been bound elsewhere in advance. However, binding +// server handles to stdio fd's is NOT a good or reliable way to do +// concurrency in HTTP servers! Use the cluster module, or if you want +// a more low-level approach, use child process IPC manually. +function test() { + const parent = spawn(process.execPath, [__filename, 'parent'], { + stdio: [ 0, 'pipe', 2 ] + }); + let json = ''; + parent.stdout.on('data', function(c) { + json += c.toString(); + if (json.includes('\n')) next(); + }); + function next() { + console.error('output from parent = %s', json); + const child = JSON.parse(json); + // Now make sure that we can request to the subprocess, then kill it. + http.get({ + server: 'localhost', + port: child.port, + path: '/', + }).on('response', function(res) { + let s = ''; + res.on('data', function(c) { + s += c.toString(); + }); + res.on('end', function() { + // Kill the subprocess before we start doing asserts. + // it's really annoying when tests leave orphans! + process.kill(child.pid, 'SIGKILL'); + try { + parent.kill(); + } catch { + // Continue regardless of error. + } + + assert.strictEqual(s, 'hello from child\n'); + assert.strictEqual(res.statusCode, 200); + }); + }); + } +} + +function parent() { + const server = net.createServer(function(conn) { + console.error('connection on parent'); + conn.end('hello from parent\n'); + }).listen(0, function() { + console.error('server listening on %d', this.address().port); + + const child = spawn(process.execPath, [__filename, 'child'], { + stdio: [ 'ignore', 'ignore', 'ignore', server._handle ], + detached: true + }); + + console.log('%j\n', { pid: child.pid, port: this.address().port }); + + // Now close the parent, so that the child is the only thing + // referencing that handle. Note that connections will still + // be accepted, because the child has the fd open, but the parent + // will exit gracefully. + server.close(); + child.unref(); + }); +} + +function child() { + // Start a server on fd=3 + http.createServer(function(req, res) { + console.error('request on child'); + console.error('%s %s', req.method, req.url, req.headers); + res.end('hello from child\n'); + }).listen({ fd: 3 }, function() { + console.error('child listening on fd=3'); + }); +} diff --git a/tests/node_compat/test/parallel/test-memory-usage-emfile.js b/tests/node_compat/test/parallel/test-memory-usage-emfile.js new file mode 100644 index 0000000000..4a89be3cb5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-memory-usage-emfile.js @@ -0,0 +1,25 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// On IBMi, the rss memory always returns zero +if (common.isIBMi) + common.skip('On IBMi, the rss memory always returns zero'); + +const assert = require('assert'); + +const fs = require('fs'); + +const files = []; + +while (files.length < 256) + files.push(fs.openSync(__filename, 'r')); + +const r = process.memoryUsage.rss(); +assert.strictEqual(r > 0, true); diff --git a/tests/node_compat/test/parallel/test-memory-usage.js b/tests/node_compat/test/parallel/test-memory-usage.js new file mode 100644 index 0000000000..8227b7b122 --- /dev/null +++ b/tests/node_compat/test/parallel/test-memory-usage.js @@ -0,0 +1,56 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Flags: --predictable-gc-schedule +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const r = process.memoryUsage(); +// On IBMi, the rss memory always returns zero +if (!common.isIBMi) { + assert.ok(r.rss > 0); + assert.ok(process.memoryUsage.rss() > 0); +} + +assert.ok(r.heapTotal > 0); +assert.ok(r.heapUsed > 0); +assert.ok(r.external > 0); + +assert.strictEqual(typeof r.arrayBuffers, 'number'); +if (r.arrayBuffers > 0) { + const size = 10 * 1024 * 1024; + // eslint-disable-next-line no-unused-vars + const ab = new ArrayBuffer(size); + + const after = process.memoryUsage(); + assert.ok(after.external - r.external >= size, + `${after.external} - ${r.external} >= ${size}`); + assert.strictEqual(after.arrayBuffers - r.arrayBuffers, size, + `${after.arrayBuffers} - ${r.arrayBuffers} === ${size}`); +} diff --git a/tests/node_compat/test/parallel/test-messagechannel.js b/tests/node_compat/test/parallel/test-messagechannel.js new file mode 100644 index 0000000000..44ddf6d7aa --- /dev/null +++ b/tests/node_compat/test/parallel/test-messagechannel.js @@ -0,0 +1,19 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +// See: https://github.com/nodejs/node/issues/49940 +(async () => { + new MessageChannel().port1.postMessage({}, { + transfer: { + *[Symbol.iterator]() {} + } + }); +})().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-microtask-queue-integration.js b/tests/node_compat/test/parallel/test-microtask-queue-integration.js new file mode 100644 index 0000000000..8abb41d364 --- /dev/null +++ b/tests/node_compat/test/parallel/test-microtask-queue-integration.js @@ -0,0 +1,70 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const implementations = [ + function(fn) { + Promise.resolve().then(fn); + }, +]; + +let expected = 0; +let done = 0; + +process.on('exit', function() { + assert.strictEqual(done, expected); +}); + +function test(scheduleMicrotask) { + let nextTickCalled = false; + expected++; + + scheduleMicrotask(function() { + process.nextTick(function() { + nextTickCalled = true; + }); + + setTimeout(function() { + assert(nextTickCalled); + done++; + }, 0); + }); +} + +// first tick case +implementations.forEach(test); + +// tick callback case +setTimeout(function() { + implementations.forEach(function(impl) { + process.nextTick(test.bind(null, impl)); + }); +}, 0); diff --git a/tests/node_compat/test/parallel/test-microtask-queue-run-immediate.js b/tests/node_compat/test/parallel/test-microtask-queue-run-immediate.js new file mode 100644 index 0000000000..a1dff2c7e9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-microtask-queue-run-immediate.js @@ -0,0 +1,66 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +function enqueueMicrotask(fn) { + Promise.resolve().then(fn); +} + +let done = 0; + +process.on('exit', function() { + assert.strictEqual(done, 2); +}); + +// No nextTick, microtask +setImmediate(function() { + enqueueMicrotask(function() { + done++; + }); +}); + + +// No nextTick, microtask with nextTick +setImmediate(function() { + let called = false; + + enqueueMicrotask(function() { + process.nextTick(function() { + called = true; + }); + }); + + setImmediate(function() { + if (called) + done++; + }); + +}); diff --git a/tests/node_compat/test/parallel/test-microtask-queue-run.js b/tests/node_compat/test/parallel/test-microtask-queue-run.js new file mode 100644 index 0000000000..43900006f0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-microtask-queue-run.js @@ -0,0 +1,66 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +function enqueueMicrotask(fn) { + Promise.resolve().then(fn); +} + +let done = 0; + +process.on('exit', function() { + assert.strictEqual(done, 2); +}); + +// No nextTick, microtask +setTimeout(function() { + enqueueMicrotask(function() { + done++; + }); +}, 0); + + +// No nextTick, microtask with nextTick +setTimeout(function() { + let called = false; + + enqueueMicrotask(function() { + process.nextTick(function() { + called = true; + }); + }); + + setTimeout(function() { + if (called) + done++; + }, 0); + +}, 0); diff --git a/tests/node_compat/test/parallel/test-module-cache.js b/tests/node_compat/test/parallel/test-module-cache.js new file mode 100644 index 0000000000..01935e9c87 --- /dev/null +++ b/tests/node_compat/test/parallel/test-module-cache.js @@ -0,0 +1,25 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const filePath = tmpdir.resolve('test-module-cache.json'); +assert.throws( + () => require(filePath), + { code: 'MODULE_NOT_FOUND' } +); + +fs.writeFileSync(filePath, '[]'); + +const content = require(filePath); +assert.strictEqual(Array.isArray(content), true); +assert.strictEqual(content.length, 0); diff --git a/tests/node_compat/test/parallel/test-module-circular-symlinks.js b/tests/node_compat/test/parallel/test-module-circular-symlinks.js new file mode 100644 index 0000000000..0b32980588 --- /dev/null +++ b/tests/node_compat/test/parallel/test-module-circular-symlinks.js @@ -0,0 +1,75 @@ +// 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. + +'use strict'; + +// This tests to make sure that modules with symlinked circular dependencies +// do not blow out the module cache and recurse forever. See issue +// https://github.com/nodejs/node/pull/5950 for context. PR #5950 attempted +// to solve a problem with symlinked peer dependencies by caching using the +// symlink path. Unfortunately, that breaks the case tested in this module +// because each symlinked module, despite pointing to the same code on disk, +// is loaded and cached as a separate module instance, which blows up the +// cache and leads to a recursion bug. + +// This test should pass in Node.js v4 and v5. It should pass in Node.js v6 +// after https://github.com/nodejs/node/pull/5950 has been reverted. + +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +// {tmpDir} +// ├── index.js +// └── node_modules +// ├── moduleA +// │ ├── index.js +// │ └── node_modules +// │ └── moduleB -> {tmpDir}/node_modules/moduleB +// └── moduleB +// ├── index.js +// └── node_modules +// └── moduleA -> {tmpDir}/node_modules/moduleA + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); +const tmpDir = tmpdir.path; + +const node_modules = path.join(tmpDir, 'node_modules'); +const moduleA = path.join(node_modules, 'moduleA'); +const moduleB = path.join(node_modules, 'moduleB'); +const moduleA_link = path.join(moduleB, 'node_modules', 'moduleA'); +const moduleB_link = path.join(moduleA, 'node_modules', 'moduleB'); + +fs.mkdirSync(node_modules); +fs.mkdirSync(moduleA); +fs.mkdirSync(moduleB); +fs.mkdirSync(path.join(moduleA, 'node_modules')); +fs.mkdirSync(path.join(moduleB, 'node_modules')); + +try { + fs.symlinkSync(moduleA, moduleA_link); + fs.symlinkSync(moduleB, moduleB_link); +} catch (err) { + if (err.code !== 'EPERM') throw err; + common.skip('insufficient privileges for symlinks'); +} + +fs.writeFileSync(path.join(tmpDir, 'index.js'), + 'module.exports = require(\'moduleA\');', 'utf8'); +fs.writeFileSync(path.join(moduleA, 'index.js'), + 'module.exports = {b: require(\'moduleB\')};', 'utf8'); +fs.writeFileSync(path.join(moduleB, 'index.js'), + 'module.exports = {a: require(\'moduleA\')};', 'utf8'); + +// Ensure that the symlinks are not followed forever... +const obj = require(path.join(tmpDir, 'index')); +assert.ok(obj); +assert.ok(obj.b); +assert.ok(obj.b.a); +assert.ok(!obj.b.a.b); diff --git a/tests/node_compat/test/parallel/test-module-isBuiltin.js b/tests/node_compat/test/parallel/test-module-isBuiltin.js new file mode 100644 index 0000000000..13746a9116 --- /dev/null +++ b/tests/node_compat/test/parallel/test-module-isBuiltin.js @@ -0,0 +1,23 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const { isBuiltin } = require('module'); + +// Includes modules in lib/ (even deprecated ones) +assert(isBuiltin('http')); +assert(isBuiltin('sys')); +assert(isBuiltin('node:fs')); +assert(isBuiltin('node:test')); + +// Does not include internal modules +assert(!isBuiltin('internal/errors')); +assert(!isBuiltin('test')); +assert(!isBuiltin('')); +assert(!isBuiltin(undefined)); diff --git a/tests/node_compat/test/parallel/test-module-multi-extensions.js b/tests/node_compat/test/parallel/test-module-multi-extensions.js new file mode 100644 index 0000000000..36de3187f9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-module-multi-extensions.js @@ -0,0 +1,100 @@ +// 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. + +'use strict'; + +// Refs: https://github.com/nodejs/node/issues/4778 + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const Module = require('module'); +const tmpdir = require('../common/tmpdir'); +const file = tmpdir.resolve('test-extensions.foo.bar'); +const dotfile = tmpdir.resolve('.bar'); +const dotfileWithExtension = tmpdir.resolve('.foo.bar'); + +tmpdir.refresh(); +fs.writeFileSync(file, 'console.log(__filename);', 'utf8'); +fs.writeFileSync(dotfile, 'console.log(__filename);', 'utf8'); +fs.writeFileSync(dotfileWithExtension, 'console.log(__filename);', 'utf8'); + +{ + require.extensions['.bar'] = common.mustNotCall(); + require.extensions['.foo.bar'] = common.mustCall(); + const modulePath = tmpdir.resolve('test-extensions'); + require(modulePath); + require(file); + delete require.cache[file]; + delete require.extensions['.bar']; + delete require.extensions['.foo.bar']; + Module._pathCache = { __proto__: null }; +} + +{ + require.extensions['.foo.bar'] = common.mustCall(); + const modulePath = tmpdir.resolve('test-extensions'); + require(modulePath); + assert.throws( + () => require(`${modulePath}.foo`), + (err) => err.message.startsWith(`Cannot find module '${modulePath}.foo'`) + ); + require(`${modulePath}.foo.bar`); + delete require.cache[file]; + delete require.extensions['.foo.bar']; + Module._pathCache = { __proto__: null }; +} + +{ + const modulePath = tmpdir.resolve('test-extensions'); + assert.throws( + () => require(modulePath), + (err) => err.message.startsWith(`Cannot find module '${modulePath}'`) + ); + delete require.cache[file]; + Module._pathCache = { __proto__: null }; +} + +{ + require.extensions['.bar'] = common.mustNotCall(); + require.extensions['.foo.bar'] = common.mustCall(); + const modulePath = tmpdir.resolve('test-extensions.foo'); + require(modulePath); + delete require.cache[file]; + delete require.extensions['.bar']; + delete require.extensions['.foo.bar']; + Module._pathCache = { __proto__: null }; +} + +{ + require.extensions['.foo.bar'] = common.mustNotCall(); + const modulePath = tmpdir.resolve('test-extensions.foo'); + assert.throws( + () => require(modulePath), + (err) => err.message.startsWith(`Cannot find module '${modulePath}'`) + ); + delete require.extensions['.foo.bar']; + Module._pathCache = { __proto__: null }; +} + +{ + require.extensions['.bar'] = common.mustNotCall(); + require(dotfile); + delete require.cache[dotfile]; + delete require.extensions['.bar']; + Module._pathCache = { __proto__: null }; +} + +{ + require.extensions['.bar'] = common.mustCall(); + require.extensions['.foo.bar'] = common.mustNotCall(); + require(dotfileWithExtension); + delete require.cache[dotfileWithExtension]; + delete require.extensions['.bar']; + delete require.extensions['.foo.bar']; + Module._pathCache = { __proto__: null }; +} diff --git a/tests/node_compat/test/parallel/test-module-nodemodulepaths.js b/tests/node_compat/test/parallel/test-module-nodemodulepaths.js new file mode 100644 index 0000000000..cccbbee7f2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-module-nodemodulepaths.js @@ -0,0 +1,134 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const _module = require('module'); + +const cases = { + 'WIN': [{ + file: 'C:\\Users\\hefangshi\\AppData\\Roaming\ +\\npm\\node_modules\\npm\\node_modules\\minimatch', + expect: [ + 'C:\\Users\\hefangshi\\AppData\\Roaming\ +\\npm\\node_modules\\npm\\node_modules\\minimatch\\node_modules', + 'C:\\Users\\hefangshi\\AppData\\Roaming\ +\\npm\\node_modules\\npm\\node_modules', + 'C:\\Users\\hefangshi\\AppData\\Roaming\\npm\\node_modules', + 'C:\\Users\\hefangshi\\AppData\\Roaming\\node_modules', + 'C:\\Users\\hefangshi\\AppData\\node_modules', + 'C:\\Users\\hefangshi\\node_modules', + 'C:\\Users\\node_modules', + 'C:\\node_modules', + ] + }, { + file: 'C:\\Users\\Rocko Artischocko\\node_stuff\\foo', + expect: [ + 'C:\\Users\\Rocko Artischocko\\node_stuff\\foo\\node_modules', + 'C:\\Users\\Rocko Artischocko\\node_stuff\\node_modules', + 'C:\\Users\\Rocko Artischocko\\node_modules', + 'C:\\Users\\node_modules', + 'C:\\node_modules', + ] + }, { + file: 'C:\\Users\\Rocko Artischocko\\node_stuff\\foo_node_modules', + expect: [ + 'C:\\Users\\Rocko \ +Artischocko\\node_stuff\\foo_node_modules\\node_modules', + 'C:\\Users\\Rocko Artischocko\\node_stuff\\node_modules', + 'C:\\Users\\Rocko Artischocko\\node_modules', + 'C:\\Users\\node_modules', + 'C:\\node_modules', + ] + }, { + file: 'C:\\node_modules', + expect: [ + 'C:\\node_modules', + ] + }, { + file: 'C:\\', + expect: [ + 'C:\\node_modules', + ] + }], + 'POSIX': [{ + file: '/usr/lib/node_modules/npm/node_modules/\ +node-gyp/node_modules/glob/node_modules/minimatch', + expect: [ + '/usr/lib/node_modules/npm/node_modules/\ +node-gyp/node_modules/glob/node_modules/minimatch/node_modules', + '/usr/lib/node_modules/npm/node_modules/\ +node-gyp/node_modules/glob/node_modules', + '/usr/lib/node_modules/npm/node_modules/node-gyp/node_modules', + '/usr/lib/node_modules/npm/node_modules', + '/usr/lib/node_modules', + '/usr/node_modules', + '/node_modules', + ] + }, { + file: '/usr/test/lib/node_modules/npm/foo', + expect: [ + '/usr/test/lib/node_modules/npm/foo/node_modules', + '/usr/test/lib/node_modules/npm/node_modules', + '/usr/test/lib/node_modules', + '/usr/test/node_modules', + '/usr/node_modules', + '/node_modules', + ] + }, { + file: '/usr/test/lib/node_modules/npm/foo_node_modules', + expect: [ + '/usr/test/lib/node_modules/npm/foo_node_modules/node_modules', + '/usr/test/lib/node_modules/npm/node_modules', + '/usr/test/lib/node_modules', + '/usr/test/node_modules', + '/usr/node_modules', + '/node_modules', + ] + }, { + file: '/node_modules', + expect: [ + '/node_modules', + ] + }, { + file: '/', + expect: [ + '/node_modules', + ] + }] +}; + +const platformCases = common.isWindows ? cases.WIN : cases.POSIX; +platformCases.forEach((c) => { + const paths = _module._nodeModulePaths(c.file); + assert.deepStrictEqual( + c.expect, paths, + `case ${c.file} failed, actual paths is ${JSON.stringify(paths)}`); +}); diff --git a/tests/node_compat/test/parallel/test-module-readonly.js b/tests/node_compat/test/parallel/test-module-readonly.js new file mode 100644 index 0000000000..f231f8f940 --- /dev/null +++ b/tests/node_compat/test/parallel/test-module-readonly.js @@ -0,0 +1,55 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +if (!common.isWindows) { + // TODO: Similar checks on *nix-like systems (e.g using chmod or the like) + common.skip('test only runs on Windows'); +} + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); +const cp = require('child_process'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +// Create readOnlyMod.js and set to read only +const readOnlyMod = tmpdir.resolve('readOnlyMod'); +const readOnlyModRelative = path.relative(__dirname, readOnlyMod); +const readOnlyModFullPath = `${readOnlyMod}.js`; + +fs.writeFileSync(readOnlyModFullPath, 'module.exports = 42;'); + +// Removed any inherited ACEs, and any explicitly granted ACEs for the +// current user +cp.execSync( + `icacls.exe "${readOnlyModFullPath}" /inheritance:r /remove "%USERNAME%"`); + +// Grant the current user read & execute only +cp.execSync(`icacls.exe "${readOnlyModFullPath}" /grant "%USERNAME%":RX`); + +let except = null; +try { + // Attempt to load the module. Will fail if write access is required + require(readOnlyModRelative); +} catch (err) { + except = err; +} + +// Remove the explicitly granted rights, and re-enable inheritance +cp.execSync( + `icacls.exe "${readOnlyModFullPath}" /remove "%USERNAME%" /inheritance:e`); + +// Delete the test module (note: tmpdir should get cleaned anyway) +fs.unlinkSync(readOnlyModFullPath); + +assert.ifError(except); diff --git a/tests/node_compat/test/parallel/test-module-relative-lookup.js b/tests/node_compat/test/parallel/test-module-relative-lookup.js new file mode 100644 index 0000000000..4e714f070f --- /dev/null +++ b/tests/node_compat/test/parallel/test-module-relative-lookup.js @@ -0,0 +1,31 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const _module = require('module'); // Avoid collision with global.module + +// Current directory gets highest priority for local modules +function testFirstInPath(moduleName, isLocalModule) { + const assertFunction = isLocalModule ? + assert.strictEqual : + assert.notStrictEqual; + + let paths = _module._resolveLookupPaths(moduleName); + + assertFunction(paths[0], '.'); + + paths = _module._resolveLookupPaths(moduleName, null); + assertFunction(paths && paths[0], '.'); +} + +testFirstInPath('./lodash', true); + +// Relative path on Windows, but a regular file name elsewhere +testFirstInPath('.\\lodash', common.isWindows); diff --git a/tests/node_compat/test/parallel/test-net-after-close.js b/tests/node_compat/test/parallel/test-net-after-close.js new file mode 100644 index 0000000000..2f4428c6ca --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-after-close.js @@ -0,0 +1,58 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const server = net.createServer(common.mustCall((s) => { + console.error('SERVER: got connection'); + s.end(); +})); + +server.listen(0, common.mustCall(() => { + const c = net.createConnection(server.address().port); + c.on('close', common.mustCall(() => { + /* eslint-disable no-unused-expressions */ + console.error('connection closed'); + assert.strictEqual(c._handle, null); + // Calling functions / accessing properties of a closed socket should not + // throw. + c.setNoDelay(); + c.setKeepAlive(); + c.bufferSize; + c.pause(); + c.resume(); + c.address(); + c.remoteAddress; + c.remotePort; + server.close(); + /* eslint-enable no-unused-expressions */ + })); +})); diff --git a/tests/node_compat/test/parallel/test-net-better-error-messages-listen.js b/tests/node_compat/test/parallel/test-net-better-error-messages-listen.js new file mode 100644 index 0000000000..f3ddc597ab --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-better-error-messages-listen.js @@ -0,0 +1,19 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const server = net.createServer(common.mustNotCall()); +server.listen(1, '1.1.1.1', common.mustNotCall()); +server.on('error', common.mustCall(function(e) { + assert.strictEqual(e.address, '1.1.1.1'); + assert.strictEqual(e.port, 1); + assert.strictEqual(e.syscall, 'listen'); +})); diff --git a/tests/node_compat/test/parallel/test-net-bind-twice.js b/tests/node_compat/test/parallel/test-net-bind-twice.js new file mode 100644 index 0000000000..1794c9a54f --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-bind-twice.js @@ -0,0 +1,43 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const server1 = net.createServer(common.mustNotCall()); +server1.listen(0, '127.0.0.1', common.mustCall(function() { + const server2 = net.createServer(common.mustNotCall()); + server2.listen(this.address().port, '127.0.0.1', common.mustNotCall()); + + server2.on('error', common.mustCall(function(e) { + assert.strictEqual(e.code, 'EADDRINUSE'); + server1.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-net-buffersize.js b/tests/node_compat/test/parallel/test-net-buffersize.js new file mode 100644 index 0000000000..71560688c2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-buffersize.js @@ -0,0 +1,59 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const iter = 10; + +const server = net.createServer(function(socket) { + socket.on('readable', function() { + socket.read(); + }); + + socket.on('end', function() { + server.close(); + }); +}); + +server.listen(0, common.mustCall(function() { + const client = net.connect(this.address().port); + + client.on('finish', common.mustCall(() => { + assert.strictEqual(client.bufferSize, 0); + })); + + for (let i = 1; i < iter; i++) { + client.write('a'); + assert.strictEqual(client.bufferSize, i); + } + + client.end(); +})); diff --git a/tests/node_compat/test/parallel/test-net-bytes-written-large.js b/tests/node_compat/test/parallel/test-net-bytes-written-large.js new file mode 100644 index 0000000000..0eae9f10d3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-bytes-written-large.js @@ -0,0 +1,74 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +// Regression test for https://github.com/nodejs/node/issues/19562: +// Writing to a socket first tries to push through as much data as possible +// without blocking synchronously, and, if that is not enough, queues more +// data up for asynchronous writing. +// Check that `bytesWritten` accounts for both parts of a write. + +const N = 10000000; +{ + // Variant 1: Write a Buffer. + const server = net.createServer(common.mustCall((socket) => { + socket.end(Buffer.alloc(N), common.mustCall(() => { + assert.strictEqual(socket.bytesWritten, N); + })); + assert.strictEqual(socket.bytesWritten, N); + })).listen(0, common.mustCall(() => { + const client = net.connect(server.address().port); + client.resume(); + client.on('close', common.mustCall(() => { + assert.strictEqual(client.bytesRead, N); + server.close(); + })); + })); +} + +{ + // Variant 2: Write a string. + const server = net.createServer(common.mustCall((socket) => { + socket.end('a'.repeat(N), common.mustCall(() => { + assert.strictEqual(socket.bytesWritten, N); + })); + assert.strictEqual(socket.bytesWritten, N); + })).listen(0, common.mustCall(() => { + const client = net.connect(server.address().port); + client.resume(); + client.on('close', common.mustCall(() => { + assert.strictEqual(client.bytesRead, N); + server.close(); + })); + })); +} + +{ + // Variant 2: writev() with mixed data. + const server = net.createServer(common.mustCall((socket) => { + socket.cork(); + socket.write('a'.repeat(N)); + assert.strictEqual(socket.bytesWritten, N); + socket.write(Buffer.alloc(N)); + assert.strictEqual(socket.bytesWritten, 2 * N); + socket.end('', common.mustCall(() => { + assert.strictEqual(socket.bytesWritten, 2 * N); + })); + socket.uncork(); + })).listen(0, common.mustCall(() => { + const client = net.connect(server.address().port); + client.resume(); + client.on('close', common.mustCall(() => { + assert.strictEqual(client.bytesRead, 2 * N); + server.close(); + })); + })); +} diff --git a/tests/node_compat/test/parallel/test-net-can-reset-timeout.js b/tests/node_compat/test/parallel/test-net-can-reset-timeout.js new file mode 100644 index 0000000000..1abd0a16a5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-can-reset-timeout.js @@ -0,0 +1,64 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +// Ref: https://github.com/nodejs/node-v0.x-archive/issues/481 + +const net = require('net'); + +const server = net.createServer(common.mustCall(function(stream) { + stream.setTimeout(100); + + stream.resume(); + + stream.once('timeout', common.mustCall(function() { + console.log('timeout'); + // Try to reset the timeout. + stream.write('WHAT.'); + })); + + stream.on('end', common.mustCall(function() { + console.log('server side end'); + stream.end(); + })); +})); + +server.listen(0, common.mustCall(function() { + const c = net.createConnection(this.address().port); + + c.on('data', function() { + c.end(); + }); + + c.on('end', function() { + console.log('client side end'); + server.close(); + }); +})); diff --git a/tests/node_compat/test/parallel/test-net-connect-call-socket-connect.js b/tests/node_compat/test/parallel/test-net-connect-call-socket-connect.js new file mode 100644 index 0000000000..db0cef479e --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-connect-call-socket-connect.js @@ -0,0 +1,46 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// This test checks that calling `net.connect` internally calls +// `Socket.prototype.connect`. +// +// This is important for people who monkey-patch `Socket.prototype.connect` +// since it's not possible to monkey-patch `net.connect` directly (as the core +// `connect` function is called internally in Node instead of calling the +// `exports.connect` function). +// +// Monkey-patching of `Socket.prototype.connect` is done by - among others - +// most APM vendors, the async-listener module and the +// continuation-local-storage module. +// +// Related: +// - https://github.com/nodejs/node/pull/12342 +// - https://github.com/nodejs/node/pull/12852 + +const net = require('net'); +const Socket = net.Socket; + +// Monkey patch Socket.prototype.connect to check that it's called. +const orig = Socket.prototype.connect; +Socket.prototype.connect = common.mustCall(function() { + return orig.apply(this, arguments); +}); + +const server = net.createServer(); + +server.listen(common.mustCall(function() { + const port = server.address().port; + const client = net.connect({ port }, common.mustCall(function() { + client.end(); + })); + client.on('end', common.mustCall(function() { + server.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-net-connect-options-fd.js b/tests/node_compat/test/parallel/test-net-connect-options-fd.js new file mode 100644 index 0000000000..f9aa99c12b --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-connect-options-fd.js @@ -0,0 +1,110 @@ +// 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); + })); +} diff --git a/tests/node_compat/test/parallel/test-net-connect-options-ipv6.js b/tests/node_compat/test/parallel/test-net-connect-options-ipv6.js new file mode 100644 index 0000000000..de309e7be2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-connect-options-ipv6.js @@ -0,0 +1,74 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Test that the family option of net.connect is honored. + +'use strict'; +const common = require('../common'); +if (!common.hasIPv6) + common.skip('no IPv6 support'); + +const assert = require('assert'); +const net = require('net'); + +const hostAddrIPv6 = '::1'; +const HOSTNAME = 'dummy'; + +const server = net.createServer({ allowHalfOpen: true }, (socket) => { + socket.resume(); + socket.on('end', common.mustCall()); + socket.end(); +}); + +function tryConnect() { + const connectOpt = { + host: HOSTNAME, + port: server.address().port, + family: 6, + allowHalfOpen: true, + lookup: common.mustCall((addr, opt, cb) => { + assert.strictEqual(addr, HOSTNAME); + assert.strictEqual(opt.family, 6); + cb(null, hostAddrIPv6, opt.family); + }) + }; + // No `mustCall`, since test could skip, and it's the only path to `close`. + const client = net.connect(connectOpt, () => { + client.resume(); + client.on('end', () => { + // Wait for next uv tick and make sure the socket stream is writable. + setTimeout(function() { + assert(client.writable); + client.end(); + }, 10); + }); + client.on('close', () => server.close()); + }); +} + +server.listen(0, hostAddrIPv6, tryConnect); diff --git a/tests/node_compat/test/parallel/test-net-connect-options-port.js b/tests/node_compat/test/parallel/test-net-connect-options-port.js new file mode 100644 index 0000000000..b4f747b3ef --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-connect-options-port.js @@ -0,0 +1,237 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const dns = require('dns'); +const net = require('net'); + +// Test wrong type of ports +{ + const portTypeError = { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }; + + syncFailToConnect(true, portTypeError); + syncFailToConnect(false, portTypeError); + syncFailToConnect([], portTypeError, true); + syncFailToConnect({}, portTypeError, true); + syncFailToConnect(null, portTypeError); +} + +// Test out of range ports +{ + const portRangeError = { + code: 'ERR_SOCKET_BAD_PORT', + name: 'RangeError' + }; + + syncFailToConnect('', portRangeError); + syncFailToConnect(' ', portRangeError); + syncFailToConnect('0x', portRangeError, true); + syncFailToConnect('-0x1', portRangeError, true); + syncFailToConnect(NaN, portRangeError); + syncFailToConnect(Infinity, portRangeError); + syncFailToConnect(-1, portRangeError); + syncFailToConnect(65536, portRangeError); +} + +// Test invalid hints +{ + // connect({hint}, cb) and connect({hint}) + const hints = (dns.ADDRCONFIG | dns.V4MAPPED | dns.ALL) + 42; + const hintOptBlocks = doConnect([{ port: 42, hints }], + () => common.mustNotCall()); + for (const fn of hintOptBlocks) { + assert.throws(fn, { + code: 'ERR_INVALID_ARG_VALUE', + name: 'TypeError', + message: /The argument 'hints' is invalid\. Received \d+/ + }); + } +} + +// Test valid combinations of connect(port) and connect(port, host) +{ + const expectedConnections = 72; + let serverConnected = 0; + + const server = net.createServer(common.mustCall((socket) => { + socket.end('ok'); + if (++serverConnected === expectedConnections) { + server.close(); + } + }, expectedConnections)); + + server.listen(0, common.localhostIPv4, common.mustCall(() => { + const port = server.address().port; + + // Total connections = 3 * 4(canConnect) * 6(doConnect) = 72 + canConnect(port); + canConnect(String(port)); + canConnect(`0x${port.toString(16)}`); + })); + + // Try connecting to random ports, but do so once the server is closed + server.on('close', () => { + asyncFailToConnect(0); + }); +} + +function doConnect(args, getCb) { + return [ + function createConnectionWithCb() { + return net.createConnection.apply(net, args.concat(getCb())) + .resume(); + }, + function createConnectionWithoutCb() { + return net.createConnection.apply(net, args) + .on('connect', getCb()) + .resume(); + }, + function connectWithCb() { + return net.connect.apply(net, args.concat(getCb())) + .resume(); + }, + function connectWithoutCb() { + return net.connect.apply(net, args) + .on('connect', getCb()) + .resume(); + }, + function socketConnectWithCb() { + const socket = new net.Socket(); + return socket.connect.apply(socket, args.concat(getCb())) + .resume(); + }, + function socketConnectWithoutCb() { + const socket = new net.Socket(); + return socket.connect.apply(socket, args) + .on('connect', getCb()) + .resume(); + }, + ]; +} + +function syncFailToConnect(port, assertErr, optOnly) { + const family = 4; + if (!optOnly) { + // connect(port, cb) and connect(port) + const portArgFunctions = doConnect([{ port, family }], + () => common.mustNotCall()); + for (const fn of portArgFunctions) { + assert.throws(fn, assertErr, `${fn.name}(${port})`); + } + + // connect(port, host, cb) and connect(port, host) + const portHostArgFunctions = doConnect([{ port, + host: 'localhost', + family }], + () => common.mustNotCall()); + for (const fn of portHostArgFunctions) { + assert.throws(fn, assertErr, `${fn.name}(${port}, 'localhost')`); + } + } + // connect({port}, cb) and connect({port}) + const portOptFunctions = doConnect([{ port, family }], + () => common.mustNotCall()); + for (const fn of portOptFunctions) { + assert.throws(fn, assertErr, `${fn.name}({port: ${port}})`); + } + + // connect({port, host}, cb) and connect({port, host}) + const portHostOptFunctions = doConnect([{ port: port, + host: 'localhost', + family: family }], + () => common.mustNotCall()); + for (const fn of portHostOptFunctions) { + assert.throws(fn, + assertErr, + `${fn.name}({port: ${port}, host: 'localhost'})`); + } +} + +function canConnect(port) { + const noop = () => common.mustCall(); + const family = 4; + + // connect(port, cb) and connect(port) + const portArgFunctions = doConnect([{ port, family }], noop); + for (const fn of portArgFunctions) { + fn(); + } + + // connect(port, host, cb) and connect(port, host) + const portHostArgFunctions = doConnect([{ port, host: 'localhost', family }], + noop); + for (const fn of portHostArgFunctions) { + fn(); + } + + // connect({port}, cb) and connect({port}) + const portOptFunctions = doConnect([{ port, family }], noop); + for (const fn of portOptFunctions) { + fn(); + } + + // connect({port, host}, cb) and connect({port, host}) + const portHostOptFns = doConnect([{ port, host: 'localhost', family }], + noop); + for (const fn of portHostOptFns) { + fn(); + } +} + +function asyncFailToConnect(port) { + const onError = () => common.mustCall((err) => { + const regexp = /^Error: connect E\w+.+$/; + assert.match(String(err), regexp); + }); + + const dont = () => common.mustNotCall(); + const family = 4; + // connect(port, cb) and connect(port) + const portArgFunctions = doConnect([{ port, family }], dont); + for (const fn of portArgFunctions) { + fn().on('error', onError()); + } + + // connect({port}, cb) and connect({port}) + const portOptFunctions = doConnect([{ port, family }], dont); + for (const fn of portOptFunctions) { + fn().on('error', onError()); + } + + // connect({port, host}, cb) and connect({port, host}) + const portHostOptFns = doConnect([{ port, host: 'localhost', family }], + dont); + for (const fn of portHostOptFns) { + fn().on('error', onError()); + } +} diff --git a/tests/node_compat/test/parallel/test-net-connect-paused-connection.js b/tests/node_compat/test/parallel/test-net-connect-paused-connection.js new file mode 100644 index 0000000000..81c28aaa89 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-connect-paused-connection.js @@ -0,0 +1,40 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +const net = require('net'); + +net.createServer(function(conn) { + conn.unref(); +}).listen(0, common.mustCall(function() { + net.connect(this.address().port, 'localhost').pause(); + + setTimeout(common.mustNotCall('expected to exit'), 1000).unref(); +})).unref(); diff --git a/tests/node_compat/test/parallel/test-net-dns-custom-lookup.js b/tests/node_compat/test/parallel/test-net-dns-custom-lookup.js new file mode 100644 index 0000000000..124a1f804b --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-dns-custom-lookup.js @@ -0,0 +1,74 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +function check(addressType, cb) { + const server = net.createServer(function(client) { + client.end(); + server.close(); + cb && cb(); + }); + + const address = addressType === 4 ? common.localhostIPv4 : '::1'; + server.listen(0, address, common.mustCall(function() { + net.connect({ + port: this.address().port, + host: 'localhost', + family: addressType, + lookup: lookup + }).on('lookup', common.mustCall(function(err, ip, type) { + assert.strictEqual(err, null); + assert.strictEqual(address, ip); + assert.strictEqual(type, addressType); + })); + })); + + function lookup(host, dnsopts, cb) { + dnsopts.family = addressType; + + if (addressType === 4) { + process.nextTick(function() { + if (dnsopts.all) { + cb(null, [{ address: common.localhostIPv4, family: 4 }]); + } else { + cb(null, common.localhostIPv4, 4); + } + }); + } else { + process.nextTick(function() { + if (dnsopts.all) { + cb(null, [{ address: '::1', family: 6 }]); + } else { + cb(null, '::1', 6); + } + }); + } + } +} + +check(4, function() { + common.hasIPv6 && check(6); +}); + +// Verify that bad lookup() IPs are handled. +{ + net.connect({ + host: 'localhost', + port: 80, + lookup(host, dnsopts, cb) { + if (dnsopts.all) { + cb(null, [{ address: undefined, family: 4 }]); + } else { + cb(null, undefined, 4); + } + } + }).on('error', common.expectsError({ code: 'ERR_INVALID_IP_ADDRESS' })); +} diff --git a/tests/node_compat/test/parallel/test-net-dns-lookup-skip.js b/tests/node_compat/test/parallel/test-net-dns-lookup-skip.js new file mode 100644 index 0000000000..5010f73e66 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-dns-lookup-skip.js @@ -0,0 +1,26 @@ +// 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. + +'use strict'; +const common = require('../common'); +const net = require('net'); + +function check(addressType) { + const server = net.createServer(function(client) { + client.end(); + server.close(); + }); + + const address = addressType === 4 ? '127.0.0.1' : '::1'; + server.listen(0, address, function() { + net.connect(this.address().port, address) + .on('lookup', common.mustNotCall()); + }); +} + +check(4); +common.hasIPv6 && check(6); diff --git a/tests/node_compat/test/parallel/test-net-dns-lookup.js b/tests/node_compat/test/parallel/test-net-dns-lookup.js new file mode 100644 index 0000000000..69278d4fbd --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-dns-lookup.js @@ -0,0 +1,47 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const server = net.createServer(function(client) { + client.end(); + server.close(); +}); + +server.listen(0, common.mustCall(function() { + net.connect(this.address().port, 'localhost') + .on('lookup', common.mustCallAtLeast(function(err, ip, type, host) { + assert.strictEqual(err, null); + assert.match(ip, /^(127\.0\.0\.1|::1)$/); + assert.match(type.toString(), /^(4|6)$/); + assert.strictEqual(host, 'localhost'); + }, 1)); +})); diff --git a/tests/node_compat/test/parallel/test-net-eaddrinuse.js b/tests/node_compat/test/parallel/test-net-eaddrinuse.js new file mode 100644 index 0000000000..12069e3cb1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-eaddrinuse.js @@ -0,0 +1,44 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const server1 = net.createServer(function(socket) { +}); +const server2 = net.createServer(function(socket) { +}); +server1.listen(0, common.mustCall(function() { + server2.on('error', function(error) { + assert.strictEqual(error.message.includes('EADDRINUSE'), true); + server1.close(); + }); + server2.listen(this.address().port); +})); diff --git a/tests/node_compat/test/parallel/test-net-error-twice.js b/tests/node_compat/test/parallel/test-net-error-twice.js new file mode 100644 index 0000000000..950847cb2e --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-error-twice.js @@ -0,0 +1,70 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const net = require('net'); + +const buf = Buffer.alloc(10 * 1024 * 1024, 0x62); + +const errs = []; +let clientSocket; +let serverSocket; + +function ready() { + if (clientSocket && serverSocket) { + clientSocket.destroy(); + serverSocket.write(buf); + } +} + +const server = net.createServer(function onConnection(conn) { + conn.on('error', function(err) { + errs.push(err); + if (errs.length > 1 && errs[0] === errs[1]) + assert.fail('Should not emit the same error twice'); + }); + conn.on('close', function() { + server.unref(); + }); + serverSocket = conn; + ready(); +}).listen(0, function() { + const client = net.connect({ port: this.address().port }); + + client.on('connect', function() { + clientSocket = client; + ready(); + }); +}); + +process.on('exit', function() { + console.log(errs); + assert.strictEqual(errs.length, 1); +}); diff --git a/tests/node_compat/test/parallel/test-net-keepalive.js b/tests/node_compat/test/parallel/test-net-keepalive.js new file mode 100644 index 0000000000..4f01b46751 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-keepalive.js @@ -0,0 +1,59 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +let serverConnection; +let clientConnection; +const echoServer = net.createServer(function(connection) { + serverConnection = connection; + setTimeout(common.mustCall(function() { + // Make sure both connections are still open + assert.strictEqual(serverConnection.readyState, 'open'); + assert.strictEqual(clientConnection.readyState, 'open'); + serverConnection.end(); + clientConnection.end(); + echoServer.close(); + }, 1), common.platformTimeout(100)); + connection.setTimeout(0); + assert.notStrictEqual(connection.setKeepAlive, undefined); + // Send a keepalive packet after 50 ms + connection.setKeepAlive(true, common.platformTimeout(50)); + connection.on('end', function() { + connection.end(); + }); +}); +echoServer.listen(0); + +echoServer.on('listening', function() { + clientConnection = net.createConnection(this.address().port); + clientConnection.setTimeout(0); +}); diff --git a/tests/node_compat/test/parallel/test-net-listen-after-destroying-stdin.js b/tests/node_compat/test/parallel/test-net-listen-after-destroying-stdin.js new file mode 100644 index 0000000000..7dbc610f95 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-listen-after-destroying-stdin.js @@ -0,0 +1,29 @@ +// 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. + +'use strict'; +// Just test that destroying stdin doesn't mess up listening on a server. +// This is a regression test for +// https://github.com/nodejs/node-v0.x-archive/issues/746. + +const common = require('../common'); +const net = require('net'); + +process.stdin.destroy(); + +const server = net.createServer(common.mustCall((socket) => { + console.log('accepted...'); + socket.end(common.mustCall(() => { console.log('finished...'); })); + server.close(common.mustCall(() => { console.log('closed'); })); +})); + + +server.listen(0, common.mustCall(() => { + console.log('listening...'); + + net.createConnection(server.address().port); +})); diff --git a/tests/node_compat/test/parallel/test-net-listen-error.js b/tests/node_compat/test/parallel/test-net-listen-error.js new file mode 100644 index 0000000000..e8a7b2a931 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-listen-error.js @@ -0,0 +1,36 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const net = require('net'); + +const server = net.createServer(function(socket) { +}); +server.listen(1, '1.1.1.1', common.mustNotCall()); // EACCES or EADDRNOTAVAIL +server.on('error', common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-net-local-address-port.js b/tests/node_compat/test/parallel/test-net-local-address-port.js new file mode 100644 index 0000000000..9b18f89ee5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-local-address-port.js @@ -0,0 +1,50 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const server = net.createServer(common.mustCall(function(socket) { + assert.strictEqual(socket.localAddress, common.localhostIPv4); + assert.strictEqual(socket.localPort, this.address().port); + assert.strictEqual(socket.localFamily, this.address().family); + socket.on('end', function() { + server.close(); + }); + socket.resume(); +})); + +server.listen(0, common.localhostIPv4, function() { + const client = net.createConnection(this.address() + .port, common.localhostIPv4); + client.on('connect', function() { + client.end(); + }); +}); diff --git a/tests/node_compat/test/parallel/test-net-pause-resume-connecting.js b/tests/node_compat/test/parallel/test-net-pause-resume-connecting.js new file mode 100644 index 0000000000..774ad66742 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-pause-resume-connecting.js @@ -0,0 +1,102 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +let connections = 0; +let dataEvents = 0; +let conn; + + +// Server +const server = net.createServer(function(conn) { + connections++; + conn.end('This was the year he fell to pieces.'); + + if (connections === 5) + server.close(); +}); + +server.listen(0, function() { + // Client 1 + conn = net.createConnection(this.address().port, 'localhost'); + conn.resume(); + conn.on('data', onDataOk); + + + // Client 2 + conn = net.createConnection(this.address().port, 'localhost'); + conn.pause(); + conn.resume(); + conn.on('data', onDataOk); + + + // Client 3 + conn = net.createConnection(this.address().port, 'localhost'); + conn.pause(); + conn.on('data', common.mustNotCall()); + scheduleTearDown(conn); + + + // Client 4 + conn = net.createConnection(this.address().port, 'localhost'); + conn.resume(); + conn.pause(); + conn.resume(); + conn.on('data', onDataOk); + + + // Client 5 + conn = net.createConnection(this.address().port, 'localhost'); + conn.resume(); + conn.resume(); + conn.pause(); + conn.on('data', common.mustNotCall()); + scheduleTearDown(conn); + + function onDataOk() { + dataEvents++; + } + + function scheduleTearDown(conn) { + setTimeout(function() { + conn.removeAllListeners('data'); + conn.resume(); + }, 100); + } +}); + + +// Exit sanity checks +process.on('exit', function() { + assert.strictEqual(connections, 5); + assert.strictEqual(dataEvents, 3); +}); diff --git a/tests/node_compat/test/parallel/test-net-persistent-keepalive.js b/tests/node_compat/test/parallel/test-net-persistent-keepalive.js new file mode 100644 index 0000000000..80ab2a08db --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-persistent-keepalive.js @@ -0,0 +1,41 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const net = require('net'); + +let serverConnection; +let clientConnection; +const echoServer = net.createServer(function(connection) { + serverConnection = connection; + setTimeout(function() { + // Make sure both connections are still open + assert.strictEqual(serverConnection.readyState, 'open'); + assert.strictEqual(clientConnection.readyState, 'open'); + serverConnection.end(); + clientConnection.end(); + echoServer.close(); + }, 600); + connection.setTimeout(0); + assert.strictEqual(typeof connection.setKeepAlive, 'function'); + connection.on('end', function() { + connection.end(); + }); +}); +echoServer.listen(0); + +echoServer.on('listening', function() { + clientConnection = new net.Socket(); + // Send a keepalive packet after 1000 ms + // and make sure it persists + const s = clientConnection.setKeepAlive(true, 400); + assert.ok(s instanceof net.Socket); + clientConnection.connect(this.address().port); + clientConnection.setTimeout(0); +}); diff --git a/tests/node_compat/test/parallel/test-net-persistent-nodelay.js b/tests/node_compat/test/parallel/test-net-persistent-nodelay.js new file mode 100644 index 0000000000..c8733e3138 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-persistent-nodelay.js @@ -0,0 +1,43 @@ +// 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'; +require('../common'); +const assert = require('assert'); +const net = require('net'); +const { internalBinding } = require('internal/test/binding'); +const TCPWrap = internalBinding('tcp_wrap').TCP; + +const echoServer = net.createServer(function(connection) { + connection.end(); +}); +echoServer.listen(0); + +let callCount = 0; + +const Socket = net.Socket; +const setNoDelay = TCPWrap.prototype.setNoDelay; + +TCPWrap.prototype.setNoDelay = function(enable) { + setNoDelay.call(this, enable); + callCount++; +}; + +echoServer.on('listening', function() { + const sock1 = new Socket(); + // setNoDelay before the handle is created + // there is probably a better way to test this + + const s = sock1.setNoDelay(); + assert.ok(s instanceof net.Socket); + sock1.connect(this.address().port); + sock1.on('end', function() { + assert.strictEqual(callCount, 1); + echoServer.close(); + }); +}); diff --git a/tests/node_compat/test/parallel/test-net-persistent-ref-unref.js b/tests/node_compat/test/parallel/test-net-persistent-ref-unref.js new file mode 100644 index 0000000000..565f1211b1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-persistent-ref-unref.js @@ -0,0 +1,48 @@ +// 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'; +require('../common'); +const assert = require('assert'); +const net = require('net'); +const { internalBinding } = require('internal/test/binding'); +const TCPWrap = internalBinding('tcp_wrap').TCP; + +const echoServer = net.createServer((conn) => { + conn.end(); +}); + +const ref = TCPWrap.prototype.ref; +const unref = TCPWrap.prototype.unref; + +let refCount = 0; + +TCPWrap.prototype.ref = function() { + ref.call(this); + refCount++; + assert.strictEqual(refCount, 0); +}; + +TCPWrap.prototype.unref = function() { + unref.call(this); + refCount--; + assert.strictEqual(refCount, -1); +}; + +echoServer.listen(0); + +echoServer.on('listening', function() { + const sock = new net.Socket(); + sock.unref(); + sock.ref(); + sock.connect(this.address().port); + sock.on('end', () => { + assert.strictEqual(refCount, 0); + echoServer.close(); + }); +}); diff --git a/tests/node_compat/test/parallel/test-net-reconnect.js b/tests/node_compat/test/parallel/test-net-reconnect.js new file mode 100644 index 0000000000..65a8718e9e --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-reconnect.js @@ -0,0 +1,95 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const net = require('net'); + +const N = 50; +let client_recv_count = 0; +let client_end_count = 0; +let disconnect_count = 0; + +const server = net.createServer(function(socket) { + console.error('SERVER: got socket connection'); + socket.resume(); + + console.error('SERVER connect, writing'); + socket.write('hello\r\n'); + + socket.on('end', () => { + console.error('SERVER socket end, calling end()'); + socket.end(); + }); + + socket.on('close', (had_error) => { + console.log(`SERVER had_error: ${JSON.stringify(had_error)}`); + assert.strictEqual(had_error, false); + }); +}); + +server.listen(0, function() { + console.log('SERVER listening'); + const client = net.createConnection(this.address().port); + + client.setEncoding('UTF8'); + + client.on('connect', () => { + console.error('CLIENT connected', client._writableState); + }); + + client.on('data', function(chunk) { + client_recv_count += 1; + console.log(`client_recv_count ${client_recv_count}`); + assert.strictEqual(chunk, 'hello\r\n'); + console.error('CLIENT: calling end', client._writableState); + client.end(); + }); + + client.on('end', () => { + console.error('CLIENT end'); + client_end_count++; + }); + + client.on('close', (had_error) => { + console.log('CLIENT disconnect'); + assert.strictEqual(had_error, false); + if (disconnect_count++ < N) + client.connect(server.address().port); // reconnect + else + server.close(); + }); +}); + +process.on('exit', () => { + assert.strictEqual(disconnect_count, N + 1); + assert.strictEqual(client_recv_count, N + 1); + assert.strictEqual(client_end_count, N + 1); +}); diff --git a/tests/node_compat/test/parallel/test-net-remote-address-port.js b/tests/node_compat/test/parallel/test-net-remote-address-port.js new file mode 100644 index 0000000000..ff1d209bea --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-remote-address-port.js @@ -0,0 +1,91 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const net = require('net'); + +let conns_closed = 0; + +const remoteAddrCandidates = [ common.localhostIPv4, + '::1', + '::ffff:127.0.0.1' ]; + +const remoteFamilyCandidates = ['IPv4', 'IPv6']; + +const server = net.createServer(common.mustCall(function(socket) { + assert.ok(remoteAddrCandidates.includes(socket.remoteAddress), + `Invalid remoteAddress: ${socket.remoteAddress}`); + assert.ok(remoteFamilyCandidates.includes(socket.remoteFamily), + `Invalid remoteFamily: ${socket.remoteFamily}`); + assert.ok(socket.remotePort); + assert.notStrictEqual(socket.remotePort, this.address().port); + socket.on('end', function() { + if (++conns_closed === 2) server.close(); + }); + socket.on('close', function() { + assert.ok(remoteAddrCandidates.includes(socket.remoteAddress)); + assert.ok(remoteFamilyCandidates.includes(socket.remoteFamily)); + }); + socket.resume(); +}, 2)); + +server.listen(0, function() { + const client = net.createConnection(this.address().port, '127.0.0.1'); + const client2 = net.createConnection(this.address().port); + + assert.strictEqual(client.remoteAddress, undefined); + assert.strictEqual(client.remoteFamily, undefined); + assert.strictEqual(client.remotePort, undefined); + assert.strictEqual(client2.remoteAddress, undefined); + assert.strictEqual(client2.remoteFamily, undefined); + assert.strictEqual(client2.remotePort, undefined); + + client.on('connect', function() { + assert.ok(remoteAddrCandidates.includes(client.remoteAddress)); + assert.ok(remoteFamilyCandidates.includes(client.remoteFamily)); + assert.strictEqual(client.remotePort, server.address().port); + client.end(); + }); + client.on('close', function() { + assert.ok(remoteAddrCandidates.includes(client.remoteAddress)); + assert.ok(remoteFamilyCandidates.includes(client.remoteFamily)); + }); + client2.on('connect', function() { + assert.ok(remoteAddrCandidates.includes(client2.remoteAddress)); + assert.ok(remoteFamilyCandidates.includes(client2.remoteFamily)); + assert.strictEqual(client2.remotePort, server.address().port); + client2.end(); + }); + client2.on('close', function() { + assert.ok(remoteAddrCandidates.includes(client2.remoteAddress)); + assert.ok(remoteFamilyCandidates.includes(client2.remoteFamily)); + }); +}); diff --git a/tests/node_compat/test/parallel/test-net-remote-address.js b/tests/node_compat/test/parallel/test-net-remote-address.js new file mode 100644 index 0000000000..a157352674 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-remote-address.js @@ -0,0 +1,30 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const net = require('net'); +const { strictEqual } = require('assert'); + +const server = net.createServer(); + +server.listen(common.mustCall(function() { + const socket = net.connect({ port: server.address().port }); + + strictEqual(socket.connecting, true); + strictEqual(socket.remoteAddress, undefined); + + socket.on('connect', common.mustCall(function() { + strictEqual(socket.remoteAddress !== undefined, true); + socket.end(); + })); + + socket.on('end', common.mustCall(function() { + server.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-net-server-capture-rejection.js b/tests/node_compat/test/parallel/test-net-server-capture-rejection.js new file mode 100644 index 0000000000..21289d571d --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-server-capture-rejection.js @@ -0,0 +1,34 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const events = require('events'); +const { createServer, connect } = require('net'); + +events.captureRejections = true; + +const server = createServer(common.mustCall(async (sock) => { + server.close(); + + const _err = new Error('kaboom'); + sock.on('error', common.mustCall((err) => { + assert.strictEqual(err, _err); + })); + throw _err; +})); + +server.listen(0, common.mustCall(() => { + const sock = connect( + server.address().port, + server.address().host + ); + + sock.on('close', common.mustCall()); +})); diff --git a/tests/node_compat/test/parallel/test-net-server-close.js b/tests/node_compat/test/parallel/test-net-server-close.js new file mode 100644 index 0000000000..417bc11d86 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-server-close.js @@ -0,0 +1,52 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const sockets = []; + +const server = net.createServer(function(c) { + c.on('close', common.mustCall()); + + sockets.push(c); + + if (sockets.length === 2) { + assert.strictEqual(server.close(), server); + sockets.forEach((c) => c.destroy()); + } +}); + +server.on('close', common.mustCall()); + +assert.strictEqual(server, server.listen(0, () => { + net.createConnection(server.address().port); + net.createConnection(server.address().port); +})); diff --git a/tests/node_compat/test/parallel/test-net-server-pause-on-connect.js b/tests/node_compat/test/parallel/test-net-server-pause-on-connect.js new file mode 100644 index 0000000000..eb2b94d51c --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-server-pause-on-connect.js @@ -0,0 +1,79 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); +const msg = 'test'; +let stopped = true; +let server1Sock; + + +const server1ConnHandler = (socket) => { + socket.on('data', function(data) { + if (stopped) { + assert.fail('data event should not have happened yet'); + } + + assert.strictEqual(data.toString(), msg); + socket.end(); + server1.close(); + }); + + server1Sock = socket; +}; + +const server1 = net.createServer({ pauseOnConnect: true }, server1ConnHandler); + +const server2ConnHandler = (socket) => { + socket.on('data', function(data) { + assert.strictEqual(data.toString(), msg); + socket.end(); + server2.close(); + + assert.strictEqual(server1Sock.bytesRead, 0); + server1Sock.resume(); + stopped = false; + }); +}; + +const server2 = net.createServer({ pauseOnConnect: false }, server2ConnHandler); + +server1.listen(0, function() { + const clientHandler = common.mustCall(function() { + server2.listen(0, function() { + net.createConnection({ port: this.address().port }).write(msg); + }); + }); + net.createConnection({ port: this.address().port }).write(msg, clientHandler); +}); + +process.on('exit', function() { + assert.strictEqual(stopped, false); +}); diff --git a/tests/node_compat/test/parallel/test-net-settimeout.js b/tests/node_compat/test/parallel/test-net-settimeout.js new file mode 100644 index 0000000000..a1905b7f19 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-settimeout.js @@ -0,0 +1,57 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// This example sets a timeout then immediately attempts to disable the timeout +// https://github.com/joyent/node/pull/2245 + +const common = require('../common'); +const net = require('net'); +const assert = require('assert'); + +const T = 100; + +const server = net.createServer(common.mustCall((c) => { + c.write('hello'); +})); + +server.listen(0, function() { + const socket = net.createConnection(this.address().port, 'localhost'); + + const s = socket.setTimeout(T, common.mustNotCall()); + assert.ok(s instanceof net.Socket); + + socket.on('data', common.mustCall(() => { + setTimeout(function() { + socket.destroy(); + server.close(); + }, T * 2); + })); + + socket.setTimeout(0); +}); diff --git a/tests/node_compat/test/parallel/test-net-socket-close-after-end.js b/tests/node_compat/test/parallel/test-net-socket-close-after-end.js new file mode 100644 index 0000000000..27540e8fe6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-close-after-end.js @@ -0,0 +1,38 @@ +// 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. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const net = require('net'); + +const server = net.createServer(); + +server.on('connection', (socket) => { + let endEmitted = false; + + socket.once('readable', () => { + setTimeout(() => { + socket.read(); + }, common.platformTimeout(100)); + }); + socket.on('end', () => { + endEmitted = true; + }); + socket.on('close', () => { + assert(endEmitted); + server.close(); + }); + socket.end('foo'); +}); + +server.listen(common.mustCall(() => { + const socket = net.createConnection(server.address().port, () => { + socket.end('foo'); + }); +})); diff --git a/tests/node_compat/test/parallel/test-net-socket-connect-invalid-autoselectfamily.js b/tests/node_compat/test/parallel/test-net-socket-connect-invalid-autoselectfamily.js new file mode 100644 index 0000000000..110aadf7dd --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-connect-invalid-autoselectfamily.js @@ -0,0 +1,16 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const net = require('net'); + +assert.throws(() => { + net.connect({ port: 8080, autoSelectFamily: 'INVALID' }); +}, { code: 'ERR_INVALID_ARG_TYPE' }); diff --git a/tests/node_compat/test/parallel/test-net-socket-connect-without-cb.js b/tests/node_compat/test/parallel/test-net-socket-connect-without-cb.js new file mode 100644 index 0000000000..20c493e2a9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-connect-without-cb.js @@ -0,0 +1,33 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// This test ensures that socket.connect can be called without callback +// which is optional. + +const net = require('net'); + +const server = net.createServer(common.mustCall(function(conn) { + conn.end(); + server.close(); +})).listen(0, common.mustCall(function() { + const client = new net.Socket(); + + client.on('connect', common.mustCall(function() { + client.end(); + })); + + const address = server.address(); + if (!common.hasIPv6 && address.family === 'IPv6') { + // Necessary to pass CI running inside containers. + client.connect(address.port); + } else { + client.connect(address); + } +})); diff --git a/tests/node_compat/test/parallel/test-net-socket-connecting.js b/tests/node_compat/test/parallel/test-net-socket-connecting.js new file mode 100644 index 0000000000..f5101e81d8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-connecting.js @@ -0,0 +1,28 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const net = require('net'); + +const server = net.createServer((conn) => { + conn.end(); + server.close(); +}).listen(0, () => { + const client = net.connect(server.address().port, () => { + assert.strictEqual(client.connecting, false); + + // Legacy getter + assert.strictEqual(client._connecting, false); + client.end(); + }); + assert.strictEqual(client.connecting, true); + + // Legacy getter + assert.strictEqual(client._connecting, true); +}); diff --git a/tests/node_compat/test/parallel/test-net-socket-destroy-send.js b/tests/node_compat/test/parallel/test-net-socket-destroy-send.js new file mode 100644 index 0000000000..b76bca875d --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-destroy-send.js @@ -0,0 +1,31 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const net = require('net'); +const assert = require('assert'); + +const server = net.createServer(); +server.listen(0, common.mustCall(function() { + const port = server.address().port; + const conn = net.createConnection(port); + + conn.on('connect', common.mustCall(function() { + // Test destroy returns this, even on multiple calls when it short-circuits. + assert.strictEqual(conn, conn.destroy().destroy()); + conn.on('error', common.mustNotCall()); + + conn.write(Buffer.from('kaboom'), common.expectsError({ + code: 'ERR_STREAM_DESTROYED', + message: 'Cannot call write after a stream was destroyed', + name: 'Error' + })); + server.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-net-socket-end-before-connect.js b/tests/node_compat/test/parallel/test-net-socket-end-before-connect.js new file mode 100644 index 0000000000..afe9664ccd --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-end-before-connect.js @@ -0,0 +1,20 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +const net = require('net'); + +const server = net.createServer(); + +server.listen(common.mustCall(() => { + const socket = net.createConnection(server.address().port); + socket.on('close', common.mustCall(() => server.close())); + socket.end(); +})); diff --git a/tests/node_compat/test/parallel/test-net-socket-end-callback.js b/tests/node_compat/test/parallel/test-net-socket-end-callback.js new file mode 100644 index 0000000000..7b6d3ae5c2 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-end-callback.js @@ -0,0 +1,29 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const net = require('net'); + +const server = net.createServer((socket) => { + socket.resume(); +}).unref(); + +server.listen(common.mustCall(() => { + const connect = (...args) => { + const socket = net.createConnection(server.address().port, () => { + socket.end(...args); + }); + }; + + const cb = common.mustCall(3); + + connect(cb); + connect('foo', cb); + connect('foo', 'utf8', cb); +})); diff --git a/tests/node_compat/test/parallel/test-net-socket-ready-without-cb.js b/tests/node_compat/test/parallel/test-net-socket-ready-without-cb.js new file mode 100644 index 0000000000..0f71f410bd --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-ready-without-cb.js @@ -0,0 +1,27 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// This test ensures that socket.connect can be called without callback +// which is optional. + +const net = require('net'); + +const server = net.createServer(common.mustCall(function(conn) { + conn.end(); + server.close(); +})).listen(0, 'localhost', common.mustCall(function() { + const client = new net.Socket(); + + client.on('ready', common.mustCall(function() { + client.end(); + })); + + client.connect(server.address()); +})); diff --git a/tests/node_compat/test/parallel/test-net-socket-timeout-unref.js b/tests/node_compat/test/parallel/test-net-socket-timeout-unref.js new file mode 100644 index 0000000000..5e3fc8bd31 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-timeout-unref.js @@ -0,0 +1,63 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +// Test that unref'ed sockets with timeouts do not prevent exit. + +const common = require('../common'); +const net = require('net'); + +const server = net.createServer(function(c) { + c.write('hello'); + c.unref(); +}); +server.listen(0); +server.unref(); + +let connections = 0; +const sockets = []; +const delays = [8, 5, 3, 6, 2, 4]; + +delays.forEach(function(T) { + const socket = net.createConnection(server.address().port, 'localhost'); + socket.on('connect', common.mustCall(function() { + if (++connections === delays.length) { + sockets.forEach(function(s) { + s.socket.setTimeout(s.timeout, function() { + s.socket.destroy(); + throw new Error('socket timed out unexpectedly'); + }); + + s.socket.unref(); + }); + } + })); + + sockets.push({ socket: socket, timeout: T * 1000 }); +}); diff --git a/tests/node_compat/test/parallel/test-net-socket-write-after-close.js b/tests/node_compat/test/parallel/test-net-socket-write-after-close.js new file mode 100644 index 0000000000..9b2150294e --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-write-after-close.js @@ -0,0 +1,49 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +{ + const server = net.createServer(); + + server.listen(common.mustCall(() => { + const port = server.address().port; + const client = net.connect({ port }, common.mustCall(() => { + client.on('error', common.mustCall((err) => { + server.close(); + assert.strictEqual(err.constructor, Error); + assert.strictEqual(err.message, 'write EBADF'); + })); + client._handle.close(); + client.write('foo'); + })); + })); +} + +{ + const server = net.createServer(); + + server.listen(common.mustCall(() => { + const port = server.address().port; + const client = net.connect({ port }, common.mustCall(() => { + client.on('error', common.expectsError({ + code: 'ERR_SOCKET_CLOSED', + message: 'Socket is closed', + name: 'Error' + })); + + server.close(); + + client._handle.close(); + client._handle = null; + client.write('foo'); + })); + })); +} diff --git a/tests/node_compat/test/parallel/test-net-socket-write-error.js b/tests/node_compat/test/parallel/test-net-socket-write-error.js new file mode 100644 index 0000000000..a330058fde --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-socket-write-error.js @@ -0,0 +1,29 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const net = require('net'); +const assert = require('assert'); + +const server = net.createServer().listen(0, connectToServer); + +function connectToServer() { + const client = net.createConnection(this.address().port, () => { + client.on('error', common.mustNotCall()); + assert.throws(() => { + client.write(1337); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); + + client.destroy(); + }) + .on('close', () => server.close()); +} diff --git a/tests/node_compat/test/parallel/test-net-sync-cork.js b/tests/node_compat/test/parallel/test-net-sync-cork.js new file mode 100644 index 0000000000..289319c429 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-sync-cork.js @@ -0,0 +1,40 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const server = net.createServer(handle); + +const N = 100; +const buf = Buffer.alloc(2, 'a'); + +server.listen(0, function() { + const conn = net.connect(this.address().port); + + conn.on('connect', () => { + let res = true; + let i = 0; + for (; i < N && res; i++) { + conn.cork(); + conn.write(buf); + res = conn.write(buf); + conn.uncork(); + } + assert.strictEqual(i, N); + conn.end(); + }); +}); + +function handle(socket) { + socket.resume(); + socket.on('error', common.mustNotCall()) + .on('close', common.mustCall(() => server.close())); +} diff --git a/tests/node_compat/test/parallel/test-net-writable.js b/tests/node_compat/test/parallel/test-net-writable.js new file mode 100644 index 0000000000..86ea2a3c03 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-writable.js @@ -0,0 +1,22 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const server = net.createServer(common.mustCall(function(s) { + server.close(); + s.end(); +})).listen(0, '127.0.0.1', common.mustCall(function() { + const socket = net.connect(this.address().port, '127.0.0.1'); + socket.on('end', common.mustCall(() => { + assert.strictEqual(socket.writable, true); + socket.write('hello world'); + })); +})); diff --git a/tests/node_compat/test/parallel/test-net-write-connect-write.js b/tests/node_compat/test/parallel/test-net-write-connect-write.js new file mode 100644 index 0000000000..a87d80479e --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-write-connect-write.js @@ -0,0 +1,53 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const server = net.createServer(function(socket) { + socket.pipe(socket); +}).listen(0, common.mustCall(function() { + const conn = net.connect(this.address().port); + let received = ''; + + conn.setEncoding('utf8'); + conn.write('before'); + conn.on('connect', function() { + conn.write(' after'); + }); + conn.on('data', function(buf) { + received += buf; + conn.end(); + }); + conn.on('end', common.mustCall(function() { + server.close(); + assert.strictEqual(received, 'before after'); + })); +})); diff --git a/tests/node_compat/test/parallel/test-net-write-fully-async-buffer.js b/tests/node_compat/test/parallel/test-net-write-fully-async-buffer.js new file mode 100644 index 0000000000..222c97ed94 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-write-fully-async-buffer.js @@ -0,0 +1,41 @@ +// 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. + +'use strict'; +// Flags: --expose-gc + +// Note: This is a variant of test-net-write-fully-async-hex-string.js. +// This always worked, but it seemed appropriate to add a test that checks the +// behavior for Buffers, too. +const common = require('../common'); +const net = require('net'); + +const data = Buffer.alloc(1000000); + +const server = net.createServer(common.mustCall(function(conn) { + conn.resume(); +})).listen(0, common.mustCall(function() { + const conn = net.createConnection(this.address().port, common.mustCall(() => { + let count = 0; + + function writeLoop() { + if (count++ === 200) { + conn.destroy(); + server.close(); + return; + } + + while (conn.write(Buffer.from(data))); + global.gc({ type: 'minor' }); + // The buffer allocated above should still be alive. + } + + conn.on('drain', writeLoop); + + writeLoop(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-net-write-fully-async-hex-string.js b/tests/node_compat/test/parallel/test-net-write-fully-async-hex-string.js new file mode 100644 index 0000000000..81a3db7010 --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-write-fully-async-hex-string.js @@ -0,0 +1,39 @@ +// 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. + +'use strict'; +// Flags: --expose-gc + +// Regression test for https://github.com/nodejs/node/issues/8251. +const common = require('../common'); +const net = require('net'); + +const data = Buffer.alloc(1000000).toString('hex'); + +const server = net.createServer(common.mustCall(function(conn) { + conn.resume(); +})).listen(0, common.mustCall(function() { + const conn = net.createConnection(this.address().port, common.mustCall(() => { + let count = 0; + + function writeLoop() { + if (count++ === 20) { + conn.destroy(); + server.close(); + return; + } + + while (conn.write(data, 'hex')); + global.gc({ type: 'minor' }); + // The buffer allocated inside the .write() call should still be alive. + } + + conn.on('drain', writeLoop); + + writeLoop(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-net-write-slow.js b/tests/node_compat/test/parallel/test-net-write-slow.js new file mode 100644 index 0000000000..0204bb979f --- /dev/null +++ b/tests/node_compat/test/parallel/test-net-write-slow.js @@ -0,0 +1,70 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +const SIZE = 2E5; +const N = 10; +let flushed = 0; +let received = 0; +const buf = Buffer.alloc(SIZE, 'a'); + +const server = net.createServer(function(socket) { + socket.setNoDelay(); + socket.setTimeout(9999); + socket.on('timeout', function() { + assert.fail(`flushed: ${flushed}, received: ${received}/${SIZE * N}`); + }); + + for (let i = 0; i < N; ++i) { + socket.write(buf, function() { + ++flushed; + if (flushed === N) { + socket.setTimeout(0); + } + }); + } + socket.end(); + +}).listen(0, common.mustCall(function() { + const conn = net.connect(this.address().port); + conn.on('data', function(buf) { + received += buf.length; + conn.pause(); + setTimeout(function() { + conn.resume(); + }, 20); + }); + conn.on('end', common.mustCall(function() { + server.close(); + assert.strictEqual(received, SIZE * N); + })); +})); diff --git a/tests/node_compat/test/parallel/test-next-tick-domain.js b/tests/node_compat/test/parallel/test-next-tick-domain.js new file mode 100644 index 0000000000..c39f56bea1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-next-tick-domain.js @@ -0,0 +1,38 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const origNextTick = process.nextTick; + +require('domain'); + +// Requiring domain should not change nextTick. +assert.strictEqual(origNextTick, process.nextTick); diff --git a/tests/node_compat/test/parallel/test-next-tick-errors.js b/tests/node_compat/test/parallel/test-next-tick-errors.js new file mode 100644 index 0000000000..a275029f5a --- /dev/null +++ b/tests/node_compat/test/parallel/test-next-tick-errors.js @@ -0,0 +1,81 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const order = []; +let exceptionHandled = false; + +// This nextTick function will throw an error. It should only be called once. +// When it throws an error, it should still get removed from the queue. +process.nextTick(function() { + order.push('A'); + // cause an error + what(); // eslint-disable-line no-undef +}); + +// This nextTick function should remain in the queue when the first one +// is removed. It should be called if the error in the first one is +// caught (which we do in this test). +process.nextTick(function() { + order.push('C'); +}); + +function testNextTickWith(val) { + assert.throws(() => { + process.nextTick(val); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); +} + +testNextTickWith(false); +testNextTickWith(true); +testNextTickWith(1); +testNextTickWith('str'); +testNextTickWith({}); +testNextTickWith([]); + +process.on('uncaughtException', function(err, errorOrigin) { + assert.strictEqual(errorOrigin, 'uncaughtException'); + + if (!exceptionHandled) { + exceptionHandled = true; + order.push('B'); + } else { + // If we get here then the first process.nextTick got called twice + order.push('OOPS!'); + } +}); + +process.on('exit', function() { + assert.deepStrictEqual(order, ['A', 'B', 'C']); +}); diff --git a/tests/node_compat/test/parallel/test-no-node-snapshot.js b/tests/node_compat/test/parallel/test-no-node-snapshot.js new file mode 100644 index 0000000000..a251c9f9d0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-no-node-snapshot.js @@ -0,0 +1,12 @@ +// 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. + +'use strict'; + +// Flags: --no-node-snapshot + +require('../common'); diff --git a/tests/node_compat/test/parallel/test-os-homedir-no-envvar.js b/tests/node_compat/test/parallel/test-os-homedir-no-envvar.js new file mode 100644 index 0000000000..f687422da8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-os-homedir-no-envvar.js @@ -0,0 +1,37 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); +const os = require('os'); +const path = require('path'); + + +if (process.argv[2] === 'child') { + if (common.isWindows) + assert.strictEqual(process.env.USERPROFILE, undefined); + else + assert.strictEqual(process.env.HOME, undefined); + + const home = os.homedir(); + + assert.strictEqual(typeof home, 'string'); + assert(home.includes(path.sep)); +} else { + if (common.isWindows) + delete process.env.USERPROFILE; + else + delete process.env.HOME; + + const child = cp.spawnSync(process.execPath, [__filename, 'child'], { + env: process.env + }); + + assert.strictEqual(child.status, 0); +} diff --git a/tests/node_compat/test/parallel/test-perf-gc-crash.js b/tests/node_compat/test/parallel/test-perf-gc-crash.js new file mode 100644 index 0000000000..474d1d0466 --- /dev/null +++ b/tests/node_compat/test/parallel/test-perf-gc-crash.js @@ -0,0 +1,32 @@ +// 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. + +'use strict'; + +require('../common'); + +// Refers to https://github.com/nodejs/node/issues/39548 + +// The test fails if this crashes. If it closes normally, +// then all is good. + +const { + PerformanceObserver, +} = require('perf_hooks'); + +// We don't actually care if the observer callback is called here. +const gcObserver = new PerformanceObserver(() => {}); + +gcObserver.observe({ entryTypes: ['gc'] }); + +gcObserver.disconnect(); + +const gcObserver2 = new PerformanceObserver(() => {}); + +gcObserver2.observe({ entryTypes: ['gc'] }); + +gcObserver2.disconnect(); diff --git a/tests/node_compat/test/parallel/test-performanceobserver-gc.js b/tests/node_compat/test/parallel/test-performanceobserver-gc.js new file mode 100644 index 0000000000..b508bc4dfc --- /dev/null +++ b/tests/node_compat/test/parallel/test-performanceobserver-gc.js @@ -0,0 +1,24 @@ +// 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. + +'use strict'; + +require('../common'); + +// Verifies that setting up two observers to listen +// to gc performance does not crash. + +const { + PerformanceObserver, +} = require('perf_hooks'); + +// We don't actually care if the callback is ever invoked in this test +const obs = new PerformanceObserver(() => {}); +const obs2 = new PerformanceObserver(() => {}); + +obs.observe({ type: 'gc' }); +obs2.observe({ type: 'gc' }); diff --git a/tests/node_compat/test/parallel/test-pipe-return-val.js b/tests/node_compat/test/parallel/test-pipe-return-val.js new file mode 100644 index 0000000000..c72bb275f8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-pipe-return-val.js @@ -0,0 +1,40 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// This test ensures SourceStream.pipe(DestStream) returns DestStream + +require('../common'); +const Stream = require('stream').Stream; +const assert = require('assert'); + +const sourceStream = new Stream(); +const destStream = new Stream(); +const result = sourceStream.pipe(destStream); + +assert.strictEqual(result, destStream); diff --git a/tests/node_compat/test/parallel/test-pipe-writev.js b/tests/node_compat/test/parallel/test-pipe-writev.js new file mode 100644 index 0000000000..9004104271 --- /dev/null +++ b/tests/node_compat/test/parallel/test-pipe-writev.js @@ -0,0 +1,52 @@ +// 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. + +'use strict'; + +const common = require('../common'); +if (common.isWindows) + common.skip('Unix-specific test'); + +const assert = require('assert'); +const net = require('net'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const server = net.createServer((connection) => { + connection.on('error', (err) => { + throw err; + }); + + const writev = connection._writev.bind(connection); + connection._writev = common.mustCall(writev); + + connection.cork(); + connection.write('pi'); + connection.write('ng'); + connection.end(); +}); + +server.on('error', (err) => { + throw err; +}); + +server.listen(common.PIPE, () => { + const client = net.connect(common.PIPE); + + client.on('error', (err) => { + throw err; + }); + + client.on('data', common.mustCall((data) => { + assert.strictEqual(data.toString(), 'ping'); + })); + + client.on('end', () => { + server.close(); + }); +}); diff --git a/tests/node_compat/test/parallel/test-process-abort.js b/tests/node_compat/test/parallel/test-process-abort.js new file mode 100644 index 0000000000..6117205e61 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-abort.js @@ -0,0 +1,19 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +if (!common.isMainThread) + common.skip('process.abort() is not available in Workers'); + +// Check that our built-in methods do not have a prototype/constructor behaviour +// if they don't need to. This could be tested for any of our C++ methods. +assert.strictEqual(process.abort.prototype, undefined); +assert.throws(() => new process.abort(), TypeError); diff --git a/tests/node_compat/test/parallel/test-process-argv-0.js b/tests/node_compat/test/parallel/test-process-argv-0.js new file mode 100644 index 0000000000..3a4aa69822 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-argv-0.js @@ -0,0 +1,49 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const path = require('path'); +const assert = require('assert'); +const spawn = require('child_process').spawn; + +if (process.argv[2] !== 'child') { + const child = spawn(process.execPath, [__filename, 'child'], { + cwd: path.dirname(process.execPath) + }); + + let childArgv0 = ''; + child.stdout.on('data', function(chunk) { + childArgv0 += chunk; + }); + process.on('exit', function() { + assert.strictEqual(childArgv0, process.execPath); + }); +} else { + process.stdout.write(process.argv[0]); +} diff --git a/tests/node_compat/test/parallel/test-process-binding.js b/tests/node_compat/test/parallel/test-process-binding.js new file mode 100644 index 0000000000..e4895ed37d --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-binding.js @@ -0,0 +1,21 @@ +// 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. + +'use strict'; +// Flags: --expose-internals +require('../common'); +const assert = require('assert'); +const { internalBinding } = require('internal/test/binding'); + +assert.throws( + function() { + process.binding('test'); + }, + /No such module: test/ +); + +internalBinding('buffer'); diff --git a/tests/node_compat/test/parallel/test-process-dlopen-undefined-exports.js b/tests/node_compat/test/parallel/test-process-dlopen-undefined-exports.js new file mode 100644 index 0000000000..615eaf7aaa --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-dlopen-undefined-exports.js @@ -0,0 +1,17 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +const someBindingPath = './test/addons/hello-world/build/Release/binding.node'; + +assert.throws(() => { + process.dlopen({ exports: undefined }, someBindingPath); +}, Error); diff --git a/tests/node_compat/test/parallel/test-process-domain-segfault.js b/tests/node_compat/test/parallel/test-process-domain-segfault.js new file mode 100644 index 0000000000..65a46cebd1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-domain-segfault.js @@ -0,0 +1,39 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); + +// This test ensures that setting `process.domain` to `null` does not result in +// node crashing with a segfault. +// https://github.com/nodejs/node-v0.x-archive/issues/4256 + +process.domain = null; +setTimeout(function() { + console.log('this console.log statement should not make node crash'); +}, 1); diff --git a/tests/node_compat/test/parallel/test-process-emitwarning.js b/tests/node_compat/test/parallel/test-process-emitwarning.js new file mode 100644 index 0000000000..7bf6082e7d --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-emitwarning.js @@ -0,0 +1,88 @@ +// 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: --no-warnings +// The flag suppresses stderr output but the warning event will still emit +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +const testMsg = 'A Warning'; +const testCode = 'CODE001'; +const testDetail = 'Some detail'; +const testType = 'CustomWarning'; + +process.on('warning', common.mustCall((warning) => { + assert(warning); + assert.match(warning.name, /^(?:Warning|CustomWarning)/); + assert.strictEqual(warning.message, testMsg); + if (warning.code) assert.strictEqual(warning.code, testCode); + if (warning.detail) assert.strictEqual(warning.detail, testDetail); +}, 15)); + +class CustomWarning extends Error { + constructor() { + super(); + this.name = testType; + this.message = testMsg; + this.code = testCode; + Error.captureStackTrace(this, CustomWarning); + } +} + +[ + [testMsg], + [testMsg, testType], + [testMsg, CustomWarning], + [testMsg, testType, CustomWarning], + [testMsg, testType, testCode], + [testMsg, { type: testType }], + [testMsg, { type: testType, code: testCode }], + [testMsg, { type: testType, code: testCode, detail: testDetail }], + [new CustomWarning()], + // Detail will be ignored for the following. No errors thrown + [testMsg, { type: testType, code: testCode, detail: true }], + [testMsg, { type: testType, code: testCode, detail: [] }], + [testMsg, { type: testType, code: testCode, detail: null }], + [testMsg, { type: testType, code: testCode, detail: 1 }], +].forEach((args) => { + process.emitWarning(...args); +}); + +const warningNoToString = new CustomWarning(); +warningNoToString.toString = null; +process.emitWarning(warningNoToString); + +const warningThrowToString = new CustomWarning(); +warningThrowToString.toString = function() { + throw new Error('invalid toString'); +}; +process.emitWarning(warningThrowToString); + +// TypeError is thrown on invalid input +[ + [1], + [{}], + [true], + [[]], + ['', '', {}], + ['', 1], + ['', '', 1], + ['', true], + ['', '', true], + ['', []], + ['', '', []], + [], + [undefined, 'foo', 'bar'], + [undefined], +].forEach((args) => { + assert.throws( + () => process.emitWarning(...args), + { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' } + ); +}); diff --git a/tests/node_compat/test/parallel/test-process-env-delete.js b/tests/node_compat/test/parallel/test-process-env-delete.js new file mode 100644 index 0000000000..cb74a681d4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-env-delete.js @@ -0,0 +1,20 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); + +process.env.foo = 'foo'; +assert.strictEqual(process.env.foo, 'foo'); +process.env.foo = undefined; +assert.strictEqual(process.env.foo, 'undefined'); + +process.env.foo = 'foo'; +assert.strictEqual(process.env.foo, 'foo'); +delete process.env.foo; +assert.strictEqual(process.env.foo, undefined); diff --git a/tests/node_compat/test/parallel/test-process-env-windows-error-reset.js b/tests/node_compat/test/parallel/test-process-env-windows-error-reset.js new file mode 100644 index 0000000000..63b44e98c7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-env-windows-error-reset.js @@ -0,0 +1,29 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); + +// This checks that after accessing a missing env var, a subsequent +// env read will succeed even for empty variables. + +{ + process.env.FOO = ''; + process.env.NONEXISTENT_ENV_VAR; // eslint-disable-line no-unused-expressions + const foo = process.env.FOO; + + assert.strictEqual(foo, ''); +} + +{ + process.env.FOO = ''; + process.env.NONEXISTENT_ENV_VAR; // eslint-disable-line no-unused-expressions + const hasFoo = 'FOO' in process.env; + + assert.strictEqual(hasFoo, true); +} diff --git a/tests/node_compat/test/parallel/test-process-getgroups.js b/tests/node_compat/test/parallel/test-process-getgroups.js new file mode 100644 index 0000000000..01eb92bf79 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-getgroups.js @@ -0,0 +1,59 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +// Check `id -G` and `process.getgroups()` return same groups. + +if (common.isOSX) + common.skip('Output of `id -G` is unreliable on Darwin.'); + +const assert = require('assert'); +const exec = require('child_process').exec; + +if (typeof process.getgroups === 'function') { + const groups = unique(process.getgroups()); + assert(Array.isArray(groups)); + assert(groups.length > 0); + exec('id -G', function(err, stdout) { + assert.ifError(err); + const real_groups = unique(stdout.match(/\d+/g).map(Number)); + assert.deepStrictEqual(groups, real_groups); + check(groups, real_groups); + check(real_groups, groups); + }); +} + +function check(a, b) { + for (let i = 0; i < a.length; ++i) assert(b.includes(a[i])); +} + +function unique(groups) { + return [...new Set(groups)].sort(); +} diff --git a/tests/node_compat/test/parallel/test-process-hrtime-bigint.js b/tests/node_compat/test/parallel/test-process-hrtime-bigint.js new file mode 100644 index 0000000000..22c382bb45 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-hrtime-bigint.js @@ -0,0 +1,21 @@ +// 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. + +'use strict'; + +// Tests that process.hrtime.bigint() works. + +require('../common'); +const assert = require('assert'); + +const start = process.hrtime.bigint(); +assert.strictEqual(typeof start, 'bigint'); + +const end = process.hrtime.bigint(); +assert.strictEqual(typeof end, 'bigint'); + +assert(end - start >= 0n); diff --git a/tests/node_compat/test/parallel/test-process-next-tick.js b/tests/node_compat/test/parallel/test-process-next-tick.js new file mode 100644 index 0000000000..b755188696 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-next-tick.js @@ -0,0 +1,56 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const N = 2; + +function cb() { + throw new Error(); +} + +for (let i = 0; i < N; ++i) { + process.nextTick(common.mustCall(cb)); +} + +process.on('uncaughtException', common.mustCall(N)); + +process.on('exit', function() { + process.removeAllListeners('uncaughtException'); +}); + +[null, 1, 'test', {}, [], Infinity, true].forEach((i) => { + assert.throws( + () => process.nextTick(i), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError', + } + ); +}); diff --git a/tests/node_compat/test/parallel/test-process-no-deprecation.js b/tests/node_compat/test/parallel/test-process-no-deprecation.js new file mode 100644 index 0000000000..310c3dbe4d --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-no-deprecation.js @@ -0,0 +1,39 @@ +// 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. + +'use strict'; +// Flags: --no-warnings + +// The --no-warnings flag only suppresses writing the warning to stderr, not the +// emission of the corresponding event. This test file can be run without it. + +const common = require('../common'); +process.noDeprecation = true; + +const assert = require('assert'); + +function listener() { + assert.fail('received unexpected warning'); +} + +process.addListener('warning', listener); + +process.emitWarning('Something is deprecated.', 'DeprecationWarning'); + +// The warning would be emitted in the next tick, so continue after that. +process.nextTick(common.mustCall(() => { + // Check that deprecations can be re-enabled. + process.noDeprecation = false; + process.removeListener('warning', listener); + + process.addListener('warning', common.mustCall((warning) => { + assert.strictEqual(warning.name, 'DeprecationWarning'); + assert.strictEqual(warning.message, 'Something else is deprecated.'); + })); + + process.emitWarning('Something else is deprecated.', 'DeprecationWarning'); +})); diff --git a/tests/node_compat/test/parallel/test-process-ppid.js b/tests/node_compat/test/parallel/test-process-ppid.js new file mode 100644 index 0000000000..f9b184e254 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-ppid.js @@ -0,0 +1,23 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const cp = require('child_process'); + +if (process.argv[2] === 'child') { + // The following console.log() call is part of the test's functionality. + console.log(process.ppid); +} else { + const child = cp.spawnSync(process.execPath, [__filename, 'child']); + + assert.strictEqual(child.status, 0); + assert.strictEqual(child.signal, null); + assert.strictEqual(+child.stdout.toString().trim(), process.pid); + assert.strictEqual(child.stderr.toString().trim(), ''); +} diff --git a/tests/node_compat/test/parallel/test-process-really-exit.js b/tests/node_compat/test/parallel/test-process-really-exit.js new file mode 100644 index 0000000000..ea98eadf35 --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-really-exit.js @@ -0,0 +1,24 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); + +// Ensure that the reallyExit hook is executed. +// see: https://github.com/nodejs/node/issues/25650 +if (process.argv[2] === 'subprocess') { + process.reallyExit = function() { + console.info('really exited'); + }; + process.exit(); +} else { + const { spawnSync } = require('child_process'); + const out = spawnSync(process.execPath, [__filename, 'subprocess']); + const observed = out.output[1].toString('utf8').trim(); + assert.strictEqual(observed, 'really exited'); +} diff --git a/tests/node_compat/test/parallel/test-process-warning.js b/tests/node_compat/test/parallel/test-process-warning.js new file mode 100644 index 0000000000..69514242db --- /dev/null +++ b/tests/node_compat/test/parallel/test-process-warning.js @@ -0,0 +1,75 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { + hijackStderr, + restoreStderr +} = require('../common/hijackstdio'); +const assert = require('assert'); + +function test1() { + // Output is skipped if the argument to the 'warning' event is + // not an Error object. + hijackStderr(common.mustNotCall('stderr.write must not be called')); + process.emit('warning', 'test'); + setImmediate(test2); +} + +function test2() { + // Output is skipped if it's a deprecation warning and + // process.noDeprecation = true + process.noDeprecation = true; + process.emitWarning('test', 'DeprecationWarning'); + process.noDeprecation = false; + setImmediate(test3); +} + +function test3() { + restoreStderr(); + // Type defaults to warning when the second argument is an object + process.emitWarning('test', {}); + process.once('warning', common.mustCall((warning) => { + assert.strictEqual(warning.name, 'Warning'); + })); + setImmediate(test4); +} + +function test4() { + // process.emitWarning will throw when process.throwDeprecation is true + // and type is `DeprecationWarning`. + process.throwDeprecation = true; + process.once('uncaughtException', (err) => { + assert.match(err.toString(), /^DeprecationWarning: test$/); + }); + try { + process.emitWarning('test', 'DeprecationWarning'); + } catch { + assert.fail('Unreachable'); + } + process.throwDeprecation = false; + setImmediate(test5); +} + +function test5() { + // Setting toString to a non-function should not cause an error + const err = new Error('test'); + err.toString = 1; + process.emitWarning(err); + setImmediate(test6); +} + +function test6() { + process.emitWarning('test', { detail: 'foo' }); + process.on('warning', (warning) => { + assert.strictEqual(warning.detail, 'foo'); + }); +} + +test1(); diff --git a/tests/node_compat/test/parallel/test-promise-handled-rejection-no-warning.js b/tests/node_compat/test/parallel/test-promise-handled-rejection-no-warning.js new file mode 100644 index 0000000000..f7d636f187 --- /dev/null +++ b/tests/node_compat/test/parallel/test-promise-handled-rejection-no-warning.js @@ -0,0 +1,14 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// This test verifies that DEP0018 does not occur when rejections are handled. +process.on('warning', common.mustNotCall()); +process.on('unhandledRejection', common.mustCall()); +Promise.reject(new Error()); diff --git a/tests/node_compat/test/parallel/test-readable-from-iterator-closing.js b/tests/node_compat/test/parallel/test-readable-from-iterator-closing.js new file mode 100644 index 0000000000..fba145d4e7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-readable-from-iterator-closing.js @@ -0,0 +1,204 @@ +// 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. + +'use strict'; + +const { mustCall, mustNotCall } = require('../common'); +const { Readable } = require('stream'); +const { strictEqual } = require('assert'); + +async function asyncSupport() { + const finallyMustCall = mustCall(); + const bodyMustCall = mustCall(); + + async function* infiniteGenerate() { + try { + while (true) yield 'a'; + } finally { + finallyMustCall(); + } + } + + const stream = Readable.from(infiniteGenerate()); + + for await (const chunk of stream) { + bodyMustCall(); + strictEqual(chunk, 'a'); + break; + } +} + +async function syncSupport() { + const finallyMustCall = mustCall(); + const bodyMustCall = mustCall(); + + function* infiniteGenerate() { + try { + while (true) yield 'a'; + } finally { + finallyMustCall(); + } + } + + const stream = Readable.from(infiniteGenerate()); + + for await (const chunk of stream) { + bodyMustCall(); + strictEqual(chunk, 'a'); + break; + } +} + +async function syncPromiseSupport() { + const returnMustBeAwaited = mustCall(); + const bodyMustCall = mustCall(); + + function* infiniteGenerate() { + try { + while (true) yield Promise.resolve('a'); + } finally { + // eslint-disable-next-line no-unsafe-finally + return { then(cb) { + returnMustBeAwaited(); + cb(); + } }; + } + } + + const stream = Readable.from(infiniteGenerate()); + + for await (const chunk of stream) { + bodyMustCall(); + strictEqual(chunk, 'a'); + break; + } +} + +async function syncRejectedSupport() { + const returnMustBeAwaited = mustCall(); + const bodyMustNotCall = mustNotCall(); + const catchMustCall = mustCall(); + const secondNextMustNotCall = mustNotCall(); + + function* generate() { + try { + yield Promise.reject('a'); + secondNextMustNotCall(); + } finally { + // eslint-disable-next-line no-unsafe-finally + return { then(cb) { + returnMustBeAwaited(); + cb(); + } }; + } + } + + const stream = Readable.from(generate()); + + try { + for await (const chunk of stream) { + bodyMustNotCall(chunk); + } + } catch { + catchMustCall(); + } +} + +async function noReturnAfterThrow() { + const returnMustNotCall = mustNotCall(); + const bodyMustNotCall = mustNotCall(); + const catchMustCall = mustCall(); + const nextMustCall = mustCall(); + + const stream = Readable.from({ + [Symbol.asyncIterator]() { return this; }, + async next() { + nextMustCall(); + throw new Error('a'); + }, + async return() { + returnMustNotCall(); + return { done: true }; + }, + }); + + try { + for await (const chunk of stream) { + bodyMustNotCall(chunk); + } + } catch { + catchMustCall(); + } +} + +async function closeStreamWhileNextIsPending() { + const finallyMustCall = mustCall(); + const dataMustCall = mustCall(); + + let resolveDestroy; + const destroyed = + new Promise((resolve) => { resolveDestroy = mustCall(resolve); }); + let resolveYielded; + const yielded = + new Promise((resolve) => { resolveYielded = mustCall(resolve); }); + + async function* infiniteGenerate() { + try { + while (true) { + yield 'a'; + resolveYielded(); + await destroyed; + } + } finally { + finallyMustCall(); + } + } + + const stream = Readable.from(infiniteGenerate()); + + stream.on('data', (data) => { + dataMustCall(); + strictEqual(data, 'a'); + }); + + yielded.then(() => { + stream.destroy(); + resolveDestroy(); + }); +} + +async function closeAfterNullYielded() { + const finallyMustCall = mustCall(); + const dataMustCall = mustCall(3); + + function* generate() { + try { + yield 'a'; + yield 'a'; + yield 'a'; + } finally { + finallyMustCall(); + } + } + + const stream = Readable.from(generate()); + + stream.on('data', (chunk) => { + dataMustCall(); + strictEqual(chunk, 'a'); + }); +} + +Promise.all([ + asyncSupport(), + syncSupport(), + syncPromiseSupport(), + syncRejectedSupport(), + noReturnAfterThrow(), + closeStreamWhileNextIsPending(), + closeAfterNullYielded(), +]).then(mustCall()); diff --git a/tests/node_compat/test/parallel/test-readable-from.js b/tests/node_compat/test/parallel/test-readable-from.js new file mode 100644 index 0000000000..066532466a --- /dev/null +++ b/tests/node_compat/test/parallel/test-readable-from.js @@ -0,0 +1,230 @@ +// 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. + +'use strict'; + +const { mustCall } = require('../common'); +const { once } = require('events'); +const { Readable } = require('stream'); +const { strictEqual, throws } = require('assert'); +const common = require('../common'); + +{ + throws(() => { + Readable.from(null); + }, /ERR_INVALID_ARG_TYPE/); +} + +async function toReadableBasicSupport() { + async function* generate() { + yield 'a'; + yield 'b'; + yield 'c'; + } + + const stream = Readable.from(generate()); + + const expected = ['a', 'b', 'c']; + + for await (const chunk of stream) { + strictEqual(chunk, expected.shift()); + } +} + +async function toReadableSyncIterator() { + function* generate() { + yield 'a'; + yield 'b'; + yield 'c'; + } + + const stream = Readable.from(generate()); + + const expected = ['a', 'b', 'c']; + + for await (const chunk of stream) { + strictEqual(chunk, expected.shift()); + } +} + +async function toReadablePromises() { + const promises = [ + Promise.resolve('a'), + Promise.resolve('b'), + Promise.resolve('c'), + ]; + + const stream = Readable.from(promises); + + const expected = ['a', 'b', 'c']; + + for await (const chunk of stream) { + strictEqual(chunk, expected.shift()); + } +} + +async function toReadableString() { + const stream = Readable.from('abc'); + + const expected = ['abc']; + + for await (const chunk of stream) { + strictEqual(chunk, expected.shift()); + } +} + +async function toReadableBuffer() { + const stream = Readable.from(Buffer.from('abc')); + + const expected = ['abc']; + + for await (const chunk of stream) { + strictEqual(chunk.toString(), expected.shift()); + } +} + +async function toReadableOnData() { + async function* generate() { + yield 'a'; + yield 'b'; + yield 'c'; + } + + const stream = Readable.from(generate()); + + let iterations = 0; + const expected = ['a', 'b', 'c']; + + stream.on('data', (chunk) => { + iterations++; + strictEqual(chunk, expected.shift()); + }); + + await once(stream, 'end'); + + strictEqual(iterations, 3); +} + +async function toReadableOnDataNonObject() { + async function* generate() { + yield 'a'; + yield 'b'; + yield 'c'; + } + + const stream = Readable.from(generate(), { objectMode: false }); + + let iterations = 0; + const expected = ['a', 'b', 'c']; + + stream.on('data', (chunk) => { + iterations++; + strictEqual(chunk instanceof Buffer, true); + strictEqual(chunk.toString(), expected.shift()); + }); + + await once(stream, 'end'); + + strictEqual(iterations, 3); +} + +async function destroysTheStreamWhenThrowing() { + async function* generate() { // eslint-disable-line require-yield + throw new Error('kaboom'); + } + + const stream = Readable.from(generate()); + + stream.read(); + + const [err] = await once(stream, 'error'); + strictEqual(err.message, 'kaboom'); + strictEqual(stream.destroyed, true); + +} + +async function asTransformStream() { + async function* generate(stream) { + for await (const chunk of stream) { + yield chunk.toUpperCase(); + } + } + + const source = new Readable({ + objectMode: true, + read() { + this.push('a'); + this.push('b'); + this.push('c'); + this.push(null); + } + }); + + const stream = Readable.from(generate(source)); + + const expected = ['A', 'B', 'C']; + + for await (const chunk of stream) { + strictEqual(chunk, expected.shift()); + } +} + +async function endWithError() { + async function* generate() { + yield 1; + yield 2; + yield Promise.reject('Boum'); + } + + const stream = Readable.from(generate()); + + const expected = [1, 2]; + + try { + for await (const chunk of stream) { + strictEqual(chunk, expected.shift()); + } + throw new Error(); + } catch (err) { + strictEqual(expected.length, 0); + strictEqual(err, 'Boum'); + } +} + +async function destroyingStreamWithErrorThrowsInGenerator() { + const validateError = common.mustCall((e) => { + strictEqual(e, 'Boum'); + }); + async function* generate() { + try { + yield 1; + yield 2; + yield 3; + throw new Error(); + } catch (e) { + validateError(e); + } + } + const stream = Readable.from(generate()); + stream.read(); + stream.once('error', common.mustCall()); + stream.destroy('Boum'); +} + +Promise.all([ + toReadableBasicSupport(), + toReadableSyncIterator(), + toReadablePromises(), + toReadableString(), + toReadableBuffer(), + toReadableOnData(), + toReadableOnDataNonObject(), + destroysTheStreamWhenThrowing(), + asTransformStream(), + endWithError(), + destroyingStreamWithErrorThrowsInGenerator(), +]).then(mustCall()); diff --git a/tests/node_compat/test/parallel/test-readable-large-hwm.js b/tests/node_compat/test/parallel/test-readable-large-hwm.js new file mode 100644 index 0000000000..79a243a9d1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-readable-large-hwm.js @@ -0,0 +1,34 @@ +// 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. + +'use strict'; +const common = require('../common'); +const { Readable } = require('stream'); + +// Make sure that readable completes +// even when reading larger buffer. +const bufferSize = 10 * 1024 * 1024; +let n = 0; +const r = new Readable({ + read() { + // Try to fill readable buffer piece by piece. + r.push(Buffer.alloc(bufferSize / 10)); + + if (n++ > 10) { + r.push(null); + } + } +}); + +r.on('readable', () => { + while (true) { + const ret = r.read(bufferSize); + if (ret === null) + break; + } +}); +r.on('end', common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-readable-single-end.js b/tests/node_compat/test/parallel/test-readable-single-end.js new file mode 100644 index 0000000000..33eb32e1fb --- /dev/null +++ b/tests/node_compat/test/parallel/test-readable-single-end.js @@ -0,0 +1,23 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { Readable } = require('stream'); + +// This test ensures that there will not be an additional empty 'readable' +// event when stream has ended (only 1 event signalling about end) + +const r = new Readable({ + read: () => {}, +}); + +r.push(null); + +r.on('readable', common.mustCall()); +r.on('end', common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-readline-async-iterators-destroy.js b/tests/node_compat/test/parallel/test-readline-async-iterators-destroy.js new file mode 100644 index 0000000000..2dcc43e05c --- /dev/null +++ b/tests/node_compat/test/parallel/test-readline-async-iterators-destroy.js @@ -0,0 +1,96 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const fs = require('fs'); +const { once } = require('events'); +const readline = require('readline'); +const assert = require('assert'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const filename = tmpdir.resolve('test.txt'); + +const testContents = [ + '', + '\n', + 'line 1', + 'line 1\nline 2 南越国是前203年至前111年存在于岭南地区的一个国家\nline 3\ntrailing', + 'line 1\nline 2\nline 3 ends with newline\n', +]; + +async function testSimpleDestroy() { + for (const fileContent of testContents) { + fs.writeFileSync(filename, fileContent); + + const readable = fs.createReadStream(filename); + const rli = readline.createInterface({ + input: readable, + crlfDelay: Infinity + }); + + const iteratedLines = []; + for await (const k of rli) { + iteratedLines.push(k); + break; + } + + const expectedLines = fileContent.split('\n'); + if (expectedLines[expectedLines.length - 1] === '') { + expectedLines.pop(); + } + expectedLines.splice(1); + + assert.deepStrictEqual(iteratedLines, expectedLines); + + rli.close(); + readable.destroy(); + + await once(readable, 'close'); + } +} + +async function testMutualDestroy() { + for (const fileContent of testContents) { + fs.writeFileSync(filename, fileContent); + + const readable = fs.createReadStream(filename); + const rli = readline.createInterface({ + input: readable, + crlfDelay: Infinity + }); + + const expectedLines = fileContent.split('\n'); + if (expectedLines[expectedLines.length - 1] === '') { + expectedLines.pop(); + } + expectedLines.splice(2); + + const iteratedLines = []; + for await (const k of rli) { + iteratedLines.push(k); + for await (const l of rli) { + iteratedLines.push(l); + break; + } + assert.deepStrictEqual(iteratedLines, expectedLines); + break; + } + + assert.deepStrictEqual(iteratedLines, expectedLines); + + rli.close(); + readable.destroy(); + + await once(readable, 'close'); + } +} + +testSimpleDestroy().then(testMutualDestroy).then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-readline-async-iterators.js b/tests/node_compat/test/parallel/test-readline-async-iterators.js new file mode 100644 index 0000000000..a9e3a282fb --- /dev/null +++ b/tests/node_compat/test/parallel/test-readline-async-iterators.js @@ -0,0 +1,127 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const fs = require('fs'); +const readline = require('readline'); +const { Readable } = require('stream'); +const assert = require('assert'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +const filename = tmpdir.resolve('test.txt'); + +const testContents = [ + '', + '\n', + 'line 1', + 'line 1\nline 2 南越国是前203年至前111年存在于岭南地区的一个国家\nline 3\ntrailing', + 'line 1\nline 2\nline 3 ends with newline\n', +]; + +async function testSimple() { + for (const fileContent of testContents) { + fs.writeFileSync(filename, fileContent); + + const readable = fs.createReadStream(filename); + const rli = readline.createInterface({ + input: readable, + crlfDelay: Infinity + }); + + const iteratedLines = []; + for await (const k of rli) { + iteratedLines.push(k); + } + + const expectedLines = fileContent.split('\n'); + if (expectedLines[expectedLines.length - 1] === '') { + expectedLines.pop(); + } + assert.deepStrictEqual(iteratedLines, expectedLines); + assert.strictEqual(iteratedLines.join(''), fileContent.replace(/\n/g, '')); + } +} + +async function testMutual() { + for (const fileContent of testContents) { + fs.writeFileSync(filename, fileContent); + + const readable = fs.createReadStream(filename); + const rli = readline.createInterface({ + input: readable, + crlfDelay: Infinity + }); + + const expectedLines = fileContent.split('\n'); + if (expectedLines[expectedLines.length - 1] === '') { + expectedLines.pop(); + } + const iteratedLines = []; + let iterated = false; + for await (const k of rli) { + // This outer loop should only iterate once. + assert.strictEqual(iterated, false); + iterated = true; + iteratedLines.push(k); + for await (const l of rli) { + iteratedLines.push(l); + } + assert.deepStrictEqual(iteratedLines, expectedLines); + } + assert.deepStrictEqual(iteratedLines, expectedLines); + } +} + +async function testSlowStreamForLeaks() { + const message = 'a\nb\nc\n'; + const DELAY = 1; + const REPETITIONS = 100; + const warningCallback = common.mustNotCall(); + process.on('warning', warningCallback); + + function getStream() { + const readable = Readable({ + objectMode: true, + }); + readable._read = () => {}; + let i = REPETITIONS; + function schedule() { + setTimeout(() => { + i--; + if (i < 0) { + readable.push(null); + } else { + readable.push(message); + schedule(); + } + }, DELAY); + } + schedule(); + return readable; + } + const iterable = readline.createInterface({ + input: getStream(), + }); + + let lines = 0; + // eslint-disable-next-line no-unused-vars + for await (const _ of iterable) { + lines++; + } + + assert.strictEqual(lines, 3 * REPETITIONS); + process.off('warning', warningCallback); +} + +testSimple() + .then(testMutual) + .then(testSlowStreamForLeaks) + .then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-readline-carriage-return-between-chunks.js b/tests/node_compat/test/parallel/test-readline-carriage-return-between-chunks.js new file mode 100644 index 0000000000..b678f8666d --- /dev/null +++ b/tests/node_compat/test/parallel/test-readline-carriage-return-between-chunks.js @@ -0,0 +1,30 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +const assert = require('node:assert'); +const readline = require('node:readline'); +const { Readable } = require('node:stream'); + + +const input = Readable.from((function*() { + yield 'a\nb'; + yield '\r\n'; +})()); +const rl = readline.createInterface({ input, crlfDelay: Infinity }); +let carriageReturns = 0; + +rl.on('line', (line) => { + if (line.includes('\r')) carriageReturns++; +}); + +rl.on('close', common.mustCall(() => { + assert.strictEqual(carriageReturns, 0); +})); diff --git a/tests/node_compat/test/parallel/test-readline-csi.js b/tests/node_compat/test/parallel/test-readline-csi.js new file mode 100644 index 0000000000..e657ed545e --- /dev/null +++ b/tests/node_compat/test/parallel/test-readline-csi.js @@ -0,0 +1,183 @@ +// 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'); +const assert = require('assert'); +const readline = require('readline'); +const { Writable } = require('stream'); +const { CSI } = require('internal/readline/utils'); + +{ + assert(CSI); + assert.strictEqual(CSI.kClearToLineBeginning, '\x1b[1K'); + assert.strictEqual(CSI.kClearToLineEnd, '\x1b[0K'); + assert.strictEqual(CSI.kClearLine, '\x1b[2K'); + assert.strictEqual(CSI.kClearScreenDown, '\x1b[0J'); + assert.strictEqual(CSI`1${2}3`, '\x1b[123'); +} + +class TestWritable extends Writable { + constructor() { + super(); + this.data = ''; + } + _write(chunk, encoding, callback) { + this.data += chunk.toString(); + callback(); + } +} + +const writable = new TestWritable(); + +assert.strictEqual(readline.clearScreenDown(writable), true); +assert.deepStrictEqual(writable.data, CSI.kClearScreenDown); +assert.strictEqual(readline.clearScreenDown(writable, common.mustCall()), true); + +// Verify that clearScreenDown() throws on invalid callback. +assert.throws(() => { + readline.clearScreenDown(writable, null); +}, /ERR_INVALID_ARG_TYPE/); + +// Verify that clearScreenDown() does not throw on null or undefined stream. +assert.strictEqual(readline.clearScreenDown(null, common.mustCall((err) => { + assert.strictEqual(err, null); +})), true); +assert.strictEqual(readline.clearScreenDown(undefined, common.mustCall()), + true); + +writable.data = ''; +assert.strictEqual(readline.clearLine(writable, -1), true); +assert.deepStrictEqual(writable.data, CSI.kClearToLineBeginning); + +writable.data = ''; +assert.strictEqual(readline.clearLine(writable, 1), true); +assert.deepStrictEqual(writable.data, CSI.kClearToLineEnd); + +writable.data = ''; +assert.strictEqual(readline.clearLine(writable, 0), true); +assert.deepStrictEqual(writable.data, CSI.kClearLine); + +writable.data = ''; +assert.strictEqual(readline.clearLine(writable, -1, common.mustCall()), true); +assert.deepStrictEqual(writable.data, CSI.kClearToLineBeginning); + +// Verify that clearLine() throws on invalid callback. +assert.throws(() => { + readline.clearLine(writable, 0, null); +}, /ERR_INVALID_ARG_TYPE/); + +// Verify that clearLine() does not throw on null or undefined stream. +assert.strictEqual(readline.clearLine(null, 0), true); +assert.strictEqual(readline.clearLine(undefined, 0), true); +assert.strictEqual(readline.clearLine(null, 0, common.mustCall((err) => { + assert.strictEqual(err, null); +})), true); +assert.strictEqual(readline.clearLine(undefined, 0, common.mustCall()), true); + +// Nothing is written when moveCursor 0, 0 +[ + [0, 0, ''], + [1, 0, '\x1b[1C'], + [-1, 0, '\x1b[1D'], + [0, 1, '\x1b[1B'], + [0, -1, '\x1b[1A'], + [1, 1, '\x1b[1C\x1b[1B'], + [-1, 1, '\x1b[1D\x1b[1B'], + [-1, -1, '\x1b[1D\x1b[1A'], + [1, -1, '\x1b[1C\x1b[1A'], +].forEach((set) => { + writable.data = ''; + assert.strictEqual(readline.moveCursor(writable, set[0], set[1]), true); + assert.deepStrictEqual(writable.data, set[2]); + writable.data = ''; + assert.strictEqual( + readline.moveCursor(writable, set[0], set[1], common.mustCall()), + true + ); + assert.deepStrictEqual(writable.data, set[2]); +}); + +// Verify that moveCursor() throws on invalid callback. +assert.throws(() => { + readline.moveCursor(writable, 1, 1, null); +}, /ERR_INVALID_ARG_TYPE/); + +// Verify that moveCursor() does not throw on null or undefined stream. +assert.strictEqual(readline.moveCursor(null, 1, 1), true); +assert.strictEqual(readline.moveCursor(undefined, 1, 1), true); +assert.strictEqual(readline.moveCursor(null, 1, 1, common.mustCall((err) => { + assert.strictEqual(err, null); +})), true); +assert.strictEqual(readline.moveCursor(undefined, 1, 1, common.mustCall()), + true); + +// Undefined or null as stream should not throw. +assert.strictEqual(readline.cursorTo(null), true); +assert.strictEqual(readline.cursorTo(), true); +assert.strictEqual(readline.cursorTo(null, 1, 1, common.mustCall()), true); +assert.strictEqual(readline.cursorTo(undefined, 1, 1, common.mustCall((err) => { + assert.strictEqual(err, null); +})), true); + +writable.data = ''; +assert.strictEqual(readline.cursorTo(writable, 'a'), true); +assert.strictEqual(writable.data, ''); + +writable.data = ''; +assert.strictEqual(readline.cursorTo(writable, 'a', 'b'), true); +assert.strictEqual(writable.data, ''); + +writable.data = ''; +assert.throws( + () => readline.cursorTo(writable, 'a', 1), + { + name: 'TypeError', + code: 'ERR_INVALID_CURSOR_POS', + message: 'Cannot set cursor row without setting its column' + }); +assert.strictEqual(writable.data, ''); + +writable.data = ''; +assert.strictEqual(readline.cursorTo(writable, 1, 'a'), true); +assert.strictEqual(writable.data, '\x1b[2G'); + +writable.data = ''; +assert.strictEqual(readline.cursorTo(writable, 1), true); +assert.strictEqual(writable.data, '\x1b[2G'); + +writable.data = ''; +assert.strictEqual(readline.cursorTo(writable, 1, 2), true); +assert.strictEqual(writable.data, '\x1b[3;2H'); + +writable.data = ''; +assert.strictEqual(readline.cursorTo(writable, 1, 2, common.mustCall()), true); +assert.strictEqual(writable.data, '\x1b[3;2H'); + +writable.data = ''; +assert.strictEqual(readline.cursorTo(writable, 1, common.mustCall()), true); +assert.strictEqual(writable.data, '\x1b[2G'); + +// Verify that cursorTo() throws on invalid callback. +assert.throws(() => { + readline.cursorTo(writable, 1, 1, null); +}, /ERR_INVALID_ARG_TYPE/); + +// Verify that cursorTo() throws if x or y is NaN. +assert.throws(() => { + readline.cursorTo(writable, NaN); +}, /ERR_INVALID_ARG_VALUE/); + +assert.throws(() => { + readline.cursorTo(writable, 1, NaN); +}, /ERR_INVALID_ARG_VALUE/); + +assert.throws(() => { + readline.cursorTo(writable, NaN, NaN); +}, /ERR_INVALID_ARG_VALUE/); diff --git a/tests/node_compat/test/parallel/test-ref-unref-return.js b/tests/node_compat/test/parallel/test-ref-unref-return.js new file mode 100644 index 0000000000..d8f919bf88 --- /dev/null +++ b/tests/node_compat/test/parallel/test-ref-unref-return.js @@ -0,0 +1,19 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const net = require('net'); +const dgram = require('dgram'); + +assert.ok((new net.Server()).ref() instanceof net.Server); +assert.ok((new net.Server()).unref() instanceof net.Server); +assert.ok((new net.Socket()).ref() instanceof net.Socket); +assert.ok((new net.Socket()).unref() instanceof net.Socket); +assert.ok((new dgram.Socket('udp4')).ref() instanceof dgram.Socket); +assert.ok((new dgram.Socket('udp6')).unref() instanceof dgram.Socket); diff --git a/tests/node_compat/test/parallel/test-regression-object-prototype.js b/tests/node_compat/test/parallel/test-regression-object-prototype.js new file mode 100644 index 0000000000..d2b9136048 --- /dev/null +++ b/tests/node_compat/test/parallel/test-regression-object-prototype.js @@ -0,0 +1,35 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +/* eslint-disable node-core/require-common-first, node-core/required-modules */ +'use strict'; + +Object.prototype.xadsadsdasasdxx = function() { +}; + +console.log('puts after'); diff --git a/tests/node_compat/test/parallel/test-require-invalid-package.js b/tests/node_compat/test/parallel/test-require-invalid-package.js new file mode 100644 index 0000000000..7c8b412dcd --- /dev/null +++ b/tests/node_compat/test/parallel/test-require-invalid-package.js @@ -0,0 +1,16 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Should be an invalid package path. +assert.throws(() => require('package.json'), + { code: 'MODULE_NOT_FOUND' } +); diff --git a/tests/node_compat/test/parallel/test-require-long-path.js b/tests/node_compat/test/parallel/test-require-long-path.js new file mode 100644 index 0000000000..c9329e4626 --- /dev/null +++ b/tests/node_compat/test/parallel/test-require-long-path.js @@ -0,0 +1,35 @@ +// 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. + +'use strict'; +const common = require('../common'); +if (!common.isWindows) + common.skip('this test is Windows-specific.'); + +const fs = require('fs'); +const path = require('path'); + +const tmpdir = require('../common/tmpdir'); + +// Make a path that is more than 260 chars long. +const dirNameLen = Math.max(260 - tmpdir.path.length, 1); +const dirName = tmpdir.resolve('x'.repeat(dirNameLen)); +const fullDirPath = path.resolve(dirName); + +const indexFile = path.join(fullDirPath, 'index.js'); +const otherFile = path.join(fullDirPath, 'other.js'); + +tmpdir.refresh(); + +fs.mkdirSync(fullDirPath); +fs.writeFileSync(indexFile, 'require("./other");'); +fs.writeFileSync(otherFile, ''); + +require(indexFile); +require(otherFile); + +tmpdir.refresh(); diff --git a/tests/node_compat/test/parallel/test-require-nul.js b/tests/node_compat/test/parallel/test-require-nul.js new file mode 100644 index 0000000000..b9a77a3004 --- /dev/null +++ b/tests/node_compat/test/parallel/test-require-nul.js @@ -0,0 +1,18 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Nul bytes should throw, not abort. +/* eslint-disable no-control-regex */ +assert.throws(() => require('\u0000ab'), /Cannot find module '\u0000ab'/); +assert.throws(() => require('a\u0000b'), /Cannot find module 'a\u0000b'/); +assert.throws(() => require('ab\u0000'), /Cannot find module 'ab\u0000'/); +/* eslint-enable no-control-regex */ diff --git a/tests/node_compat/test/parallel/test-require-process.js b/tests/node_compat/test/parallel/test-require-process.js new file mode 100644 index 0000000000..dff056e4f3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-require-process.js @@ -0,0 +1,14 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const nativeProcess = require('process'); +// require('process') should return global process reference +assert.strictEqual(nativeProcess, process); diff --git a/tests/node_compat/test/parallel/test-signal-handler-remove-on-exit.js b/tests/node_compat/test/parallel/test-signal-handler-remove-on-exit.js new file mode 100644 index 0000000000..71ad993e20 --- /dev/null +++ b/tests/node_compat/test/parallel/test-signal-handler-remove-on-exit.js @@ -0,0 +1,16 @@ +// 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. + +'use strict'; +require('../common'); + +// Regression test for https://github.com/nodejs/node/issues/30581 +// This script should not crash. + +function dummy() {} +process.on('SIGINT', dummy); +process.on('exit', () => process.removeListener('SIGINT', dummy)); diff --git a/tests/node_compat/test/parallel/test-signal-handler.js b/tests/node_compat/test/parallel/test-signal-handler.js new file mode 100644 index 0000000000..a4cfad7f4d --- /dev/null +++ b/tests/node_compat/test/parallel/test-signal-handler.js @@ -0,0 +1,63 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +const common = require('../common'); + +if (common.isWindows) + common.skip('SIGUSR1 and SIGHUP signals are not supported'); +if (!common.isMainThread) + common.skip('Signal handling in Workers is not supported'); + +console.log(`process.pid: ${process.pid}`); + +process.on('SIGUSR1', common.mustCall()); + +process.on('SIGUSR1', common.mustCall(function() { + setTimeout(function() { + console.log('End.'); + process.exit(0); + }, 5); +})); + +let i = 0; +setInterval(function() { + console.log(`running process...${++i}`); + + if (i === 5) { + process.kill(process.pid, 'SIGUSR1'); + } +}, 1); + +// Test on condition where a watcher for SIGNAL +// has been previously registered, and `process.listeners(SIGNAL).length === 1` +process.on('SIGHUP', common.mustNotCall()); +process.removeAllListeners('SIGHUP'); +process.on('SIGHUP', common.mustCall()); +process.kill(process.pid, 'SIGHUP'); diff --git a/tests/node_compat/test/parallel/test-socket-address.js b/tests/node_compat/test/parallel/test-socket-address.js new file mode 100644 index 0000000000..7b132402aa --- /dev/null +++ b/tests/node_compat/test/parallel/test-socket-address.js @@ -0,0 +1,24 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +// This tests checks that if server._handle.getsockname +// returns an error number, an error is thrown. + +const server = net.createServer({}); +server.listen(0, common.mustCall(function() { + server._handle.getsockname = function(out) { + return -1; + }; + assert.throws(() => this.address(), + /^Error: address [\w|\s-\d]+$/); + server.close(); +})); diff --git a/tests/node_compat/test/parallel/test-socket-write-after-fin-error.js b/tests/node_compat/test/parallel/test-socket-write-after-fin-error.js new file mode 100644 index 0000000000..525627f434 --- /dev/null +++ b/tests/node_compat/test/parallel/test-socket-write-after-fin-error.js @@ -0,0 +1,69 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); + +// This is similar to simple/test-socket-write-after-fin, except that +// we don't set allowHalfOpen. Then we write after the client has sent +// a FIN, and this is an error. However, the standard "write after end" +// message is too vague, and doesn't actually tell you what happens. + +const net = require('net'); +let serverData = ''; +let gotServerEnd = false; +let clientData = ''; +let gotClientEnd = false; +let gotServerError = false; + +const server = net.createServer(function(sock) { + sock.setEncoding('utf8'); + sock.on('error', function() {}); + + sock.on('data', function(c) { + serverData += c; + }); + sock.on('end', function() { + gotServerEnd = true; + setImmediate(() => { + sock.write(serverData, function(er) { + console.error(`${er.code}: ${er.message}`); + gotServerError = er; + }); + sock.end(); + }); + }); + server.close(); +}); +server.listen(0, function() { + const sock = net.connect(this.address().port); + sock.setEncoding('utf8'); + sock.on('data', function(c) { + clientData += c; + }); + + sock.on('end', function() { + gotClientEnd = true; + }); + + process.on('exit', function() { + assert.strictEqual(clientData, ''); + assert.strictEqual(serverData, 'hello1hello2hello3\nTHUNDERMUSCLE!'); + assert(gotClientEnd); + assert(gotServerEnd); + assert(gotServerError); + assert.strictEqual(gotServerError.code, 'EPIPE'); + assert.notStrictEqual(gotServerError.message, 'write after end'); + console.log('ok'); + }); + + sock.write('hello1'); + sock.write('hello2'); + sock.write('hello3\n'); + sock.end('THUNDERMUSCLE!'); +}); diff --git a/tests/node_compat/test/parallel/test-source-map-enable.js b/tests/node_compat/test/parallel/test-source-map-enable.js new file mode 100644 index 0000000000..b373aadda9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-source-map-enable.js @@ -0,0 +1,388 @@ +// 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. + +'use strict'; + +if (!process.features.inspector) return; + +const common = require('../common'); +const assert = require('assert'); +const { dirname } = require('path'); +const fs = require('fs'); +const path = require('path'); +const { spawnSync } = require('child_process'); +const { pathToFileURL } = require('url'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +let dirc = 0; +function nextdir() { + return process.env.NODE_V8_COVERAGE || + tmpdir.resolve(`source_map_${++dirc}`); +} + +// Outputs source maps when event loop is drained, with no async logic. +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/source-map/basic'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + if (output.status !== 0) { + console.log(output.stderr.toString()); + } + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const sourceMap = getSourceMapFromCache('basic.js', coverageDirectory); + assert.strictEqual(sourceMap.url, 'https://ci.nodejs.org/418'); +} + +// Outputs source maps when process.kill(process.pid, "SIGINT"); exits process. +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/source-map/sigint'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + if (!common.isWindows) { + if (output.signal !== 'SIGINT') { + console.log(output.stderr.toString()); + } + assert.strictEqual(output.signal, 'SIGINT'); + } + assert.strictEqual(output.stderr.toString(), ''); + const sourceMap = getSourceMapFromCache('sigint.js', coverageDirectory); + assert.strictEqual(sourceMap.url, 'https://ci.nodejs.org/402'); +} + +// Outputs source maps when source-file calls process.exit(1). +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/source-map/exit-1'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + assert.strictEqual(output.stderr.toString(), ''); + const sourceMap = getSourceMapFromCache('exit-1.js', coverageDirectory); + assert.strictEqual(sourceMap.url, 'https://ci.nodejs.org/404'); +} + +// Outputs source-maps for esm module. +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + '--no-warnings', + require.resolve('../fixtures/source-map/esm-basic.mjs'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + assert.strictEqual(output.stderr.toString(), ''); + const sourceMap = getSourceMapFromCache('esm-basic.mjs', coverageDirectory); + assert.strictEqual(sourceMap.url, 'https://ci.nodejs.org/405'); +} + +// Loads source-maps with relative path from .map file on disk. +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/source-map/disk-relative-path'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const sourceMap = getSourceMapFromCache( + 'disk-relative-path.js', + coverageDirectory + ); + // Source-map should have been loaded from disk and sources should have been + // rewritten, such that they're absolute paths. + assert.strictEqual( + dirname(pathToFileURL( + require.resolve('../fixtures/source-map/disk-relative-path')).href), + dirname(sourceMap.data.sources[0]) + ); +} + +// Loads source-maps from inline data URL. +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/source-map/inline-base64.js'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const sourceMap = getSourceMapFromCache( + 'inline-base64.js', + coverageDirectory + ); + // base64 JSON should have been decoded, and paths to sources should have + // been rewritten such that they're absolute: + assert.strictEqual( + dirname(pathToFileURL( + require.resolve('../fixtures/source-map/inline-base64')).href), + dirname(sourceMap.data.sources[0]) + ); +} + +// base64 encoding error does not crash application. +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/source-map/inline-base64-type-error.js'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const sourceMap = getSourceMapFromCache( + 'inline-base64-type-error.js', + coverageDirectory + ); + + assert.strictEqual(sourceMap.data, null); +} + +// JSON error does not crash application. +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/source-map/inline-base64-json-error.js'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const sourceMap = getSourceMapFromCache( + 'inline-base64-json-error.js', + coverageDirectory + ); + + assert.strictEqual(sourceMap.data, null); +} + +// Does not apply source-map to stack trace if --experimental-modules +// is not set. +{ + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/source-map/uglify-throw.js'), + ]); + assert.strictEqual( + output.stderr.toString().match(/.*uglify-throw-original\.js:5:9/), + null + ); + assert.strictEqual( + output.stderr.toString().match(/.*uglify-throw-original\.js:9:3/), + null + ); +} + +// Applies source-maps generated by uglifyjs to stack trace. +{ + const output = spawnSync(process.execPath, [ + '--enable-source-maps', + require.resolve('../fixtures/source-map/uglify-throw.js'), + ]); + assert.match( + output.stderr.toString(), + /.*uglify-throw-original\.js:5:9/ + ); + assert.match( + output.stderr.toString(), + /.*uglify-throw-original\.js:9:3/ + ); + assert.match(output.stderr.toString(), /at Hello/); +} + +// Applies source-maps generated by tsc to stack trace. +{ + const output = spawnSync(process.execPath, [ + '--enable-source-maps', + require.resolve('../fixtures/source-map/typescript-throw.js'), + ]); + assert.ok(output.stderr.toString().match(/.*typescript-throw\.ts:18:11/)); + assert.ok(output.stderr.toString().match(/.*typescript-throw\.ts:24:1/)); +} + +// Applies source-maps generated by babel to stack trace. +{ + const output = spawnSync(process.execPath, [ + '--enable-source-maps', + require.resolve('../fixtures/source-map/babel-throw.js'), + ]); + assert.ok( + output.stderr.toString().match(/.*babel-throw-original\.js:18:31/) + ); +} + +// Applies source-maps generated by nyc to stack trace. +{ + const output = spawnSync(process.execPath, [ + '--enable-source-maps', + require.resolve('../fixtures/source-map/istanbul-throw.js'), + ]); + assert.ok( + output.stderr.toString().match(/.*istanbul-throw-original\.js:5:9/) + ); + assert.ok( + output.stderr.toString().match(/.*istanbul-throw-original\.js:9:3/) + ); +} + +// Applies source-maps in esm modules to stack trace. +{ + const output = spawnSync(process.execPath, [ + '--enable-source-maps', + require.resolve('../fixtures/source-map/babel-esm.mjs'), + ]); + assert.ok( + output.stderr.toString().match(/.*babel-esm-original\.mjs:9:29/) + ); +} + +// Does not persist url parameter if source-map has been parsed. +{ + const coverageDirectory = nextdir(); + spawnSync(process.execPath, [ + require.resolve('../fixtures/source-map/inline-base64.js'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + const sourceMap = getSourceMapFromCache( + 'inline-base64.js', + coverageDirectory + ); + assert.strictEqual(sourceMap.url, null); +} + +// Persists line lengths for in-memory representation of source file. +{ + const coverageDirectory = nextdir(); + spawnSync(process.execPath, [ + require.resolve('../fixtures/source-map/istanbul-throw.js'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + const sourceMap = getSourceMapFromCache( + 'istanbul-throw.js', + coverageDirectory + ); + if (common.checkoutEOL === '\r\n') { + assert.deepStrictEqual(sourceMap.lineLengths, [1086, 31, 185, 649, 0]); + } else { + assert.deepStrictEqual(sourceMap.lineLengths, [1085, 30, 184, 648, 0]); + } +} + +// trace.length === 0 . +{ + const output = spawnSync(process.execPath, [ + '--enable-source-maps', + require.resolve('../fixtures/source-map/emptyStackError.js'), + ]); + + assert.ok( + output.stderr.toString().match('emptyStackError') + ); +} + +// Does not attempt to apply path resolution logic to absolute URLs +// with schemes. +// Refs: https://github.com/webpack/webpack/issues/9601 +// Refs: https://sourcemaps.info/spec.html#h.75yo6yoyk7x5 +{ + const output = spawnSync(process.execPath, [ + '--enable-source-maps', + require.resolve('../fixtures/source-map/webpack.js'), + ]); + // Error in original context of source content: + assert.match( + output.stderr.toString(), + /throw new Error\('oh no!'\)\r?\n.*\^/ + ); + // Rewritten stack trace: + assert.match(output.stderr.toString(), /webpack:\/\/\/webpack\.js:14:9/); + assert.match(output.stderr.toString(), /at functionD.*14:9/); + assert.match(output.stderr.toString(), /at functionC.*10:3/); +} + +// Stores and applies source map associated with file that throws while +// being required. +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + '--enable-source-maps', + require.resolve('../fixtures/source-map/throw-on-require-entry.js'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + const sourceMap = getSourceMapFromCache( + 'throw-on-require.js', + coverageDirectory + ); + // Rewritten stack trace. + assert.match(output.stderr.toString(), /throw-on-require\.ts:9:9/); + // Source map should have been serialized. + assert.ok(sourceMap); +} + +// Does not throw TypeError when primitive value is thrown. +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + '--enable-source-maps', + require.resolve('../fixtures/source-map/throw-string.js'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + const sourceMap = getSourceMapFromCache( + 'throw-string.js', + coverageDirectory + ); + // Original stack trace. + assert.match(output.stderr.toString(), /goodbye/); + // Source map should have been serialized. + assert.ok(sourceMap); +} + +// Does not throw TypeError when exception occurs as result of missing named +// export. +{ + const coverageDirectory = nextdir(); + const output = spawnSync(process.execPath, [ + '--enable-source-maps', + require.resolve('../fixtures/source-map/esm-export-missing.mjs'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + const sourceMap = getSourceMapFromCache( + 'esm-export-missing.mjs', + coverageDirectory + ); + // Module loader error displayed. + assert.match(output.stderr.toString(), + /does not provide an export named 'Something'/); + // Source map should have been serialized. + assert.ok(sourceMap); +} + +// Does not include null for async/await with esm +// Refs: https://github.com/nodejs/node/issues/42417 +{ + const output = spawnSync(process.execPath, [ + '--enable-source-maps', + require.resolve('../fixtures/source-map/throw-async.mjs'), + ]); + // Error in original context of source content: + assert.match( + output.stderr.toString(), + /throw new Error\(message\)\r?\n.*\^/ + ); + // Rewritten stack trace: + assert.match(output.stderr.toString(), /at Throw \([^)]+throw-async\.ts:4:9\)/); +} + +function getSourceMapFromCache(fixtureFile, coverageDirectory) { + const jsonFiles = fs.readdirSync(coverageDirectory); + for (const jsonFile of jsonFiles) { + let maybeSourceMapCache; + try { + maybeSourceMapCache = require( + path.join(coverageDirectory, jsonFile) + )['source-map-cache'] || {}; + } catch (err) { + console.warn(err); + maybeSourceMapCache = {}; + } + const keys = Object.keys(maybeSourceMapCache); + for (const key of keys) { + if (key.includes(fixtureFile)) { + return maybeSourceMapCache[key]; + } + } + } +} diff --git a/tests/node_compat/test/parallel/test-spawn-cmd-named-pipe.js b/tests/node_compat/test/parallel/test-spawn-cmd-named-pipe.js new file mode 100644 index 0000000000..47b012a9ca --- /dev/null +++ b/tests/node_compat/test/parallel/test-spawn-cmd-named-pipe.js @@ -0,0 +1,57 @@ +// 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. + +'use strict'; +const common = require('../common'); +// This test is intended for Windows only +if (!common.isWindows) + common.skip('this test is Windows-specific.'); + +const assert = require('assert'); + +if (!process.argv[2]) { + // parent + const net = require('net'); + const spawn = require('child_process').spawn; + const path = require('path'); + + const pipeNamePrefix = `${path.basename(__filename)}.${process.pid}`; + const stdinPipeName = `\\\\.\\pipe\\${pipeNamePrefix}.stdin`; + const stdoutPipeName = `\\\\.\\pipe\\${pipeNamePrefix}.stdout`; + + const stdinPipeServer = net.createServer(function(c) { + c.on('end', common.mustCall()); + c.end('hello'); + }); + stdinPipeServer.listen(stdinPipeName); + + const output = []; + + const stdoutPipeServer = net.createServer(function(c) { + c.on('data', function(x) { + output.push(x); + }); + c.on('end', common.mustCall(function() { + assert.strictEqual(output.join(''), 'hello'); + })); + }); + stdoutPipeServer.listen(stdoutPipeName); + + const args = + [`"${__filename}"`, 'child', '<', stdinPipeName, '>', stdoutPipeName]; + + const child = spawn(`"${process.execPath}"`, args, { shell: true }); + + child.on('exit', common.mustCall(function(exitCode) { + stdinPipeServer.close(); + stdoutPipeServer.close(); + assert.strictEqual(exitCode, 0); + })); +} else { + // child + process.stdin.pipe(process.stdout); +} diff --git a/tests/node_compat/test/parallel/test-stdin-hang.js b/tests/node_compat/test/parallel/test-stdin-hang.js new file mode 100644 index 0000000000..26e98abe03 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stdin-hang.js @@ -0,0 +1,39 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); + +// This test *only* verifies that invoking the stdin getter does not +// cause node to hang indefinitely. +// If it does, then the test-runner will nuke it. + +// invoke the getter. +process.stdin; // eslint-disable-line no-unused-expressions + +console.error('Should exit normally now.'); diff --git a/tests/node_compat/test/parallel/test-stdin-pipe-large.js b/tests/node_compat/test/parallel/test-stdin-pipe-large.js new file mode 100644 index 0000000000..cdc4e9ff05 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stdin-pipe-large.js @@ -0,0 +1,30 @@ +// 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. + +'use strict'; +// See https://github.com/nodejs/node/issues/5927 + +const common = require('../common'); +const assert = require('assert'); +const spawn = require('child_process').spawn; + +if (process.argv[2] === 'child') { + process.stdin.pipe(process.stdout); + return; +} + +const child = spawn(process.execPath, [__filename, 'child'], { stdio: 'pipe' }); + +const expectedBytes = 1024 * 1024; +let readBytes = 0; + +child.stdin.end(Buffer.alloc(expectedBytes)); + +child.stdout.on('data', (chunk) => readBytes += chunk.length); +child.stdout.on('end', common.mustCall(() => { + assert.strictEqual(readBytes, expectedBytes); +})); diff --git a/tests/node_compat/test/parallel/test-stdin-pipe-resume.js b/tests/node_compat/test/parallel/test-stdin-pipe-resume.js new file mode 100644 index 0000000000..52054d2dda --- /dev/null +++ b/tests/node_compat/test/parallel/test-stdin-pipe-resume.js @@ -0,0 +1,34 @@ +// 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. + +'use strict'; +// This tests that piping stdin will cause it to resume() as well. +require('../common'); +const assert = require('assert'); + +if (process.argv[2] === 'child') { + process.stdin.pipe(process.stdout); +} else { + const spawn = require('child_process').spawn; + const buffers = []; + const child = spawn(process.execPath, [__filename, 'child']); + child.stdout.on('data', function(c) { + buffers.push(c); + }); + child.stdout.on('close', function() { + const b = Buffer.concat(buffers).toString(); + assert.strictEqual(b, 'Hello, world\n'); + console.log('ok'); + }); + child.stdin.write('Hel'); + child.stdin.write('lo,'); + child.stdin.write(' wo'); + setTimeout(function() { + child.stdin.write('rld\n'); + child.stdin.end(); + }, 10); +} diff --git a/tests/node_compat/test/parallel/test-stdin-script-child-option.js b/tests/node_compat/test/parallel/test-stdin-script-child-option.js new file mode 100644 index 0000000000..1d4cd00e1e --- /dev/null +++ b/tests/node_compat/test/parallel/test-stdin-script-child-option.js @@ -0,0 +1,24 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const expected = '--option-to-be-seen-on-child'; + +const { spawn } = require('child_process'); +const child = spawn(process.execPath, ['-', expected], { stdio: 'pipe' }); + +child.stdin.end('console.log(process.argv[2])'); + +let actual = ''; +child.stdout.setEncoding('utf8'); +child.stdout.on('data', (chunk) => actual += chunk); +child.stdout.on('end', common.mustCall(() => { + assert.strictEqual(actual.trim(), expected); +})); diff --git a/tests/node_compat/test/parallel/test-stdio-pipe-access.js b/tests/node_compat/test/parallel/test-stdio-pipe-access.js new file mode 100644 index 0000000000..ab1db54cca --- /dev/null +++ b/tests/node_compat/test/parallel/test-stdio-pipe-access.js @@ -0,0 +1,45 @@ +// 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. + +'use strict'; +const common = require('../common'); +if (!common.isMainThread) + common.skip("Workers don't have process-like stdio"); + +// Test if Node handles accessing process.stdin if it is a redirected +// pipe without deadlocking +const { spawn, spawnSync } = require('child_process'); + +const numTries = 5; +const who = process.argv.length <= 2 ? 'runner' : process.argv[2]; + +switch (who) { + case 'runner': + for (let num = 0; num < numTries; ++num) { + spawnSync(process.argv0, + [process.argv[1], 'parent'], + { 'stdio': 'inherit' }); + } + break; + case 'parent': { + const middle = spawn(process.argv0, + [process.argv[1], 'middle'], + { 'stdio': 'pipe' }); + middle.stdout.on('data', () => {}); + break; + } + case 'middle': + spawn(process.argv0, + [process.argv[1], 'bottom'], + { 'stdio': [ process.stdin, + process.stdout, + process.stderr ] }); + break; + case 'bottom': + process.stdin; // eslint-disable-line no-unused-expressions + break; +} diff --git a/tests/node_compat/test/parallel/test-stdio-pipe-redirect.js b/tests/node_compat/test/parallel/test-stdio-pipe-redirect.js new file mode 100644 index 0000000000..d2d51f7a69 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stdio-pipe-redirect.js @@ -0,0 +1,49 @@ +// 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. + +'use strict'; +const common = require('../common'); +if (!common.isMainThread) + common.skip("Workers don't have process-like stdio"); + +// Test if Node handles redirecting one child process stdout to another +// process stdin without crashing. +const spawn = require('child_process').spawn; + +const writeSize = 100; +const totalDots = 10000; + +const who = process.argv.length <= 2 ? 'parent' : process.argv[2]; + +switch (who) { + case 'parent': { + const consumer = spawn(process.argv0, [process.argv[1], 'consumer'], { + stdio: ['pipe', 'ignore', 'inherit'], + }); + const producer = spawn(process.argv0, [process.argv[1], 'producer'], { + stdio: ['pipe', consumer.stdin, 'inherit'], + }); + process.stdin.on('data', () => {}); + producer.on('exit', process.exit); + break; + } + case 'producer': { + const buffer = Buffer.alloc(writeSize, '.'); + let written = 0; + const write = () => { + if (written < totalDots) { + written += writeSize; + process.stdout.write(buffer, write); + } + }; + write(); + break; + } + case 'consumer': + process.stdin.on('data', () => {}); + break; +} diff --git a/tests/node_compat/test/parallel/test-stdio-pipe-stderr.js b/tests/node_compat/test/parallel/test-stdio-pipe-stderr.js new file mode 100644 index 0000000000..d8242a916e --- /dev/null +++ b/tests/node_compat/test/parallel/test-stdio-pipe-stderr.js @@ -0,0 +1,43 @@ +// 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. + +'use strict'; +require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const { spawnSync } = require('child_process'); + +// Test that invoking node with require, and piping stderr to file, +// does not result in exception, +// see: https://github.com/nodejs/node/issues/11257 + +tmpdir.refresh(); +const fakeModulePath = tmpdir.resolve('batman.js'); +const stderrOutputPath = tmpdir.resolve('stderr-output.txt'); +// We need to redirect stderr to a file to produce #11257 +const stream = fs.createWriteStream(stderrOutputPath); + +// The error described in #11257 only happens when we require a +// non-built-in module. +fs.writeFileSync(fakeModulePath, '', 'utf8'); + +stream.on('open', () => { + spawnSync(process.execPath, { + input: `require(${JSON.stringify(fakeModulePath)})`, + stdio: ['pipe', 'pipe', stream] + }); + const stderr = fs.readFileSync(stderrOutputPath, 'utf8').trim(); + assert.strictEqual( + stderr, + '', + `piping stderr to file should not result in exception: ${stderr}` + ); + stream.end(); + fs.unlinkSync(stderrOutputPath); + fs.unlinkSync(fakeModulePath); +}); diff --git a/tests/node_compat/test/parallel/test-stdio-undestroy.js b/tests/node_compat/test/parallel/test-stdio-undestroy.js new file mode 100644 index 0000000000..f10ec0726d --- /dev/null +++ b/tests/node_compat/test/parallel/test-stdio-undestroy.js @@ -0,0 +1,43 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const spawn = require('child_process').spawn; + +if (process.argv[2] === 'child') { + process.stdout.destroy(); + process.stderr.destroy(); + console.log('stdout'); + process.stdout.write('rocks\n'); + console.error('stderr'); + setTimeout(function() { + process.stderr.write('rocks too\n'); + }, 10); + return; +} + +const proc = spawn(process.execPath, [__filename, 'child'], { stdio: 'pipe' }); + +let stdout = ''; +proc.stdout.setEncoding('utf8'); +proc.stdout.on('data', common.mustCallAtLeast(function(chunk) { + stdout += chunk; +}, 1)); + +let stderr = ''; +proc.stderr.setEncoding('utf8'); +proc.stderr.on('data', common.mustCallAtLeast(function(chunk) { + stderr += chunk; +}, 1)); + +proc.on('exit', common.mustCall(function(exitCode) { + assert.strictEqual(exitCode, 0); + assert.strictEqual(stdout, 'stdout\nrocks\n'); + assert.strictEqual(stderr, 'stderr\nrocks too\n'); +})); diff --git a/tests/node_compat/test/parallel/test-stdout-cannot-be-closed-child-process-pipe.js b/tests/node_compat/test/parallel/test-stdout-cannot-be-closed-child-process-pipe.js new file mode 100644 index 0000000000..91dfd44cf6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stdout-cannot-be-closed-child-process-pipe.js @@ -0,0 +1,39 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); + +if (process.argv[2] === 'child') + process.stdout.end('foo'); +else + parent(); + +function parent() { + const spawn = require('child_process').spawn; + const child = spawn(process.execPath, [__filename, 'child']); + let out = ''; + let err = ''; + + child.stdout.setEncoding('utf8'); + child.stderr.setEncoding('utf8'); + + child.stdout.on('data', function(c) { + out += c; + }); + child.stderr.on('data', function(c) { + err += c; + }); + + child.on('close', function(code, signal) { + assert.strictEqual(code, 0); + assert.strictEqual(err, ''); + assert.strictEqual(out, 'foo'); + console.log('ok'); + }); +} diff --git a/tests/node_compat/test/parallel/test-stdout-pipeline-destroy.js b/tests/node_compat/test/parallel/test-stdout-pipeline-destroy.js new file mode 100644 index 0000000000..196f4a96e7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stdout-pipeline-destroy.js @@ -0,0 +1,38 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { Transform, Readable, pipeline } = require('stream'); +const assert = require('assert'); + +const reader = new Readable({ + read(size) { this.push('foo'); } +}); + +let count = 0; + +const err = new Error('this-error-gets-hidden'); + +const transform = new Transform({ + transform(chunk, enc, cb) { + if (count++ >= 5) + this.emit('error', err); + else + cb(null, count.toString() + '\n'); + } +}); + +pipeline( + reader, + transform, + process.stdout, + common.mustCall((e) => { + assert.strictEqual(e, err); + }) +); diff --git a/tests/node_compat/test/parallel/test-stdout-stderr-reading.js b/tests/node_compat/test/parallel/test-stdout-stderr-reading.js new file mode 100644 index 0000000000..25eb25b7b0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stdout-stderr-reading.js @@ -0,0 +1,74 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +// Verify that stdout is never read from. +const net = require('net'); +const read = net.Socket.prototype.read; + +net.Socket.prototype.read = function() { + if (this.fd === 1) + throw new Error('reading from stdout!'); + if (this.fd === 2) + throw new Error('reading from stderr!'); + return read.apply(this, arguments); +}; + +if (process.argv[2] === 'child') + child(); +else + parent(); + +function parent() { + const spawn = require('child_process').spawn; + const node = process.execPath; + + const c1 = spawn(node, [__filename, 'child']); + let c1out = ''; + c1.stdout.setEncoding('utf8'); + c1.stdout.on('data', function(chunk) { + c1out += chunk; + }); + c1.stderr.setEncoding('utf8'); + c1.stderr.on('data', function(chunk) { + console.error(`c1err: ${chunk.split('\n').join('\nc1err: ')}`); + }); + c1.on('close', common.mustCall(function(code, signal) { + assert(!code); + assert(!signal); + assert.strictEqual(c1out, 'ok\n'); + console.log('ok'); + })); + + const c2 = spawn(node, ['-e', 'console.log("ok")']); + let c2out = ''; + c2.stdout.setEncoding('utf8'); + c2.stdout.on('data', function(chunk) { + c2out += chunk; + }); + c1.stderr.setEncoding('utf8'); + c1.stderr.on('data', function(chunk) { + console.error(`c1err: ${chunk.split('\n').join('\nc1err: ')}`); + }); + c2.on('close', common.mustCall(function(code, signal) { + assert(!code); + assert(!signal); + assert.strictEqual(c2out, 'ok\n'); + console.log('ok'); + })); +} + +function child() { + // Should not be reading *ever* in here. + net.Socket.prototype.read = function() { + throw new Error('no reading allowed in child'); + }; + console.log('ok'); +} diff --git a/tests/node_compat/test/parallel/test-stdout-stderr-write.js b/tests/node_compat/test/parallel/test-stdout-stderr-write.js new file mode 100644 index 0000000000..afce78d19f --- /dev/null +++ b/tests/node_compat/test/parallel/test-stdout-stderr-write.js @@ -0,0 +1,15 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); + +// https://github.com/nodejs/node/pull/39246 +assert.strictEqual(process.stderr.write('asd'), true); +assert.strictEqual(process.stdout.write('asd'), true); diff --git a/tests/node_compat/test/parallel/test-stream-catch-rejections.js b/tests/node_compat/test/parallel/test-stream-catch-rejections.js new file mode 100644 index 0000000000..909f031b27 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-catch-rejections.js @@ -0,0 +1,58 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const stream = require('stream'); +const assert = require('assert'); + +{ + const r = new stream.Readable({ + captureRejections: true, + read() { + } + }); + r.push('hello'); + r.push('world'); + + const err = new Error('kaboom'); + + r.on('error', common.mustCall((_err) => { + assert.strictEqual(err, _err); + assert.strictEqual(r.destroyed, true); + })); + + r.on('data', async () => { + throw err; + }); +} + +{ + const w = new stream.Writable({ + captureRejections: true, + highWaterMark: 1, + write(chunk, enc, cb) { + process.nextTick(cb); + } + }); + + const err = new Error('kaboom'); + + w.write('hello', () => { + w.write('world'); + }); + + w.on('error', common.mustCall((_err) => { + assert.strictEqual(err, _err); + assert.strictEqual(w.destroyed, true); + })); + + w.on('drain', common.mustCall(async () => { + throw err; + }, 2)); +} diff --git a/tests/node_compat/test/parallel/test-stream-decoder-objectmode.js b/tests/node_compat/test/parallel/test-stream-decoder-objectmode.js new file mode 100644 index 0000000000..816f35a3fa --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-decoder-objectmode.js @@ -0,0 +1,27 @@ +// 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. + +'use strict'; + +require('../common'); +const stream = require('stream'); +const assert = require('assert'); + +const readable = new stream.Readable({ + read: () => {}, + encoding: 'utf16le', + objectMode: true +}); + +readable.push(Buffer.from('abc', 'utf16le')); +readable.push(Buffer.from('def', 'utf16le')); +readable.push(null); + +// Without object mode, these would be concatenated into a single chunk. +assert.strictEqual(readable.read(), 'abc'); +assert.strictEqual(readable.read(), 'def'); +assert.strictEqual(readable.read(), null); diff --git a/tests/node_compat/test/parallel/test-stream-duplex-readable-writable.js b/tests/node_compat/test/parallel/test-stream-duplex-readable-writable.js new file mode 100644 index 0000000000..82dfb54afb --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-duplex-readable-writable.js @@ -0,0 +1,53 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { Duplex } = require('stream'); +const assert = require('assert'); + +{ + const duplex = new Duplex({ + readable: false + }); + assert.strictEqual(duplex.readable, false); + duplex.push('asd'); + duplex.on('error', common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_STREAM_PUSH_AFTER_EOF'); + })); + duplex.on('data', common.mustNotCall()); + duplex.on('end', common.mustNotCall()); +} + +{ + const duplex = new Duplex({ + writable: false, + write: common.mustNotCall() + }); + assert.strictEqual(duplex.writable, false); + duplex.write('asd'); + duplex.on('error', common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_STREAM_WRITE_AFTER_END'); + })); + duplex.on('finish', common.mustNotCall()); +} + +{ + const duplex = new Duplex({ + readable: false + }); + assert.strictEqual(duplex.readable, false); + duplex.on('data', common.mustNotCall()); + duplex.on('end', common.mustNotCall()); + async function run() { + for await (const chunk of duplex) { + assert(false, chunk); + } + } + run().then(common.mustCall()); +} diff --git a/tests/node_compat/test/parallel/test-stream-end-of-streams.js b/tests/node_compat/test/parallel/test-stream-end-of-streams.js new file mode 100644 index 0000000000..3ac78238ce --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-end-of-streams.js @@ -0,0 +1,27 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const { Duplex, finished } = require('stream'); + +assert.throws( + () => { + // Passing empty object to mock invalid stream + // should throw error + finished({}, () => {}); + }, + { code: 'ERR_INVALID_ARG_TYPE' } +); + +const streamObj = new Duplex(); +streamObj.end(); +// Below code should not throw any errors as the +// streamObj is `Stream` +finished(streamObj, () => {}); diff --git a/tests/node_compat/test/parallel/test-stream-filter.js b/tests/node_compat/test/parallel/test-stream-filter.js new file mode 100644 index 0000000000..7043365ce9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-filter.js @@ -0,0 +1,183 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { + Readable, +} = require('stream'); +const assert = require('assert'); +const { once } = require('events'); +const { setTimeout } = require('timers/promises'); + +{ + // Filter works on synchronous streams with a synchronous predicate + const stream = Readable.from([1, 2, 3, 4, 5]).filter((x) => x < 3); + const result = [1, 2]; + (async () => { + for await (const item of stream) { + assert.strictEqual(item, result.shift()); + } + })().then(common.mustCall()); +} + +{ + // Filter works on synchronous streams with an asynchronous predicate + const stream = Readable.from([1, 2, 3, 4, 5]).filter(async (x) => { + await Promise.resolve(); + return x > 3; + }); + const result = [4, 5]; + (async () => { + for await (const item of stream) { + assert.strictEqual(item, result.shift()); + } + })().then(common.mustCall()); +} + +{ + // Map works on asynchronous streams with a asynchronous mapper + const stream = Readable.from([1, 2, 3, 4, 5]).map(async (x) => { + await Promise.resolve(); + return x + x; + }).filter((x) => x > 5); + const result = [6, 8, 10]; + (async () => { + for await (const item of stream) { + assert.strictEqual(item, result.shift()); + } + })().then(common.mustCall()); +} + +{ + // Filter works on an infinite stream + const stream = Readable.from(async function* () { + while (true) yield 1; + }()).filter(common.mustCall(async (x) => { + return x < 3; + }, 5)); + (async () => { + let i = 1; + for await (const item of stream) { + assert.strictEqual(item, 1); + if (++i === 5) break; + } + })().then(common.mustCall()); +} + +{ + // Filter works on constructor created streams + let i = 0; + const stream = new Readable({ + read() { + if (i === 10) { + this.push(null); + return; + } + this.push(Uint8Array.from([i])); + i++; + }, + highWaterMark: 0, + }).filter(common.mustCall(async ([x]) => { + return x !== 5; + }, 10)); + (async () => { + const result = (await stream.toArray()).map((x) => x[0]); + const expected = [...Array(10).keys()].filter((x) => x !== 5); + assert.deepStrictEqual(result, expected); + })().then(common.mustCall()); +} + +{ + // Throwing an error during `filter` (sync) + const stream = Readable.from([1, 2, 3, 4, 5]).filter((x) => { + if (x === 3) { + throw new Error('boom'); + } + return true; + }); + assert.rejects( + stream.map((x) => x + x).toArray(), + /boom/, + ).then(common.mustCall()); +} + +{ + // Throwing an error during `filter` (async) + const stream = Readable.from([1, 2, 3, 4, 5]).filter(async (x) => { + if (x === 3) { + throw new Error('boom'); + } + return true; + }); + assert.rejects( + stream.filter(() => true).toArray(), + /boom/, + ).then(common.mustCall()); +} + +{ + // Concurrency + AbortSignal + const ac = new AbortController(); + let calls = 0; + const stream = Readable.from([1, 2, 3, 4]).filter(async (_, { signal }) => { + calls++; + await once(signal, 'abort'); + }, { signal: ac.signal, concurrency: 2 }); + // pump + assert.rejects(async () => { + for await (const item of stream) { + // nope + console.log(item); + } + }, { + name: 'AbortError', + }).then(common.mustCall()); + + setImmediate(() => { + ac.abort(); + assert.strictEqual(calls, 2); + }); +} + +{ + // Concurrency result order + const stream = Readable.from([1, 2]).filter(async (item, { signal }) => { + await setTimeout(10 - item, { signal }); + return true; + }, { concurrency: 2 }); + + (async () => { + const expected = [1, 2]; + for await (const item of stream) { + assert.strictEqual(item, expected.shift()); + } + })().then(common.mustCall()); +} + +{ + // Error cases + assert.throws(() => Readable.from([1]).filter(1), /ERR_INVALID_ARG_TYPE/); + assert.throws(() => Readable.from([1]).filter((x) => x, { + concurrency: 'Foo' + }), /ERR_OUT_OF_RANGE/); + assert.throws(() => Readable.from([1]).filter((x) => x, 1), /ERR_INVALID_ARG_TYPE/); +} +{ + // Test result is a Readable + const stream = Readable.from([1, 2, 3, 4, 5]).filter((x) => true); + assert.strictEqual(stream.readable, true); +} +{ + const stream = Readable.from([1, 2, 3, 4, 5]); + Object.defineProperty(stream, 'map', { + value: common.mustNotCall(), + }); + // Check that map isn't getting called. + stream.filter(() => true); +} diff --git a/tests/node_compat/test/parallel/test-stream-flatMap.js b/tests/node_compat/test/parallel/test-stream-flatMap.js new file mode 100644 index 0000000000..7575f90d65 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-flatMap.js @@ -0,0 +1,138 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const { + Readable, +} = require('stream'); +const assert = require('assert'); +const { setTimeout } = require('timers/promises'); +const { createReadStream } = require('fs'); + +function oneTo5() { + return Readable.from([1, 2, 3, 4, 5]); +} + +{ + // flatMap works on synchronous streams with a synchronous mapper + (async () => { + assert.deepStrictEqual( + await oneTo5().flatMap((x) => [x + x]).toArray(), + [2, 4, 6, 8, 10] + ); + assert.deepStrictEqual( + await oneTo5().flatMap(() => []).toArray(), + [] + ); + assert.deepStrictEqual( + await oneTo5().flatMap((x) => [x, x]).toArray(), + [1, 1, 2, 2, 3, 3, 4, 4, 5, 5] + ); + })().then(common.mustCall()); +} + + +{ + // flatMap works on sync/async streams with an asynchronous mapper + (async () => { + assert.deepStrictEqual( + await oneTo5().flatMap(async (x) => [x, x]).toArray(), + [1, 1, 2, 2, 3, 3, 4, 4, 5, 5] + ); + const asyncOneTo5 = oneTo5().map(async (x) => x); + assert.deepStrictEqual( + await asyncOneTo5.flatMap(async (x) => [x, x]).toArray(), + [1, 1, 2, 2, 3, 3, 4, 4, 5, 5] + ); + })().then(common.mustCall()); +} +{ + // flatMap works on a stream where mapping returns a stream + (async () => { + const result = await oneTo5().flatMap(async (x) => { + return Readable.from([x, x]); + }).toArray(); + assert.deepStrictEqual(result, [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]); + })().then(common.mustCall()); + // flatMap works on an objectMode stream where mappign returns a stream + (async () => { + const result = await oneTo5().flatMap(() => { + return createReadStream(fixtures.path('x.txt')); + }).toArray(); + // The resultant stream is in object mode so toArray shouldn't flatten + assert.strictEqual(result.length, 5); + assert.deepStrictEqual( + Buffer.concat(result).toString(), + 'xyz\n'.repeat(5) + ); + + })().then(common.mustCall()); + +} + +{ + // Concurrency + AbortSignal + const ac = new AbortController(); + const stream = oneTo5().flatMap(common.mustNotCall(async (_, { signal }) => { + await setTimeout(100, { signal }); + }), { signal: ac.signal, concurrency: 2 }); + // pump + assert.rejects(async () => { + for await (const item of stream) { + // nope + console.log(item); + } + }, { + name: 'AbortError', + }).then(common.mustCall()); + + queueMicrotask(() => { + ac.abort(); + }); +} + +{ + // Already aborted AbortSignal + const stream = oneTo5().flatMap(common.mustNotCall(async (_, { signal }) => { + await setTimeout(100, { signal }); + }), { signal: AbortSignal.abort() }); + // pump + assert.rejects(async () => { + for await (const item of stream) { + // nope + console.log(item); + } + }, { + name: 'AbortError', + }).then(common.mustCall()); +} + +{ + // Error cases + assert.throws(() => Readable.from([1]).flatMap(1), /ERR_INVALID_ARG_TYPE/); + assert.throws(() => Readable.from([1]).flatMap((x) => x, { + concurrency: 'Foo' + }), /ERR_OUT_OF_RANGE/); + assert.throws(() => Readable.from([1]).flatMap((x) => x, 1), /ERR_INVALID_ARG_TYPE/); + assert.throws(() => Readable.from([1]).flatMap((x) => x, { signal: true }), /ERR_INVALID_ARG_TYPE/); +} +{ + // Test result is a Readable + const stream = oneTo5().flatMap((x) => x); + assert.strictEqual(stream.readable, true); +} +{ + const stream = oneTo5(); + Object.defineProperty(stream, 'map', { + value: common.mustNotCall(), + }); + // Check that map isn't getting called. + stream.flatMap(() => true); +} diff --git a/tests/node_compat/test/parallel/test-stream-forEach.js b/tests/node_compat/test/parallel/test-stream-forEach.js new file mode 100644 index 0000000000..748193e1ba --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-forEach.js @@ -0,0 +1,146 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { + Readable, +} = require('stream'); +const assert = require('assert'); +const { once } = require('events'); + +{ + // forEach works on synchronous streams with a synchronous predicate + const stream = Readable.from([1, 2, 3]); + const result = [1, 2, 3]; + (async () => { + await stream.forEach((value) => assert.strictEqual(value, result.shift())); + })().then(common.mustCall()); +} + +{ + // forEach works an asynchronous streams + const stream = Readable.from([1, 2, 3]).filter(async (x) => { + await Promise.resolve(); + return true; + }); + const result = [1, 2, 3]; + (async () => { + await stream.forEach((value) => assert.strictEqual(value, result.shift())); + })().then(common.mustCall()); +} + +{ + // forEach works on asynchronous streams with a asynchronous forEach fn + const stream = Readable.from([1, 2, 3]).filter(async (x) => { + await Promise.resolve(); + return true; + }); + const result = [1, 2, 3]; + (async () => { + await stream.forEach(async (value) => { + await Promise.resolve(); + assert.strictEqual(value, result.shift()); + }); + })().then(common.mustCall()); +} + +{ + // forEach works on an infinite stream + const ac = new AbortController(); + const { signal } = ac; + const stream = Readable.from(async function* () { + while (true) yield 1; + }(), { signal }); + let i = 0; + assert.rejects(stream.forEach(common.mustCall((x) => { + i++; + if (i === 10) ac.abort(); + assert.strictEqual(x, 1); + }, 10)), { name: 'AbortError' }).then(common.mustCall()); +} + +{ + // Emitting an error during `forEach` + const stream = Readable.from([1, 2, 3, 4, 5]); + assert.rejects(stream.forEach(async (x) => { + if (x === 3) { + stream.emit('error', new Error('boom')); + } + }), /boom/).then(common.mustCall()); +} + +{ + // Throwing an error during `forEach` (sync) + const stream = Readable.from([1, 2, 3, 4, 5]); + assert.rejects(stream.forEach((x) => { + if (x === 3) { + throw new Error('boom'); + } + }), /boom/).then(common.mustCall()); +} + +{ + // Throwing an error during `forEach` (async) + const stream = Readable.from([1, 2, 3, 4, 5]); + assert.rejects(stream.forEach(async (x) => { + if (x === 3) { + return Promise.reject(new Error('boom')); + } + }), /boom/).then(common.mustCall()); +} + +{ + // Concurrency + AbortSignal + const ac = new AbortController(); + let calls = 0; + const forEachPromise = + Readable.from([1, 2, 3, 4]).forEach(async (_, { signal }) => { + calls++; + await once(signal, 'abort'); + }, { signal: ac.signal, concurrency: 2, highWaterMark: 0 }); + // pump + assert.rejects(async () => { + await forEachPromise; + }, { + name: 'AbortError', + }).then(common.mustCall()); + + setImmediate(() => { + ac.abort(); + assert.strictEqual(calls, 2); + }); +} + +{ + // Error cases + assert.rejects(async () => { + await Readable.from([1]).forEach(1); + }, /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); + assert.rejects(async () => { + await Readable.from([1]).forEach((x) => x, { + concurrency: 'Foo' + }); + }, /ERR_OUT_OF_RANGE/).then(common.mustCall()); + assert.rejects(async () => { + await Readable.from([1]).forEach((x) => x, 1); + }, /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); +} +{ + // Test result is a Promise + const stream = Readable.from([1, 2, 3, 4, 5]).forEach((_) => true); + assert.strictEqual(typeof stream.then, 'function'); +} +{ + const stream = Readable.from([1, 2, 3, 4, 5]); + Object.defineProperty(stream, 'map', { + value: common.mustNotCall(), + }); + // Check that map isn't getting called. + stream.forEach(() => true); +} diff --git a/tests/node_compat/test/parallel/test-stream-passthrough-drain.js b/tests/node_compat/test/parallel/test-stream-passthrough-drain.js new file mode 100644 index 0000000000..7e4cddc289 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-passthrough-drain.js @@ -0,0 +1,17 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { PassThrough } = require('stream'); + +const pt = new PassThrough({ highWaterMark: 0 }); +pt.on('drain', common.mustCall()); +assert(!pt.write('hello1')); +pt.read(); +pt.read(); diff --git a/tests/node_compat/test/parallel/test-stream-pipe-error-unhandled.js b/tests/node_compat/test/parallel/test-stream-pipe-error-unhandled.js new file mode 100644 index 0000000000..f4e9f3b4c7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipe-error-unhandled.js @@ -0,0 +1,28 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Readable, Writable } = require('stream'); + +process.on('uncaughtException', common.mustCall((err) => { + assert.strictEqual(err.message, 'asd'); +})); + +const r = new Readable({ + read() { + this.push('asd'); + } +}); +const w = new Writable({ + autoDestroy: true, + write() {} +}); + +r.pipe(w); +w.destroy(new Error('asd')); diff --git a/tests/node_compat/test/parallel/test-stream-pipeline-duplex.js b/tests/node_compat/test/parallel/test-stream-pipeline-duplex.js new file mode 100644 index 0000000000..b2c0258fc9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipeline-duplex.js @@ -0,0 +1,28 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { pipeline, Duplex, PassThrough } = require('stream'); +const assert = require('assert'); + +const remote = new PassThrough(); +const local = new Duplex({ + read() {}, + write(chunk, enc, callback) { + callback(); + } +}); + +pipeline(remote, local, remote, common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_STREAM_PREMATURE_CLOSE'); +})); + +setImmediate(() => { + remote.end(); +}); diff --git a/tests/node_compat/test/parallel/test-stream-pipeline-listeners.js b/tests/node_compat/test/parallel/test-stream-pipeline-listeners.js new file mode 100644 index 0000000000..09ccc7ea47 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipeline-listeners.js @@ -0,0 +1,83 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { pipeline, Duplex, PassThrough, Writable } = require('stream'); +const assert = require('assert'); + +process.on('uncaughtException', common.mustCall((err) => { + assert.strictEqual(err.message, 'no way'); +}, 2)); + +// Ensure that listeners is removed if last stream is readable +// And other stream's listeners unchanged +const a = new PassThrough(); +a.end('foobar'); +const b = new Duplex({ + write(chunk, encoding, callback) { + callback(); + } +}); +pipeline(a, b, common.mustCall((error) => { + if (error) { + assert.ifError(error); + } + + assert(a.listenerCount('error') > 0); + assert.strictEqual(b.listenerCount('error'), 0); + setTimeout(() => { + assert.strictEqual(b.listenerCount('error'), 0); + b.destroy(new Error('no way')); + }, 100); +})); + +// Async generators +const c = new PassThrough(); +c.end('foobar'); +const d = pipeline( + c, + async function* (source) { + for await (const chunk of source) { + yield String(chunk).toUpperCase(); + } + }, + common.mustCall((error) => { + if (error) { + assert.ifError(error); + } + + assert(c.listenerCount('error') > 0); + assert.strictEqual(d.listenerCount('error'), 0); + setTimeout(() => { + assert.strictEqual(b.listenerCount('error'), 0); + d.destroy(new Error('no way')); + }, 100); + }) +); + +// If last stream is not readable, will not throw and remove listeners +const e = new PassThrough(); +e.end('foobar'); +const f = new Writable({ + write(chunk, encoding, callback) { + callback(); + } +}); +pipeline(e, f, common.mustCall((error) => { + if (error) { + assert.ifError(error); + } + + assert(e.listenerCount('error') > 0); + assert(f.listenerCount('error') > 0); + setTimeout(() => { + assert(f.listenerCount('error') > 0); + f.destroy(new Error('no way')); + }, 100); +})); diff --git a/tests/node_compat/test/parallel/test-stream-pipeline-uncaught.js b/tests/node_compat/test/parallel/test-stream-pipeline-uncaught.js new file mode 100644 index 0000000000..77c409c967 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-pipeline-uncaught.js @@ -0,0 +1,29 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { + pipeline, + PassThrough +} = require('stream'); +const assert = require('assert'); + +process.on('uncaughtException', common.mustCall((err) => { + assert.strictEqual(err.message, 'error'); +})); + +// Ensure that pipeline that ends with Promise +// still propagates error to uncaughtException. +const s = new PassThrough(); +s.end('data'); +pipeline(s, async function(source) { + for await (const chunk of source) { } // eslint-disable-line no-unused-vars, no-empty +}, common.mustSucceed(() => { + throw new Error('error'); +})); diff --git a/tests/node_compat/test/parallel/test-stream-push-order.js b/tests/node_compat/test/parallel/test-stream-push-order.js new file mode 100644 index 0000000000..c0202df542 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-push-order.js @@ -0,0 +1,59 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const Readable = require('stream').Readable; +const assert = require('assert'); + +const s = new Readable({ + highWaterMark: 20, + encoding: 'ascii' +}); + +const list = ['1', '2', '3', '4', '5', '6']; + +s._read = function(n) { + const one = list.shift(); + if (!one) { + s.push(null); + } else { + const two = list.shift(); + s.push(one); + s.push(two); + } +}; + +s.read(0); + +// ACTUALLY [1, 3, 5, 6, 4, 2] + +process.on('exit', function() { + assert.strictEqual(s.readableBuffer.join(','), '1,2,3,4,5,6'); + console.log('ok'); +}); diff --git a/tests/node_compat/test/parallel/test-stream-readable-strategy-option.js b/tests/node_compat/test/parallel/test-stream-readable-strategy-option.js new file mode 100644 index 0000000000..2c8712ee51 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-strategy-option.js @@ -0,0 +1,82 @@ +// 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. + +'use strict'; +const common = require('../common'); +const { Readable } = require('stream'); +const assert = require('assert'); +const { strictEqual } = require('assert'); + +{ + // Strategy 2 + const streamData = ['a', 'b', 'c', null]; + + // Fulfill a Readable object + const readable = new Readable({ + read: common.mustCall(() => { + process.nextTick(() => { + readable.push(streamData.shift()); + }); + }, streamData.length), + }); + + // Use helper to convert it to a Web ReadableStream using ByteLength strategy + const readableStream = Readable.toWeb(readable, { + strategy: new ByteLengthQueuingStrategy({ highWaterMark: 1 }), + }); + + assert(!readableStream.locked); + readableStream.getReader().read().then(common.mustCall()); +} + +{ + // Strategy 2 + const streamData = ['a', 'b', 'c', null]; + + // Fulfill a Readable object + const readable = new Readable({ + read: common.mustCall(() => { + process.nextTick(() => { + readable.push(streamData.shift()); + }); + }, streamData.length), + }); + + // Use helper to convert it to a Web ReadableStream using Count strategy + const readableStream = Readable.toWeb(readable, { + strategy: new CountQueuingStrategy({ highWaterMark: 1 }), + }); + + assert(!readableStream.locked); + readableStream.getReader().read().then(common.mustCall()); +} + +{ + const desireSizeExpected = 2; + + const stringStream = new ReadableStream( + { + start(controller) { + // Check if the strategy is being assigned on the init of the ReadableStream + strictEqual(controller.desiredSize, desireSizeExpected); + controller.enqueue('a'); + controller.enqueue('b'); + controller.close(); + }, + }, + new CountQueuingStrategy({ highWaterMark: desireSizeExpected }) + ); + + const reader = stringStream.getReader(); + + reader.read().then(common.mustCall()); + reader.read().then(common.mustCall()); + reader.read().then(({ value, done }) => { + strictEqual(value, undefined); + strictEqual(done, true); + }); +} diff --git a/tests/node_compat/test/parallel/test-stream-readable-unpipe-resume.js b/tests/node_compat/test/parallel/test-stream-readable-unpipe-resume.js new file mode 100644 index 0000000000..f8ff846afa --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-readable-unpipe-resume.js @@ -0,0 +1,27 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const stream = require('stream'); +const fs = require('fs'); + +const readStream = fs.createReadStream(process.execPath); + +const transformStream = new stream.Transform({ + transform: common.mustCall(() => { + readStream.unpipe(); + readStream.resume(); + }) +}); + +readStream.on('end', common.mustCall()); + +readStream + .pipe(transformStream) + .resume(); diff --git a/tests/node_compat/test/parallel/test-stream-reduce.js b/tests/node_compat/test/parallel/test-stream-reduce.js new file mode 100644 index 0000000000..e0ec0f26d9 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-reduce.js @@ -0,0 +1,139 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { + Readable, +} = require('stream'); +const assert = require('assert'); + +function sum(p, c) { + return p + c; +} + +{ + // Does the same thing as `(await stream.toArray()).reduce(...)` + (async () => { + const tests = [ + [[], sum, 0], + [[1], sum, 0], + [[1, 2, 3, 4, 5], sum, 0], + [[...Array(100).keys()], sum, 0], + [['a', 'b', 'c'], sum, ''], + [[1, 2], sum], + [[1, 2, 3], (x, y) => y], + ]; + for (const [values, fn, initial] of tests) { + const streamReduce = await Readable.from(values) + .reduce(fn, initial); + const arrayReduce = values.reduce(fn, initial); + assert.deepStrictEqual(streamReduce, arrayReduce); + } + // Does the same thing as `(await stream.toArray()).reduce(...)` with an + // asynchronous reducer + for (const [values, fn, initial] of tests) { + const streamReduce = await Readable.from(values) + .map(async (x) => x) + .reduce(fn, initial); + const arrayReduce = values.reduce(fn, initial); + assert.deepStrictEqual(streamReduce, arrayReduce); + } + })().then(common.mustCall()); +} +{ + // Works with an async reducer, with or without initial value + (async () => { + const six = await Readable.from([1, 2, 3]).reduce(async (p, c) => p + c, 0); + assert.strictEqual(six, 6); + })().then(common.mustCall()); + (async () => { + const six = await Readable.from([1, 2, 3]).reduce(async (p, c) => p + c); + assert.strictEqual(six, 6); + })().then(common.mustCall()); +} +{ + // Works lazily + assert.rejects(Readable.from([1, 2, 3, 4, 5, 6]) + .map(common.mustCall((x) => { + return x; + }, 3)) // Two consumed and one buffered by `map` due to default concurrency + .reduce(async (p, c) => { + if (p === 1) { + throw new Error('boom'); + } + return c; + }, 0) + , /boom/).then(common.mustCall()); +} + +{ + // Support for AbortSignal + const ac = new AbortController(); + assert.rejects(async () => { + await Readable.from([1, 2, 3]).reduce(async (p, c) => { + if (c === 3) { + await new Promise(() => {}); // Explicitly do not pass signal here + } + return Promise.resolve(); + }, 0, { signal: ac.signal }); + }, { + name: 'AbortError', + }).then(common.mustCall()); + ac.abort(); +} + + +{ + // Support for AbortSignal - pre aborted + const stream = Readable.from([1, 2, 3]); + assert.rejects(async () => { + await stream.reduce(async (p, c) => { + if (c === 3) { + await new Promise(() => {}); // Explicitly do not pass signal here + } + return Promise.resolve(); + }, 0, { signal: AbortSignal.abort() }); + }, { + name: 'AbortError', + }).then(common.mustCall(() => { + assert.strictEqual(stream.destroyed, true); + })); +} + +{ + // Support for AbortSignal - deep + const stream = Readable.from([1, 2, 3]); + assert.rejects(async () => { + await stream.reduce(async (p, c, { signal }) => { + signal.addEventListener('abort', common.mustCall(), { once: true }); + if (c === 3) { + await new Promise(() => {}); // Explicitly do not pass signal here + } + return Promise.resolve(); + }, 0, { signal: AbortSignal.abort() }); + }, { + name: 'AbortError', + }).then(common.mustCall(() => { + assert.strictEqual(stream.destroyed, true); + })); +} + +{ + // Error cases + assert.rejects(() => Readable.from([]).reduce(1), /TypeError/).then(common.mustCall()); + assert.rejects(() => Readable.from([]).reduce('5'), /TypeError/).then(common.mustCall()); + assert.rejects(() => Readable.from([]).reduce((x, y) => x + y, 0, 1), /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); + assert.rejects(() => Readable.from([]).reduce((x, y) => x + y, 0, { signal: true }), /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); +} + +{ + // Test result is a Promise + const result = Readable.from([1, 2, 3, 4, 5]).reduce(sum, 0); + assert.ok(result instanceof Promise); +} diff --git a/tests/node_compat/test/parallel/test-stream-toArray.js b/tests/node_compat/test/parallel/test-stream-toArray.js new file mode 100644 index 0000000000..514c03112a --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-toArray.js @@ -0,0 +1,100 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const { + Readable, +} = require('stream'); +const assert = require('assert'); + +{ + // Works on a synchronous stream + (async () => { + const tests = [ + [], + [1], + [1, 2, 3], + Array(100).fill().map((_, i) => i), + ]; + for (const test of tests) { + const stream = Readable.from(test); + const result = await stream.toArray(); + assert.deepStrictEqual(result, test); + } + })().then(common.mustCall()); +} + +{ + // Works on a non-object-mode stream + (async () => { + const firstBuffer = Buffer.from([1, 2, 3]); + const secondBuffer = Buffer.from([4, 5, 6]); + const stream = Readable.from( + [firstBuffer, secondBuffer], + { objectMode: false }); + const result = await stream.toArray(); + assert.strictEqual(Array.isArray(result), true); + assert.deepStrictEqual(result, [firstBuffer, secondBuffer]); + })().then(common.mustCall()); +} + +{ + // Works on an asynchronous stream + (async () => { + const tests = [ + [], + [1], + [1, 2, 3], + Array(100).fill().map((_, i) => i), + ]; + for (const test of tests) { + const stream = Readable.from(test).map((x) => Promise.resolve(x)); + const result = await stream.toArray(); + assert.deepStrictEqual(result, test); + } + })().then(common.mustCall()); +} + +{ + // Support for AbortSignal + const ac = new AbortController(); + let stream; + assert.rejects(async () => { + stream = Readable.from([1, 2, 3]).map(async (x) => { + if (x === 3) { + await new Promise(() => {}); // Explicitly do not pass signal here + } + return Promise.resolve(x); + }); + await stream.toArray({ signal: ac.signal }); + }, { + name: 'AbortError', + }).then(common.mustCall(() => { + // Only stops toArray, does not destroy the stream + assert(stream.destroyed, false); + })); + ac.abort(); +} +{ + // Test result is a Promise + const result = Readable.from([1, 2, 3, 4, 5]).toArray(); + assert.strictEqual(result instanceof Promise, true); +} +{ + // Error cases + assert.rejects(async () => { + await Readable.from([1]).toArray(1); + }, /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); + + assert.rejects(async () => { + await Readable.from([1]).toArray({ + signal: true + }); + }, /ERR_INVALID_ARG_TYPE/).then(common.mustCall()); +} diff --git a/tests/node_compat/test/parallel/test-stream-toWeb-allows-server-response.js b/tests/node_compat/test/parallel/test-stream-toWeb-allows-server-response.js new file mode 100644 index 0000000000..656013d89d --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-toWeb-allows-server-response.js @@ -0,0 +1,36 @@ +// 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. + +'use strict'; +const common = require('../common'); +const { Writable } = require('stream'); + +const assert = require('assert'); +const http = require('http'); + +// Check if Writable.toWeb works on the response object after creating a server. +const server = http.createServer( + common.mustCall((req, res) => { + const webStreamResponse = Writable.toWeb(res); + assert.strictEqual(webStreamResponse instanceof WritableStream, true); + res.end(); + }) +); + +server.listen( + 0, + common.mustCall(() => { + http.get( + { + port: server.address().port, + }, + common.mustCall(() => { + server.close(); + }) + ); + }) +); diff --git a/tests/node_compat/test/parallel/test-stream-transform-hwm0.js b/tests/node_compat/test/parallel/test-stream-transform-hwm0.js new file mode 100644 index 0000000000..dad67ae4a0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-transform-hwm0.js @@ -0,0 +1,35 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const { Transform } = require('stream'); + +const t = new Transform({ + objectMode: true, highWaterMark: 0, + transform(chunk, enc, callback) { + process.nextTick(() => callback(null, chunk, enc)); + } +}); + +assert.strictEqual(t.write(1), false); +t.on('drain', common.mustCall(() => { + assert.strictEqual(t.write(2), false); + t.end(); +})); + +t.once('readable', common.mustCall(() => { + assert.strictEqual(t.read(), 1); + setImmediate(common.mustCall(() => { + assert.strictEqual(t.read(), null); + t.once('readable', common.mustCall(() => { + assert.strictEqual(t.read(), 2); + })); + })); +})); diff --git a/tests/node_compat/test/parallel/test-stream-writable-end-cb-uncaught.js b/tests/node_compat/test/parallel/test-stream-writable-end-cb-uncaught.js new file mode 100644 index 0000000000..40ef4e274c --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream-writable-end-cb-uncaught.js @@ -0,0 +1,31 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const stream = require('stream'); + +process.on('uncaughtException', common.mustCall((err) => { + assert.strictEqual(err.message, 'kaboom'); +})); + +const writable = new stream.Writable(); +const _err = new Error('kaboom'); + +writable._write = (chunk, encoding, cb) => { + cb(); +}; +writable._final = (cb) => { + cb(_err); +}; + +writable.write('asd'); +writable.end(common.mustCall((err) => { + assert.strictEqual(err, _err); +})); diff --git a/tests/node_compat/test/parallel/test-stream2-finish-pipe-error.js b/tests/node_compat/test/parallel/test-stream2-finish-pipe-error.js new file mode 100644 index 0000000000..3a0b820b4d --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream2-finish-pipe-error.js @@ -0,0 +1,27 @@ +// 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. + +'use strict'; +const common = require('../common'); +const stream = require('stream'); + +process.on('uncaughtException', common.mustCall()); + +const r = new stream.Readable(); +r._read = function(size) { + r.push(Buffer.allocUnsafe(size)); +}; + +const w = new stream.Writable(); +w._write = function(data, encoding, cb) { + cb(null); +}; + +r.pipe(w); + +// end() after pipe should cause unhandled exception +w.end(); diff --git a/tests/node_compat/test/parallel/test-stream3-pipeline-async-iterator.js b/tests/node_compat/test/parallel/test-stream3-pipeline-async-iterator.js new file mode 100644 index 0000000000..6b22012769 --- /dev/null +++ b/tests/node_compat/test/parallel/test-stream3-pipeline-async-iterator.js @@ -0,0 +1,34 @@ +// 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. + +/* eslint-disable node-core/require-common-first, require-yield */ +'use strict'; +const { pipeline } = require('node:stream/promises'); +{ + // Ensure that async iterators can act as readable and writable streams + async function* myCustomReadable() { + yield 'Hello'; + yield 'World'; + } + + const messages = []; + async function* myCustomWritable(stream) { + for await (const chunk of stream) { + messages.push(chunk); + } + } + + (async () => { + await pipeline( + myCustomReadable, + myCustomWritable, + ); + // Importing here to avoid initializing streams + require('assert').deepStrictEqual(messages, ['Hello', 'World']); + })() + .then(require('../common').mustCall()); +} diff --git a/tests/node_compat/test/parallel/test-stringbytes-external.js b/tests/node_compat/test/parallel/test-stringbytes-external.js new file mode 100644 index 0000000000..78f3c8608f --- /dev/null +++ b/tests/node_compat/test/parallel/test-stringbytes-external.js @@ -0,0 +1,150 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +// Minimum string size to overflow into external string space +const EXTERN_APEX = 0xFBEE9; + +// Manually controlled string for checking binary output +let ucs2_control = 'a\u0000'; +let write_str = 'a'; + + +// First do basic checks +let b = Buffer.from(write_str, 'ucs2'); +// first check latin1 +let c = b.toString('latin1'); +assert.strictEqual(b[0], 0x61); +assert.strictEqual(b[1], 0); +assert.strictEqual(ucs2_control, c); +// now check binary +c = b.toString('binary'); +assert.strictEqual(b[0], 0x61); +assert.strictEqual(b[1], 0); +assert.strictEqual(ucs2_control, c); + +// Now create big strings +const size = 1 << 20; +write_str = write_str.repeat(size); +ucs2_control = ucs2_control.repeat(size); + +// Check resultant buffer and output string +b = Buffer.from(write_str, 'ucs2'); +// Check fist Buffer created from write string +for (let i = 0; i < b.length; i += 2) { + assert.strictEqual(b[i], 0x61); + assert.strictEqual(b[i + 1], 0); +} + +// Create another string to create an external string +const b_ucs = b.toString('ucs2'); + +// Check control against external binary string +const l_bin = b.toString('latin1'); +assert.strictEqual(ucs2_control, l_bin); + +// Check control against external binary string +const b_bin = b.toString('binary'); +assert.strictEqual(ucs2_control, b_bin); + +// Create buffer copy from external +const c_bin = Buffer.from(l_bin, 'latin1'); +const c_ucs = Buffer.from(b_ucs, 'ucs2'); +// Make sure they're the same length +assert.strictEqual(c_bin.length, c_ucs.length); +// Make sure Buffers from externals are the same +for (let i = 0; i < c_bin.length; i++) { + assert.strictEqual(c_bin[i], c_ucs[i]); +} +// Check resultant strings +assert.strictEqual(c_bin.toString('ucs2'), c_ucs.toString('ucs2')); +assert.strictEqual(c_bin.toString('latin1'), ucs2_control); +assert.strictEqual(c_ucs.toString('latin1'), ucs2_control); + + +// Now let's test BASE64 and HEX encoding/decoding +const RADIOS = 2; +const PRE_HALF_APEX = Math.ceil(EXTERN_APEX / 2) - RADIOS; +const PRE_3OF4_APEX = Math.ceil((EXTERN_APEX / 4) * 3) - RADIOS; + +{ + for (let j = 0; j < RADIOS * 2; j += 1) { + const datum = b; + const slice = datum.slice(0, PRE_HALF_APEX + j); + const slice2 = datum.slice(0, PRE_HALF_APEX + j + 2); + const pumped_string = slice.toString('hex'); + const pumped_string2 = slice2.toString('hex'); + const decoded = Buffer.from(pumped_string, 'hex'); + + // The string are the same? + for (let k = 0; k < pumped_string.length; ++k) { + assert.strictEqual(pumped_string[k], pumped_string2[k]); + } + + // The recoded buffer is the same? + for (let i = 0; i < decoded.length; ++i) { + assert.strictEqual(datum[i], decoded[i]); + } + } +} + +{ + for (let j = 0; j < RADIOS * 2; j += 1) { + const datum = b; + const slice = datum.slice(0, PRE_3OF4_APEX + j); + const slice2 = datum.slice(0, PRE_3OF4_APEX + j + 2); + const pumped_string = slice.toString('base64'); + const pumped_string2 = slice2.toString('base64'); + const decoded = Buffer.from(pumped_string, 'base64'); + + // The string are the same? + for (let k = 0; k < pumped_string.length - 3; ++k) { + assert.strictEqual(pumped_string[k], pumped_string2[k]); + } + + // The recoded buffer is the same? + for (let i = 0; i < decoded.length; ++i) { + assert.strictEqual(datum[i], decoded[i]); + } + } +} + +// https://github.com/nodejs/node/issues/1024 +{ + const a = 'x'.repeat(1 << 20 - 1); + const b = Buffer.from(a, 'ucs2').toString('ucs2'); + const c = Buffer.from(b, 'utf8').toString('utf8'); + + assert.strictEqual(a.length, b.length); + assert.strictEqual(b.length, c.length); + + assert.strictEqual(a, b); + assert.strictEqual(b, c); +} diff --git a/tests/node_compat/test/parallel/test-sync-fileread.js b/tests/node_compat/test/parallel/test-sync-fileread.js new file mode 100644 index 0000000000..5d76339867 --- /dev/null +++ b/tests/node_compat/test/parallel/test-sync-fileread.js @@ -0,0 +1,14 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const fixtures = require('../common/fixtures'); + +assert.strictEqual(fs.readFileSync(fixtures.path('x.txt')).toString(), 'xyz\n'); diff --git a/tests/node_compat/test/parallel/test-sys.js b/tests/node_compat/test/parallel/test-sys.js new file mode 100644 index 0000000000..284d622ba4 --- /dev/null +++ b/tests/node_compat/test/parallel/test-sys.js @@ -0,0 +1,35 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const sys = require('sys'); // eslint-disable-line no-restricted-modules +const util = require('util'); + +assert.strictEqual(sys, util); diff --git a/tests/node_compat/test/parallel/test-tick-processor-arguments.js b/tests/node_compat/test/parallel/test-tick-processor-arguments.js new file mode 100644 index 0000000000..3ece0fe78d --- /dev/null +++ b/tests/node_compat/test/parallel/test-tick-processor-arguments.js @@ -0,0 +1,39 @@ +// 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. + +'use strict'; +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const fs = require('fs'); +const assert = require('assert'); +const { spawnSync } = require('child_process'); + +if (!common.enoughTestMem) + common.skip('skipped due to memory requirements'); +if (common.isAIX) + common.skip('does not work on AIX'); + +tmpdir.refresh(); + +// Generate log file. +spawnSync(process.execPath, [ '--prof', '-p', '42' ], { cwd: tmpdir.path }); + +const files = fs.readdirSync(tmpdir.path); +const logfile = files.filter((name) => /\.log$/.test(name))[0]; +assert(logfile); + +// Make sure that the --preprocess argument is passed through correctly, +// as an example flag listed in deps/v8/tools/tickprocessor.js. +// Any of the other flags there should work for this test too, if --preprocess +// is ever removed. +const { stdout } = spawnSync( + process.execPath, + [ '--prof-process', '--preprocess', logfile ], + { cwd: tmpdir.path, encoding: 'utf8', maxBuffer: Infinity }); + +// Make sure that the result is valid JSON. +JSON.parse(stdout); diff --git a/tests/node_compat/test/parallel/test-timers-clearImmediate-als.js b/tests/node_compat/test/parallel/test-timers-clearImmediate-als.js new file mode 100644 index 0000000000..b9a7d9a4d7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-clearImmediate-als.js @@ -0,0 +1,35 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { AsyncLocalStorage } = require('async_hooks'); + +// This is an asynclocalstorage variant of test-timers-clearImmediate.js +const asyncLocalStorage = new AsyncLocalStorage(); +const N = 3; + +function next() { + const fn = common.mustCall(onImmediate); + asyncLocalStorage.run(new Map(), common.mustCall(() => { + const immediate = setImmediate(fn); + const store = asyncLocalStorage.getStore(); + store.set('immediate', immediate); + })); +} + +function onImmediate() { + const store = asyncLocalStorage.getStore(); + const immediate = store.get('immediate'); + assert.strictEqual(immediate.constructor.name, 'Immediate'); + clearImmediate(immediate); +} + +for (let i = 0; i < N; i++) { + next(); +} diff --git a/tests/node_compat/test/parallel/test-timers-immediate-queue.js b/tests/node_compat/test/parallel/test-timers-immediate-queue.js new file mode 100644 index 0000000000..9a025624f3 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-immediate-queue.js @@ -0,0 +1,64 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +// setImmediate should run clear its queued cbs once per event loop turn +// but immediates queued while processing the current queue should happen +// on the next turn of the event loop. + +// hit should be the exact same size of QUEUE, if we're letting things +// recursively add to the immediate QUEUE hit will be > QUEUE + +let ticked = false; + +let hit = 0; +const QUEUE = 10; + +function run() { + if (hit === 0) { + setTimeout(() => { ticked = true; }, 1); + const now = Date.now(); + while (Date.now() - now < 2); + } + + if (ticked) return; + + hit += 1; + setImmediate(run); +} + +for (let i = 0; i < QUEUE; i++) + setImmediate(run); + +process.on('exit', function() { + console.log('hit', hit); + assert.strictEqual(hit, QUEUE); +}); diff --git a/tests/node_compat/test/parallel/test-timers-immediate.js b/tests/node_compat/test/parallel/test-timers-immediate.js new file mode 100644 index 0000000000..847901146c --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-immediate.js @@ -0,0 +1,50 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +let mainFinished = false; + +setImmediate(common.mustCall(function() { + assert.strictEqual(mainFinished, true); + clearImmediate(immediateB); +})); + +const immediateB = setImmediate(common.mustNotCall()); + +setImmediate(common.mustCall((...args) => { + assert.deepStrictEqual(args, [1, 2, 3]); +}), 1, 2, 3); + +setImmediate(common.mustCall((...args) => { + assert.deepStrictEqual(args, [1, 2, 3, 4, 5]); +}), 1, 2, 3, 4, 5); + +mainFinished = true; diff --git a/tests/node_compat/test/parallel/test-timers-refresh-in-callback.js b/tests/node_compat/test/parallel/test-timers-refresh-in-callback.js new file mode 100644 index 0000000000..8267eff10c --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-refresh-in-callback.js @@ -0,0 +1,21 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +// This test checks whether a refresh called inside the callback will keep +// the event loop alive to run the timer again. + +let didCall = false; +const timer = setTimeout(common.mustCall(() => { + if (!didCall) { + didCall = true; + timer.refresh(); + } +}, 2), 1); diff --git a/tests/node_compat/test/parallel/test-timers-setimmediate-infinite-loop.js b/tests/node_compat/test/parallel/test-timers-setimmediate-infinite-loop.js new file mode 100644 index 0000000000..bf269db64f --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-setimmediate-infinite-loop.js @@ -0,0 +1,26 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// This test ensures that if an Immediate callback clears subsequent +// immediates we don't get stuck in an infinite loop. +// +// If the process does get stuck, it will be timed out by the test +// runner. +// +// Ref: https://github.com/nodejs/node/issues/9756 + +setImmediate(common.mustCall(function() { + clearImmediate(i2); + clearImmediate(i3); +})); + +const i2 = setImmediate(common.mustNotCall()); + +const i3 = setImmediate(common.mustNotCall()); diff --git a/tests/node_compat/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js b/tests/node_compat/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js new file mode 100644 index 0000000000..80658b4d67 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js @@ -0,0 +1,50 @@ +// 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. + +'use strict'; + +// Regression test for https://github.com/nodejs/node-v0.x-archive/issues/8897. + +const common = require('../common'); +const net = require('net'); +const Countdown = require('../common/countdown'); + +const clients = []; + +const server = net.createServer(function onClient(client) { + clients.push(client); + + if (clients.length === 2) { + // Enroll two timers, and make the one supposed to fire first + // unenroll the other one supposed to fire later. This mutates + // the list of unref timers when traversing it, and exposes the + // original issue in joyent/node#8897. + clients[0].setTimeout(1, () => { + clients[1].setTimeout(0); + clients[0].end(); + clients[1].end(); + }); + + // Use a delay that is higher than the lowest timer resolution across all + // supported platforms, so that the two timers don't fire at the same time. + clients[1].setTimeout(50); + } +}); + +server.listen(0, common.mustCall(() => { + const countdown = new Countdown(2, () => server.close()); + + { + const client = net.connect({ port: server.address().port }); + client.on('end', () => countdown.dec()); + } + + { + const client = net.connect({ port: server.address().port }); + client.on('end', () => countdown.dec()); + } +})); diff --git a/tests/node_compat/test/parallel/test-timers-unref.js b/tests/node_compat/test/parallel/test-timers-unref.js new file mode 100644 index 0000000000..ca4145d3ef --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-unref.js @@ -0,0 +1,88 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +const common = require('../common'); + +const assert = require('assert'); + +let unref_interval = false; +let unref_timer = false; +let checks = 0; + +const LONG_TIME = 10 * 1000; +const SHORT_TIME = 100; + +const timer = setTimeout(() => {}, 10); +assert.strictEqual(timer.hasRef(), true); +// Should not throw. +timer.unref().ref().unref(); +assert.strictEqual(timer.hasRef(), false); + +setInterval(() => {}, 10).unref().ref().unref(); + +setInterval(common.mustNotCall('Interval should not fire'), LONG_TIME).unref(); +setTimeout(common.mustNotCall('Timer should not fire'), LONG_TIME).unref(); + +const interval = setInterval(common.mustCall(() => { + unref_interval = true; + clearInterval(interval); +}), SHORT_TIME); +interval.unref(); + +setTimeout(common.mustCall(() => { + unref_timer = true; +}), SHORT_TIME).unref(); + +const check_unref = setInterval(() => { + if (checks > 5 || (unref_interval && unref_timer)) + clearInterval(check_unref); + checks += 1; +}, 100); + +{ + const timeout = + setTimeout(common.mustCall(() => { + timeout.unref(); + }), SHORT_TIME); +} + +{ + // Should not timeout the test + const timeout = + setInterval(() => timeout.unref(), SHORT_TIME); +} + +// Should not assert on args.Holder()->InternalFieldCount() > 0. +// See https://github.com/nodejs/node-v0.x-archive/issues/4261. +{ + const t = setInterval(() => {}, 1); + process.nextTick(t.unref.bind({})); + process.nextTick(t.unref.bind(t)); +} diff --git a/tests/node_compat/test/parallel/test-timers-unrefd-interval-still-fires.js b/tests/node_compat/test/parallel/test-timers-unrefd-interval-still-fires.js new file mode 100644 index 0000000000..79b68e467d --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-unrefd-interval-still-fires.js @@ -0,0 +1,29 @@ +// 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. + +'use strict'; +// Regression test for https://github.com/nodejs/node-v0.x-archive/issues/8900. +const common = require('../common'); + +const TEST_DURATION = common.platformTimeout(1000); +let N = 3; + +const keepOpen = + setTimeout( + common.mustNotCall('Test timed out. keepOpen was not canceled.'), + TEST_DURATION); + +const timer = setInterval(common.mustCall(() => { + if (--N === 0) { + clearInterval(timer); + timer._onTimeout = + common.mustNotCall('Unrefd interval fired after being cleared'); + clearTimeout(keepOpen); + } +}, N), 1); + +timer.unref(); diff --git a/tests/node_compat/test/parallel/test-timers-unrefed-in-beforeexit.js b/tests/node_compat/test/parallel/test-timers-unrefed-in-beforeexit.js new file mode 100644 index 0000000000..c551d61373 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-unrefed-in-beforeexit.js @@ -0,0 +1,14 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +process.on('beforeExit', common.mustCall(() => { + setTimeout(common.mustNotCall(), 1).unref(); +})); diff --git a/tests/node_compat/test/parallel/test-timers-unrefed-in-callback.js b/tests/node_compat/test/parallel/test-timers-unrefed-in-callback.js new file mode 100644 index 0000000000..362af6516b --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers-unrefed-in-callback.js @@ -0,0 +1,63 @@ +// 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. + +'use strict'; +// Checks that setInterval timers keep running even when they're +// unrefed within their callback. + +const common = require('../common'); +const net = require('net'); + +let counter1 = 0; +let counter2 = 0; + +// Test1 checks that clearInterval works as expected for a timer +// unrefed within its callback: it removes the timer and its callback +// is not called anymore. Note that the only reason why this test is +// robust is that: +// 1. the repeated timer it creates has a delay of 1ms +// 2. when this test is completed, another test starts that creates a +// new repeated timer with the same delay (1ms) +// 3. because of the way timers are implemented in libuv, if two +// repeated timers A and B are created in that order with the same +// delay, it is guaranteed that the first occurrence of timer A +// will fire before the first occurrence of timer B +// 4. as a result, when the timer created by Test2 fired 11 times, if +// the timer created by Test1 hadn't been removed by clearInterval, +// it would have fired 11 more times, and the assertion in the +// process'exit event handler would fail. +function Test1() { + // Server only for maintaining event loop + const server = net.createServer().listen(0); + + const timer1 = setInterval(common.mustCall(() => { + timer1.unref(); + if (counter1++ === 3) { + clearInterval(timer1); + server.close(() => { + Test2(); + }); + } + }, 4), 1); +} + + +// Test2 checks setInterval continues even if it is unrefed within +// timer callback. counter2 continues to be incremented more than 11 +// until server close completed. +function Test2() { + // Server only for maintaining event loop + const server = net.createServer().listen(0); + + const timer2 = setInterval(() => { + timer2.unref(); + if (counter2++ === 3) + server.close(); + }, 1); +} + +Test1(); diff --git a/tests/node_compat/test/parallel/test-timers.js b/tests/node_compat/test/parallel/test-timers.js new file mode 100644 index 0000000000..a2f218df81 --- /dev/null +++ b/tests/node_compat/test/parallel/test-timers.js @@ -0,0 +1,88 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const inputs = [ + undefined, + null, + true, + false, + '', + [], + {}, + NaN, + +Infinity, + -Infinity, + (1.0 / 0.0), // sanity check + parseFloat('x'), // NaN + -10, + -1, + -0.5, + -0.1, + -0.0, + 0, + 0.0, + 0.1, + 0.5, + 1, + 1.0, + 2147483648, // Browser behavior: timeouts > 2^31-1 run on next tick + 12345678901234, // ditto +]; + +const timeouts = []; +const intervals = []; + +inputs.forEach((value, index) => { + setTimeout(() => { + timeouts[index] = true; + }, value); + + const handle = setInterval(() => { + clearInterval(handle); // Disarm timer or we'll never finish + intervals[index] = true; + }, value); +}); + +// All values in inputs array coerce to 1 ms. Therefore, they should all run +// before a timer set here for 2 ms. + +setTimeout(common.mustCall(() => { + // Assert that all other timers have run + inputs.forEach((value, index) => { + assert(timeouts[index]); + assert(intervals[index]); + }); +}), 2); + +// Test 10 ms timeout separately. +setTimeout(common.mustCall(), 10); +setInterval(common.mustCall(function() { clearInterval(this); }), 10); diff --git a/tests/node_compat/test/parallel/test-tls-alert-handling.js b/tests/node_compat/test/parallel/test-tls-alert-handling.js new file mode 100644 index 0000000000..d682d5bcbb --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-alert-handling.js @@ -0,0 +1,103 @@ +// 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. + +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.opensslCli) + common.skip('node compiled without OpenSSL CLI'); + +const assert = require('assert'); +const net = require('net'); +const tls = require('tls'); +const fixtures = require('../common/fixtures'); + +let clientClosed = false; +let errorReceived = false; +function canCloseServer() { + return clientClosed && errorReceived; +} + +function loadPEM(n) { + return fixtures.readKey(`${n}.pem`, 'utf-8'); +} + +const opts = { + key: loadPEM('agent2-key'), + cert: loadPEM('agent2-cert') +}; + +const max_iter = 20; +let iter = 0; + +const errorHandler = common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_SSL_WRONG_VERSION_NUMBER'); + assert.strictEqual(err.library, 'SSL routines'); + if (!common.hasOpenSSL3) assert.strictEqual(err.function, 'ssl3_get_record'); + assert.strictEqual(err.reason, 'wrong version number'); + errorReceived = true; + if (canCloseServer()) + server.close(); +}); +const server = tls.createServer(opts, common.mustCall(function(s) { + s.pipe(s); + s.on('error', errorHandler); +}, 2)); + +server.listen(0, common.mustCall(function() { + sendClient(); +})); + +server.on('tlsClientError', common.mustNotCall()); + +server.on('error', common.mustNotCall()); + +function sendClient() { + const client = tls.connect(server.address().port, { + rejectUnauthorized: false + }); + client.on('data', common.mustCall(function() { + if (iter++ === 2) sendBADTLSRecord(); + if (iter < max_iter) { + client.write('a'); + return; + } + client.end(); + }, max_iter)); + client.write('a', common.mustCall()); + client.on('error', common.mustNotCall()); + client.on('close', common.mustCall(function() { + clientClosed = true; + if (canCloseServer()) + server.close(); + })); +} + + +function sendBADTLSRecord() { + const BAD_RECORD = Buffer.from([0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); + const socket = net.connect(server.address().port); + const client = tls.connect({ + socket: socket, + rejectUnauthorized: false + }, common.mustCall(function() { + client.write('x'); + client.on('data', (data) => { + socket.end(BAD_RECORD); + }); + })); + client.on('error', common.mustCall((err) => { + assert.strictEqual(err.code, 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION'); + assert.strictEqual(err.library, 'SSL routines'); + if (!common.hasOpenSSL3) + assert.strictEqual(err.function, 'ssl3_read_bytes'); + assert.strictEqual(err.reason, 'tlsv1 alert protocol version'); + })); +} diff --git a/tests/node_compat/test/parallel/test-tls-alert.js b/tests/node_compat/test/parallel/test-tls-alert.js new file mode 100644 index 0000000000..b3e8a948ce --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-alert.js @@ -0,0 +1,60 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.opensslCli) + common.skip('node compiled without OpenSSL CLI.'); + +const assert = require('assert'); +const { execFile } = require('child_process'); +const tls = require('tls'); +const fixtures = require('../common/fixtures'); + +function loadPEM(n) { + return fixtures.readKey(`${n}.pem`); +} + +const server = tls.Server({ + secureProtocol: 'TLSv1_2_server_method', + key: loadPEM('agent2-key'), + cert: loadPEM('agent2-cert') +}, null).listen(0, common.mustCall(() => { + const args = ['s_client', '-quiet', '-tls1_1', + '-cipher', (common.hasOpenSSL31 ? 'DEFAULT:@SECLEVEL=0' : 'DEFAULT'), + '-connect', `127.0.0.1:${server.address().port}`]; + + execFile(common.opensslCli, args, common.mustCall((err, _, stderr) => { + assert.strictEqual(err.code, 1); + assert.match(stderr, /SSL alert number 70/); + server.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-tls-client-renegotiation-limit.js b/tests/node_compat/test/parallel/test-tls-client-renegotiation-limit.js new file mode 100644 index 0000000000..9f50d82dde --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-client-renegotiation-limit.js @@ -0,0 +1,108 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.opensslCli) + common.skip('node compiled without OpenSSL CLI.'); + +const assert = require('assert'); +const tls = require('tls'); +const fixtures = require('../common/fixtures'); + +// Renegotiation as a protocol feature was dropped after TLS1.2. +tls.DEFAULT_MAX_VERSION = 'TLSv1.2'; + +// Renegotiation limits to test +const LIMITS = [0, 1, 2, 3, 5, 10, 16]; + +{ + let n = 0; + function next() { + if (n >= LIMITS.length) return; + tls.CLIENT_RENEG_LIMIT = LIMITS[n++]; + test(next); + } + next(); +} + +function test(next) { + const options = { + cert: fixtures.readKey('rsa_cert.crt'), + key: fixtures.readKey('rsa_private.pem'), + }; + + const server = tls.createServer(options, (conn) => { + conn.on('error', (err) => { + console.error(`Caught exception: ${err}`); + assert.match(err.message, /TLS session renegotiation attack/); + conn.destroy(); + }); + conn.pipe(conn); + }); + + server.listen(0, () => { + const options = { + host: server.address().host, + port: server.address().port, + rejectUnauthorized: false, + }; + const client = tls.connect(options, spam); + + let renegs = 0; + + client.on('close', () => { + assert.strictEqual(renegs, tls.CLIENT_RENEG_LIMIT + 1); + server.close(); + process.nextTick(next); + }); + + client.on('error', (err) => { + console.log('CLIENT ERR', err); + throw err; + }); + + client.on('close', (hadErr) => { + assert.strictEqual(hadErr, false); + }); + + // Simulate renegotiation attack + function spam() { + client.write(''); + client.renegotiate({}, (err) => { + assert.ifError(err); + assert.ok(renegs <= tls.CLIENT_RENEG_LIMIT); + spam(); + }); + renegs++; + } + }); +} diff --git a/tests/node_compat/test/parallel/test-tls-dhe.js b/tests/node_compat/test/parallel/test-tls-dhe.js new file mode 100644 index 0000000000..ea3503f0f6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-dhe.js @@ -0,0 +1,119 @@ +// 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: --no-warnings +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.opensslCli) + common.skip('missing openssl-cli'); + +const assert = require('assert'); +const { X509Certificate } = require('crypto'); +const { once } = require('events'); +const tls = require('tls'); +const { execFile } = require('child_process'); +const fixtures = require('../common/fixtures'); + +const key = fixtures.readKey('agent2-key.pem'); +const cert = fixtures.readKey('agent2-cert.pem'); + +// Prefer DHE over ECDHE when possible. +const dheCipher = 'DHE-RSA-AES128-SHA256'; +const ecdheCipher = 'ECDHE-RSA-AES128-SHA256'; +const ciphers = `${dheCipher}:${ecdheCipher}`; + +// Test will emit a warning because the DH parameter size is < 2048 bits +common.expectWarning('SecurityWarning', + 'DH parameter is less than 2048 bits'); + +function loadDHParam(n) { + const keyname = `dh${n}.pem`; + return fixtures.readKey(keyname); +} + +function test(dhparam, keylen, expectedCipher) { + const options = { + key, + cert, + ciphers, + dhparam, + maxVersion: 'TLSv1.2', + }; + + const server = tls.createServer(options, (conn) => conn.end()); + + server.listen(0, '127.0.0.1', common.mustCall(() => { + const args = ['s_client', '-connect', `127.0.0.1:${server.address().port}`, + '-cipher', `${ciphers}:@SECLEVEL=1`]; + + execFile(common.opensslCli, args, common.mustSucceed((stdout) => { + assert(keylen === null || + stdout.includes(`Server Temp Key: DH, ${keylen} bits`)); + assert(stdout.includes(`Cipher : ${expectedCipher}`)); + server.close(); + })); + })); + + return once(server, 'close'); +} + +function testCustomParam(keylen, expectedCipher) { + const dhparam = loadDHParam(keylen); + if (keylen === 'error') keylen = null; + return test(dhparam, keylen, expectedCipher); +} + +(async () => { + // By default, DHE is disabled while ECDHE is enabled. + for (const dhparam of [undefined, null]) { + await test(dhparam, null, ecdheCipher); + } + + // The DHE parameters selected by OpenSSL depend on the strength of the + // certificate's key. For this test, we can assume that the modulus length + // of the certificate's key is equal to the size of the DHE parameter, but + // that is really only true for a few modulus lengths. + const { + publicKey: { asymmetricKeyDetails: { modulusLength } } + } = new X509Certificate(cert); + await test('auto', modulusLength, dheCipher); + + assert.throws(() => { + testCustomParam(512); + }, /DH parameter is less than 1024 bits/); + + // Custom DHE parameters are supported (but discouraged). + await testCustomParam(1024, dheCipher); + await testCustomParam(2048, dheCipher); + + // Invalid DHE parameters are discarded. ECDHE remains enabled. + await testCustomParam('error', ecdheCipher); +})().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-tls-ecdh-auto.js b/tests/node_compat/test/parallel/test-tls-ecdh-auto.js new file mode 100644 index 0000000000..c06dbe1b8a --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-ecdh-auto.js @@ -0,0 +1,50 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// This test ensures that the value "auto" on ecdhCurve option is +// supported to enable automatic curve selection in TLS server. + +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.opensslCli) + common.skip('missing openssl-cli'); + +const assert = require('assert'); +const tls = require('tls'); +const { execFile } = require('child_process'); +const fixtures = require('../common/fixtures'); + +function loadPEM(n) { + return fixtures.readKey(`${n}.pem`); +} + +const options = { + key: loadPEM('agent2-key'), + cert: loadPEM('agent2-cert'), + ciphers: '-ALL:ECDHE-RSA-AES128-SHA256', + ecdhCurve: 'auto', + maxVersion: 'TLSv1.2', +}; + +const reply = 'I AM THE WALRUS'; // Something recognizable + +const server = tls.createServer(options, (conn) => { + conn.end(reply); +}).listen(0, common.mustCall(() => { + const args = ['s_client', + '-cipher', `${options.ciphers}`, + '-connect', `127.0.0.1:${server.address().port}`]; + + execFile(common.opensslCli, args, common.mustSucceed((stdout) => { + assert(stdout.includes(reply)); + server.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-tls-ecdh-multiple.js b/tests/node_compat/test/parallel/test-tls-ecdh-multiple.js new file mode 100644 index 0000000000..04163acced --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-ecdh-multiple.js @@ -0,0 +1,68 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// This test ensures that ecdhCurve option of TLS server supports colon +// separated ECDH curve names as value. + +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.opensslCli) + common.skip('missing openssl-cli'); + +const assert = require('assert'); +const tls = require('tls'); +const { execFile } = require('child_process'); +const fixtures = require('../common/fixtures'); + +function loadPEM(n) { + return fixtures.readKey(`${n}.pem`); +} + +const options = { + key: loadPEM('agent2-key'), + cert: loadPEM('agent2-cert'), + ciphers: '-ALL:ECDHE-RSA-AES128-SHA256', + ecdhCurve: 'secp256k1:prime256v1:secp521r1', + maxVersion: 'TLSv1.2', +}; + +const reply = 'I AM THE WALRUS'; // Something recognizable + +const server = tls.createServer(options, (conn) => { + conn.end(reply); +}).listen(0, common.mustCall(() => { + const args = ['s_client', + '-cipher', `${options.ciphers}`, + '-connect', `127.0.0.1:${server.address().port}`]; + + execFile(common.opensslCli, args, common.mustSucceed((stdout) => { + assert(stdout.includes(reply)); + server.close(); + })); +})); + +{ + // Some unsupported curves. + const unsupportedCurves = [ + 'wap-wsg-idm-ecid-wtls1', + 'c2pnb163v1', + 'prime192v3', + ]; + + // Brainpool is not supported in FIPS mode. + if (common.hasFipsCrypto) + unsupportedCurves.push('brainpoolP256r1'); + + unsupportedCurves.forEach((ecdhCurve) => { + assert.throws(() => tls.createServer({ ecdhCurve }), + /Error: Failed to set ECDH curve/); + }); +} diff --git a/tests/node_compat/test/parallel/test-tls-ecdh.js b/tests/node_compat/test/parallel/test-tls-ecdh.js new file mode 100644 index 0000000000..169e629f8a --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-ecdh.js @@ -0,0 +1,66 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.opensslCli) + common.skip('missing openssl-cli'); + +const assert = require('assert'); +const tls = require('tls'); + +const exec = require('child_process').exec; + +const options = { + key: fixtures.readKey('agent2-key.pem'), + cert: fixtures.readKey('agent2-cert.pem'), + ciphers: '-ALL:ECDHE-RSA-AES128-SHA256', + ecdhCurve: 'prime256v1', + maxVersion: 'TLSv1.2' +}; + +const reply = 'I AM THE WALRUS'; // Something recognizable + +const server = tls.createServer(options, common.mustCall(function(conn) { + conn.end(reply); +})); + +server.listen(0, '127.0.0.1', common.mustCall(function() { + const cmd = `"${common.opensslCli}" s_client -cipher ${ + options.ciphers} -connect 127.0.0.1:${this.address().port}`; + + exec(cmd, common.mustSucceed((stdout, stderr) => { + assert(stdout.includes(reply)); + server.close(); + })); +})); diff --git a/tests/node_compat/test/parallel/test-tls-enable-trace-cli.js b/tests/node_compat/test/parallel/test-tls-enable-trace-cli.js new file mode 100644 index 0000000000..ba049f611f --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-enable-trace-cli.js @@ -0,0 +1,75 @@ +// 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.hasCrypto) common.skip('missing crypto'); +const fixtures = require('../common/fixtures'); + +// Test --trace-tls CLI flag. + +const assert = require('assert'); +const { fork } = require('child_process'); + +if (process.argv[2] === 'test') + return test(); + +const binding = require('internal/test/binding').internalBinding; + +if (!binding('tls_wrap').HAVE_SSL_TRACE) + return common.skip('no SSL_trace() compiled into openssl'); + +const child = fork(__filename, ['test'], { + silent: true, + execArgv: ['--trace-tls'] +}); + +let stdout = ''; +let stderr = ''; +child.stdout.setEncoding('utf8'); +child.stderr.setEncoding('utf8'); +child.stdout.on('data', (data) => stdout += data); +child.stderr.on('data', (data) => stderr += data); +child.on('close', common.mustCall((code, signal) => { + // For debugging and observation of actual trace output. + console.log(stderr); + + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + assert.strictEqual(stdout.trim(), ''); + assert.match(stderr, /Warning: Enabling --trace-tls can expose sensitive/); + assert.match(stderr, /Sent Record/); +})); + +function test() { + const { + connect, keys + } = require(fixtures.path('tls-connect')); + + connect({ + client: { + checkServerIdentity: (servername, cert) => { }, + ca: `${keys.agent1.cert}\n${keys.agent6.ca}`, + }, + server: { + cert: keys.agent6.cert, + key: keys.agent6.key + }, + }, common.mustCall((err, pair, cleanup) => { + if (pair.server.err) { + console.trace('server', pair.server.err); + } + if (pair.client.err) { + console.trace('client', pair.client.err); + } + assert.ifError(pair.server.err); + assert.ifError(pair.client.err); + + return cleanup(); + })); +} diff --git a/tests/node_compat/test/parallel/test-tls-enable-trace.js b/tests/node_compat/test/parallel/test-tls-enable-trace.js new file mode 100644 index 0000000000..30be82b47e --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-enable-trace.js @@ -0,0 +1,65 @@ +// 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.hasCrypto) common.skip('missing crypto'); +const fixtures = require('../common/fixtures'); + +// Test enableTrace: option for TLS. + +const assert = require('assert'); +const { fork } = require('child_process'); + +if (process.argv[2] === 'test') + return test(); + +const binding = require('internal/test/binding').internalBinding; + +if (!binding('tls_wrap').HAVE_SSL_TRACE) + return common.skip('no SSL_trace() compiled into openssl'); + +const child = fork(__filename, ['test'], { silent: true }); + +let stderr = ''; +child.stderr.setEncoding('utf8'); +child.stderr.on('data', (data) => stderr += data); +child.on('close', common.mustCall(() => { + assert.match(stderr, /Received Record/); + assert.match(stderr, /ClientHello/); +})); + +// For debugging and observation of actual trace output. +child.stderr.pipe(process.stderr); +child.stdout.pipe(process.stdout); + +child.on('exit', common.mustCall((code) => { + assert.strictEqual(code, 0); +})); + +function test() { + const { + connect, keys + } = require(fixtures.path('tls-connect')); + + connect({ + client: { + checkServerIdentity: (servername, cert) => { }, + ca: `${keys.agent1.cert}\n${keys.agent6.ca}`, + }, + server: { + cert: keys.agent6.cert, + key: keys.agent6.key, + enableTrace: true, + }, + }, common.mustCall((err, pair, cleanup) => { + pair.client.conn.enableTrace(); + + return cleanup(); + })); +} diff --git a/tests/node_compat/test/parallel/test-tls-env-extra-ca-no-crypto.js b/tests/node_compat/test/parallel/test-tls-env-extra-ca-no-crypto.js new file mode 100644 index 0000000000..7ed55855b5 --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-env-extra-ca-no-crypto.js @@ -0,0 +1,29 @@ +// 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. + +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const { fork } = require('child_process'); + +// This test ensures that trying to load extra certs won't throw even when +// there is no crypto support, i.e., built with "./configure --without-ssl". +if (process.argv[2] === 'child') { + // exit +} else { + const NODE_EXTRA_CA_CERTS = fixtures.path('keys', 'ca1-cert.pem'); + + fork( + __filename, + ['child'], + { env: { ...process.env, NODE_EXTRA_CA_CERTS } }, + ).on('exit', common.mustCall(function(status) { + // Client did not succeed in connecting + assert.strictEqual(status, 0); + })); +} diff --git a/tests/node_compat/test/parallel/test-tls-ocsp-callback.js b/tests/node_compat/test/parallel/test-tls-ocsp-callback.js new file mode 100644 index 0000000000..ca89ef3838 --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-ocsp-callback.js @@ -0,0 +1,120 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +if (!common.opensslCli) + common.skip('node compiled without OpenSSL CLI.'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +const tls = require('tls'); +const fixtures = require('../common/fixtures'); + +const assert = require('assert'); + +const SSL_OP_NO_TICKET = require('crypto').constants.SSL_OP_NO_TICKET; + +const pfx = fixtures.readKey('agent1.pfx'); +const key = fixtures.readKey('agent1-key.pem'); +const cert = fixtures.readKey('agent1-cert.pem'); +const ca = fixtures.readKey('ca1-cert.pem'); + +function test(testOptions, cb) { + const options = { + key, + cert, + ca: [ca] + }; + const requestCount = testOptions.response ? 0 : 1; + + if (!testOptions.ocsp) + assert.strictEqual(testOptions.response, undefined); + + if (testOptions.pfx) { + delete options.key; + delete options.cert; + options.pfx = testOptions.pfx; + options.passphrase = testOptions.passphrase; + } + + const server = tls.createServer(options, common.mustCall((cleartext) => { + cleartext.on('error', function(er) { + // We're ok with getting ECONNRESET in this test, but it's + // timing-dependent, and thus unreliable. Any other errors + // are just failures, though. + if (er.code !== 'ECONNRESET') + throw er; + }); + cleartext.end(); + }, requestCount)); + + if (!testOptions.ocsp) + server.on('OCSPRequest', common.mustNotCall()); + else + server.on('OCSPRequest', common.mustCall((cert, issuer, callback) => { + assert.ok(Buffer.isBuffer(cert)); + assert.ok(Buffer.isBuffer(issuer)); + + // Callback a little later to ensure that async really works. + return setTimeout(callback, 100, null, testOptions.response ? + Buffer.from(testOptions.response) : null); + })); + + server.listen(0, function() { + const client = tls.connect({ + port: this.address().port, + requestOCSP: testOptions.ocsp, + secureOptions: testOptions.ocsp ? 0 : SSL_OP_NO_TICKET, + rejectUnauthorized: false + }, common.mustCall(requestCount)); + + client.on('OCSPResponse', common.mustCall((resp) => { + if (testOptions.response) { + assert.strictEqual(resp.toString(), testOptions.response); + client.destroy(); + } else { + assert.strictEqual(resp, null); + } + }, testOptions.ocsp === false ? 0 : 1)); + + client.on('close', common.mustCall(() => { + server.close(cb); + })); + }); +} + +test({ ocsp: true, response: false }); +test({ ocsp: true, response: 'hello world' }); +test({ ocsp: false }); + +if (!common.hasFipsCrypto) { + test({ ocsp: true, response: 'hello pfx', pfx: pfx, passphrase: 'sample' }); +} diff --git a/tests/node_compat/test/parallel/test-tls-psk-server.js b/tests/node_compat/test/parallel/test-tls-psk-server.js new file mode 100644 index 0000000000..2263fb901d --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-psk-server.js @@ -0,0 +1,84 @@ +// 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. + +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); +if (!common.opensslCli) + common.skip('missing openssl cli'); + +const assert = require('assert'); + +const tls = require('tls'); +const spawn = require('child_process').spawn; + +const CIPHERS = 'PSK+HIGH'; +const KEY = 'd731ef57be09e5204f0b205b60627028'; +const IDENTITY = 'TestUser'; + +const server = tls.createServer({ + ciphers: CIPHERS, + pskIdentityHint: IDENTITY, + pskCallback(socket, identity) { + assert.ok(socket instanceof tls.TLSSocket); + assert.ok(typeof identity === 'string'); + if (identity === IDENTITY) + return Buffer.from(KEY, 'hex'); + } +}); + +server.on('connection', common.mustCall()); + +server.on('secureConnection', (socket) => { + socket.write('hello\r\n'); + + socket.on('data', (data) => { + socket.write(data); + }); +}); + +let gotHello = false; +let sentWorld = false; +let gotWorld = false; + +server.listen(0, () => { + const client = spawn(common.opensslCli, [ + 's_client', + '-connect', `127.0.0.1:${server.address().port}`, + '-cipher', CIPHERS, + '-psk', KEY, + '-psk_identity', IDENTITY, + ]); + + let out = ''; + + client.stdout.setEncoding('utf8'); + client.stdout.on('data', (d) => { + out += d; + + if (!gotHello && /hello/.test(out)) { + gotHello = true; + client.stdin.write('world\r\n'); + sentWorld = true; + } + + if (!gotWorld && /world/.test(out)) { + gotWorld = true; + client.stdin.end(); + } + }); + + client.on('exit', common.mustCall((code) => { + assert.ok(gotHello); + assert.ok(sentWorld); + assert.ok(gotWorld); + assert.strictEqual(code, 0); + server.close(); + })); +}); diff --git a/tests/node_compat/test/parallel/test-tls-securepair-server.js b/tests/node_compat/test/parallel/test-tls-securepair-server.js new file mode 100644 index 0000000000..67c727f880 --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-securepair-server.js @@ -0,0 +1,152 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.opensslCli) + common.skip('missing openssl-cli'); + +const assert = require('assert'); +const tls = require('tls'); +const net = require('net'); +const spawn = require('child_process').spawn; +const fixtures = require('../common/fixtures'); + +const key = fixtures.readKey('rsa_private.pem'); +const cert = fixtures.readKey('rsa_cert.crt'); + +function log(a) { + console.error('***server***', a); +} + +const server = net.createServer(common.mustCall(function(socket) { + log(`connection fd=${socket.fd}`); + const sslcontext = tls.createSecureContext({ key, cert }); + sslcontext.context.setCiphers('RC4-SHA:AES128-SHA:AES256-SHA'); + + const pair = tls.createSecurePair(sslcontext, true); + + assert.ok(pair.encrypted.writable); + assert.ok(pair.cleartext.writable); + + pair.encrypted.pipe(socket); + socket.pipe(pair.encrypted); + + log('i set it secure'); + + pair.on('secure', function() { + log('connected+secure!'); + pair.cleartext.write('hello\r\n'); + log(pair.cleartext.getPeerCertificate()); + log(pair.cleartext.getCipher()); + }); + + pair.cleartext.on('data', function(data) { + log(`read bytes ${data.length}`); + pair.cleartext.write(data); + }); + + socket.on('end', function() { + log('socket end'); + }); + + pair.cleartext.on('error', function(err) { + log('got error: '); + log(err); + socket.destroy(); + }); + + pair.encrypted.on('error', function(err) { + log('encrypted error: '); + log(err); + socket.destroy(); + }); + + socket.on('error', function(err) { + log('socket error: '); + log(err); + socket.destroy(); + }); + + socket.on('close', function(err) { + log('socket closed'); + }); + + pair.on('error', function(err) { + log('secure error: '); + log(err); + socket.destroy(); + }); +})); + +let gotHello = false; +let sentWorld = false; +let gotWorld = false; + +server.listen(0, common.mustCall(function() { + // To test use: openssl s_client -connect localhost:8000 + + const args = ['s_client', '-connect', `127.0.0.1:${this.address().port}`]; + + const client = spawn(common.opensslCli, args); + + + let out = ''; + + client.stdout.setEncoding('utf8'); + client.stdout.on('data', function(d) { + out += d; + + if (!gotHello && /hello/.test(out)) { + gotHello = true; + client.stdin.write('world\r\n'); + sentWorld = true; + } + + if (!gotWorld && /world/.test(out)) { + gotWorld = true; + client.stdin.end(); + } + }); + + client.stdout.pipe(process.stdout, { end: false }); + + client.on('exit', common.mustCall(function(code) { + assert.strictEqual(code, 0); + server.close(); + })); +})); + +process.on('exit', function() { + assert.ok(gotHello); + assert.ok(sentWorld); + assert.ok(gotWorld); +}); diff --git a/tests/node_compat/test/parallel/test-tls-server-verify.js b/tests/node_compat/test/parallel/test-tls-server-verify.js new file mode 100644 index 0000000000..e4fe6ef4c0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-server-verify.js @@ -0,0 +1,355 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.opensslCli) + common.skip('node compiled without OpenSSL CLI.'); + +// This is a rather complex test which sets up various TLS servers with node +// and connects to them using the 'openssl s_client' command line utility +// with various keys. Depending on the certificate authority and other +// parameters given to the server, the various clients are +// - rejected, +// - accepted and "unauthorized", or +// - accepted and "authorized". + +const assert = require('assert'); +const { spawn } = require('child_process'); +const { SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION } = + require('crypto').constants; +const tls = require('tls'); +const fixtures = require('../common/fixtures'); + +const testCases = + [{ title: 'Do not request certs. Everyone is unauthorized.', + requestCert: false, + rejectUnauthorized: false, + renegotiate: false, + CAs: ['ca1-cert'], + clients: + [{ name: 'agent1', shouldReject: false, shouldAuth: false }, + { name: 'agent2', shouldReject: false, shouldAuth: false }, + { name: 'agent3', shouldReject: false, shouldAuth: false }, + { name: 'nocert', shouldReject: false, shouldAuth: false }, + ] }, + + { title: 'Allow both authed and unauthed connections with CA1', + requestCert: true, + rejectUnauthorized: false, + renegotiate: false, + CAs: ['ca1-cert'], + clients: + [{ name: 'agent1', shouldReject: false, shouldAuth: true }, + { name: 'agent2', shouldReject: false, shouldAuth: false }, + { name: 'agent3', shouldReject: false, shouldAuth: false }, + { name: 'nocert', shouldReject: false, shouldAuth: false }, + ] }, + + { title: 'Do not request certs at connection. Do that later', + requestCert: false, + rejectUnauthorized: false, + renegotiate: true, + CAs: ['ca1-cert'], + clients: + [{ name: 'agent1', shouldReject: false, shouldAuth: true }, + { name: 'agent2', shouldReject: false, shouldAuth: false }, + { name: 'agent3', shouldReject: false, shouldAuth: false }, + { name: 'nocert', shouldReject: false, shouldAuth: false }, + ] }, + + { title: 'Allow only authed connections with CA1', + requestCert: true, + rejectUnauthorized: true, + renegotiate: false, + CAs: ['ca1-cert'], + clients: + [{ name: 'agent1', shouldReject: false, shouldAuth: true }, + { name: 'agent2', shouldReject: true }, + { name: 'agent3', shouldReject: true }, + { name: 'nocert', shouldReject: true }, + ] }, + + { title: 'Allow only authed connections with CA1 and CA2', + requestCert: true, + rejectUnauthorized: true, + renegotiate: false, + CAs: ['ca1-cert', 'ca2-cert'], + clients: + [{ name: 'agent1', shouldReject: false, shouldAuth: true }, + { name: 'agent2', shouldReject: true }, + { name: 'agent3', shouldReject: false, shouldAuth: true }, + { name: 'nocert', shouldReject: true }, + ] }, + + + { title: 'Allow only certs signed by CA2 but not in the CRL', + requestCert: true, + rejectUnauthorized: true, + renegotiate: false, + CAs: ['ca2-cert'], + crl: 'ca2-crl', + clients: [ + { name: 'agent1', shouldReject: true, shouldAuth: false }, + { name: 'agent2', shouldReject: true, shouldAuth: false }, + { name: 'agent3', shouldReject: false, shouldAuth: true }, + // Agent4 has a cert in the CRL. + { name: 'agent4', shouldReject: true, shouldAuth: false }, + { name: 'nocert', shouldReject: true }, + ] }, + ]; + +function filenamePEM(n) { + return fixtures.path('keys', `${n}.pem`); +} + +function loadPEM(n) { + return fixtures.readKey(`${n}.pem`); +} + + +const serverKey = loadPEM('agent2-key'); +const serverCert = loadPEM('agent2-cert'); + + +function runClient(prefix, port, options, cb) { + + // Client can connect in three ways: + // - Self-signed cert + // - Certificate, but not signed by CA. + // - Certificate signed by CA. + + const args = ['s_client', '-connect', `127.0.0.1:${port}`]; + + console.log(`${prefix} connecting with`, options.name); + + switch (options.name) { + case 'agent1': + // Signed by CA1 + args.push('-key'); + args.push(filenamePEM('agent1-key')); + args.push('-cert'); + args.push(filenamePEM('agent1-cert')); + break; + + case 'agent2': + // Self-signed + // This is also the key-cert pair that the server will use. + args.push('-key'); + args.push(filenamePEM('agent2-key')); + args.push('-cert'); + args.push(filenamePEM('agent2-cert')); + break; + + case 'agent3': + // Signed by CA2 + args.push('-key'); + args.push(filenamePEM('agent3-key')); + args.push('-cert'); + args.push(filenamePEM('agent3-cert')); + break; + + case 'agent4': + // Signed by CA2 (rejected by ca2-crl) + args.push('-key'); + args.push(filenamePEM('agent4-key')); + args.push('-cert'); + args.push(filenamePEM('agent4-cert')); + break; + + case 'nocert': + // Do not send certificate + break; + + default: + throw new Error(`${prefix}Unknown agent name`); + } + + // To test use: openssl s_client -connect localhost:8000 + const client = spawn(common.opensslCli, args); + + let out = ''; + + let rejected = true; + let authed = false; + let goodbye = false; + + client.stdout.setEncoding('utf8'); + client.stdout.on('data', function(d) { + out += d; + + if (!goodbye && /_unauthed/.test(out)) { + console.error(`${prefix} * unauthed`); + goodbye = true; + client.kill(); + authed = false; + rejected = false; + } + + if (!goodbye && /_authed/.test(out)) { + console.error(`${prefix} * authed`); + goodbye = true; + client.kill(); + authed = true; + rejected = false; + } + }); + + client.on('exit', function(code) { + if (options.shouldReject) { + assert.strictEqual( + rejected, true, + `${prefix}${options.name} NOT rejected, but should have been`); + } else { + assert.strictEqual( + rejected, false, + `${prefix}${options.name} rejected, but should NOT have been`); + assert.strictEqual( + authed, options.shouldAuth, + `${prefix}${options.name} authed is ${authed} but should have been ${ + options.shouldAuth}`); + } + + cb(); + }); +} + + +// Run the tests +let successfulTests = 0; +function runTest(port, testIndex) { + const prefix = `${testIndex} `; + const tcase = testCases[testIndex]; + if (!tcase) return; + + console.error(`${prefix}Running '${tcase.title}'`); + + const cas = tcase.CAs.map(loadPEM); + + const crl = tcase.crl ? loadPEM(tcase.crl) : null; + + const serverOptions = { + key: serverKey, + cert: serverCert, + ca: cas, + crl: crl, + requestCert: tcase.requestCert, + rejectUnauthorized: tcase.rejectUnauthorized + }; + + // If renegotiating - session might be resumed and openssl won't request + // client's certificate (probably because of bug in the openssl) + if (tcase.renegotiate) { + serverOptions.secureOptions = + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION; + // Renegotiation as a protocol feature was dropped after TLS1.2. + serverOptions.maxVersion = 'TLSv1.2'; + } + + let renegotiated = false; + const server = tls.Server(serverOptions, function handleConnection(c) { + c.on('error', function(e) { + // child.kill() leads ECONNRESET error in the TLS connection of + // openssl s_client via spawn(). A test result is already + // checked by the data of client.stdout before child.kill() so + // these tls errors can be ignored. + }); + if (tcase.renegotiate && !renegotiated) { + renegotiated = true; + setTimeout(function() { + console.error(`${prefix}- connected, renegotiating`); + c.write('\n_renegotiating\n'); + return c.renegotiate({ + requestCert: true, + rejectUnauthorized: false + }, function(err) { + assert.ifError(err); + c.write('\n_renegotiated\n'); + handleConnection(c); + }); + }, 200); + return; + } + + if (c.authorized) { + console.error(`${prefix}- authed connection: ${ + c.getPeerCertificate().subject.CN}`); + c.write('\n_authed\n'); + } else { + console.error(`${prefix}- unauthed connection: %s`, c.authorizationError); + c.write('\n_unauthed\n'); + } + }); + + function runNextClient(clientIndex) { + const options = tcase.clients[clientIndex]; + if (options) { + runClient(`${prefix}${clientIndex} `, port, options, function() { + runNextClient(clientIndex + 1); + }); + } else { + server.close(); + successfulTests++; + runTest(0, nextTest++); + } + } + + server.listen(port, function() { + port = server.address().port; + if (tcase.debug) { + console.error(`${prefix}TLS server running on port ${port}`); + } else if (tcase.renegotiate) { + runNextClient(0); + } else { + let clientsCompleted = 0; + for (let i = 0; i < tcase.clients.length; i++) { + runClient(`${prefix}${i} `, port, tcase.clients[i], function() { + clientsCompleted++; + if (clientsCompleted === tcase.clients.length) { + server.close(); + successfulTests++; + runTest(0, nextTest++); + } + }); + } + } + }); +} + + +let nextTest = 0; +runTest(0, nextTest++); + + +process.on('exit', function() { + assert.strictEqual(successfulTests, testCases.length); +}); diff --git a/tests/node_compat/test/parallel/test-tls-session-cache.js b/tests/node_compat/test/parallel/test-tls-session-cache.js new file mode 100644 index 0000000000..c1523d7617 --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-session-cache.js @@ -0,0 +1,171 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const tls = require('tls'); +const { spawn } = require('child_process'); + +if (!common.opensslCli) + common.skip('node compiled without OpenSSL CLI.'); + + +doTest({ tickets: false }, function() { + doTest({ tickets: true }, function() { + doTest({ tickets: false, invalidSession: true }, function() { + console.error('all done'); + }); + }); +}); + +function doTest(testOptions, callback) { + const key = fixtures.readKey('rsa_private.pem'); + const cert = fixtures.readKey('rsa_cert.crt'); + const options = { + key, + cert, + ca: [cert], + requestCert: true, + rejectUnauthorized: false, + secureProtocol: 'TLS_method', + ciphers: 'RSA@SECLEVEL=0' + }; + let requestCount = 0; + let resumeCount = 0; + let newSessionCount = 0; + let session; + + const server = tls.createServer(options, function(cleartext) { + cleartext.on('error', function(er) { + // We're ok with getting ECONNRESET in this test, but it's + // timing-dependent, and thus unreliable. Any other errors + // are just failures, though. + if (er.code !== 'ECONNRESET') + throw er; + }); + ++requestCount; + cleartext.end(''); + }); + server.on('newSession', function(id, data, cb) { + ++newSessionCount; + // Emulate asynchronous store + setImmediate(() => { + assert.ok(!session); + session = { id, data }; + cb(); + }); + }); + server.on('resumeSession', function(id, callback) { + ++resumeCount; + assert.ok(session); + assert.strictEqual(session.id.toString('hex'), id.toString('hex')); + + let data = session.data; + + // Return an invalid session to test Node does not crash. + if (testOptions.invalidSession) { + data = Buffer.from('INVALID SESSION'); + session = null; + } + + // Just to check that async really works there + setImmediate(() => { + callback(null, data); + }); + }); + + server.listen(0, function() { + const args = [ + 's_client', + '-tls1', + '-cipher', (common.hasOpenSSL31 ? 'DEFAULT:@SECLEVEL=0' : 'DEFAULT'), + '-connect', `localhost:${this.address().port}`, + '-servername', 'ohgod', + '-key', fixtures.path('keys/rsa_private.pem'), + '-cert', fixtures.path('keys/rsa_cert.crt'), + '-reconnect', + ].concat(testOptions.tickets ? [] : '-no_ticket'); + + function spawnClient() { + const client = spawn(common.opensslCli, args, { + stdio: [ 0, 1, 'pipe' ] + }); + let err = ''; + client.stderr.setEncoding('utf8'); + client.stderr.on('data', function(chunk) { + err += chunk; + }); + + client.on('exit', common.mustCall(function(code, signal) { + if (code !== 0) { + // If SmartOS and connection refused, then retry. See + // https://github.com/nodejs/node/issues/2663. + if (common.isSunOS && err.includes('Connection refused')) { + requestCount = 0; + spawnClient(); + return; + } + assert.fail(`code: ${code}, signal: ${signal}, output: ${err}`); + } + assert.strictEqual(code, 0); + server.close(common.mustCall(function() { + setImmediate(callback); + })); + })); + } + + spawnClient(); + }); + + process.on('exit', function() { + // Each test run connects 6 times: an initial request and 5 reconnect + // requests. + assert.strictEqual(requestCount, 6); + + if (testOptions.tickets) { + // No session cache callbacks are called. + assert.strictEqual(resumeCount, 0); + assert.strictEqual(newSessionCount, 0); + } else if (testOptions.invalidSession) { + // The resume callback was called, but each connection established a + // fresh session. + assert.strictEqual(resumeCount, 5); + assert.strictEqual(newSessionCount, 6); + } else { + // The resume callback was called, and only the initial connection + // establishes a fresh session. + assert.ok(session); + assert.strictEqual(resumeCount, 5); + assert.strictEqual(newSessionCount, 1); + } + }); +} diff --git a/tests/node_compat/test/parallel/test-tls-set-ciphers.js b/tests/node_compat/test/parallel/test-tls-set-ciphers.js new file mode 100644 index 0000000000..c7dddd9aa0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-set-ciphers.js @@ -0,0 +1,138 @@ +// 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. + +'use strict'; +const common = require('../common'); +if (!common.hasOpenSSL3) + common.skip('missing crypto, or OpenSSL version lower than 3'); + +const fixtures = require('../common/fixtures'); +const { inspect } = require('util'); + +// Test cipher: option for TLS. + +const { + assert, connect, keys +} = require(fixtures.path('tls-connect')); + + +function test(cciphers, sciphers, cipher, cerr, serr, options) { + assert(cipher || cerr || serr, 'test missing any expectations'); + const where = inspect(new Error()).split('\n')[2].replace(/[^(]*/, ''); + + const max_tls_ver = (ciphers, options) => { + if (options instanceof Object && Object.hasOwn(options, 'maxVersion')) + return options.maxVersion; + if ((typeof ciphers === 'string' || ciphers instanceof String) && ciphers.length > 0 && !ciphers.includes('TLS_')) + return 'TLSv1.2'; + + return 'TLSv1.3'; + }; + + connect({ + client: { + checkServerIdentity: (servername, cert) => { }, + ca: `${keys.agent1.cert}\n${keys.agent6.ca}`, + ciphers: cciphers, + maxVersion: max_tls_ver(cciphers, options), + }, + server: { + cert: keys.agent6.cert, + key: keys.agent6.key, + ciphers: sciphers, + maxVersion: max_tls_ver(sciphers, options), + }, + }, common.mustCall((err, pair, cleanup) => { + function u(_) { return _ === undefined ? 'U' : _; } + console.log('test:', u(cciphers), u(sciphers), + 'expect', u(cipher), u(cerr), u(serr)); + console.log(' ', where); + if (!cipher) { + console.log('client', pair.client.err ? pair.client.err.code : undefined); + console.log('server', pair.server.err ? pair.server.err.code : undefined); + if (cerr) { + assert(pair.client.err); + assert.strictEqual(pair.client.err.code, cerr); + } + if (serr) { + assert(pair.server.err); + assert.strictEqual(pair.server.err.code, serr); + } + return cleanup(); + } + + const reply = 'So long and thanks for all the fish.'; + + assert.ifError(err); + assert.ifError(pair.server.err); + assert.ifError(pair.client.err); + assert(pair.server.conn); + assert(pair.client.conn); + assert.strictEqual(pair.client.conn.getCipher().name, cipher); + assert.strictEqual(pair.server.conn.getCipher().name, cipher); + + pair.server.conn.write(reply); + + pair.client.conn.on('data', common.mustCall((data) => { + assert.strictEqual(data.toString(), reply); + return cleanup(); + })); + })); +} + +const U = undefined; + +// Have shared ciphers. +test(U, 'AES256-SHA', 'AES256-SHA'); +test('AES256-SHA', U, 'AES256-SHA'); + +test(U, 'TLS_AES_256_GCM_SHA384', 'TLS_AES_256_GCM_SHA384'); +test('TLS_AES_256_GCM_SHA384', U, 'TLS_AES_256_GCM_SHA384'); +test('TLS_AES_256_GCM_SHA384:!TLS_CHACHA20_POLY1305_SHA256', U, 'TLS_AES_256_GCM_SHA384'); + +// Do not have shared ciphers. +test('TLS_AES_256_GCM_SHA384', 'TLS_CHACHA20_POLY1305_SHA256', + U, 'ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE', 'ERR_SSL_NO_SHARED_CIPHER'); + +test('AES128-SHA', 'AES256-SHA', U, 'ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE', + 'ERR_SSL_NO_SHARED_CIPHER'); +test('AES128-SHA:TLS_AES_256_GCM_SHA384', + 'TLS_CHACHA20_POLY1305_SHA256:AES256-SHA', + U, 'ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE', 'ERR_SSL_NO_SHARED_CIPHER'); + +// Cipher order ignored, TLS1.3 chosen before TLS1.2. +test('AES256-SHA:TLS_AES_256_GCM_SHA384', U, 'TLS_AES_256_GCM_SHA384'); +test(U, 'AES256-SHA:TLS_AES_256_GCM_SHA384', 'TLS_AES_256_GCM_SHA384'); + +// Cipher order ignored, TLS1.3 before TLS1.2 and +// cipher suites are not disabled if TLS ciphers are set only +// TODO: maybe these tests should be reworked so maxVersion clamping +// is done explicitly and not implicitly in the test() function +test('AES256-SHA', U, 'TLS_AES_256_GCM_SHA384', U, U, { maxVersion: 'TLSv1.3' }); +test(U, 'AES256-SHA', 'TLS_AES_256_GCM_SHA384', U, U, { maxVersion: 'TLSv1.3' }); + +// TLS_AES_128_CCM_8_SHA256 & TLS_AES_128_CCM_SHA256 are not enabled by +// default, but work. +test('TLS_AES_128_CCM_8_SHA256', U, + U, 'ERR_SSL_SSLV3_ALERT_HANDSHAKE_FAILURE', 'ERR_SSL_NO_SHARED_CIPHER'); + +test('TLS_AES_128_CCM_8_SHA256', 'TLS_AES_128_CCM_8_SHA256', + 'TLS_AES_128_CCM_8_SHA256'); + +// Invalid cipher values +test(9, 'AES256-SHA', U, 'ERR_INVALID_ARG_TYPE', U); +test('AES256-SHA', 9, U, U, 'ERR_INVALID_ARG_TYPE'); +test(':', 'AES256-SHA', U, 'ERR_INVALID_ARG_VALUE', U); +test('AES256-SHA', ':', U, U, 'ERR_INVALID_ARG_VALUE'); + +// Using '' is synonymous for "use default ciphers" +test('TLS_AES_256_GCM_SHA384', '', 'TLS_AES_256_GCM_SHA384'); +test('', 'TLS_AES_256_GCM_SHA384', 'TLS_AES_256_GCM_SHA384'); + +// Using null should be treated the same as undefined. +test(null, 'AES256-SHA', 'AES256-SHA'); +test('AES256-SHA', null, 'AES256-SHA'); diff --git a/tests/node_compat/test/parallel/test-tls-transport-destroy-after-own-gc.js b/tests/node_compat/test/parallel/test-tls-transport-destroy-after-own-gc.js new file mode 100644 index 0000000000..68ec2c8f90 --- /dev/null +++ b/tests/node_compat/test/parallel/test-tls-transport-destroy-after-own-gc.js @@ -0,0 +1,36 @@ +// 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-gc +'use strict'; + +// Regression test for https://github.com/nodejs/node/issues/17475 +// Unfortunately, this tests only "works" reliably when checked with valgrind or +// a similar tool. + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const { TLSSocket } = require('tls'); +const makeDuplexPair = require('../common/duplexpair'); + +let { clientSide } = makeDuplexPair(); + +let clientTLS = new TLSSocket(clientSide, { isServer: false }); +let clientTLSHandle = clientTLS._handle; // eslint-disable-line no-unused-vars + +setImmediate(() => { + clientTLS = null; + global.gc(); + clientTLSHandle = null; + global.gc(); + setImmediate(() => { + clientSide = null; + global.gc(); + }); +}); diff --git a/tests/node_compat/test/parallel/test-trace-events-async-hooks-dynamic.js b/tests/node_compat/test/parallel/test-trace-events-async-hooks-dynamic.js new file mode 100644 index 0000000000..6c320b54c0 --- /dev/null +++ b/tests/node_compat/test/parallel/test-trace-events-async-hooks-dynamic.js @@ -0,0 +1,69 @@ +// 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. + +'use strict'; + +// This tests that tracing can be enabled dynamically with the +// trace_events module. + +const common = require('../common'); +try { + require('trace_events'); +} catch { + common.skip('missing trace events'); +} + +const assert = require('assert'); +const cp = require('child_process'); +const fs = require('fs'); + +const enable = `require("trace_events").createTracing( +{ categories: ["node.async_hooks"] }).enable();`; +const code = + 'setTimeout(() => { for (let i = 0; i < 100000; i++) { "test" + i } }, 1)'; + +const tmpdir = require('../common/tmpdir'); +const filename = tmpdir.resolve('node_trace.1.log'); + +tmpdir.refresh(); +const proc = cp.spawnSync( + process.execPath, + ['-e', enable + code ], + { + cwd: tmpdir.path, + env: { ...process.env, + 'NODE_DEBUG_NATIVE': 'tracing', + 'NODE_DEBUG': 'tracing' } + }); + +console.log('process exit with signal:', proc.signal); +console.log('process stderr:', proc.stderr.toString()); + +assert.strictEqual(proc.status, 0); +assert(fs.existsSync(filename)); +const data = fs.readFileSync(filename, 'utf-8'); +const traces = JSON.parse(data).traceEvents; + +function filterTimeoutTraces(trace) { + if (trace.pid !== proc.pid) + return false; + if (trace.cat !== 'node,node.async_hooks') + return false; + if (trace.name !== 'Timeout') + return false; + return true; +} + +{ + const timeoutTraces = traces.filter(filterTimeoutTraces); + assert.notDeepStrictEqual(timeoutTraces, []); + const threads = new Set(); + for (const trace of timeoutTraces) { + threads.add(trace.tid); + } + assert.notDeepStrictEqual(timeoutTraces, []); +} diff --git a/tests/node_compat/test/parallel/test-trace-events-async-hooks-worker.js b/tests/node_compat/test/parallel/test-trace-events-async-hooks-worker.js new file mode 100644 index 0000000000..c924afc56d --- /dev/null +++ b/tests/node_compat/test/parallel/test-trace-events-async-hooks-worker.js @@ -0,0 +1,78 @@ +// 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. + +'use strict'; + +// This tests that enabling node.async_hooks in main threads also +// affects the workers. + +const common = require('../common'); +try { + require('trace_events'); +} catch { + common.skip('missing trace events'); +} + +const assert = require('assert'); +const cp = require('child_process'); +const fs = require('fs'); + +const code = + 'setTimeout(() => { for (let i = 0; i < 100000; i++) { "test" + i } }, 1)'; +const worker = +`const { Worker } = require('worker_threads'); +const worker = new Worker('${code}', +{ eval: true, stdout: true, stderr: true }); +worker.stdout.on('data', + (chunk) => console.log('worker', chunk.toString())); +worker.stderr.on('data', + (chunk) => console.error('worker', chunk.toString())); +worker.on('exit', () => { ${code} })`; + +const tmpdir = require('../common/tmpdir'); +const filename = tmpdir.resolve('node_trace.1.log'); + +tmpdir.refresh(); +const proc = cp.spawnSync( + process.execPath, + [ '--trace-event-categories', 'node.async_hooks', '-e', worker ], + { + cwd: tmpdir.path, + env: { ...process.env, + 'NODE_DEBUG_NATIVE': 'tracing', + 'NODE_DEBUG': 'tracing' } + }); + +console.log('process exit with signal:', proc.signal); +console.log('process stderr:', proc.stderr.toString()); + +assert.strictEqual(proc.status, 0); +assert(fs.existsSync(filename)); +const data = fs.readFileSync(filename, 'utf-8'); +const traces = JSON.parse(data).traceEvents; + +function filterTimeoutTraces(trace) { + if (trace.pid !== proc.pid) + return false; + if (trace.cat !== 'node,node.async_hooks') + return false; + if (trace.name !== 'Timeout') + return false; + return true; +} + +{ + const timeoutTraces = traces.filter(filterTimeoutTraces); + assert.notDeepStrictEqual(timeoutTraces, []); + const threads = new Set(); + for (const trace of timeoutTraces) { + threads.add(trace.tid); + } + assert.notDeepStrictEqual(timeoutTraces, []); + console.log('Threads with Timeout traces:', threads); + assert.strictEqual(threads.size, 2); +} diff --git a/tests/node_compat/test/parallel/test-tz-version.js b/tests/node_compat/test/parallel/test-tz-version.js new file mode 100644 index 0000000000..e09c23db55 --- /dev/null +++ b/tests/node_compat/test/parallel/test-tz-version.js @@ -0,0 +1,35 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +if (!common.hasIntl) { + common.skip('missing Intl'); +} + +// Refs: https://github.com/nodejs/node/blob/1af63a90ca3a59ca05b3a12ad7dbea04008db7d9/configure.py#L1694-L1711 +if (process.config.variables.icu_path !== 'deps/icu-small') { + // If Node.js is configured to use its built-in ICU, it uses a strict subset + // of ICU formed using `tools/icu/shrink-icu-src.py`, which is present in + // `deps/icu-small`. It is not the same as configuring the build with + // `./configure --with-intl=small-icu`. The latter only uses a subset of the + // locales, i.e., it uses the English locale, `root,en`, by default and other + // locales can also be specified using the `--with-icu-locales` option. + common.skip('not using the icu data file present in deps/icu-small/source/data/in/icudt##l.dat.bz2'); +} + +const fixtures = require('../common/fixtures'); + +// This test ensures the correctness of the automated timezone upgrade PRs. + +const { strictEqual } = require('assert'); +const { readFileSync } = require('fs'); + +const expectedVersion = readFileSync(fixtures.path('tz-version.txt'), 'utf8').trim(); +strictEqual(process.versions.tz, expectedVersion); diff --git a/tests/node_compat/test/parallel/test-utf8-scripts.js b/tests/node_compat/test/parallel/test-utf8-scripts.js new file mode 100644 index 0000000000..e18b4fa71a --- /dev/null +++ b/tests/node_compat/test/parallel/test-utf8-scripts.js @@ -0,0 +1,37 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); + +// üäö + +console.log('Σὲ γνωρίζω ἀπὸ τὴν κόψη'); + +assert.match('Hellö Wörld', /Hellö Wörld/); diff --git a/tests/node_compat/test/parallel/test-util-inspect-getters-accessing-this.js b/tests/node_compat/test/parallel/test-util-inspect-getters-accessing-this.js new file mode 100644 index 0000000000..14a2be456c --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-inspect-getters-accessing-this.js @@ -0,0 +1,74 @@ +// 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. + +'use strict'; + +require('../common'); + +// This test ensures that util.inspect logs getters +// which access this. + +const assert = require('assert'); + +const { inspect } = require('util'); + +{ + class X { + constructor() { + this._y = 123; + } + + get y() { + return this._y; + } + } + + const result = inspect(new X(), { + getters: true, + showHidden: true + }); + + assert.strictEqual( + result, + 'X { _y: 123, [y]: [Getter: 123] }' + ); +} + +// Regression test for https://github.com/nodejs/node/issues/37054 +{ + class A { + constructor(B) { + this.B = B; + } + get b() { + return this.B; + } + } + + class B { + constructor() { + this.A = new A(this); + } + get a() { + return this.A; + } + } + + const result = inspect(new B(), { + depth: 1, + getters: true, + showHidden: true + }); + + assert.strictEqual( + result, + ' B {\n' + + ' A: A { B: [Circular *1], [b]: [Getter] [Circular *1] },\n' + + ' [a]: [Getter] A { B: [Circular *1], [b]: [Getter] [Circular *1] }\n' + + '}', + ); +} diff --git a/tests/node_compat/test/parallel/test-util-primordial-monkeypatching.js b/tests/node_compat/test/parallel/test-util-primordial-monkeypatching.js new file mode 100644 index 0000000000..927a350428 --- /dev/null +++ b/tests/node_compat/test/parallel/test-util-primordial-monkeypatching.js @@ -0,0 +1,18 @@ +// 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. + +'use strict'; + +// Monkeypatch Object.keys() so that it throws an unexpected error. This tests +// that `util.inspect()` is unaffected by monkey-patching `Object`. + +require('../common'); +const assert = require('assert'); +const util = require('util'); + +Object.keys = () => { throw new Error('fhqwhgads'); }; +assert.strictEqual(util.inspect({}), '{}'); diff --git a/tests/node_compat/test/parallel/test-uv-binding-constant.js b/tests/node_compat/test/parallel/test-uv-binding-constant.js new file mode 100644 index 0000000000..a4b74fddae --- /dev/null +++ b/tests/node_compat/test/parallel/test-uv-binding-constant.js @@ -0,0 +1,26 @@ +// 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'; + +require('../common'); +const assert = require('assert'); +const { internalBinding } = require('internal/test/binding'); +const uv = internalBinding('uv'); + +// Ensures that the `UV_...` values in internalBinding('uv') +// are constants. + +const keys = Object.keys(uv); +keys.forEach((key) => { + if (key.startsWith('UV_')) { + const val = uv[key]; + assert.throws(() => uv[key] = 1, TypeError); + assert.strictEqual(uv[key], val); + } +}); diff --git a/tests/node_compat/test/parallel/test-uv-unmapped-exception.js b/tests/node_compat/test/parallel/test-uv-unmapped-exception.js new file mode 100644 index 0000000000..7e0ff2b682 --- /dev/null +++ b/tests/node_compat/test/parallel/test-uv-unmapped-exception.js @@ -0,0 +1,33 @@ +// 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'; +require('../common'); +const assert = require('assert'); +const { uvException, uvExceptionWithHostPort } = require('internal/errors'); + +{ + const exception = uvException({ errno: 100, syscall: 'open' }); + + assert.strictEqual(exception.message, 'UNKNOWN: unknown error, open'); + assert.strictEqual(exception.errno, 100); + assert.strictEqual(exception.syscall, 'open'); + assert.strictEqual(exception.code, 'UNKNOWN'); +} + +{ + const exception = uvExceptionWithHostPort(100, 'listen', '127.0.0.1', 80); + + assert.strictEqual(exception.message, + 'listen UNKNOWN: unknown error 127.0.0.1:80'); + assert.strictEqual(exception.code, 'UNKNOWN'); + assert.strictEqual(exception.errno, 100); + assert.strictEqual(exception.syscall, 'listen'); + assert.strictEqual(exception.address, '127.0.0.1'); + assert.strictEqual(exception.port, 80); +} diff --git a/tests/node_compat/test/parallel/test-v8-coverage.js b/tests/node_compat/test/parallel/test-v8-coverage.js new file mode 100644 index 0000000000..4b3c01a438 --- /dev/null +++ b/tests/node_compat/test/parallel/test-v8-coverage.js @@ -0,0 +1,212 @@ +// 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. + +'use strict'; + +if (!process.features.inspector) return; + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); +const { spawnSync } = require('child_process'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +let dirc = 0; +function nextdir() { + return `cov_${++dirc}`; +} + +// Outputs coverage when event loop is drained, with no async logic. +{ + const coverageDirectory = tmpdir.resolve(nextdir()); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/v8-coverage/basic'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + if (output.status !== 0) { + console.log(output.stderr.toString()); + } + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const fixtureCoverage = getFixtureCoverage('basic.js', coverageDirectory); + assert.ok(fixtureCoverage); + // First branch executed. + assert.strictEqual(fixtureCoverage.functions[0].ranges[0].count, 1); + // Second branch did not execute. + assert.strictEqual(fixtureCoverage.functions[0].ranges[1].count, 0); +} + +// Outputs coverage when error is thrown in first tick. +{ + const coverageDirectory = tmpdir.resolve(nextdir()); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/v8-coverage/throw'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + if (output.status !== 1) { + console.log(output.stderr.toString()); + } + assert.strictEqual(output.status, 1); + const fixtureCoverage = getFixtureCoverage('throw.js', coverageDirectory); + assert.ok(fixtureCoverage, 'coverage not found for file'); + // First branch executed. + assert.strictEqual(fixtureCoverage.functions[0].ranges[0].count, 1); + // Second branch did not execute. + assert.strictEqual(fixtureCoverage.functions[0].ranges[1].count, 0); +} + +// Outputs coverage when process.exit(1) exits process. +{ + const coverageDirectory = tmpdir.resolve(nextdir()); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/v8-coverage/exit-1'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + if (output.status !== 1) { + console.log(output.stderr.toString()); + } + assert.strictEqual(output.status, 1); + assert.strictEqual(output.stderr.toString(), ''); + const fixtureCoverage = getFixtureCoverage('exit-1.js', coverageDirectory); + assert.ok(fixtureCoverage, 'coverage not found for file'); + // First branch executed. + assert.strictEqual(fixtureCoverage.functions[0].ranges[0].count, 1); + // Second branch did not execute. + assert.strictEqual(fixtureCoverage.functions[0].ranges[1].count, 0); +} + +// Outputs coverage when process.kill(process.pid, "SIGINT"); exits process. +{ + const coverageDirectory = tmpdir.resolve(nextdir()); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/v8-coverage/sigint'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + if (!common.isWindows) { + if (output.signal !== 'SIGINT') { + console.log(output.stderr.toString()); + } + assert.strictEqual(output.signal, 'SIGINT'); + } + assert.strictEqual(output.stderr.toString(), ''); + const fixtureCoverage = getFixtureCoverage('sigint.js', coverageDirectory); + assert.ok(fixtureCoverage); + // First branch executed. + assert.strictEqual(fixtureCoverage.functions[0].ranges[0].count, 1); + // Second branch did not execute. + assert.strictEqual(fixtureCoverage.functions[0].ranges[1].count, 0); +} + +// Outputs coverage from subprocess. +{ + const coverageDirectory = tmpdir.resolve(nextdir()); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/v8-coverage/spawn-subprocess'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + if (output.status !== 0) { + console.log(output.stderr.toString()); + } + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const fixtureCoverage = getFixtureCoverage('subprocess.js', + coverageDirectory); + assert.ok(fixtureCoverage); + // First branch executed. + assert.strictEqual(fixtureCoverage.functions[1].ranges[0].count, 1); + // Second branch did not execute. + assert.strictEqual(fixtureCoverage.functions[1].ranges[1].count, 0); +} + +// Outputs coverage from worker. +{ + const coverageDirectory = tmpdir.resolve(nextdir()); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/v8-coverage/worker'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + if (output.status !== 0) { + console.log(output.stderr.toString()); + } + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const fixtureCoverage = getFixtureCoverage('subprocess.js', + coverageDirectory); + assert.ok(fixtureCoverage); + // First branch executed. + assert.strictEqual(fixtureCoverage.functions[1].ranges[0].count, 1); + // Second branch did not execute. + assert.strictEqual(fixtureCoverage.functions[1].ranges[1].count, 0); +} + +// Does not output coverage if NODE_V8_COVERAGE is empty. +{ + const coverageDirectory = tmpdir.resolve(nextdir()); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/v8-coverage/spawn-subprocess-no-cov'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + if (output.status !== 0) { + console.log(output.stderr.toString()); + } + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const fixtureCoverage = getFixtureCoverage('subprocess.js', + coverageDirectory); + assert.strictEqual(fixtureCoverage, undefined); +} + +// Disables async hooks before writing coverage. +{ + const coverageDirectory = tmpdir.resolve(nextdir()); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/v8-coverage/async-hooks'), + ], { env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } }); + if (output.status !== 0) { + console.log(output.stderr.toString()); + } + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const fixtureCoverage = getFixtureCoverage('async-hooks.js', + coverageDirectory); + assert.ok(fixtureCoverage); + // First branch executed. + assert.strictEqual(fixtureCoverage.functions[0].ranges[0].count, 1); +} + +// Outputs coverage when the coverage directory is not absolute. +{ + const coverageDirectory = nextdir(); + const absoluteCoverageDirectory = tmpdir.resolve(coverageDirectory); + const output = spawnSync(process.execPath, [ + require.resolve('../fixtures/v8-coverage/basic'), + ], { + cwd: tmpdir.path, + env: { ...process.env, NODE_V8_COVERAGE: coverageDirectory } + }); + if (output.status !== 0) { + console.log(output.stderr.toString()); + } + assert.strictEqual(output.status, 0); + assert.strictEqual(output.stderr.toString(), ''); + const fixtureCoverage = getFixtureCoverage('basic.js', + absoluteCoverageDirectory); + assert.ok(fixtureCoverage); + // First branch executed. + assert.strictEqual(fixtureCoverage.functions[0].ranges[0].count, 1); + // Second branch did not execute. + assert.strictEqual(fixtureCoverage.functions[0].ranges[1].count, 0); +} + +// Extracts the coverage object for a given fixture name. +function getFixtureCoverage(fixtureFile, coverageDirectory) { + const coverageFiles = fs.readdirSync(coverageDirectory); + for (const coverageFile of coverageFiles) { + const coverage = require(path.join(coverageDirectory, coverageFile)); + for (const fixtureCoverage of coverage.result) { + if (fixtureCoverage.url.indexOf(`/${fixtureFile}`) !== -1) { + return fixtureCoverage; + } + } + } +} diff --git a/tests/node_compat/test/parallel/test-v8-deserialize-buffer.js b/tests/node_compat/test/parallel/test-v8-deserialize-buffer.js new file mode 100644 index 0000000000..5740e0dbab --- /dev/null +++ b/tests/node_compat/test/parallel/test-v8-deserialize-buffer.js @@ -0,0 +1,14 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const v8 = require('v8'); + +process.on('warning', common.mustNotCall()); +v8.deserialize(v8.serialize(Buffer.alloc(0))); diff --git a/tests/node_compat/test/parallel/test-v8-flag-pool-size-0.js b/tests/node_compat/test/parallel/test-v8-flag-pool-size-0.js new file mode 100644 index 0000000000..cce685573d --- /dev/null +++ b/tests/node_compat/test/parallel/test-v8-flag-pool-size-0.js @@ -0,0 +1,17 @@ +// 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: --v8-pool-size=0 --expose-gc + +'use strict'; + +require('../common'); + +// This verifies that V8 tasks scheduled by GC are handled on worker threads if +// `--v8-pool-size=0` is given. The worker threads are managed by Node.js' +// `v8::Platform` implementation. +globalThis.gc(); diff --git a/tests/node_compat/test/parallel/test-v8-global-setter.js b/tests/node_compat/test/parallel/test-v8-global-setter.js new file mode 100644 index 0000000000..68ee7230f8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-v8-global-setter.js @@ -0,0 +1,36 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); + +// This test ensures v8 correctly sets a property on the global object if it +// has a setter interceptor in strict mode. +// https://github.com/nodejs/node-v0.x-archive/issues/6235 + +require('vm').runInNewContext('"use strict"; var v = 1; v = 2'); diff --git a/tests/node_compat/test/parallel/test-v8-stop-coverage.js b/tests/node_compat/test/parallel/test-v8-stop-coverage.js new file mode 100644 index 0000000000..6092d7115d --- /dev/null +++ b/tests/node_compat/test/parallel/test-v8-stop-coverage.js @@ -0,0 +1,41 @@ +// 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. + +'use strict'; + +if (!process.features.inspector) return; + +require('../common'); +const fixtures = require('../common/fixtures'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const { spawnSync } = require('child_process'); + +tmpdir.refresh(); +const intervals = 20; + +{ + const output = spawnSync(process.execPath, [ + '-r', + fixtures.path('v8-coverage', 'stop-coverage'), + '-r', + fixtures.path('v8-coverage', 'take-coverage'), + fixtures.path('v8-coverage', 'interval'), + ], { + env: { + ...process.env, + NODE_V8_COVERAGE: tmpdir.path, + NODE_DEBUG_NATIVE: 'INSPECTOR_PROFILER', + TEST_INTERVALS: intervals + }, + }); + console.log(output.stderr.toString()); + assert.strictEqual(output.status, 0); + const coverageFiles = fs.readdirSync(tmpdir.path); + assert.strictEqual(coverageFiles.length, 0); +} diff --git a/tests/node_compat/test/parallel/test-v8-take-coverage-noop.js b/tests/node_compat/test/parallel/test-v8-take-coverage-noop.js new file mode 100644 index 0000000000..931895097e --- /dev/null +++ b/tests/node_compat/test/parallel/test-v8-take-coverage-noop.js @@ -0,0 +1,39 @@ +// 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. + +'use strict'; + +if (!process.features.inspector) return; + +require('../common'); +const fixtures = require('../common/fixtures'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const { spawnSync } = require('child_process'); + +tmpdir.refresh(); + +// v8.takeCoverage() should be a noop if NODE_V8_COVERAGE is not set. +const intervals = 40; +{ + const output = spawnSync(process.execPath, [ + '-r', + fixtures.path('v8-coverage', 'take-coverage'), + fixtures.path('v8-coverage', 'interval'), + ], { + env: { + ...process.env, + NODE_DEBUG_NATIVE: 'INSPECTOR_PROFILER', + TEST_INTERVALS: intervals + }, + }); + console.log(output.stderr.toString()); + assert.strictEqual(output.status, 0); + const coverageFiles = fs.readdirSync(tmpdir.path); + assert.strictEqual(coverageFiles.length, 0); +} diff --git a/tests/node_compat/test/parallel/test-v8-take-coverage.js b/tests/node_compat/test/parallel/test-v8-take-coverage.js new file mode 100644 index 0000000000..af5bd7b402 --- /dev/null +++ b/tests/node_compat/test/parallel/test-v8-take-coverage.js @@ -0,0 +1,91 @@ +// 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. + +'use strict'; + +if (!process.features.inspector) return; + +require('../common'); +const fixtures = require('../common/fixtures'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const { spawnSync } = require('child_process'); + +tmpdir.refresh(); +const intervals = 40; +// Outputs coverage when v8.takeCoverage() is invoked. +{ + const output = spawnSync(process.execPath, [ + '-r', + fixtures.path('v8-coverage', 'take-coverage'), + fixtures.path('v8-coverage', 'interval'), + ], { + env: { + ...process.env, + NODE_V8_COVERAGE: tmpdir.path, + NODE_DEBUG_NATIVE: 'INSPECTOR_PROFILER', + TEST_INTERVALS: intervals + }, + }); + console.log(output.stderr.toString()); + assert.strictEqual(output.status, 0); + const coverageFiles = fs.readdirSync(tmpdir.path); + + let coverages = []; + for (const coverageFile of coverageFiles) { + const coverage = require(tmpdir.resolve(coverageFile)); + for (const result of coverage.result) { + if (result.url.includes('/interval')) { + coverages.push({ + file: coverageFile, + func: result.functions.find((f) => f.functionName === 'interval'), + timestamp: coverage.timestamp + }); + } + } + } + + coverages = coverages.sort((a, b) => { return a.timestamp - b.timestamp; }); + // There should be two coverages taken, one triggered by v8.takeCoverage(), + // the other by process exit. + console.log('Coverages:', coverages); + assert.strictEqual(coverages.length, 3); + + let blockHitsTotal = 0; + for (let i = 0; i < coverages.length; ++i) { + const { ranges } = coverages[i].func; + console.log('coverage', i, ranges); + + if (i !== coverages.length - 1) { + // When the first two coverages are taken: + assert.strictEqual(ranges.length, 2); + const blockHits = ranges[0].count; + // The block inside interval() should be hit at least once. + assert.notStrictEqual(blockHits, 0); + blockHitsTotal += blockHits; + // The else branch should not be hit. + const elseBranchHits = ranges[1].count; + assert.strictEqual(elseBranchHits, 0); + } else { + // At process exit: + assert.strictEqual(ranges.length, 3); + const blockHits = ranges[0].count; + // The block inside interval() should be hit at least once more. + assert.notStrictEqual(blockHits, 0); + blockHitsTotal += blockHits; + // The else branch should be hit exactly once. + const elseBranchHits = ranges[2].count; + assert.strictEqual(elseBranchHits, 1); + const ifBranchHits = ranges[1].count; + assert.strictEqual(ifBranchHits, blockHits - elseBranchHits); + } + } + + // The block should be hit `intervals` times in total. + assert.strictEqual(blockHitsTotal, intervals); +} diff --git a/tests/node_compat/test/parallel/test-weakref.js b/tests/node_compat/test/parallel/test-weakref.js new file mode 100644 index 0000000000..119bf612ae --- /dev/null +++ b/tests/node_compat/test/parallel/test-weakref.js @@ -0,0 +1,20 @@ +// 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. + +'use strict'; + +// Flags: --expose-gc + +require('../common'); +const assert = require('assert'); + +const w = new globalThis.WeakRef({}); + +setTimeout(() => { + globalThis.gc(); + assert.strictEqual(w.deref(), undefined); +}, 200); diff --git a/tests/node_compat/test/parallel/test-webcrypto-encrypt-decrypt.js b/tests/node_compat/test/parallel/test-webcrypto-encrypt-decrypt.js new file mode 100644 index 0000000000..1bbfd185e1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-webcrypto-encrypt-decrypt.js @@ -0,0 +1,131 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const { subtle } = globalThis.crypto; + +// This is only a partial test. The WebCrypto Web Platform Tests +// will provide much greater coverage. + +// Test Encrypt/Decrypt RSA-OAEP +{ + const buf = globalThis.crypto.getRandomValues(new Uint8Array(50)); + + async function test() { + const ec = new TextEncoder(); + const { publicKey, privateKey } = await subtle.generateKey({ + name: 'RSA-OAEP', + modulusLength: 2048, + publicExponent: new Uint8Array([1, 0, 1]), + hash: 'SHA-384', + }, true, ['encrypt', 'decrypt']); + + const ciphertext = await subtle.encrypt({ + name: 'RSA-OAEP', + label: ec.encode('a label') + }, publicKey, buf); + + const plaintext = await subtle.decrypt({ + name: 'RSA-OAEP', + label: ec.encode('a label') + }, privateKey, ciphertext); + + assert.strictEqual( + Buffer.from(plaintext).toString('hex'), + Buffer.from(buf).toString('hex')); + } + + test().then(common.mustCall()); +} + +// Test Encrypt/Decrypt AES-CTR +{ + const buf = globalThis.crypto.getRandomValues(new Uint8Array(50)); + const counter = globalThis.crypto.getRandomValues(new Uint8Array(16)); + + async function test() { + const key = await subtle.generateKey({ + name: 'AES-CTR', + length: 256 + }, true, ['encrypt', 'decrypt']); + + const ciphertext = await subtle.encrypt( + { name: 'AES-CTR', counter, length: 64 }, key, buf, + ); + + const plaintext = await subtle.decrypt( + { name: 'AES-CTR', counter, length: 64 }, key, ciphertext, + ); + + assert.strictEqual( + Buffer.from(plaintext).toString('hex'), + Buffer.from(buf).toString('hex')); + } + + test().then(common.mustCall()); +} + +// Test Encrypt/Decrypt AES-CBC +{ + const buf = globalThis.crypto.getRandomValues(new Uint8Array(50)); + const iv = globalThis.crypto.getRandomValues(new Uint8Array(16)); + + async function test() { + const key = await subtle.generateKey({ + name: 'AES-CBC', + length: 256 + }, true, ['encrypt', 'decrypt']); + + const ciphertext = await subtle.encrypt( + { name: 'AES-CBC', iv }, key, buf, + ); + + const plaintext = await subtle.decrypt( + { name: 'AES-CBC', iv }, key, ciphertext, + ); + + assert.strictEqual( + Buffer.from(plaintext).toString('hex'), + Buffer.from(buf).toString('hex')); + } + + test().then(common.mustCall()); +} + +// Test Encrypt/Decrypt AES-GCM +{ + const buf = globalThis.crypto.getRandomValues(new Uint8Array(50)); + const iv = globalThis.crypto.getRandomValues(new Uint8Array(12)); + + async function test() { + const key = await subtle.generateKey({ + name: 'AES-GCM', + length: 256 + }, true, ['encrypt', 'decrypt']); + + const ciphertext = await subtle.encrypt( + { name: 'AES-GCM', iv }, key, buf, + ); + + const plaintext = await subtle.decrypt( + { name: 'AES-GCM', iv }, key, ciphertext, + ); + + assert.strictEqual( + Buffer.from(plaintext).toString('hex'), + Buffer.from(buf).toString('hex')); + } + + test().then(common.mustCall()); +} diff --git a/tests/node_compat/test/parallel/test-websocket.js b/tests/node_compat/test/parallel/test-websocket.js new file mode 100644 index 0000000000..3251711732 --- /dev/null +++ b/tests/node_compat/test/parallel/test-websocket.js @@ -0,0 +1,14 @@ +// 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: --experimental-websocket +'use strict'; + +require('../common'); +const assert = require('assert'); + +assert.strictEqual(typeof WebSocket, 'function'); diff --git a/tests/node_compat/test/parallel/test-webstream-string-tag.js b/tests/node_compat/test/parallel/test-webstream-string-tag.js new file mode 100644 index 0000000000..9c44b57ce8 --- /dev/null +++ b/tests/node_compat/test/parallel/test-webstream-string-tag.js @@ -0,0 +1,25 @@ +// 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. + +'use strict'; + +require('../common'); + +const assert = require('assert'); + +const classesToBeTested = [ WritableStream, WritableStreamDefaultWriter, WritableStreamDefaultController, + ReadableStream, ReadableStreamBYOBRequest, ReadableStreamDefaultReader, + ReadableStreamBYOBReader, ReadableStreamDefaultController, ReadableByteStreamController, + ByteLengthQueuingStrategy, CountQueuingStrategy, TransformStream, + TransformStreamDefaultController]; + + +classesToBeTested.forEach((cls) => { + assert.strictEqual(cls.prototype[Symbol.toStringTag], cls.name); + assert.deepStrictEqual(Object.getOwnPropertyDescriptor(cls.prototype, Symbol.toStringTag), + { configurable: true, enumerable: false, value: cls.name, writable: false }); +}); diff --git a/tests/node_compat/test/parallel/test-whatwg-readablebytestreambyob.js b/tests/node_compat/test/parallel/test-whatwg-readablebytestreambyob.js new file mode 100644 index 0000000000..db0125bde1 --- /dev/null +++ b/tests/node_compat/test/parallel/test-whatwg-readablebytestreambyob.js @@ -0,0 +1,69 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +const { + open, +} = require('fs/promises'); + +const { + Buffer, +} = require('buffer'); + +class Source { + async start(controller) { + this.file = await open(__filename); + this.controller = controller; + } + + async pull(controller) { + const byobRequest = controller.byobRequest; + const view = byobRequest.view; + + const { + bytesRead, + } = await this.file.read({ + buffer: view, + offset: view.byteOffset, + length: view.byteLength + }); + + if (bytesRead === 0) { + await this.file.close(); + this.controller.close(); + } + + byobRequest.respond(bytesRead); + } + + get type() { return 'bytes'; } + + get autoAllocateChunkSize() { return 1024; } +} + +(async () => { + const source = new Source(); + const stream = new ReadableStream(source); + + const { emitWarning } = process; + + process.emitWarning = common.mustNotCall(); + + try { + const reader = stream.getReader({ mode: 'byob' }); + + let result; + do { + result = await reader.read(Buffer.alloc(100)); + } while (!result.done); + } finally { + process.emitWarning = emitWarning; + } +})().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-worker-cleanexit-with-js.js b/tests/node_compat/test/parallel/test-worker-cleanexit-with-js.js new file mode 100644 index 0000000000..1be06d3347 --- /dev/null +++ b/tests/node_compat/test/parallel/test-worker-cleanexit-with-js.js @@ -0,0 +1,28 @@ +// 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. + +'use strict'; +const common = require('../common'); + +// Harden the thread interactions on the exit path. +// Ensure workers are able to bail out safe at +// arbitrary execution points. By running a lot of +// JS code in a tight loop, the expectation +// is that those will be at various control flow points +// preferably in the JS land. + +const { Worker } = require('worker_threads'); +const code = 'setInterval(() => {' + + "require('v8').deserialize(require('v8').serialize({ foo: 'bar' }));" + + "require('vm').runInThisContext('x = \"foo\";');" + + "eval('const y = \"vm\";');}, 10);"; +for (let i = 0; i < 9; i++) { + new Worker(code, { eval: true }); +} +new Worker(code, { eval: true }).on('online', common.mustCall((msg) => { + process.exit(0); +})); diff --git a/tests/node_compat/test/parallel/test-worker-on-process-exit.js b/tests/node_compat/test/parallel/test-worker-on-process-exit.js new file mode 100644 index 0000000000..4e821c2ac6 --- /dev/null +++ b/tests/node_compat/test/parallel/test-worker-on-process-exit.js @@ -0,0 +1,29 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); +const { spawnSync } = require('child_process'); +const { Worker } = require('worker_threads'); + +// Test that 'exit' events for Workers are not received when the main thread +// terminates itself through process.exit(). + +if (process.argv[2] !== 'child') { + const { + stdout, stderr, status + } = spawnSync(process.execPath, [__filename, 'child'], { encoding: 'utf8' }); + assert.strictEqual(stderr, ''); + assert.strictEqual(stdout, ''); + assert.strictEqual(status, 0); +} else { + const nestedWorker = new Worker('setInterval(() => {}, 100)', { eval: true }); + // This console.log() should never fire. + nestedWorker.on('exit', () => console.log('exit event received')); + nestedWorker.on('online', () => process.exit()); +} diff --git a/tests/node_compat/test/parallel/test-worker-ref-onexit.js b/tests/node_compat/test/parallel/test-worker-ref-onexit.js new file mode 100644 index 0000000000..6bfccb7e8f --- /dev/null +++ b/tests/node_compat/test/parallel/test-worker-ref-onexit.js @@ -0,0 +1,19 @@ +// 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. + +'use strict'; +const common = require('../common'); +const { Worker } = require('worker_threads'); + +// Check that worker.unref() makes the 'exit' event not be emitted, if it is +// the only thing we would otherwise be waiting for. + +// Use `setInterval()` to make sure the worker is alive until the end of the +// event loop turn. +const w = new Worker('setInterval(() => {}, 100);', { eval: true }); +w.unref(); +w.on('exit', common.mustNotCall()); diff --git a/tests/node_compat/test/parallel/test-worker-terminate-unrefed.js b/tests/node_compat/test/parallel/test-worker-terminate-unrefed.js new file mode 100644 index 0000000000..3647c96efd --- /dev/null +++ b/tests/node_compat/test/parallel/test-worker-terminate-unrefed.js @@ -0,0 +1,23 @@ +// 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. + +'use strict'; +const common = require('../common'); +const { once } = require('events'); +const { Worker } = require('worker_threads'); + +// Test that calling worker.terminate() on an unref()’ed Worker instance +// still resolves the returned Promise. + +async function test() { + const worker = new Worker('setTimeout(() => {}, 1000000);', { eval: true }); + await once(worker, 'online'); + worker.unref(); + await worker.terminate(); +} + +test().then(common.mustCall()); diff --git a/tests/node_compat/test/parallel/test-zlib-create-raw.js b/tests/node_compat/test/parallel/test-zlib-create-raw.js new file mode 100644 index 0000000000..d8367a889b --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-create-raw.js @@ -0,0 +1,22 @@ +// 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. + +'use strict'; + +require('../common'); +const assert = require('assert'); +const zlib = require('zlib'); + +{ + const inflateRaw = zlib.createInflateRaw(); + assert(inflateRaw instanceof zlib.InflateRaw); +} + +{ + const deflateRaw = zlib.createDeflateRaw(); + assert(deflateRaw instanceof zlib.DeflateRaw); +} diff --git a/tests/node_compat/test/parallel/test-zlib-flush-write-sync-interleaved.js b/tests/node_compat/test/parallel/test-zlib-flush-write-sync-interleaved.js new file mode 100644 index 0000000000..c398880fc7 --- /dev/null +++ b/tests/node_compat/test/parallel/test-zlib-flush-write-sync-interleaved.js @@ -0,0 +1,64 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { createGzip, createGunzip, Z_PARTIAL_FLUSH } = require('zlib'); + +// Verify that .flush() behaves like .write() in terms of ordering, e.g. in +// a sequence like .write() + .flush() + .write() + .flush() each .flush() call +// only affects the data written before it. +// Refs: https://github.com/nodejs/node/issues/28478 + +const compress = createGzip(); +const decompress = createGunzip(); +decompress.setEncoding('utf8'); + +const events = []; +const compressedChunks = []; + +for (const chunk of ['abc', 'def', 'ghi']) { + compress.write(chunk, common.mustCall(() => events.push({ written: chunk }))); + compress.flush(Z_PARTIAL_FLUSH, common.mustCall(() => { + events.push('flushed'); + const chunk = compress.read(); + if (chunk !== null) + compressedChunks.push(chunk); + })); +} + +compress.end(common.mustCall(() => { + events.push('compress end'); + writeToDecompress(); +})); + +function writeToDecompress() { + // Write the compressed chunks to a decompressor, one by one, in order to + // verify that the flushes actually worked. + const chunk = compressedChunks.shift(); + if (chunk === undefined) return decompress.end(); + decompress.write(chunk, common.mustCall(() => { + events.push({ read: decompress.read() }); + writeToDecompress(); + })); +} + +process.on('exit', () => { + assert.deepStrictEqual(events, [ + { written: 'abc' }, + 'flushed', + { written: 'def' }, + 'flushed', + { written: 'ghi' }, + 'flushed', + 'compress end', + { read: 'abc' }, + { read: 'def' }, + { read: 'ghi' }, + ]); +}); diff --git a/tests/node_compat/test/pseudo-tty/test-set-raw-mode-reset-process-exit.js b/tests/node_compat/test/pseudo-tty/test-set-raw-mode-reset-process-exit.js new file mode 100644 index 0000000000..29d2b58232 --- /dev/null +++ b/tests/node_compat/test/pseudo-tty/test-set-raw-mode-reset-process-exit.js @@ -0,0 +1,25 @@ +// 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. + +'use strict'; +require('../common'); +const child_process = require('child_process'); + +// Tests that exiting through process.exit() resets the TTY mode. + +child_process.spawnSync(process.execPath, [ + '-e', 'process.stdin.setRawMode(true); process.exit(0)', +], { stdio: 'inherit' }); + +const { stdout } = child_process.spawnSync('stty', { + stdio: ['inherit', 'pipe', 'inherit'], + encoding: 'utf8', +}); + +if (stdout.match(/-echo\b/)) { + console.log(stdout); +} diff --git a/tests/node_compat/test/pseudo-tty/test-set-raw-mode-reset.js b/tests/node_compat/test/pseudo-tty/test-set-raw-mode-reset.js new file mode 100644 index 0000000000..2fbfeb3ee8 --- /dev/null +++ b/tests/node_compat/test/pseudo-tty/test-set-raw-mode-reset.js @@ -0,0 +1,26 @@ +// 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. + +'use strict'; +require('../common'); +const child_process = require('child_process'); + +// Tests that exiting through normal means resets the TTY mode. +// Refs: https://github.com/nodejs/node/issues/21020 + +child_process.spawnSync(process.execPath, [ + '-e', 'process.stdin.setRawMode(true)', +], { stdio: 'inherit' }); + +const { stdout } = child_process.spawnSync('stty', { + stdio: ['inherit', 'pipe', 'inherit'], + encoding: 'utf8', +}); + +if (stdout.match(/-echo\b/)) { + console.log(stdout); +} diff --git a/tests/node_compat/test/pseudo-tty/test-tty-stdin-call-end.js b/tests/node_compat/test/pseudo-tty/test-tty-stdin-call-end.js new file mode 100644 index 0000000000..60570b5746 --- /dev/null +++ b/tests/node_compat/test/pseudo-tty/test-tty-stdin-call-end.js @@ -0,0 +1,15 @@ +// 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. + +'use strict'; + +require('../common'); + +// This tests verifies that process.stdin.end() does not +// crash the process with ENOTCONN + +process.stdin.end(); diff --git a/tests/node_compat/test/pummel/test-crypto-dh-hash.js b/tests/node_compat/test/pummel/test-crypto-dh-hash.js new file mode 100644 index 0000000000..846856806c --- /dev/null +++ b/tests/node_compat/test/pummel/test-crypto-dh-hash.js @@ -0,0 +1,66 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) { + common.skip('node compiled without OpenSSL.'); +} + +if (common.isPi) { + common.skip('Too slow for Raspberry Pi devices'); +} + +if (!common.hasOpenSSL3) { + common.skip('Too slow when dynamically linked against OpenSSL 1.1.1'); +} + +const assert = require('assert'); +const crypto = require('crypto'); + +const hashes = { + modp1: '630e9acd2cc63f7e80d8507624ba60ac0757201a', + modp2: '18f7aa964484137f57bca64b21917a385b6a0b60', + modp5: 'c0a8eec0c2c8a5ec2f9c26f9661eb339a010ec61', + modp14: 'af5455606fe74cec49782bb374e4c63c9b1d132c', + modp15: '7bdd39e5cdbb9748113933e5c2623b559c534e74', + modp16: 'daea5277a7ad0116e734a8e0d2f297ef759d1161', + modp17: '3b62aaf0142c2720f0bf26a9589b0432c00eadc1', + modp18: 'a870b491bbbec9b131ae9878d07449d32e54f160', +}; + +for (const name in hashes) { + const group = crypto.getDiffieHellman(name); + const prime = group.getPrime('hex'); + const hash1 = hashes[name]; + const hash2 = crypto.createHash('sha1') + .update(prime.toUpperCase()).digest('hex'); + assert.strictEqual(hash1, hash2); + assert.strictEqual(group.getGenerator('hex'), '02'); +} diff --git a/tests/node_compat/test/pummel/test-crypto-timing-safe-equal-benchmarks.js b/tests/node_compat/test/pummel/test-crypto-timing-safe-equal-benchmarks.js new file mode 100644 index 0000000000..e7f7b0fede --- /dev/null +++ b/tests/node_compat/test/pummel/test-crypto-timing-safe-equal-benchmarks.js @@ -0,0 +1,129 @@ +// 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. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (!common.enoughTestMem) + common.skip('memory-intensive test'); + +const assert = require('assert'); +const crypto = require('crypto'); + +function runOneBenchmark(compareFunc, firstBufFill, secondBufFill, bufSize) { + return eval(` + const firstBuffer = Buffer.alloc(bufSize, firstBufFill); + const secondBuffer = Buffer.alloc(bufSize, secondBufFill); + + const startTime = process.hrtime(); + const result = compareFunc(firstBuffer, secondBuffer); + const endTime = process.hrtime(startTime); + + // Ensure that the result of the function call gets used, so it doesn't + // get discarded due to engine optimizations. + assert.strictEqual(result, firstBufFill === secondBufFill); + + endTime[0] * 1e9 + endTime[1]; + `); +} + +function getTValue(compareFunc) { + const numTrials = 1e5; + const bufSize = 10000; + // Perform benchmarks to verify that timingSafeEqual is actually timing-safe. + + const rawEqualBenches = Array(numTrials); + const rawUnequalBenches = Array(numTrials); + + for (let i = 0; i < numTrials; i++) { + if (Math.random() < 0.5) { + // First benchmark: comparing two equal buffers + rawEqualBenches[i] = runOneBenchmark(compareFunc, 'A', 'A', bufSize); + // Second benchmark: comparing two unequal buffers + rawUnequalBenches[i] = runOneBenchmark(compareFunc, 'B', 'C', bufSize); + } else { + // Flip the order of the benchmarks half of the time. + rawUnequalBenches[i] = runOneBenchmark(compareFunc, 'B', 'C', bufSize); + rawEqualBenches[i] = runOneBenchmark(compareFunc, 'A', 'A', bufSize); + } + } + + const equalBenches = filterOutliers(rawEqualBenches); + const unequalBenches = filterOutliers(rawUnequalBenches); + + // Use a two-sample t-test to determine whether the timing difference between + // the benchmarks is statistically significant. + // https://wikipedia.org/wiki/Student%27s_t-test#Independent_two-sample_t-test + + const equalMean = mean(equalBenches); + const unequalMean = mean(unequalBenches); + + const equalLen = equalBenches.length; + const unequalLen = unequalBenches.length; + + const combinedStd = combinedStandardDeviation(equalBenches, unequalBenches); + const standardErr = combinedStd * Math.sqrt(1 / equalLen + 1 / unequalLen); + + return (equalMean - unequalMean) / standardErr; +} + +// Returns the mean of an array +function mean(array) { + return array.reduce((sum, val) => sum + val, 0) / array.length; +} + +// Returns the sample standard deviation of an array +function standardDeviation(array) { + const arrMean = mean(array); + const total = array.reduce((sum, val) => sum + Math.pow(val - arrMean, 2), 0); + return Math.sqrt(total / (array.length - 1)); +} + +// Returns the common standard deviation of two arrays +function combinedStandardDeviation(array1, array2) { + const sum1 = Math.pow(standardDeviation(array1), 2) * (array1.length - 1); + const sum2 = Math.pow(standardDeviation(array2), 2) * (array2.length - 1); + return Math.sqrt((sum1 + sum2) / (array1.length + array2.length - 2)); +} + +// Filter large outliers from an array. A 'large outlier' is a value that is at +// least 50 times larger than the mean. This prevents the tests from failing +// due to the standard deviation increase when a function unexpectedly takes +// a very long time to execute. +function filterOutliers(array) { + const arrMean = mean(array); + return array.filter((value) => value / arrMean < 50); +} + +// t_(0.99995, ∞) +// i.e. If a given comparison function is indeed timing-safe, the t-test result +// has a 99.99% chance to be below this threshold. Unfortunately, this means +// that this test will be a bit flakey and will fail 0.01% of the time even if +// crypto.timingSafeEqual is working properly. +// t-table ref: http://www.sjsu.edu/faculty/gerstman/StatPrimer/t-table.pdf +// Note that in reality there are roughly `2 * numTrials - 2` degrees of +// freedom, not ∞. However, assuming `numTrials` is large, this doesn't +// significantly affect the threshold. +const T_THRESHOLD = 3.892; + +const t = getTValue(crypto.timingSafeEqual); +assert( + Math.abs(t) < T_THRESHOLD, + `timingSafeEqual should not leak information from its execution time (t=${t})`, +); + +// As a coherence check to make sure the statistical tests are working, run the +// same benchmarks again, this time with an unsafe comparison function. In this +// case the t-value should be above the threshold. +const unsafeCompare = (bufA, bufB) => bufA.equals(bufB); +const t2 = getTValue(unsafeCompare); +assert( + Math.abs(t2) > T_THRESHOLD, + `Buffer#equals should leak information from its execution time (t=${t2})`, +); diff --git a/tests/node_compat/test/pummel/test-dh-regr.js b/tests/node_compat/test/pummel/test-dh-regr.js new file mode 100644 index 0000000000..d09f3a2616 --- /dev/null +++ b/tests/node_compat/test/pummel/test-dh-regr.js @@ -0,0 +1,66 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) { + common.skip('missing crypto'); +} + +if (common.isPi) { + common.skip('Too slow for Raspberry Pi devices'); +} + +const assert = require('assert'); +const crypto = require('crypto'); + +// FIPS requires length >= 1024 but we use 512/256 in this test to keep it from +// taking too long and timing out in CI. +const length = (common.hasFipsCrypto) ? 1024 : common.hasOpenSSL3 ? 512 : 256; + +const p = crypto.createDiffieHellman(length).getPrime(); + +for (let i = 0; i < 2000; i++) { + const a = crypto.createDiffieHellman(p); + const b = crypto.createDiffieHellman(p); + + a.generateKeys(); + b.generateKeys(); + + const aSecret = a.computeSecret(b.getPublicKey()); + const bSecret = b.computeSecret(a.getPublicKey()); + + assert.deepStrictEqual( + aSecret, + bSecret, + 'Secrets should be equal.\n' + + `aSecret: ${aSecret.toString('base64')}\n` + + `bSecret: ${bSecret.toString('base64')}`, + ); +} diff --git a/tests/node_compat/test/pummel/test-fs-largefile.js b/tests/node_compat/test/pummel/test-fs-largefile.js new file mode 100644 index 0000000000..2a7741f092 --- /dev/null +++ b/tests/node_compat/test/pummel/test-fs-largefile.js @@ -0,0 +1,63 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +const assert = require('assert'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +try { + + const filepath = tmpdir.resolve('large.txt'); + const fd = fs.openSync(filepath, 'w+'); + const offset = 5 * 1024 * 1024 * 1024; // 5GB + const message = 'Large File'; + + fs.ftruncateSync(fd, offset); + assert.strictEqual(fs.statSync(filepath).size, offset); + const writeBuf = Buffer.from(message); + fs.writeSync(fd, writeBuf, 0, writeBuf.length, offset); + const readBuf = Buffer.allocUnsafe(writeBuf.length); + fs.readSync(fd, readBuf, 0, readBuf.length, offset); + assert.strictEqual(readBuf.toString(), message); + fs.readSync(fd, readBuf, 0, 1, 0); + assert.strictEqual(readBuf[0], 0); + + // Verify that floating point positions do not throw. + fs.writeSync(fd, writeBuf, 0, writeBuf.length, 42.000001); + fs.close(fd, common.mustCall()); +} catch (e) { + if (e.code !== 'ENOSPC') { + throw e; + } + common.skip('insufficient disk space'); +} diff --git a/tests/node_compat/test/pummel/test-fs-readfile-tostring-fail.js b/tests/node_compat/test/pummel/test-fs-readfile-tostring-fail.js new file mode 100644 index 0000000000..b0df8eec6e --- /dev/null +++ b/tests/node_compat/test/pummel/test-fs-readfile-tostring-fail.js @@ -0,0 +1,84 @@ +// 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. + +'use strict'; + +const common = require('../common'); + +if (!common.enoughTestMem) + common.skip('intensive toString tests due to memory confinements'); + +const assert = require('assert'); +const fs = require('fs'); +const cp = require('child_process'); +const kStringMaxLength = require('buffer').constants.MAX_STRING_LENGTH; +if (common.isAIX && (Number(cp.execSync('ulimit -f')) * 512) < kStringMaxLength) + common.skip('intensive toString tests due to file size confinements'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +if (!tmpdir.hasEnoughSpace(kStringMaxLength)) { + common.skip(`Not enough space in ${tmpdir.path}`); +} + +const file = tmpdir.resolve('toobig.txt'); +const stream = fs.createWriteStream(file, { + flags: 'a', +}); + +stream.on('error', (err) => { throw err; }); + +const size = kStringMaxLength / 200; +const a = Buffer.alloc(size, 'a'); +let expectedSize = 0; + +for (let i = 0; i < 201; i++) { + stream.write(a, (err) => { assert.ifError(err); }); + expectedSize += a.length; +} + +stream.end(); +stream.on('finish', common.mustCall(function() { + assert.strictEqual(stream.bytesWritten, expectedSize, + `${stream.bytesWritten} bytes written (expected ${expectedSize} bytes).`); + fs.readFile(file, 'utf8', common.mustCall(function(err, buf) { + assert.ok(err instanceof Error); + if (err.message !== 'Array buffer allocation failed') { + const stringLengthHex = kStringMaxLength.toString(16); + common.expectsError({ + message: 'Cannot create a string longer than ' + + `0x${stringLengthHex} characters`, + code: 'ERR_STRING_TOO_LONG', + name: 'Error', + })(err); + } + assert.strictEqual(buf, undefined); + })); +})); + +function destroy() { + try { + fs.unlinkSync(file); + } catch { + // it may not exist + } +} + +process.on('exit', destroy); + +process.on('SIGINT', function() { + destroy(); + process.exit(); +}); + +// To make sure we don't leave a very large file +// on test machines in the event this test fails. +process.on('uncaughtException', function(err) { + destroy(); + throw err; +}); diff --git a/tests/node_compat/test/pummel/test-fs-watch-system-limit.js b/tests/node_compat/test/pummel/test-fs-watch-system-limit.js new file mode 100644 index 0000000000..cadb48033a --- /dev/null +++ b/tests/node_compat/test/pummel/test-fs-watch-system-limit.js @@ -0,0 +1,77 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const child_process = require('child_process'); +const fs = require('fs'); +const stream = require('stream'); + +if (!common.isLinux) { + common.skip('The fs watch limit is OS-dependent'); +} + +if (common.isPi) { + common.skip('Too slow for Raspberry Pi devices'); +} + +try { + // Ensure inotify limit is low enough for the test to actually exercise the + // limit with small enough resources. + const limit = Number( + fs.readFileSync('/proc/sys/fs/inotify/max_user_watches', 'utf8')); + if (limit > 16384) + common.skip('inotify limit is quite large'); +} catch (e) { + if (e.code === 'ENOENT') + common.skip('the inotify /proc subsystem does not exist'); + // Fail on other errors. + throw e; +} + +const processes = []; +const gatherStderr = new stream.PassThrough(); +gatherStderr.setEncoding('utf8'); +gatherStderr.setMaxListeners(Infinity); + +let finished = false; +function spawnProcesses() { + for (let i = 0; i < 10; ++i) { + const proc = child_process.spawn( + process.execPath, + [ '-e', + `process.chdir(${JSON.stringify(__dirname)}); + for (const file of fs.readdirSync('.')) + fs.watch(file, () => {});`, + ], { stdio: ['inherit', 'inherit', 'pipe'] }); + proc.stderr.pipe(gatherStderr); + processes.push(proc); + } + + setTimeout(() => { + if (!finished && processes.length < 200) + spawnProcesses(); + }, 100); +} + +spawnProcesses(); + +let accumulated = ''; +gatherStderr.on('data', common.mustCallAtLeast((chunk) => { + accumulated += chunk; + if (accumulated.includes('Error:') && !finished) { + assert( + accumulated.includes('ENOSPC: System limit for number ' + + 'of file watchers reached') || + accumulated.includes('EMFILE: '), + accumulated); + console.log(`done after ${processes.length} processes, cleaning up`); + finished = true; + processes.forEach((proc) => proc.kill()); + } +}, 1)); diff --git a/tests/node_compat/test/pummel/test-heapsnapshot-near-heap-limit-big.js b/tests/node_compat/test/pummel/test-heapsnapshot-near-heap-limit-big.js new file mode 100644 index 0000000000..e1bb1280a3 --- /dev/null +++ b/tests/node_compat/test/pummel/test-heapsnapshot-near-heap-limit-big.js @@ -0,0 +1,49 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const { spawnSync } = require('child_process'); +const fixtures = require('../common/fixtures'); +const fs = require('fs'); +const env = { + ...process.env, + NODE_DEBUG_NATIVE: 'diagnostics', +}; + +if (!common.enoughTestMem) + common.skip('Insufficient memory for snapshot test'); + +{ + console.log('\nTesting limit = 3'); + tmpdir.refresh(); + const child = spawnSync(process.execPath, [ + '--heapsnapshot-near-heap-limit=3', + '--max-old-space-size=512', + fixtures.path('workload', 'grow.js'), + ], { + cwd: tmpdir.path, + env: { + ...env, + TEST_CHUNK: 2000, + }, + }); + const stderr = child.stderr.toString(); + console.log(stderr); + assert(common.nodeProcessAborted(child.status, child.signal), + 'process should have aborted, but did not'); + const list = fs.readdirSync(tmpdir.path) + .filter((file) => file.endsWith('.heapsnapshot')); + const risky = [...stderr.matchAll( + /Not generating snapshots because it's too risky/g)].length; + assert(list.length + risky > 0 && list.length <= 3, + `Generated ${list.length} snapshots ` + + `and ${risky} was too risky`); +} diff --git a/tests/node_compat/test/pummel/test-net-many-clients.js b/tests/node_compat/test/pummel/test-net-many-clients.js new file mode 100644 index 0000000000..a1789fa355 --- /dev/null +++ b/tests/node_compat/test/pummel/test-net-many-clients.js @@ -0,0 +1,107 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +require('../common'); +const assert = require('assert'); +const net = require('net'); + +// settings +const bytes = 1024 * 40; +const concurrency = 50; +const connections_per_client = 3; + +// measured +let total_connections = 0; + +const body = 'C'.repeat(bytes); + +const server = net.createServer(function(c) { + total_connections++; + console.log('connected', total_connections); + c.write(body); + c.end(); +}); + +function runClient(port, callback) { + const client = net.createConnection(port); + + client.connections = 0; + + client.setEncoding('utf8'); + + client.on('connect', function() { + console.log('c'); + client.recved = ''; + client.connections += 1; + }); + + client.on('data', function(chunk) { + this.recved += chunk; + }); + + client.on('end', function() { + client.end(); + }); + + client.on('error', function(e) { + console.log('\n\nERROOOOOr'); + throw e; + }); + + client.on('close', function(had_error) { + console.log('.'); + assert.strictEqual(had_error, false); + assert.strictEqual(client.recved.length, bytes); + + if (client.fd) { + console.log(client.fd); + } + assert.ok(!client.fd); + + if (this.connections < connections_per_client) { + this.connect(port); + } else { + callback(); + } + }); +} + +server.listen(0, function() { + let finished_clients = 0; + for (let i = 0; i < concurrency; i++) { + runClient(server.address().port, function() { + if (++finished_clients === concurrency) server.close(); + }); + } +}); + +process.on('exit', function() { + assert.strictEqual(total_connections, connections_per_client * concurrency); + console.log('\nokay!'); +}); diff --git a/tests/node_compat/test/pummel/test-net-pingpong-delay.js b/tests/node_compat/test/pummel/test-net-pingpong-delay.js new file mode 100644 index 0000000000..8eb3edfa24 --- /dev/null +++ b/tests/node_compat/test/pummel/test-net-pingpong-delay.js @@ -0,0 +1,114 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +function pingPongTest(host, on_complete) { + const N = 100; + const DELAY = 1; + let count = 0; + let client_ended = false; + + const server = net.createServer({ allowHalfOpen: true }, function(socket) { + socket.setEncoding('utf8'); + + socket.on('data', function(data) { + console.log(data); + assert.strictEqual(data, 'PING'); + assert.strictEqual(socket.readyState, 'open'); + assert.strictEqual(count <= N, true); + setTimeout(function() { + assert.strictEqual(socket.readyState, 'open'); + socket.write('PONG'); + }, DELAY); + }); + + socket.on('timeout', function() { + console.error('server-side timeout!!'); + assert.strictEqual(false, true); + }); + + socket.on('end', function() { + console.log('server-side socket EOF'); + assert.strictEqual(socket.readyState, 'writeOnly'); + socket.end(); + }); + + socket.on('close', function(had_error) { + console.log('server-side socket.end'); + assert.strictEqual(had_error, false); + assert.strictEqual(socket.readyState, 'closed'); + socket.server.close(); + }); + }); + + server.listen(0, host, common.mustCall(function() { + const client = net.createConnection(server.address().port, host); + + client.setEncoding('utf8'); + + client.on('connect', function() { + assert.strictEqual(client.readyState, 'open'); + client.write('PING'); + }); + + client.on('data', function(data) { + console.log(data); + assert.strictEqual(data, 'PONG'); + assert.strictEqual(client.readyState, 'open'); + + setTimeout(function() { + assert.strictEqual(client.readyState, 'open'); + if (count++ < N) { + client.write('PING'); + } else { + console.log('closing client'); + client.end(); + client_ended = true; + } + }, DELAY); + }); + + client.on('timeout', function() { + console.error('client-side timeout!!'); + assert.strictEqual(false, true); + }); + + client.on('close', common.mustCall(function() { + console.log('client.end'); + assert.strictEqual(count, N + 1); + assert.ok(client_ended); + if (on_complete) on_complete(); + })); + })); +} + +pingPongTest(); diff --git a/tests/node_compat/test/pummel/test-process-cpuUsage.js b/tests/node_compat/test/pummel/test-process-cpuUsage.js new file mode 100644 index 0000000000..b571e0ced8 --- /dev/null +++ b/tests/node_compat/test/pummel/test-process-cpuUsage.js @@ -0,0 +1,37 @@ +// 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. + +'use strict'; +require('../common'); +const assert = require('assert'); + +const start = process.cpuUsage(); + +// Run a busy-loop for specified # of milliseconds. +const RUN_FOR_MS = 500; + +// Define slop factor for checking maximum expected diff values. +const SLOP_FACTOR = 2; + +// Run a busy loop. +const now = Date.now(); +while (Date.now() - now < RUN_FOR_MS); + +// Get a diff reading from when we started. +const diff = process.cpuUsage(start); + +const MICROSECONDS_PER_MILLISECOND = 1000; + +// Diff usages should be >= 0, <= ~RUN_FOR_MS millis. +// Let's be generous with the slop factor, defined above, in case other things +// are happening on this CPU. The <= check may be invalid if the node process +// is making use of multiple CPUs, in which case, just remove it. +assert(diff.user >= 0); +assert(diff.user <= SLOP_FACTOR * RUN_FOR_MS * MICROSECONDS_PER_MILLISECOND); + +assert(diff.system >= 0); +assert(diff.system <= SLOP_FACTOR * RUN_FOR_MS * MICROSECONDS_PER_MILLISECOND); diff --git a/tests/node_compat/test/pummel/test-stream-pipe-multi.js b/tests/node_compat/test/pummel/test-stream-pipe-multi.js new file mode 100644 index 0000000000..979a722a54 --- /dev/null +++ b/tests/node_compat/test/pummel/test-stream-pipe-multi.js @@ -0,0 +1,129 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +// Test that having a bunch of streams piping in parallel +// doesn't break anything. + +require('../common'); +const assert = require('assert'); +const Stream = require('stream').Stream; +const rr = []; +const ww = []; +const cnt = 100; +const chunks = 1000; +const chunkSize = 250; +const data = Buffer.allocUnsafe(chunkSize); +let wclosed = 0; +let rclosed = 0; + +function FakeStream() { + Stream.apply(this); + this.wait = false; + this.writable = true; + this.readable = true; +} + +FakeStream.prototype = { __proto__: Stream.prototype }; + +FakeStream.prototype.write = function(chunk) { + console.error(this.ID, 'write', this.wait); + if (this.wait) { + process.nextTick(this.emit.bind(this, 'drain')); + } + this.wait = !this.wait; + return this.wait; +}; + +FakeStream.prototype.end = function() { + this.emit('end'); + process.nextTick(this.close.bind(this)); +}; + +// noop - closes happen automatically on end. +FakeStream.prototype.close = function() { + this.emit('close'); +}; + + +// Expect all streams to close properly. +process.on('exit', function() { + assert.strictEqual(wclosed, cnt); + assert.strictEqual(rclosed, cnt); +}); + +for (let i = 0; i < chunkSize; i++) { + data[i] = i; +} + +for (let i = 0; i < cnt; i++) { + const r = new FakeStream(); + r.on('close', function() { + console.error(this.ID, 'read close'); + rclosed++; + }); + rr.push(r); + + const w = new FakeStream(); + w.on('close', function() { + console.error(this.ID, 'write close'); + wclosed++; + }); + ww.push(w); + + r.ID = w.ID = i; + r.pipe(w); +} + +// Now start passing through data. +// Simulate a relatively fast async stream. +rr.forEach(function(r) { + let cnt = chunks; + let paused = false; + + r.on('pause', function() { + paused = true; + }); + + r.on('resume', function() { + paused = false; + step(); + }); + + function step() { + r.emit('data', data); + if (--cnt === 0) { + r.end(); + return; + } + if (paused) return; + process.nextTick(step); + } + + process.nextTick(step); +}); diff --git a/tests/node_compat/test/sequential/test-buffer-creation-regression.js b/tests/node_compat/test/sequential/test-buffer-creation-regression.js new file mode 100644 index 0000000000..d4b46fc894 --- /dev/null +++ b/tests/node_compat/test/sequential/test-buffer-creation-regression.js @@ -0,0 +1,43 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); + +function test(arrayBuffer, offset, length) { + const uint8Array = new Uint8Array(arrayBuffer, offset, length); + for (let i = 0; i < length; i += 1) { + uint8Array[i] = 1; + } + + const buffer = Buffer.from(arrayBuffer, offset, length); + for (let i = 0; i < length; i += 1) { + assert.strictEqual(buffer[i], 1); + } +} + +const acceptableOOMErrors = [ + 'Array buffer allocation failed', + 'Invalid array buffer length', +]; + +const length = 1000; +const offset = 4294967296; /* 1 << 32 */ +const size = offset + length; +let arrayBuffer; + +try { + arrayBuffer = new ArrayBuffer(size); +} catch (e) { + if (e instanceof RangeError && acceptableOOMErrors.includes(e.message)) + common.skip(`Unable to allocate ${size} bytes for ArrayBuffer`); + throw e; +} + +test(arrayBuffer, offset, length); diff --git a/tests/node_compat/test/sequential/test-http-server-keep-alive-timeout-slow-server.js b/tests/node_compat/test/sequential/test-http-server-keep-alive-timeout-slow-server.js new file mode 100644 index 0000000000..c07eae3f8d --- /dev/null +++ b/tests/node_compat/test/sequential/test-http-server-keep-alive-timeout-slow-server.js @@ -0,0 +1,57 @@ +// 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. + +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const server = http.createServer(common.mustCall((req, res) => { + if (req.url === '/first') { + res.end('ok'); + return; + } + setTimeout(() => { + res.end('ok'); + }, common.platformTimeout(500)); +}, 2)); + +server.keepAliveTimeout = common.platformTimeout(200); + +const agent = new http.Agent({ + keepAlive: true, + maxSockets: 1 +}); + +function request(path, callback) { + const port = server.address().port; + const req = http.request({ agent, path, port }, common.mustCall((res) => { + assert.strictEqual(res.statusCode, 200); + + res.setEncoding('utf8'); + + let result = ''; + res.on('data', (chunk) => { + result += chunk; + }); + + res.on('end', common.mustCall(() => { + assert.strictEqual(result, 'ok'); + callback(); + })); + })); + req.end(); +} + +server.listen(0, common.mustCall(() => { + request('/first', () => { + request('/second', () => { + server.close(); + }); + }); +})); diff --git a/tests/node_compat/test/sequential/test-net-better-error-messages-port.js b/tests/node_compat/test/sequential/test-net-better-error-messages-port.js new file mode 100644 index 0000000000..f718ca3f84 --- /dev/null +++ b/tests/node_compat/test/sequential/test-net-better-error-messages-port.js @@ -0,0 +1,24 @@ +// 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. + +'use strict'; +const common = require('../common'); +const net = require('net'); +const assert = require('assert'); + +const c = net.createConnection(common.PORT); + +c.on('connect', common.mustNotCall()); + +c.on('error', common.mustCall(function(error) { + // Family autoselection might be skipped if only a single address is returned by DNS. + const failedAttempt = Array.isArray(error.errors) ? error.errors[0] : error; + + assert.strictEqual(failedAttempt.code, 'ECONNREFUSED'); + assert.strictEqual(failedAttempt.port, common.PORT); + assert.match(failedAttempt.address, /^(127\.0\.0\.1|::1)$/); +})); diff --git a/tests/node_compat/test/sequential/test-net-connect-handle-econnrefused.js b/tests/node_compat/test/sequential/test-net-connect-handle-econnrefused.js new file mode 100644 index 0000000000..629705564b --- /dev/null +++ b/tests/node_compat/test/sequential/test-net-connect-handle-econnrefused.js @@ -0,0 +1,39 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const net = require('net'); +const assert = require('assert'); + +const c = net.createConnection(common.PORT); +c.on('connect', common.mustNotCall()); +c.on('error', common.mustCall((e) => { + assert.strictEqual(c.connecting, false); + assert.strictEqual(e.code, 'ECONNREFUSED'); +})); diff --git a/tests/node_compat/test/sequential/test-net-connect-local-error.js b/tests/node_compat/test/sequential/test-net-connect-local-error.js new file mode 100644 index 0000000000..d11ef37bc3 --- /dev/null +++ b/tests/node_compat/test/sequential/test-net-connect-local-error.js @@ -0,0 +1,53 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + +// EADDRINUSE is expected to occur on FreeBSD +// Ref: https://github.com/nodejs/node/issues/13055 +const expectedErrorCodes = ['ECONNREFUSED', 'EADDRINUSE']; + +const optionsIPv4 = { + port: common.PORT, + family: 4, + localPort: common.PORT + 1, + localAddress: common.localhostIPv4 +}; + +const optionsIPv6 = { + host: '::1', + family: 6, + port: common.PORT + 2, + localPort: common.PORT + 3, + localAddress: '::1', +}; + +function onError(err, options) { + assert.ok(expectedErrorCodes.includes(err.code)); + assert.strictEqual(err.syscall, 'connect'); + assert.strictEqual(err.localPort, options.localPort); + assert.strictEqual(err.localAddress, options.localAddress); + assert.strictEqual( + err.message, + `connect ${err.code} ${err.address}:${err.port} ` + + `- Local (${err.localAddress}:${err.localPort})` + ); +} + +const clientIPv4 = net.connect(optionsIPv4); +clientIPv4.on('error', common.mustCall((err) => onError(err, optionsIPv4))); + +if (!common.hasIPv6) { + common.printSkipMessage('ipv6 part of test, no IPv6 support'); + return; +} + +const clientIPv6 = net.connect(optionsIPv6); +clientIPv6.on('error', common.mustCall((err) => onError(err, optionsIPv6))); diff --git a/tests/node_compat/test/sequential/test-net-reconnect-error.js b/tests/node_compat/test/sequential/test-net-reconnect-error.js new file mode 100644 index 0000000000..450a0798bf --- /dev/null +++ b/tests/node_compat/test/sequential/test-net-reconnect-error.js @@ -0,0 +1,50 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const net = require('net'); +const assert = require('assert'); +const N = 20; +let disconnectCount = 0; + +const c = net.createConnection(common.PORT); + +c.on('connect', common.mustNotCall('client should not have connected')); + +c.on('error', common.mustCall((error) => { + // Family autoselection might be skipped if only a single address is returned by DNS. + const actualError = Array.isArray(error.errors) ? error.errors[0] : error; + + assert.strictEqual(actualError.code, 'ECONNREFUSED'); +}, N + 1)); + +c.on('close', common.mustCall(() => { + if (disconnectCount++ < N) + c.connect(common.PORT); // reconnect +}, N + 1)); diff --git a/tests/node_compat/test/sequential/test-net-response-size.js b/tests/node_compat/test/sequential/test-net-response-size.js new file mode 100644 index 0000000000..2c279aaad0 --- /dev/null +++ b/tests/node_compat/test/sequential/test-net-response-size.js @@ -0,0 +1,82 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +// Make sure the net module's server doesn't throw an error when handling +// responses that are either too long or too small (especially on Windows) +// https://github.com/nodejs/node-v0.x-archive/issues/1697 + +const net = require('net'); +const cp = require('child_process'); + +if (process.argv[2] === 'server') { + // Server + + const server = net.createServer(function(conn) { + conn.on('data', function(data) { + console.log(`server received ${data.length} bytes`); + }); + + conn.on('close', function() { + server.close(); + }); + }); + + server.listen(common.PORT, '127.0.0.1', function() { + console.log('Server running.'); + }); + +} else { + // Client + + const serverProcess = cp.spawn(process.execPath, [process.argv[1], 'server']); + serverProcess.stdout.pipe(process.stdout); + serverProcess.stderr.pipe(process.stdout); + + serverProcess.stdout.once('data', function() { + const client = net.createConnection(common.PORT, '127.0.0.1'); + client.on('connect', function() { + const alot = Buffer.allocUnsafe(1024); + const alittle = Buffer.allocUnsafe(1); + + for (let i = 0; i < 100; i++) { + client.write(alot); + } + + // Block the event loop for 1 second + const start = (new Date()).getTime(); + while ((new Date()).getTime() < start + 1000); + + client.write(alittle); + + client.destroySoon(); + }); + }); +} diff --git a/tests/node_compat/test/sequential/test-net-server-bind.js b/tests/node_compat/test/sequential/test-net-server-bind.js new file mode 100644 index 0000000000..7048c097d6 --- /dev/null +++ b/tests/node_compat/test/sequential/test-net-server-bind.js @@ -0,0 +1,71 @@ +// 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. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + + +// With only a callback, server should get a port assigned by the OS +{ + const server = net.createServer(common.mustNotCall()); + + server.listen(common.mustCall(function() { + assert.ok(server.address().port > 100); + server.close(); + })); +} + +// No callback to listen(), assume we can bind in 100 ms +{ + const server = net.createServer(common.mustNotCall()); + + server.listen(common.PORT); + + setTimeout(function() { + const address = server.address(); + assert.strictEqual(address.port, common.PORT); + + if (address.family === 'IPv6') + assert.strictEqual(server._connectionKey, `6::::${address.port}`); + else + assert.strictEqual(server._connectionKey, `4:0.0.0.0:${address.port}`); + + server.close(); + }, 100); +} + +// Callback to listen() +{ + const server = net.createServer(common.mustNotCall()); + + server.listen(common.PORT + 1, common.mustCall(function() { + assert.strictEqual(server.address().port, common.PORT + 1); + server.close(); + })); +} + +// Backlog argument +{ + const server = net.createServer(common.mustNotCall()); + + server.listen(common.PORT + 2, '0.0.0.0', 127, common.mustCall(function() { + assert.strictEqual(server.address().port, common.PORT + 2); + server.close(); + })); +} + +// Backlog argument without host argument +{ + const server = net.createServer(common.mustNotCall()); + + server.listen(common.PORT + 3, 127, common.mustCall(function() { + assert.strictEqual(server.address().port, common.PORT + 3); + server.close(); + })); +} diff --git a/tests/node_compat/test/sequential/test-tls-lookup.js b/tests/node_compat/test/sequential/test-tls-lookup.js new file mode 100644 index 0000000000..3801e3073e --- /dev/null +++ b/tests/node_compat/test/sequential/test-tls-lookup.js @@ -0,0 +1,41 @@ +// 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. + +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const tls = require('tls'); + +['foobar', 1, {}, []].forEach(function connectThrows(input) { + const opts = { + host: 'localhost', + port: common.PORT, + lookup: input + }; + + assert.throws(() => { + tls.connect(opts); + }, { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError' + }); +}); + +connectDoesNotThrow(common.mustCall()); + +function connectDoesNotThrow(input) { + const opts = { + host: 'localhost', + port: common.PORT, + lookup: input + }; + + tls.connect(opts); +} diff --git a/tests/node_compat/test/sequential/test-tls-psk-client.js b/tests/node_compat/test/sequential/test-tls-psk-client.js new file mode 100644 index 0000000000..89b13301f0 --- /dev/null +++ b/tests/node_compat/test/sequential/test-tls-psk-client.js @@ -0,0 +1,117 @@ +// 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. + +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); +if (!common.opensslCli) + common.skip('missing openssl cli'); + +const assert = require('assert'); +const tls = require('tls'); +const net = require('net'); +const { spawn } = require('child_process'); + +const CIPHERS = 'PSK+HIGH'; +const KEY = 'd731ef57be09e5204f0b205b60627028'; +const IDENTITY = 'Client_identity'; // Hardcoded by `openssl s_server` +const useIPv4 = !common.hasIPv6; + +const server = spawn(common.opensslCli, [ + 's_server', + '-accept', common.PORT, + '-cipher', CIPHERS, + '-psk', KEY, + '-psk_hint', IDENTITY, + '-nocert', + '-rev', + ...(useIPv4 ? ['-4'] : []), +], { encoding: 'utf8' }); +let serverErr = ''; +let serverOut = ''; +server.stderr.on('data', (data) => serverErr += data); +server.stdout.on('data', (data) => serverOut += data); +server.on('error', common.mustNotCall()); +server.on('exit', (code, signal) => { + // Server is expected to be terminated by cleanUp(). + assert.strictEqual(code, null, + `'${server.spawnfile} ${server.spawnargs.join(' ')}' unexpected exited with output:\n${serverOut}\n${serverErr}`); + assert.strictEqual(signal, 'SIGTERM'); +}); + +const cleanUp = (err) => { + clearTimeout(timeout); + if (err) + console.log('Failed:', err); + server.kill(); + process.exitCode = err ? 1 : 0; +}; + +const timeout = setTimeout(() => cleanUp('Timed out'), 5000); + +function waitForPort(port, cb) { + const socket = net.connect(common.PORT, () => { + socket.on('data', () => {}); + socket.end(); + socket.on('end', cb); + }); + socket.on('error', (e) => { + if (e.code === 'ENOENT' || e.code === 'ECONNREFUSED') { + setTimeout(() => waitForPort(port, cb), 1000); + } else { + cb(e); + } + }); +} + +waitForPort(common.PORT, common.mustCall((err) => { + if (err) { + cleanUp(err); + return; + } + + const message = 'hello'; + const reverse = message.split('').reverse().join(''); + runClient(message, common.mustCall((err, data) => { + try { + if (!err) assert.strictEqual(data.trim(), reverse); + } finally { + cleanUp(err); + } + })); +})); + +function runClient(message, cb) { + const s = tls.connect(common.PORT, { + ciphers: CIPHERS, + checkServerIdentity: () => {}, + pskCallback(hint) { + // 'hint' will be null in TLS1.3. + if (hint === null || hint === IDENTITY) { + return { + identity: IDENTITY, + psk: Buffer.from(KEY, 'hex') + }; + } + } + }); + s.on('secureConnect', common.mustCall(() => { + let data = ''; + s.on('data', common.mustCallAtLeast((d) => { + data += d; + })); + s.on('end', common.mustCall(() => { + cb(null, data); + })); + s.end(message); + })); + s.on('error', (e) => { + cb(e); + }); +} diff --git a/tests/node_compat/test/sequential/test-tls-securepair-client.js b/tests/node_compat/test/sequential/test-tls-securepair-client.js new file mode 100644 index 0000000000..eed5b221c4 --- /dev/null +++ b/tests/node_compat/test/sequential/test-tls-securepair-client.js @@ -0,0 +1,193 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +const common = require('../common'); + +if (!common.opensslCli) + common.skip('node compiled without OpenSSL CLI.'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (common.isWindows) + common.skip('test does not work on Windows'); // ...but it should! + +const net = require('net'); +const assert = require('assert'); +const fixtures = require('../common/fixtures'); +const tls = require('tls'); +const spawn = require('child_process').spawn; + +const useIPv4 = !common.hasIPv6; + +test1(); + +// simple/test-tls-securepair-client +function test1() { + test('keys/rsa_private.pem', 'keys/rsa_cert.crt', null, test2); +} + +// simple/test-tls-ext-key-usage +function test2() { + function check(pair) { + // "TLS Web Client Authentication" + assert.strictEqual(pair.cleartext.getPeerCertificate().ext_key_usage.length, + 1); + assert.strictEqual(pair.cleartext.getPeerCertificate().ext_key_usage[0], + '1.3.6.1.5.5.7.3.2'); + } + test('keys/agent4-key.pem', 'keys/agent4-cert.pem', check); +} + +function test(keyPath, certPath, check, next) { + const key = fixtures.readSync(keyPath).toString(); + const cert = fixtures.readSync(certPath).toString(); + + const server = spawn(common.opensslCli, ['s_server', + '-accept', 0, + '-cert', fixtures.path(certPath), + '-key', fixtures.path(keyPath), + ...(useIPv4 ? ['-4'] : []), + ]); + server.stdout.pipe(process.stdout); + server.stderr.pipe(process.stdout); + + + let state = 'WAIT-ACCEPT'; + + let serverStdoutBuffer = ''; + server.stdout.setEncoding('utf8'); + server.stdout.on('data', function(s) { + serverStdoutBuffer += s; + console.log(state); + switch (state) { + case 'WAIT-ACCEPT': { + const matches = serverStdoutBuffer.match(/ACCEPT .*?:(\d+)/); + if (matches) { + const port = matches[1]; + state = 'WAIT-HELLO'; + startClient(port); + } + break; + } + case 'WAIT-HELLO': + if (/hello/.test(serverStdoutBuffer)) { + + // End the current SSL connection and exit. + // See s_server(1ssl). + server.stdin.write('Q'); + + state = 'WAIT-SERVER-CLOSE'; + } + break; + + default: + break; + } + }); + + + const timeout = setTimeout(function() { + server.kill(); + process.exit(1); + }, 5000); + + let gotWriteCallback = false; + let serverExitCode = -1; + + server.on('exit', function(code) { + serverExitCode = code; + clearTimeout(timeout); + if (next) next(); + }); + + + function startClient(port) { + const s = new net.Stream(); + + const sslcontext = tls.createSecureContext({ key, cert }); + sslcontext.context.setCiphers('RC4-SHA:AES128-SHA:AES256-SHA'); + + const pair = tls.createSecurePair(sslcontext, false); + + assert.ok(pair.encrypted.writable); + assert.ok(pair.cleartext.writable); + + pair.encrypted.pipe(s); + s.pipe(pair.encrypted); + + s.connect(port); + + s.on('connect', function() { + console.log('client connected'); + setTimeout(function() { + pair.cleartext.write('hello\r\n', function() { + gotWriteCallback = true; + }); + }, 500); + }); + + pair.on('secure', function() { + console.log('client: connected+secure!'); + console.log('client pair.cleartext.getPeerCertificate(): %j', + pair.cleartext.getPeerCertificate()); + console.log('client pair.cleartext.getCipher(): %j', + pair.cleartext.getCipher()); + if (check) check(pair); + }); + + pair.cleartext.on('data', function(d) { + console.log('cleartext: %s', d.toString()); + }); + + s.on('close', function() { + console.log('client close'); + }); + + pair.encrypted.on('error', function(err) { + console.log(`encrypted error: ${err}`); + }); + + s.on('error', function(err) { + console.log(`socket error: ${err}`); + }); + + pair.on('error', function(err) { + console.log(`secure error: ${err}`); + }); + } + + + process.on('exit', function() { + assert.strictEqual(serverExitCode, 0); + assert.strictEqual(state, 'WAIT-SERVER-CLOSE'); + assert.ok(gotWriteCallback); + }); +} diff --git a/tests/node_compat/test/sequential/test-tls-session-timeout.js b/tests/node_compat/test/sequential/test-tls-session-timeout.js new file mode 100644 index 0000000000..b8d03c17ae --- /dev/null +++ b/tests/node_compat/test/sequential/test-tls-session-timeout.js @@ -0,0 +1,140 @@ +// 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. + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); + +if (!common.opensslCli) + common.skip('node compiled without OpenSSL CLI.'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); + +doTest(); + +// This test consists of three TLS requests -- +// * The first one should result in a new connection because we don't have +// a valid session ticket. +// * The second one should result in connection resumption because we used +// the session ticket we saved from the first connection. +// * The third one should result in a new connection because the ticket +// that we used has expired by now. + +function doTest() { + const assert = require('assert'); + const tls = require('tls'); + const fs = require('fs'); + const fixtures = require('../common/fixtures'); + const spawn = require('child_process').spawn; + + const SESSION_TIMEOUT = 1; + + const key = fixtures.readKey('rsa_private.pem'); + const cert = fixtures.readKey('rsa_cert.crt'); + const options = { + key: key, + cert: cert, + ca: [cert], + sessionTimeout: SESSION_TIMEOUT, + maxVersion: 'TLSv1.2', + }; + + // We need to store a sample session ticket in the fixtures directory because + // `s_client` behaves incorrectly if we do not pass in both the `-sess_in` + // and the `-sess_out` flags, and the `-sess_in` argument must point to a + // file containing a proper serialization of a session ticket. + // To avoid a source control diff, we copy the ticket to a temporary file. + + const sessionFileName = (function() { + const ticketFileName = 'tls-session-ticket.txt'; + const tmpPath = tmpdir.resolve(ticketFileName); + fs.writeFileSync(tmpPath, fixtures.readSync(ticketFileName)); + return tmpPath; + }()); + + // Expects a callback -- cb(connectionType : enum ['New'|'Reused']) + + function Client(cb) { + const flags = [ + 's_client', + '-connect', `localhost:${common.PORT}`, + '-sess_in', sessionFileName, + '-sess_out', sessionFileName, + ]; + const client = spawn(common.opensslCli, flags, { + stdio: ['ignore', 'pipe', 'ignore'] + }); + + let clientOutput = ''; + client.stdout.on('data', (data) => { + clientOutput += data.toString(); + }); + client.on('exit', (code) => { + let connectionType; + const grepConnectionType = (line) => { + const matches = line.match(/(New|Reused), /); + if (matches) { + connectionType = matches[1]; + return true; + } + }; + const lines = clientOutput.split('\n'); + if (!lines.some(grepConnectionType)) { + throw new Error('unexpected output from openssl client'); + } + assert.strictEqual(code, 0); + cb(connectionType); + }); + } + + const server = tls.createServer(options, (cleartext) => { + cleartext.on('error', (er) => { + if (er.code !== 'ECONNRESET') + throw er; + }); + cleartext.end(); + }); + + server.listen(common.PORT, () => { + Client((connectionType) => { + assert.strictEqual(connectionType, 'New'); + Client((connectionType) => { + assert.strictEqual(connectionType, 'Reused'); + setTimeout(() => { + Client((connectionType) => { + assert.strictEqual(connectionType, 'New'); + server.close(); + }); + }, (SESSION_TIMEOUT + 1) * 1000); + }); + }); + }); +}