From 436ed79e01956ceed5fed0d173544928315d6296 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 27 Oct 2026 06:07:48 -0400 Subject: [PATCH 1/6] test(gapic-generator): manage Showcase test alignment when PyPI google-api-core lags monorepo --- .../gapic-generator/tests/system/conftest.py | 60 ++++++++++++++++++- .../tests/system/test_span_compliance.py | 5 ++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/packages/gapic-generator/tests/system/conftest.py b/packages/gapic-generator/tests/system/conftest.py index 83e92aadca2a..afd17d726f9a 100644 --- a/packages/gapic-generator/tests/system/conftest.py +++ b/packages/gapic-generator/tests/system/conftest.py @@ -13,10 +13,13 @@ # limitations under the License. +import filecmp import os +from pathlib import Path from typing import Sequence, Tuple from unittest import mock +import google.api_core import grpc import pytest import pytest_asyncio @@ -29,6 +32,59 @@ except ImportError: _observability = None + +def _installed_core_matches_monorepo() -> bool: + """Returns True if the installed google.api_core matches the monorepo source. + + When running Showcase tests against PyPI dependencies (e.g. non-canary CI jobs), + the installed `google-api-core` release may lag behind unreleased changes in + `packages/google-api-core`. Comparing the installed package files against the + monorepo source allows system tests to still execute end-to-end RPCs against + PyPI `google-api-core` while deferring strict monorepo-specific assertions to + `showcase-canary` (`INSTALL_LOCAL_CORE=true`). + """ + monorepo_core_dir = ( + Path(__file__).resolve().parents[3] / "google-api-core" / "google" / "api_core" + ) + if not monorepo_core_dir.is_dir() or not getattr(google.api_core, "__file__", None): + return True + + installed_core_dir = Path(google.api_core.__file__).resolve().parent + if installed_core_dir == monorepo_core_dir: + return True + + for src_file in monorepo_core_dir.rglob("*.py"): + rel_path = src_file.relative_to(monorepo_core_dir) + installed_file = installed_core_dir / rel_path + if not installed_file.is_file() or not filecmp.cmp( + src_file, installed_file, shallow=False + ): + return False + return True + + +INSTALLED_CORE_MATCHES_MONOREPO = _installed_core_matches_monorepo() + + +def pytest_configure(config): + config.addinivalue_line( + "markers", + "requires_current_core: mark test as requiring installed google-api-core to match monorepo source.", + ) + + +def pytest_collection_modifyitems(config, items): + if INSTALLED_CORE_MATCHES_MONOREPO: + return + skip_marker = pytest.mark.skip( + reason="Installed PyPI google-api-core differs from monorepo source; " + "validated by showcase-canary (INSTALL_LOCAL_CORE=true)." + ) + for item in items: + if "requires_current_core" in item.keywords: + item.add_marker(skip_marker) + + try: from google.auth.aio import credentials as ga_credentials_async @@ -38,8 +94,8 @@ HAS_GOOGLE_AUTH_AIO = False import google.auth from google.auth import credentials as ga_credentials - from google.showcase import EchoClient, IdentityClient, MessagingClient + try: from google.showcase import ResumableUploadServiceClient @@ -74,8 +130,8 @@ try: from google.showcase import ResumableUploadServiceAsyncClient from google.showcase_v1beta1.services.resumable_upload_service.transports.rest_asyncio import ( - AsyncResumableUploadServiceRestTransport, AsyncResumableUploadServiceRestInterceptor, + AsyncResumableUploadServiceRestTransport, ) HAS_ASYNC_REST_RESUMABLE_UPLOAD_TRANSPORT = True diff --git a/packages/gapic-generator/tests/system/test_span_compliance.py b/packages/gapic-generator/tests/system/test_span_compliance.py index 0fe731d9026f..87710a2225fc 100644 --- a/packages/gapic-generator/tests/system/test_span_compliance.py +++ b/packages/gapic-generator/tests/system/test_span_compliance.py @@ -715,6 +715,11 @@ def test_feature(feature_id: str, row: dict[str, str], span_exporter, monkeypatc f"(captured {len(tier_spans)} {tier} spans)" ) target_span = tier_spans[attempt_idx] + if not conftest.INSTALLED_CORE_MATCHES_MONOREPO: + pytest.skip( + "PyPI google-api-core differs from monorepo; " + "strict span attribute matrix is validated in showcase-canary" + ) assert_span_matches_row(target_span, row, t3_spans) From 7e7aa7eef80ea903041250bc2a6828b5f57698d1 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 27 Oct 2026 07:26:39 -0400 Subject: [PATCH 2/6] test(gapic-generator): use text comparison for monorepo core sync check --- packages/gapic-generator/tests/system/conftest.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/gapic-generator/tests/system/conftest.py b/packages/gapic-generator/tests/system/conftest.py index afd17d726f9a..50ee7fae4c3f 100644 --- a/packages/gapic-generator/tests/system/conftest.py +++ b/packages/gapic-generator/tests/system/conftest.py @@ -13,7 +13,6 @@ # limitations under the License. -import filecmp import os from pathlib import Path from typing import Sequence, Tuple @@ -56,8 +55,10 @@ def _installed_core_matches_monorepo() -> bool: for src_file in monorepo_core_dir.rglob("*.py"): rel_path = src_file.relative_to(monorepo_core_dir) installed_file = installed_core_dir / rel_path - if not installed_file.is_file() or not filecmp.cmp( - src_file, installed_file, shallow=False + if not installed_file.is_file(): + return False + if src_file.read_text(encoding="utf-8") != installed_file.read_text( + encoding="utf-8" ): return False return True From 778efdee3603f4dcfc26ab9b904e3703e2ee39b4 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 27 Oct 2026 09:45:51 -0400 Subject: [PATCH 3/6] test(gapic-generator): clarify monorepo core sync checks with named variables --- .../gapic-generator/tests/system/conftest.py | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/packages/gapic-generator/tests/system/conftest.py b/packages/gapic-generator/tests/system/conftest.py index 50ee7fae4c3f..eb254d668cd0 100644 --- a/packages/gapic-generator/tests/system/conftest.py +++ b/packages/gapic-generator/tests/system/conftest.py @@ -42,25 +42,42 @@ def _installed_core_matches_monorepo() -> bool: PyPI `google-api-core` while deferring strict monorepo-specific assertions to `showcase-canary` (`INSTALL_LOCAL_CORE=true`). """ + repo_root = Path(__file__).resolve().parents[4] monorepo_core_dir = ( - Path(__file__).resolve().parents[3] / "google-api-core" / "google" / "api_core" + repo_root / "packages" / "google-api-core" / "google" / "api_core" ) - if not monorepo_core_dir.is_dir() or not getattr(google.api_core, "__file__", None): + installed_core_init = getattr(google.api_core, "__file__", None) + + # Are we running outside the monorepo (e.g. in a standalone export) + # where the sibling `packages/google-api-core` directory does not exist? + # If so, there is no local monorepo source to compare against, so do not skip tests. + has_monorepo_source = monorepo_core_dir.is_dir() and installed_core_init is not None + if not has_monorepo_source: return True - installed_core_dir = Path(google.api_core.__file__).resolve().parent - if installed_core_dir == monorepo_core_dir: + # Was `google-api-core` installed in editable mode (`pip install -e`) + # or via PYTHONPATH directly from the monorepo (`showcase-canary`)? + # If both paths resolve to the same directory, the code is guaranteed to match. + installed_core_dir = Path(installed_core_init).resolve().parent + is_editable_monorepo_install = installed_core_dir == monorepo_core_dir + if is_editable_monorepo_install: return True - for src_file in monorepo_core_dir.rglob("*.py"): - rel_path = src_file.relative_to(monorepo_core_dir) - installed_file = installed_core_dir / rel_path + # Is `google-api-core` installed from PyPI into `site-packages`. + # Because `version.py` on `main` is not bumped until release time, we cannot + # rely on `__version__` to detect unreleased commits. Instead, verify that every + # Python file in the monorepo exists in the installed package with identical text. + for monorepo_file in monorepo_core_dir.rglob("*.py"): + relative_path = monorepo_file.relative_to(monorepo_core_dir) + installed_file = installed_core_dir / relative_path if not installed_file.is_file(): return False - if src_file.read_text(encoding="utf-8") != installed_file.read_text( - encoding="utf-8" - ): + + monorepo_code = monorepo_file.read_text(encoding="utf-8") + installed_code = installed_file.read_text(encoding="utf-8") + if monorepo_code != installed_code: return False + return True From 704ed7390845683a34b819aad3c0aef781816b48 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 27 Oct 2026 13:18:32 -0400 Subject: [PATCH 4/6] test(gapic-generator): scope core sync check by file and run assertions before skipping --- .../gapic-generator/tests/system/conftest.py | 46 ++++++++++++------- .../tests/system/test_span_compliance.py | 15 +++--- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/packages/gapic-generator/tests/system/conftest.py b/packages/gapic-generator/tests/system/conftest.py index eb254d668cd0..64ace1c1299d 100644 --- a/packages/gapic-generator/tests/system/conftest.py +++ b/packages/gapic-generator/tests/system/conftest.py @@ -13,6 +13,7 @@ # limitations under the License. +import functools import os from pathlib import Path from typing import Sequence, Tuple @@ -32,7 +33,8 @@ _observability = None -def _installed_core_matches_monorepo() -> bool: +@functools.lru_cache(maxsize=None) +def installed_core_matches_monorepo(*relative_paths: str) -> bool: """Returns True if the installed google.api_core matches the monorepo source. When running Showcase tests against PyPI dependencies (e.g. non-canary CI jobs), @@ -41,6 +43,11 @@ def _installed_core_matches_monorepo() -> bool: monorepo source allows system tests to still execute end-to-end RPCs against PyPI `google-api-core` while deferring strict monorepo-specific assertions to `showcase-canary` (`INSTALL_LOCAL_CORE=true`). + + Args: + *relative_paths: Optional file paths relative to `google/api_core` + (e.g. `"_observability.py"`). If omitted, all `.py` files in + `google/api_core` are compared. """ repo_root = Path(__file__).resolve().parents[4] monorepo_core_dir = ( @@ -63,14 +70,20 @@ def _installed_core_matches_monorepo() -> bool: if is_editable_monorepo_install: return True - # Is `google-api-core` installed from PyPI into `site-packages`. + # Is `google-api-core` installed from PyPI into `site-packages`? # Because `version.py` on `main` is not bumped until release time, we cannot - # rely on `__version__` to detect unreleased commits. Instead, verify that every - # Python file in the monorepo exists in the installed package with identical text. - for monorepo_file in monorepo_core_dir.rglob("*.py"): + # rely on `__version__` to detect unreleased commits. Instead, verify that the + # target Python file(s) in the monorepo exist in the installed package with + # identical text. + target_files = ( + [monorepo_core_dir / rel_path for rel_path in relative_paths] + if relative_paths + else list(monorepo_core_dir.rglob("*.py")) + ) + for monorepo_file in target_files: relative_path = monorepo_file.relative_to(monorepo_core_dir) installed_file = installed_core_dir / relative_path - if not installed_file.is_file(): + if not monorepo_file.is_file() or not installed_file.is_file(): return False monorepo_code = monorepo_file.read_text(encoding="utf-8") @@ -81,26 +94,27 @@ def _installed_core_matches_monorepo() -> bool: return True -INSTALLED_CORE_MATCHES_MONOREPO = _installed_core_matches_monorepo() +INSTALLED_CORE_MATCHES_MONOREPO = installed_core_matches_monorepo() def pytest_configure(config): config.addinivalue_line( "markers", - "requires_current_core: mark test as requiring installed google-api-core to match monorepo source.", + "requires_current_core(*relative_paths): mark test as requiring installed " + "google-api-core (or specific files within it) to match monorepo source.", ) def pytest_collection_modifyitems(config, items): - if INSTALLED_CORE_MATCHES_MONOREPO: - return - skip_marker = pytest.mark.skip( - reason="Installed PyPI google-api-core differs from monorepo source; " - "validated by showcase-canary (INSTALL_LOCAL_CORE=true)." - ) for item in items: - if "requires_current_core" in item.keywords: - item.add_marker(skip_marker) + marker = item.get_closest_marker("requires_current_core") + if marker is not None and not installed_core_matches_monorepo(*marker.args): + item.add_marker( + pytest.mark.skip( + reason="Installed PyPI google-api-core differs from monorepo source; " + "validated by showcase-canary (INSTALL_LOCAL_CORE=true)." + ) + ) try: diff --git a/packages/gapic-generator/tests/system/test_span_compliance.py b/packages/gapic-generator/tests/system/test_span_compliance.py index 87710a2225fc..a843ba51dd9e 100644 --- a/packages/gapic-generator/tests/system/test_span_compliance.py +++ b/packages/gapic-generator/tests/system/test_span_compliance.py @@ -715,12 +715,15 @@ def test_feature(feature_id: str, row: dict[str, str], span_exporter, monkeypatc f"(captured {len(tier_spans)} {tier} spans)" ) target_span = tier_spans[attempt_idx] - if not conftest.INSTALLED_CORE_MATCHES_MONOREPO: - pytest.skip( - "PyPI google-api-core differs from monorepo; " - "strict span attribute matrix is validated in showcase-canary" - ) - assert_span_matches_row(target_span, row, t3_spans) + try: + assert_span_matches_row(target_span, row, t3_spans) + except AssertionError: + if not conftest.installed_core_matches_monorepo("_observability.py"): + pytest.skip( + "PyPI google-api-core (_observability.py) differs from monorepo; " + "strict span attribute matrix is validated in showcase-canary" + ) + raise # --------------------------------------------------------------------------- From 5227d1c25f2498e6393b7c2a2dcd2821816f73e4 Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 27 Oct 2026 13:33:31 -0400 Subject: [PATCH 5/6] test(gapic-generator): run span assertions first and only skip on failure when core differs --- .../gapic-generator/tests/system/conftest.py | 46 +++++++------------ .../tests/system/test_span_compliance.py | 4 +- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/packages/gapic-generator/tests/system/conftest.py b/packages/gapic-generator/tests/system/conftest.py index 64ace1c1299d..eb254d668cd0 100644 --- a/packages/gapic-generator/tests/system/conftest.py +++ b/packages/gapic-generator/tests/system/conftest.py @@ -13,7 +13,6 @@ # limitations under the License. -import functools import os from pathlib import Path from typing import Sequence, Tuple @@ -33,8 +32,7 @@ _observability = None -@functools.lru_cache(maxsize=None) -def installed_core_matches_monorepo(*relative_paths: str) -> bool: +def _installed_core_matches_monorepo() -> bool: """Returns True if the installed google.api_core matches the monorepo source. When running Showcase tests against PyPI dependencies (e.g. non-canary CI jobs), @@ -43,11 +41,6 @@ def installed_core_matches_monorepo(*relative_paths: str) -> bool: monorepo source allows system tests to still execute end-to-end RPCs against PyPI `google-api-core` while deferring strict monorepo-specific assertions to `showcase-canary` (`INSTALL_LOCAL_CORE=true`). - - Args: - *relative_paths: Optional file paths relative to `google/api_core` - (e.g. `"_observability.py"`). If omitted, all `.py` files in - `google/api_core` are compared. """ repo_root = Path(__file__).resolve().parents[4] monorepo_core_dir = ( @@ -70,20 +63,14 @@ def installed_core_matches_monorepo(*relative_paths: str) -> bool: if is_editable_monorepo_install: return True - # Is `google-api-core` installed from PyPI into `site-packages`? + # Is `google-api-core` installed from PyPI into `site-packages`. # Because `version.py` on `main` is not bumped until release time, we cannot - # rely on `__version__` to detect unreleased commits. Instead, verify that the - # target Python file(s) in the monorepo exist in the installed package with - # identical text. - target_files = ( - [monorepo_core_dir / rel_path for rel_path in relative_paths] - if relative_paths - else list(monorepo_core_dir.rglob("*.py")) - ) - for monorepo_file in target_files: + # rely on `__version__` to detect unreleased commits. Instead, verify that every + # Python file in the monorepo exists in the installed package with identical text. + for monorepo_file in monorepo_core_dir.rglob("*.py"): relative_path = monorepo_file.relative_to(monorepo_core_dir) installed_file = installed_core_dir / relative_path - if not monorepo_file.is_file() or not installed_file.is_file(): + if not installed_file.is_file(): return False monorepo_code = monorepo_file.read_text(encoding="utf-8") @@ -94,27 +81,26 @@ def installed_core_matches_monorepo(*relative_paths: str) -> bool: return True -INSTALLED_CORE_MATCHES_MONOREPO = installed_core_matches_monorepo() +INSTALLED_CORE_MATCHES_MONOREPO = _installed_core_matches_monorepo() def pytest_configure(config): config.addinivalue_line( "markers", - "requires_current_core(*relative_paths): mark test as requiring installed " - "google-api-core (or specific files within it) to match monorepo source.", + "requires_current_core: mark test as requiring installed google-api-core to match monorepo source.", ) def pytest_collection_modifyitems(config, items): + if INSTALLED_CORE_MATCHES_MONOREPO: + return + skip_marker = pytest.mark.skip( + reason="Installed PyPI google-api-core differs from monorepo source; " + "validated by showcase-canary (INSTALL_LOCAL_CORE=true)." + ) for item in items: - marker = item.get_closest_marker("requires_current_core") - if marker is not None and not installed_core_matches_monorepo(*marker.args): - item.add_marker( - pytest.mark.skip( - reason="Installed PyPI google-api-core differs from monorepo source; " - "validated by showcase-canary (INSTALL_LOCAL_CORE=true)." - ) - ) + if "requires_current_core" in item.keywords: + item.add_marker(skip_marker) try: diff --git a/packages/gapic-generator/tests/system/test_span_compliance.py b/packages/gapic-generator/tests/system/test_span_compliance.py index a843ba51dd9e..6743fdfd09f4 100644 --- a/packages/gapic-generator/tests/system/test_span_compliance.py +++ b/packages/gapic-generator/tests/system/test_span_compliance.py @@ -718,9 +718,9 @@ def test_feature(feature_id: str, row: dict[str, str], span_exporter, monkeypatc try: assert_span_matches_row(target_span, row, t3_spans) except AssertionError: - if not conftest.installed_core_matches_monorepo("_observability.py"): + if not conftest.INSTALLED_CORE_MATCHES_MONOREPO: pytest.skip( - "PyPI google-api-core (_observability.py) differs from monorepo; " + "PyPI google-api-core differs from monorepo; " "strict span attribute matrix is validated in showcase-canary" ) raise From 1f69e89c5c79df7aed894095bc2790c85a148a2f Mon Sep 17 00:00:00 2001 From: chalmer lowe Date: Tue, 27 Oct 2026 16:14:54 -0400 Subject: [PATCH 6/6] test(gapic-generator): replace unused marker hooks with skip_on_core_mismatch context manager --- .../gapic-generator/tests/system/conftest.py | 30 ++++++++----------- .../tests/system/test_span_compliance.py | 9 +----- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/packages/gapic-generator/tests/system/conftest.py b/packages/gapic-generator/tests/system/conftest.py index eb254d668cd0..0f5643241f4f 100644 --- a/packages/gapic-generator/tests/system/conftest.py +++ b/packages/gapic-generator/tests/system/conftest.py @@ -13,6 +13,7 @@ # limitations under the License. +import contextlib import os from pathlib import Path from typing import Sequence, Tuple @@ -84,23 +85,18 @@ def _installed_core_matches_monorepo() -> bool: INSTALLED_CORE_MATCHES_MONOREPO = _installed_core_matches_monorepo() -def pytest_configure(config): - config.addinivalue_line( - "markers", - "requires_current_core: mark test as requiring installed google-api-core to match monorepo source.", - ) - - -def pytest_collection_modifyitems(config, items): - if INSTALLED_CORE_MATCHES_MONOREPO: - return - skip_marker = pytest.mark.skip( - reason="Installed PyPI google-api-core differs from monorepo source; " - "validated by showcase-canary (INSTALL_LOCAL_CORE=true)." - ) - for item in items: - if "requires_current_core" in item.keywords: - item.add_marker(skip_marker) +@contextlib.contextmanager +def skip_on_core_mismatch(): + """Runs assertions and skips only if they fail while PyPI google-api-core lags monorepo.""" + try: + yield + except AssertionError: + if not INSTALLED_CORE_MATCHES_MONOREPO: + pytest.skip( + "Installed PyPI google-api-core differs from monorepo source; " + "validated by showcase-canary (INSTALL_LOCAL_CORE=true)." + ) + raise try: diff --git a/packages/gapic-generator/tests/system/test_span_compliance.py b/packages/gapic-generator/tests/system/test_span_compliance.py index 6743fdfd09f4..d78354dc020f 100644 --- a/packages/gapic-generator/tests/system/test_span_compliance.py +++ b/packages/gapic-generator/tests/system/test_span_compliance.py @@ -715,15 +715,8 @@ def test_feature(feature_id: str, row: dict[str, str], span_exporter, monkeypatc f"(captured {len(tier_spans)} {tier} spans)" ) target_span = tier_spans[attempt_idx] - try: + with conftest.skip_on_core_mismatch(): assert_span_matches_row(target_span, row, t3_spans) - except AssertionError: - if not conftest.INSTALLED_CORE_MATCHES_MONOREPO: - pytest.skip( - "PyPI google-api-core differs from monorepo; " - "strict span attribute matrix is validated in showcase-canary" - ) - raise # ---------------------------------------------------------------------------