Skip to content

test(wasi): add tokio runtime lifecycle regression test#10379

Merged
graphite-app[bot] merged 1 commit into
mainfrom
07-22-test_wasi_add_tokio_runtime_lifecycle_regression_test
Jul 22, 2026
Merged

test(wasi): add tokio runtime lifecycle regression test#10379
graphite-app[bot] merged 1 commit into
mainfrom
07-22-test_wasi_add_tokio_runtime_lifecycle_regression_test

Conversation

@shulaoda

@shulaoda shulaoda commented Jul 22, 2026

Copy link
Copy Markdown
Member

Description

Follow-up to #10363, which must land first. Adds regression coverage for the Access tokio runtime failed in spawn crash class fixed there.

This bug class was invisible to every existing CI test. The runtime acquire and release functions are no-ops on native targets, and no CI test actually executed the WASI binding: the WASI workflow builds the wasm binding and runs the stability test and the examples, but those load the native binding that the same job builds for tooling. So an unbalanced runtime release could only ever crash on StackBlitz, never in CI.

The new tests/wasi/runtime-lifecycle.mjs is a plain node script following the test:stability pattern, wired into the WASI workflow right after the build step. It forces the real wasm binding and covers three sequences:

Two details are load-bearing. NAPI_RS_FORCE_WASI is set to error inside the script before importing rolldown, because true silently falls back to the native binding when the wasi files are missing and the test would pass without testing anything. After the import the script also asserts via require.cache that rolldown-binding.wasi.cjs was really loaded.

Verification

