Skip to content
5 changes: 5 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@ jobs:
uses: adafruit/workflows-circuitpython-libs/build@main
with:
package-prefix: "asyncio"

test-v9-0-0-alpha5:
uses: ./.github/workflows/run-tests.yml
with:
cp-version: 9.0.0-alpha.5
63 changes: 63 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
#
# SPDX-License-Identifier: MIT

name: Run tests

on:
workflow_call:
inputs:
cp-version:
required: true
type: string

jobs:
run:
runs-on: ubuntu-22.04
env:
CP_VERSION: ${{ inputs.cp-version }}
steps:
- name: Set up repository
uses: actions/checkout@v3
with:
submodules: false
fetch-depth: 1
- name: Set up circuitpython repository
uses: actions/checkout@v3
with:
ref: ${{ inputs.cp-version }}
repository: adafruit/circuitpython
path: ./circuitpython/
submodules: false
fetch-depth: 1
fetch-tags: true
- name: Set up python
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: CircuitPython dependencies
id: cp-deps
run: python tools/ci_fetch_deps.py tests
shell: bash
working-directory: ./circuitpython/
- name: Fetch relevant submodules
id: submodules
run: python tools/ci_fetch_deps.py tests
working-directory: ./circuitpython
- name: Install python dependencies
run: pip install -r requirements-dev.txt
shell: bash
working-directory: ./circuitpython/
- name: Build mpy-cross
run: make -C mpy-cross -j2
working-directory: ./circuitpython/
- name: Build unix port
run: make -C ports/unix VARIANT=coverage BUILD=build-coverage PROG=micropython -j2
working-directory: ./circuitpython/
- name: Run tests
run: ./run_tests.py
working-directory: tests
env:
MICROPY_CPYTHON3: python3.8
MICROPY_MICROPYTHON: ../circuitpython/ports/unix/build-coverage/micropython
MICROPYPATH: ../:../circuitpython/frozen/Adafruit_CircuitPython_Ticks
4 changes: 4 additions & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# SPDX-FileCopyrightText: 2019 Damien P. George
#
# SPDX-License-Identifier: MIT
*.out
28 changes: 28 additions & 0 deletions tests/asyncio/asyncio_await_return.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# SPDX-FileCopyrightText: 2019 Damien P. George
#
# SPDX-License-Identifier: MIT
#
# MicroPython uasyncio module
# MIT license; Copyright (c) 2019 Damien P. George
#
# pylint: skip-file
#
# Test that tasks return their value correctly to the caller

import asyncio


async def example():
return 42


async def main():
# Call function directly via an await
print(await example())

# Create a task and await on it
task = asyncio.create_task(example())
print(await task)


asyncio.run(main())
5 changes: 5 additions & 0 deletions tests/asyncio/asyncio_await_return.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: 2019 Damien P. George
#
# SPDX-License-Identifier: MIT
42
42
50 changes: 50 additions & 0 deletions tests/asyncio/asyncio_basic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# SPDX-FileCopyrightText: 2019 Damien P. George
#
# SPDX-License-Identifier: MIT
#
# MicroPython uasyncio module
# MIT license; Copyright (c) 2019 Damien P. George
#
# pylint: skip-file

import asyncio
import time


if hasattr(time, "ticks_ms"):
ticks = time.ticks_ms
ticks_diff = time.ticks_diff
else:
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.2, "short")
t1 = ticks()
await delay_print(0.4, "long")
t2 = ticks()
await delay_print(-1, "negative")
t3 = ticks()

print(
"took {} {} {}".format(
round(ticks_diff(t1, t0), -2),
round(ticks_diff(t2, t1), -2),
round(ticks_diff(t3, t2), -2),
)
)


asyncio.run(main())
9 changes: 9 additions & 0 deletions tests/asyncio/asyncio_basic.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# SPDX-FileCopyrightText: 2019 Damien P. George
#
# SPDX-License-Identifier: MIT
start
after sleep
short
long
negative
took 200 400 0
26 changes: 26 additions & 0 deletions tests/asyncio/asyncio_basic2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# SPDX-FileCopyrightText: 2019 Damien P. George
#
# SPDX-License-Identifier: MIT
#
# MicroPython uasyncio module
# MIT license; Copyright (c) 2019 Damien P. George
#
# pylint: skip-file

import asyncio


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()))
7 changes: 7 additions & 0 deletions tests/asyncio/asyncio_basic2.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SPDX-FileCopyrightText: 2019 Damien P. George
#
# SPDX-License-Identifier: MIT
main start
forever start
main done
42
38 changes: 38 additions & 0 deletions tests/asyncio/asyncio_cancel_fair.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# SPDX-FileCopyrightText: 2019 Damien P. George
#
# SPDX-License-Identifier: MIT
#
# MicroPython uasyncio module
# MIT license; Copyright (c) 2019 Damien P. George
#
# pylint: skip-file
#
# Test fairness of cancelling a task
# That tasks which continuously cancel each other don't take over the scheduler
import asyncio


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())
27 changes: 27 additions & 0 deletions tests/asyncio/asyncio_cancel_fair.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# SPDX-FileCopyrightText: 2019 Damien P. George
#
# SPDX-License-Identifier: MIT
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
38 changes: 38 additions & 0 deletions tests/asyncio/asyncio_cancel_fair2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# SPDX-FileCopyrightText: 2019 Damien P. George
#
# SPDX-License-Identifier: MIT
#
# MicroPython uasyncio module
# MIT license; Copyright (c) 2019 Damien P. George
#
# pylint: skip-file
#
# Test fairness of cancelling a task
# That tasks which keeps being cancelled by multiple other tasks gets a chance to run
import asyncio


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())
11 changes: 11 additions & 0 deletions tests/asyncio/asyncio_cancel_fair2.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: 2019 Damien P. George
#
# SPDX-License-Identifier: MIT
sleep a
sleep b 0
sleep b 1
sleep b 2
cancelled a
done b 0
done b 1
done b 2
32 changes: 32 additions & 0 deletions tests/asyncio/asyncio_cancel_self.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# SPDX-FileCopyrightText: 2019 Damien P. George
#
# SPDX-License-Identifier: MIT
#
# MicroPython uasyncio module
# MIT license; Copyright (c) 2019 Damien P. George
#
# pylint: skip-file
#
# Test a task cancelling itself (currently unsupported)
import asyncio


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)
5 changes: 5 additions & 0 deletions tests/asyncio/asyncio_cancel_self.py.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: 2019 Damien P. George
#
# SPDX-License-Identifier: MIT
task start
can't cancel self
Loading