Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add tests for asyncio #58

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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