Skip to content

test: add session fixture to enable all catalogs for tests#903

Merged
fege merged 7 commits intoopendatahub-io:mainfrom
fege:enable_catalogs
Dec 4, 2025
Merged

test: add session fixture to enable all catalogs for tests#903
fege merged 7 commits intoopendatahub-io:mainfrom
fege:enable_catalogs

Conversation

@fege
Copy link
Copy Markdown
Contributor

@fege fege commented Dec 3, 2025

Introduce enabled_model_catalog_config_map session-scoped fixture to centrally manage catalog enablement across all model catalog tests.

Description

How Has This Been Tested?

Merge criteria:

  • The commits are squashed in a cohesive manner and have meaningful messages.
  • Testing instructions have been added in the PR body (for PRs involving changes that are not immediately obvious).
  • The developer has manually tested the changes and verified that the changes work

Summary by CodeRabbit

  • Tests
    • Enhanced test infrastructure for model catalog validation with improved fixture setup.
    • Expanded test coverage for model catalog search, filtering, and data retrieval operations.
    • Strengthened error handling and retry mechanisms in API validation utilities.

✏️ Tip: You can customize this high-level summary in your review settings.

Introduce `enabled_model_catalog_config_map` session-scoped fixture to centrally manage
catalog enablement across all model catalog tests.
@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 3, 2025

The following are automatically added/executed:

  • PR size label.
  • Run pre-commit
  • Run tox
  • Add PR author as the PR assignee
  • Build image based on the PR

Available user actions:

  • To mark a PR as WIP, add /wip in a comment. To remove it from the PR comment /wip cancel to the PR.
  • To block merging of a PR, add /hold in a comment. To un-block merging of PR comment /hold cancel.
  • To mark a PR as approved, add /lgtm in a comment. To remove, add /lgtm cancel.
    lgtm label removed on each new commit push.
  • To mark PR as verified comment /verified to the PR, to un-verify comment /verified cancel to the PR.
    verified label removed on each new commit push.
  • To Cherry-pick a merged PR /cherry-pick <target_branch_name> to the PR. If <target_branch_name> is valid,
    and the current PR is merged, a cherry-picked PR would be created and linked to the current PR.
  • To build and push image to quay, add /build-push-pr-image in a comment. This would create an image with tag
    pr-<pr_number> to quay repository. This image tag, however would be deleted on PR merge or close action.
Supported labels

{'/wip', '/cherry-pick', '/hold', '/build-push-pr-image', '/verified', '/lgtm'}

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 3, 2025

📝 Walkthrough

Walkthrough

This change introduces a new session-scoped pytest fixture that enables all model catalog sources by reading, updating, and writing Kubernetes ConfigMaps. The fixture is then integrated into multiple test methods across the model catalog test suite. Additionally, error handling is added to manage transient 401 authorization errors in model catalog API utilities.

Changes

Cohort / File(s) Summary
New fixture for enabling model catalog sources
tests/model_registry/model_catalog/conftest.py
Added session-scoped enabled_model_catalog_config_map fixture that reads the operator-managed default sources ConfigMap, enables all catalogs in sources.yaml, and writes to the user-managed model catalog ConfigMap. Imports updated to include DEFAULT_MODEL_CATALOG_CM and DEFAULT_CUSTOM_MODEL_CATALOG constants.
Fixture parameter integration in test methods
tests/model_registry/model_catalog/test_default_model_catalog.py, tests/model_registry/model_catalog/test_filter_options_endpoint.py, tests/model_registry/model_catalog/test_model_search.py
Added enabled_model_catalog_config_map: ConfigMap parameter to 30+ test method signatures across TestModelCatalogDefault, TestModelCatalogDefaultData, TestSearchModelCatalog, TestSearchModelArtifact, TestSearchModelCatalogQParameter, TestSearchModelsByFilterQuery, and filter options endpoint test classes. Added ConfigMap import to test files where needed.
Error handling and logging updates
tests/model_registry/utils.py
Added new TransientUnauthorizedError exception class for retryable 401 errors. Updated execute_get_call to raise TransientUnauthorizedError on HTTP 401 and ResourceNotFoundError on other failures. Enhanced wait_for_model_catalog_api retry configuration to include TransientUnauthorizedError and check both /sources and /models endpoints. Updated validate_model_catalog_sources logging prefix and assertion logic to require exact match of catalog count.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Fixture implementation logic (conftest.py): Review the ConfigMap manipulation flow, readiness checks, and YAML handling to ensure correct catalog enablement.
  • Error handling changes (utils.py): Verify that TransientUnauthorizedError handling is appropriate for 401 scenarios, that retry logic correctly includes this exception, and that assertion changes in validate_model_catalog_sources match intended behavior.
  • Test fixture integration: While repetitive across many test methods, ensure the fixture parameter is correctly positioned in each signature and that all related tests have the parameter added as intended.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a session fixture to enable all catalogs for tests, which aligns with the new enabled_model_catalog_config_map fixture and its integration across multiple test files.
