Skip to content
Draft
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
3 changes: 3 additions & 0 deletions bind-operator/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ disable = ["too-many-arguments"]
[tool.pytest.ini_options]
minversion = "6.0"
log_cli_level = "INFO"
markers = [
"abort_on_fail: abort test execution on first failure in marked test",
]

# Linting tools configuration
[tool.ruff]
Expand Down
4 changes: 3 additions & 1 deletion bind-operator/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def pytest_addoption(parser):
"""Parse additional pytest options.

Args:
parser: Pytest parser.
parser: the parser
"""
parser.addoption("--charm-file", action="store", default=None)
parser.addoption(
Expand All @@ -17,3 +17,5 @@ def pytest_addoption(parser):
default=False,
help="This will skip deployment of the charms. Useful for local testing.",
)
parser.addoption("--model", action="store", default=None)
parser.addoption("--keep-models", action="store_true", default=False)
80 changes: 59 additions & 21 deletions bind-operator/tests/integration/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,75 @@

import pathlib
import subprocess # nosec B404
import typing

import jubilant
import pytest
import pytest_asyncio
import yaml
from pytest_operator.plugin import Model, OpsTest


@pytest.fixture(scope="module", name="charmcraft")
def fixture_charmcraft():
"""Provide charmcraft."""
yield yaml.safe_load(pathlib.Path("./charmcraft.yaml").read_text(encoding="UTF-8"))
@pytest.fixture(scope="module", name="juju")
def juju_fixture(
request: pytest.FixtureRequest,
) -> typing.Generator[jubilant.Juju, None, None]:
"""Pytest fixture that wraps jubilant.juju.

Args:
request: fixture request

Returns:
juju
"""

def show_debug_log(juju: jubilant.Juju):
"""Show debug log.

Args:
juju: Jubilant.juju
"""
if request.session.testsfailed:
log = juju.debug_log(limit=1000)
print(log, end="")

use_existing = request.config.getoption("--use-existing", default=False)
if use_existing:
juju = jubilant.Juju()
yield juju
show_debug_log(juju)
return

model = request.config.getoption("--model", default=None)
if model:
juju = jubilant.Juju(model=model)
yield juju
show_debug_log(juju)
return

keep_models = request.config.getoption("--keep-models", default=False)
with jubilant.temp_model(keep=keep_models) as juju:
juju.wait_timeout = 10 * 60
yield juju
show_debug_log(juju)
return

@pytest.fixture(scope="module", name="app_name")
def fixture_app_name(charmcraft):
"""Provide app name from the charmcraft."""
yield charmcraft["name"]

@pytest.fixture(scope="module", name="metadata")
def fixture_metadata():
"""Provide charm metadata."""
yield yaml.safe_load(pathlib.Path("./charmcraft.yaml").read_text(encoding="UTF-8"))


@pytest.fixture(scope="module", name="model")
def model_fixture(ops_test: OpsTest) -> Model:
"""Juju model API client."""
assert ops_test.model
return ops_test.model
@pytest.fixture(scope="module", name="app_name")
def fixture_app_name(metadata):
"""Provide app name from the metadata."""
yield metadata["name"]


@pytest.fixture(scope="module", name="charm_file")
def charm_file_fixture(app_name, pytestconfig: pytest.Config):
"""Pytest fixture that packs the charm and returns the filename, or --charm-file if set."""
charm_file = pytestconfig.getoption("--charm-file")
charm_file = pytestconfig.getoption("--charm-file", default=None)
if charm_file:
yield charm_file
return
Expand All @@ -54,19 +93,18 @@ def charm_file_fixture(app_name, pytestconfig: pytest.Config):

@pytest_asyncio.fixture(scope="module", name="app")
async def app_fixture(
juju: jubilant.Juju,
app_name: str,
pytestconfig: pytest.Config,
model: Model,
charm_file: str,
):
"""Build the charm and deploys it."""
use_existing = pytestconfig.getoption("--use-existing", default=False)
if use_existing:
yield model.applications[app_name]
yield app_name
return

application = await model.deploy(f"./{charm_file}", application_name=app_name, resources={})

await model.wait_for_idle(apps=[application.name], status="active")
juju.deploy(charm_file, app_name, resources={})
juju.wait(lambda status: jubilant.all_active(status, app_name))

yield application
yield app_name
Loading
Loading