Skip to content

test: add test to initiate mr with secure db connection#320

Merged
fege merged 34 commits intoopendatahub-io:mainfrom
fege:secure-db
Jun 19, 2025
Merged

test: add test to initiate mr with secure db connection#320
fege merged 34 commits intoopendatahub-io:mainfrom
fege:secure-db

Conversation

@fege
Copy link
Copy Markdown
Contributor

@fege fege commented May 28, 2025

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2025

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Introduced comprehensive tests for secure Model Registry integration with MySQL using SSL/TLS, including scenarios for both valid and invalid CA certificates.
    • Added utilities for generating and managing CA and server certificates, creating Kubernetes secrets, and composing CA bundles.
    • Enhanced MySQL deployment and test configuration to support SSL certificate mounting and verification.
  • Tests

    • Added fixtures and test utilities to streamline secure deployment and validation of Model Registry with MySQL SSL.
    • Implemented tests verifying correct model registration behavior under secure and misconfigured CA scenarios.
  • Bug Fixes

    • Enabled configurable SSL verification in REST API calls for more robust testing of secure connections.
  • Chores

    • Improved logging setup for better traceability during test runs.
    • Updated documentation for test fixtures to clarify parameters and behavior.

Summary by CodeRabbit

  • New Features
    • Introduced tests for secure Model Registry integration with MySQL SSL/TLS, including scenarios for both valid and invalid CA certificates.
    • Added utilities for generating CA and server certificates, creating Kubernetes secrets from files, and composing CA bundles with router certificates.
  • Tests
    • Added comprehensive fixtures and test cases to validate Model Registry behavior with secure MySQL deployments.
  • Chores
    • Enhanced logging and configuration options for test environments.

Walkthrough

This update introduces secure MySQL SSL/TLS integration testing for the Model Registry, including new constants, certificate and secret utilities, and comprehensive pytest fixtures for deploying and validating Model Registry behavior with both valid and invalid CA certificates. It also adds new tests, updates configuration fixtures, and enhances certificate management utilities.

Changes

Files/Paths Change Summary
tests/model_registry/constants.py Added four string constants for secure model registry and CA configuration.
tests/model_registry/rest_api/conftest.py Added multiple pytest fixtures for secure MySQL/Model Registry deployment, CA patching, SSL artifact generation, and Kubernetes resource management for integration testing.
tests/model_registry/rest_api/test_model_registry_secure_db.py Added a new test class with two methods to verify Model Registry registration with valid and invalid CA certificates in secure MySQL setups.
tests/model_registry/rest_api/utils.py Updated REST API utility functions to support SSL verification parameter; added certificate/key generation functions using OpenSSL.
tests/model_registry/conftest.py Updated the MySQL config fixture to accept optional port and CA configmap parameters via request, with an added docstring.
conftest.py Added two logger instances at the module level.
utilities/certificates_utils.py Added utilities for creating Kubernetes secrets from files and composing CA bundles with router certificates; imported ConfigMap resource.
tests/model_registry/utils.py Added utility functions to add MySQL TLS certificate volumes and apply SSL-related args and volume mounts to MySQL container specs.

Suggested labels

size/l, Verified, Documentation

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@fege
Copy link
Copy Markdown
Contributor Author

fege commented May 28, 2025

/wip

@github-actions
Copy link
Copy Markdown

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', '/hold', '/wip', '/verified'}

@fege
Copy link
Copy Markdown
Contributor Author

fege commented May 28, 2025

@coderabbitai fullreview

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@fege I'll conduct a full review of this PR. Let me first gather information about the changes made.


🏁 Script executed:

#!/bin/bash
# Get the PR diff to understand what changes were made
git diff origin/main...HEAD --name-only

# Get the detailed diff to see the actual changes
git diff origin/main...HEAD

# Also check if there are any new files added
git diff origin/main...HEAD --diff-filter=A --name-only

Length of output: 252


Let me check the branch structure and find the correct way to get the PR changes.


🏁 Script executed:

#!/bin/bash
# Check what branches exist
git branch -a

# Check the current branch
git branch --show-current

# Get the latest commits to understand the structure
git log --oneline -10

# Try to get changes from the current branch compared to a likely main branch
git diff HEAD~5..HEAD --name-only || true

# Check if there's a master branch instead
git diff origin/master...HEAD --name-only || true

Length of output: 629


Now I can see the branch structure. Let me get the changes between main and the current PR branch.


🏁 Script executed:

#!/bin/bash
# Try comparing main vs current branch
git diff main..HEAD --name-only

# Get the detailed diff
git diff main..HEAD

# Check the commit history on this branch
git log main..HEAD --oneline

# If still no changes, check what files exist in the repo
ls -la

# Check if there are any Python files or test files
find . -name "*.py" -type f | head -20

Length of output: 94943


@fege I've completed a comprehensive review of this PR. Here are my findings:

🔍 Summary of Changes

This PR includes several significant modifications:

  • TrustyAI Testing Simplification: Removal of RBAC-related fixtures and authentication mechanisms
  • Model Registry Enhancement: Addition of secure database connectivity with SSL/TLS support
  • CI/CD Improvements: Workflow fixes and dependency updates
  • Dependency Management: Version updates and downgrades

📝 Detailed Review

Positive Changes

1. CI/CD Workflow Fix

# .github/workflows/verify_build_container.yml
+ - uses: actions/checkout@v4

Good fix - adds missing checkout step before the existing checkout with specific configuration.

2. Model Registry Security Enhancement
The new secure database functionality in test_model_registry_secure_db.py is well-structured:

  • Proper SSL/TLS configuration with CA certificates
  • Clean fixture design in conftest.py
  • Appropriate test validation

⚠️ Areas of Concern

1. TrustyAI Authentication Removal
The removal of RBAC fixtures (isvc_getter_service_account, isvc_getter_role, etc.) significantly simplifies the test setup but raises questions:

# Before: Used dedicated service account token
- inference_token=isvc_getter_token,
# After: Uses admin token
+ token=token,

