diff --git a/src/charm.py b/src/charm.py index 151ce0a4..3f2e8045 100755 --- a/src/charm.py +++ b/src/charm.py @@ -180,7 +180,9 @@ def remove_secret(self, scope, key) -> None: content = secret.get_content() if not content.get(key) or content[key] == Config.Secrets.SECRET_DELETED_LABEL: - logger.error(f"Non-existing secret {scope}:{key} was attempted to be removed.") + logger.error( + f"Non-existing secret {scope}:{key} was attempted to be removed." + ) return content[key] = Config.Secrets.SECRET_DELETED_LABEL @@ -266,7 +268,9 @@ def set_user_roles(self, roles: List[str]) -> None: return # a mongos shard can only be related to one config server - config_server_rel = self.model.relations[Config.Relations.CLUSTER_RELATIONS_NAME][0] + config_server_rel = self.model.relations[ + Config.Relations.CLUSTER_RELATIONS_NAME + ][0] self.cluster.database_requires.update_relation_data( config_server_rel.id, {USER_ROLES_TAG: roles_str} ) @@ -279,14 +283,18 @@ def set_database(self, database: str) -> None: return # a mongos shard can only be related to one config server - config_server_rel = self.model.relations[Config.Relations.CLUSTER_RELATIONS_NAME][0] + config_server_rel = self.model.relations[ + Config.Relations.CLUSTER_RELATIONS_NAME + ][0] self.cluster.database_requires.update_relation_data( config_server_rel.id, {DATABASE_TAG: database} ) def set_external_connectivity(self, external_connectivity: bool) -> None: """Sets the connectivity type for mongos.""" - self.app_peer_data[EXTERNAL_CONNECTIVITY_TAG] = json.dumps(external_connectivity) + self.app_peer_data[EXTERNAL_CONNECTIVITY_TAG] = json.dumps( + external_connectivity + ) def check_relation_broken_or_scale_down(self, event: RelationDepartedEvent) -> None: """Checks relation departed event is the result of removed relation or scale down. @@ -360,7 +368,9 @@ def _unit_ip(self, unit: Unit) -> str: """Returns the ip address of a given unit.""" # check if host is current host if unit == self.unit: - return str(self.model.get_binding(Config.Relations.PEERS).network.bind_address) + return str( + self.model.get_binding(Config.Relations.PEERS).network.bind_address + ) # check if host is a peer elif unit in self._peers.data: return str(self._peers.data[unit].get("private-address")) diff --git a/tests/integration/external_relations/test_charm.py b/tests/integration/external_relations/test_charm.py index d5b6f781..29ad6834 100644 --- a/tests/integration/external_relations/test_charm.py +++ b/tests/integration/external_relations/test_charm.py @@ -100,7 +100,9 @@ async def test_mongos_starts_with_config_server(ops_test: OpsTest) -> None: ) mongos_unit = ops_test.model.applications[MONGOS_APP_NAME].units[0] - mongos_running = await check_mongos(ops_test, mongos_unit, auth=False, external=True) + mongos_running = await check_mongos( + ops_test, mongos_unit, auth=False, external=True + ) assert mongos_running, "Mongos is not currently running." @@ -110,6 +112,10 @@ async def test_mongos_has_user(ops_test: OpsTest) -> None: """Verify mongos has user and is able to connect externally via IP-address.""" mongos_unit = ops_test.model.applications[MONGOS_APP_NAME].units[0] mongos_running = await check_mongos( - ops_test, mongos_unit, app_name=DATA_INTEGRATOR_APP_NAME, auth=True, external=True + ops_test, + mongos_unit, + app_name=DATA_INTEGRATOR_APP_NAME, + auth=True, + external=True, ) assert mongos_running, "Mongos is not currently running." diff --git a/tests/integration/helpers.py b/tests/integration/helpers.py index a68e4619..35c39751 100644 --- a/tests/integration/helpers.py +++ b/tests/integration/helpers.py @@ -4,7 +4,6 @@ import json import yaml from typing import Optional, Dict -import subprocess MONGOS_SOCKET = "%2Fvar%2Fsnap%2Fcharmed-mongodb%2Fcommon%2Fvar%2Fmongodb-27018.sock" MONGOS_APP_NAME = "mongos" @@ -12,7 +11,11 @@ async def generate_mongos_command( - ops_test: OpsTest, auth: bool, app_name: Optional[str], uri: str = None, external: bool = False + ops_test: OpsTest, + auth: bool, + app_name: Optional[str], + uri: str = None, + external: bool = False, ) -> str: """Generates a command which verifies mongos is running.""" mongodb_uri = uri or await generate_mongos_uri(ops_test, auth, app_name, external) @@ -28,7 +31,9 @@ async def check_mongos( external: bool = False, ) -> bool: """Returns whether mongos is running on the provided unit.""" - mongos_check = await generate_mongos_command(ops_test, auth, app_name, uri, external) + mongos_check = await generate_mongos_command( + ops_test, auth, app_name, uri, external + ) # since mongos is communicating only via the unix domain socket, we cannot connect to it via # traditional pymongo methods @@ -64,12 +69,16 @@ async def generate_mongos_uri( ) -> str: """Generates a URI for accessing mongos.""" host = ( - MONGOS_SOCKET if not external else await get_ip_address(ops_test, app_name=MONGOS_APP_NAME) + MONGOS_SOCKET + if not external + else await get_ip_address(ops_test, app_name=MONGOS_APP_NAME) ) if not auth: return f"mongodb://{host}:27018" - secret_uri = await get_application_relation_data(ops_test, app_name, "mongos", "secret-user") + secret_uri = await get_application_relation_data( + ops_test, app_name, "mongos", "secret-user" + ) secret_data = await get_secret_data(ops_test, secret_uri) return secret_data.get("uris") @@ -116,7 +125,9 @@ async def get_application_relation_data( data = yaml.safe_load(raw_data) # Filter the data based on the relation name. - relation_data = [v for v in data[unit.name]["relation-info"] if v["endpoint"] == relation_name] + relation_data = [ + v for v in data[unit.name]["relation-info"] if v["endpoint"] == relation_name + ] if relation_id: # Filter the data based on the relation id. relation_data = [v for v in relation_data if v["relation-id"] == relation_id] diff --git a/tests/integration/test_charm.py b/tests/integration/test_charm.py index 39c1c07e..b26578f0 100644 --- a/tests/integration/test_charm.py +++ b/tests/integration/test_charm.py @@ -165,9 +165,15 @@ async def test_user_with_extra_roles(ops_test: OpsTest) -> None: return_code == 0 ), f"mongos user does not have correct permissions to create new user, error: {std_err}" - test_user_uri = f"mongodb://{TEST_USER_NAME}:{TEST_USER_PWD}@{MONGOS_SOCKET}/{TEST_DB_NAME}" + test_user_uri = ( + f"mongodb://{TEST_USER_NAME}:{TEST_USER_PWD}@{MONGOS_SOCKET}/{TEST_DB_NAME}" + ) mongos_running = await check_mongos( - ops_test, mongos_unit, app_name=APPLICATION_APP_NAME, auth=True, uri=test_user_uri + ops_test, + mongos_unit, + app_name=APPLICATION_APP_NAME, + auth=True, + uri=test_user_uri, ) assert mongos_running, "User created is not accessible." @@ -237,7 +243,9 @@ async def test_mongos_stops_without_config_server(ops_test: OpsTest) -> None: secrets = await get_application_relation_data( ops_test, "application", "mongos_proxy", "secret-user" ) - assert secrets is None, "mongos still has connection info without being connected to cluster." + assert ( + secrets is None + ), "mongos still has connection info without being connected to cluster." # verify that Charmed MongoDB is blocked waiting for config-server await ops_test.model.wait_for_idle( diff --git a/tests/unit/test_config_server_lib.py b/tests/unit/test_config_server_lib.py index d24c38f2..42236a10 100644 --- a/tests/unit/test_config_server_lib.py +++ b/tests/unit/test_config_server_lib.py @@ -31,9 +31,7 @@ def setUp(self): # related to duplicated events. delattr(DatabaseRequiresEvents, f"{CLUSTER_ALIAS}_database_created") delattr(DatabaseRequiresEvents, f"{CLUSTER_ALIAS}_endpoints_changed") - delattr( - DatabaseRequiresEvents, f"{CLUSTER_ALIAS}_read_only_endpoints_changed" - ) + delattr(DatabaseRequiresEvents, f"{CLUSTER_ALIAS}_read_only_endpoints_changed") except AttributeError: # Ignore the events not existing before the first test. pass @@ -48,14 +46,18 @@ def setUp(self): @patch("ops.framework.EventBase.defer") @patch("charm.ClusterRequirer.update_keyfile") def test_on_relation_changed_waits_keyfile(self, update_keyfile, defer): - """Tests that relation changed waits for keyfile.""" + """Tests that relation changed does not wait for keyfile. + + When mongos is incorrectly integrated with a non-config server (ie shard), it can end up + waiting forever for a keyfile + """ # fails due to being run on non-config-server - relation_id = self.harness.add_relation("cluster", "config-server") - self.harness.add_relation_unit(relation_id, "config-server/0") - self.harness.update_relation_data(relation_id, "config-server/0", PEER_ADDR) + relation_id = self.harness.add_relation("cluster", "shard") + self.harness.add_relation_unit(relation_id, "shard/0") + self.harness.update_relation_data(relation_id, "shard/0", PEER_ADDR) update_keyfile.assert_not_called() - defer.assert_called() + defer.assert_not_called() @patch("charm.MongosOperatorCharm.push_file_to_unit") @patch("charm.MongosOperatorCharm.get_keyfile_contents")