From c51b56038ba344dece607eb5f035dca544187813 Mon Sep 17 00:00:00 2001 From: Malcolm Smith Date: Sun, 27 Oct 2024 02:35:53 +0000 Subject: [PATCH] Android: Update tests for newly-available functions affected by SELinux (#126015) Skip tests on Android that involve use of SELinux-protected methods. --- Lib/test/support/__init__.py | 5 +++++ Lib/test/test_socket.py | 5 +++++ Lib/test/test_termios.py | 17 +++++++++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index ff917c98ed8..7c1ef42a497 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -520,6 +520,11 @@ is_jython = sys.platform.startswith('java') is_android = sys.platform == "android" +def skip_android_selinux(name): + return unittest.skipIf( + sys.platform == "android", f"Android blocks {name} with SELinux" + ) + if sys.platform not in {"win32", "vxworks", "ios", "tvos", "watchos"}: unix_shell = '/system/bin/sh' if is_android else '/bin/sh' else: diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 663fa50c086..f2bc52ba6e8 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -1111,6 +1111,7 @@ class GeneralModuleTests(unittest.TestCase): @unittest.skipUnless(hasattr(socket, 'if_nameindex'), 'socket.if_nameindex() not available.') + @support.skip_android_selinux('if_nameindex') def testInterfaceNameIndex(self): interfaces = socket.if_nameindex() for index, name in interfaces: @@ -1127,6 +1128,7 @@ class GeneralModuleTests(unittest.TestCase): @unittest.skipUnless(hasattr(socket, 'if_indextoname'), 'socket.if_indextoname() not available.') + @support.skip_android_selinux('if_indextoname') def testInvalidInterfaceIndexToName(self): self.assertRaises(OSError, socket.if_indextoname, 0) self.assertRaises(OverflowError, socket.if_indextoname, -1) @@ -1146,6 +1148,7 @@ class GeneralModuleTests(unittest.TestCase): @unittest.skipUnless(hasattr(socket, 'if_nametoindex'), 'socket.if_nametoindex() not available.') + @support.skip_android_selinux('if_nametoindex') def testInvalidInterfaceNameToIndex(self): self.assertRaises(TypeError, socket.if_nametoindex, 0) self.assertRaises(OSError, socket.if_nametoindex, '_DEADBEEF') @@ -1878,6 +1881,7 @@ class GeneralModuleTests(unittest.TestCase): @unittest.skipIf(sys.platform == 'win32', 'does not work on Windows') @unittest.skipIf(AIX, 'Symbolic scope id does not work') @unittest.skipUnless(hasattr(socket, 'if_nameindex'), "test needs socket.if_nameindex()") + @support.skip_android_selinux('if_nameindex') def test_getaddrinfo_ipv6_scopeid_symbolic(self): # Just pick up any network interface (Linux, Mac OS X) (ifindex, test_interface) = socket.if_nameindex()[0] @@ -1911,6 +1915,7 @@ class GeneralModuleTests(unittest.TestCase): @unittest.skipIf(sys.platform == 'win32', 'does not work on Windows') @unittest.skipIf(AIX, 'Symbolic scope id does not work') @unittest.skipUnless(hasattr(socket, 'if_nameindex'), "test needs socket.if_nameindex()") + @support.skip_android_selinux('if_nameindex') def test_getnameinfo_ipv6_scopeid_symbolic(self): # Just pick up any network interface. (ifindex, test_interface) = socket.if_nameindex()[0] diff --git a/Lib/test/test_termios.py b/Lib/test/test_termios.py index b98cbd553da..d6eb00175b4 100644 --- a/Lib/test/test_termios.py +++ b/Lib/test/test_termios.py @@ -3,6 +3,7 @@ import os import sys import tempfile import unittest +from test import support from test.support.import_helper import import_module termios = import_module('termios') @@ -18,10 +19,16 @@ class TestFunctions(unittest.TestCase): tmp = self.enterContext(tempfile.TemporaryFile(mode='wb', buffering=0)) self.bad_fd = tmp.fileno() - def assertRaisesTermiosError(self, errno, callable, *args): + def assertRaisesTermiosError(self, err, callable, *args): + # Some versions of Android return EACCES when calling termios functions + # on a regular file. + errs = [err] + if sys.platform == 'android' and err == errno.ENOTTY: + errs.append(errno.EACCES) + with self.assertRaises(termios.error) as cm: callable(*args) - self.assertEqual(cm.exception.args[0], errno) + self.assertIn(cm.exception.args[0], errs) def test_tcgetattr(self): attrs = termios.tcgetattr(self.fd) @@ -90,6 +97,7 @@ class TestFunctions(unittest.TestCase): self.assertRaises(TypeError, termios.tcsetattr, object(), termios.TCSANOW, attrs) self.assertRaises(TypeError, termios.tcsetattr, self.fd, termios.TCSANOW) + @support.skip_android_selinux('tcsendbreak') def test_tcsendbreak(self): try: termios.tcsendbreak(self.fd, 1) @@ -100,6 +108,7 @@ class TestFunctions(unittest.TestCase): raise termios.tcsendbreak(self.stream, 1) + @support.skip_android_selinux('tcsendbreak') def test_tcsendbreak_errors(self): self.assertRaises(OverflowError, termios.tcsendbreak, self.fd, 2**1000) self.assertRaises(TypeError, termios.tcsendbreak, self.fd, 0.0) @@ -110,10 +119,12 @@ class TestFunctions(unittest.TestCase): self.assertRaises(TypeError, termios.tcsendbreak, object(), 0) self.assertRaises(TypeError, termios.tcsendbreak, self.fd) + @support.skip_android_selinux('tcdrain') def test_tcdrain(self): termios.tcdrain(self.fd) termios.tcdrain(self.stream) + @support.skip_android_selinux('tcdrain') def test_tcdrain_errors(self): self.assertRaisesTermiosError(errno.ENOTTY, termios.tcdrain, self.bad_fd) self.assertRaises(ValueError, termios.tcdrain, -1) @@ -136,12 +147,14 @@ class TestFunctions(unittest.TestCase): self.assertRaises(TypeError, termios.tcflush, object(), termios.TCIFLUSH) self.assertRaises(TypeError, termios.tcflush, self.fd) + @support.skip_android_selinux('tcflow') def test_tcflow(self): termios.tcflow(self.fd, termios.TCOOFF) termios.tcflow(self.fd, termios.TCOON) termios.tcflow(self.fd, termios.TCIOFF) termios.tcflow(self.fd, termios.TCION) + @support.skip_android_selinux('tcflow') def test_tcflow_errors(self): self.assertRaisesTermiosError(errno.EINVAL, termios.tcflow, self.fd, -1) self.assertRaises(OverflowError, termios.tcflow, self.fd, 2**1000)