Concern: Are we testing realistic authentication scenarios? Using admin tokens instead of service-specific tokens may miss real-world permission issues.

2. Dependency Downgrade

# .pre-commit-config.yaml  
- rev: v0.11.11
+ rev: v0.11.10

Question: What's the reason for downgrading Ruff? This seems unusual unless there's a specific compatibility issue.

3. aiohttp Version Downgrade
The uv.lock shows aiohttp downgraded from 3.12.2 to 3.11.18. This could indicate:

  • Compatibility issues with newer versions
  • Security implications (should verify if 3.11.18 has known vulnerabilities)

🐛 Potential Issues

1. Missing Import Cleanup

# tests/model_explainability/trustyai_service/conftest.py
from ocp_resources.role import Role  # Still imported but unused
from ocp_resources.role_binding import RoleBinding  # Still imported but unused  
from ocp_resources.service_account import ServiceAccount  # Still imported but unused

2. Inconsistent Function Signatures
Some test methods have inconsistent parameter removal:

# Some methods cleaned up properly
def test_fairness_send_inference_and_verify_trustyai_service_with_pvc_storage(
    self, admin_client, current_client_token, model_namespace, trustyai_service_with_pvc_storage, onnx_loan_model
):

# Others might have formatting issues due to line length

🔧 Recommendations

1. Address Unused Imports

# Remove these unused imports from conftest.py
- from ocp_resources.role import Role
- from ocp_resources.role_binding import RoleBinding  
- from ocp_resources.service_account import ServiceAccount
- from utilities.infra import create_inference_token

2. Document Authentication Changes
Consider adding comments explaining why the simplified authentication approach is sufficient for testing purposes.

3. Verify Dependency Changes

  • Confirm the Ruff downgrade is intentional and document the reason
  • Verify aiohttp 3.11.18 doesn't have security vulnerabilities
  • Consider pinning specific versions with justification

4. Test Coverage Validation
Ensure the simplified TrustyAI tests still provide adequate coverage of authentication scenarios in realistic deployment conditions.

🎯 Overall Assessment

The changes appear to be part of a legitimate refactoring effort to simplify test infrastructure while adding new secure database functionality. However, the authentication simplification should be carefully validated to ensure it doesn't reduce test coverage of real-world scenarios.

Priority: Address the unused imports and document the rationale for authentication changes before merging.

Copy link
Copy Markdown
Collaborator

@dbasunag dbasunag left a comment

Choose a reason for hiding this comment

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

I started reviewing before noticing it is draft and I feel giving this reviews now, would help with moving the PR fast. Let me know if you disagree, then I will totally stay off till you indicate otherwise.

Comment thread tests/model_registry/rest_api/test_model_registry_secure_db.py Outdated
Comment thread tests/model_registry/rest_api/test_model_registry_secure_db.py
Comment thread tests/model_registry/rest_api/conftest.py Outdated
@fege
Copy link
Copy Markdown
Contributor Author

fege commented May 29, 2025

I started reviewing before noticing it is draft and I feel giving this reviews now, would help with moving the PR fast. Let me know if you disagree, then I will totally stay off till you indicate otherwise.

yes that was exactly my intention, to get early reviews to avoid to take a "wrong" path in the solution 👍

@fege fege marked this pull request as ready for review June 3, 2025 14:26
@fege fege requested a review from a team as a code owner June 3, 2025 14:26
@fege fege removed the wip label Jun 3, 2025
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: 2

♻️ Duplicate comments (1)
tests/model_registry/rest_api/test_model_registry_secure_db.py (1)

74-95: LGTM! Comprehensive secure DB validation with verification issue.

The test properly validates successful model registration with secure database connections using valid CA certificates.

The assertion on line 92 only validates the ID field as noted in previous reviews. This is consistent with the existing codebase approach.

Fix line length issues:

     """
-    Deploys Model Registry with a secure MySQL DB (SSL/TLS), registers a model, and checks functionality.
-    Uses a CA bundle file for SSL verification by passing it directly to the verify parameter.
+    Deploys Model Registry with a secure MySQL DB (SSL/TLS), registers a model, 
+    and checks functionality. Uses a CA bundle file for SSL verification by 
+    passing it directly to the verify parameter.
     """
     model_name = generate_random_name(prefix="model-rest-api")
     MODEL_REGISTER_DATA["register_model_data"]["name"] = model_name
@@ -89,6 +89,9 @@
         data_dict=MODEL_REGISTER_DATA,
         verify=local_ca_bundle,
     )
-    assert result["register_model"].get("id"), "Model registration failed with secure DB connection."
+    assert result["register_model"].get(
+        "id"
+    ), "Model registration failed with secure DB connection."
     for k, v in MODEL_REGISTER_DATA["register_model_data"].items():
         assert result["register_model"][k] == v, f"Expected {k}={v}, got {result[k]}"
-    LOGGER.info(f"Model registered successfully with secure DB using {local_ca_bundle}")
+    LOGGER.info(
+        f"Model registered successfully with secure DB using {local_ca_bundle}"
+    )
🧰 Tools
🪛 Pylint (3.3.7)

[convention] 81-81: Line too long (109/100)

(C0301)


[convention] 92-92: Line too long (105/100)

(C0301)

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

13-13: Fix import organization and order.

The static analysis identifies several import issues that should be addressed:

  1. Line 13 is too long (115 characters)
  2. Import order is incorrect - third-party imports should come before first-party imports
  3. Imports from the same package should be grouped together

Apply this diff to fix the import organization:

-from tests.model_registry.constants import MR_DB_IMAGE_DIGEST, ISTIO_CONFIG_DICT, DB_RESOURCES_NAME, SECURE_MR_NAME
+from ocp_resources.secret import Secret
+from tests.model_registry.constants import (
+    MR_DB_IMAGE_DIGEST,
+    ISTIO_CONFIG_DICT, 
+    DB_RESOURCES_NAME,
+    SECURE_MR_NAME,
+)
 from utilities.exceptions import ProtocolNotSupportedError, TooManyServicesError
 from utilities.constants import Protocols, Annotations
