test(parity): add node:process granular suite - #1331
Merged
Conversation
proggeramlug
force-pushed
the
feat/process-node-suite
branch
2 times, most recently
from
May 22, 2026 11:42
11ff9b1 to
bab130d
Compare
Contributor
Author
|
Final-pass update: suite is now 52 cases, 28 pass. Added kill/chdir/debugPort/argv[1] (pass) and report/connected/memoryUsage.rss/getBuiltinModule/loadEnvFile/sourceMapsEnabled/title-set (gaps → #1395–#1401). Every failure maps to a granular issue in known_failures.json; cross-checked no stale/untracked. |
proggeramlug
added a commit
that referenced
this pull request
May 22, 2026
…sweep (#1414) Rolls up 26 PRs that merged to main post-v0.5.1023 without version bumps: - node:crypto gap-fixes (#1386 #1393 #1394 #1402 #1405): randomInt, timingSafeEqual, getHashes/getCiphers, sha224/sha384, base64 digest, Buffer hash input, no-arg digest() → Buffer, pbkdf2Sync digest arg, scryptSync. - node:perf_hooks (#1321 + #1328 #1342 coverage): performance + User Timing + PerformanceObserver native impl, granular node-suite + edge-case coverage. - #1090 GC checkpoint runtime work (#1324). - #1311 geisterhand on iOS (#1316 #1383 #1384 #1385). - #1312 process.env.X (unset) is nullish undefined (#1314). - #1319 thread-safety hardening for cross-thread runtime statics. - #1322 exact-head GC evidence packet. - #1323 wasm timers dispatch through mem_call bridge (#1329). - #1317 node:timers/promises shadow-segfault fix (#1326). - #1330 node:process suite (#1331). - #1292 bcrypt.hash() returns String (#1307). - #1293 fastify .json()/.body external-fastify dispatch (#1308). - #1296 app pattern performance gaps. - #1297 diagnostics_channel parity. - #1301 iOS App Groups capability (#1313). - #1318 #1325 os/methods/modern-methods static dispatch. - #1315 expanded Node parity test coverage. - #1382 ui-ios stdlib pump for async fetch. - #1392 ui-wasm reactive state + setText (#1404).
proggeramlug
added a commit
that referenced
this pull request
May 23, 2026
…test global-timer pollution CI flake on #1331 (`event_pump::tests::wait_returns_when_timer_due` returning in 426µs instead of ~50ms). `js_wait_for_event`'s wait budget is derived from GLOBAL timer state and `SERIAL` only serializes the event_pump tests against each other — a concurrently-running non-serialized test (a timer/promise test in another module) can inject a sooner deadline or notify and shorten any single measurement. Pollution never lengthens a wait past its 50ms budget, so a working wait blocks ~50ms on at least one un-polluted attempt. Replace the single-shot measurement with the file's established retry-until-clean shape (same as `sustained_budget_zero_spin_is_throttled`): drain leaked timer/notify state at the start of each attempt, schedule our 50ms timer, measure, and accept the test as soon as one attempt lands in [40ms, 500ms). Stays deterministic against a real budget bug (which would return early on *every* attempt) while tolerating the cross-test race. Verified: full multi-threaded `cargo test -p perry-runtime` passes (wait_returns_when_timer_due OK); 5× targeted stress all green.
This was referenced May 23, 2026
proggeramlug
force-pushed
the
feat/process-node-suite
branch
from
May 23, 2026 09:36
a084b37 to
a83ac81
Compare
proggeramlug
added a commit
that referenced
this pull request
May 23, 2026
…e_parity.sh First exhaustive node:process suite on main: 60 granular cases (39 pass / 22 fail) covering shape, platform, env, cwd, version + versions sub-fields, argv, nextTick, hrtime + bigint, props, memory + rss + available, cpu + threadCpuUsage, uptime, stdout/stderr fds + write, global identity, release, exec-argv, exit + exit-code, events (on/emit/listeners), methods (umask/abort/emit-warning/kill/chdir/get-builtin-module/load-env-file/ source-maps-enabled/dlopen/ref-unref/exit), resource (usage + active), features, config, ipc (connected/send-disconnect), report, allowed flags, title, sub-fields, unix uid/gid, module-load-list, finalization, exception uncaught-capture, shapes ppid/debug-port/method-types/process-object/ module-load-list, exit-code, hrtime tuple form. 22 failing cases tracked in known_failures.json with granular per-gap issue references. Method-value reflection (#1343), env-write (#1344), hrtime() tuple (#1345), and argv0/execPath/title (#1346) were originally fixed in #1371 but that PR merged into the #1331 branch only — #1331 was rebased onto current main and those fixes were dropped; the issues are reopened. Adds run_module_parity.sh: thin wrapper that runs ./run_parity_tests.sh --suite node-suite --module <m> for a list of modules (default: process + perf_hooks) and prints a combined per-module + total summary.
…e_parity.sh First exhaustive node:process suite on main: 60 granular cases (39 pass / 22 fail) covering shape, platform, env, cwd, version + versions sub-fields, argv, nextTick, hrtime + bigint, props, memory + rss + available, cpu + threadCpuUsage, uptime, stdout/stderr fds + write, global identity, release, exec-argv, exit + exit-code, events (on/emit/listeners), methods (umask/abort/emit-warning/kill/chdir/get-builtin-module/load-env-file/ source-maps-enabled/dlopen/ref-unref/exit), resource (usage + active), features, config, ipc (connected/send-disconnect), report, allowed flags, title, sub-fields, unix uid/gid, module-load-list, finalization, exception uncaught-capture, shapes ppid/debug-port/method-types/process-object/ module-load-list, exit-code, hrtime tuple form. 22 failing cases tracked in known_failures.json with granular per-gap issue references. Method-value reflection (#1343), env-write (#1344), hrtime() tuple (#1345), and argv0/execPath/title (#1346) were originally fixed in onto current main and those fixes were dropped; the issues are reopened. Adds run_module_parity.sh: thin wrapper that runs ./run_parity_tests.sh --suite node-suite --module <m> for a list of modules (default: process + perf_hooks) and prints a combined per-module + total summary.
proggeramlug
force-pushed
the
feat/process-node-suite
branch
from
May 23, 2026 09:39
a83ac81 to
63014c4
Compare
2 tasks
proggeramlug
added a commit
that referenced
this pull request
May 23, 2026
Node's `process.dlopen(module, filename, flags?)` is the native-addon (.node) loader. Perry was reading it as a bare number, so `typeof process.dlopen === "function"` returned false and call sites crashed with "value is not a function". Perry statically links every dependency at compile time — there's no dynamic loader to wire up. The closest no-op is to return undefined: optional-dep wrappers that feature-detect on `typeof process.dlopen === "function"` first see a "loaded" non-error and fall back to their pure-JS path; real addon-loading attempts surface as undefined exports downstream. - Call lowering (`native_module.rs`): folds to `Expr::Undefined`, sitting next to the `ref` / `unref` / `setSourceMapsEnabled` / `getBuiltinModule` arms. - Typeof fold (`lower_expr.rs`): adds `dlopen` to the same process-method-as-function list. Test: test-parity/node-suite/process/methods/dlopen.ts (already in the granular suite from #1331) now passes — byte-identical to `node --experimental-strip-types`.
2 tasks
proggeramlug
added a commit
that referenced
this pull request
May 23, 2026
Node exposes `process.hasUncaughtExceptionCaptureCallback()` (boolean getter) + `process.setUncaughtExceptionCaptureCallback(fn|null)` (installs/clears a single capture callback that intercepts uncaught exceptions before the `uncaughtException` event fires). Perry was reading both as bare numbers — `typeof` lied with `"number"` and any call crashed with "value is not a function". Perry doesn't expose the underlying capture hook, so both behave as no-ops: - `hasUncaughtExceptionCaptureCallback()` → `Expr::Bool(false)`. - `setUncaughtExceptionCaptureCallback(fn|null)` → `Expr::Undefined`. Both names are added to the typeof-fold list in `lower_expr.rs` so feature-detection (`typeof process.X === "function"`) returns `"function"`, sitting next to the `ref` / `unref` / `setSourceMapsEnabled` / `getBuiltinModule` / `dlopen` arms. Test: test-parity/node-suite/process/exception/uncaught-capture.ts (in the granular suite from #1331) now passes — byte-identical to `node --experimental-strip-types`.
2 tasks
proggeramlug
added a commit
that referenced
this pull request
May 23, 2026
…1344) (#1504) Pre-fix `process.env.X = v` hit the generic `js_object_set_field_by_name` path and stored on a cached ProcessEnv backing object, but the read side (`process.env.X` → `EnvGet`) consults `std::env::var` directly. The value never round-tripped: child processes inherited the unmodified parent env, and even `console.log(process.env.X)` immediately after the assignment came back `undefined`. Route `PropertySet { object: ProcessEnv, property, value }` through a new `js_setenv(name, value)` runtime helper that: - coerces the value to a string via `js_jsvalue_to_string` (matches Node's `process.env.PORT = 8080` → `"8080"` coercion), - writes via `std::env::set_var(name, str_value)` — exactly the same store the existing `js_getenv` read side consults. Add a matching `js_removeenv(name)` for the future `delete process.env.X` hookup (HIR side is already in flight in #1331's branch). Closes #1344.
proggeramlug
added a commit
that referenced
this pull request
May 23, 2026
…1505) Node 20.12+ exposes `process.loadEnvFile(path?)` to read a `.env` file from disk and add its KEY=value entries to process.env. Perry was reading it as a bare number, so `typeof process.loadEnvFile === "function"` returned false and call sites crashed with "value is not a function". Perry today doesn't persist `process.env.X = v` writes (tracked in #1344), so eagerly loading a `.env` would be moot. Returning undefined is the closest no-op for the probe-and-call pattern. Real `.env` loading is tracked separately — this PR closes the typeof / call-doesn't-crash gap. - Call lowering (`native_module.rs`): folds to `Expr::Undefined`, sitting next to the `ref` / `unref` / `setSourceMapsEnabled` / `getBuiltinModule` / `dlopen` / `hasUncaughtExceptionCaptureCallback` / `setUncaughtExceptionCaptureCallback` arms. - Typeof fold (`lower_expr.rs`): adds `loadEnvFile` to the same process-method-as-function list. Test: test-parity/node-suite/process/methods/load-env-file.ts (in the granular suite from #1331) now passes — byte-identical to `node --experimental-strip-types`.
2 tasks
proggeramlug
added a commit
that referenced
this pull request
May 23, 2026
…1478) (#1507) Node's `performance.markResourceTiming(info, ...)` records a PerformanceResourceTiming entry built from a PerformanceTimingInfo- shaped object (paired with `clearResourceTimings` / `setResourceTimingBufferSize`). Perry was reading the property as undefined — `typeof performance.markResourceTiming === "function"` returned false and any call crashed. Perry doesn't track the resource-timing buffer yet, so the call is a no-op returning undefined. The accompanying read of `performance.getEntriesByType("resource")` still returns an empty array, matching the no-recorded-entries shape. - HIR dispatch (`module_static.rs`): adds `markResourceTiming` to the perf_hooks NativeMethodCall list. - Codegen (`perf_hooks.rs`): folds the call to undefined, sitting next to the `clearResourceTimings` / `setResourceTimingBufferSize` arms. - Property-read typeof (`object/native_module.rs`): adds `("perf_hooks", "markResourceTiming")` to the callable-export list so `typeof performance.markResourceTiming === "function"` matches Node and `const f = performance.markResourceTiming` is a callable bound-method closure. Test: test-parity/node-suite/perf_hooks/resource-timing/mark-resource-timing.ts (in the granular suite from #1331) now passes — byte-identical to `node --experimental-strip-types`.
2 tasks
proggeramlug
added a commit
that referenced
this pull request
May 23, 2026
…1479) (#1516) Node returns `"[object Performance]"` from `Object.prototype.toString.call(performance)` — that's the spec'd host-tag for the `Performance` interface. Perry was returning the generic `"[object Object]"` because the perf_hooks namespace is a `NATIVE_MODULE_CLASS_ID`-tagged ObjectHeader: it never reaches the class-level `Symbol.toStringTag` hook (those are keyed by user-class class_id). - `read_native_module_name(obj_ptr)` helper in `object/native_module.rs` decodes the module-name string stored in field 0 of the namespace ObjectHeader. - `js_object_to_string` in `object/mod.rs`: after the class-level hook misses, if `class_id == NATIVE_MODULE_CLASS_ID` look up the module name and map it via a new `native_module_to_string_tag` table. Today the only entry is `perf_hooks → "Performance"`; future modules with a defined Node tag (`url → "URL"`, `events → "EventEmitter"`, etc.) slot in here. Test: test-parity/node-suite/perf_hooks/shapes/to-string-tag.ts (in the granular suite from #1331) now passes — byte-identical to `node --experimental-strip-types`. `performance[Symbol.toStringTag]` reading "Performance" directly remains a separate gap (Symbol-keyed property dispatch on namespace objects); the spec-compliant toString path is now covered.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Comprehensive
node:processnode-suite (there was none before). 41 granular cases covering the deterministic surface, validated againstnode --experimental-strip-types. Tests use the globalprocess(the primary API). This branch also carries #1371's runtime fixes (merged in), so it lands tests and impl together.Passing (24/41)
object shape · platform/arch · pid · ppid · env reads +
Object.keys· cwd() · version + versions.node/v8 · argv shape · nextTick ordering/returns-undefined · hrtime() tuple + bigint · memoryUsage() · uptime() · stdout/stderr write + fds · global identity · method-value typeof · env writes · argv0/execPath/title (bold = fixed by #1371).Gaps (17/41) — each tracked by its own granular issue
Every failure is recorded in
known_failures.jsonpointing at its specific issue (no umbrellas). No version bump / CHANGELOG.