Skip to content

Commit 71701e1

Browse files
committed
Add ClockEventLoop class with fixture and test (close pytest-dev#95)
1 parent 1ada096 commit 71701e1

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

pytest_asyncio/plugin.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,23 @@ def pytest_runtest_setup(item):
159159
item.fixturenames.append(fixture)
160160

161161

162+
class ClockEventLoop(asyncio.SelectorEventLoop):
163+
_now = 0
164+
165+
def time(self):
166+
return self._now
167+
168+
def advance_time(self, amount):
169+
# advance the clock and run the loop
170+
self._now += amount
171+
self._run_once()
172+
173+
if amount > 0:
174+
# Once advanced, new tasks may have just been scheduled for running
175+
# in the next loop, advance once more to start these handlers
176+
self._run_once()
177+
178+
162179
# maps marker to the name of the event loop fixture that will be available
163180
# to marked test functions
164181
_markers_2_fixtures = {
@@ -174,6 +191,15 @@ def event_loop(request):
174191
loop.close()
175192

176193

194+
@pytest.yield_fixture
195+
def clock_event_loop(request):
196+
"""Create an instance of the default event loop for each test case."""
197+
loop = ClockEventLoop()
198+
asyncio.get_event_loop_policy().set_event_loop(loop)
199+
yield loop
200+
loop.close()
201+
202+
177203
@pytest.fixture
178204
def unused_tcp_port():
179205
"""Find an unused localhost TCP port from 1024-65535 and return it."""

tests/test_simple_35.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,22 @@ async def test_asyncio_marker_method(self, event_loop):
8686
def test_async_close_loop(event_loop):
8787
event_loop.close()
8888
return 'ok'
89+
90+
91+
def test_clock_loop(clock_event_loop):
92+
assert clock_event_loop.time() == 0
93+
94+
async def foo():
95+
await asyncio.sleep(1)
96+
97+
# create the task
98+
task = clock_event_loop.create_task(foo())
99+
assert not task.done()
100+
101+
# start the task
102+
clock_event_loop.advance_time(0)
103+
assert not task.done()
104+
105+
# process the timeout
106+
clock_event_loop.advance_time(1)
107+
assert task.done()

0 commit comments

Comments
 (0)