1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407
|
--- a/test/common.py
+++ b/test/common.py
@@ -60,6 +60,7 @@
EMTEST_SKIP_SLOW = None
EMTEST_SKIP_FLAKY = None
EMTEST_RETRY_FLAKY = None
+EMTEST_LACKS_CLOSURE_COMPILER = None
EMTEST_LACKS_NATIVE_CLANG = None
EMTEST_VERBOSE = None
EMTEST_REBASELINE = None
@@ -232,6 +233,17 @@
return lambda f: f
+def requires_closure_compiler(func):
+ assert callable(func)
+
+ def decorated(self, *args, **kwargs):
+ if EMTEST_LACKS_CLOSURE_COMPILER:
+ return self.skipTest('closure compiler tests are disabled')
+ return func(self, *args, **kwargs)
+
+ return decorated
+
+
def requires_native_clang(func):
assert callable(func)
--- a/test/runner.py
+++ b/test/runner.py
@@ -401,6 +401,7 @@
common.EMTEST_DETECT_TEMPFILE_LEAKS = int(os.getenv('EMTEST_DETECT_TEMPFILE_LEAKS', '0'))
common.EMTEST_ALL_ENGINES = int(os.getenv('EMTEST_ALL_ENGINES', '0'))
common.EMTEST_SKIP_SLOW = int(os.getenv('EMTEST_SKIP_SLOW', '0'))
+ common.EMTEST_LACKS_CLOSURE_COMPILER = int(os.getenv('EMTEST_LACKS_CLOSURE_COMPILER', '0'))
common.EMTEST_SKIP_FLAKY = int(os.getenv('EMTEST_SKIP_FLAKY', '0'))
common.EMTEST_RETRY_FLAKY = int(os.getenv('EMTEST_RETRY_FLAKY', '0'))
common.EMTEST_LACKS_NATIVE_CLANG = int(os.getenv('EMTEST_LACKS_NATIVE_CLANG', '0'))
--- a/test/test_core.py
+++ b/test/test_core.py
@@ -22,14 +22,14 @@
from tools.utils import WINDOWS, MACOS, write_file, delete_file
from tools import shared, building, config, utils, webassembly
import common
-from common import RunnerCore, path_from_root, requires_native_clang, test_file, create_file
+from common import RunnerCore, path_from_root, requires_closure_compiler, requires_native_clang, test_file, create_file
from common import skip_if, no_windows, no_mac, is_slow_test, parameterized, parameterize
from common import env_modify, with_env_modify, disabled, flaky, node_pthreads, also_with_wasm_bigint
from common import read_file, read_binary, requires_v8, requires_node, requires_wasm2js, requires_node_canary
from common import compiler_for, crossplatform, no_4gb, no_2gb, also_with_minimal_runtime
from common import also_with_noderawfs, also_with_wasmfs
from common import with_all_eh_sjlj, with_all_sjlj, also_with_standalone_wasm, can_do_standalone, no_wasm64, requires_wasm_exnref
-from common import NON_ZERO, WEBIDL_BINDER, EMBUILDER, PYTHON
+from common import NON_ZERO, EMTEST_LACKS_CLOSURE_COMPILER, WEBIDL_BINDER, EMBUILDER, PYTHON
import clang_native
# decorators for limiting which modes a test can run in
@@ -328,7 +328,7 @@
# Use closure in some tests for some additional coverage
def maybe_closure(self):
- if '--closure=1' not in self.emcc_args and self.should_use_closure():
+ if '--closure=1' not in self.emcc_args and self.should_use_closure() and not EMTEST_LACKS_CLOSURE_COMPILER:
self.emcc_args += ['--closure=1']
logger.debug('using closure compiler..')
return True
@@ -5398,7 +5398,7 @@
def test_files(self):
# Use closure here, to test we don't break FS stuff
- if '-O3' in self.emcc_args and self.is_wasm2js():
+ if '-O3' in self.emcc_args and self.is_wasm2js() and not EMTEST_LACKS_CLOSURE_COMPILER:
print('closure 2')
self.emcc_args += ['--closure', '2'] # Use closure 2 here for some additional coverage
# Sadly --closure=2 is not yet free of closure warnings
@@ -7948,6 +7948,7 @@
self.assertLessEqual(start_wat_addr, dwarf_addr)
self.assertLessEqual(dwarf_addr, end_wat_addr)
+ @requires_closure_compiler
def test_modularize_closure_pre(self):
# test that the combination of modularize + closure + pre-js works. in that mode,
# closure should not minify the Module object in a way that the pre-js cannot use it.
@@ -9029,6 +9030,7 @@
@no_wasm2js('TODO: ASAN in wasm2js')
@no_wasm64('TODO: ASAN in memory64')
@no_2gb('asan doesnt support GLOBAL_BASE')
+ @requires_closure_compiler
def test_asan_modularized_with_closure(self):
# the bug is that createModule() returns undefined, instead of the
# proper Promise object.
--- a/test/test_other.py
+++ b/test/test_other.py
@@ -32,8 +32,8 @@
from tools.shared import EMCC, EMXX, EMAR, EMRANLIB, FILE_PACKAGER, LLVM_NM
from tools.shared import CLANG_CC, CLANG_CXX, LLVM_AR, LLVM_DWARFDUMP, LLVM_DWP, EMCMAKE, EMCONFIGURE, WASM_LD
from common import RunnerCore, path_from_root, is_slow_test, ensure_dir, disabled, make_executable
-from common import env_modify, no_mac, no_windows, only_windows, requires_native_clang, with_env_modify
-from common import create_file, parameterized, NON_ZERO, node_pthreads, TEST_ROOT, test_file
+from common import env_modify, no_mac, no_windows, only_windows, requires_closure_compiler, requires_native_clang, with_env_modify
+from common import create_file, parameterized, NON_ZERO, EMTEST_LACKS_CLOSURE_COMPILER, node_pthreads, TEST_ROOT, test_file
from common import compiler_for, EMBUILDER, requires_v8, requires_node, requires_wasm64, requires_node_canary
from common import requires_wasm_exnref, crossplatform, with_all_eh_sjlj, with_all_sjlj
from common import also_with_standalone_wasm, also_with_wasm2js, also_with_noderawfs, also_with_wasmfs
@@ -381,6 +381,7 @@
self.assertContained("new Worker(new URL('hello_world.mjs', import.meta.url), workerOptions)", src)
self.assertContained('hello, world!', self.run_js('hello_world.mjs'))
+ @requires_closure_compiler
def test_emcc_output_mjs_closure(self):
self.run_process([EMCC, '-o', 'hello_world.mjs',
'--extern-post-js', test_file('modularize_post_js.js'),
@@ -2785,6 +2786,7 @@
self.do_runf(test_file('hello_world.c'), 'prepre\npre-run\nhello, world!\n',
emcc_args=['--pre-js', 'pre.js', '--pre-js', 'pre2.js'])
+ @requires_closure_compiler
def test_extern_prepost(self):
create_file('extern-pre.js', '// I am an external pre.\n')
create_file('extern-post.js', '// I am an external post.\n')
@@ -3182,6 +3184,7 @@
''')
self.do_runf('main.cpp', '42', emcc_args=['-lembind', '--post-js', 'post.js'])
+ @requires_closure_compiler
def test_embind_closure_no_dynamic_execution(self):
create_file('post.js', '''
Module['onRuntimeInitialized'] = () => {
@@ -3841,6 +3844,7 @@
self.assertLess(output.count('Cannot enlarge memory arrays'), 6)
@requires_node
+ @requires_closure_compiler
def test_module_exports_with_closure(self):
# This test checks that module.export is retained when JavaScript
# is minified by compiling with --closure 1
@@ -4791,6 +4795,7 @@
output = self.run_js('a.out.js')
self.assertContained('|5|', output)
+ @requires_closure_compiler
def test_LEGACY_VM_SUPPORT(self):
# when modern features are lacking, we can polyfill them or at least warn
create_file('pre.js', 'Math.imul = undefined;')
@@ -6476,12 +6481,13 @@
test(['-sASSERTIONS=0'], 120000) # we don't care about code size with assertions
test(['-O1'], 91000)
test(['-O2'], 46000)
- test(['-O3', '--closure=1'], 17000)
- # js too
- # -Wclosure is needed due to
- # https://github.com/google/closure-compiler/issues/4108
- test(['-O3', '--closure=1', '-Wno-closure', '-sWASM=0'], 36000)
- test(['-O3', '--closure=2', '-Wno-closure', '-sWASM=0'], 33000) # might change now and then
+ if not EMTEST_LACKS_CLOSURE_COMPILER:
+ test(['-O3', '--closure=1'], 17000)
+ # js too
+ # -Wclosure is needed due to
+ # https://github.com/google/closure-compiler/issues/4108
+ test(['-O3', '--closure=1', '-Wno-closure', '-sWASM=0'], 36000)
+ test(['-O3', '--closure=2', '-Wno-closure', '-sWASM=0'], 33000) # might change now and then
def test_no_main_loop(self):
MAINLOOP = 'var MainLoop'
@@ -7880,7 +7886,7 @@
'-sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=$dynCall',
'-sEXPORTED_RUNTIME_METHODS=getTempRet0',
'-sEXPORTED_FUNCTIONS=_test_return64', '-o', 'test.js', '-O2',
- '--closure=1', '-g1', '-sWASM_ASYNC_COMPILATION=0'] + args)
+ '--closure=0' if EMTEST_LACKS_CLOSURE_COMPILER else '--closure=1', '-g1', '-sWASM_ASYNC_COMPILATION=0'] + args)
# Simple test program to load the test.js binding library and call the binding to the
# C function returning the 64 bit long.
@@ -9312,6 +9318,7 @@
for std in ([], ['-std=c89']):
self.run_process([EMCC] + std + ['-Werror', '-Wall', '-pedantic', 'a.c', 'b.c'])
+ @requires_closure_compiler
@is_slow_test
@parameterized({
'': (True,),
@@ -9324,6 +9331,8 @@
# skip unhelpful option combinations
if closure_enabled and debug_enabled:
continue
+ if closure_enabled and not EMTEST_LACKS_CLOSURE_COMPILER:
+ continue
cmd = [EMCC, test_file('hello_world.c')] + self.get_emcc_args()
@@ -9454,6 +9463,7 @@
assert_aliases_match('MAXIMUM_MEMORY', 'WASM_MEM_MAX', '16777216', ['-sALLOW_MEMORY_GROWTH'])
assert_aliases_match('MAXIMUM_MEMORY', 'BINARYEN_MEM_MAX', '16777216', ['-sALLOW_MEMORY_GROWTH'])
+ @requires_closure_compiler
def test_IGNORE_CLOSURE_COMPILER_ERRORS(self):
create_file('pre.js', r'''
// make closure compiler very very angry
@@ -9504,6 +9514,7 @@
self.do_other_test('test_full_js_library_except.cpp')
@crossplatform
+ @requires_closure_compiler
@parameterized({
'': [[]],
# bigint support is interesting to test here because it changes which
@@ -9569,6 +9580,7 @@
self.assertContained('.' + sym, js)
@also_with_wasm64
+ @requires_closure_compiler
def test_closure_webgpu(self):
# This test can be removed if USE_WEBGPU is later included in INCLUDE_FULL_LIBRARY.
self.build(test_file('hello_world.c'), emcc_args=[
@@ -9580,6 +9592,7 @@
# Tests --closure-args command line flag
@crossplatform
+ @requires_closure_compiler
def test_closure_externs(self):
# Test with relocate path to the externs file to ensure that incoming relative paths
# are translated correctly (Since closure runs with a different CWD)
@@ -9596,6 +9609,7 @@
args)
# Tests that it is possible to enable the Closure compiler via --closure=1 even if any of the input files reside in a path with unicode characters.
+ @requires_closure_compiler
def test_closure_cmdline_utf8_chars(self):
test = "☃ äö Ć € ' 🦠.c"
shutil.copy(test_file('hello_world.c'), test)
@@ -9603,6 +9617,7 @@
create_file(externs, '')
self.run_process([EMCC, test, '--closure=1', '--closure-args', '--externs "' + externs + '"'])
+ @requires_closure_compiler
def test_closure_type_annotations(self):
# Verify that certain type annotations exist to allow closure to avoid
# ambiguity and maximize optimization opportunities in user code.
@@ -9868,11 +9883,12 @@
self.assertContained('GROWABLE_HEAP_I8().set([ 1, 2, 3 ], $0 >>> 0)',
read_file('a.out.js'))
+ # FIXME: skip tests when closure is lacking instead of doing same tests twice
@parameterized({
'': ([],), # noqa
'O3': (['-O3'],), # noqa
- 'closure': (['--closure=1'],), # noqa
- 'closure_O3': (['--closure=1', '-O3'],), # noqa
+ 'closure': (['--closure=0' if EMTEST_LACKS_CLOSURE_COMPILER else '--closure=1'],), # noqa
+ 'closure_O3': (['--closure=0' if EMTEST_LACKS_CLOSURE_COMPILER else '--closure=1', '-O3'],), # noqa
})
def test_EM_ASM_ES6(self, args):
create_file('src.c', r'''
@@ -10838,7 +10854,10 @@
for wasm in ([], ['-sWASM=0']):
# Currently we rely on Closure for full minification of every appearance of JS function names.
# TODO: Add minification also for non-Closure users and add [] to this list to test minification without Closure.
- for closure in [['--closure=1']]:
+ closure_cases = [[]]
+ if not EMTEST_LACKS_CLOSURE_COMPILER:
+ closure_cases.append(['--closure=1'])
+ for closure in closure_cases:
args = [EMCC, '-O3', '--js-library', 'library_long.js', 'main_long.c', '-o', 'a.html'] + wasm + closure
print(' '.join(args))
self.run_process(args)
@@ -10868,15 +10887,16 @@
self.assertNotContained('invoke_ii', output)
self.assertNotContained('invoke_v', output)
+ # FIXME: skip tests when closure is lacking instead of doing same tests twice
@parameterized({
'O0': (False, ['-O0']), # noqa
'O0_emit': (True, ['-O0', '-sEMIT_EMSCRIPTEN_LICENSE']), # noqa
'O2': (False, ['-O2']), # noqa
'O2_emit': (True, ['-O2', '-sEMIT_EMSCRIPTEN_LICENSE']), # noqa
'O2_js_emit': (True, ['-O2', '-sEMIT_EMSCRIPTEN_LICENSE', '-sWASM=0']), # noqa
- 'O2_closure': (False, ['-O2', '--closure=1']), # noqa
- 'O2_closure_emit': (True, ['-O2', '-sEMIT_EMSCRIPTEN_LICENSE', '--closure=1']), # noqa
- 'O2_closure_js_emit': (True, ['-O2', '-sEMIT_EMSCRIPTEN_LICENSE', '--closure=1', '-sWASM=0']), # noqa
+ 'O2_closure': (False, ['-O2', '--closure=0' if EMTEST_LACKS_CLOSURE_COMPILER else '--closure=1']), # noqa
+ 'O2_closure_emit': (True, ['-O2', '-sEMIT_EMSCRIPTEN_LICENSE', '--closure=0' if EMTEST_LACKS_CLOSURE_COMPILER else '--closure=1']), # noqa
+ 'O2_closure_js_emit': (True, ['-O2', '-sEMIT_EMSCRIPTEN_LICENSE', '--closure=0' if EMTEST_LACKS_CLOSURE_COMPILER else '--closure=1', '-sWASM=0']), # noqa
})
def test_emscripten_license(self, expect_license, args):
# fastcomp does not support the new license flag
@@ -10956,7 +10976,7 @@
'-sSTRICT',
'--output_eol', 'linux',
'-Oz',
- '--closure=1',
+ '--closure=0' if EMTEST_LACKS_CLOSURE_COMPILER else '--closure=1',
'-DNDEBUG',
'-ffast-math']
@@ -11503,6 +11523,7 @@
# otherwise in such a trivial program).
self.assertLess(no, 0.95 * yes)
+ @requires_closure_compiler
def test_INCOMING_MODULE_JS_API(self):
def test(args):
self.run_process([EMCC, test_file('hello_world.c'), '-O3', '--closure=1', '-sENVIRONMENT=node,shell', '--output_eol=linux'] + args)
@@ -11645,6 +11666,7 @@
self.assertContainedIf('exception catching is disabled, this exception cannot be caught', result, expect_caught)
self.assertContainedIf('CAUGHT', result, expect_caught)
+ @requires_closure_compiler
def test_exceptions_with_closure_and_without_catching(self):
# using invokes will require setThrew(), and closure will error if it is not
# defined. this test checks that we define it even without catching any
@@ -11982,11 +12004,14 @@
def test_warning_flags(self):
self.run_process([EMCC, '-c', '-o', 'hello.o', test_file('hello_world.c')])
- cmd = [EMCC, 'hello.o', '-o', 'a.js', '-g', '--closure=1']
+ cmd = [EMCC, 'hello.o', '-o', 'a.js', '-g']
+ if not EMTEST_LACKS_CLOSURE_COMPILER:
+ cmd.append(['--closure=1'])
# warning that is enabled by default
- stderr = self.run_process(cmd, stderr=PIPE).stderr
- self.assertContained('emcc: warning: disabling closure because debug info was requested [-Wemcc]', stderr)
+ if not EMTEST_LACKS_CLOSURE_COMPILER:
+ stderr = self.run_process(cmd, stderr=PIPE).stderr
+ self.assertContained('emcc: warning: disabling closure because debug info was requested [-Wemcc]', stderr)
# -w to suppress warnings
stderr = self.run_process(cmd + ['-w'], stderr=PIPE).stderr
@@ -11997,12 +12022,14 @@
self.assertNotContained('warning', stderr)
# with -Werror should fail
- stderr = self.expect_fail(cmd + ['-Werror'])
- self.assertContained('error: disabling closure because debug info was requested [-Wemcc] [-Werror]', stderr)
+ if not EMTEST_LACKS_CLOSURE_COMPILER:
+ stderr = self.expect_fail(cmd + ['-Werror'])
+ self.assertContained('error: disabling closure because debug info was requested [-Wemcc] [-Werror]', stderr)
# with -Werror + -Wno-error=<type> should only warn
- stderr = self.run_process(cmd + ['-Werror', '-Wno-error=emcc'], stderr=PIPE).stderr
- self.assertContained('emcc: warning: disabling closure because debug info was requested [-Wemcc]', stderr)
+ if not EMTEST_LACKS_CLOSURE_COMPILER:
+ stderr = self.run_process(cmd + ['-Werror', '-Wno-error=emcc'], stderr=PIPE).stderr
+ self.assertContained('emcc: warning: disabling closure because debug info was requested [-Wemcc]', stderr)
# check that `-Werror=foo` also enales foo
stderr = self.expect_fail(cmd + ['-Werror=legacy-settings', '-sTOTAL_MEMORY'])
@@ -12187,6 +12214,7 @@
for engine in config.WASM_ENGINES:
self.assertContained(expected, self.run_js('test.wasm', engine))
+ @requires_closure_compiler
@parameterized({
'wasm2js': (['-sWASM=0'],),
'modularize': (['-sMODULARIZE', '--extern-post-js', test_file('modularize_post_js.js')],),
@@ -12232,6 +12260,7 @@
self.assertContained('function signature mismatch: foo', stderr)
# Verifies that warning messages that Closure outputs are recorded to console
+ @requires_closure_compiler
def test_closure_warnings(self):
# Default should be no warnings
proc = self.run_process([EMCC, test_file('test_closure_warning.c'), '-O3', '--closure=1'], stderr=PIPE)
@@ -12729,6 +12758,7 @@
self.assertContained('hello, world!', self.run_js('a.out.js'))
# Test that Closure prints out clear readable error messages when there are errors.
+ @requires_closure_compiler
def test_closure_errors(self):
err = self.expect_fail([EMCC, test_file('closure_error.c'), '-O2', '--closure=1'])
lines = err.split('\n')
@@ -12747,16 +12777,19 @@
self.assertNotEqual(idx1, idx2)
# Make sure that --cpuprofiler compiles with --closure 1
+ @requires_closure_compiler
def test_cpuprofiler_closure(self):
# TODO: Enable '-Werror=closure' in the following, but that has currently regressed.
self.run_process([EMCC, test_file('hello_world.c'), '-O2', '--closure=1', '--cpuprofiler'])
# Make sure that --memoryprofiler compiles with --closure 1
+ @requires_closure_compiler
def test_memoryprofiler_closure(self):
# TODO: Enable '-Werror=closure' in the following, but that has currently regressed.
self.run_process([EMCC, test_file('hello_world.c'), '-O2', '--closure=1', '--memoryprofiler'])
# Make sure that --threadprofiler compiles with --closure 1
+ @requires_closure_compiler
def test_threadprofiler_closure(self):
# TODO: Enable '-Werror=closure' in the following, but that has currently regressed.
self.run_process([EMCC, test_file('hello_world.c'), '-O2', '-pthread', '--closure=1', '--threadprofiler', '-sASSERTIONS'])
@@ -13326,6 +13359,7 @@
err = self.run_js('test_pthread_js_exception.js', assert_returncode=NON_ZERO)
self.assertContained('missing is not defined', err)
+ @requires_closure_compiler
def test_config_closure_compiler(self):
self.run_process([EMCC, test_file('hello_world.c'), '--closure=1'])
with env_modify({'EM_CLOSURE_COMPILER': sys.executable}):
@@ -13607,6 +13641,7 @@
# as `examples/`?)
self.run_process([EMCC, test_file('hello_function.cpp'), '-o', 'function.html', '-sEXPORTED_FUNCTIONS=_int_sqrt', '-sEXPORTED_RUNTIME_METHODS=ccall,cwrap'])
+ @requires_closure_compiler
@parameterized({
'': ([],),
'O3': (['-O3'],),
|