Kaydet (Commit) e78cbeca authored tarafından Charles-François Natali's avatar Charles-François Natali

Issue #12656: Add tests for IPv6 and Unix sockets to test_asyncore.

üst e9e95ae9
...@@ -87,6 +87,13 @@ def capture_server(evt, buf, serv): ...@@ -87,6 +87,13 @@ def capture_server(evt, buf, serv):
serv.close() serv.close()
evt.set() evt.set()
def bind_af_aware(sock, addr):
"""Helper function to bind a socket according to its family."""
if sock.family == socket.AF_UNIX:
# Make sure the path doesn't exist.
unlink(addr)
sock.bind(addr)
class HelperFunctionTests(unittest.TestCase): class HelperFunctionTests(unittest.TestCase):
def test_readwriteexc(self): def test_readwriteexc(self):
...@@ -467,22 +474,22 @@ class BaseTestHandler(asyncore.dispatcher): ...@@ -467,22 +474,22 @@ class BaseTestHandler(asyncore.dispatcher):
raise raise
class TCPServer(asyncore.dispatcher): class BaseServer(asyncore.dispatcher):
"""A server which listens on an address and dispatches the """A server which listens on an address and dispatches the
connection to a handler. connection to a handler.
""" """
def __init__(self, handler=BaseTestHandler, host=HOST, port=0): def __init__(self, family, addr, handler=BaseTestHandler):
asyncore.dispatcher.__init__(self) asyncore.dispatcher.__init__(self)
self.create_socket() self.create_socket(family)
self.set_reuse_addr() self.set_reuse_addr()
self.bind((host, port)) bind_af_aware(self.socket, addr)
self.listen(5) self.listen(5)
self.handler = handler self.handler = handler
@property @property
def address(self): def address(self):
return self.socket.getsockname()[:2] return self.socket.getsockname()
def handle_accepted(self, sock, addr): def handle_accepted(self, sock, addr):
self.handler(sock) self.handler(sock)
...@@ -493,9 +500,9 @@ class TCPServer(asyncore.dispatcher): ...@@ -493,9 +500,9 @@ class TCPServer(asyncore.dispatcher):
class BaseClient(BaseTestHandler): class BaseClient(BaseTestHandler):
def __init__(self, address): def __init__(self, family, address):
BaseTestHandler.__init__(self) BaseTestHandler.__init__(self)
self.create_socket() self.create_socket(family)
self.connect(address) self.connect(address)
def handle_connect(self): def handle_connect(self):
...@@ -525,8 +532,8 @@ class BaseTestAPI(unittest.TestCase): ...@@ -525,8 +532,8 @@ class BaseTestAPI(unittest.TestCase):
def handle_connect(self): def handle_connect(self):
self.flag = True self.flag = True
server = TCPServer() server = BaseServer(self.family, self.addr)
client = TestClient(server.address) client = TestClient(self.family, server.address)
self.loop_waiting_for_flag(client) self.loop_waiting_for_flag(client)
def test_handle_accept(self): def test_handle_accept(self):
...@@ -534,18 +541,18 @@ class BaseTestAPI(unittest.TestCase): ...@@ -534,18 +541,18 @@ class BaseTestAPI(unittest.TestCase):
class TestListener(BaseTestHandler): class TestListener(BaseTestHandler):
def __init__(self): def __init__(self, family, addr):
BaseTestHandler.__init__(self) BaseTestHandler.__init__(self)
self.create_socket() self.create_socket(family)
self.bind((HOST, 0)) bind_af_aware(self.socket, addr)
self.listen(5) self.listen(5)
self.address = self.socket.getsockname()[:2] self.address = self.socket.getsockname()
def handle_accept(self): def handle_accept(self):
self.flag = True self.flag = True
server = TestListener() server = TestListener(self.family, self.addr)
client = BaseClient(server.address) client = BaseClient(self.family, server.address)
self.loop_waiting_for_flag(server) self.loop_waiting_for_flag(server)
def test_handle_accepted(self): def test_handle_accepted(self):
...@@ -553,12 +560,12 @@ class BaseTestAPI(unittest.TestCase): ...@@ -553,12 +560,12 @@ class BaseTestAPI(unittest.TestCase):
class TestListener(BaseTestHandler): class TestListener(BaseTestHandler):
def __init__(self): def __init__(self, family, addr):
BaseTestHandler.__init__(self) BaseTestHandler.__init__(self)
self.create_socket() self.create_socket(family)
self.bind((HOST, 0)) bind_af_aware(self.socket, addr)
self.listen(5) self.listen(5)
self.address = self.socket.getsockname()[:2] self.address = self.socket.getsockname()
def handle_accept(self): def handle_accept(self):
asyncore.dispatcher.handle_accept(self) asyncore.dispatcher.handle_accept(self)
...@@ -567,8 +574,8 @@ class BaseTestAPI(unittest.TestCase): ...@@ -567,8 +574,8 @@ class BaseTestAPI(unittest.TestCase):
sock.close() sock.close()
self.flag = True self.flag = True
server = TestListener() server = TestListener(self.family, self.addr)
client = BaseClient(server.address) client = BaseClient(self.family, server.address)
self.loop_waiting_for_flag(server) self.loop_waiting_for_flag(server)
...@@ -584,8 +591,8 @@ class BaseTestAPI(unittest.TestCase): ...@@ -584,8 +591,8 @@ class BaseTestAPI(unittest.TestCase):
BaseTestHandler.__init__(self, conn) BaseTestHandler.__init__(self, conn)
self.send(b'x' * 1024) self.send(b'x' * 1024)
server = TCPServer(TestHandler) server = BaseServer(self.family, self.addr, TestHandler)
client = TestClient(server.address) client = TestClient(self.family, server.address)
self.loop_waiting_for_flag(client) self.loop_waiting_for_flag(client)
def test_handle_write(self): def test_handle_write(self):
...@@ -595,8 +602,8 @@ class BaseTestAPI(unittest.TestCase): ...@@ -595,8 +602,8 @@ class BaseTestAPI(unittest.TestCase):
def handle_write(self): def handle_write(self):
self.flag = True self.flag = True
server = TCPServer() server = BaseServer(self.family, self.addr)
client = TestClient(server.address) client = TestClient(self.family, server.address)
self.loop_waiting_for_flag(client) self.loop_waiting_for_flag(client)
def test_handle_close(self): def test_handle_close(self):
...@@ -619,8 +626,8 @@ class BaseTestAPI(unittest.TestCase): ...@@ -619,8 +626,8 @@ class BaseTestAPI(unittest.TestCase):
BaseTestHandler.__init__(self, conn) BaseTestHandler.__init__(self, conn)
self.close() self.close()
server = TCPServer(TestHandler) server = BaseServer(self.family, self.addr, TestHandler)
client = TestClient(server.address) client = TestClient(self.family, server.address)
self.loop_waiting_for_flag(client) self.loop_waiting_for_flag(client)
@unittest.skipIf(sys.platform.startswith("sunos"), @unittest.skipIf(sys.platform.startswith("sunos"),
...@@ -629,6 +636,8 @@ class BaseTestAPI(unittest.TestCase): ...@@ -629,6 +636,8 @@ class BaseTestAPI(unittest.TestCase):
# Make sure handle_expt is called on OOB data received. # Make sure handle_expt is called on OOB data received.
# Note: this might fail on some platforms as OOB data is # Note: this might fail on some platforms as OOB data is
# tenuously supported and rarely used. # tenuously supported and rarely used.
if self.family == socket.AF_UNIX:
self.skipTest("Not applicable to AF_UNIX sockets.")
class TestClient(BaseClient): class TestClient(BaseClient):
def handle_expt(self): def handle_expt(self):
...@@ -639,8 +648,8 @@ class BaseTestAPI(unittest.TestCase): ...@@ -639,8 +648,8 @@ class BaseTestAPI(unittest.TestCase):
BaseTestHandler.__init__(self, conn) BaseTestHandler.__init__(self, conn)
self.socket.send(bytes(chr(244), 'latin-1'), socket.MSG_OOB) self.socket.send(bytes(chr(244), 'latin-1'), socket.MSG_OOB)
server = TCPServer(TestHandler) server = BaseServer(self.family, self.addr, TestHandler)
client = TestClient(server.address) client = TestClient(self.family, server.address)
self.loop_waiting_for_flag(client) self.loop_waiting_for_flag(client)
def test_handle_error(self): def test_handle_error(self):
...@@ -657,13 +666,13 @@ class BaseTestAPI(unittest.TestCase): ...@@ -657,13 +666,13 @@ class BaseTestAPI(unittest.TestCase):
else: else:
raise Exception("exception not raised") raise Exception("exception not raised")
server = TCPServer() server = BaseServer(self.family, self.addr)
client = TestClient(server.address) client = TestClient(self.family, server.address)
self.loop_waiting_for_flag(client) self.loop_waiting_for_flag(client)
def test_connection_attributes(self): def test_connection_attributes(self):
server = TCPServer() server = BaseServer(self.family, self.addr)
client = BaseClient(server.address) client = BaseClient(self.family, server.address)
# we start disconnected # we start disconnected
self.assertFalse(server.connected) self.assertFalse(server.connected)
...@@ -693,25 +702,29 @@ class BaseTestAPI(unittest.TestCase): ...@@ -693,25 +702,29 @@ class BaseTestAPI(unittest.TestCase):
def test_create_socket(self): def test_create_socket(self):
s = asyncore.dispatcher() s = asyncore.dispatcher()
s.create_socket() s.create_socket(self.family)
self.assertEqual(s.socket.family, socket.AF_INET) self.assertEqual(s.socket.family, self.family)
SOCK_NONBLOCK = getattr(socket, 'SOCK_NONBLOCK', 0) SOCK_NONBLOCK = getattr(socket, 'SOCK_NONBLOCK', 0)
self.assertEqual(s.socket.type, socket.SOCK_STREAM | SOCK_NONBLOCK) self.assertEqual(s.socket.type, socket.SOCK_STREAM | SOCK_NONBLOCK)
def test_bind(self): def test_bind(self):
if self.family == socket.AF_UNIX:
self.skipTest("Not applicable to AF_UNIX sockets.")
s1 = asyncore.dispatcher() s1 = asyncore.dispatcher()
s1.create_socket() s1.create_socket(self.family)
s1.bind((HOST, 0)) s1.bind(self.addr)
s1.listen(5) s1.listen(5)
port = s1.socket.getsockname()[1] port = s1.socket.getsockname()[1]
s2 = asyncore.dispatcher() s2 = asyncore.dispatcher()
s2.create_socket() s2.create_socket(self.family)
# EADDRINUSE indicates the socket was correctly bound # EADDRINUSE indicates the socket was correctly bound
self.assertRaises(socket.error, s2.bind, (HOST, port)) self.assertRaises(socket.error, s2.bind, (self.addr[0], port))
def test_set_reuse_addr(self): def test_set_reuse_addr(self):
sock = socket.socket() if self.family == socket.AF_UNIX:
self.skipTest("Not applicable to AF_UNIX sockets.")
sock = socket.socket(self.family)
try: try:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
except socket.error: except socket.error:
...@@ -719,11 +732,11 @@ class BaseTestAPI(unittest.TestCase): ...@@ -719,11 +732,11 @@ class BaseTestAPI(unittest.TestCase):
else: else:
# if SO_REUSEADDR succeeded for sock we expect asyncore # if SO_REUSEADDR succeeded for sock we expect asyncore
# to do the same # to do the same
s = asyncore.dispatcher(socket.socket()) s = asyncore.dispatcher(socket.socket(self.family))
self.assertFalse(s.socket.getsockopt(socket.SOL_SOCKET, self.assertFalse(s.socket.getsockopt(socket.SOL_SOCKET,
socket.SO_REUSEADDR)) socket.SO_REUSEADDR))
s.socket.close() s.socket.close()
s.create_socket() s.create_socket(self.family)
s.set_reuse_addr() s.set_reuse_addr()
self.assertTrue(s.socket.getsockopt(socket.SOL_SOCKET, self.assertTrue(s.socket.getsockopt(socket.SOL_SOCKET,
socket.SO_REUSEADDR)) socket.SO_REUSEADDR))
...@@ -731,18 +744,44 @@ class BaseTestAPI(unittest.TestCase): ...@@ -731,18 +744,44 @@ class BaseTestAPI(unittest.TestCase):
sock.close() sock.close()
class TestAPI_UseSelect(BaseTestAPI): class TestAPI_UseIPv4Sockets(BaseTestAPI):
family = socket.AF_INET
addr = (HOST, 0)
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 support required')
class TestAPI_UseIPv6Sockets(BaseTestAPI):
family = socket.AF_INET6
addr = ('::1', 0)
@unittest.skipUnless(hasattr(socket, 'AF_UNIX'), 'Unix sockets required')
class TestAPI_UseUnixSockets(BaseTestAPI):
family = socket.AF_UNIX
addr = support.TESTFN
use_poll = False
def tearDown(self):
unlink(self.addr)
BaseTestAPI.tearDown(self)
class TestAPI_UseIPv4Select(TestAPI_UseIPv4Sockets):
use_poll = False use_poll = False
@unittest.skipUnless(hasattr(select, 'poll'), 'select.poll required') @unittest.skipUnless(hasattr(select, 'poll'), 'select.poll required')
class TestAPI_UsePoll(BaseTestAPI): class TestAPI_UseIPv4Poll(TestAPI_UseIPv4Sockets):
use_poll = True use_poll = True
class TestAPI_UseIPv6Select(TestAPI_UseIPv6Sockets):
use_poll = False
@unittest.skipUnless(hasattr(select, 'poll'), 'select.poll required')
class TestAPI_UseIPv6Poll(TestAPI_UseIPv6Sockets):
use_poll = True
def test_main(): def test_main():
tests = [HelperFunctionTests, DispatcherTests, DispatcherWithSendTests, tests = [HelperFunctionTests, DispatcherTests, DispatcherWithSendTests,
DispatcherWithSendTests_UsePoll, TestAPI_UseSelect, DispatcherWithSendTests_UsePoll, FileWrapperTest,
TestAPI_UsePoll, FileWrapperTest] TestAPI_UseIPv4Select, TestAPI_UseIPv4Poll, TestAPI_UseIPv6Select,
TestAPI_UseIPv6Poll, TestAPI_UseUnixSockets]
run_unittest(*tests) run_unittest(*tests)
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -1221,6 +1221,8 @@ Extension Modules ...@@ -1221,6 +1221,8 @@ Extension Modules
Tests Tests
----- -----
- Issue #12656: Add tests for IPv6 and Unix sockets to test_asyncore.
- Issue #6484: Add unit tests for mailcap module (patch by Gregory Nofi) - Issue #6484: Add unit tests for mailcap module (patch by Gregory Nofi)
- Issue #11651: Improve the Makefile test targets to run more of the test suite - Issue #11651: Improve the Makefile test targets to run more of the test suite
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment