From 83129c2eeae43794dd8744a899c828c2d45c9bd8 Mon Sep 17 00:00:00 2001 From: Alex Petenchea Date: Sun, 8 Sep 2024 18:49:44 +0300 Subject: [PATCH] Adding 3.12.2 features --- arango/cluster.py | 55 ++++++++++++++++++++++++++++++++++++++++++ arango/database.py | 17 +++++++++++-- arango/exceptions.py | 4 +++ tests/test_cluster.py | 24 ++++++++++++++++++ tests/test_database.py | 7 ++++-- 5 files changed, 103 insertions(+), 4 deletions(-) diff --git a/arango/cluster.py b/arango/cluster.py index dffaeb04..ea13279d 100644 --- a/arango/cluster.py +++ b/arango/cluster.py @@ -15,6 +15,7 @@ ClusterServerRoleError, ClusterServerStatisticsError, ClusterServerVersionError, + ClusterVpackSortMigrationError, ) from arango.formatter import format_body from arango.request import Request @@ -444,3 +445,57 @@ def response_handler(resp: Response) -> bool: return result return self._execute(request, response_handler) + + def vpack_sort_migration_status(self) -> Result[Json]: + """Query the status of the vpack sorting migration. + + :return: Status of the VPack sort migration. + :rtype: dict + """ + request = Request( + method="get", endpoint="/_admin/cluster/vpackSortMigration/status" + ) + + def response_handler(resp: Response) -> Json: + if not resp.is_success: + raise ClusterVpackSortMigrationError(resp, request) + result: Json = resp.body["result"] + return result + + return self._execute(request, response_handler) + + def vpack_sort_migration_index_check(self) -> Result[Json]: + """Check for indexes impacted by the sorting behavior before 3.12.2. + + :return: Status of indexes. + :rtype: dict + """ + request = Request( + method="get", endpoint="/_admin/cluster/vpackSortMigration/check" + ) + + def response_handler(resp: Response) -> Json: + if not resp.is_success: + raise ClusterVpackSortMigrationError(resp, request) + result: Json = resp.body["result"] + return result + + return self._execute(request, response_handler) + + def migrate_vpack_sorting(self) -> Result[Json]: + """Migrate instances to the new VPack sorting behavior. + + :return: Status of the VPack sort migration. + :rtype: dict + """ + request = Request( + method="put", endpoint="/_admin/cluster/vpackSortMigration/migrate" + ) + + def response_handler(resp: Response) -> Json: + if not resp.is_success: + raise ClusterVpackSortMigrationError(resp, request) + result: Json = resp.body["result"] + return result + + return self._execute(request, response_handler) diff --git a/arango/database.py b/arango/database.py index 22f6d731..6145b8fb 100644 --- a/arango/database.py +++ b/arango/database.py @@ -935,7 +935,9 @@ def response_handler(resp: Response) -> Json: return self._execute(request, response_handler) - def log_levels(self, server_id: Optional[str] = None) -> Result[Json]: + def log_levels( + self, server_id: Optional[str] = None, with_appenders: Optional[bool] = None + ) -> Result[Json]: """Return current logging levels. :param server_id: Forward log level to a specific server. This makes it @@ -943,12 +945,16 @@ def log_levels(self, server_id: Optional[str] = None) -> Result[Json]: JWT authentication whereas Coordinators also support authentication using usernames and passwords. :type server_id: str + :param with_appenders: Include appenders in the response. + :type with_appenders: bool :return: Current logging levels. :rtype: dict """ params: Params = {} if server_id is not None: params["serverId"] = server_id + if with_appenders is not None: + params["withAppenders"] = with_appenders request = Request(method="get", endpoint="/_admin/log/level", params=params) @@ -961,7 +967,10 @@ def response_handler(resp: Response) -> Json: return self._execute(request, response_handler) def set_log_levels( - self, server_id: Optional[str] = None, **kwargs: Dict[str, Any] + self, + server_id: Optional[str] = None, + with_appenders: Optional[bool] = None, + **kwargs: Dict[str, Any], ) -> Result[Json]: """Set the logging levels. @@ -983,6 +992,8 @@ def set_log_levels( JWT authentication whereas Coordinators also support authentication using usernames and passwords. :type server_id: str | None + :param with_appenders: Include appenders in the request. + :type with_appenders: bool | None :param kwargs: Logging levels. :type kwargs: Dict[str, Any] :return: New logging levels. @@ -991,6 +1002,8 @@ def set_log_levels( params: Params = {} if server_id is not None: params["serverId"] = server_id + if with_appenders is not None: + params["withAppenders"] = with_appenders request = Request( method="put", endpoint="/_admin/log/level", params=params, data=kwargs diff --git a/arango/exceptions.py b/arango/exceptions.py index 58d99088..28295b2b 100644 --- a/arango/exceptions.py +++ b/arango/exceptions.py @@ -1047,6 +1047,10 @@ class ClusterRebalanceError(ArangoServerError): """Failed to execute cluster re-balancing operation (load/set).""" +class ClusterVpackSortMigrationError(ArangoServerError): + """Failed to execute vpack sort migration request.""" + + ################## # JWT Exceptions # ################## diff --git a/tests/test_cluster.py b/tests/test_cluster.py index d5ab4365..0a4cd19f 100644 --- a/tests/test_cluster.py +++ b/tests/test_cluster.py @@ -2,6 +2,7 @@ import warnings import pytest +from packaging import version from arango.errno import DATABASE_NOT_FOUND, FORBIDDEN from arango.exceptions import ( @@ -16,6 +17,7 @@ ClusterServerRoleError, ClusterServerStatisticsError, ClusterServerVersionError, + ClusterVpackSortMigrationError, ) from tests.helpers import assert_raises @@ -235,3 +237,25 @@ def test_cluster_rebalance(sys_db, bad_db, cluster): with assert_raises(ClusterRebalanceError) as err: bad_db.cluster.rebalance() assert err.value.error_code == FORBIDDEN + + +def test_vpack_sort_migration(sys_db, bad_db, db_version, cluster): + if not cluster: + pytest.skip("Only tested in a cluster setup") + if db_version < version.parse("3.12.2"): + pytest.skip("vpackSortMigration is only tested in 3.12.2+") + + sys_db.cluster.vpack_sort_migration_status() + with assert_raises(ClusterVpackSortMigrationError) as err: + bad_db.cluster.vpack_sort_migration_status() + assert err.value.error_code == FORBIDDEN + + sys_db.cluster.vpack_sort_migration_index_check() + with assert_raises(ClusterVpackSortMigrationError) as err: + bad_db.cluster.vpack_sort_migration_index_check() + assert err.value.error_code == FORBIDDEN + + sys_db.cluster.migrate_vpack_sorting() + with assert_raises(ClusterVpackSortMigrationError) as err: + bad_db.cluster.migrate_vpack_sorting() + assert err.value.error_code == FORBIDDEN diff --git a/tests/test_database.py b/tests/test_database.py index 6ac64e1f..1a716400 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -99,8 +99,8 @@ def test_database_misc_methods(client, sys_db, db, bad_db, cluster, secret, db_v assert err.value.error_code in {11, 1228} # Test get server required database version - version = db.required_db_version() - assert isinstance(version, str) + required_version = db.required_db_version() + assert isinstance(required_version, str) # Test get server target version with bad database with assert_raises(ServerRequiredDBVersionError): @@ -252,6 +252,9 @@ def test_database_misc_methods(client, sys_db, db, bad_db, cluster, secret, db_v # Test get log levels default_log_levels = sys_db.log_levels() assert isinstance(default_log_levels, dict) + if db_version >= version.parse("3.12.2"): + log_levels_with_appenders = sys_db.log_levels(with_appenders=True) + assert isinstance(log_levels_with_appenders, dict) # Test get log levels with bad database with assert_raises(ServerLogLevelError) as err: