From 032ef1dc5ebf7367b773b087816066d618c16ef3 Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Tue, 27 Aug 2024 02:50:24 +0200 Subject: [PATCH] Support dart2wasm in node.js tests (#2259) Support `dart2wasm` as a compiler for tests running in Node.js. `dart2wasm` emits a `.mjs` file exporting definitions to load generated wasm modules, the only additional thing we have to do is wrap that in a simple entrypoint file compiling the wasm module and invoking the startup wrapper. There's no support for stack trace maps yet. We also don't support precompiled node wasm tests yet (`dart2wasm` is also not currently supported by `build_web_compilers`, so we're blocked on that either way). In the test runtime, I had to migrate off `require` as that function is not in the global context for `.mjs` files. It looks like we can use `await import` instead though. If we need to support ancient Node versions that lack `import` support, I can adapt that to still use `require` when compiled with `dart2js` for compatibility. --- .github/workflows/dart.yml | 162 +++++++++--------- integration_tests/regression/pubspec.yaml | 2 +- integration_tests/spawn_hybrid/pubspec.yaml | 2 +- integration_tests/wasm/dart_test.yaml | 3 + integration_tests/wasm/pubspec.yaml | 2 +- pkgs/checks/pubspec.yaml | 2 +- pkgs/test/CHANGELOG.md | 3 +- pkgs/test/lib/src/bootstrap/node.dart | 2 +- pkgs/test/lib/src/runner/node/platform.dart | 147 ++++++++++++---- .../lib/src/runner/node/socket_channel.dart | 39 ++--- pkgs/test/pubspec.yaml | 2 +- pkgs/test/test/runner/node/runner_test.dart | 117 ++++++++++++- pkgs/test/test/runner/runner_test.dart | 2 +- pkgs/test_api/CHANGELOG.md | 3 +- pkgs/test_api/lib/src/backend/runtime.dart | 4 +- pkgs/test_api/pubspec.yaml | 2 +- pkgs/test_core/CHANGELOG.md | 3 +- .../lib/src/runner/wasm_compiler_pool.dart | 6 + pkgs/test_core/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 20 files changed, 356 insertions(+), 151 deletions(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 6298e160e..1c3895356 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -40,23 +40,23 @@ jobs: - name: mono_repo self validate run: dart pub global run mono_repo generate --validate job_002: - name: "analyze_and_format; linux; Dart 3.5.0-259.0.dev; PKGS: integration_tests/regression, integration_tests/wasm; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos`" + name: "analyze_and_format; linux; Dart 3.5.0-311.0.dev; PKGS: integration_tests/regression, integration_tests/wasm; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:integration_tests/regression-integration_tests/wasm;commands:format-analyze_0" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:integration_tests/regression-integration_tests/wasm;commands:format-analyze_0" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:integration_tests/regression-integration_tests/wasm - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:integration_tests/regression-integration_tests/wasm + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -87,23 +87,23 @@ jobs: if: "always() && steps.integration_tests_wasm_pub_upgrade.conclusion == 'success'" working-directory: integration_tests/wasm job_003: - name: "analyze_and_format; linux; Dart 3.5.0-259.0.dev; PKGS: pkgs/checks, pkgs/test_core; `dart analyze`" + name: "analyze_and_format; linux; Dart 3.5.0-311.0.dev; PKGS: pkgs/checks, pkgs/test_core; `dart analyze`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/checks-pkgs/test_core;commands:analyze_1" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/checks-pkgs/test_core;commands:analyze_1" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/checks-pkgs/test_core - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/checks-pkgs/test_core + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -238,13 +238,13 @@ jobs: if: "always() && steps.pkgs_test_core_pub_upgrade.conclusion == 'success'" working-directory: pkgs/test_core job_005: - name: "analyze_and_format; windows; Dart 3.5.0-259.0.dev; PKG: integration_tests/wasm; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos`" + name: "analyze_and_format; windows; Dart 3.5.0-311.0.dev; PKG: integration_tests/wasm; `dart format --output=none --set-exit-if-changed .`, `dart analyze --fatal-infos`" runs-on: windows-latest steps: - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -286,23 +286,23 @@ jobs: if: "always() && steps.integration_tests_wasm_pub_upgrade.conclusion == 'success'" working-directory: integration_tests/wasm job_007: - name: "unit_test; linux; Dart 3.5.0-259.0.dev; PKG: integration_tests/regression; `dart test`" + name: "unit_test; linux; Dart 3.5.0-311.0.dev; PKG: integration_tests/regression; `dart test`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:integration_tests/regression;commands:command_00" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:integration_tests/regression;commands:command_00" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:integration_tests/regression - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:integration_tests/regression + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -323,23 +323,23 @@ jobs: - job_005 - job_006 job_008: - name: "unit_test; linux; Dart 3.5.0-259.0.dev; PKG: pkgs/checks; `dart test`" + name: "unit_test; linux; Dart 3.5.0-311.0.dev; PKG: pkgs/checks; `dart test`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/checks;commands:command_00" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/checks;commands:command_00" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/checks - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/checks + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -360,23 +360,23 @@ jobs: - job_005 - job_006 job_009: - name: "unit_test; linux; Dart 3.5.0-259.0.dev; PKG: pkgs/test_core; `dart test`" + name: "unit_test; linux; Dart 3.5.0-311.0.dev; PKG: pkgs/test_core; `dart test`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test_core;commands:command_00" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test_core;commands:command_00" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test_core - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test_core + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -397,23 +397,23 @@ jobs: - job_005 - job_006 job_010: - name: "unit_test; linux; Dart 3.5.0-259.0.dev; PKG: integration_tests/spawn_hybrid; `dart test -p chrome,vm,node`" + name: "unit_test; linux; Dart 3.5.0-311.0.dev; PKG: integration_tests/spawn_hybrid; `dart test -p chrome,vm,node`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:integration_tests/spawn_hybrid;commands:test_1" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:integration_tests/spawn_hybrid;commands:test_1" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:integration_tests/spawn_hybrid - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:integration_tests/spawn_hybrid + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -434,23 +434,23 @@ jobs: - job_005 - job_006 job_011: - name: "unit_test; linux; Dart 3.5.0-259.0.dev; PKG: integration_tests/wasm; `dart test --timeout=60s`" + name: "unit_test; linux; Dart 3.5.0-311.0.dev; PKG: integration_tests/wasm; `dart test --timeout=60s`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:integration_tests/wasm;commands:test_2" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:integration_tests/wasm;commands:test_2" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:integration_tests/wasm - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:integration_tests/wasm + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -471,23 +471,23 @@ jobs: - job_005 - job_006 job_012: - name: "unit_test; linux; Dart 3.5.0-259.0.dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 0`" + name: "unit_test; linux; Dart 3.5.0-311.0.dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 0`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test;commands:command_01" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test;commands:command_01" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -508,23 +508,23 @@ jobs: - job_005 - job_006 job_013: - name: "unit_test; linux; Dart 3.5.0-259.0.dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 1`" + name: "unit_test; linux; Dart 3.5.0-311.0.dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 1`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test;commands:command_02" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test;commands:command_02" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -545,23 +545,23 @@ jobs: - job_005 - job_006 job_014: - name: "unit_test; linux; Dart 3.5.0-259.0.dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 2`" + name: "unit_test; linux; Dart 3.5.0-311.0.dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 2`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test;commands:command_03" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test;commands:command_03" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -582,23 +582,23 @@ jobs: - job_005 - job_006 job_015: - name: "unit_test; linux; Dart 3.5.0-259.0.dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 3`" + name: "unit_test; linux; Dart 3.5.0-311.0.dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 3`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test;commands:command_04" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test;commands:command_04" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -619,23 +619,23 @@ jobs: - job_005 - job_006 job_016: - name: "unit_test; linux; Dart 3.5.0-259.0.dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 4`" + name: "unit_test; linux; Dart 3.5.0-311.0.dev; PKG: pkgs/test; `xvfb-run -s \"-screen 0 1024x768x24\" dart test --preset travis --total-shards 5 --shard-index 4`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test;commands:command_05" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test;commands:command_05" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -656,23 +656,23 @@ jobs: - job_005 - job_006 job_017: - name: "unit_test; linux; Dart 3.5.0-259.0.dev; PKG: pkgs/test_api; `dart test --preset travis -x browser`" + name: "unit_test; linux; Dart 3.5.0-311.0.dev; PKG: pkgs/test_api; `dart test --preset travis -x browser`" runs-on: ubuntu-latest steps: - name: Cache Pub hosted dependencies uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 with: path: "~/.pub-cache/hosted" - key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test_api;commands:command_11" + key: "os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test_api;commands:command_11" restore-keys: | - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev;packages:pkgs/test_api - os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-259.0.dev + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev;packages:pkgs/test_api + os:ubuntu-latest;pub-cache-hosted;sdk:3.5.0-311.0.dev os:ubuntu-latest;pub-cache-hosted os:ubuntu-latest - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -1100,13 +1100,13 @@ jobs: - job_005 - job_006 job_029: - name: "unit_test; windows; Dart 3.5.0-259.0.dev; PKG: integration_tests/spawn_hybrid; `dart test -p chrome,vm,node`" + name: "unit_test; windows; Dart 3.5.0-311.0.dev; PKG: integration_tests/spawn_hybrid; `dart test -p chrome,vm,node`" runs-on: windows-latest steps: - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -1127,13 +1127,13 @@ jobs: - job_005 - job_006 job_030: - name: "unit_test; windows; Dart 3.5.0-259.0.dev; PKG: integration_tests/wasm; `dart test --timeout=60s`" + name: "unit_test; windows; Dart 3.5.0-311.0.dev; PKG: integration_tests/wasm; `dart test --timeout=60s`" runs-on: windows-latest steps: - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -1154,13 +1154,13 @@ jobs: - job_005 - job_006 job_031: - name: "unit_test; windows; Dart 3.5.0-259.0.dev; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 0`" + name: "unit_test; windows; Dart 3.5.0-311.0.dev; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 0`" runs-on: windows-latest steps: - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -1181,13 +1181,13 @@ jobs: - job_005 - job_006 job_032: - name: "unit_test; windows; Dart 3.5.0-259.0.dev; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 1`" + name: "unit_test; windows; Dart 3.5.0-311.0.dev; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 1`" runs-on: windows-latest steps: - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -1208,13 +1208,13 @@ jobs: - job_005 - job_006 job_033: - name: "unit_test; windows; Dart 3.5.0-259.0.dev; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 2`" + name: "unit_test; windows; Dart 3.5.0-311.0.dev; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 2`" runs-on: windows-latest steps: - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -1235,13 +1235,13 @@ jobs: - job_005 - job_006 job_034: - name: "unit_test; windows; Dart 3.5.0-259.0.dev; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 3`" + name: "unit_test; windows; Dart 3.5.0-311.0.dev; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 3`" runs-on: windows-latest steps: - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 @@ -1262,13 +1262,13 @@ jobs: - job_005 - job_006 job_035: - name: "unit_test; windows; Dart 3.5.0-259.0.dev; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 4`" + name: "unit_test; windows; Dart 3.5.0-311.0.dev; PKG: pkgs/test; `dart test --preset travis --total-shards 5 --shard-index 4`" runs-on: windows-latest steps: - name: Setup Dart SDK uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 with: - sdk: "3.5.0-259.0.dev" + sdk: "3.5.0-311.0.dev" - id: checkout name: Checkout repository uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 diff --git a/integration_tests/regression/pubspec.yaml b/integration_tests/regression/pubspec.yaml index 6c5b2796d..6ef1bb936 100644 --- a/integration_tests/regression/pubspec.yaml +++ b/integration_tests/regression/pubspec.yaml @@ -1,7 +1,7 @@ name: regression_tests publish_to: none environment: - sdk: ^3.5.0-259.0.dev + sdk: ^3.5.0-311.0.dev resolution: workspace dependencies: test: any diff --git a/integration_tests/spawn_hybrid/pubspec.yaml b/integration_tests/spawn_hybrid/pubspec.yaml index e2fa3ee43..0f1d6f7d0 100644 --- a/integration_tests/spawn_hybrid/pubspec.yaml +++ b/integration_tests/spawn_hybrid/pubspec.yaml @@ -1,7 +1,7 @@ name: spawn_hybrid publish_to: none environment: - sdk: ^3.5.0-259.0.dev + sdk: ^3.5.0-311.0.dev resolution: workspace dependencies: async: ^2.9.0 diff --git a/integration_tests/wasm/dart_test.yaml b/integration_tests/wasm/dart_test.yaml index c53292fc7..14308c465 100644 --- a/integration_tests/wasm/dart_test.yaml +++ b/integration_tests/wasm/dart_test.yaml @@ -1,2 +1,5 @@ platforms: [chrome, firefox] +# Node doesn't work because the version available in the current Ubuntu GitHub runners is too +# old to support WASM+GC, which would be required to run Dart tests. +#platforms: [chrome, firefox, node] compilers: [dart2wasm] diff --git a/integration_tests/wasm/pubspec.yaml b/integration_tests/wasm/pubspec.yaml index b3024c7cc..8dc9ef989 100644 --- a/integration_tests/wasm/pubspec.yaml +++ b/integration_tests/wasm/pubspec.yaml @@ -1,7 +1,7 @@ name: wasm_tests publish_to: none environment: - sdk: ^3.5.0-259.0.dev + sdk: ^3.5.0-311.0.dev resolution: workspace dev_dependencies: test: any diff --git a/pkgs/checks/pubspec.yaml b/pkgs/checks/pubspec.yaml index c1b031db7..6c6d43a61 100644 --- a/pkgs/checks/pubspec.yaml +++ b/pkgs/checks/pubspec.yaml @@ -7,7 +7,7 @@ repository: https://github.com/dart-lang/test/tree/master/pkgs/checks resolution: workspace environment: - sdk: ^3.5.0-259.0.dev + sdk: ^3.5.0-311.0.dev dependencies: async: ^2.8.0 diff --git a/pkgs/test/CHANGELOG.md b/pkgs/test/CHANGELOG.md index 7a7f16529..cc228ade6 100644 --- a/pkgs/test/CHANGELOG.md +++ b/pkgs/test/CHANGELOG.md @@ -1,7 +1,8 @@ ## 1.25.9-wip * Fix dart2wasm tests on windows. -* Increase SDK constraint to ^3.5.0-259.0.dev. +* Increase SDK constraint to ^3.5.0-311.0.dev. +* Support running Node.js tests compiled with dart2wasm. ## 1.25.8 diff --git a/pkgs/test/lib/src/bootstrap/node.dart b/pkgs/test/lib/src/bootstrap/node.dart index 8612dbcc0..21089a47b 100644 --- a/pkgs/test/lib/src/bootstrap/node.dart +++ b/pkgs/test/lib/src/bootstrap/node.dart @@ -14,5 +14,5 @@ void internalBootstrapNodeTest(Function Function() getMain) { if (serialized is! Map) return; setStackTraceMapper(JSStackTraceMapper.deserialize(serialized)!); }); - socketChannel().pipe(channel); + socketChannel().then((socket) => socket.pipe(channel)); } diff --git a/pkgs/test/lib/src/runner/node/platform.dart b/pkgs/test/lib/src/runner/node/platform.dart index b27009e07..16cd9c6ee 100644 --- a/pkgs/test/lib/src/runner/node/platform.dart +++ b/pkgs/test/lib/src/runner/node/platform.dart @@ -16,6 +16,7 @@ import 'package:test_api/backend.dart' import 'package:test_core/src/runner/application_exception.dart'; // ignore: implementation_imports import 'package:test_core/src/runner/configuration.dart'; // ignore: implementation_imports import 'package:test_core/src/runner/dart2js_compiler_pool.dart'; // ignore: implementation_imports +import 'package:test_core/src/runner/load_exception.dart'; // ignore: implementation_imports import 'package:test_core/src/runner/package_version.dart'; // ignore: implementation_imports import 'package:test_core/src/runner/platform.dart'; // ignore: implementation_imports import 'package:test_core/src/runner/plugin/customizable_platform.dart'; // ignore: implementation_imports @@ -23,10 +24,10 @@ import 'package:test_core/src/runner/plugin/environment.dart'; // ignore: implem import 'package:test_core/src/runner/plugin/platform_helpers.dart'; // ignore: implementation_imports import 'package:test_core/src/runner/runner_suite.dart'; // ignore: implementation_imports import 'package:test_core/src/runner/suite.dart'; // ignore: implementation_imports +import 'package:test_core/src/runner/wasm_compiler_pool.dart'; // ignore: implementation_imports import 'package:test_core/src/util/errors.dart'; // ignore: implementation_imports import 'package:test_core/src/util/io.dart'; // ignore: implementation_imports import 'package:test_core/src/util/package_config.dart'; // ignore: implementation_imports -import 'package:test_core/src/util/pair.dart'; // ignore: implementation_imports import 'package:test_core/src/util/stack_trace_mapper.dart'; // ignore: implementation_imports import 'package:yaml/yaml.dart'; @@ -40,7 +41,8 @@ class NodePlatform extends PlatformPlugin final Configuration _config; /// The [Dart2JsCompilerPool] managing active instances of `dart2js`. - final _compilers = Dart2JsCompilerPool(['-Dnode=true', '--server-mode']); + final _jsCompilers = Dart2JsCompilerPool(['-Dnode=true', '--server-mode']); + final _wasmCompilers = WasmCompilerPool(['-Dnode=true']); /// The temporary directory in which compiled JS is emitted. final _compiledDir = createTempDir(); @@ -75,15 +77,17 @@ class NodePlatform extends PlatformPlugin @override Future load(String path, SuitePlatform platform, SuiteConfiguration suiteConfig, Map message) async { - if (platform.compiler != Compiler.dart2js) { + if (platform.compiler != Compiler.dart2js && + platform.compiler != Compiler.dart2wasm) { throw StateError( 'Unsupported compiler for the Node platform ${platform.compiler}.'); } - var pair = await _loadChannel(path, platform, suiteConfig); + var (channel, stackMapper) = + await _loadChannel(path, platform, suiteConfig); var controller = deserializeSuite(path, platform, suiteConfig, - const PluginEnvironment(), pair.first, message); + const PluginEnvironment(), channel, message); - controller.channel('test.node.mapper').sink.add(pair.last?.serialize()); + controller.channel('test.node.mapper').sink.add(stackMapper?.serialize()); return await controller.suite; } @@ -92,16 +96,13 @@ class NodePlatform extends PlatformPlugin /// /// Returns that channel along with a [StackTraceMapper] representing the /// source map for the compiled suite. - Future, StackTraceMapper?>> _loadChannel( - String path, - SuitePlatform platform, - SuiteConfiguration suiteConfig) async { + Future<(StreamChannel, StackTraceMapper?)> _loadChannel(String path, + SuitePlatform platform, SuiteConfiguration suiteConfig) async { final servers = await _loopback(); try { - var pair = await _spawnProcess( - path, platform.runtime, suiteConfig, servers.first.port); - var process = pair.first; + var (process, stackMapper) = + await _spawnProcess(path, platform, suiteConfig, servers.first.port); // Forward Node's standard IO to the print handler so it's associated with // the load test. @@ -110,7 +111,19 @@ class NodePlatform extends PlatformPlugin process.stdout.transform(lineSplitter).listen(print); process.stderr.transform(lineSplitter).listen(print); - var socket = await StreamGroup.merge(servers).first; + // Wait for the first connection (either over ipv4 or v6). If the proccess + // exits before it connects, throw instead of waiting for a connection + // indefinitely. + var socket = await Future.any([ + StreamGroup.merge(servers).first, + process.exitCode.then((_) => null), + ]); + + if (socket == null) { + throw LoadException( + path, 'Node exited before connecting to the test channel.'); + } + var channel = StreamChannel(socket.cast>(), socket) .transform(StreamChannelTransformer.fromCodec(utf8)) .transform(_chunksToLines) @@ -120,7 +133,7 @@ class NodePlatform extends PlatformPlugin sink.close(); })); - return Pair(channel, pair.last); + return (channel, stackMapper); } finally { unawaited(Future.wait(servers.map((s) => s.close().then((v) => v).onError((_, __) => null)))); @@ -131,23 +144,28 @@ class NodePlatform extends PlatformPlugin /// /// Returns that channel along with a [StackTraceMapper] representing the /// source map for the compiled suite. - Future> _spawnProcess(String path, - Runtime runtime, SuiteConfiguration suiteConfig, int socketPort) async { + Future<(Process, StackTraceMapper?)> _spawnProcess( + String path, + SuitePlatform platform, + SuiteConfiguration suiteConfig, + int socketPort) async { if (_config.suiteDefaults.precompiledPath != null) { - return _spawnPrecompiledProcess(path, runtime, suiteConfig, socketPort, - _config.suiteDefaults.precompiledPath!); + return _spawnPrecompiledProcess(path, platform.runtime, suiteConfig, + socketPort, _config.suiteDefaults.precompiledPath!); } else { - return _spawnNormalProcess(path, runtime, suiteConfig, socketPort); + return switch (platform.compiler) { + Compiler.dart2js => _spawnNormalJsProcess( + path, platform.runtime, suiteConfig, socketPort), + Compiler.dart2wasm => _spawnNormalWasmProcess( + path, platform.runtime, suiteConfig, socketPort), + _ => throw StateError('Unsupported compiler ${platform.compiler}'), + }; } } - /// Compiles [testPath] with dart2js, adds the node preamble, and then spawns - /// a Node.js process that loads that Dart test suite. - Future> _spawnNormalProcess(String testPath, - Runtime runtime, SuiteConfiguration suiteConfig, int socketPort) async { - var dir = Directory(_compiledDir).createTempSync('test_').path; - var jsPath = p.join(dir, '${p.basename(testPath)}.node_test.dart.js'); - await _compilers.compile(''' + Future _entrypointScriptForTest( + String testPath, SuiteConfiguration suiteConfig) async { + return ''' ${suiteConfig.metadata.languageVersionComment ?? await rootPackageLanguageVersionComment} import "package:test/src/bootstrap/node.dart"; @@ -156,7 +174,20 @@ class NodePlatform extends PlatformPlugin void main() { internalBootstrapNodeTest(() => test.main); } - ''', jsPath, suiteConfig); + '''; + } + + /// Compiles [testPath] with dart2js, adds the node preamble, and then spawns + /// a Node.js process that loads that Dart test suite. + Future<(Process, StackTraceMapper?)> _spawnNormalJsProcess(String testPath, + Runtime runtime, SuiteConfiguration suiteConfig, int socketPort) async { + var dir = Directory(_compiledDir).createTempSync('test_').path; + var jsPath = p.join(dir, '${p.basename(testPath)}.node_test.dart.js'); + await _jsCompilers.compile( + await _entrypointScriptForTest(testPath, suiteConfig), + jsPath, + suiteConfig, + ); // Add the Node.js preamble to ensure that the dart2js output is // compatible. Use the minified version so the source map remains valid. @@ -173,12 +204,63 @@ class NodePlatform extends PlatformPlugin packageMap: (await currentPackageConfig).toPackageMap()); } - return Pair(await _startProcess(runtime, jsPath, socketPort), mapper); + return (await _startProcess(runtime, jsPath, socketPort), mapper); + } + + /// Compiles [testPath] with dart2wasm, adds a JS entrypoint and then spawns + /// a Node.js process loading the compiled test suite. + Future<(Process, StackTraceMapper?)> _spawnNormalWasmProcess(String testPath, + Runtime runtime, SuiteConfiguration suiteConfig, int socketPort) async { + var dir = Directory(_compiledDir).createTempSync('test_').path; + // dart2wasm will emit a .wasm file and a .mjs file responsible for loading + // that file. + var wasmPath = p.join(dir, '${p.basename(testPath)}.node_test.dart.wasm'); + var loader = '${p.basename(testPath)}.node_test.dart.wasm.mjs'; + + // We need to create an additional entrypoint file loading the wasm module. + var jsPath = p.join(dir, '${p.basename(testPath)}.node_test.dart.js'); + + await _wasmCompilers.compile( + await _entrypointScriptForTest(testPath, suiteConfig), + wasmPath, + suiteConfig, + ); + + await File(jsPath).writeAsString(''' +const { createReadStream } = require('fs'); +const { once } = require('events'); +const { PassThrough } = require('stream'); + +const main = async () => { + const { instantiate, invoke } = await import("./$loader"); + + const wasmContents = createReadStream("$wasmPath.wasm"); + const stream = new PassThrough(); + wasmContents.pipe(stream); + + await once(wasmContents, 'open'); + const response = new Response( + stream, + { + headers: { + "Content-Type": "application/wasm" + } + } + ); + const instancePromise = WebAssembly.compileStreaming(response); + const module = await instantiate(instancePromise, {}); + invoke(module); +}; + +main(); +'''); + + return (await _startProcess(runtime, jsPath, socketPort), null); } /// Spawns a Node.js process that loads the Dart test suite at [testPath] /// under [precompiledPath]. - Future> _spawnPrecompiledProcess( + Future<(Process, StackTraceMapper?)> _spawnPrecompiledProcess( String testPath, Runtime runtime, SuiteConfiguration suiteConfig, @@ -195,7 +277,7 @@ class NodePlatform extends PlatformPlugin .toPackageMap()); } - return Pair(await _startProcess(runtime, jsPath, socketPort), mapper); + return (await _startProcess(runtime, jsPath, socketPort), mapper); } /// Starts the Node.js process for [runtime] with [jsPath]. @@ -224,7 +306,8 @@ class NodePlatform extends PlatformPlugin @override Future close() => _closeMemo.runOnce(() async { - await _compilers.close(); + await _jsCompilers.close(); + await _wasmCompilers.close(); await Directory(_compiledDir).deleteWithRetry(); }); final _closeMemo = AsyncMemoizer(); diff --git a/pkgs/test/lib/src/runner/node/socket_channel.dart b/pkgs/test/lib/src/runner/node/socket_channel.dart index 4e8a35036..95e81de96 100644 --- a/pkgs/test/lib/src/runner/node/socket_channel.dart +++ b/pkgs/test/lib/src/runner/node/socket_channel.dart @@ -1,46 +1,41 @@ // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. - -@JS() -library; - import 'dart:async'; import 'dart:convert'; +import 'dart:js_interop'; -import 'package:js/js.dart'; import 'package:stream_channel/stream_channel.dart'; -@JS('require') -external _Net _require(String module); - @JS('process.argv') -external List get _args; +external JSArray get _args; -@JS() -class _Net { +extension type _Net._(JSObject _) { external _Socket connect(int port); } -@JS() -class _Socket { - external void setEncoding(String encoding); - external void on(String event, void Function(String chunk) callback); - external void write(String data); +extension type _Socket._(JSObject _) { + external void setEncoding(JSString encoding); + external void on(JSString event, JSFunction callback); + external void write(JSString data); } /// Returns a [StreamChannel] of JSON-encodable objects that communicates over a /// socket whose port is given by `process.argv[2]`. -StreamChannel socketChannel() { - var net = _require('net'); - var socket = net.connect(int.parse(_args[2])); - socket.setEncoding('utf8'); +Future> socketChannel() async { + final net = (await importModule('node:net'.toJS).toDart) as _Net; + + var socket = net.connect(int.parse(_args.toDart[2].toDart)); + socket.setEncoding('utf8'.toJS); var socketSink = StreamController(sync: true) - ..stream.listen((event) => socket.write('${jsonEncode(event)}\n')); + ..stream.listen((event) => socket.write('${jsonEncode(event)}\n'.toJS)); var socketStream = StreamController(sync: true); - socket.on('data', allowInterop(socketStream.add)); + socket.on( + 'data'.toJS, + ((JSString chunk) => socketStream.add(chunk.toDart)).toJS, + ); return StreamChannel.withCloseGuarantee( socketStream.stream.transform(const LineSplitter()).map(jsonDecode), diff --git a/pkgs/test/pubspec.yaml b/pkgs/test/pubspec.yaml index 73b746e23..f398a41b6 100644 --- a/pkgs/test/pubspec.yaml +++ b/pkgs/test/pubspec.yaml @@ -6,7 +6,7 @@ repository: https://github.com/dart-lang/test/tree/master/pkgs/test resolution: workspace environment: - sdk: ^3.5.0-259.0.dev + sdk: ^3.5.0-311.0.dev dependencies: analyzer: '>=5.12.0 <7.0.0' diff --git a/pkgs/test/test/runner/node/runner_test.dart b/pkgs/test/test/runner/node/runner_test.dart index aba260440..82d2321b8 100644 --- a/pkgs/test/test/runner/node/runner_test.dart +++ b/pkgs/test/test/runner/node/runner_test.dart @@ -6,6 +6,10 @@ @Tags(['node']) library; +import 'dart:convert'; +import 'dart:io'; + +import 'package:test/src/runner/executable_settings.dart'; import 'package:test/test.dart'; import 'package:test_core/src/util/io.dart'; import 'package:test_descriptor/test_descriptor.dart' as d; @@ -28,6 +32,47 @@ final _failure = ''' } '''; +({int major, String full})? _nodeVersion; + +({int major, String full}) _readNodeVersion() { + final process = Process.runSync( + ExecutableSettings( + linuxExecutable: 'node', + macOSExecutable: 'node', + windowsExecutable: 'node.exe', + ).executable, + ['--version'], + stdoutEncoding: utf8, + ); + if (process.exitCode != 0) { + throw const OSError('Could not run node --version'); + } + + final version = RegExp(r'v(\d+)\..*'); + final parsed = version.firstMatch(process.stdout as String)!; + return (major: int.parse(parsed.group(1)!), full: process.stdout); +} + +String? skipBelowMajorNodeVersion(int minimumMajorVersion) { + final (:major, :full) = _nodeVersion ??= _readNodeVersion(); + if (major < minimumMajorVersion) { + return 'This test requires Node $minimumMajorVersion.x or later, ' + 'but is running on $full'; + } + + return null; +} + +String? skipAboveMajorNodeVersion(int maximumMajorVersion) { + final (:major, :full) = _nodeVersion ??= _readNodeVersion(); + if (major > maximumMajorVersion) { + return 'This test requires Node $maximumMajorVersion.x or older, ' + 'but is running on $full'; + } + + return null; +} + void main() { setUpAll(precompileTestExecutable); @@ -116,6 +161,15 @@ void main() { expect(test.stdout, emitsThrough(contains('+1: All tests passed!'))); await test.shouldExit(0); }); + + test('compiled with dart2wasm', () async { + await d.file('test.dart', _success).create(); + var test = + await runTest(['-p', 'node', '--compiler', 'dart2wasm', 'test.dart']); + + expect(test.stdout, emitsThrough(contains('+1: All tests passed!'))); + await test.shouldExit(0); + }, skip: skipBelowMajorNodeVersion(22)); }); test('defines a node environment constant', () async { @@ -148,11 +202,72 @@ void main() { } ''').create(); - var test = await runTest(['-p', 'node', '-p', 'vm', 'test.dart']); + var test = + await runTest(['-p', 'node', '-p', 'vm', '-c', 'dart2js', 'test.dart']); expect(test.stdout, emitsThrough(contains('+1 -1: Some tests failed.'))); await test.shouldExit(1); }); + test('runs failing tests that fail only on node (with dart2wasm)', () async { + await d.file('test.dart', ''' + import 'package:path/path.dart' as p; + import 'package:test/test.dart'; + + void main() { + test("test", () { + if (const bool.fromEnvironment("node")) { + throw TestFailure("oh no"); + } + }); + } + ''').create(); + + var test = await runTest([ + '-p', + 'node', + '-p', + 'vm', + '-c', + 'dart2js', + '-c', + 'dart2wasm', + 'test.dart' + ]); + expect(test.stdout, emitsThrough(contains('+1 -2: Some tests failed.'))); + await test.shouldExit(1); + }, skip: skipBelowMajorNodeVersion(22)); + + test( + 'gracefully handles wasm errors on old node versions', + () async { + // Old Node.JS versions can't read the WebAssembly modules emitted by + // dart2wasm. The node process exits before connecting to the server + // opened by the test runner, leading to timeouts. So, this is a + // regression test for https://github.com/dart-lang/test/pull/2259#issuecomment-2307868442 + await d.file('test.dart', ''' + import 'package:test/test.dart'; + + void main() { + test("test", () { + // Should pass on newer node versions + }); + } + ''').create(); + + var test = await runTest(['-p', 'node', '-c', 'dart2wasm', 'test.dart']); + expect( + test.stdout, + emitsInOrder([ + emitsThrough( + contains('Node exited before connecting to the test channel.')), + emitsThrough(contains('-1: Some tests failed.')), + ]), + ); + await test.shouldExit(1); + }, + skip: skipAboveMajorNodeVersion(21), + ); + test('forwards prints from the Node test', () async { await d.file('test.dart', ''' import 'dart:async'; diff --git a/pkgs/test/test/runner/runner_test.dart b/pkgs/test/test/runner/runner_test.dart index 75a3f3b40..056a6f0e9 100644 --- a/pkgs/test/test/runner/runner_test.dart +++ b/pkgs/test/test/runner/runner_test.dart @@ -131,7 +131,7 @@ final _runtimeCompilers = [ '[firefox]: dart2js (default), dart2wasm', if (Platform.isMacOS) '[safari]: dart2js (default)', '[edge]: dart2js (default)', - '[node]: dart2js (default)', + '[node]: dart2js (default), dart2wasm', ].map((str) => ' $str').join('\n'); void main() { diff --git a/pkgs/test_api/CHANGELOG.md b/pkgs/test_api/CHANGELOG.md index cb9a01226..9fc91d676 100644 --- a/pkgs/test_api/CHANGELOG.md +++ b/pkgs/test_api/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.7.4-wip -* Increase SDK constraint to ^3.5.0-259.0.dev. +* Increase SDK constraint to ^3.5.0-311.0.dev. +* Support running Node.js tests compiled with dart2wasm. ## 0.7.3 diff --git a/pkgs/test_api/lib/src/backend/runtime.dart b/pkgs/test_api/lib/src/backend/runtime.dart index d875632b2..ceef2277e 100644 --- a/pkgs/test_api/lib/src/backend/runtime.dart +++ b/pkgs/test_api/lib/src/backend/runtime.dart @@ -41,8 +41,8 @@ final class Runtime { isBrowser: true, isBlink: true); /// The command-line Node.js VM. - static const Runtime nodeJS = - Runtime('Node.js', 'node', Compiler.dart2js, [Compiler.dart2js]); + static const Runtime nodeJS = Runtime('Node.js', 'node', Compiler.dart2js, + [Compiler.dart2js, Compiler.dart2wasm]); /// The platforms that are supported by the test runner by default. static const List builtIn = [ diff --git a/pkgs/test_api/pubspec.yaml b/pkgs/test_api/pubspec.yaml index c34f9fc3b..0b8e712c6 100644 --- a/pkgs/test_api/pubspec.yaml +++ b/pkgs/test_api/pubspec.yaml @@ -6,7 +6,7 @@ repository: https://github.com/dart-lang/test/tree/master/pkgs/test_api resolution: workspace environment: - sdk: ^3.5.0-259.0.dev + sdk: ^3.5.0-311.0.dev dependencies: async: ^2.5.0 diff --git a/pkgs/test_core/CHANGELOG.md b/pkgs/test_core/CHANGELOG.md index 7d160afee..610311022 100644 --- a/pkgs/test_core/CHANGELOG.md +++ b/pkgs/test_core/CHANGELOG.md @@ -1,7 +1,8 @@ ## 0.6.6-wip * Fix dart2wasm tests on windows. -* Increase SDK constraint to ^3.5.0-259.0.dev. +* Increase SDK constraint to ^3.5.0-311.0.dev. +* Allow passing additional arguments to `dart compile wasm`. ## 0.6.5 diff --git a/pkgs/test_core/lib/src/runner/wasm_compiler_pool.dart b/pkgs/test_core/lib/src/runner/wasm_compiler_pool.dart index 748719c93..c4318f5a2 100644 --- a/pkgs/test_core/lib/src/runner/wasm_compiler_pool.dart +++ b/pkgs/test_core/lib/src/runner/wasm_compiler_pool.dart @@ -17,9 +17,14 @@ import 'suite.dart'; /// /// This limits the number of compiler instances running concurrently. class WasmCompilerPool extends CompilerPool { + /// Extra arguments to pass to `dart compile js`. + final List _extraArgs; + /// The currently-active dart2wasm processes. final _processes = {}; + WasmCompilerPool([this._extraArgs = const []]); + /// Compiles [code] to [path]. /// /// This wraps the Dart code in the standard browser-testing wrapper. @@ -41,6 +46,7 @@ class WasmCompilerPool extends CompilerPool { for (var experiment in enabledExperiments) '--enable-experiment=$experiment', '-O0', + ..._extraArgs, '-o', outWasmPath, wrapperPath, diff --git a/pkgs/test_core/pubspec.yaml b/pkgs/test_core/pubspec.yaml index 8bdc66b4f..35b030bc2 100644 --- a/pkgs/test_core/pubspec.yaml +++ b/pkgs/test_core/pubspec.yaml @@ -5,7 +5,7 @@ repository: https://github.com/dart-lang/test/tree/master/pkgs/test_core resolution: workspace environment: - sdk: ^3.5.0-259.0.dev + sdk: ^3.5.0-311.0.dev dependencies: analyzer: '>=3.3.0 <7.0.0' diff --git a/pubspec.yaml b/pubspec.yaml index 3bb4f67fa..88154f075 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: test_workspace publish_to: none environment: - sdk: ^3.5.0-259.0.dev # Must be ^3.5.0 or later for workspace to be allowed + sdk: ^3.5.0-311.0.dev # Must be ^3.5.0 or later for workspace to be allowed workspace: - integration_tests/regression - integration_tests/spawn_hybrid