Skip to content

Commit 7de1ea4

Browse files
committed
add unit test
1 parent d1d8902 commit 7de1ea4

File tree

2 files changed

+76
-3
lines changed

2 files changed

+76
-3
lines changed

cadence/workflow/deterministic_event_loop.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from asyncio import AbstractEventLoop, BaseEventLoop, EventLoop, futures, tasks
1+
from asyncio import AbstractEventLoop, futures, tasks
22
from asyncio import Future
33
import logging
44
import collections
@@ -108,6 +108,9 @@ def create_task(self, coro, **kwargs):
108108
# task.exception().__traceback__->BaseEventLoop.create_task->task
109109
del task
110110

111+
def create_future(self):
112+
return futures.Future(loop=self)
113+
111114
def _run_once(self):
112115
ntodo = len(self._ready)
113116
for i in range(ntodo):
@@ -165,7 +168,5 @@ def _run_until_complete_cb(fut: Future):
165168
if not fut.cancelled():
166169
exc = fut.exception()
167170
if isinstance(exc, (SystemExit, KeyboardInterrupt)):
168-
# Issue #22429: run_forever() already finished, no need to
169-
# stop it.
170171
return
171172
fut.get_loop().stop()
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import pytest
2+
import asyncio
3+
from cadence.workflow.deterministic_event_loop import DeterministicEventLoop
4+
5+
6+
async def coro_append(results: list, i: int):
7+
results.append(i)
8+
9+
async def coro_await(size: int):
10+
results = []
11+
for i in range(size):
12+
await coro_append(results, i)
13+
return results
14+
15+
async def coro_await_future(future: asyncio.Future):
16+
return await future
17+
18+
async def coro_await_task(size: int):
19+
results = []
20+
for i in range(size):
21+
asyncio.create_task(coro_append(results, i))
22+
return results
23+
24+
class TestDeterministicEventLoop:
25+
"""Test suite for DeterministicEventLoop using table-driven tests."""
26+
27+
def setup_method(self):
28+
"""Setup method called before each test."""
29+
self.loop = DeterministicEventLoop()
30+
31+
def teardown_method(self):
32+
"""Teardown method called after each test."""
33+
if not self.loop.is_closed():
34+
self.loop.close()
35+
assert self.loop.is_closed() is True
36+
37+
def test_call_soon(self):
38+
"""Test _run_once executes single callback."""
39+
results = []
40+
expected = []
41+
for i in range(10000):
42+
expected.append(i)
43+
self.loop.call_soon(lambda x=i: results.append(x))
44+
45+
self.loop._run_once()
46+
47+
assert results == expected
48+
assert self.loop.is_running() is False
49+
50+
def test_run_until_complete(self):
51+
size = 10000
52+
results = self.loop.run_until_complete(coro_await(size))
53+
assert results == list(range(size))
54+
assert self.loop.is_running() is False
55+
assert self.loop.is_closed() is False
56+
57+
@pytest.mark.parametrize("result, exception, expected, expected_exception",
58+
[(10000, None, 10000, None), (None, ValueError("test"), None, ValueError)])
59+
def test_create_future(self, result, exception, expected, expected_exception):
60+
future = self.loop.create_future()
61+
if expected_exception is not None:
62+
with pytest.raises(expected_exception):
63+
future.set_exception(exception)
64+
self.loop.run_until_complete(coro_await_future(future))
65+
else:
66+
future.set_result(result)
67+
assert self.loop.run_until_complete(coro_await_future(future)) == expected
68+
69+
def test_create_task(self):
70+
size = 10000
71+
results = self.loop.run_until_complete(coro_await_task(size))
72+
assert results == list(range(size))

0 commit comments

Comments
 (0)