PageRenderTime 157ms CodeModel.GetById 4ms app.highlight 135ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/test/test_socket.py

https://bitbucket.org/shashank/jython
Python | 2508 lines | 2249 code | 155 blank | 104 comment | 137 complexity | 8b43af09cc79562df502e66d3bd8843e MD5 | raw file
   1import java
   2
   3import unittest
   4from test import test_support
   5
   6import errno
   7import jarray
   8import Queue
   9import platform
  10import select
  11import socket
  12import struct
  13import sys
  14import time
  15import thread, threading
  16from weakref import proxy
  17from StringIO import StringIO
  18
  19PORT = 50100
  20HOST = 'localhost'
  21MSG = 'Michael Gilfix was here\n'
  22EIGHT_BIT_MSG = 'Bh\xed Al\xe1in \xd3 Cinn\xe9ide anseo\n'
  23os_name = platform.java_ver()[3][0]
  24is_bsd = os_name == 'Mac OS X' or 'BSD' in os_name
  25is_solaris = os_name == 'SunOS'
  26
  27class SocketTCPTest(unittest.TestCase):
  28
  29    HOST = HOST
  30    PORT = PORT
  31
  32    def setUp(self):
  33        self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  34        self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  35        self.serv.bind((self.HOST, self.PORT))
  36        self.serv.listen(1)
  37
  38    def tearDown(self):
  39        self.serv.close()
  40        self.serv = None
  41
  42class SocketUDPTest(unittest.TestCase):
  43
  44    HOST = HOST
  45    PORT = PORT
  46
  47    def setUp(self):
  48        self.serv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  49        self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  50        self.serv.bind((self.HOST, self.PORT))
  51
  52    def tearDown(self):
  53        self.serv.close()
  54        self.serv = None
  55
  56class ThreadableTest:
  57    """Threadable Test class
  58
  59    The ThreadableTest class makes it easy to create a threaded
  60    client/server pair from an existing unit test. To create a
  61    new threaded class from an existing unit test, use multiple
  62    inheritance:
  63
  64        class NewClass (OldClass, ThreadableTest):
  65            pass
  66
  67    This class defines two new fixture functions with obvious
  68    purposes for overriding:
  69
  70        clientSetUp ()
  71        clientTearDown ()
  72
  73    Any new test functions within the class must then define
  74    tests in pairs, where the test name is preceeded with a
  75    '_' to indicate the client portion of the test. Ex:
  76
  77        def testFoo(self):
  78            # Server portion
  79
  80        def _testFoo(self):
  81            # Client portion
  82
  83    Any exceptions raised by the clients during their tests
  84    are caught and transferred to the main thread to alert
  85    the testing framework.
  86
  87    Note, the server setup function cannot call any blocking
  88    functions that rely on the client thread during setup,
  89    unless serverExplicityReady() is called just before
  90    the blocking call (such as in setting up a client/server
  91    connection and performing the accept() in setUp().
  92    """
  93
  94    def __init__(self):
  95        # Swap the true setup function
  96        self.__setUp = self.setUp
  97        self.__tearDown = self.tearDown
  98        self.setUp = self._setUp
  99        self.tearDown = self._tearDown
 100
 101    def serverExplicitReady(self):
 102        """This method allows the server to explicitly indicate that
 103        it wants the client thread to proceed. This is useful if the
 104        server is about to execute a blocking routine that is
 105        dependent upon the client thread during its setup routine."""
 106        self.server_ready.set()
 107
 108    def _setUp(self):
 109        self.server_ready = threading.Event()
 110        self.client_ready = threading.Event()
 111        self.done = threading.Event()
 112        self.queue = Queue.Queue(1)
 113
 114        # Do some munging to start the client test.
 115        methodname = self.id()
 116        i = methodname.rfind('.')
 117        methodname = methodname[i+1:]
 118        self.test_method_name = methodname
 119        test_method = getattr(self, '_' + methodname)
 120        self.client_thread = thread.start_new_thread(
 121            self.clientRun, (test_method,))
 122
 123        self.__setUp()
 124        if not self.server_ready.isSet():
 125            self.server_ready.set()
 126        self.client_ready.wait()
 127
 128    def _tearDown(self):
 129        self.done.wait()
 130        self.__tearDown()
 131
 132        if not self.queue.empty():
 133            msg = self.queue.get()
 134            self.fail(msg)
 135
 136    def clientRun(self, test_func):
 137        self.server_ready.wait()
 138        self.client_ready.set()
 139        self.clientSetUp()
 140        if not callable(test_func):
 141            raise TypeError, "test_func must be a callable function"
 142        try:
 143            test_func()
 144        except Exception, strerror:
 145            self.queue.put(strerror)
 146        self.clientTearDown()
 147
 148    def clientSetUp(self):
 149        raise NotImplementedError, "clientSetUp must be implemented."
 150
 151    def clientTearDown(self):
 152        self.done.set()
 153        if sys.platform[:4] != 'java':
 154            # This causes the whole process to exit on jython
 155            # Probably related to problems with daemon status of threads
 156            thread.exit()
 157
 158class ThreadedTCPSocketTest(SocketTCPTest, ThreadableTest):
 159
 160    def __init__(self, methodName='runTest'):
 161        SocketTCPTest.__init__(self, methodName=methodName)
 162        ThreadableTest.__init__(self)
 163
 164    def clientSetUp(self):
 165        self.cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 166        self.cli.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 167
 168    def clientTearDown(self):
 169        self.cli.close()
 170        self.cli = None
 171        ThreadableTest.clientTearDown(self)
 172
 173class ThreadedUDPSocketTest(SocketUDPTest, ThreadableTest):
 174
 175    def __init__(self, methodName='runTest'):
 176        SocketUDPTest.__init__(self, methodName=methodName)
 177        ThreadableTest.__init__(self)
 178
 179    def clientSetUp(self):
 180        self.cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 181        self.cli.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 182
 183class SocketConnectedTest(ThreadedTCPSocketTest):
 184
 185    def __init__(self, methodName='runTest'):
 186        ThreadedTCPSocketTest.__init__(self, methodName=methodName)
 187
 188    def setUp(self):
 189        ThreadedTCPSocketTest.setUp(self)
 190        # Indicate explicitly we're ready for the client thread to
 191        # proceed and then perform the blocking call to accept
 192        self.serverExplicitReady()
 193        conn, addr = self.serv.accept()
 194        self.cli_conn = conn
 195
 196    def tearDown(self):
 197        self.cli_conn.close()
 198        self.cli_conn = None
 199        ThreadedTCPSocketTest.tearDown(self)
 200
 201    def clientSetUp(self):
 202        ThreadedTCPSocketTest.clientSetUp(self)
 203        self.cli.connect((self.HOST, self.PORT))
 204        self.serv_conn = self.cli
 205
 206    def clientTearDown(self):
 207        self.serv_conn.close()
 208        self.serv_conn = None
 209        ThreadedTCPSocketTest.clientTearDown(self)
 210
 211class SocketPairTest(unittest.TestCase, ThreadableTest):
 212
 213    def __init__(self, methodName='runTest'):
 214        unittest.TestCase.__init__(self, methodName=methodName)
 215        ThreadableTest.__init__(self)
 216
 217    def setUp(self):
 218        self.serv, self.cli = socket.socketpair()
 219
 220    def tearDown(self):
 221        self.serv.close()
 222        self.serv = None
 223
 224    def clientSetUp(self):
 225        pass
 226
 227    def clientTearDown(self):
 228        self.cli.close()
 229        self.cli = None
 230        ThreadableTest.clientTearDown(self)
 231
 232
 233#######################################################################
 234## Begin Tests
 235
 236class GeneralModuleTests(unittest.TestCase):
 237
 238    def test_weakref(self):
 239        if sys.platform[:4] == 'java': return
 240        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 241        p = proxy(s)
 242        self.assertEqual(p.fileno(), s.fileno())
 243        s.close()
 244        s = None
 245        try:
 246            p.fileno()
 247        except ReferenceError:
 248            pass
 249        else:
 250            self.fail('Socket proxy still exists')
 251
 252    def testSocketError(self):
 253        # Testing socket module exceptions
 254        def raise_error(*args, **kwargs):
 255            raise socket.error
 256        def raise_herror(*args, **kwargs):
 257            raise socket.herror
 258        def raise_gaierror(*args, **kwargs):
 259            raise socket.gaierror
 260        self.failUnlessRaises(socket.error, raise_error,
 261                              "Error raising socket exception.")
 262        self.failUnlessRaises(socket.error, raise_herror,
 263                              "Error raising socket exception.")
 264        self.failUnlessRaises(socket.error, raise_gaierror,
 265                              "Error raising socket exception.")
 266
 267    def testCrucialConstants(self):
 268        # Testing for mission critical constants
 269        socket.AF_INET
 270        socket.SOCK_STREAM
 271        socket.SOCK_DGRAM
 272        socket.SOCK_RAW
 273        socket.SOCK_RDM
 274        socket.SOCK_SEQPACKET
 275        socket.SOL_SOCKET
 276        socket.SO_REUSEADDR
 277
 278    def testConstantToNameMapping(self):
 279        # Testing for mission critical constants
 280        for name, expected_name_starts in [
 281            ('IPPROTO_ICMP',  ['IPPROTO_']),
 282            ('IPPROTO_TCP',   ['IPPROTO_']),
 283            ('IPPROTO_UDP',   ['IPPROTO_']),
 284            ('SO_BROADCAST',  ['SO_', 'TCP_']),
 285            ('SO_KEEPALIVE',  ['SO_', 'TCP_']),
 286            ('SO_ACCEPTCONN', ['SO_', 'TCP_']),
 287            ('SO_DEBUG',      ['SO_', 'TCP_']),
 288            ('SOCK_DGRAM',    ['SOCK_']),
 289            ('SOCK_RAW',      ['SOCK_']),
 290            ('SOL_SOCKET',    ['SOL_', 'IPPROTO_']),
 291            ('TCP_NODELAY',   ['SO_', 'TCP_']),
 292            ]:
 293            self.failUnlessEqual(socket._constant_to_name(getattr(socket, name), expected_name_starts), name)
 294
 295    def testHostnameRes(self):
 296        # Testing hostname resolution mechanisms
 297        hostname = socket.gethostname()
 298        self.assert_(isinstance(hostname, str))
 299        try:
 300            ip = socket.gethostbyname(hostname)
 301            self.assert_(isinstance(ip, str))
 302        except socket.error:
 303            # Probably name lookup wasn't set up right; skip this test
 304            self.fail("Probably name lookup wasn't set up right; skip testHostnameRes.gethostbyname")
 305            return
 306        self.assert_(ip.find('.') >= 0, "Error resolving host to ip.")
 307        try:
 308            hname, aliases, ipaddrs = socket.gethostbyaddr(ip)
 309            self.assert_(isinstance(hname, str))
 310            for hosts in aliases, ipaddrs:
 311                self.assert_(all(isinstance(host, str) for host in hosts))
 312        except socket.error:
 313            # Probably a similar problem as above; skip this test
 314            self.fail("Probably name lookup wasn't set up right; skip testHostnameRes.gethostbyaddr")
 315            return
 316        all_host_names = [hostname, hname] + aliases
 317        fqhn = socket.getfqdn()
 318        self.assert_(isinstance(fqhn, str))
 319        if not fqhn in all_host_names:
 320            self.fail("Error testing host resolution mechanisms.")
 321
 322    def testRefCountGetNameInfo(self):
 323        # Testing reference count for getnameinfo
 324        import sys
 325        if hasattr(sys, "getrefcount"):
 326            try:
 327                # On some versions, this loses a reference
 328                orig = sys.getrefcount(__name__)
 329                socket.getnameinfo(__name__,0)
 330            except SystemError:
 331                if sys.getrefcount(__name__) <> orig:
 332                    self.fail("socket.getnameinfo loses a reference")
 333
 334    def testInterpreterCrash(self):
 335        if sys.platform[:4] == 'java': return
 336        # Making sure getnameinfo doesn't crash the interpreter
 337        try:
 338            # On some versions, this crashes the interpreter.
 339            socket.getnameinfo(('x', 0, 0, 0), 0)
 340        except socket.error:
 341            pass
 342
 343# Need to implement binary AND for ints and longs
 344
 345    def testNtoH(self):
 346        if sys.platform[:4] == 'java': return # problems with int & long
 347        # This just checks that htons etc. are their own inverse,
 348        # when looking at the lower 16 or 32 bits.
 349        sizes = {socket.htonl: 32, socket.ntohl: 32,
 350                 socket.htons: 16, socket.ntohs: 16}
 351        for func, size in sizes.items():
 352            mask = (1L<<size) - 1
 353            for i in (0, 1, 0xffff, ~0xffff, 2, 0x01234567, 0x76543210):
 354                self.assertEqual(i & mask, func(func(i&mask)) & mask)
 355
 356            swapped = func(mask)
 357            self.assertEqual(swapped & mask, mask)
 358            self.assertRaises(OverflowError, func, 1L<<34)
 359
 360    def testGetServBy(self):
 361        eq = self.assertEqual
 362        # Find one service that exists, then check all the related interfaces.
 363        # I've ordered this by protocols that have both a tcp and udp
 364        # protocol, at least for modern Linuxes.
 365        if sys.platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6',
 366                            'darwin') or is_bsd:
 367            # avoid the 'echo' service on this platform, as there is an
 368            # assumption breaking non-standard port/protocol entry
 369            services = ('daytime', 'qotd', 'domain')
 370        else:
 371            services = ('echo', 'daytime', 'domain')
 372        for service in services:
 373            try:
 374                port = socket.getservbyname(service, 'tcp')
 375                break
 376            except socket.error:
 377                pass
 378        else:
 379            raise socket.error
 380        # Try same call with optional protocol omitted
 381        port2 = socket.getservbyname(service)
 382        eq(port, port2)
 383        # Try udp, but don't barf it it doesn't exist
 384        try:
 385            udpport = socket.getservbyname(service, 'udp')
 386        except socket.error:
 387            udpport = None
 388        else:
 389            eq(udpport, port)
 390        # Now make sure the lookup by port returns the same service name
 391        eq(socket.getservbyport(port2), service)
 392        eq(socket.getservbyport(port, 'tcp'), service)
 393        if udpport is not None:
 394            eq(socket.getservbyport(udpport, 'udp'), service)
 395
 396    def testGetServByExceptions(self):
 397        # First getservbyname
 398        try:
 399            result = socket.getservbyname("nosuchservice")
 400        except socket.error:
 401            pass
 402        except Exception, x:
 403            self.fail("getservbyname raised wrong exception for non-existent service: %s" % str(x))
 404        else:
 405            self.fail("getservbyname failed to raise exception for non-existent service: %s" % str(result))
 406
 407        # Now getservbyport
 408        try:
 409            result = socket.getservbyport(55555)
 410        except socket.error:
 411            pass
 412        except Exception, x:
 413            self.fail("getservbyport raised wrong exception for unknown port: %s" % str(x))
 414        else:
 415            self.fail("getservbyport failed to raise exception for unknown port: %s" % str(result))
 416
 417    def testGetProtoByName(self):
 418        self.failUnlessEqual(socket.IPPROTO_TCP, socket.getprotobyname("tcp"))
 419        self.failUnlessEqual(socket.IPPROTO_UDP, socket.getprotobyname("udp"))
 420        try:
 421            result = socket.getprotobyname("nosuchproto")
 422        except socket.error:
 423            pass
 424        except Exception, x:
 425            self.fail("getprotobyname raised wrong exception for unknown protocol: %s" % str(x))
 426        else:
 427            self.fail("getprotobyname failed to raise exception for unknown protocol: %s" % str(result))
 428
 429    def testDefaultTimeout(self):
 430        # Testing default timeout
 431        # The default timeout should initially be None
 432        self.assertEqual(socket.getdefaulttimeout(), None)
 433        s = socket.socket()
 434        self.assertEqual(s.gettimeout(), None)
 435        s.close()
 436
 437        # Set the default timeout to 10, and see if it propagates
 438        socket.setdefaulttimeout(10)
 439        self.assertEqual(socket.getdefaulttimeout(), 10)
 440        s = socket.socket()
 441        self.assertEqual(s.gettimeout(), 10)
 442        s.close()
 443
 444        # Reset the default timeout to None, and see if it propagates
 445        socket.setdefaulttimeout(None)
 446        self.assertEqual(socket.getdefaulttimeout(), None)
 447        s = socket.socket()
 448        self.assertEqual(s.gettimeout(), None)
 449        s.close()
 450
 451        # Check that setting it to an invalid value raises ValueError
 452        self.assertRaises(ValueError, socket.setdefaulttimeout, -1)
 453
 454        # Check that setting it to an invalid type raises TypeError
 455        self.assertRaises(TypeError, socket.setdefaulttimeout, "spam")
 456
 457    def testIPv4toString(self):
 458        if not hasattr(socket, 'inet_pton'):
 459            return # No inet_pton() on this platform
 460        from socket import inet_aton as f, inet_pton, AF_INET
 461        g = lambda a: inet_pton(AF_INET, a)
 462
 463        self.assertEquals('\x00\x00\x00\x00', f('0.0.0.0'))
 464        self.assertEquals('\xff\x00\xff\x00', f('255.0.255.0'))
 465        self.assertEquals('\xaa\xaa\xaa\xaa', f('170.170.170.170'))
 466        self.assertEquals('\x01\x02\x03\x04', f('1.2.3.4'))
 467
 468        self.assertEquals('\x00\x00\x00\x00', g('0.0.0.0'))
 469        self.assertEquals('\xff\x00\xff\x00', g('255.0.255.0'))
 470        self.assertEquals('\xaa\xaa\xaa\xaa', g('170.170.170.170'))
 471
 472    def testIPv6toString(self):
 473        if not hasattr(socket, 'inet_pton'):
 474            return # No inet_pton() on this platform
 475        try:
 476            from socket import inet_pton, AF_INET6, has_ipv6
 477            if not has_ipv6:
 478                return
 479        except ImportError:
 480            return
 481        f = lambda a: inet_pton(AF_INET6, a)
 482
 483        self.assertEquals('\x00' * 16, f('::'))
 484        self.assertEquals('\x00' * 16, f('0::0'))
 485        self.assertEquals('\x00\x01' + '\x00' * 14, f('1::'))
 486        self.assertEquals(
 487            '\x45\xef\x76\xcb\x00\x1a\x56\xef\xaf\xeb\x0b\xac\x19\x24\xae\xae',
 488            f('45ef:76cb:1a:56ef:afeb:bac:1924:aeae')
 489        )
 490
 491    def test_inet_pton_exceptions(self):
 492        if not hasattr(socket, 'inet_pton'):
 493            return # No inet_pton() on this platform
 494
 495        try:
 496            socket.inet_pton(socket.AF_UNSPEC, "doesntmatter")
 497        except socket.error, se:
 498            self.failUnlessEqual(se[0], errno.EAFNOSUPPORT)
 499        except Exception, x:
 500            self.fail("inet_pton raised wrong exception for incorrect address family AF_UNSPEC: %s" % str(x))
 501
 502        try:
 503            socket.inet_pton(socket.AF_INET, "1.2.3.")
 504        except socket.error, se:
 505            pass
 506        except Exception, x:
 507            self.fail("inet_pton raised wrong exception for invalid AF_INET address: %s" % str(x))
 508
 509        try:
 510            socket.inet_pton(socket.AF_INET6, ":::")
 511        except socket.error, se:
 512            pass
 513        except Exception, x:
 514            self.fail("inet_pton raised wrong exception for invalid AF_INET6 address: %s" % str(x))
 515
 516    def testStringToIPv4(self):
 517        if not hasattr(socket, 'inet_ntop'):
 518            return # No inet_ntop() on this platform
 519        from socket import inet_ntoa as f, inet_ntop, AF_INET
 520        g = lambda a: inet_ntop(AF_INET, a)
 521
 522        self.assertEquals('1.0.1.0', f('\x01\x00\x01\x00'))
 523        self.assertEquals('170.85.170.85', f('\xaa\x55\xaa\x55'))
 524        self.assertEquals('255.255.255.255', f('\xff\xff\xff\xff'))
 525        self.assertEquals('1.2.3.4', f('\x01\x02\x03\x04'))
 526
 527        self.assertEquals('1.0.1.0', g('\x01\x00\x01\x00'))
 528        self.assertEquals('170.85.170.85', g('\xaa\x55\xaa\x55'))
 529        self.assertEquals('255.255.255.255', g('\xff\xff\xff\xff'))
 530
 531    def testStringToIPv6(self):
 532        if not hasattr(socket, 'inet_ntop'):
 533            return # No inet_ntop() on this platform
 534        try:
 535            from socket import inet_ntop, AF_INET6, has_ipv6
 536            if not has_ipv6:
 537                return
 538        except ImportError:
 539            return
 540        f = lambda a: inet_ntop(AF_INET6, a)
 541
 542#        self.assertEquals('::', f('\x00' * 16))
 543#        self.assertEquals('::1', f('\x00' * 15 + '\x01'))
 544        # java.net.InetAddress always return the full unabbreviated form
 545        self.assertEquals('0:0:0:0:0:0:0:0', f('\x00' * 16))
 546        self.assertEquals('0:0:0:0:0:0:0:1', f('\x00' * 15 + '\x01'))
 547        self.assertEquals(
 548            'aef:b01:506:1001:ffff:9997:55:170',
 549            f('\x0a\xef\x0b\x01\x05\x06\x10\x01\xff\xff\x99\x97\x00\x55\x01\x70')
 550        )
 551
 552    def test_inet_ntop_exceptions(self):
 553        if not hasattr(socket, 'inet_ntop'):
 554            return # No inet_ntop() on this platform
 555        valid_address = '\x01\x01\x01\x01'
 556        invalid_address = '\x01\x01\x01\x01\x01'
 557
 558        try:
 559            socket.inet_ntop(socket.AF_UNSPEC, valid_address)
 560        except ValueError, v:
 561            pass
 562        except Exception, x:
 563            self.fail("inet_ntop raised wrong exception for incorrect address family AF_UNSPEC: %s" % str(x))
 564
 565        try:
 566            socket.inet_ntop(socket.AF_INET, invalid_address)
 567        except ValueError, v:
 568            pass
 569        except Exception, x:
 570            self.fail("inet_ntop raised wrong exception for invalid AF_INET address: %s" % str(x))
 571
 572        try:
 573            socket.inet_ntop(socket.AF_INET6, invalid_address)
 574        except ValueError, v:
 575            pass
 576        except Exception, x:
 577            self.fail("inet_ntop raised wrong exception for invalid AF_INET address: %s" % str(x))
 578
 579    # XXX The following don't test module-level functionality...
 580
 581    def testSockName(self):
 582        # Testing getsockname()
 583        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 584        sock.bind(("0.0.0.0", PORT+1))
 585        name = sock.getsockname()
 586        self.assertEqual(name, ("0.0.0.0", PORT+1))
 587
 588    def testSockAttributes(self):
 589        # Testing required attributes
 590        for family in [socket.AF_INET, socket.AF_INET6]:
 591            for sock_type in [socket.SOCK_STREAM, socket.SOCK_DGRAM]:
 592                s = socket.socket(family, sock_type)
 593                self.assertEqual(s.family, family)
 594                self.assertEqual(s.type, sock_type)
 595                if sock_type == socket.SOCK_STREAM:
 596                    self.assertEqual(s.proto, socket.IPPROTO_TCP)
 597                else:
 598                    self.assertEqual(s.proto, socket.IPPROTO_UDP)
 599
 600    def testGetSockOpt(self):
 601        # Testing getsockopt()
 602        # We know a socket should start without reuse==0
 603        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 604        reuse = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
 605        self.failIf(reuse != 0, "initial mode is reuse")
 606
 607    def testSetSockOpt(self):
 608        # Testing setsockopt()
 609        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 610        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 611        reuse = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
 612        self.failIf(reuse == 0, "failed to set reuse mode")
 613
 614    def testSendAfterClose(self):
 615        # testing send() after close() with timeout
 616        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 617        sock.settimeout(1)
 618        sock.close()
 619        self.assertRaises(socket.error, sock.send, "spam")
 620
 621class IPAddressTests(unittest.TestCase):
 622
 623    def testValidIpV4Addresses(self):
 624        for a in [
 625            "0.0.0.1",
 626            "1.0.0.1",
 627            "127.0.0.1",
 628            "255.12.34.56",
 629            "255.255.255.255",
 630        ]:
 631            self.failUnless(socket.is_ipv4_address(a), "is_ipv4_address failed for valid IPV4 address '%s'" % a)
 632            self.failUnless(socket.is_ip_address(a), "is_ip_address failed for valid IPV4 address '%s'" % a)
 633            
 634    def testInvalidIpV4Addresses(self):
 635        for a in [
 636            "99.2",
 637            "99.2.4",
 638            "-10.1.2.3",
 639            "256.0.0.0",
 640            "0.256.0.0",
 641            "0.0.256.0",
 642            "0.0.0.256",
 643            "255.24.x.100",
 644            "255.24.-1.128",
 645            "255.24.-1.128.",
 646            "255.0.0.999",
 647        ]:
 648            self.failUnless(not socket.is_ipv4_address(a), "not is_ipv4_address failed for invalid IPV4 address '%s'" % a)
 649            self.failUnless(not socket.is_ip_address(a), "not is_ip_address failed for invalid IPV4 address '%s'" % a)
 650
 651    def testValidIpV6Addresses(self):
 652        for a in [
 653            "::",
 654            "::1",
 655            "fe80::1",
 656            "::192.168.1.1",
 657            "0:0:0:0:0:0:0:0",
 658            "1080::8:800:2C:4A",
 659            "FEC0:0:0:0:0:0:0:1",
 660            "::FFFF:192.168.1.1",
 661            "abcd:ef:111:f123::1",
 662            "1138:0:0:0:8:80:800:417A",
 663            "fecc:face::b00c:f001:fedc:fedd",
 664            "CaFe:BaBe:dEAd:BeeF:12:345:6789:abcd",
 665        ]:
 666            self.failUnless(socket.is_ipv6_address(a), "is_ipv6_address failed for valid IPV6 address '%s'" % a)
 667            self.failUnless(socket.is_ip_address(a), "is_ip_address failed for valid IPV6 address '%s'" % a)
 668            
 669    def testInvalidIpV6Addresses(self):
 670        for a in [
 671            "2001:db8:::192.0.2.1", # from RFC 5954
 672            "CaFe:BaBe:dEAd:BeeF:12:345:6789:abcd:",
 673            "CaFe:BaBe:dEAd:BeeF:12:345:6789:abcd:ef",
 674            "CaFFe:1a77e:dEAd:BeeF:12:345:6789:abcd",
 675        ]:
 676            self.failUnless(not socket.is_ipv6_address(a), "not is_ipv6_address failed for invalid IPV6 address '%s'" % a)
 677            self.failUnless(not socket.is_ip_address(a), "not is_ip_address failed for invalid IPV6 address '%s'" % a)
 678
 679    def testRFC5952(self):
 680        for a in [
 681            "2001:db8::",
 682            "2001:db8::1",
 683            "2001:db8:0::1",
 684            "2001:db8:0:0::1",
 685            "2001:db8:0:0:0::1",
 686            "2001:DB8:0:0:1::1",
 687            "2001:db8:0:0:1::1",
 688            "2001:db8::1:0:0:1",
 689            "2001:0db8::1:0:0:1",
 690            "2001:db8::0:1:0:0:1",
 691            "2001:db8:0:0:1:0:0:1",
 692            "2001:db8:0000:0:1::1",
 693            "2001:db8::aaaa:0:0:1",
 694            "2001:db8:0:0:aaaa::1",
 695            "2001:0db8:0:0:1:0:0:1",
 696            "2001:db8:aaaa:bbbb:cccc:dddd::1",
 697            "2001:db8:aaaa:bbbb:cccc:dddd:0:1",
 698            "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1",
 699            "2001:db8:aaaa:bbbb:cccc:dddd:eeee:01",
 700            "2001:db8:aaaa:bbbb:cccc:dddd:eeee:001",
 701            "2001:db8:aaaa:bbbb:cccc:dddd:eeee:0001",
 702            "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa",
 703            "2001:db8:aaaa:bbbb:cccc:dddd:eeee:AAAA",
 704            "2001:db8:aaaa:bbbb:cccc:dddd:eeee:AaAa",
 705        ]:
 706            self.failUnless(socket.is_ipv6_address(a), "is_ipv6_address failed for valid RFC 5952 IPV6 address '%s'" % a)
 707            self.failUnless(socket.is_ip_address(a), "is_ip_address failed for valid RFC 5952 IPV6 address '%s'" % a)
 708      
 709class TestSocketOptions(unittest.TestCase):
 710
 711    def setUp(self):
 712        self.test_udp = self.test_tcp_client = self.test_tcp_server = 0
 713
 714    def _testSetAndGetOption(self, sock, level, option, values):
 715        for expected_value in values:
 716            sock.setsockopt(level, option, expected_value)
 717            retrieved_value = sock.getsockopt(level, option)
 718            msg = "Retrieved option(%s, %s) value %s != %s(value set)" % (level, option, retrieved_value, expected_value)
 719            if option == socket.SO_RCVBUF:
 720                self.assert_(retrieved_value >= expected_value, msg)
 721            else:
 722                self.failUnlessEqual(retrieved_value, expected_value, msg)
 723
 724    def _testUDPOption(self, level, option, values):
 725        try:
 726            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 727            self._testSetAndGetOption(sock, level, option, values)
 728            # now bind the socket i.e. cause the implementation socket to be created
 729            sock.bind( (HOST, PORT) )
 730            retrieved_option_value = sock.getsockopt(level, option)
 731            self.failUnlessEqual(retrieved_option_value, values[-1], \
 732                 "Option value '(%s, %s)'='%s' did not propagate to implementation socket: got %s" % (level, option, values[-1], retrieved_option_value) )
 733            self._testSetAndGetOption(sock, level, option, values)
 734        finally:
 735            sock.close()
 736
 737    def _testTCPClientOption(self, level, option, values):
 738        sock = None
 739        try:
 740            # First listen on a server socket, so that the connection won't be refused.
 741            server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 742            server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 743            server_sock.bind( (HOST, PORT) )
 744            server_sock.listen(50)
 745            # Now do the tests
 746            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 747            self._testSetAndGetOption(sock, level, option, values)
 748            # now connect the socket i.e. cause the implementation socket to be created
 749            # First bind, so that the SO_REUSEADDR setting propagates
 750            sock.bind( (HOST, PORT+1) )
 751            sock.connect( (HOST, PORT) )
 752            retrieved_option_value = sock.getsockopt(level, option)
 753            msg = "Option value '%s'='%s' did not propagate to implementation socket: got %s" % (option, values[-1], retrieved_option_value)
 754            if option in (socket.SO_RCVBUF, socket.SO_SNDBUF):
 755                # NOTE: there's no guarantee that bufsize will be the
 756                # exact setsockopt value, particularly after
 757                # establishing a connection. seems it will be *at least*
 758                # the values we test (which are rather small) on
 759                # BSDs.
 760                self.assert_(retrieved_option_value >= values[-1], msg)
 761            else:
 762                self.failUnlessEqual(retrieved_option_value, values[-1], msg)
 763            self._testSetAndGetOption(sock, level, option, values)
 764        finally:
 765            server_sock.close()
 766            if sock:
 767                sock.close()
 768
 769    def _testTCPClientInheritedOption(self, level, option, values):
 770        cli_sock = accepted_sock = None
 771        try:
 772            server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 773            server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 774            self._testSetAndGetOption(server_sock, level, option, values)
 775            # now bind and listen on the socket i.e. cause the implementation socket to be created
 776            server_sock.bind( (HOST, PORT) )
 777            server_sock.listen(50)
 778            # Now create client socket to connect to server
 779            cli_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 780            cli_sock.connect( (HOST, PORT) )
 781            accepted_sock = server_sock.accept()[0]
 782            retrieved_option_value = accepted_sock.getsockopt(level, option)
 783            msg = "Option value '(%s,%s)'='%s' did not propagate to accepted socket: got %s" % (level, option, values[-1], retrieved_option_value)
 784            if option == socket.SO_RCVBUF:
 785                # NOTE: see similar bsd/solaris workaround above
 786                self.assert_(retrieved_option_value >= values[-1], msg)
 787            else:
 788                self.failUnlessEqual(retrieved_option_value, values[-1], msg)
 789            self._testSetAndGetOption(accepted_sock, level, option, values)
 790        finally:
 791            server_sock.close()
 792            if cli_sock:
 793                cli_sock.close()
 794            if accepted_sock:
 795                accepted_sock.close()
 796
 797    def _testTCPServerOption(self, level, option, values):
 798        try:
 799            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 800            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 801            self._testSetAndGetOption(sock, level, option, values)
 802            # now bind and listen on the socket i.e. cause the implementation socket to be created
 803            sock.bind( (HOST, PORT) )
 804            sock.listen(50)
 805            retrieved_option_value = sock.getsockopt(level, option)
 806            msg = "Option value '(%s,%s)'='%s' did not propagate to implementation socket. Got %s" % (level, option, values[-1], retrieved_option_value)
 807            if option == socket.SO_RCVBUF:
 808                # NOTE: see similar bsd/solaris workaround above
 809                self.assert_(retrieved_option_value >= values[-1], msg)
 810            else:
 811                self.failUnlessEqual(retrieved_option_value, values[-1], msg)
 812            self._testSetAndGetOption(sock, level, option, values)
 813        finally:
 814            sock.close()
 815
 816    def _testOption(self, level, option, values):
 817        for flag, func in [
 818            (self.test_udp,        self._testUDPOption),
 819            (self.test_tcp_client, self._testTCPClientOption),
 820            (self.test_tcp_server, self._testTCPServerOption),
 821        ]:
 822            if flag:
 823                func(level, option, values)
 824            else:
 825                try:
 826                    func(level, option, values)
 827                except socket.error, se:
 828                    self.failUnlessEqual(se[0], errno.ENOPROTOOPT, "Wrong errno from unsupported option exception: %d" % se[0])
 829                except Exception, x:
 830                    self.fail("Wrong exception raised from unsupported option: %s" % str(x))
 831                else:
 832                    self.fail("Setting unsupported option should have raised an exception")
 833
 834    def _testInheritedOption(self, level, option, values):
 835        try:
 836            self._testTCPClientInheritedOption(level, option, values)
 837        except Exception, x:
 838            self.fail("Inherited option should not have raised exception: %s" % str(x))
 839
 840class TestSupportedOptions(TestSocketOptions):
 841
 842    def testSO_BROADCAST(self):
 843        self.test_udp = 1
 844        self._testOption(socket.SOL_SOCKET, socket.SO_BROADCAST, [0, 1])
 845
 846    def testSO_KEEPALIVE(self):
 847        self.test_tcp_client = 1
 848        self.test_tcp_server = 1
 849        self._testOption(socket.SOL_SOCKET, socket.SO_KEEPALIVE, [0, 1])
 850        self._testInheritedOption(socket.SOL_SOCKET, socket.SO_KEEPALIVE, [0, 1])
 851
 852    def testSO_LINGER(self):
 853        self.test_tcp_client = 1
 854        self.test_tcp_server = 1
 855        off = struct.pack('ii', 0, 0)
 856        on_2_seconds = struct.pack('ii', 1, 2)
 857        self._testOption(socket.SOL_SOCKET, socket.SO_LINGER, [off, on_2_seconds])
 858        self._testInheritedOption(socket.SOL_SOCKET, socket.SO_LINGER, [off, on_2_seconds])
 859
 860    def testSO_OOBINLINE(self):
 861        self.test_tcp_client = 1
 862        self.test_tcp_server = 1
 863        self._testOption(socket.SOL_SOCKET, socket.SO_OOBINLINE, [0, 1])
 864        self._testInheritedOption(socket.SOL_SOCKET, socket.SO_OOBINLINE, [0, 1])
 865
 866    def testSO_RCVBUF(self):
 867        self.test_udp        = 1
 868        self.test_tcp_client = 1
 869        self.test_tcp_server = 1
 870        self._testOption(socket.SOL_SOCKET, socket.SO_RCVBUF, [1024, 4096, 16384])
 871        self._testInheritedOption(socket.SOL_SOCKET, socket.SO_RCVBUF, [1024, 4096, 16384])
 872
 873    def testSO_REUSEADDR(self):
 874        self.test_udp        = 1
 875        self.test_tcp_client = 1
 876        self.test_tcp_server = 1
 877        self._testOption(socket.SOL_SOCKET, socket.SO_REUSEADDR, [0, 1])
 878        self._testInheritedOption(socket.SOL_SOCKET, socket.SO_REUSEADDR, [0, 1])
 879
 880    def testSO_SNDBUF(self):
 881        self.test_udp        = 1
 882        self.test_tcp_client = 1
 883        self.test_tcp_server = 1
 884        self._testOption(socket.SOL_SOCKET, socket.SO_SNDBUF, [1024, 4096, 16384])
 885        self._testInheritedOption(socket.SOL_SOCKET, socket.SO_SNDBUF, [1024, 4096, 16384])
 886
 887    def testSO_TIMEOUT(self):
 888        self.test_udp        = 1
 889        self.test_tcp_client = 1
 890        self.test_tcp_server = 1
 891        self._testOption(socket.SOL_SOCKET, socket.SO_TIMEOUT, [0, 1, 1000])
 892        # We don't test inheritance here because both server and client sockets have SO_TIMEOUT
 893        # but it doesn't inherit.
 894
 895    def testTCP_NODELAY(self):
 896        self.test_tcp_client = 1
 897        self.test_tcp_server = 1
 898        self._testOption(socket.IPPROTO_TCP, socket.TCP_NODELAY, [0, 1])
 899        self._testInheritedOption(socket.IPPROTO_TCP, socket.TCP_NODELAY, [0, 1])
 900
 901class TestPseudoOptions(unittest.TestCase):
 902
 903    def testSO_ACCEPTCONN(self):
 904        for socket_type, listen, expected_result in [
 905            (socket.SOCK_STREAM, 0, 0),
 906            (socket.SOCK_STREAM, 1, 1),
 907            (socket.SOCK_DGRAM,   0, Exception),
 908            ]:
 909            s = socket.socket(socket.AF_INET, socket_type)
 910            if listen:
 911                s.listen(1)
 912            try:
 913                result = s.getsockopt(socket.SOL_SOCKET, socket.SO_ACCEPTCONN)
 914                if expected_result is not Exception:
 915                    self.failUnlessEqual(result, expected_result)
 916            except socket.error, se:
 917                if expected_result is Exception:
 918                    if se[0] != errno.ENOPROTOOPT:
 919                        self.fail("getsockopt(SO_ACCEPTCONN) on wrong socket type raised wrong exception: %s" % str(se))
 920                else:
 921                    self.fail("getsocket(SO_ACCEPTCONN) on valid socket type should not have raised exception: %s" % (str(se)))
 922
 923    def testSO_ERROR(self):
 924        for socket_type in [socket.SOCK_STREAM, socket.SOCK_DGRAM]:
 925            s = socket.socket(socket.AF_INET, socket_type)
 926            self.failUnlessEqual(s.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR), 0)
 927            try:
 928                # Now cause an error
 929                s.connect(("localhost", 100000))
 930                self.fail("Operation '%s' that should have failed to generate SO_ERROR did not" % operation)
 931            except socket.error, se:
 932                so_error = s.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
 933                self.failUnlessEqual(so_error, se[0])
 934            # Now retrieve the option again - it should be zero
 935            self.failUnlessEqual(s.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR), 0)
 936
 937    def testSO_TYPE(self):
 938        for socket_type in [socket.SOCK_STREAM, socket.SOCK_DGRAM]:
 939            s = socket.socket(socket.AF_INET, socket_type)
 940            self.failUnlessEqual(s.getsockopt(socket.SOL_SOCKET, socket.SO_TYPE), socket_type)
 941
 942class TestUnsupportedOptions(TestSocketOptions):
 943
 944    def testSO_DEBUG(self):
 945        self.failUnless(hasattr(socket, 'SO_DEBUG'))
 946
 947    def testSO_DONTROUTE(self):
 948        self.failUnless(hasattr(socket, 'SO_DONTROUTE'))
 949
 950    def testSO_EXCLUSIVEADDRUSE(self):
 951        # this is an MS specific option that will not be appearing on java
 952        # http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6421091
 953        # http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6402335
 954        self.failUnless(hasattr(socket, 'SO_EXCLUSIVEADDRUSE'))
 955
 956    def testSO_RCVLOWAT(self):
 957        self.failUnless(hasattr(socket, 'SO_RCVLOWAT'))
 958
 959    def testSO_RCVTIMEO(self):
 960        self.failUnless(hasattr(socket, 'SO_RCVTIMEO'))
 961
 962    def testSO_REUSEPORT(self):
 963        # not yet supported on java
 964        # http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6432031
 965        self.failUnless(hasattr(socket, 'SO_REUSEPORT'))
 966
 967    def testSO_SNDLOWAT(self):
 968        self.failUnless(hasattr(socket, 'SO_SNDLOWAT'))
 969
 970    def testSO_SNDTIMEO(self):
 971        self.failUnless(hasattr(socket, 'SO_SNDTIMEO'))
 972
 973    def testSO_USELOOPBACK(self):
 974        self.failUnless(hasattr(socket, 'SO_USELOOPBACK'))
 975
 976class BasicTCPTest(SocketConnectedTest):
 977
 978    def __init__(self, methodName='runTest'):
 979        SocketConnectedTest.__init__(self, methodName=methodName)
 980
 981    def testRecv(self):
 982        # Testing large receive over TCP
 983        msg = self.cli_conn.recv(1024)
 984        self.assertEqual(msg, MSG)
 985
 986    def _testRecv(self):
 987        self.serv_conn.send(MSG)
 988
 989    def testRecvTimeoutMode(self):
 990        # Do this test in timeout mode, because the code path is different
 991        self.cli_conn.settimeout(10)
 992        msg = self.cli_conn.recv(1024)
 993        self.assertEqual(msg, MSG)
 994
 995    def _testRecvTimeoutMode(self):
 996        self.serv_conn.settimeout(10)
 997        self.serv_conn.send(MSG)
 998
 999    def testOverFlowRecv(self):
