Skip to content

Commit 83114d4

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 e94989d commit 83114d4

File tree

6 files changed

+153
-5
lines changed

6 files changed

+153
-5
lines changed

.circleci/config.yml

Lines changed: 12 additions & 3 deletions
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:
@@ -160,6 +163,9 @@ commands:
160163
# Must be absolute path or relative path from working_directory
161164
at: ~/
162165
- checkout
166+
- run:
167+
name: submodule update
168+
command: git submodule update --init
163169
- emsdk-env
164170
- npm-install
165171
- run:
@@ -250,7 +256,7 @@ commands:
250256
EXTRA_AUTOSTART=$TMPDIR/autostart startx /usr/bin/openbox-session -- $DISPLAY -config ~/.config/X11/xorg.conf -nolisten tcp &
251257
cat $TMPDIR/fifo > /dev/null # wait until $EXTRA_AUTOSTART is spawned, which indicates the end of Openbox initialization
252258
rm -r $TMPDIR
253-
python3 tests/runner.py browser skip:browser.test_sdl2_mouse skip:browser.test_html5_webgl_create_context skip:browser.test_webgl_offscreen_canvas_in_pthread skip:browser.test_webgl_offscreen_canvas_in_mainthread_after_pthread skip:browser.test_glut_glutget
259+
python3 tests/runner.py browser posixtest.test_pthread_create_1_1 skip:browser.test_sdl2_mouse skip:browser.test_html5_webgl_create_context skip:browser.test_webgl_offscreen_canvas_in_pthread skip:browser.test_webgl_offscreen_canvas_in_mainthread_after_pthread skip:browser.test_glut_glutget
254260
python3 tests/runner.py emrun
255261
openbox --exit
256262
wait || true # wait for startx to shutdown cleanly, or not
@@ -261,6 +267,9 @@ commands:
261267
# Must be absolute path or relative path from working_directory
262268
at: ~/
263269
- checkout
270+
- run:
271+
name: submodule update
272+
command: git submodule update --init
264273
- emsdk-env
265274
- npm-install
266275
- run:
@@ -282,7 +291,7 @@ commands:
282291
command: |
283292
export EMTEST_BROWSER="/usr/bin/google-chrome $CHROME_FLAGS_BASE $CHROME_FLAGS_HEADLESS $CHROME_FLAGS_WASM $CHROME_FLAGS_NOCACHE"
284293
# skip test_zzz_zzz_4GB_fail as it OOMs on the current bot
285-
python3 tests/runner.py browser skip:browser.test_zzz_zzz_4GB_fail
294+
python3 tests/runner.py browser posixtest.test_pthread_create_1_1 skip:browser.test_zzz_zzz_4GB_fail
286295
python3 tests/runner.py emrun
287296
test-sockets-chrome:
288297
description: "Runs emscripten sockets tests under chrome"
@@ -384,7 +393,7 @@ jobs:
384393
steps:
385394
- run-tests:
386395
# 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"
396+
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"
388397
test-wasm3:
389398
executor: bionic
390399
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: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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, 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 = ['-I' + os.path.join(testsuite_root, 'include'),
88+
'-Werror',
89+
'-Wno-format-security',
90+
'-Wno-int-conversion',
91+
'-sUSE_PTHREADS',
92+
'-sEXIT_RUNTIME',
93+
'-sTOTAL_MEMORY=268435456',
94+
'-sPTHREAD_POOL_SIZE=40']
95+
if browser:
96+
# Only are only needed for browser tests of the was btest
97+
# injects headers using `-include` flag.
98+
args += ['-Wno-macro-redefined', '-D_GNU_SOURCE']
99+
self.btest(testfile, args=args, expected='exit:0')
100+
else:
101+
self.run_process([EMCC, testfile, '-o', 'test.js'] + args)
102+
self.run_js('test.js', engine=engine)
103+
104+
return f
105+
106+
107+
for testdir in get_pthread_tests():
108+
basename = os.path.basename(testdir)
109+
for test_file in glob.glob(os.path.join(testdir, '*.c')):
110+
if not os.path.basename(test_file)[0].isdigit():
111+
continue
112+
test_suffix = os.path.splitext(os.path.basename(test_file))[0]
113+
test_suffix = test_suffix.replace('-', '_')
114+
test_name = 'test_' + basename + '_' + test_suffix
115+
setattr(posixtest, test_name, make_test(test_name, test_file, browser=False))
116+
setattr(test_posixtest_browser.posixtest_browser, test_name, make_test(test_name, test_file, browser=True))

tests/test_posixtest_browser.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""See test_posixtest.py
2+
3+
This class is only in its own file so that we can
4+
run the non-browser versions in parallel.
5+
6+
Currently only entire modules can be marked as
7+
parallel.
8+
"""
9+
10+
from runner import BrowserCore
11+
12+
13+
class posixtest_browser(BrowserCore):
14+
"""Run the suite in the browser (serially)
15+
16+
This class get populated dynamically below.
17+
"""
18+
pass

0 commit comments

Comments
 (0)