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

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


The following commit(s) were added to refs/heads/main by this push:
     new 31af3a58d27 Fix selective tests checks when system tests are modified 
(#45131)
31af3a58d27 is described below

commit 31af3a58d27c47e47c9d8d0422f205477f428fc2
Author: Jarek Potiuk <[email protected]>
AuthorDate: Sat Dec 21 16:09:36 2024 +0100

    Fix selective tests checks when system tests are modified (#45131)
    
    When providers system tests were modified in provider tests were
    modified, selective checks had two bugs that compounded led to provider 
tests
    being skipped.
    
    1) Modification of system tests lead to "all providers affected"
       condition (wrongly) - because "TESTS" were checked as root path
       before "SYSTEM TESTS" - and since system tests were subfolder
       of tests, the code that checked if system tests path belongs
       to provider never found it.
    
    2) "All Providers affected" in such case (when it was not caused by
       another condition lead to "skip-provider-tests" set to true due
       to missing "else" in one of the conditions.
    
    This PR fixes both cases and simplifies the conditions so that they are
    easier to understand and modify. Those conditions will be further
    simplified when we separate providers to separate projects #44511
    because there we will not have to check separately several sub-folders
    of airflow, but for now it's good enough.
    
    Some of those conditions are simplified as well because we are in
    Python 3.9+ and "is_relative_to" is now available in Path.
---
 .../src/airflow_breeze/utils/selective_checks.py   | 65 +++++++-------
 dev/breeze/tests/test_selective_checks.py          | 98 ++++++++++++++++++++++
 2 files changed, 130 insertions(+), 33 deletions(-)

diff --git a/dev/breeze/src/airflow_breeze/utils/selective_checks.py 
b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
index 07b25ae98c7..1a7b2f1d2d5 100644
--- a/dev/breeze/src/airflow_breeze/utils/selective_checks.py
+++ b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
@@ -326,30 +326,28 @@ TEST_TYPE_EXCLUDES = HashableDict({})
 
 def find_provider_affected(changed_file: str, include_docs: bool) -> str | 
None:
     file_path = AIRFLOW_SOURCES_ROOT / changed_file
-    # is_relative_to is only available in Python 3.9 - we should simplify this 
check when we are Python 3.9+
-    for provider_root in (TESTS_PROVIDERS_ROOT, SYSTEM_TESTS_PROVIDERS_ROOT, 
AIRFLOW_PROVIDERS_NS_PACKAGE):
-        try:
-            file_path.relative_to(provider_root)
-            relative_base_path = provider_root
+    # Check providers in SRC/SYSTEM_TESTS/TESTS/(optionally) DOCS
+    for provider_root in (SYSTEM_TESTS_PROVIDERS_ROOT, TESTS_PROVIDERS_ROOT, 
AIRFLOW_PROVIDERS_NS_PACKAGE):
+        if file_path.is_relative_to(provider_root):
+            provider_base_path = provider_root
             break
-        except ValueError:
-            pass
     else:
-        if include_docs:
-            try:
-                relative_path = file_path.relative_to(DOCS_DIR)
-                if 
relative_path.parts[0].startswith("apache-airflow-providers-"):
-                    return 
relative_path.parts[0].replace("apache-airflow-providers-", "").replace("-", 
".")
-            except ValueError:
-                pass
+        if include_docs and file_path.is_relative_to(DOCS_DIR):
+            relative_path = file_path.relative_to(DOCS_DIR)
+            if relative_path.parts[0].startswith("apache-airflow-providers-"):
+                return 
relative_path.parts[0].replace("apache-airflow-providers-", "").replace("-", 
".")
         return None
 
+    # Find if the path under src/system tests/tests belongs to provider or is 
a common code across
+    # multiple providers
     for parent_dir_path in file_path.parents:
-        if parent_dir_path == relative_base_path:
+        if parent_dir_path == provider_base_path:
+            # We have not found any provider specific path up to the root of 
the provider base folder
             break
-        relative_path = parent_dir_path.relative_to(relative_base_path)
+        relative_path = parent_dir_path.relative_to(provider_base_path)
+        # check if this path belongs to a specific provider
         if (AIRFLOW_PROVIDERS_NS_PACKAGE / relative_path / 
"provider.yaml").exists():
-            return 
str(parent_dir_path.relative_to(relative_base_path)).replace(os.sep, ".")
+            return 
str(parent_dir_path.relative_to(provider_base_path)).replace(os.sep, ".")
     # If we got here it means that some "common" files were modified. so we 
need to test all Providers
     return "Providers"
 
@@ -852,14 +850,13 @@ class SelectiveChecks:
             )
         # sort according to predefined order
         sorted_candidate_test_types = sorted(candidate_test_types)
