Skip to content

Commit 6b9b7e0

Browse files
committed
test: add tests for new task result and exception behavior
1 parent 4f41506 commit 6b9b7e0

6 files changed

+253
-0
lines changed
+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Test cancelling a task
2+
3+
try:
4+
import asyncio
5+
except ImportError:
6+
print("SKIP")
7+
raise SystemExit
8+
9+
10+
async def task(s, allow_cancel):
11+
try:
12+
print("task start")
13+
await asyncio.sleep(s)
14+
print("task done")
15+
except asyncio.CancelledError as er:
16+
print("task cancel")
17+
if allow_cancel:
18+
raise er
19+
20+
21+
async def task2(allow_cancel):
22+
print("task 2")
23+
try:
24+
await asyncio.create_task(task(0.05, allow_cancel))
25+
except asyncio.CancelledError as er:
26+
print("task 2 cancel")
27+
raise er
28+
print("task 2 done")
29+
30+
31+
async def main():
32+
# Cancel task immediately
33+
t = asyncio.create_task(task(2, True))
34+
print(t.cancel())
35+
36+
print("main checking task is cancelled", t.cancelled())
37+
38+
# Cancel task after it has started
39+
t = asyncio.create_task(task(2, True))
40+
await asyncio.sleep(0.01)
41+
print(t.cancel())
42+
print("main sleep")
43+
await asyncio.sleep(0.01)
44+
45+
print("main checking task is cancelled", t.cancelled())
46+
47+
# Cancel task multiple times after it has started
48+
t = asyncio.create_task(task(2, True))
49+
await asyncio.sleep(0.01)
50+
for _ in range(4):
51+
print(t.cancel())
52+
print("main sleep")
53+
await asyncio.sleep(0.01)
54+
55+
print("main checking task is cancelled", t.cancelled())
56+
57+
# Await on a cancelled task
58+
print("main wait")
59+
try:
60+
await t
61+
except asyncio.CancelledError:
62+
print("main got CancelledError")
63+
64+
# Cancel task after it has finished
65+
t = asyncio.create_task(task(0.01, False))
66+
await asyncio.sleep(0.05)
67+
print(t.cancel())
68+
69+
print("main checking task is cancelled", t.cancelled())
70+
71+
# Nested: task2 waits on task, task2 is cancelled (should cancel task then task2)
72+
print("----")
73+
t = asyncio.create_task(task2(True))
74+
await asyncio.sleep(0.01)
75+
print("main cancel")
76+
t.cancel()
77+
print("main sleep")
78+
await asyncio.sleep(0.1)
79+
80+
print("main checking task 2 is cancelled", t.cancelled())
81+
82+
83+
asyncio.run(main())
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
True
2+
task start
3+
True
4+
main sleep
5+
task cancel
6+
task start
7+
True
8+
True
9+
True
10+
True
11+
main sleep
12+
task cancel
13+
main wait
14+
main got CancelledError
15+
task start
16+
task done
17+
False
18+
----
19+
task 2
20+
task start
21+
main cancel
22+
main sleep
23+
task cancel
24+
task 2 cancel
25+
----
26+
task 2
27+
task start
28+
main cancel
29+
main sleep
30+
task cancel
31+
task 2 done
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Test the Task.done() method
2+
3+
try:
4+
import asyncio
5+
except ImportError:
6+
print("SKIP")
7+
raise SystemExit
8+
9+
10+
async def task(t, exc=None):
11+
if t >= 0:
12+
await asyncio.sleep(t)
13+
if exc:
14+
raise exc
15+
16+
17+
async def main():
18+
# Task that is not done yet raises an InvalidStateError
19+
print("=" * 10)
20+
t = asyncio.create_task(task(1))
21+
await asyncio.sleep(0)
22+
try:
23+
t.exception()
24+
assert False, "Should not get here"
25+
except Exception as e:
26+
print("Tasks that aren't done yet raise an InvalidStateError:", repr(e))
27+
28+
# Task that is cancelled raises CancelledError
29+
print("=" * 10)
30+
t = asyncio.create_task(task(1))
31+
t.cancel()
32+
await asyncio.sleep(0)
33+
try:
34+
t.exception()
35+
print(t.cancelled())
36+
assert False, "Should not get here"
37+
except asyncio.CancelledError as e:
38+
print("Cancelled tasks cannot retrieve exception:", repr(e))
39+
40+
# Task that starts, runs and finishes without an exception should return None
41+
print("=" * 10)
42+
t = asyncio.create_task(task(0.01))
43+
await t
44+
print("None when no exception:", t.exception())
45+
46+
# Task that raises immediately should return that exception
47+
print("=" * 10)
48+
t = asyncio.create_task(task(-1, ValueError))
49+
try:
50+
await t
51+
assert False, "Should not get here"
52+
except ValueError as e:
53+
pass
54+
print("Returned Exception:", repr(t.exception()))
55+
56+
57+
asyncio.run(main())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
==========
2+
InvalidStateError('Exception is not set.',)
3+
==========

tests/extmod/asyncio_task_result.py

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Test the Task.done() method
2+
3+
try:
4+
import asyncio
5+
except ImportError:
6+
print("SKIP")
7+
raise SystemExit
8+
9+
10+
async def task(t, exc=None, ret=None):
11+
if t >= 0:
12+
await asyncio.sleep(t)
13+
if exc:
14+
raise exc
15+
return ret
16+
17+
18+
async def main():
19+
# Task that is not done yet raises an InvalidStateError
20+
print("=" * 10)
21+
t = asyncio.create_task(task(1))
22+
await asyncio.sleep(0)
23+
try:
24+
t.result()
25+
assert False, "Should not get here"
26+
except Exception as e:
27+
print("InvalidStateError if still running:", repr(e))
28+
29+
# Task that is cancelled raises CancelledError
30+
print("=" * 10)
31+
t = asyncio.create_task(task(1))
32+
t.cancel()
33+
await asyncio.sleep(0)
34+
try:
35+
t.result()
36+
assert False, "Should not get here"
37+
except asyncio.CancelledError as e:
38+
print("CancelledError when retrieving result from cancelled task:", repr(e))
39+
40+
# Task that raises immediately should raise that exception when calling result
41+
print("=" * 10)
42+
t = asyncio.create_task(task(-1, ValueError))
43+
try:
44+
await t
45+
assert False, "Should not get here"
46+
except ValueError as e:
47+
pass
48+
49+
try:
50+
t.result()
51+
assert False, "Should not get here"
52+
except ValueError as e:
53+
print("Error raised when result is attempted on task with error:", repr(e))
54+
55+
# Task that starts, runs and finishes without an exception or value should return None
56+
print("=" * 10)
57+
t = asyncio.create_task(task(0.01))
58+
await t
59+
print("Empty Result should be None:", t.result())
60+
assert t.result() is None
61+
62+
# Task that starts, runs and finishes without exception should return result
63+
print("=" * 10)
64+
t = asyncio.create_task(task(0.01, None, "hello world"))
65+
await t
66+
print("Happy path, result is returned:", t.result())
67+
68+
69+
asyncio.run(main())
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
==========
2+
InvalidStateError if still running: InvalidStateError('Result is not ready.',)
3+
==========
4+
CancelledError when retrieving result from cancelled task: CancelledError()
5+
==========
6+
Error raised when result is attempted on task with error: ValueError()
7+
==========
8+
Empty Result should be None: None
9+
==========
10+
Happy path, result is returned: hello world

0 commit comments

Comments
 (0)