-from ocp_resources.secret import Secret

Also applies to: 16-16

🧰 Tools
🪛 Pylint (3.3.7)

[convention] 13-13: Line too long (115/100)

(C0301)


270-302: LGTM! Well-structured utility function with minor formatting issue.

The create_secure_model_registry function is well-designed and properly constructs a ModelRegistry resource with secure MySQL configuration. The function signature and implementation are clear and appropriate.

Fix the line length issue on line 293:

-            "host": f"{model_registry_db_service.name}.{model_registry_db_service.namespace}.svc.cluster.local",
+            "host": (
+                f"{model_registry_db_service.name}."
+                f"{model_registry_db_service.namespace}.svc.cluster.local"
+            ),
🧰 Tools
🪛 Pylint (3.3.7)

[convention] 293-293: Line too long (112/100)

(C0301)

tests/model_registry/rest_api/utils.py (2)

32-35: LGTM! SSL verification enhancement with minor documentation issue.

The addition of the verify parameter to enable configurable SSL certificate verification is well-implemented and necessary for the secure database testing functionality.

Add a docstring to maintain consistency with other functions in the module:

 def execute_model_registry_post_command(
     url: str, headers: dict[str, str], data_json: dict[str, Any], verify: bool | str = False
 ) -> dict[Any, Any]:
+    """
+    Execute a POST request to the Model Registry API.
+    
+    Args:
+        url: The API endpoint URL
+        headers: HTTP headers for the request
+        data_json: JSON data to send in the request body
+        verify: SSL certificate verification (bool or path to CA bundle)
+    
+    Returns:
+        The JSON response as a dictionary
+    """
🧰 Tools
🪛 Pylint (3.3.7)

[convention] 32-32: Missing function or method docstring

(C0116)


64-96: LGTM! Proper parameter propagation with minor formatting issue.

The verify parameter is correctly propagated through all the POST calls in the register_model_rest_api function, enabling end-to-end SSL verification control.

Fix the line length issue on line 88:

-        url=f"{model_registry_rest_url}{MODEL_REGISTRY_BASE_URI}model_versions/{model_version['id']}/artifacts",
+        url=(
+            f"{model_registry_rest_url}{MODEL_REGISTRY_BASE_URI}"
+            f"model_versions/{model_version['id']}/artifacts"
+        ),
🧰 Tools
🪛 Pylint (3.3.7)

[convention] 88-88: Line too long (112/100)

(C0301)


[convention] 64-64: Missing function or method docstring

(C0116)

tests/model_registry/rest_api/test_model_registry_secure_db.py (2)

1-11: Add module docstring and fix import organization.

The module is missing a docstring and has import order issues that should be addressed for consistency.

Apply this diff to add documentation and fix imports:

+"""
+Test module for Model Registry functionality with secure MySQL database connections.
+
+This module contains tests that validate SSL/TLS connectivity scenarios including
+both valid and invalid CA certificate configurations.
+"""
+from typing import Self
+
 import pytest
 import requests
-from typing import Self
+
 from tests.model_registry.rest_api.utils import register_model_rest_api
 from tests.model_registry.rest_api.constants import MODEL_REGISTER_DATA
+from tests.model_registry.utils import generate_random_name
 from utilities.constants import DscComponents
+
 from simple_logger.logger import get_logger
-from tests.model_registry.utils import generate_random_name
🧰 Tools
🪛 Pylint (3.3.7)

[convention] 1-1: Missing module docstring

(C0114)


[error] 7-7: Unable to import 'simple_logger.logger'

(E0401)


[convention] 3-3: standard import "typing.Self" should be placed before third party imports "pytest", "requests"

(C0411)


[convention] 7-7: third party import "simple_logger.logger.get_logger" should be placed before first party imports "tests.model_registry.rest_api.utils.register_model_rest_api", "tests.model_registry.rest_api.constants.MODEL_REGISTER_DATA", "utilities.constants.DscComponents"

(C0411)


[convention] 8-8: Imports from package tests are not grouped

(C0412)


44-65: LGTM! Robust SSL error validation with minor issues.

The test correctly validates that SSL certificate verification fails with an invalid CA, and the assertion properly checks for the expected error message.

Address the unused parameter warning and line length:

 def test_register_model_with_invalid_ca(
     self: Self,
-    patch_invalid_ca: dict[str, str],
+    patch_invalid_ca: dict[str, str],  # pylint: disable=unused-argument
     model_registry_rest_url: str,
     model_registry_rest_headers: dict[str, str],
 ) -> None:
     """
-    Test that model registration fails with an SSLError when the Model Registry is deployed
-    with an invalid CA certificate.
+    Test that model registration fails with an SSLError when the Model Registry 
+    is deployed with an invalid CA certificate.
     """

Note: The patch_invalid_ca parameter is needed for the fixture to execute even if not directly used in the test body.

🧰 Tools
🪛 Pylint (3.3.7)

[warning] 46-46: Unused argument 'patch_invalid_ca'

(W0613)

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

16-16: Remove unused logger import and variable.

The get_logger import and LOGGER variable are not used anywhere in this file.

Apply this diff to remove the unused logger:

-from simple_logger.logger import get_logger
 from ocp_resources.model_registry import ModelRegistry


-LOGGER = get_logger(name=__name__)
-

Also applies to: 20-20

🧰 Tools
🪛 Pylint (3.3.7)

[error] 16-16: Unable to import 'simple_logger.logger'

(E0401)


[convention] 16-16: third party import "simple_logger.logger.get_logger" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4743739 and 32b67ce.