Docstring Coverage ✅ Passed Docstring coverage is 90.91% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
tests/model_registry/model_catalog/conftest.py (1)

40-79: Consider adding cleanup call to is_model_catalog_ready after the ResourceEditor context exits.

The fixture correctly enables all catalogs via ResourceEditor, but unlike the similar updated_catalog_config_map fixture (lines 91-113), it doesn't call is_model_catalog_ready after the context manager exits to ensure proper cleanup/reset of the model catalog pods.

Since this is a session-scoped fixture, missing cleanup may not affect individual test runs, but could leave the environment in an unexpected state if the fixture is used in isolation or if tests run after session teardown depend on the default state.

Consider adding cleanup for consistency:

     with ResourceEditor(patches={user_sources_cm: patches}):
         is_model_catalog_ready(client=admin_client, model_registry_namespace=model_registry_namespace)
         yield user_sources_cm
+    is_model_catalog_ready(client=admin_client, model_registry_namespace=model_registry_namespace)
tests/model_registry/model_catalog/test_model_search.py (1)

429-436: Consider parameter ordering for consistency.

In test_q_parameter_empty_query, the enabled_model_catalog_config_map fixture parameter appears after search_term (line 433), while in all other methods it appears first. Consider reordering for consistency across the test suite.

     @pytest.mark.parametrize("search_term", ["", None])
     def test_q_parameter_empty_query(
         self: Self,
-        search_term,
         enabled_model_catalog_config_map: ConfigMap,
+        search_term,
         model_catalog_rest_url: list[str],
         model_registry_rest_headers: dict[str, str],
     ):
tests/model_registry/model_catalog/test_default_model_catalog.py (1)

164-171: Handle intentionally unused enabled_model_catalog_config_map to satisfy Ruff

enabled_model_catalog_config_map: ConfigMap is added to these tests purely to trigger the session-scoped fixture’s side effects, so it’s intentionally unused in the bodies. Ruff now reports ARG002 for each of these parameters.

To keep the semantics while avoiding repeated warnings, consider one of:

  • Make the fixture autouse for the relevant scope and drop it from the signatures, for example in this module or per class:
pytestmark = [
    ...,
    pytest.mark.usefixtures("enabled_model_catalog_config_map"),
]

or @pytest.mark.usefixtures("enabled_model_catalog_config_map") on the specific classes.

  • If you prefer the explicit parameter, mark it as intentionally unused, e.g.:
def test_model_default_catalog_get_model_by_name(
    self: Self,
    enabled_model_catalog_config_map: ConfigMap,
    ...
):
    del enabled_model_catalog_config_map  # consume fixture, silence ARG002
    ...

or add a # noqa: ARG002 comment on the parameter line per your linting conventions.

This keeps the new catalog-enabling behavior while making the linter happy.

Also applies to: 201-248, 258-378

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6c29e38 and 143a5f6.

📒 Files selected for processing (7)
  • tests/model_registry/model_catalog/conftest.py (2 hunks)
  • tests/model_registry/model_catalog/test_custom_model_catalog.py (0 hunks)
  • tests/model_registry/model_catalog/test_default_model_catalog.py (7 hunks)
  • tests/model_registry/model_catalog/test_filter_options_endpoint.py (3 hunks)
  • tests/model_registry/model_catalog/test_model_catalog_negative.py (1 hunks)
  • tests/model_registry/model_catalog/test_model_search.py (15 hunks)
  • tests/model_registry/utils.py (1 hunks)
💤 Files with no reviewable changes (1)
  • tests/model_registry/model_catalog/test_custom_model_catalog.py
🧰 Additional context used
🧬 Code graph analysis (5)
tests/model_registry/utils.py (1)
tests/model_registry/model_catalog/conftest.py (1)
  • expected_catalog_values (117-118)
tests/model_registry/model_catalog/test_filter_options_endpoint.py (1)
tests/model_registry/model_catalog/conftest.py (1)
  • enabled_model_catalog_config_map (41-78)
tests/model_registry/model_catalog/conftest.py (3)
tests/conftest.py (1)
  • admin_client (78-79)
