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

xuanwo pushed a commit to branch xuanwo/behavior-script
in repository https://gitbox.apache.org/repos/asf/opendal.git

commit 49e1b72cd465f41f5149bc69398ab5860f8e6746
Author: Xuanwo <[email protected]>
AuthorDate: Mon Dec 22 19:12:43 2025 +0800

    ci: Refactor behavior test planner for services split
---
 .github/scripts/test_behavior/plan.py      | 98 ++++++++----------------------
 .github/scripts/test_behavior/test_plan.py | 15 ++++-
 2 files changed, 39 insertions(+), 74 deletions(-)

diff --git a/.github/scripts/test_behavior/plan.py 
b/.github/scripts/test_behavior/plan.py
index 3a05e333f..162ea2f85 100755
--- a/.github/scripts/test_behavior/plan.py
+++ b/.github/scripts/test_behavior/plan.py
@@ -33,8 +33,6 @@ PROJECT_DIR = GITHUB_DIR.parent
 
 LANGUAGE_BINDING = ["java", "python", "nodejs", "go", "c", "cpp"]
 
-BIN = []
-
 INTEGRATIONS = ["object_store"]
 
 
@@ -92,8 +90,6 @@ class Hint:
     binding_c: bool = field(default=False, init=False)
     # Is binding cpp affected?
     binding_cpp: bool = field(default=False, init=False)
-    # Is bin ofs affected?
-    bin_ofs: bool = field(default=False, init=False)
     # Is integration object_store affected ?
     integration_object_store: bool = field(default=False, init=False)
 
@@ -109,6 +105,17 @@ def calculate_hint(changed_files: list[str]) -> Hint:
     # Remove all files that end with `.md`
     changed_files = [f for f in changed_files if not f.endswith(".md")]
 
+    def mark_service_affected(service: str) -> None:
+        hint.core = True
+        for language in LANGUAGE_BINDING:
+            setattr(hint, f"binding_{language}", True)
+        for integration in INTEGRATIONS:
+            setattr(hint, f"integration_{integration}", True)
+
+        hint.services.add(service)
+        hint.services.add(service.replace("-", "_"))
+        hint.services.add(service.replace("_", "-"))
+
     for p in changed_files:
         # workflow behavior tests affected
         if p == ".github/workflows/test_behavior.yml":
@@ -128,11 +135,6 @@ def calculate_hint(changed_files: list[str]) -> Hint:
                 setattr(hint, f"binding_{language}", True)
                 hint.all_service = True
 
-        for bin in BIN:
-            if p == f".github/workflows/test_behavior_bin_{bin}.yml":
-                setattr(hint, f"bin_{bin}", True)
-                hint.all_service = True
-
         for integration in INTEGRATIONS:
             if p == 
f".github/workflows/test_behavior_integration_{integration}.yml":
                 setattr(hint, f"integration_{integration}", True)
@@ -145,7 +147,10 @@ def calculate_hint(changed_files: list[str]) -> Hint:
             and not p.startswith("core/edge/")
             and not p.startswith("core/fuzz/")
             and not p.startswith("core/src/services/")
+            and not p.startswith("core/core/src/services/")
+            and not p.startswith("core/services/")
             and not p.startswith("core/src/docs/")
+            and not p.startswith("core/core/src/docs/")
         ):
             hint.core = True
             hint.binding_java = True
@@ -154,7 +159,6 @@ def calculate_hint(changed_files: list[str]) -> Hint:
             hint.binding_go = True
             hint.binding_c = True
             hint.binding_cpp = True
-            hint.bin_ofs = True
             for integration in INTEGRATIONS:
                 setattr(hint, f"integration_{integration}", True)
             hint.all_service = True
@@ -181,12 +185,6 @@ def calculate_hint(changed_files: list[str]) -> Hint:
             hint.binding_go = True
             hint.all_service = True
 
-        # bin affected
-        for bin in BIN:
-            if p.startswith(f"bin/{bin}"):
-                setattr(hint, f"bin_{bin}", True)
-                hint.all_service = True
-
         # integration affected
         for integration in INTEGRATIONS:
             if p.startswith(f"integrations/{integration}"):
@@ -196,38 +194,27 @@ def calculate_hint(changed_files: list[str]) -> Hint:
         # core service affected
         match = re.search(r"core/src/services/([^/]+)/", p)
         if match:
-            hint.core = True
-            for language in LANGUAGE_BINDING:
-                setattr(hint, f"binding_{language}", True)
-            for bin in BIN:
-                setattr(hint, f"bin_{bin}", True)
-            for integration in INTEGRATIONS:
-                setattr(hint, f"integration_{integration}", True)
-            hint.services.add(match.group(1))
+            mark_service_affected(match.group(1))
+
+        # service crate affected
+        match = re.search(r"core/services/([^/]+)/", p)
+        if match:
+            mark_service_affected(match.group(1))
+
+        # opendal-core internal service affected
+        match = re.search(r"core/core/src/services/([^/]+)/", p)
+        if match:
+            mark_service_affected(match.group(1))
 
         # core test affected
         match = re.search(r".github/services/([^/]+)/", p)
         if match:
