Skip to content

Commit 34af0a1

Browse files
committed
Merge pull request #14 from pytest-dev/unused_tcp_port_factory
Unused TCP port factory fixture. Bump to 0.2.0.
2 parents 952895d + cc99eee commit 34af0a1

File tree

4 files changed

+88
-2
lines changed

4 files changed

+88
-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

+17
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,20 @@ 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+
101+
while port in produced:
102+
port = unused_tcp_port()
103+
104+
produced.add(port)
105+
106+
return port
107+
return factory

tests/test_simple.py

+57
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import os
44
import pytest
55

6+
import pytest_asyncio.plugin
7+
68

79
@asyncio.coroutine
810
def async_coro(loop):
@@ -71,6 +73,61 @@ def closer(_, writer):
7173
yield from server1.wait_closed()
7274

7375

76+
@pytest.mark.asyncio
77+
def test_unused_port_factory_fixture(unused_tcp_port_factory, event_loop):
78+
"""Test the unused TCP port factory fixture."""
79+
80+
@asyncio.coroutine
81+
def closer(_, writer):
82+
writer.close()
83+
84+
port1, port2, port3 = (unused_tcp_port_factory(), unused_tcp_port_factory(),
85+
unused_tcp_port_factory())
86+
87+
server1 = yield from asyncio.start_server(closer, host='localhost',
88+
port=port1,
89+
loop=event_loop)
90+
server2 = yield from asyncio.start_server(closer, host='localhost',
91+
port=port2,
92+
loop=event_loop)
93+
server3 = yield from asyncio.start_server(closer, host='localhost',
94+
port=port3,
95+
loop=event_loop)
96+
97+
for port in port1, port2, port3:
98+
with pytest.raises(IOError):
99+
yield from asyncio.start_server(closer, host='localhost',
100+
port=port,
101+
loop=event_loop)
102+
103+
server1.close()
104+
yield from server1.wait_closed()
105+
server2.close()
106+
yield from server2.wait_closed()
107+
server3.close()
108+
yield from server3.wait_closed()
109+
110+
111+
def test_unused_port_factory_duplicate(unused_tcp_port_factory, monkeypatch):
112+
"""Test correct avoidance of duplicate ports."""
113+
counter = 0
114+
115+
def mock_unused_tcp_port():
116+
"""Force some duplicate ports."""
117+
nonlocal counter
118+
counter += 1
119+
if counter < 5:
120+
return 10000
121+
else:
122+
return 10000 + counter
123+
124+
monkeypatch.setattr(pytest_asyncio.plugin, 'unused_tcp_port',
125+
mock_unused_tcp_port)
126+
127+
assert unused_tcp_port_factory() == 10000
128+
assert unused_tcp_port_factory() > 10000
129+
130+
74131
class Test:
75132
"""Test that asyncio marked functions work in test methods."""
76133

0 commit comments

Comments
 (0)