Skip to content

Commit c8ea7fd

Browse files
committed
Integrate posixtestsuite for pthread testing
This change adds posixtestsuite as a git submodule (in tests/third_party). It also adds a new test suite that auto-populates based on the files in `posixtestsuite/conformance/interfaces/pthread_*` The submodule is optional in that the testsuite simply remains empty if it is not found.
1 parent 4dc0974 commit c8ea7fd

File tree

6 files changed

+129
-3
lines changed

6 files changed

+129
-3
lines changed

.circleci/config.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ commands:
123123
# Must be absolute path or relative path from working_directory
124124
at: ~/
125125
- checkout
126+
- run:
127+
name: submodule update
128+
command: git submodule update --init
126129
- emsdk-env
127130
- npm-install
128131
- run:
@@ -384,7 +387,7 @@ jobs:
384387
steps:
385388
- run-tests:
386389
# also add a few asan tests
387-
test_targets: "wasm2 asan.test_embind* asan.test_abort_on_exceptions asan.test_ubsan_full_left_shift_fsanitize_integer"
390+
test_targets: "wasm2 asan.test_embind* asan.test_abort_on_exceptions asan.test_ubsan_full_left_shift_fsanitize_integer posixtest.test_pthread_create_1_1"
388391
test-wasm3:
389392
executor: bionic
390393
steps:

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "tests/third_party/posixtestsuite"]
2+
path = tests/third_party/posixtestsuite
3+
url = https://github.com/juj/posixtestsuite

src/preamble.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ var ABORT = false;
6060
// set by exit() and abort(). Passed to 'onExit' handler.
6161
// NOTE: This is also used as the process return code code in shell environments
6262
// but only when noExitRuntime is false.
63-
var EXITSTATUS = 0;
63+
var EXITSTATUS;
6464

6565
/** @type {function(*, string=)} */
6666
function assert(condition, text) {

tests/runner.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@ def make_executable(name):
305305
'asan',
306306
'lsan',
307307
'wasm2ss',
308+
'posixtest',
309+
'posixtest_browser',
308310
]
309311

310312

@@ -1827,7 +1829,7 @@ def flattened_tests(loaded_tests):
18271829

18281830

18291831
def suite_for_module(module, tests):
1830-
suite_supported = module.__name__ in ('test_core', 'test_other')
1832+
suite_supported = module.__name__ in ('test_core', 'test_other', 'test_posixtest')
18311833
if not EMTEST_SAVE_DIR:
18321834
has_multiple_tests = len(tests) > 1
18331835
has_multiple_cores = parallel_testsuite.num_cores() > 1

tests/test_posixtest.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# Copyright 2020 The Emscripten Authors. All rights reserved.
2+
# Emscripten is available under two separate licenses, the MIT license and the
3+
# University of Illinois/NCSA Open Source License. Both these licenses can be
4+
# found in the LICENSE file.
5+
6+
"""Runs the pthreads test from the upstream posixtest suite in:
7+
./tests/third_party/posixtestsuite
8+
See
9+
https://github.com/juj/posixtestsuite
10+
"""
11+
12+
import glob
13+
import os
14+
15+
from runner import RunnerCore, BrowserCore, path_from_root
16+
from tools import config
17+
from tools.shared import EMCC
18+
import test_posixtest_browser
19+
20+
testsuite_root = path_from_root('tests/third_party/posixtestsuite')
21+
22+
23+
class posixtest(RunnerCore):
24+
"""Run the suite under node (and in parallel)
25+
26+
This class get populated dynamically below.
27+
"""
28+
pass
29+
30+
31+
def filter_tests(all_tests):
32+
pthread_tests = [t for t in all_tests if t.startswith('pthread_')]
33+
# filter out some tests we don't support
34+
pthread_tests = [t for t in pthread_tests if not t.startswith('pthread_atfork')]
35+
pthread_tests = [t for t in pthread_tests if not t.startswith('pthread_sigmask')]
36+
return pthread_tests
37+
38+
39+
def get_pthread_tests():
40+
# For now, we don't require the submodule to exist. In this case we just report
41+
# no tests
42+
pthread_test_root = os.path.join(testsuite_root, 'conformance', 'interfaces')
43+
if not os.path.exists(pthread_test_root):
44+
print('posixtestsuite not found (run git submodule update --init?)')
45+
return []
46+
pthread_tests = filter_tests(os.listdir(pthread_test_root))
47+
pthread_tests = [os.path.join(pthread_test_root, t) for t in pthread_tests]
48+
return pthread_tests
49+
50+
51+
engine = config.NODE_JS + ['--experimental-wasm-threads', '--experimental-wasm-bulk-memory']
52+
53+
# Mark certain tests as not passing
54+
disabled = {
55+
'test_pthread_create_11_1': 'never returns',
56+
'test_pthread_barrier_wait_2_1': 'never returns',
57+
'test_pthread_cond_timedwait_2_6': 'never returns',
58+
'test_pthread_cond_timedwait_4_3': 'never returns',
59+
'test_pthread_attr_setscope_5_1': 'internally skipped (PTS_UNTESTED)',
60+
'test_pthread_cond_wait_2_3': 'never returns',
61+
'test_pthread_create_5_1': 'never returns',
62+
'test_pthread_exit_1_2': 'never returns',
63+
'test_pthread_exit_2_2': 'never returns',
64+
'test_pthread_exit_3_2': 'never returns',
65+
'test_pthread_exit_4_1': 'never returns',
66+
'test_pthread_getcpuclockid_1_1': 'never returns',
67+
'test_pthread_key_create_1_2': 'never returns',
68+
'test_pthread_rwlock_rdlock_1_1': 'fails with "main: Unexpected thread state"',
69+
'test_pthread_rwlock_timedrdlock_1_1': 'fails with "main: Unexpected thread state"',
70+
'test_pthread_rwlock_timedrdlock_3_1': 'fails with "main: Unexpected thread state"',
71+
'test_pthread_rwlock_timedrdlock_5_1': 'fails with "main: Unexpected thread state"',
72+
'test_pthread_rwlock_timedwrlock_1_1': 'fails with "main: Unexpected thread state"',
73+
'test_pthread_rwlock_timedwrlock_3_1': 'fails with "main: Unexpected thread state"',
74+
'test_pthread_rwlock_timedwrlock_5_1': 'fails with "main: Unexpected thread state"',
75+
'test_pthread_rwlock_wrlock_1_1': 'fails with "main: Unexpected thread state"',
76+
'test_pthread_rwlock_trywrlock_1_1': 'fails with "main: Unexpected thread state"',
77+
'test_pthread_spin_destroy_3_1': 'never returns',
78+
'test_pthread_spin_init_4_1': 'never returns',
79+
}
80+
81+
82+
def make_test(name, testfile, browser):
83+
84+
def f(self):
85+
if name in disabled:
86+
self.skipTest(disabled[name])
87+
args = [testfile,
88+
'-I' + os.path.join(testsuite_root, 'include'),
89+
'-Werror',
90+
'-Wno-format-security',
91+
'-Wno-int-conversion',
92+
'-sUSE_PTHREADS',
93+
'-sEXIT_RUNTIME',
94+
'-sTOTAL_MEMORY=268435456',
95+
'-sPTHREAD_POOL_SIZE=40']
96+
if browser:
97+
# Only are only needed for browser tests of the was btest
98+
# injects headers using `-include` flag.
99+
args += ['-Wno-macro-redefined', '-D_GNU_SOURCE']
100+
self.btest(testfile, args=args, expected='exit:0')
101+
else:
102+
self.run_process([EMCC, '-o', 'test.js'] + args)
103+
self.run_js('test.js', engine=engine)
104+
105+
return f
106+
107+
108+
for testdir in get_pthread_tests():
109+
basename = os.path.basename(testdir)
110+
for test_file in glob.glob(os.path.join(testdir, '*.c')):
111+
if not os.path.basename(test_file)[0].isdigit():
112+
continue
113+
test_suffix = os.path.splitext(os.path.basename(test_file))[0]
114+
test_suffix = test_suffix.replace('-', '_')
115+
test_name = 'test_' + basename + '_' + test_suffix
116+
setattr(posixtest, test_name, make_test(test_name, test_file, browser=False))
117+
setattr(test_posixtest_browser.posixtest_browser, test_name, make_test(test_name, test_file, browser=True))

tests/third_party/posixtestsuite

Submodule posixtestsuite added at 2637242

0 commit comments

Comments
 (0)