📒 Files selected for processing (5)
  • tests/model_registry/constants.py (1 hunks)
  • tests/model_registry/rest_api/conftest.py (2 hunks)
  • tests/model_registry/rest_api/test_model_registry_secure_db.py (1 hunks)
  • tests/model_registry/rest_api/utils.py (3 hunks)
  • tests/model_registry/utils.py (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
tests/model_registry/utils.py (2)
utilities/constants.py (2)
  • Annotations (124-139)
  • KubernetesIo (125-129)
tests/model_registry/conftest.py (3)
  • model_registry_namespace (54-55)
  • model_registry_db_service (59-84)
  • model_registry_db_secret (103-115)
tests/model_registry/rest_api/utils.py (1)
tests/model_registry/rest_api/conftest.py (2)
  • model_registry_rest_url (24-26)
  • model_registry_rest_headers (30-35)
🪛 Pylint (3.3.7)
tests/model_registry/utils.py

[convention] 13-13: Line too long (115/100)

(C0301)


[error] 16-16: Unable to import 'ocp_resources.secret'

(E0401)


[convention] 16-16: third party import "ocp_resources.secret.Secret" should be placed before first party imports "tests.model_registry.constants.MR_DB_IMAGE_DIGEST", "utilities.exceptions.ProtocolNotSupportedError", "utilities.constants.Protocols"

(C0411)


[convention] 16-16: Imports from package ocp_resources are not grouped

(C0412)


[convention] 293-293: Line too long (112/100)

(C0301)

tests/model_registry/rest_api/utils.py

[convention] 32-32: Missing function or method docstring

(C0116)


[convention] 88-88: Line too long (112/100)

(C0301)

tests/model_registry/rest_api/test_model_registry_secure_db.py

[convention] 33-33: Line too long (109/100)

(C0301)


[convention] 81-81: Line too long (109/100)

(C0301)


[convention] 92-92: Line too long (105/100)

(C0301)


[convention] 1-1: Missing module docstring

(C0114)


[error] 7-7: Unable to import 'simple_logger.logger'

(E0401)


[warning] 46-46: Unused argument 'patch_invalid_ca'

(W0613)


[convention] 3-3: standard import "typing.Self" should be placed before third party imports "pytest", "requests"

(C0411)


[convention] 7-7: third party import "simple_logger.logger.get_logger" should be placed before first party imports "tests.model_registry.rest_api.utils.register_model_rest_api", "tests.model_registry.rest_api.constants.MODEL_REGISTER_DATA", "utilities.constants.DscComponents"

(C0411)


[convention] 8-8: Imports from package tests are not grouped

(C0412)

tests/model_registry/rest_api/conftest.py

[convention] 7-7: Line too long (109/100)

(C0301)


[convention] 11-11: Line too long (112/100)

(C0301)


[convention] 12-12: Line too long (108/100)

(C0301)


[convention] 1-1: Missing module docstring

(C0114)


[error] 4-4: Unable to import 'kubernetes.dynamic'

(E0401)


[error] 9-9: Unable to import 'ocp_resources.deployment'

(E0401)


[error] 10-10: Unable to import 'ocp_resources.service'

(E0401)


[error] 13-13: Unable to import 'ocp_resources.resource'

(E0401)


[error] 14-14: Unable to import 'ocp_resources.secret'

(E0401)


[error] 15-15: Unable to import 'ocp_resources.config_map'

(E0401)


[error] 16-16: Unable to import 'simple_logger.logger'

(E0401)


[error] 17-17: Unable to import 'ocp_resources.model_registry'

(E0401)


[convention] 9-9: third party import "ocp_resources.deployment.Deployment" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols"

(C0411)


[convention] 10-10: third party import "ocp_resources.service.Service" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols"

(C0411)


[convention] 13-13: third party import "ocp_resources.resource.ResourceEditor" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 14-14: third party import "ocp_resources.secret.Secret" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 15-15: third party import "ocp_resources.config_map.ConfigMap" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 16-16: third party import "simple_logger.logger.get_logger" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 17-17: third party import "ocp_resources.model_registry.ModelRegistry" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 11-11: Imports from package tests are not grouped

(C0412)


[convention] 13-13: Imports from package ocp_resources are not grouped

(C0412)


[convention] 17-17: Imports from package ocp_resources are not grouped

(C0412)


[convention] 77-77: Line too long (106/100)

(C0301)


[convention] 124-124: Line too long (104/100)

(C0301)


[convention] 138-138: Line too long (115/100)

(C0301)


[convention] 154-154: Line too long (109/100)

(C0301)


[convention] 156-156: Line too long (120/100)

(C0301)


[convention] 168-168: Line too long (109/100)

(C0301)


[convention] 179-179: Line too long (112/100)

(C0301)


[warning] 99-99: Redefining name 'patch_invalid_ca' from outer scope (line 66)

(W0621)


[warning] 164-164: Using open without explicitly specifying an encoding

(W1514)


[warning] 177-177: Catching too general exception Exception

(W0718)


[warning] 172-172: Using open without explicitly specifying an encoding

(W1514)


[warning] 175-175: Using open without explicitly specifying an encoding

(W1514)

🔇 Additional comments (4)
tests/model_registry/constants.py (1)

47-50: LGTM! Well-defined constants for secure configuration.

The new constants are appropriately named and will help maintain consistency across the secure Model Registry test infrastructure. The file path construction using f-string is clean and readable.

tests/model_registry/rest_api/conftest.py (3)

65-92: Well-structured fixture for testing invalid CA scenarios.

The patch_invalid_ca fixture is properly implemented with:

  • Parametrizable CA ConfigMap and file names
  • Clean resource management using ResourceEditor
  • Appropriate yielding of the CA file path for test consumption
🧰 Tools
🪛 Pylint (3.3.7)

[convention] 77-77: Line too long (106/100)

(C0301)


94-112: Clean implementation for Model Registry with custom CA.

The fixture properly leverages the patch_invalid_ca fixture to create a Model Registry instance configured with a custom CA certificate.

🧰 Tools
🪛 Pylint (3.3.7)

[warning] 99-99: Redefining name 'patch_invalid_ca' from outer scope (line 66)

(W0621)


114-151: Comprehensive fixture for secure MySQL and Model Registry setup.

Excellent implementation that:

  • Properly configures MySQL with SSL/TLS by adding the --ssl-ca argument
  • Correctly mounts the CA ConfigMap in the MySQL deployment
  • Uses nested context managers for clean resource management
  • Ensures Model Registry is available before yielding
🧰 Tools
🪛 Pylint (3.3.7)

[convention] 124-124: Line too long (104/100)

(C0301)


[convention] 138-138: Line too long (115/100)

(C0301)

Comment thread tests/model_registry/rest_api/conftest.py Outdated
Comment thread tests/model_registry/rest_api/conftest.py Outdated
@github-actions github-actions Bot added size/xl and removed size/l labels Jun 4, 2025
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 (2)
tests/model_registry/rest_api/conftest.py (2)

195-195: Add explicit encoding to file operations.

File operations should specify encoding explicitly to avoid platform-dependent behavior.

Apply this diff to add explicit encoding:

-    with open(ca_bundle_path, "w") as f:
+    with open(ca_bundle_path, "w", encoding="utf-8") as f:
         f.write(ca_bundle_content)

     try:
         router_secret = Secret(client=admin_client, name="router-ca", namespace="openshift-ingress-operator")
         router_ca_b64 = router_secret.instance.data.get("tls.crt")
         if router_ca_b64:
             router_ca_content = base64.b64decode(router_ca_b64).decode("utf-8")
-            with open(ca_bundle_path, "r") as bundle:
+            with open(ca_bundle_path, "r", encoding="utf-8") as bundle:
                 bundle_content = bundle.read()
             if router_ca_content not in bundle_content:
-                with open(ca_bundle_path, "a") as bundle_append:
+                with open(ca_bundle_path, "a", encoding="utf-8") as bundle_append:
                     bundle_append.write("\n" + router_ca_content)

Also applies to: 203-203, 206-206

🧰 Tools
🪛 Pylint (3.3.7)

[warning] 195-195: Using open without explicitly specifying an encoding

(W1514)


208-211: Improve exception handling specificity.

Catching generic Exception is too broad and might hide unexpected errors. Consider catching more specific exceptions or logging the error before failing.

Apply this diff to improve exception handling:

-    except Exception:
+    except Exception as e:
+        LOGGER.warning(f"Failed to append router CA: {e}")
         pytest.fail(
             "router-ca secret not found in openshift-ingress-operator. Proceeding without appending ingress CA."
         )
🧰 Tools
🪛 Pylint (3.3.7)

[convention] 210-210: Line too long (112/100)

(C0301)


[warning] 208-208: Catching too general exception Exception

(W0718)

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

13-13: Consider reordering imports to follow PEP 8 conventions.

The imports should be grouped: standard library, third-party packages, then local imports. The Secret import is currently mixed with local imports.

Apply this diff to improve import organization:

 from kubernetes.dynamic import DynamicClient
 from ocp_resources.namespace import Namespace
 from ocp_resources.pod import Pod
 from ocp_resources.service import Service
+from ocp_resources.secret import Secret
 from ocp_resources.model_registry_modelregistry_opendatahub_io import ModelRegistry
 from kubernetes.dynamic.exceptions import ResourceNotFoundError
 from simple_logger.logger import get_logger
 from timeout_sampler import TimeoutExpiredError, TimeoutSampler
 from kubernetes.dynamic.exceptions import NotFoundError
 from tests.model_registry.constants import MR_DB_IMAGE_DIGEST, DB_RESOURCES_NAME
 from utilities.exceptions import ProtocolNotSupportedError, TooManyServicesError
 from utilities.constants import Protocols, Annotations
-from ocp_resources.secret import Secret

Also applies to: 16-16

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

1-29: Organize imports following PEP 8 conventions.

The imports should be grouped and ordered: standard library, third-party packages, then local imports. Currently, third-party imports are mixed with local imports.

Apply this diff to improve import organization:

-from typing import Any, Generator
 import os
 import base64
+from typing import Any, Generator
+
 from kubernetes.dynamic import DynamicClient
+from ocp_resources.config_map import ConfigMap
+from ocp_resources.deployment import Deployment
+from ocp_resources.model_registry import ModelRegistry
+from ocp_resources.resource import ResourceEditor
+from ocp_resources.secret import Secret
+from ocp_resources.service import Service
 import pytest
+from simple_logger.logger import get_logger
+
 from tests.model_registry.rest_api.constants import MODEL_REGISTRY_BASE_URI
 from tests.model_registry.rest_api.utils import register_model_rest_api, execute_model_registry_patch_command
-from utilities.constants import Protocols
-from ocp_resources.deployment import Deployment
-from ocp_resources.service import Service
 from tests.model_registry.utils import (
     get_model_registry_deployment_template_dict,
     create_model_registry_instance,
     make_mysql_config,
 )
 from tests.model_registry.constants import (
     DB_RESOURCES_NAME,
     CA_MOUNT_PATH,
     CA_FILE_PATH,
     CA_CONFIGMAP_NAME,
     SECURE_MR_NAME,
     ISTIO_CONFIG_DICT,
     MODEL_REGISTRY_STANDARD_LABELS,
 )
-from ocp_resources.resource import ResourceEditor
-from ocp_resources.secret import Secret
-from ocp_resources.config_map import ConfigMap
-from simple_logger.logger import get_logger
-from ocp_resources.model_registry import ModelRegistry
+from utilities.constants import Protocols
🧰 Tools
🪛 Pylint (3.3.7)

[convention] 7-7: Line too long (109/100)

(C0301)


[convention] 1-1: Missing module docstring

(C0114)


[error] 4-4: Unable to import 'kubernetes.dynamic'

(E0401)


[error] 9-9: Unable to import 'ocp_resources.deployment'

(E0401)


[error] 10-10: Unable to import 'ocp_resources.service'

(E0401)


[error] 25-25: Unable to import 'ocp_resources.resource'

(E0401)


[error] 26-26: Unable to import 'ocp_resources.secret'

(E0401)


[error] 27-27: Unable to import 'ocp_resources.config_map'

(E0401)


[error] 28-28: Unable to import 'simple_logger.logger'

(E0401)


[error] 29-29: Unable to import 'ocp_resources.model_registry'

(E0401)


[convention] 9-9: third party import "ocp_resources.deployment.Deployment" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols"

(C0411)


[convention] 10-10: third party import "ocp_resources.service.Service" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols"

(C0411)


[convention] 25-25: third party import "ocp_resources.resource.ResourceEditor" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 26-26: third party import "ocp_resources.secret.Secret" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 27-27: third party import "ocp_resources.config_map.ConfigMap" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 28-28: third party import "simple_logger.logger.get_logger" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 29-29: third party import "ocp_resources.model_registry.ModelRegistry" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 11-15: Imports from package tests are not grouped

(C0412)


[convention] 25-25: Imports from package ocp_resources are not grouped

(C0412)


[convention] 29-29: Imports from package ocp_resources are not grouped

(C0412)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32b67ce and b1ac604.

📒 Files selected for processing (3)
  • tests/model_registry/constants.py (1 hunks)
  • tests/model_registry/rest_api/conftest.py (2 hunks)
  • tests/model_registry/utils.py (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • tests/model_registry/constants.py
🧰 Additional context used
🧬 Code Graph Analysis (1)
tests/model_registry/utils.py (2)
utilities/exceptions.py (2)
  • ProtocolNotSupportedError (8-13)
  • TooManyServicesError (16-21)
utilities/constants.py (2)
  • Protocols (87-94)
  • Annotations (124-139)
🪛 Pylint (3.3.7)
tests/model_registry/rest_api/conftest.py

[convention] 7-7: Line too long (109/100)

(C0301)


[convention] 1-1: Missing module docstring

(C0114)


[error] 4-4: Unable to import 'kubernetes.dynamic'

(E0401)


[error] 9-9: Unable to import 'ocp_resources.deployment'

(E0401)


[error] 10-10: Unable to import 'ocp_resources.service'

(E0401)


[error] 25-25: Unable to import 'ocp_resources.resource'

(E0401)


[error] 26-26: Unable to import 'ocp_resources.secret'

(E0401)


[error] 27-27: Unable to import 'ocp_resources.config_map'

(E0401)


[error] 28-28: Unable to import 'simple_logger.logger'

(E0401)


[error] 29-29: Unable to import 'ocp_resources.model_registry'

(E0401)


[convention] 9-9: third party import "ocp_resources.deployment.Deployment" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols"

(C0411)


[convention] 10-10: third party import "ocp_resources.service.Service" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols"

(C0411)


[convention] 25-25: third party import "ocp_resources.resource.ResourceEditor" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 26-26: third party import "ocp_resources.secret.Secret" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 27-27: third party import "ocp_resources.config_map.ConfigMap" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 28-28: third party import "simple_logger.logger.get_logger" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 29-29: third party import "ocp_resources.model_registry.ModelRegistry" should be placed before first party imports "tests.model_registry.rest_api.constants.MODEL_REGISTRY_BASE_URI", "tests.model_registry.rest_api.utils.register_model_rest_api", "utilities.constants.Protocols", "tests.model_registry.utils.get_model_registry_deployment_template_dict", "tests.model_registry.constants.DB_RESOURCES_NAME"

(C0411)


[convention] 11-15: Imports from package tests are not grouped

(C0412)


[convention] 25-25: Imports from package ocp_resources are not grouped

(C0412)


[convention] 29-29: Imports from package ocp_resources are not grouped

(C0412)


[convention] 89-89: Line too long (106/100)

(C0301)


[convention] 146-146: Line too long (104/100)

(C0301)


[convention] 160-160: Line too long (115/100)

(C0301)


[convention] 185-185: Line too long (109/100)

(C0301)


[convention] 187-187: Line too long (120/100)

(C0301)


[convention] 199-199: Line too long (109/100)

(C0301)


[convention] 210-210: Line too long (112/100)

(C0301)


[warning] 111-111: Redefining name 'patch_invalid_ca' from outer scope (line 78)

(W0621)


[warning] 195-195: Using open without explicitly specifying an encoding

(W1514)


[warning] 208-208: Catching too general exception Exception

(W0718)


[warning] 203-203: Using open without explicitly specifying an encoding

(W1514)


[warning] 206-206: Using open without explicitly specifying an encoding

(W1514)

tests/model_registry/utils.py

[error] 16-16: Unable to import 'ocp_resources.secret'

(E0401)


[convention] 16-16: third party import "ocp_resources.secret.Secret" should be placed before first party imports "tests.model_registry.constants.MR_DB_IMAGE_DIGEST", "utilities.exceptions.ProtocolNotSupportedError", "utilities.constants.Protocols"

(C0411)


[convention] 16-16: Imports from package ocp_resources are not grouped

(C0412)

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

321-349: Well-implemented MySQL configuration utility.

The make_mysql_config function is well-structured and correctly constructs the MySQL configuration dictionary with SSL support. The function properly:

  • Builds the service host using Kubernetes DNS conventions
  • Extracts database credentials from the secret
  • Includes SSL CA configuration for secure connections
  • Uses sensible defaults for port and resource name
tests/model_registry/rest_api/conftest.py (2)

77-103: Good fixture design for CA certificate testing.

The patch_invalid_ca fixture is well-implemented for testing invalid CA certificate scenarios. It properly uses the ResourceEditor context manager to patch the ConfigMap and yields the CA file path for use in tests.

🧰 Tools
🪛 Pylint (3.3.7)

[convention] 89-89: Line too long (106/100)

(C0301)


136-181: Well-structured secure MySQL deployment fixture.

The deploy_secure_mysql_and_mr fixture effectively configures MySQL with SSL/TLS by:

  • Adding SSL CA arguments to the MySQL container
  • Mounting the CA ConfigMap as a volume
  • Creating a secure Model Registry instance
  • Using proper nested context managers for resource lifecycle
🧰 Tools
🪛 Pylint (3.3.7)

[convention] 146-146: Line too long (104/100)

(C0301)


[convention] 160-160: Line too long (115/100)

(C0301)

Comment thread tests/model_registry/rest_api/conftest.py Outdated
lugi0
lugi0 previously approved these changes Jun 4, 2025
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.

A potential improvement that we can also handle in a separate PR, other than that LGTM

Comment thread tests/model_registry/utils.py Outdated
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: 2

🧹 Nitpick comments (4)
utilities/certificates_utils.py (1)

127-138: Doc-string refers to wrong resource type

The parameter description still says “client: The admin client to create the ConfigMap” while this helper creates a Secret.
Please fix to avoid confusion for future readers.

tests/model_registry/rest_api/test_model_registry_secure_db.py (1)

79-88: Assertion on string value is brittle; assert the exception class instead

requests.exceptions.SSLError is already captured by pytest.raises.
Checking that the string contains “SSLError” is redundant and may break
if the exception message changes.

-        assert "SSLError" in str(exc_info.value), (
-            f"Expected SSL certificate verification failure, got: {exc_info.value}"
-        )
+        assert exc_info.type is requests.exceptions.SSLError
tests/model_registry/rest_api/utils.py (1)

36-40: Logging leaks full response bodies

LOGGER.info(..., rep: {resp.text}) logs the entire server response which may contain
credentials or PII (e.g., connection strings).
Consider downgrading to DEBUG or redacting sensitive fields before logging.

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

140-147: Hard-coded arg/volume indices assume single-container template

mysql_template["spec"]["containers"][0] mutates the first container
unconditionally. If the template ever adds an init-container before MySQL,
this will patch the wrong one.
Search for the container by name (as you already do later in
patch_mysql_deployment_with_ssl_ca) for consistency.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3500ff0 and 71b9f5a.

📒 Files selected for processing (5)
  • tests/model_registry/conftest.py (1 hunks)
  • tests/model_registry/rest_api/conftest.py (2 hunks)
  • tests/model_registry/rest_api/test_model_registry_secure_db.py (1 hunks)
  • tests/model_registry/rest_api/utils.py (6 hunks)
  • utilities/certificates_utils.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/model_registry/conftest.py
🧰 Additional context used
🧠 Learnings (2)
tests/model_registry/rest_api/utils.py (1)
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#320
File: tests/model_registry/rest_api/utils.py:40-44
Timestamp: 2025-06-18T06:42:37.696Z
Learning: In tests/model_registry/rest_api/utils.py, the user prefers to keep the default value of verify=False in execute_model_registry_post_command to maintain backward compatibility, rather than changing it to True for security reasons.
tests/model_registry/rest_api/conftest.py (2)
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#320
File: tests/model_registry/rest_api/conftest.py:200-216
Timestamp: 2025-06-05T14:32:40.247Z
Learning: In the opendatahub-tests repository, the test fixtures should raise exceptions on cleanup failures rather than just logging warnings. The user fege prefers strict cleanup behavior where tests fail if cleanup doesn't work properly, rather than silently continuing.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#320
File: tests/model_registry/rest_api/conftest.py:257-264
Timestamp: 2025-06-18T08:27:21.097Z
Learning: In tests/model_registry/rest_api/conftest.py, the user fege prefers using next() without a default value to raise StopIteration when the mysql container is not found, rather than gracefully handling it with None checks. This is a deliberate "fail fast" design choice.
🪛 Pylint (3.3.7)
tests/model_registry/rest_api/conftest.py

[refactor] 151-151: Too many arguments (6/5)

(R0913)


[refactor] 151-151: Too many positional arguments (6/5)

(R0917)


[refactor] 239-239: Too many arguments (6/5)

(R0913)


[refactor] 239-239: Too many positional arguments (6/5)

(R0917)


[refactor] 239-239: Too many local variables (16/15)

(R0914)


[refactor] 261-261: Do not raise StopIteration in generator, use return statement instead

(R1708)

tests/model_registry/rest_api/test_model_registry_secure_db.py

[refactor] 58-58: Too many arguments (6/5)

(R0913)


[refactor] 58-58: Too many positional arguments (6/5)

(R0917)


[refactor] 105-105: Too many arguments (6/5)

(R0913)


[refactor] 105-105: Too many positional arguments (6/5)

(R0917)

🔇 Additional comments (1)
tests/model_registry/rest_api/test_model_registry_secure_db.py (1)

2-3: typing.Self requires Python ≥ 3.11 – confirm runtime version

The project previously targeted Python 3.10.
If the test suite still runs against 3.10 images, importing Self will raise ImportError.
Please verify the CI image or gate the import with a fallback.

Comment thread utilities/certificates_utils.py
Comment thread tests/model_registry/rest_api/conftest.py
@fege fege requested review from dbasunag and lugi0 June 18, 2025 15:54
lugi0
lugi0 previously approved these changes Jun 18, 2025
Copy link
Copy Markdown
Collaborator

@dbasunag dbasunag left a comment

Choose a reason for hiding this comment

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

Looks good @fege . I added a few comments though.

Comment thread tests/model_registry/rest_api/conftest.py Outdated
Comment thread tests/model_registry/rest_api/conftest.py Outdated
Comment thread tests/model_registry/rest_api/test_model_registry_secure_db.py
Comment thread tests/model_registry/rest_api/test_model_registry_secure_db.py
Comment thread tests/model_registry/rest_api/test_model_registry_secure_db.py Outdated
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: 2

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

228-229: Add explicit encoding to file operations.

File operations should specify encoding explicitly to avoid platform-dependent behavior.

This issue was already identified in past reviews and appears to have been addressed in commit 3a056d2, but the change may not be visible in the current diff.

🧹 Nitpick comments (4)
tests/model_registry/utils.py (1)

266-288: Consider using deep copy for deployment spec manipulation.

The function uses list(spec["volumes"]) which creates a shallow copy. If the original volumes contain nested dictionaries, mutations could affect the original spec unexpectedly.

Consider using deep copy for safer manipulation:

+import copy

def add_mysql_certs_volumes_to_deployment(
    spec: dict[str, Any],
    ca_configmap_name: str,
) -> list[dict[str, Any]]:
    """
    Adds the MySQL certs volumes to the deployment.
    ...
    """
-    volumes = list(spec["volumes"])
+    volumes = copy.deepcopy(spec["volumes"])
    volumes.extend([
        {"name": ca_configmap_name, "configMap": {"name": ca_configmap_name}},
        {"name": "mysql-server-cert", "secret": {"secretName": "mysql-server-cert"}},
        {"name": "mysql-server-key", "secret": {"secretName": "mysql-server-key"}},
    ])
    return volumes
tests/model_registry/rest_api/test_model_registry_secure_db.py (2)

42-82: Test method complexity could be reduced.

The test method has 7 parameters which makes it complex to understand and maintain. Consider extracting some setup logic into separate fixtures or helper methods.

The static analysis correctly identifies this as having too many arguments. While the test logic is sound, consider breaking down the fixture dependencies or using fixture composition to reduce parameter count.


84-124: Test method complexity - same issue as first test.

Similar to the first test method, this one also has 7 parameters. The complexity warning applies here as well.

Consider the same approach as suggested for the first test method to reduce parameter complexity.

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

199-208: CA bundle file creation in current directory may cause conflicts.

Creating the CA bundle file in the current working directory with a fixed name could cause conflicts if tests run in parallel or if the file already exists.

Consider using a unique temporary file path:

def local_ca_bundle(request: pytest.FixtureRequest, admin_client: DynamicClient) -> Generator[str, Any, Any]:
    """
    Creates a local CA bundle file by fetching the CA bundle from a ConfigMap and appending the router CA from a Secret.
    ...
    """
+    import tempfile
+    import os
    ca_bundle_filename = getattr(request, "param", {}).get("cert_name", "ca-bundle.crt")
+    temp_dir = tempfile.mkdtemp(prefix="mr_ca_")
+    ca_bundle_path = os.path.join(temp_dir, ca_bundle_filename)
-    ca_bundle_path = getattr(request, "param", {}).get("cert_name", "ca-bundle.crt")
    create_ca_bundle_with_router_cert(
        client=admin_client,
        namespace=py_config["model_registry_namespace"],
        ca_bundle_path=ca_bundle_path,
        cert_name=ca_bundle_path,
    )
    yield ca_bundle_path

-    os.remove(ca_bundle_path)
+    import shutil
+    shutil.rmtree(temp_dir, ignore_errors=True)

However, I notice from past comments you're keeping the current implementation for now, so this is just a suggestion for future consideration.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 71b9f5a and 778d675.

📒 Files selected for processing (4)
  • tests/model_registry/rest_api/conftest.py (2 hunks)
  • tests/model_registry/rest_api/test_model_registry_secure_db.py (1 hunks)
  • tests/model_registry/utils.py (1 hunks)
  • utilities/certificates_utils.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • utilities/certificates_utils.py
🧰 Additional context used
🧠 Learnings (1)
tests/model_registry/rest_api/conftest.py (2)
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#320
File: tests/model_registry/rest_api/conftest.py:200-216
Timestamp: 2025-06-05T14:32:40.247Z
Learning: In the opendatahub-tests repository, the test fixtures should raise exceptions on cleanup failures rather than just logging warnings. The user fege prefers strict cleanup behavior where tests fail if cleanup doesn't work properly, rather than silently continuing.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#320
File: tests/model_registry/rest_api/conftest.py:257-264
Timestamp: 2025-06-18T08:27:21.114Z
Learning: In tests/model_registry/rest_api/conftest.py, the user fege prefers using next() without a default value to raise StopIteration when the mysql container is not found, rather than gracefully handling it with None checks. This is a deliberate "fail fast" design choice.
🪛 Pylint (3.3.7)
tests/model_registry/rest_api/conftest.py

[refactor] 156-156: Too many arguments (6/5)

(R0913)


[refactor] 156-156: Too many positional arguments (6/5)

(R0917)


[refactor] 244-244: Too many arguments (6/5)

(R0913)


[refactor] 244-244: Too many positional arguments (6/5)

(R0917)


[refactor] 260-260: Do not raise StopIteration in generator, use return statement instead

(R1708)

tests/model_registry/rest_api/test_model_registry_secure_db.py

[refactor] 55-55: Too many arguments (7/5)

(R0913)


[refactor] 55-55: Too many positional arguments (7/5)

(R0917)


[refactor] 99-99: Too many arguments (7/5)

(R0913)


[refactor] 99-99: Too many positional arguments (7/5)

(R0917)

🔇 Additional comments (2)
tests/model_registry/rest_api/test_model_registry_secure_db.py (1)

75-75: Confirming URL annotation format for get_endpoint_from_mr_service

I looked at get_endpoint_from_mr_service in tests/model_registry/utils.py. It simply reads

svc.instance.metadata.annotations[f"{ADDRESS_ANNOTATION_PREFIX}{protocol}"]

where ADDRESS_ANNOTATION_PREFIX = "routing.opendatahub.io/external-address-". To see how that annotation is set, we need to inspect the fixtures in tests/model_registry/conftest.py that deploy the model registry and create the Route/Service.

#!/bin/bash
# Show where the external-address annotation is populated
rg -n "external-address-REST" -C3 tests/model_registry/conftest.py
sed -n '230,300p' tests/model_registry/conftest.py
tests/model_registry/rest_api/conftest.py (1)

346-349: Good practice using deep copy for test data.

The fixture correctly uses copy.deepcopy(MODEL_REGISTER_DATA) to avoid mutating the original constant, which is a good practice for test data generation.

Comment thread tests/model_registry/utils.py
Comment thread tests/model_registry/rest_api/conftest.py
Copy link
Copy Markdown
Contributor

@sheltoncyril sheltoncyril left a comment

Choose a reason for hiding this comment

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

/lgtm

@github-actions
Copy link
Copy Markdown

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

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.

5 participants