Skip to content

Commit

Permalink
Try not to rerender on legacy rel change
Browse files Browse the repository at this point in the history
  • Loading branch information
dragomirp committed Feb 10, 2024
1 parent 57c6d4c commit 1ae3f8c
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 4 deletions.
1 change: 0 additions & 1 deletion src/relations/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,6 @@ def _on_relation_changed(self, change_event: RelationChangedEvent):
change_event.defer()
return

self.charm.render_pgb_config(reload_pgbouncer=True)
if self.charm.unit.is_leader():
self.update_connection_info(change_event.relation, self.charm.config["listen_port"])
self.update_databags(
Expand Down
163 changes: 160 additions & 3 deletions tests/unit/relations/test_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# See LICENSE file for licensing details.

import unittest
from unittest.mock import MagicMock, patch
from unittest.mock import Mock, PropertyMock, patch

from charms.pgbouncer_k8s.v0.pgb import parse_dict_to_kv_string
from ops.testing import Harness
Expand Down Expand Up @@ -59,11 +59,127 @@ def test_correct_admin_perms_set_in_constructor(self):
assert self.charm.legacy_db_admin_relation.relation_name == "db-admin"
assert self.charm.legacy_db_admin_relation.admin is True

@patch("relations.backend_database.BackendDatabaseRequires.check_backend", return_value=True)
@patch(
"relations.backend_database.BackendDatabaseRequires.postgres", new_callable=PropertyMock
)
@patch("charms.pgbouncer_k8s.v0.pgb.generate_password", return_value="test_pass")
@patch("charms.postgresql_k8s.v0.postgresql.PostgreSQL")
@patch("charms.postgresql_k8s.v0.postgresql.PostgreSQL.create_user")
@patch("charms.postgresql_k8s.v0.postgresql.PostgreSQL.create_database")
@patch("relations.backend_database.BackendDatabaseRequires.initialise_auth_function")
@patch("charm.PgBouncerK8sCharm.set_relation_databases")
@patch("charm.PgBouncerK8sCharm.generate_relation_databases")
def test_on_relation_joined(
self,
_gen_rel_dbs,
_set_rel_dbs,
_init_auth,
_create_database,
_create_user,
_postgres,
_gen_pw,
_backend_pg,
_check_backend,
):
self.harness.set_leader(True)

_gen_rel_dbs.return_value = {}

mock_event = Mock()
mock_event.app.name = "external_test_app"
mock_event.relation.id = 1

database = "test_db"
user = "pgbouncer_k8s_user_1_None"
password = _gen_pw.return_value

_set_rel_dbs.reset_mock()
relation_data = mock_event.relation.data = {}
relation_data[self.charm.unit] = {}
relation_data[self.charm.app] = {}
relation_data[mock_event.app] = {"database": database}
_backend_pg.return_value = _postgres
_postgres.create_user = _create_user
_postgres.create_database = _create_database

_set_rel_dbs.reset_mock()
self.db_admin_relation._on_relation_joined(mock_event)
_set_rel_dbs.assert_called_once_with({1: {'name': "test_db", "legacy": True}})

_create_user.assert_called_with(user, password, admin=True)
_create_database.assert_called_with(database, user)
_init_auth.assert_called_with([database])

for dbag in [relation_data[self.charm.unit], relation_data[self.charm.app]]:
assert dbag["database"] == database
assert dbag["user"] == user
assert dbag["password"] == password

# Check admin permissions aren't present when we use db_relation
_set_rel_dbs.reset_mock()
self.db_relation._on_relation_joined(mock_event)
_create_user.assert_called_with(user, password, admin=False)
_set_rel_dbs.assert_called_once_with({1: {'name': "test_db", "legacy": True}})

@patch("relations.backend_database.BackendDatabaseRequires.check_backend", return_value=True)
@patch(
"relations.backend_database.BackendDatabaseRequires.postgres", new_callable=PropertyMock
)
@patch("relations.db.DbProvides.get_databags", return_value=[{}])
@patch("relations.db.DbProvides.update_connection_info")
@patch("relations.db.DbProvides.update_databags")
@patch("relations.db.DbProvides.get_allowed_units")
@patch("relations.db.DbProvides.get_allowed_subnets")
@patch("relations.db.DbProvides._get_state")
def test_on_relation_changed(
self,
_get_state,
_allowed_subnets,
_allowed_units,
_update_databags,
_update_connection_info,
_get_databags,
_backend_postgres,
_check_backend,
):
self.harness.set_leader()

database = "test_db"
user = "test_user"
password = "test_pw"
_get_databags.return_value[0] = {
"database": database,
"user": user,
"password": password,
}

# Call the function
event = Mock()
self.db_relation._on_relation_changed(event)

_update_connection_info.assert_called_with(
event.relation, self.charm.config["listen_port"]
)
_update_databags.assert_called_with(
event.relation,
{
"allowed-subnets": _allowed_subnets.return_value,
"allowed-units": _allowed_units.return_value,
"version": self.charm.backend.postgres.get_postgresql_version(),
"host": self.charm.unit_pod_hostname,
"user": user,
"password": password,
"database": database,
"state": _get_state.return_value,
},
)

@patch("relations.db.DbProvides.get_databags", return_value=[{}])
@patch("relations.db.DbProvides.get_external_app")
@patch("relations.db.DbProvides.update_databags")
def test_update_connection_info(self, _update_databags, _get_external_app, _get_databags):
relation = MagicMock()
relation = Mock()
database = "test_db"
user = "test_user"
password = "test_pw"
Expand Down Expand Up @@ -104,7 +220,7 @@ def test_update_connection_info(self, _update_databags, _get_external_app, _get_
@patch("relations.db.DbProvides.get_allowed_units", return_value="test_string")
def test_on_relation_departed(self, _get_units):
self.harness.set_leader(True)
mock_event = MagicMock()
mock_event = Mock()
mock_event.relation.data = {
self.charm.app: {"allowed-units": "app"},
self.charm.unit: {"allowed-units": "unit"},
Expand All @@ -119,3 +235,44 @@ def test_on_relation_departed(self, _get_units):

self.assertDictEqual(app_databag, expected_app_databag)
self.assertDictEqual(unit_databag, expected_unit_databag)

@patch("relations.backend_database.BackendDatabaseRequires.check_backend", return_value=True)
@patch("charms.postgresql_k8s.v0.postgresql.PostgreSQL")
@patch("charms.postgresql_k8s.v0.postgresql.PostgreSQL.delete_user")
@patch(
"relations.backend_database.BackendDatabaseRequires.postgres", new_callable=PropertyMock
)
@patch("relations.backend_database.BackendDatabaseRequires.remove_auth_function")
@patch("charm.PgBouncerK8sCharm.set_relation_databases")
@patch("charm.PgBouncerK8sCharm.generate_relation_databases")
def test_on_relation_broken(
self,
_gen_rel_dbs,
_set_rel_dbs,
_remove_auth,
_backend_postgres,
_delete_user,
_postgres,
_check_backend,
):
_gen_rel_dbs.return_value = {"42": {"name": "test_db", "legacy": True}}
self.harness.set_leader(True)
database = "test_db"
username = "test_user"
_backend_postgres.return_value = _postgres
_postgres.delete_user = _delete_user

mock_event = Mock()
databag = {
"user": username,
"database": database,
}
mock_event.relation.id = 42
mock_event.relation.data = {}
mock_event.relation.data[self.charm.unit] = databag
mock_event.relation.data[self.charm.app] = databag

self.db_relation._on_relation_broken(mock_event)

_delete_user.assert_called_once_with(username)
_set_rel_dbs.assert_called_once_with({})

0 comments on commit 1ae3f8c

Please sign in to comment.