Skip to content

Add HF positive tests with wildcard#1003

Merged
dbasunag merged 6 commits intoopendatahub-io:mainfrom
dbasunag:hf_positive
Jan 15, 2026
Merged

Add HF positive tests with wildcard#1003
dbasunag merged 6 commits intoopendatahub-io:mainfrom
dbasunag:hf_positive

Conversation

@dbasunag
Copy link
Copy Markdown
Collaborator

@dbasunag dbasunag commented Jan 9, 2026

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
    • Added parameterized pattern-matching tests to validate inclusion/exclusion behavior for HuggingFace model imports.
    • Added a test fixture to compute expected model counts from the HuggingFace API for assertions.
    • Introduced retrying wait utilities to ensure imports and catalog retrievals reach expected counts before asserting.
    • Added cluster-log inspection utilities and improved logging to surface import/retrieval decisions.

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

@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 9, 2026

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

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 9, 2026

📝 Walkthrough

Walkthrough

Adds a pytest fixture to count HuggingFace models matching include/exclude patterns, introduces retry-backed utilities to wait for HF model import and catalog retrieval match (including pod log inspection), and adds parameterized tests validating inclusion/exclusion pattern behavior against the model catalog.

Changes

Cohort / File(s) Summary
Fixture: HF API filtering
tests/model_registry/model_catalog/huggingface/conftest.py
Adds num_models_from_hf_api_with_matching_criteria pytest fixture that reads request.param (included/excluded patterns), calls HfApi to list models for an org, filters model IDs by start/end matches while logging add/skip decisions, and returns the final count (+29/-0).
Tests: pattern matching
tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py
Adds TestHFPatternMatching with parameterized test_hugging_face_models which uses catalog REST endpoints and new wait utilities to assert expected HF model counts under various include/exclude/catalog configurations (+90/-1).
Utilities: wait & pod helpers
tests/model_registry/model_catalog/huggingface/utils.py
Adds wait_for_huggingface_retrival_match (retry-decorated), wait_for_hugging_face_model_import (inspects model catalog pod logs, retry-decorated), and get_model_catalog_pod; introduces logger usage and pod lookup for import verification (+47/-2).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add HF positive tests with wildcard' is partially related to the changeset. It mentions adding tests for HuggingFace with wildcard, which is reflected in the new test class TestHFPatternMatching and related utilities, but it does not capture the broader scope of changes including pattern matching validation (inclusion/exclusion logic) and fixture additions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

🧹 Recent nitpick comments
tests/model_registry/model_catalog/huggingface/conftest.py (1)

13-36: Add a docstring to the fixture.

Per coding guidelines, fixtures should have Google-format docstrings. This fixture's filtering logic (inclusion/exclusion patterns) warrants documentation for maintainability.

📝 Proposed docstring
 `@pytest.fixture`()
 def num_models_from_hf_api_with_matching_criteria(request: pytest.FixtureRequest, huggingface_api: HfApi) -> int:
+    """Count HuggingFace models matching include/exclude pattern criteria.
+    
+    Args:
+        request: Pytest fixture request containing param dict with keys:
+            - org_name: HuggingFace organization/author to query.
+            - excluded_str: Optional suffix pattern to exclude models.
+            - included_str: Optional prefix pattern to include models.
+        huggingface_api: HfApi instance for querying HuggingFace Hub.
+    
+    Returns:
+        Count of models matching the specified criteria.
+    """
     excluded_str = request.param.get("excluded_str")
tests/model_registry/model_catalog/huggingface/utils.py (1)

130-142: Add a docstring to this utility function.

Per coding guidelines for tests/**/utils.py, utility functions should have docstrings explaining their purpose.

📝 Proposed docstring
 `@retry`(wait_timeout=60, sleep=5)
 def wait_for_hugging_face_model_import(
     admin_client: DynamicClient, model_registry_namespace: str, hf_id: str, expected_num_models_from_hf_api: int
 ) -> bool:
+    """Wait for HuggingFace model import confirmation in pod logs.
+    
+    Retries for up to 60 seconds with 5-second intervals.
+    
+    Args:
+        admin_client: Kubernetes dynamic client.
+        model_registry_namespace: Namespace containing the model catalog pod.
+        hf_id: HuggingFace catalog source identifier.
+        expected_num_models_from_hf_api: Expected number of imported models.
+    
+    Returns:
+        True if import confirmation found in logs, False otherwise.
+    """
     LOGGER.info("Checking pod log for model import information")
tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py (2)

61-62: Add a docstring to the test class.

Per coding guidelines, test classes should have docstrings explaining what they test.

📝 Proposed docstring
 class TestHFPatternMatching:
+    """Test HuggingFace model inclusion/exclusion pattern matching in catalog configurations."""
+
     `@pytest.mark.parametrize`(

126-138: Remove unused huggingface_api parameter and update the docstring.

The huggingface_api parameter is unused in this test (flagged by static analysis). It's only needed as a transitive dependency of num_models_from_hf_api_with_matching_criteria, which pytest resolves automatically without explicit declaration.

Also, the docstring says "excluded models" but this test validates both inclusion and exclusion patterns.

📝 Proposed fix
     def test_hugging_face_models(
         self: Self,
         admin_client: DynamicClient,
         model_registry_namespace: str,
         updated_catalog_config_map_scope_function: ConfigMap,
         model_catalog_rest_url: list[str],
         model_registry_rest_headers: dict[str, str],
-        huggingface_api: bool,
         num_models_from_hf_api_with_matching_criteria: int,
     ):
         """
-        Test that excluded models do not appear in the catalog API response
+        Test that catalog API returns models matching the configured include/exclude patterns.
+        
+        Given: A catalog configuration with specific include/exclude model patterns.
+        When: Models are imported from HuggingFace.
+        Then: The catalog API returns only models matching the filter criteria.
         """

📜 Recent 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 3cbbc93 and 16cf444.

📒 Files selected for processing (3)
  • tests/model_registry/model_catalog/huggingface/conftest.py
  • tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py
  • tests/model_registry/model_catalog/huggingface/utils.py
🧰 Additional context used
📓 Path-based instructions (4)
tests/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

tests/**/*.py: Every test MUST have a docstring explaining what it tests
Apply relevant markers from pytest.ini: tier (smoke, sanity, tier1, tier2), component (model_serving, model_registry, llama_stack), infrastructure (gpu, parallel, slow)
Use Given-When-Then format in test docstrings for behavioral clarity
Use openshift-python-wrapper for all Kubernetes API calls
Kubernetes resource lifecycle MUST use context managers to ensure cleanup
Add type annotations to test code and fixtures (mypy strict enforced)
Write Google-format docstrings for tests and fixtures

Files:

  • tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py
  • tests/model_registry/model_catalog/huggingface/utils.py
  • tests/model_registry/model_catalog/huggingface/conftest.py
tests/**/test_*.py

📄 CodeRabbit inference engine (AGENTS.md)

Do not import heavy resources at module level; defer to fixture scope

Files:

  • tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py
tests/**/utils.py

📄 CodeRabbit inference engine (AGENTS.md)

Component-specific utility functions should be placed in component-level utils.py files

Files:

  • tests/model_registry/model_catalog/huggingface/utils.py
tests/**/conftest.py

📄 CodeRabbit inference engine (AGENTS.md)

tests/**/conftest.py: Fixture names MUST be nouns: storage_secret not create_secret
Use context managers for resource lifecycle management in fixtures
Fixtures do one thing only—compose them rather than nesting
Use narrowest scope that meets the need: function > class > module > session

Files:

  • tests/model_registry/model_catalog/huggingface/conftest.py
🧬 Code graph analysis (1)
tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py (1)
tests/model_registry/model_catalog/huggingface/utils.py (2)
  • wait_for_huggingface_retrival_match (105-127)
  • wait_for_hugging_face_model_import (131-142)
🪛 Ruff (0.14.11)
tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py

130-130: Unused method argument: updated_catalog_config_map_scope_function

(ARG002)


133-133: Unused method argument: huggingface_api

(ARG002)

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

140-151: LGTM!

The test flow is correct: first waits for model import confirmation in pod logs, then verifies the catalog API returns the expected count. The @retry decorators on the utility functions handle the implicit assertion via timeout.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


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: 3

🤖 Fix all issues with AI agents
In
@tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py:
- Around line 59-150: The test test_hugging_face_models currently catches
TimeoutExpiredError and falls back to checking pod logs via
get_model_catalog_pod() and a hardcoded log string, which masks API failures and
couples the test to log text; remove the TimeoutExpiredError fallback so the
test relies solely on wait_for_huggingface_retrival_match() (or increase its
timeout there if needed) and let the test fail if the catalog API times out, and
also correct the huggingface_api fixture type annotation from bool to HfApi (or
remove the unused parameter) so the fixture typing matches actual return type.

In @tests/model_registry/model_catalog/huggingface/utils.py:
- Around line 131-135: Update the docstring for get_model_catalog_pod to
accurately describe what the function returns: replace the misleading "Get the
PostgreSQL pod for model catalog database." with something like "Get the model
catalog pod in the given namespace." Keep the rest of the function unchanged
(catalog_pods, Pod.get, label_selector and return of catalog_pods[0]) so only
the docstring text is corrected.
🧹 Nitpick comments (1)
tests/model_registry/model_catalog/huggingface/conftest.py (1)

14-36: Consider adding error handling for HuggingFace API calls.

The fixture calls huggingface_api.list_models() without error handling. Network issues or API rate limits could cause test failures that are hard to diagnose.

🛡️ Proposed error handling
 @pytest.fixture()
 def expected_num_models_from_hf_api(request: pytest.FixtureRequest, huggingface_api: HfApi) -> int:
     excluded_str = request.param.get("excluded_str")
     included_str = request.param.get("included_str")
-    models = huggingface_api.list_models(author=request.param["org_name"], limit=10000)
+    try:
+        models = huggingface_api.list_models(author=request.param["org_name"], limit=10000)
+    except Exception as e:
+        LOGGER.error(f"Failed to fetch models from HuggingFace API: {e}")
+        raise
     model_list = []
📜 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 4592fa9 and c088cb9.

📒 Files selected for processing (4)
  • tests/model_registry/model_catalog/conftest.py
  • tests/model_registry/model_catalog/huggingface/conftest.py
  • tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py
  • tests/model_registry/model_catalog/huggingface/utils.py
🧰 Additional context used
🧬 Code graph analysis (1)
tests/model_registry/model_catalog/conftest.py (2)
tests/model_registry/utils.py (1)
  • wait_for_model_catalog_api (718-727)
tests/model_registry/conftest.py (1)
  • model_registry_rest_headers (399-400)
🪛 Ruff (0.14.10)
tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py

126-126: Unused method argument: updated_catalog_config_map_scope_function

(ARG002)


129-129: Unused method argument: huggingface_api

(ARG002)

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

389-390: LGTM! Ensures API readiness after teardown.

The addition of wait_for_model_catalog_api after teardown aligns with the pattern used in other fixtures and ensures the catalog API is fully operational before the next test begins.

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

3-5: LGTM! Proper logging setup.

Logger initialization follows the established pattern in the codebase.

tests/model_registry/model_catalog/huggingface/utils.py (1)

3-12: LGTM! Clean imports and logging setup.

The new imports support HuggingFace integration and retry logic appropriately.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py (1)

40-57: Incorrect type annotation for huggingface_api parameter.

The huggingface_api fixture (defined in conftest.py) returns an HfApi instance, not a bool. The type annotation should match the actual fixture return type.

📝 Proposed fix
     def test_huggingface_model_metadata(
         self: Self,
         updated_catalog_config_map: tuple[ConfigMap, str, str],
         model_catalog_rest_url: list[str],
         model_registry_rest_headers: dict[str, str],
         expected_catalog_values: dict[str, str],
-        huggingface_api: bool,
+        huggingface_api: HfApi,
     ):

Add the import at the top of the file:

from huggingface_hub import HfApi
🧹 Nitpick comments (4)
tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py (1)

60-145: Class docstring missing and test docstring doesn't follow conventions.

Per coding guidelines, tests must have docstrings using Given-When-Then format for behavioral clarity. Additionally:

  1. Class docstring: TestHFPatternMatching lacks a docstring explaining what it tests
  2. Test docstring: The current docstring says "excluded models" but the test covers multiple patterns including wildcards, allowed organizations, and inclusion patterns
  3. Type annotation: Same huggingface_api: bool issue as above - should be HfApi

Note: The static analysis flags updated_catalog_config_map_scope_function and huggingface_api as unused, but these are required — the former triggers the indirect parametrization fixture, and the latter is a dependency for expected_num_models_from_hf_api.

📝 Proposed improvements
 class TestHFPatternMatching:
+    """Tests for HuggingFace catalog pattern matching including wildcards, org filtering, and inclusion/exclusion."""
+
     `@pytest.mark.parametrize`(
         ...
     )
     def test_hugging_face_models(
         self: Self,
         updated_catalog_config_map_scope_function: ConfigMap,
         model_catalog_rest_url: list[str],
         model_registry_rest_headers: dict[str, str],
-        huggingface_api: bool,
+        huggingface_api: HfApi,
         expected_num_models_from_hf_api: int,
     ):
         """
-        Test that excluded models do not appear in the catalog API response
+        Test HuggingFace model pattern matching in catalog configurations.
+
+        Given: A catalog configuration with inclusion/exclusion patterns
+        When: Models are imported from HuggingFace
+        Then: The catalog API returns only models matching the configured patterns
         """
tests/model_registry/model_catalog/huggingface/utils.py (3)

104-127: Typo in function name and missing docstring.

  1. Typo: wait_for_huggingface_retrival_match should be wait_for_huggingface_retrieval_match ("retrieval" not "retrival")
  2. Missing docstring: Per coding guidelines, utility functions should have Google-format docstrings
  3. Hardcoded page size: pageSize=1000 on line 112 could truncate results if the HF organization has more models
📝 Proposed fix
 `@retry`(wait_timeout=60, sleep=5)
-def wait_for_huggingface_retrival_match(
+def wait_for_huggingface_retrieval_match(
     source_id: str,
     model_catalog_rest_url: list[str],
     model_registry_rest_headers: dict[str, str],
     expected_num_models_from_hf_api: int,
 ) -> bool | None:
+    """Poll the catalog API until the model count matches the expected HuggingFace count.
+
+    Args:
+        source_id: The catalog source identifier.
+        model_catalog_rest_url: List of catalog API base URLs.
+        model_registry_rest_headers: Headers for API authentication.
+        expected_num_models_from_hf_api: Expected number of models from HuggingFace.
+
+    Returns:
+        True if counts match, None otherwise (triggers retry).
+    """
     # Get all models from the catalog API for the given source
-    url = f"{model_catalog_rest_url[0]}models?source={source_id}&pageSize=1000"
+    url = f"{model_catalog_rest_url[0]}models?source={source_id}&pageSize=10000"

Note: The caller in test_huggingface_model_validation.py will also need to be updated to use the corrected function name.


130-133: Add docstring to get_model_catalog_pod.

The function lacks a docstring explaining its purpose and parameters. As noted in past reviews, the previous docstring incorrectly mentioned PostgreSQL.

📝 Proposed fix
 def get_model_catalog_pod(namespace: str = "rhoai-model-registries") -> Pod:
+    """Get the model catalog pod from the specified namespace.
+
+    Args:
+        namespace: Kubernetes namespace to search. Defaults to "rhoai-model-registries".
+
+    Returns:
+        The first model catalog Pod found.
+
+    Raises:
+        AssertionError: If no model catalog pod is found.
+    """
     catalog_pods = list(Pod.get(namespace=namespace, label_selector="app.kubernetes.io/name=model-catalog"))
     assert catalog_pods, f"No model catalog pod found in namespace {namespace}"
     return catalog_pods[0]

136-146: Log level and verbosity issues in wait_for_hugging_face_model_import.

  1. Incorrect log levels: Lines 138 and 142 use LOGGER.warning for informational messages. Use LOGGER.info instead since these are not warning conditions.
  2. Excessive logging: Line 145 dumps the entire pod log on every retry iteration, which could be very verbose and flood logs.
  3. Missing docstring: Add Google-format docstring per coding guidelines.
📝 Proposed fix
 `@retry`(wait_timeout=60, sleep=5)
 def wait_for_hugging_face_model_import(hf_id: str, expected_num_models_from_hf_api: int) -> bool:
-    LOGGER.warning("Checking pod log for model import information")
+    """Wait for HuggingFace model import to complete by checking pod logs.
+
+    Args:
+        hf_id: The HuggingFace catalog source identifier.
+        expected_num_models_from_hf_api: Expected number of models to be imported.
+
+    Returns:
+        True if import is confirmed, False otherwise (triggers retry).
+    """
+    LOGGER.info("Checking pod log for model import information")
     pod = get_model_catalog_pod()
     log = pod.log(container="catalog")
     if f"{hf_id}: loaded {expected_num_models_from_hf_api} models" in log and f"{hf_id}: cleaned up 0 models" in log:
-        LOGGER.warning(f"Found log entry confirming model(s) imported for id: {hf_id}")
+        LOGGER.info(f"Found log entry confirming model(s) imported for id: {hf_id}")
         return True
     else:
-        LOGGER.warning(f"No relevant log entry: {log}")
+        LOGGER.debug("Import not yet complete, retrying...")
         return False
📜 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 6caab88 and e2a2edc.

📒 Files selected for processing (2)
  • tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py
  • tests/model_registry/model_catalog/huggingface/utils.py
🧰 Additional context used
📓 Path-based instructions (3)
tests/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

tests/**/*.py: Every test MUST have a docstring explaining what it tests
Apply relevant markers from pytest.ini: tier (smoke, sanity, tier1, tier2), component (model_serving, model_registry, llama_stack), infrastructure (gpu, parallel, slow)
Use Given-When-Then format in test docstrings for behavioral clarity
Use openshift-python-wrapper for all Kubernetes API calls
Kubernetes resource lifecycle MUST use context managers to ensure cleanup
Add type annotations to test code and fixtures (mypy strict enforced)
Write Google-format docstrings for tests and fixtures

Files:

  • tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py
  • tests/model_registry/model_catalog/huggingface/utils.py
tests/**/test_*.py

📄 CodeRabbit inference engine (AGENTS.md)

Do not import heavy resources at module level; defer to fixture scope

Files:

  • tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py
tests/**/utils.py

📄 CodeRabbit inference engine (AGENTS.md)

Component-specific utility functions should be placed in component-level utils.py files

Files:

  • tests/model_registry/model_catalog/huggingface/utils.py
🧬 Code graph analysis (1)
tests/model_registry/model_catalog/huggingface/utils.py (4)
tests/model_registry/utils.py (1)
  • execute_get_command (730-738)
tests/model_registry/model_catalog/conftest.py (1)
  • model_catalog_rest_url (413-422)
tests/model_registry/conftest.py (1)
  • model_registry_rest_headers (399-400)
tests/model_registry/model_catalog/huggingface/conftest.py (1)
  • expected_num_models_from_hf_api (14-36)
🪛 Ruff (0.14.11)
tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py

127-127: Unused method argument: updated_catalog_config_map_scope_function

(ARG002)


130-130: Unused method argument: huggingface_api

(ARG002)

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py (1)

40-57: Pre-existing type annotation issue.

Line 46 has huggingface_api: bool but the fixture returns HfApi() and the function assert_huggingface_values_matches_model_catalog_api_values expects HfApi. This would fail mypy strict checking.

📝 Suggested fix
     def test_huggingface_model_metadata(
         self: Self,
         updated_catalog_config_map: tuple[ConfigMap, str, str],
         model_catalog_rest_url: list[str],
         model_registry_rest_headers: dict[str, str],
         expected_catalog_values: dict[str, str],
-        huggingface_api: bool,
+        huggingface_api: HfApi,
     ):

Note: You'll need to add the import:

from huggingface_hub import HfApi
♻️ Duplicate comments (2)
tests/model_registry/model_catalog/huggingface/utils.py (1)

130-133: Add docstring for the utility function.

The function lacks documentation. Per coding guidelines, utility functions should have Google-format docstrings.

📝 Suggested docstring
 def get_model_catalog_pod(namespace: str = "rhoai-model-registries") -> Pod:
+    """
+    Get the model catalog pod from the specified namespace.
+
+    Args:
+        namespace: Kubernetes namespace to search. Defaults to "rhoai-model-registries".
+
+    Returns:
+        The first matching model catalog Pod.
+
+    Raises:
+        AssertionError: If no model catalog pod is found.
+    """
     catalog_pods = list(Pod.get(namespace=namespace, label_selector="app.kubernetes.io/name=model-catalog"))
     assert catalog_pods, f"No model catalog pod found in namespace {namespace}"
     return catalog_pods[0]
tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py (1)

125-145: Fix type annotation and improve docstring.

  1. Incorrect type annotation (line 130): huggingface_api: bool should be HfApi since the fixture returns HfApi(). Alternatively, remove the parameter since it's only used indirectly through expected_num_models_from_hf_api.

  2. Docstring update: The docstring says "excluded models" but the test validates wildcard, allowed organization, exclusion, and inclusion patterns. Per coding guidelines, use Given-When-Then format.

  3. Unused parameters: updated_catalog_config_map_scope_function and huggingface_api are flagged by static analysis as unused. They're needed for fixture activation but could be documented or handled via usefixtures.

📝 Suggested improvements
+    `@pytest.mark.usefixtures`("updated_catalog_config_map_scope_function")
     def test_hugging_face_models(
         self: Self,
-        updated_catalog_config_map_scope_function: ConfigMap,
         model_catalog_rest_url: list[str],
         model_registry_rest_headers: dict[str, str],
-        huggingface_api: bool,
         expected_num_models_from_hf_api: int,
     ):
         """
-        Test that excluded models do not appear in the catalog API response
+        Test HuggingFace catalog pattern matching behavior.
+
+        Given: A catalog configuration with include/exclude patterns
+        When: Models are imported from HuggingFace
+        Then: The catalog API returns only models matching the pattern criteria
         """
🧹 Nitpick comments (3)
tests/model_registry/model_catalog/huggingface/utils.py (2)

104-127: Add docstring and consider explicit return value.

Per coding guidelines, utility functions should have Google-format docstrings. The function is missing documentation explaining its purpose, parameters, and return behavior.

Additionally, the function implicitly returns None when counts don't match (causing retry), but the return type hints bool | None. Consider explicitly returning False for clarity.

📝 Suggested docstring and explicit return
 `@retry`(wait_timeout=60, sleep=5)
 def wait_for_huggingface_retrival_match(
     source_id: str,
     model_catalog_rest_url: list[str],
     model_registry_rest_headers: dict[str, str],
     expected_num_models_from_hf_api: int,
 ) -> bool | None:
+    """
+    Poll the catalog API until model count matches expected HuggingFace count.
+
+    Retries for up to 60 seconds with 5-second intervals.
+
+    Args:
+        source_id: The catalog source identifier to query.
+        model_catalog_rest_url: List of catalog API base URLs.
+        model_registry_rest_headers: HTTP headers for authentication.
+        expected_num_models_from_hf_api: Expected number of models from HF API.
+
+    Returns:
+        True if counts match, None otherwise (triggers retry).
+    """
     # Get all models from the catalog API for the given source
     ...
     LOGGER.warning(
         f"Expected {expected_num_models_from_hf_api} "
         "models to be present in response. "
         f"Found {response['size']}. Models in "
         f"response: {models_response}"
     )
+    return None

136-146: Add docstring and adjust log levels.

The function lacks documentation. Additionally, log levels appear inconsistent:

  • Line 138: "Checking pod log" should be LOGGER.info (routine operation)
  • Line 142: Success confirmation should be LOGGER.info (expected outcome)
  • Line 145: Failure case appropriately uses warning
📝 Suggested improvements
 `@retry`(wait_timeout=60, sleep=5)
 def wait_for_hugging_face_model_import(hf_id: str, expected_num_models_from_hf_api: int) -> bool:
-    LOGGER.warning("Checking pod log for model import information")
+    """
+    Wait for HuggingFace model import confirmation in pod logs.
+
+    Polls the model catalog pod logs for import completion message.
+    Retries for up to 60 seconds with 5-second intervals.
+
+    Args:
+        hf_id: The HuggingFace source identifier.
+        expected_num_models_from_hf_api: Expected number of imported models.
+
+    Returns:
+        True if import confirmed in logs, False otherwise (triggers retry).
+    """
+    LOGGER.info("Checking pod log for model import information")
     pod = get_model_catalog_pod()
     log = pod.log(container="catalog")
     if f"{hf_id}: loaded {expected_num_models_from_hf_api} models" in log and f"{hf_id}: cleaned up 0 models" in log:
-        LOGGER.warning(f"Found log entry confirming model(s) imported for id: {hf_id}")
+        LOGGER.info(f"Found log entry confirming model(s) imported for id: {hf_id}")
         return True
     else:
         LOGGER.warning(f"No relevant log entry: {log}")
         return False
tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py (1)

60-61: Add class docstring and pytest markers.

Per coding guidelines:

  1. Every test class should have a docstring explaining what it tests
  2. Tests should apply relevant markers from pytest.ini (tier markers like smoke, sanity, tier1, tier2; component markers like model_registry)
📝 Suggested class setup
+@pytest.mark.tier2
+@pytest.mark.model_registry
 class TestHFPatternMatching:
+    """Test HuggingFace catalog pattern matching for include/exclude model filters."""
+
     `@pytest.mark.parametrize`(
📜 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 e2a2edc and 3cbbc93.

📒 Files selected for processing (2)
  • tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py
  • tests/model_registry/model_catalog/huggingface/utils.py
🧰 Additional context used
📓 Path-based instructions (3)
tests/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

tests/**/*.py: Every test MUST have a docstring explaining what it tests
Apply relevant markers from pytest.ini: tier (smoke, sanity, tier1, tier2), component (model_serving, model_registry, llama_stack), infrastructure (gpu, parallel, slow)
Use Given-When-Then format in test docstrings for behavioral clarity
Use openshift-python-wrapper for all Kubernetes API calls
Kubernetes resource lifecycle MUST use context managers to ensure cleanup
Add type annotations to test code and fixtures (mypy strict enforced)
Write Google-format docstrings for tests and fixtures

Files:

  • tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py
  • tests/model_registry/model_catalog/huggingface/utils.py
tests/**/test_*.py

📄 CodeRabbit inference engine (AGENTS.md)

Do not import heavy resources at module level; defer to fixture scope

Files:

  • tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py
tests/**/utils.py

📄 CodeRabbit inference engine (AGENTS.md)

Component-specific utility functions should be placed in component-level utils.py files

Files:

  • tests/model_registry/model_catalog/huggingface/utils.py
🧬 Code graph analysis (2)
tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py (3)
tests/model_registry/model_catalog/huggingface/utils.py (2)
  • wait_for_huggingface_retrival_match (105-127)
  • wait_for_hugging_face_model_import (137-146)
tests/model_registry/conftest.py (1)
  • model_registry_rest_headers (399-400)
tests/model_registry/model_catalog/huggingface/conftest.py (2)
  • huggingface_api (9-10)
  • expected_num_models_from_hf_api (14-36)
tests/model_registry/model_catalog/huggingface/utils.py (4)
tests/model_registry/utils.py (1)
  • execute_get_command (730-738)
tests/model_registry/model_catalog/conftest.py (1)
  • model_catalog_rest_url (413-422)
tests/model_registry/conftest.py (1)
  • model_registry_rest_headers (399-400)
tests/model_registry/model_catalog/huggingface/conftest.py (1)
  • expected_num_models_from_hf_api (14-36)
🪛 Ruff (0.14.11)
tests/model_registry/model_catalog/huggingface/test_huggingface_model_validation.py

127-127: Unused method argument: updated_catalog_config_map_scope_function

(ARG002)


130-130: Unused method argument: huggingface_api

(ARG002)

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link
Copy Markdown
Contributor

@lugi0 lugi0 left a comment

Choose a reason for hiding this comment

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

I would remove the duplicate function, other than that LGTM

@dbasunag dbasunag requested a review from lugi0 January 15, 2026 14:17
Copy link
Copy Markdown
Contributor

@fege fege left a comment

Choose a reason for hiding this comment

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

/lgtm

@dbasunag dbasunag enabled auto-merge (squash) January 15, 2026 14:19
@dbasunag dbasunag merged commit 76ec8f7 into opendatahub-io:main Jan 15, 2026
8 checks passed
@dbasunag dbasunag deleted the hf_positive branch January 15, 2026 15:28
@github-actions
Copy link
Copy Markdown

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

mwaykole pushed a commit to mwaykole/opendatahub-tests that referenced this pull request Jan 23, 2026
* Add HF positive tests with wildcard

* Updates to add checks to catalog pod log

* updates based on review comments
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