/Lib/test/test_socket.py
Python | 4862 lines | 4490 code | 194 blank | 178 comment | 48 complexity | b1eff7364c201dacfce594d5ae3d8484 MD5 | raw file
1#!/usr/bin/env python3 2 3import unittest 4from test import support 5from unittest.case import _ExpectedFailure 6 7import errno 8import io 9import socket 10import select 11import tempfile 12import _testcapi 13import time 14import traceback 15import queue 16import sys 17import os 18import array 19import platform 20import contextlib 21from weakref import proxy 22import signal 23import math 24import pickle 25import struct 26try: 27 import fcntl 28except ImportError: 29 fcntl = False 30try: 31 import multiprocessing 32except ImportError: 33 multiprocessing = False 34 35HOST = support.HOST 36MSG = 'Michael Gilfix was here\u1234\r\n'.encode('utf-8') ## test unicode string and carriage return 37 38try: 39 import _thread as thread 40 import threading 41except ImportError: 42 thread = None 43 threading = None 44 45def _have_socket_can(): 46 """Check whether CAN sockets are supported on this host.""" 47 try: 48 s = socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) 49 except (AttributeError, OSError): 50 return False 51 else: 52 s.close() 53 return True 54 55def _have_socket_rds(): 56 """Check whether RDS sockets are supported on this host.""" 57 try: 58 s = socket.socket(socket.PF_RDS, socket.SOCK_SEQPACKET, 0) 59 except (AttributeError, OSError): 60 return False 61 else: 62 s.close() 63 return True 64 65HAVE_SOCKET_CAN = _have_socket_can() 66 67HAVE_SOCKET_RDS = _have_socket_rds() 68 69# Size in bytes of the int type 70SIZEOF_INT = array.array("i").itemsize 71 72class SocketTCPTest(unittest.TestCase): 73 74 def setUp(self): 75 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 76 self.port = support.bind_port(self.serv) 77 self.serv.listen(1) 78 79 def tearDown(self): 80 self.serv.close() 81 self.serv = None 82 83class SocketUDPTest(unittest.TestCase): 84 85 def setUp(self): 86 self.serv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 87 self.port = support.bind_port(self.serv) 88 89 def tearDown(self): 90 self.serv.close() 91 self.serv = None 92 93class ThreadSafeCleanupTestCase(unittest.TestCase): 94 """Subclass of unittest.TestCase with thread-safe cleanup methods. 95 96 This subclass protects the addCleanup() and doCleanups() methods 97 with a recursive lock. 98 """ 99 100 if threading: 101 def __init__(self, *args, **kwargs): 102 super().__init__(*args, **kwargs) 103 self._cleanup_lock = threading.RLock() 104 105 def addCleanup(self, *args, **kwargs): 106 with self._cleanup_lock: 107 return super().addCleanup(*args, **kwargs) 108 109 def doCleanups(self, *args, **kwargs): 110 with self._cleanup_lock: 111 return super().doCleanups(*args, **kwargs) 112 113class SocketCANTest(unittest.TestCase): 114 115 """To be able to run this test, a `vcan0` CAN interface can be created with 116 the following commands: 117 # modprobe vcan 118 # ip link add dev vcan0 type vcan 119 # ifconfig vcan0 up 120 """ 121 interface = 'vcan0' 122 bufsize = 128 123 124 def setUp(self): 125 self.s = socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) 126 self.addCleanup(self.s.close) 127 try: 128 self.s.bind((self.interface,)) 129 except OSError: 130 self.skipTest('network interface `%s` does not exist' % 131 self.interface) 132 133 134class SocketRDSTest(unittest.TestCase): 135 136 """To be able to run this test, the `rds` kernel module must be loaded: 137 # modprobe rds 138 """ 139 bufsize = 8192 140 141 def setUp(self): 142 self.serv = socket.socket(socket.PF_RDS, socket.SOCK_SEQPACKET, 0) 143 self.addCleanup(self.serv.close) 144 try: 145 self.port = support.bind_port(self.serv) 146 except OSError: 147 self.skipTest('unable to bind RDS socket') 148 149 150class ThreadableTest: 151 """Threadable Test class 152 153 The ThreadableTest class makes it easy to create a threaded 154 client/server pair from an existing unit test. To create a 155 new threaded class from an existing unit test, use multiple 156 inheritance: 157 158 class NewClass (OldClass, ThreadableTest): 159 pass 160 161 This class defines two new fixture functions with obvious 162 purposes for overriding: 163 164 clientSetUp () 165 clientTearDown () 166 167 Any new test functions within the class must then define 168 tests in pairs, where the test name is preceeded with a 169 '_' to indicate the client portion of the test. Ex: 170 171 def testFoo(self): 172 # Server portion 173 174 def _testFoo(self): 175 # Client portion 176 177 Any exceptions raised by the clients during their tests 178 are caught and transferred to the main thread to alert 179 the testing framework. 180 181 Note, the server setup function cannot call any blocking 182 functions that rely on the client thread during setup, 183 unless serverExplicitReady() is called just before 184 the blocking call (such as in setting up a client/server 185 connection and performing the accept() in setUp(). 186 """ 187 188 def __init__(self): 189 # Swap the true setup function 190 self.__setUp = self.setUp 191 self.__tearDown = self.tearDown 192 self.setUp = self._setUp 193 self.tearDown = self._tearDown 194 195 def serverExplicitReady(self): 196 """This method allows the server to explicitly indicate that 197 it wants the client thread to proceed. This is useful if the 198 server is about to execute a blocking routine that is 199 dependent upon the client thread during its setup routine.""" 200 self.server_ready.set() 201 202 def _setUp(self): 203 self.server_ready = threading.Event() 204 self.client_ready = threading.Event() 205 self.done = threading.Event() 206 self.queue = queue.Queue(1) 207 self.server_crashed = False 208 209 # Do some munging to start the client test. 210 methodname = self.id() 211 i = methodname.rfind('.') 212 methodname = methodname[i+1:] 213 test_method = getattr(self, '_' + methodname) 214 self.client_thread = thread.start_new_thread( 215 self.clientRun, (test_method,)) 216 217 try: 218 self.__setUp() 219 except: 220 self.server_crashed = True 221 raise 222 finally: 223 self.server_ready.set() 224 self.client_ready.wait() 225 226 def _tearDown(self): 227 self.__tearDown() 228 self.done.wait() 229 230 if self.queue.qsize(): 231 exc = self.queue.get() 232 raise exc 233 234 def clientRun(self, test_func): 235 self.server_ready.wait() 236 self.clientSetUp() 237 self.client_ready.set() 238 if self.server_crashed: 239 self.clientTearDown() 240 return 241 if not hasattr(test_func, '__call__'): 242 raise TypeError("test_func must be a callable function") 243 try: 244 test_func() 245 except _ExpectedFailure: 246 # We deliberately ignore expected failures 247 pass 248 except BaseException as e: 249 self.queue.put(e) 250 finally: 251 self.clientTearDown() 252 253 def clientSetUp(self): 254 raise NotImplementedError("clientSetUp must be implemented.") 255 256 def clientTearDown(self): 257 self.done.set() 258 thread.exit() 259 260class ThreadedTCPSocketTest(SocketTCPTest, ThreadableTest): 261 262 def __init__(self, methodName='runTest'): 263 SocketTCPTest.__init__(self, methodName=methodName) 264 ThreadableTest.__init__(self) 265 266 def clientSetUp(self): 267 self.cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 268 269 def clientTearDown(self): 270 self.cli.close() 271 self.cli = None 272 ThreadableTest.clientTearDown(self) 273 274class ThreadedUDPSocketTest(SocketUDPTest, ThreadableTest): 275 276 def __init__(self, methodName='runTest'): 277 SocketUDPTest.__init__(self, methodName=methodName) 278 ThreadableTest.__init__(self) 279 280 def clientSetUp(self): 281 self.cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 282 283 def clientTearDown(self): 284 self.cli.close() 285 self.cli = None 286 ThreadableTest.clientTearDown(self) 287 288class ThreadedCANSocketTest(SocketCANTest, ThreadableTest): 289 290 def __init__(self, methodName='runTest'): 291 SocketCANTest.__init__(self, methodName=methodName) 292 ThreadableTest.__init__(self) 293 294 def clientSetUp(self): 295 self.cli = socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) 296 try: 297 self.cli.bind((self.interface,)) 298 except OSError: 299 # skipTest should not be called here, and will be called in the 300 # server instead 301 pass 302 303 def clientTearDown(self): 304 self.cli.close() 305 self.cli = None 306 ThreadableTest.clientTearDown(self) 307 308class ThreadedRDSSocketTest(SocketRDSTest, ThreadableTest): 309 310 def __init__(self, methodName='runTest'): 311 SocketRDSTest.__init__(self, methodName=methodName) 312 ThreadableTest.__init__(self) 313 314 def clientSetUp(self): 315 self.cli = socket.socket(socket.PF_RDS, socket.SOCK_SEQPACKET, 0) 316 try: 317 # RDS sockets must be bound explicitly to send or receive data 318 self.cli.bind((HOST, 0)) 319 self.cli_addr = self.cli.getsockname() 320 except OSError: 321 # skipTest should not be called here, and will be called in the 322 # server instead 323 pass 324 325 def clientTearDown(self): 326 self.cli.close() 327 self.cli = None 328 ThreadableTest.clientTearDown(self) 329 330class SocketConnectedTest(ThreadedTCPSocketTest): 331 """Socket tests for client-server connection. 332 333 self.cli_conn is a client socket connected to the server. The 334 setUp() method guarantees that it is connected to the server. 335 """ 336 337 def __init__(self, methodName='runTest'): 338 ThreadedTCPSocketTest.__init__(self, methodName=methodName) 339 340 def setUp(self): 341 ThreadedTCPSocketTest.setUp(self) 342 # Indicate explicitly we're ready for the client thread to 343 # proceed and then perform the blocking call to accept 344 self.serverExplicitReady() 345 conn, addr = self.serv.accept() 346 self.cli_conn = conn 347 348 def tearDown(self): 349 self.cli_conn.close() 350 self.cli_conn = None 351 ThreadedTCPSocketTest.tearDown(self) 352 353 def clientSetUp(self): 354 ThreadedTCPSocketTest.clientSetUp(self) 355 self.cli.connect((HOST, self.port)) 356 self.serv_conn = self.cli 357 358 def clientTearDown(self): 359 self.serv_conn.close() 360 self.serv_conn = None 361 ThreadedTCPSocketTest.clientTearDown(self) 362 363class SocketPairTest(unittest.TestCase, ThreadableTest): 364 365 def __init__(self, methodName='runTest'): 366 unittest.TestCase.__init__(self, methodName=methodName) 367 ThreadableTest.__init__(self) 368 369 def setUp(self): 370 self.serv, self.cli = socket.socketpair() 371 372 def tearDown(self): 373 self.serv.close() 374 self.serv = None 375 376 def clientSetUp(self): 377 pass 378 379 def clientTearDown(self): 380 self.cli.close() 381 self.cli = None 382 ThreadableTest.clientTearDown(self) 383 384 385# The following classes are used by the sendmsg()/recvmsg() tests. 386# Combining, for instance, ConnectedStreamTestMixin and TCPTestBase 387# gives a drop-in replacement for SocketConnectedTest, but different 388# address families can be used, and the attributes serv_addr and 389# cli_addr will be set to the addresses of the endpoints. 390 391class SocketTestBase(unittest.TestCase): 392 """A base class for socket tests. 393 394 Subclasses must provide methods newSocket() to return a new socket 395 and bindSock(sock) to bind it to an unused address. 396 397 Creates a socket self.serv and sets self.serv_addr to its address. 398 """ 399 400 def setUp(self): 401 self.serv = self.newSocket() 402 self.bindServer() 403 404 def bindServer(self): 405 """Bind server socket and set self.serv_addr to its address.""" 406 self.bindSock(self.serv) 407 self.serv_addr = self.serv.getsockname() 408 409 def tearDown(self): 410 self.serv.close() 411 self.serv = None 412 413 414class SocketListeningTestMixin(SocketTestBase): 415 """Mixin to listen on the server socket.""" 416 417 def setUp(self): 418 super().setUp() 419 self.serv.listen(1) 420 421 422class ThreadedSocketTestMixin(ThreadSafeCleanupTestCase, SocketTestBase, 423 ThreadableTest): 424 """Mixin to add client socket and allow client/server tests. 425 426 Client socket is self.cli and its address is self.cli_addr. See 427 ThreadableTest for usage information. 428 """ 429 430 def __init__(self, *args, **kwargs): 431 super().__init__(*args, **kwargs) 432 ThreadableTest.__init__(self) 433 434 def clientSetUp(self): 435 self.cli = self.newClientSocket() 436 self.bindClient() 437 438 def newClientSocket(self): 439 """Return a new socket for use as client.""" 440 return self.newSocket() 441 442 def bindClient(self): 443 """Bind client socket and set self.cli_addr to its address.""" 444 self.bindSock(self.cli) 445 self.cli_addr = self.cli.getsockname() 446 447 def clientTearDown(self): 448 self.cli.close() 449 self.cli = None 450 ThreadableTest.clientTearDown(self) 451 452 453class ConnectedStreamTestMixin(SocketListeningTestMixin, 454 ThreadedSocketTestMixin): 455 """Mixin to allow client/server stream tests with connected client. 456 457 Server's socket representing connection to client is self.cli_conn 458 and client's connection to server is self.serv_conn. (Based on 459 SocketConnectedTest.) 460 """ 461 462 def setUp(self): 463 super().setUp() 464 # Indicate explicitly we're ready for the client thread to 465 # proceed and then perform the blocking call to accept 466 self.serverExplicitReady() 467 conn, addr = self.serv.accept() 468 self.cli_conn = conn 469 470 def tearDown(self): 471 self.cli_conn.close() 472 self.cli_conn = None 473 super().tearDown() 474 475 def clientSetUp(self): 476 super().clientSetUp() 477 self.cli.connect(self.serv_addr) 478 self.serv_conn = self.cli 479 480 def clientTearDown(self): 481 self.serv_conn.close() 482 self.serv_conn = None 483 super().clientTearDown() 484 485 486class UnixSocketTestBase(SocketTestBase): 487 """Base class for Unix-domain socket tests.""" 488 489 # This class is used for file descriptor passing tests, so we 490 # create the sockets in a private directory so that other users 491 # can't send anything that might be problematic for a privileged 492 # user running the tests. 493 494 def setUp(self): 495 self.dir_path = tempfile.mkdtemp() 496 self.addCleanup(os.rmdir, self.dir_path) 497 super().setUp() 498 499 def bindSock(self, sock): 500 path = tempfile.mktemp(dir=self.dir_path) 501 sock.bind(path) 502 self.addCleanup(support.unlink, path) 503 504class UnixStreamBase(UnixSocketTestBase): 505 """Base class for Unix-domain SOCK_STREAM tests.""" 506 507 def newSocket(self): 508 return socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 509 510 511class InetTestBase(SocketTestBase): 512 """Base class for IPv4 socket tests.""" 513 514 host = HOST 515 516 def setUp(self): 517 super().setUp() 518 self.port = self.serv_addr[1] 519 520 def bindSock(self, sock): 521 support.bind_port(sock, host=self.host) 522 523class TCPTestBase(InetTestBase): 524 """Base class for TCP-over-IPv4 tests.""" 525 526 def newSocket(self): 527 return socket.socket(socket.AF_INET, socket.SOCK_STREAM) 528 529class UDPTestBase(InetTestBase): 530 """Base class for UDP-over-IPv4 tests.""" 531 532 def newSocket(self): 533 return socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 534 535class SCTPStreamBase(InetTestBase): 536 """Base class for SCTP tests in one-to-one (SOCK_STREAM) mode.""" 537 538 def newSocket(self): 539 return socket.socket(socket.AF_INET, socket.SOCK_STREAM, 540 socket.IPPROTO_SCTP) 541 542 543class Inet6TestBase(InetTestBase): 544 """Base class for IPv6 socket tests.""" 545 546 # Don't use "localhost" here - it may not have an IPv6 address 547 # assigned to it by default (e.g. in /etc/hosts), and if someone 548 # has assigned it an IPv4-mapped address, then it's unlikely to 549 # work with the full IPv6 API. 550 host = "::1" 551 552class UDP6TestBase(Inet6TestBase): 553 """Base class for UDP-over-IPv6 tests.""" 554 555 def newSocket(self): 556 return socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) 557 558 559# Test-skipping decorators for use with ThreadableTest. 560 561def skipWithClientIf(condition, reason): 562 """Skip decorated test if condition is true, add client_skip decorator. 563 564 If the decorated object is not a class, sets its attribute 565 "client_skip" to a decorator which will return an empty function 566 if the test is to be skipped, or the original function if it is 567 not. This can be used to avoid running the client part of a 568 skipped test when using ThreadableTest. 569 """ 570 def client_pass(*args, **kwargs): 571 pass 572 def skipdec(obj): 573 retval = unittest.skip(reason)(obj) 574 if not isinstance(obj, type): 575 retval.client_skip = lambda f: client_pass 576 return retval 577 def noskipdec(obj): 578 if not (isinstance(obj, type) or hasattr(obj, "client_skip")): 579 obj.client_skip = lambda f: f 580 return obj 581 return skipdec if condition else noskipdec 582 583 584def requireAttrs(obj, *attributes): 585 """Skip decorated test if obj is missing any of the given attributes. 586 587 Sets client_skip attribute as skipWithClientIf() does. 588 """ 589 missing = [name for name in attributes if not hasattr(obj, name)] 590 return skipWithClientIf( 591 missing, "don't have " + ", ".join(name for name in missing)) 592 593 594def requireSocket(*args): 595 """Skip decorated test if a socket cannot be created with given arguments. 596 597 When an argument is given as a string, will use the value of that 598 attribute of the socket module, or skip the test if it doesn't 599 exist. Sets client_skip attribute as skipWithClientIf() does. 600 """ 601 err = None 602 missing = [obj for obj in args if 603 isinstance(obj, str) and not hasattr(socket, obj)] 604 if missing: 605 err = "don't have " + ", ".join(name for name in missing) 606 else: 607 callargs = [getattr(socket, obj) if isinstance(obj, str) else obj 608 for obj in args] 609 try: 610 s = socket.socket(*callargs) 611 except OSError as e: 612 # XXX: check errno? 613 err = str(e) 614 else: 615 s.close() 616 return skipWithClientIf( 617 err is not None, 618 "can't create socket({0}): {1}".format( 619 ", ".join(str(o) for o in args), err)) 620 621 622####################################################################### 623## Begin Tests 624 625class GeneralModuleTests(unittest.TestCase): 626 627 def test_repr(self): 628 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 629 self.addCleanup(s.close) 630 self.assertTrue(repr(s).startswith("<socket.socket object")) 631 632 def test_weakref(self): 633 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 634 p = proxy(s) 635 self.assertEqual(p.fileno(), s.fileno()) 636 s.close() 637 s = None 638 try: 639 p.fileno() 640 except ReferenceError: 641 pass 642 else: 643 self.fail('Socket proxy still exists') 644 645 def testSocketError(self): 646 # Testing socket module exceptions 647 msg = "Error raising socket exception (%s)." 648 with self.assertRaises(OSError, msg=msg % 'OSError'): 649 raise OSError 650 with self.assertRaises(OSError, msg=msg % 'socket.herror'): 651 raise socket.herror 652 with self.assertRaises(OSError, msg=msg % 'socket.gaierror'): 653 raise socket.gaierror 654 655 def testSendtoErrors(self): 656 # Testing that sendto doens't masks failures. See #10169. 657 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 658 self.addCleanup(s.close) 659 s.bind(('', 0)) 660 sockname = s.getsockname() 661 # 2 args 662 with self.assertRaises(TypeError) as cm: 663 s.sendto('\u2620', sockname) 664 self.assertEqual(str(cm.exception), 665 "'str' does not support the buffer interface") 666 with self.assertRaises(TypeError) as cm: 667 s.sendto(5j, sockname) 668 self.assertEqual(str(cm.exception), 669 "'complex' does not support the buffer interface") 670 with self.assertRaises(TypeError) as cm: 671 s.sendto(b'foo', None) 672 self.assertIn('not NoneType',str(cm.exception)) 673 # 3 args 674 with self.assertRaises(TypeError) as cm: 675 s.sendto('\u2620', 0, sockname) 676 self.assertEqual(str(cm.exception), 677 "'str' does not support the buffer interface") 678 with self.assertRaises(TypeError) as cm: 679 s.sendto(5j, 0, sockname) 680 self.assertEqual(str(cm.exception), 681 "'complex' does not support the buffer interface") 682 with self.assertRaises(TypeError) as cm: 683 s.sendto(b'foo', 0, None) 684 self.assertIn('not NoneType', str(cm.exception)) 685 with self.assertRaises(TypeError) as cm: 686 s.sendto(b'foo', 'bar', sockname) 687 self.assertIn('an integer is required', str(cm.exception)) 688 with self.assertRaises(TypeError) as cm: 689 s.sendto(b'foo', None, None) 690 self.assertIn('an integer is required', str(cm.exception)) 691 # wrong number of args 692 with self.assertRaises(TypeError) as cm: 693 s.sendto(b'foo') 694 self.assertIn('(1 given)', str(cm.exception)) 695 with self.assertRaises(TypeError) as cm: 696 s.sendto(b'foo', 0, sockname, 4) 697 self.assertIn('(4 given)', str(cm.exception)) 698 699 def testCrucialConstants(self): 700 # Testing for mission critical constants 701 socket.AF_INET 702 socket.SOCK_STREAM 703 socket.SOCK_DGRAM 704 socket.SOCK_RAW 705 socket.SOCK_RDM 706 socket.SOCK_SEQPACKET 707 socket.SOL_SOCKET 708 socket.SO_REUSEADDR 709 710 def testHostnameRes(self): 711 # Testing hostname resolution mechanisms 712 hostname = socket.gethostname() 713 try: 714 ip = socket.gethostbyname(hostname) 715 except OSError: 716 # Probably name lookup wasn't set up right; skip this test 717 return 718 self.assertTrue(ip.find('.') >= 0, "Error resolving host to ip.") 719 try: 720 hname, aliases, ipaddrs = socket.gethostbyaddr(ip) 721 except OSError: 722 # Probably a similar problem as above; skip this test 723 return 724 all_host_names = [hostname, hname] + aliases 725 fqhn = socket.getfqdn(ip) 726 if not fqhn in all_host_names: 727 self.fail("Error testing host resolution mechanisms. (fqdn: %s, all: %s)" % (fqhn, repr(all_host_names))) 728 729 @unittest.skipUnless(hasattr(socket, 'sethostname'), "test needs socket.sethostname()") 730 @unittest.skipUnless(hasattr(socket, 'gethostname'), "test needs socket.gethostname()") 731 def test_sethostname(self): 732 oldhn = socket.gethostname() 733 try: 734 socket.sethostname('new') 735 except OSError as e: 736 if e.errno == errno.EPERM: 737 self.skipTest("test should be run as root") 738 else: 739 raise 740 try: 741 # running test as root! 742 self.assertEqual(socket.gethostname(), 'new') 743 # Should work with bytes objects too 744 socket.sethostname(b'bar') 745 self.assertEqual(socket.gethostname(), 'bar') 746 finally: 747 socket.sethostname(oldhn) 748 749 @unittest.skipUnless(hasattr(socket, 'if_nameindex'), 750 'socket.if_nameindex() not available.') 751 def testInterfaceNameIndex(self): 752 interfaces = socket.if_nameindex() 753 for index, name in interfaces: 754 self.assertIsInstance(index, int) 755 self.assertIsInstance(name, str) 756 # interface indices are non-zero integers 757 self.assertGreater(index, 0) 758 _index = socket.if_nametoindex(name) 759 self.assertIsInstance(_index, int) 760 self.assertEqual(index, _index) 761 _name = socket.if_indextoname(index) 762 self.assertIsInstance(_name, str) 763 self.assertEqual(name, _name) 764 765 @unittest.skipUnless(hasattr(socket, 'if_nameindex'), 766 'socket.if_nameindex() not available.') 767 def testInvalidInterfaceNameIndex(self): 768 # test nonexistent interface index/name 769 self.assertRaises(OSError, socket.if_indextoname, 0) 770 self.assertRaises(OSError, socket.if_nametoindex, '_DEADBEEF') 771 # test with invalid values 772 self.assertRaises(TypeError, socket.if_nametoindex, 0) 773 self.assertRaises(TypeError, socket.if_indextoname, '_DEADBEEF') 774 775 def testRefCountGetNameInfo(self): 776 # Testing reference count for getnameinfo 777 if hasattr(sys, "getrefcount"): 778 try: 779 # On some versions, this loses a reference 780 orig = sys.getrefcount(__name__) 781 socket.getnameinfo(__name__,0) 782 except TypeError: 783 if sys.getrefcount(__name__) != orig: 784 self.fail("socket.getnameinfo loses a reference") 785 786 def testInterpreterCrash(self): 787 # Making sure getnameinfo doesn't crash the interpreter 788 try: 789 # On some versions, this crashes the interpreter. 790 socket.getnameinfo(('x', 0, 0, 0), 0) 791 except OSError: 792 pass 793 794 def testNtoH(self): 795 # This just checks that htons etc. are their own inverse, 796 # when looking at the lower 16 or 32 bits. 797 sizes = {socket.htonl: 32, socket.ntohl: 32, 798 socket.htons: 16, socket.ntohs: 16} 799 for func, size in sizes.items(): 800 mask = (1<<size) - 1 801 for i in (0, 1, 0xffff, ~0xffff, 2, 0x01234567, 0x76543210): 802 self.assertEqual(i & mask, func(func(i&mask)) & mask) 803 804 swapped = func(mask) 805 self.assertEqual(swapped & mask, mask) 806 self.assertRaises(OverflowError, func, 1<<34) 807 808 def testNtoHErrors(self): 809 good_values = [ 1, 2, 3, 1, 2, 3 ] 810 bad_values = [ -1, -2, -3, -1, -2, -3 ] 811 for k in good_values: 812 socket.ntohl(k) 813 socket.ntohs(k) 814 socket.htonl(k) 815 socket.htons(k) 816 for k in bad_values: 817 self.assertRaises(OverflowError, socket.ntohl, k) 818 self.assertRaises(OverflowError, socket.ntohs, k) 819 self.assertRaises(OverflowError, socket.htonl, k) 820 self.assertRaises(OverflowError, socket.htons, k) 821 822 def testGetServBy(self): 823 eq = self.assertEqual 824 # Find one service that exists, then check all the related interfaces. 825 # I've ordered this by protocols that have both a tcp and udp 826 # protocol, at least for modern Linuxes. 827 if (sys.platform.startswith(('freebsd', 'netbsd')) 828 or sys.platform in ('linux', 'darwin')): 829 # avoid the 'echo' service on this platform, as there is an 830 # assumption breaking non-standard port/protocol entry 831 services = ('daytime', 'qotd', 'domain') 832 else: 833 services = ('echo', 'daytime', 'domain') 834 for service in services: 835 try: 836 port = socket.getservbyname(service, 'tcp') 837 break 838 except OSError: 839 pass 840 else: 841 raise OSError 842 # Try same call with optional protocol omitted 843 port2 = socket.getservbyname(service) 844 eq(port, port2) 845 # Try udp, but don't barf it it doesn't exist 846 try: 847 udpport = socket.getservbyname(service, 'udp') 848 except OSError: 849 udpport = None 850 else: 851 eq(udpport, port) 852 # Now make sure the lookup by port returns the same service name 853 eq(socket.getservbyport(port2), service) 854 eq(socket.getservbyport(port, 'tcp'), service) 855 if udpport is not None: 856 eq(socket.getservbyport(udpport, 'udp'), service) 857 # Make sure getservbyport does not accept out of range ports. 858 self.assertRaises(OverflowError, socket.getservbyport, -1) 859 self.assertRaises(OverflowError, socket.getservbyport, 65536) 860 861 def testDefaultTimeout(self): 862 # Testing default timeout 863 # The default timeout should initially be None 864 self.assertEqual(socket.getdefaulttimeout(), None) 865 s = socket.socket() 866 self.assertEqual(s.gettimeout(), None) 867 s.close() 868 869 # Set the default timeout to 10, and see if it propagates 870 socket.setdefaulttimeout(10) 871 self.assertEqual(socket.getdefaulttimeout(), 10) 872 s = socket.socket() 873 self.assertEqual(s.gettimeout(), 10) 874 s.close() 875 876 # Reset the default timeout to None, and see if it propagates 877 socket.setdefaulttimeout(None) 878 self.assertEqual(socket.getdefaulttimeout(), None) 879 s = socket.socket() 880 self.assertEqual(s.gettimeout(), None) 881 s.close() 882 883 # Check that setting it to an invalid value raises ValueError 884 self.assertRaises(ValueError, socket.setdefaulttimeout, -1) 885 886 # Check that setting it to an invalid type raises TypeError 887 self.assertRaises(TypeError, socket.setdefaulttimeout, "spam") 888 889 def testIPv4_inet_aton_fourbytes(self): 890 if not hasattr(socket, 'inet_aton'): 891 return # No inet_aton, nothing to check 892 # Test that issue1008086 and issue767150 are fixed. 893 # It must return 4 bytes. 894 self.assertEqual(b'\x00'*4, socket.inet_aton('0.0.0.0')) 895 self.assertEqual(b'\xff'*4, socket.inet_aton('255.255.255.255')) 896 897 def testIPv4toString(self): 898 if not hasattr(socket, 'inet_pton'): 899 return # No inet_pton() on this platform 900 from socket import inet_aton as f, inet_pton, AF_INET 901 g = lambda a: inet_pton(AF_INET, a) 902 903 assertInvalid = lambda func,a: self.assertRaises( 904 (OSError, ValueError), func, a 905 ) 906 907 self.assertEqual(b'\x00\x00\x00\x00', f('0.0.0.0')) 908 self.assertEqual(b'\xff\x00\xff\x00', f('255.0.255.0')) 909 self.assertEqual(b'\xaa\xaa\xaa\xaa', f('170.170.170.170')) 910 self.assertEqual(b'\x01\x02\x03\x04', f('1.2.3.4')) 911 self.assertEqual(b'\xff\xff\xff\xff', f('255.255.255.255')) 912 assertInvalid(f, '0.0.0.') 913 assertInvalid(f, '300.0.0.0') 914 assertInvalid(f, 'a.0.0.0') 915 assertInvalid(f, '1.2.3.4.5') 916 assertInvalid(f, '::1') 917 918 self.assertEqual(b'\x00\x00\x00\x00', g('0.0.0.0')) 919 self.assertEqual(b'\xff\x00\xff\x00', g('255.0.255.0')) 920 self.assertEqual(b'\xaa\xaa\xaa\xaa', g('170.170.170.170')) 921 self.assertEqual(b'\xff\xff\xff\xff', g('255.255.255.255')) 922 assertInvalid(g, '0.0.0.') 923 assertInvalid(g, '300.0.0.0') 924 assertInvalid(g, 'a.0.0.0') 925 assertInvalid(g, '1.2.3.4.5') 926 assertInvalid(g, '::1') 927 928 def testIPv6toString(self): 929 if not hasattr(socket, 'inet_pton'): 930 return # No inet_pton() on this platform 931 try: 932 from socket import inet_pton, AF_INET6, has_ipv6 933 if not has_ipv6: 934 return 935 except ImportError: 936 return 937 f = lambda a: inet_pton(AF_INET6, a) 938 assertInvalid = lambda a: self.assertRaises( 939 (OSError, ValueError), f, a 940 ) 941 942 self.assertEqual(b'\x00' * 16, f('::')) 943 self.assertEqual(b'\x00' * 16, f('0::0')) 944 self.assertEqual(b'\x00\x01' + b'\x00' * 14, f('1::')) 945 self.assertEqual( 946 b'\x45\xef\x76\xcb\x00\x1a\x56\xef\xaf\xeb\x0b\xac\x19\x24\xae\xae', 947 f('45ef:76cb:1a:56ef:afeb:bac:1924:aeae') 948 ) 949 self.assertEqual( 950 b'\xad\x42\x0a\xbc' + b'\x00' * 4 + b'\x01\x27\x00\x00\x02\x54\x00\x02', 951 f('ad42:abc::127:0:254:2') 952 ) 953 self.assertEqual(b'\x00\x12\x00\x0a' + b'\x00' * 12, f('12:a::')) 954 assertInvalid('0x20::') 955 assertInvalid(':::') 956 assertInvalid('::0::') 957 assertInvalid('1::abc::') 958 assertInvalid('1::abc::def') 959 assertInvalid('1:2:3:4:5:6:') 960 assertInvalid('1:2:3:4:5:6') 961 assertInvalid('1:2:3:4:5:6:7:8:') 962 assertInvalid('1:2:3:4:5:6:7:8:0') 963 964 self.assertEqual(b'\x00' * 12 + b'\xfe\x2a\x17\x40', 965 f('::254.42.23.64') 966 ) 967 self.assertEqual( 968 b'\x00\x42' + b'\x00' * 8 + b'\xa2\x9b\xfe\x2a\x17\x40', 969 f('42::a29b:254.42.23.64') 970 ) 971 self.assertEqual( 972 b'\x00\x42\xa8\xb9\x00\x00\x00\x02\xff\xff\xa2\x9b\xfe\x2a\x17\x40', 973 f('42:a8b9:0:2:ffff:a29b:254.42.23.64') 974 ) 975 assertInvalid('255.254.253.252') 976 assertInvalid('1::260.2.3.0') 977 assertInvalid('1::0.be.e.0') 978 assertInvalid('1:2:3:4:5:6:7:1.2.3.4') 979 assertInvalid('::1.2.3.4:0') 980 assertInvalid('0.100.200.0:3:4:5:6:7:8') 981 982 def testStringToIPv4(self): 983 if not hasattr(socket, 'inet_ntop'): 984 return # No inet_ntop() on this platform 985 from socket import inet_ntoa as f, inet_ntop, AF_INET 986 g = lambda a: inet_ntop(AF_INET, a) 987 assertInvalid = lambda func,a: self.assertRaises( 988 (OSError, ValueError), func, a 989 ) 990 991 self.assertEqual('1.0.1.0', f(b'\x01\x00\x01\x00')) 992 self.assertEqual('170.85.170.85', f(b'\xaa\x55\xaa\x55')) 993 self.assertEqual('255.255.255.255', f(b'\xff\xff\xff\xff')) 994 self.assertEqual('1.2.3.4', f(b'\x01\x02\x03\x04')) 995 assertInvalid(f, b'\x00' * 3) 996 assertInvalid(f, b'\x00' * 5) 997 assertInvalid(f, b'\x00' * 16) 998 999 self.assertEqual('1.0.1.0', g(b'\x01\x00\x01\x00')) 1000 self.assertEqual('170.85.170.85', g(b'\xaa\x55\xaa\x55')) 1001 self.assertEqual('255.255.255.255', g(b'\xff\xff\xff\xff')) 1002 assertInvalid(g, b'\x00' * 3) 1003 assertInvalid(g, b'\x00' * 5) 1004 assertInvalid(g, b'\x00' * 16) 1005 1006 def testStringToIPv6(self): 1007 if not hasattr(socket, 'inet_ntop'): 1008 return # No inet_ntop() on this platform 1009 try: 1010 from socket import inet_ntop, AF_INET6, has_ipv6 1011 if not has_ipv6: 1012 return 1013 except ImportError: 1014 return 1015 f = lambda a: inet_ntop(AF_INET6, a) 1016 assertInvalid = lambda a: self.assertRaises( 1017 (OSError, ValueError), f, a 1018 ) 1019 1020 self.assertEqual('::', f(b'\x00' * 16)) 1021 self.assertEqual('::1', f(b'\x00' * 15 + b'\x01')) 1022 self.assertEqual( 1023 'aef:b01:506:1001:ffff:9997:55:170', 1024 f(b'\x0a\xef\x0b\x01\x05\x06\x10\x01\xff\xff\x99\x97\x00\x55\x01\x70') 1025 ) 1026 1027 assertInvalid(b'\x12' * 15) 1028 assertInvalid(b'\x12' * 17) 1029 assertInvalid(b'\x12' * 4) 1030 1031 # XXX The following don't test module-level functionality... 1032 1033 def testSockName(self): 1034 # Testing getsockname() 1035 port = support.find_unused_port() 1036 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 1037 self.addCleanup(sock.close) 1038 sock.bind(("0.0.0.0", port)) 1039 name = sock.getsockname() 1040 # XXX(nnorwitz): http://tinyurl.com/os5jz seems to indicate 1041 # it reasonable to get the host's addr in addition to 0.0.0.0. 1042 # At least for eCos. This is required for the S/390 to pass. 1043 try: 1044 my_ip_addr = socket.gethostbyname(socket.gethostname()) 1045 except OSError: 1046 # Probably name lookup wasn't set up right; skip this test 1047 return 1048 self.assertIn(name[0], ("0.0.0.0", my_ip_addr), '%s invalid' % name[0]) 1049 self.assertEqual(name[1], port) 1050 1051 def testGetSockOpt(self): 1052 # Testing getsockopt() 1053 # We know a socket should start without reuse==0 1054 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 1055 self.addCleanup(sock.close) 1056 reuse = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) 1057 self.assertFalse(reuse != 0, "initial mode is reuse") 1058 1059 def testSetSockOpt(self): 1060 # Testing setsockopt() 1061 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 1062 self.addCleanup(sock.close) 1063 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 1064 reuse = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) 1065 self.assertFalse(reuse == 0, "failed to set reuse mode") 1066 1067 def testSendAfterClose(self): 1068 # testing send() after close() with timeout 1069 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 1070 sock.settimeout(1) 1071 sock.close() 1072 self.assertRaises(OSError, sock.send, b"spam") 1073 1074 def testNewAttributes(self): 1075 # testing .family, .type and .protocol 1076 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 1077 self.assertEqual(sock.family, socket.AF_INET) 1078 self.assertEqual(sock.type, socket.SOCK_STREAM) 1079 self.assertEqual(sock.proto, 0) 1080 sock.close() 1081 1082 def test_getsockaddrarg(self): 1083 host = '0.0.0.0' 1084 port = support.find_unused_port() 1085 big_port = port + 65536 1086 neg_port = port - 65536 1087 sock = socket.socket() 1088 try: 1089 self.assertRaises(OverflowError, sock.bind, (host, big_port)) 1090 self.assertRaises(OverflowError, sock.bind, (host, neg_port)) 1091 sock.bind((host, port)) 1092 finally: 1093 sock.close() 1094 1095 @unittest.skipUnless(os.name == "nt", "Windows specific") 1096 def test_sock_ioctl(self): 1097 self.assertTrue(hasattr(socket.socket, 'ioctl')) 1098 self.assertTrue(hasattr(socket, 'SIO_RCVALL')) 1099 self.assertTrue(hasattr(socket, 'RCVALL_ON')) 1100 self.assertTrue(hasattr(socket, 'RCVALL_OFF')) 1101 self.assertTrue(hasattr(socket, 'SIO_KEEPALIVE_VALS')) 1102 s = socket.socket() 1103 self.addCleanup(s.close) 1104 self.assertRaises(ValueError, s.ioctl, -1, None) 1105 s.ioctl(socket.SIO_KEEPALIVE_VALS, (1, 100, 100)) 1106 1107 def testGetaddrinfo(self): 1108 try: 1109 socket.getaddrinfo('localhost', 80) 1110 except socket.gaierror as err: 1111 if err.errno == socket.EAI_SERVICE: 1112 # see http://bugs.python.org/issue1282647 1113 self.skipTest("buggy libc version") 1114 raise 1115 # len of every sequence is supposed to be == 5 1116 for info in socket.getaddrinfo(HOST, None): 1117 self.assertEqual(len(info), 5) 1118 # host can be a domain name, a string representation of an 1119 # IPv4/v6 address or None 1120 socket.getaddrinfo('localhost', 80) 1121 socket.getaddrinfo('127.0.0.1', 80) 1122 socket.getaddrinfo(None, 80) 1123 if support.IPV6_ENABLED: 1124 socket.getaddrinfo('::1', 80) 1125 # port can be a string service name such as "http", a numeric 1126 # port number or None 1127 socket.getaddrinfo(HOST, "http") 1128 socket.getaddrinfo(HOST, 80) 1129 socket.getaddrinfo(HOST, None) 1130 # test family and socktype filters 1131 infos = socket.getaddrinfo(HOST, None, socket.AF_INET) 1132 for family, _, _, _, _ in infos: 1133 self.assertEqual(family, socket.AF_INET) 1134 infos = socket.getaddrinfo(HOST, None, 0, socket.SOCK_STREAM) 1135 for _, socktype, _, _, _ in infos: 1136 self.assertEqual(socktype, socket.SOCK_STREAM) 1137 # test proto and flags arguments 1138 socket.getaddrinfo(HOST, None, 0, 0, socket.SOL_TCP) 1139 socket.getaddrinfo(HOST, None, 0, 0, 0, socket.AI_PASSIVE) 1140 # a server willing to support both IPv4 and IPv6 will 1141 # usually do this 1142 socket.getaddrinfo(None, 0, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, 1143 socket.AI_PASSIVE) 1144 # test keyword arguments 1145 a = socket.getaddrinfo(HOST, None) 1146 b = socket.getaddrinfo(host=HOST, port=None) 1147 self.assertEqual(a, b) 1148 a = socket.getaddrinfo(HOST, None, socket.AF_INET) 1149 b = socket.getaddrinfo(HOST, None, family=socket.AF_INET) 1150 self.assertEqual(a, b) 1151 a = socket.getaddrinfo(HOST, None, 0, socket.SOCK_STREAM) 1152 b = socket.getaddrinfo(HOST, None, type=socket.SOCK_STREAM) 1153 self.assertEqual(a, b) 1154 a = socket.getaddrinfo(HOST, None, 0, 0, socket.SOL_TCP) 1155 b = socket.getaddrinfo(HOST, None, proto=socket.SOL_TCP) 1156 self.assertEqual(a, b) 1157 a = socket.getaddrinfo(HOST, None, 0, 0, 0, socket.AI_PASSIVE) 1158 b = socket.getaddrinfo(HOST, None, flags=socket.AI_PASSIVE) 1159 self.assertEqual(a, b) 1160 a = socket.getaddrinfo(None, 0, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, 1161 socket.AI_PASSIVE) 1162 b = socket.getaddrinfo(host=None, port=0, family=socket.AF_UNSPEC, 1163 type=socket.SOCK_STREAM, proto=0, 1164 flags=socket.AI_PASSIVE) 1165 self.assertEqual(a, b) 1166 # Issue #6697. 1167 self.assertRaises(UnicodeEncodeError, socket.getaddrinfo, 'localhost', '\uD800') 1168 1169 def test_getnameinfo(self): 1170 # only IP addresses are allowed 1171 self.assertRaises(OSError, socket.getnameinfo, ('mail.python.org',0), 0) 1172 1173 @unittest.skipUnless(support.is_resource_enabled('network'), 1174 'network is not enabled') 1175 def test_idna(self): 1176 # Check for internet access before running test (issue #12804). 1177 try: 1178 socket.gethostbyname('python.org') 1179 except socket.gaierror as e: 1180 if e.errno == socket.EAI_NODATA: 1181 self.skipTest('internet access required for this test') 1182 # these should all be successful 1183 socket.gethostbyname('испытание.python.org') 1184 socket.gethostbyname_ex('испытание.python.org') 1185 socket.getaddrinfo('испытание.python.org',0,socket.AF_UNSPEC,socket.SOCK_STREAM) 1186 # this may not work if the forward lookup choses the IPv6 address, as that doesn't 1187 # have a reverse entry yet 1188 # socket.gethostbyaddr('испытание.python.org') 1189 1190 def check_sendall_interrupted(self, with_timeout): 1191 # socketpair() is not stricly required, but it makes things easier. 1192 if not hasattr(signal, 'alarm') or not hasattr(socket, 'socketpair'): 1193 self.skipTest("signal.alarm and socket.socketpair required for this test") 1194 # Our signal handlers clobber the C errno by calling a math function 1195 # with an invalid domain value. 1196 def ok_handler(*args): 1197 self.assertRaises(ValueError, math.acosh, 0) 1198 def raising_handler(*args): 1199 self.assertRaises(ValueError, math.acosh, 0) 1200 1 // 0 1201 c, s = socket.socketpair() 1202 old_alarm = signal.signal(signal.SIGALRM, raising_handler) 1203 try: 1204 if with_timeout: 1205 # Just above the one second minimum for signal.alarm 1206 c.settimeout(1.5) 1207 with self.assertRaises(ZeroDivisionError): 1208 signal.alarm(1) 1209 c.sendall(b"x" * (1024**2)) 1210 if with_timeout: 1211 signal.signal(signal.SIGALRM, ok_handler) 1212 signal.alarm(1) 1213 self.assertRaises(socket.timeout, c.sendall, b"x" * (1024**2)) 1214 finally: 1215 signal.signal(signal.SIGALRM, old_alarm) 1216 c.close() 1217 s.close() 1218 1219 def test_sendall_interrupted(self): 1220 self.check_sendall_interrupted(False) 1221 1222 def test_sendall_interrupted_with_timeout(self): 1223 self.check_sendall_interrupted(True) 1224 1225 def test_dealloc_warn(self): 1226 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 1227 r = repr(sock) 1228 with self.assertWarns(ResourceWarning) as cm: 1229 sock = None 1230 support.gc_collect() 1231 self.assertIn(r, str(cm.warning.args[0])) 1232 # An open socket file object gets dereferenced after the socket 1233 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 1234 f = sock.makefile('rb') 1235 r = repr(sock) 1236 sock = None 1237 support.gc_collect() 1238 with self.assertWarns(ResourceWarning): 1239 f = None 1240 support.gc_collect() 1241 1242 def test_name_closed_socketio(self): 1243 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: 1244 fp = sock.makefile("rb") 1245 fp.close() 1246 self.assertEqual(repr(fp), "<_io.BufferedReader name=-1>") 1247 1248 def test_unusable_closed_socketio(self): 1249 with socket.socket() as sock: 1250 fp = sock.makefile("rb", buffering=0) 1251 self.assertTrue(fp.readable()) 1252 self.assertFalse(fp.writable()) 1253 self.assertFalse(fp.seekable()) 1254 fp.close() 1255 self.assertRaises(ValueError, fp.readable) 1256 self.assertRaises(ValueError, fp.writable) 1257 self.assertRaises(ValueError, fp.seekable) 1258 1259 def test_pickle(self): 1260 sock = socket.socket() 1261 with sock: 1262 for protocol in range(pickle.HIGHEST_PROTOCOL + 1): 1263 self.assertRaises(TypeError, pickle.dumps, sock, protocol) 1264 1265 def test_listen_backlog0(self): 1266 srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 1267 srv.bind((HOST, 0)) 1268 # backlog = 0 1269 srv.listen(0) 1270 srv.close() 1271 1272 @unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.') 1273 def test_flowinfo(self): 1274 self.assertRaises(OverflowError, socket.getnameinfo, 1275 ('::1',0, 0xffffffff), 0) 1276 with socket.socket(socket.AF_INET6, socket.SOCK_STREAM) as s: 1277 self.assertRaises(OverflowError, s.bind, ('::1', 0, -10)) 1278 1279 1280@unittest.skipUnless(HAVE_SOCKET_CAN, 'SocketCan required for this test.') 1281class BasicCANTest(unittest.TestCase): 1282 1283 def testCrucialConstants(self): 1284 socket.AF_CAN 1285 socket.PF_CAN 1286 socket.CAN_RAW 1287 1288 def testCreateSocket(self): 1289 with socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) as s: 1290 pass 1291 1292 def testBindAny(self): 1293 with socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) as s: 1294 s.bind(('', )) 1295 1296 def testTooLongInterfaceName(self): 1297 # most systems limit IFNAMSIZ to 16, take 1024 to be sure 1298 with socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) as s: 1299 self.assertRaisesRegex(OSError, 'interface name too long', 1300 s.bind, ('x' * 1024,)) 1301 1302 @unittest.skipUnless(hasattr(socket, "CAN_RAW_LOOPBACK"), 1303 'socket.CAN_RAW_LOOPBACK required for this test.') 1304 def testLoopback(self): 1305 with socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) as s: 1306 for loopback in (0, 1): 1307 s.setsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_LOOPBACK, 1308 loopback) 1309 self.assertEqual(loopback, 1310 s.getsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_LOOPBACK)) 1311 1312 @unittest.skipUnless(hasattr(socket, "CAN_RAW_FILTER"), 1313 'socket.CAN_RAW_FILTER required for this test.') 1314 def testFilter(self): 1315 can_id, can_mask = 0x200, 0x700 1316 can_filter = struct.pack("=II", can_id, can_mask) 1317 with socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW) as s: 1318 s.setsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_FILTER, can_filter) 1319 self.assertEqual(can_filter, 1320 s.getsockopt(socket.SOL_CAN_RAW, socket.CAN_RAW_FILTER, 8)) 1321 1322 1323@unittest.skipUnless(HAVE_SOCKET_CAN, 'SocketCan required for this test.') 1324@unittest.skipUnless(thread, 'Threading required for this test.') 1325class CANTest(ThreadedCANSocketTest): 1326 1327 """The CAN frame structure is defined in <linux/can.h>: 1328 1329 struct can_frame { 1330 canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */ 1331 __u8 can_dlc; /* data length code: 0 .. 8 */ 1332 __u8 data[8] __attribute__((aligned(8))); 1333 }; 1334 """ 1335 can_frame_fmt = "=IB3x8s" 1336 1337 def __init__(self, methodName='runTest'): 1338 ThreadedCANSocketTest.__init__(self, methodName=methodName) 1339 1340 @classmethod 1341 def build_can_frame(cls, can_id, data): 1342 """Build a CAN frame.""" 1343 can_dlc = len(data) 1344 data = data.ljust(8, b'\x00') 1345 return struct.pack(cls.can_frame_fmt, can_id, can_dlc, data) 1346 1347 @classmethod 1348 def dissect_can_frame(cls, frame): 1349 """Dissect a CAN frame.""" 1350 can_id, can_dlc, data = struct.unpack(cls.can_frame_fmt, frame) 1351 return (can_id, can_dlc, data[:can_dlc]) 1352 1353 def testSendFrame(self): 1354 cf, addr = self.s.recvfrom(self.bufsize) 1355 self.assertEqual(self.cf, cf) 1356 self.assertEqual(addr[0], self.interface) 1357 self.assertEqual(addr[1], socket.AF_CAN) 1358 1359 def _testSendFrame(self): 1360 self.cf = self.build_can_frame(0x00, b'\x01\x02\x03\x04\x05') 1361 self.cli.send(self.cf) 1362 1363 def testSendMaxFrame(self): 1364 cf, addr = self.s.recvfrom(self.bufsize) 1365 self.assertEqual(self.cf, cf) 1366 1367 def _testSendMaxFrame(self): 1368 self.cf = self.build_can_frame(0x00, b'\x07' * 8) 1369 self.cli.send(self.cf) 1370 1371 def testSendMultiFrames(self): 1372 cf, addr = self.s.recvfrom(self.bufsize) 1373 self.assertEqual(self.cf1, cf) 1374 1375 cf, addr = self.s.recvfrom(self.bufsize) 1376 self.assertEqual(self.cf2, cf) 1377 1378 def _testSendMultiFrames(self): 1379 self.cf1 = self.build_can_frame(0x07, b'\x44\x33\x22\x11') 1380 self.cli.send(self.cf1) 1381 1382 self.cf2 = self.build_can_frame(0x12, b'\x99\x22\x33') 1383 self.cli.send(self.cf2) 1384 1385 1386@unittest.skipUnless(HAVE_SOCKET_RDS, 'RDS sockets required for this test.') 1387class BasicRDSTest(unittest.TestCase): 1388 1389 def testCrucialConstants(self): 1390 socket.AF_RDS 1391 socket.PF_RDS 1392 1393 def testCreateSocket(self): 1394 with socket.socket(socket.PF_RDS, socket.SOCK_SEQPACKET, 0) as s: 1395 pass 1396 1397 def testSocketBufferSize(self): 1398 bufsize = 16384 1399 with socket.socket(socket.PF_RDS, socket.SOCK_SEQPACKET, 0) as s: 1400 s.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, bufsize) 1401 s.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, bufsize) 1402 1403 1404@unittest.skipUnless(HAVE_SOCKET_RDS, 'RDS sockets required for this test.') 1405@unittest.skipUnless(thread, 'Threading required for this test.') 1406class RDSTest(ThreadedRDSSocketTest): 1407 1408 def __init__(self, methodName='runTest'): 1409 ThreadedRDSSocketTest.__init__(self, methodName=methodName) 1410 1411 def setUp(self): 1412 super().setUp() 1413 self.evt = threading.Event() 1414 1415 def testSendAndRecv(self): 1416 data, addr = self.serv.recvfrom(self.bufsize) 1417 self.assertEqual(self.data, data) 1418 self.assertEqual(self.cli_addr, addr) 1419 1420 def _testSendAndRecv(self): 1421 self.data = b'spam' 1422 self.cli.sendto(self.data, 0, (HOST, self.port)) 1423 1424 def testPeek(self): 1425 data, addr = self.serv.recvfrom(self.bufsize, socket.MSG_PEEK) 1426 self.assertEqual(self.data, data) 1427 data, addr = self.serv.recvfrom(self.bufsize) 1428 self.assertEqual(self.data, data) 1429 1430 def _testPeek(self): 1431 self.data = b'spam' 1432 self.cli.sendto(self.data, 0, (HOST, self.port)) 1433 1434 @requireAttrs(socket.socket, 'recvmsg') 1435 def testSendAndRecvMsg(self): 1436 data, ancdata, msg_flags, addr = self.serv.recvmsg(self.bufsize) 1437 self.assertEqual(self.data, data) 1438 1439 @requireAttrs(socket.socket, 'sendmsg') 1440 def _testSendAndRecvMsg(self): 1441 self.data = b'hello ' * 10 1442 self.cli.sendmsg([self.data], (), 0, (HOST, self.port)) 1443 1444 def testSendAndRecvMulti(self): 1445 data, addr = self.serv.recvfrom(self.bufsize) 1446 self.assertEqual(self.data1, data) 1447 1448 data, addr = self.serv.recvfrom(self.bufsize) 1449 self.assertEqual(self.data2, data) 1450 1451 def _testSendAndRecvMulti(self): 1452 self.data1 = b'bacon' 1453 self.cli.sendto(self.data1, 0, (HOST, self.port)) 1454 1455 self.data2 = b'egg' 1456 self.cli.sendto(self.data2, 0, (HOST, self.port)) 1457 1458 def testSelect(self): 1459 r, w, x = select.select([self.serv], [], [], 3.0) 1460 self.assertIn(self.serv, r) 1461 data, addr = self.serv.recvfrom(self.bufsize) 1462 self.assertEqual(self.data, data) 1463 1464 def _testSelect(self): 1465 self.data = b'select' 1466 self.cli.sendto(self.data, 0, (HOST, self.port)) 1467 1468 def testCongestion(self): 1469 # wait until the sender is done 1470 self.evt.wait() 1471 1472 def _testCongestion(self): 1473 # test the behavior in case of congestion 1474 self.data = b'fill' 1475 self.cli.setblocking(False) 1476 try: 1477 # try to lower the receiver's socket buffer size 1478 self.cli.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 16384) 1479 except OSError: 1480 pass 1481 with self.assertRaises(OSError) as cm: 1482 try: 1483 # fill the receiver's socket buffer 1484 while True: 1485 self.cli.sendto(self.data, 0, (HOST, self.port)) 1486 finally: 1487 # signal the receiver we're done 1488 self.evt.set() 1489 # sendto() should have failed with ENOBUFS 1490 self.assertEqual(cm.exception.errno, errno.ENOBUFS) 1491 # and we should have received a congestion notification through poll 1492 r, w, x = select.select([self.serv], [], [], 3.0) 1493 self.assertIn(self.serv, r) 1494 1495 1496@unittest.skipUnless(thread, 'Threading required for this test.') 1497class BasicTCPTest(SocketConnectedTest): 1498 1499 def __init__(self, methodName='runTest'): 1500 SocketConnectedTest.__init__(self, methodName=methodName) 1501 1502 def testRecv(self): 1503 # Testing large receive over TCP 1504 msg = self.cli_conn.recv(1024) 1505 self.assertEqual(msg, MSG) 1506 1507 def _testRecv(self): 1508 self.serv_conn.send(MSG) 1509 1510 def testOverFlowRecv(self): 1511 # Testing receive in chunks over TCP 1512 seg1 = self.cli_conn.recv(len(MSG) - 3) 1513 seg2 = self.cli_conn.recv(1024) 1514 msg = seg1 + seg2 1515 self.assertEqual(msg, MSG) 1516 1517 def _testOverFlowRecv(self): 1518 self.serv_conn.send(MSG) 1519 1520 def testRecvFrom(self): 1521 # Testing large recvfrom() over TCP 1522 msg, addr = self.cli_conn.recvfrom(1024) 1523 self.assertEqual(msg, MSG) 1524 1525 def _testRecvFrom(self): 1526 self.serv_conn.send(MSG) 1527 1528 def testOverFlowRecvFrom(self): 1529 # Testing recvfrom() in chunks over TCP 1530 seg1, addr = self.cli_conn.recvfrom(len(MSG)-3) 1531 seg2, addr = self.cli_conn.recvfrom(1024) 1532 msg = seg1 + seg2 1533 self.assertEqual(msg, MSG) 1534 1535 def _testOverFlowRecvFrom(self): 1536 self.serv_conn.send(MSG) 1537 1538 def testSendAll(self): 1539 # Testing sendall() with a 2048 byte string over TCP 1540 msg = b'' 1541 while 1: 1542 read = self.cli_conn.recv(1024) 1543 if not read: 1544 break 1545 msg += read 1546 self.assertEqual(msg, b'f' * 2048) 1547 1548 def _testSendAll(self): 1549 big_chunk = b'f' * 2048 1550 self.serv_conn.sendall(big_chunk) 1551 1552 def testFromFd(self): 1553 # Testing fromfd() 1554 fd = self.cli_conn.fileno() 1555 sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM) 1556 self.addCleanup(sock.close) 1557 self.assertIsInstance(sock, socket.socket) 1558 msg = sock.recv(1024) 1559 self.assertEqual(msg, MSG) 1560 1561 def _testFromFd(self): 1562 self.serv_conn.send(MSG) 1563 1564 def testDup(self): 1565 # Testing dup() 1566 sock = self.cli_conn.dup() 1567 self.addCleanup(sock.close) 1568 msg = sock.recv(1024) 1569 self.assertEqual(msg, MSG) 1570 1571 def _testDup(self): 1572 self.serv_conn.send(MSG) 1573 1574 def testShutdown(self): 1575 # Testing shutdown() 1576 msg = self.cli_conn.recv(1024) 1577 self.assertEqual(msg, MSG) 1578 # wait for _testShutdown to finish: on OS X, when the server 1579 # closes the connection the client also becomes disconnected, 1580 # and the client's shutdown call will fail. (Issue #4397.) 1581 self.done.wait() 1582 1583 def _testShutdown(self): 1584 self.serv_conn.send(MSG) 1585 self.serv_conn.shutdown(2) 1586 1587 def testDetach(self): 1588 # Testing detach() 1589 fileno = self.cli_conn.fileno() 1590 f = self.cli_conn.detach() 1591 self.assertEqual(f, fileno) 1592 # cli_conn cannot be used anymore... 1593 self.assertTrue(self.cli_conn._closed) 1594 self.assertRaises(OSError, self.cli_conn.recv, 1024) 1595 self.cli_conn.close() 1596 # ...but we can create another socket using the (still open) 1597 # file descriptor 1598 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, fileno=f) 1599 self.addCleanup(sock.close) 1600 msg = sock.recv(1024) 1601 self.assertEqual(msg, MSG) 1602 1603 def _testDetach(self): 1604 self.serv_conn.send(MSG) 1605 1606@unittest.skipUnless(thread, 'Threading required for this test.') 1607class BasicUDPTest(ThreadedUDPSocketTest): 1608 1609 def __init__(self, methodName='runTest'): 1610 ThreadedUDPSocketTest.__init__(self, methodName=methodName) 1611 1612 def testSendtoAndRecv(self): 1613 # Testing sendto() and Recv() over UDP 1614 msg = self.serv.recv(len(MSG)) 1615 self.assertEqual(msg, MSG) 1616 1617 def _testSendtoAndRecv(self): 1618 self.cli.sendto(MSG, 0, (HOST, self.port)) 1619 1620 def testRecvFrom(self): 1621 # Testing recvfrom() over UDP 1622 msg, addr = self.serv.recvfrom(len(MSG)) 1623 self.assertEqual(msg, MSG) 1624 1625 def _testRecvFrom(self): 1626 self.cli.sendto(MSG, 0, (HOST, self.port)) 1627 1628 def testRecvFromNegative(self): 1629 # Negative lengths passed to recvfrom should give ValueError. 1630 self.assertRaises(ValueError, self.serv.recvfrom, -1) 1631 1632 def _testRecvFromNegative(self): 1633 self.cli.sendto(MSG, 0, (HOST, self.port)) 1634 1635# Tests for the sendmsg()/recvmsg() interface. Where possible, the 1636# same test code is used with different families and types of socket 1637# (e.g. stream, datagram), and tests using recvmsg() are repeated 1638# using recvmsg_into(). 1639# 1640# The generic test classes such as SendmsgTests and 1641# RecvmsgGenericTests inherit from SendrecvmsgBase and expect to be 1642# supplied with sockets cli_sock and serv_sock representing the 1643# client's and the server's end of the connection respectively, and 1644# attributes cli_addr and serv_addr holding their (numeric where 1645# appropriate) addresses. 1646# 1647# The final concrete test classes combine these with subclasses of 1648# SocketTestBase which set up client and server sockets of a specific 1649# type, and with subclasses of SendrecvmsgBase such as 1650# SendrecvmsgDgramBase and SendrecvmsgConnectedBase which map these 1651# sockets to cli_sock and serv_sock and override the methods and 1652# attributes of SendrecvmsgBase to fill in destination addresses if 1653# needed when sending, check for specific flags in msg_flags, etc. 1654# 1655# RecvmsgIntoMixin provides a version of doRecvmsg() implemented using 1656# recvmsg_into(). 1657 1658# XXX: like the other datagram (UDP) tests in this module, the code 1659# here assumes that datagram delivery on the local machine will be 1660# reliable. 1661 1662class SendrecvmsgBase(ThreadSafeCleanupTestCase): 1663 # Base class for sendmsg()/recvmsg() tests. 1664 1665 # Time in seconds to wait before considering a test failed, or 1666 # None for no timeout. Not all tests actually set a timeout. 1667 fail_timeout = 3.0 1668 1669 def setUp(self): 1670 self.misc_event = threading.Event() 1671 super().setUp() 1672 1673 def sendToServer(self, msg): 1674 # Send msg to the server. 1675 return self.cli_sock.send(msg) 1676 1677 # Tuple of alternative default arguments for sendmsg() when called 1678 # via sendmsgToServer() (e.g. to include a destination address). 1679 sendmsg_to_server_defaults = () 1680 1681 def sendmsgToServer(self, *args): 1682 # Call sendmsg() on self.cli_sock with the given arguments, 1683 # filling in any arguments which are not supplied with the 1684 # corresponding items of self.sendmsg_to_server_defaults, if 1685 # any. 1686 return self.cli_sock.sendmsg( 1687 *(args + self.sendmsg_to_server_defaults[len(args):])) 1688 1689 def doRecvmsg(self, sock, bufsize, *args): 1690 # Call recvmsg() on sock with given arguments and return its 1691 # result. Should be used for tests which can use either 1692 # recvmsg() or recvmsg_into() - RecvmsgIntoMixin overrides 1693 # this method with one which emulates it using recvmsg_into(), 1694 # thus allowing the same test to be used for both methods. 1695 result = sock.recvmsg(bufsize, *args) 1696 self.registerRecvmsgResult(result) 1697 return result 1698 1699 def registerRecvmsgResult(self, result): 1700 # Called by doRecvmsg() with the return value of recvmsg() or 1701 # recvmsg_into(). Can be overridden to arrange cleanup based 1702 # on the returned ancillary data, for instance. 1703 pass 1704 1705 def checkRecvmsgAddress(self, addr1, addr2): 1706 # Called to compare the received address with the address of 1707 # the peer. 1708 self.assertEqual(addr1, addr2) 1709 1710 # Flags that are normally unset in msg_flags 1711 msg_flags_common_unset = 0 1712 for name in ("MSG_CTRUNC", "MSG_OOB"): 1713 msg_flags_common_unset |= getattr(socket, name, 0) 1714 1715 # Flags that are normally set 1716 msg_flags_common_set = 0 1717 1718 # Flags set when a complete record has been received (e.g. MSG_EOR 1719 # for SCTP) 1720 msg_flags_eor_indicator = 0 1721 1722 # Flags set when a complete record has not been received 1723 # (e.g. MSG_TRUNC for datagram sockets) 1724 msg_flags_non_eor_indicator = 0 1725 1726 def checkFlags(self, flags, eor=None, checkset=0, checkunset=0, ignore=0): 1727 # Method to check the value of msg_flags returned by recvmsg[_into](). 1728 # 1729 # Checks that all bits in msg_flags_common_set attribute are 1730 # set in "flags" and all bits in msg_flags_common_unset are 1731 # unset. 1732 # 1733 # The "eor" argument specifies whether the flags should 1734 # indicate that a full record (or datagram) has been received. 1735 # If "eor" is None, no checks are done; otherwise, checks 1736 # that: 1737 # 1738 # * if "eor" is true, all bits in msg_flags_eor_indicator are 1739 # set and all bits in msg_flags_non_eor_indicator are unset 1740 # 1741 # * if "eor" is false, all bits in msg_flags_non_eor_indicator 1742 # are set and all bits in msg_flags_eor_indicator are unset 1743 # 1744 # If "checkset" and/or "checkunset" are supplied, they require 1745 # the given bits to be set or unset respectively, overriding 1746 # what the attributes require for those bits. 1747 # 1748 # If any bits are set in "ignore", they will not be checked, 1749 # regardless of the other inputs. 1750 # 1751 # Will raise Exception if the inputs require a bit to be both 1752 # set and unset, and it is not ignored. 1753 1754 defaultset = self.msg_flags_common_set 1755 defaultunset = self.msg_flags_common_unset 1756 1757 if eor: 1758 defaultset |= self.msg_flags_eor_indicator 1759 defaultunset |= self.msg_flags_non_eor_indicator 1760 elif eor is not None: 1761 defaultset |= self.msg_flags_non_eor_indicator 1762 defaultunset |= self.msg_flags_eor_indicator 1763 1764 # Function arguments override defaults 1765 defaultset &= ~checkunset 1766 defaultunset &= ~checkset 1767 1768 # Merge arguments with remaining defaults, and check for conflicts 1769 checkset |= defaultset 1770 checkunset |= defaultunset 1771 inboth = checkset & checkunset & ~ignore 1772 if inboth: 1773 raise Exception("contradictory set, unset requirements for flags " 1774 "{0:#x}".format(inboth)) 1775 1776 # Compare with given msg_flags value 1777 mask = (checkset | checkunset) & ~ignore 1778 self.assertEqual(flags & mask, checkset & mask) 1779 1780 1781class RecvmsgIntoMixin(SendrecvmsgBase): 1782 # Mixin to implement doRecvmsg() using recvmsg_into(). 1783 1784 def doRecvmsg(self, sock, bufsize, *args): 1785 buf = bytearray(bufsize) 1786 result = sock.recvmsg_into([buf], *args) 1787 self.registerRecvmsgResult(result) 1788 self.assertGreaterEqual(result[0], 0) 1789 self.assertLessEqual(result[0], bufsize) 1790 return (bytes(buf[:result[0]]),) + result[1:] 1791 1792 1793class SendrecvmsgDgramFlagsBase(SendrecvmsgBase): 1794 # Defines flags to be checked in msg_flags for datagram sockets. 1795 1796 @property 1797 def msg_flags_non_eor_indicator(self): 1798 return super().msg_flags_non_eor_indicator | socket.MSG_TRUNC 1799 1800 1801class SendrecvmsgSCTPFlagsBase(SendrecvmsgBase): 1802 # Defines flags to be checked in msg_flags for SCTP sockets. 1803 1804 @property 1805 def msg_flags_eor_indicator(self): 1806 return super().msg_flags_eor_indicator | socket.MSG_EOR 1807 1808 1809class SendrecvmsgConnectionlessBase(SendrecvmsgBase): 1810 # Base class for tests on connectionless-mode sockets. Users must 1811 # supply sockets on attributes cli and serv to be mapped to 1812 # cli_sock and serv_sock respectively. 1813 1814 @property 1815 def serv_sock(self): 1816 return self.serv 1817 1818 @property 1819 def cli_sock(self): 1820 return self.cli 1821 1822 @property 1823 def sendmsg_to_server_defaults(self): 1824 return ([], [], 0, self.serv_addr) 1825 1826 def sendToServer(self, msg): 1827 return self.cli_sock.sendto(msg, self.serv_addr) 1828 1829 1830class SendrecvmsgConnectedBase(SendrecvmsgBase): 1831 # Base class for tests on connected sockets. Users must supply 1832 # sockets on attributes serv_conn and cli_conn (representing the 1833 # connections *to* the server and the client), to be mapped to 1834 # cli_sock and serv_sock respectively. 1835 1836 @property 1837 def serv_sock(self): 1838 return self.cli_conn 1839 1840 @property 1841 def cli_sock(self): 1842 return self.serv_conn 1843 1844 def checkRecvmsgAddress(self, addr1, addr2): 1845 # Address is currently "unspecified" for a connected socket, 1846 # so we don't examine it 1847 pass 1848 1849 1850class SendrecvmsgServerTimeoutBase(SendrecvmsgBase): 1851 # Base class to set a timeout on server's socket. 1852 1853 def setUp(self): 1854 super().setUp() 1855 self.serv_sock.settimeout(self.fail_timeout) 1856 1857 1858class SendmsgTests(SendrecvmsgServerTimeoutBase): 1859 # Tests for sendmsg() which can use any socket type and do not 1860 # involve recvmsg() or recvmsg_into(). 1861 1862 def testSendmsg(self): 1863 # Send a simple message with sendmsg(). 1864 self.assertEqual(self.serv_sock.recv(len(MSG)), MSG) 1865 1866 def _testSendmsg(self): 1867 self.assertEqual(self.sendmsgToServer([MSG]), len(MSG)) 1868 1869 def testSendmsgDataGenerator(self): 1870 # Send from buffer obtained from a generator (not a sequence). 1871 self.assertEqual(self.serv_sock.recv(len(MSG)), MSG) 1872 1873 def _testSendmsgDataGenerator(self): 1874 self.assertEqual(self.sendmsgToServer((o for o in [MSG])), 1875 len(MSG)) 1876 1877 def testSendmsgAncillaryGenerator(self): 1878 # Gather (empty) ancillary data from a generator. 1879 self.assertEqual(self.serv_sock.recv(len(MSG)), MSG) 1880 1881 def _testSendmsgAncillaryGenerator(self): 1882 self.assertEqual(self.sendmsgToServer([MSG], (o for o in [])), 1883 len(MSG)) 1884 1885 def testSendmsgArray(self): 1886 # Send data from an array instead of the usual bytes object. 1887 self.assertEqual(self.serv_sock.recv(len(MSG)), MSG) 1888 1889 def _testSendmsgArray(self): 1890 self.assertEqual(self.sendmsgToServer([array.array("B", MSG)]), 1891 len(MSG)) 1892 1893 def testSendmsgGather(self): 1894 # Send message data from more than one buffer (gather write). 1895 self.assertEqual(self.serv_sock.recv(len(MSG)), MSG) 1896 1897 def _testSendmsgGather(self): 1898 self.assertEqual(self.sendmsgToServer([MSG[:3], MSG[3:]]), len(MSG)) 1899 1900 def testSendmsgBadArgs(self): 1901 # Check that sendmsg() rejects invalid arguments. 1902 self.assertEqual(self.serv_sock.recv(1000), b"done") 1903 1904 def _testSendmsgBadArgs(self): 1905 self.assertRaises(TypeError, self.cli_sock.sendmsg) 1906 self.assertRaises(TypeError, self.sendmsgToServer, 1907 b"not in an iterable") 1908 self.assertRaises(TypeError, self.sendmsgToServer, 1909 object()) 1910 self.assertRaises(TypeError, self.sendmsgToServer, 1911 [object()]) 1912 self.assertRaises(TypeError, self.sendmsgToServer, 1913 [MSG, object()]) 1914 self.assertRaises(TypeError, self.sendmsgToServer, 1915 [MSG], object()) 1916 self.assertRaises(TypeError, self.sendmsgToServer, 1917 [MSG], [], object()) 1918 self.assertRaises(TypeError, self.sendmsgToServer, 1919 [MSG], [], 0, object()) 1920 self.sendToServer(b"done") 1921 1922 def testSendmsgBadCmsg(self): 1923 # Check that invalid ancillary data items are rejected. 1924 self.assertEqual(self.serv_sock.recv(1000), b"done") 1925 1926 def _testSendmsgBadCmsg(self): 1927 self.assertRaises(TypeError, self.sendmsgToServer, 1928 [MSG], [object()]) 1929 self.assertRaises(TypeError, self.sendmsgToServer, 1930 [MSG], [(object(), 0, b"data")]) 1931 self.assertRaises(TypeError, self.sendmsgToServer, 1932 [MSG], [(0, object(), b"data")]) 1933 self.assertRaises(TypeError, self.sendmsgToServer, 1934 [MSG], [(0, 0, object())]) 1935 self.assertRaises(TypeError, self.sendmsgToServer, 1936 [MSG], [(0, 0)]) 1937 self.assertRaises(TypeError, self.sendmsgToServer, 1938 [MSG], [(0, 0, b"data", 42)]) 1939 self.sendToServer(b"done") 1940 1941 @requireAttrs(socket, "CMSG_SPACE") 1942 def testSendmsgBadMultiCmsg(self): 1943 # Check that invalid ancillary data items are rejected when 1944 # more than one item is present. 1945 self.assertEqual(self.serv_sock.recv(1000), b"done") 1946 1947 @testSendmsgBadMultiCmsg.client_skip 1948 def _testSendmsgBadMultiCmsg(self): 1949 self.assertRaises(TypeError, self.sendmsgToServer, 1950 [MSG], [0, 0, b""]) 1951 self.assertRaises(TypeError, self.sendmsgToServer, 1952 [MSG], [(0, 0, b""), object()]) 1953 self.sendToServer(b"done") 1954 1955 def testSendmsgExcessCmsgReject(self): 1956 # Check that sendmsg() rejects excess ancillary data items 1957 # when the number that can be sent is limited. 1958 self.assertEqual(self.serv_sock.recv(1000), b"done") 1959 1960 def _testSendmsgExcessCmsgReject(self): 1961 if not hasattr(socket, "CMSG_SPACE"): 1962 # Can only send one item 1963 with self.assertRaises(OSError) as cm: 1964 self.sendmsgToServer([MSG], [(0, 0, b""), (0, 0, b"")]) 1965 self.assertIsNone(cm.exception.errno) 1966 self.sendToServer(b"done") 1967 1968 def testSendmsgAfterClose(self): 1969 # Check that sendmsg() fails on a closed socket. 1970 pass 1971 1972 def _testSendmsgAfterClose(self): 1973 self.cli_sock.close() 1974 self.assertRaises(OSError, self.sendmsgToServer, [MSG]) 1975 1976 1977class SendmsgStreamTests(SendmsgTests): 1978 # Tests for sendmsg() which require a stream socket and do not 1979 # involve recvmsg() or recvmsg_into(). 1980 1981 def testSendmsgExplicitNoneAddr(self): 1982 # Check that peer address can be specified as None. 1983 self.assertEqual(self.serv_sock.recv(len(MSG)), MSG) 1984 1985 def _testSendmsgExplicitNoneAddr(self): 1986 self.assertEqual(self.sendmsgToServer([MSG], [], 0, None), len(MSG)) 1987 1988 def testSendmsgTimeout(self): 1989 # Check that timeout works with sendmsg(). 1990 self.assertEqual(self.serv_sock.recv(512), b"a"*512) 1991 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 1992 1993 def _testSendmsgTimeout(self): 1994 try: 1995 self.cli_sock.settimeout(0.03) 1996 with self.assertRaises(socket.timeout): 1997 while True: 1998 self.sendmsgToServer([b"a"*512]) 1999 finally: 2000 self.misc_event.set() 2001 2002 # XXX: would be nice to have more tests for sendmsg flags argument. 2003 2004 # Linux supports MSG_DONTWAIT when sending, but in general, it 2005 # only works when receiving. Could add other platforms if they 2006 # support it too. 2007 @skipWithClientIf(sys.platform not in {"linux2"}, 2008 "MSG_DONTWAIT not known to work on this platform when " 2009 "sending") 2010 def testSendmsgDontWait(self): 2011 # Check that MSG_DONTWAIT in flags causes non-blocking behaviour. 2012 self.assertEqual(self.serv_sock.recv(512), b"a"*512) 2013 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 2014 2015 @testSendmsgDontWait.client_skip 2016 def _testSendmsgDontWait(self): 2017 try: 2018 with self.assertRaises(OSError) as cm: 2019 while True: 2020 self.sendmsgToServer([b"a"*512], [], socket.MSG_DONTWAIT) 2021 self.assertIn(cm.exception.errno, 2022 (errno.EAGAIN, errno.EWOULDBLOCK)) 2023 finally: 2024 self.misc_event.set() 2025 2026 2027class SendmsgConnectionlessTests(SendmsgTests): 2028 # Tests for sendmsg() which require a connectionless-mode 2029 # (e.g. datagram) socket, and do not involve recvmsg() or 2030 # recvmsg_into(). 2031 2032 def testSendmsgNoDestAddr(self): 2033 # Check that sendmsg() fails when no destination address is 2034 # given for unconnected socket. 2035 pass 2036 2037 def _testSendmsgNoDestAddr(self): 2038 self.assertRaises(OSError, self.cli_sock.sendmsg, 2039 [MSG]) 2040 self.assertRaises(OSError, self.cli_sock.sendmsg, 2041 [MSG], [], 0, None) 2042 2043 2044class RecvmsgGenericTests(SendrecvmsgBase): 2045 # Tests for recvmsg() which can also be emulated using 2046 # recvmsg_into(), and can use any socket type. 2047 2048 def testRecvmsg(self): 2049 # Receive a simple message with recvmsg[_into](). 2050 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, len(MSG)) 2051 self.assertEqual(msg, MSG) 2052 self.checkRecvmsgAddress(addr, self.cli_addr) 2053 self.assertEqual(ancdata, []) 2054 self.checkFlags(flags, eor=True) 2055 2056 def _testRecvmsg(self): 2057 self.sendToServer(MSG) 2058 2059 def testRecvmsgExplicitDefaults(self): 2060 # Test recvmsg[_into]() with default arguments provided explicitly. 2061 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2062 len(MSG), 0, 0) 2063 self.assertEqual(msg, MSG) 2064 self.checkRecvmsgAddress(addr, self.cli_addr) 2065 self.assertEqual(ancdata, []) 2066 self.checkFlags(flags, eor=True) 2067 2068 def _testRecvmsgExplicitDefaults(self): 2069 self.sendToServer(MSG) 2070 2071 def testRecvmsgShorter(self): 2072 # Receive a message smaller than buffer. 2073 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2074 len(MSG) + 42) 2075 self.assertEqual(msg, MSG) 2076 self.checkRecvmsgAddress(addr, self.cli_addr) 2077 self.assertEqual(ancdata, []) 2078 self.checkFlags(flags, eor=True) 2079 2080 def _testRecvmsgShorter(self): 2081 self.sendToServer(MSG) 2082 2083 # FreeBSD < 8 doesn't always set the MSG_TRUNC flag when a truncated 2084 # datagram is received (issue #13001). 2085 @support.requires_freebsd_version(8) 2086 def testRecvmsgTrunc(self): 2087 # Receive part of message, check for truncation indicators. 2088 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2089 len(MSG) - 3) 2090 self.assertEqual(msg, MSG[:-3]) 2091 self.checkRecvmsgAddress(addr, self.cli_addr) 2092 self.assertEqual(ancdata, []) 2093 self.checkFlags(flags, eor=False) 2094 2095 @support.requires_freebsd_version(8) 2096 def _testRecvmsgTrunc(self): 2097 self.sendToServer(MSG) 2098 2099 def testRecvmsgShortAncillaryBuf(self): 2100 # Test ancillary data buffer too small to hold any ancillary data. 2101 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2102 len(MSG), 1) 2103 self.assertEqual(msg, MSG) 2104 self.checkRecvmsgAddress(addr, self.cli_addr) 2105 self.assertEqual(ancdata, []) 2106 self.checkFlags(flags, eor=True) 2107 2108 def _testRecvmsgShortAncillaryBuf(self): 2109 self.sendToServer(MSG) 2110 2111 def testRecvmsgLongAncillaryBuf(self): 2112 # Test large ancillary data buffer. 2113 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2114 len(MSG), 10240) 2115 self.assertEqual(msg, MSG) 2116 self.checkRecvmsgAddress(addr, self.cli_addr) 2117 self.assertEqual(ancdata, []) 2118 self.checkFlags(flags, eor=True) 2119 2120 def _testRecvmsgLongAncillaryBuf(self): 2121 self.sendToServer(MSG) 2122 2123 def testRecvmsgAfterClose(self): 2124 # Check that recvmsg[_into]() fails on a closed socket. 2125 self.serv_sock.close() 2126 self.assertRaises(OSError, self.doRecvmsg, self.serv_sock, 1024) 2127 2128 def _testRecvmsgAfterClose(self): 2129 pass 2130 2131 def testRecvmsgTimeout(self): 2132 # Check that timeout works. 2133 try: 2134 self.serv_sock.settimeout(0.03) 2135 self.assertRaises(socket.timeout, 2136 self.doRecvmsg, self.serv_sock, len(MSG)) 2137 finally: 2138 self.misc_event.set() 2139 2140 def _testRecvmsgTimeout(self): 2141 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 2142 2143 @requireAttrs(socket, "MSG_PEEK") 2144 def testRecvmsgPeek(self): 2145 # Check that MSG_PEEK in flags enables examination of pending 2146 # data without consuming it. 2147 2148 # Receive part of data with MSG_PEEK. 2149 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2150 len(MSG) - 3, 0, 2151 socket.MSG_PEEK) 2152 self.assertEqual(msg, MSG[:-3]) 2153 self.checkRecvmsgAddress(addr, self.cli_addr) 2154 self.assertEqual(ancdata, []) 2155 # Ignoring MSG_TRUNC here (so this test is the same for stream 2156 # and datagram sockets). Some wording in POSIX seems to 2157 # suggest that it needn't be set when peeking, but that may 2158 # just be a slip. 2159 self.checkFlags(flags, eor=False, 2160 ignore=getattr(socket, "MSG_TRUNC", 0)) 2161 2162 # Receive all data with MSG_PEEK. 2163 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2164 len(MSG), 0, 2165 socket.MSG_PEEK) 2166 self.assertEqual(msg, MSG) 2167 self.checkRecvmsgAddress(addr, self.cli_addr) 2168 self.assertEqual(ancdata, []) 2169 self.checkFlags(flags, eor=True) 2170 2171 # Check that the same data can still be received normally. 2172 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, len(MSG)) 2173 self.assertEqual(msg, MSG) 2174 self.checkRecvmsgAddress(addr, self.cli_addr) 2175 self.assertEqual(ancdata, []) 2176 self.checkFlags(flags, eor=True) 2177 2178 @testRecvmsgPeek.client_skip 2179 def _testRecvmsgPeek(self): 2180 self.sendToServer(MSG) 2181 2182 @requireAttrs(socket.socket, "sendmsg") 2183 def testRecvmsgFromSendmsg(self): 2184 # Test receiving with recvmsg[_into]() when message is sent 2185 # using sendmsg(). 2186 self.serv_sock.settimeout(self.fail_timeout) 2187 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, len(MSG)) 2188 self.assertEqual(msg, MSG) 2189 self.checkRecvmsgAddress(addr, self.cli_addr) 2190 self.assertEqual(ancdata, []) 2191 self.checkFlags(flags, eor=True) 2192 2193 @testRecvmsgFromSendmsg.client_skip 2194 def _testRecvmsgFromSendmsg(self): 2195 self.assertEqual(self.sendmsgToServer([MSG[:3], MSG[3:]]), len(MSG)) 2196 2197 2198class RecvmsgGenericStreamTests(RecvmsgGenericTests): 2199 # Tests which require a stream socket and can use either recvmsg() 2200 # or recvmsg_into(). 2201 2202 def testRecvmsgEOF(self): 2203 # Receive end-of-stream indicator (b"", peer socket closed). 2204 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 1024) 2205 self.assertEqual(msg, b"") 2206 self.checkRecvmsgAddress(addr, self.cli_addr) 2207 self.assertEqual(ancdata, []) 2208 self.checkFlags(flags, eor=None) # Might not have end-of-record marker 2209 2210 def _testRecvmsgEOF(self): 2211 self.cli_sock.close() 2212 2213 def testRecvmsgOverflow(self): 2214 # Receive a message in more than one chunk. 2215 seg1, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2216 len(MSG) - 3) 2217 self.checkRecvmsgAddress(addr, self.cli_addr) 2218 self.assertEqual(ancdata, []) 2219 self.checkFlags(flags, eor=False) 2220 2221 seg2, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 1024) 2222 self.checkRecvmsgAddress(addr, self.cli_addr) 2223 self.assertEqual(ancdata, []) 2224 self.checkFlags(flags, eor=True) 2225 2226 msg = seg1 + seg2 2227 self.assertEqual(msg, MSG) 2228 2229 def _testRecvmsgOverflow(self): 2230 self.sendToServer(MSG) 2231 2232 2233class RecvmsgTests(RecvmsgGenericTests): 2234 # Tests for recvmsg() which can use any socket type. 2235 2236 def testRecvmsgBadArgs(self): 2237 # Check that recvmsg() rejects invalid arguments. 2238 self.assertRaises(TypeError, self.serv_sock.recvmsg) 2239 self.assertRaises(ValueError, self.serv_sock.recvmsg, 2240 -1, 0, 0) 2241 self.assertRaises(ValueError, self.serv_sock.recvmsg, 2242 len(MSG), -1, 0) 2243 self.assertRaises(TypeError, self.serv_sock.recvmsg, 2244 [bytearray(10)], 0, 0) 2245 self.assertRaises(TypeError, self.serv_sock.recvmsg, 2246 object(), 0, 0) 2247 self.assertRaises(TypeError, self.serv_sock.recvmsg, 2248 len(MSG), object(), 0) 2249 self.assertRaises(TypeError, self.serv_sock.recvmsg, 2250 len(MSG), 0, object()) 2251 2252 msg, ancdata, flags, addr = self.serv_sock.recvmsg(len(MSG), 0, 0) 2253 self.assertEqual(msg, MSG) 2254 self.checkRecvmsgAddress(addr, self.cli_addr) 2255 self.assertEqual(ancdata, []) 2256 self.checkFlags(flags, eor=True) 2257 2258 def _testRecvmsgBadArgs(self): 2259 self.sendToServer(MSG) 2260 2261 2262class RecvmsgIntoTests(RecvmsgIntoMixin, RecvmsgGenericTests): 2263 # Tests for recvmsg_into() which can use any socket type. 2264 2265 def testRecvmsgIntoBadArgs(self): 2266 # Check that recvmsg_into() rejects invalid arguments. 2267 buf = bytearray(len(MSG)) 2268 self.assertRaises(TypeError, self.serv_sock.recvmsg_into) 2269 self.assertRaises(TypeError, self.serv_sock.recvmsg_into, 2270 len(MSG), 0, 0) 2271 self.assertRaises(TypeError, self.serv_sock.recvmsg_into, 2272 buf, 0, 0) 2273 self.assertRaises(TypeError, self.serv_sock.recvmsg_into, 2274 [object()], 0, 0) 2275 self.assertRaises(TypeError, self.serv_sock.recvmsg_into, 2276 [b"I'm not writable"], 0, 0) 2277 self.assertRaises(TypeError, self.serv_sock.recvmsg_into, 2278 [buf, object()], 0, 0) 2279 self.assertRaises(ValueError, self.serv_sock.recvmsg_into, 2280 [buf], -1, 0) 2281 self.assertRaises(TypeError, self.serv_sock.recvmsg_into, 2282 [buf], object(), 0) 2283 self.assertRaises(TypeError, self.serv_sock.recvmsg_into, 2284 [buf], 0, object()) 2285 2286 nbytes, ancdata, flags, addr = self.serv_sock.recvmsg_into([buf], 0, 0) 2287 self.assertEqual(nbytes, len(MSG)) 2288 self.assertEqual(buf, bytearray(MSG)) 2289 self.checkRecvmsgAddress(addr, self.cli_addr) 2290 self.assertEqual(ancdata, []) 2291 self.checkFlags(flags, eor=True) 2292 2293 def _testRecvmsgIntoBadArgs(self): 2294 self.sendToServer(MSG) 2295 2296 def testRecvmsgIntoGenerator(self): 2297 # Receive into buffer obtained from a generator (not a sequence). 2298 buf = bytearray(len(MSG)) 2299 nbytes, ancdata, flags, addr = self.serv_sock.recvmsg_into( 2300 (o for o in [buf])) 2301 self.assertEqual(nbytes, len(MSG)) 2302 self.assertEqual(buf, bytearray(MSG)) 2303 self.checkRecvmsgAddress(addr, self.cli_addr) 2304 self.assertEqual(ancdata, []) 2305 self.checkFlags(flags, eor=True) 2306 2307 def _testRecvmsgIntoGenerator(self): 2308 self.sendToServer(MSG) 2309 2310 def testRecvmsgIntoArray(self): 2311 # Receive into an array rather than the usual bytearray. 2312 buf = array.array("B", [0] * len(MSG)) 2313 nbytes, ancdata, flags, addr = self.serv_sock.recvmsg_into([buf]) 2314 self.assertEqual(nbytes, len(MSG)) 2315 self.assertEqual(buf.tobytes(), MSG) 2316 self.checkRecvmsgAddress(addr, self.cli_addr) 2317 self.assertEqual(ancdata, []) 2318 self.checkFlags(flags, eor=True) 2319 2320 def _testRecvmsgIntoArray(self): 2321 self.sendToServer(MSG) 2322 2323 def testRecvmsgIntoScatter(self): 2324 # Receive into multiple buffers (scatter write). 2325 b1 = bytearray(b"----") 2326 b2 = bytearray(b"0123456789") 2327 b3 = bytearray(b"--------------") 2328 nbytes, ancdata, flags, addr = self.serv_sock.recvmsg_into( 2329 [b1, memoryview(b2)[2:9], b3]) 2330 self.assertEqual(nbytes, len(b"Mary had a little lamb")) 2331 self.assertEqual(b1, bytearray(b"Mary")) 2332 self.assertEqual(b2, bytearray(b"01 had a 9")) 2333 self.assertEqual(b3, bytearray(b"little lamb---")) 2334 self.checkRecvmsgAddress(addr, self.cli_addr) 2335 self.assertEqual(ancdata, []) 2336 self.checkFlags(flags, eor=True) 2337 2338 def _testRecvmsgIntoScatter(self): 2339 self.sendToServer(b"Mary had a little lamb") 2340 2341 2342class CmsgMacroTests(unittest.TestCase): 2343 # Test the functions CMSG_LEN() and CMSG_SPACE(). Tests 2344 # assumptions used by sendmsg() and recvmsg[_into](), which share 2345 # code with these functions. 2346 2347 # Match the definition in socketmodule.c 2348 socklen_t_limit = min(0x7fffffff, _testcapi.INT_MAX) 2349 2350 @requireAttrs(socket, "CMSG_LEN") 2351 def testCMSG_LEN(self): 2352 # Test CMSG_LEN() with various valid and invalid values, 2353 # checking the assumptions used by recvmsg() and sendmsg(). 2354 toobig = self.socklen_t_limit - socket.CMSG_LEN(0) + 1 2355 values = list(range(257)) + list(range(toobig - 257, toobig)) 2356 2357 # struct cmsghdr has at least three members, two of which are ints 2358 self.assertGreater(socket.CMSG_LEN(0), array.array("i").itemsize * 2) 2359 for n in values: 2360 ret = socket.CMSG_LEN(n) 2361 # This is how recvmsg() calculates the data size 2362 self.assertEqual(ret - socket.CMSG_LEN(0), n) 2363 self.assertLessEqual(ret, self.socklen_t_limit) 2364 2365 self.assertRaises(OverflowError, socket.CMSG_LEN, -1) 2366 # sendmsg() shares code with these functions, and requires 2367 # that it reject values over the limit. 2368 self.assertRaises(OverflowError, socket.CMSG_LEN, toobig) 2369 self.assertRaises(OverflowError, socket.CMSG_LEN, sys.maxsize) 2370 2371 @requireAttrs(socket, "CMSG_SPACE") 2372 def testCMSG_SPACE(self): 2373 # Test CMSG_SPACE() with various valid and invalid values, 2374 # checking the assumptions used by sendmsg(). 2375 toobig = self.socklen_t_limit - socket.CMSG_SPACE(1) + 1 2376 values = list(range(257)) + list(range(toobig - 257, toobig)) 2377 2378 last = socket.CMSG_SPACE(0) 2379 # struct cmsghdr has at least three members, two of which are ints 2380 self.assertGreater(last, array.array("i").itemsize * 2) 2381 for n in values: 2382 ret = socket.CMSG_SPACE(n) 2383 self.assertGreaterEqual(ret, last) 2384 self.assertGreaterEqual(ret, socket.CMSG_LEN(n)) 2385 self.assertGreaterEqual(ret, n + socket.CMSG_LEN(0)) 2386 self.assertLessEqual(ret, self.socklen_t_limit) 2387 last = ret 2388 2389 self.assertRaises(OverflowError, socket.CMSG_SPACE, -1) 2390 # sendmsg() shares code with these functions, and requires 2391 # that it reject values over the limit. 2392 self.assertRaises(OverflowError, socket.CMSG_SPACE, toobig) 2393 self.assertRaises(OverflowError, socket.CMSG_SPACE, sys.maxsize) 2394 2395 2396class SCMRightsTest(SendrecvmsgServerTimeoutBase): 2397 # Tests for file descriptor passing on Unix-domain sockets. 2398 2399 # Invalid file descriptor value that's unlikely to evaluate to a 2400 # real FD even if one of its bytes is replaced with a different 2401 # value (which shouldn't actually happen). 2402 badfd = -0x5555 2403 2404 def newFDs(self, n): 2405 # Return a list of n file descriptors for newly-created files 2406 # containing their list indices as ASCII numbers. 2407 fds = [] 2408 for i in range(n): 2409 fd, path = tempfile.mkstemp() 2410 self.addCleanup(os.unlink, path) 2411 self.addCleanup(os.close, fd) 2412 os.write(fd, str(i).encode()) 2413 fds.append(fd) 2414 return fds 2415 2416 def checkFDs(self, fds): 2417 # Check that the file descriptors in the given list contain 2418 # their correct list indices as ASCII numbers. 2419 for n, fd in enumerate(fds): 2420 os.lseek(fd, 0, os.SEEK_SET) 2421 self.assertEqual(os.read(fd, 1024), str(n).encode()) 2422 2423 def registerRecvmsgResult(self, result): 2424 self.addCleanup(self.closeRecvmsgFDs, result) 2425 2426 def closeRecvmsgFDs(self, recvmsg_result): 2427 # Close all file descriptors specified in the ancillary data 2428 # of the given return value from recvmsg() or recvmsg_into(). 2429 for cmsg_level, cmsg_type, cmsg_data in recvmsg_result[1]: 2430 if (cmsg_level == socket.SOL_SOCKET and 2431 cmsg_type == socket.SCM_RIGHTS): 2432 fds = array.array("i") 2433 fds.frombytes(cmsg_data[: 2434 len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) 2435 for fd in fds: 2436 os.close(fd) 2437 2438 def createAndSendFDs(self, n): 2439 # Send n new file descriptors created by newFDs() to the 2440 # server, with the constant MSG as the non-ancillary data. 2441 self.assertEqual( 2442 self.sendmsgToServer([MSG], 2443 [(socket.SOL_SOCKET, 2444 socket.SCM_RIGHTS, 2445 array.array("i", self.newFDs(n)))]), 2446 len(MSG)) 2447 2448 def checkRecvmsgFDs(self, numfds, result, maxcmsgs=1, ignoreflags=0): 2449 # Check that constant MSG was received with numfds file 2450 # descriptors in a maximum of maxcmsgs control messages (which 2451 # must contain only complete integers). By default, check 2452 # that MSG_CTRUNC is unset, but ignore any flags in 2453 # ignoreflags. 2454 msg, ancdata, flags, addr = result 2455 self.assertEqual(msg, MSG) 2456 self.checkRecvmsgAddress(addr, self.cli_addr) 2457 self.checkFlags(flags, eor=True, checkunset=socket.MSG_CTRUNC, 2458 ignore=ignoreflags) 2459 2460 self.assertIsInstance(ancdata, list) 2461 self.assertLessEqual(len(ancdata), maxcmsgs) 2462 fds = array.array("i") 2463 for item in ancdata: 2464 self.assertIsInstance(item, tuple) 2465 cmsg_level, cmsg_type, cmsg_data = item 2466 self.assertEqual(cmsg_level, socket.SOL_SOCKET) 2467 self.assertEqual(cmsg_type, socket.SCM_RIGHTS) 2468 self.assertIsInstance(cmsg_data, bytes) 2469 self.assertEqual(len(cmsg_data) % SIZEOF_INT, 0) 2470 fds.frombytes(cmsg_data) 2471 2472 self.assertEqual(len(fds), numfds) 2473 self.checkFDs(fds) 2474 2475 def testFDPassSimple(self): 2476 # Pass a single FD (array read from bytes object). 2477 self.checkRecvmsgFDs(1, self.doRecvmsg(self.serv_sock, 2478 len(MSG), 10240)) 2479 2480 def _testFDPassSimple(self): 2481 self.assertEqual( 2482 self.sendmsgToServer( 2483 [MSG], 2484 [(socket.SOL_SOCKET, 2485 socket.SCM_RIGHTS, 2486 array.array("i", self.newFDs(1)).tobytes())]), 2487 len(MSG)) 2488 2489 def testMultipleFDPass(self): 2490 # Pass multiple FDs in a single array. 2491 self.checkRecvmsgFDs(4, self.doRecvmsg(self.serv_sock, 2492 len(MSG), 10240)) 2493 2494 def _testMultipleFDPass(self): 2495 self.createAndSendFDs(4) 2496 2497 @requireAttrs(socket, "CMSG_SPACE") 2498 def testFDPassCMSG_SPACE(self): 2499 # Test using CMSG_SPACE() to calculate ancillary buffer size. 2500 self.checkRecvmsgFDs( 2501 4, self.doRecvmsg(self.serv_sock, len(MSG), 2502 socket.CMSG_SPACE(4 * SIZEOF_INT))) 2503 2504 @testFDPassCMSG_SPACE.client_skip 2505 def _testFDPassCMSG_SPACE(self): 2506 self.createAndSendFDs(4) 2507 2508 def testFDPassCMSG_LEN(self): 2509 # Test using CMSG_LEN() to calculate ancillary buffer size. 2510 self.checkRecvmsgFDs(1, 2511 self.doRecvmsg(self.serv_sock, len(MSG), 2512 socket.CMSG_LEN(4 * SIZEOF_INT)), 2513 # RFC 3542 says implementations may set 2514 # MSG_CTRUNC if there isn't enough space 2515 # for trailing padding. 2516 ignoreflags=socket.MSG_CTRUNC) 2517 2518 def _testFDPassCMSG_LEN(self): 2519 self.createAndSendFDs(1) 2520 2521 # Issue #12958: The following test has problems on Mac OS X 2522 @support.anticipate_failure(sys.platform == "darwin") 2523 @requireAttrs(socket, "CMSG_SPACE") 2524 def testFDPassSeparate(self): 2525 # Pass two FDs in two separate arrays. Arrays may be combined 2526 # into a single control message by the OS. 2527 self.checkRecvmsgFDs(2, 2528 self.doRecvmsg(self.serv_sock, len(MSG), 10240), 2529 maxcmsgs=2) 2530 2531 @testFDPassSeparate.client_skip 2532 @support.anticipate_failure(sys.platform == "darwin") 2533 def _testFDPassSeparate(self): 2534 fd0, fd1 = self.newFDs(2) 2535 self.assertEqual( 2536 self.sendmsgToServer([MSG], [(socket.SOL_SOCKET, 2537 socket.SCM_RIGHTS, 2538 array.array("i", [fd0])), 2539 (socket.SOL_SOCKET, 2540 socket.SCM_RIGHTS, 2541 array.array("i", [fd1]))]), 2542 len(MSG)) 2543 2544 # Issue #12958: The following test has problems on Mac OS X 2545 @support.anticipate_failure(sys.platform == "darwin") 2546 @requireAttrs(socket, "CMSG_SPACE") 2547 def testFDPassSeparateMinSpace(self): 2548 # Pass two FDs in two separate arrays, receiving them into the 2549 # minimum space for two arrays. 2550 self.checkRecvmsgFDs(2, 2551 self.doRecvmsg(self.serv_sock, len(MSG), 2552 socket.CMSG_SPACE(SIZEOF_INT) + 2553 socket.CMSG_LEN(SIZEOF_INT)), 2554 maxcmsgs=2, ignoreflags=socket.MSG_CTRUNC) 2555 2556 @testFDPassSeparateMinSpace.client_skip 2557 @support.anticipate_failure(sys.platform == "darwin") 2558 def _testFDPassSeparateMinSpace(self): 2559 fd0, fd1 = self.newFDs(2) 2560 self.assertEqual( 2561 self.sendmsgToServer([MSG], [(socket.SOL_SOCKET, 2562 socket.SCM_RIGHTS, 2563 array.array("i", [fd0])), 2564 (socket.SOL_SOCKET, 2565 socket.SCM_RIGHTS, 2566 array.array("i", [fd1]))]), 2567 len(MSG)) 2568 2569 def sendAncillaryIfPossible(self, msg, ancdata): 2570 # Try to send msg and ancdata to server, but if the system 2571 # call fails, just send msg with no ancillary data. 2572 try: 2573 nbytes = self.sendmsgToServer([msg], ancdata) 2574 except OSError as e: 2575 # Check that it was the system call that failed 2576 self.assertIsInstance(e.errno, int) 2577 nbytes = self.sendmsgToServer([msg]) 2578 self.assertEqual(nbytes, len(msg)) 2579 2580 def testFDPassEmpty(self): 2581 # Try to pass an empty FD array. Can receive either no array 2582 # or an empty array. 2583 self.checkRecvmsgFDs(0, self.doRecvmsg(self.serv_sock, 2584 len(MSG), 10240), 2585 ignoreflags=socket.MSG_CTRUNC) 2586 2587 def _testFDPassEmpty(self): 2588 self.sendAncillaryIfPossible(MSG, [(socket.SOL_SOCKET, 2589 socket.SCM_RIGHTS, 2590 b"")]) 2591 2592 def testFDPassPartialInt(self): 2593 # Try to pass a truncated FD array. 2594 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2595 len(MSG), 10240) 2596 self.assertEqual(msg, MSG) 2597 self.checkRecvmsgAddress(addr, self.cli_addr) 2598 self.checkFlags(flags, eor=True, ignore=socket.MSG_CTRUNC) 2599 self.assertLessEqual(len(ancdata), 1) 2600 for cmsg_level, cmsg_type, cmsg_data in ancdata: 2601 self.assertEqual(cmsg_level, socket.SOL_SOCKET) 2602 self.assertEqual(cmsg_type, socket.SCM_RIGHTS) 2603 self.assertLess(len(cmsg_data), SIZEOF_INT) 2604 2605 def _testFDPassPartialInt(self): 2606 self.sendAncillaryIfPossible( 2607 MSG, 2608 [(socket.SOL_SOCKET, 2609 socket.SCM_RIGHTS, 2610 array.array("i", [self.badfd]).tobytes()[:-1])]) 2611 2612 @requireAttrs(socket, "CMSG_SPACE") 2613 def testFDPassPartialIntInMiddle(self): 2614 # Try to pass two FD arrays, the first of which is truncated. 2615 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2616 len(MSG), 10240) 2617 self.assertEqual(msg, MSG) 2618 self.checkRecvmsgAddress(addr, self.cli_addr) 2619 self.checkFlags(flags, eor=True, ignore=socket.MSG_CTRUNC) 2620 self.assertLessEqual(len(ancdata), 2) 2621 fds = array.array("i") 2622 # Arrays may have been combined in a single control message 2623 for cmsg_level, cmsg_type, cmsg_data in ancdata: 2624 self.assertEqual(cmsg_level, socket.SOL_SOCKET) 2625 self.assertEqual(cmsg_type, socket.SCM_RIGHTS) 2626 fds.frombytes(cmsg_data[: 2627 len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) 2628 self.assertLessEqual(len(fds), 2) 2629 self.checkFDs(fds) 2630 2631 @testFDPassPartialIntInMiddle.client_skip 2632 def _testFDPassPartialIntInMiddle(self): 2633 fd0, fd1 = self.newFDs(2) 2634 self.sendAncillaryIfPossible( 2635 MSG, 2636 [(socket.SOL_SOCKET, 2637 socket.SCM_RIGHTS, 2638 array.array("i", [fd0, self.badfd]).tobytes()[:-1]), 2639 (socket.SOL_SOCKET, 2640 socket.SCM_RIGHTS, 2641 array.array("i", [fd1]))]) 2642 2643 def checkTruncatedHeader(self, result, ignoreflags=0): 2644 # Check that no ancillary data items are returned when data is 2645 # truncated inside the cmsghdr structure. 2646 msg, ancdata, flags, addr = result 2647 self.assertEqual(msg, MSG) 2648 self.checkRecvmsgAddress(addr, self.cli_addr) 2649 self.assertEqual(ancdata, []) 2650 self.checkFlags(flags, eor=True, checkset=socket.MSG_CTRUNC, 2651 ignore=ignoreflags) 2652 2653 def testCmsgTruncNoBufSize(self): 2654 # Check that no ancillary data is received when no buffer size 2655 # is specified. 2656 self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG)), 2657 # BSD seems to set MSG_CTRUNC only 2658 # if an item has been partially 2659 # received. 2660 ignoreflags=socket.MSG_CTRUNC) 2661 2662 def _testCmsgTruncNoBufSize(self): 2663 self.createAndSendFDs(1) 2664 2665 def testCmsgTrunc0(self): 2666 # Check that no ancillary data is received when buffer size is 0. 2667 self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG), 0), 2668 ignoreflags=socket.MSG_CTRUNC) 2669 2670 def _testCmsgTrunc0(self): 2671 self.createAndSendFDs(1) 2672 2673 # Check that no ancillary data is returned for various non-zero 2674 # (but still too small) buffer sizes. 2675 2676 def testCmsgTrunc1(self): 2677 self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG), 1)) 2678 2679 def _testCmsgTrunc1(self): 2680 self.createAndSendFDs(1) 2681 2682 def testCmsgTrunc2Int(self): 2683 # The cmsghdr structure has at least three members, two of 2684 # which are ints, so we still shouldn't see any ancillary 2685 # data. 2686 self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG), 2687 SIZEOF_INT * 2)) 2688 2689 def _testCmsgTrunc2Int(self): 2690 self.createAndSendFDs(1) 2691 2692 def testCmsgTruncLen0Minus1(self): 2693 self.checkTruncatedHeader(self.doRecvmsg(self.serv_sock, len(MSG), 2694 socket.CMSG_LEN(0) - 1)) 2695 2696 def _testCmsgTruncLen0Minus1(self): 2697 self.createAndSendFDs(1) 2698 2699 # The following tests try to truncate the control message in the 2700 # middle of the FD array. 2701 2702 def checkTruncatedArray(self, ancbuf, maxdata, mindata=0): 2703 # Check that file descriptor data is truncated to between 2704 # mindata and maxdata bytes when received with buffer size 2705 # ancbuf, and that any complete file descriptor numbers are 2706 # valid. 2707 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2708 len(MSG), ancbuf) 2709 self.assertEqual(msg, MSG) 2710 self.checkRecvmsgAddress(addr, self.cli_addr) 2711 self.checkFlags(flags, eor=True, checkset=socket.MSG_CTRUNC) 2712 2713 if mindata == 0 and ancdata == []: 2714 return 2715 self.assertEqual(len(ancdata), 1) 2716 cmsg_level, cmsg_type, cmsg_data = ancdata[0] 2717 self.assertEqual(cmsg_level, socket.SOL_SOCKET) 2718 self.assertEqual(cmsg_type, socket.SCM_RIGHTS) 2719 self.assertGreaterEqual(len(cmsg_data), mindata) 2720 self.assertLessEqual(len(cmsg_data), maxdata) 2721 fds = array.array("i") 2722 fds.frombytes(cmsg_data[: 2723 len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) 2724 self.checkFDs(fds) 2725 2726 def testCmsgTruncLen0(self): 2727 self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(0), maxdata=0) 2728 2729 def _testCmsgTruncLen0(self): 2730 self.createAndSendFDs(1) 2731 2732 def testCmsgTruncLen0Plus1(self): 2733 self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(0) + 1, maxdata=1) 2734 2735 def _testCmsgTruncLen0Plus1(self): 2736 self.createAndSendFDs(2) 2737 2738 def testCmsgTruncLen1(self): 2739 self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(SIZEOF_INT), 2740 maxdata=SIZEOF_INT) 2741 2742 def _testCmsgTruncLen1(self): 2743 self.createAndSendFDs(2) 2744 2745 def testCmsgTruncLen2Minus1(self): 2746 self.checkTruncatedArray(ancbuf=socket.CMSG_LEN(2 * SIZEOF_INT) - 1, 2747 maxdata=(2 * SIZEOF_INT) - 1) 2748 2749 def _testCmsgTruncLen2Minus1(self): 2750 self.createAndSendFDs(2) 2751 2752 2753class RFC3542AncillaryTest(SendrecvmsgServerTimeoutBase): 2754 # Test sendmsg() and recvmsg[_into]() using the ancillary data 2755 # features of the RFC 3542 Advanced Sockets API for IPv6. 2756 # Currently we can only handle certain data items (e.g. traffic 2757 # class, hop limit, MTU discovery and fragmentation settings) 2758 # without resorting to unportable means such as the struct module, 2759 # but the tests here are aimed at testing the ancillary data 2760 # handling in sendmsg() and recvmsg() rather than the IPv6 API 2761 # itself. 2762 2763 # Test value to use when setting hop limit of packet 2764 hop_limit = 2 2765 2766 # Test value to use when setting traffic class of packet. 2767 # -1 means "use kernel default". 2768 traffic_class = -1 2769 2770 def ancillaryMapping(self, ancdata): 2771 # Given ancillary data list ancdata, return a mapping from 2772 # pairs (cmsg_level, cmsg_type) to corresponding cmsg_data. 2773 # Check that no (level, type) pair appears more than once. 2774 d = {} 2775 for cmsg_level, cmsg_type, cmsg_data in ancdata: 2776 self.assertNotIn((cmsg_level, cmsg_type), d) 2777 d[(cmsg_level, cmsg_type)] = cmsg_data 2778 return d 2779 2780 def checkHopLimit(self, ancbufsize, maxhop=255, ignoreflags=0): 2781 # Receive hop limit into ancbufsize bytes of ancillary data 2782 # space. Check that data is MSG, ancillary data is not 2783 # truncated (but ignore any flags in ignoreflags), and hop 2784 # limit is between 0 and maxhop inclusive. 2785 self.serv_sock.setsockopt(socket.IPPROTO_IPV6, 2786 socket.IPV6_RECVHOPLIMIT, 1) 2787 self.misc_event.set() 2788 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2789 len(MSG), ancbufsize) 2790 2791 self.assertEqual(msg, MSG) 2792 self.checkRecvmsgAddress(addr, self.cli_addr) 2793 self.checkFlags(flags, eor=True, checkunset=socket.MSG_CTRUNC, 2794 ignore=ignoreflags) 2795 2796 self.assertEqual(len(ancdata), 1) 2797 self.assertIsInstance(ancdata[0], tuple) 2798 cmsg_level, cmsg_type, cmsg_data = ancdata[0] 2799 self.assertEqual(cmsg_level, socket.IPPROTO_IPV6) 2800 self.assertEqual(cmsg_type, socket.IPV6_HOPLIMIT) 2801 self.assertIsInstance(cmsg_data, bytes) 2802 self.assertEqual(len(cmsg_data), SIZEOF_INT) 2803 a = array.array("i") 2804 a.frombytes(cmsg_data) 2805 self.assertGreaterEqual(a[0], 0) 2806 self.assertLessEqual(a[0], maxhop) 2807 2808 @requireAttrs(socket, "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT") 2809 def testRecvHopLimit(self): 2810 # Test receiving the packet hop limit as ancillary data. 2811 self.checkHopLimit(ancbufsize=10240) 2812 2813 @testRecvHopLimit.client_skip 2814 def _testRecvHopLimit(self): 2815 # Need to wait until server has asked to receive ancillary 2816 # data, as implementations are not required to buffer it 2817 # otherwise. 2818 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 2819 self.sendToServer(MSG) 2820 2821 @requireAttrs(socket, "CMSG_SPACE", "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT") 2822 def testRecvHopLimitCMSG_SPACE(self): 2823 # Test receiving hop limit, using CMSG_SPACE to calculate buffer size. 2824 self.checkHopLimit(ancbufsize=socket.CMSG_SPACE(SIZEOF_INT)) 2825 2826 @testRecvHopLimitCMSG_SPACE.client_skip 2827 def _testRecvHopLimitCMSG_SPACE(self): 2828 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 2829 self.sendToServer(MSG) 2830 2831 # Could test receiving into buffer sized using CMSG_LEN, but RFC 2832 # 3542 says portable applications must provide space for trailing 2833 # padding. Implementations may set MSG_CTRUNC if there isn't 2834 # enough space for the padding. 2835 2836 @requireAttrs(socket.socket, "sendmsg") 2837 @requireAttrs(socket, "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT") 2838 def testSetHopLimit(self): 2839 # Test setting hop limit on outgoing packet and receiving it 2840 # at the other end. 2841 self.checkHopLimit(ancbufsize=10240, maxhop=self.hop_limit) 2842 2843 @testSetHopLimit.client_skip 2844 def _testSetHopLimit(self): 2845 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 2846 self.assertEqual( 2847 self.sendmsgToServer([MSG], 2848 [(socket.IPPROTO_IPV6, socket.IPV6_HOPLIMIT, 2849 array.array("i", [self.hop_limit]))]), 2850 len(MSG)) 2851 2852 def checkTrafficClassAndHopLimit(self, ancbufsize, maxhop=255, 2853 ignoreflags=0): 2854 # Receive traffic class and hop limit into ancbufsize bytes of 2855 # ancillary data space. Check that data is MSG, ancillary 2856 # data is not truncated (but ignore any flags in ignoreflags), 2857 # and traffic class and hop limit are in range (hop limit no 2858 # more than maxhop). 2859 self.serv_sock.setsockopt(socket.IPPROTO_IPV6, 2860 socket.IPV6_RECVHOPLIMIT, 1) 2861 self.serv_sock.setsockopt(socket.IPPROTO_IPV6, 2862 socket.IPV6_RECVTCLASS, 1) 2863 self.misc_event.set() 2864 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2865 len(MSG), ancbufsize) 2866 2867 self.assertEqual(msg, MSG) 2868 self.checkRecvmsgAddress(addr, self.cli_addr) 2869 self.checkFlags(flags, eor=True, checkunset=socket.MSG_CTRUNC, 2870 ignore=ignoreflags) 2871 self.assertEqual(len(ancdata), 2) 2872 ancmap = self.ancillaryMapping(ancdata) 2873 2874 tcdata = ancmap[(socket.IPPROTO_IPV6, socket.IPV6_TCLASS)] 2875 self.assertEqual(len(tcdata), SIZEOF_INT) 2876 a = array.array("i") 2877 a.frombytes(tcdata) 2878 self.assertGreaterEqual(a[0], 0) 2879 self.assertLessEqual(a[0], 255) 2880 2881 hldata = ancmap[(socket.IPPROTO_IPV6, socket.IPV6_HOPLIMIT)] 2882 self.assertEqual(len(hldata), SIZEOF_INT) 2883 a = array.array("i") 2884 a.frombytes(hldata) 2885 self.assertGreaterEqual(a[0], 0) 2886 self.assertLessEqual(a[0], maxhop) 2887 2888 @requireAttrs(socket, "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT", 2889 "IPV6_RECVTCLASS", "IPV6_TCLASS") 2890 def testRecvTrafficClassAndHopLimit(self): 2891 # Test receiving traffic class and hop limit as ancillary data. 2892 self.checkTrafficClassAndHopLimit(ancbufsize=10240) 2893 2894 @testRecvTrafficClassAndHopLimit.client_skip 2895 def _testRecvTrafficClassAndHopLimit(self): 2896 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 2897 self.sendToServer(MSG) 2898 2899 @requireAttrs(socket, "CMSG_SPACE", "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT", 2900 "IPV6_RECVTCLASS", "IPV6_TCLASS") 2901 def testRecvTrafficClassAndHopLimitCMSG_SPACE(self): 2902 # Test receiving traffic class and hop limit, using 2903 # CMSG_SPACE() to calculate buffer size. 2904 self.checkTrafficClassAndHopLimit( 2905 ancbufsize=socket.CMSG_SPACE(SIZEOF_INT) * 2) 2906 2907 @testRecvTrafficClassAndHopLimitCMSG_SPACE.client_skip 2908 def _testRecvTrafficClassAndHopLimitCMSG_SPACE(self): 2909 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 2910 self.sendToServer(MSG) 2911 2912 @requireAttrs(socket.socket, "sendmsg") 2913 @requireAttrs(socket, "CMSG_SPACE", "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT", 2914 "IPV6_RECVTCLASS", "IPV6_TCLASS") 2915 def testSetTrafficClassAndHopLimit(self): 2916 # Test setting traffic class and hop limit on outgoing packet, 2917 # and receiving them at the other end. 2918 self.checkTrafficClassAndHopLimit(ancbufsize=10240, 2919 maxhop=self.hop_limit) 2920 2921 @testSetTrafficClassAndHopLimit.client_skip 2922 def _testSetTrafficClassAndHopLimit(self): 2923 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 2924 self.assertEqual( 2925 self.sendmsgToServer([MSG], 2926 [(socket.IPPROTO_IPV6, socket.IPV6_TCLASS, 2927 array.array("i", [self.traffic_class])), 2928 (socket.IPPROTO_IPV6, socket.IPV6_HOPLIMIT, 2929 array.array("i", [self.hop_limit]))]), 2930 len(MSG)) 2931 2932 @requireAttrs(socket.socket, "sendmsg") 2933 @requireAttrs(socket, "CMSG_SPACE", "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT", 2934 "IPV6_RECVTCLASS", "IPV6_TCLASS") 2935 def testOddCmsgSize(self): 2936 # Try to send ancillary data with first item one byte too 2937 # long. Fall back to sending with correct size if this fails, 2938 # and check that second item was handled correctly. 2939 self.checkTrafficClassAndHopLimit(ancbufsize=10240, 2940 maxhop=self.hop_limit) 2941 2942 @testOddCmsgSize.client_skip 2943 def _testOddCmsgSize(self): 2944 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 2945 try: 2946 nbytes = self.sendmsgToServer( 2947 [MSG], 2948 [(socket.IPPROTO_IPV6, socket.IPV6_TCLASS, 2949 array.array("i", [self.traffic_class]).tobytes() + b"\x00"), 2950 (socket.IPPROTO_IPV6, socket.IPV6_HOPLIMIT, 2951 array.array("i", [self.hop_limit]))]) 2952 except OSError as e: 2953 self.assertIsInstance(e.errno, int) 2954 nbytes = self.sendmsgToServer( 2955 [MSG], 2956 [(socket.IPPROTO_IPV6, socket.IPV6_TCLASS, 2957 array.array("i", [self.traffic_class])), 2958 (socket.IPPROTO_IPV6, socket.IPV6_HOPLIMIT, 2959 array.array("i", [self.hop_limit]))]) 2960 self.assertEqual(nbytes, len(MSG)) 2961 2962 # Tests for proper handling of truncated ancillary data 2963 2964 def checkHopLimitTruncatedHeader(self, ancbufsize, ignoreflags=0): 2965 # Receive hop limit into ancbufsize bytes of ancillary data 2966 # space, which should be too small to contain the ancillary 2967 # data header (if ancbufsize is None, pass no second argument 2968 # to recvmsg()). Check that data is MSG, MSG_CTRUNC is set 2969 # (unless included in ignoreflags), and no ancillary data is 2970 # returned. 2971 self.serv_sock.setsockopt(socket.IPPROTO_IPV6, 2972 socket.IPV6_RECVHOPLIMIT, 1) 2973 self.misc_event.set() 2974 args = () if ancbufsize is None else (ancbufsize,) 2975 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 2976 len(MSG), *args) 2977 2978 self.assertEqual(msg, MSG) 2979 self.checkRecvmsgAddress(addr, self.cli_addr) 2980 self.assertEqual(ancdata, []) 2981 self.checkFlags(flags, eor=True, checkset=socket.MSG_CTRUNC, 2982 ignore=ignoreflags) 2983 2984 @requireAttrs(socket, "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT") 2985 def testCmsgTruncNoBufSize(self): 2986 # Check that no ancillary data is received when no ancillary 2987 # buffer size is provided. 2988 self.checkHopLimitTruncatedHeader(ancbufsize=None, 2989 # BSD seems to set 2990 # MSG_CTRUNC only if an item 2991 # has been partially 2992 # received. 2993 ignoreflags=socket.MSG_CTRUNC) 2994 2995 @testCmsgTruncNoBufSize.client_skip 2996 def _testCmsgTruncNoBufSize(self): 2997 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 2998 self.sendToServer(MSG) 2999 3000 @requireAttrs(socket, "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT") 3001 def testSingleCmsgTrunc0(self): 3002 # Check that no ancillary data is received when ancillary 3003 # buffer size is zero. 3004 self.checkHopLimitTruncatedHeader(ancbufsize=0, 3005 ignoreflags=socket.MSG_CTRUNC) 3006 3007 @testSingleCmsgTrunc0.client_skip 3008 def _testSingleCmsgTrunc0(self): 3009 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 3010 self.sendToServer(MSG) 3011 3012 # Check that no ancillary data is returned for various non-zero 3013 # (but still too small) buffer sizes. 3014 3015 @requireAttrs(socket, "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT") 3016 def testSingleCmsgTrunc1(self): 3017 self.checkHopLimitTruncatedHeader(ancbufsize=1) 3018 3019 @testSingleCmsgTrunc1.client_skip 3020 def _testSingleCmsgTrunc1(self): 3021 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 3022 self.sendToServer(MSG) 3023 3024 @requireAttrs(socket, "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT") 3025 def testSingleCmsgTrunc2Int(self): 3026 self.checkHopLimitTruncatedHeader(ancbufsize=2 * SIZEOF_INT) 3027 3028 @testSingleCmsgTrunc2Int.client_skip 3029 def _testSingleCmsgTrunc2Int(self): 3030 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 3031 self.sendToServer(MSG) 3032 3033 @requireAttrs(socket, "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT") 3034 def testSingleCmsgTruncLen0Minus1(self): 3035 self.checkHopLimitTruncatedHeader(ancbufsize=socket.CMSG_LEN(0) - 1) 3036 3037 @testSingleCmsgTruncLen0Minus1.client_skip 3038 def _testSingleCmsgTruncLen0Minus1(self): 3039 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 3040 self.sendToServer(MSG) 3041 3042 @requireAttrs(socket, "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT") 3043 def testSingleCmsgTruncInData(self): 3044 # Test truncation of a control message inside its associated 3045 # data. The message may be returned with its data truncated, 3046 # or not returned at all. 3047 self.serv_sock.setsockopt(socket.IPPROTO_IPV6, 3048 socket.IPV6_RECVHOPLIMIT, 1) 3049 self.misc_event.set() 3050 msg, ancdata, flags, addr = self.doRecvmsg( 3051 self.serv_sock, len(MSG), socket.CMSG_LEN(SIZEOF_INT) - 1) 3052 3053 self.assertEqual(msg, MSG) 3054 self.checkRecvmsgAddress(addr, self.cli_addr) 3055 self.checkFlags(flags, eor=True, checkset=socket.MSG_CTRUNC) 3056 3057 self.assertLessEqual(len(ancdata), 1) 3058 if ancdata: 3059 cmsg_level, cmsg_type, cmsg_data = ancdata[0] 3060 self.assertEqual(cmsg_level, socket.IPPROTO_IPV6) 3061 self.assertEqual(cmsg_type, socket.IPV6_HOPLIMIT) 3062 self.assertLess(len(cmsg_data), SIZEOF_INT) 3063 3064 @testSingleCmsgTruncInData.client_skip 3065 def _testSingleCmsgTruncInData(self): 3066 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 3067 self.sendToServer(MSG) 3068 3069 def checkTruncatedSecondHeader(self, ancbufsize, ignoreflags=0): 3070 # Receive traffic class and hop limit into ancbufsize bytes of 3071 # ancillary data space, which should be large enough to 3072 # contain the first item, but too small to contain the header 3073 # of the second. Check that data is MSG, MSG_CTRUNC is set 3074 # (unless included in ignoreflags), and only one ancillary 3075 # data item is returned. 3076 self.serv_sock.setsockopt(socket.IPPROTO_IPV6, 3077 socket.IPV6_RECVHOPLIMIT, 1) 3078 self.serv_sock.setsockopt(socket.IPPROTO_IPV6, 3079 socket.IPV6_RECVTCLASS, 1) 3080 self.misc_event.set() 3081 msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 3082 len(MSG), ancbufsize) 3083 3084 self.assertEqual(msg, MSG) 3085 self.checkRecvmsgAddress(addr, self.cli_addr) 3086 self.checkFlags(flags, eor=True, checkset=socket.MSG_CTRUNC, 3087 ignore=ignoreflags) 3088 3089 self.assertEqual(len(ancdata), 1) 3090 cmsg_level, cmsg_type, cmsg_data = ancdata[0] 3091 self.assertEqual(cmsg_level, socket.IPPROTO_IPV6) 3092 self.assertIn(cmsg_type, {socket.IPV6_TCLASS, socket.IPV6_HOPLIMIT}) 3093 self.assertEqual(len(cmsg_data), SIZEOF_INT) 3094 a = array.array("i") 3095 a.frombytes(cmsg_data) 3096 self.assertGreaterEqual(a[0], 0) 3097 self.assertLessEqual(a[0], 255) 3098 3099 # Try the above test with various buffer sizes. 3100 3101 @requireAttrs(socket, "CMSG_SPACE", "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT", 3102 "IPV6_RECVTCLASS", "IPV6_TCLASS") 3103 def testSecondCmsgTrunc0(self): 3104 self.checkTruncatedSecondHeader(socket.CMSG_SPACE(SIZEOF_INT), 3105 ignoreflags=socket.MSG_CTRUNC) 3106 3107 @testSecondCmsgTrunc0.client_skip 3108 def _testSecondCmsgTrunc0(self): 3109 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 3110 self.sendToServer(MSG) 3111 3112 @requireAttrs(socket, "CMSG_SPACE", "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT", 3113 "IPV6_RECVTCLASS", "IPV6_TCLASS") 3114 def testSecondCmsgTrunc1(self): 3115 self.checkTruncatedSecondHeader(socket.CMSG_SPACE(SIZEOF_INT) + 1) 3116 3117 @testSecondCmsgTrunc1.client_skip 3118 def _testSecondCmsgTrunc1(self): 3119 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 3120 self.sendToServer(MSG) 3121 3122 @requireAttrs(socket, "CMSG_SPACE", "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT", 3123 "IPV6_RECVTCLASS", "IPV6_TCLASS") 3124 def testSecondCmsgTrunc2Int(self): 3125 self.checkTruncatedSecondHeader(socket.CMSG_SPACE(SIZEOF_INT) + 3126 2 * SIZEOF_INT) 3127 3128 @testSecondCmsgTrunc2Int.client_skip 3129 def _testSecondCmsgTrunc2Int(self): 3130 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 3131 self.sendToServer(MSG) 3132 3133 @requireAttrs(socket, "CMSG_SPACE", "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT", 3134 "IPV6_RECVTCLASS", "IPV6_TCLASS") 3135 def testSecondCmsgTruncLen0Minus1(self): 3136 self.checkTruncatedSecondHeader(socket.CMSG_SPACE(SIZEOF_INT) + 3137 socket.CMSG_LEN(0) - 1) 3138 3139 @testSecondCmsgTruncLen0Minus1.client_skip 3140 def _testSecondCmsgTruncLen0Minus1(self): 3141 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 3142 self.sendToServer(MSG) 3143 3144 @requireAttrs(socket, "CMSG_SPACE", "IPV6_RECVHOPLIMIT", "IPV6_HOPLIMIT", 3145 "IPV6_RECVTCLASS", "IPV6_TCLASS") 3146 def testSecomdCmsgTruncInData(self): 3147 # Test truncation of the second of two control messages inside 3148 # its associated data. 3149 self.serv_sock.setsockopt(socket.IPPROTO_IPV6, 3150 socket.IPV6_RECVHOPLIMIT, 1) 3151 self.serv_sock.setsockopt(socket.IPPROTO_IPV6, 3152 socket.IPV6_RECVTCLASS, 1) 3153 self.misc_event.set() 3154 msg, ancdata, flags, addr = self.doRecvmsg( 3155 self.serv_sock, len(MSG), 3156 socket.CMSG_SPACE(SIZEOF_INT) + socket.CMSG_LEN(SIZEOF_INT) - 1) 3157 3158 self.assertEqual(msg, MSG) 3159 self.checkRecvmsgAddress(addr, self.cli_addr) 3160 self.checkFlags(flags, eor=True, checkset=socket.MSG_CTRUNC) 3161 3162 cmsg_types = {socket.IPV6_TCLASS, socket.IPV6_HOPLIMIT} 3163 3164 cmsg_level, cmsg_type, cmsg_data = ancdata.pop(0) 3165 self.assertEqual(cmsg_level, socket.IPPROTO_IPV6) 3166 cmsg_types.remove(cmsg_type) 3167 self.assertEqual(len(cmsg_data), SIZEOF_INT) 3168 a = array.array("i") 3169 a.frombytes(cmsg_data) 3170 self.assertGreaterEqual(a[0], 0) 3171 self.assertLessEqual(a[0], 255) 3172 3173 if ancdata: 3174 cmsg_level, cmsg_type, cmsg_data = ancdata.pop(0) 3175 self.assertEqual(cmsg_level, socket.IPPROTO_IPV6) 3176 cmsg_types.remove(cmsg_type) 3177 self.assertLess(len(cmsg_data), SIZEOF_INT) 3178 3179 self.assertEqual(ancdata, []) 3180 3181 @testSecomdCmsgTruncInData.client_skip 3182 def _testSecomdCmsgTruncInData(self): 3183 self.assertTrue(self.misc_event.wait(timeout=self.fail_timeout)) 3184 self.sendToServer(MSG) 3185 3186 3187# Derive concrete test classes for different socket types. 3188 3189class SendrecvmsgUDPTestBase(SendrecvmsgDgramFlagsBase, 3190 SendrecvmsgConnectionlessBase, 3191 ThreadedSocketTestMixin, UDPTestBase): 3192 pass 3193 3194@requireAttrs(socket.socket, "sendmsg") 3195@unittest.skipUnless(thread, 'Threading required for this test.') 3196class SendmsgUDPTest(SendmsgConnectionlessTests, SendrecvmsgUDPTestBase): 3197 pass 3198 3199@requireAttrs(socket.socket, "recvmsg") 3200@unittest.skipUnless(thread, 'Threading required for this test.') 3201class RecvmsgUDPTest(RecvmsgTests, SendrecvmsgUDPTestBase): 3202 pass 3203 3204@requireAttrs(socket.socket, "recvmsg_into") 3205@unittest.skipUnless(thread, 'Threading required for this test.') 3206class RecvmsgIntoUDPTest(RecvmsgIntoTests, SendrecvmsgUDPTestBase): 3207 pass 3208 3209 3210class SendrecvmsgUDP6TestBase(SendrecvmsgDgramFlagsBase, 3211 SendrecvmsgConnectionlessBase, 3212 ThreadedSocketTestMixin, UDP6TestBase): 3213 pass 3214 3215@requireAttrs(socket.socket, "sendmsg") 3216@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.') 3217@requireSocket("AF_INET6", "SOCK_DGRAM") 3218@unittest.skipUnless(thread, 'Threading required for this test.') 3219class SendmsgUDP6Test(SendmsgConnectionlessTests, SendrecvmsgUDP6TestBase): 3220 pass 3221 3222@requireAttrs(socket.socket, "recvmsg") 3223@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.') 3224@requireSocket("AF_INET6", "SOCK_DGRAM") 3225@unittest.skipUnless(thread, 'Threading required for this test.') 3226class RecvmsgUDP6Test(RecvmsgTests, SendrecvmsgUDP6TestBase): 3227 pass 3228 3229@requireAttrs(socket.socket, "recvmsg_into") 3230@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.') 3231@requireSocket("AF_INET6", "SOCK_DGRAM") 3232@unittest.skipUnless(thread, 'Threading required for this test.') 3233class RecvmsgIntoUDP6Test(RecvmsgIntoTests, SendrecvmsgUDP6TestBase): 3234 pass 3235 3236@requireAttrs(socket.socket, "recvmsg") 3237@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.') 3238@requireAttrs(socket, "IPPROTO_IPV6") 3239@requireSocket("AF_INET6", "SOCK_DGRAM") 3240@unittest.skipUnless(thread, 'Threading required for this test.') 3241class RecvmsgRFC3542AncillaryUDP6Test(RFC3542AncillaryTest, 3242 SendrecvmsgUDP6TestBase): 3243 pass 3244 3245@requireAttrs(socket.socket, "recvmsg_into") 3246@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test.') 3247@requireAttrs(socket, "IPPROTO_IPV6") 3248@requireSocket("AF_INET6", "SOCK_DGRAM") 3249@unittest.skipUnless(thread, 'Threading required for this test.') 3250class RecvmsgIntoRFC3542AncillaryUDP6Test(RecvmsgIntoMixin, 3251 RFC3542AncillaryTest, 3252 SendrecvmsgUDP6TestBase): 3253 pass 3254 3255 3256class SendrecvmsgTCPTestBase(SendrecvmsgConnectedBase, 3257 ConnectedStreamTestMixin, TCPTestBase): 3258 pass 3259 3260@requireAttrs(socket.socket, "sendmsg") 3261@unittest.skipUnless(thread, 'Threading required for this test.') 3262class SendmsgTCPTest(SendmsgStreamTests, SendrecvmsgTCPTestBase): 3263 pass 3264 3265@requireAttrs(socket.socket, "recvmsg") 3266@unittest.skipUnless(thread, 'Threading required for this test.') 3267class RecvmsgTCPTest(RecvmsgTests, RecvmsgGenericStreamTests, 3268 SendrecvmsgTCPTestBase): 3269 pass 3270 3271@requireAttrs(socket.socket, "recvmsg_into") 3272@unittest.skipUnless(thread, 'Threading required for this test.') 3273class RecvmsgIntoTCPTest(RecvmsgIntoTests, RecvmsgGenericStreamTests, 3274 SendrecvmsgTCPTestBase): 3275 pass 3276 3277 3278class SendrecvmsgSCTPStreamTestBase(SendrecvmsgSCTPFlagsBase, 3279 SendrecvmsgConnectedBase, 3280 ConnectedStreamTestMixin, SCTPStreamBase): 3281 pass 3282 3283@requireAttrs(socket.socket, "sendmsg") 3284@requireSocket("AF_INET", "SOCK_STREAM", "IPPROTO_SCTP") 3285@unittest.skipUnless(thread, 'Threading required for this test.') 3286class SendmsgSCTPStreamTest(SendmsgStreamTests, SendrecvmsgSCTPStreamTestBase): 3287 pass 3288 3289@requireAttrs(socket.socket, "recvmsg") 3290@requireSocket("AF_INET", "SOCK_STREAM", "IPPROTO_SCTP") 3291@unittest.skipUnless(thread, 'Threading required for this test.') 3292class RecvmsgSCTPStreamTest(RecvmsgTests, RecvmsgGenericStreamTests, 3293 SendrecvmsgSCTPStreamTestBase): 3294 3295 def testRecvmsgEOF(self): 3296 try: 3297 super(RecvmsgSCTPStreamTest, self).testRecvmsgEOF() 3298 except OSError as e: 3299 if e.errno != errno.ENOTCONN: 3300 raise 3301 self.skipTest("sporadic ENOTCONN (kernel issue?) - see issue #13876") 3302 3303@requireAttrs(socket.socket, "recvmsg_into") 3304@requireSocket("AF_INET", "SOCK_STREAM", "IPPROTO_SCTP") 3305@unittest.skipUnless(thread, 'Threading required for this test.') 3306class RecvmsgIntoSCTPStreamTest(RecvmsgIntoTests, RecvmsgGenericStreamTests, 3307 SendrecvmsgSCTPStreamTestBase): 3308 3309 def testRecvmsgEOF(self): 3310 try: 3311 super(RecvmsgIntoSCTPStreamTest, self).testRecvmsgEOF() 3312 except OSError as e: 3313 if e.errno != errno.ENOTCONN: 3314 raise 3315 self.skipTest("sporadic ENOTCONN (kernel issue?) - see issue #13876") 3316 3317 3318class SendrecvmsgUnixStreamTestBase(SendrecvmsgConnectedBase, 3319 ConnectedStreamTestMixin, UnixStreamBase): 3320 pass 3321 3322@requireAttrs(socket.socket, "sendmsg") 3323@requireAttrs(socket, "AF_UNIX") 3324@unittest.skipUnless(thread, 'Threading required for this test.') 3325class SendmsgUnixStreamTest(SendmsgStreamTests, SendrecvmsgUnixStreamTestBase): 3326 pass 3327 3328@requireAttrs(socket.socket, "recvmsg") 3329@requireAttrs(socket, "AF_UNIX") 3330@unittest.skipUnless(thread, 'Threading required for this test.') 3331class RecvmsgUnixStreamTest(RecvmsgTests, RecvmsgGenericStreamTests, 3332 SendrecvmsgUnixStreamTestBase): 3333 pass 3334 3335@requireAttrs(socket.socket, "recvmsg_into") 3336@requireAttrs(socket, "AF_UNIX") 3337@unittest.skipUnless(thread, 'Threading required for this test.') 3338class RecvmsgIntoUnixStreamTest(RecvmsgIntoTests, RecvmsgGenericStreamTests, 3339 SendrecvmsgUnixStreamTestBase): 3340 pass 3341 3342@requireAttrs(socket.socket, "sendmsg", "recvmsg") 3343@requireAttrs(socket, "AF_UNIX", "SOL_SOCKET", "SCM_RIGHTS") 3344@unittest.skipUnless(thread, 'Threading required for this test.') 3345class RecvmsgSCMRightsStreamTest(SCMRightsTest, SendrecvmsgUnixStreamTestBase): 3346 pass 3347 3348@requireAttrs(socket.socket, "sendmsg", "recvmsg_into") 3349@requireAttrs(socket, "AF_UNIX", "SOL_SOCKET", "SCM_RIGHTS") 3350@unittest.skipUnless(thread, 'Threading required for this test.') 3351class RecvmsgIntoSCMRightsStreamTest(RecvmsgIntoMixin, SCMRightsTest, 3352 SendrecvmsgUnixStreamTestBase): 3353 pass 3354 3355 3356# Test interrupting the interruptible send/receive methods with a 3357# signal when a timeout is set. These tests avoid having multiple 3358# threads alive during the test so that the OS cannot deliver the 3359# signal to the wrong one. 3360 3361class InterruptedTimeoutBase(unittest.TestCase): 3362 # Base class for interrupted send/receive tests. Installs an 3363 # empty handler for SIGALRM and removes it on teardown, along with 3364 # any scheduled alarms. 3365 3366 def setUp(self): 3367 super().setUp() 3368 orig_alrm_handler = signal.signal(signal.SIGALRM, 3369 lambda signum, frame: None) 3370 self.addCleanup(signal.signal, signal.SIGALRM, orig_alrm_handler) 3371 self.addCleanup(self.setAlarm, 0) 3372 3373 # Timeout for socket operations 3374 timeout = 4.0 3375 3376 # Provide setAlarm() method to schedule delivery of SIGALRM after 3377 # given number of seconds, or cancel it if zero, and an 3378 # appropriate time value to use. Use setitimer() if available. 3379 if hasattr(signal, "setitimer"): 3380 alarm_time = 0.05 3381 3382 def setAlarm(self, seconds): 3383 signal.setitimer(signal.ITIMER_REAL, seconds) 3384 else: 3385 # Old systems may deliver the alarm up to one second early 3386 alarm_time = 2 3387 3388 def setAlarm(self, seconds): 3389 signal.alarm(seconds) 3390 3391 3392# Require siginterrupt() in order to ensure that system calls are 3393# interrupted by default. 3394@requireAttrs(signal, "siginterrupt") 3395@unittest.skipUnless(hasattr(signal, "alarm") or hasattr(signal, "setitimer"), 3396 "Don't have signal.alarm or signal.setitimer") 3397class InterruptedRecvTimeoutTest(InterruptedTimeoutBase, UDPTestBase): 3398 # Test interrupting the recv*() methods with signals when a 3399 # timeout is set. 3400 3401 def setUp(self): 3402 super().setUp() 3403 self.serv.settimeout(self.timeout) 3404 3405 def checkInterruptedRecv(self, func, *args, **kwargs): 3406 # Check that func(*args, **kwargs) raises OSError with an 3407 # errno of EINTR when interrupted by a signal. 3408 self.setAlarm(self.alarm_time) 3409 with self.assertRaises(OSError) as cm: 3410 func(*args, **kwargs) 3411 self.assertNotIsInstance(cm.exception, socket.timeout) 3412 self.assertEqual(cm.exception.errno, errno.EINTR) 3413 3414 def testInterruptedRecvTimeout(self): 3415 self.checkInterruptedRecv(self.serv.recv, 1024) 3416 3417 def testInterruptedRecvIntoTimeout(self): 3418 self.checkInterruptedRecv(self.serv.recv_into, bytearray(1024)) 3419 3420 def testInterruptedRecvfromTimeout(self): 3421 self.checkInterruptedRecv(self.serv.recvfrom, 1024) 3422 3423 def testInterruptedRecvfromIntoTimeout(self): 3424 self.checkInterruptedRecv(self.serv.recvfrom_into, bytearray(1024)) 3425 3426 @requireAttrs(socket.socket, "recvmsg") 3427 def testInterruptedRecvmsgTimeout(self): 3428 self.checkInterruptedRecv(self.serv.recvmsg, 1024) 3429 3430 @requireAttrs(socket.socket, "recvmsg_into") 3431 def testInterruptedRecvmsgIntoTimeout(self): 3432 self.checkInterruptedRecv(self.serv.recvmsg_into, [bytearray(1024)]) 3433 3434 3435# Require siginterrupt() in order to ensure that system calls are 3436# interrupted by default. 3437@requireAttrs(signal, "siginterrupt") 3438@unittest.skipUnless(hasattr(signal, "alarm") or hasattr(signal, "setitimer"), 3439 "Don't have signal.alarm or signal.setitimer") 3440@unittest.skipUnless(thread, 'Threading required for this test.') 3441class InterruptedSendTimeoutTest(InterruptedTimeoutBase, 3442 ThreadSafeCleanupTestCase, 3443 SocketListeningTestMixin, TCPTestBase): 3444 # Test interrupting the interruptible send*() methods with signals 3445 # when a timeout is set. 3446 3447 def setUp(self): 3448 super().setUp() 3449 self.serv_conn = self.newSocket() 3450 self.addCleanup(self.serv_conn.close) 3451 # Use a thread to complete the connection, but wait for it to 3452 # terminate before running the test, so that there is only one 3453 # thread to accept the signal. 3454 cli_thread = threading.Thread(target=self.doConnect) 3455 cli_thread.start() 3456 self.cli_conn, addr = self.serv.accept() 3457 self.addCleanup(self.cli_conn.close) 3458 cli_thread.join() 3459 self.serv_conn.settimeout(self.timeout) 3460 3461 def doConnect(self): 3462 self.serv_conn.connect(self.serv_addr) 3463 3464 def checkInterruptedSend(self, func, *args, **kwargs): 3465 # Check that func(*args, **kwargs), run in a loop, raises 3466 # OSError with an errno of EINTR when interrupted by a 3467 # signal. 3468 with self.assertRaises(OSError) as cm: 3469 while True: 3470 self.setAlarm(self.alarm_time) 3471 func(*args, **kwargs) 3472 self.assertNotIsInstance(cm.exception, socket.timeout) 3473 self.assertEqual(cm.exception.errno, errno.EINTR) 3474 3475 # Issue #12958: The following tests have problems on Mac OS X 3476 @support.anticipate_failure(sys.platform == "darwin") 3477 def testInterruptedSendTimeout(self): 3478 self.checkInterruptedSend(self.serv_conn.send, b"a"*512) 3479 3480 @support.anticipate_failure(sys.platform == "darwin") 3481 def testInterruptedSendtoTimeout(self): 3482 # Passing an actual address here as Python's wrapper for 3483 # sendto() doesn't allow passing a zero-length one; POSIX 3484 # requires that the address is ignored since the socket is 3485 # connection-mode, however. 3486 self.checkInterruptedSend(self.serv_conn.sendto, b"a"*512, 3487 self.serv_addr) 3488 3489 @support.anticipate_failure(sys.platform == "darwin") 3490 @requireAttrs(socket.socket, "sendmsg") 3491 def testInterruptedSendmsgTimeout(self): 3492 self.checkInterruptedSend(self.serv_conn.sendmsg, [b"a"*512]) 3493 3494 3495@unittest.skipUnless(thread, 'Threading required for this test.') 3496class TCPCloserTest(ThreadedTCPSocketTest): 3497 3498 def testClose(self): 3499 conn, addr = self.serv.accept() 3500 conn.close() 3501 3502 sd = self.cli 3503 read, write, err = select.select([sd], [], [], 1.0) 3504 self.assertEqual(read, [sd]) 3505 self.assertEqual(sd.recv(1), b'') 3506 3507 # Calling close() many times should be safe. 3508 conn.close() 3509 conn.close() 3510 3511 def _testClose(self): 3512 self.cli.connect((HOST, self.port)) 3513 time.sleep(1.0) 3514 3515@unittest.skipUnless(thread, 'Threading required for this test.') 3516class BasicSocketPairTest(SocketPairTest): 3517 3518 def __init__(self, methodName='runTest'): 3519 SocketPairTest.__init__(self, methodName=methodName) 3520 3521 def _check_defaults(self, sock): 3522 self.assertIsInstance(sock, socket.socket) 3523 if hasattr(socket, 'AF_UNIX'): 3524 self.assertEqual(sock.family, socket.AF_UNIX) 3525 else: 3526 self.assertEqual(sock.family, socket.AF_INET) 3527 self.assertEqual(sock.type, socket.SOCK_STREAM) 3528 self.assertEqual(sock.proto, 0) 3529 3530 def _testDefaults(self): 3531 self._check_defaults(self.cli) 3532 3533 def testDefaults(self): 3534 self._check_defaults(self.serv) 3535 3536 def testRecv(self): 3537 msg = self.serv.recv(1024) 3538 self.assertEqual(msg, MSG) 3539 3540 def _testRecv(self): 3541 self.cli.send(MSG) 3542 3543 def testSend(self): 3544 self.serv.send(MSG) 3545 3546 def _testSend(self): 3547 msg = self.cli.recv(1024) 3548 self.assertEqual(msg, MSG) 3549 3550@unittest.skipUnless(thread, 'Threading required for this test.') 3551class NonBlockingTCPTests(ThreadedTCPSocketTest): 3552 3553 def __init__(self, methodName='runTest'): 3554 ThreadedTCPSocketTest.__init__(self, methodName=methodName) 3555 3556 def testSetBlocking(self): 3557 # Testing whether set blocking works 3558 self.serv.setblocking(0) 3559 start = time.time() 3560 try: 3561 self.serv.accept() 3562 except OSError: 3563 pass 3564 end = time.time() 3565 self.assertTrue((end - start) < 1.0, "Error setting non-blocking mode.") 3566 3567 def _testSetBlocking(self): 3568 pass 3569 3570 if hasattr(socket, "SOCK_NONBLOCK"): 3571 @support.requires_linux_version(2, 6, 28) 3572 def testInitNonBlocking(self): 3573 # reinit server socket 3574 self.serv.close() 3575 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM | 3576 socket.SOCK_NONBLOCK) 3577 self.port = support.bind_port(self.serv) 3578 self.serv.listen(1) 3579 # actual testing 3580 start = time.time() 3581 try: 3582 self.serv.accept() 3583 except OSError: 3584 pass 3585 end = time.time() 3586 self.assertTrue((end - start) < 1.0, "Error creating with non-blocking mode.") 3587 3588 def _testInitNonBlocking(self): 3589 pass 3590 3591 def testInheritFlags(self): 3592 # Issue #7995: when calling accept() on a listening socket with a 3593 # timeout, the resulting socket should not be non-blocking. 3594 self.serv.settimeout(10) 3595 try: 3596 conn, addr = self.serv.accept() 3597 message = conn.recv(len(MSG)) 3598 finally: 3599 conn.close() 3600 self.serv.settimeout(None) 3601 3602 def _testInheritFlags(self): 3603 time.sleep(0.1) 3604 self.cli.connect((HOST, self.port)) 3605 time.sleep(0.5) 3606 self.cli.send(MSG) 3607 3608 def testAccept(self): 3609 # Testing non-blocking accept 3610 self.serv.setblocking(0) 3611 try: 3612 conn, addr = self.serv.accept() 3613 except OSError: 3614 pass 3615 else: 3616 self.fail("Error trying to do non-blocking accept.") 3617 read, write, err = select.select([self.serv], [], []) 3618 if self.serv in read: 3619 conn, addr = self.serv.accept() 3620 conn.close() 3621 else: 3622 self.fail("Error trying to do accept after select.") 3623 3624 def _testAccept(self): 3625 time.sleep(0.1) 3626 self.cli.connect((HOST, self.port)) 3627 3628 def testConnect(self): 3629 # Testing non-blocking connect 3630 conn, addr = self.serv.accept() 3631 conn.close() 3632 3633 def _testConnect(self): 3634 self.cli.settimeout(10) 3635 self.cli.connect((HOST, self.port)) 3636 3637 def testRecv(self): 3638 # Testing non-blocking recv 3639 conn, addr = self.serv.accept() 3640 conn.setblocking(0) 3641 try: 3642 msg = conn.recv(len(MSG)) 3643 except OSError: 3644 pass 3645 else: 3646 self.fail("Error trying to do non-blocking recv.") 3647 read, write, err = select.select([conn], [], []) 3648 if conn in read: 3649 msg = conn.recv(len(MSG)) 3650 conn.close() 3651 self.assertEqual(msg, MSG) 3652 else: 3653 self.fail("Error during select call to non-blocking socket.") 3654 3655 def _testRecv(self): 3656 self.cli.connect((HOST, self.port)) 3657 time.sleep(0.1) 3658 self.cli.send(MSG) 3659 3660@unittest.skipUnless(thread, 'Threading required for this test.') 3661class FileObjectClassTestCase(SocketConnectedTest): 3662 """Unit tests for the object returned by socket.makefile() 3663 3664 self.read_file is the io object returned by makefile() on 3665 the client connection. You can read from this file to 3666 get output from the server. 3667 3668 self.write_file is the io object returned by makefile() on the 3669 server connection. You can write to this file to send output 3670 to the client. 3671 """ 3672 3673 bufsize = -1 # Use default buffer size 3674 encoding = 'utf-8' 3675 errors = 'strict' 3676 newline = None 3677 3678 read_mode = 'rb' 3679 read_msg = MSG 3680 write_mode = 'wb' 3681 write_msg = MSG 3682 3683 def __init__(self, methodName='runTest'): 3684 SocketConnectedTest.__init__(self, methodName=methodName) 3685 3686 def setUp(self): 3687 self.evt1, self.evt2, self.serv_finished, self.cli_finished = [ 3688 threading.Event() for i in range(4)] 3689 SocketConnectedTest.setUp(self) 3690 self.read_file = self.cli_conn.makefile( 3691 self.read_mode, self.bufsize, 3692 encoding = self.encoding, 3693 errors = self.errors, 3694 newline = self.newline) 3695 3696 def tearDown(self): 3697 self.serv_finished.set() 3698 self.read_file.close() 3699 self.assertTrue(self.read_file.closed) 3700 self.read_file = None 3701 SocketConnectedTest.tearDown(self) 3702 3703 def clientSetUp(self): 3704 SocketConnectedTest.clientSetUp(self) 3705 self.write_file = self.serv_conn.makefile( 3706 self.write_mode, self.bufsize, 3707 encoding = self.encoding, 3708 errors = self.errors, 3709 newline = self.newline) 3710 3711 def clientTearDown(self): 3712 self.cli_finished.set() 3713 self.write_file.close() 3714 self.assertTrue(self.write_file.closed) 3715 self.write_file = None 3716 SocketConnectedTest.clientTearDown(self) 3717 3718 def testReadAfterTimeout(self): 3719 # Issue #7322: A file object must disallow further reads 3720 # after a timeout has occurred. 3721 self.cli_conn.settimeout(1) 3722 self.read_file.read(3) 3723 # First read raises a timeout 3724 self.assertRaises(socket.timeout, self.read_file.read, 1) 3725 # Second read is disallowed 3726 with self.assertRaises(OSError) as ctx: 3727 self.read_file.read(1) 3728 self.assertIn("cannot read from timed out object", str(ctx.exception)) 3729 3730 def _testReadAfterTimeout(self): 3731 self.write_file.write(self.write_msg[0:3]) 3732 self.write_file.flush() 3733 self.serv_finished.wait() 3734 3735 def testSmallRead(self): 3736 # Performing small file read test 3737 first_seg = self.read_file.read(len(self.read_msg)-3) 3738 second_seg = self.read_file.read(3) 3739 msg = first_seg + second_seg 3740 self.assertEqual(msg, self.read_msg) 3741 3742 def _testSmallRead(self): 3743 self.write_file.write(self.write_msg) 3744 self.write_file.flush() 3745 3746 def testFullRead(self): 3747 # read until EOF 3748 msg = self.read_file.read() 3749 self.assertEqual(msg, self.read_msg) 3750 3751 def _testFullRead(self): 3752 self.write_file.write(self.write_msg) 3753 self.write_file.close() 3754 3755 def testUnbufferedRead(self): 3756 # Performing unbuffered file read test 3757 buf = type(self.read_msg)() 3758 while 1: 3759 char = self.read_file.read(1) 3760 if not char: 3761 break 3762 buf += char 3763 self.assertEqual(buf, self.read_msg) 3764 3765 def _testUnbufferedRead(self): 3766 self.write_file.write(self.write_msg) 3767 self.write_file.flush() 3768 3769 def testReadline(self): 3770 # Performing file readline test 3771 line = self.read_file.readline() 3772 self.assertEqual(line, self.read_msg) 3773 3774 def _testReadline(self): 3775 self.write_file.write(self.write_msg) 3776 self.write_file.flush() 3777 3778 def testCloseAfterMakefile(self): 3779 # The file returned by makefile should keep the socket open. 3780 self.cli_conn.close() 3781 # read until EOF 3782 msg = self.read_file.read() 3783 self.assertEqual(msg, self.read_msg) 3784 3785 def _testCloseAfterMakefile(self): 3786 self.write_file.write(self.write_msg) 3787 self.write_file.flush() 3788 3789 def testMakefileAfterMakefileClose(self): 3790 self.read_file.close() 3791 msg = self.cli_conn.recv(len(MSG)) 3792 if isinstance(self.read_msg, str): 3793 msg = msg.decode() 3794 self.assertEqual(msg, self.read_msg) 3795 3796 def _testMakefileAfterMakefileClose(self): 3797 self.write_file.write(self.write_msg) 3798 self.write_file.flush() 3799 3800 def testClosedAttr(self): 3801 self.assertTrue(not self.read_file.closed) 3802 3803 def _testClosedAttr(self): 3804 self.assertTrue(not self.write_file.closed) 3805 3806 def testAttributes(self): 3807 self.assertEqual(self.read_file.mode, self.read_mode) 3808 self.assertEqual(self.read_file.name, self.cli_conn.fileno()) 3809 3810 def _testAttributes(self): 3811 self.assertEqual(self.write_file.mode, self.write_mode) 3812 self.assertEqual(self.write_file.name, self.serv_conn.fileno()) 3813 3814 def testRealClose(self): 3815 self.read_file.close() 3816 self.assertRaises(ValueError, self.read_file.fileno) 3817 self.cli_conn.close() 3818 self.assertRaises(OSError, self.cli_conn.getsockname) 3819 3820 def _testRealClose(self): 3821 pass 3822 3823 3824class FileObjectInterruptedTestCase(unittest.TestCase): 3825 """Test that the file object correctly handles EINTR internally.""" 3826 3827 class MockSocket(object): 3828 def __init__(self, recv_funcs=()): 3829 # A generator that returns callables that we'll call for each 3830 # call to recv(). 3831 self._recv_step = iter(recv_funcs) 3832 3833 def recv_into(self, buffer): 3834 data = next(self._recv_step)() 3835 assert len(buffer) >= len(data) 3836 buffer[:len(data)] = data 3837 return len(data) 3838 3839 def _decref_socketios(self): 3840 pass 3841 3842 def _textiowrap_for_test(self, buffering=-1): 3843 raw = socket.SocketIO(self, "r") 3844 if buffering < 0: 3845 buffering = io.DEFAULT_BUFFER_SIZE 3846 if buffering == 0: 3847 return raw 3848 buffer = io.BufferedReader(raw, buffering) 3849 text = io.TextIOWrapper(buffer, None, None) 3850 text.mode = "rb" 3851 return text 3852 3853 @staticmethod 3854 def _raise_eintr(): 3855 raise OSError(errno.EINTR, "interrupted") 3856 3857 def _textiowrap_mock_socket(self, mock, buffering=-1): 3858 raw = socket.SocketIO(mock, "r") 3859 if buffering < 0: 3860 buffering = io.DEFAULT_BUFFER_SIZE 3861 if buffering == 0: 3862 return raw 3863 buffer = io.BufferedReader(raw, buffering) 3864 text = io.TextIOWrapper(buffer, None, None) 3865 text.mode = "rb" 3866 return text 3867 3868 def _test_readline(self, size=-1, buffering=-1): 3869 mock_sock = self.MockSocket(recv_funcs=[ 3870 lambda : b"This is the first line\nAnd the sec", 3871 self._raise_eintr, 3872 lambda : b"ond line is here\n", 3873 lambda : b"", 3874 lambda : b"", # XXX(gps): io library does an extra EOF read 3875 ]) 3876 fo = mock_sock._textiowrap_for_test(buffering=buffering) 3877 self.assertEqual(fo.readline(size), "This is the first line\n") 3878 self.assertEqual(fo.readline(size), "And the second line is here\n") 3879 3880 def _test_read(self, size=-1, buffering=-1): 3881 mock_sock = self.MockSocket(recv_funcs=[ 3882 lambda : b"This is the first line\nAnd the sec", 3883 self._raise_eintr, 3884 lambda : b"ond line is here\n", 3885 lambda : b"", 3886 lambda : b"", # XXX(gps): io library does an extra EOF read 3887 ]) 3888 expecting = (b"This is the first line\n" 3889 b"And the second line is here\n") 3890 fo = mock_sock._textiowrap_for_test(buffering=buffering) 3891 if buffering == 0: 3892 data = b'' 3893 else: 3894 data = '' 3895 expecting = expecting.decode('utf-8') 3896 while len(data) != len(expecting): 3897 part = fo.read(size) 3898 if not part: 3899 break 3900 data += part 3901 self.assertEqual(data, expecting) 3902 3903 def test_default(self): 3904 self._test_readline() 3905 self._test_readline(size=100) 3906 self._test_read() 3907 self._test_read(size=100) 3908 3909 def test_with_1k_buffer(self): 3910 self._test_readline(buffering=1024) 3911 self._test_readline(size=100, buffering=1024) 3912 self._test_read(buffering=1024) 3913 self._test_read(size=100, buffering=1024) 3914 3915 def _test_readline_no_buffer(self, size=-1): 3916 mock_sock = self.MockSocket(recv_funcs=[ 3917 lambda : b"a", 3918 lambda : b"\n", 3919 lambda : b"B", 3920 self._raise_eintr, 3921 lambda : b"b", 3922 lambda : b"", 3923 ]) 3924 fo = mock_sock._textiowrap_for_test(buffering=0) 3925 self.assertEqual(fo.readline(size), b"a\n") 3926 self.assertEqual(fo.readline(size), b"Bb") 3927 3928 def test_no_buffer(self): 3929 self._test_readline_no_buffer() 3930 self._test_readline_no_buffer(size=4) 3931 self._test_read(buffering=0) 3932 self._test_read(size=100, buffering=0) 3933 3934 3935class UnbufferedFileObjectClassTestCase(FileObjectClassTestCase): 3936 3937 """Repeat the tests from FileObjectClassTestCase with bufsize==0. 3938 3939 In this case (and in this case only), it should be possible to 3940 create a file object, read a line from it, create another file 3941 object, read another line from it, without loss of data in the 3942 first file object's buffer. Note that http.client relies on this 3943 when reading multiple requests from the same socket.""" 3944 3945 bufsize = 0 # Use unbuffered mode 3946 3947 def testUnbufferedReadline(self): 3948 # Read a line, create a new file object, read another line with it 3949 line = self.read_file.readline() # first line 3950 self.assertEqual(line, b"A. " + self.write_msg) # first line 3951 self.read_file = self.cli_conn.makefile('rb', 0) 3952 line = self.read_file.readline() # second line 3953 self.assertEqual(line, b"B. " + self.write_msg) # second line 3954 3955 def _testUnbufferedReadline(self): 3956 self.write_file.write(b"A. " + self.write_msg) 3957 self.write_file.write(b"B. " + self.write_msg) 3958 self.write_file.flush() 3959 3960 def testMakefileClose(self): 3961 # The file returned by makefile should keep the socket open... 3962 self.cli_conn.close() 3963 msg = self.cli_conn.recv(1024) 3964 self.assertEqual(msg, self.read_msg) 3965 # ...until the file is itself closed 3966 self.read_file.close() 3967 self.assertRaises(OSError, self.cli_conn.recv, 1024) 3968 3969 def _testMakefileClose(self): 3970 self.write_file.write(self.write_msg) 3971 self.write_file.flush() 3972 3973 def testMakefileCloseSocketDestroy(self): 3974 refcount_before = sys.getrefcount(self.cli_conn) 3975 self.read_file.close() 3976 refcount_after = sys.getrefcount(self.cli_conn) 3977 self.assertEqual(refcount_before - 1, refcount_after) 3978 3979 def _testMakefileCloseSocketDestroy(self): 3980 pass 3981 3982 # Non-blocking ops 3983 # NOTE: to set `read_file` as non-blocking, we must call 3984 # `cli_conn.setblocking` and vice-versa (see setUp / clientSetUp). 3985 3986 def testSmallReadNonBlocking(self): 3987 self.cli_conn.setblocking(False) 3988 self.assertEqual(self.read_file.readinto(bytearray(10)), None) 3989 self.assertEqual(self.read_file.read(len(self.read_msg) - 3), None) 3990 self.evt1.set() 3991 self.evt2.wait(1.0) 3992 first_seg = self.read_file.read(len(self.read_msg) - 3) 3993 if first_seg is None: 3994 # Data not arrived (can happen under Windows), wait a bit 3995 time.sleep(0.5) 3996 first_seg = self.read_file.read(len(self.read_msg) - 3) 3997 buf = bytearray(10) 3998 n = self.read_file.readinto(buf) 3999 self.assertEqual(n, 3) 4000 msg = first_seg + buf[:n] 4001 self.assertEqual(msg, self.read_msg) 4002 self.assertEqual(self.read_file.readinto(bytearray(16)), None) 4003 self.assertEqual(self.read_file.read(1), None) 4004 4005 def _testSmallReadNonBlocking(self): 4006 self.evt1.wait(1.0) 4007 self.write_file.write(self.write_msg) 4008 self.write_file.flush() 4009 self.evt2.set() 4010 # Avoid cloding the socket before the server test has finished, 4011 # otherwise system recv() will return 0 instead of EWOULDBLOCK. 4012 self.serv_finished.wait(5.0) 4013 4014 def testWriteNonBlocking(self): 4015 self.cli_finished.wait(5.0) 4016 # The client thread can't skip directly - the SkipTest exception 4017 # would appear as a failure. 4018 if self.serv_skipped: 4019 self.skipTest(self.serv_skipped) 4020 4021 def _testWriteNonBlocking(self): 4022 self.serv_skipped = None 4023 self.serv_conn.setblocking(False) 4024 # Try to saturate the socket buffer pipe with repeated large writes. 4025 BIG = b"x" * (1024 ** 2) 4026 LIMIT = 10 4027 # The first write() succeeds since a chunk of data can be buffered 4028 n = self.write_file.write(BIG) 4029 self.assertGreater(n, 0) 4030 for i in range(LIMIT): 4031 n = self.write_file.write(BIG) 4032 if n is None: 4033 # Succeeded 4034 break 4035 self.assertGreater(n, 0) 4036 else: 4037 # Let us know that this test didn't manage to establish 4038 # the expected conditions. This is not a failure in itself but, 4039 # if it happens repeatedly, the test should be fixed. 4040 self.serv_skipped = "failed to saturate the socket buffer" 4041 4042 4043class LineBufferedFileObjectClassTestCase(FileObjectClassTestCase): 4044 4045 bufsize = 1 # Default-buffered for reading; line-buffered for writing 4046 4047 4048class SmallBufferedFileObjectClassTestCase(FileObjectClassTestCase): 4049 4050 bufsize = 2 # Exercise the buffering code 4051 4052 4053class UnicodeReadFileObjectClassTestCase(FileObjectClassTestCase): 4054 """Tests for socket.makefile() in text mode (rather than binary)""" 4055 4056 read_mode = 'r' 4057 read_msg = MSG.decode('utf-8') 4058 write_mode = 'wb' 4059 write_msg = MSG 4060 newline = '' 4061 4062 4063class UnicodeWriteFileObjectClassTestCase(FileObjectClassTestCase): 4064 """Tests for socket.makefile() in text mode (rather than binary)""" 4065 4066 read_mode = 'rb' 4067 read_msg = MSG 4068 write_mode = 'w' 4069 write_msg = MSG.decode('utf-8') 4070 newline = '' 4071 4072 4073class UnicodeReadWriteFileObjectClassTestCase(FileObjectClassTestCase): 4074 """Tests for socket.makefile() in text mode (rather than binary)""" 4075 4076 read_mode = 'r' 4077 read_msg = MSG.decode('utf-8') 4078 write_mode = 'w' 4079 write_msg = MSG.decode('utf-8') 4080 newline = '' 4081 4082 4083class NetworkConnectionTest(object): 4084 """Prove network connection.""" 4085 4086 def clientSetUp(self): 4087 # We're inherited below by BasicTCPTest2, which also inherits 4088 # BasicTCPTest, which defines self.port referenced below. 4089 self.cli = socket.create_connection((HOST, self.port)) 4090 self.serv_conn = self.cli 4091 4092class BasicTCPTest2(NetworkConnectionTest, BasicTCPTest): 4093 """Tests that NetworkConnection does not break existing TCP functionality. 4094 """ 4095 4096class NetworkConnectionNoServer(unittest.TestCase): 4097 4098 class MockSocket(socket.socket): 4099 def connect(self, *args): 4100 raise socket.timeout('timed out') 4101 4102 @contextlib.contextmanager 4103 def mocked_socket_module(self): 4104 """Return a socket which times out on connect""" 4105 old_socket = socket.socket 4106 socket.socket = self.MockSocket 4107 try: 4108 yield 4109 finally: 4110 socket.socket = old_socket 4111 4112 def test_connect(self): 4113 port = support.find_unused_port() 4114 cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 4115 self.addCleanup(cli.close) 4116 with self.assertRaises(OSError) as cm: 4117 cli.connect((HOST, port)) 4118 self.assertEqual(cm.exception.errno, errno.ECONNREFUSED) 4119 4120 def test_create_connection(self): 4121 # Issue #9792: errors raised by create_connection() should have 4122 # a proper errno attribute. 4123 port = support.find_unused_port() 4124 with self.assertRaises(OSError) as cm: 4125 socket.create_connection((HOST, port)) 4126 4127 # Issue #16257: create_connection() calls getaddrinfo() against 4128 # 'localhost'. This may result in an IPV6 addr being returned 4129 # as well as an IPV4 one: 4130 # >>> socket.getaddrinfo('localhost', port, 0, SOCK_STREAM) 4131 # >>> [(2, 2, 0, '', ('127.0.0.1', 41230)), 4132 # (26, 2, 0, '', ('::1', 41230, 0, 0))] 4133 # 4134 # create_connection() enumerates through all the addresses returned 4135 # and if it doesn't successfully bind to any of them, it propagates 4136 # the last exception it encountered. 4137 # 4138 # On Solaris, ENETUNREACH is returned in this circumstance instead 4139 # of ECONNREFUSED. So, if that errno exists, add it to our list of 4140 # expected errnos. 4141 expected_errnos = [ errno.ECONNREFUSED, ] 4142 if hasattr(errno, 'ENETUNREACH'): 4143 expected_errnos.append(errno.ENETUNREACH) 4144 4145 self.assertIn(cm.exception.errno, expected_errnos) 4146 4147 def test_create_connection_timeout(self): 4148 # Issue #9792: create_connection() should not recast timeout errors 4149 # as generic socket errors. 4150 with self.mocked_socket_module(): 4151 with self.assertRaises(socket.timeout): 4152 socket.create_connection((HOST, 1234)) 4153 4154 4155@unittest.skipUnless(thread, 'Threading required for this test.') 4156class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest): 4157 4158 def __init__(self, methodName='runTest'): 4159 SocketTCPTest.__init__(self, methodName=methodName) 4160 ThreadableTest.__init__(self) 4161 4162 def clientSetUp(self): 4163 self.source_port = support.find_unused_port() 4164 4165 def clientTearDown(self): 4166 self.cli.close() 4167 self.cli = None 4168 ThreadableTest.clientTearDown(self) 4169 4170 def _justAccept(self): 4171 conn, addr = self.serv.accept() 4172 conn.close() 4173 4174 testFamily = _justAccept 4175 def _testFamily(self): 4176 self.cli = socket.create_connection((HOST, self.port), timeout=30) 4177 self.addCleanup(self.cli.close) 4178 self.assertEqual(self.cli.family, 2) 4179 4180 testSourceAddress = _justAccept 4181 def _testSourceAddress(self): 4182 self.cli = socket.create_connection((HOST, self.port), timeout=30, 4183 source_address=('', self.source_port)) 4184 self.addCleanup(self.cli.close) 4185 self.assertEqual(self.cli.getsockname()[1], self.source_port) 4186 # The port number being used is sufficient to show that the bind() 4187 # call happened. 4188 4189 testTimeoutDefault = _justAccept 4190 def _testTimeoutDefault(self): 4191 # passing no explicit timeout uses socket's global default 4192 self.assertTrue(socket.getdefaulttimeout() is None) 4193 socket.setdefaulttimeout(42) 4194 try: 4195 self.cli = socket.create_connection((HOST, self.port)) 4196 self.addCleanup(self.cli.close) 4197 finally: 4198 socket.setdefaulttimeout(None) 4199 self.assertEqual(self.cli.gettimeout(), 42) 4200 4201 testTimeoutNone = _justAccept 4202 def _testTimeoutNone(self): 4203 # None timeout means the same as sock.settimeout(None) 4204 self.assertTrue(socket.getdefaulttimeout() is None) 4205 socket.setdefaulttimeout(30) 4206 try: 4207 self.cli = socket.create_connection((HOST, self.port), timeout=None) 4208 self.addCleanup(self.cli.close) 4209 finally: 4210 socket.setdefaulttimeout(None) 4211 self.assertEqual(self.cli.gettimeout(), None) 4212 4213 testTimeoutValueNamed = _justAccept 4214 def _testTimeoutValueNamed(self): 4215 self.cli = socket.create_connection((HOST, self.port), timeout=30) 4216 self.assertEqual(self.cli.gettimeout(), 30) 4217 4218 testTimeoutValueNonamed = _justAccept 4219 def _testTimeoutValueNonamed(self): 4220 self.cli = socket.create_connection((HOST, self.port), 30) 4221 self.addCleanup(self.cli.close) 4222 self.assertEqual(self.cli.gettimeout(), 30) 4223 4224@unittest.skipUnless(thread, 'Threading required for this test.') 4225class NetworkConnectionBehaviourTest(SocketTCPTest, ThreadableTest): 4226 4227 def __init__(self, methodName='runTest'): 4228 SocketTCPTest.__init__(self, methodName=methodName) 4229 ThreadableTest.__init__(self) 4230 4231 def clientSetUp(self): 4232 pass 4233 4234 def clientTearDown(self): 4235 self.cli.close() 4236 self.cli = None 4237 ThreadableTest.clientTearDown(self) 4238 4239 def testInsideTimeout(self): 4240 conn, addr = self.serv.accept() 4241 self.addCleanup(conn.close) 4242 time.sleep(3) 4243 conn.send(b"done!") 4244 testOutsideTimeout = testInsideTimeout 4245 4246 def _testInsideTimeout(self): 4247 self.cli = sock = socket.create_connection((HOST, self.port)) 4248 data = sock.recv(5) 4249 self.assertEqual(data, b"done!") 4250 4251 def _testOutsideTimeout(self): 4252 self.cli = sock = socket.create_connection((HOST, self.port), timeout=1) 4253 self.assertRaises(socket.timeout, lambda: sock.recv(5)) 4254 4255 4256class TCPTimeoutTest(SocketTCPTest): 4257 4258 def testTCPTimeout(self): 4259 def raise_timeout(*args, **kwargs): 4260 self.serv.settimeout(1.0) 4261 self.serv.accept() 4262 self.assertRaises(socket.timeout, raise_timeout, 4263 "Error generating a timeout exception (TCP)") 4264 4265 def testTimeoutZero(self): 4266 ok = False 4267 try: 4268 self.serv.settimeout(0.0) 4269 foo = self.serv.accept() 4270 except socket.timeout: 4271 self.fail("caught timeout instead of error (TCP)") 4272 except OSError: 4273 ok = True 4274 except: 4275 self.fail("caught unexpected exception (TCP)") 4276 if not ok: 4277 self.fail("accept() returned success when we did not expect it") 4278 4279 def testInterruptedTimeout(self): 4280 # XXX I don't know how to do this test on MSWindows or any other 4281 # plaform that doesn't support signal.alarm() or os.kill(), though 4282 # the bug should have existed on all platforms. 4283 if not hasattr(signal, "alarm"): 4284 return # can only test on *nix 4285 self.serv.settimeout(5.0) # must be longer than alarm 4286 class Alarm(Exception): 4287 pass 4288 def alarm_handler(signal, frame): 4289 raise Alarm 4290 old_alarm = signal.signal(signal.SIGALRM, alarm_handler) 4291 try: 4292 signal.alarm(2) # POSIX allows alarm to be up to 1 second early 4293 try: 4294 foo = self.serv.accept() 4295 except socket.timeout: 4296 self.fail("caught timeout instead of Alarm") 4297 except Alarm: 4298 pass 4299 except: 4300 self.fail("caught other exception instead of Alarm:" 4301 " %s(%s):\n%s" % 4302 (sys.exc_info()[:2] + (traceback.format_exc(),))) 4303 else: 4304 self.fail("nothing caught") 4305 finally: 4306 signal.alarm(0) # shut off alarm 4307 except Alarm: 4308 self.fail("got Alarm in wrong place") 4309 finally: 4310 # no alarm can be pending. Safe to restore old handler. 4311 signal.signal(signal.SIGALRM, old_alarm) 4312 4313class UDPTimeoutTest(SocketUDPTest): 4314 4315 def testUDPTimeout(self): 4316 def raise_timeout(*args, **kwargs): 4317 self.serv.settimeout(1.0) 4318 self.serv.recv(1024) 4319 self.assertRaises(socket.timeout, raise_timeout, 4320 "Error generating a timeout exception (UDP)") 4321 4322 def testTimeoutZero(self): 4323 ok = False 4324 try: 4325 self.serv.settimeout(0.0) 4326 foo = self.serv.recv(1024) 4327 except socket.timeout: 4328 self.fail("caught timeout instead of error (UDP)") 4329 except OSError: 4330 ok = True 4331 except: 4332 self.fail("caught unexpected exception (UDP)") 4333 if not ok: 4334 self.fail("recv() returned success when we did not expect it") 4335 4336class TestExceptions(unittest.TestCase): 4337 4338 def testExceptionTree(self): 4339 self.assertTrue(issubclass(OSError, Exception)) 4340 self.assertTrue(issubclass(socket.herror, OSError)) 4341 self.assertTrue(issubclass(socket.gaierror, OSError)) 4342 self.assertTrue(issubclass(socket.timeout, OSError)) 4343 4344class TestLinuxAbstractNamespace(unittest.TestCase): 4345 4346 UNIX_PATH_MAX = 108 4347 4348 def testLinuxAbstractNamespace(self): 4349 address = b"\x00python-test-hello\x00\xff" 4350 with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s1: 4351 s1.bind(address) 4352 s1.listen(1) 4353 with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s2: 4354 s2.connect(s1.getsockname()) 4355 with s1.accept()[0] as s3: 4356 self.assertEqual(s1.getsockname(), address) 4357 self.assertEqual(s2.getpeername(), address) 4358 4359 def testMaxName(self): 4360 address = b"\x00" + b"h" * (self.UNIX_PATH_MAX - 1) 4361 with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s: 4362 s.bind(address) 4363 self.assertEqual(s.getsockname(), address) 4364 4365 def testNameOverflow(self): 4366 address = "\x00" + "h" * self.UNIX_PATH_MAX 4367 with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s: 4368 self.assertRaises(OSError, s.bind, address) 4369 4370 def testStrName(self): 4371 # Check that an abstract name can be passed as a string. 4372 s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 4373 try: 4374 s.bind("\x00python\x00test\x00") 4375 self.assertEqual(s.getsockname(), b"\x00python\x00test\x00") 4376 finally: 4377 s.close() 4378 4379class TestUnixDomain(unittest.TestCase): 4380 4381 def setUp(self): 4382 self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 4383 4384 def tearDown(self): 4385 self.sock.close() 4386 4387 def encoded(self, path): 4388 # Return the given path encoded in the file system encoding, 4389 # or skip the test if this is not possible. 4390 try: 4391 return os.fsencode(path) 4392 except UnicodeEncodeError: 4393 self.skipTest( 4394 "Pathname {0!a} cannot be represented in file " 4395 "system encoding {1!r}".format( 4396 path, sys.getfilesystemencoding())) 4397 4398 def bind(self, sock, path): 4399 # Bind the socket 4400 try: 4401 sock.bind(path) 4402 except OSError as e: 4403 if str(e) == "AF_UNIX path too long": 4404 self.skipTest( 4405 "Pathname {0!a} is too long to serve as a AF_UNIX path" 4406 .format(path)) 4407 else: 4408 raise 4409 4410 def testStrAddr(self): 4411 # Test binding to and retrieving a normal string pathname. 4412 path = os.path.abspath(support.TESTFN) 4413 self.bind(self.sock, path) 4414 self.addCleanup(support.unlink, path) 4415 self.assertEqual(self.sock.getsockname(), path) 4416 4417 def testBytesAddr(self): 4418 # Test binding to a bytes pathname. 4419 path = os.path.abspath(support.TESTFN) 4420 self.bind(self.sock, self.encoded(path)) 4421 self.addCleanup(support.unlink, path) 4422 self.assertEqual(self.sock.getsockname(), path) 4423 4424 def testSurrogateescapeBind(self): 4425 # Test binding to a valid non-ASCII pathname, with the 4426 # non-ASCII bytes supplied using surrogateescape encoding. 4427 path = os.path.abspath(support.TESTFN_UNICODE) 4428 b = self.encoded(path) 4429 self.bind(self.sock, b.decode("ascii", "surrogateescape")) 4430 self.addCleanup(support.unlink, path) 4431 self.assertEqual(self.sock.getsockname(), path) 4432 4433 def testUnencodableAddr(self): 4434 # Test binding to a pathname that cannot be encoded in the 4435 # file system encoding. 4436 if support.TESTFN_UNENCODABLE is None: 4437 self.skipTest("No unencodable filename available") 4438 path = os.path.abspath(support.TESTFN_UNENCODABLE) 4439 self.bind(self.sock, path) 4440 self.addCleanup(support.unlink, path) 4441 self.assertEqual(self.sock.getsockname(), path) 4442 4443@unittest.skipUnless(thread, 'Threading required for this test.') 4444class BufferIOTest(SocketConnectedTest): 4445 """ 4446 Test the buffer versions of socket.recv() and socket.send(). 4447 """ 4448 def __init__(self, methodName='runTest'): 4449 SocketConnectedTest.__init__(self, methodName=methodName) 4450 4451 def testRecvIntoArray(self): 4452 buf = bytearray(1024) 4453 nbytes = self.cli_conn.recv_into(buf) 4454 self.assertEqual(nbytes, len(MSG)) 4455 msg = buf[:len(MSG)] 4456 self.assertEqual(msg, MSG) 4457 4458 def _testRecvIntoArray(self): 4459 buf = bytes(MSG) 4460 self.serv_conn.send(buf) 4461 4462 def testRecvIntoBytearray(self): 4463 buf = bytearray(1024) 4464 nbytes = self.cli_conn.recv_into(buf) 4465 self.assertEqual(nbytes, len(MSG)) 4466 msg = buf[:len(MSG)] 4467 self.assertEqual(msg, MSG) 4468 4469 _testRecvIntoBytearray = _testRecvIntoArray 4470 4471 def testRecvIntoMemoryview(self): 4472 buf = bytearray(1024) 4473 nbytes = self.cli_conn.recv_into(memoryview(buf)) 4474 self.assertEqual(nbytes, len(MSG)) 4475 msg = buf[:len(MSG)] 4476 self.assertEqual(msg, MSG) 4477 4478 _testRecvIntoMemoryview = _testRecvIntoArray 4479 4480 def testRecvFromIntoArray(self): 4481 buf = bytearray(1024) 4482 nbytes, addr = self.cli_conn.recvfrom_into(buf) 4483 self.assertEqual(nbytes, len(MSG)) 4484 msg = buf[:len(MSG)] 4485 self.assertEqual(msg, MSG) 4486 4487 def _testRecvFromIntoArray(self): 4488 buf = bytes(MSG) 4489 self.serv_conn.send(buf) 4490 4491 def testRecvFromIntoBytearray(self): 4492 buf = bytearray(1024) 4493 nbytes, addr = self.cli_conn.recvfrom_into(buf) 4494 self.assertEqual(nbytes, len(MSG)) 4495 msg = buf[:len(MSG)] 4496 self.assertEqual(msg, MSG) 4497 4498 _testRecvFromIntoBytearray = _testRecvFromIntoArray 4499 4500 def testRecvFromIntoMemoryview(self): 4501 buf = bytearray(1024) 4502 nbytes, addr = self.cli_conn.recvfrom_into(memoryview(buf)) 4503 self.assertEqual(nbytes, len(MSG)) 4504 msg = buf[:len(MSG)] 4505 self.assertEqual(msg, MSG) 4506 4507 _testRecvFromIntoMemoryview = _testRecvFromIntoArray 4508 4509 4510TIPC_STYPE = 2000 4511TIPC_LOWER = 200 4512TIPC_UPPER = 210 4513 4514def isTipcAvailable(): 4515 """Check if the TIPC module is loaded 4516 4517 The TIPC module is not loaded automatically on Ubuntu and probably 4518 other Linux distros. 4519 """ 4520 if not hasattr(socket, "AF_TIPC"): 4521 return False 4522 if not os.path.isfile("/proc/modules"): 4523 return False 4524 with open("/proc/modules") as f: 4525 for line in f: 4526 if line.startswith("tipc "): 4527 return True 4528 if support.verbose: 4529 print("TIPC module is not loaded, please 'sudo modprobe tipc'") 4530 return False 4531 4532class TIPCTest(unittest.TestCase): 4533 def testRDM(self): 4534 srv = socket.socket(socket.AF_TIPC, socket.SOCK_RDM) 4535 cli = socket.socket(socket.AF_TIPC, socket.SOCK_RDM) 4536 self.addCleanup(srv.close) 4537 self.addCleanup(cli.close) 4538 4539 srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 4540 srvaddr = (socket.TIPC_ADDR_NAMESEQ, TIPC_STYPE, 4541 TIPC_LOWER, TIPC_UPPER) 4542 srv.bind(srvaddr) 4543 4544 sendaddr = (socket.TIPC_ADDR_NAME, TIPC_STYPE, 4545 TIPC_LOWER + int((TIPC_UPPER - TIPC_LOWER) / 2), 0) 4546 cli.sendto(MSG, sendaddr) 4547 4548 msg, recvaddr = srv.recvfrom(1024) 4549 4550 self.assertEqual(cli.getsockname(), recvaddr) 4551 self.assertEqual(msg, MSG) 4552 4553 4554class TIPCThreadableTest(unittest.TestCase, ThreadableTest): 4555 def __init__(self, methodName = 'runTest'): 4556 unittest.TestCase.__init__(self, methodName = methodName) 4557 ThreadableTest.__init__(self) 4558 4559 def setUp(self): 4560 self.srv = socket.socket(socket.AF_TIPC, socket.SOCK_STREAM) 4561 self.addCleanup(self.srv.close) 4562 self.srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 4563 srvaddr = (socket.TIPC_ADDR_NAMESEQ, TIPC_STYPE, 4564 TIPC_LOWER, TIPC_UPPER) 4565 self.srv.bind(srvaddr) 4566 self.srv.listen(5) 4567 self.serverExplicitReady() 4568 self.conn, self.connaddr = self.srv.accept() 4569 self.addCleanup(self.conn.close) 4570 4571 def clientSetUp(self): 4572 # The is a hittable race between serverExplicitReady() and the 4573 # accept() call; sleep a little while to avoid it, otherwise 4574 # we could get an exception 4575 time.sleep(0.1) 4576 self.cli = socket.socket(socket.AF_TIPC, socket.SOCK_STREAM) 4577 self.addCleanup(self.cli.close) 4578 addr = (socket.TIPC_ADDR_NAME, TIPC_STYPE, 4579 TIPC_LOWER + int((TIPC_UPPER - TIPC_LOWER) / 2), 0) 4580 self.cli.connect(addr) 4581 self.cliaddr = self.cli.getsockname() 4582 4583 def testStream(self): 4584 msg = self.conn.recv(1024) 4585 self.assertEqual(msg, MSG) 4586 self.assertEqual(self.cliaddr, self.connaddr) 4587 4588 def _testStream(self): 4589 self.cli.send(MSG) 4590 self.cli.close() 4591 4592 4593@unittest.skipUnless(thread, 'Threading required for this test.') 4594class ContextManagersTest(ThreadedTCPSocketTest): 4595 4596 def _testSocketClass(self): 4597 # base test 4598 with socket.socket() as sock: 4599 self.assertFalse(sock._closed) 4600 self.assertTrue(sock._closed) 4601 # close inside with block 4602 with socket.socket() as sock: 4603 sock.close() 4604 self.assertTrue(sock._closed) 4605 # exception inside with block 4606 with socket.socket() as sock: 4607 self.assertRaises(OSError, sock.sendall, b'foo') 4608 self.assertTrue(sock._closed) 4609 4610 def testCreateConnectionBase(self): 4611 conn, addr = self.serv.accept() 4612 self.addCleanup(conn.close) 4613 data = conn.recv(1024) 4614 conn.sendall(data) 4615 4616 def _testCreateConnectionBase(self): 4617 address = self.serv.getsockname() 4618 with socket.create_connection(address) as sock: 4619 self.assertFalse(sock._closed) 4620 sock.sendall(b'foo') 4621 self.assertEqual(sock.recv(1024), b'foo') 4622 self.assertTrue(sock._closed) 4623 4624 def testCreateConnectionClose(self): 4625 conn, addr = self.serv.accept() 4626 self.addCleanup(conn.close) 4627 data = conn.recv(1024) 4628 conn.sendall(data) 4629 4630 def _testCreateConnectionClose(self): 4631 address = self.serv.getsockname() 4632 with socket.create_connection(address) as sock: 4633 sock.close() 4634 self.assertTrue(sock._closed) 4635 self.assertRaises(OSError, sock.sendall, b'foo') 4636 4637 4638@unittest.skipUnless(hasattr(socket, "SOCK_CLOEXEC"), 4639 "SOCK_CLOEXEC not defined") 4640@unittest.skipUnless(fcntl, "module fcntl not available") 4641class CloexecConstantTest(unittest.TestCase): 4642 @support.requires_linux_version(2, 6, 28) 4643 def test_SOCK_CLOEXEC(self): 4644 with socket.socket(socket.AF_INET, 4645 socket.SOCK_STREAM | socket.SOCK_CLOEXEC) as s: 4646 self.assertTrue(s.type & socket.SOCK_CLOEXEC) 4647 self.assertTrue(fcntl.fcntl(s, fcntl.F_GETFD) & fcntl.FD_CLOEXEC) 4648 4649 4650@unittest.skipUnless(hasattr(socket, "SOCK_NONBLOCK"), 4651 "SOCK_NONBLOCK not defined") 4652class NonblockConstantTest(unittest.TestCase): 4653 def checkNonblock(self, s, nonblock=True, timeout=0.0): 4654 if nonblock: 4655 self.assertTrue(s.type & socket.SOCK_NONBLOCK) 4656 self.assertEqual(s.gettimeout(), timeout) 4657 else: 4658 self.assertFalse(s.type & socket.SOCK_NONBLOCK) 4659 self.assertEqual(s.gettimeout(), None) 4660 4661 @support.requires_linux_version(2, 6, 28) 4662 def test_SOCK_NONBLOCK(self): 4663 # a lot of it seems silly and redundant, but I wanted to test that 4664 # changing back and forth worked ok 4665 with socket.socket(socket.AF_INET, 4666 socket.SOCK_STREAM | socket.SOCK_NONBLOCK) as s: 4667 self.checkNonblock(s) 4668 s.setblocking(1) 4669 self.checkNonblock(s, False) 4670 s.setblocking(0) 4671 self.checkNonblock(s) 4672 s.settimeout(None) 4673 self.checkNonblock(s, False) 4674 s.settimeout(2.0) 4675 self.checkNonblock(s, timeout=2.0) 4676 s.setblocking(1) 4677 self.checkNonblock(s, False) 4678 # defaulttimeout 4679 t = socket.getdefaulttimeout() 4680 socket.setdefaulttimeout(0.0) 4681 with socket.socket() as s: 4682 self.checkNonblock(s) 4683 socket.setdefaulttimeout(None) 4684 with socket.socket() as s: 4685 self.checkNonblock(s, False) 4686 socket.setdefaulttimeout(2.0) 4687 with socket.socket() as s: 4688 self.checkNonblock(s, timeout=2.0) 4689 socket.setdefaulttimeout(None) 4690 with socket.socket() as s: 4691 self.checkNonblock(s, False) 4692 socket.setdefaulttimeout(t) 4693 4694 4695@unittest.skipUnless(os.name == "nt", "Windows specific") 4696@unittest.skipUnless(multiprocessing, "need multiprocessing") 4697class TestSocketSharing(SocketTCPTest): 4698 # This must be classmethod and not staticmethod or multiprocessing 4699 # won't be able to bootstrap it. 4700 @classmethod 4701 def remoteProcessServer(cls, q): 4702 # Recreate socket from shared data 4703 sdata = q.get() 4704 message = q.get() 4705 4706 s = socket.fromshare(sdata) 4707 s2, c = s.accept() 4708 4709 # Send the message 4710 s2.sendall(message) 4711 s2.close() 4712 s.close() 4713 4714 def testShare(self): 4715 # Transfer the listening server socket to another process 4716 # and service it from there. 4717 4718 # Create process: 4719 q = multiprocessing.Queue() 4720 p = multiprocessing.Process(target=self.remoteProcessServer, args=(q,)) 4721 p.start() 4722 4723 # Get the shared socket data 4724 data = self.serv.share(p.pid) 4725 4726 # Pass the shared socket to the other process 4727 addr = self.serv.getsockname() 4728 self.serv.close() 4729 q.put(data) 4730 4731 # The data that the server will send us 4732 message = b"slapmahfro" 4733 q.put(message) 4734 4735 # Connect 4736 s = socket.create_connection(addr) 4737 # listen for the data 4738 m = [] 4739 while True: 4740 data = s.recv(100) 4741 if not data: 4742 break 4743 m.append(data) 4744 s.close() 4745 received = b"".join(m) 4746 self.assertEqual(received, message) 4747 p.join() 4748 4749 def testShareLength(self): 4750 data = self.serv.share(os.getpid()) 4751 self.assertRaises(ValueError, socket.fromshare, data[:-1]) 4752 self.assertRaises(ValueError, socket.fromshare, data+b"foo") 4753 4754 def compareSockets(self, org, other): 4755 # socket sharing is expected to work only for blocking socket 4756 # since the internal python timout value isn't transfered. 4757 self.assertEqual(org.gettimeout(), None) 4758 self.assertEqual(org.gettimeout(), other.gettimeout()) 4759 4760 self.assertEqual(org.family, other.family) 4761 self.assertEqual(org.type, other.type) 4762 # If the user specified "0" for proto, then 4763 # internally windows will have picked the correct value. 4764 # Python introspection on the socket however will still return 4765 # 0. For the shared socket, the python value is recreated 4766 # from the actual value, so it may not compare correctly. 4767 if org.proto != 0: 4768 self.assertEqual(org.proto, other.proto) 4769 4770 def testShareLocal(self): 4771 data = self.serv.share(os.getpid()) 4772 s = socket.fromshare(data) 4773 try: 4774 self.compareSockets(self.serv, s) 4775 finally: 4776 s.close() 4777 4778 def testTypes(self): 4779 families = [socket.AF_INET, socket.AF_INET6] 4780 types = [socket.SOCK_STREAM, socket.SOCK_DGRAM] 4781 for f in families: 4782 for t in types: 4783 try: 4784 source = socket.socket(f, t) 4785 except OSError: 4786 continue # This combination is not supported 4787 try: 4788 data = source.share(os.getpid()) 4789 shared = socket.fromshare(data) 4790 try: 4791 self.compareSockets(source, shared) 4792 finally: 4793 shared.close() 4794 finally: 4795 source.close() 4796 4797 4798def test_main(): 4799 tests = [GeneralModuleTests, BasicTCPTest, TCPCloserTest, TCPTimeoutTest, 4800 TestExceptions, BufferIOTest, BasicTCPTest2, BasicUDPTest, UDPTimeoutTest ] 4801 4802 tests.extend([ 4803 NonBlockingTCPTests, 4804 FileObjectClassTestCase, 4805 FileObjectInterruptedTestCase, 4806 UnbufferedFileObjectClassTestCase, 4807 LineBufferedFileObjectClassTestCase, 4808 SmallBufferedFileObjectClassTestCase, 4809 UnicodeReadFileObjectClassTestCase, 4810 UnicodeWriteFileObjectClassTestCase, 4811 UnicodeReadWriteFileObjectClassTestCase, 4812 NetworkConnectionNoServer, 4813 NetworkConnectionAttributesTest, 4814 NetworkConnectionBehaviourTest, 4815 ContextManagersTest, 4816 CloexecConstantTest, 4817 NonblockConstantTest 4818 ]) 4819 if hasattr(socket, "socketpair"): 4820 tests.append(BasicSocketPairTest) 4821 if hasattr(socket, "AF_UNIX"): 4822 tests.append(TestUnixDomain) 4823 if sys.platform == 'linux': 4824 tests.append(TestLinuxAbstractNamespace) 4825 if isTipcAvailable(): 4826 tests.append(TIPCTest) 4827 tests.append(TIPCThreadableTest) 4828 tests.extend([BasicCANTest, CANTest]) 4829 tests.extend([BasicRDSTest, RDSTest]) 4830 tests.extend([ 4831 CmsgMacroTests, 4832 SendmsgUDPTest, 4833 RecvmsgUDPTest, 4834 RecvmsgIntoUDPTest, 4835 SendmsgUDP6Test, 4836 RecvmsgUDP6Test, 4837 RecvmsgRFC3542AncillaryUDP6Test, 4838 RecvmsgIntoRFC3542AncillaryUDP6Test, 4839 RecvmsgIntoUDP6Test, 4840 SendmsgTCPTest, 4841 RecvmsgTCPTest, 4842 RecvmsgIntoTCPTest, 4843 SendmsgSCTPStreamTest, 4844 RecvmsgSCTPStreamTest, 4845 RecvmsgIntoSCTPStreamTest, 4846 SendmsgUnixStreamTest, 4847 RecvmsgUnixStreamTest, 4848 RecvmsgIntoUnixStreamTest, 4849 RecvmsgSCMRightsStreamTest, 4850 RecvmsgIntoSCMRightsStreamTest, 4851 # These are slow when setitimer() is not available 4852 InterruptedRecvTimeoutTest, 4853 InterruptedSendTimeoutTest, 4854 TestSocketSharing, 4855 ]) 4856 4857 thread_info = support.threading_setup() 4858 support.run_unittest(*tests) 4859 support.threading_cleanup(*thread_info) 4860 4861if __name__ == "__main__": 4862 test_main()