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

https://bitbucket.org/pypy/pypy/ · Python · 874 lines · 738 code · 77 blank · 59 comment · 65 complexity · b793748f98ef50884185c6a5d243c753 MD5 · raw file

  1. import sys, os
  2. import pytest
  3. from pypy.tool.pytest.objspace import gettestobjspace
  4. from pypy.interpreter.gateway import interp2app
  5. from pypy.module._file.test.test_file import regex_search
  6. from rpython.tool.udir import udir
  7. from rpython.rlib import rsocket
  8. from rpython.rtyper.lltypesystem import lltype, rffi
  9. def setup_module(mod):
  10. mod.space = gettestobjspace(usemodules=['_socket', 'array', 'struct'])
  11. global socket
  12. import socket
  13. mod.w_socket = space.appexec([], "(): import _socket as m; return m")
  14. mod.path = udir.join('fd')
  15. mod.path.write('fo')
  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 pytest.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. pytest.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. pytest.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. pytest.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. pytest.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. pytest.skip('No socket.inet_pton on this platform')
  158. if not socket.has_ipv6:
  159. pytest.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. pytest.skip('No socket.inet_pton on this platform')
  178. if not socket.has_ipv6:
  179. pytest.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. pytest.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. pytest.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. pytest.skip("posix specific test")
  230. # HACK: To get the correct interface number 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. cls.w_regex_search = space.wrap(interp2app(regex_search))
  285. def teardown_class(cls):
  286. if not cls.runappdirect:
  287. cls.space.sys.getmodule('_socket').shutdown(cls.space)
  288. def test_module(self):
  289. import _socket
  290. assert _socket.socket.__name__ == 'socket'
  291. assert _socket.socket.__module__ == '_socket'
  292. def test_ntoa_exception(self):
  293. import _socket
  294. raises(_socket.error, _socket.inet_ntoa, b"ab")
  295. def test_aton_exceptions(self):
  296. import _socket
  297. tests = ["127.0.0.256", "127.0.0.255555555555555555", "127.2b.0.0",
  298. "127.2.0.0.1", "127.2.0."]
  299. for ip in tests:
  300. raises(_socket.error, _socket.inet_aton, ip)
  301. def test_ntop_exceptions(self):
  302. import _socket
  303. if not hasattr(_socket, 'inet_ntop'):
  304. skip('No socket.inet_pton on this platform')
  305. for family, packed, exception in \
  306. [(_socket.AF_INET + _socket.AF_INET6, "", _socket.error),
  307. (_socket.AF_INET, "a", ValueError),
  308. (_socket.AF_INET6, "a", ValueError),
  309. (_socket.AF_INET, u"aa\u2222a", UnicodeEncodeError)]:
  310. raises(exception, _socket.inet_ntop, family, packed)
  311. def test_pton_exceptions(self):
  312. import _socket
  313. if not hasattr(_socket, 'inet_pton'):
  314. skip('No socket.inet_pton on this platform')
  315. tests = [
  316. (_socket.AF_INET + _socket.AF_INET6, ""),
  317. (_socket.AF_INET, "127.0.0.256"),
  318. (_socket.AF_INET, "127.0.0.255555555555555555"),
  319. (_socket.AF_INET, "127.2b.0.0"),
  320. (_socket.AF_INET, "127.2.0.0.1"),
  321. (_socket.AF_INET, "127.2..0"),
  322. (_socket.AF_INET6, "127.0.0.1"),
  323. (_socket.AF_INET6, "1::2::3"),
  324. (_socket.AF_INET6, "1: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:1:1::1:1:1:1:1"),
  327. (_socket.AF_INET6, "1::22222:1"),
  328. (_socket.AF_INET6, "1::eg"),
  329. ]
  330. for family, ip in tests:
  331. raises(_socket.error, _socket.inet_pton, family, ip)
  332. def test_newsocket_error(self):
  333. import _socket
  334. raises(_socket.error, _socket.socket, 10001, _socket.SOCK_STREAM, 0)
  335. def test_socket_fileno(self):
  336. import _socket
  337. s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
  338. assert s.fileno() > -1
  339. assert isinstance(s.fileno(), int)
  340. def test_socket_repr(self):
  341. import _socket
  342. s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM)
  343. try:
  344. expected = ('<socket object, fd=%s, family=%s, type=%s, protocol=%s>'
  345. % (s.fileno(), s.family, s.type, s.proto))
  346. assert repr(s) == expected
  347. finally:
  348. s.close()
  349. expected = ('<socket object, fd=-1, family=%s, type=%s, protocol=%s>'
  350. % (s.family, s.type, s.proto))
  351. assert repr(s) == expected
  352. def test_socket_close(self):
  353. import _socket, os
  354. s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
  355. fileno = s.fileno()
  356. assert s.fileno() >= 0
  357. s.close()
  358. assert s.fileno() < 0
  359. s.close()
  360. if os.name != 'nt':
  361. raises(OSError, os.close, fileno)
  362. def test_socket_track_resources(self):
  363. import _socket, os, gc, sys, cStringIO
  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. if os.name != 'nt':
  371. raises(OSError, os.close, fileno)
  372. @pytest.mark.skipif("config.option.runappdirect")
  373. def test_track_resources(self):
  374. import os, gc, sys, cStringIO
  375. import _socket
  376. if '__pypy__' not in sys.builtin_module_names:
  377. skip("pypy specific test")
  378. #
  379. def fn(flag1, flag2, do_close=False):
  380. sys.pypy_set_track_resources(flag1)
  381. mysock = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
  382. sys.pypy_set_track_resources(flag2)
  383. buf = cStringIO.StringIO()
  384. preverr = sys.stderr
  385. try:
  386. sys.stderr = buf
  387. if do_close:
  388. mysock.close()
  389. del mysock
  390. gc.collect() # force __del__ to be called
  391. finally:
  392. sys.stderr = preverr
  393. sys.pypy_set_track_resources(False)
  394. return buf.getvalue()
  395. # check with track_resources disabled
  396. assert fn(False, False) == ""
  397. #
  398. # check that we don't get the warning if we actually closed the socket
  399. msg = fn(True, True, do_close=True)
  400. assert msg == ''
  401. #
  402. # check with track_resources enabled
  403. msg = fn(True, True)
  404. assert self.regex_search(r"""
  405. WARNING: unclosed <socket object, .*>
  406. Created at \(most recent call last\):
  407. File ".*", line .*, in test_track_resources
  408. File ".*", line .*, in fn
  409. """, msg)
  410. #
  411. # track_resources is enabled after the construction of the socket. in
  412. # this case, the socket is not registered for finalization at all, so
  413. # we don't see a message
  414. msg = fn(False, True)
  415. assert msg == ''
  416. def test_socket_close_error(self):
  417. import _socket, os
  418. if os.name == 'nt':
  419. skip("Windows sockets are not files")
  420. s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
  421. os.close(s.fileno())
  422. s.close()
  423. def test_socket_connect(self):
  424. import _socket, os
  425. s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
  426. # it would be nice to have a test which works even if there is no
  427. # network connection. However, this one is "good enough" for now. Skip
  428. # it if there is no connection.
  429. try:
  430. s.connect(("www.python.org", 80))
  431. except _socket.gaierror as ex:
  432. skip("GAIError - probably no connection: %s" % str(ex.args))
  433. name = s.getpeername() # Will raise socket.error if not connected
  434. assert name[1] == 80
  435. s.close()
  436. def test_socket_connect_ex(self):
  437. import _socket
  438. s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
  439. # The following might fail if the DNS redirects failed requests to a
  440. # catch-all address (i.e. opendns).
  441. # Make sure we get an app-level error, not an interp one.
  442. raises(_socket.gaierror, s.connect_ex, ("wrong.invalid", 80))
  443. s.close()
  444. def test_socket_connect_typeerrors(self):
  445. tests = [
  446. "",
  447. ("80"),
  448. ("80", "80"),
  449. (80, 80),
  450. ]
  451. import _socket
  452. s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
  453. for args in tests:
  454. raises((TypeError, ValueError), s.connect, args)
  455. s.close()
  456. def test_bigport(self):
  457. import _socket
  458. s = _socket.socket()
  459. exc = raises(OverflowError, s.connect, ("localhost", -1))
  460. assert "port must be 0-65535." in str(exc.value)
  461. exc = raises(OverflowError, s.connect, ("localhost", 1000000))
  462. assert "port must be 0-65535." in str(exc.value)
  463. s = _socket.socket(_socket.AF_INET6)
  464. exc = raises(OverflowError, s.connect, ("::1", 1234, 1048576))
  465. assert "flowinfo must be 0-1048575." in str(exc.value)
  466. def test_NtoH(self):
  467. import sys
  468. import _socket as socket
  469. # This just checks that htons etc. are their own inverse,
  470. # when looking at the lower 16 or 32 bits.
  471. sizes = {socket.htonl: 32, socket.ntohl: 32,
  472. socket.htons: 16, socket.ntohs: 16}
  473. for func, size in sizes.items():
  474. mask = (1 << size) - 1
  475. for i in (0, 1, 0xffff, ~0xffff, 2, 0x01234567, 0x76543210):
  476. assert i & mask == func(func(i&mask)) & mask
  477. swapped = func(mask)
  478. assert swapped & mask == mask
  479. try:
  480. func(-1)
  481. except (OverflowError, ValueError):
  482. pass
  483. else:
  484. assert False
  485. try:
  486. func(sys.maxint*2+2)
  487. except OverflowError:
  488. pass
  489. else:
  490. assert False
  491. def test_NtoH_overflow(self):
  492. skip("we are not checking for overflowing values yet")
  493. import _socket as socket
  494. # Checks that we cannot give too large values to htons etc.
  495. # Skipped for now; CPython 2.6 is also not consistent.
  496. sizes = {socket.htonl: 32, socket.ntohl: 32,
  497. socket.htons: 16, socket.ntohs: 16}
  498. for func, size in sizes.items():
  499. try:
  500. func(1 << size)
  501. except OverflowError:
  502. pass
  503. else:
  504. assert False
  505. def test_newsocket(self):
  506. import socket
  507. s = socket.socket()
  508. def test_subclass(self):
  509. from _socket import socket
  510. class MySock(socket):
  511. blah = 123
  512. s = MySock()
  513. assert s.blah == 123
  514. def test_getsetsockopt(self):
  515. import _socket as socket
  516. import struct
  517. # A socket should start with reuse == 0
  518. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  519. reuse = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
  520. assert reuse == 0
  521. #
  522. raises(TypeError, s.setsockopt, socket.SOL_SOCKET,
  523. socket.SO_REUSEADDR, 2 ** 31)
  524. raises(TypeError, s.setsockopt, socket.SOL_SOCKET,
  525. socket.SO_REUSEADDR, 2 ** 32 + 1)
  526. assert s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) == 0
  527. #
  528. s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  529. reuse = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR)
  530. assert reuse != 0
  531. # String case
  532. intsize = struct.calcsize('i')
  533. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  534. reusestr = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
  535. intsize)
  536. (reuse,) = struct.unpack('i', reusestr)
  537. assert reuse == 0
  538. reusestr = struct.pack('i', 1)
  539. s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, reusestr)
  540. reusestr = s.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
  541. intsize)
  542. (reuse,) = struct.unpack('i', reusestr)
  543. assert reuse != 0
  544. def test_socket_ioctl(self):
  545. import _socket, sys
  546. if sys.platform != 'win32':
  547. skip("win32 only")
  548. assert hasattr(_socket.socket, 'ioctl')
  549. assert hasattr(_socket, 'SIO_RCVALL')
  550. assert hasattr(_socket, 'RCVALL_ON')
  551. assert hasattr(_socket, 'RCVALL_OFF')
  552. assert hasattr(_socket, 'SIO_KEEPALIVE_VALS')
  553. s = _socket.socket()
  554. raises(ValueError, s.ioctl, -1, None)
  555. s.ioctl(_socket.SIO_KEEPALIVE_VALS, (1, 100, 100))
  556. def test_dup(self):
  557. import _socket as socket
  558. if not hasattr(socket.socket, 'dup'):
  559. skip('No dup() on this platform')
  560. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  561. s.bind(('localhost', 0))
  562. s2 = s.dup()
  563. assert s.fileno() != s2.fileno()
  564. assert s.getsockname() == s2.getsockname()
  565. def test_buffer_or_unicode(self):
  566. # Test that send/sendall/sendto accept a buffer or a unicode as arg
  567. import _socket, os
  568. s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
  569. # XXX temporarily we use python.org to test, will have more robust tests
  570. # in the absence of a network connection later when more parts of the
  571. # socket API are implemented. Currently skip the test if there is no
  572. # connection.
  573. try:
  574. s.connect(("www.python.org", 80))
  575. except _socket.gaierror as ex:
  576. skip("GAIError - probably no connection: %s" % str(ex.args))
  577. exc = raises(TypeError, s.send, None)
  578. assert str(exc.value) == "must be string or buffer, not None"
  579. assert s.send(buffer('')) == 0
  580. assert s.sendall(buffer('')) is None
  581. assert s.send(memoryview('')) == 0
  582. assert s.sendall(memoryview('')) is None
  583. assert s.send(u'') == 0
  584. assert s.sendall(u'') is None
  585. raises(UnicodeEncodeError, s.send, u'\xe9')
  586. s.close()
  587. s = _socket.socket(_socket.AF_INET, _socket.SOCK_DGRAM, 0)
  588. s.sendto(buffer(''), ('localhost', 9)) # Send to discard port.
  589. s.close()
  590. def test_unix_socket_connect(self):
  591. import _socket, os
  592. if not hasattr(_socket, 'AF_UNIX'):
  593. skip('AF_UNIX not supported.')
  594. oldcwd = os.getcwd()
  595. os.chdir(self.udir)
  596. try:
  597. sockpath = 'app_test_unix_socket_connect'
  598. serversock = _socket.socket(_socket.AF_UNIX)
  599. serversock.bind(sockpath)
  600. serversock.listen(1)
  601. clientsock = _socket.socket(_socket.AF_UNIX)
  602. clientsock.connect(sockpath)
  603. s, addr = serversock.accept()
  604. assert not addr
  605. s.send(b'X')
  606. data = clientsock.recv(100)
  607. assert data == b'X'
  608. clientsock.send(b'Y')
  609. data = s.recv(100)
  610. assert data == b'Y'
  611. clientsock.close()
  612. s.close()
  613. finally:
  614. os.chdir(oldcwd)
  615. def test_automatic_shutdown(self):
  616. # doesn't really test anything, but at least should not explode
  617. # in close_all_sockets()
  618. import _socket
  619. self.foo = _socket.socket()
  620. class AppTestNetlink:
  621. def setup_class(cls):
  622. if not hasattr(os, 'getpid'):
  623. pytest.skip("AF_NETLINK needs os.getpid()")
  624. w_ok = space.appexec([], "(): import _socket; " +
  625. "return hasattr(_socket, 'AF_NETLINK')")
  626. if not space.is_true(w_ok):
  627. pytest.skip("no AF_NETLINK on this platform")
  628. cls.space = space
  629. def test_connect_to_kernel_netlink_routing_socket(self):
  630. import _socket, os
  631. s = _socket.socket(_socket.AF_NETLINK, _socket.SOCK_DGRAM, _socket.NETLINK_ROUTE)
  632. assert s.getsockname() == (0, 0)
  633. s.bind((0, 0))
  634. a, b = s.getsockname()
  635. assert a == os.getpid()
  636. assert b == 0
  637. class AppTestPacket:
  638. def setup_class(cls):
  639. if not hasattr(os, 'getuid') or os.getuid() != 0:
  640. pytest.skip("AF_PACKET needs to be root for testing")
  641. w_ok = space.appexec([], "(): import _socket; " +
  642. "return hasattr(_socket, 'AF_PACKET')")
  643. if not space.is_true(w_ok):
  644. pytest.skip("no AF_PACKET on this platform")
  645. cls.space = space
  646. def test_convert_between_tuple_and_sockaddr_ll(self):
  647. import _socket
  648. s = _socket.socket(_socket.AF_PACKET, _socket.SOCK_RAW)
  649. assert s.getsockname() == ('', 0, 0, 0, '')
  650. s.bind(('lo', 123))
  651. a, b, c, d, e = s.getsockname()
  652. assert (a, b, c) == ('lo', 123, 0)
  653. assert isinstance(d, int)
  654. assert isinstance(e, str)
  655. assert 0 <= len(e) <= 8
  656. class AppTestSocketTCP:
  657. HOST = 'localhost'
  658. spaceconfig = {'usemodules': ['_socket', 'array']}
  659. def setup_method(self, method):
  660. w_HOST = self.space.wrap(self.HOST)
  661. self.w_serv =self.space.appexec([w_socket, w_HOST],
  662. '''(_socket, HOST):
  663. serv = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM)
  664. serv.bind((HOST, 0))
  665. serv.listen(1)
  666. return serv
  667. ''')
  668. def teardown_method(self, method):
  669. if hasattr(self, 'w_serv'):
  670. self.space.appexec([self.w_serv], '(serv): serv.close()')
  671. self.w_serv = None
  672. def test_timeout(self):
  673. from _socket import timeout
  674. def raise_timeout():
  675. self.serv.settimeout(1.0)
  676. self.serv.accept()
  677. raises(timeout, raise_timeout)
  678. def test_timeout_zero(self):
  679. from _socket import error
  680. def raise_error():
  681. self.serv.settimeout(0.0)
  682. foo = self.serv.accept()
  683. raises(error, raise_error)
  684. def test_recv_send_timeout(self):
  685. from _socket import socket, timeout, SOL_SOCKET, SO_RCVBUF, SO_SNDBUF
  686. cli = socket()
  687. cli.connect(self.serv.getsockname())
  688. t, addr = self.serv.accept()
  689. cli.settimeout(1.0)
  690. # test recv() timeout
  691. t.send(b'*')
  692. buf = cli.recv(100)
  693. assert buf == b'*'
  694. raises(timeout, cli.recv, 100)
  695. # test that send() works
  696. count = cli.send(b'!')
  697. assert count == 1
  698. buf = t.recv(1)
  699. assert buf == b'!'
  700. # test that sendall() works
  701. count = cli.sendall(b'?')
  702. assert count is None
  703. buf = t.recv(1)
  704. assert buf == b'?'
  705. # speed up filling the buffers
  706. t.setsockopt(SOL_SOCKET, SO_RCVBUF, 4096)
  707. cli.setsockopt(SOL_SOCKET, SO_SNDBUF, 4096)
  708. # test send() timeout
  709. count = 0
  710. try:
  711. while 1:
  712. count += cli.send(b'foobar' * 70)
  713. assert count < 100000
  714. except timeout:
  715. pass
  716. t.recv(count)
  717. # test sendall() timeout
  718. try:
  719. while 1:
  720. cli.sendall(b'foobar' * 70)
  721. except timeout:
  722. pass
  723. # done
  724. cli.close()
  725. t.close()
  726. def test_recv_into(self):
  727. import socket
  728. import array
  729. MSG = b'dupa was here\n'
  730. cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  731. cli.connect(self.serv.getsockname())
  732. conn, addr = self.serv.accept()
  733. buf = buffer(MSG)
  734. conn.send(buf)
  735. buf = array.array('b', b' ' * 1024)
  736. nbytes = cli.recv_into(buf)
  737. assert nbytes == len(MSG)
  738. msg = buf.tostring()[:len(MSG)]
  739. assert msg == MSG
  740. conn.send(MSG)
  741. buf = bytearray(1024)
  742. nbytes = cli.recv_into(memoryview(buf))
  743. assert nbytes == len(MSG)
  744. msg = buf[:len(MSG)]
  745. assert msg == MSG
  746. def test_recvfrom_into(self):
  747. import socket
  748. import array
  749. MSG = b'dupa was here\n'
  750. cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  751. cli.connect(self.serv.getsockname())
  752. conn, addr = self.serv.accept()
  753. buf = buffer(MSG)
  754. conn.send(buf)
  755. buf = array.array('b', b' ' * 1024)
  756. nbytes, addr = cli.recvfrom_into(buf)
  757. assert nbytes == len(MSG)
  758. msg = buf.tostring()[:len(MSG)]
  759. assert msg == MSG
  760. conn.send(MSG)
  761. buf = bytearray(1024)
  762. nbytes, addr = cli.recvfrom_into(memoryview(buf))
  763. assert nbytes == len(MSG)
  764. msg = buf[:len(MSG)]
  765. assert msg == MSG
  766. conn.send(MSG)
  767. buf = bytearray(8)
  768. exc = raises(ValueError, cli.recvfrom_into, buf, 1024)
  769. assert str(exc.value) == "nbytes is greater than the length of the buffer"
  770. def test_family(self):
  771. import socket
  772. cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  773. assert cli.family == socket.AF_INET
  774. class AppTestErrno:
  775. spaceconfig = {'usemodules': ['_socket']}
  776. def test_errno(self):
  777. from socket import socket, AF_INET, SOCK_STREAM, error
  778. import errno
  779. s = socket(AF_INET, SOCK_STREAM)
  780. exc = raises(error, s.accept)
  781. assert isinstance(exc.value, error)
  782. assert isinstance(exc.value, IOError)
  783. # error is EINVAL, or WSAEINVAL on Windows
  784. assert exc.value.errno == getattr(errno, 'WSAEINVAL', errno.EINVAL)
  785. assert isinstance(exc.value.message, str)