Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrated all scenario tests to scenario 7 #405

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
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
26 changes: 14 additions & 12 deletions tests/interface/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import pytest
from interface_tester import InterfaceTester
from ops.pebble import Layer
from scenario.state import Container, ExecOutput, State
from scenario.state import Container, Exec, State

from charm import TraefikIngressCharm

Expand All @@ -30,20 +30,22 @@ def interface_tester(interface_tester: InterfaceTester):
# since we're passing a config, we have to provide all defaulted values
"routing_mode": "path",
},
containers=[
containers={
# unless the traefik service reports active, the
# charm won't publish the ingress url.
Container(
name="traefik",
can_connect=True,
exec_mock={
(
"find",
"/opt/traefik/juju",
"-name",
"*.yaml",
"-delete",
): ExecOutput()
execs={
Exec(
(
"find",
"/opt/traefik/juju",
"-name",
"*.yaml",
"-delete",
)
)
},
layers={
"foo": Layer(
Expand All @@ -61,8 +63,8 @@ def interface_tester(interface_tester: InterfaceTester):
}
)
},
)
],
),
},
),
)
yield interface_tester
2 changes: 1 addition & 1 deletion tests/scenario/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,6 @@ def create_ingress_relation(

# No `next_relation_id()` nor `get_next_id()` in Relation.
if rel_id is not None:
args["relation_id"] = rel_id
args["id"] = rel_id

return Relation(**args)
14 changes: 7 additions & 7 deletions tests/scenario/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import pytest
from ops import pebble
from scenario import Container, Context, ExecOutput, Model, Mount
from scenario import Container, Context, Exec, Model, Mount

from charm import TraefikIngressCharm

Expand Down Expand Up @@ -47,17 +47,17 @@ def traefik_container(tmp_path):
}
)

opt = Mount("/opt/", tmp_path)
opt = Mount(location="/opt/", source=tmp_path)

