/pypy/module/_socket/test/test_sock_app.py
Python | 686 lines | 648 code | 23 blank | 15 comment | 22 complexity | b9118deb8d9e256273841f9ce8372b89 MD5 | raw file
1import sys 2import py 3from pypy.tool.pytest.objspace import gettestobjspace 4from pypy.tool.udir import udir 5from pypy.rlib import rsocket 6from pypy.rpython.lltypesystem import lltype, rffi 7 8def setup_module(mod): 9 mod.space = gettestobjspace(usemodules=['_socket', 'array', 'struct']) 10 global socket 11 import socket 12 mod.w_socket = space.appexec([], "(): import _socket as m; return m") 13 mod.path = udir.join('fd') 14 mod.path.write('fo') 15 mod.raises = py.test.raises # make raises available from app-level tests 16 mod.skip = py.test.skip 17 18def test_gethostname(): 19 host = space.appexec([w_socket], "(_socket): return _socket.gethostname()") 20 assert space.unwrap(host) == socket.gethostname() 21 22def test_gethostbyname(): 23 host = "localhost" 24 ip = space.appexec([w_socket, space.wrap(host)], 25 "(_socket, host): return _socket.gethostbyname(host)") 26 assert space.unwrap(ip) == socket.gethostbyname(host) 27 28def test_gethostbyname_ex(): 29 host = "localhost" 30 ip = space.appexec([w_socket, space.wrap(host)], 31 "(_socket, host): return _socket.gethostbyname_ex(host)") 32 assert isinstance(space.unwrap(ip), tuple) 33 assert space.unwrap(ip) == socket.gethostbyname_ex(host) 34 35def test_gethostbyaddr(): 36 host = "localhost" 37 expected = socket.gethostbyaddr(host) 38 expecteds = (expected, expected[:2]+(['0.0.0.0'],)) 39 ip = space.appexec([w_socket, space.wrap(host)], 40 "(_socket, host): return _socket.gethostbyaddr(host)") 41 assert space.unwrap(ip) in expecteds 42 host = "127.0.0.1" 43 expected = socket.gethostbyaddr(host) 44 expecteds = (expected, expected[:2]+(['0.0.0.0'],)) 45 ip = space.appexec([w_socket, space.wrap(host)], 46 "(_socket, host): return _socket.gethostbyaddr(host)") 47 assert space.unwrap(ip) in expecteds 48 49def test_getservbyname(): 50 name = "smtp" 51 # 2 args version 52 port = space.appexec([w_socket, space.wrap(name)], 53 "(_socket, name): return _socket.getservbyname(name, 'tcp')") 54 assert space.unwrap(port) == 25 55 # 1 arg version 56 if sys.version_info < (2, 4): 57 py.test.skip("getservbyname second argument is not optional before python 2.4") 58 port = space.appexec([w_socket, space.wrap(name)], 59 "(_socket, name): return _socket.getservbyname(name)") 60 assert space.unwrap(port) == 25 61 62def test_getservbyport(): 63 if sys.version_info < (2, 4): 64 py.test.skip("getservbyport does not exist before python 2.4") 65 port = 25 66 # 2 args version 67 name = space.appexec([w_socket, space.wrap(port)], 68 "(_socket, port): return _socket.getservbyport(port, 'tcp')") 69 assert space.unwrap(name) == "smtp" 70 name = space.appexec([w_socket, space.wrap(port)], 71 """(_socket, port): 72 try: 73 return _socket.getservbyport(port, 42) 74 except TypeError: 75 return 'OK' 76 """) 77 assert space.unwrap(name) == 'OK' 78 # 1 arg version 79 name = space.appexec([w_socket, space.wrap(port)], 80 "(_socket, port): return _socket.getservbyport(port)") 81 assert space.unwrap(name) == "smtp" 82 83 from pypy.interpreter.error import OperationError 84 exc = raises(OperationError, space.appexec, 85 [w_socket], "(_socket): return _socket.getservbyport(-1)") 86 assert exc.value.match(space, space.w_ValueError) 87 88def test_getprotobyname(): 89 name = "tcp" 90 w_n = space.appexec([w_socket, space.wrap(name)], 91 "(_socket, name): return _socket.getprotobyname(name)") 92 assert space.unwrap(w_n) == socket.IPPROTO_TCP 93 94def test_fromfd(): 95 # XXX review 96 if not hasattr(socket, 'fromfd'): 97 py.test.skip("No socket.fromfd on this platform") 98 orig_fd = path.open() 99 fd = space.appexec([w_socket, space.wrap(orig_fd.fileno()), 100 space.wrap(socket.AF_INET), space.wrap(socket.SOCK_STREAM), 101 space.wrap(0)], 102 """(_socket, fd, family, type, proto): 103 return _socket.fromfd(fd, family, type, proto)""") 104 105 assert space.unwrap(space.call_method(fd, 'fileno')) 106 fd = space.appexec([w_socket, space.wrap(orig_fd.fileno()), 107 space.wrap(socket.AF_INET), space.wrap(socket.SOCK_STREAM)], 108 """(_socket, fd, family, type): 109 return _socket.fromfd(fd, family, type)""") 110 111 assert space.unwrap(space.call_method(fd, 'fileno')) 112 113def test_ntohs(): 114 w_n = space.appexec([w_socket, space.wrap(125)], 115 "(_socket, x): return _socket.ntohs(x)") 116 assert space.unwrap(w_n) == socket.ntohs(125) 117 118def test_ntohl(): 119 w_n = space.appexec([w_socket, space.wrap(125)], 120 "(_socket, x): return _socket.ntohl(x)") 121 assert space.unwrap(w_n) == socket.ntohl(125) 122 w_n = space.appexec([w_socket, space.wrap(0x89abcdef)], 123 "(_socket, x): return _socket.ntohl(x)") 124 assert space.unwrap(w_n) in (0x89abcdef, 0xefcdab89) 125 space.raises_w(space.w_OverflowError, space.appexec, 126 [w_socket, space.wrap(1<<32)], 127 "(_socket, x): return _socket.ntohl(x)") 128 129def test_htons(): 130 w_n = space.appexec([w_socket, space.wrap(125)], 131 "(_socket, x): return _socket.htons(x)") 132 assert space.unwrap(w_n) == socket.htons(125) 133 134def test_htonl(): 135 w_n = space.appexec([w_socket, space.wrap(125)], 136 "(_socket, x): return _socket.htonl(x)") 137 assert space.unwrap(w_n) == socket.htonl(125) 138 w_n = space.appexec([w_socket, space.wrap(0x89abcdef)], 139 "(_socket, x): return _socket.htonl(x)") 140 assert space.unwrap(w_n) in (0x89abcdef, 0xefcdab89) 141 space.raises_w(space.w_OverflowError, space.appexec, 142 [w_socket, space.wrap(1<<32)], 143 "(_socket, x): return _socket.htonl(x)") 144 145def test_aton_ntoa(): 146 ip = '123.45.67.89' 147 packed = socket.inet_aton(ip) 148 w_p = space.appexec([w_socket, space.wrap(ip)], 149 "(_socket, ip): return _socket.inet_aton(ip)") 150 assert space.unwrap(w_p) == packed 151 w_ip = space.appexec([w_socket, space.wrap(packed)], 152 "(_socket, p): return _socket.inet_ntoa(p)") 153 assert space.unwrap(w_ip) == ip 154 155def test_pton_ntop_ipv4(): 156 if not hasattr(socket, 'inet_pton'): 157 py.test.skip('No socket.inet_pton on this platform') 158 tests = [ 159 ("123.45.67.89", "\x7b\x2d\x43\x59"), 160 ("0.0.0.0", "\x00" * 4), 161 ("255.255.255.255", "\xff" * 4), 162 ] 163 for ip, packed in tests: 164 w_p = space.appexec([w_socket, space.wrap(ip)], 165 "(_socket, ip): return _socket.inet_pton(_socket.AF_INET, ip)") 166 assert space.unwrap(w_p) == packed 167 w_ip = space.appexec([w_socket, w_p], 168 "(_socket, p): return _socket.inet_ntop(_socket.AF_INET, p)") 169 assert space.unwrap(w_ip) == ip 170 171def test_ntop_ipv6(): 172 if not hasattr(socket, 'inet_pton'): 173 py.test.skip('No socket.inet_pton on this platform') 174 if not socket.has_ipv6: 175 py.test.skip("No IPv6 on this platform") 176 tests = [ 177 ("\x00" * 16, "::"), 178 ("\x01" * 16, ":".join(["101"] * 8)), 179 ("\x00\x00\x10\x10" * 4, None), #"::1010:" + ":".join(["0:1010"] * 3)), 180 ("\x00" * 12 + "\x01\x02\x03\x04", "::1.2.3.4"), 181 ("\x00" * 10 + "\xff\xff\x01\x02\x03\x04", "::ffff:1.2.3.4"), 182 ] 183 for packed, ip in tests: 184 w_ip = space.appexec([w_socket, space.wrap(packed)], 185 "(_socket, packed): return _socket.inet_ntop(_socket.AF_INET6, packed)") 186 if ip is not None: # else don't check for the precise representation 187 assert space.unwrap(w_ip) == ip 188 w_packed = space.appexec([w_socket, w_ip], 189 "(_socket, ip): return _socket.inet_pton(_socket.AF_INET6, ip)") 190 assert space.unwrap(w_packed) == packed 191 192def test_pton_ipv6(): 193 if not hasattr(socket, 'inet_pton'): 194 py.test.skip('No socket.inet_pton on this platform') 195 if not socket.has_ipv6: 196 py.test.skip("No IPv6 on this platform") 197 tests = [ 198 ("\x00" * 16, "::"), 199 ("\x01" * 16, ":".join(["101"] * 8)), 200 ("\x00\x01" + "\x00" * 12 + "\x00\x02", "1::2"), 201 ("\x00" * 4 + "\x00\x01" * 6, "::1:1:1:1:1:1"), 202 ("\x00\x01" * 6 + "\x00" * 4, "1:1:1:1:1:1::"), 203 ("\xab\xcd\xef\00" + "\x00" * 12, "ABCD:EF00::"), 204 ("\xab\xcd\xef\00" + "\x00" * 12, "abcd:ef00::"), 205 ("\x00\x00\x10\x10" * 4, "::1010:" + ":".join(["0:1010"] * 3)), 206 ("\x00" * 12 + "\x01\x02\x03\x04", "::1.2.3.4"), 207 ("\x00" * 10 + "\xff\xff\x01\x02\x03\x04", "::ffff:1.2.3.4"), 208 ] 209 for packed, ip in tests: 210 w_packed = space.appexec([w_socket, space.wrap(ip)], 211 "(_socket, ip): return _socket.inet_pton(_socket.AF_INET6, ip)") 212 assert space.unwrap(w_packed) == packed 213 214def test_has_ipv6(): 215 py.test.skip("has_ipv6 is always True on PyPy for now") 216 res = space.appexec([w_socket], "(_socket): return _socket.has_ipv6") 217 assert space.unwrap(res) == socket.has_ipv6 218 219def test_getaddrinfo(): 220 host = "localhost" 221 port = 25 222 info = socket.getaddrinfo(host, port) 223 w_l = space.appexec([w_socket, space.wrap(host), space.wrap(port)], 224 "(_socket, host, port): return _socket.getaddrinfo(host, port)") 225 assert space.unwrap(w_l) == info 226 py.test.skip("Unicode conversion is too slow") 227 w_l = space.appexec([w_socket, space.wrap(unicode(host)), space.wrap(port)], 228 "(_socket, host, port): return _socket.getaddrinfo(host, port)") 229 assert space.unwrap(w_l) == info 230 231def test_unknown_addr_as_object(): 232 c_addr = lltype.malloc(rsocket._c.sockaddr, flavor='raw') 233 c_addr.c_sa_data[0] = 'c' 234 rffi.setintfield(c_addr, 'c_sa_family', 15) 235 # XXX what size to pass here? for the purpose of this test it has 236 # to be short enough so we have some data, 1 sounds good enough 237 # + sizeof USHORT 238 w_obj = rsocket.Address(c_addr, 1 + 2).as_object(-1, space) 239 assert space.is_true(space.isinstance(w_obj, space.w_tuple)) 240 assert space.int_w(space.getitem(w_obj, space.wrap(0))) == 15 241 assert space.str_w(space.getitem(w_obj, space.wrap(1))) == 'c' 242 243def test_addr_raw_packet(): 244 if not hasattr(rsocket._c, 'sockaddr_ll'): 245 py.test.skip("posix specific test") 246 # HACK: To get the correct interface numer of lo, which in most cases is 1, 247 # but can be anything (i.e. 39), we need to call the libc function 248 # if_nametoindex to get the correct index 249 import ctypes 250 libc = ctypes.CDLL(ctypes.util.find_library('c')) 251 ifnum = libc.if_nametoindex('lo') 252 253 c_addr_ll = lltype.malloc(rsocket._c.sockaddr_ll, flavor='raw') 254 addrlen = rffi.sizeof(rsocket._c.sockaddr_ll) 255 c_addr = rffi.cast(lltype.Ptr(rsocket._c.sockaddr), c_addr_ll) 256 rffi.setintfield(c_addr_ll, 'c_sll_ifindex', ifnum) 257 rffi.setintfield(c_addr_ll, 'c_sll_protocol', 8) 258 rffi.setintfield(c_addr_ll, 'c_sll_pkttype', 13) 259 rffi.setintfield(c_addr_ll, 'c_sll_hatype', 0) 260 rffi.setintfield(c_addr_ll, 'c_sll_halen', 3) 261 c_addr_ll.c_sll_addr[0] = 'a' 262 c_addr_ll.c_sll_addr[1] = 'b' 263 c_addr_ll.c_sll_addr[2] = 'c' 264 rffi.setintfield(c_addr, 'c_sa_family', socket.AF_PACKET) 265 # fd needs to be somehow valid 266 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 267 fd = s.fileno() 268 w_obj = rsocket.make_address(c_addr, addrlen).as_object(fd, space) 269 lltype.free(c_addr_ll, flavor='raw') 270 assert space.is_true(space.eq(w_obj, space.newtuple([ 271 space.wrap('lo'), 272 space.wrap(socket.ntohs(8)), 273 space.wrap(13), 274 space.wrap(False), 275 space.wrap("abc"), 276 ]))) 277 278def test_getnameinfo(): 279 host = "127.0.0.1" 280 port = 25 281 info = socket.getnameinfo((host, port), 0) 282 w_l = space.appexec([w_socket, space.wrap(host), space.wrap(port)], 283 "(_socket, host, port): return _socket.getnameinfo((host, port), 0)") 284 assert space.unwrap(w_l) == info 285 286def test_timeout(): 287 space.appexec([w_socket, space.wrap(25.4)], 288 "(_socket, timeout): _socket.setdefaulttimeout(timeout)") 289 w_t = space.appexec([w_socket], 290 "(_socket): return _socket.getdefaulttimeout()") 291 assert space.unwrap(w_t) == 25.4 292 293 space.appexec([w_socket, space.w_None], 294 "(_socket, timeout): _socket.setdefaulttimeout(timeout)") 295 w_t = space.appexec([w_socket], 296 "(_socket): return _socket.getdefaulttimeout()") 297 assert space.unwrap(w_t) is None 298 299 300# XXX also need tests for other connection and timeout errors 301 302 303class AppTestSocket: 304 def setup_class(cls): 305 cls.space = space 306 cls.w_udir = space.wrap(str(udir)) 307 308 def test_ntoa_exception(self): 309 import _socket 310 raises(_socket.error, _socket.inet_ntoa, "ab") 311 312 def test_aton_exceptions(self): 313 import _socket 314 tests = ["127.0.0.256", "127.0.0.255555555555555555", "127.2b.0.0", 315 "127.2.0.0.1", "127.2.0."] 316 for ip in tests: 317 raises(_socket.error, _socket.inet_aton, ip) 318 319 def test_ntop_exceptions(self): 320 import _socket 321 if not hasattr(_socket, 'inet_ntop'): 322 skip('No socket.inet_pton on this platform') 323 for family, packed, exception in \ 324 [(_socket.AF_INET + _socket.AF_INET6, "", _socket.error), 325 (_socket.AF_INET, "a", ValueError), 326 (_socket.AF_INET6, "a", ValueError), 327 (_socket.AF_INET, u"aa\u2222a", UnicodeEncodeError)]: 328 raises(exception, _socket.inet_ntop, family, packed) 329 330 def test_pton_exceptions(self): 331 import _socket 332 if not hasattr(_socket, 'inet_pton'): 333 skip('No socket.inet_pton on this platform') 334 tests = [ 335 (_socket.AF_INET + _socket.AF_INET6, ""), 336 (_socket.AF_INET, "127.0.0.256"), 337 (_socket.AF_INET, "127.0.0.255555555555555555"), 338 (_socket.AF_INET, "127.2b.0.0"), 339 (_socket.AF_INET, "127.2.0.0.1"), 340 (_socket.AF_INET, "127.2..0"), 341 (_socket.AF_INET6, "127.0.0.1"), 342 (_socket.AF_INET6, "1::2::3"), 343 (_socket.AF_INET6, "1:1:1:1:1:1:1:1:1"), 344 (_socket.AF_INET6, "1:1:1:1:1:1:1:1::"), 345 (_socket.AF_INET6, "1:1:1::1:1:1:1:1"), 346 (_socket.AF_INET6, "1::22222:1"), 347 (_socket.AF_INET6, "1::eg"), 348 ] 349 for family, ip in tests: 350 raises(_socket.error, _socket.inet_pton, family, ip) 351 352 def test_newsocket_error(self): 353 import _socket 354 raises(_socket.error, _socket.socket, 10001, _socket.SOCK_STREAM, 0) 355 356 def test_socket_fileno(self): 357 import _socket 358 s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) 359 assert s.fileno() > -1 360 assert isinstance(s.fileno(), int) 361 362 def test_socket_close(self): 363 import _socket 364 s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) 365 fileno = s.fileno() 366 assert s.fileno() >= 0 367 s.close() 368 assert s.fileno() < 0 369 s.close() 370 371 def test_socket_close_error(self): 372 import _socket, os 373 if os.name == 'nt': 374 skip("Windows sockets are not files") 375 s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) 376 os.close(s.fileno()) 377 raises(_socket.error, s.close) 378 379 def test_socket_connect(self): 380 import _socket, os 381 s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) 382 # it would be nice to have a test which works even if there is no 383 # network connection. However, this one is "good enough" for now. Skip 384 # it if there is no connection. 385 try: 386 s.connect(("www.python.org", 80)) 387 except _socket.gaierror, ex: 388 skip("GAIError - probably no connection: %s" % str(ex.args)) 389 name = s.getpeername() # Will raise socket.error if not connected 390 assert name[1] == 80 391 s.close() 392 393 def test_socket_connect_ex(self): 394 import _socket 395 s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) 396 # Make sure we get an app-level error, not an interp one. 397 raises(_socket.gaierror, s.connect_ex, ("wrong.invalid", 80)) 398 s.close() 399 400 def test_socket_connect_typeerrors(self): 401 tests = [ 402 "", 403 ("80"), 404 ("80", "80"), 405 (80, 80), 406 ] 407 import _socket 408 s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) 409 for args in tests: 410 raises((TypeError, ValueError), s.connect, args) 411 s.close() 412 413 def test_bigport(self): 414 import _socket 415 s = _socket.socket() 416 raises(ValueError, s.connect, ("localhost", 1000000)) 417 raises(ValueError, s.connect, ("localhost", -1)) 418 419 def test_NtoH(self): 420 import sys 421 import _socket as socket 422 # This just checks that htons etc. are their own inverse, 423 # when looking at the lower 16 or 32 bits. 424 sizes = {socket.htonl: 32, socket.ntohl: 32, 425 socket.htons: 16, socket.ntohs: 16} 426 for func, size in sizes.items(): 427 mask = (1L<<size) - 1 428 for i in (0, 1, 0xffff, ~0xffff, 2, 0x01234567, 0x76543210): 429 assert i & mask == func(func(i&mask)) & mask 430 431 swapped = func(mask) 432 assert swapped & mask == mask 433 try: 434 func(-1) 435 except (OverflowError, ValueError): 436 pass 437 else: 438 assert False 439 try: 440 func(sys.maxint*2+2) 441 except OverflowError: 442 pass 443 else: 444 assert False 445 446 def test_NtoH_overflow(self): 447 skip("we are not checking for overflowing values yet") 448 import _socket as socket 449 # Checks that we cannot give too large values to htons etc. 450 # Skipped for now; CPython 2.6 is also not consistent. 451 sizes = {socket.htonl: 32, socket.ntohl: 32, 452 socket.htons: 16, socket.ntohs: 16} 453 for func, size in sizes.items(): 454 try: 455 func(1L << size) 456 except OverflowError: 457 pass 458 else: 459 assert False 460 461 def test_newsocket(self): 462 import socket 463 s = socket.socket() 464 465 def test_getsetsockopt(self): 466 import _socket as socket 467 import struct 468 # A socket sould start with reuse == 0 469 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 470 reuse = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) 471 assert reuse == 0 472 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 473 reuse = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) 474 assert reuse != 0 475 # String case 476 intsize = struct.calcsize('i') 477 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 478 reusestr = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 479 intsize) 480 (reuse,) = struct.unpack('i', reusestr) 481 assert reuse == 0 482 reusestr = struct.pack('i', 1) 483 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, reusestr) 484 reusestr = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 485 intsize) 486 (reuse,) = struct.unpack('i', reusestr) 487 assert reuse != 0 488 489 def test_socket_ioctl(self): 490 import _socket, sys 491 if sys.platform != 'win32': 492 skip("win32 only") 493 assert hasattr(_socket.socket, 'ioctl') 494 assert hasattr(_socket, 'SIO_RCVALL') 495 assert hasattr(_socket, 'RCVALL_ON') 496 assert hasattr(_socket, 'RCVALL_OFF') 497 assert hasattr(_socket, 'SIO_KEEPALIVE_VALS') 498 s = _socket.socket() 499 raises(ValueError, s.ioctl, -1, None) 500 s.ioctl(_socket.SIO_KEEPALIVE_VALS, (1, 100, 100)) 501 502 def test_dup(self): 503 import _socket as socket 504 if not hasattr(socket.socket, 'dup'): 505 skip('No dup() on this platform') 506 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 507 s.bind(('localhost', 0)) 508 s2 = s.dup() 509 assert s.fileno() != s2.fileno() 510 assert s.getsockname() == s2.getsockname() 511 512 def test_buffer_or_unicode(self): 513 # Test that send/sendall/sendto accept a buffer or a unicode as arg 514 import _socket, os 515 s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0) 516 # XXX temporarily we use python.org to test, will have more robust tests 517 # in the absence of a network connection later when more parts of the 518 # socket API are implemented. Currently skip the test if there is no 519 # connection. 520 try: 521 s.connect(("www.python.org", 80)) 522 except _socket.gaierror, ex: 523 skip("GAIError - probably no connection: %s" % str(ex.args)) 524 s.send(buffer('')) 525 s.sendall(buffer('')) 526 s.send(u'') 527 s.sendall(u'') 528 raises(UnicodeEncodeError, s.send, u'\xe9') 529 s.close() 530 s = _socket.socket(_socket.AF_INET, _socket.SOCK_DGRAM, 0) 531 s.sendto(buffer(''), ('localhost', 9)) # Send to discard port. 532 s.close() 533 534 def test_unix_socket_connect(self): 535 import _socket, os 536 if not hasattr(_socket, 'AF_UNIX'): 537 skip('AF_UNIX not supported.') 538 oldcwd = os.getcwd() 539 os.chdir(self.udir) 540 try: 541 sockpath = 'app_test_unix_socket_connect' 542 543 serversock = _socket.socket(_socket.AF_UNIX) 544 serversock.bind(sockpath) 545 serversock.listen(1) 546 547 clientsock = _socket.socket(_socket.AF_UNIX) 548 clientsock.connect(sockpath) 549 s, addr = serversock.accept() 550 assert not addr 551 552 s.send('X') 553 data = clientsock.recv(100) 554 assert data == 'X' 555 clientsock.send('Y') 556 data = s.recv(100) 557 assert data == 'Y' 558 559 clientsock.close() 560 s.close() 561 finally: 562 os.chdir(oldcwd) 563 564 565class AppTestSocketTCP: 566 def setup_class(cls): 567 cls.space = space 568 569 HOST = 'localhost' 570 571 def setup_method(self, method): 572 w_HOST = space.wrap(self.HOST) 573 self.w_serv = space.appexec([w_socket, w_HOST], 574 '''(_socket, HOST): 575 serv = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM) 576 serv.bind((HOST, 0)) 577 serv.listen(1) 578 return serv 579 ''') 580 def teardown_method(self, method): 581 if hasattr(self, 'w_serv'): 582 space.appexec([self.w_serv], '(serv): serv.close()') 583 self.w_serv = None 584 585 def test_timeout(self): 586 from _socket import timeout 587 def raise_timeout(): 588 self.serv.settimeout(1.0) 589 self.serv.accept() 590 raises(timeout, raise_timeout) 591 592 def test_timeout_zero(self): 593 from _socket import error 594 def raise_error(): 595 self.serv.settimeout(0.0) 596 foo = self.serv.accept() 597 raises(error, raise_error) 598 599 def test_recv_send_timeout(self): 600 from _socket import socket, timeout 601 cli = socket() 602 cli.connect(self.serv.getsockname()) 603 t, addr = self.serv.accept() 604 cli.settimeout(1.0) 605 # test recv() timeout 606 t.send('*') 607 buf = cli.recv(100) 608 assert buf == '*' 609 raises(timeout, cli.recv, 100) 610 # test that send() works 611 count = cli.send('!') 612 assert count == 1 613 buf = t.recv(1) 614 assert buf == '!' 615 # test that sendall() works 616 cli.sendall('?') 617 assert count == 1 618 buf = t.recv(1) 619 assert buf == '?' 620 # test send() timeout 621 count = 0 622 try: 623 while 1: 624 count += cli.send('foobar' * 70) 625 except timeout: 626 pass 627 t.recv(count) 628 # test sendall() timeout 629 try: 630 while 1: 631 cli.sendall('foobar' * 70) 632 except timeout: 633 pass 634 # done 635 cli.close() 636 t.close() 637 638 def test_recv_into(self): 639 import socket 640 import array 641 MSG = 'dupa was here\n' 642 cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 643 cli.connect(self.serv.getsockname()) 644 conn, addr = self.serv.accept() 645 buf = buffer(MSG) 646 conn.send(buf) 647 buf = array.array('c', ' '*1024) 648 nbytes = cli.recv_into(buf) 649 assert nbytes == len(MSG) 650 msg = buf.tostring()[:len(MSG)] 651 assert msg == MSG 652 653 def test_recvfrom_into(self): 654 import socket 655 import array 656 MSG = 'dupa was here\n' 657 cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 658 cli.connect(self.serv.getsockname()) 659 conn, addr = self.serv.accept() 660 buf = buffer(MSG) 661 conn.send(buf) 662 buf = array.array('c', ' '*1024) 663 nbytes, addr = cli.recvfrom_into(buf) 664 assert nbytes == len(MSG) 665 msg = buf.tostring()[:len(MSG)] 666 assert msg == MSG 667 668 def test_family(self): 669 import socket 670 cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 671 assert cli.family == socket.AF_INET 672 673class AppTestErrno: 674 def setup_class(cls): 675 cls.space = space 676 677 def test_errno(self): 678 from socket import socket, AF_INET, SOCK_STREAM, error 679 import errno 680 s = socket(AF_INET, SOCK_STREAM) 681 exc = raises(error, s.accept) 682 assert isinstance(exc.value, error) 683 assert isinstance(exc.value, IOError) 684 # error is EINVAL, or WSAEINVAL on Windows 685 assert exc.value.errno == getattr(errno, 'WSAEINVAL', errno.EINVAL) 686 assert isinstance(exc.value.message, str)