You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ORPA-pyOpenRPA/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/gevent/tests/test__makefile_ref.py

517 lines
17 KiB

from __future__ import print_function
import os
from gevent import monkey; monkey.patch_all()
import socket
import ssl
import threading
import unittest
import errno
import weakref
import gevent.testing as greentest
dirname = os.path.dirname(os.path.abspath(__file__))
certfile = os.path.join(dirname, '2_7_keycert.pem')
pid = os.getpid()
PY3 = greentest.PY3
PYPY = greentest.PYPY
CPYTHON = not PYPY
PY2 = not PY3
fd_types = int
if PY3:
long = int
fd_types = (int, long)
WIN = greentest.WIN
from gevent.testing import get_open_files
try:
import psutil
except ImportError:
psutil = None
class Test(greentest.TestCase):
extra_allowed_open_states = ()
def tearDown(self):
self.extra_allowed_open_states = ()
super(Test, self).tearDown()
def assert_raises_EBADF(self, func):
try:
result = func()
except (socket.error, OSError) as ex:
# Windows/Py3 raises "OSError: [WinError 10038]"
if ex.args[0] == errno.EBADF:
return
if WIN and ex.args[0] == 10038:
return
raise
raise AssertionError('NOT RAISED EBADF: %r() returned %r' % (func, result))
def assert_fd_open(self, fileno):
assert isinstance(fileno, fd_types)
open_files = get_open_files()
if fileno not in open_files:
raise AssertionError('%r is not open:\n%s' % (fileno, open_files['data']))
def assert_fd_closed(self, fileno):
assert isinstance(fileno, fd_types), repr(fileno)
assert fileno > 0, fileno
open_files = get_open_files()
if fileno in open_files:
raise AssertionError('%r is not closed:\n%s' % (fileno, open_files['data']))
def _assert_sock_open(self, sock):
# requires the psutil output
open_files = get_open_files()
sockname = sock.getsockname()
for x in open_files['data']:
if getattr(x, 'laddr', None) == sockname:
assert x.status in (psutil.CONN_LISTEN, psutil.CONN_ESTABLISHED) + self.extra_allowed_open_states, x.status
return
raise AssertionError("%r is not open:\n%s" % (sock, open_files['data']))
def assert_open(self, sock, *rest):
if isinstance(sock, fd_types):
if not WIN:
self.assert_fd_open(sock)
else:
fileno = sock.fileno()
assert isinstance(fileno, fd_types), fileno
sockname = sock.getsockname()
assert isinstance(sockname, tuple), sockname
if not WIN:
self.assert_fd_open(fileno)
else:
self._assert_sock_open(sock)
if rest:
self.assert_open(rest[0], *rest[1:])
def assert_closed(self, sock, *rest):
if isinstance(sock, fd_types):
self.assert_fd_closed(sock)
else:
# Under Python3, the socket module returns -1 for a fileno
# of a closed socket; under Py2 it raises
if PY3:
self.assertEqual(sock.fileno(), -1)
else:
self.assert_raises_EBADF(sock.fileno)
self.assert_raises_EBADF(sock.getsockname)
self.assert_raises_EBADF(sock.accept)
if rest:
self.assert_closed(rest[0], *rest[1:])
def make_open_socket(self):
s = socket.socket()
s.bind(('127.0.0.1', 0))
self._close_on_teardown(s)
if WIN or greentest.LINUX:
# Windows and linux (with psutil) doesn't show as open until
# we call listen (linux with lsof accepts either)
s.listen(1)
self.assert_open(s, s.fileno())
return s
if CPYTHON and PY2:
# Keeping raw sockets alive keeps SSL sockets
# from being closed too, at least on CPython2, so we
# need to use weakrefs.
# In contrast, on PyPy, *only* having a weakref lets the
# original socket die and leak
def _close_on_teardown(self, resource):
self.close_on_teardown.append(weakref.ref(resource))
return resource
def _tearDownCloseOnTearDown(self):
self.close_on_teardown = [r() for r in self.close_on_teardown if r() is not None]
super(Test, self)._tearDownCloseOnTearDown()
# Sometimes its this one, sometimes it's test_ssl. No clue why or how.
@greentest.skipOnAppVeyor("This sometimes times out for no apparent reason.")
class TestSocket(Test):
def test_simple_close(self):
s = self.make_open_socket()
fileno = s.fileno()
s.close()
self.assert_closed(s, fileno)
def test_makefile1(self):
s = self.make_open_socket()
fileno = s.fileno()
f = s.makefile()
self.assert_open(s, fileno)
s.close()
# Under python 2, this closes socket wrapper object but not the file descriptor;
# under python 3, both stay open
if PY3:
self.assert_open(s, fileno)
else:
self.assert_closed(s)
self.assert_open(fileno)
f.close()
self.assert_closed(s)
self.assert_closed(fileno)
def test_makefile2(self):
s = self.make_open_socket()
fileno = s.fileno()
self.assert_open(s, fileno)
f = s.makefile()
self.assert_open(s)
self.assert_open(s, fileno)
f.close()
# closing fileobject does not close the socket
self.assert_open(s, fileno)
s.close()
self.assert_closed(s, fileno)
def test_server_simple(self):
listener = socket.socket()
listener.bind(('127.0.0.1', 0))
port = listener.getsockname()[1]
listener.listen(1)
connector = socket.socket()
self._close_on_teardown(connector)
def connect():
connector.connect(('127.0.0.1', port))
t = threading.Thread(target=connect)
t.start()
try:
client_socket, _addr = listener.accept()
fileno = client_socket.fileno()
self.assert_open(client_socket, fileno)
client_socket.close()
self.assert_closed(client_socket)
finally:
t.join()
listener.close()
connector.close()
def test_server_makefile1(self):
listener = socket.socket()
listener.bind(('127.0.0.1', 0))
port = listener.getsockname()[1]
listener.listen(1)
connector = socket.socket()
self._close_on_teardown(connector)
def connect():
connector.connect(('127.0.0.1', port))
t = threading.Thread(target=connect)
t.start()
try:
client_socket, _addr = listener.accept()
fileno = client_socket.fileno()
f = client_socket.makefile()
self.assert_open(client_socket, fileno)
client_socket.close()
# Under python 2, this closes socket wrapper object but not the file descriptor;
# under python 3, both stay open
if PY3:
self.assert_open(client_socket, fileno)
else:
self.assert_closed(client_socket)
self.assert_open(fileno)
f.close()
self.assert_closed(client_socket, fileno)
finally:
t.join()
listener.close()
connector.close()
def test_server_makefile2(self):
listener = socket.socket()
listener.bind(('127.0.0.1', 0))
port = listener.getsockname()[1]
listener.listen(1)
connector = socket.socket()
self._close_on_teardown(connector)
def connect():
connector.connect(('127.0.0.1', port))
t = threading.Thread(target=connect)
t.start()
try:
client_socket, _addr = listener.accept()
fileno = client_socket.fileno()
f = client_socket.makefile()
self.assert_open(client_socket, fileno)
# closing fileobject does not close the socket
f.close()
self.assert_open(client_socket, fileno)
client_socket.close()
self.assert_closed(client_socket, fileno)
finally:
t.join()
listener.close()
connector.close()
@greentest.skipOnAppVeyor("This sometimes times out for no apparent reason.")
class TestSSL(Test):
def _ssl_connect_task(self, connector, port):
connector.connect(('127.0.0.1', port))
try:
# Note: We get ResourceWarning about 'x'
# on Python 3 if we don't join the spawned thread
x = ssl.wrap_socket(connector)
except socket.error:
# Observed on Windows with PyPy2 5.9.0 and libuv:
# if we don't switch in a timely enough fashion,
# the server side runs ahead of us and closes
# our socket first, so this fails.
pass
else:
#self._close_on_teardown(x)
x.close()
def _make_ssl_connect_task(self, connector, port):
t = threading.Thread(target=self._ssl_connect_task, args=(connector, port))
t.daemon = True
return t
def __cleanup(self, task, *sockets):
# workaround for test_server_makefile1, test_server_makefile2,
# test_server_simple, test_serverssl_makefile1.
# On PyPy on Linux, it is important to join the SSL Connect
# Task FIRST, before closing the sockets. If we do it after
# (which makes more sense) we hang. It's not clear why, except
# that it has something to do with context switches. Inserting a call to
# gevent.sleep(0.1) instead of joining the task has the same
# effect. If the previous tests hang, then later tests can fail with
# SSLError: unknown alert type.
# XXX: Why do those two things happen?
# On PyPy on macOS, we don't have that problem and can use the
# more logical order.
task.join()
for s in sockets:
s.close()
del sockets
del task
def test_simple_close(self):
s = self.make_open_socket()
fileno = s.fileno()
s = ssl.wrap_socket(s)
self._close_on_teardown(s)
fileno = s.fileno()
self.assert_open(s, fileno)
s.close()
self.assert_closed(s, fileno)
def test_makefile1(self):
raw_s = self.make_open_socket()
s = ssl.wrap_socket(raw_s)
self._close_on_teardown(s)
fileno = s.fileno()
self.assert_open(s, fileno)
f = s.makefile()
self.assert_open(s, fileno)
s.close()
self.assert_open(s, fileno)
f.close()
raw_s.close()
self.assert_closed(s, fileno)
def test_makefile2(self):
s = self.make_open_socket()
fileno = s.fileno()
s = ssl.wrap_socket(s)
self._close_on_teardown(s)
fileno = s.fileno()
self.assert_open(s, fileno)
f = s.makefile()
self.assert_open(s, fileno)
f.close()
# closing fileobject does not close the socket
self.assert_open(s, fileno)
s.close()
self.assert_closed(s, fileno)
def test_server_simple(self):
listener = socket.socket()
listener.bind(('127.0.0.1', 0))
port = listener.getsockname()[1]
listener.listen(1)
connector = socket.socket()
self._close_on_teardown(connector)
t = self._make_ssl_connect_task(connector, port)
t.start()
try:
client_socket, _addr = listener.accept()
self._close_on_teardown(client_socket.close)
client_socket = ssl.wrap_socket(client_socket, keyfile=certfile, certfile=certfile, server_side=True)
self._close_on_teardown(client_socket)
fileno = client_socket.fileno()
self.assert_open(client_socket, fileno)
client_socket.close()
self.assert_closed(client_socket, fileno)
finally:
self.__cleanup(t, listener, connector)
def test_server_makefile1(self):
listener = socket.socket()
self._close_on_teardown(listener)
listener.bind(('127.0.0.1', 0))
port = listener.getsockname()[1]
listener.listen(1)
connector = socket.socket()
self._close_on_teardown(connector)
t = self._make_ssl_connect_task(connector, port)
t.start()
try:
client_socket, _addr = listener.accept()
self._close_on_teardown(client_socket.close) # hard ref
client_socket = ssl.wrap_socket(client_socket, keyfile=certfile, certfile=certfile, server_side=True)
self._close_on_teardown(client_socket)
fileno = client_socket.fileno()
self.assert_open(client_socket, fileno)
f = client_socket.makefile()
self.assert_open(client_socket, fileno)
client_socket.close()
self.assert_open(client_socket, fileno)
f.close()
self.assert_closed(client_socket, fileno)
finally:
self.__cleanup(t, listener, connector)
def test_server_makefile2(self):
listener = socket.socket()
listener.bind(('127.0.0.1', 0))
port = listener.getsockname()[1]
listener.listen(1)
connector = socket.socket()
self._close_on_teardown(connector)
t = self._make_ssl_connect_task(connector, port)
t.start()
try:
client_socket, _addr = listener.accept()
self._close_on_teardown(client_socket)
client_socket = ssl.wrap_socket(client_socket, keyfile=certfile, certfile=certfile, server_side=True)
self._close_on_teardown(client_socket)
fileno = client_socket.fileno()
self.assert_open(client_socket, fileno)
f = client_socket.makefile()
self.assert_open(client_socket, fileno)
# Closing fileobject does not close SSLObject
f.close()
self.assert_open(client_socket, fileno)
client_socket.close()
self.assert_closed(client_socket, fileno)
finally:
self.__cleanup(t, connector, listener, client_socket)
def test_serverssl_makefile1(self):
listener = socket.socket()
fileno = listener.fileno()
listener.bind(('127.0.0.1', 0))
port = listener.getsockname()[1]
listener.listen(1)
self._close_on_teardown(listener)
listener = ssl.wrap_socket(listener, keyfile=certfile, certfile=certfile)
connector = socket.socket()
self._close_on_teardown(connector)
t = self._make_ssl_connect_task(connector, port)
t.start()
try:
client_socket, _addr = listener.accept()
fileno = client_socket.fileno()
self.assert_open(client_socket, fileno)
f = client_socket.makefile()
self.assert_open(client_socket, fileno)
client_socket.close()
self.assert_open(client_socket, fileno)
f.close()
self.assert_closed(client_socket, fileno)
finally:
self.__cleanup(t, listener, connector)
@greentest.skipIf(greentest.RUNNING_ON_TRAVIS and greentest.PY37 and greentest.LIBUV,
"Often segfaults, cannot reproduce locally. "
"Not too worried about this before Python 3.7rc1. "
"https://travis-ci.org/gevent/gevent/jobs/327357684")
def test_serverssl_makefile2(self):
listener = socket.socket()
self._close_on_teardown(listener)
listener.bind(('127.0.0.1', 0))
port = listener.getsockname()[1]
listener.listen(1)
listener = ssl.wrap_socket(listener, keyfile=certfile, certfile=certfile)
connector = socket.socket()
def connect():
connector.connect(('127.0.0.1', port))
s = ssl.wrap_socket(connector)
s.sendall(b'test_serverssl_makefile2')
s.close()
connector.close()
t = threading.Thread(target=connect)
t.daemon = True
t.start()
try:
client_socket, _addr = listener.accept()
fileno = client_socket.fileno()
self.assert_open(client_socket, fileno)
f = client_socket.makefile()
self.assert_open(client_socket, fileno)
self.assertEqual(f.read(), 'test_serverssl_makefile2')
self.assertEqual(f.read(), '')
f.close()
if WIN and psutil:
# Hmm?
self.extra_allowed_open_states = (psutil.CONN_CLOSE_WAIT,)
self.assert_open(client_socket, fileno)
client_socket.close()
self.assert_closed(client_socket, fileno)
finally:
self.__cleanup(t, listener)
if __name__ == '__main__':
unittest.main()