return Container(
name="traefik",
can_connect=True,
layers={"traefik": layer},
exec_mock={
("update-ca-certificates", "--fresh"): ExecOutput(),
("find", "/opt/traefik/juju", "-name", "*.yaml", "-delete"): ExecOutput(),
("/usr/bin/traefik", "version"): ExecOutput(stdout="42.42"),
execs={
Exec(command_prefix=("update-ca-certificates", "--fresh")),
Exec(command_prefix=("find", "/opt/traefik/juju", "-name", "*.yaml", "-delete")),
Exec(command_prefix=("/usr/bin/traefik", "version"), stdout="42.42"),
},
service_status={"traefik": pebble.ServiceStatus.ACTIVE},
service_statuses={"traefik": pebble.ServiceStatus.ACTIVE},
mounts={"opt": opt},
)
20 changes: 12 additions & 8 deletions tests/scenario/test_config_mgm.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from dataclasses import replace

from scenario import Relation, State


Expand All @@ -6,7 +8,7 @@ def ipu():
endpoint="ingress-per-unit",
interface="ingress_per_unit",
remote_app_name="remote",
relation_id=0,
id=0,
remote_units_data={
0: {
"port": "9999",
Expand All @@ -21,26 +23,28 @@ def ipu():
def test_dynamic_config_create(traefik_container, traefik_ctx, tmp_path):
rel = ipu()
traefik_ctx.run(
rel.created_event, State(relations=[rel], containers=[traefik_container], leader=True)
traefik_ctx.on.relation_created(rel),
State(relations=[rel], containers=[traefik_container], leader=True),
)
dynamic_config_dir = tmp_path / "traefik" / "juju"
assert dynamic_config_dir.exists()
files = list(dynamic_config_dir.iterdir())
assert len(files) == 1
assert files[0].name == f"juju_ingress_ingress-per-unit_{rel.relation_id}_remote.yaml"
assert files[0].name == f"juju_ingress_ingress-per-unit_{rel.id}_remote.yaml"


def test_dynamic_config_remove_on_broken(traefik_container, traefik_ctx, tmp_path):
dynamic_config_dir = tmp_path / "traefik" / "juju"
rel = ipu()
dynamic_config_dir.mkdir(parents=True)
ingress_config_fname = (
dynamic_config_dir / f"juju_ingress_ingress-per-unit_{rel.relation_id}_remote.yaml"
dynamic_config_dir / f"juju_ingress_ingress-per-unit_{rel.id}_remote.yaml"
)
ingress_config_fname.touch()

traefik_ctx.run(
rel.broken_event, State(relations=[rel], containers=[traefik_container], leader=True)
traefik_ctx.on.relation_broken(rel),
State(relations=[rel], containers=[traefik_container], leader=True),
)

assert dynamic_config_dir.exists()
Expand All @@ -50,16 +54,16 @@ def test_dynamic_config_remove_on_broken(traefik_container, traefik_ctx, tmp_pat

def test_dynamic_config_remove_on_departed(traefik_container, traefik_ctx, tmp_path):
dynamic_config_dir = tmp_path / "traefik" / "juju"
rel = ipu().replace(remote_units_data={})
rel = replace(ipu(), remote_units_data={})

dynamic_config_dir.mkdir(parents=True)
ingress_config_fname = (
dynamic_config_dir / f"juju_ingress_ingress-per-unit_{rel.relation_id}_remote.yaml"
dynamic_config_dir / f"juju_ingress_ingress-per-unit_{rel.id}_remote.yaml"
)
ingress_config_fname.touch()

traefik_ctx.run(
rel.departed_event(remote_unit_id=0),
traefik_ctx.on.relation_departed(rel, remote_unit=0),
State(relations=[rel], containers=[traefik_container], leader=True),
)

Expand Down
54 changes: 26 additions & 28 deletions tests/scenario/test_ingress_per_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# THEN the traefik config file is updated
import json
import tempfile
from dataclasses import replace
from pathlib import Path

import pytest
Expand All @@ -16,17 +17,22 @@
)
from ops import CharmBase, Framework
from scenario import Context, Mount, Relation, State
from scenario.context import CharmEvents

from tests.scenario._utils import create_ingress_relation

on = CharmEvents()


@pytest.mark.parametrize(
"port, ip, host", ((80, "1.1.1.1", "1.1.1.1"), (81, "10.1.10.1", "10.1.10.1"))
)
@pytest.mark.parametrize("event_name", ("joined", "changed", "created"))
@pytest.mark.parametrize(
"event_source", (on.relation_joined, on.relation_changed, on.relation_created)
)
@pytest.mark.parametrize("scheme", ("http", "https"))
def test_ingress_per_app_created(
traefik_ctx, port, ip, host, model, traefik_container, event_name, tmp_path, scheme
traefik_ctx, port, ip, host, model, traefik_container, event_source, tmp_path, scheme
):
"""Check the config when a new ingress per app is created or changes (single remote unit)."""
ipa = create_ingress_relation(port=port, scheme=scheme, hosts=[host], ips=[ip])
Expand All @@ -38,12 +44,11 @@ def test_ingress_per_app_created(
)

# WHEN any relevant event fires
event = getattr(ipa, f"{event_name}_event")
traefik_ctx.run(event, state)
traefik_ctx.run(event_source(ipa), state)

generated_config = yaml.safe_load(
traefik_container.get_filesystem(traefik_ctx)
.joinpath(f"opt/traefik/juju/juju_ingress_ingress_{ipa.relation_id}_remote.yaml")
.joinpath(f"opt/traefik/juju/juju_ingress_ingress_{ipa.id}_remote.yaml")
.read_text()
)

Expand All @@ -66,10 +71,10 @@ def test_ingress_per_app_created(
"port, ip, host", ((80, "1.1.1.{}", "1.1.1.{}"), (81, "10.1.10.{}", "10.1.10.{}"))
)
@pytest.mark.parametrize("n_units", (2, 3, 10))
@pytest.mark.parametrize("evt_name", ("joined", "changed"))
@pytest.mark.parametrize("event_source", (on.relation_joined, on.relation_changed))
@pytest.mark.parametrize("scheme", ("http", "https"))
def test_ingress_per_app_scale(
traefik_ctx, host, ip, port, model, traefik_container, tmp_path, n_units, scheme, evt_name
traefik_ctx, host, ip, port, model, traefik_container, tmp_path, n_units, scheme, event_source
):
"""Check the config when a new ingress per app unit joins."""
relation_id = 42
Expand Down Expand Up @@ -120,7 +125,7 @@ def test_ingress_per_app_scale(
relations=[ipa],
)

traefik_ctx.run(getattr(ipa, evt_name + "_event"), state)
traefik_ctx.run(event_source(ipa), state)

new_config = yaml.safe_load(cfg_file.read_text())
# verify that the config has changed!
Expand All @@ -143,11 +148,6 @@ def test_ingress_per_app_scale(
# d["service"][svc_name]["loadBalancer"]["servers"][0]["url"] == leader_url


@pytest.mark.parametrize(
"port, ip, host", ((80, "1.1.1.1", "1.1.1.1"), (81, "10.1.10.1", "10.1.10.1"))
)
@pytest.mark.parametrize("evt_name", ("joined", "changed"))
@pytest.mark.parametrize("leader", (True, False))
def get_requirer_ctx(host, ip, port):
class MyRequirer(CharmBase):
def __init__(self, framework: Framework):
Expand All @@ -164,17 +164,17 @@ def __init__(self, framework: Framework):
@pytest.mark.parametrize(
"port, ip, host", ((80, "1.1.1.1", "1.1.1.1"), (81, "10.1.10.1", "1.1.1.1"))
)
@pytest.mark.parametrize("evt_name", ("joined", "changed"))
@pytest.mark.parametrize("event_source", (on.relation_joined, on.relation_changed))
@pytest.mark.parametrize("leader", (True, False))
def test_ingress_per_app_requirer_with_auto_data(host, ip, port, model, evt_name, leader):
def test_ingress_per_app_requirer_with_auto_data(host, ip, port, model, event_source, leader):
ipa = Relation("ingress")
state = State(
model=model,
leader=leader,
relations=[ipa],
)
requirer_ctx = get_requirer_ctx(host, ip, port)
state_out = requirer_ctx.run(getattr(ipa, evt_name + "_event"), state)
state_out = requirer_ctx.run(event_source(ipa), state)

ipa_out = state_out.get_relations("ingress")[0]
assert ipa_out.local_unit_data == {"host": json.dumps(host), "ip": json.dumps(ip)}
Expand All @@ -192,11 +192,13 @@ def test_ingress_per_app_cleanup_on_remove(model, traefik_ctx, traefik_container
ipa = create_ingress_relation()

td = tempfile.TemporaryDirectory()
filename = f"juju_ingress_ingress_{ipa.relation_id}_remote.yaml"
filename = f"juju_ingress_ingress_{ipa.id}_remote.yaml"
conf_file = Path(td.name).joinpath(filename)
conf_file.write_text("foobar")

traefik_container = traefik_container.replace(mounts={"conf": Mount("/opt/traefik/", td.name)})
traefik_container = replace(
traefik_container, mounts={"conf": Mount(location="/opt/traefik/", source=td.name)}
)

state = State(
model=model,
Expand All @@ -206,7 +208,7 @@ def test_ingress_per_app_cleanup_on_remove(model, traefik_ctx, traefik_container
)

# WHEN the relation goes
traefik_ctx.run(ipa.broken_event, state)
traefik_ctx.run(on.relation_broken(ipa), state)

# THEN the config file was deleted
mock_dynamic_config_folder = traefik_container.get_filesystem(traefik_ctx).joinpath(
Expand Down Expand Up @@ -242,7 +244,7 @@ def test_ingress_per_app_v1_upgrade_v2(
)

# WHEN a charm upgrade occurs
with requirer_ctx.manager("upgrade-charm", state) as mgr:
with requirer_ctx(on.upgrade_charm(), state) as mgr:
assert not mgr.charm.ipa.is_ready()
state_out = mgr.run()
assert not mgr.charm.ipa.is_ready()
Expand Down Expand Up @@ -283,18 +285,14 @@ def test_proxied_endpoints(
state = State(leader=True, relations=[ipav1, ipav2, ipu], containers=[traefik_container])

# WHEN we get any event
with traefik_ctx.manager("update-status", state) as mgr:
with traefik_ctx(on.update_status(), state) as mgr:
charm = mgr.charm

# populate the local app databags
charm.ingress_per_appv1.publish_url(
charm.model.get_relation("ingress", ipav1.relation_id), url1
)
charm.ingress_per_appv2.publish_url(
charm.model.get_relation("ingress", ipav2.relation_id), url2
)
charm.ingress_per_appv1.publish_url(charm.model.get_relation("ingress", ipav1.id), url1)
charm.ingress_per_appv2.publish_url(charm.model.get_relation("ingress", ipav2.id), url2)
charm.ingress_per_unit.publish_url(
charm.model.get_relation("ingress-per-unit", ipu.relation_id), "remote/0", url3
charm.model.get_relation("ingress-per-unit", ipu.id), "remote/0", url3
)

# THEN the charm can fetch the proxied endpoints without errors
Expand Down
5 changes: 4 additions & 1 deletion tests/scenario/test_ingress_per_unit.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import pytest
from scenario import Relation, State
from scenario.context import CharmEvents

from tests.scenario.conftest import MOCK_EXTERNAL_HOSTNAME

on = CharmEvents()


@pytest.mark.parametrize("leader", (True, False))
@pytest.mark.parametrize("url", ("url.com", "http://foo.bar.baz"))
Expand Down Expand Up @@ -39,7 +42,7 @@ def test_ingress_unit_provider_request_response(
containers=[traefik_container],
)

state_out = traefik_ctx.run(ipu.changed_event, state)
state_out = traefik_ctx.run(on.relation_changed(ipu), state)

ipu_out = state_out.get_relations(ipu.endpoint)[0]

Expand Down
Loading
Loading