odoo_mqtt/.github/workflows/iot-bridge-test.yml
matthias.lotz fdddba7469 Phase 1: Foundation & Quality Tools
Implemented comprehensive development infrastructure:

1.1 Code Quality Tools:
- Created pyproject.toml with configurations for:
  * Black (code formatter, line-length=100)
  * isort (import sorter, black profile)
  * mypy (type checker, lenient settings for gradual adoption)
  * pytest (test runner with coverage)
  * ruff (modern linter replacing flake8/pylint)
  * bandit (security scanner)
- Added .pre-commit-config.yaml with:
  * File hygiene hooks (trailing whitespace, EOF, YAML/JSON checks)
  * Code formatting (black, isort, ruff)
  * Security checks (bandit)
- Created requirements-dev.txt for development dependencies
- Added .gitignore for Python projects

1.2 Test Infrastructure:
- Created tests/conftest.py with shared fixtures:
  * Config fixtures (mqtt_config, odoo_config, bridge_config, etc.)
  * MQTT client mocks (mock_mqtt_client, mock_paho_mqtt_client)
  * Odoo client mocks (mock_odoo_client, mock_requests)
  * Device/parser fixtures (shelly_pm_message, mock_parser)
  * Session detector & event queue fixtures
- Created tests/helpers.py with test utilities:
  * assert_event_valid, assert_mqtt_topic_valid
  * create_mock_mqtt_message
  * wait_for_condition helper
- Created tests/fixtures/ with specialized fixtures:
  * mqtt_fixtures.py: MQTT message factory, simulated broker
  * config_fixtures.py: Config file factory, minimal/full configs
  * device_fixtures.py: Device events, session events, Shelly payloads

1.3 CI/CD Pipeline:
- Created .github/workflows/iot-bridge-test.yml:
  * Lint job: ruff, black, isort, bandit
  * Type check job: mypy
  * Test job: pytest on Python 3.10, 3.11, 3.12 with coverage
  * Integration test job: with Mosquitto MQTT broker service
  * Docker build test job
  * Quality gate job: ensures all checks pass

Documentation:
- Updated README.md with Development section:
  * Local setup instructions
  * Code quality tools usage
  * Testing commands
  * Updated project structure diagram

Benefits:
- Automated code quality checks via pre-commit hooks
- Comprehensive test fixtures reduce test boilerplate
- CI/CD pipeline catches issues early
- Matrix testing ensures Python 3.10-3.12 compatibility
- Foundation for gradual type safety improvements (Phase 3)

See OPTIMIZATION_PLAN.md Phase 1 for details.
2026-02-18 22:11:25 +01:00

197 lines
5.6 KiB
YAML

name: IoT Bridge - Tests & Quality Checks
on:
push:
branches: [main, develop, iot-bridge]
paths:
- "iot_bridge/**"
- ".github/workflows/iot-bridge-test.yml"
pull_request:
branches: [main, develop]
paths:
- "iot_bridge/**"
defaults:
run:
working-directory: ./iot_bridge
jobs:
# ============================================================================
# Code Quality Checks
# ============================================================================
lint:
name: Lint & Format Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: "pip"
cache-dependency-path: iot_bridge/requirements*.txt
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Run Ruff (linter)
run: ruff check .
- name: Run Black (format check)
run: black --check .
- name: Run isort (import check)
run: isort --check-only .
- name: Run Bandit (security check)
run: bandit -r . -ll
# ============================================================================
# Type Checking
# ============================================================================
typecheck:
name: Type Check (mypy)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: "pip"
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Run mypy
run: mypy . --config-file=pyproject.toml
# ============================================================================
# Unit & Integration Tests
# ============================================================================
test:
name: Tests (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Run unit tests
run: pytest tests/unit -v --cov=. --cov-report=xml --cov-report=term
- name: Upload coverage to Codecov
if: matrix.python-version == '3.10'
uses: codecov/codecov-action@v4
with:
files: ./iot_bridge/coverage.xml
flags: unittests
name: codecov-iot-bridge
# ============================================================================
# Integration Tests (requires services)
# ============================================================================
integration-test:
name: Integration Tests
runs-on: ubuntu-latest
services:
mosquitto:
image: eclipse-mosquitto:2
ports:
- 1883:1883
options: >-
--health-cmd "mosquitto_sub -t '$$SYS/#' -C 1"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: "pip"
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Run integration tests
env:
MQTT_BROKER: localhost
MQTT_PORT: 1883
run: pytest tests/integration -v --cov=. --cov-report=xml
# ============================================================================
# Docker Build Test
# ============================================================================
docker-build:
name: Docker Build Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker image
uses: docker/build-push-action@v5
with:
context: ./iot_bridge
push: false
tags: iot-bridge:test
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Test Docker image
run: |
docker run --rm iot-bridge:test python -c "import main; print('OK')"
# ============================================================================
# Summary Job
# ============================================================================
quality-gate:
name: Quality Gate
runs-on: ubuntu-latest
needs: [lint, typecheck, test, integration-test, docker-build]
if: always()
steps:
- name: Check all jobs passed
run: |
if [[ "${{ needs.lint.result }}" != "success" ]] || \
[[ "${{ needs.typecheck.result }}" != "success" ]] || \
[[ "${{ needs.test.result }}" != "success" ]] || \
[[ "${{ needs.integration-test.result }}" != "success" ]] || \
[[ "${{ needs.docker-build.result }}" != "success" ]]; then
echo "Quality gate failed!"
exit 1
fi
echo "✅ All quality checks passed!"