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
|
# Copyright 2020 The Emscripten Authors. All rights reserved.
# Emscripten is available under two separate licenses, the MIT license and the
# University of Illinois/NCSA Open Source License. Both these licenses can be
# found in the LICENSE file.
"""Runs the pthreads test from the upstream posixtest suite in:
./tests/third_party/posixtestsuite
See
https://github.com/emscripten-core/posixtestsuite
"""
import glob
import os
import unittest
from common import RunnerCore, path_from_root, node_pthreads
import test_posixtest_browser
testsuite_root = path_from_root('tests/third_party/posixtestsuite')
class posixtest(RunnerCore):
"""Run the suite under node (and in parallel)
This class get populated dynamically below.
"""
pass
def filter_tests(all_tests):
pthread_tests = [t for t in all_tests if t.startswith('pthread_')]
return pthread_tests
def get_pthread_tests():
# For now, we don't require the submodule to exist. In this case we just report
# no tests
pthread_test_root = os.path.join(testsuite_root, 'conformance', 'interfaces')
if not os.path.exists(pthread_test_root):
print('posixtestsuite not found (run git submodule update --init?)')
return []
pthread_tests = filter_tests(os.listdir(pthread_test_root))
pthread_tests = [os.path.join(pthread_test_root, t) for t in pthread_tests]
return pthread_tests
# Mark certain tests as unsupported
# TODO: Investigate failing semaphores tests.
unsupported_noreturn = {
'test_pthread_atfork_1_1': 'fork() and multiple processes are not supported',
'test_pthread_atfork_1_2': 'fork() and multiple processes are not supported',
'test_pthread_atfork_2_1': 'fork() and multiple processes are not supported',
'test_pthread_atfork_2_2': 'fork() and multiple processes are not supported',
'test_pthread_atfork_3_2': 'fork() and multiple processes are not supported',
'test_pthread_atfork_4_1': 'fork() and multiple processes are not supported',
'test_pthread_kill_1_1': 'signals are not supported',
'test_pthread_create_1_5': 'fork() and multiple processes are not supported',
'test_pthread_exit_6_1': 'lacking necessary mmap() support',
'test_pthread_spin_lock_1_1': 'signals are not supported',
'test_pthread_mutex_lock_5_1': 'signals are not supported',
'test_pthread_mutexattr_settype_2_1': 'interrupting pthread_mutex_lock wait via SIGALRM is not supported',
'test_pthread_spin_lock_3_1': 'signals are not supported',
'test_pthread_create_14_1': 'creates too many threads',
'test_pthread_detach_4_3': 'creates too many threads',
'test_pthread_join_6_3': 'creates too many threads',
'test_pthread_barrier_wait_3_2': 'signals are not supported',
'test_pthread_cond_broadcast_1_2': 'tries to create 10,0000 threads, then depends on fork()',
}
unsupported = {
'test_pthread_attr_setinheritsched_2_2': 'scheduling policy/parameters are not supported',
'test_pthread_attr_setinheritsched_2_3': 'scheduling policy/parameters are not supported',
'test_pthread_attr_setinheritsched_2_4': 'scheduling policy/parameters are not supported',
'test_pthread_attr_setschedparam_1_3': 'scheduling policy/parameters are not supported',
'test_pthread_attr_setschedparam_1_4': 'scheduling policy/parameters are not supported',
'test_pthread_attr_setschedpolicy_4_1': 'scheduling policy/parameters are not supported',
'test_pthread_barrierattr_getpshared_2_1': 'shm_open and shm_unlink are not supported',
'test_pthread_barrier_wait_3_1': 'signals are not supported',
'test_pthread_cond_broadcast_2_3': 'lacking necessary mmap() support',
'test_pthread_cond_destroy_2_1': 'lacking necessary mmap() support',
'test_pthread_cond_init_1_2': 'clock_settime() is not supported',
'test_pthread_cond_init_1_3': 'lacking necessary mmap() support',
'test_pthread_cond_init_2_2': 'clock_settime() is not supported',
'test_pthread_cond_init_4_1': 'fork() and multiple processes are not supported',
'test_pthread_cond_signal_1_2': 'lacking necessary mmap() support',
'test_pthread_cond_timedwait_2_4': 'lacking necessary mmap() support',
'test_pthread_cond_timedwait_2_7': 'lacking necessary mmap() support',
'test_pthread_cond_timedwait_4_2': 'lacking necessary mmap() support',
'test_pthread_cond_wait_2_2': 'lacking necessary mmap() support',
'test_pthread_create_8_1': 'signals are not supported',
'test_pthread_create_8_2': 'signals are not supported',
'test_pthread_create_11_1': '_POSIX_THREAD_CPUTIME not supported',
'test_pthread_getcpuclockid_1_1': 'pthread_getcpuclockid not supported',
'test_pthread_getschedparam_1_3': 'scheduling policy/parameters are not supported',
'test_pthread_getschedparam_1_2': 'scheduling policy/parameters are not supported',
'test_pthread_kill_1_2': 'signals are not supported',
'test_pthread_mutexattr_getprioceiling_1_2': 'pthread_mutexattr_setprioceiling is not supported',
'test_pthread_mutexattr_getprotocol_1_2': 'pthread_mutexattr_setprotocol is not supported',
'test_pthread_mutexattr_setprioceiling_1_1': 'pthread_mutexattr_setprioceiling is not supported',
'test_pthread_mutexattr_setprioceiling_3_1': 'pthread_mutexattr_setprioceiling is not supported',
'test_pthread_mutexattr_setprioceiling_3_2': 'pthread_mutexattr_setprioceiling is not supported',
'test_pthread_mutexattr_setprotocol_1_1': 'setting pthread_mutexattr_setprotocol to a nonzero value is not supported',
'test_pthread_mutex_getprioceiling_1_1': 'pthread_mutex_getprioceiling is not supported',
'test_pthread_mutex_init_5_1': 'fork() and multiple processes are not supported',
'test_pthread_mutex_trylock_1_2': 'lacking necessary mmap() support',
'test_pthread_mutex_trylock_2_1': 'lacking necessary mmap() support',
'test_pthread_mutex_trylock_4_2': 'lacking necessary mmap() support',
'test_pthread_rwlockattr_getpshared_2_1': 'shm_open and shm_unlink are not supported',
'test_pthread_rwlock_rdlock_2_1': 'thread priorities not supported, cannot test rwlocking in priority order',
'test_pthread_rwlock_rdlock_2_2': 'thread priorities not supported, cannot test rwlocking in priority order',
'test_pthread_rwlock_rdlock_4_1': 'signals are not supported',
'test_pthread_rwlock_timedrdlock_6_1': 'signals are not supported',
'test_pthread_rwlock_timedrdlock_6_2': 'signals are not supported',
'test_pthread_rwlock_timedwrlock_6_1': 'signals are not supported',
'test_pthread_rwlock_timedwrlock_6_2': 'signals are not supported',
'test_pthread_rwlock_wrlock_2_1': 'signals are not supported',
'test_pthread_setschedparam_1_1': 'scheduling policy/parameters are not supported',
'test_pthread_setschedparam_1_2': 'scheduling policy/parameters are not supported',
'test_pthread_setschedparam_4_1': 'scheduling policy/parameters are not supported',
'test_pthread_setschedprio_1_1': 'scheduling policy/parameters are not supported',
'test_pthread_spin_init_2_1': 'shm_open and shm_unlink are not supported',
'test_pthread_spin_init_2_2': 'shm_open and shm_unlink are not supported',
}
# Mark certain tests as flaky, which may sometimes fail.
# TODO investigate these tests.
flaky = {
'test_pthread_cond_signal_1_1': 'flaky: https://github.com/emscripten-core/emscripten/issues/13283',
'test_pthread_barrier_wait_2_1': 'flaky: https://github.com/emscripten-core/emscripten/issues/14508',
'test_pthread_rwlock_unlock_3_1': 'Test fail: writer did not get write lock, when main release the lock',
'test_pthread_mutex_init_1_2': 'flaky: https://github.com/emscripten-core/posixtestsuite/pull/9',
'test_pthread_mutex_init_3_2': 'flaky: https://github.com/emscripten-core/posixtestsuite/pull/9',
}
# Mark certain tests as disabled. These are tests that are either flaky or never return.
disabled = {
**flaky,
**unsupported_noreturn,
'test_pthread_create_10_1': 'broken test: https://github.com/emscripten-core/posixtestsuite/issues/10 (also relies on SIGSEGV which we don\'t support)',
}
# These tests are known to fail reliably. We run them anyway so that we can
# detect fixes overtime.
expect_fail = {
**unsupported,
'test_pthread_attr_setscope_5_1': 'internally skipped (PTS_UNTESTED)',
}
def make_test(name, testfile, browser):
@node_pthreads
def f(self):
if name in disabled:
self.skipTest(disabled[name])
args = ['-I' + os.path.join(testsuite_root, 'include'),
'-Werror',
'-Wno-format-security',
'-Wno-int-conversion',
'-sUSE_PTHREADS',
'-sEXIT_RUNTIME',
'-sTOTAL_MEMORY=256mb',
'-sPTHREAD_POOL_SIZE=40']
if browser:
self.btest_exit(testfile, args=args)
else:
self.do_runf(testfile, emcc_args=args, output_basename=name)
if name in expect_fail:
f = unittest.expectedFailure(f)
return f
for testdir in get_pthread_tests():
basename = os.path.basename(testdir)
for test_file in glob.glob(os.path.join(testdir, '*.c')):
if not os.path.basename(test_file)[0].isdigit():
continue
test_suffix = os.path.splitext(os.path.basename(test_file))[0]
test_suffix = test_suffix.replace('-', '_')
test_name = 'test_' + basename + '_' + test_suffix
setattr(posixtest, test_name, make_test(test_name, test_file, browser=False))
setattr(test_posixtest_browser.posixtest_browser, test_name, make_test(test_name, test_file, browser=True))
|