-            hint.core = True
-            for language in LANGUAGE_BINDING:
-                setattr(hint, f"binding_{language}", True)
-            for bin in BIN:
-                setattr(hint, f"bin_{bin}", True)
-            for integration in INTEGRATIONS:
-                setattr(hint, f"integration_{integration}", True)
-            hint.services.add(match.group(1))
+            mark_service_affected(match.group(1))
 
         # fixture affected
         match = re.search(r"fixtures/([^/]+)/", p)
         if match:
-            hint.core = True
-            for language in LANGUAGE_BINDING:
-                setattr(hint, f"binding_{language}", True)
-            for bin in BIN:
-                setattr(hint, f"bin_{bin}", True)
-            for integration in INTEGRATIONS:
-                setattr(hint, f"integration_{integration}", True)
-            hint.services.add(match.group(1))
+            mark_service_affected(match.group(1))
 
     return hint
 
@@ -300,29 +287,6 @@ def generate_language_binding_cases(
     return cases
 
 
-def generate_bin_cases(
-    cases: list[dict[str, str]], hint: Hint, bin: str
-) -> list[dict[str, str]]:
-    # Return empty if this bin is False
-    if not getattr(hint, f"bin_{bin}"):
-        return []
-
-    cases = unique_cases(cases)
-
-    if bin == "ofs":
-        supported_services = ["fs", "s3"]
-        cases = [v for v in cases if v["service"] in supported_services]
-
-    # Return all services if all_service is True
-    if hint.all_service:
-        return cases
-
-    # Filter all cases that not shown up in changed files
-    cases = [v for v in cases if v["service"] in hint.services]
-
-    return cases
-
-
 def generate_integration_cases(
     cases: list[dict[str, str]], hint: Hint, integration: str
 ) -> list[dict[str, str]]:
@@ -401,14 +365,6 @@ def plan(changed_files: list[str]) -> dict[str, Any]:
                     }
                 )
 
-    for bin in BIN:
-        jobs[f"bin_{bin}"] = []
-        jobs["components"][f"bin_{bin}"] = False
-        bin_cases = generate_bin_cases(cases, hint, bin)
-        if len(bin_cases) > 0:
-            jobs["components"][f"bin_{bin}"] = True
-            jobs[f"bin_{bin}"].append({"os": "ubuntu-latest", "cases": 
bin_cases})
-
     for integration in INTEGRATIONS:
         jobs[f"integration_{integration}"] = []
         jobs["components"][f"integration_{integration}"] = False
diff --git a/.github/scripts/test_behavior/test_plan.py 
b/.github/scripts/test_behavior/test_plan.py
index aa213c7ba..6c31ac5ae 100644
--- a/.github/scripts/test_behavior/test_plan.py
+++ b/.github/scripts/test_behavior/test_plan.py
@@ -33,16 +33,25 @@ class BehaviorTestPlan(unittest.TestCase):
         self.assertTrue(result["components"]["core"])
 
     def test_core_services_fs(self):
-        result = plan(["core/src/services/fs/mod.rs"])
+        result = plan(["core/services/fs/src/lib.rs"])
         self.assertTrue(result["components"]["core"])
         self.assertTrue(len(result["core"]) > 0)
 
         cases = [v["service"] for v in result["core"][0]["cases"]]
-        # Should not contain fs
+        # Should contain fs
         self.assertTrue("fs" in cases)
         # Should not contain s3
         self.assertFalse("s3" in cases)
 
+    def test_core_services_hdfs_native_mapping(self):
+        result = plan(["core/services/hdfs-native/src/lib.rs"])
+        self.assertTrue(result["components"]["core"])
+        self.assertTrue(len(result["core"]) > 0)
+
+        cases = [v["service"] for v in result["core"][0]["cases"]]
+        self.assertTrue("hdfs_native" in cases)
+        self.assertFalse("fs" in cases)
+
     def test_binding_java(self):
         result = plan(["bindings/java/pom.xml"])
         self.assertFalse(result["components"]["core"])
@@ -56,7 +65,7 @@ class BehaviorTestPlan(unittest.TestCase):
         self.assertTrue(result["components"]["integration_object_store"])
         self.assertTrue(len(result["integration_object_store"]) > 0)
 
-        result = plan(["core/src/services/fs/mod.rs"])
+        result = plan(["core/services/fs/src/lib.rs"])
         cases = [v["service"] for v in 
result["integration_object_store"][0]["cases"]]
         # Should contain fs
         self.assertTrue("fs" in cases)

Reply via email to