Skip to content

Commit

Permalink
Remove scenario.Relation wrapper in unit tests (#111)
Browse files Browse the repository at this point in the history
Use .replace() with .next_relation_id() instead (added in scenario
4.0.2)
  • Loading branch information
carlcsaposs-canonical authored Jul 21, 2023
1 parent 51eb4c6 commit cbc3a86
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 87 deletions.
31 changes: 20 additions & 11 deletions tests/unit/scenario_/database_relations/combinations.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,35 @@
import itertools
import typing

from ..wrapper import Relation
import scenario


def _relation_combinations(
*, relation_amounts: typing.Iterable[int], relations: list[Relation]
) -> list[typing.Iterable[Relation]]:
*, relation_amounts: typing.Iterable[int], relations: list[scenario.Relation]
) -> list[list[scenario.Relation]]:
"""Get all combinations of `relations` for each length in `relation_amounts`."""
combinations = []
for number_of_relations in relation_amounts:
for combination in itertools.combinations_with_replacement(relations, number_of_relations):
combination: tuple[Relation]
combinations.append(combination)
combination: tuple[scenario.Relation]
combinations.append(
[
relation.replace(relation_id=scenario.Relation.next_relation_id())
for relation in combination
]
)
return combinations


def incomplete_provides(*relation_amounts: int) -> list[typing.Iterable[Relation]]:
def incomplete_provides(*relation_amounts: int) -> list[list[scenario.Relation]]:
databags = [{}]
relations = []
for remote_app_name in ["remote", "mysql-test-app"]:
relations.extend(
_relation_combinations(
relation_amounts=relation_amounts,
relations=[
Relation(
scenario.Relation(
endpoint="database",
remote_app_name=remote_app_name,
remote_app_data=databag,
Expand All @@ -43,20 +48,24 @@ def incomplete_provides(*relation_amounts: int) -> list[typing.Iterable[Relation

def unsupported_extra_user_role_provides(
*relation_amounts: int,
) -> list[typing.Iterable[Relation]]:
) -> list[list[scenario.Relation]]:
databags = [
{"database": "myappA", "extra-user-roles": "admin"},
{"database": "myappB", "extra-user-roles": "mysqlrouter"},
]
return _relation_combinations(
relation_amounts=relation_amounts,
relations=[Relation(endpoint="database", remote_app_data=databag) for databag in databags],
relations=[
scenario.Relation(endpoint="database", remote_app_data=databag) for databag in databags
],
)


def complete_provides(*relation_amounts: int) -> list[typing.Iterable[Relation]]:
def complete_provides(*relation_amounts: int) -> list[list[scenario.Relation]]:
databags = [{"database": "myappA"}, {"database": "foo"}]
return _relation_combinations(
relation_amounts=relation_amounts,
relations=[Relation(endpoint="database", remote_app_data=databag) for databag in databags],
relations=[
scenario.Relation(endpoint="database", remote_app_data=databag) for databag in databags
],
)
11 changes: 5 additions & 6 deletions tests/unit/scenario_/database_relations/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
# See LICENSE file for licensing details.

import pytest

from ..wrapper import Relation
import scenario


@pytest.fixture(params=["remote", "mysql-k8s"])
Expand All @@ -28,15 +27,15 @@ def app_name(request):
},
]
)
def incomplete_requires(app_name, request) -> Relation:
return Relation(
def incomplete_requires(app_name, request) -> scenario.Relation:
return scenario.Relation(
endpoint="backend-database", remote_app_name=app_name, remote_app_data=request.param
)


@pytest.fixture
def complete_requires() -> Relation:
return Relation(
def complete_requires() -> scenario.Relation:
return scenario.Relation(
endpoint="backend-database",
remote_app_data={
"endpoints": "mysql-k8s-primary:5432",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

import kubernetes_charm

from ..wrapper import Relation
from . import combinations


Expand All @@ -23,19 +22,13 @@ def model_service_domain(monkeypatch, request):
return request.param


def output_states(
*, relations: list[Relation | scenario.Relation]
) -> typing.Iterable[scenario.State]:
def output_states(*, relations: list[scenario.Relation]) -> typing.Iterable[scenario.State]:
"""Run scenario test for each `abstract_charm.reconcile_database_relations` event.
Excludes *-relation-breaking events
The output state of each test should be identical for all events.
"""
for index, relation in enumerate(relations):
if isinstance(relation, Relation):
relations[index] = relation.freeze()
relations: list[scenario.Relation]
context = scenario.Context(kubernetes_charm.KubernetesRouterCharm)
container = scenario.Container("mysql-router", can_connect=True)
input_state = scenario.State(
Expand Down Expand Up @@ -115,9 +108,6 @@ def test_complete_requires_and_provides_unsupported_extra_user_role(
unsupported_extra_user_role_provides_s,
model_service_domain,
):
# Needed to access `.relation_id`
complete_provides_s = [relation.freeze() for relation in complete_provides_s]

for state in output_states(
relations=[
complete_requires,
Expand Down Expand Up @@ -155,9 +145,6 @@ def test_incomplete_provides(complete_requires, incomplete_provides_s):

@pytest.mark.parametrize("complete_provides_s", combinations.complete_provides(1, 2, 4))
def test_complete_provides(complete_requires, complete_provides_s, model_service_domain):
# Needed to access `.relation_id`
complete_provides_s = [relation.freeze() for relation in complete_provides_s]

for state in output_states(relations=[complete_requires, *complete_provides_s]):
assert state.app_status == ops.ActiveStatus()
for index, provides in enumerate(complete_provides_s, 1):
Expand All @@ -176,9 +163,6 @@ def test_complete_provides(complete_requires, complete_provides_s, model_service
def test_complete_provides_and_incomplete_provides(
complete_requires, complete_provides_s, incomplete_provides_s, model_service_domain
):
# Needed to access `.relation_id`
complete_provides_s = [relation.freeze() for relation in complete_provides_s]

for state in output_states(
relations=[complete_requires, *complete_provides_s, *incomplete_provides_s]
):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,10 @@

import kubernetes_charm

from ..wrapper import Relation
from . import combinations


def output_state(
*, relations: list[Relation | scenario.Relation], event: scenario.Event
) -> scenario.State:
for index, relation in enumerate(relations):
if isinstance(relation, Relation):
relations[index] = relation.freeze()
relations: list[scenario.Relation]
def output_state(*, relations: list[scenario.Relation], event: scenario.Event) -> scenario.State:
context = scenario.Context(kubernetes_charm.KubernetesRouterCharm)
container = scenario.Container("mysql-router", can_connect=True)
input_state = scenario.State(
Expand All @@ -32,37 +25,40 @@ def output_state(

@pytest.mark.parametrize("complete_provides_s", combinations.complete_provides(1, 3))
def test_breaking_requires_and_complete_provides(complete_requires, complete_provides_s):
for provides in complete_provides_s:
provides.local_app_data = {
"database": "foobar",
"endpoints": "mysql-router-k8s.my-model.svc.cluster.local:6446",
"read-only-endpoints": "mysql-router-k8s.my-model.svc.cluster.local:6447",
"username": "foouser",
"password": "foobar",
}
complete_requires = complete_requires.freeze()
complete_provides_s = [
relation.replace(
local_app_data={
"database": "foobar",
"endpoints": "mysql-router-k8s.my-model.svc.cluster.local:6446",
"read-only-endpoints": "mysql-router-k8s.my-model.svc.cluster.local:6447",
"username": "foouser",
"password": "foobar",
}
)
for relation in complete_provides_s
]
state = output_state(
relations=[complete_requires, *complete_provides_s], event=complete_requires.broken_event
)

assert state.app_status == ops.BlockedStatus("Missing relation: backend-database")
for index, provides in enumerate(complete_provides_s, 1):
assert state.relations[index].local_app_data == {}


@pytest.mark.parametrize("complete_provides_s", combinations.complete_provides(1, 3))
def test_complete_requires_and_breaking_provides(complete_requires, complete_provides_s):
for provides in complete_provides_s:
provides.local_app_data = {
"database": "foobar",
"endpoints": "mysql-router-k8s.my-model.svc.cluster.local:6446",
"read-only-endpoints": "mysql-router-k8s.my-model.svc.cluster.local:6447",
"username": "foouser",
"password": "foobar",
}
# Needed to access `.broken_event`
complete_provides_s = [relation.freeze() for relation in complete_provides_s]

complete_provides_s = [
relation.replace(
local_app_data={
"database": "foobar",
"endpoints": "mysql-router-k8s.my-model.svc.cluster.local:6446",
"read-only-endpoints": "mysql-router-k8s.my-model.svc.cluster.local:6447",
"username": "foouser",
"password": "foobar",
}
)
for relation in complete_provides_s
]
state = output_state(
relations=[complete_requires, *complete_provides_s],
event=complete_provides_s[-1].broken_event,
Expand Down
24 changes: 0 additions & 24 deletions tests/unit/scenario_/wrapper.py

This file was deleted.

0 comments on commit cbc3a86

Please sign in to comment.