/Lib/test/test_socket.py
Python | 2056 lines | 1845 code | 103 blank | 108 comment | 70 complexity | fe9c7ab96b978b282c29429f935ed60b MD5 | raw file
Large files files are truncated, but you can click here to view the full file
1#!/usr/bin/env python3 2 3import unittest 4from test import support 5 6import errno 7import io 8import socket 9import select 10import time 11import traceback 12import queue 13import sys 14import os 15import array 16import platform 17import contextlib 18from weakref import proxy 19import signal 20import math 21import pickle 22try: 23 import fcntl 24except ImportError: 25 fcntl = False 26 27def try_address(host, port=0, family=socket.AF_INET): 28 """Try to bind a socket on the given host:port and return True 29 if that has been possible.""" 30 try: 31 sock = socket.socket(family, socket.SOCK_STREAM) 32 sock.bind((host, port)) 33 except (socket.error, socket.gaierror): 34 return False 35 else: 36 sock.close() 37 return True 38 39def linux_version(): 40 try: 41 # platform.release() is something like '2.6.33.7-desktop-2mnb' 42 version_string = platform.release().split('-')[0] 43 return tuple(map(int, version_string.split('.'))) 44 except ValueError: 45 return 0, 0, 0 46 47HOST = support.HOST 48MSG = 'Michael Gilfix was here\u1234\r\n'.encode('utf-8') ## test unicode string and carriage return 49SUPPORTS_IPV6 = socket.has_ipv6 and try_address('::1', family=socket.AF_INET6) 50 51try: 52 import _thread as thread 53 import threading 54except ImportError: 55 thread = None 56 threading = None 57 58class SocketTCPTest(unittest.TestCase): 59 60 def setUp(self): 61 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 62 self.port = support.bind_port(self.serv) 63 self.serv.listen(1) 64 65 def tearDown(self): 66 self.serv.close() 67 self.serv = None 68 69class SocketUDPTest(unittest.TestCase): 70 71 def setUp(self): 72 self.serv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 73 self.port = support.bind_port(self.serv) 74 75 def tearDown(self): 76 self.serv.close() 77 self.serv = None 78 79class ThreadableTest: 80 """Threadable Test class 81 82 The ThreadableTest class makes it easy to create a threaded 83 client/server pair from an existing unit test. To create a 84 new threaded class from an existing unit test, use multiple 85 inheritance: 86 87 class NewClass (OldClass, ThreadableTest): 88 pass 89 90 This class defines two new fixture functions with obvious 91 purposes for overriding: 92 93 clientSetUp () 94 clientTearDown () 95 96 Any new test functions within the class must then define 97 tests in pairs, where the test name is preceeded with a 98 '_' to indicate the client portion of the test. Ex: 99 100 def testFoo(self): 101 # Server portion 102 103 def _testFoo(self): 104 # Client portion 105 106 Any exceptions raised by the clients during their tests 107 are caught and transferred to the main thread to alert 108 the testing framework. 109 110 Note, the server setup function cannot call any blocking 111 functions that rely on the client thread during setup, 112 unless serverExplicitReady() is called just before 113 the blocking call (such as in setting up a client/server 114 connection and performing the accept() in setUp(). 115 """ 116 117 def __init__(self): 118 # Swap the true setup function 119 self.__setUp = self.setUp 120 self.__tearDown = self.tearDown 121 self.setUp = self._setUp 122 self.tearDown = self._tearDown 123 124 def serverExplicitReady(self): 125 """This method allows the server to explicitly indicate that 126 it wants the client thread to proceed. This is useful if the 127 server is about to execute a blocking routine that is 128 dependent upon the client thread during its setup routine.""" 129 self.server_ready.set() 130 131 def _setUp(self): 132 self.server_ready = threading.Event() 133 self.client_ready = threading.Event() 134 self.done = threading.Event() 135 self.queue = queue.Queue(1) 136 137 # Do some munging to start the client test. 138 methodname = self.id() 139 i = methodname.rfind('.') 140 methodname = methodname[i+1:] 141 test_method = getattr(self, '_' + methodname) 142 self.client_thread = thread.start_new_thread( 143 self.clientRun, (test_method,)) 144 145 self.__setUp() 146 if not self.server_ready.is_set(): 147 self.server_ready.set() 148 self.client_ready.wait() 149 150 def _tearDown(self): 151 self.__tearDown() 152 self.done.wait() 153 154 if self.queue.qsize(): 155 exc = self.queue.get() 156 raise exc 157 158 def clientRun(self, test_func): 159 self.server_ready.wait() 160 self.client_ready.set() 161 self.clientSetUp() 162 if not hasattr(test_func, '__call__'): 163 raise TypeError("test_func must be a callable function") 164 try: 165 test_func() 166 except BaseException as e: 167 self.queue.put(e) 168 finally: 169 self.clientTearDown() 170 171 def clientSetUp(self): 172 raise NotImplementedError("clientSetUp must be implemented.") 173 174 def clientTearDown(self): 175 self.done.set() 176 thread.exit() 177 178class ThreadedTCPSocketTest(SocketTCPTest, ThreadableTest): 179 180 def __init__(self, methodName='runTest'): 181 SocketTCPTest.__init__(self, methodName=methodName) 182 ThreadableTest.__init__(self) 183 184 def clientSetUp(self): 185 self.cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 186 187 def clientTearDown(self): 188 self.cli.close() 189 self.cli = None 190 ThreadableTest.clientTearDown(self) 191 192class ThreadedUDPSocketTest(SocketUDPTest, ThreadableTest): 193 194 def __init__(self, methodName='runTest'): 195 SocketUDPTest.__init__(self, methodName=methodName) 196 ThreadableTest.__init__(self) 197 198 def clientSetUp(self): 199 self.cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 200 201 def clientTearDown(self): 202 self.cli.close() 203 self.cli = None 204 ThreadableTest.clientTearDown(self) 205 206class SocketConnectedTest(ThreadedTCPSocketTest): 207 """Socket tests for client-server connection. 208 209 self.cli_conn is a client socket connected to the server. The 210 setUp() method guarantees that it is connected to the server. 211 """ 212 213 def __init__(self, methodName='runTest'): 214 ThreadedTCPSocketTest.__init__(self, methodName=methodName) 215 216 def setUp(self): 217 ThreadedTCPSocketTest.setUp(self) 218 # Indicate explicitly we're ready for the client thread to 219 # proceed and then perform the blocking call to accept 220 self.serverExplicitReady() 221 conn, addr = self.serv.accept() 222 self.cli_conn = conn 223 224 def tearDown(self): 225 self.cli_conn.close() 226 self.cli_conn = None 227 ThreadedTCPSocketTest.tearDown(self) 228 229 def clientSetUp(self): 230 ThreadedTCPSocketTest.clientSetUp(self) 231 self.cli.connect((HOST, self.port)) 232 self.serv_conn = self.cli 233 234 def clientTearDown(self): 235 self.serv_conn.close() 236 self.serv_conn = None 237 ThreadedTCPSocketTest.clientTearDown(self) 238 239class SocketPairTest(unittest.TestCase, ThreadableTest): 240 241 def __init__(self, methodName='runTest'): 242 unittest.TestCase.__init__(self, methodName=methodName) 243 ThreadableTest.__init__(self) 244 245 def setUp(self): 246 self.serv, self.cli = socket.socketpair() 247 248 def tearDown(self): 249 self.serv.close() 250 self.serv = None 251 252 def clientSetUp(self): 253 pass 254 255 def clientTearDown(self): 256 self.cli.close() 257 self.cli = None 258 ThreadableTest.clientTearDown(self) 259 260 261####################################################################### 262## Begin Tests 263 264class GeneralModuleTests(unittest.TestCase): 265 266 def test_repr(self): 267 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 268 self.addCleanup(s.close) 269 self.assertTrue(repr(s).startswith("<socket.socket object")) 270 271 def test_weakref(self): 272 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 273 p = proxy(s) 274 self.assertEqual(p.fileno(), s.fileno()) 275 s.close() 276 s = None 277 try: 278 p.fileno() 279 except ReferenceError: 280 pass 281 else: 282 self.fail('Socket proxy still exists') 283 284 def testSocketError(self): 285 # Testing socket module exceptions 286 def raise_error(*args, **kwargs): 287 raise socket.error 288 def raise_herror(*args, **kwargs): 289 raise socket.herror 290 def raise_gaierror(*args, **kwargs): 291 raise socket.gaierror 292 self.assertRaises(socket.error, raise_error, 293 "Error raising socket exception.") 294 self.assertRaises(socket.error, raise_herror, 295 "Error raising socket exception.") 296 self.assertRaises(socket.error, raise_gaierror, 297 "Error raising socket exception.") 298 299 def testCrucialConstants(self): 300 # Testing for mission critical constants 301 socket.AF_INET 302 socket.SOCK_STREAM 303 socket.SOCK_DGRAM 304 socket.SOCK_RAW 305 socket.SOCK_RDM 306 socket.SOCK_SEQPACKET 307 socket.SOL_SOCKET 308 socket.SO_REUSEADDR 309 310 def testHostnameRes(self): 311 # Testing hostname resolution mechanisms 312 hostname = socket.gethostname() 313 try: 314 ip = socket.gethostbyname(hostname) 315 except socket.error: 316 # Probably name lookup wasn't set up right; skip this test 317 return 318 self.assertTrue(ip.find('.') >= 0, "Error resolving host to ip.") 319 try: 320 hname, aliases, ipaddrs = socket.gethostbyaddr(ip) 321 except socket.error: 322 # Probably a similar problem as above; skip this test 323 return 324 all_host_names = [hostname, hname] + aliases 325 fqhn = socket.getfqdn(ip) 326 if not fqhn in all_host_names: 327 self.fail("Error testing host resolution mechanisms. (fqdn: %s, all: %s)" % (fqhn, repr(all_host_names))) 328 329 @unittest.skipUnless(hasattr(socket, 'sethostname'), "test needs socket.sethostname()") 330 @unittest.skipUnless(hasattr(socket, 'gethostname'), "test needs socket.gethostname()") 331 def test_sethostname(self): 332 oldhn = socket.gethostname() 333 try: 334 socket.sethostname('new') 335 except socket.error as e: 336 if e.errno == errno.EPERM: 337 self.skipTest("test should be run as root") 338 else: 339 raise 340 try: 341 # running test as root! 342 self.assertEqual(socket.gethostname(), 'new') 343 # Should work with bytes objects too 344 socket.sethostname(b'bar') 345 self.assertEqual(socket.gethostname(), 'bar') 346 finally: 347 socket.sethostname(oldhn) 348 349 def testRefCountGetNameInfo(self): 350 # Testing reference count for getnameinfo 351 if hasattr(sys, "getrefcount"): 352 try: 353 # On some versions, this loses a reference 354 orig = sys.getrefcount(__name__) 355 socket.getnameinfo(__name__,0) 356 except TypeError: 357 if sys.getrefcount(__name__) != orig: 358 self.fail("socket.getnameinfo loses a reference") 359 360 def testInterpreterCrash(self): 361 # Making sure getnameinfo doesn't crash the interpreter 362 try: 363 # On some versions, this crashes the interpreter. 364 socket.getnameinfo(('x', 0, 0, 0), 0) 365 except socket.error: 366 pass 367 368 def testNtoH(self): 369 # This just checks that htons etc. are their own inverse, 370 # when looking at the lower 16 or 32 bits. 371 sizes = {socket.htonl: 32, socket.ntohl: 32, 372 socket.htons: 16, socket.ntohs: 16} 373 for func, size in sizes.items(): 374 mask = (1<<size) - 1 375 for i in (0, 1, 0xffff, ~0xffff, 2, 0x01234567, 0x76543210): 376 self.assertEqual(i & mask, func(func(i&mask)) & mask) 377 378 swapped = func(mask) 379 self.assertEqual(swapped & mask, mask) 380 self.assertRaises(OverflowError, func, 1<<34) 381 382 def testNtoHErrors(self): 383 good_values = [ 1, 2, 3, 1, 2, 3 ] 384 bad_values = [ -1, -2, -3, -1, -2, -3 ] 385 for k in good_values: 386 socket.ntohl(k) 387 socket.ntohs(k) 388 socket.htonl(k) 389 socket.htons(k) 390 for k in bad_values: 391 self.assertRaises(OverflowError, socket.ntohl, k) 392 self.assertRaises(OverflowError, socket.ntohs, k) 393 self.assertRaises(OverflowError, socket.htonl, k) 394 self.assertRaises(OverflowError, socket.htons, k) 395 396 def testGetServBy(self): 397 eq = self.assertEqual 398 # Find one service that exists, then check all the related interfaces. 399 # I've ordered this by protocols that have both a tcp and udp 400 # protocol, at least for modern Linuxes. 401 if (sys.platform.startswith('linux') or 402 sys.platform.startswith('freebsd') or 403 sys.platform.startswith('netbsd') or 404 sys.platform == 'darwin'): 405 # avoid the 'echo' service on this platform, as there is an 406 # assumption breaking non-standard port/protocol entry 407 services = ('daytime', 'qotd', 'domain') 408 else: 409 services = ('echo', 'daytime', 'domain') 410 for service in services: 411 try: 412 port = socket.getservbyname(service, 'tcp') 413 break 414 except socket.error: 415 pass 416 else: 417 raise socket.error 418 # Try same call with optional protocol omitted 419 port2 = socket.getservbyname(service) 420 eq(port, port2) 421 # Try udp, but don't barf it it doesn't exist 422 try: 423 udpport = socket.getservbyname(service, 'udp') 424 except socket.error: 425 udpport = None 426 else: 427 eq(udpport, port) 428 # Now make sure the lookup by port returns the same service name 429 eq(socket.getservbyport(port2), service) 430 eq(socket.getservbyport(port, 'tcp'), service) 431 if udpport is not None: 432 eq(socket.getservbyport(udpport, 'udp'), service) 433 # Make sure getservbyport does not accept out of range ports. 434 self.assertRaises(OverflowError, socket.getservbyport, -1) 435 self.assertRaises(OverflowError, socket.getservbyport, 65536) 436 437 def testDefaultTimeout(self): 438 # Testing default timeout 439 # The default timeout should initially be None 440 self.assertEqual(socket.getdefaulttimeout(), None) 441 s = socket.socket() 442 self.assertEqual(s.gettimeout(), None) 443 s.close() 444 445 # Set the default timeout to 10, and see if it propagates 446 socket.setdefaulttimeout(10) 447 self.assertEqual(socket.getdefaulttimeout(), 10) 448 s = socket.socket() 449 self.assertEqual(s.gettimeout(), 10) 450 s.close() 451 452 # Reset the default timeout to None, and see if it propagates 453 socket.setdefaulttimeout(None) 454 self.assertEqual(socket.getdefaulttimeout(), None) 455 s = socket.socket() 456 self.assertEqual(s.gettimeout(), None) 457 s.close() 458 459 # Check that setting it to an invalid value raises ValueError 460 self.assertRaises(ValueError, socket.setdefaulttimeout, -1) 461 462 # Check that setting it to an invalid type raises TypeError 463 self.assertRaises(TypeError, socket.setdefaulttimeout, "spam") 464 465 def testIPv4_inet_aton_fourbytes(self): 466 if not hasattr(socket, 'inet_aton'): 467 return # No inet_aton, nothing to check 468 # Test that issue1008086 and issue767150 are fixed. 469 # It must return 4 bytes. 470 self.assertEqual(b'\x00'*4, socket.inet_aton('0.0.0.0')) 471 self.assertEqual(b'\xff'*4, socket.inet_aton('255.255.255.255')) 472 473 def testIPv4toString(self): 474 if not hasattr(socket, 'inet_pton'): 475 return # No inet_pton() on this platform 476 from socket import inet_aton as f, inet_pton, AF_INET 477 g = lambda a: inet_pton(AF_INET, a) 478 479 self.assertEqual(b'\x00\x00\x00\x00', f('0.0.0.0')) 480 self.assertEqual(b'\xff\x00\xff\x00', f('255.0.255.0')) 481 self.assertEqual(b'\xaa\xaa\xaa\xaa', f('170.170.170.170')) 482 self.assertEqual(b'\x01\x02\x03\x04', f('1.2.3.4')) 483 self.assertEqual(b'\xff\xff\xff\xff', f('255.255.255.255')) 484 485 self.assertEqual(b'\x00\x00\x00\x00', g('0.0.0.0')) 486 self.assertEqual(b'\xff\x00\xff\x00', g('255.0.255.0')) 487 self.assertEqual(b'\xaa\xaa\xaa\xaa', g('170.170.170.170')) 488 self.assertEqual(b'\xff\xff\xff\xff', g('255.255.255.255')) 489 490 def testIPv6toString(self): 491 if not hasattr(socket, 'inet_pton'): 492 return # No inet_pton() on this platform 493 try: 494 from socket import inet_pton, AF_INET6, has_ipv6 495 if not has_ipv6: 496 return 497 except ImportError: 498 return 499 f = lambda a: inet_pton(AF_INET6, a) 500 501 self.assertEqual(b'\x00' * 16, f('::')) 502 self.assertEqual(b'\x00' * 16, f('0::0')) 503 self.assertEqual(b'\x00\x01' + b'\x00' * 14, f('1::')) 504 self.assertEqual( 505 b'\x45\xef\x76\xcb\x00\x1a\x56\xef\xaf\xeb\x0b\xac\x19\x24\xae\xae', 506 f('45ef:76cb:1a:56ef:afeb:bac:1924:aeae') 507 ) 508 509 def testStringToIPv4(self): 510 if not hasattr(socket, 'inet_ntop'): 511 return # No inet_ntop() on this platform 512 from socket import inet_ntoa as f, inet_ntop, AF_INET 513 g = lambda a: inet_ntop(AF_INET, a) 514 515 self.assertEqual('1.0.1.0', f(b'\x01\x00\x01\x00')) 516 self.assertEqual('170.85.170.85', f(b'\xaa\x55\xaa\x55')) 517 self.assertEqual('255.255.255.255', f(b'\xff\xff\xff\xff')) 518 self.assertEqual('1.2.3.4', f(b'\x01\x02\x03\x04')) 519 520 self.assertEqual('1.0.1.0', g(b'\x01\x00\x01\x00')) 521 self.assertEqual('170.85.170.85', g(b'\xaa\x55\xaa\x55')) 522 self.assertEqual('255.255.255.255', g(b'\xff\xff\xff\xff')) 523 524 def testStringToIPv6(self): 525 if not hasattr(socket, 'inet_ntop'): 526 return # No inet_ntop() on this platform 527 try: 528 from socket import inet_ntop, AF_INET6, has_ipv6 529 if not has_ipv6: 530 return 531 except ImportError: 532 return 533 f = lambda a: inet_ntop(AF_INET6, a) 534 535 self.assertEqual('::', f(b'\x00' * 16)) 536 self.assertEqual('::1', f(b'\x00' * 15 + b'\x01')) 537 self.assertEqual( 538 'aef:b01:506:1001:ffff:9997:55:170', 539 f(b'\x0a\xef\x0b\x01\x05\x06\x10\x01\xff\xff\x99\x97\x00\x55\x01\x70') 540 ) 541 542 # XXX The following don't test module-level functionality... 543 544 def _get_unused_port(self, bind_address='0.0.0.0'): 545 """Use a temporary socket to elicit an unused ephemeral port. 546 547 Args: 548 bind_address: Hostname or IP address to search for a port on. 549 550 Returns: A most likely to be unused port. 551 """ 552 tempsock = socket.socket() 553 tempsock.bind((bind_address, 0)) 554 host, port = tempsock.getsockname() 555 tempsock.close() 556 return port 557 558 def testSockName(self): 559 # Testing getsockname() 560 port = self._get_unused_port() 561 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 562 self.addCleanup(sock.close) 563 sock.bind(("0.0.0.0", port)) 564 name = sock.getsockname() 565 # XXX(nnorwitz): http://tinyurl.com/os5jz seems to indicate 566 # it reasonable to get the host's addr in addition to 0.0.0.0. 567 # At least for eCos. This is required for the S/390 to pass. 568 try: 569 my_ip_addr = socket.gethostbyname(socket.gethostname()) 570 except socket.error: 571 # Probably name lookup wasn't set up right; skip this test 572 return 573 self.assertIn(name[0], ("0.0.0.0", my_ip_addr), '%s invalid' % name[0]) 574 self.assertEqual(name[1], port) 575 576 def testGetSockOpt(self): 577 # Testing getsockopt() 578 # We know a socket should start without reuse==0 579 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 580 self.addCleanup(sock.close) 581 reuse = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) 582 self.assertFalse(reuse != 0, "initial mode is reuse") 583 584 def testSetSockOpt(self): 585 # Testing setsockopt() 586 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 587 self.addCleanup(sock.close) 588 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 589 reuse = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) 590 self.assertFalse(reuse == 0, "failed to set reuse mode") 591 592 def testSendAfterClose(self): 593 # testing send() after close() with timeout 594 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 595 sock.settimeout(1) 596 sock.close() 597 self.assertRaises(socket.error, sock.send, b"spam") 598 599 def testNewAttributes(self): 600 # testing .family, .type and .protocol 601 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 602 self.assertEqual(sock.family, socket.AF_INET) 603 self.assertEqual(sock.type, socket.SOCK_STREAM) 604 self.assertEqual(sock.proto, 0) 605 sock.close() 606 607 def test_getsockaddrarg(self): 608 host = '0.0.0.0' 609 port = self._get_unused_port(bind_address=host) 610 big_port = port + 65536 611 neg_port = port - 65536 612 sock = socket.socket() 613 try: 614 self.assertRaises(OverflowError, sock.bind, (host, big_port)) 615 self.assertRaises(OverflowError, sock.bind, (host, neg_port)) 616 sock.bind((host, port)) 617 finally: 618 sock.close() 619 620 @unittest.skipUnless(os.name == "nt", "Windows specific") 621 def test_sock_ioctl(self): 622 self.assertTrue(hasattr(socket.socket, 'ioctl')) 623 self.assertTrue(hasattr(socket, 'SIO_RCVALL')) 624 self.assertTrue(hasattr(socket, 'RCVALL_ON')) 625 self.assertTrue(hasattr(socket, 'RCVALL_OFF')) 626 self.assertTrue(hasattr(socket, 'SIO_KEEPALIVE_VALS')) 627 s = socket.socket() 628 self.addCleanup(s.close) 629 self.assertRaises(ValueError, s.ioctl, -1, None) 630 s.ioctl(socket.SIO_KEEPALIVE_VALS, (1, 100, 100)) 631 632 def testGetaddrinfo(self): 633 try: 634 socket.getaddrinfo('localhost', 80) 635 except socket.gaierror as err: 636 if err.errno == socket.EAI_SERVICE: 637 # see http://bugs.python.org/issue1282647 638 self.skipTest("buggy libc version") 639 raise 640 # len of every sequence is supposed to be == 5 641 for info in socket.getaddrinfo(HOST, None): 642 self.assertEqual(len(info), 5) 643 # host can be a domain name, a string representation of an 644 # IPv4/v6 address or None 645 socket.getaddrinfo('localhost', 80) 646 socket.getaddrinfo('127.0.0.1', 80) 647 socket.getaddrinfo(None, 80) 648 if SUPPORTS_IPV6: 649 socket.getaddrinfo('::1', 80) 650 # port can be a string service name such as "http", a numeric 651 # port number or None 652 socket.getaddrinfo(HOST, "http") 653 socket.getaddrinfo(HOST, 80) 654 socket.getaddrinfo(HOST, None) 655 # test family and socktype filters 656 infos = socket.getaddrinfo(HOST, None, socket.AF_INET) 657 for family, _, _, _, _ in infos: 658 self.assertEqual(family, socket.AF_INET) 659 infos = socket.getaddrinfo(HOST, None, 0, socket.SOCK_STREAM) 660 for _, socktype, _, _, _ in infos: 661 self.assertEqual(socktype, socket.SOCK_STREAM) 662 # test proto and flags arguments 663 socket.getaddrinfo(HOST, None, 0, 0, socket.SOL_TCP) 664 socket.getaddrinfo(HOST, None, 0, 0, 0, socket.AI_PASSIVE) 665 # a server willing to support both IPv4 and IPv6 will 666 # usually do this 667 socket.getaddrinfo(None, 0, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, 668 socket.AI_PASSIVE) 669 # test keyword arguments 670 a = socket.getaddrinfo(HOST, None) 671 b = socket.getaddrinfo(host=HOST, port=None) 672 self.assertEqual(a, b) 673 a = socket.getaddrinfo(HOST, None, socket.AF_INET) 674 b = socket.getaddrinfo(HOST, None, family=socket.AF_INET) 675 self.assertEqual(a, b) 676 a = socket.getaddrinfo(HOST, None, 0, socket.SOCK_STREAM) 677 b = socket.getaddrinfo(HOST, None, type=socket.SOCK_STREAM) 678 self.assertEqual(a, b) 679 a = socket.getaddrinfo(HOST, None, 0, 0, socket.SOL_TCP) 680 b = socket.getaddrinfo(HOST, None, proto=socket.SOL_TCP) 681 self.assertEqual(a, b) 682 a = socket.getaddrinfo(HOST, None, 0, 0, 0, socket.AI_PASSIVE) 683 b = socket.getaddrinfo(HOST, None, flags=socket.AI_PASSIVE) 684 self.assertEqual(a, b) 685 a = socket.getaddrinfo(None, 0, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, 686 socket.AI_PASSIVE) 687 b = socket.getaddrinfo(host=None, port=0, family=socket.AF_UNSPEC, 688 type=socket.SOCK_STREAM, proto=0, 689 flags=socket.AI_PASSIVE) 690 self.assertEqual(a, b) 691 # Issue #6697. 692 self.assertRaises(UnicodeEncodeError, socket.getaddrinfo, 'localhost', '\uD800') 693 694 def test_getnameinfo(self): 695 # only IP addresses are allowed 696 self.assertRaises(socket.error, socket.getnameinfo, ('mail.python.org',0), 0) 697 698 @unittest.skipUnless(support.is_resource_enabled('network'), 699 'network is not enabled') 700 def test_idna(self): 701 support.requires('network') 702 # these should all be successful 703 socket.gethostbyname('испытание.python.org') 704 socket.gethostbyname_ex('испытание.python.org') 705 socket.getaddrinfo('испытание.python.org',0,socket.AF_UNSPEC,socket.SOCK_STREAM) 706 # this may not work if the forward lookup choses the IPv6 address, as that doesn't 707 # have a reverse entry yet 708 # socket.gethostbyaddr('испытание.python.org') 709 710 def check_sendall_interrupted(self, with_timeout): 711 # socketpair() is not stricly required, but it makes things easier. 712 if not hasattr(signal, 'alarm') or not hasattr(socket, 'socketpair'): 713 self.skipTest("signal.alarm and socket.socketpair required for this test") 714 # Our signal handlers clobber the C errno by calling a math function 715 # with an invalid domain value. 716 def ok_handler(*args): 717 self.assertRaises(ValueError, math.acosh, 0) 718 def raising_handler(*args): 719 self.assertRaises(ValueError, math.acosh, 0) 720 1 // 0 721 c, s = socket.socketpair() 722 old_alarm = signal.signal(signal.SIGALRM, raising_handler) 723 try: 724 if with_timeout: 725 # Just above the one second minimum for signal.alarm 726 c.settimeout(1.5) 727 with self.assertRaises(ZeroDivisionError): 728 signal.alarm(1) 729 c.sendall(b"x" * (1024**2)) 730 if with_timeout: 731 signal.signal(signal.SIGALRM, ok_handler) 732 signal.alarm(1) 733 self.assertRaises(socket.timeout, c.sendall, b"x" * (1024**2)) 734 finally: 735 signal.signal(signal.SIGALRM, old_alarm) 736 c.close() 737 s.close() 738 739 def test_sendall_interrupted(self): 740 self.check_sendall_interrupted(False) 741 742 def test_sendall_interrupted_with_timeout(self): 743 self.check_sendall_interrupted(True) 744 745 def test_dealloc_warn(self): 746 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 747 r = repr(sock) 748 with self.assertWarns(ResourceWarning) as cm: 749 sock = None 750 support.gc_collect() 751 self.assertIn(r, str(cm.warning.args[0])) 752 # An open socket file object gets dereferenced after the socket 753 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 754 f = sock.makefile('rb') 755 r = repr(sock) 756 sock = None 757 support.gc_collect() 758 with self.assertWarns(ResourceWarning): 759 f = None 760 support.gc_collect() 761 762 def test_name_closed_socketio(self): 763 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: 764 fp = sock.makefile("rb") 765 fp.close() 766 self.assertEqual(repr(fp), "<_io.BufferedReader name=-1>") 767 768 def test_pickle(self): 769 sock = socket.socket() 770 with sock: 771 for protocol in range(pickle.HIGHEST_PROTOCOL + 1): 772 self.assertRaises(TypeError, pickle.dumps, sock, protocol) 773 774 775@unittest.skipUnless(thread, 'Threading required for this test.') 776class BasicTCPTest(SocketConnectedTest): 777 778 def __init__(self, methodName='runTest'): 779 SocketConnectedTest.__init__(self, methodName=methodName) 780 781 def testRecv(self): 782 # Testing large receive over TCP 783 msg = self.cli_conn.recv(1024) 784 self.assertEqual(msg, MSG) 785 786 def _testRecv(self): 787 self.serv_conn.send(MSG) 788 789 def testOverFlowRecv(self): 790 # Testing receive in chunks over TCP 791 seg1 = self.cli_conn.recv(len(MSG) - 3) 792 seg2 = self.cli_conn.recv(1024) 793 msg = seg1 + seg2 794 self.assertEqual(msg, MSG) 795 796 def _testOverFlowRecv(self): 797 self.serv_conn.send(MSG) 798 799 def testRecvFrom(self): 800 # Testing large recvfrom() over TCP 801 msg, addr = self.cli_conn.recvfrom(1024) 802 self.assertEqual(msg, MSG) 803 804 def _testRecvFrom(self): 805 self.serv_conn.send(MSG) 806 807 def testOverFlowRecvFrom(self): 808 # Testing recvfrom() in chunks over TCP 809 seg1, addr = self.cli_conn.recvfrom(len(MSG)-3) 810 seg2, addr = self.cli_conn.recvfrom(1024) 811 msg = seg1 + seg2 812 self.assertEqual(msg, MSG) 813 814 def _testOverFlowRecvFrom(self): 815 self.serv_conn.send(MSG) 816 817 def testSendAll(self): 818 # Testing sendall() with a 2048 byte string over TCP 819 msg = b'' 820 while 1: 821 read = self.cli_conn.recv(1024) 822 if not read: 823 break 824 msg += read 825 self.assertEqual(msg, b'f' * 2048) 826 827 def _testSendAll(self): 828 big_chunk = b'f' * 2048 829 self.serv_conn.sendall(big_chunk) 830 831 def testFromFd(self): 832 # Testing fromfd() 833 fd = self.cli_conn.fileno() 834 sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM) 835 self.addCleanup(sock.close) 836 self.assertIsInstance(sock, socket.socket) 837 msg = sock.recv(1024) 838 self.assertEqual(msg, MSG) 839 840 def _testFromFd(self): 841 self.serv_conn.send(MSG) 842 843 def testDup(self): 844 # Testing dup() 845 sock = self.cli_conn.dup() 846 self.addCleanup(sock.close) 847 msg = sock.recv(1024) 848 self.assertEqual(msg, MSG) 849 850 def _testDup(self): 851 self.serv_conn.send(MSG) 852 853 def testShutdown(self): 854 # Testing shutdown() 855 msg = self.cli_conn.recv(1024) 856 self.assertEqual(msg, MSG) 857 # wait for _testShutdown to finish: on OS X, when the server 858 # closes the connection the client also becomes disconnected, 859 # and the client's shutdown call will fail. (Issue #4397.) 860 self.done.wait() 861 862 def _testShutdown(self): 863 self.serv_conn.send(MSG) 864 self.serv_conn.shutdown(2) 865 866 def testDetach(self): 867 # Testing detach() 868 fileno = self.cli_conn.fileno() 869 f = self.cli_conn.detach() 870 self.assertEqual(f, fileno) 871 # cli_conn cannot be used anymore... 872 self.assertRaises(socket.error, self.cli_conn.recv, 1024) 873 self.cli_conn.close() 874 # ...but we can create another socket using the (still open) 875 # file descriptor 876 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, fileno=f) 877 self.addCleanup(sock.close) 878 msg = sock.recv(1024) 879 self.assertEqual(msg, MSG) 880 881 def _testDetach(self): 882 self.serv_conn.send(MSG) 883 884@unittest.skipUnless(thread, 'Threading required for this test.') 885class BasicUDPTest(ThreadedUDPSocketTest): 886 887 def __init__(self, methodName='runTest'): 888 ThreadedUDPSocketTest.__init__(self, methodName=methodName) 889 890 def testSendtoAndRecv(self): 891 # Testing sendto() and Recv() over UDP 892 msg = self.serv.recv(len(MSG)) 893 self.assertEqual(msg, MSG) 894 895 def _testSendtoAndRecv(self): 896 self.cli.sendto(MSG, 0, (HOST, self.port)) 897 898 def testRecvFrom(self): 899 # Testing recvfrom() over UDP 900 msg, addr = self.serv.recvfrom(len(MSG)) 901 self.assertEqual(msg, MSG) 902 903 def _testRecvFrom(self): 904 self.cli.sendto(MSG, 0, (HOST, self.port)) 905 906 def testRecvFromNegative(self): 907 # Negative lengths passed to recvfrom should give ValueError. 908 self.assertRaises(ValueError, self.serv.recvfrom, -1) 909 910 def _testRecvFromNegative(self): 911 self.cli.sendto(MSG, 0, (HOST, self.port)) 912 913@unittest.skipUnless(thread, 'Threading required for this test.') 914class TCPCloserTest(ThreadedTCPSocketTest): 915 916 def testClose(self): 917 conn, addr = self.serv.accept() 918 conn.close() 919 920 sd = self.cli 921 read, write, err = select.select([sd], [], [], 1.0) 922 self.assertEqual(read, [sd]) 923 self.assertEqual(sd.recv(1), b'') 924 925 # Calling close() many times should be safe. 926 conn.close() 927 conn.close() 928 929 def _testClose(self): 930 self.cli.connect((HOST, self.port)) 931 time.sleep(1.0) 932 933@unittest.skipUnless(thread, 'Threading required for this test.') 934class BasicSocketPairTest(SocketPairTest): 935 936 def __init__(self, methodName='runTest'): 937 SocketPairTest.__init__(self, methodName=methodName) 938 939 def _check_defaults(self, sock): 940 self.assertIsInstance(sock, socket.socket) 941 if hasattr(socket, 'AF_UNIX'): 942 self.assertEqual(sock.family, socket.AF_UNIX) 943 else: 944 self.assertEqual(sock.family, socket.AF_INET) 945 self.assertEqual(sock.type, socket.SOCK_STREAM) 946 self.assertEqual(sock.proto, 0) 947 948 def _testDefaults(self): 949 self._check_defaults(self.cli) 950 951 def testDefaults(self): 952 self._check_defaults(self.serv) 953 954 def testRecv(self): 955 msg = self.serv.recv(1024) 956 self.assertEqual(msg, MSG) 957 958 def _testRecv(self): 959 self.cli.send(MSG) 960 961 def testSend(self): 962 self.serv.send(MSG) 963 964 def _testSend(self): 965 msg = self.cli.recv(1024) 966 self.assertEqual(msg, MSG) 967 968@unittest.skipUnless(thread, 'Threading required for this test.') 969class NonBlockingTCPTests(ThreadedTCPSocketTest): 970 971 def __init__(self, methodName='runTest'): 972 ThreadedTCPSocketTest.__init__(self, methodName=methodName) 973 974 def testSetBlocking(self): 975 # Testing whether set blocking works 976 self.serv.setblocking(0) 977 start = time.time() 978 try: 979 self.serv.accept() 980 except socket.error: 981 pass 982 end = time.time() 983 self.assertTrue((end - start) < 1.0, "Error setting non-blocking mode.") 984 985 def _testSetBlocking(self): 986 pass 987 988 if hasattr(socket, "SOCK_NONBLOCK"): 989 def testInitNonBlocking(self): 990 v = linux_version() 991 if v < (2, 6, 28): 992 self.skipTest("Linux kernel 2.6.28 or higher required, not %s" 993 % ".".join(map(str, v))) 994 # reinit server socket 995 self.serv.close() 996 self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM | 997 socket.SOCK_NONBLOCK) 998 self.port = support.bind_port(self.serv) 999 self.serv.listen(1) 1000 # actual testing 1001 start = time.time() 1002 try: 1003 self.serv.accept() 1004 except socket.error: 1005 pass 1006 end = time.time() 1007 self.assertTrue((end - start) < 1.0, "Error creating with non-blocking mode.") 1008 1009 def _testInitNonBlocking(self): 1010 pass 1011 1012 def testInheritFlags(self): 1013 # Issue #7995: when calling accept() on a listening socket with a 1014 # timeout, the resulting socket should not be non-blocking. 1015 self.serv.settimeout(10) 1016 try: 1017 conn, addr = self.serv.accept() 1018 message = conn.recv(len(MSG)) 1019 finally: 1020 conn.close() 1021 self.serv.settimeout(None) 1022 1023 def _testInheritFlags(self): 1024 time.sleep(0.1) 1025 self.cli.connect((HOST, self.port)) 1026 time.sleep(0.5) 1027 self.cli.send(MSG) 1028 1029 def testAccept(self): 1030 # Testing non-blocking accept 1031 self.serv.setblocking(0) 1032 try: 1033 conn, addr = self.serv.accept() 1034 except socket.error: 1035 pass 1036 else: 1037 self.fail("Error trying to do non-blocking accept.") 1038 read, write, err = select.select([self.serv], [], []) 1039 if self.serv in read: 1040 conn, addr = self.serv.accept() 1041 conn.close() 1042 else: 1043 self.fail("Error trying to do accept after select.") 1044 1045 def _testAccept(self): 1046 time.sleep(0.1) 1047 self.cli.connect((HOST, self.port)) 1048 1049 def testConnect(self): 1050 # Testing non-blocking connect 1051 conn, addr = self.serv.accept() 1052 conn.close() 1053 1054 def _testConnect(self): 1055 self.cli.settimeout(10) 1056 self.cli.connect((HOST, self.port)) 1057 1058 def testRecv(self): 1059 # Testing non-blocking recv 1060 conn, addr = self.serv.accept() 1061 conn.setblocking(0) 1062 try: 1063 msg = conn.recv(len(MSG)) 1064 except socket.error: 1065 pass 1066 else: 1067 self.fail("Error trying to do non-blocking recv.") 1068 read, write, err = select.select([conn], [], []) 1069 if conn in read: 1070 msg = conn.recv(len(MSG)) 1071 conn.close() 1072 self.assertEqual(msg, MSG) 1073 else: 1074 self.fail("Error during select call to non-blocking socket.") 1075 1076 def _testRecv(self): 1077 self.cli.connect((HOST, self.port)) 1078 time.sleep(0.1) 1079 self.cli.send(MSG) 1080 1081@unittest.skipUnless(thread, 'Threading required for this test.') 1082class FileObjectClassTestCase(SocketConnectedTest): 1083 """Unit tests for the object returned by socket.makefile() 1084 1085 self.read_file is the io object returned by makefile() on 1086 the client connection. You can read from this file to 1087 get output from the server. 1088 1089 self.write_file is the io object returned by makefile() on the 1090 server connection. You can write to this file to send output 1091 to the client. 1092 """ 1093 1094 bufsize = -1 # Use default buffer size 1095 encoding = 'utf-8' 1096 errors = 'strict' 1097 newline = None 1098 1099 read_mode = 'rb' 1100 read_msg = MSG 1101 write_mode = 'wb' 1102 write_msg = MSG 1103 1104 def __init__(self, methodName='runTest'): 1105 SocketConnectedTest.__init__(self, methodName=methodName) 1106 1107 def setUp(self): 1108 self.evt1, self.evt2, self.serv_finished, self.cli_finished = [ 1109 threading.Event() for i in range(4)] 1110 SocketConnectedTest.setUp(self) 1111 self.read_file = self.cli_conn.makefile( 1112 self.read_mode, self.bufsize, 1113 encoding = self.encoding, 1114 errors = self.errors, 1115 newline = self.newline) 1116 1117 def tearDown(self): 1118 self.serv_finished.set() 1119 self.read_file.close() 1120 self.assertTrue(self.read_file.closed) 1121 self.read_file = None 1122 SocketConnectedTest.tearDown(self) 1123 1124 def clientSetUp(self): 1125 SocketConnectedTest.clientSetUp(self) 1126 self.write_file = self.serv_conn.makefile( 1127 self.write_mode, self.bufsize, 1128 encoding = self.encoding, 1129 errors = self.errors, 1130 newline = self.newline) 1131 1132 def clientTearDown(self): 1133 self.cli_finished.set() 1134 self.write_file.close() 1135 self.assertTrue(self.write_file.closed) 1136 self.write_file = None 1137 SocketConnectedTest.clientTearDown(self) 1138 1139 def testReadAfterTimeout(self): 1140 # Issue #7322: A file object must disallow further reads 1141 # after a timeout has occurred. 1142 self.cli_conn.settimeout(1) 1143 self.read_file.read(3) 1144 # First read raises a timeout 1145 self.assertRaises(socket.timeout, self.read_file.read, 1) 1146 # Second read is disallowed 1147 with self.assertRaises(IOError) as ctx: 1148 self.read_file.read(1) 1149 self.assertIn("cannot read from timed out object", str(ctx.exception)) 1150 1151 def _testReadAfterTimeout(self): 1152 self.write_file.write(self.write_msg[0:3]) 1153 self.write_file.flush() 1154 self.serv_finished.wait() 1155 1156 def testSmallRead(self): 1157 # Performing small file read test 1158 first_seg = self.read_file.read(len(self.read_msg)-3) 1159 second_seg = self.read_file.read(3) 1160 msg = first_seg + second_seg 1161 self.assertEqual(msg, self.read_msg) 1162 1163 def _testSmallRead(self): 1164 self.write_file.write(self.write_msg) 1165 self.write_file.flush() 1166 1167 def testFullRead(self): 1168 # read until EOF 1169 msg = self.read_file.read() 1170 self.assertEqual(msg, self.read_msg) 1171 1172 def _testFullRead(self): 1173 self.write_file.write(self.write_msg) 1174 self.write_file.close() 1175 1176 def testUnbufferedRead(self): 1177 # Performing unbuffered file read test 1178 buf = type(self.read_msg)() 1179 while 1: 1180 char = self.read_file.read(1) 1181 if not char: 1182 break 1183 buf += char 1184 self.assertEqual(buf, self.read_msg) 1185 1186 def _testUnbufferedRead(self): 1187 self.write_file.write(self.write_msg) 1188 self.write_file.flush() 1189 1190 def testReadline(self): 1191 # Performing file readline test 1192 line = self.read_file.readline() 1193 self.assertEqual(line, self.read_msg) 1194 1195 def _testReadline(self): 1196 self.write_file.write(self.write_msg) 1197 self.write_file.flush() 1198 1199 def testCloseAfterMakefile(self): 1200 # The file returned by makefile should keep the socket open. 1201 self.cli_conn.close() 1202 # read until EOF 1203 msg = self.read_file.read() 1204 self.assertEqual(msg, self.read_msg) 1205 1206 def _testCloseAfterMakefile(self): 1207 self.write_file.write(self.write_msg) 1208 self.write_file.flush() 1209 1210 def testMakefileAfterMakefileClose(self): 1211 self.read_file.close() 1212 msg = self.cli_conn.recv(len(MSG)) 1213 if isinstance(self.read_msg, str): 1214 msg = msg.decode() 1215 self.assertEqual(msg, self.read_msg) 1216 1217 def _testMakefileAfterMakefileClose(self): 1218 self.write_file.write(self.write_msg) 1219 self.write_file.flush() 1220 1221 def testClosedAttr(self): 1222 self.assertTrue(not self.read_file.closed) 1223 1224 def _testClosedAttr(self): 1225 self.assertTrue(not self.write_file.closed) 1226 1227 def testAttributes(self): 1228 self.assertEqual(self.read_file.mode, self.read_mode) 1229 self.assertEqual(self.read_file.name, self.cli_conn.fileno()) 1230 1231 def _testAttributes(self): 1232 self.assertEqual(self.write_file.mode, self.write_mode) 1233 self.assertEqual(self.write_file.name, self.serv_conn.fileno()) 1234 1235 def testRealClose(self): 1236 self.read_file.close() 1237 self.assertRaises(ValueError, self.read_file.fileno) 1238 self.cli_conn.close() 1239 self.assertRaises(socket.error, self.cli_conn.getsockname) 1240 1241 def _testRealClose(self): 1242 pass 1243 1244 1245class FileObjectInterruptedTestCase(unittest.TestCase): 1246 """Test that the file object correctly handles EINTR internally.""" 1247 1248 class MockSocket(object): 1249 def __init__(self, recv_funcs=()): 1250 # A generator that returns callables that we'll call for each 1251 # call to recv(). 1252 self._recv_step = iter(recv_funcs) 1253 1254 def recv_into(self, buffer): 1255 data = next(self._recv_step)() 1256 assert len(buffer) >= len(data) 1257 buffer[:len(data)] = data 1258 return len(data) 1259 1260 def _decref_socketios(self): 1261 pass 1262 1263 def _textiowrap_for_test(self, buffering=-1): 1264 raw = socket.SocketIO(self, "r") 1265 if buffering < 0: 1266 buffering = io.DEFAULT_BUFFER_SIZE 1267 if buffering == 0: 1268 return raw 1269 buffer = io.BufferedReader(raw, buffering) 1270 text = io.TextIOWrapper(buffer, None, None) 1271 text.mode = "rb" 1272 return text 1273 1274 @staticmethod 1275 def _raise_eintr(): 1276 raise socket.error(errno.EINTR) 1277 1278 def _textiowrap_mock_socket(self, mock, buffering=-1): 1279 raw = socket.SocketIO(mock, "r") 1280 if buffering < 0: 1281 buffering = io.DEFAULT_BUFFER_SIZE 1282 if buffering == 0: 1283 return raw 1284 buffer = io.BufferedReader(raw, buffering) 1285 text = io.TextIOWrapper(buffer, None, None) 1286 text.mode = "rb" 1287 return text 1288 1289 def _test_readline(self, size=-1, buffering=-1): 1290 mock_sock = self.MockSocket(recv_funcs=[ 1291 lambda : b"This is the first line\nAnd the sec", 1292 self._raise_eintr, 1293 lambda : b"ond line is here\n", 1294 lambda : b"", 1295 lambda : b"", # XXX(gps): io library does an extra EOF read 1296 ]) 1297 fo = mock_sock._textiowrap_for_test(buffering=buffering) 1298 self.assertEqual(fo.readline(size), "This is the first line\n") 1299 self.assertEqual(fo.readline(size), "And the second line is here\n") 1300 1301 def _test_read(self, size=-1, buffering=-1): 1302 mock_sock = self.MockSocket(recv_funcs=[ 1303 lambda : b"This is the first line\nAnd the sec", 1304 self._raise_eintr, 1305 lambda : b"ond line is here\n", 1306 lambda : b"", 1307 lambda : b"", # XXX(gps): io library does an extra EOF read 1308 ]) 1309 expecting = (b"This is the first line\n" 1310 b"And the second line is here\n") 1311 fo = mock_sock._textiowrap_for_test(buffering=buffering) 1312 if buffering == 0: 1313 data = b'' 1314 else: 1315 data = '' 1316 expecting = expecting.decode('utf-8') 1317 while len(data) != len(expecting): 1318 part = fo.read(size) 1319 if not part: 1320 break 1321 data += part 1322 self.assertEqual(data, expecting) 1323 1324 def test_default(self): 1325 self._test_readline() 1326 self._test_readline(size=100) 1327 self._test_read() 1328 self._test_read(size=100) 1329 1330 def test_with_1k_buffer(self): 1331 self._test_readline(buffering=1024) 1332 self._test_readline(size=100, buffering=1024) 1333 self._test_read(buffering=1024) 1334 self._test_read(size=100, buffering=1024) 1335 1336 def _test_readline_no_buffer(self, size=-1): 1337 mock_sock = self.MockSocket(recv_funcs=[ 1338 lambda : b"a", 1339 lambda : b"\n", 1340 lambda : b"B", 1341 self._raise_eintr, 1342 lambda : b"b", 1343 lambda : b"", 1344 ]) 1345 fo = mock_sock._textiowrap_for_test(buffering=0) 1346 self.assertEqual(fo.readline(size), b"a\n") 1347 self.assertEqual(fo.readline(size), b"Bb") 1348 1349 def test_no_buffer(self): 1350 self._test_readline_no_buffer() 1351 self._test_readline_no_buffer(size=4) 1352 self._test_read(buffering=0) 1353 self._test_read(size=100, buffering=0) 1354 1355 1356class UnbufferedFileObjectClassTestCase(FileObjectClassTestCase): 1357 1358 """Repeat the tests from FileObjectClassTestCase with bufsize==0. 1359 1360 In this case (and in this case only), it should be possible to 1361 create a file object, read a line from it, create another file 1362 object, read another line from it, without loss of data in the 1363 first file object's buffer. Note that http.client relies on this 1364 when reading multiple requests from the same socket.""" 1365 1366 bufsize = 0 # Use unbuffered mode 1367 1368 def testUnbufferedReadline(self): 1369 # Read a line, create a new file object, read another line with it 1370 line = self.read_file.readline() # first line 1371 self.assertEqual(line, b"A. " + self.write_msg) # first line 1372 self.read_file = self.cli_conn.makefile('rb', 0) 1373 line = self.read_file.readline() # second line 1374 self.assertEqual(line, b"B. " + self.write_msg) # second line 1375 1376 def _testUnbufferedReadline(self): 1377 self.write_file.write(b"A. " + self.write_msg) 1378 self.write_file.write(b"B. " + self.write_msg) 1379 self.write_file.flush() 1380 1381 def testMakefileClose(self): 1382 # The file returned by makefile should keep the socket open... 1383 self.cli_conn.close() 1384 msg = self.cli_conn.recv(1024) 1385 self.assertEqual(msg, self.read_msg) 1386 # ...until the file is itself closed 1387 self.read_file.close() 1388 self.assertRaises(socket.error, self.cli_conn.recv, 1024) 1389 1390 def _testMakefileClose(self): 1391 self.write_file.write(self.write_msg) 1392 self.write_file.flush() 1393 1394 def testMakefileCloseSocketDestroy(self): 1395 refcount_before = sys.getrefcount(self.cli_conn) 1396 self.read_file.close() 1397 refcount_after = sys.getrefcount(self.cli_conn) 1398 self.assertEqual(refcount_before - 1, refcount_after) 1399 1400 def _testMakefileCloseSocketDestroy(self): 1401 pass 1402 1403 # Non-blocking ops 1404 # NOTE: to set `read_file` as non-blocking, we must call 1405 # `cli_conn.setblocking` and vice-versa (see setUp / clientSetUp). 1406 1407 def testSmallReadNonBlocking(self): 1408 self.cli_conn.setblocking(False) 1409 self.assertEqual(self.read_file.readinto(bytearray(10)), None) 1410 self.assertEqual(self.read_file.read(len(self.read_msg) - 3), None) 1411 self.evt1.set() 1412 self.evt2.wait(1.0) 1413 first_seg = self.read_file.read(len(self.read_msg) - 3) 1414 buf = bytearray(10) 1415 n = self.read_file.readinto(buf) 1416 self.assertEqual(n, 3) 1417 msg = first_seg + buf[:n] 1418 self.assertEqual(msg, self.read_msg) 1419 self.assertEqual(self.read_file.readinto(bytearray(16)), None) 1420 self.assertEqual(self.read_…
Large files files are truncated, but you can click here to view the full file