Skip to content

Commit

Permalink
Merge pull request #339 from canonical/backport-handle-relation-broken
Browse files Browse the repository at this point in the history
backport(fix): Handle relation-broken events (#272)
  • Loading branch information
orfeas-k authored Sep 27, 2023
2 parents 93dbb5c + 61da1df commit ec3569b
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
10 changes: 9 additions & 1 deletion charms/kfp-api/src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,15 @@ def _get_relational_db_data(self) -> dict:
self._get_db_relation("relational-db")

# retrieve database data from library
relation_data = self.database.fetch_relation_data()
try:
# if called in response to a '*-relation-broken' event, this will raise an exception
relation_data = self.database.fetch_relation_data()
except KeyError:
self.logger.error("Failed to retrieve relation data from library")
raise GenericCharmRuntimeError(
"Failed to retrieve relational-db data. This is to be expected if executed in"
" response to a '*-relation-broken' event"
)
# parse data in relation
# this also validates expected data by means of KeyError exception
for val in relation_data.values():
Expand Down
8 changes: 8 additions & 0 deletions charms/kfp-api/tests/integration/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ async def test_msql_relation_with_relational_db_relation(self, ops_test: OpsTest
)
assert ops_test.model.applications[APP_NAME].units[0].workload_status == "blocked"

# remove redundant relation
await ops_test.juju("remove-relation", f"{APP_NAME}:mysql", "kfp-db:mysql")

async def test_prometheus_grafana_integration(self, ops_test: OpsTest):
"""Deploy prometheus, grafana and required relations, then test the metrics."""
prometheus = "prometheus-k8s"
Expand Down Expand Up @@ -240,3 +243,8 @@ async def test_prometheus_grafana_integration(self, ops_test: OpsTest):
wait=wait_exponential(multiplier=1, min=1, max=10),
reraise=True,
)

async def test_remove_application(self, ops_test: OpsTest):
"""Test that the application can be removed successfully."""
await ops_test.model.remove_application(app_name=APP_NAME, block_until_done=True)
assert APP_NAME not in ops_test.model.applications
40 changes: 39 additions & 1 deletion charms/kfp-api/tests/unit/test_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@

import pytest
import yaml
from ops.model import ActiveStatus, BlockedStatus, WaitingStatus
from ops.model import ActiveStatus, BlockedStatus, MaintenanceStatus, WaitingStatus
from ops.testing import Harness

from charm import ErrorWithStatus, KfpApiOperator

KFP_API_CONTAINER_NAME = "apiserver"


@pytest.fixture()
def mocked_resource_handler(mocker):
Expand Down Expand Up @@ -570,3 +572,39 @@ def test_relational_db_relation_with_data(
"db_host": "host",
"db_port": "1234",
}

def test_relational_db_relation_broken(
self,
mocked_resource_handler,
mocked_lightkube_client,
mocked_kubernetes_service_patcher,
harness: Harness,
):
"""Test that a relation broken event is properly handled."""
database = MagicMock()
fetch_relation_data = MagicMock(side_effect=KeyError())
database.fetch_relation_data = fetch_relation_data
harness.model.get_relation = MagicMock(
side_effect=self._get_relation_db_only_side_effect_func
)

rel_name = "relational-db"
rel_id = harness.add_relation(rel_name, "relational-db-provider")

harness.begin()
harness.set_leader(True)
harness.container_pebble_ready(KFP_API_CONTAINER_NAME)

assert harness.model.unit.status == WaitingStatus("Waiting for relational-db data")

harness.charm.database = database
del harness.model.get_relation

harness._emit_relation_broken(rel_name, rel_id, "kfp-api")

assert harness.model.unit.status == BlockedStatus(
"Please add required database relation: eg. relational-db"
)

harness.charm.on.remove.emit()
assert harness.model.unit.status == MaintenanceStatus("K8S resources removed")

0 comments on commit ec3569b

Please sign in to comment.