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
17 changes: 17 additions & 0 deletions docs/release-notes/artifacts/pr0646.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version_schema: 2

changes:
- title: Refactored get-proxied-endpoints action tests
author: minulo
type: minor
description: >
Refactored the get-proxied-endpoints Juju action tests to follow the
same style as the rest of the test suite. No user-facing behavior
changed.
Comment thread
minulo marked this conversation as resolved.
urls:
pr:
- https://github.com/canonical/haproxy-operator/pull/646
related_doc:
related_issue:
visibility: internal
highlight: false
274 changes: 140 additions & 134 deletions haproxy-operator/tests/unit/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,144 +342,150 @@ def test_ca_certificates_removed(monkeypatch: pytest.MonkeyPatch, receive_ca_cer


@pytest.mark.usefixtures("systemd_mock", "mocks_external_calls")
class TestGetProxiedEndpointsAction:
"""Test "get-proxied-endpoints" Action"""

def test_no_backend_filter(self) -> None:
"""
arrange: create state with one haproxy-route relation containing
hostname, additional_hostnames, and paths.
act: trigger the get-proxied-endpoints action without a backend filter.
assert: returns a list of all proxied endpoints for every hostname/path combination.
"""
context = ops.testing.Context(HAProxyCharm)

haproxy_route_relation = ops.testing.Relation(
"haproxy-route",
remote_app_data={
"hostname": f'"{TEST_EXTERNAL_HOSTNAME_CONFIG}"',
"additional_hostnames": json.dumps(
[
f"ok2.{TEST_EXTERNAL_HOSTNAME_CONFIG}",
f"ok3.{TEST_EXTERNAL_HOSTNAME_CONFIG}",
]
),
"paths": '["/v1", "/v2"]',
"ports": "[443]",
"protocol": '"http"',
"service": '"haproxy-tutorial-ingress-configurator"',
},
remote_units_data={0: {"address": '"10.75.1.129"'}},
)
charm_state = ops.testing.State(
relations=[haproxy_route_relation],
leader=True,
model=ops.testing.Model(name="haproxy-tutorial"),
app_status=ops.testing.ActiveStatus(),
unit_status=ops.testing.ActiveStatus(),
)
context.run(context.on.action("get-proxied-endpoints"), charm_state)

out = context.action_results
assert out is not None

assert set(json.loads(out["endpoints"])) == {
"https://haproxy.internal/v1",
"https://haproxy.internal/v2",
"https://ok2.haproxy.internal/v1",
"https://ok2.haproxy.internal/v2",
"https://ok3.haproxy.internal/v1",
"https://ok3.haproxy.internal/v2",
}

def test_no_backend_filter_no_endpoints(self) -> None:
"""
arrange: create state with no haproxy-route relations.
act: trigger the get-proxied-endpoints action without a backend filter.
assert: returns an empty list.
"""
context = ops.testing.Context(HAProxyCharm)
charm_state = ops.testing.State(
relations=[],
leader=True,
model=ops.testing.Model(name="haproxy-tutorial"),
app_status=ops.testing.ActiveStatus(),
unit_status=ops.testing.ActiveStatus(),
)
context.run(context.on.action("get-proxied-endpoints"), charm_state)

out = context.action_results

assert out == {"endpoints": "[]"}

def test_with_backend_filter(self) -> None:
"""
arrange: create state with a haproxy-route relation for a specific backend.
act: trigger the get-proxied-endpoints action with the backend filter.
assert: returns a list containing the endpoint for that backend.
"""
service_name = "haproxy-tutorial-ingress-configurator"
context = ops.testing.Context(HAProxyCharm)
haproxy_route_relation = ops.testing.Relation(
"haproxy-route",
remote_app_data={
"hostname": f'"{TEST_EXTERNAL_HOSTNAME_CONFIG}"',
"ports": "[443]",
"protocol": '"http"',
"service": f'"{service_name}"',
},
remote_units_data={0: {"address": '"10.75.1.129"'}},
)
charm_state = ops.testing.State(
relations=[haproxy_route_relation],
leader=True,
model=ops.testing.Model(name="haproxy-tutorial"),
app_status=ops.testing.ActiveStatus(),
unit_status=ops.testing.ActiveStatus(),
)
context.run(
context.on.action("get-proxied-endpoints", params={"backend": service_name}),
charm_state,
)
def test_get_proxied_endpoints_no_backend_filter() -> None:
"""
arrange: create state with one haproxy-route relation containing
hostname, additional_hostnames, and paths.
act: trigger the get-proxied-endpoints action without a backend filter.
assert: returns a list of all proxied endpoints for every hostname/path combination.
"""
context = ops.testing.Context(HAProxyCharm)

out = context.action_results

assert out == {"endpoints": f'["https://{TEST_EXTERNAL_HOSTNAME_CONFIG}"]'}

def test_with_backend_filter_non_existing_backend(self) -> None:
"""
arrange: create state with a haproxy-route relation for a specific backend.
act: trigger the get-proxied-endpoints action with a non-existing backend name.
assert: raises ActionFailed indicating the backend does not exist.
"""
service_name = "haproxy-tutorial-ingress-configurator"
context = ops.testing.Context(HAProxyCharm)
haproxy_route_relation = ops.testing.Relation(
"haproxy-route",
remote_app_data={
"hostname": f'"{TEST_EXTERNAL_HOSTNAME_CONFIG}"',
"ports": "[443]",
"protocol": '"http"',
"service": f'"{service_name}"',
},
remote_units_data={0: {"address": '"10.75.1.129"'}},
)
charm_state = ops.testing.State(
relations=[haproxy_route_relation],
leader=True,
model=ops.testing.Model(name="haproxy-tutorial"),
app_status=ops.testing.ActiveStatus(),
unit_status=ops.testing.ActiveStatus(),
)
haproxy_route_relation = ops.testing.Relation(
"haproxy-route",
remote_app_data={
"hostname": f'"{TEST_EXTERNAL_HOSTNAME_CONFIG}"',
"additional_hostnames": json.dumps(
[
f"ok2.{TEST_EXTERNAL_HOSTNAME_CONFIG}",
f"ok3.{TEST_EXTERNAL_HOSTNAME_CONFIG}",
]
),
"paths": '["/v1", "/v2"]',
"ports": "[443]",
"protocol": '"http"',
"service": '"haproxy-tutorial-ingress-configurator"',
},
remote_units_data={0: {"address": '"10.75.1.129"'}},
)
charm_state = ops.testing.State(
relations=[haproxy_route_relation],
leader=True,
model=ops.testing.Model(name="haproxy-tutorial"),
app_status=ops.testing.ActiveStatus(),
unit_status=ops.testing.ActiveStatus(),
)

context.run(
context.on.action("get-proxied-endpoints", params={"backend": "random_name"}),
charm_state,
)
context.run(context.on.action("get-proxied-endpoints"), charm_state)

out = context.action_results
assert out is not None

assert set(json.loads(out["endpoints"])) == {
"https://haproxy.internal/v1",
"https://haproxy.internal/v2",
"https://ok2.haproxy.internal/v1",
"https://ok2.haproxy.internal/v2",
"https://ok3.haproxy.internal/v1",
"https://ok3.haproxy.internal/v2",
}


@pytest.mark.usefixtures("systemd_mock", "mocks_external_calls")
def test_get_proxied_endpoints_no_backend_filter_no_endpoints() -> None:
"""
arrange: create state with no haproxy-route relations.
act: trigger the get-proxied-endpoints action without a backend filter.
assert: returns an empty list.
"""
context = ops.testing.Context(HAProxyCharm)
charm_state = ops.testing.State(
relations=[],
leader=True,
model=ops.testing.Model(name="haproxy-tutorial"),
app_status=ops.testing.ActiveStatus(),
unit_status=ops.testing.ActiveStatus(),
)

context.run(context.on.action("get-proxied-endpoints"), charm_state)

out = context.action_results

assert out == {"endpoints": "[]"}


@pytest.mark.usefixtures("systemd_mock", "mocks_external_calls")
def test_get_proxied_endpoints_with_backend_filter() -> None:
"""
arrange: create state with a haproxy-route relation for a specific backend.
act: trigger the get-proxied-endpoints action with the backend filter.
assert: returns a list containing the endpoint for that backend.
"""
service_name = "haproxy-tutorial-ingress-configurator"
context = ops.testing.Context(HAProxyCharm)
haproxy_route_relation = ops.testing.Relation(
"haproxy-route",
remote_app_data={
"hostname": f'"{TEST_EXTERNAL_HOSTNAME_CONFIG}"',
"ports": "[443]",
"protocol": '"http"',
"service": f'"{service_name}"',
},
remote_units_data={0: {"address": '"10.75.1.129"'}},
)
charm_state = ops.testing.State(
relations=[haproxy_route_relation],
leader=True,
model=ops.testing.Model(name="haproxy-tutorial"),
app_status=ops.testing.ActiveStatus(),
unit_status=ops.testing.ActiveStatus(),
)

context.run(
context.on.action("get-proxied-endpoints", params={"backend": service_name}),
charm_state,
)

out = context.action_results

assert out == {"endpoints": f'["https://{TEST_EXTERNAL_HOSTNAME_CONFIG}"]'}


@pytest.mark.usefixtures("systemd_mock", "mocks_external_calls")
def test_get_proxied_endpoints_with_backend_filter_non_existing_backend() -> None:
"""
arrange: create state with a haproxy-route relation for a specific backend.
act: trigger the get-proxied-endpoints action with a non-existing backend name.
assert: returns an empty list when the backend does not exist.
"""
Comment thread
Copilot marked this conversation as resolved.
service_name = "haproxy-tutorial-ingress-configurator"
context = ops.testing.Context(HAProxyCharm)
haproxy_route_relation = ops.testing.Relation(
"haproxy-route",
remote_app_data={
"hostname": f'"{TEST_EXTERNAL_HOSTNAME_CONFIG}"',
"ports": "[443]",
"protocol": '"http"',
"service": f'"{service_name}"',
},
remote_units_data={0: {"address": '"10.75.1.129"'}},
)
charm_state = ops.testing.State(
relations=[haproxy_route_relation],
leader=True,
model=ops.testing.Model(name="haproxy-tutorial"),
app_status=ops.testing.ActiveStatus(),
unit_status=ops.testing.ActiveStatus(),
)

context.run(
context.on.action("get-proxied-endpoints", params={"backend": "random_name"}),
charm_state,
)

out = context.action_results
out = context.action_results

assert out == {"endpoints": "[]"}
assert out == {"endpoints": "[]"}


@pytest.mark.usefixtures("systemd_mock", "mocks_external_calls")
Expand Down
Loading