From 1d2b766100e1807d5fb7df858776a755644ed41b Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 2 Jun 2022 23:50:44 -0700 Subject: [PATCH] gh-90473: Skip and document more failing tests on WASI (GH-93436) - Mark more ``umask()`` cases - ``dup()`` is not supported - ``/dev/null`` is not available - document missing features - mark more modules as not available (cherry picked from commit 069c96f84ccd302436be180c8628289cc0efa977) Co-authored-by: Christian Heimes --- Lib/test/test_compileall.py | 3 +++ Lib/test/test_import/__init__.py | 8 ++++++-- Lib/test/test_os.py | 8 +++++++- Lib/test/test_pathlib.py | 3 +++ Lib/test/test_shutil.py | 1 + Tools/wasm/README.md | 14 +++++++++++++- Tools/wasm/config.site-wasm32-wasi | 1 + configure | 3 +++ configure.ac | 7 +++++-- 9 files changed, 42 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py index 1a9fc973c3a..73c83c9bf1e 100644 --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -434,6 +434,9 @@ class CompileallTestsWithoutSourceEpoch(CompileallTestsBase, pass +# WASI does not have a temp directory and uses cwd instead. The cwd contains +# non-ASCII chars, so _walk_dir() fails to encode self.directory. +@unittest.skipIf(support.is_wasi, "tempdir is not encodable on WASI") class EncodingTest(unittest.TestCase): """Issue 6716: compileall should escape source code when printing errors to stdout.""" diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index be88677dc69..35c260bd634 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -20,7 +20,8 @@ from unittest import mock from test.support import os_helper from test.support import ( - STDLIB_DIR, is_jython, swap_attr, swap_item, cpython_only, is_emscripten) + STDLIB_DIR, is_jython, swap_attr, swap_item, cpython_only, is_emscripten, + is_wasi) from test.support.import_helper import ( forget, make_legacy_pyc, unlink, unload, DirsOnSysPath, CleanImport) from test.support.os_helper import ( @@ -535,7 +536,10 @@ class FilePermissionTests(unittest.TestCase): @unittest.skipUnless(os.name == 'posix', "test meaningful only on posix systems") - @unittest.skipIf(is_emscripten, "Emscripten's umask is a stub.") + @unittest.skipIf( + is_emscripten or is_wasi, + "Emscripten's/WASI's umask is a stub." + ) def test_creation_mode(self): mask = 0o022 with temp_umask(mask), _ready_to_import() as (name, path): diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 009bb5aec35..f304c5e01e5 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -186,6 +186,9 @@ class FileTests(unittest.TestCase): @unittest.skipIf( support.is_emscripten, "Test is unstable under Emscripten." ) + @unittest.skipIf( + support.is_wasi, "WASI does not support dup." + ) def test_closerange(self): first = os.open(os_helper.TESTFN, os.O_CREAT|os.O_RDWR) # We must allocate two consecutive file descriptors, otherwise @@ -1588,7 +1591,10 @@ class MakedirTests(unittest.TestCase): 'dir5', 'dir6') os.makedirs(path) - @unittest.skipIf(support.is_emscripten, "Emscripten's umask is a stub.") + @unittest.skipIf( + support.is_emscripten or support.is_wasi, + "Emscripten's/WASI's umask is a stub." + ) def test_mode(self): with os_helper.temp_umask(0o002): base = os_helper.TESTFN diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index ac3e652631b..72b63d0b618 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -2375,6 +2375,9 @@ class _BasePathTest(object): @unittest.skipIf( is_emscripten, "Unix sockets are not implemented on Emscripten." ) + @unittest.skipIf( + is_wasi, "Cannot create socket on WASI." + ) def test_is_socket_true(self): P = self.cls(BASE, 'mysock') sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index a61bb126e4e..c94390589af 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -2652,6 +2652,7 @@ class TestGetTerminalSize(unittest.TestCase): self.assertEqual(expected, actual) + @unittest.skipIf(support.is_wasi, "WASI has no /dev/null") def test_fallback(self): with os_helper.EnvironmentVarGuard() as env: del env['LINES'] diff --git a/Tools/wasm/README.md b/Tools/wasm/README.md index 239eb90d074..6bb9bd99784 100644 --- a/Tools/wasm/README.md +++ b/Tools/wasm/README.md @@ -237,13 +237,25 @@ are: ``socket.gethostbyname()`` are not implemented and always fail. - ``chmod(2)`` is not available. It's not possible to modify file permissions, yet. A future version of WASI may provide a limited ``set_permissions`` API. +- User/group related features like ``os.chown()``, ``os.getuid``, etc. are + stubs or fail with ``ENOTSUP``. - File locking (``fcntl``) is not available. - ``os.pipe()``, ``os.mkfifo()``, and ``os.mknod()`` are not supported. - ``process_time`` does not work as expected because it's implemented using wall clock. -- ``os.umask`` is a stub. +- ``os.umask()`` is a stub. - ``sys.executable`` is empty. - ``/dev/null`` / ``os.devnull`` may not be available. +- ``os.utime*()`` is buggy in WASM SDK 15.0, see + [utimensat() with timespec=NULL sets wrong time](https://github.com/bytecodealliance/wasmtime/issues/4184) +- ``os.symlink()`` fails with ``PermissionError`` when attempting to create a + symlink with an absolute path with wasmtime 0.36.0. The wasmtime runtime + uses ``openat2(2)`` syscall with flag ``RESOLVE_BENEATH`` to open files. + The flag causes the syscall to reject symlinks with absolute paths. +- ``os.curdir`` (aka ``.``) seems to behave differently, which breaks some + ``importlib`` tests that add ``.`` to ``sys.path`` and indirectly + ``sys.path_importer_cache``. +- WASI runtime environments may not provide a dedicated temp directory. # Detect WebAssembly builds diff --git a/Tools/wasm/config.site-wasm32-wasi b/Tools/wasm/config.site-wasm32-wasi index ee3fc830e3d..a6fcbed48fa 100644 --- a/Tools/wasm/config.site-wasm32-wasi +++ b/Tools/wasm/config.site-wasm32-wasi @@ -26,6 +26,7 @@ ac_cv_func_mkfifo=no ac_cv_func_mkfifoat=no ac_cv_func_mknod=no ac_cv_func_mknodat=no +ac_cv_func_makedev=no # fdopendir() fails on SDK 15.0, # OSError: [Errno 28] Invalid argument: '.' diff --git a/configure b/configure index 5ee45f320df..e91d04b3b66 100755 --- a/configure +++ b/configure @@ -22584,6 +22584,9 @@ case $ac_sys_system in #( py_cv_module__ctypes_test=n/a py_cv_module_fcntl=n/a + py_cv_module_mmap=n/a + py_cv_module_resource=n/a + py_cv_module_termios=n/a py_cv_module_=n/a diff --git a/configure.ac b/configure.ac index 91f124aebb6..2e2e24ceca9 100644 --- a/configure.ac +++ b/configure.ac @@ -6673,10 +6673,13 @@ AS_CASE([$ac_sys_system], ], [Emscripten/node*], [], [WASI/*], [ - dnl WASI SDK 15.0 does not support file locking. + dnl WASI SDK 15.0 does not support file locking, mmap, and more. PY_STDLIB_MOD_SET_NA( [_ctypes_test], - [fcntl], + [fcntl], + [mmap], + [resource], + [termios], ) ] )