Skip to content
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
9 changes: 8 additions & 1 deletion .github/workflows/agent-tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,11 @@ jobs:
if-no-files-found: error
retention-days: 2
- name: Run charm integration tests
run: uvx --with tox-uv tox -e integration
run: uvx --with tox-uv tox -e integration -- --juju-dump-logs logs
- name: Upload logs
if: ${{ !cancelled() }}
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: juju-dump-logs
path: agent/charms/testflinger-agent-host-charm/logs
retention-days: 2
9 changes: 8 additions & 1 deletion .github/workflows/server-tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,11 @@ jobs:
if-no-files-found: error
retention-days: 2
- name: Run charm integration tests
run: uvx --with tox-uv tox -e integration
run: uvx --with tox-uv tox -e integration -- --juju-dump-logs logs
- name: Upload logs
if: ${{ !cancelled() }}
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: juju-dump-logs
path: server/charm/logs
retention-days: 2
7 changes: 2 additions & 5 deletions agent/charms/testflinger-agent-host-charm/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ dependencies = [
[dependency-groups]
lint = ["ruff"]
unit = ["coverage[toml]", "ops[testing]", "pytest"]
integration = ["jubilant>=1.6.2", "ops[testing]", "pytest", "requests"]
integration = ["jubilant>=1.6.2", "pytest", "pytest-jubilant", "requests"]

[tool.coverage.run]
branch = true
Expand All @@ -33,10 +33,7 @@ log_cli_level = "INFO"
[tool.ruff]
line-length = 79
extend-exclude = ["lib"]
include = [
"src/**/*.py",
"tests/**/*.py",
]
include = ["src/**/*.py", "tests/**/*.py"]

[tool.ruff.lint]
select = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import json
import logging
import os
import sys
import time
from datetime import datetime, timezone
from pathlib import Path

Expand Down Expand Up @@ -39,20 +37,6 @@ def create_mock_token(juju: jubilant.Juju, app_name: str):
)


@pytest.fixture(scope="module")
def juju(request: pytest.FixtureRequest):
"""Create temporary Juju model for running tests."""
with jubilant.temp_model() as juju:
juju.wait_timeout = 600
yield juju

if request.session.testsfailed:
logger.info("Collecting Juju logs...")
time.sleep(0.5) # Wait for Juju to process logs.
log = juju.debug_log(limit=1000)
print(log, end="", file=sys.stderr)


@pytest.fixture(scope="session")
def charm_path():
"""Return the path of the charm under test."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from pathlib import Path

import jubilant
import pytest
import yaml
from conftest import create_mock_token

Expand All @@ -27,6 +28,7 @@
APP_NAME = METADATA["name"]


@pytest.mark.juju_setup
def test_deploy(charm_path: Path, juju: jubilant.Juju):
"""Deploy the charm under test."""
juju.deploy(charm_path.resolve(), app=APP_NAME)
Expand Down Expand Up @@ -154,3 +156,9 @@ def test_supervisord_agent_running(juju: jubilant.Juju):
if "RUNNING" in line
]
assert len(running_agents) == 2


@pytest.mark.juju_teardown
def test_destroy(juju: jubilant.Juju):
"""Tear down the charm under test."""
juju.remove_application(APP_NAME)
17 changes: 15 additions & 2 deletions agent/charms/testflinger-agent-host-charm/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 3 additions & 6 deletions server/charm/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ dependencies = [
[dependency-groups]
lint = ["ruff"]
unit = ["coverage[toml]", "ops[testing]", "pytest"]
integration = ["jubilant", "ops[testing]", "pytest", "requests"]
integration = ["jubilant", "pytest", "pytest-jubilant", "requests"]

[tool.coverage.run]
branch = true
Expand All @@ -29,10 +29,7 @@ log_cli_level = "INFO"
[tool.ruff]
line-length = 79
extend-exclude = ["lib"]
include = [
"src/**/*.py",
"tests/**/*.py",
]
include = ["src/**/*.py", "tests/**/*.py"]

[tool.ruff.lint]
select = [
Expand Down Expand Up @@ -63,4 +60,4 @@ ignore = [
]

[tool.ruff.lint.pydocstyle]
convention = "pep257"
convention = "pep257"
17 changes: 0 additions & 17 deletions server/charm/tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,13 @@

import logging
import os
import sys
import time
from pathlib import Path

import jubilant
import pytest

logger = logging.getLogger(__name__)


@pytest.fixture(scope="module")
def juju(request: pytest.FixtureRequest):
"""Create temporary Juju model for running tests."""
with jubilant.temp_model() as juju:
juju.wait_timeout = 600
yield juju

if request.session.testsfailed:
logger.info("Collecting Juju logs...")
time.sleep(0.5) # Wait for Juju to process logs.
log = juju.debug_log(limit=1000)
print(log, end="", file=sys.stderr)


@pytest.fixture(scope="session")
def charm_path():
"""Return the path of the charm under test."""
Expand Down
9 changes: 9 additions & 0 deletions server/charm/tests/integration/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
from pathlib import Path

import jubilant
import pytest

from .helpers import APP_NAME, METADATA, MONGODB_CHARM, app_is_up, retry

DEFAULT_HTTP_PORT = 5000


@pytest.mark.juju_setup
def test_deploy(charm_path: Path, juju: jubilant.Juju):
"""Deploy the charm under test.