tests/model_registry/conftest.py (1)
  • model_registry_namespace (75-76)
tests/model_registry/utils.py (1)
  • is_model_catalog_ready (674-686)
tests/model_registry/model_catalog/test_default_model_catalog.py (1)
tests/model_registry/model_catalog/conftest.py (1)
  • enabled_model_catalog_config_map (41-78)
tests/model_registry/model_catalog/test_model_search.py (2)
tests/model_registry/model_catalog/conftest.py (1)
  • enabled_model_catalog_config_map (41-78)
tests/model_registry/conftest.py (1)
  • model_catalog_rest_url (640-649)
🪛 Ruff (0.14.7)
tests/model_registry/model_catalog/test_filter_options_endpoint.py

48-48: Unused method argument: enabled_model_catalog_config_map

(ARG002)


101-101: Unused method argument: enabled_model_catalog_config_map

(ARG002)

tests/model_registry/model_catalog/test_default_model_catalog.py

167-167: Unused method argument: enabled_model_catalog_config_map

(ARG002)


203-203: Unused method argument: enabled_model_catalog_config_map

(ARG002)


216-216: Unused method argument: enabled_model_catalog_config_map

(ARG002)


234-234: Unused method argument: enabled_model_catalog_config_map

(ARG002)


260-260: Unused method argument: enabled_model_catalog_config_map

(ARG002)


277-277: Unused method argument: enabled_model_catalog_config_map

(ARG002)


331-331: Unused method argument: enabled_model_catalog_config_map

(ARG002)

tests/model_registry/model_catalog/test_model_search.py

36-36: Unused method argument: enabled_model_catalog_config_map

(ARG002)


68-68: Unused method argument: enabled_model_catalog_config_map

(ARG002)


111-111: Unused method argument: enabled_model_catalog_config_map

(ARG002)


155-155: Unused method argument: enabled_model_catalog_config_map

(ARG002)


221-221: Unused method argument: enabled_model_catalog_config_map

(ARG002)


260-260: Unused method argument: enabled_model_catalog_config_map

(ARG002)


312-312: Unused method argument: enabled_model_catalog_config_map

(ARG002)


352-352: Unused method argument: enabled_model_catalog_config_map

(ARG002)


403-403: Unused method argument: enabled_model_catalog_config_map

(ARG002)


433-433: Unused method argument: enabled_model_catalog_config_map

(ARG002)


451-451: Unused method argument: enabled_model_catalog_config_map

(ARG002)


497-497: Unused method argument: enabled_model_catalog_config_map

(ARG002)


543-543: Unused method argument: enabled_model_catalog_config_map

(ARG002)


583-583: Unused method argument: enabled_model_catalog_config_map

(ARG002)

🔇 Additional comments (10)
tests/model_registry/utils.py (2)

744-744: LGTM!

The logging prefix improves clarity by identifying the log output context.


746-746: Verify the removal of the +2 offset is correct for all test scenarios.

The assertion now expects len(results) == len(expected_catalog_values) without the previous +2 offset. This change assumes the enabled_model_catalog_config_map fixture now explicitly enables all catalogs, making the expected count match exactly.

Ensure this change doesn't break tests where the fixture is not used or where additional default catalogs might still be present. Verify that all test paths through this assertion account for the expected catalog count consistently.

tests/model_registry/model_catalog/test_model_catalog_negative.py (1)

84-95: LGTM!

Adding enabled: true to the catalog configuration aligns with the PR's objective of enabling catalogs for tests. This ensures the negative test scenario properly tests rejection of duplicate enabled catalogs in the custom configmap.

tests/model_registry/model_catalog/conftest.py (2)

20-24: LGTM!

The imports are correctly updated to include the constants needed for the new fixture.


57-65: Consider handling yaml.safe_load returning None for empty YAML.

If default_sources_yaml is an empty string, yaml.safe_load("") returns None, which is correctly handled by the if parsed_yaml and "catalogs" in parsed_yaml check. However, logging a warning and falling back to the original (empty) sources YAML may not be the intended behavior.

Verify this is the expected behavior when the default sources ConfigMap has no catalogs defined, or if an error should be raised instead.

tests/model_registry/model_catalog/test_filter_options_endpoint.py (3)

4-4: LGTM!

Import added for the ConfigMap type hint used with the new fixture parameter.


46-52: Fixture dependency pattern is correct; static analysis warning can be ignored.

The enabled_model_catalog_config_map parameter is intentionally added to ensure the fixture runs before the test, enabling all catalogs. The parameter appears unused because the test relies on the fixture's side effect (catalog enablement), not its return value. This is a standard pytest pattern for setup fixtures.

