PageRenderTime 97ms CodeModel.GetById 3ms app.highlight 81ms RepoModel.GetById 2ms app.codeStats 0ms

/Lib/test/test_socket.py

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

Large files files are truncated, but you can click here to view the full file