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

https://bitbucket.org/vanl/pypy · Python · 797 lines · 677 code · 71 blank · 49 comment · 58 complexity · 0c3017e24cb8a2e776fd2190f8ed933b MD5 · raw file

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