mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
bpo-35934: Add socket.create_server() utility function (GH-11784)
This commit is contained in:
parent
58721a9030
commit
eb7e29f2a9
17 changed files with 289 additions and 88 deletions
|
@ -6068,9 +6068,133 @@ class TestMSWindowsTCPFlags(unittest.TestCase):
|
|||
self.assertEqual([], unknown,
|
||||
"New TCP flags were discovered. See bpo-32394 for more information")
|
||||
|
||||
|
||||
class CreateServerTest(unittest.TestCase):
|
||||
|
||||
def test_address(self):
|
||||
port = support.find_unused_port()
|
||||
with socket.create_server(("127.0.0.1", port)) as sock:
|
||||
self.assertEqual(sock.getsockname()[0], "127.0.0.1")
|
||||
self.assertEqual(sock.getsockname()[1], port)
|
||||
if support.IPV6_ENABLED:
|
||||
with socket.create_server(("::1", port),
|
||||
family=socket.AF_INET6) as sock:
|
||||
self.assertEqual(sock.getsockname()[0], "::1")
|
||||
self.assertEqual(sock.getsockname()[1], port)
|
||||
|
||||
def test_family_and_type(self):
|
||||
with socket.create_server(("127.0.0.1", 0)) as sock:
|
||||
self.assertEqual(sock.family, socket.AF_INET)
|
||||
self.assertEqual(sock.type, socket.SOCK_STREAM)
|
||||
if support.IPV6_ENABLED:
|
||||
with socket.create_server(("::1", 0), family=socket.AF_INET6) as s:
|
||||
self.assertEqual(s.family, socket.AF_INET6)
|
||||
self.assertEqual(sock.type, socket.SOCK_STREAM)
|
||||
|
||||
def test_reuse_port(self):
|
||||
if not hasattr(socket, "SO_REUSEPORT"):
|
||||
with self.assertRaises(ValueError):
|
||||
socket.create_server(("localhost", 0), reuse_port=True)
|
||||
else:
|
||||
with socket.create_server(("localhost", 0)) as sock:
|
||||
opt = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT)
|
||||
self.assertEqual(opt, 0)
|
||||
with socket.create_server(("localhost", 0), reuse_port=True) as sock:
|
||||
opt = sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT)
|
||||
self.assertNotEqual(opt, 0)
|
||||
|
||||
@unittest.skipIf(not hasattr(_socket, 'IPPROTO_IPV6') or
|
||||
not hasattr(_socket, 'IPV6_V6ONLY'),
|
||||
"IPV6_V6ONLY option not supported")
|
||||
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test')
|
||||
def test_ipv6_only_default(self):
|
||||
with socket.create_server(("::1", 0), family=socket.AF_INET6) as sock:
|
||||
assert sock.getsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY)
|
||||
|
||||
@unittest.skipIf(not socket.has_dualstack_ipv6(),
|
||||
"dualstack_ipv6 not supported")
|
||||
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test')
|
||||
def test_dualstack_ipv6_family(self):
|
||||
with socket.create_server(("::1", 0), family=socket.AF_INET6,
|
||||
dualstack_ipv6=True) as sock:
|
||||
self.assertEqual(sock.family, socket.AF_INET6)
|
||||
|
||||
|
||||
class CreateServerFunctionalTest(unittest.TestCase):
|
||||
timeout = 3
|
||||
|
||||
def setUp(self):
|
||||
self.thread = None
|
||||
|
||||
def tearDown(self):
|
||||
if self.thread is not None:
|
||||
self.thread.join(self.timeout)
|
||||
|
||||
def echo_server(self, sock):
|
||||
def run(sock):
|
||||
with sock:
|
||||
conn, _ = sock.accept()
|
||||
with conn:
|
||||
event.wait(self.timeout)
|
||||
msg = conn.recv(1024)
|
||||
if not msg:
|
||||
return
|
||||
conn.sendall(msg)
|
||||
|
||||
event = threading.Event()
|
||||
sock.settimeout(self.timeout)
|
||||
self.thread = threading.Thread(target=run, args=(sock, ))
|
||||
self.thread.start()
|
||||
event.set()
|
||||
|
||||
def echo_client(self, addr, family):
|
||||
with socket.socket(family=family) as sock:
|
||||
sock.settimeout(self.timeout)
|
||||
sock.connect(addr)
|
||||
sock.sendall(b'foo')
|
||||
self.assertEqual(sock.recv(1024), b'foo')
|
||||
|
||||
def test_tcp4(self):
|
||||
port = support.find_unused_port()
|
||||
with socket.create_server(("", port)) as sock:
|
||||
self.echo_server(sock)
|
||||
self.echo_client(("127.0.0.1", port), socket.AF_INET)
|
||||
|
||||
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test')
|
||||
def test_tcp6(self):
|
||||
port = support.find_unused_port()
|
||||
with socket.create_server(("", port),
|
||||
family=socket.AF_INET6) as sock:
|
||||
self.echo_server(sock)
|
||||
self.echo_client(("::1", port), socket.AF_INET6)
|
||||
|
||||
# --- dual stack tests
|
||||
|
||||
@unittest.skipIf(not socket.has_dualstack_ipv6(),
|
||||
"dualstack_ipv6 not supported")
|
||||
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test')
|
||||
def test_dual_stack_client_v4(self):
|
||||
port = support.find_unused_port()
|
||||
with socket.create_server(("", port), family=socket.AF_INET6,
|
||||
dualstack_ipv6=True) as sock:
|
||||
self.echo_server(sock)
|
||||
self.echo_client(("127.0.0.1", port), socket.AF_INET)
|
||||
|
||||
@unittest.skipIf(not socket.has_dualstack_ipv6(),
|
||||
"dualstack_ipv6 not supported")
|
||||
@unittest.skipUnless(support.IPV6_ENABLED, 'IPv6 required for this test')
|
||||
def test_dual_stack_client_v6(self):
|
||||
port = support.find_unused_port()
|
||||
with socket.create_server(("", port), family=socket.AF_INET6,
|
||||
dualstack_ipv6=True) as sock:
|
||||
self.echo_server(sock)
|
||||
self.echo_client(("::1", port), socket.AF_INET6)
|
||||
|
||||
|
||||
def test_main():
|
||||
tests = [GeneralModuleTests, BasicTCPTest, TCPCloserTest, TCPTimeoutTest,
|
||||
TestExceptions, BufferIOTest, BasicTCPTest2, BasicUDPTest, UDPTimeoutTest ]
|
||||
TestExceptions, BufferIOTest, BasicTCPTest2, BasicUDPTest,
|
||||
UDPTimeoutTest, CreateServerTest, CreateServerFunctionalTest]
|
||||
|
||||
tests.extend([
|
||||
NonBlockingTCPTests,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue