mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	gh-71052: Add test exclusions to support running the test suite on Android (#115918)
This commit is contained in:
		
							parent
							
								
									83c5ecdeec
								
							
						
					
					
						commit
						41d5391c55
					
				
					 12 changed files with 58 additions and 27 deletions
				
			
		|  | @ -532,24 +532,33 @@ def requires_debug_ranges(reason='requires co_positions / debug_ranges'): | |||
| is_emscripten = sys.platform == "emscripten" | ||||
| is_wasi = sys.platform == "wasi" | ||||
| 
 | ||||
| # Apple mobile platforms (iOS/tvOS/watchOS) are POSIX-like but do not | ||||
| # have subprocess or fork support. | ||||
| is_apple_mobile = sys.platform in {"ios", "tvos", "watchos"} | ||||
| is_apple = is_apple_mobile or sys.platform == "darwin" | ||||
| 
 | ||||
| has_fork_support = hasattr(os, "fork") and not ( | ||||
|     # WASM and Apple mobile platforms do not support subprocesses. | ||||
|     is_emscripten | ||||
|     or is_wasi | ||||
|     or is_apple_mobile | ||||
| 
 | ||||
|     # Although Android supports fork, it's unsafe to call it from Python because | ||||
|     # all Android apps are multi-threaded. | ||||
|     or is_android | ||||
| ) | ||||
| 
 | ||||
| def requires_fork(): | ||||
|     return unittest.skipUnless(has_fork_support, "requires working os.fork()") | ||||
| 
 | ||||
| has_subprocess_support = not ( | ||||
|     # WASM and Apple mobile platforms do not support subprocesses. | ||||
|     is_emscripten | ||||
|     or is_wasi | ||||
|     or is_apple_mobile | ||||
| 
 | ||||
|     # Although Android supports subproceses, they're almost never useful in | ||||
|     # practice (see PEP 738). And most of the tests that use them are calling | ||||
|     # sys.executable, which won't work when Python is embedded in an Android app. | ||||
|     or is_android | ||||
| ) | ||||
| 
 | ||||
| def requires_subprocess(): | ||||
|  |  | |||
|  | @ -198,6 +198,23 @@ def skip_unless_symlink(test): | |||
|     return test if ok else unittest.skip(msg)(test) | ||||
| 
 | ||||
| 
 | ||||
| _can_hardlink = None | ||||
| 
 | ||||
| def can_hardlink(): | ||||
|     global _can_hardlink | ||||
|     if _can_hardlink is None: | ||||
|         # Android blocks hard links using SELinux | ||||
|         # (https://stackoverflow.com/q/32365690). | ||||
|         _can_hardlink = hasattr(os, "link") and not support.is_android | ||||
|     return _can_hardlink | ||||
| 
 | ||||
| 
 | ||||
| def skip_unless_hardlink(test): | ||||
|     ok = can_hardlink() | ||||
|     msg = "requires hardlink support" | ||||
|     return test if ok else unittest.skip(msg)(test) | ||||
| 
 | ||||
| 
 | ||||
| _can_xattr = None | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -13,6 +13,8 @@ | |||
| from test import support | ||||
| from test.support import os_helper | ||||
| 
 | ||||
| if not support.has_subprocess_support: | ||||
|     raise unittest.SkipTest("test module requires subprocess") | ||||
| 
 | ||||
| if support.MS_WINDOWS: | ||||
|     import msvcrt | ||||
|  | @ -47,7 +49,6 @@ def _start(self, *args, **kwargs): | |||
|         self._proc.pid = -1 | ||||
| 
 | ||||
| 
 | ||||
| @support.requires_subprocess() | ||||
| class SubprocessTransportTests(test_utils.TestCase): | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
|  | @ -111,7 +112,6 @@ def test_subprocess_repr(self): | |||
|         transport.close() | ||||
| 
 | ||||
| 
 | ||||
| @support.requires_subprocess() | ||||
| class SubprocessMixin: | ||||
| 
 | ||||
|     def test_stdin_stdout(self): | ||||
|  |  | |||
|  | @ -977,7 +977,7 @@ class CommandLineTestsNoSourceEpoch(CommandLineTestsBase, | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') | ||||
| @os_helper.skip_unless_hardlink | ||||
| class HardlinkDedupTestsBase: | ||||
|     # Test hardlink_dupes parameter of compileall.compile_dir() | ||||
| 
 | ||||
|  |  | |||
|  | @ -129,7 +129,8 @@ def test_fcntl_bad_file_overflow(self): | |||
|             fcntl.fcntl(BadFile(INT_MIN - 1), fcntl.F_SETFL, os.O_NONBLOCK) | ||||
| 
 | ||||
|     @unittest.skipIf( | ||||
|         platform.machine().startswith('arm') and platform.system() == 'Linux', | ||||
|         any(platform.machine().startswith(name) for name in {"arm", "aarch"}) | ||||
|         and platform.system() in {"Linux", "Android"}, | ||||
|         "ARM Linux returns EINVAL for F_NOTIFY DN_MULTISHOT") | ||||
|     def test_fcntl_64_bit(self): | ||||
|         # Issue #1309352: fcntl shouldn't fail when the third arg fits in a | ||||
|  |  | |||
|  | @ -164,6 +164,7 @@ def test_sys_path_0(self): | |||
| 
 | ||||
| class FinalizationTests(TestBase): | ||||
| 
 | ||||
|     @support.requires_subprocess() | ||||
|     def test_gh_109793(self): | ||||
|         # Make sure finalization finishes and the correct error code | ||||
|         # is reported, even when subinterpreters get cleaned up at the end. | ||||
|  |  | |||
|  | @ -1592,6 +1592,9 @@ def test_yields_correct_dir_fd(self): | |||
|     @unittest.skipIf( | ||||
|         support.is_emscripten, "Cannot dup stdout on Emscripten" | ||||
|     ) | ||||
|     @unittest.skipIf( | ||||
|         support.is_android, "dup return value is unpredictable on Android" | ||||
|     ) | ||||
|     def test_fd_leak(self): | ||||
|         # Since we're opening a lot of FDs, we must be careful to avoid leaks: | ||||
|         # we both check that calling fwalk() a large number of times doesn't | ||||
|  | @ -2492,8 +2495,10 @@ def test_listdir(self): | |||
|         # test listdir without arguments | ||||
|         current_directory = os.getcwd() | ||||
|         try: | ||||
|             os.chdir(os.sep) | ||||
|             self.assertEqual(set(os.listdir()), set(os.listdir(os.sep))) | ||||
|             # The root directory is not readable on Android, so use a directory | ||||
|             # we created ourselves. | ||||
|             os.chdir(self.dir) | ||||
|             self.assertEqual(set(os.listdir()), expected) | ||||
|         finally: | ||||
|             os.chdir(current_directory) | ||||
| 
 | ||||
|  | @ -4838,7 +4843,7 @@ def check_entry(self, entry, name, is_dir, is_file, is_symlink): | |||
|                                os.name == 'nt') | ||||
| 
 | ||||
|     def test_attributes(self): | ||||
|         link = hasattr(os, 'link') | ||||
|         link = os_helper.can_hardlink() | ||||
|         symlink = os_helper.can_symlink() | ||||
| 
 | ||||
|         dirname = os.path.join(self.path, "dir") | ||||
|  |  | |||
|  | @ -796,7 +796,7 @@ def test_rmdir(self): | |||
|         self.assertFileNotFound(p.stat) | ||||
|         self.assertFileNotFound(p.unlink) | ||||
| 
 | ||||
|     @unittest.skipUnless(hasattr(os, "link"), "os.link() is not present") | ||||
|     @os_helper.skip_unless_hardlink | ||||
|     def test_hardlink_to(self): | ||||
|         P = self.cls(self.base) | ||||
|         target = P / 'fileA' | ||||
|  |  | |||
|  | @ -1270,9 +1270,10 @@ def test_get_and_set_scheduler_and_param(self): | |||
|         self.assertIn(mine, possible_schedulers) | ||||
|         try: | ||||
|             parent = posix.sched_getscheduler(os.getppid()) | ||||
|         except OSError as e: | ||||
|             if e.errno != errno.EPERM: | ||||
|                 raise | ||||
|         except PermissionError: | ||||
|             # POSIX specifies EPERM, but Android returns EACCES. Both errno | ||||
|             # values are mapped to PermissionError. | ||||
|             pass | ||||
|         else: | ||||
|             self.assertIn(parent, possible_schedulers) | ||||
|         self.assertRaises(OSError, posix.sched_getscheduler, -1) | ||||
|  | @ -1287,9 +1288,8 @@ def test_get_and_set_scheduler_and_param(self): | |||
|             try: | ||||
|                 posix.sched_setscheduler(0, mine, param) | ||||
|                 posix.sched_setparam(0, param) | ||||
|             except OSError as e: | ||||
|                 if e.errno != errno.EPERM: | ||||
|                     raise | ||||
|             except PermissionError: | ||||
|                 pass | ||||
|             self.assertRaises(OSError, posix.sched_setparam, -1, param) | ||||
| 
 | ||||
|         self.assertRaises(OSError, posix.sched_setscheduler, -1, mine, param) | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| import sys | ||||
| import unittest | ||||
| from test.support import ( | ||||
|     is_apple_mobile, is_emscripten, is_wasi, reap_children, verbose | ||||
|     is_android, is_apple_mobile, is_emscripten, is_wasi, reap_children, verbose | ||||
| ) | ||||
| from test.support.import_helper import import_module | ||||
| from test.support.os_helper import TESTFN, unlink | ||||
|  | @ -9,9 +8,8 @@ | |||
| # Skip these tests if termios is not available | ||||
| import_module('termios') | ||||
| 
 | ||||
| # Skip tests on WASM platforms, plus iOS/tvOS/watchOS | ||||
| if is_apple_mobile or is_emscripten or is_wasi: | ||||
|     raise unittest.SkipTest(f"pty tests not required on {sys.platform}") | ||||
| if is_android or is_apple_mobile or is_emscripten or is_wasi: | ||||
|     raise unittest.SkipTest("pty is not available on this platform") | ||||
| 
 | ||||
| import errno | ||||
| import os | ||||
|  |  | |||
|  | @ -19,8 +19,9 @@ | |||
| import tempfile | ||||
| from test.support import (captured_stdout, captured_stderr, | ||||
|                           skip_if_broken_multiprocessing_synchronize, verbose, | ||||
|                           requires_subprocess, is_apple_mobile, is_emscripten, | ||||
|                           is_wasi, requires_venv_with_pip, TEST_HOME_DIR, | ||||
|                           requires_subprocess, is_android, is_apple_mobile, | ||||
|                           is_emscripten, is_wasi, | ||||
|                           requires_venv_with_pip, TEST_HOME_DIR, | ||||
|                           requires_resource, copy_python_src_ignore) | ||||
| from test.support.os_helper import (can_symlink, EnvironmentVarGuard, rmtree) | ||||
| import unittest | ||||
|  | @ -39,10 +40,8 @@ | |||
|     or sys._base_executable != sys.executable, | ||||
|     'cannot run venv.create from within a venv on this platform') | ||||
| 
 | ||||
| # Skip tests on WASM platforms, plus iOS/tvOS/watchOS | ||||
| if is_apple_mobile or is_emscripten or is_wasi: | ||||
|     raise unittest.SkipTest(f"venv tests not required on {sys.platform}") | ||||
| 
 | ||||
| if is_android or is_apple_mobile or is_emscripten or is_wasi: | ||||
|     raise unittest.SkipTest("venv is not available on this platform") | ||||
| 
 | ||||
| @requires_subprocess() | ||||
| def check_output(cmd, encoding=None): | ||||
|  |  | |||
|  | @ -0,0 +1 @@ | |||
| Add test exclusions to support running the test suite on Android. | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Malcolm Smith
						Malcolm Smith