Skip to content

Commit 98eaff3

Browse files
committed
Unused TCP port factory fixture. Bump to 0.2.0.
1 parent 952895d commit 98eaff3

File tree

4 files changed

+63
-2
lines changed

4 files changed

+63
-2
lines changed

README.rst

+13-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Features
3030
--------
3131

3232
- fixtures for creating and injecting versions of the asyncio event loop
33+
- fixtures for injecting unused tcp ports
3334
- pytest markers for treating tests as asyncio coroutines
3435

3536

@@ -72,9 +73,20 @@ The ``event_loop_process_pool`` fixture is almost identical to the
7273

7374
``unused_tcp_port``
7475
~~~~~~~~~~~~~~~~~~~
75-
Finds and yields an unused TCP port on the localhost interface. Useful for
76+
Finds and yields a single unused TCP port on the localhost interface. Useful for
7677
binding temporary test servers.
7778

79+
``unused_tcp_port_factory``
80+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
81+
A callable which returns a different unused TCP port each invocation. Useful
82+
when several unused TCP ports are required in a test.
83+
84+
.. code-block:: python
85+
86+
def a_test(unused_tcp_port_factory):
87+
port1, port2 = unused_tcp_port_factory(), unused_tcp_port_factory()
88+
...
89+
7890
Markers
7991
-------
8092

pytest_asyncio/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.1.3'
1+
__version__ = '0.2.0'

pytest_asyncio/plugin.py

+14
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,17 @@ def unused_tcp_port():
8888
with closing(socket.socket()) as sock:
8989
sock.bind(('127.0.0.1', 0))
9090
return sock.getsockname()[1]
91+
92+
93+
@pytest.fixture
94+
def unused_tcp_port_factory():
95+
"""A factory function, producing different unused TCP ports."""
96+
produced = set()
97+
98+
def factory():
99+
port = unused_tcp_port()
100+
while port in produced:
101+
port = unused_tcp_port
102+
103+
return port
104+
return factory

tests/test_simple.py

+35
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,41 @@ def closer(_, writer):
7171
yield from server1.wait_closed()
7272

7373

74+
@pytest.mark.asyncio
75+
def test_unused_port_factory_fixture(unused_tcp_port_factory, event_loop):
76+
"""Test the unused TCP port factory fixture."""
77+
78+
@asyncio.coroutine
79+
def closer(_, writer):
80+
writer.close()
81+
82+
port1, port2, port3 = (unused_tcp_port_factory(), unused_tcp_port_factory(),
83+
unused_tcp_port_factory())
84+
85+
server1 = yield from asyncio.start_server(closer, host='localhost',
86+
port=port1,
87+
loop=event_loop)
88+
server2 = yield from asyncio.start_server(closer, host='localhost',
89+
port=port2,
90+
loop=event_loop)
91+
server3 = yield from asyncio.start_server(closer, host='localhost',
92+
port=port3,
93+
loop=event_loop)
94+
95+
for port in port1, port2, port3:
96+
with pytest.raises(IOError):
97+
yield from asyncio.start_server(closer, host='localhost',
98+
port=port,
99+
loop=event_loop)
100+
101+
server1.close()
102+
yield from server1.wait_closed()
103+
server2.close()
104+
yield from server2.wait_closed()
105+
server3.close()
106+
yield from server3.wait_closed()
107+
108+
74109
class Test:
75110
"""Test that asyncio marked functions work in test methods."""
76111

0 commit comments

Comments
 (0)