Skip to content

Commit

Permalink
Merge pull request #53 from kardia-as/add-unit-tests
Browse files Browse the repository at this point in the history
Add unit tests
  • Loading branch information
DamKast authored Jul 2, 2024
2 parents 1d0179e + aa69ef2 commit c7644c4
Show file tree
Hide file tree
Showing 47 changed files with 5,763 additions and 133 deletions.
75 changes: 68 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ name: CI
# yamllint disable-line rule:truthy
on:
push:
pull_request: ~

env:
CACHE_VERSION: 1
DEFAULT_PYTHON: 3.8
PRE_COMMIT_HOME: ~/.cache/pre-commit
CODE_FOLDER: zigpy_zboss
CACHE_VERSION: 3
DEFAULT_PYTHON: 3.10.8
PRE_COMMIT_CACHE_PATH: ~/.cache/pre-commit

jobs:
# Separate job to pre-populate the base dependency cache
Expand All @@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9, "3.10", "3.11"]
python-version: ["3.10.8", "3.11.0", "3.12"]
steps:
- name: Check out code from GitHub
uses: actions/checkout@v2
Expand All @@ -44,6 +44,7 @@ jobs:
python -m venv venv
. venv/bin/activate
pip install -U pip setuptools pre-commit
pip install -r requirements_test.txt
pip install -e .
pre-commit:
Expand Down Expand Up @@ -76,7 +77,7 @@ jobs:
id: cache-precommit
uses: actions/cache@v2
with:
path: ${{ env.PRE_COMMIT_HOME }}
path: ${{ env.PRE_COMMIT_CACHE_PATH }}
key: |
${{ env.CACHE_VERSION}}-${{ runner.os }}-pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
restore-keys: |
Expand All @@ -86,6 +87,15 @@ jobs:
run: |
. venv/bin/activate
pre-commit install-hooks
- name: Cache pre-commit environment
uses: actions/cache/save@v3
with:
path: ${{ env.PRE_COMMIT_CACHE_PATH }}
key: ${{ steps.cache-precommit.outputs.cache-primary-key }}
- name: Lint and static analysis
run: |
. venv/bin/activate
pre-commit run --show-diff-on-failure --color=always --all-files
lint-flake8:
name: Check flake8
Expand Down Expand Up @@ -117,7 +127,7 @@ jobs:
id: cache-precommit
uses: actions/cache@v2
with:
path: ${{ env.PRE_COMMIT_HOME }}
path: ${{ env.PRE_COMMIT_CACHE_PATH }}
key: |
${{ env.CACHE_VERSION}}-${{ runner.os }}-pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
- name: Fail job if cache restore failed
Expand All @@ -132,3 +142,54 @@ jobs:
run: |
. venv/bin/activate
pre-commit run --hook-stage manual flake8 --all-files
pytest:
runs-on: ubuntu-latest
needs: prepare-base
strategy:
matrix:
python-version: ["3.10.8", "3.11.0", "3.12"]
name: >-
Run tests Python ${{ matrix.python-version }}
steps:
- name: Check out code from GitHub
uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
id: python
with:
python-version: ${{ matrix.python-version }}
- name: Restore base Python virtual environment
id: cache-venv
uses: actions/cache@v2
with:
path: venv
key: >-
${{ env.CACHE_VERSION}}-${{ runner.os }}-base-venv-${{
steps.python.outputs.python-version }}-${{
hashFiles('pyproject.toml') }}
- name: Fail job if Python cache restore failed
if: steps.cache-venv.outputs.cache-hit != 'true'
run: |
echo "Failed to restore Python virtual environment from cache"
exit 1
- name: Register Python problem matcher
run: |
echo "::add-matcher::.github/workflows/matchers/python.json"
- name: Install Pytest Annotation plugin
run: |
. venv/bin/activate
# Ideally this should be part of our dependencies
# However this plugin is fairly new and doesn't run correctly
# on a non-GitHub environment.
pip install pytest-github-actions-annotate-failures
- name: Run pytest
run: |
. venv/bin/activate
pytest \
-qq \
--timeout=20 \
--durations=10 \
-o console_output_style=count \
-p no:sugar \
tests
19 changes: 10 additions & 9 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: debug-statements

- repo: https://github.com/pycqa/flake8
rev: 6.0.0
rev: 5.0.4
hooks:
- id: flake8
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0

- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: debug-statements
- id: no-commit-to-branch
args:
- --branch=dev
- --branch=main
- --branch=rc
- id: isort
6 changes: 6 additions & 0 deletions requirements_test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pytest>=7.3.1
pytest-asyncio>=0.21.0
pytest-timeout>=2.1.0
pytest-mock>=3.10.0
pytest-cov>=4.1.0
flake8==5.0.4
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for zigpy-zboss."""
1 change: 1 addition & 0 deletions tests/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for api."""
73 changes: 73 additions & 0 deletions tests/api/test_connect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"""Test cases for zigpy-zboss API connect/close methods."""
import pytest

from zigpy_zboss.api import ZBOSS

from ..conftest import BaseServerZBOSS, config_for_port_path


@pytest.mark.asyncio
async def test_connect_no_test(make_zboss_server):
"""Test that ZBOSS.connect() can connect."""
zboss_server = make_zboss_server(server_cls=BaseServerZBOSS)
zboss = ZBOSS(config_for_port_path(zboss_server.port_path))

await zboss.connect()

# Nothing will be sent
assert zboss_server._uart.data_received.call_count == 0

zboss.close()


@pytest.mark.asyncio
async def test_api_close(connected_zboss, mocker):
"""Test that ZBOSS.close() properly cleans up the object."""
zboss, zboss_server = connected_zboss
uart = zboss._uart
mocker.spy(uart, "close")

# add some dummy listeners, should be cleared on close
zboss._listeners = {
'listener1': [mocker.Mock()], 'listener2': [mocker.Mock()]
}

zboss.close()

# Make sure our UART was actually closed
assert zboss._uart is None
assert zboss._app is None
assert uart.close.call_count == 1

# ZBOSS.close should not throw any errors if called multiple times
zboss.close()
zboss.close()

def dict_minus(d, minus):
return {k: v for k, v in d.items() if k not in minus}

ignored_keys = [
"_blocking_request_lock",
"_reset_uart_reconnect",
"_disconnected_event",
"nvram",
"version"
]

# Closing ZBOSS should reset it completely to that of a fresh object
# We have to ignore our mocked method and the lock
zboss2 = ZBOSS(zboss._config)
assert (
zboss2._blocking_request_lock.locked()
== zboss._blocking_request_lock.locked()
)
assert dict_minus(zboss.__dict__, ignored_keys) == dict_minus(
zboss2.__dict__, ignored_keys
)

zboss2.close()
zboss2.close()

assert dict_minus(zboss.__dict__, ignored_keys) == dict_minus(
zboss2.__dict__, ignored_keys
)
Loading

0 comments on commit c7644c4

Please sign in to comment.