The Ruff ARG002 warning is a false positive in this context.


99-105: Same fixture dependency pattern; approved.

Consistent with the previous test method, this fixture parameter ensures catalogs are enabled before database validation tests run.

tests/model_registry/model_catalog/test_model_search.py (2)

3-3: LGTM!

Import added for the ConfigMap type hint.


34-39: Fixture dependency pattern is intentional; static analysis warnings are false positives.

The enabled_model_catalog_config_map parameter is added to 14 test methods across this file to ensure the session-scoped fixture runs before any model catalog tests. This is a standard pytest pattern where the fixture's side effect (enabling all catalogs in the ConfigMap) is required, not its return value.

All Ruff ARG002 warnings for this fixture parameter throughout the file can be safely ignored.

@fege
Copy link
Copy Markdown
Contributor Author

fege commented Dec 3, 2025

/build-push-pr-image

@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 3, 2025

Status of building tag pr-903: success.
Status of pushing tag pr-903 to image registry: success.

@fege
Copy link
Copy Markdown
Contributor Author

fege commented Dec 3, 2025

/build-push-pr-image

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
tests/model_registry/model_catalog/conftest.py (1)

41-79: Fixture behavior looks correct; consider preserving extra YAML keys and extracting a helper

The overall flow of enabled_model_catalog_config_map looks solid: it fails fast when catalogs are missing, enables all catalogs, patches the user-managed ConfigMap via ResourceEditor, and waits for readiness before yielding.

Two optional cleanups you might consider:

  • If sources.yaml ever gains additional top-level keys, constructing enabled_yaml_dict = {"catalogs": parsed_yaml["catalogs"]} will silently drop them. Preserving them is safer:
-    for catalog in parsed_yaml["catalogs"]:
-        catalog["enabled"] = True
-    enabled_yaml_dict = {"catalogs": parsed_yaml["catalogs"]}
-    enabled_sources_yaml = yaml.dump(enabled_yaml_dict, default_flow_style=False, sort_keys=False)
+    for catalog in parsed_yaml["catalogs"]:
+        catalog["enabled"] = True
+    # Preserve any additional top-level keys instead of dropping everything but "catalogs".
+    enabled_yaml_dict = dict(parsed_yaml)
+    enabled_yaml_dict["catalogs"] = parsed_yaml["catalogs"]
+    enabled_sources_yaml = yaml.dump(enabled_yaml_dict, default_flow_style=False, sort_keys=False)
  • The YAML parsing and “enable all catalogs” logic is fairly self-contained and might be worth moving into a small utility in tests.model_registry.utils if you expect to reuse it elsewhere, as was suggested in earlier review feedback.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between abb347f and 341a0c0.

📒 Files selected for processing (2)
  • tests/model_registry/model_catalog/conftest.py (2 hunks)
  • tests/model_registry/model_catalog/test_custom_model_catalog.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
tests/model_registry/model_catalog/conftest.py (3)
tests/conftest.py (1)
  • admin_client (78-79)
tests/model_registry/conftest.py (1)
  • model_registry_namespace (75-76)
tests/model_registry/utils.py (1)
  • is_model_catalog_ready (674-686)
tests/model_registry/model_catalog/test_custom_model_catalog.py (1)
tests/model_registry/model_catalog/conftest.py (1)
  • enabled_model_catalog_config_map (42-78)
🪛 Ruff (0.14.7)
tests/model_registry/model_catalog/conftest.py

60-60: Avoid specifying long messages outside the exception class

(TRY003)

tests/model_registry/model_catalog/test_custom_model_catalog.py

58-58: Unused method argument: enabled_model_catalog_config_map

(ARG002)


74-74: Unused method argument: enabled_model_catalog_config_map

(ARG002)

🔇 Additional comments (1)
tests/model_registry/model_catalog/conftest.py (1)

21-25: New constants imports are consistent with usage

The additional imports (CUSTOM_CATALOG_ID1, DEFAULT_MODEL_CATALOG_CM, DEFAULT_CUSTOM_MODEL_CATALOG) are all used below and line up with the new fixture behavior and existing helpers. No issues here.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 3, 2025

Status of building tag pr-903: success.
Status of pushing tag pr-903 to image registry: success.

lugi0
lugi0 previously approved these changes Dec 3, 2025
dbasunag
dbasunag previously approved these changes Dec 3, 2025
@fege fege dismissed stale reviews from dbasunag and lugi0 via 049052e December 4, 2025 11:12
@fege
Copy link
Copy Markdown
Contributor Author

