class TestDashboardConsumer(unittest.TestCase): def setUp(self): self.harness = Harness(ConsumerCharm, meta=CONSUMER_META) self.harness._backend.model_name = "testing" self.harness._backend.model_uuid = "abcdefgh-1234" self.addCleanup(self.harness.cleanup) self.harness.set_leader(True) self.harness.begin() def test_consumer_does_not_set_dashboard_without_monitoring(self): rel_id = self.harness.add_relation("grafana-dashboard", "consumer") self.harness.add_relation_unit(rel_id, "consumer/0") self.harness.charm.consumer.add_dashboard(DASHBOARD_TMPL) self.assertEqual(self.harness.charm._stored.invalid_events, 1) def test_consumer_sets_dashboard_data(self): rel_id = self.harness.add_relation("grafana-dashboard", "consumer") self.harness.add_relation_unit(rel_id, "consumer/0") mon_rel_id = self.harness.add_relation("monitoring", "consumer") self.harness.add_relation_unit(mon_rel_id, "monitoring/0") self.harness.charm.consumer.add_dashboard(DASHBOARD_TMPL) data = json.loads( self.harness.get_relation_data( rel_id, self.harness.model.app.name)["dashboards"]) return_data = { "monitoring_identifier": "testing_abcdefgh-1234_monitoring", "monitoring_target": "Consumer-tester [ testing / abcdefgh-1234 ]", "monitoring_query": "juju_model='testing',juju_model_uuid='abcdefgh-1234',juju_application='consumer-tester'", "template": "\n\n", "removed": False, "invalidated": False, "invalidated_reason": "", "uuid": "12345678", } self.assertEqual(return_data, data) def test_consumer_can_remove_dashboard(self): rel_id = self.harness.add_relation("grafana-dashboard", "consumer") self.harness.add_relation_unit(rel_id, "consumer/0") mon_rel_id = self.harness.add_relation("monitoring", "consumer") self.harness.add_relation_unit(mon_rel_id, "monitoring/0") self.harness.charm.consumer.add_dashboard(DASHBOARD_TMPL) data = json.loads( self.harness.get_relation_data( rel_id, self.harness.model.app.name)["dashboards"]) return_data = { "monitoring_identifier": "testing_abcdefgh-1234_monitoring", "monitoring_target": "Consumer-tester [ testing / abcdefgh-1234 ]", "monitoring_query": "juju_model='testing',juju_model_uuid='abcdefgh-1234',juju_application='consumer-tester'", "template": "\n\n", "removed": False, "invalidated": False, "invalidated_reason": "", "uuid": "12345678", } self.assertEqual(return_data, data) self.harness.charm.consumer.remove_dashboard() return_data = { "monitoring_identifier": "testing_abcdefgh-1234_monitoring", "monitoring_target": "Consumer-tester [ testing / abcdefgh-1234 ]", "monitoring_query": "juju_model='testing',juju_model_uuid='abcdefgh-1234',juju_application='consumer-tester'", "template": "\n\n", "removed": True, "invalidated": False, "invalidated_reason": "", "uuid": "12345678", } def test_consumer_resends_dashboard_after_monitoring_established(self): rel_id = self.harness.add_relation("grafana-dashboard", "consumer") self.harness.add_relation_unit(rel_id, "consumer/0") self.harness.charm.consumer.add_dashboard(DASHBOARD_TMPL) self.assertEqual(self.harness.charm._stored.invalid_events, 1) mon_rel_id = self.harness.add_relation("monitoring", "consumer") self.harness.add_relation_unit(mon_rel_id, "monitoring/0") data = json.loads( self.harness.get_relation_data( rel_id, self.harness.model.app.name)["dashboards"]) return_data = { "monitoring_identifier": "testing_abcdefgh-1234_monitoring", "monitoring_target": "Consumer-tester [ testing / abcdefgh-1234 ]", "monitoring_query": "juju_model='testing',juju_model_uuid='abcdefgh-1234',juju_application='consumer-tester'", "template": "\n\n", "removed": False, "invalidated": False, "invalidated_reason": "", "uuid": "12345678", } self.assertEqual(return_data, data) def test_consumer_invalidates_dashboard_after_monitoring_established_then_broken( self, ): rel_id = self.harness.add_relation("grafana-dashboard", "consumer") self.harness.add_relation_unit(rel_id, "consumer/0") self.harness.charm.consumer.add_dashboard(DASHBOARD_TMPL) self.assertEqual(self.harness.charm._stored.invalid_events, 1) mon_rel_id = self.harness.add_relation("monitoring", "consumer") self.harness.add_relation_unit(mon_rel_id, "monitoring/0") self.harness.remove_relation(mon_rel_id) data = json.loads( self.harness.get_relation_data( rel_id, self.harness.model.app.name)["dashboards"]) return_data = { "monitoring_identifier": "testing_abcdefgh-1234_monitoring", "monitoring_target": "Consumer-tester [ testing / abcdefgh-1234 ]", "monitoring_query": "juju_model='testing',juju_model_uuid='abcdefgh-1234',juju_application='consumer-tester'", "template": "\n\n", "removed": False, "invalidated": True, "invalidated_reason": "Waiting for a monitoring relation to send dashboard data", "uuid": "12345678", } self.assertEqual(return_data, data) self.assertEqual(self.harness.charm._stored.invalid_events, 1)
class TestDatase(unittest.TestCase): def setUp(self): self.harness = Harness(MySQLOperatorCharm) self.addCleanup(self.harness.cleanup) self.harness.begin() self.peer_relation_id = self.harness.add_relation( "database-peers", "database-peers") self.harness.add_relation_unit(self.peer_relation_id, "mysql/1") self.database_relation_id = self.harness.add_relation( DB_RELATION_NAME, "app") self.harness.add_relation_unit(self.database_relation_id, "app/0") self.charm = self.harness.charm @patch_network_get(private_address="1.1.1.1") @patch("mysqlsh_helpers.MySQL.get_mysql_version", return_value="8.0.29-0ubuntu0.20.04.3") @patch( "mysqlsh_helpers.MySQL.get_cluster_members_addresses", return_value={"2.2.2.1:3306", "2.2.2.3:3306", "2.2.2.2:3306"}, ) @patch("mysqlsh_helpers.MySQL.get_cluster_primary_address", return_value="2.2.2.2:3306") @patch("mysqlsh_helpers.MySQL.create_application_database_and_scoped_user") @patch("relations.database.generate_random_password", return_value="super_secure_password") def test_database_requested( self, _generate_random_password, _create_application_database_and_scoped_user, _get_cluster_primary_address, _get_cluster_members_addresses, _get_mysql_version, ): # run start-up events to enable usage of the helper class self.harness.set_leader(True) self.charm.on.config_changed.emit() # confirm that the relation databag is empty database_relation_databag = self.harness.get_relation_data( self.database_relation_id, self.harness.charm.app) database_relation = self.charm.model.get_relation(DB_RELATION_NAME) app_unit = list(database_relation.units)[0] # simulate cluster initialized by editing the flag self.harness.update_relation_data(self.peer_relation_id, self.charm.app.name, {"units-added-to-cluster": "1"}) self.assertEqual(database_relation_databag, {}) self.assertEqual(database_relation.data.get(app_unit), {}) self.assertEqual(database_relation.data.get(self.charm.unit), {}) # update the app leader unit data to trigger database_requested event self.harness.update_relation_data(self.database_relation_id, "app", {"database": "test_db"}) self.assertEqual( database_relation_databag, { "data": '{"database": "test_db"}', "password": "******", "username": f"relation-{self.database_relation_id}", "endpoints": "2.2.2.2:3306", "version": "8.0.29-0ubuntu0.20.04.3", "read-only-endpoints": "2.2.2.1:3306,2.2.2.3:3306", }, ) _generate_random_password.assert_called_once() _create_application_database_and_scoped_user.assert_called_once() _get_cluster_primary_address.assert_called_once() _get_cluster_members_addresses.assert_called_once() _get_mysql_version.assert_called_once() @patch_network_get(private_address="1.1.1.1") @patch("mysqlsh_helpers.MySQL.delete_user_for_relation") def test_database_broken(self, _delete_user_for_relation): # run start-up events to enable usage of the helper class self.harness.set_leader(True) self.charm.on.config_changed.emit() self.harness.remove_relation(self.database_relation_id) _delete_user_for_relation.assert_called_once_with( self.database_relation_id) @patch_network_get(private_address="1.1.1.1") @patch("mysqlsh_helpers.MySQL.delete_user_for_relation") def test_database_broken_failure(self, _delete_user_for_relation): # run start-up events to enable usage of the helper class self.harness.set_leader(True) self.charm.on.config_changed.emit() _delete_user_for_relation.side_effect = MySQLDeleteUserForRelationError( ) self.harness.remove_relation(self.database_relation_id) _delete_user_for_relation.assert_called_once()
class TestMariaDBRelation(unittest.TestCase): def setUp(self): self.harness = Harness(MySQLOperatorCharm) self.addCleanup(self.harness.cleanup) self.harness.begin() self.peer_relation_id = self.harness.add_relation( "database-peers", "database-peers") self.harness.add_relation_unit(self.peer_relation_id, "mysql/1") self.charm = self.harness.charm @patch_network_get(private_address="1.1.1.1") @patch("mysqlsh_helpers.MySQL.does_mysql_user_exist", return_value=False) @patch("mysqlsh_helpers.MySQL.get_cluster_primary_address", return_value="1.1.1.1:3306") @patch( "relations.mysql.MySQLRelation._get_or_set_password_in_peer_databag", return_value="super_secure_password", ) @patch("mysqlsh_helpers.MySQL.create_application_database_and_scoped_user") def test_maria_db_relation_created( self, _create_application_database_and_scoped_user, _get_or_set_password_in_peer_databag, _get_cluster_primary_address, _does_mysql_user_exist, ): # run start-up events to enable usage of the helper class self.harness.set_leader(True) self.charm.on.config_changed.emit() self.harness.update_config({ "mysql-interface-user": "******", "mysql-interface-database": "default_database" }) # Relate to emit relation created event self.maria_db_relation_id = self.harness.add_relation( LEGACY_MYSQL, "other-app") self.harness.add_relation_unit(self.maria_db_relation_id, "other-app/0") self.assertEqual(_get_or_set_password_in_peer_databag.call_count, 1) _create_application_database_and_scoped_user.assert_called_once_with( "default_database", "mysql", "super_secure_password", "%", "mysql-legacy-relation") _get_cluster_primary_address.assert_called_once() _does_mysql_user_exist.assert_called_once_with("mysql", "%") maria_db_relation = self.charm.model.get_relation(LEGACY_MYSQL) peer_relation = self.charm.model.get_relation(PEER) # confirm that the relation databag is populated self.assertEqual( maria_db_relation.data.get(self.charm.unit), { "database": "default_database", "host": "1.1.1.1", "password": "******", "port": "3306", "root_password": peer_relation.data.get(self.charm.app)["root-password"], "user": "******", }, ) @patch_network_get(private_address="1.1.1.1") @patch("mysqlsh_helpers.MySQL.does_mysql_user_exist", return_value=False) @patch("mysqlsh_helpers.MySQL.get_cluster_primary_address", return_value="1.1.1.1:3306") @patch("mysqlsh_helpers.MySQL.delete_users_for_unit") @patch( "relations.mysql.MySQLRelation._get_or_set_password_in_peer_databag", return_value="super_secure_password", ) @patch("mysqlsh_helpers.MySQL.create_application_database_and_scoped_user") def test_maria_db_relation_departed( self, _create_application_database_and_scoped_user, _get_or_set_password_in_peer_databag, _delete_users_for_unit, _get_cluster_primary_address, _does_mysql_user_exist, ): # run start-up events to enable usage of the helper class self.harness.set_leader(True) self.charm.on.config_changed.emit() self.maria_db_relation_id = self.harness.add_relation( LEGACY_MYSQL, "other-app") self.harness.add_relation_unit(self.maria_db_relation_id, "other-app/0") # Workaround ops.testing not setting `departing_unit` in v1.5.0 # ref https://github.com/canonical/operator/pull/790 maria_db_relation = self.charm.model.get_relation(LEGACY_MYSQL) with patch.object(RelationDepartedEvent, "departing_unit", new_callable=PropertyMock) as mock_departing_unit: mock_departing_unit.return_value = list(maria_db_relation.units)[0] self.harness.remove_relation(self.maria_db_relation_id) _delete_users_for_unit.assert_called_once_with("mysql-legacy-relation")