1000        # Testing receive in chunks over TCP
1001        seg1 = self.cli_conn.recv(len(MSG) - 3)
1002        seg2 = self.cli_conn.recv(1024)
1003        msg = seg1 + seg2
1004        self.assertEqual(msg, MSG)
1005
1006    def _testOverFlowRecv(self):
1007        self.serv_conn.send(MSG)
1008
1009    def testRecvFrom(self):
1010        # Testing large recvfrom() over TCP
1011        msg, addr = self.cli_conn.recvfrom(1024)
1012        self.assertEqual(msg, MSG)
1013
1014    def _testRecvFrom(self):
1015        self.serv_conn.send(MSG)
1016
1017    def testOverFlowRecvFrom(self):
1018        # Testing recvfrom() in chunks over TCP
1019        seg1, addr = self.cli_conn.recvfrom(len(MSG)-3)
1020        seg2, addr = self.cli_conn.recvfrom(1024)
1021        msg = seg1 + seg2
1022        self.assertEqual(msg, MSG)
1023
1024    def _testOverFlowRecvFrom(self):
1025        self.serv_conn.send(MSG)
1026
1027    def testSendAll(self):
1028        # Testing sendall() with a 2048 byte string over TCP
1029        msg = ''
1030        while 1:
1031            read = self.cli_conn.recv(1024)
1032            if not read:
1033                break
1034            msg += read
1035        self.assertEqual(msg, 'f' * 2048)
1036
1037    def _testSendAll(self):
1038        big_chunk = 'f' * 2048
1039        self.serv_conn.sendall(big_chunk)
1040
1041    def testFromFd(self):
1042        # Testing fromfd()
1043        if not hasattr(socket, "fromfd"):
1044            return # On Windows, this doesn't exist
1045        fd = self.cli_conn.fileno()
1046        sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
1047        msg = sock.recv(1024)
1048        self.assertEqual(msg, MSG)
1049
1050    def _testFromFd(self):
1051        self.serv_conn.send(MSG)
1052
1053    def testShutdown(self):
1054        # Testing shutdown()
1055        msg = self.cli_conn.recv(1024)
1056        self.assertEqual(msg, MSG)
1057
1058    def _testShutdown(self):
1059        self.serv_conn.send(MSG)
1060        self.serv_conn.shutdown(2)
1061
1062    def testSendAfterRemoteClose(self):
1063        self.cli_conn.close()
1064
1065    def _testSendAfterRemoteClose(self):
1066        for x in range(5):
1067            try:
1068                self.serv_conn.send("spam")
1069            except socket.error, se:
1070                self.failUnlessEqual(se[0], errno.ECONNRESET)
1071                return
1072            except Exception, x:
1073                self.fail("Sending on remotely closed socket raised wrong exception: %s" % x)
1074            time.sleep(0.5)
1075        self.fail("Sending on remotely closed socket should have raised exception")
1076
1077    def testDup(self):
1078        msg = self.cli_conn.recv(len(MSG))
1079        self.assertEqual(msg, MSG)
1080
1081        dup_conn = self.cli_conn.dup()
1082        msg = dup_conn.recv(len('and ' + MSG))
1083        self.assertEqual(msg, 'and ' +  MSG)
1084
1085    def _testDup(self):
1086        self.serv_conn.send(MSG)
1087        self.serv_conn.send('and ' + MSG)
1088
1089class UDPBindTest(unittest.TestCase):
1090
1091    HOST = HOST
1092    PORT = PORT
1093
1094    def setUp(self):
1095        self.sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
1096
1097    def testBindSpecific(self):
1098        self.sock.bind( (self.HOST, self.PORT) ) # Use a specific port
1099        actual_port = self.sock.getsockname()[1]
1100        self.failUnless(actual_port == self.PORT,
1101            "Binding to specific port number should have returned same number: %d != %d" % (actual_port, self.PORT))
1102
1103    def testBindEphemeral(self):
1104        self.sock.bind( (self.HOST, 0) ) # let system choose a free port
1105        self.failUnless(self.sock.getsockname()[1] != 0, "Binding to port zero should have allocated an ephemeral port number")
1106
1107    def testShutdown(self):
1108        self.sock.bind( (self.HOST, self.PORT) )
1109        self.sock.shutdown(socket.SHUT_RDWR)
1110
1111    def tearDown(self):
1112        self.sock.close()
1113
1114class BasicUDPTest(ThreadedUDPSocketTest):
1115
1116    def __init__(self, methodName='runTest'):
1117        ThreadedUDPSocketTest.__init__(self, methodName=methodName)
1118
1119    def testSendtoAndRecv(self):
1120        # Testing sendto() and recv() over UDP
1121        msg = self.serv.recv(len(MSG))
1122        self.assertEqual(msg, MSG)
1123
1124    def _testSendtoAndRecv(self):
1125        self.cli.sendto(MSG, 0, (self.HOST, self.PORT))
1126
1127    def testSendtoAndRecvTimeoutMode(self):
1128        # Need to test again in timeout mode, which follows
1129        # a different code path
1130        self.serv.settimeout(10)
1131        msg = self.serv.recv(len(MSG))
1132        self.assertEqual(msg, MSG)
1133
1134    def _testSendtoAndRecvTimeoutMode(self):
1135        self.cli.settimeout(10)
1136        self.cli.sendto(MSG, 0, (self.HOST, self.PORT))
1137
1138    def testSendAndRecv(self):
1139        # Testing send() and recv() over connect'ed UDP
1140        msg = self.serv.recv(len(MSG))
1141        self.assertEqual(msg, MSG)
1142
1143    def _testSendAndRecv(self):
1144        self.cli.connect( (self.HOST, self.PORT) )
1145        self.cli.send(MSG, 0)
1146
1147    def testSendAndRecvTimeoutMode(self):
1148        # Need to test again in timeout mode, which follows
1149        # a different code path
1150        self.serv.settimeout(10)
1151        # Testing send() and recv() over connect'ed UDP
1152        msg = self.serv.recv(len(MSG))
1153        self.assertEqual(msg, MSG)
1154
1155    def _testSendAndRecvTimeoutMode(self):
1156        self.cli.connect( (self.HOST, self.PORT) )
1157        self.cli.settimeout(10)
1158        self.cli.send(MSG, 0)
1159
1160    def testRecvFrom(self):
1161        # Testing recvfrom() over UDP
1162        msg, addr = self.serv.recvfrom(len(MSG))
1163        self.assertEqual(msg, MSG)
1164
1165    def _testRecvFrom(self):
1166        self.cli.sendto(MSG, 0, (self.HOST, self.PORT))
1167
1168    def testRecvFromTimeoutMode(self):
1169        # Need to test again in timeout mode, which follows
1170        # a different code path
1171        self.serv.settimeout(10)
1172        msg, addr = self.serv.recvfrom(len(MSG))
1173        self.assertEqual(msg, MSG)
1174
1175    def _testRecvFromTimeoutMode(self):
1176        self.cli.settimeout(10)
1177        self.cli.sendto(MSG, 0, (self.HOST, self.PORT))
1178
1179    def testSendtoEightBitSafe(self):
1180        # This test is necessary because java only supports signed bytes
1181        msg = self.serv.recv(len(EIGHT_BIT_MSG))
1182        self.assertEqual(msg, EIGHT_BIT_MSG)
1183
1184    def _testSendtoEightBitSafe(self):
1185        self.cli.sendto(EIGHT_BIT_MSG, 0, (self.HOST, self.PORT))
1186
1187    def testSendtoEightBitSafeTimeoutMode(self):
1188        # Need to test again in timeout mode, which follows
1189        # a different code path
1190        self.serv.settimeout(10)
1191        msg = self.serv.recv(len(EIGHT_BIT_MSG))
1192        self.assertEqual(msg, EIGHT_BIT_MSG)
1193
1194    def _testSendtoEightBitSafeTimeoutMode(self):
1195        self.cli.settimeout(10)
1196        self.cli.sendto(EIGHT_BIT_MSG, 0, (self.HOST, self.PORT))
1197
1198class UDPBroadcastTest(ThreadedUDPSocketTest):
1199
1200    def setUp(self):
1201        self.serv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
1202        self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1203
1204    def testBroadcast(self):
1205        self.serv.bind( ("", self.PORT) )
1206        msg = self.serv.recv(len(EIGHT_BIT_MSG))
1207        self.assertEqual(msg, EIGHT_BIT_MSG)
1208
1209    def _testBroadcast(self):
1210        self.cli.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
1211        self.cli.sendto(EIGHT_BIT_MSG, ("<broadcast>", self.PORT) )
1212
1213class BasicSocketPairTest(SocketPairTest):
1214
1215    def __init__(self, methodName='runTest'):
1216        SocketPairTest.__init__(self, methodName=methodName)
1217
1218    def testRecv(self):
1219        msg = self.serv.recv(1024)
1220        self.assertEqual(msg, MSG)
1221
1222    def _testRecv(self):
1223        self.cli.send(MSG)
1224
1225    def testSend(self):
1226        self.serv.send(MSG)
1227
1228    def _testSend(self):
1229        msg = self.cli.recv(1024)
1230        self.assertEqual(msg, MSG)
1231
1232class NonBlockingTCPServerTests(SocketTCPTest):
1233
1234    def testSetBlocking(self):
1235        # Testing whether set blocking works
1236        self.serv.setblocking(0)
1237        start = time.time()
1238        try:
1239            self.serv.accept()
1240        except socket.error:
1241            pass
1242        end = time.time()
1243        self.assert_((end - start) < 1.0, "Error setting non-blocking mode.")
1244
1245    def testGetBlocking(self):
1246        # Testing whether set blocking works
1247        self.serv.setblocking(0)
1248        self.failUnless(not self.serv.getblocking(), "Getblocking return true instead of false")
1249        self.serv.setblocking(1)
1250        self.failUnless(self.serv.getblocking(), "Getblocking return false instead of true")
1251
1252    def testAcceptNoConnection(self):
1253        # Testing non-blocking accept returns immediately when no connection
1254        self.serv.setblocking(0)
1255        try:
1256            conn, addr = self.serv.accept()
1257        except socket.error:
1258            pass
1259        else:
1260            self.fail("Error trying to do non-blocking accept.")
1261
1262class NonBlockingTCPTests(ThreadedTCPSocketTest):
1263
1264    def __init__(self, methodName='runTest'):
1265        ThreadedTCPSocketTest.__init__(self, methodName=methodName)
1266
1267    def testAcceptConnection(self):
1268        # Testing non-blocking accept works when connection present
1269        self.serv.setblocking(0)
1270        read, write, err = select.select([self.serv], [], [])
1271        if self.serv in read:
1272            conn, addr = self.serv.accept()
1273        else:
1274            self.fail("Error trying to do accept after select: server socket was not in 'read'able list")
1275
1276    def _testAcceptConnection(self):
1277        # Make a connection to the server
1278        self.cli.connect((self.HOST, self.PORT))
1279
1280    #
1281    # AMAK: 20070311
1282    # Introduced a new test for non-blocking connect
1283    # Renamed old testConnect to testBlockingConnect
1284    #
1285
1286    def testBlockingConnect(self):
1287        # Testing blocking connect
1288        conn, addr = self.serv.accept()
1289
1290    def _testBlockingConnect(self):
1291        # Testing blocking connect
1292        self.cli.settimeout(10)
1293        self.cli.connect((self.HOST, self.PORT))
1294
1295    def testNonBlockingConnect(self):
1296        # Testing non-blocking connect
1297        conn, addr = self.serv.accept()
1298
1299    def _testNonBlockingConnect(self):
1300        # Testing non-blocking connect
1301        self.cli.setblocking(0)
1302        result = self.cli.connect_ex((self.HOST, self.PORT))
1303        rfds, wfds, xfds = select.select([], [self.cli], [])
1304        self.failUnless(self.cli in wfds)
1305        try:
1306            self.cli.send(MSG)
1307        except socket.error:
1308            self.fail("Sending on connected socket should not have raised socket.error")
1309
1310    #
1311    # AMAK: 20070518
1312    # Introduced a new test for connect with bind to specific local address
1313    #
1314
1315    def testConnectWithLocalBind(self):
1316        # Test blocking connect
1317        conn, addr = self.serv.accept()
1318
1319    def _testConnectWithLocalBind(self):
1320        # Testing blocking connect with local bind
1321        cli_port = self.PORT - 1
1322        while True:
1323            # Keep trying until a local port is available
1324            self.cli.settimeout(1)
1325            self.cli.bind( (self.HOST, cli_port) )
1326            try:
1327                self.cli.connect((self.HOST, self.PORT))
1328                break
1329            except socket.error, se:
1330                # cli_port is in use (maybe in TIME_WAIT state from a
1331                # previous test run). reset the client socket and try
1332                # again
1333                self.failUnlessEqual(se[0], errno.EADDRINUSE)
1334                try:
1335                    self.cli.close()
1336                except socket.error:
1337                    pass
1338                self.clientSetUp()
1339                cli_port -= 1
1340        bound_host, bound_port = self.cli.getsockname()
1341        self.failUnlessEqual(bound_port, cli_port)
1342
1343    def testRecvData(self):
1344        # Testing non-blocking recv
1345        conn, addr = self.serv.accept()
1346        conn.setblocking(0)
1347        rfds, wfds, xfds = select.select([conn], [], [])
1348        if conn in rfds:
1349            msg = conn.recv(len(MSG))
1350            self.assertEqual(msg, MSG)
1351        else:
1352            self.fail("Non-blocking socket with data should been in read list.")
1353
1354    def _testRecvData(self):
1355        self.cli.connect((self.HOST, self.PORT))
1356        self.cli.send(MSG)
1357
1358    def testRecvNoData(self):
1359        # Testing non-blocking recv
1360        conn, addr = self.serv.accept()
1361        conn.setblocking(0)
1362        try:
1363            msg = conn.recv(len(MSG))
1364        except socket.error:
1365            pass
1366        else:
1367            self.fail("Non-blocking recv of no data should have raised socket.error.")
1368
1369    def _testRecvNoData(self):
1370        self.cli.connect((self.HOST, self.PORT))
1371        time.sleep(0.1)
1372
1373class NonBlockingUDPTests(ThreadedUDPSocketTest): pass
1374
1375#
1376# TODO: Write some non-blocking UDP tests
1377#
1378
1379class TCPFileObjectClassOpenCloseTests(SocketConnectedTest):
1380
1381    def testCloseFileDoesNotCloseSocket(self):
1382        # This test is necessary on java/jython
1383        msg = self.cli_conn.recv(1024)
1384        self.assertEqual(msg, MSG)
1385
1386    def _testCloseFileDoesNotCloseSocket(self):
1387        self.cli_file = self.serv_conn.makefile('wb')
1388        self.cli_file.close()
1389        try:
1390            self.serv_conn.send(MSG)
1391        except Exception, x:
1392            self.fail("Closing file wrapper appears to have closed underlying socket: %s" % str(x))
1393
1394    def testCloseSocketDoesNotCloseFile(self):
1395        msg = self.cli_conn.recv(1024)
1396        self.assertEqual(msg, MSG)
1397
1398    def _testCloseSocketDoesNotCloseFile(self):
1399        self.cli_file = self.serv_conn.makefile('wb')
1400        self.serv_conn.close()
1401        try:
1402            self.cli_file.write(MSG)
1403            self.cli_file.flush()
1404        except Exception, x:
1405            self.fail("Closing socket appears to have closed file wrapper: %s" % str(x))
1406
1407class UDPFileObjectClassOpenCloseTests(ThreadedUDPSocketTest):
1408
1409    def testCloseFileDoesNotCloseSocket(self):
1410        # This test is necessary on java/jython
1411        msg = self.serv.recv(1024)
1412        self.assertEqual(msg, MSG)
1413
1414    def _testCloseFileDoesNotCloseSocket(self):
1415        self.cli_file = self.cli.makefile('wb')
1416        self.cli_file.close()
1417        try:
1418            self.cli.sendto(MSG, 0, (self.HOST, self.PORT))
1419        except Exception, x:
1420            self.fail("Closing file wrapper appears to have closed underlying socket: %s" % str(x))
1421
1422    def testCloseSocketDoesNotCloseFile(self):
1423        self.serv_file = self.serv.makefile('rb')
1424        self.serv.close()
1425        msg = self.serv_file.readline()
1426        self.assertEqual(msg, MSG)
1427
1428    def _testCloseSocketDoesNotCloseFile(self):
1429        try:
1430            self.cli.sendto(MSG, 0, (self.HOST, self.PORT))
1431        except Exception, x:
1432            self.fail("Closing file wrapper appears to have closed underlying socket: %s" % str(x))
1433
1434class FileAndDupOpenCloseTests(SocketConnectedTest):
1435
1436    def testCloseDoesNotCloseOthers(self):
1437        msg = self.cli_conn.recv(len(MSG))
1438        self.assertEqual(msg, MSG)
1439
1440        msg = self.cli_conn.recv(len('and ' + MSG))
1441        self.assertEqual(msg, 'and ' + MSG)
1442
1443    def _testCloseDoesNotCloseOthers(self):
1444        self.dup_conn1 = self.serv_conn.dup()
1445        self.dup_conn2 = self.serv_conn.dup()
1446        self.cli_file = self.serv_conn.makefile('wb')
1447        self.serv_conn.close()
1448        self.dup_conn1.close()
1449
1450        try:
1451            self.serv_conn.send(MSG)
1452        except socket.error, se:
1453            self.failUnlessEqual(se[0], errno.EBADF)
1454        else:
1455            self.fail("Original socket did not close")
1456        try:
1457            self.dup_conn1.send(MSG)
1458        except socket.error, se:
1459            self.failUnlessEqual(se[0], errno.EBADF)
1460        else:
1461            self.fail("Duplicate socket 1 did not close")
1462
1463        self.dup_conn2.send(MSG)
1464        self.dup_conn2.close()
1465
1466        try:
1467            self.cli_file.write('and ' + MSG)
1468        except Exception, x:
1469            self.fail("Closing others appears to have closed the socket file: %s" % str(x))
1470        self.cli_file.close()
1471
1472class FileObjectClassTestCase(SocketConnectedTest):
1473
1474    bufsize = -1 # Use default buffer size
1475
1476    def __init__(self, methodName='runTest'):
1477        SocketConnectedTest.__init__(self, methodName=methodName)
1478
1479    def setUp(self):
1480        SocketConnectedTest.setUp(self)
1481        self.serv_file = self.cli_conn.makefile('rb', self.bufsize)
1482
1483    def tearDown(self):
1484        self.serv_file.close()
1485        self.assert_(self.serv_file.closed)
1486        self.serv_file = None
1487        SocketConnectedTest.tearDown(self)
1488
1489    def clientSetUp(self):
1490        SocketConnectedTest.clientSetUp(self)
1491        self.cli_file = self.serv_conn.makefile('wb')
1492
1493    def clientTearDown(self):
1494        self.cli_file.close()
1495        self.assert_(self.cli_file.closed)
1496        self.cli_file = None
1497        SocketConnectedTest.clientTearDown(self)
1498
1499    def testSmallRead(self):
1500        # Performing small file read test
1501        first_seg = self.serv_file.read(len(MSG)-3)
1502        second_seg = self.serv_file.read(3)
1503        msg = first_seg + second_seg
1504        self.assertEqual(msg, MSG)
1505
1506    def _testSmallRead(self):
1507        self.cli_file.write(MSG)
1508        self.cli_file.flush()
1509
1510    def testFullRead(self):
1511        # read until EOF
1512        msg = self.serv_file.read()
1513        self.assertEqual(msg, MSG)
1514
1515    def _testFullRead(self):
1516        self.cli_file.write(MSG)
1517        self.cli_file.flush()
1518
1519    def testUnbufferedRead(self):
1520        # Performing unbuffered file read test
1521        buf = ''
1522        while 1:
1523            char = self.serv_file.read(1)
1524            if not char:
1525                break
1526            buf += char
1527        self.assertEqual(buf, MSG)
1528
1529    def _testUnbufferedRead(self):
1530        self.cli_file.write(MSG)
1531        self.cli_file.flush()
1532
1533    def testReadline(self):
1534        # Performing file readline test
1535        line = self.serv_file.readline()
1536        self.assertEqual(line, MSG)
1537
1538    def _testReadline(self):
1539        self.cli_file.write(MSG)
1540        self.cli_file.flush()
1541
1542    def testClosedAttr(self):
1543        self.assert_(not self.serv_file.closed)
1544
1545    def _testClosedAttr(self):
1546        self.assert_(not self.cli_file.closed)
1547
1548class PrivateFileObjectTestCase(unittest.TestCase):
1549
1550    """Test usage of socket._fileobject with an arbitrary socket-like
1551    object.
1552
1553    E.g. urllib2 wraps an httplib.HTTPResponse object with _fileobject.
1554    """
1555
1556    def setUp(self):
1557        self.socket_like = StringIO()
1558        self.socket_like.recv = self.socket_like.read
1559        self.socket_like.sendall = self.socket_like.write
1560
1561    def testPrivateFileObject(self):
1562        fileobject = socket._fileobject(self.socket_like, 'rb')
1563        fileobject.write('hello jython')
1564        fileobject.flush()
1565        self.socket_like.seek(0)
1566        self.assertEqual(fileobject.read(), 'hello jython')
1567
1568class UnbufferedFileObjectClassTestCase(FileObjectClassTestCase):
1569
1570    """Repeat the tests from FileObjectClassTestCase with bufsize==0.
1571
1572    In this case (and in this case only), it should be possible to
1573    create a file object, read a line from it, create another file
1574    object, read another line from it, without loss of data in the
1575    first file object's buffer.  Note that httplib relies on this
1576    when reading multiple requests from the same socket."""
1577
1578    bufsize = 0 # Use unbuffered mode
1579
1580    def testUnbufferedReadline(self):
1581        # Read a line, create a new file object, read another line with it
1582        line = self.serv_file.readline() # first line
1583        self.assertEqual(line, "A. " + MSG) # first line
1584        self.serv_file = self.cli_conn.makefile('rb', 0)
1585        line = self.serv_file.readline() # second line
1586        self.assertEqual(line, "B. " + MSG) # second line
1587
1588    def _testUnbufferedReadline(self):
1589        self.cli_file.write("A. " + MSG)
1590        self.cli_file.write("B. " + MSG)
1591        self.cli_file.flush()
1592
1593class LineBufferedFileObjectClassTestCase(FileObjectClassTestCase):
1594
1595    bufsize = 1 # Default-buffered for reading; line-buffered for writing
1596
1597
1598class SmallBufferedFileObjectClassTestCase(FileObjectClassTestCase):
1599
1600    bufsize = 2 # Exercise the buffering code
1601
1602class TCPServerTimeoutTest(SocketTCPTest):
1603
1604    def testAcceptTimeout(self):
1605        def raise_timeout(*args, **kwargs):
1606            self.serv.settimeout(1.0)
1607            self.serv.accept()
1608        self.failUnlessRaises(socket.timeout, raise_timeout,
1609                              "TCP socket accept failed to generate a timeout exception (TCP)")
1610
1611    def testTimeoutZero(self):
1612        ok = False
1613        try:
1614            self.serv.settimeout(0.0)
1615            foo = self.serv.accept()
1616        except socket.timeout:
1617            self.fail("caught timeout instead of error (TCP)")
1618        except socket.error:
1619            ok = True
1620        except Exception, x:
1621            self.fail("caught unexpected exception (TCP): %s" % str(x))
1622        if not ok:
1623            self.fail("accept() returned success when we did not expect it")
1624
1625class TCPClientTimeoutTest(SocketTCPTest):
1626
1627    def testConnectTimeout(self):
1628        cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1629        cli.settimeout(0.1)
1630        host = '192.168.192.168'
1631        try:
1632            cli.connect((host, 5000))
1633        except socket.timeout, st:
1634            pass
1635        except Exception, x:
1636            self.fail("Client socket timeout should have raised socket.timeout, not %s" % str(x))
1637        else:
1638            self.fail('''Client socket timeout should have raised
1639socket.timeout.  This tries to connect to %s in the assumption that it isn't
1640used, but if it is on your network this failure is bogus.''' % host)
1641
1642    def testConnectDefaultTimeout(self):
1643        _saved_timeout = socket.getdefaulttimeout()
1644        socket.setdefaulttimeout(0.1)
1645        cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1646        host = '192.168.192.168'
1647        try:
1648            cli.connect((host, 5000))
1649        except socket.timeout, st:
1650            pass
1651        except Exception, x:
1652            self.fail("Client socket timeout should have raised socket.timeout, not %s" % str(x))
1653        else:
1654            self.fail('''Client socket timeout should have raised
1655socket.timeout.  This tries to connect to %s in the assumption that it isn't
1656used, but if it is on your network this failure is bogus.''' % host)
1657        socket.setdefaulttimeout(_saved_timeout)
1658
1659    def testRecvTimeout(self):
1660        def raise_timeout(*args, **kwargs):
1661            cli_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1662            cli_sock.connect( (HOST, PORT) )
1663            cli_sock.settimeout(1)
1664            cli_sock.recv(1024)
1665        self.failUnlessRaises(socket.timeout, raise_timeout,
1666                              "TCP socket recv failed to generate a timeout exception (TCP)")
1667
1668    # Disable this test, but leave it present for documentation purposes
1669    # socket timeouts only work for read and accept, not for write
1670    # http://java.sun.com/j2se/1.4.2/docs/api/java/net/SocketTimeoutException.html
1671    def estSendTimeout(self):
1672        def raise_timeout(*args, **kwargs):
1673            cli_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1674            cli_sock.connect( (HOST, PORT) )
1675            # First fill the socket
1676            cli_sock.settimeout(1)
1677            sent = 0
1678            while True:
1679                bytes_sent = cli_sock.send(MSG)
1680                sent += bytes_sent
1681        self.failUnlessRaises(socket.timeout, raise_timeout,
1682                              "TCP socket send failed to generate a timeout exception (TCP)")
1683
1684    def testSwitchModes(self):
1685        cli_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1686        cli_sock.connect( (HOST, PORT) )
1687        # set non-blocking mode
1688        cli_sock.setblocking(0)
1689        # then set timeout mode
1690        cli_sock.settimeout(1)
1691        try:
1692            cli_sock.send(MSG)
1693        except Exception, x:
1694            self.fail("Switching mode from non-blocking to timeout raised exception: %s" % x)
1695        else:
1696            pass
1697
1698#
1699# AMAK: 20070307
1700# Corrected the superclass of UDPTimeoutTest
1701#
1702
1703class UDPTimeoutTest(SocketUDPTest):
1704
1705    def testUDPTimeout(self):
1706        def raise_timeout(*args, **kwargs):
1707            self.serv.settimeout(1.0)
1708            self.serv.recv(1024)
1709        self.failUnlessRaises(socket.timeout, raise_timeout,
1710                              "Error generating a timeout exception (UDP)")
1711
1712    def testTimeoutZero(self):
1713        ok = False
1714        try:
1715            self.serv.settimeout(0.0)
1716            foo = self.serv.recv(1024)
1717        except socket.timeout:
1718            self.fail("caught timeout instead of error (UDP)")
1719        except socket.error:
1720            ok = True
1721        except Exception, x:
1722            self.fail("caught unexpected exception (UDP): %s" % str(x))
1723        if not ok:
1724            self.fail("recv() returned success when we did not expect it")
1725
1726class TestGetAddrInfo(unittest.TestCase):
1727
1728    def testBadFamily(self):
1729        try:
1730            socket.getaddrinfo(HOST, PORT, 9999)
1731        except socket.gaierror, gaix:
1732            self.failUnlessEqual(gaix[0], errno.EIO)
1733        except Exception, x:
1734            self.fail("getaddrinfo with bad family raised wrong exception: %s" % x)
1735        else:
1736            self.fail("getaddrinfo with bad family should have raised exception")
1737
1738    def testBadSockType(self):
1739        for socktype in [socket.SOCK_RAW, socket.SOCK_RDM, socket.SOCK_SEQPACKET]:
1740            try:
1741                socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socktype)
1742            except socket.error, se:
1743                self.failUnlessEqual(se[0], errno.ESOCKTNOSUPPORT)
1744            except Exception, x:
1745                self.fail("getaddrinfo with bad socktype raised wrong exception: %s" % x)
1746            else:
1747                self.fail("getaddrinfo with bad socktype should have raised exception")
1748
1749    def testBadSockTypeProtoCombination(self):
1750        for socktype, proto in [
1751            (socket.SOCK_STREAM, socket.IPPROTO_UDP),
1752            (socket.SOCK_STREAM, socket.IPPROTO_ICMP),
1753            (socket.SOCK_DGRAM,  socket.IPPROTO_TCP),
1754            (socket.SOCK_DGRAM,  socket.IPPROTO_FRAGMENT),
1755            ]:
1756            try:
1757                results = socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socktype, proto)
1758                self.failUnless(len(results) == 0, "getaddrinfo with bad socktype/proto combo should not have returned results")
1759            except Exception, x:
1760                self.fail("getaddrinfo with bad socktype/proto combo should not have raised exception")
1761
1762    def testNoSockTypeWithProto(self):
1763        for expect_results, proto in [
1764            (True,  socket.IPPROTO_UDP),
1765            (False, socket.IPPROTO_ICMP),
1766            (True,  socket.IPPROTO_TCP),
1767            (False, socket.IPPROTO_FRAGMENT),
1768            ]:
1769            try:
1770                results = socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, 0, proto)
1771                if expect_results:
1772                    self.failUnless(len(results) > 0, "getaddrinfo with no socktype and supported proto combo should have returned results")
1773                else:
1774                    self.failUnless(len(results) == 0, "getaddrinfo with no socktype and unsupported proto combo should not have returned results")
1775            except Exception, x:
1776                self.fail("getaddrinfo with no socktype (un)supported proto combo should not have raised exception")
1777
1778    def testReturnsAreStrings(self):
1779        addrinfos = socket.getaddrinfo(HOST, PORT)
1780        for addrinfo in addrinfos:
1781            family, socktype, proto, canonname, sockaddr = addrinfo
1782            self.assert_(isinstance(canonname, str))
1783            self.assert_(isinstance(sockaddr[0], str))
1784
1785    def testAI_PASSIVE(self):
1786        # Disabling this test for now; it's expectations are not portable.
1787        # Expected results are too dependent on system config to be made portable between systems.
1788        # And the only way to determine what configuration to test is to use the 
1789        # java.net.InetAddress.getAllByName() method, which is what is used to 
1790        # implement the getaddrinfo() function. Therefore, no real point in the test.
1791        return
1792        IPV4_LOOPBACK = "127.0.0.1"
1793        local_hostname = java.net.InetAddress.getLocalHost().getHostName()
1794        local_ip_address = java.net.InetAddress.getLocalHost().getHostAddress()
1795        for flags, host_param, expected_canonname, expected_sockaddr in [
1796            # First passive flag
1797            (socket.AI_PASSIVE, None, "", socket.INADDR_ANY),
1798            (socket.AI_PASSIVE, "", "", local_ip_address),
1799            (socket.AI_PASSIVE, "localhost", "", IPV4_LOOPBACK),
1800            (socket.AI_PASSIVE, local_hostname, "", local_ip_address),
1801            # Now passive flag AND canonname flag
1802            # Commenting out all AI_CANONNAME tests, results too dependent on system config
1803            #(socket.AI_PASSIVE|socket.AI_CANONNAME, None, "127.0.0.1", "127.0.0.1"),
1804            #(socket.AI_PASSIVE|socket.AI_CANONNAME, "", local_hostname, local_ip_address),
1805            # The following gives varying results across platforms and configurations: commenting out for now.
1806            # Javadoc: http://java.sun.com/j2se/1.5.0/docs/api/java/net/InetAddress.html#getCanonicalHostName()
1807            #(socket.AI_PASSIVE|socket.AI_CANONNAME, "localhost", local_hostname, IPV4_LOOPBACK),
1808            #(socket.AI_PASSIVE|socket.AI_CANONNAME, local_hostname, local_hostname, local_ip_address),
1809        ]:
1810            addrinfos = socket.getaddrinfo(host_param, 0, socket.AF_INET, socket.SOCK_STREAM, 0, flags)
1811            for family, socktype, proto, canonname, sockaddr in addrinfos:
1812                self.failUnlessEqual(expected_canonname, canonname, "For hostname '%s' and flags %d, canonname '%s' != '%s'" % (host_param, flags, expected_canonname, canonname) )
1813                self.failUnlessEqual(expected_sockaddr, sockaddr[0], "For hostname '%s' and flags %d, sockaddr '%s' != '%s'" % (host_param, flags, expected_sockaddr, sockaddr[0]) )
1814
1815    def testIPV4AddressesOnly(self):
1816        socket._use_ipv4_addresses_only(True)
1817        def doAddressTest(addrinfos):
1818            for family, socktype, proto, canonname, sockaddr in addrinfos:
1819                self.failIf(":" in sockaddr[0], "Incorrectly received IPv6 address '%s'" % (sockaddr[0]) )
1820        doAddressTest(socket.getaddrinfo("localhost", 0, socket.AF_INET6, socket.SOCK_STREAM, 0, 0))
1821        doAddressTest(socket.getaddrinfo("localhost", 0, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, 0))
1822        socket._use_ipv4_addresses_only(False)
1823
1824    def testAddrTupleTypes(self):
1825        ipv4_address_tuple = socket.getaddrinfo("localhost", 80, socket.AF_INET, socket.SOCK_STREAM, 0, 0)[0][4]
1826        self.failUnlessEqual(ipv4_address_tuple[0], "127.0.0.1")
1827        self.failUnlessEqual(ipv4_address_tuple[1], 80)
1828        self.failUnlessRaises(IndexError, lambda: ipv4_address_tuple[2])
1829        self.failUnlessEqual(str(ipv4_address_tuple), "('127.0.0.1', 80)")
1830        self.failUnlessEqual(repr(ipv4_address_tuple), "('127.0.0.1', 80)")
1831
1832        addrinfo = socket.getaddrinfo("localhost", 80, socket.AF_INET6, socket.SOCK_STREAM, 0, 0)
1833        if not addrinfo:
1834            # Maybe no IPv6 configured on the test machine.
1835            return
1836        ipv6_address_tuple = addrinfo[0][4]
1837        self.failUnless     (ipv6_address_tuple[0] in ["::1", "0:0:0:0:0:0:0:1"])
1838        self.failUnlessEqual(ipv6_address_tuple[1], 80)
1839        self.failUnlessEqual(ipv6_address_tuple[2], 0)
1840        # Can't have an expectation for scope
1841        try:
1842            ipv6_address_tuple[3]
1843        except IndexError:
1844            self.fail("Failed to retrieve third element of ipv6 4-tuple")
1845        self.failUnlessRaises(IndexError, lambda: ipv6_address_tuple[4])
1846        # These str/repr tests may fail on some systems: the scope element of the tuple may be non-zero
1847        # In this case, we'll have to change the test to use .startswith() or .split() to exclude the scope element
1848        self.failUnless(str(ipv6_address_tuple) in ["('::1', 80, 0, 0)", "('0:0:0:0:0:0:0:1', 80, 0, 0)"])
1849        self.failUnless(repr(ipv6_address_tuple) in ["('::1', 80, 0, 0)", "('0:0:0:0:0:0:0:1', 80, 0, 0)"])
1850
1851    def testNonIntPort(self):
1852        hostname = "localhost"
1853
1854        # Port value of None should map to 0
1855        addrs = socket.getaddrinfo(hostname, None)
1856        for a in addrs:
1857            self.failUnlessEqual(a[4][1], 0, "Port value of None should have returned 0")
1858
1859        # Port value can be a string rep of the port number
1860        addrs = socket.getaddrinfo(hostname, "80")
1861        for a in addrs:
1862            self.failUnlessEqual(a[4][1], 80, "Port value of '80' should have returned 80")
1863
1864        # Can also specify a service name
1865        # This test assumes that service http will always be at port 80
1866        addrs = socket.getaddrinfo(hostname, "http")
1867        for a in addrs:
1868            self.failUnlessEqual(a[4][1], 80, "Port value of 'http' should have returned 80")
1869
1870        # Check treatment of non-integer numeric port
1871        try:
1872            socket.getaddrinfo(hostname, 79.99)
1873        except socket.error, se:
1874            self.failUnlessEqual(se[0], "Int or String expected")
1875        except Exception, x:
1876            self.fail("getaddrinfo for float port number raised wrong exception: %s" % str(x))
1877        else:
1878            self.fail("getaddrinfo for float port number failed to raise exception")
1879
1880        # Check treatment of non-integer numeric port, as a string
1881        # The result is that it should fail in the same way as a non-existent service
1882        try:
1883            socket.getaddrinfo(hostname, "79.99")
1884        except socket.gaierror, g:
1885            self.failUnlessEqual(g[0], socket.EAI_SERVICE)
1886        except Exception, x:
1887            self.fail("getaddrinfo for non-integer numeric port, as a string raised wrong exception: %s" % str(x))
1888        else:
1889            self.fail("getaddrinfo for non-integer numeric port, as a string failed to raise exception")
1890
1891        # Check enforcement of AI_NUMERICSERV
1892        try:
1893            socket.getaddrinfo(hostname, "http", 0, 0, 0, socket.AI_NUMERICSERV)
1894        except socket.gaierror, g:
1895            self.failUnlessEqual(g[0], socket.EAI_NONAME)
1896        except Exception, x:
1897            self.fail("getaddrinfo for service name with AI_NUMERICSERV raised wrong exception: %s" % str(x))
1898        else:
1899            self.fail("getaddrinfo for service name with AI_NUMERICSERV failed to raise exception")
1900
1901        # Check treatment of non-existent service
1902        try:
1903            socket.getaddrinfo(hostname, "nosuchservice")
1904        except socket.gaierror, g:
1905            self.failUnlessEqual(g[0], socket.EAI_SERVICE)
1906        except Exception, x:
1907            self.fail("getaddrinfo for unknown service name raised wrong exception: %s" % str(x))
1908        else:
1909            self.fail("getaddrinfo for unknown service name failed to raise exception")
1910
1911    def testHostNames(self):
1912        # None is only acceptable if AI_NUMERICHOST is not specified
1913        for flags, expect_exception in [(0, False), (socket.AI_NUMERICHOST, True)]:
1914            try:
1915                socket.getaddrinfo(None, 80, 0, 0, 0, flags)
1916                if expect_exception:
1917                    self.fail("Non-numeric hostname == None should have raised exception")
1918            except Exception, x:
1919                if not expect_exception:
1920                    self.fail("hostname == None should not have raised exception: %s" % str(x))
1921
1922        # Check enforcement of AI_NUMERICHOST
1923        for host in ["", " ", "localhost"]:
1924            try:
1925                socket.getaddrinfo(host, 80, 0, 0, 0, socket.AI_NUMERICHOST)
1926            except socket.gaierror, ge:
1927                self.failUnlessEqual(ge[0], socket.EAI_NONAME)
1928            except Exception, x:
1929                self.fail("Non-numeric host with AI_NUMERICHOST raised wrong exception: %s" % str(x))
1930            else:
1931                self.fail("Non-numeric hostname '%s' with AI_NUMERICHOST should have raised exception" % host)
1932
1933        # Check enforcement of AI_NUMERICHOST with wrong address families
1934        for host, family in [("127.0.0.1", socket.AF_INET6), ("::1", socket.AF_INET)]:
1935            try:
1936                socket.getaddrinfo(host, 80, family, 0, 0, socket.AI_NUMERICHOST)
1937            except socket.gaierror, ge:
1938                self.failUnlessEqual(ge[0], socket.EAI_ADDRFAMILY)
1939            except Exception, x:
1940                self.fail("Numeric host '%s' in wrong family '%s' with AI_NUMERICHOST raised wrong exception: %s" % 
1941                    (host, family, str(x)) )
1942            else:
1943                self.fail("Numeric host '%s' in wrong family '%s' with AI_NUMERICHOST should have raised exception" % 
1944                    (host, family) )
1945
1946class TestGetNameInfo(unittest.TestCase):
1947
1948    def testBadParameters(self):
1949        for address, flags in [
1950            ( (0,0),       0),
1951            ( (0,"http"),  0),
1952            ( "localhost", 0),
1953            ( 0,           0),
1954            ( ("",),       0),
1955        ]:
1956            try:
1957                socket.getnameinfo(address, flags)
1958            except TypeError:
1959                pass
1960            except Exception, x:
1961                self.fail("Bad getnameinfo parameters (%s, %s) raised wrong exception: %s" % (str(address), flags, str(x)))
1962            else:
1963                self.fail("Bad getnameinfo parameters (%s, %s) failed to raise exception" % (str(address), flags))
1964
1965    def testPort(self):
1966        for address, flags, expected in [
1967            ( ("127.0.0.1", 25),  0,                     "smtp" ),
1968            ( ("127.0.0.1", 25),  socket.NI_NUMERICSERV, 25     ),
1969            ( ("127.0.0.1", 513), socket.NI_DGRAM,       "who"  ),
1970            ( ("127.0.0.1", 513), 0,                     "login"),
1971        ]:
1972            result = socket.getnameinfo(address, flags)
1973            self.failUnlessEqual(result[1], expected)
1974
1975    def testHost(self):
1976        for address, flags, expected in [
1977            ( ("www.python.org", 80),  0,                     "dinsdale.python.org"),
1978            ( ("www.python.org", 80),  socket.NI_NUMERICHOST, "82.94.164.162"      ),
1979            ( ("www.python.org", 80),  socket.NI_NAMEREQD,    "dinsdale.python.org"),
1980            ( ("82.94.164.162",  80),  socket.NI_NAMEREQD,    "dinsdale.python.org"),
1981        ]:
1982            result = socket.getnameinfo(address, flags)
1983            self.failUnlessEqual(result[0], expected)
1984
1985    def testNI_NAMEREQD(self):
1986        # This test may delay for some seconds
1987        unreversible_address = "198.51.100.1"
1988        try:
1989            socket.getnameinfo( (unreversible_address, 80), socket.NI_NAMEREQD)
1990        except socket.gaierror, ge:
1991            self.failUnlessEqual(ge[0], socket.EAI_NONAME)
1992        except Exception, x:
1993            self.fail("Unreversible address with NI_NAMEREQD (%s) raised wrong exception: %s" % (unreversible_address, str(x)))
1994        else:
1995            self.fail("Unreversible address with NI_NAMEREQD (%s) failed to raise exception" % unreversible_address)
1996
1997    def testHostIdna(self):
1998        fqdn = u"\u043f\u0440\u0430\u0432\u0438\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u043e.\u0440\u0444"
1999        idn  = "xn--80aealotwbjpid2k.xn--p1ai"
2000        ip   = "95.173.135.62"
2001        try:
2002            import java.net.IDN
2003        except ImportError:
2004            try:
2005                socket.getnameinfo( (fqdn, 80), 0)
2006            except UnicodeEncodeError:
2007                pass
2008            except Exception, x:
2009                self.fail("International domain without java.net.IDN raised wrong exception: %s" % str(x))
2010            else:
2011                self.fail("International domain without java.net.IDN failed to raise exception")
2012        else:
2013            # have to disable this test until I find an IDN that reverses to the punycode name
2014            return
2015            for address, flags, expected in [
2016                ( (fqdn, 80),  0,             idn  ),
2017                ( (fqdn, 80),  socket.NI_IDN, fqdn ),
2018            ]:
2019                result = socket.getnameinfo(address, flags)
2020                self.failUnlessEqual(result[0], expected)
2021
2022class TestJython_get_jsockaddr(unittest.TestCase):
2023    "These tests are specific to jython: they test a key internal routine"
2024
2025    def testIPV4AddressesFromGetAddrInfo(self):
2026        local_addr = socket.getaddrinfo("localhost", 80, socket.AF_INET, socket.SOCK_STREAM, 0, 0)[0][4]
2027        sockaddr = socket._get_jsockaddr(local_addr, socket.AF_INET, None, 0, 0)
2028        self.failUnless(isinstance(sockaddr, java.net.InetSocketAddress), "_get_jsockaddr returned wrong type: '%s'" % str(type(sockaddr)))
2029        self.failUnlessEqual(sockaddr.address.hostAddress, "127.0.0.1")
2030        self.failUnlessEqual(sockaddr.port, 80)
2031
2032    def testIPV6AddressesFromGetAddrInfo(self):
2033        addrinfo = socket.getaddrinfo("localhost", 80, socket.AF_INET6, socket.SOCK_STREAM, 0, 0)
2034        if not addrinfo and is_bsd:
2035            # older FreeBSDs may have spotty IPV6 Java support
2036            return
2037        local_addr = addrinfo[0][4]
2038        sockaddr = socket._get_jsockaddr(local_addr, socket.AF_INET6, None, 0, 0)
2039        self.failUnless(isinstance(sockaddr, java.net.InetSocketAddress), "_get_jsockaddr returned wrong type: '%s'" % str(type(sockaddr)))
2040        self.failUnless(sockaddr.address.hostAddress in ["::1", "0:0:0:0:0:0:0:1"])
2041        self.failUnlessEqual(sockaddr.port, 80)
2042
2043    def testAddressesFrom2Tuple(self):
2044        for family, addr_tuple, jaddress_type, expected in [
2045            (socket.AF_INET,  ("localhost", 80), java.net.Inet4Address, ["127.0.0.1"]),
2046            (socket.AF_INET6, ("localhost", 80), java.net.Inet6Address, ["::1", "0:0:0:0:0:0:0:1"]),
2047            ]:
2048            sockaddr = socket._get_jsockaddr(addr_tuple, family, 0, 0, 0)
2049            self.failUnless(isinstance(sockaddr, java.net.InetSocketAddress), "_get_jsockaddr returned wrong type: '%s'" % str(type(sockaddr)))
2050            self.failUnless(isinstance(sockaddr.address, jaddress_type), "_get_jsockaddr returned wrong address type: '%s'(family=%d)" % (str(type(sockaddr.address)), family))
2051            self.failUnless(sockaddr.address.hostAddress in expected)
2052            self.failUnlessEqual(sockaddr.port, 80)
2053
2054    def testAddressesFrom4Tuple(self):
2055        for addr_tuple in [
2056            ("localhost", 80),
2057            ("localhost", 80, 0, 0),
2058            ]:
2059            sockaddr = socket._get_jsockaddr(addr_tuple, socket.AF_INET6, 0, 0, 0)
2060            self.failUnless(isinstance(sockaddr, java.net.InetSocketAddress), "_get_jsockaddr returned wrong type: '%s'" % str(type(sockaddr)))
2061            self.failUnless(isinstance(sockaddr.address, java.net.Inet6Address), "_get_jsockaddr returned wrong address type: '%s'" % str(type(sockaddr.address)))
2062            self.failUnless(sockaddr.address.hostAddress in ["::1", "0:0:0:0:0:0:0:1"])
2063            self.failUnlessEqual(sockaddr.address.scopeId, 0)
2064            self.failUnlessEqual(sockaddr.port, 80)
2065
2066    def testSpecialHostnames(self):
2067        for family, sock_type, flags, addr_tuple, expected in [
2068            ( socket.AF_INET,  0,                 0,                 ("", 80),            ["localhost"]),
2069            ( socket.AF_INET,  0,                 socket.AI_PASSIVE, ("", 80),            [socket.INADDR_ANY]),
2070            ( socket.AF_INET6, 0,                 0,                 ("", 80),            ["localhost"]),
2071            ( socket.AF_INET6, 0,                 socket.AI_PASSIVE, ("", 80),            [socket.IN6ADDR_ANY_INIT, "0:0:0:0:0:0:0:0"]),
2072            ( socket.AF_INET,  socket.SOCK_DGRAM, 0,                 ("<broadcast>", 80), [socket.INADDR_BROADCAST]),
2073            ]:
2074            sockaddr = socket._get_jsockaddr(addr_tuple, family, sock_type, 0, flags)
2075            self.failUnless(sockaddr.hostName in expected, "_get_jsockaddr returned wrong hostname '%s' for special hostname '%s'(family=%d)" % (sockaddr.hostName, addr_tuple[0], family))
2076
2077    def testNoneTo_get_jsockaddr(self):
2078        for family, flags, expected in [
2079            ( socket.AF_INET,  0,                 ["localhost"]),
2080            ( socket.AF_INET,  socket.AI_PASSIVE, [socket.INADDR_ANY]),
2081            ( socket.AF_INET6, 0,                 ["localhost"]),
2082            ( socket.AF_INET6, socket.AI_PASSIVE, [socket.IN6ADDR_ANY_INIT, "0:0:0:0:0:0:0:0"]),
2083            ]:
2084            sockaddr = socket._get_jsockaddr(None, family, 0, 0, flags)
2085            self.failUnless(sockaddr.hostName in expected, "_get_jsockaddr returned wrong hostname '%s' for sock tuple == None (family=%d)" % (sockaddr.hostName, family))
2086
2087    def testBadAddressTuples(self):
2088        for family, address_tuple in [
2089            ( socket.AF_INET,  ()                      ),
2090            ( socket.AF_INET,  ("")                    ),
2091            ( socket.AF_INET,  (80)                    ),
2092            ( socket.AF_INET,  ("localhost", 80, 0)    ),
2093            ( socket.AF_INET,  ("localhost", 80, 0, 0) ),
2094            ( socket.AF_INET6,  ()                      ),
2095            ( socket.AF_INET6,  ("")                    ),
2096            ( socket.AF_INET6,  (80)                    ),
2097            ( socket.AF_INET6,  ("localhost", 80, 0)    ),
2098            ]:
2099            try:
2100                sockaddr = socket._get_jsockaddr(address_tuple, family, None, 0, 0)
2101            except TypeError:
2102                pass
2103            else:
2104                self.fail("Bad tuple %s (family=%d) should have raised TypeError" % (str(address_tuple), family))
2105
2106class TestExceptions(unittest.TestCase):
2107
2108    def testExceptionTree(self):
2109        self.assert_(issubclass(socket.error, IOError))
2110        self.assert_(issubclass(socket.herror, socket.error))
2111        self.assert_(issubclass(socket.gaierror, socket.error))
2112        self.assert_(issubclass(socket.timeout, socket.error))
2113
2114    def testExceptionAtributes(self):
2115        for exc_class_name in ['error', 'herror', 'gaierror', 'timeout']:
2116            exc_class = getattr(socket, exc_class_name)
2117            exc = exc_class(12345, "Expected message")
2118            self.failUnlessEqual(getattr(exc, 'errno'), 12345, "Socket module exceptions must have an 'errno' attribute")
2119            self.failUnlessEqual(getattr(exc, 'strerror'), "Expected message", "Socket module exceptions must have an 'strerror' attribute")
2120
2121class TestJythonExceptionsShared:
2122
2123    def tearDown(self):
2124        self.s.close()
2125        self.s = None
2126
2127    def testHostNotFound(self):
2128        try:
2129            socket.gethostbyname("doesnotexist")
2130        except socket.gaierror, gaix:
2131            self.failUnlessEqual(gaix[0], errno.EGETADDRINFOFAILED)
2132        except Exception, x:
2133            self.fail("Get host name for non-existent host raised wrong exception: %s" % x)
2134
2135    def testUnresolvedAddress(self):
2136        try:
2137            self.s.connect( ('non.existent.server', PORT) )
2138        except socket.gaierror, gaix:
2139            self.failUnlessEqual(gaix[0], errno.EGETADDRINFOFAILED)
2140        except Exception, x:
2141            self.fail("Get host name for non-existent host raised wrong exception: %s" % x)
2142        else:
2143            self.fail("Get host name for non-existent host should have raised exception")
2144
2145    def testSocketNotConnected(self):
2146        try:
2147            self.s.send(MSG)
2148        except socket.error, se:
2149            self.failUnlessEqual(se[0], errno.ENOTCONN)
2150        except Exception, x:
2151            self.fail("Send on unconnected socket raised wrong exception: %s" % x)
2152        else:
2153            self.fail("Send on unconnected socket raised exception")
2154
2155    def testSocketNotBound(self):
2156        try:
2157            result = self.s.recv(1024)
2158        except socket.error, se:
2159            self.failUnlessEqual(se[0], errno.ENOTCONN)
2160        except Exception, x:
2161            self.fail("Receive on unbound socket raised wrong exception: %s" % x)
2162        else:
2163            self.fail("Receive on unbound socket raised exception")
2164
2165    def testClosedSocket(self):
2166        self.s.close()
2167        try:
2168            self.s.send(MSG)
2169        except socket.error, se:
2170            self.failUnlessEqual(se[0], errno.EBADF)
2171
2172        dup = self.s.dup()
2173        try:
2174            dup.send(MSG)
2175        except socket.error, se:
2176            self.failUnlessEqual(se[0], errno.EBADF)
2177
2178        fp = self.s.makefile()
2179        try:
2180            fp.write(MSG)
2181            fp.flush()
2182        except socket.error, se:
2183            self.failUnlessEqual(se[0], errno.EBADF)
2184
2185class TestJythonTCPExceptions(TestJythonExceptionsShared, unittest.TestCase):
2186
2187    def setUp(self):
2188        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2189        self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2190
2191    def testConnectionRefused(self):
2192        try:
2193            # This port should not be open at this time
2194            self.s.connect( (HOST, PORT) )
2195        except socket.error, se:
2196            self.failUnlessEqual(se[0], errno.ECONNREFUSED)
2197        except Exception, x:
2198            self.fail("Connection to non-existent host/port raised wrong exception: %s" % x)
2199        else:
2200            self.fail("Socket (%s,%s) should not have been listening at this time" % (HOST, PORT))
2201
2202    def testBindException(self):
2203        # First bind to the target port
2204        self.s.bind( (HOST, PORT) )
2205        self.s.listen(50)
2206        try:
2207            # And then try to bind again
2208            t = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2209            t.bind( (HOST, PORT) )
2210            t.listen(50)
2211        except socket.error, se:
2212            self.failUnlessEqual(se[0], errno.EADDRINUSE)
2213        except Exception, x:
2214            self.fail("Binding to already bound host/port raised wrong exception: %s" % x)
2215        else:
2216            self.fail("Binding to already bound host/port should have raised exception")
2217
2218class TestJythonUDPExceptions(TestJythonExceptionsShared, unittest.TestCase):
2219
2220    def setUp(self):
2221        self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
2222        self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2223
2224    def testBindException(self):
2225        # First bind to the target port
2226        self.s.bind( (HOST, PORT) )
2227        try:
2228            # And then try to bind again
2229            t = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
2230            t.bind( (HOST, PORT) )
2231        except socket.error, se:
2232            self.failUnlessEqual(se[0], errno.EADDRINUSE)
2233        except Exception, x:
2234            self.fail("Binding to already bound host/port raised wrong exception: %s" % x)
2235        else:
2236            self.fail("Binding to already bound host/port should have raised exception")
2237
2238class TestAddressParameters:
2239
2240    def testBindNonTupleEndpointRaisesTypeError(self):
2241        try:
2242            self.socket.bind(HOST, PORT)
2243        except TypeError:
2244            pass
2245        else:
2246            self.fail("Illegal non-tuple bind address did not raise TypeError")
2247
2248    def testConnectNonTupleEndpointRaisesTypeError(self):
2249        try:
2250            self.socket.connect(HOST, PORT)
2251        except TypeError:
2252            pass
2253        else:
2254            self.fail("Illegal non-tuple connect address did not raise TypeError")
2255
2256    def testConnectExNonTupleEndpointRaisesTypeError(self):
2257        try:
2258            self.socket.connect_ex(HOST, PORT)
2259        except TypeError:
2260            pass
2261        else:
2262            self.fail("Illegal non-tuple connect address did not raise TypeError")
2263
2264class TestTCPAddressParameters(unittest.TestCase, TestAddressParameters):
2265
2266    def setUp(self):
2267        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2268
2269class TestUDPAddressParameters(unittest.TestCase, TestAddressParameters):
2270
2271    def setUp(self):
2272        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
2273
2274class UnicodeTest(ThreadedTCPSocketTest):
2275
2276    def testUnicodeHostname(self):
2277        pass
2278
2279    def _testUnicodeHostname(self):
2280        self.cli.connect((unicode(self.HOST), self.PORT))
2281
2282class IDNATest(unittest.TestCase):
2283
2284    def testGetAddrInfoIDNAHostname(self):
2285        idna_domain = u"al\u00e1n.com"
2286        if socket.supports('idna'):
2287            try:
2288                addresses = socket.getaddrinfo(idna_domain, 80)
2289                self.failUnless(len(addresses) > 0, "No addresses returned for test IDNA domain '%s'" % repr(idna_domain))
2290            except Exception, x:
2291                self.fail("Unexpected exception raised for socket.getaddrinfo(%s)" % repr(idna_domain))
2292        else:
2293            try:
2294                socket.getaddrinfo(idna_domain, 80)
2295            except UnicodeEncodeError:
2296                pass
2297            except Exception, x:
2298                self.fail("Non ascii domain '%s' should have raised UnicodeEncodeError, not %s" % (repr(idna_domain), str(x)))
2299            else:
2300                self.fail("Non ascii domain '%s' should have raised UnicodeEncodeError: no exception raised" % repr(idna_domain))
2301
2302    def testAddrTupleIDNAHostname(self):
2303        idna_domain = u"al\u00e1n.com"
2304        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2305        if socket.supports('idna'):
2306            try:
2307                s.bind( (idna_domain, 80) )
2308            except socket.error:
2309                # We're not worried about socket errors, i.e. bind problems, etc.
2310                pass
2311            except Exception, x:
2312                self.fail("Unexpected exception raised for socket.bind(%s)" % repr(idna_domain))
2313        else:
2314            try:
2315                s.bind( (idna_domain, 80) )
2316            except UnicodeEncodeError:
2317                pass
2318            except Exception, x:
2319                self.fail("Non ascii domain '%s' should have raised UnicodeEncodeError, not %s" % (repr(idna_domain), str(x)))
2320            else:
2321                self.fail("Non ascii domain '%s' should have raised UnicodeEncodeError: no exception raised" % repr(idna_domain))
2322
2323class TestInvalidUsage(unittest.TestCase):
2324
2325    def setUp(self):
2326        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2327
2328    def testShutdownIOOnListener(self):
2329        self.socket.listen(50) # socket is now a server socket
2330        try:
2331            self.socket.shutdown(socket.SHUT_RDWR)
2332        except Exception, x:
2333            self.fail("Shutdown on listening socket should not have raised socket exception, not %s" % str(x))
2334        else:
2335            pass
2336
2337    def testShutdownOnUnconnectedSocket(self):
2338        try:
2339            self.socket.shutdown(socket.SHUT_RDWR)
2340        except socket.error, se:
2341            self.failUnlessEqual(se[0], errno.ENOTCONN, "Shutdown on unconnected socket should have raised errno.ENOTCONN, not %s" % str(se[0]))
2342        except Exception, x:
2343            self.fail("Shutdown on unconnected socket should have raised socket exception, not %s" % str(x))
2344        else:
2345            self.fail("Shutdown on unconnected socket should have raised socket exception")
2346
2347class TestGetSockAndPeerName:
2348
2349    def testGetpeernameNoImpl(self):
2350        try:
2351            self.s.getpeername()
2352        except socket.error, se:
2353            if se[0] == errno.ENOTCONN:
2354                return
2355        self.fail("getpeername() on unconnected socket should have raised socket.error")
2356
2357    def testGetsocknameUnboundNoImpl(self):
2358        try:
2359            self.s.getsockname()
2360        except socket.error, se:
2361            if se[0] == errno.EINVAL:
2362                return
2363        self.fail("getsockname() on unconnected socket should have raised socket.error")
2364
2365    def testGetsocknameBoundNoImpl(self):
2366        self.s.bind( ("localhost", 0) )
2367        try:
2368            self.s.getsockname()
2369        except socket.error, se:
2370            self.fail("getsockname() on bound socket should have not raised socket.error")
2371
2372    def testGetsocknameImplCreated(self):
2373        self._create_impl_socket()
2374        try:
2375            self.s.getsockname()
2376        except socket.error, se:
2377            self.fail("getsockname() on active socket should not have raised socket.error")
2378
2379    def tearDown(self):
2380        self.s.close()
2381
2382class TestGetSockAndPeerNameTCPClient(unittest.TestCase, TestGetSockAndPeerName):
2383
2384    def setUp(self):
2385        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2386        # This server is not needed for all tests, but create it anyway
2387        # It uses an ephemeral port, so there should be no port clashes or
2388        # problems with reuse.
2389        self.server_peer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2390        self.server_peer.bind( ("localhost", 0) )
2391        self.server_peer.listen(5)
2392
2393    def _create_impl_socket(self):
2394        self.s.connect(self.server_peer.getsockname())
2395
2396    def testGetpeernameImplCreated(self):
2397        self._create_impl_socket()
2398        try:
2399            self.s.getpeername()
2400        except socket.error, se:
2401            self.fail("getpeername() on active socket should not have raised socket.error")
2402        self.failUnlessEqual(self.s.getpeername(), self.server_peer.getsockname())
2403
2404    def tearDown(self):
2405        self.server_peer.close()
2406
2407class TestGetSockAndPeerNameTCPServer(unittest.TestCase, TestGetSockAndPeerName):
2408
2409    def setUp(self):
2410        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2411
2412    def _create_impl_socket(self):
2413        self.s.bind(("localhost", 0))
2414        self.s.listen(5)
2415
2416    def testGetpeernameImplCreated(self):
2417        self._create_impl_socket()
2418        try:
2419            self.s.getpeername()
2420        except socket.error, se:
2421            if se[0] == errno.ENOTCONN:
2422                return
2423        self.fail("getpeername() on listening socket should have raised socket.error")
2424
2425class TestGetSockAndPeerNameUDP(unittest.TestCase, TestGetSockAndPeerName):
2426
2427    def setUp(self):
2428        self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
2429
2430    def _create_impl_socket(self):
2431        # Binding is enough to cause socket impl creation
2432        self.s.bind(("localhost", 0))
2433
2434    def testGetpeernameImplCreatedNotConnected(self):
2435        self._create_impl_socket()
2436        try:
2437            self.s.getpeername()
2438        except socket.error, se:
2439            if se[0] == errno.ENOTCONN:
2440                return
2441        self.fail("getpeername() on unconnected UDP socket should have raised socket.error")
2442
2443    def testGetpeernameImplCreatedAndConnected(self):
2444        # This test also tests that an UDP socket can be bound and connected at the same time
2445        self._create_impl_socket()
2446        # Need to connect to an UDP port
2447        self._udp_peer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
2448        self._udp_peer.bind( ("localhost", 0) )
2449        self.s.connect(self._udp_peer.getsockname())
2450        try:
2451            try:
2452                self.s.getpeername()
2453            except socket.error, se:
2454                self.fail("getpeername() on connected UDP socket should not have raised socket.error")
2455            self.failUnlessEqual(self.s.getpeername(), self._udp_peer.getsockname())
2456        finally:
2457            self._udp_peer.close()
2458
2459def test_main():
2460    tests = [
2461        GeneralModuleTests,
2462        IPAddressTests,
2463        TestSupportedOptions,
2464        TestPseudoOptions,
2465        TestUnsupportedOptions,
2466        BasicTCPTest,
2467        TCPServerTimeoutTest,
2468        TCPClientTimeoutTest,
2469        TestExceptions,
2470        TestInvalidUsage,
2471        TestGetAddrInfo,
2472        TestGetNameInfo,
2473        TestTCPAddressParameters,
2474        TestUDPAddressParameters,
2475        UDPBindTest,
2476        BasicUDPTest,
2477        UDPTimeoutTest,
2478        NonBlockingTCPTests,
2479        NonBlockingUDPTests,
2480        TCPFileObjectClassOpenCloseTests,
2481        UDPFileObjectClassOpenCloseTests,
2482        FileAndDupOpenCloseTests,
2483        FileObjectClassTestCase,
2484        PrivateFileObjectTestCase,
2485        UnbufferedFileObjectClassTestCase,
2486        LineBufferedFileObjectClassTestCase,
2487        SmallBufferedFileObjectClassTestCase,
2488        UnicodeTest,
2489        IDNATest,
2490        TestGetSockAndPeerNameTCPClient, 
2491        TestGetSockAndPeerNameTCPServer, 
2492        TestGetSockAndPeerNameUDP,
2493    ]
2494    if hasattr(socket, "socketpair"):
2495        tests.append(BasicSocketPairTest)
2496    if sys.platform[:4] == 'java':
2497        tests.append(TestJythonTCPExceptions)
2498        tests.append(TestJythonUDPExceptions)
2499        tests.append(TestJython_get_jsockaddr)
2500    # TODO: Broadcast requires permission, and is blocked by some firewalls
2501    # Need some way to discover the network setup on the test machine
2502    if False:
2503        tests.append(UDPBroadcastTest)
2504    suites = [unittest.makeSuite(klass, 'test') for klass in tests]
2505    test_support._run_suite(unittest.TestSuite(suites))
2506
2507if __name__ == "__main__":
2508    test_main()