Expand Down Expand Up @@ -52,3 +54,10 @@ def test_application_is_up(juju: jubilant.Juju):
ip = juju.status().apps[APP_NAME].units[f"{APP_NAME}/0"].address
base_url = f"http://{ip}:{DEFAULT_HTTP_PORT}"
assert app_is_up(base_url)


@pytest.mark.juju_teardown
def test_destroy(juju: jubilant.Juju):
"""Tear down the charm under test."""
juju.remove_application(APP_NAME)
juju.remove_application(MONGODB_CHARM)
10 changes: 10 additions & 0 deletions server/charm/tests/integration/test_nginx_ingress.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from pathlib import Path

import jubilant
import pytest
import requests

from .helpers import (
Expand All @@ -35,6 +36,7 @@
INGRESS_NAME = "ingress"


@pytest.mark.juju_setup
def test_deploy(charm_path: Path, juju: jubilant.Juju):
"""Test deploying the charm under test with ingress relation."""
# Deploy the testflinger charm
Expand Down Expand Up @@ -86,3 +88,11 @@ def test_ingress_is_up(juju: jubilant.Juju):
)
base_url = f"http://{DEFAULT_EXTERNAL_HOSTNAME}"
assert app_is_up(base_url, session=session)


@pytest.mark.juju_teardown
def test_destroy(juju: jubilant.Juju):
"""Tear down the charm under test."""
juju.remove_application(APP_NAME)
juju.remove_application(MONGODB_CHARM)
juju.remove_application(INGRESS_NAME)
10 changes: 10 additions & 0 deletions server/charm/tests/integration/test_traefik_ingress.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from pathlib import Path

import jubilant
import pytest
import requests

from .helpers import (
Expand All @@ -38,6 +39,7 @@
INGRESS_NAME = "traefik"


@pytest.mark.juju_setup
def test_deploy(charm_path: Path, juju: jubilant.Juju):
"""Test deploying the charm under test with traefik ingress relation."""
# Deploy the testflinger charm
Expand Down Expand Up @@ -132,3 +134,11 @@ def test_ingress_is_up_traefik_hostname(juju: jubilant.Juju):
result = app_is_up(base_url, session=session)
logger.info("Connectivity test: %s", "PASS" if result else "FAIL")
assert result


@pytest.mark.juju_teardown
def test_destroy(juju: jubilant.Juju):
"""Tear down the charm under test."""
juju.remove_application(APP_NAME)
juju.remove_application(MONGODB_CHARM)
juju.remove_application(INGRESS_NAME)
17 changes: 15 additions & 2 deletions server/charm/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading