PageRenderTime 3ms CodeModel.GetById 2ms app.highlight 56ms RepoModel.GetById 1ms app.codeStats 1ms

/pypy/module/_socket/test/test_sock_app.py

https://bitbucket.org/jphalip/pypy
Python | 690 lines | 652 code | 23 blank | 15 comment | 22 complexity | 7733db4d42da88d8ac8fbfaca6f4ba4e MD5 | raw file
  1import sys
  2import py
  3from pypy.tool.pytest.objspace import gettestobjspace
  4from rpython.tool.udir import udir
  5from rpython.rlib import rsocket
  6from rpython.rtyper.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    from pypy.module._socket.interp_socket import addr_as_object
233    c_addr = lltype.malloc(rsocket._c.sockaddr, flavor='raw')
234    c_addr.c_sa_data[0] = 'c'
235    rffi.setintfield(c_addr, 'c_sa_family', 15)
236    # XXX what size to pass here? for the purpose of this test it has
237    #     to be short enough so we have some data, 1 sounds good enough
238    #     + sizeof USHORT
239    w_obj = addr_as_object(rsocket.Address(c_addr, 1 + 2), -1, space)
240    assert space.is_true(space.isinstance(w_obj, space.w_tuple))
241    assert space.int_w(space.getitem(w_obj, space.wrap(0))) == 15
242    assert space.str_w(space.getitem(w_obj, space.wrap(1))) == 'c'
243
244def test_addr_raw_packet():
245    from pypy.module._socket.interp_socket import addr_as_object
246    if not hasattr(rsocket._c, 'sockaddr_ll'):
247        py.test.skip("posix specific test")
248    # HACK: To get the correct interface numer of lo, which in most cases is 1,
249    # but can be anything (i.e. 39), we need to call the libc function
250    # if_nametoindex to get the correct index
251    import ctypes
252    libc = ctypes.CDLL(ctypes.util.find_library('c'))
253    ifnum = libc.if_nametoindex('lo')
254
255    c_addr_ll = lltype.malloc(rsocket._c.sockaddr_ll, flavor='raw')
256    addrlen = rffi.sizeof(rsocket._c.sockaddr_ll)
257    c_addr = rffi.cast(lltype.Ptr(rsocket._c.sockaddr), c_addr_ll)
258    rffi.setintfield(c_addr_ll, 'c_sll_ifindex', ifnum)
259    rffi.setintfield(c_addr_ll, 'c_sll_protocol', 8)
260    rffi.setintfield(c_addr_ll, 'c_sll_pkttype', 13)
261    rffi.setintfield(c_addr_ll, 'c_sll_hatype', 0)
262    rffi.setintfield(c_addr_ll, 'c_sll_halen', 3)
263    c_addr_ll.c_sll_addr[0] = 'a'
264    c_addr_ll.c_sll_addr[1] = 'b'
265    c_addr_ll.c_sll_addr[2] = 'c'
266    rffi.setintfield(c_addr, 'c_sa_family', socket.AF_PACKET)
267    # fd needs to be somehow valid
268    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
269    fd = s.fileno()
270    w_obj = addr_as_object(rsocket.make_address(c_addr, addrlen), fd, space)
271    lltype.free(c_addr_ll, flavor='raw')
272    assert space.is_true(space.eq(w_obj, space.newtuple([
273        space.wrap('lo'),
274        space.wrap(socket.ntohs(8)),
275        space.wrap(13),
276        space.wrap(False),
277        space.wrap("abc"),
278        ])))
279
280def test_getnameinfo():
281    host = "127.0.0.1"
282    port = 25
283    info = socket.getnameinfo((host, port), 0)
284    w_l = space.appexec([w_socket, space.wrap(host), space.wrap(port)],
285                        "(_socket, host, port): return _socket.getnameinfo((host, port), 0)")
286    assert space.unwrap(w_l) == info
287
288def test_timeout():
289    space.appexec([w_socket, space.wrap(25.4)],
290                  "(_socket, timeout): _socket.setdefaulttimeout(timeout)")
291    w_t = space.appexec([w_socket],
292                  "(_socket): return _socket.getdefaulttimeout()")
293    assert space.unwrap(w_t) == 25.4
294
295    space.appexec([w_socket, space.w_None],
296                  "(_socket, timeout): _socket.setdefaulttimeout(timeout)")
297    w_t = space.appexec([w_socket],
298                  "(_socket): return _socket.getdefaulttimeout()")
299    assert space.unwrap(w_t) is None
300
301
302# XXX also need tests for other connection and timeout errors
303
304
305class AppTestSocket:
306    def setup_class(cls):
307        cls.space = space
308        cls.w_udir = space.wrap(str(udir))
309
310    def test_ntoa_exception(self):
311        import _socket
312        raises(_socket.error, _socket.inet_ntoa, "ab")
313
314    def test_aton_exceptions(self):
315        import _socket
316        tests = ["127.0.0.256", "127.0.0.255555555555555555", "127.2b.0.0",
317            "127.2.0.0.1", "127.2.0."]
318        for ip in tests:
319            raises(_socket.error, _socket.inet_aton, ip)
320
321    def test_ntop_exceptions(self):
322        import _socket
323        if not hasattr(_socket, 'inet_ntop'):
324            skip('No socket.inet_pton on this platform')
325        for family, packed, exception in \
326                    [(_socket.AF_INET + _socket.AF_INET6, "", _socket.error),
327                     (_socket.AF_INET, "a", ValueError),
328                     (_socket.AF_INET6, "a", ValueError),
329                     (_socket.AF_INET, u"aa\u2222a", UnicodeEncodeError)]:
330            raises(exception, _socket.inet_ntop, family, packed)
331
332    def test_pton_exceptions(self):
333        import _socket
334        if not hasattr(_socket, 'inet_pton'):
335            skip('No socket.inet_pton on this platform')
336        tests = [
337            (_socket.AF_INET + _socket.AF_INET6, ""),
338            (_socket.AF_INET, "127.0.0.256"),
339            (_socket.AF_INET, "127.0.0.255555555555555555"),
340            (_socket.AF_INET, "127.2b.0.0"),
341            (_socket.AF_INET, "127.2.0.0.1"),
342            (_socket.AF_INET, "127.2..0"),
343            (_socket.AF_INET6, "127.0.0.1"),
344            (_socket.AF_INET6, "1::2::3"),
345            (_socket.AF_INET6, "1:1:1:1:1:1:1:1:1"),
346            (_socket.AF_INET6, "1:1:1:1:1:1:1:1::"),
347            (_socket.AF_INET6, "1:1:1::1:1:1:1:1"),
348            (_socket.AF_INET6, "1::22222:1"),
349            (_socket.AF_INET6, "1::eg"),
350        ]
351        for family, ip in tests:
352            raises(_socket.error, _socket.inet_pton, family, ip)
353
354    def test_newsocket_error(self):
355        import _socket
356        raises(_socket.error, _socket.socket, 10001, _socket.SOCK_STREAM, 0)
357
358    def test_socket_fileno(self):
359        import _socket
360        s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
361        assert s.fileno() > -1
362        assert isinstance(s.fileno(), int)
363
364    def test_socket_close(self):
365        import _socket, os
366        s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
367        fileno = s.fileno()
368        assert s.fileno() >= 0
369        s.close()
370        assert s.fileno() < 0
371        s.close()
372        if os.name != 'nt':
373            raises(OSError, os.close, fileno)
374
375    def test_socket_close_error(self):
376        import _socket, os
377        if os.name == 'nt':
378            skip("Windows sockets are not files")
379        s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
380        os.close(s.fileno())
381        s.close()
382
383    def test_socket_connect(self):
384        import _socket, os
385        s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
386        # it would be nice to have a test which works even if there is no
387        # network connection. However, this one is "good enough" for now. Skip
388        # it if there is no connection.
389        try:
390            s.connect(("www.python.org", 80))
391        except _socket.gaierror, ex:
392            skip("GAIError - probably no connection: %s" % str(ex.args))
393        name = s.getpeername() # Will raise socket.error if not connected
394        assert name[1] == 80
395        s.close()
396    
397    def test_socket_connect_ex(self):
398        import _socket
399        s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
400        # Make sure we get an app-level error, not an interp one.
401        raises(_socket.gaierror, s.connect_ex, ("wrong.invalid", 80))
402        s.close()
403
404    def test_socket_connect_typeerrors(self):
405        tests = [
406            "",
407            ("80"),
408            ("80", "80"),
409            (80, 80),
410        ]
411        import _socket
412        s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
413        for args in tests:
414            raises((TypeError, ValueError), s.connect, args)
415        s.close()
416
417    def test_bigport(self):
418        import _socket
419        s = _socket.socket()
420        raises(ValueError, s.connect, ("localhost", 1000000))
421        raises(ValueError, s.connect, ("localhost", -1))
422
423    def test_NtoH(self):
424        import sys
425        import _socket as socket
426        # This just checks that htons etc. are their own inverse,
427        # when looking at the lower 16 or 32 bits.
428        sizes = {socket.htonl: 32, socket.ntohl: 32,
429                 socket.htons: 16, socket.ntohs: 16}
430        for func, size in sizes.items():
431            mask = (1L<<size) - 1
432            for i in (0, 1, 0xffff, ~0xffff, 2, 0x01234567, 0x76543210):
433                assert i & mask == func(func(i&mask)) & mask
434
435            swapped = func(mask)
436            assert swapped & mask == mask
437            try:
438                func(-1)
439            except (OverflowError, ValueError):
440                pass
441            else:
442                assert False
443            try:
444                func(sys.maxint*2+2)
445            except OverflowError:
446                pass
447            else:
448                assert False
449
450    def test_NtoH_overflow(self):
451        skip("we are not checking for overflowing values yet")
452        import _socket as socket
453        # Checks that we cannot give too large values to htons etc.
454        # Skipped for now; CPython 2.6 is also not consistent.
455        sizes = {socket.htonl: 32, socket.ntohl: 32,
456                 socket.htons: 16, socket.ntohs: 16}
457        for func, size in sizes.items():
458            try:
459                func(1L << size)
460            except OverflowError:
461                pass
462            else:
463                assert False
464
465    def test_newsocket(self):
466        import socket
467        s = socket.socket()
468
469    def test_getsetsockopt(self):
470        import _socket as socket
471        import struct
472        # A socket sould start with reuse == 0
473        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
474        reuse = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
475        assert reuse == 0
476        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
477        reuse = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
478        assert reuse != 0
479        # String case
480        intsize = struct.calcsize('i')
481        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
482        reusestr = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
483                                intsize)
484        (reuse,) = struct.unpack('i', reusestr)
485        assert reuse == 0
486        reusestr = struct.pack('i', 1)
487        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, reusestr)
488        reusestr = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
489                                intsize)
490        (reuse,) = struct.unpack('i', reusestr)
491        assert reuse != 0
492
493    def test_socket_ioctl(self):
494        import _socket, sys
495        if sys.platform != 'win32':
496            skip("win32 only")
497        assert hasattr(_socket.socket, 'ioctl')
498        assert hasattr(_socket, 'SIO_RCVALL')
499        assert hasattr(_socket, 'RCVALL_ON')
500        assert hasattr(_socket, 'RCVALL_OFF')
501        assert hasattr(_socket, 'SIO_KEEPALIVE_VALS')
502        s = _socket.socket()
503        raises(ValueError, s.ioctl, -1, None)
504        s.ioctl(_socket.SIO_KEEPALIVE_VALS, (1, 100, 100))
505
506    def test_dup(self):
507        import _socket as socket
508        if not hasattr(socket.socket, 'dup'):
509            skip('No dup() on this platform')
510        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
511        s.bind(('localhost', 0))
512        s2 = s.dup()
513        assert s.fileno() != s2.fileno()
514        assert s.getsockname() == s2.getsockname()
515
516    def test_buffer_or_unicode(self):
517        # Test that send/sendall/sendto accept a buffer or a unicode as arg
518        import _socket, os
519        s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
520        # XXX temporarily we use python.org to test, will have more robust tests
521        # in the absence of a network connection later when more parts of the
522        # socket API are implemented.  Currently skip the test if there is no
523        # connection.
524        try:
525            s.connect(("www.python.org", 80))
526        except _socket.gaierror, ex:
527            skip("GAIError - probably no connection: %s" % str(ex.args))
528        s.send(buffer(''))
529        s.sendall(buffer(''))
530        s.send(u'')
531        s.sendall(u'')
532        raises(UnicodeEncodeError, s.send, u'\xe9')
533        s.close()
534        s = _socket.socket(_socket.AF_INET, _socket.SOCK_DGRAM, 0)
535        s.sendto(buffer(''), ('localhost', 9)) # Send to discard port.
536        s.close()
537
538    def test_unix_socket_connect(self):
539        import _socket, os
540        if not hasattr(_socket, 'AF_UNIX'):
541            skip('AF_UNIX not supported.')
542        oldcwd = os.getcwd()
543        os.chdir(self.udir)
544        try:
545            sockpath = 'app_test_unix_socket_connect'
546
547            serversock = _socket.socket(_socket.AF_UNIX)
548            serversock.bind(sockpath)
549            serversock.listen(1)
550
551            clientsock = _socket.socket(_socket.AF_UNIX)
552            clientsock.connect(sockpath)
553            s, addr = serversock.accept()
554            assert not addr
555
556            s.send('X')
557            data = clientsock.recv(100)
558            assert data == 'X'
559            clientsock.send('Y')
560            data = s.recv(100)
561            assert data == 'Y'
562
563            clientsock.close()
564            s.close()
565        finally:
566            os.chdir(oldcwd)
567
568
569class AppTestSocketTCP:
570    def setup_class(cls):
571        cls.space = space
572
573    HOST = 'localhost'
574        
575    def setup_method(self, method):
576        w_HOST = space.wrap(self.HOST)
577        self.w_serv = space.appexec([w_socket, w_HOST],
578            '''(_socket, HOST):
579            serv = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM)
580            serv.bind((HOST, 0))
581            serv.listen(1)
582            return serv
583            ''')
584    def teardown_method(self, method):
585        if hasattr(self, 'w_serv'):
586            space.appexec([self.w_serv], '(serv): serv.close()')
587            self.w_serv = None
588
589    def test_timeout(self):
590        from _socket import timeout
591        def raise_timeout():
592            self.serv.settimeout(1.0)
593            self.serv.accept()
594        raises(timeout, raise_timeout)
595
596    def test_timeout_zero(self):
597        from _socket import error
598        def raise_error():
599            self.serv.settimeout(0.0)
600            foo = self.serv.accept()
601        raises(error, raise_error)
602
603    def test_recv_send_timeout(self):
604        from _socket import socket, timeout
605        cli = socket()
606        cli.connect(self.serv.getsockname())
607        t, addr = self.serv.accept()
608        cli.settimeout(1.0)
609        # test recv() timeout
610        t.send('*')
611        buf = cli.recv(100)
612        assert buf == '*'
613        raises(timeout, cli.recv, 100)
614        # test that send() works
615        count = cli.send('!')
616        assert count == 1
617        buf = t.recv(1)
618        assert buf == '!'
619        # test that sendall() works
620        cli.sendall('?')
621        assert count == 1
622        buf = t.recv(1)
623        assert buf == '?'
624        # test send() timeout
625        count = 0
626        try:
627            while 1:
628                count += cli.send('foobar' * 70)
629        except timeout:
630            pass
631        t.recv(count)    
632        # test sendall() timeout
633        try:
634            while 1:
635                cli.sendall('foobar' * 70)
636        except timeout:
637            pass
638        # done
639        cli.close()
640        t.close()
641
642    def test_recv_into(self):
643        import socket
644        import array
645        MSG = 'dupa was here\n'
646        cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
647        cli.connect(self.serv.getsockname())
648        conn, addr = self.serv.accept()
649        buf = buffer(MSG)
650        conn.send(buf)
651        buf = array.array('c', ' '*1024)
652        nbytes = cli.recv_into(buf)
653        assert nbytes == len(MSG)
654        msg = buf.tostring()[:len(MSG)]
655        assert msg == MSG
656
657    def test_recvfrom_into(self):
658        import socket
659        import array
660        MSG = 'dupa was here\n'
661        cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
662        cli.connect(self.serv.getsockname())
663        conn, addr = self.serv.accept()
664        buf = buffer(MSG)
665        conn.send(buf)
666        buf = array.array('c', ' '*1024)
667        nbytes, addr = cli.recvfrom_into(buf)
668        assert nbytes == len(MSG)
669        msg = buf.tostring()[:len(MSG)]
670        assert msg == MSG
671
672    def test_family(self):
673        import socket
674        cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
675        assert cli.family == socket.AF_INET
676
677class AppTestErrno:
678    def setup_class(cls):
679        cls.space = space
680
681    def test_errno(self):
682        from socket import socket, AF_INET, SOCK_STREAM, error
683        import errno
684        s = socket(AF_INET, SOCK_STREAM)
685        exc = raises(error, s.accept)
686        assert isinstance(exc.value, error)
687        assert isinstance(exc.value, IOError)
688        # error is EINVAL, or WSAEINVAL on Windows
689        assert exc.value.errno == getattr(errno, 'WSAEINVAL', errno.EINVAL)
690        assert isinstance(exc.value.message, str)