Skip to content

test(dgram): expand Node 26.5.0 parity coverage - #6894

Open
TheHypnoo wants to merge 3 commits into
mainfrom
test/expand-node-dgram-parity
Open

test(dgram): expand Node 26.5.0 parity coverage#6894
TheHypnoo wants to merge 3 commits into
mainfrom
test/expand-node-dgram-parity

Conversation

@TheHypnoo

@TheHypnoo TheHypnoo commented Jul 27, 2026

Copy link
Copy Markdown
Member

Summary

Expands granular node:dgram parity coverage from 38 to 54 deterministic fixtures using Node 26.5.0 as the oracle and pinned Deno/Bun sources as comparison evidence.

Changes

  • Add 16 focused fixtures for API shape, descriptors, receiver checks, synchronous bind/connect, disposal, lookup, IPv6, callback receiver, and scatter ownership.
  • Move socket cleanup into finally across the suite and remove persistent listeners after each contract settles.
  • Replace external DNS, fixed-port, and real multicast paths with loopback, ephemeral ports, and validation-only probes.
  • Record per-fixture Node/Deno/Bun evidence, exclusions, reproducible commands, and the repeated Perry baseline of 18/54.

Related issue

n/a

Test plan

  • cargo build --release -p perry
  • Node 26.5.0: 54/54, three stable runs
  • Perry: 18/54 with 36 stable diffs, three clean runs
  • Deno 2.9.3: 35 match / 9 diff / 10 error, three stable runs
  • Bun 1.2.18: 37 match / 16 diff / 1 error, three stable runs
  • deno fmt --check on all 54 fixtures
  • baseline JSON and git diff --check
  • cargo build --release for the whole workspace was not run; the affected perry package build passes
  • workspace tests were not run; this change only updates the focused parity suite
  • cargo fmt --all -- --check stops on unchanged main formatting in collect_modules.rs
  • ./scripts/check_file_size.sh stops on unchanged oversized object/mod.rs and readline.rs

Screenshots / output

dgram                    18     54   33.3  diff=36

Checklist

  • I have NOT bumped the workspace version or edited CLAUDE.md / CHANGELOG.md
  • My commits follow the repository's conventional commit style
  • I've read CONTRIBUTING.md and agree to the Code of Conduct

Summary by CodeRabbit

  • New Features
    • Expanded UDP socket parity coverage with 16 new checks, including IPv6 loopback, synchronous bind/connect, async disposal, export/descriptor shape, and send/receiver validation scenarios.
  • Documentation
    • Reworked dgram parity documentation with pinned oracle references, fixture mapping, repeated-run results, explicit exclusions, and exact verification commands.
  • Tests
    • Updated the dgram baseline totals from 38 to 54 checks while keeping 18 passing results.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR expands node:dgram parity coverage with new API, lifecycle, IPv6, send, and validation fixtures; hardens socket and listener cleanup; documents pinned oracle results and verification; and raises the dgram baseline total from 38 to 54.

Changes

node:dgram parity coverage

