Skip to content

Commit

Permalink
fix: go into blocked status when database relation is removed (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
dariofaccin authored Nov 17, 2023
1 parent dd0b988 commit 82a4370
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 18 deletions.
9 changes: 9 additions & 0 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def __init__(self, *args):
self.framework.observe(self.on.remove, self._on_remove)
self.framework.observe(self.on.config_changed, self._configure_amf)
self.framework.observe(self.on.database_relation_joined, self._configure_amf)
self.framework.observe(self.on.database_relation_broken, self._on_database_relation_broken)
self.framework.observe(self._database.on.database_created, self._configure_amf)
self.framework.observe(self.on.amf_pebble_ready, self._configure_amf)
self.framework.observe(self._nrf_requires.on.nrf_available, self._configure_amf)
Expand Down Expand Up @@ -283,6 +284,14 @@ def _on_nrf_broken(self, event: EventBase) -> None:
"""
self.unit.status = BlockedStatus("Waiting for fiveg-nrf relation")

def _on_database_relation_broken(self, event: EventBase) -> None:
"""Event handler for database relation broken.
Args:
event: Juju event
"""
self.unit.status = BlockedStatus("Waiting for database relation")

def _generate_private_key(self) -> None:
"""Generates and stores private key."""
private_key = generate_private_key()
Expand Down
26 changes: 26 additions & 0 deletions tests/integration/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,29 @@ async def test_restore_tls_and_wait_for_active_status(ops_test: OpsTest, build_a
)
await ops_test.model.integrate(relation1=APP_NAME, relation2=TLS_PROVIDER_CHARM_NAME)
await ops_test.model.wait_for_idle(apps=[APP_NAME], status="active", timeout=1000)


@pytest.mark.skip(
reason="Bug in MongoDB: https://github.com/canonical/mongodb-k8s-operator/issues/218"
)
@pytest.mark.abort_on_fail
async def test_remove_database_and_wait_for_blocked_status(ops_test: OpsTest, build_and_deploy):
assert ops_test.model
await ops_test.model.remove_application(DB_CHARM_NAME, block_until_done=True)
await ops_test.model.wait_for_idle(apps=[APP_NAME], status="blocked", timeout=60)


@pytest.mark.skip(
reason="Bug in MongoDB: https://github.com/canonical/mongodb-k8s-operator/issues/218"
)
@pytest.mark.abort_on_fail
async def test_restore_database_and_wait_for_active_status(ops_test: OpsTest, build_and_deploy):
assert ops_test.model
await ops_test.model.deploy(
DB_CHARM_NAME,
application_name=DB_CHARM_NAME,
channel="5/edge",
trust=True,
)
await ops_test.model.integrate(relation1=APP_NAME, relation2=DB_CHARM_NAME)
await ops_test.model.wait_for_idle(apps=[APP_NAME], status="active", timeout=1000)
74 changes: 56 additions & 18 deletions tests/unit/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def setUp(self):
self.harness.set_leader(is_leader=True)
self.harness.begin()

def _database_is_available(self):
def _create_database_relation_and_populate_data(self) -> int:
database_relation_id = self.harness.add_relation("database", "mongodb")
self.harness.add_relation_unit(
relation_id=database_relation_id, remote_unit_name="mongodb/0"
Expand All @@ -41,6 +41,7 @@ def _database_is_available(self):
"uris": "http://dummy",
},
)
return database_relation_id

@staticmethod
def _read_file(path: str) -> str:
Expand Down Expand Up @@ -114,7 +115,7 @@ def test_given_amf_charm_in_active_state_when_nrf_relation_breaks_then_status_is
patch_nrf_url.return_value = "http://nrf:8081"
self.harness.set_can_connect(container="amf", val=True)
nrf_relation_id = self.harness.add_relation(relation_name="fiveg-nrf", remote_app="nrf")
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")

self.harness.remove_relation(nrf_relation_id)
Expand All @@ -124,6 +125,43 @@ def test_given_amf_charm_in_active_state_when_nrf_relation_breaks_then_status_is
BlockedStatus("Waiting for fiveg-nrf relation"),
)

@patch("ops.model.Container.pull")
@patch("ops.model.Container.exists")
@patch("ops.model.Container.push", new=Mock)
@patch("charm.check_output")
@patch("charms.sdcore_nrf.v0.fiveg_nrf.NRFRequires.nrf_url", new_callable=PropertyMock)
@patch("charms.data_platform_libs.v0.data_interfaces.DatabaseRequires.is_resource_created")
def test_given_amf_charm_in_active_state_when_database_relation_breaks_then_status_is_blocked(
self,
patch_is_resource_created,
patch_nrf_url,
patch_check_output,
patch_exists,
patch_pull,
):
patch_pull.return_value = StringIO(
self._read_file("tests/unit/expected_config/config.conf").strip()
)
patch_exists.return_value = True
patch_check_output.return_value = b"1.1.1.1"
patch_exists.return_value = True
patch_is_resource_created.return_value = True
patch_nrf_url.return_value = "http://nrf:8081"
self.harness.set_can_connect(container="amf", val=True)
self.harness.add_relation(relation_name="fiveg-nrf", remote_app="nrf")
database_relation_id = self._create_database_relation_and_populate_data()
self.harness.add_relation(
relation_name="certificates", remote_app="tls-certificates-operator"
)
self.harness.container_pebble_ready("amf")

self.harness.remove_relation(database_relation_id)

self.assertEqual(
self.harness.model.unit.status,
BlockedStatus("Waiting for database relation"),
)

@patch("charm.generate_private_key")
@patch("ops.model.Container.push")
def test_given_relations_created_and_database_not_available_when_pebble_ready_then_status_is_waiting( # noqa: E501
Expand Down Expand Up @@ -181,7 +219,7 @@ def test_given_nrf_data_not_available_when_pebble_ready_then_status_is_waiting(
self.harness.add_relation(
relation_name="certificates", remote_app="tls-certificates-operator"
)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")
self.assertEqual(
self.harness.model.unit.status,
Expand All @@ -204,7 +242,7 @@ def test_given_storage_not_attached_when_pebble_ready_then_status_is_waiting(
self.harness.add_relation(
relation_name="certificates", remote_app="tls-certificates-operator"
)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")
self.assertEqual(
self.harness.model.unit.status,
Expand Down Expand Up @@ -237,7 +275,7 @@ def test_given_certificates_not_stored_when_pebble_ready_then_status_is_waiting(
self.harness.add_relation(
relation_name="certificates", remote_app="tls-certificates-operator"
)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")
self.assertEqual(
self.harness.model.unit.status,
Expand Down Expand Up @@ -280,7 +318,7 @@ def test_given_relations_created_and_database_available_and_nrf_data_available_a
relation_name="certificates", remote_app="tls-certificates-operator"
)
self.harness.charm._on_certificate_available(event=event)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")
with open("tests/unit/expected_config/config.conf") as expected_config_file:
expected_content = expected_config_file.read()
Expand Down Expand Up @@ -335,7 +373,7 @@ def test_given_content_of_config_file_changed_when_pebble_ready_then_config_file
relation_name="certificates", remote_app="tls-certificates-operator"
)
self.harness.charm._on_certificate_available(event=event)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")
with open("tests/unit/expected_config/config.conf") as expected_config_file:
expected_content = expected_config_file.read()
Expand Down Expand Up @@ -387,7 +425,7 @@ def test_given_content_of_config_file_not_changed_when_pebble_ready_then_config_
self.harness.add_relation(
relation_name="certificates", remote_app="tls-certificates-operator"
)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")
patch_push.assert_called_once_with(
path="/support/TLS/amf.key",
Expand Down Expand Up @@ -420,7 +458,7 @@ def test_given_relations_available_and_config_pushed_when_pebble_ready_then_pebb
self.harness.add_relation(
relation_name="certificates", remote_app="tls-certificates-operator"
)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")
expected_plan = {
"services": {
Expand Down Expand Up @@ -470,7 +508,7 @@ def test_relations_available_and_config_pushed_and_pebble_updated_when_pebble_re
self.harness.add_relation(
relation_name="certificates", remote_app="tls-certificates-operator"
)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")
self.assertEqual(
self.harness.model.unit.status,
Expand All @@ -495,7 +533,7 @@ def test_given_empty_ip_address_when_pebble_ready_then_status_is_waiting(
self.harness.add_relation(
relation_name="certificates", remote_app="tls-certificates-operator"
)
self._database_is_available()
self._create_database_relation_and_populate_data()

self.harness.container_pebble_ready(container_name="amf")

Expand Down Expand Up @@ -556,7 +594,7 @@ def test_given_n2_information_and_service_is_running_when_fiveg_n2_relation_join
self.harness.add_relation(
relation_name="certificates", remote_app="tls-certificates-operator"
)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")

relation_id = self.harness.add_relation(relation_name="fiveg-n2", remote_app="n2-requirer")
Expand Down Expand Up @@ -606,7 +644,7 @@ def test_given_n2_information_and_service_is_running_and_n2_config_is_overriden_
self.harness.update_config(
{"external-amf-ip": "2.2.2.2", "external-amf-hostname": "amf.burger.com"}
)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")

relation_id = self.harness.add_relation(relation_name="fiveg-n2", remote_app="n2-requirer")
Expand Down Expand Up @@ -652,7 +690,7 @@ def test_given_n2_information_and_service_is_running_and_lb_service_has_no_hostn
relation_name="certificates", remote_app="tls-certificates-operator"
)
self.harness.update_config({"external-amf-ip": "2.2.2.2"})
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")

relation_id = self.harness.add_relation(relation_name="fiveg-n2", remote_app="n2-requirer")
Expand Down Expand Up @@ -699,7 +737,7 @@ def test_given_n2_information_and_service_is_running_and_metallb_service_is_not_
self.harness.add_relation(
relation_name="certificates", remote_app="tls-certificates-operator"
)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")
relation_id = self.harness.add_relation(relation_name="fiveg-n2", remote_app="n2-requirer")
self.harness.add_relation_unit(relation_id=relation_id, remote_unit_name="n2-requirer/0")
Expand Down Expand Up @@ -749,7 +787,7 @@ def test_given_service_starts_running_after_n2_relation_joined_when_pebble_ready
self.harness.add_relation(
relation_name="certificates", remote_app="tls-certificates-operator"
)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")

relation_data = self.harness.get_relation_data(
Expand Down Expand Up @@ -795,7 +833,7 @@ def test_given_more_than_one_n2_requirers_join_n2_relation_when_service_starts_t
self.harness.add_relation(
relation_name="certificates", remote_app="tls-certificates-operator"
)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready("amf")

relation_1_id = self.harness.add_relation(
Expand Down Expand Up @@ -868,7 +906,7 @@ def test_given_certificates_are_stored_when_on_certificates_relation_broken_then
self.harness.add_relation(
relation_name="certificates", remote_app="tls-certificates-operator"
)
self._database_is_available()
self._create_database_relation_and_populate_data()
self.harness.charm._on_certificates_relation_broken(event=Mock())
self.assertEqual(
self.harness.charm.unit.status, BlockedStatus("Waiting for certificates relation")
Expand Down

0 comments on commit 82a4370

Please sign in to comment.