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