PageRenderTime 112ms CodeModel.GetById 3ms app.highlight 97ms RepoModel.GetById 1ms app.codeStats 1ms

/Lib/test/test_socket.py

https://bitbucket.org/python_mirrors/sandbox-guido
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