Red and green were produced under identical conditions (same machine, same stable toolchain, napi 3.11.0 on both sides, wasm binding forced and asserted). On main (aa73a6848, without #10363) the test exits 1 in the first sequence with the exact issue signature: Access tokio runtime failed in spawn in napi's tokio_runtime.rs, followed by RuntimeError: unreachable. On top of #10363 all three sequences pass.

To run locally: pnpm build-wasi:debug in packages/rolldown (dist only contains the wasi files when built with TARGET=rolldown-wasi), then pnpm test:wasi-runtime in packages/rolldown/tests.

shulaoda commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

How to use the Graphite Merge Queue

Add the label graphite: merge-when-ready to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@shulaoda
shulaoda marked this pull request as ready for review July 22, 2026 06:29
@shulaoda
shulaoda requested a review from h-a-n-a July 22, 2026 06:42
@graphite-app
graphite-app Bot changed the base branch from 07-20-fix_pair_tokio_runtime_acquire_and_release_on_wasm_to_prevent_premature_shutdown to graphite-base/10379 July 22, 2026 06:46

shulaoda commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

Merge activity

  • Jul 22, 6:48 AM UTC: The merge label 'graphite: merge-when-ready' was detected. This PR will be added to the Graphite merge queue once it meets the requirements.
  • Jul 22, 7:00 AM UTC: shulaoda added this pull request to the Graphite merge queue.
  • Jul 22, 7:09 AM UTC: Merged by the Graphite merge queue.

@graphite-app
graphite-app Bot force-pushed the 07-22-test_wasi_add_tokio_runtime_lifecycle_regression_test branch from 7e23056 to ab367ba Compare July 22, 2026 06:54
@graphite-app
graphite-app Bot force-pushed the graphite-base/10379 branch from 6535e5d to 77c8ff9 Compare July 22, 2026 06:54
@graphite-app
graphite-app Bot changed the base branch from graphite-base/10379 to main July 22, 2026 06:55
@graphite-app
graphite-app Bot force-pushed the 07-22-test_wasi_add_tokio_runtime_lifecycle_regression_test branch from ab367ba to 872262a Compare July 22, 2026 06:55

@hyfdev hyfdev left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The three scenarios cover the failure modes from #8411, #8747, and the shared invariant behind both fixes. The test forces the WASI binding with NAPI_RS_FORCE_WASI=error, verifies it loaded, and CI confirms all three pass on this head.

— Review by @hyfdev, assisted by deepseek-v4-pro

@netlify

netlify Bot commented Jul 22, 2026

Copy link
Copy Markdown

Deploy Preview for rolldown-rs canceled.

Name Link
🔨 Latest commit ab000c4
🔍 Latest deploy log https://app.netlify.com/projects/rolldown-rs/deploys/6a606bb0a28cc90008d529ef

### Description

Follow-up to #10363, which must land first. Adds regression coverage for the `Access tokio runtime failed in spawn` crash class fixed there.

This bug class was invisible to every existing CI test. The runtime acquire and release functions are no-ops on native targets, and no CI test actually executed the WASI binding: the WASI workflow builds the wasm binding and runs the stability test and the examples, but those load the native binding that the same job builds for tooling. So an unbalanced runtime release could only ever crash on StackBlitz, never in CI.

The new `tests/wasi/runtime-lifecycle.mjs` is a plain node script following the `test:stability` pattern, wired into the WASI workflow right after the build step. It forces the real wasm binding and covers three sequences:

- The #8411 shape: a build that gets closed (Vite bundling `vite.config.ts`), then a `DevEngine` is created and run.
- The #8747 shape: a build that gets closed, then `watch()` runs until `BUNDLE_END`.
- The invariant behind both: closing one consumer while a `DevEngine` is still alive must not tear the runtime down under the engine.

Two details are load-bearing. `NAPI_RS_FORCE_WASI` is set to `error` inside the script before importing rolldown, because `true` silently falls back to the native binding when the wasi files are missing and the test would pass without testing anything. After the import the script also asserts via `require.cache` that `rolldown-binding.wasi.cjs` was really loaded.

### Verification

Red and green were produced under identical conditions (same machine, same stable toolchain, napi 3.11.0 on both sides, wasm binding forced and asserted). On `main` (`aa73a6848`, without #10363) the test exits 1 in the first sequence with the exact issue signature: `Access tokio runtime failed in spawn` in napi's `tokio_runtime.rs`, followed by `RuntimeError: unreachable`. On top of #10363 all three sequences pass.

To run locally: `pnpm build-wasi:debug` in `packages/rolldown` (dist only contains the wasi files when built with `TARGET=rolldown-wasi`), then `pnpm test:wasi-runtime` in `packages/rolldown/tests`.

<!--
- What is this PR solving? Write a clear and concise description.
- Reference the issues it solves (e.g. `fixes #123`).
- What other alternatives have you explored?
- Are there any parts you think require more attention from reviewers?

Also, please make sure you do the following:

- Read the Contributing Guidelines at https://rolldown.rs/contribution-guide/.
- Check that there isn't already a PR that solves the problem the same way. If you find a duplicate, please help us review it.
- Update the corresponding documentation if needed.
- Include relevant tests that fail without this PR but pass with it. If the tests are not included, explain why.

Thank you for contributing to Rolldown!
-->
@graphite-app
graphite-app Bot force-pushed the 07-22-test_wasi_add_tokio_runtime_lifecycle_regression_test branch from 872262a to ab000c4 Compare July 22, 2026 07:05
@graphite-app
graphite-app Bot merged commit ab000c4 into main Jul 22, 2026
32 of 33 checks passed
@graphite-app
graphite-app Bot deleted the 07-22-test_wasi_add_tokio_runtime_lifecycle_regression_test branch July 22, 2026 07:09
Brooooooklyn added a commit that referenced this pull request Jul 22, 2026
#10379 added tests/wasi/runtime-lifecycle.mjs to regression-cover the
"Access tokio runtime failed in spawn" crash class (#8411/#8747), driving
dev() and watch() on the WASI binding to exercise the shared *tokio*
runtime's acquire/release refcount.

This branch is tokio-free: the WASI binding runs the shared CurrentThread
runtime owned by the N-API environment (the JS runtime leases are no-ops),
so that refcount and its crash class cannot exist; and dev()/watch() are
unsupported on the WASI artifact by design. The imported test therefore
failed at the first dev() call with ERR_ROLLDOWN_UNSUPPORTED_RUNTIME_FEATURE.

Adapted to the tokio-free equivalents while keeping the WASI-binding
force-load + assertion that made the lane valuable:
  1. repeated sequential build+close — runtime survives a consumer closing
  2. two builds alive, close one — the other still works (#8411/#8747
     invariant via the WASI-supported API)
  3. dev() rejects synchronously with the unsupported-runtime code
  4. watch() reports unsupported through its ERROR-event lifecycle
Verified each assertion against the code: dev-engine.ts assertRuntimeFeature
('dev'), watch/index.ts + watch-emitter.ts failSetup emitting {code:'ERROR'}.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01T34fMrYCf2V13Mg8BKmnda
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.

3 participants