Layer / File(s) Summary
Oracle documentation and baseline
test-parity/node-suite/dgram/STATUS.md, test-parity/node_suite_baseline.json
Documents the Node.js 26.5.0 oracle, fixture map, repeated results, verification harness, exclusions, and updated baseline total.
API and networking contracts
test-parity/node-suite/dgram/api/*, connection/*, control/*, default-import-shape.ts, ipv6-loopback.ts
Adds export, socket identity, descriptor, receiver validation, connection, control, import-shape, and IPv6 loopback coverage.
Socket lifecycle coverage
test-parity/node-suite/dgram/lifecycle/*
Adds bind, close, lookup, disposal, abort, conflict, retry, and post-close cases while guaranteeing teardown.
Controls and unicast behavior
test-parity/node-suite/dgram/metrics/*, multicast-membership.ts, socket-controls.ts, unicast-loopback.ts
Hardens metrics, membership, socket-control, and unicast fixtures with deterministic cleanup and listener removal.
Send and validation contracts
test-parity/node-suite/dgram/send/*, validation/*
Adds and restructures send, callback, overload, blocklist, address, buffer, scatter-copy, and invalid-argument coverage.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

Possibly related PRs

  • PerryTS/perry#6442 — Strong overlap with the dgram documentation and several fixtures revised here.

Suggested labels: ready

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main change: expanding dgram parity coverage against Node 26.5.0.
Description check ✅ Passed The description follows the template well, covering summary, changes, related issue, test plan, output, and checklist.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/expand-node-dgram-parity

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test-parity/node-suite/dgram/lifecycle/bind-overloads.ts`:
- Around line 3-4: Add explicit test cases in bind-overloads.ts for the
no-argument bind() overload and the bind(port, callback) overload, alongside the
existing "port-address" and "options" modes. Ensure each case creates and binds
a UDP4 socket and preserves the suite’s existing lifecycle assertions and
cleanup.

In `@test-parity/node-suite/dgram/validation/message-views.ts`:
- Around line 37-61: The scatter test currently awaits scatterReceived before
determining whether send succeeded, which can hang when the callback reports an
error. In the scatterResult === "none" branch, await scatterCallback first,
inspect its success outcome, and only await scatterReceived when delivery
succeeded; preserve the existing logging and callback result reporting.

In `@test-parity/node-suite/dgram/validation/send-arguments.ts`:
- Around line 30-33: Update the cleanup logic in the send-argument validation
flow to call socket.bind only when the socket was not already implicitly or
explicitly bound by socket.send/socket.sendto. Track the socket’s bound or
established state during the probe, then conditionally bind before socket.close
in the finally block so ERR_SOCKET_ALREADY_BOUND cannot mask the validation
result.

In `@test-parity/node-suite/dgram/validation/sendto.ts`:
- Around line 36-39: Update the finally block in the sendto validation test to
remove the unconditional socket.bind call and close the already-bound socket
directly with socket.close(resolve), ensuring cleanup does not mask failures
from the sendto checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 555455c6-9ccf-4de8-9583-d4629f9889f8

📥 Commits

Reviewing files that changed from the base of the PR and between 5b4e70e and 6578a89.

📒 Files selected for processing (56)
  • test-parity/node-suite/dgram/STATUS.md
  • test-parity/node-suite/dgram/api/export-shape.ts
  • test-parity/node-suite/dgram/api/receiver-validation.ts
  • test-parity/node-suite/dgram/api/socket-aliases.ts
  • test-parity/node-suite/dgram/api/socket-class.ts
  • test-parity/node-suite/dgram/api/socket-descriptors.ts
  • test-parity/node-suite/dgram/connection/connect-ordering.ts
  • test-parity/node-suite/dgram/connection/connect-sync.ts
  • test-parity/node-suite/dgram/connection/state-transitions.ts
  • test-parity/node-suite/dgram/control/ttl-validation.ts
  • test-parity/node-suite/dgram/default-import-shape.ts
  • test-parity/node-suite/dgram/ipv6-loopback.ts
  • test-parity/node-suite/dgram/lifecycle/abort-signal.ts
  • test-parity/node-suite/dgram/lifecycle/async-dispose-lifecycle.ts
  • test-parity/node-suite/dgram/lifecycle/async-dispose-shape.ts
  • test-parity/node-suite/dgram/lifecycle/bind-conflict.ts
  • test-parity/node-suite/dgram/lifecycle/bind-error-details.ts
  • test-parity/node-suite/dgram/lifecycle/bind-error-retry.ts
  • test-parity/node-suite/dgram/lifecycle/bind-overloads.ts
  • test-parity/node-suite/dgram/lifecycle/bind-state.ts
  • test-parity/node-suite/dgram/lifecycle/bind-sync.ts
  • test-parity/node-suite/dgram/lifecycle/close-arguments.ts
  • test-parity/node-suite/dgram/lifecycle/close-ordering.ts
  • test-parity/node-suite/dgram/lifecycle/closed-state.ts
  • test-parity/node-suite/dgram/lifecycle/custom-lookup.ts
  • test-parity/node-suite/dgram/lifecycle/default-lookup.ts
  • test-parity/node-suite/dgram/metrics/buffer-sizes.ts
  • test-parity/node-suite/dgram/metrics/create-socket-buffer-options.ts
  • test-parity/node-suite/dgram/metrics/queue-and-ref.ts
  • test-parity/node-suite/dgram/multicast-membership.ts
  • test-parity/node-suite/dgram/send/blocklist.ts
  • test-parity/node-suite/dgram/send/buffer-range.ts
  • test-parity/node-suite/dgram/send/callback-ordering.ts
  • test-parity/node-suite/dgram/send/callback-receiver.ts
  • test-parity/node-suite/dgram/send/connected-overloads.ts
  • test-parity/node-suite/dgram/send/create-socket-listener.ts
  • test-parity/node-suite/dgram/send/default-address-values.ts
  • test-parity/node-suite/dgram/send/default-host.ts
  • test-parity/node-suite/dgram/send/empty-and-multiple.ts
  • test-parity/node-suite/dgram/send/empty-array.ts
  • test-parity/node-suite/dgram/send/error-routing.ts
  • test-parity/node-suite/dgram/send/implicit-bind-state.ts
  • test-parity/node-suite/dgram/send/ipv6-default-host.ts
  • test-parity/node-suite/dgram/send/overloads.ts
  • test-parity/node-suite/dgram/send/scatter-copy.ts
  • test-parity/node-suite/dgram/socket-controls.ts
  • test-parity/node-suite/dgram/unicast-loopback.ts
  • test-parity/node-suite/dgram/validation/address-arguments.ts
  • test-parity/node-suite/dgram/validation/buffer-bounds.ts
  • test-parity/node-suite/dgram/validation/connected-send-arguments.ts
  • test-parity/node-suite/dgram/validation/create-socket-advanced-options.ts
  • test-parity/node-suite/dgram/validation/create-socket-options.ts
  • test-parity/node-suite/dgram/validation/message-views.ts
  • test-parity/node-suite/dgram/validation/send-arguments.ts
  • test-parity/node-suite/dgram/validation/sendto.ts
  • test-parity/node_suite_baseline.json

Comment on lines +3 to 4
for (const mode of ["port-address", "options"] as const) {
const socket = dgram.createSocket("udp4");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check whether default/port-only bind overloads are covered elsewhere in the dgram suite
rg -n '\.bind\(\)' test-parity/node-suite/dgram -g '*.ts'
rg -n '\.bind\(0\)' test-parity/node-suite/dgram -g '*.ts'
rg -n '\.bind\(0,\s*(undefined)?\)' test-parity/node-suite/dgram -g '*.ts'

Repository: PerryTS/perry

Length of output: 151


🏁 Script executed:

#!/bin/bash
set -u

printf 'Files under dgram suite:\n'
git ls-files 'test-parity/node-suite/dgram/*.ts' | sed -n '1,120p'

printf '\nAll bind calls in dgram TypeScript fixtures:\n'
rg -n --color=never -C 3 '\.bind\s*\(' test-parity/node-suite/dgram -g '*.ts' || true

printf '\nRelevant fixture snippets:\n'
for f in test-parity/node-suite/dgram/bind-overloads.ts test-parity/node-suite/dgram/bind-sync.ts test-parity/node-suite/dgram/bind-state.ts; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    wc -l "$f"
    sed -n '1,220p' "$f"
  fi
done

Repository: PerryTS/perry

Length of output: 38448


🌐 Web query:

Node.js dgram Socket bind port-only overload behavior bind(port callback)

💡 Result:

In Node.js, the dgram.Socket.bind method provides an overloaded signature, socket.bind([port][, address][, callback]), where parameters are optional [1][2]. When you use the overload that accepts only a port and a callback, specifically socket.bind(port, callback), the behavior is as follows: 1. Port Binding: The socket attempts to listen for datagram messages on the specified port [1]. If the port is 0, the operating system assigns a random available port [1][2]. 2. Address Assignment: Because the address parameter is omitted in this overload, the operating system defaults to listening on all available network interfaces (typically 0.0.0.0 for IPv4 or:: for IPv6) [1][2]. 3. Callback Execution: The callback function is invoked once the binding process is complete [1]. It receives no parameters [1]. 4. Event Emission: Upon successful binding, the socket also emits a 'listening' event [1][2]. Node.js documentation notes that while you can use both a 'listening' event listener and the callback, doing so is generally considered redundant or not very useful [1][2]. If the binding operation fails—for example, if the port is already in use—an 'error' event is generated on the socket object [1][2]. In rare circumstances, such as attempting to bind a socket that has already been closed, the method may throw an Error [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -u

printf 'All non-bind helper bind calls in dgram TypeScript fixtures:\n'
python3 - <<'PY'
import subprocess, pathlib, re

files = subprocess.check_output(["git", "ls-files", "test-parity/node-suite/dgram/*.ts"], text=True).splitlines()
patterns = {
    'no_args': re.compile(r'bind\s*\(\s*\)'),
    'port_only': re.compile(r'bind\s*\(\s*-?\d+|0\s*\)') if False else re.compile(r'bind\s*\(\s*-?\d+\b[^,\n]*\)'),  # broad filter only
}
for f in files:
    for i, line in enumerate(pathlib.Path(f).read_text(errors='replace').splitlines(), 1):
        if '.bind(' in line or 'bind(' in line and not line.strip().startswith('//') and not line.strip().startswith('#'):
            print(f"{f}:{i}:{line.strip()}")
PY

printf '\nRelevant lifecycle bind fixture snippets:\n'
for f in test-parity/node-suite/dgram/lifecycle/bind-sync.ts test-parity/node-suite/dgram/lifecycle/bind-state.ts test-parity/node-suite/dgram/lifecycle/bind-overloads.ts; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    wc -l "$f"
    sed -n '1,180p' "$f"
  fi
done

Repository: PerryTS/perry

Length of output: 11008


Add coverage for the omitted bind overload shapes.

bind-overloads.ts now only exercises bind(port, address, callback) and bind(options, callback). The suite needs explicit fixtures or cases for bind() and bind(port, callback) so bind() overload coverage is not reduced.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test-parity/node-suite/dgram/lifecycle/bind-overloads.ts` around lines 3 - 4,
Add explicit test cases in bind-overloads.ts for the no-argument bind() overload
and the bind(port, callback) overload, alongside the existing "port-address" and
"options" modes. Ensure each case creates and binds a UDP4 socket and preserves
the suite’s existing lifecycle assertions and cleanup.

Comment thread test-parity/node-suite/dgram/validation/message-views.ts
Comment thread test-parity/node-suite/dgram/validation/send-arguments.ts
Comment thread test-parity/node-suite/dgram/validation/sendto.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test-parity/node-suite/dgram/validation/send-arguments.ts`:
- Line 16: Update the Promise around socket.bind in the validation test to
resolve on the one-shot listening event and reject on the one-shot error event,
removing both listeners after either outcome. Ensure bind failures settle the
Promise so the existing finally cleanup can close the socket.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 99d34f0d-52c9-4e2d-97b6-362970b69568

📥 Commits

Reviewing files that changed from the base of the PR and between 6578a89 and 3621219.

📒 Files selected for processing (3)
  • test-parity/node-suite/dgram/validation/message-views.ts
  • test-parity/node-suite/dgram/validation/send-arguments.ts
  • test-parity/node-suite/dgram/validation/sendto.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • test-parity/node-suite/dgram/validation/message-views.ts
  • test-parity/node-suite/dgram/validation/sendto.ts


await new Promise<void>((resolve) => socket.close(() => resolve()));
try {
await new Promise<void>((resolve) => socket.bind(0, "127.0.0.1", resolve));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

fd -a 'send-arguments\.ts$' . || true
file="$(fd 'send-arguments\.ts$' . | head -n 1 || true)"
if [ -n "${file:-}" ]; then
  echo "FILE=$file"
  wc -l "$file"
  echo "---"
  cat -n "$file"
fi

echo "--- tests around bind ---"
rg -n "bind\\(|error\\(|listen|finally|cleanup|close" test-parity/node-suite/dgram/validation/send-arguments.ts test-parity/node-suite/dgram -S || true

Repository: PerryTS/perry

Length of output: 36526


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="$(fd 'send-arguments\.ts$' . | head -n 1 || true)"
if [ -n "${file:-}" ]; then
  echo "FILE=$file"
  wc -l "$file"
  echo "---"
  cat -n "$file"
fi

echo "--- tests around bind ---"
rg -n "bind\\(|error\\(|listen|finally|cleanup|close" test-parity/node-suite/dgram/validation/send-arguments.ts test-parity/node-suite/dgram -S || true

Repository: PerryTS/perry

Length of output: 36362


Reject the bind Promise on socket errors.

If socket.bind() fails, Node emits an 'error' event rather than invoking the listening callback. The current Promise therefore never settles, and the finally cleanup may not close the socket. Use one-shot listening/error listeners and remove them after either outcome.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test-parity/node-suite/dgram/validation/send-arguments.ts` at line 16, Update
the Promise around socket.bind in the validation test to resolve on the one-shot
listening event and reject on the one-shot error event, removing both listeners
after either outcome. Ensure bind failures settle the Promise so the existing
finally cleanup can close the socket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant