diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 996b8c8dbc698..4088bb71e747f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -178,6 +178,8 @@ set(SWIFT_LIT_ENVIRONMENT "" CACHE STRING "Environment to use for lit invocation option(SWIFT_TEST_USE_LEAKS "Run Swift stdlib tests under leaks" FALSE) +option(SWIFT_TEST_WASM_RUNTIME "Wasm runtime used for running Wasm tests" "wasmkit") + function(setup_lit_args ARGS_VAR_OUT tested_sdk test_results_dir resource_dir_override) set(swift_lit_args_result) diff --git a/test/lit.cfg b/test/lit.cfg index ca1316248a2a5..da4adc4aa9dd4 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -2093,7 +2093,8 @@ elif kIsWASI: config.swift_test_options, config.swift_frontend_test_options]) subst_target_swift_frontend_mock_sdk = config.target_swift_frontend subst_target_swift_frontend_mock_sdk_after = "" - config.target_run = os.path.join(config.swift_utils, 'wasm-run.py') + config.target_run = f"{os.path.join(config.swift_utils, 'wasm-run.py')} " \ + f"-r {config.wasm_runtime}" config.target_env_prefix = 'WASM_RUN_CHILD_' if 'interpret' in lit_config.params: diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in index 5c4aff51df932..269735bfe0910 100644 --- a/test/lit.site.cfg.in +++ b/test/lit.site.cfg.in @@ -55,10 +55,17 @@ config.exe_linker_flags = r'''@CMAKE_EXE_LINKER_FLAGS@''' # --- Darwin --- config.darwin_xcrun_toolchain = "@SWIFT_DARWIN_XCRUN_TOOLCHAIN@" -# --- android --- +config.darwin_enable_maccatalyst = "@SWIFT_ENABLE_MACCATALYST@" == "TRUE" +config.darwin_maccatalyst_build_flavor = "@BUILD_FLAVOR@" +config.darwin_osx_variant_suffix = "@DEFAULT_OSX_VARIANT_SUFFIX@" + +# --- Android --- config.android_ndk_path = "@SWIFT_ANDROID_NDK_PATH@" config.android_api_level = "@SWIFT_ANDROID_API_LEVEL@" +# --- Wasm --- +config.wasm_runtime = "@SWIFT_TEST_WASM_RUNTIME@" + # --- Windows --- msvc_runtime_flags = { 'MultiThreaded': 'MT', @@ -69,10 +76,6 @@ msvc_runtime_flags = { config.swift_stdlib_msvc_runtime = \ msvc_runtime_flags["@SWIFT_STDLIB_MSVC_RUNTIME_LIBRARY@"] -config.darwin_enable_maccatalyst = "@SWIFT_ENABLE_MACCATALYST@" == "TRUE" -config.darwin_maccatalyst_build_flavor = "@BUILD_FLAVOR@" -config.darwin_osx_variant_suffix = "@DEFAULT_OSX_VARIANT_SUFFIX@" - # If we are not testing against the host compiler, we are testing against the # just built compiler. Add that as a feature so we can conditionally mark tests # as requiring a just_built_compiler. diff --git a/utils/build_swift/build_swift/driver_arguments.py b/utils/build_swift/build_swift/driver_arguments.py index 6a62e11b47bad..9042797caacd0 100644 --- a/utils/build_swift/build_swift/driver_arguments.py +++ b/utils/build_swift/build_swift/driver_arguments.py @@ -1183,6 +1183,11 @@ def create_argument_parser(): 'Then re-builds the TSan runtime (compiler-rt) using this ' 'freshly-built Clang and runs the TSan libdispatch tests.') + option('--test-with-wasm-runtime', store, metavar='WASM_RUNTIME', + choices=['wasmkit', 'nodejs'], default='wasmkit', + help='Wasm runtime to use when running tests. Available choices: ' + '`wasmkit` or `nodejs`') + option('--skip-test-osx', toggle_false('test_osx'), help='skip testing Swift stdlibs for Mac OS X') option('--skip-test-linux', toggle_false('test_linux'), diff --git a/utils/build_swift/tests/expected_options.py b/utils/build_swift/tests/expected_options.py index be2939b7e343e..aa5d512ae0a09 100644 --- a/utils/build_swift/tests/expected_options.py +++ b/utils/build_swift/tests/expected_options.py @@ -339,6 +339,7 @@ 'test_swiftdocc': False, 'test_toolchainbenchmarks': False, 'test_wasmstdlib': False, + 'test_with_wasm_runtime': 'wasmkit', 'tvos': False, 'tvos_all': False, 'validation_test': None, @@ -806,6 +807,7 @@ class BuildScriptImplOption(_BaseOption): choices=['armv7', 'aarch64', 'x86_64']), ChoicesOption('--foundation-tests-build-type', dest='foundation_tests_build_variant', choices=['Debug', 'Release']), + ChoicesOption('--test-with-wasm-runtime', choices=['wasmkit', 'nodejs']), StrOption('--android-api-level'), StrOption('--build-args'), diff --git a/utils/swift_build_support/swift_build_support/products/wasmkit.py b/utils/swift_build_support/swift_build_support/products/wasmkit.py index 8756b8930377e..77938578ed24b 100644 --- a/utils/swift_build_support/swift_build_support/products/wasmkit.py +++ b/utils/swift_build_support/swift_build_support/products/wasmkit.py @@ -68,7 +68,7 @@ def build(self, host_target): shutil.copy(bin_path, dest_bin_path) @classmethod - def cli_file_path(cls, build_dir): + def cli_file_path(cls, build_dir) -> str: return os.path.join(build_dir, 'bin', 'wasmkit') diff --git a/utils/swift_build_support/swift_build_support/products/wasmstdlib.py b/utils/swift_build_support/swift_build_support/products/wasmstdlib.py index 404c0366b76d3..0b463d43ae450 100644 --- a/utils/swift_build_support/swift_build_support/products/wasmstdlib.py +++ b/utils/swift_build_support/swift_build_support/products/wasmstdlib.py @@ -11,6 +11,10 @@ # ---------------------------------------------------------------------------- import os +import shutil +import sys + +from typing import NoReturn from . import cmake_product from . import llvm @@ -206,6 +210,8 @@ def _build_stdlib(self, host_target, target_triple, llvm_cmake_dir): self.cmake_options.define('SWIFT_DRIVER_TEST_OPTIONS:STRING', ' ' + ' '.join(test_driver_options)) + self.cmake_options.define('SWIFT_TEST_WASM_RUNTIME', self.args.test_with_wasm_runtime) + # Configure with WebAssembly target variant, and build with just-built toolchain self.build_with_cmake([], self._build_variant, [], prefer_native_toolchain=not self.args.build_runtime_with_host_compiler) @@ -213,24 +219,43 @@ def _build_stdlib(self, host_target, target_triple, llvm_cmake_dir): def add_extra_cmake_options(self): self.cmake_options.define('SWIFT_THREADING_PACKAGE:STRING', 'none') + def _wasm_runtime_lookup_failed(self) -> NoReturn: + print("wasmstdlib testing: Wasm runtime not found") + sys.exit(1) + + def infer_wasm_runtime(self, host_target) -> str: + build_root = os.path.dirname(self.build_dir) + if self.args.test_with_wasm_runtime == 'wasmkit': + wasmkit_build_path = os.path.join( + build_root, '%s-%s' % ('wasmkit', host_target)) + return wasmkit.WasmKit.cli_file_path(wasmkit_build_path) + elif self.args.test_with_wasm_runtime == 'nodejs': + result = shutil.which('node') + if result: + return result + else: + self._wasm_runtime_lookup_failed() + else: + self._wasm_runtime_lookup_failed() + + def test(self, host_target): self._test(host_target, 'wasm32-wasip1') def _test(self, host_target, target_triple): - build_root = os.path.dirname(self.build_dir) bin_paths = [ os.path.join(self._host_swift_build_dir(host_target), 'bin'), os.path.join(self._host_llvm_build_dir(host_target), 'bin'), os.environ['PATH'] ] - wasmkit_build_path = os.path.join( - build_root, '%s-%s' % ('wasmkit', host_target)) - wasmkit_bin_path = wasmkit.WasmKit.cli_file_path(wasmkit_build_path) - if not os.path.exists(wasmkit_bin_path) or not self.should_test_executable(): + + wasm_runtime_bin_path = self.infer_wasm_runtime(host_target) + print(f"wasm_runtime_bin_path is {wasm_runtime_bin_path}") + if not os.path.exists(wasm_runtime_bin_path) or not self.should_test_executable(): test_target = "check-swift-only_non_executable-wasi-wasm32-custom" else: test_target = "check-swift-wasi-wasm32-custom" - bin_paths = [os.path.dirname(wasmkit_bin_path)] + bin_paths + bin_paths = [os.path.dirname(wasm_runtime_bin_path)] + bin_paths env = { 'PATH': os.path.pathsep.join(bin_paths), diff --git a/utils/wasm-run.py b/utils/wasm-run.py index 6b13cb43ca0f1..533e1fb4197b8 100755 --- a/utils/wasm-run.py +++ b/utils/wasm-run.py @@ -24,12 +24,16 @@ def run(self, args): subprocess.check_call(command) def invocation(self, args): - command = ["wasmkit", "run"] - envs = collect_wasm_env() - for key in envs: - command.append("--env") - command.append(f"{key}={envs[key]}") - command.append("--") + if args.runtime == 'nodejs': + command = [os.path.join(os.path.dirname(__file__), 'wasm', 'node-wasi-runner')] + else: + command = ["wasmkit", "run"] + envs = collect_wasm_env() + for key in envs: + command.append("--env") + command.append(f"{key}={envs[key]}") + command.append("--") + command.extend(args.command) return command @@ -42,6 +46,11 @@ def main(): parser.add_argument('-n', '--dry-run', action='store_true', dest='dry_run', help="print the commands that would have been run, but" " don't actually run them") + parser.add_argument('-r', '--runtime', metavar='WASM_RUNTIME', + choices=['wasmkit', 'nodejs'], default='wasmkit', + help='Wasm runtime to use when running tests. Available choices: ' + '`wasmkit` or `nodejs`') + parser.add_argument('command', nargs=argparse.REMAINDER, help='the command to run', metavar='command...')