Skip to content

Commit 9a9beff

Browse files
authored
Safari test skips (#25528)
Improve Safari test harness skips to be aware of Safari version.
1 parent 7fb8817 commit 9a9beff

File tree

1 file changed

+46
-14
lines changed

1 file changed

+46
-14
lines changed

test/test_browser.py

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66
import argparse
77
import os
8+
import plistlib
89
import random
10+
import re
911
import shlex
1012
import shutil
1113
import subprocess
@@ -26,8 +28,9 @@
2628
from common import HttpServerThread, requires_dev_dependency
2729
from tools import shared
2830
from tools import ports
31+
from tools.feature_matrix import UNSUPPORTED
2932
from tools.shared import EMCC, WINDOWS, FILE_PACKAGER, PIPE, DEBUG
30-
from tools.utils import delete_dir
33+
from tools.utils import delete_dir, memoize
3134

3235

3336
def make_test_chunked_synchronous_xhr_server(support_byte_ranges, data, port):
@@ -141,6 +144,20 @@ def is_swiftshader(_):
141144
return is_chrome() and '--use-gl=swiftshader' in common.EMTEST_BROWSER
142145

143146

147+
@memoize
148+
def get_safari_version():
149+
if not is_safari():
150+
return UNSUPPORTED
151+
plist_path = os.path.join(common.EMTEST_BROWSER.strip(), 'Contents', 'version.plist')
152+
version_str = plistlib.load(open(plist_path, 'rb')).get('CFBundleShortVersionString')
153+
# Split into parts (major.minor.patch)
154+
parts = (version_str.split('.') + ['0', '0', '0'])[:3]
155+
# Convert each part into integers, discarding any trailing string, e.g. '13a' -> 13.
156+
parts = [int(re.match(r"\d+", s).group()) if re.match(r"\d+", s) else 0 for s in parts]
157+
# Return version as XXYYZZ
158+
return parts[0] * 10000 + parts[1] * 100 + parts[2]
159+
160+
144161
no_swiftshader = skip_if_simple('not compatible with swiftshader', is_swiftshader)
145162

146163
no_chrome = skip_if('no_chrome', lambda _: is_chrome(), 'chrome is not supported')
@@ -150,6 +167,18 @@ def is_swiftshader(_):
150167
no_safari = skip_if('no_safari', lambda _: is_safari(), 'safari is not supported')
151168

152169

170+
def requires_version(name, version_getter):
171+
assert callable(version_getter)
172+
173+
def decorator(min_required_version, note=''):
174+
return skip_if_simple(name, lambda _: version_getter() < min_required_version, f'{name} v{version_getter()} is not supported (need v{min_required_version} at minimum) {note}')
175+
176+
return decorator
177+
178+
179+
requires_safari_version = requires_version('safari', get_safari_version)
180+
181+
153182
def is_jspi(args):
154183
return '-sASYNCIFY=2' in args
155184

@@ -289,6 +318,7 @@ def test_sdl1(self):
289318
def test_sdl1_es6(self):
290319
self.reftest('hello_world_sdl.c', 'htmltest.png', cflags=['-sUSE_SDL', '-lGL', '-sEXPORT_ES6'])
291320

321+
@no_safari('TODO: Fails in NEW Safari 26.0.1 (21622.1.22.11.15), but not in OLD Safari 17.6 (17618.3.11.11.7, 17618) or Safari 18.5 (20621.2.5.11.8)')
292322
def test_emscripten_log(self):
293323
self.btest_exit('test_emscripten_log.cpp', cflags=['-Wno-deprecated-pragma', '-gsource-map', '-g2'])
294324

@@ -1443,6 +1473,7 @@ def test_separate_metadata_later(self):
14431473
self.run_process([FILE_PACKAGER, 'more.data', '--preload', 'data.dat', '--separate-metadata', '--js-output=more.js'])
14441474
self.btest(Path('browser/separate_metadata_later.cpp'), '1', cflags=['-sFORCE_FILESYSTEM'])
14451475

1476+
@requires_safari_version(260001, 'TODO: Fails with "Assertion failed: false"') # Fails in Safari 18.5 (20621.2.5.11.8) with Intel x64 CPU only. Passes on Safari 18.5 (20621.2.5.11.8) with ARM M1, Safari 17.6 (17618.3.11.11.7, 17618)/x64 and Safari 26.0.1 (21622.1.22.11.15)/M4
14461477
def test_idbstore(self):
14471478
secret = str(time.time())
14481479
for stage in (0, 1, 2, 3, 0, 1, 2, 0, 0, 1, 4, 2, 5, 0, 4, 6, 5):
@@ -2800,7 +2831,7 @@ def test_webgl2_pbo(self):
28002831
self.btest_exit('webgl2_pbo.c', cflags=['-sMAX_WEBGL_VERSION=2', '-lGL'])
28012832

28022833
@no_firefox('fails on CI likely due to GPU drivers there')
2803-
@no_safari('TODO: Fails with report_result?5') # Safari 17.6 (17618.3.11.11.7, 17618)
2834+
@no_safari('TODO: Fails with report_result?5') # Fails in Safari 17.6 (17618.3.11.11.7, 17618), Safari 26.0.1 (21622.1.22.11.15)
28042835
@requires_graphics_hardware
28052836
def test_webgl2_sokol_mipmap(self):
28062837
self.reftest('third_party/sokol/mipmap-emsc.c', 'third_party/sokol/mipmap-emsc.png',
@@ -2959,7 +2990,7 @@ def test_sdl2_image_jpeg(self):
29592990
@also_with_wasmfs
29602991
@requires_graphics_hardware
29612992
@with_all_sjlj
2962-
@no_safari('Test enables Wasm exceptions, so will not run in Safari 17.6 (17618.3.11.11.7, 17618)') # Safari 17.6 (17618.3.11.11.7, 17618)
2993+
@requires_safari_version(170601, 'TODO: Test enables Wasm exceptions') # Fails in Safari 17.6 (17618.3.11.11.7, 17618), passes in Safari 18.5 (20621.2.5.11.8) and Safari 26.0.1 (21622.1.22.11.15)
29632994
def test_sdl2_image_formats(self):
29642995
shutil.copy(test_file('screenshot.png'), '.')
29652996
shutil.copy(test_file('screenshot.jpg'), '.')
@@ -3361,7 +3392,7 @@ def test_async_returnvalue(self, args):
33613392
create_file('filey.txt', 'sync_tunnel\nsync_tunnel_bool\n')
33623393
self.btest('test_async_returnvalue.c', '0', cflags=['-sASSERTIONS', '-sASYNCIFY', '-sASYNCIFY_IGNORE_INDIRECT', '--js-library', test_file('browser/test_async_returnvalue.js')] + args)
33633394

3364-
@no_safari('TODO: Never reports a result, so times out') # Safari 17.6 (17618.3.11.11.7, 17618)
3395+
@no_safari('TODO: Never reports a result, so times out') # Fails in Safari 17.6 (17618.3.11.11.7, 17618), Safari 26.0.1 (21622.1.22.11.15)
33653396
def test_async_bad_list(self):
33663397
self.btest('test_async_bad_list.c', '0', cflags=['-sASYNCIFY', '-sASYNCIFY_ONLY=waka', '--profiling'])
33673398

@@ -3414,7 +3445,7 @@ def test_modularize(self, args, code, opts):
34143445
self.run_browser('a.html', '/report_result?0')
34153446

34163447
@no_firefox('source phase imports not implemented yet in firefox')
3417-
@no_safari('croaks on line "import source wasmModule from \'./out.wasm\';"') # Safari 17.6 (17618.3.11.11.7, 17618)
3448+
@no_safari('TODO: croaks on line "import source wasmModule from \'./out.wasm\';"') # Fails in Safari 17.6 (17618.3.11.11.7, 17618), Safari 26.0.1 (21622.1.22.11.15)
34183449
def test_source_phase_imports(self):
34193450
self.compile_btest('browser_test_hello_world.c', ['-sEXPORT_ES6', '-sSOURCE_PHASE_IMPORTS', '-Wno-experimental', '-o', 'out.mjs'])
34203451
create_file('a.html', '''
@@ -3801,7 +3832,7 @@ def test_pthread_gcc_64bit_atomic_fetch_and_op(self):
38013832

38023833
# Test the old GCC atomic __sync_op_and_fetch builtin operations.
38033834
@also_with_wasm2js
3804-
@no_safari('TODO: browser.test_pthread_gcc_atomic_op_and_fetch_wasm2js fails with "abort:Assertion failed: nand_and_fetch_data == -1"') # Safari 17.6 (17618.3.11.11.7, 17618)
3835+
@requires_safari_version(170601, 'TODO: browser.test_pthread_gcc_atomic_op_and_fetch_wasm2js fails with "abort:Assertion failed: nand_and_fetch_data == -1"') # Fails in Safari 17.6 (17618.3.11.11.7, 17618), passes in Safari 18.5 (20621.2.5.11.8) and Safari 26.0.1 (21622.1.22.11.15)
38053836
def test_pthread_gcc_atomic_op_and_fetch(self):
38063837
self.cflags += ['-Wno-sync-fetch-and-nand-semantics-changed']
38073838
self.btest_exit('pthread/test_pthread_gcc_atomic_op_and_fetch.c', cflags=['-O3', '-pthread', '-sPTHREAD_POOL_SIZE=8'])
@@ -3899,7 +3930,7 @@ def test_pthread_cleanup(self):
38993930
'': ([],),
39003931
'spinlock': (['-DSPINLOCK_TEST'],),
39013932
})
3902-
@no_safari('TODO: browser.test_pthread_mutex and browser.test_pthread_mutex_spinlock both hang Safari') # Safari 17.6 (17618.3.11.11.7, 17618)
3933+
@requires_safari_version(170601, 'TODO: browser.test_pthread_mutex and browser.test_pthread_mutex_spinlock both hang Safari') # Fails in Safari 17.6 (17618.3.11.11.7, 17618), passes in Safari 18.5 (20621.2.5.11.8) and Safari 26.0.1 (21622.1.22.11.15)
39033934
def test_pthread_mutex(self, args):
39043935
self.btest_exit('pthread/test_pthread_mutex.c', cflags=['-O3', '-pthread', '-sPTHREAD_POOL_SIZE=8'] + args)
39053936

@@ -4087,7 +4118,7 @@ def test_pthread_safe_stack(self):
40874118
'no_leak': ['test_pthread_lsan_no_leak', []],
40884119
})
40894120
@no_firefox('https://github.com/emscripten-core/emscripten/issues/15978')
4090-
@no_safari('TODO: browser.test_pthread_lsan_leak fails with /report_result?0') # Safari 17.6 (17618.3.11.11.7, 17618)
4121+
@no_safari('TODO: browser.test_pthread_lsan_leak fails with /report_result?0') # Fails in Safari 17.6 (17618.3.11.11.7, 17618), Safari 26.0.1 (21622.1.22.11.15)
40914122
def test_pthread_lsan(self, name, args):
40924123
self.btest(Path('pthread', name + '.cpp'), expected='1', cflags=['-fsanitize=leak', '-pthread', '-sPROXY_TO_PTHREAD', '--pre-js', test_file('pthread', name + '.js')] + args)
40934124

@@ -4099,7 +4130,7 @@ def test_pthread_lsan(self, name, args):
40994130
'leak': ['test_pthread_lsan_leak', ['-gsource-map']],
41004131
'no_leak': ['test_pthread_lsan_no_leak', []],
41014132
})
4102-
@no_safari('TODO: browser.test_pthread_asan_leak fails with /report_result?0') # Safari 17.6 (17618.3.11.11.7, 17618)
4133+
@no_safari('TODO: browser.test_pthread_asan_leak fails with /report_result?0') # Fails in Safari 17.6 (17618.3.11.11.7, 17618), Safari 26.0.1 (21622.1.22.11.15)
41034134
def test_pthread_asan(self, name, args):
41044135
self.btest(Path('pthread', name + '.cpp'), expected='1', cflags=['-fsanitize=address', '-pthread', '-sPROXY_TO_PTHREAD', '--pre-js', test_file('pthread', name + '.js')] + args)
41054136

@@ -4113,7 +4144,7 @@ def test_pthread_asan_use_after_free(self):
41134144
@no_2gb('ASAN + GLOBAL_BASE')
41144145
@no_4gb('ASAN + GLOBAL_BASE')
41154146
@no_firefox('https://github.com/emscripten-core/emscripten/issues/20006')
4116-
@no_safari('TODO: Hangs') # Safari Version 18.5 (20621.2.5.11.8)
4147+
@no_safari('TODO: Hangs') # Fails in Safari 17.6 (17618.3.11.11.7, 17618), Safari 26.0.1 (21622.1.22.11.15)
41174148
@also_with_wasmfs
41184149
def test_pthread_asan_use_after_free_2(self):
41194150
# similiar to test_pthread_asan_use_after_free, but using a pool instead
@@ -4132,7 +4163,7 @@ def test_pthread_exit_process(self):
41324163
args += ['--pre-js', test_file('core/pthread/test_pthread_exit_runtime.pre.js')]
41334164
self.btest('core/pthread/test_pthread_exit_runtime.c', expected='onExit status: 42', cflags=args)
41344165

4135-
@no_safari('TODO: Fails with report_result?unexpected: [object ErrorEvent]') # Safari 17.6 (17618.3.11.11.7, 17618)
4166+
@no_safari('TODO: Fails with report_result?unexpected: [object ErrorEvent]') # Fails in Safari 17.6 (17618.3.11.11.7, 17618), Safari 26.0.1 (21622.1.22.11.15)
41364167
def test_pthread_trap(self):
41374168
create_file('pre.js', '''
41384169
if (typeof window === 'object' && window) {
@@ -5321,6 +5352,7 @@ def test_4gb(self):
53215352

53225353
# Tests that emmalloc supports up to 4GB Wasm heaps.
53235354
@no_firefox('no 4GB support yet')
5355+
@requires_safari_version(170601, 'Assertion failed: emscripten_get_heap_size() == MAX_HEAP') # Fails in Safari 17.6 (17618.3.11.11.7, 17618)
53245356
@no_4gb('uses MAXIMUM_MEMORY')
53255357
def test_emmalloc_4gb(self):
53265358
# For now, keep this in browser as this suite runs serially, which
@@ -5389,7 +5421,7 @@ def test_wasmfs_fetch_backend_threaded(self, args):
53895421
'jspi': (['-Wno-experimental', '-sASYNCIFY=2'],),
53905422
'jspi_wasm_bigint': (['-Wno-experimental', '-sASYNCIFY=2', '-sWASM_BIGINT'],),
53915423
})
5392-
@no_safari('TODO: Fails with abort:Assertion failed: err == 0') # Safari 17.6 (17618.3.11.11.7, 17618)
5424+
@no_safari('TODO: Fails with abort:Assertion failed: err == 0') # Fails in Safari 17.6 (17618.3.11.11.7, 17618), Safari 26.0.1 (21622.1.22.11.15)
53935425
def test_wasmfs_opfs(self, args):
53945426
if '-sASYNCIFY=2' in args:
53955427
self.require_jspi()
@@ -5399,7 +5431,7 @@ def test_wasmfs_opfs(self, args):
53995431
self.btest_exit(test, cflags=args + ['-DWASMFS_RESUME'])
54005432

54015433
@no_firefox('no OPFS support yet')
5402-
@no_safari('TODO: Fails with exception:Did not get expected EIO when unlinking file') # Safari 17.6 (17618.3.11.11.7, 17618)
5434+
@no_safari('TODO: Fails with exception:Did not get expected EIO when unlinking file') # Fails in Safari 17.6 (17618.3.11.11.7, 17618) and Safari 26.0.1 (21622.1.22.11.15)
54035435
def test_wasmfs_opfs_errors(self):
54045436
test = test_file('wasmfs/wasmfs_opfs_errors.c')
54055437
postjs = test_file('wasmfs/wasmfs_opfs_errors_post.js')
@@ -5474,7 +5506,7 @@ def test_manual_pthread_proxy_hammer(self, args):
54745506
def test_assert_failure(self):
54755507
self.btest('test_assert_failure.c', 'abort:Assertion failed: false && "this is a test"')
54765508

5477-
@no_safari('TODO: Fails with report_result?exception:rejected! / undefined') # Safari 17.6 (17618.3.11.11.7, 17618)
5509+
@no_safari('TODO: Fails with report_result?exception:rejected!') # Fails in Safari 17.6 (17618.3.11.11.7, 17618), Safari 26.0.1 (21622.1.22.11.15)
54785510
def test_pthread_unhandledrejection(self):
54795511
# Check that an unhandled promise rejection is propagated to the main thread
54805512
# as an error. This test is failing if it hangs!

0 commit comments

Comments
 (0)