-        get_console().print("[warning]Selected test type candidates to 
run:[/]")
+        get_console().print("[warning]Selected core test type candidates to 
run:[/]")
         get_console().print(sorted_candidate_test_types)
         return sorted_candidate_test_types
 
     def _get_providers_test_types_to_run(self, split_to_individual_providers: 
bool = False) -> list[str]:
         if self._default_branch != "main":
             return []
-        affected_providers: AllProvidersSentinel | list[str] | None = 
ALL_PROVIDERS_SENTINEL
         if self.full_tests_needed:
             if split_to_individual_providers:
                 return list(providers_test_type())
@@ -885,18 +882,20 @@ class SelectiveChecks:
                     include_docs=False,
                 )
         candidate_test_types: set[str] = set()
-        if affected_providers and not isinstance(affected_providers, 
AllProvidersSentinel):
+        if isinstance(affected_providers, AllProvidersSentinel):
+            if split_to_individual_providers:
+                for provider in get_available_packages():
+                    candidate_test_types.add(f"Providers[{provider}]")
+            else:
+                candidate_test_types.add("Providers")
+        elif affected_providers:
             if split_to_individual_providers:
                 for provider in affected_providers:
                     candidate_test_types.add(f"Providers[{provider}]")
             else:
                 
candidate_test_types.add(f"Providers[{','.join(sorted(affected_providers))}]")
-        elif split_to_individual_providers:
-            candidate_test_types.discard("Providers")
-            for provider in get_available_packages():
-                candidate_test_types.add(f"Providers[{provider}]")
         sorted_candidate_test_types = sorted(candidate_test_types)
-        get_console().print("[warning]Selected test type candidates to 
run:[/]")
+        get_console().print("[warning]Selected providers test type candidates 
to run:[/]")
         get_console().print(sorted_candidate_test_types)
         return sorted_candidate_test_types
 
@@ -1442,7 +1441,7 @@ class SelectiveChecks:
         return self._github_actor in COMMITTERS
 
     def _find_all_providers_affected(self, include_docs: bool) -> list[str] | 
AllProvidersSentinel | None:
-        all_providers: set[str] = set()
+        affected_providers: set[str] = set()
 
         all_providers_affected = False
         suspended_providers: set[str] = set()
@@ -1454,11 +1453,11 @@ class SelectiveChecks:
                 if provider not in DEPENDENCIES:
                     suspended_providers.add(provider)
                 else:
-                    all_providers.add(provider)
+                    affected_providers.add(provider)
         if self.needs_api_tests:
-            all_providers.add("fab")
+            affected_providers.add("fab")
         if self.needs_ol_tests:
-            all_providers.add("openlineage")
+            affected_providers.add("openlineage")
         if all_providers_affected:
             return ALL_PROVIDERS_SENTINEL
         if suspended_providers:
@@ -1490,14 +1489,14 @@ class SelectiveChecks:
                 get_console().print(
                     "[info]This PR had `allow suspended provider changes` 
label set so it will continue"
                 )
-        if not all_providers:
+        if not affected_providers:
             return None
 
-        for provider in list(all_providers):
-            all_providers.update(
+        for provider in list(affected_providers):
+            affected_providers.update(
                 get_related_providers(provider, upstream_dependencies=True, 
downstream_dependencies=True)
             )
-        return sorted(all_providers)
+        return sorted(affected_providers)
 
     def _is_canary_run(self):
         return (
diff --git a/dev/breeze/tests/test_selective_checks.py 
b/dev/breeze/tests/test_selective_checks.py
index 7107b15a175..e020f7edfad 100644
--- a/dev/breeze/tests/test_selective_checks.py
+++ b/dev/breeze/tests/test_selective_checks.py
@@ -369,6 +369,104 @@ def assert_outputs_are_printed(expected_outputs: 
dict[str, str], stderr: str):
                 id="Selected Providers and docs should run",
             )
         ),
+        (
+            pytest.param(
+                ("providers/tests/system/apache/beam/file.py",),
+                {
+                    "selected-providers-list-as-string": "apache.beam 
common.compat google",
+                    "all-python-versions": "['3.9']",
+                    "all-python-versions-list-as-string": "3.9",
+                    "python-versions": "['3.9']",
+                    "python-versions-list-as-string": "3.9",
+                    "ci-image-build": "true",
+                    "prod-image-build": "false",
+                    "needs-helm-tests": "false",
+                    "run-tests": "true",
+                    "run-amazon-tests": "false",
+                    "docs-build": "false",
+                    "skip-pre-commits": (
+                        
"identity,lint-helm-chart,mypy-airflow,mypy-dev,mypy-docs"
+                        
",mypy-providers,mypy-task-sdk,ts-compile-format-lint-ui,ts-compile-format-lint-www"
+                    ),
+                    "run-kubernetes-tests": "false",
+                    "upgrade-to-newer-dependencies": "false",
+                    "core-test-types-list-as-string": "Always",
+                    "providers-test-types-list-as-string": 
"Providers[apache.beam,common.compat] Providers[google]",
+                    "individual-providers-test-types-list-as-string": 
"Providers[apache.beam] Providers[common.compat] Providers[google]",
+                    "needs-mypy": "true",
+                    "mypy-checks": "['mypy-providers']",
+                    "skip-providers-tests": "false",
+                },
+                id="Selected Providers and docs should run when system tests 
are modified",
+            )
+        ),
+        (
+            pytest.param(
+                ("providers/tests/system/apache/beam/file.py", 
"providers/tests/apache/beam/file.py"),
+                {
+                    "selected-providers-list-as-string": "apache.beam 
common.compat google",
+                    "all-python-versions": "['3.9']",
+                    "all-python-versions-list-as-string": "3.9",
+                    "python-versions": "['3.9']",
+                    "python-versions-list-as-string": "3.9",
+                    "ci-image-build": "true",
+                    "prod-image-build": "false",
+                    "needs-helm-tests": "false",
+                    "run-tests": "true",
+                    "run-amazon-tests": "false",
+                    "docs-build": "false",
+                    "skip-pre-commits": (
+                        
"identity,lint-helm-chart,mypy-airflow,mypy-dev,mypy-docs"
+                        
",mypy-providers,mypy-task-sdk,ts-compile-format-lint-ui,ts-compile-format-lint-www"
+                    ),
+                    "run-kubernetes-tests": "false",
+                    "upgrade-to-newer-dependencies": "false",
+                    "core-test-types-list-as-string": "Always",
+                    "providers-test-types-list-as-string": 
"Providers[apache.beam,common.compat] Providers[google]",
+                    "individual-providers-test-types-list-as-string": 
"Providers[apache.beam] Providers[common.compat] Providers[google]",
+                    "needs-mypy": "true",
+                    "mypy-checks": "['mypy-providers']",
+                    "skip-providers-tests": "false",
+                },
+                id="Selected Providers and docs should run when both system 
tests and tests are modified",
+            )
+        ),
+        (
+            pytest.param(
+                (
+                    "providers/tests/system/apache/beam/file.py",
+                    "providers/tests/apache/beam/file.py",
+                    "providers/tests/system/zendesk/file.py",
+                    "providers/tests/zendesk/file.py",
+                ),
+                {
+                    "selected-providers-list-as-string": "apache.beam 
common.compat google zendesk",
+                    "all-python-versions": "['3.9']",
+                    "all-python-versions-list-as-string": "3.9",
+                    "python-versions": "['3.9']",
+                    "python-versions-list-as-string": "3.9",
+                    "ci-image-build": "true",
+                    "prod-image-build": "false",
+                    "needs-helm-tests": "false",
+                    "run-tests": "true",
+                    "run-amazon-tests": "false",
+                    "docs-build": "false",
+                    "skip-pre-commits": (
+                        
"identity,lint-helm-chart,mypy-airflow,mypy-dev,mypy-docs"
+                        
",mypy-providers,mypy-task-sdk,ts-compile-format-lint-ui,ts-compile-format-lint-www"
+                    ),
+                    "run-kubernetes-tests": "false",
+                    "upgrade-to-newer-dependencies": "false",
+                    "core-test-types-list-as-string": "Always",
+                    "providers-test-types-list-as-string": 
"Providers[apache.beam,common.compat,zendesk] Providers[google]",
+                    "individual-providers-test-types-list-as-string": 
"Providers[apache.beam] Providers[common.compat] Providers[google] 
Providers[zendesk]",
+                    "needs-mypy": "true",
+                    "mypy-checks": "['mypy-providers']",
+                    "skip-providers-tests": "false",
+                },
+                id="Selected Providers and docs should run when both system 
tests and tests are modified for more than one provider",
+            )
+        ),
         (
             pytest.param(
                 ("docs/file.rst",),

Reply via email to