fege commented Dec 4, 2025

/build-push-pr-image

@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 4, 2025

Status of building tag pr-903: success.
Status of pushing tag pr-903 to image registry: success.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
tests/model_registry/utils.py (2)

702-716: 401 handling and long exception messages in execute_get_call

The split between retryable 401s (TransientUnauthorizedError) and other non-2xx responses (ResourceNotFoundError) makes sense for wait_for_model_catalog_api. To reduce duplication and satisfy Ruff (TRY003), consider shortening the f-string messages or centralizing the message construction inside the exception class (e.g., have the exception accept url and response and build __str__ there).


755-767: Tightened length assertion and expected_catalog_values type

The stricter assert len(results) == len(expected_catalog_values) is fine if tests always enumerate all expected catalogs; if the API can legitimately return extra system catalogs, this may over-constrain the check and could be relaxed back to a subset assertion. Also, expected_catalog_values is annotated as dict[str, str] but is iterated as a sequence of dicts (expected_entry["id"]), so the runtime expectation is effectively Sequence[Mapping]. Updating the type hint (and any docstring) to reflect the actual structure would avoid confusion.

tests/model_registry/model_catalog/conftest.py (1)

41-79: Behaviour and scope of enabled_model_catalog_config_map

Enabling all catalogs by reading DEFAULT_MODEL_CATALOG_CM and patching DEFAULT_CUSTOM_MODEL_CATALOG via ResourceEditor looks correct and matches the test intent. A couple of points to double‑check:

  • The fixture rewrites sources.yaml to only contain a catalogs list, dropping any other top‑level keys (labels, etc.) that might exist in the operator‑managed ConfigMap. If other tests depend on additional keys from sources.yaml, consider preserving them instead of reconstructing a minimal dict.
  • The readiness gate here relies on is_model_catalog_ready only. If you still see transient 401s in tests that depend solely on this fixture, it might be worth also calling wait_for_model_catalog_api (mirroring updated_catalog_config_map), at the cost of adding its dependencies to this fixture’s signature.

The RuntimeError("No catalogs found in default sources ConfigMap") path is also a reasonable early‑fail, and addresses the earlier comment about failing fast when inputs are bad.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 341a0c0 and 049052e.

📒 Files selected for processing (2)
  • tests/model_registry/model_catalog/conftest.py (2 hunks)
  • tests/model_registry/utils.py (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
tests/model_registry/model_catalog/conftest.py (1)
tests/model_registry/utils.py (1)
  • is_model_catalog_ready (679-691)
tests/model_registry/utils.py (2)
tests/model_registry/model_catalog/utils.py (1)
  • ResourceNotFoundError (32-33)
tests/model_registry/model_catalog/conftest.py (1)
  • expected_catalog_values (117-118)
🪛 Ruff (0.14.7)
tests/model_registry/model_catalog/conftest.py

60-60: Avoid specifying long messages outside the exception class

(TRY003)

tests/model_registry/utils.py

713-713: Avoid specifying long messages outside the exception class

(TRY003)


715-715: Avoid specifying long messages outside the exception class

(TRY003)

🔇 Additional comments (3)
tests/model_registry/utils.py (2)

46-50: Custom transient error type is clear and self-contained

Defining TransientUnauthorizedError for retryable 401s keeps retry logic explicit and readable; no issues from a correctness standpoint.


719-729: wait_for_model_catalog_api readiness check looks robust

Checking both /sources and /models and retrying on ResourceNotFoundError and TransientUnauthorizedError should make the catalog API readiness much less flaky under OAuth/kube‑rbac‑proxy initialization; the implementation aligns with existing URL usage patterns in this file.

tests/model_registry/model_catalog/conftest.py (1)

21-25: New constants import matches downstream usage

Importing CUSTOM_CATALOG_ID1, DEFAULT_MODEL_CATALOG_CM, and DEFAULT_CUSTOM_MODEL_CATALOG aligns with how they’re referenced later in this module; nothing else to adjust here.

@fege fege requested review from dbasunag and lugi0 December 4, 2025 11:25
@fege fege enabled auto-merge (squash) December 4, 2025 14:30
@fege fege merged commit 6d1cce3 into opendatahub-io:main Dec 4, 2025
8 checks passed
@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 4, 2025

Status of building tag latest: success.
Status of pushing tag latest to image registry: success.

@fege fege deleted the enable_catalogs branch December 4, 2025 14:33
mwaykole pushed a commit to mwaykole/opendatahub-tests that referenced this pull request Jan 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants