This is an automated email from the ASF dual-hosted git repository.

jerryshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new 4059726b7f [#5820] test(client-python): Improve IT server lifecycle 
(#11977)
4059726b7f is described below

commit 4059726b7f6435941d710b4f223da9767cc9698f
Author: Henry Chen <[email protected]>
AuthorDate: Thu Jul 16 12:00:34 2026 +0800

    [#5820] test(client-python): Improve IT server lifecycle (#11977)
    
    ### What changes were proposed in this pull request?
    
    This PR improves the Gravitino server lifecycle used by Python client
    integration tests.
    
    The Gradle `integrationTest` task now uses dedicated
    `startGravitinoServer` and `stopGravitinoServer` tasks, with
    `stopGravitinoServer` registered through `finalizedBy` so Gradle
    attempts to stop the server even when the integration test task fails.
    
    When `START_EXTERNAL_GRAVITINO=true` and the expected external Gravitino
    server is unavailable, fail the integration test immediately with a
    clear exception instead of only logging an error and continuing.
    
    This PR also centralizes the `START_EXTERNAL_GRAVITINO` check in
    `IntegrationTestEnv.use_external_gravitino()` and updates several
    authorization-related integration tests to reuse that helper.
    
    ### Why are the changes needed?
    
    The Python client integration test setup already supports using an
    externally started Gravitino server in CI. However, the server lifecycle
    logic was still embedded directly inside the `integrationTest` task, and
    the external-server environment check was duplicated across multiple
    test classes.
    
    Separating start and stop into dedicated Gradle tasks makes the
    lifecycle easier to understand and safer on failure. Centralizing the
    environment check also keeps related integration tests consistent.
    
    Failing fast makes a missing or unreachable externally managed server
    immediately visible to CI and developers, avoiding follow-up failures
    with less actionable error messages.
    
    Related to #5820.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No. This change only affects Python client integration test
    infrastructure.
    
    ### How was this patch tested?
    
    - `git diff --check`
---
 clients/client-python/build.gradle.kts                | 19 +++++++++++++------
 .../tests/integration/integration_test_env.py         | 19 ++++++++++---------
 .../tests/integration/test_group_management.py        | 10 ++--------
 clients/client-python/tests/integration/test_owner.py | 10 ++--------
 .../tests/integration/test_role_management.py         | 10 ++--------
 clients/client-python/tests/integration/test_user.py  | 10 ++--------
 6 files changed, 31 insertions(+), 47 deletions(-)

diff --git a/clients/client-python/build.gradle.kts 
b/clients/client-python/build.gradle.kts
index a0caf0d523..3311608c80 100644
--- a/clients/client-python/build.gradle.kts
+++ b/clients/client-python/build.gradle.kts
@@ -186,11 +186,22 @@ tasks {
     args = listOf("scripts/generate_version.py")
   }
 
-  val integrationTest by registering(VenvTask::class) {
-    doFirst {
+  val stopGravitinoServer by registering {
+    doLast {
+      gravitinoServer("stop")
+    }
+  }
+
+  val startGravitinoServer by registering {
+    finalizedBy(stopGravitinoServer)
+    doLast {
       gravitinoServer("start")
     }
+  }
 
+  val integrationTest by registering(VenvTask::class) {
+    dependsOn(startGravitinoServer)
+    finalizedBy(stopGravitinoServer)
     venvExec = "coverage"
     args = listOf("run", "--branch", "-m", "unittest")
     workingDir = projectDir.resolve("./tests/integration")
@@ -213,10 +224,6 @@ tasks {
       "PYTHONPATH" to "${project.rootDir.path}/clients/client-python"
     ))
     environment = envMap
-
-    doLast {
-      gravitinoServer("stop")
-    }
   }
 
   val unitCoverageReport by registering(VenvTask::class){
diff --git a/clients/client-python/tests/integration/integration_test_env.py 
b/clients/client-python/tests/integration/integration_test_env.py
index ca943ab6f6..03bd013334 100644
--- a/clients/client-python/tests/integration/integration_test_env.py
+++ b/clients/client-python/tests/integration/integration_test_env.py
@@ -67,15 +67,19 @@ class IntegrationTestEnv(unittest.TestCase):
     gravitino_startup_script = None
     gravitino_admin_client: GravitinoAdminClient = None
 
+    @staticmethod
+    def use_external_gravitino() -> bool:
+        return os.environ.get("START_EXTERNAL_GRAVITINO", "").lower() == "true"
+
     @classmethod
     def setUpClass(cls):
-        if (
-            os.environ.get("START_EXTERNAL_GRAVITINO") is not None
-            and os.environ.get("START_EXTERNAL_GRAVITINO").lower() == "true"
-        ):
+        if cls.use_external_gravitino():
             # Maybe Gravitino server already startup by Gradle test command or 
developer manual startup.
             if not check_gravitino_server_status():
-                logger.error("ERROR: Can't find online Gravitino server!")
+                raise GravitinoRuntimeException(
+                    "Gravitino server at http://localhost:8090/api/version is 
unavailable "
+                    "while START_EXTERNAL_GRAVITINO is enabled."
+                )
             return
 
         cls._get_gravitino_home()
@@ -117,10 +121,7 @@ class IntegrationTestEnv(unittest.TestCase):
 
     @classmethod
     def tearDownClass(cls):
-        if (
-            os.environ.get("START_EXTERNAL_GRAVITINO") is not None
-            and os.environ.get("START_EXTERNAL_GRAVITINO").lower() == "true"
-        ):
+        if cls.use_external_gravitino():
             return
 
         logger.info("Stop integration test environment...")
diff --git a/clients/client-python/tests/integration/test_group_management.py 
b/clients/client-python/tests/integration/test_group_management.py
index 1e0a8c0095..8917d63984 100644
--- a/clients/client-python/tests/integration/test_group_management.py
+++ b/clients/client-python/tests/integration/test_group_management.py
@@ -44,10 +44,7 @@ class TestGroupManagement(IntegrationTestEnv):
         }
         cls._reset_conf(auth_confs, conf_path)
         cls._append_conf(auth_confs, conf_path)
-        if (
-            os.environ.get("START_EXTERNAL_GRAVITINO") is not None
-            and os.environ.get("START_EXTERNAL_GRAVITINO").lower() == "true"
-        ):
+        if cls.use_external_gravitino():
             cls.restart_server()
         else:
             super().setUpClass()
@@ -62,10 +59,7 @@ class TestGroupManagement(IntegrationTestEnv):
         }
         cls._reset_conf(reset_confs, conf_path)
         cls._append_conf(reset_confs, conf_path)
-        if (
-            os.environ.get("START_EXTERNAL_GRAVITINO") is not None
-            and os.environ.get("START_EXTERNAL_GRAVITINO").lower() == "true"
-        ):
+        if cls.use_external_gravitino():
             cls.restart_server()
         else:
             super().tearDownClass()
diff --git a/clients/client-python/tests/integration/test_owner.py 
b/clients/client-python/tests/integration/test_owner.py
index f292fcb4da..563b6869c6 100644
--- a/clients/client-python/tests/integration/test_owner.py
+++ b/clients/client-python/tests/integration/test_owner.py
@@ -52,10 +52,7 @@ class TestOwner(IntegrationTestEnv):
         conf_path = os.path.join(cls.gravitino_home, "conf", "gravitino.conf")
         cls._reset_conf({"gravitino.authorization.enable": "true"}, conf_path)
         cls._append_conf({"gravitino.authorization.enable": "true"}, conf_path)
-        if (
-            os.environ.get("START_EXTERNAL_GRAVITINO") is not None
-            and os.environ.get("START_EXTERNAL_GRAVITINO").lower() == "true"
-        ):
+        if cls.use_external_gravitino():
             cls.restart_server()
         else:
             super().setUpClass()
@@ -65,10 +62,7 @@ class TestOwner(IntegrationTestEnv):
     def tearDownClass(cls):
         conf_path = os.path.join(cls.gravitino_home, "conf", "gravitino.conf")
         cls._reset_conf({"gravitino.authorization.enable": "false"}, conf_path)
-        if (
-            os.environ.get("START_EXTERNAL_GRAVITINO") is not None
-            and os.environ.get("START_EXTERNAL_GRAVITINO").lower() == "true"
-        ):
+        if cls.use_external_gravitino():
             cls.restart_server()
         else:
             super().tearDownClass()
diff --git a/clients/client-python/tests/integration/test_role_management.py 
b/clients/client-python/tests/integration/test_role_management.py
index 99e6df2dfd..5486f8fa0c 100644
--- a/clients/client-python/tests/integration/test_role_management.py
+++ b/clients/client-python/tests/integration/test_role_management.py
@@ -46,10 +46,7 @@ class TestRoleManagement(IntegrationTestEnv):
         }
         cls._reset_conf(auth_confs, conf_path)
         cls._append_conf(auth_confs, conf_path)
-        if (
-            os.environ.get("START_EXTERNAL_GRAVITINO") is not None
-            and os.environ.get("START_EXTERNAL_GRAVITINO").lower() == "true"
-        ):
+        if cls.use_external_gravitino():
             cls.restart_server()
         else:
             super().setUpClass()
@@ -64,10 +61,7 @@ class TestRoleManagement(IntegrationTestEnv):
         }
         cls._reset_conf(reset_confs, conf_path)
         cls._append_conf(reset_confs, conf_path)
-        if (
-            os.environ.get("START_EXTERNAL_GRAVITINO") is not None
-            and os.environ.get("START_EXTERNAL_GRAVITINO").lower() == "true"
-        ):
+        if cls.use_external_gravitino():
             cls.restart_server()
         else:
             super().tearDownClass()
diff --git a/clients/client-python/tests/integration/test_user.py 
b/clients/client-python/tests/integration/test_user.py
index 9178df7600..f8720b1f1d 100644
--- a/clients/client-python/tests/integration/test_user.py
+++ b/clients/client-python/tests/integration/test_user.py
@@ -47,10 +47,7 @@ class TestUser(IntegrationTestEnv):
         }
         cls._reset_conf(auth_confs, conf_path)
         cls._append_conf(auth_confs, conf_path)
-        if (
-            os.environ.get("START_EXTERNAL_GRAVITINO") is not None
-            and os.environ.get("START_EXTERNAL_GRAVITINO").lower() == "true"
-        ):
+        if cls.use_external_gravitino():
             cls.restart_server()
         else:
             super().setUpClass()
@@ -65,10 +62,7 @@ class TestUser(IntegrationTestEnv):
         }
         cls._reset_conf(reset_confs, conf_path)
         cls._append_conf(reset_confs, conf_path)
-        if (
-            os.environ.get("START_EXTERNAL_GRAVITINO") is not None
-            and os.environ.get("START_EXTERNAL_GRAVITINO").lower() == "true"
-        ):
+        if cls.use_external_gravitino():
             cls.restart_server()
         else:
             super().tearDownClass()

Reply via email to