tests/extmod: Add uasyncio tests.
All .exp files are included because they require CPython 3.8 which may not always be available.
This commit is contained in:
parent
63b9944382
commit
c4935f3049
26
tests/extmod/uasyncio_await_return.py
Normal file
26
tests/extmod/uasyncio_await_return.py
Normal file
@ -0,0 +1,26 @@
|
||||
# Test that tasks return their value correctly to the caller
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def foo():
|
||||
return 42
|
||||
|
||||
|
||||
async def main():
|
||||
# Call function directly via an await
|
||||
print(await foo())
|
||||
|
||||
# Create a task and await on it
|
||||
task = asyncio.create_task(foo())
|
||||
print(await task)
|
||||
|
||||
|
||||
asyncio.run(main())
|
2
tests/extmod/uasyncio_await_return.py.exp
Normal file
2
tests/extmod/uasyncio_await_return.py.exp
Normal file
@ -0,0 +1,2 @@
|
||||
42
|
||||
42
|
43
tests/extmod/uasyncio_basic.py
Normal file
43
tests/extmod/uasyncio_basic.py
Normal file
@ -0,0 +1,43 @@
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
try:
|
||||
import utime
|
||||
|
||||
ticks = utime.ticks_ms
|
||||
ticks_diff = utime.ticks_diff
|
||||
except:
|
||||
import time
|
||||
|
||||
ticks = lambda: int(time.time() * 1000)
|
||||
ticks_diff = lambda t1, t0: t1 - t0
|
||||
|
||||
|
||||
async def delay_print(t, s):
|
||||
await asyncio.sleep(t)
|
||||
print(s)
|
||||
|
||||
|
||||
async def main():
|
||||
print("start")
|
||||
|
||||
await asyncio.sleep(0.001)
|
||||
print("after sleep")
|
||||
|
||||
t0 = ticks()
|
||||
await delay_print(0.02, "short")
|
||||
t1 = ticks()
|
||||
await delay_print(0.04, "long")
|
||||
t2 = ticks()
|
||||
|
||||
print("took {} {}".format(round(ticks_diff(t1, t0), -1), round(ticks_diff(t2, t1), -1)))
|
||||
|
||||
|
||||
asyncio.run(main())
|
5
tests/extmod/uasyncio_basic.py.exp
Normal file
5
tests/extmod/uasyncio_basic.py.exp
Normal file
@ -0,0 +1,5 @@
|
||||
start
|
||||
after sleep
|
||||
short
|
||||
long
|
||||
took 20 40
|
24
tests/extmod/uasyncio_basic2.py
Normal file
24
tests/extmod/uasyncio_basic2.py
Normal file
@ -0,0 +1,24 @@
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def forever():
|
||||
print("forever start")
|
||||
await asyncio.sleep(10)
|
||||
|
||||
|
||||
async def main():
|
||||
print("main start")
|
||||
asyncio.create_task(forever())
|
||||
await asyncio.sleep(0.001)
|
||||
print("main done")
|
||||
return 42
|
||||
|
||||
|
||||
print(asyncio.run(main()))
|
4
tests/extmod/uasyncio_basic2.py.exp
Normal file
4
tests/extmod/uasyncio_basic2.py.exp
Normal file
@ -0,0 +1,4 @@
|
||||
main start
|
||||
forever start
|
||||
main done
|
||||
42
|
37
tests/extmod/uasyncio_cancel_fair.py
Normal file
37
tests/extmod/uasyncio_cancel_fair.py
Normal file
@ -0,0 +1,37 @@
|
||||
# Test fairness of cancelling a task
|
||||
# That tasks which continuously cancel each other don't take over the scheduler
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def task(id, other):
|
||||
for i in range(3):
|
||||
try:
|
||||
print("start", id)
|
||||
await asyncio.sleep(0)
|
||||
print("done", id)
|
||||
except asyncio.CancelledError as er:
|
||||
print("cancelled", id)
|
||||
if other is not None:
|
||||
print(id, "cancels", other)
|
||||
tasks[other].cancel()
|
||||
|
||||
|
||||
async def main():
|
||||
global tasks
|
||||
tasks = [
|
||||
asyncio.create_task(task(0, 1)),
|
||||
asyncio.create_task(task(1, 0)),
|
||||
asyncio.create_task(task(2, None)),
|
||||
]
|
||||
await tasks[2]
|
||||
|
||||
|
||||
asyncio.run(main())
|
24
tests/extmod/uasyncio_cancel_fair.py.exp
Normal file
24
tests/extmod/uasyncio_cancel_fair.py.exp
Normal file
@ -0,0 +1,24 @@
|
||||
start 0
|
||||
start 1
|
||||
start 2
|
||||
done 0
|
||||
0 cancels 1
|
||||
start 0
|
||||
cancelled 1
|
||||
1 cancels 0
|
||||
start 1
|
||||
done 2
|
||||
start 2
|
||||
cancelled 0
|
||||
0 cancels 1
|
||||
start 0
|
||||
cancelled 1
|
||||
1 cancels 0
|
||||
start 1
|
||||
done 2
|
||||
start 2
|
||||
cancelled 0
|
||||
0 cancels 1
|
||||
cancelled 1
|
||||
1 cancels 0
|
||||
done 2
|
37
tests/extmod/uasyncio_cancel_fair2.py
Normal file
37
tests/extmod/uasyncio_cancel_fair2.py
Normal file
@ -0,0 +1,37 @@
|
||||
# Test fairness of cancelling a task
|
||||
# That tasks which keeps being cancelled by multiple other tasks gets a chance to run
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def task_a():
|
||||
try:
|
||||
while True:
|
||||
print("sleep a")
|
||||
await asyncio.sleep(0)
|
||||
except asyncio.CancelledError:
|
||||
print("cancelled a")
|
||||
|
||||
|
||||
async def task_b(id, other):
|
||||
while other.cancel():
|
||||
print("sleep b", id)
|
||||
await asyncio.sleep(0)
|
||||
print("done b", id)
|
||||
|
||||
|
||||
async def main():
|
||||
t = asyncio.create_task(task_a())
|
||||
for i in range(3):
|
||||
asyncio.create_task(task_b(i, t))
|
||||
await t
|
||||
|
||||
|
||||
asyncio.run(main())
|
8
tests/extmod/uasyncio_cancel_fair2.py.exp
Normal file
8
tests/extmod/uasyncio_cancel_fair2.py.exp
Normal file
@ -0,0 +1,8 @@
|
||||
sleep a
|
||||
sleep b 0
|
||||
sleep b 1
|
||||
sleep b 2
|
||||
cancelled a
|
||||
done b 0
|
||||
done b 1
|
||||
done b 2
|
31
tests/extmod/uasyncio_cancel_self.py
Normal file
31
tests/extmod/uasyncio_cancel_self.py
Normal file
@ -0,0 +1,31 @@
|
||||
# Test a task cancelling itself (currently unsupported)
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def task():
|
||||
print("task start")
|
||||
global_task.cancel()
|
||||
|
||||
|
||||
async def main():
|
||||
global global_task
|
||||
global_task = asyncio.create_task(task())
|
||||
try:
|
||||
await global_task
|
||||
except asyncio.CancelledError:
|
||||
print("main cancel")
|
||||
print("main done")
|
||||
|
||||
|
||||
try:
|
||||
asyncio.run(main())
|
||||
except RuntimeError as er:
|
||||
print(er)
|
2
tests/extmod/uasyncio_cancel_self.py.exp
Normal file
2
tests/extmod/uasyncio_cancel_self.py.exp
Normal file
@ -0,0 +1,2 @@
|
||||
task start
|
||||
cannot cancel self
|
85
tests/extmod/uasyncio_cancel_task.py
Normal file
85
tests/extmod/uasyncio_cancel_task.py
Normal file
@ -0,0 +1,85 @@
|
||||
# Test cancelling a task
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def task(s, allow_cancel):
|
||||
try:
|
||||
print("task start")
|
||||
await asyncio.sleep(s)
|
||||
print("task done")
|
||||
except asyncio.CancelledError as er:
|
||||
print("task cancel")
|
||||
if allow_cancel:
|
||||
raise er
|
||||
|
||||
|
||||
async def task2(allow_cancel):
|
||||
print("task 2")
|
||||
try:
|
||||
await asyncio.create_task(task(0.05, allow_cancel))
|
||||
except asyncio.CancelledError as er:
|
||||
print("task 2 cancel")
|
||||
raise er
|
||||
print("task 2 done")
|
||||
|
||||
|
||||
async def main():
|
||||
# Cancel task immediately
|
||||
t = asyncio.create_task(task(2, True))
|
||||
print(t.cancel())
|
||||
|
||||
# Cancel task after it has started
|
||||
t = asyncio.create_task(task(2, True))
|
||||
await asyncio.sleep(0.01)
|
||||
print(t.cancel())
|
||||
print("main sleep")
|
||||
await asyncio.sleep(0.01)
|
||||
|
||||
# Cancel task multiple times after it has started
|
||||
t = asyncio.create_task(task(2, True))
|
||||
await asyncio.sleep(0.01)
|
||||
for _ in range(4):
|
||||
print(t.cancel())
|
||||
print("main sleep")
|
||||
await asyncio.sleep(0.01)
|
||||
|
||||
# Await on a cancelled task
|
||||
print("main wait")
|
||||
try:
|
||||
await t
|
||||
except asyncio.CancelledError:
|
||||
print("main got CancelledError")
|
||||
|
||||
# Cancel task after it has finished
|
||||
t = asyncio.create_task(task(0.01, False))
|
||||
await asyncio.sleep(0.05)
|
||||
print(t.cancel())
|
||||
|
||||
# Nested: task2 waits on task, task2 is cancelled (should cancel task then task2)
|
||||
print("----")
|
||||
t = asyncio.create_task(task2(True))
|
||||
await asyncio.sleep(0.01)
|
||||
print("main cancel")
|
||||
t.cancel()
|
||||
print("main sleep")
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
# Nested: task2 waits on task, task2 is cancelled but task doesn't allow it (task2 should continue)
|
||||
print("----")
|
||||
t = asyncio.create_task(task2(False))
|
||||
await asyncio.sleep(0.01)
|
||||
print("main cancel")
|
||||
t.cancel()
|
||||
print("main sleep")
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
|
||||
asyncio.run(main())
|
31
tests/extmod/uasyncio_cancel_task.py.exp
Normal file
31
tests/extmod/uasyncio_cancel_task.py.exp
Normal file
@ -0,0 +1,31 @@
|
||||
True
|
||||
task start
|
||||
True
|
||||
main sleep
|
||||
task cancel
|
||||
task start
|
||||
True
|
||||
True
|
||||
True
|
||||
True
|
||||
main sleep
|
||||
task cancel
|
||||
main wait
|
||||
main got CancelledError
|
||||
task start
|
||||
task done
|
||||
False
|
||||
----
|
||||
task 2
|
||||
task start
|
||||
main cancel
|
||||
main sleep
|
||||
task cancel
|
||||
task 2 cancel
|
||||
----
|
||||
task 2
|
||||
task start
|
||||
main cancel
|
||||
main sleep
|
||||
task cancel
|
||||
task 2 done
|
98
tests/extmod/uasyncio_event.py
Normal file
98
tests/extmod/uasyncio_event.py
Normal file
@ -0,0 +1,98 @@
|
||||
# Test Event class
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def task(id, ev):
|
||||
print("start", id)
|
||||
print(await ev.wait())
|
||||
print("end", id)
|
||||
|
||||
|
||||
async def task_delay_set(t, ev):
|
||||
await asyncio.sleep(t)
|
||||
print("set event")
|
||||
ev.set()
|
||||
|
||||
|
||||
async def main():
|
||||
ev = asyncio.Event()
|
||||
|
||||
# Set and clear without anything waiting, and test is_set()
|
||||
print(ev.is_set())
|
||||
ev.set()
|
||||
print(ev.is_set())
|
||||
ev.clear()
|
||||
print(ev.is_set())
|
||||
|
||||
# Create 2 tasks waiting on the event
|
||||
print("----")
|
||||
asyncio.create_task(task(1, ev))
|
||||
asyncio.create_task(task(2, ev))
|
||||
print("yield")
|
||||
await asyncio.sleep(0)
|
||||
print("set event")
|
||||
ev.set()
|
||||
print("yield")
|
||||
await asyncio.sleep(0)
|
||||
|
||||
# Create a task waiting on the already-set event
|
||||
print("----")
|
||||
asyncio.create_task(task(3, ev))
|
||||
print("yield")
|
||||
await asyncio.sleep(0)
|
||||
|
||||
# Clear event, start a task, then set event again
|
||||
print("----")
|
||||
print("clear event")
|
||||
ev.clear()
|
||||
asyncio.create_task(task(4, ev))
|
||||
await asyncio.sleep(0)
|
||||
print("set event")
|
||||
ev.set()
|
||||
await asyncio.sleep(0)
|
||||
|
||||
# Cancel a task waiting on an event (set event then cancel task)
|
||||
print("----")
|
||||
ev = asyncio.Event()
|
||||
t = asyncio.create_task(task(5, ev))
|
||||
await asyncio.sleep(0)
|
||||
ev.set()
|
||||
t.cancel()
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
# Cancel a task waiting on an event (cancel task then set event)
|
||||
print("----")
|
||||
ev = asyncio.Event()
|
||||
t = asyncio.create_task(task(6, ev))
|
||||
await asyncio.sleep(0)
|
||||
t.cancel()
|
||||
ev.set()
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
# Wait for an event that does get set in time
|
||||
print("----")
|
||||
ev.clear()
|
||||
asyncio.create_task(task_delay_set(0.01, ev))
|
||||
await asyncio.wait_for(ev.wait(), 0.1)
|
||||
await asyncio.sleep(0)
|
||||
|
||||
# Wait for an event that doesn't get set in time
|
||||
print("----")
|
||||
ev.clear()
|
||||
asyncio.create_task(task_delay_set(0.1, ev))
|
||||
try:
|
||||
await asyncio.wait_for(ev.wait(), 0.01)
|
||||
except asyncio.TimeoutError:
|
||||
print("TimeoutError")
|
||||
await ev.wait()
|
||||
|
||||
|
||||
asyncio.run(main())
|
33
tests/extmod/uasyncio_event.py.exp
Normal file
33
tests/extmod/uasyncio_event.py.exp
Normal file
@ -0,0 +1,33 @@
|
||||
False
|
||||
True
|
||||
False
|
||||
----
|
||||
yield
|
||||
start 1
|
||||
start 2
|
||||
set event
|
||||
yield
|
||||
True
|
||||
end 1
|
||||
True
|
||||
end 2
|
||||
----
|
||||
yield
|
||||
start 3
|
||||
True
|
||||
end 3
|
||||
----
|
||||
clear event
|
||||
start 4
|
||||
set event
|
||||
True
|
||||
end 4
|
||||
----
|
||||
start 5
|
||||
----
|
||||
start 6
|
||||
----
|
||||
set event
|
||||
----
|
||||
TimeoutError
|
||||
set event
|
40
tests/extmod/uasyncio_event_fair.py
Normal file
40
tests/extmod/uasyncio_event_fair.py
Normal file
@ -0,0 +1,40 @@
|
||||
# Test fairness of Event.set()
|
||||
# That tasks which continuously wait on events don't take over the scheduler
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def task1(id):
|
||||
for i in range(4):
|
||||
print("sleep", id)
|
||||
await asyncio.sleep(0)
|
||||
|
||||
|
||||
async def task2(id, ev):
|
||||
for i in range(4):
|
||||
ev.set()
|
||||
ev.clear()
|
||||
print("wait", id)
|
||||
await ev.wait()
|
||||
|
||||
|
||||
async def main():
|
||||
ev = asyncio.Event()
|
||||
tasks = [
|
||||
asyncio.create_task(task1(0)),
|
||||
asyncio.create_task(task2(2, ev)),
|
||||
asyncio.create_task(task1(1)),
|
||||
asyncio.create_task(task2(3, ev)),
|
||||
]
|
||||
await tasks[1]
|
||||
ev.set()
|
||||
|
||||
|
||||
asyncio.run(main())
|
16
tests/extmod/uasyncio_event_fair.py.exp
Normal file
16
tests/extmod/uasyncio_event_fair.py.exp
Normal file
@ -0,0 +1,16 @@
|
||||
sleep 0
|
||||
wait 2
|
||||
sleep 1
|
||||
wait 3
|
||||
sleep 0
|
||||
sleep 1
|
||||
wait 2
|
||||
sleep 0
|
||||
sleep 1
|
||||
wait 3
|
||||
sleep 0
|
||||
sleep 1
|
||||
wait 2
|
||||
wait 3
|
||||
wait 2
|
||||
wait 3
|
60
tests/extmod/uasyncio_exception.py
Normal file
60
tests/extmod/uasyncio_exception.py
Normal file
@ -0,0 +1,60 @@
|
||||
# Test general exception handling
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
# main task raising an exception
|
||||
async def main():
|
||||
print("main start")
|
||||
raise ValueError(1)
|
||||
print("main done")
|
||||
|
||||
|
||||
try:
|
||||
asyncio.run(main())
|
||||
except ValueError as er:
|
||||
print("ValueError", er.args[0])
|
||||
|
||||
# sub-task raising an exception
|
||||
async def task():
|
||||
print("task start")
|
||||
raise ValueError(2)
|
||||
print("task done")
|
||||
|
||||
|
||||
async def main():
|
||||
print("main start")
|
||||
t = asyncio.create_task(task())
|
||||
await t
|
||||
print("main done")
|
||||
|
||||
|
||||
try:
|
||||
asyncio.run(main())
|
||||
except ValueError as er:
|
||||
print("ValueError", er.args[0])
|
||||
|
||||
# main task raising an exception with sub-task not yet scheduled
|
||||
# TODO not currently working, task is never scheduled
|
||||
async def task():
|
||||
# print('task run') uncomment this line when it works
|
||||
pass
|
||||
|
||||
|
||||
async def main():
|
||||
print("main start")
|
||||
asyncio.create_task(task())
|
||||
raise ValueError(3)
|
||||
print("main done")
|
||||
|
||||
|
||||
try:
|
||||
asyncio.run(main())
|
||||
except ValueError as er:
|
||||
print("ValueError", er.args[0])
|
7
tests/extmod/uasyncio_exception.py.exp
Normal file
7
tests/extmod/uasyncio_exception.py.exp
Normal file
@ -0,0 +1,7 @@
|
||||
main start
|
||||
ValueError 1
|
||||
main start
|
||||
task start
|
||||
ValueError 2
|
||||
main start
|
||||
ValueError 3
|
32
tests/extmod/uasyncio_fair.py
Normal file
32
tests/extmod/uasyncio_fair.py
Normal file
@ -0,0 +1,32 @@
|
||||
# Test fairness of scheduler
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def task(id, t):
|
||||
print("task start", id)
|
||||
while True:
|
||||
if t > 0:
|
||||
print("task work", id)
|
||||
await asyncio.sleep(t)
|
||||
|
||||
|
||||
async def main():
|
||||
t1 = asyncio.create_task(task(1, -0.01))
|
||||
t2 = asyncio.create_task(task(2, 0.1))
|
||||
t3 = asyncio.create_task(task(3, 0.2))
|
||||
await asyncio.sleep(0.5)
|
||||
t1.cancel()
|
||||
t2.cancel()
|
||||
t3.cancel()
|
||||
print("finish")
|
||||
|
||||
|
||||
asyncio.run(main())
|
12
tests/extmod/uasyncio_fair.py.exp
Normal file
12
tests/extmod/uasyncio_fair.py.exp
Normal file
@ -0,0 +1,12 @@
|
||||
task start 1
|
||||
task start 2
|
||||
task work 2
|
||||
task start 3
|
||||
task work 3
|
||||
task work 2
|
||||
task work 3
|
||||
task work 2
|
||||
task work 2
|
||||
task work 3
|
||||
task work 2
|
||||
finish
|
49
tests/extmod/uasyncio_gather.py
Normal file
49
tests/extmod/uasyncio_gather.py
Normal file
@ -0,0 +1,49 @@
|
||||
# test uasyncio.gather() function
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def factorial(name, number):
|
||||
f = 1
|
||||
for i in range(2, number + 1):
|
||||
print("Task {}: Compute factorial({})...".format(name, i))
|
||||
await asyncio.sleep(0.01)
|
||||
f *= i
|
||||
print("Task {}: factorial({}) = {}".format(name, number, f))
|
||||
return f
|
||||
|
||||
|
||||
async def task(id):
|
||||
print("start", id)
|
||||
await asyncio.sleep(0.2)
|
||||
print("end", id)
|
||||
|
||||
|
||||
async def gather_task():
|
||||
print("gather_task")
|
||||
await asyncio.gather(task(1), task(2))
|
||||
print("gather_task2")
|
||||
|
||||
|
||||
async def main():
|
||||
# Simple gather with return values
|
||||
print(await asyncio.gather(factorial("A", 2), factorial("B", 3), factorial("C", 4),))
|
||||
|
||||
# Cancel a multi gather
|
||||
# TODO doesn't work, Task should not forward cancellation from gather to sub-task
|
||||
# but rather CancelledError should cancel the gather directly, which will then cancel
|
||||
# all sub-tasks explicitly
|
||||
# t = asyncio.create_task(gather_task())
|
||||
# await asyncio.sleep(0.1)
|
||||
# t.cancel()
|
||||
# await asyncio.sleep(0.01)
|
||||
|
||||
|
||||
asyncio.run(main())
|
10
tests/extmod/uasyncio_gather.py.exp
Normal file
10
tests/extmod/uasyncio_gather.py.exp
Normal file
@ -0,0 +1,10 @@
|
||||
Task A: Compute factorial(2)...
|
||||
Task B: Compute factorial(2)...
|
||||
Task C: Compute factorial(2)...
|
||||
Task A: factorial(2) = 2
|
||||
Task B: Compute factorial(3)...
|
||||
Task C: Compute factorial(3)...
|
||||
Task B: factorial(3) = 6
|
||||
Task C: Compute factorial(4)...
|
||||
Task C: factorial(4) = 24
|
||||
[2, 6, 24]
|
20
tests/extmod/uasyncio_get_event_loop.py
Normal file
20
tests/extmod/uasyncio_get_event_loop.py
Normal file
@ -0,0 +1,20 @@
|
||||
# Test get_event_loop()
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def main():
|
||||
print("start")
|
||||
await asyncio.sleep(0.01)
|
||||
print("end")
|
||||
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(main())
|
46
tests/extmod/uasyncio_heaplock.py
Normal file
46
tests/extmod/uasyncio_heaplock.py
Normal file
@ -0,0 +1,46 @@
|
||||
# test that basic scheduling of tasks, and uasyncio.sleep_ms, does not use the heap
|
||||
|
||||
import micropython
|
||||
|
||||
# strict stackless builds can't call functions without allocating a frame on the heap
|
||||
try:
|
||||
f = lambda: 0
|
||||
micropython.heap_lock()
|
||||
f()
|
||||
micropython.heap_unlock()
|
||||
except RuntimeError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def task(id, n, t):
|
||||
for i in range(n):
|
||||
print(id, i)
|
||||
await asyncio.sleep_ms(t)
|
||||
|
||||
|
||||
async def main():
|
||||
t1 = asyncio.create_task(task(1, 4, 10))
|
||||
t2 = asyncio.create_task(task(2, 4, 25))
|
||||
|
||||
micropython.heap_lock()
|
||||
|
||||
print("start")
|
||||
await asyncio.sleep_ms(1)
|
||||
print("sleep")
|
||||
await asyncio.sleep_ms(100)
|
||||
print("finish")
|
||||
|
||||
micropython.heap_unlock()
|
||||
|
||||
|
||||
asyncio.run(main())
|
11
tests/extmod/uasyncio_heaplock.py.exp
Normal file
11
tests/extmod/uasyncio_heaplock.py.exp
Normal file
@ -0,0 +1,11 @@
|
||||
start
|
||||
1 0
|
||||
2 0
|
||||
sleep
|
||||
1 1
|
||||
1 2
|
||||
2 1
|
||||
1 3
|
||||
2 2
|
||||
2 3
|
||||
finish
|
97
tests/extmod/uasyncio_lock.py
Normal file
97
tests/extmod/uasyncio_lock.py
Normal file
@ -0,0 +1,97 @@
|
||||
# Test Lock class
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def task_loop(id, lock):
|
||||
print("task start", id)
|
||||
for i in range(3):
|
||||
async with lock:
|
||||
print("task have", id, i)
|
||||
print("task end", id)
|
||||
|
||||
|
||||
async def task_sleep(lock):
|
||||
async with lock:
|
||||
print("task have", lock.locked())
|
||||
await asyncio.sleep(0.2)
|
||||
print("task release", lock.locked())
|
||||
await lock.acquire()
|
||||
print("task have again")
|
||||
lock.release()
|
||||
|
||||
|
||||
async def task_cancel(id, lock, to_cancel=None):
|
||||
try:
|
||||
async with lock:
|
||||
print("task got", id)
|
||||
await asyncio.sleep(0.1)
|
||||
print("task release", id)
|
||||
if to_cancel:
|
||||
to_cancel[0].cancel()
|
||||
except asyncio.CancelledError:
|
||||
print("task cancel", id)
|
||||
|
||||
|
||||
async def main():
|
||||
lock = asyncio.Lock()
|
||||
|
||||
# Basic acquire/release
|
||||
print(lock.locked())
|
||||
await lock.acquire()
|
||||
print(lock.locked())
|
||||
await asyncio.sleep(0)
|
||||
lock.release()
|
||||
print(lock.locked())
|
||||
await asyncio.sleep(0)
|
||||
|
||||
# Use with "async with"
|
||||
async with lock:
|
||||
print("have lock")
|
||||
|
||||
# 3 tasks wanting the lock
|
||||
print("----")
|
||||
asyncio.create_task(task_loop(1, lock))
|
||||
asyncio.create_task(task_loop(2, lock))
|
||||
t3 = asyncio.create_task(task_loop(3, lock))
|
||||
await lock.acquire()
|
||||
await asyncio.sleep(0)
|
||||
lock.release()
|
||||
await t3
|
||||
|
||||
# 2 sleeping tasks both wanting the lock
|
||||
print("----")
|
||||
asyncio.create_task(task_sleep(lock))
|
||||
await asyncio.sleep(0.1)
|
||||
await task_sleep(lock)
|
||||
|
||||
# 3 tasks, the first cancelling the second, the third should still run
|
||||
print("----")
|
||||
ts = [None]
|
||||
asyncio.create_task(task_cancel(0, lock, ts))
|
||||
ts[0] = asyncio.create_task(task_cancel(1, lock))
|
||||
asyncio.create_task(task_cancel(2, lock))
|
||||
await asyncio.sleep(0.3)
|
||||
print(lock.locked())
|
||||
|
||||
# 3 tasks, the second and third being cancelled while waiting on the lock
|
||||
print("----")
|
||||
t0 = asyncio.create_task(task_cancel(0, lock))
|
||||
t1 = asyncio.create_task(task_cancel(1, lock))
|
||||
t2 = asyncio.create_task(task_cancel(2, lock))
|
||||
await asyncio.sleep(0.05)
|
||||
t1.cancel()
|
||||
await asyncio.sleep(0.1)
|
||||
t2.cancel()
|
||||
await asyncio.sleep(0.1)
|
||||
print(lock.locked())
|
||||
|
||||
|
||||
asyncio.run(main())
|
41
tests/extmod/uasyncio_lock.py.exp
Normal file
41
tests/extmod/uasyncio_lock.py.exp
Normal file
@ -0,0 +1,41 @@
|
||||
False
|
||||
True
|
||||
False
|
||||
have lock
|
||||
----
|
||||
task start 1
|
||||
task start 2
|
||||
task start 3
|
||||
task have 1 0
|
||||
task have 2 0
|
||||
task have 3 0
|
||||
task have 1 1
|
||||
task have 2 1
|
||||
task have 3 1
|
||||
task have 1 2
|
||||
task end 1
|
||||
task have 2 2
|
||||
task end 2
|
||||
task have 3 2
|
||||
task end 3
|
||||
----
|
||||
task have True
|
||||
task release False
|
||||
task have True
|
||||
task release False
|
||||
task have again
|
||||
task have again
|
||||
----
|
||||
task got 0
|
||||
task release 0
|
||||
task cancel 1
|
||||
task got 2
|
||||
task release 2
|
||||
False
|
||||
----
|
||||
task got 0
|
||||
task cancel 1
|
||||
task release 0
|
||||
task got 2
|
||||
task cancel 2
|
||||
False
|
55
tests/extmod/uasyncio_lock_cancel.py
Normal file
55
tests/extmod/uasyncio_lock_cancel.py
Normal file
@ -0,0 +1,55 @@
|
||||
# Test that locks work when cancelling multiple waiters on the lock
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def task(i, lock, lock_flag):
|
||||
print("task", i, "start")
|
||||
try:
|
||||
await lock.acquire()
|
||||
except asyncio.CancelledError:
|
||||
print("task", i, "cancel")
|
||||
return
|
||||
print("task", i, "lock_flag", lock_flag[0])
|
||||
lock_flag[0] = True
|
||||
await asyncio.sleep(0)
|
||||
lock.release()
|
||||
lock_flag[0] = False
|
||||
print("task", i, "done")
|
||||
|
||||
|
||||
async def main():
|
||||
# Create a lock and acquire it so the tasks below must wait
|
||||
lock = asyncio.Lock()
|
||||
await lock.acquire()
|
||||
lock_flag = [True]
|
||||
|
||||
# Create 4 tasks and let them all run
|
||||
t0 = asyncio.create_task(task(0, lock, lock_flag))
|
||||
t1 = asyncio.create_task(task(1, lock, lock_flag))
|
||||
t2 = asyncio.create_task(task(2, lock, lock_flag))
|
||||
t3 = asyncio.create_task(task(3, lock, lock_flag))
|
||||
await asyncio.sleep(0)
|
||||
|
||||
# Cancel 2 of the tasks (which are waiting on the lock) and release the lock
|
||||
t1.cancel()
|
||||
t2.cancel()
|
||||
lock.release()
|
||||
lock_flag[0] = False
|
||||
|
||||
# Let the tasks run to completion
|
||||
for _ in range(4):
|
||||
await asyncio.sleep(0)
|
||||
|
||||
# The locke should be unlocked
|
||||
print(lock.locked())
|
||||
|
||||
|
||||
asyncio.run(main())
|
11
tests/extmod/uasyncio_lock_cancel.py.exp
Normal file
11
tests/extmod/uasyncio_lock_cancel.py.exp
Normal file
@ -0,0 +1,11 @@
|
||||
task 0 start
|
||||
task 1 start
|
||||
task 2 start
|
||||
task 3 start
|
||||
task 1 cancel
|
||||
task 2 cancel
|
||||
task 0 lock_flag False
|
||||
task 0 done
|
||||
task 3 lock_flag False
|
||||
task 3 done
|
||||
False
|
62
tests/extmod/uasyncio_wait_for.py
Normal file
62
tests/extmod/uasyncio_wait_for.py
Normal file
@ -0,0 +1,62 @@
|
||||
# Test asyncio.wait_for
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
async def task(id, t):
|
||||
print("task start", id)
|
||||
await asyncio.sleep(t)
|
||||
print("task end", id)
|
||||
return id * 2
|
||||
|
||||
|
||||
async def task_catch():
|
||||
print("task_catch start")
|
||||
try:
|
||||
await asyncio.sleep(0.2)
|
||||
except asyncio.CancelledError:
|
||||
print("ignore cancel")
|
||||
print("task_catch done")
|
||||
|
||||
|
||||
async def task_raise():
|
||||
print("task start")
|
||||
raise ValueError
|
||||
|
||||
|
||||
async def main():
|
||||
# When task finished before the timeout
|
||||
print(await asyncio.wait_for(task(1, 0.01), 10))
|
||||
|
||||
# When timeout passes and task is cancelled
|
||||
try:
|
||||
print(await asyncio.wait_for(task(2, 10), 0.01))
|
||||
except asyncio.TimeoutError:
|
||||
print("timeout")
|
||||
|
||||
# When timeout passes and task is cancelled, but task ignores the cancellation request
|
||||
try:
|
||||
print(await asyncio.wait_for(task_catch(), 0.1))
|
||||
except asyncio.TimeoutError:
|
||||
print("TimeoutError")
|
||||
|
||||
# When task raises an exception
|
||||
try:
|
||||
print(await asyncio.wait_for(task_raise(), 1))
|
||||
except ValueError:
|
||||
print("ValueError")
|
||||
|
||||
# Timeout of None means wait forever
|
||||
print(await asyncio.wait_for(task(3, 0.1), None))
|
||||
|
||||
print("finish")
|
||||
|
||||
|
||||
asyncio.run(main())
|
15
tests/extmod/uasyncio_wait_for.py.exp
Normal file
15
tests/extmod/uasyncio_wait_for.py.exp
Normal file
@ -0,0 +1,15 @@
|
||||
task start 1
|
||||
task end 1
|
||||
2
|
||||
task start 2
|
||||
timeout
|
||||
task_catch start
|
||||
ignore cancel
|
||||
task_catch done
|
||||
TimeoutError
|
||||
task start
|
||||
ValueError
|
||||
task start 3
|
||||
task end 3
|
||||
6
|
||||
finish
|
77
tests/extmod/uasyncio_wait_task.py
Normal file
77
tests/extmod/uasyncio_wait_task.py
Normal file
@ -0,0 +1,77 @@
|
||||
# Test waiting on a task
|
||||
|
||||
try:
|
||||
import uasyncio as asyncio
|
||||
except ImportError:
|
||||
try:
|
||||
import asyncio
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
try:
|
||||
import utime
|
||||
|
||||
ticks = utime.ticks_ms
|
||||
ticks_diff = utime.ticks_diff
|
||||
except:
|
||||
import time
|
||||
|
||||
ticks = lambda: int(time.time() * 1000)
|
||||
ticks_diff = lambda t1, t0: t1 - t0
|
||||
|
||||
|
||||
async def task(t):
|
||||
print("task", t)
|
||||
|
||||
|
||||
async def delay_print(t, s):
|
||||
await asyncio.sleep(t)
|
||||
print(s)
|
||||
|
||||
|
||||
async def task_raise():
|
||||
print("task_raise")
|
||||
raise ValueError
|
||||
|
||||
|
||||
async def main():
|
||||
print("start")
|
||||
|
||||
# Wait on a task
|
||||
t = asyncio.create_task(task(1))
|
||||
await t
|
||||
|
||||
# Wait on a task that's already done
|
||||
t = asyncio.create_task(task(2))
|
||||
await asyncio.sleep(0.001)
|
||||
await t
|
||||
|
||||
# Wait again on same task
|
||||
await t
|
||||
|
||||
print("----")
|
||||
|
||||
# Create 2 tasks
|
||||
ts1 = asyncio.create_task(delay_print(0.04, "hello"))
|
||||
ts2 = asyncio.create_task(delay_print(0.08, "world"))
|
||||
|
||||
# Time how long the tasks take to finish, they should execute in parallel
|
||||
print("start")
|
||||
t0 = ticks()
|
||||
await ts1
|
||||
t1 = ticks()
|
||||
await ts2
|
||||
t2 = ticks()
|
||||
print("took {} {}".format(round(ticks_diff(t1, t0), -1), round(ticks_diff(t2, t1), -1)))
|
||||
|
||||
# Wait on a task that raises an exception
|
||||
t = asyncio.create_task(task_raise())
|
||||
try:
|
||||
await t
|
||||
except ValueError:
|
||||
print("ValueError")
|
||||
|
||||
|
||||
asyncio.run(main())
|
10
tests/extmod/uasyncio_wait_task.py.exp
Normal file
10
tests/extmod/uasyncio_wait_task.py.exp
Normal file
@ -0,0 +1,10 @@
|
||||
start
|
||||
task 1
|
||||
task 2
|
||||
----
|
||||
start
|
||||
hello
|
||||
world
|
||||
took 40 40
|
||||
task_raise
|
||||
ValueError
|
Loading…
x
Reference in New Issue
Block a user