diff --git a/.github/workflows/behave_next_python.yml b/.github/workflows/behave_next_python.yml deleted file mode 100644 index 9e311271..00000000 --- a/.github/workflows/behave_next_python.yml +++ /dev/null @@ -1,84 +0,0 @@ ---- -name: Run behave with unsupported Python versions - -on: - push: - branches: - - '**' - pull_request: - branches: - - main - - develop - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -jobs: - behave_next_python: - name: Run Behave - runs-on: ubuntu-latest - continue-on-error: true - strategy: - max-parallel: 4 - matrix: - python-version: ['3.13'] - - steps: - - name: Check out the code - uses: actions/checkout@v4 - - - name: Set up Docker - uses: docker/setup-buildx-action@v3 - - - name: Install Docker Compose - run: | - sudo apt-get update - sudo apt-get install -y docker-compose make - - - name: Check Docker state (pre-build) - run: docker ps - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_HUB_PULL_AUTH_USER }} - password: ${{ secrets.DOCKER_HUB_PULL_AUTH_PAT }} - - - name: Build Docker images - run: make build - env: - PYTHON_IMAGE_VER: "${{ matrix.python-version }}" - - - name: Migrate Database - run: | - make migrate || echo "::warning:: migrate failed on future Python version ${{ matrix.python-version }}." - - - name: Run Application - run: | - make run || echo "::warning:: run failed on future Python version ${{ matrix.python-version }}." - - - name: Check Docker state (pre-test) - run: docker ps - - - name: Run pytest + behave with Coverage - env: - POSTGRES_USER: scram - POSTGRES_DB: test_scram - run: | - make coverage.xml || echo "::warning:: pytest + behave failed on future Python version ${{ matrix.python-version }}." - - - name: Dump docker logs on failure - if: failure() - uses: jwalton/gh-docker-logs@v2 - - - name: Check Docker state (post-test) - if: always() - run: docker ps - - - name: Stop Services - if: always() - run: make stop - - - name: Clean Up - if: always() - run: make clean diff --git a/.github/workflows/coverage-finish.yml b/.github/workflows/coverage-finish.yml deleted file mode 100644 index bf626561..00000000 --- a/.github/workflows/coverage-finish.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: Finish Coverage - -on: - workflow_run: - workflows: ["Run pytest", "Run behave"] - types: - - completed - -jobs: - finish: - runs-on: ubuntu-latest - permissions: - contents: read - needs: [behave, pytest] - steps: - - name: Finish Coveralls - uses: coverallsapp/github-action@v2 - with: - parallel-finished: true - fail-on-error: false diff --git a/.github/workflows/behave.yml b/.github/workflows/django.yml similarity index 55% rename from .github/workflows/behave.yml rename to .github/workflows/django.yml index 2cdb52b7..7a0bd69a 100644 --- a/.github/workflows/behave.yml +++ b/.github/workflows/django.yml @@ -1,26 +1,29 @@ --- -name: Run behave +name: Run Django Tests on: push: branches: - - "**" + - main pull_request: branches: - - main - - develop + - '**' # Allows you to run this workflow manually from the Actions tab workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: write + checks: write jobs: - behave: - name: Run Behave + django: + name: Run Django Tests runs-on: ubuntu-latest - strategy: - max-parallel: 4 - matrix: - python-version: ["3.11", "3.12"] steps: - name: Check out the code @@ -29,27 +32,24 @@ jobs: - name: Set up Docker uses: docker/setup-buildx-action@v3 - - name: Install Docker Compose - run: | - sudo apt-get update - sudo apt-get install -y docker-compose make - - - name: Check Docker state (pre-build) - run: docker ps - - name: Login to Docker Hub + if: ${{ !env.ACT }} uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_HUB_PULL_AUTH_USER }} password: ${{ secrets.DOCKER_HUB_PULL_AUTH_PAT }} + - name: Check Docker state (pre-build) + run: docker ps + - name: Build Docker images run: make build - env: - PYTHON_IMAGE_VER: "${{ matrix.python-version }}" + + - name: Check for missing migrations + run: docker compose run --rm django python manage.py makemigrations --check - name: Migrate Database - run: make migrate + run: docker compose run --rm django python manage.py migrate --fake-initial --noinput -v 2 - name: Run Application run: make run @@ -57,48 +57,54 @@ jobs: - name: Check Docker state (pre-test) run: docker ps - - name: Run pytest + behave with Coverage + - name: Run Django Pytest + env: + POSTGRES_USER: scram + POSTGRES_DB: test_scram + run: make pytest-django + + - name: Run Django Behave (Acceptance Tests) + env: + POSTGRES_USER: scram + POSTGRES_DB: test_scram + run: make behave-django + + - name: Run Django Integration Tests env: POSTGRES_USER: scram POSTGRES_DB: test_scram - run: make coverage.xml + run: make integration-django + + - name: Generate Coverage Report + run: | + docker compose run --rm -w /app django coverage report + docker compose run --rm -w /app django coverage xml - name: Dump docker logs on failure if: failure() uses: jwalton/gh-docker-logs@v2 - name: Upload Coverage to Coveralls - if: matrix.python-version == '3.12' + if: ${{ !env.ACT }} uses: coverallsapp/github-action@v2 with: - parallel: true - flag-name: behave - fail-on-error: false + fail-on-error: false - name: Upload Coverage to GitHub - if: matrix.python-version == '3.12' + if: ${{ !env.ACT }} uses: actions/upload-artifact@v4 with: name: coverage-report path: django/coverage.xml - name: Display Coverage Metrics - if: matrix.python-version == '3.12' + if: ${{ !env.ACT }} uses: 5monkeys/cobertura-action@v14 with: - minimum_coverage: "50" - report_name: "Django Pytest/Behave Coverage" + minimum_coverage: "70" + report_name: "Django Coverage" path: django/coverage.xml - - name: Check Docker state (post-test) if: always() run: docker ps - - - name: Stop Services - if: always() - run: make stop - - - name: Clean Up - if: always() - run: make clean diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml deleted file mode 100644 index 7148d8d2..00000000 --- a/.github/workflows/pytest.yml +++ /dev/null @@ -1,110 +0,0 @@ ---- -name: Run pytest - -on: - push: - branches: - - '**' - pull_request: - branches: - - main - - develop - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -jobs: - pytest: - name: Run Pytest - runs-on: ubuntu-latest - strategy: - max-parallel: 4 - matrix: - python-version: ['3.11', '3.12'] - - services: - postgres: - image: postgres:latest - env: - POSTGRES_USER: scram - POSTGRES_PASSWORD: '' - POSTGRES_DB: test_scram_${{ matrix.python-version }} - POSTGRES_HOST_AUTH_METHOD: trust - ports: - - 5432:5432 - options: >- - --health-cmd "pg_isready -U scram" - --health-interval 10s - --health-timeout 5s - --health-retries 5 - - redis: - image: redis:8.2.2 - ports: - - 6379:6379 - - steps: - - name: Check out the code - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_HUB_PULL_AUTH_USER }} - password: ${{ secrets.DOCKER_HUB_PULL_AUTH_PAT }} - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python -m pip install uv pytest-github-actions-annotate-failures - uv pip install --system -r django/requirements/local.txt --prerelease=allow - - - name: Apply migrations - env: - DATABASE_URL: "postgres://scram:@localhost:5432/test_scram_${{ matrix.python-version }}" - run: | - cd django/src - python manage.py makemigrations --noinput - python manage.py migrate --noinput - - - name: Check for missing migrations - env: - DATABASE_URL: "postgres://scram:@localhost:5432/test_scram_${{ matrix.python-version }}" - run: cd django/src && python manage.py makemigrations --check - - - name: Run Pytest - env: - DATABASE_URL: "postgres://scram:@localhost:5432/test_scram_${{ matrix.python-version }}" - REDIS_HOST: "localhost" - run: cd django/src && pytest - - - name: Install Scheduler Dependencies - run: | - cd scheduler - uv sync - - - name: Run Scheduler Tests - run: | - cd scheduler - uv run pytest - - - name: Upload Coverage to Coveralls - if: matrix.python-version == '3.12' - uses: coverallsapp/github-action@v2 - with: - file: ./scheduler/coverage.xml - parallel: true - flag-name: scheduler - fail-on-error: false - - - name: Display Scheduler Coverage Metrics for scheduler tests - if: matrix.python-version == '3.12' - uses: 5monkeys/cobertura-action@v14 - with: - report_name: "Pytest Celery Scheduler Coverage" - path: ./scheduler/coverage.xml - minimum_coverage: "80" diff --git a/.github/workflows/pytest_next_python.yml b/.github/workflows/pytest_next_python.yml deleted file mode 100644 index 59c7865b..00000000 --- a/.github/workflows/pytest_next_python.yml +++ /dev/null @@ -1,85 +0,0 @@ ---- -name: Run pytest with unsupported Python versions - -on: - push: - branches: - - '**' - pull_request: - branches: - - main - - develop - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -jobs: - pytest_next_python: - name: Run Pytest - runs-on: ubuntu-latest - continue-on-error: true - strategy: - max-parallel: 4 - matrix: - python-version: ['3.13'] - - services: - postgres: - image: postgres:latest - env: - POSTGRES_USER: scram - POSTGRES_PASSWORD: '' - POSTGRES_DB: test_scram - POSTGRES_HOST_AUTH_METHOD: trust - ports: - - 5432:5432 - options: >- - --health-cmd "pg_isready -U scram" - --health-interval 10s - --health-timeout 5s - --health-retries 5 - - redis: - image: redis:8.2.2 - ports: - - 6379:6379 - - steps: - - name: Check out the code - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python -m pip install uv - uv pip install --system -r django/requirements/local.txt --prerelease=allow - # https://github.com/pytest-dev/pytest-github-actions-annotate-failures/pull/68 isn't yet in a release - uv pip install --system git+https://github.com/pytest-dev/pytest-github-actions-annotate-failures.git@6e66cd895fe05cd09be8bad58f5d79110a20385f - - - name: Apply unapplied migrations - env: - DATABASE_URL: "postgres://scram:@localhost:5432/test_scram" - run: | - cd django/src - python manage.py makemigrations --noinput || true - python manage.py migrate --fake-initial --noinput -v 2 - - - name: Check for duplicate migrations - run: | - cd django/src - if python manage.py makemigrations --dry-run | grep "No changes detected"; then - echo "No duplicate migrations detected." - else - echo "Warning: Potential duplicate migrations detected. Please review." - fi - - - name: Run Pytest - env: - DATABASE_URL: "postgres://scram:@localhost:5432/test_scram" - REDIS_HOST: "localhost" - run: | - cd django/src && pytest || echo "::warning:: Failed on future Python version ${{ matrix.python-version }}." diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml index 9747c6d6..a7a15b84 100644 --- a/.github/workflows/ruff.yml +++ b/.github/workflows/ruff.yml @@ -1,17 +1,23 @@ +--- name: Run ruff on: push: branches: - - '**' + - main pull_request: branches: - - main - - develop + - '**' # Allows you to run this workflow manually from the Actions tab workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read jobs: ruff: runs-on: ubuntu-latest @@ -19,11 +25,14 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Install dependencies - run: pip install ruff==0.14.14 - - - name: Fail if we have any style errors - run: ruff check --output-format=github + - name: Run ruff check + uses: astral-sh/ruff-action@v3 + with: + version: "0.15.12" + args: check --output-format=github - - name: Fail if the code is not formatted correctly (like Black) - run: ruff format --diff + - name: Run ruff format check + uses: astral-sh/ruff-action@v3 + with: + version: "0.15.12" + args: format --diff diff --git a/.github/workflows/scheduler.yml b/.github/workflows/scheduler.yml new file mode 100644 index 00000000..ed6ca43f --- /dev/null +++ b/.github/workflows/scheduler.yml @@ -0,0 +1,51 @@ +--- +name: Run Scheduler Tests + +on: + push: + branches: + - main + pull_request: + branches: + - '**' + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: write + checks: write + +jobs: + scheduler: + name: Run Scheduler Tests + runs-on: ubuntu-latest + + steps: + - name: Check out the code + uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v5 + + - name: Run Scheduler Tests + run: make test-scheduler + + - name: Upload Coverage to Coveralls + if: ${{ !env.ACT }} + uses: coverallsapp/github-action@v2 + with: + file: ./scheduler/coverage.xml + + - name: Display Scheduler Coverage Metrics + if: ${{ !env.ACT }} + uses: 5monkeys/cobertura-action@v14 + with: + report_name: "Scheduler Coverage" + path: ./scheduler/coverage.xml + minimum_coverage: "80" diff --git a/.github/workflows/scripts.yml b/.github/workflows/scripts.yml new file mode 100644 index 00000000..919a8b11 --- /dev/null +++ b/.github/workflows/scripts.yml @@ -0,0 +1,52 @@ +--- +name: Run Scripts Tests + +on: + push: + branches: + - main + pull_request: + branches: + - '**' + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: write + checks: write + +jobs: + scripts: + name: Run Scripts Tests + runs-on: ubuntu-latest + + steps: + - name: Check out the code + uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v5 + + - name: Run Scripts Tests + run: make test-scripts + + - name: Upload Coverage to Coveralls + if: ${{ !env.ACT }} + uses: coverallsapp/github-action@v2 + with: + file: ./scripts/coverage.xml + fail-on-error: false + + - name: Display Scripts Coverage Metrics + if: ${{ !env.ACT }} + uses: 5monkeys/cobertura-action@v14 + with: + report_name: "Scripts Coverage" + path: ./scripts/coverage.xml + minimum_coverage: "50" diff --git a/.github/workflows/translator.yml b/.github/workflows/translator.yml new file mode 100644 index 00000000..6118ff73 --- /dev/null +++ b/.github/workflows/translator.yml @@ -0,0 +1,84 @@ +--- +name: Run Translator Tests + +on: + push: + branches: + - main + pull_request: + branches: + - '**' + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + pull-requests: write + checks: write +jobs: + translator: + name: Run Translator Tests + runs-on: ubuntu-latest + + steps: + - name: Check out the code + uses: actions/checkout@v4 + + - name: Set up Docker + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + if: ${{ !env.ACT }} + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_PULL_AUTH_USER }} + password: ${{ secrets.DOCKER_HUB_PULL_AUTH_PAT }} + + - name: Check Docker state (pre-build) + run: docker ps + + - name: Build Docker images + run: make build + + - name: Migrate Database + run: make migrate + + - name: Run Application + run: make run + + - name: Check Docker state (pre-test) + run: docker ps + + - name: Run Translator Behave Tests + run: make behave-translator + + - name: Copy Coverage Report + run: docker compose cp translator:/app/coverage.xml ./translator/coverage.xml + + - name: Dump docker logs on failure + if: failure() + uses: jwalton/gh-docker-logs@v2 + + - name: Upload Coverage to Coveralls + if: ${{ !env.ACT }} + uses: coverallsapp/github-action@v2 + with: + file: ./translator/coverage.xml + fail-on-error: false + + - name: Display Translator Coverage Metrics + if: ${{ !env.ACT }} + uses: 5monkeys/cobertura-action@v14 + with: + report_name: "Translator Coverage" + path: ./translator/coverage.xml + minimum_coverage: "80" + + - name: Check Docker state (post-test) + if: always() + run: docker ps diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e5572b1c..14e58844 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,4 @@ -exclude: 'docs|migrations|.git|.tox' +exclude: 'docs|migrations|^\.git/|\.tox' default_stages: [pre-commit] fail_fast: true @@ -25,6 +25,11 @@ repos: pass_filenames: false always_run: true + - repo: https://github.com/rhysd/actionlint + rev: v1.7.12 + hooks: + - id: actionlint + - repo: https://github.com/astral-sh/uv-pre-commit rev: 0.11.8 hooks: diff --git a/Makefile b/Makefile index 75501f61..368c6fcf 100644 --- a/Makefile +++ b/Makefile @@ -2,46 +2,30 @@ PYTHON_IMAGE_VER ?= 3.12 POSTGRES_IMAGE_VER ?= 18 -.DEFAULT_GOAL := help - -## toggle-prod: configure make to use the production stack -.Phony: toggle-prod -toggle-prod: - @ln -sf compose.override.production.yml compose.override.yml +ACT := act --rm --container-options "--privileged -u root" --container-architecture linux/amd64 --platform ubuntu-latest=catthehacker/ubuntu:act-latest -## toggle-local: configure make to use the local stack -.Phony: toggle-local -toggle-local: - @ln -sf compose.override.local.yml compose.override.yml - -# Since toggle-(local|prod) are phony targets, this file is not -# tracked to compare if its "newer" so running another target with -# this as a prereq will not run this target again. That would -# overwrite compose.override.yml back to compose.override.local.yml no -# matter what, which is bad. Phony targets prevents this -## compose.override.yml: creates file compose.override.yml on first run (as a prereq) -compose.override.yml: - @ln -sf compose.override.local.yml compose.override.yml +.DEFAULT_GOAL := help -## behave-all: runs behave inside the containers against all of your features -.Phony: behave-all -behave-all: compose.override.yml +## behave-django: runs behave inside the django containers against all of your features. +.Phony: behave-django +behave-django: compose.override.yml @docker compose run --rm -w /app -e PYTHONPATH=/app/src django coverage run -a src/manage.py behave --no-input --simple -## behave: runs behave inside the containers against a specific feature (append FEATURE=feature_name_here) -.Phony: behave -behave: compose.override.yml +## behave-django-feature: runs a single django behave feature (append FEATURE=feature_name_here) +.Phony: behave-django-feature +behave-django-feature: compose.override.yml @docker compose run --rm -w /app -e PYTHONPATH=/app/src django python src/manage.py behave --no-input --simple -i $(FEATURE) -## integration-tests: runs multi-instance system tests against docker compose running containers -.Phony: integration-tests -integration-tests: run - @docker compose exec -T -w /app -e PYTHONPATH=/app/src django coverage run -a src/manage.py behave --no-input --use-existing-database src/scram/route_manager/tests/integration - -## behave-translator +## behave-translator: runs translator behave tests with coverage .Phony: behave-translator behave-translator: compose.override.yml - @docker compose exec -T translator behave /app/tests/acceptance/features + @docker compose exec -T translator coverage run --source=translator -m behave /app/tests/acceptance/features + @docker compose exec -T translator coverage xml -o /app/coverage.xml + +## behave-translator-feature: runs a single translator behave feature (append FEATURE=feature_name_here) +.Phony: behave-translator-feature +behave-translator-feature: compose.override.yml + @docker compose exec -T translator python -m behave /app/tests/acceptance/features -i $(FEATURE) ## build: rebuilds all your containers or a single one if CONTAINER is specified .Phony: build @@ -50,14 +34,15 @@ build: compose.override.yml @docker compose up -d --no-deps $(CONTAINER) @docker compose restart $(CONTAINER) -## coverage.xml: generate coverage from test runs -coverage.xml: pytest behave-all integration-tests behave-translator - @docker compose run --rm -w /app django coverage report - @docker compose run --rm -w /app django coverage xml - -## ci-test: runs all tests just like Github CI does +## ci-test: runs all CI workflows locally via act; requires act (`brew install act`) .Phony: ci-test -ci-test: | toggle-local build migrate run coverage.xml +ci-test: + @$(ACT) push --workflows .github/workflows/ruff.yml + @$(ACT) push --workflows .github/workflows/scripts.yml + @$(ACT) push --workflows .github/workflows/scheduler.yml + @$(ACT) push --workflows .github/workflows/translator.yml + @$(ACT) push --workflows .github/workflows/django.yml +# @$(ACT) push --workflows .github/workflows/type-check.yml ## clean: remove local containers and volumes .Phony: clean @@ -65,25 +50,57 @@ clean: compose.override.yml @docker compose rm -f -s @docker volume prune -f -## collect-static: run collect static admin command +## collectstatic: run collect static admin command .Phony: collectstatic collectstatic: compose.override.yml @docker compose run --rm django python manage.py collectstatic +# Since toggle-(local|prod) are phony targets, this file is not +# tracked to compare if its "newer" so running another target with +# this as a prereq will not run this target again. That would +# overwrite compose.override.yml back to compose.override.local.yml no +# matter what, which is bad. Phony targets prevents this +## compose.override.yml: creates file compose.override.yml on first run (as a prereq) +compose.override.yml: + @ln -sf compose.override.local.yml compose.override.yml + +## copy-libs: copy the translator autogenerated libraries into the translator directory +.Phony: copy-libs +copy-libs: + @docker compose cp translator:/app/gobgp_pb2.py translator/ + @docker compose cp translator:/app/gobgp_pb2.pyi translator/ + @docker compose cp translator:/app/gobgp_pb2_grpc.py translator/ + @docker compose cp translator:/app/attribute_pb2.py translator/ + @docker compose cp translator:/app/attribute_pb2.pyi translator/ + @docker compose cp translator:/app/attribute_pb2_grpc.py translator/ + @docker compose cp translator:/app/capability_pb2.py translator/ + @docker compose cp translator:/app/capability_pb2.pyi translator/ + @docker compose cp translator:/app/capability_pb2_grpc.py translator/ + ## django-addr: get the IP and ephemeral port assigned to docker:8000 .Phony: django-addr django-addr: compose.override.yml @docker compose port django 8000 +## django-open: open a browser for http://$(make django-addr) +.Phony: django-open +django-open: compose.override.yml + @open http://$$(make django-addr) + ## django-url: get the URL based on http://$(make django-addr) .Phony: django-url django-url: compose.override.yml @echo http://$$(make django-addr) -## django-open: open a browser for http://$(make django-addr) -.Phony: django-open -django-open: compose.override.yml - @open http://$$(make django-addr) +## docs-build: build the documentation +.Phony: docs-build +docs-build: + @docker compose run --rm docs mkdocs build + +## docs-serve: build and run a server with the documentation +.Phony: docs-serve +docs-serve: + @docker compose run --rm docs mkdocs serve -a 0.0.0.0:8888 ## down: turn down docker compose stack .Phony: down @@ -106,7 +123,12 @@ gobgp-neighbor: compose.override.yml help: Makefile @sed -n 's/^##//p' $< -# TODO: When we move to flowspec this -a flag with change +## integration-django: runs multi-instance system tests against docker compose running containers +.Phony: integration-django +integration-django: run + @docker compose exec -T -w /app -e PYTHONPATH=/app/src django coverage run -a src/manage.py behave --no-input --use-existing-database src/scram/route_manager/tests/integration + +# TODO: When we move to flowspec this -a flag will change ## list-routes: list gobgp routes .Phony: list-routes list-routes: compose.override.yml @@ -124,26 +146,16 @@ migrate: compose.override.yml pass-reset: compose.override.yml @docker compose run --rm django python manage.py changepassword admin -## pytest: runs pytest inside the containers -.Phony: pytest -pytest: compose.override.yml +## pytest-django: runs pytest inside the django container +.Phony: pytest-django +pytest-django: compose.override.yml @docker compose run --rm -w /app -e PYTHONPATH=/app/src django coverage run -m pytest -## pytest-scheduler: runs scheduler package tests with coverage -.Phony: pytest-scheduler -pytest-scheduler: - @cd scheduler && uv run pytest - ## run: brings up the containers as described in compose.override.yml .Phony: run run: compose.override.yml @docker compose up -d -## pytest-scheduler: runs scheduler package tests with coverage -.Phony: pytest-scripts -pytest-scripts: - @cd scripts && uv run pytest tests/ - ## stop: turns off running containers .Phony: stop stop: compose.override.yml @@ -154,34 +166,45 @@ stop: compose.override.yml tail-log: compose.override.yml @docker compose logs -f $(CONTAINER) +## test: run all tests (django + translator + scheduler + scripts) +.Phony: test +test: test-django test-translator test-scheduler test-scripts + +## test-django: start everything and then run all django tests (pytest + behave + integration) generating coverage +.Phony: test-django +test-django: toggle-local build migrate run pytest-django behave-django integration-django + @docker compose run --rm -w /app django coverage report + @docker compose run --rm -w /app django coverage xml + +## test-scheduler: runs scheduler package tests with coverage +.Phony: test-scheduler +test-scheduler: + @cd scheduler && uv run pytest + +## test-scripts: runs scripts package tests with coverage +.Phony: test-scripts +test-scripts: + @cd scripts && uv run pytest tests/ + +## test-translator: start everything and run translator behave tests with coverage +.Phony: test-translator +test-translator: toggle-local build migrate run behave-translator + +## toggle-local: configure make to use the local stack +.Phony: toggle-local +toggle-local: + @ln -sf compose.override.local.yml compose.override.yml + +## toggle-prod: configure make to use the production stack +.Phony: toggle-prod +toggle-prod: + @ln -sf compose.override.production.yml compose.override.yml + ## type-check: static type checking .Phony: type-check type-check: compose.override.yml @docker compose run --rm -w /app -e PYTHONPATH=/app/src django mypy src/scram -## docs-build: build the documentation -.Phony: docs-build -docs-build: - @docker compose run --rm docs mkdocs build - -## docs-serve: build and run a server with the documentation -.Phony: docs-serve -docs-serve: - @docker compose run --rm docs mkdocs serve -a 0.0.0.0:8888 - -## copy-libs: copy the translator autogenerated libraries into the translator directory -.Phony: copy-libs -copy-libs: - @docker compose cp translator:/app/gobgp_pb2.py translator/ - @docker compose cp translator:/app/gobgp_pb2.pyi translator/ - @docker compose cp translator:/app/gobgp_pb2_grpc.py translator/ - @docker compose cp translator:/app/attribute_pb2.py translator/ - @docker compose cp translator:/app/attribute_pb2.pyi translator/ - @docker compose cp translator:/app/attribute_pb2_grpc.py translator/ - @docker compose cp translator:/app/capability_pb2.py translator/ - @docker compose cp translator:/app/capability_pb2.pyi translator/ - @docker compose cp translator:/app/capability_pb2_grpc.py translator/ - ## update-env-docs: update environment variable documentation append CHECK=true to get a diff if not up to date .Phony: update-env-docs update-env-docs: diff --git a/docs/development_guide.md b/docs/development_guide.md index 38b6d5a4..87bfa63c 100644 --- a/docs/development_guide.md +++ b/docs/development_guide.md @@ -58,6 +58,7 @@ You will need to create and authorize a client before you can make any API calls ```python import uuid + print(str(uuid.uuid4())) ``` diff --git a/uv.lock b/uv.lock index cc4b2ba3..ba472e43 100644 --- a/uv.lock +++ b/uv.lock @@ -1128,21 +1128,19 @@ wheels = [ [[package]] name = "tornado" -version = "6.5.4" +version = "6.5.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/37/1d/0a336abf618272d53f62ebe274f712e213f5a03c0b2339575430b8362ef2/tornado-6.5.4.tar.gz", hash = "sha256:a22fa9047405d03260b483980635f0b041989d8bcc9a313f8fe18b411d84b1d7", size = 513632, upload-time = "2025-12-15T19:21:03.836Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/f1/3173dfa4a18db4a9b03e5d55325559dab51ee653763bb8745a75af491286/tornado-6.5.5.tar.gz", hash = "sha256:192b8f3ea91bd7f1f50c06955416ed76c6b72f96779b962f07f911b91e8d30e9", size = 516006, upload-time = "2026-03-10T21:31:02.067Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ab/a9/e94a9d5224107d7ce3cc1fab8d5dc97f5ea351ccc6322ee4fb661da94e35/tornado-6.5.4-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d6241c1a16b1c9e4cc28148b1cda97dd1c6cb4fb7068ac1bedc610768dff0ba9", size = 443909, upload-time = "2025-12-15T19:20:48.382Z" }, - { url = "https://files.pythonhosted.org/packages/db/7e/f7b8d8c4453f305a51f80dbb49014257bb7d28ccb4bbb8dd328ea995ecad/tornado-6.5.4-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2d50f63dda1d2cac3ae1fa23d254e16b5e38153758470e9956cbc3d813d40843", size = 442163, upload-time = "2025-12-15T19:20:49.791Z" }, - { url = "https://files.pythonhosted.org/packages/ba/b5/206f82d51e1bfa940ba366a8d2f83904b15942c45a78dd978b599870ab44/tornado-6.5.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1cf66105dc6acb5af613c054955b8137e34a03698aa53272dbda4afe252be17", size = 445746, upload-time = "2025-12-15T19:20:51.491Z" }, - { url = "https://files.pythonhosted.org/packages/8e/9d/1a3338e0bd30ada6ad4356c13a0a6c35fbc859063fa7eddb309183364ac1/tornado-6.5.4-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50ff0a58b0dc97939d29da29cd624da010e7f804746621c78d14b80238669335", size = 445083, upload-time = "2025-12-15T19:20:52.778Z" }, - { url = "https://files.pythonhosted.org/packages/50/d4/e51d52047e7eb9a582da59f32125d17c0482d065afd5d3bc435ff2120dc5/tornado-6.5.4-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5fb5e04efa54cf0baabdd10061eb4148e0be137166146fff835745f59ab9f7f", size = 445315, upload-time = "2025-12-15T19:20:53.996Z" }, - { url = "https://files.pythonhosted.org/packages/27/07/2273972f69ca63dbc139694a3fc4684edec3ea3f9efabf77ed32483b875c/tornado-6.5.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9c86b1643b33a4cd415f8d0fe53045f913bf07b4a3ef646b735a6a86047dda84", size = 446003, upload-time = "2025-12-15T19:20:56.101Z" }, - { url = "https://files.pythonhosted.org/packages/d1/83/41c52e47502bf7260044413b6770d1a48dda2f0246f95ee1384a3cd9c44a/tornado-6.5.4-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:6eb82872335a53dd063a4f10917b3efd28270b56a33db69009606a0312660a6f", size = 445412, upload-time = "2025-12-15T19:20:57.398Z" }, - { url = "https://files.pythonhosted.org/packages/10/c7/bc96917f06cbee182d44735d4ecde9c432e25b84f4c2086143013e7b9e52/tornado-6.5.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6076d5dda368c9328ff41ab5d9dd3608e695e8225d1cd0fd1e006f05da3635a8", size = 445392, upload-time = "2025-12-15T19:20:58.692Z" }, - { url = "https://files.pythonhosted.org/packages/0c/1a/d7592328d037d36f2d2462f4bc1fbb383eec9278bc786c1b111cbbd44cfa/tornado-6.5.4-cp39-abi3-win32.whl", hash = "sha256:1768110f2411d5cd281bac0a090f707223ce77fd110424361092859e089b38d1", size = 446481, upload-time = "2025-12-15T19:21:00.008Z" }, - { url = "https://files.pythonhosted.org/packages/d6/6d/c69be695a0a64fd37a97db12355a035a6d90f79067a3cf936ec2b1dc38cd/tornado-6.5.4-cp39-abi3-win_amd64.whl", hash = "sha256:fa07d31e0cd85c60713f2b995da613588aa03e1303d75705dca6af8babc18ddc", size = 446886, upload-time = "2025-12-15T19:21:01.287Z" }, - { url = "https://files.pythonhosted.org/packages/50/49/8dc3fd90902f70084bd2cd059d576ddb4f8bb44c2c7c0e33a11422acb17e/tornado-6.5.4-cp39-abi3-win_arm64.whl", hash = "sha256:053e6e16701eb6cbe641f308f4c1a9541f91b6261991160391bfc342e8a551a1", size = 445910, upload-time = "2025-12-15T19:21:02.571Z" }, + { url = "https://files.pythonhosted.org/packages/59/8c/77f5097695f4dd8255ecbd08b2a1ed8ba8b953d337804dd7080f199e12bf/tornado-6.5.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:487dc9cc380e29f58c7ab88f9e27cdeef04b2140862e5076a66fb6bb68bb1bfa", size = 445983, upload-time = "2026-03-10T21:30:44.28Z" }, + { url = "https://files.pythonhosted.org/packages/ab/5e/7625b76cd10f98f1516c36ce0346de62061156352353ef2da44e5c21523c/tornado-6.5.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65a7f1d46d4bb41df1ac99f5fcb685fb25c7e61613742d5108b010975a9a6521", size = 444246, upload-time = "2026-03-10T21:30:46.571Z" }, + { url = "https://files.pythonhosted.org/packages/b2/04/7b5705d5b3c0fab088f434f9c83edac1573830ca49ccf29fb83bf7178eec/tornado-6.5.5-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e74c92e8e65086b338fd56333fb9a68b9f6f2fe7ad532645a290a464bcf46be5", size = 447229, upload-time = "2026-03-10T21:30:48.273Z" }, + { url = "https://files.pythonhosted.org/packages/34/01/74e034a30ef59afb4097ef8659515e96a39d910b712a89af76f5e4e1f93c/tornado-6.5.5-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:435319e9e340276428bbdb4e7fa732c2d399386d1de5686cb331ec8eee754f07", size = 448192, upload-time = "2026-03-10T21:30:51.22Z" }, + { url = "https://files.pythonhosted.org/packages/be/00/fe9e02c5a96429fce1a1d15a517f5d8444f9c412e0bb9eadfbe3b0fc55bf/tornado-6.5.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3f54aa540bdbfee7b9eb268ead60e7d199de5021facd276819c193c0fb28ea4e", size = 448039, upload-time = "2026-03-10T21:30:53.52Z" }, + { url = "https://files.pythonhosted.org/packages/82/9e/656ee4cec0398b1d18d0f1eb6372c41c6b889722641d84948351ae19556d/tornado-6.5.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:36abed1754faeb80fbd6e64db2758091e1320f6bba74a4cf8c09cd18ccce8aca", size = 447445, upload-time = "2026-03-10T21:30:55.541Z" }, + { url = "https://files.pythonhosted.org/packages/5a/76/4921c00511f88af86a33de770d64141170f1cfd9c00311aea689949e274e/tornado-6.5.5-cp39-abi3-win32.whl", hash = "sha256:dd3eafaaeec1c7f2f8fdcd5f964e8907ad788fe8a5a32c4426fbbdda621223b7", size = 448582, upload-time = "2026-03-10T21:30:57.142Z" }, + { url = "https://files.pythonhosted.org/packages/2c/23/f6c6112a04d28eed765e374435fb1a9198f73e1ec4b4024184f21faeb1ad/tornado-6.5.5-cp39-abi3-win_amd64.whl", hash = "sha256:6443a794ba961a9f619b1ae926a2e900ac20c34483eea67be4ed8f1e58d3ef7b", size = 448990, upload-time = "2026-03-10T21:30:58.857Z" }, + { url = "https://files.pythonhosted.org/packages/b7/c8/876602cbc96469911f0939f703453c1157b0c826ecb05bdd32e023397d4e/tornado-6.5.5-cp39-abi3-win_arm64.whl", hash = "sha256:2c9a876e094109333f888539ddb2de4361743e5d21eece20688e3e351e4990a6", size = 448016, upload-time = "2026-03-10T21:31:00.43Z" }, ] [[package]]