diff --git a/.circleci/config.yml b/.circleci/config.yml index 216191cfb44a8..bc8c24a9061c1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -874,8 +874,6 @@ jobs: - upload-test-results test-bun: executor: linux-python - environment: - OVERRIDE_NODE_JS_TEST_VERSION: "v24.0.0" steps: - checkout - pip-install @@ -884,8 +882,8 @@ jobs: name: install bun command: | curl -fsSL https://bun.com/install | bash - echo "NODE_JS_TEST = os.path.expanduser('~/.bun/bin/bun')" >> ~/emsdk/.emscripten - echo "JS_ENGINES = [NODE_JS_TEST]" >> ~/emsdk/.emscripten + echo "BUN = os.path.expanduser('~/.bun/bin/bun')" >> ~/emsdk/.emscripten + echo "JS_ENGINES = [BUN]" >> ~/emsdk/.emscripten - run-tests: test_targets: " core0.test_hello_world @@ -907,6 +905,7 @@ jobs: - run-tests: test_targets: " core0.test_hello_world + core2.test_pthread_create " test-jsc: executor: linux-python diff --git a/test/common.py b/test/common.py index 6cb0cd560bead..50fd810544e0f 100644 --- a/test/common.py +++ b/test/common.py @@ -265,6 +265,27 @@ def get_output_suffix(args): return '.js' +def match_engine_executable(engine, name): + basename = os.path.basename(engine[0]) + return name in basename + + +def engine_is_node(engine): + return match_engine_executable(engine, 'node') + + +def engine_is_v8(engine): + return match_engine_executable(engine, 'd8') or match_engine_executable(engine, 'v8') + + +def engine_is_deno(engine): + return match_engine_executable(engine, 'deno') + + +def engine_is_bun(engine): + return match_engine_executable(engine, 'bun') + + class RunnerMeta(type): @classmethod def make_test(mcs, name, func, suffix, args): @@ -362,9 +383,23 @@ def check_dylink(self): def get_v8(self): """Return v8 engine, if one is configured, otherwise None""" - if not config.V8_ENGINE or config.V8_ENGINE not in config.JS_ENGINES: - return None - return config.V8_ENGINE + for engine in config.JS_ENGINES: + if engine_is_v8(engine): + return engine + return None + + def require_pthreads(self): + self.setup_pthreads() + for engine in self.js_engines: + if engine_is_node(engine): + self.require_node() + nodejs = self.get_nodejs() + self.node_args += shared.node_pthread_flags(nodejs) + return + elif engine_is_bun(engine) or engine_is_deno(engine): + self.require_engine(engine) + return + self.fail('no JS engine found capable of running pthreads') def require_v8(self): if 'EMTEST_SKIP_V8' in os.environ: @@ -377,9 +412,10 @@ def require_v8(self): def get_nodejs(self): """Return nodejs engine, if one is configured, otherwise None""" - if config.NODE_JS_TEST not in config.JS_ENGINES: - return None - return config.NODE_JS_TEST + for engine in config.JS_ENGINES: + if engine_is_node(engine): + return engine + return None def require_node(self): if 'EMTEST_SKIP_NODE' in os.environ: @@ -390,15 +426,6 @@ def require_node(self): self.require_engine(nodejs) return nodejs - def get_node_test_version(self, nodejs): - override = os.environ.get('OVERRIDE_NODE_JS_TEST_VERSION') - if override: - override = override.removeprefix('v') - override = override.split('-')[0].split('.') - override = tuple(int(v) for v in override) - return override - return shared.get_node_version(nodejs) - def node_is_canary(self, nodejs): return nodejs and nodejs[0] and ('canary' in nodejs[0] or 'nightly' in nodejs[0]) @@ -441,7 +468,7 @@ def try_require_node_version(self, major, minor = 0, revision = 0): nodejs = self.get_nodejs() if not nodejs: self.skipTest('Test requires nodejs to run') - version = self.get_node_test_version(nodejs) + version = shared.get_node_version(nodejs) if version < (major, minor, revision): return False @@ -559,14 +586,10 @@ def setup_wasmfs_test(self): self.set_setting('WASMFS') self.cflags += ['-DWASMFS'] - def setup_node_pthreads(self): - self.require_node() + def setup_pthreads(self): self.cflags += ['-Wno-pthreads-mem-growth', '-pthread'] if self.get_setting('MINIMAL_RUNTIME'): self.skipTest('node pthreads not yet supported with MINIMAL_RUNTIME') - nodejs = self.get_nodejs() - self.js_engines = [nodejs] - self.node_args += shared.node_pthread_flags(nodejs) def set_temp_dir(self, temp_dir): self.temp_dir = temp_dir @@ -626,7 +649,7 @@ def setUp(self): nodejs = self.get_nodejs() if nodejs: - node_version = self.get_node_test_version(nodejs) + node_version = shared.get_node_version(nodejs) if node_version < (13, 0, 0): self.node_args.append('--unhandled-rejections=strict') elif node_version < (15, 0, 0): diff --git a/test/decorators.py b/test/decorators.py index 11984fc12fb51..6ee4a26473c8a 100644 --- a/test/decorators.py +++ b/test/decorators.py @@ -208,7 +208,7 @@ def node_pthreads(func): @wraps(func) def decorated(self, *args, **kwargs): - self.setup_node_pthreads() + self.require_pthreads() return func(self, *args, **kwargs) return decorated diff --git a/test/test_core.py b/test/test_core.py index e98390ec09e1f..f5b0669f1697b 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -1991,7 +1991,7 @@ def test_em_asm_2(self): @flaky('https://github.com/emscripten-core/emscripten/issues/25175') def test_main_thread_em_asm(self, args): if args: - self.setup_node_pthreads() + self.require_pthreads() src = read_file(test_file('core/test_em_asm_2.cpp')) create_file('test.cpp', src.replace('EM_ASM', 'MAIN_THREAD_EM_ASM')) @@ -2061,7 +2061,7 @@ def test_em_js(self, args, force_c): self.check_dylink() self.cflags += ['-sEXPORTED_FUNCTIONS=_main,_malloc'] + args if '-pthread' in args: - self.setup_node_pthreads() + self.require_pthreads() self.do_core_test('test_em_js.cpp', force_c=force_c) if self.get_setting('WASM_ESM_INTEGRATION'): @@ -2742,7 +2742,7 @@ def test_pthread_run_script(self): self.do_runf('pthread/test_pthread_run_script.c') # Run the test again with PROXY_TO_PTHREAD - self.setup_node_pthreads() + self.require_pthreads() self.set_setting('PROXY_TO_PTHREAD') self.set_setting('EXIT_RUNTIME') self.do_runf('pthread/test_pthread_run_script.c') @@ -2918,7 +2918,7 @@ def test_dlfcn_missing(self): }) def test_dlfcn_basic(self, args): if args: - self.setup_node_pthreads() + self.require_pthreads() self.cflags += args create_file('libside.cpp', ''' #include @@ -6811,7 +6811,7 @@ def test_sqlite(self, use_pthreads): self.cflags += ['-lstubs'] if use_pthreads: self.cflags.append('-pthread') - self.setup_node_pthreads() + self.require_pthreads() self.cflags += ['-sUSE_SQLITE3'] self.do_run_in_out_file_test('sqlite/test.c') @@ -9433,7 +9433,7 @@ def test_Module_dynamicLibraries(self, args): ''') if args: - self.setup_node_pthreads() + self.require_pthreads() self.dylink_test( r''' @@ -9661,7 +9661,7 @@ def test_poll_blocking(self): }) def test_pipe_select(self, args): if args: - self.setup_node_pthreads() + self.require_pthreads() self.do_runf('core/test_pipe_select.c', cflags=args) @also_without_bigint @@ -9759,7 +9759,7 @@ def test_modularize_instance_hello(self): @no_strict_js('MODULARIZE is not compatible with STRICT_JS') def test_modularize_instance(self, args): if args: - self.setup_node_pthreads() + self.require_pthreads() create_file('library.js', '''\ addToLibrary({ $baz: () => console.log('baz'), diff --git a/test/test_other.py b/test/test_other.py index 114cd46410fde..4e5523ddfd018 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -6643,7 +6643,7 @@ def test_ld_library_path(self, args): if '-pthread' in args: self.skipTest('Problems with readFile from pthread') if '-pthread' in args: - self.setup_node_pthreads() + self.require_pthreads() create_file('hello1_dep.c', r''' #include @@ -12357,7 +12357,7 @@ def test_gen_struct_info(self): self.assertFileContents(path_from_root('src/struct_info_generated.json'), read_file('out.json')) # Same again for wasm64 - node_version = self.get_node_test_version(self.get_nodejs()) + node_version = shared.get_node_version(self.get_nodejs()) if node_version and node_version >= (14, 0, 0): self.run_process([PYTHON, path_from_root('tools/gen_struct_info.py'), '--wasm64', '-o', 'out.json']) self.assertFileContents(path_from_root('src/struct_info_generated_wasm64.json'), read_file('out.json')) @@ -12870,7 +12870,7 @@ def test_node_unhandled_rejection(self): self.build('main.c', cflags=['--pre-js=pre.js', '-sNODEJS_CATCH_REJECTION=0']) self.assertNotContained('unhandledRejection', read_file('main.js')) - if self.get_node_test_version(self.get_nodejs())[0] >= 15: + if shared.get_node_version(self.get_nodejs())[0] >= 15: self.skipTest('old behaviour of node JS cannot be tested on node v15 or above') output = self.run_js('main.js') @@ -12881,7 +12881,7 @@ def test_default_pthread_stack_size(self): self.do_runf('other/test_default_pthread_stack_size.c') # Same again with pthreads enabled - self.setup_node_pthreads() + self.require_pthreads() self.do_other_test('test_default_pthread_stack_size.c') # Same again but with a custom stack size @@ -13949,7 +13949,7 @@ def test_parseTools_legacy(self): @requires_node def test_min_node_version(self): - node_version = self.get_node_test_version(self.get_nodejs()) + node_version = shared.get_node_version(self.get_nodejs()) node_version = '.'.join(str(x) for x in node_version) self.set_setting('MIN_NODE_VERSION', 300000) expected = 'This emscripten-generated code requires node v30.0.0 (detected v%s' % node_version @@ -14230,7 +14230,7 @@ def test_add_js_function_bigint(self, memory64, wasm_function): }) def test_preload_module(self, args): if '-pthread' in args: - self.setup_node_pthreads() + self.require_pthreads() # TODO(sbc): This test is copyied from test_browser.py. Perhaps find a better way to # share code between them. create_file('library.c', r'''