Skip to content

Use exitStack to support multiple resource creations#420

Closed
dbasunag wants to merge 2 commits intoopendatahub-io:mainfrom
dbasunag:multi
Closed

Use exitStack to support multiple resource creations#420
dbasunag wants to merge 2 commits intoopendatahub-io:mainfrom
dbasunag:multi

Conversation

@dbasunag
Copy link
Copy Markdown
Collaborator

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

@dbasunag dbasunag requested a review from a team as a code owner July 11, 2025 02:41
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jul 11, 2025

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added support for testing and managing multiple Model Registry instances concurrently.
    • Introduced new utility functions for generating resources and model registration data.
    • Added new test constants and a test suite for validating multiple Model Registry instances.
  • Bug Fixes

    • Updated tests and fixtures to handle lists of resources, improving reliability when working with multiple instances.
  • Refactor

    • Standardized test code and fixtures to use lists for resources and clients.
    • Updated parameter and variable names for consistency across tests.
  • Style

    • Minor formatting improvements in test files.
  • Chores

    • Removed unused constants and imports.
    • Improved test maintainability and scalability for future enhancements.

Walkthrough

This change refactors Model Registry test infrastructure to support multiple resource instances in parallel. Fixtures, utility functions, and test code are updated to handle lists of resources rather than single objects. New utility functions enable programmatic creation of multiple Kubernetes resources, and test logic is adjusted accordingly throughout the suite.

Changes

Files/Paths Change Summary
tests/model_registry/conftest.py Refactored all fixtures to yield lists of resources (e.g., Service, Secret, Deployment, ModelRegistry) using new helper functions; removed single-instance logic and the model_registry_mysql_config fixture; updated dependent fixtures and control flow for lists.
tests/model_registry/constants.py Split resource name constants into base and indexed forms; removed unused MODEL_REGISTRY_STANDARD_LABELS constant.
tests/model_registry/image_validation/test_verify_rhoai_images.py
tests/model_registry/negative_tests/test_db_migration.py
Updated test parameter types from single ModelRegistry to list[Any]; removed direct ModelRegistry imports.
tests/model_registry/negative_tests/test_model_registry_creation_negative.py Replaced old resource name constants with new base name constants in test logic.
tests/model_registry/python_client/test_model_registry_creation.py Changed test parameters to accept lists of ModelRegistryClient and REST URLs; updated code to use first element of lists.
tests/model_registry/rbac/conftest.py Removed extraneous blank line in imports.
tests/model_registry/rbac/test_mr_rbac.py
tests/model_registry/rbac/test_mr_rbac_sa.py
Changed REST endpoint parameters from string to list; updated usages to access first element; added model_registry_instance fixture to relevant tests.
tests/model_registry/rest_api/conftest.py Updated fixtures to accept and process lists of resources instead of single instances; adjusted logic to use first element; updated label handling and MySQL config retrieval.
tests/model_registry/rest_api/constants.py Added new constants for custom properties, model version and artifact descriptions, and state attributes for REST API testing.
tests/model_registry/rest_api/test_model_registry_rest_api.py Updated references to model_registry_instance to use first element of list throughout test methods.
tests/model_registry/rest_api/test_model_registry_secure_db.py Changed test parameter and fixture names from MySQL config to Model Registry instance for consistency.
tests/model_registry/rest_api/test_multple_mr.py Added new test module to validate multiple Model Registry instances and their REST APIs.
tests/model_registry/rest_api/utils.py Added utility function to generate lists of model registration data for testing multiple models.
tests/model_registry/upgrade/test_model_registry_upgrade.py Updated test parameters to accept lists of clients and instances; changed all usages to access first element.
tests/model_registry/utils.py Added multiple utility functions to create lists of Kubernetes resources and ModelRegistry objects; added helper for standard labels and MySQL config.

Possibly related PRs

  • opendatahub-io/opendatahub-tests#362: Refactors similar fixtures in tests/model_registry/conftest.py to add OAuth proxy parameterization, indicating related changes at the fixture level but with a different focus (multi-instance support vs. OAuth).

Suggested labels

size/xxl, lgtm-by-dbasunag, lgtm-by-fege, ModelRegistry, Utilities, build-push-pr-image

Suggested reviewers

  • lugi0
  • fege
✨ 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.

@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

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

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

🔭 Outside diff range comments (1)
tests/model_registry/conftest.py (1)

193-195: Return type inconsistency in post-upgrade path.

The post-upgrade path yields a single ModelRegistry instance but the return type annotation indicates list[Any]. This should yield a list for consistency.

-        mr_instance = ModelRegistry(name=MR_INSTANCE_NAME, namespace=model_registry_namespace, ensure_exists=True)
-        yield mr_instance
-        mr_instance.delete(wait=True)
+        mr_instance = ModelRegistry(name=MR_INSTANCE_NAME, namespace=model_registry_namespace, ensure_exists=True)
+        yield [mr_instance]
+        mr_instance.delete(wait=True)
🧹 Nitpick comments (5)
tests/model_registry/rest_api/test_multple_mr.py (1)

16-16: Consider making NUM_RESOURCES configurable.

The hardcoded NUM_RESOURCES = {"num": 3} could be made configurable through pytest parameters or environment variables to allow different test scenarios without code changes.

-NUM_RESOURCES = {"num": 3}
+NUM_RESOURCES = {"num": int(os.environ.get("MR_TEST_INSTANCES", "3"))}

Don't forget to add the import:

+import os
tests/model_registry/rbac/test_mr_rbac_sa.py (2)

41-42: Consider adding bounds checking for list access.

The parameter type change from single string to list is consistent with the multi-instance refactor. However, accessing [0] without bounds checking could fail if the list is empty.

Consider adding a check like:

+    if not model_registry_instance_rest_endpoint:
+        pytest.fail("No model registry endpoints available")
     rest_endpoint = model_registry_instance_rest_endpoint[0]

Also applies to: 72-73


78-78: Fix logging inconsistency.

Line 78 logs the entire list while other log statements (line 48) only log the first element. This creates inconsistent log output.

-        LOGGER.info(f"Targeting Model Registry REST endpoint: {model_registry_instance_rest_endpoint}")
+        LOGGER.info(f"Targeting Model Registry REST endpoint: {model_registry_instance_rest_endpoint[0]}")
tests/model_registry/upgrade/test_model_registry_upgrade.py (1)

38-38: Consider adding defensive checks for list access.

Similar to other files, accessing [0] without bounds checking could fail if the lists are empty. While this is unlikely in the test context, adding defensive checks would make the code more robust.

Consider adding checks like:

assert model_registry_client, "No model registry clients available"
assert model_registry_instance, "No model registry instances available"

Also applies to: 56-56, 68-68, 77-77, 88-88

tests/model_registry/conftest.py (1)

401-402: Document the behavior of using only the first client.

The fixture receives a list of clients but only uses the first one. Consider adding a comment to clarify this is intentional.

 def registered_model(request: FixtureRequest, model_registry_client: list[ModelRegistryClient]) -> RegisteredModel:
+    # Use the first client from the list for single model registration
     return model_registry_client[0].register_model(
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 76564ac and a10c4a6.

📒 Files selected for processing (17)
  • tests/model_registry/conftest.py (9 hunks)
  • tests/model_registry/constants.py (3 hunks)
  • tests/model_registry/image_validation/test_verify_rhoai_images.py (2 hunks)
  • tests/model_registry/negative_tests/test_db_migration.py (2 hunks)
  • tests/model_registry/negative_tests/test_model_registry_creation_negative.py (3 hunks)
  • tests/model_registry/python_client/test_model_registry_creation.py (3 hunks)
  • tests/model_registry/rbac/conftest.py (0 hunks)
  • tests/model_registry/rbac/test_mr_rbac.py (6 hunks)
  • tests/model_registry/rbac/test_mr_rbac_sa.py (3 hunks)
  • tests/model_registry/rest_api/conftest.py (11 hunks)
  • tests/model_registry/rest_api/constants.py (1 hunks)
  • tests/model_registry/rest_api/test_model_registry_rest_api.py (1 hunks)
  • tests/model_registry/rest_api/test_model_registry_secure_db.py (4 hunks)
  • tests/model_registry/rest_api/test_multple_mr.py (1 hunks)
  • tests/model_registry/rest_api/utils.py (3 hunks)
  • tests/model_registry/upgrade/test_model_registry_upgrade.py (3 hunks)
  • tests/model_registry/utils.py (2 hunks)
💤 Files with no reviewable changes (1)
  • tests/model_registry/rbac/conftest.py
🧰 Additional context used
🧠 Learnings (17)
📓 Common learnings
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:166-175
Timestamp: 2025-06-16T11:25:39.599Z
Learning: In tests/model_registry/rbac/conftest.py, predictable names are intentionally used for test resources (like RoleBindings and groups) instead of random names. This design choice prioritizes exposing cleanup failures from previous test runs through name collisions rather than masking such issues with random names. The philosophy is that test failures should be observable and informative to help debug underlying infrastructure or cleanup issues.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
Learnt from: adolfo-ab
PR: opendatahub-io/opendatahub-tests#334
File: tests/model_explainability/trustyai_service/test_trustyai_service.py:52-65
Timestamp: 2025-06-05T10:05:17.642Z
Learning: For TrustyAI image validation tests: operator image tests require admin_client, related_images_refs, and trustyai_operator_configmap fixtures, while service image tests would require different fixtures like trustyai_service_with_pvc_storage, model_namespace, and current_client_token.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#409
File: tests/model_registry/negative_tests/test_db_migration.py:47-57
Timestamp: 2025-07-09T08:50:22.172Z
Learning: In negative tests for model registry database migration failures (like test_db_migration_negative), the model registry pod is expected to be in a failed state (not Running) when the database is dirty. The test fetches logs from the failed pod to verify the expected error message about dirty database version, so waiting for Running status would be inappropriate.
tests/model_registry/negative_tests/test_model_registry_creation_negative.py (7)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:166-175
Timestamp: 2025-06-16T11:25:39.599Z
Learning: In tests/model_registry/rbac/conftest.py, predictable names are intentionally used for test resources (like RoleBindings and groups) instead of random names. This design choice prioritizes exposing cleanup failures from previous test runs through name collisions rather than masking such issues with random names. The philosophy is that test failures should be observable and informative to help debug underlying infrastructure or cleanup issues.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#409
File: tests/model_registry/negative_tests/test_db_migration.py:47-57
Timestamp: 2025-07-09T08:50:22.172Z
Learning: In negative tests for model registry database migration failures (like test_db_migration_negative), the model registry pod is expected to be in a failed state (not Running) when the database is dirty. The test fetches logs from the failed pod to verify the expected error message about dirty database version, so waiting for Running status would be inappropriate.
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.705Z
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.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:355-371
Timestamp: 2025-06-16T11:25:51.461Z
Learning: In the opendatahub-tests repository, the login_as_test_user fixture in tests/model_registry/rbac/conftest.py intentionally logs back in as the original admin user without providing a password using login_with_user_password. This behavior is acceptable in their testing environment.
Learnt from: adolfo-ab
PR: opendatahub-io/opendatahub-tests#334
File: tests/model_explainability/trustyai_service/test_trustyai_service.py:52-65
Timestamp: 2025-06-05T10:05:17.642Z
Learning: For TrustyAI image validation tests: operator image tests require admin_client, related_images_refs, and trustyai_operator_configmap fixtures, while service image tests would require different fixtures like trustyai_service_with_pvc_storage, model_namespace, and current_client_token.
tests/model_registry/rest_api/utils.py (5)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
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.705Z
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.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#409
File: tests/model_registry/negative_tests/test_db_migration.py:47-57
Timestamp: 2025-07-09T08:50:22.172Z
Learning: In negative tests for model registry database migration failures (like test_db_migration_negative), the model registry pod is expected to be in a failed state (not Running) when the database is dirty. The test fetches logs from the failed pod to verify the expected error message about dirty database version, so waiting for Running status would be inappropriate.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:166-175
Timestamp: 2025-06-16T11:25:39.599Z
Learning: In tests/model_registry/rbac/conftest.py, predictable names are intentionally used for test resources (like RoleBindings and groups) instead of random names. This design choice prioritizes exposing cleanup failures from previous test runs through name collisions rather than masking such issues with random names. The philosophy is that test failures should be observable and informative to help debug underlying infrastructure or cleanup issues.
tests/model_registry/negative_tests/test_db_migration.py (4)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#296
File: tests/model_registry/rbac/test_mr_rbac_sa.py:1-4
Timestamp: 2025-05-06T23:36:04.545Z
Learning: The opendatahub-tests repository is pinned to Python 3.12, which supports `typing.Self` natively, so there's no need for backward compatibility imports from typing_extensions.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#409
File: tests/model_registry/negative_tests/test_db_migration.py:47-57
Timestamp: 2025-07-09T08:50:22.172Z
Learning: In negative tests for model registry database migration failures (like test_db_migration_negative), the model registry pod is expected to be in a failed state (not Running) when the database is dirty. The test fetches logs from the failed pod to verify the expected error message about dirty database version, so waiting for Running status would be inappropriate.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
tests/model_registry/image_validation/test_verify_rhoai_images.py (4)
Learnt from: adolfo-ab
PR: opendatahub-io/opendatahub-tests#334
File: tests/model_explainability/trustyai_service/test_trustyai_service.py:52-65
Timestamp: 2025-06-05T10:05:17.642Z
Learning: For TrustyAI image validation tests: operator image tests require admin_client, related_images_refs, and trustyai_operator_configmap fixtures, while service image tests would require different fixtures like trustyai_service_with_pvc_storage, model_namespace, and current_client_token.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#409
File: tests/model_registry/negative_tests/test_db_migration.py:47-57
Timestamp: 2025-07-09T08:50:22.172Z
Learning: In negative tests for model registry database migration failures (like test_db_migration_negative), the model registry pod is expected to be in a failed state (not Running) when the database is dirty. The test fetches logs from the failed pod to verify the expected error message about dirty database version, so waiting for Running status would be inappropriate.
tests/model_registry/python_client/test_model_registry_creation.py (5)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: lugi0
PR: opendatahub-io/opendatahub-tests#296
File: tests/model_registry/rbac/test_mr_rbac_sa.py:0-0
Timestamp: 2025-05-07T10:40:15.681Z
Learning: The `build_mr_client_args` function in the Model Registry RBAC tests uses simple string splitting (`rest_endpoint.split(":")`) for endpoint parsing by design. This implementation is intentionally non-robust to serve as a detection mechanism for any unexpected changes to the endpoint format.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#283
File: tests/model_registry/rbac/utils.py:31-32
Timestamp: 2025-05-22T14:14:45.746Z
Learning: In the OpenDataHub tests codebase, the ModelRegistryClient accepts the port parameter as a string, and explicit conversion to integer is not required.
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.705Z
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/rbac/test_mr_rbac.py (9)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:355-371
Timestamp: 2025-06-16T11:25:51.461Z
Learning: In the opendatahub-tests repository, the login_as_test_user fixture in tests/model_registry/rbac/conftest.py intentionally logs back in as the original admin user without providing a password using login_with_user_password. This behavior is acceptable in their testing environment.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:166-175
Timestamp: 2025-06-16T11:25:39.599Z
Learning: In tests/model_registry/rbac/conftest.py, predictable names are intentionally used for test resources (like RoleBindings and groups) instead of random names. This design choice prioritizes exposing cleanup failures from previous test runs through name collisions rather than masking such issues with random names. The philosophy is that test failures should be observable and informative to help debug underlying infrastructure or cleanup issues.
Learnt from: lugi0
PR: opendatahub-io/opendatahub-tests#296
File: tests/model_registry/rbac/test_mr_rbac_sa.py:0-0
Timestamp: 2025-05-07T10:40:15.681Z
Learning: The `build_mr_client_args` function in the Model Registry RBAC tests uses simple string splitting (`rest_endpoint.split(":")`) for endpoint parsing by design. This implementation is intentionally non-robust to serve as a detection mechanism for any unexpected changes to the endpoint format.
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.705Z
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.
Learnt from: adolfo-ab
PR: opendatahub-io/opendatahub-tests#334
File: tests/model_explainability/trustyai_service/test_trustyai_service.py:52-65
Timestamp: 2025-06-05T10:05:17.642Z
Learning: For TrustyAI image validation tests: operator image tests require admin_client, related_images_refs, and trustyai_operator_configmap fixtures, while service image tests would require different fixtures like trustyai_service_with_pvc_storage, model_namespace, and current_client_token.
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.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#409
File: tests/model_registry/negative_tests/test_db_migration.py:47-57
Timestamp: 2025-07-09T08:50:22.172Z
Learning: In negative tests for model registry database migration failures (like test_db_migration_negative), the model registry pod is expected to be in a failed state (not Running) when the database is dirty. The test fetches logs from the failed pod to verify the expected error message about dirty database version, so waiting for Running status would be inappropriate.
tests/model_registry/rest_api/test_model_registry_secure_db.py (10)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
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.705Z
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.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:166-175
Timestamp: 2025-06-16T11:25:39.599Z
Learning: In tests/model_registry/rbac/conftest.py, predictable names are intentionally used for test resources (like RoleBindings and groups) instead of random names. This design choice prioritizes exposing cleanup failures from previous test runs through name collisions rather than masking such issues with random names. The philosophy is that test failures should be observable and informative to help debug underlying infrastructure or cleanup issues.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:355-371
Timestamp: 2025-06-16T11:25:51.461Z
Learning: In the opendatahub-tests repository, the login_as_test_user fixture in tests/model_registry/rbac/conftest.py intentionally logs back in as the original admin user without providing a password using login_with_user_password. This behavior is acceptable in their testing environment.
Learnt from: adolfo-ab
PR: opendatahub-io/opendatahub-tests#334
File: tests/model_explainability/trustyai_service/test_trustyai_service.py:52-65
Timestamp: 2025-06-05T10:05:17.642Z
Learning: For TrustyAI image validation tests: operator image tests require admin_client, related_images_refs, and trustyai_operator_configmap fixtures, while service image tests would require different fixtures like trustyai_service_with_pvc_storage, model_namespace, and current_client_token.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#338
File: tests/model_registry/rbac/test_mr_rbac.py:24-53
Timestamp: 2025-06-06T12:22:57.057Z
Learning: In the opendatahub-tests repository, prefer keeping test parameterization configurations inline rather than extracting them to separate variables/constants, as it makes triaging easier by avoiding the need to jump between different parts of the file to understand the test setup.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#283
File: tests/model_registry/test_user_permission.py:31-31
Timestamp: 2025-05-05T13:48:02.409Z
Learning: In the opendatahub-tests repository, bypassing TLS verification with `--insecure-skip-tls-verify=true` is an acceptable practice in test environments, particularly in the model registry tests.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#409
File: tests/model_registry/negative_tests/test_db_migration.py:47-57
Timestamp: 2025-07-09T08:50:22.172Z
Learning: In negative tests for model registry database migration failures (like test_db_migration_negative), the model registry pod is expected to be in a failed state (not Running) when the database is dirty. The test fetches logs from the failed pod to verify the expected error message about dirty database version, so waiting for Running status would be inappropriate.
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.
tests/model_registry/constants.py (5)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#338
File: tests/model_registry/rbac/test_mr_rbac.py:24-53
Timestamp: 2025-06-06T12:22:57.057Z
Learning: In the opendatahub-tests repository, prefer keeping test parameterization configurations inline rather than extracting them to separate variables/constants, as it makes triaging easier by avoiding the need to jump between different parts of the file to understand the test setup.
Learnt from: adolfo-ab
PR: opendatahub-io/opendatahub-tests#334
File: tests/model_explainability/trustyai_service/test_trustyai_service.py:52-65
Timestamp: 2025-06-05T10:05:17.642Z
Learning: For TrustyAI image validation tests: operator image tests require admin_client, related_images_refs, and trustyai_operator_configmap fixtures, while service image tests would require different fixtures like trustyai_service_with_pvc_storage, model_namespace, and current_client_token.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:166-175
Timestamp: 2025-06-16T11:25:39.599Z
Learning: In tests/model_registry/rbac/conftest.py, predictable names are intentionally used for test resources (like RoleBindings and groups) instead of random names. This design choice prioritizes exposing cleanup failures from previous test runs through name collisions rather than masking such issues with random names. The philosophy is that test failures should be observable and informative to help debug underlying infrastructure or cleanup issues.
tests/model_registry/rest_api/constants.py (1)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
tests/model_registry/rest_api/test_multple_mr.py (6)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:166-175
Timestamp: 2025-06-16T11:25:39.599Z
Learning: In tests/model_registry/rbac/conftest.py, predictable names are intentionally used for test resources (like RoleBindings and groups) instead of random names. This design choice prioritizes exposing cleanup failures from previous test runs through name collisions rather than masking such issues with random names. The philosophy is that test failures should be observable and informative to help debug underlying infrastructure or cleanup issues.
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.705Z
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.
Learnt from: adolfo-ab
PR: opendatahub-io/opendatahub-tests#334
File: tests/model_explainability/trustyai_service/test_trustyai_service.py:52-65
Timestamp: 2025-06-05T10:05:17.642Z
Learning: For TrustyAI image validation tests: operator image tests require admin_client, related_images_refs, and trustyai_operator_configmap fixtures, while service image tests would require different fixtures like trustyai_service_with_pvc_storage, model_namespace, and current_client_token.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#409
File: tests/model_registry/negative_tests/test_db_migration.py:47-57
Timestamp: 2025-07-09T08:50:22.172Z
Learning: In negative tests for model registry database migration failures (like test_db_migration_negative), the model registry pod is expected to be in a failed state (not Running) when the database is dirty. The test fetches logs from the failed pod to verify the expected error message about dirty database version, so waiting for Running status would be inappropriate.
tests/model_registry/rest_api/test_model_registry_rest_api.py (7)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
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.705Z
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.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:166-175
Timestamp: 2025-06-16T11:25:39.599Z
Learning: In tests/model_registry/rbac/conftest.py, predictable names are intentionally used for test resources (like RoleBindings and groups) instead of random names. This design choice prioritizes exposing cleanup failures from previous test runs through name collisions rather than masking such issues with random names. The philosophy is that test failures should be observable and informative to help debug underlying infrastructure or cleanup issues.
Learnt from: lugi0
PR: opendatahub-io/opendatahub-tests#296
File: tests/model_registry/rbac/test_mr_rbac_sa.py:0-0
Timestamp: 2025-05-07T10:40:15.681Z
Learning: The `build_mr_client_args` function in the Model Registry RBAC tests uses simple string splitting (`rest_endpoint.split(":")`) for endpoint parsing by design. This implementation is intentionally non-robust to serve as a detection mechanism for any unexpected changes to the endpoint format.
Learnt from: adolfo-ab
PR: opendatahub-io/opendatahub-tests#334
File: tests/model_explainability/trustyai_service/test_trustyai_service.py:52-65
Timestamp: 2025-06-05T10:05:17.642Z
Learning: For TrustyAI image validation tests: operator image tests require admin_client, related_images_refs, and trustyai_operator_configmap fixtures, while service image tests would require different fixtures like trustyai_service_with_pvc_storage, model_namespace, and current_client_token.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#409
File: tests/model_registry/negative_tests/test_db_migration.py:47-57
Timestamp: 2025-07-09T08:50:22.172Z
Learning: In negative tests for model registry database migration failures (like test_db_migration_negative), the model registry pod is expected to be in a failed state (not Running) when the database is dirty. The test fetches logs from the failed pod to verify the expected error message about dirty database version, so waiting for Running status would be inappropriate.
tests/model_registry/rbac/test_mr_rbac_sa.py (7)
Learnt from: lugi0
PR: opendatahub-io/opendatahub-tests#296
File: tests/model_registry/rbac/test_mr_rbac_sa.py:0-0
Timestamp: 2025-05-07T10:40:15.681Z
Learning: The `build_mr_client_args` function in the Model Registry RBAC tests uses simple string splitting (`rest_endpoint.split(":")`) for endpoint parsing by design. This implementation is intentionally non-robust to serve as a detection mechanism for any unexpected changes to the endpoint format.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:166-175
Timestamp: 2025-06-16T11:25:39.599Z
Learning: In tests/model_registry/rbac/conftest.py, predictable names are intentionally used for test resources (like RoleBindings and groups) instead of random names. This design choice prioritizes exposing cleanup failures from previous test runs through name collisions rather than masking such issues with random names. The philosophy is that test failures should be observable and informative to help debug underlying infrastructure or cleanup issues.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:355-371
Timestamp: 2025-06-16T11:25:51.461Z
Learning: In the opendatahub-tests repository, the login_as_test_user fixture in tests/model_registry/rbac/conftest.py intentionally logs back in as the original admin user without providing a password using login_with_user_password. This behavior is acceptable in their testing environment.
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.705Z
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.
Learnt from: adolfo-ab
PR: opendatahub-io/opendatahub-tests#334
File: tests/model_explainability/trustyai_service/test_trustyai_service.py:52-65
Timestamp: 2025-06-05T10:05:17.642Z
Learning: For TrustyAI image validation tests: operator image tests require admin_client, related_images_refs, and trustyai_operator_configmap fixtures, while service image tests would require different fixtures like trustyai_service_with_pvc_storage, model_namespace, and current_client_token.
tests/model_registry/utils.py (5)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:166-175
Timestamp: 2025-06-16T11:25:39.599Z
Learning: In tests/model_registry/rbac/conftest.py, predictable names are intentionally used for test resources (like RoleBindings and groups) instead of random names. This design choice prioritizes exposing cleanup failures from previous test runs through name collisions rather than masking such issues with random names. The philosophy is that test failures should be observable and informative to help debug underlying infrastructure or cleanup issues.
Learnt from: adolfo-ab
PR: opendatahub-io/opendatahub-tests#334
File: tests/model_explainability/trustyai_service/test_trustyai_service.py:52-65
Timestamp: 2025-06-05T10:05:17.642Z
Learning: For TrustyAI image validation tests: operator image tests require admin_client, related_images_refs, and trustyai_operator_configmap fixtures, while service image tests would require different fixtures like trustyai_service_with_pvc_storage, model_namespace, and current_client_token.
Learnt from: lugi0
PR: opendatahub-io/opendatahub-tests#296
File: tests/model_registry/rbac/test_mr_rbac_sa.py:0-0
Timestamp: 2025-05-07T10:40:15.681Z
Learning: The `build_mr_client_args` function in the Model Registry RBAC tests uses simple string splitting (`rest_endpoint.split(":")`) for endpoint parsing by design. This implementation is intentionally non-robust to serve as a detection mechanism for any unexpected changes to the endpoint format.
tests/model_registry/upgrade/test_model_registry_upgrade.py (5)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
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.705Z
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.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#409
File: tests/model_registry/negative_tests/test_db_migration.py:47-57
Timestamp: 2025-07-09T08:50:22.172Z
Learning: In negative tests for model registry database migration failures (like test_db_migration_negative), the model registry pod is expected to be in a failed state (not Running) when the database is dirty. The test fetches logs from the failed pod to verify the expected error message about dirty database version, so waiting for Running status would be inappropriate.
Learnt from: adolfo-ab
PR: opendatahub-io/opendatahub-tests#334
File: tests/model_explainability/trustyai_service/test_trustyai_service.py:52-65
Timestamp: 2025-06-05T10:05:17.642Z
Learning: For TrustyAI image validation tests: operator image tests require admin_client, related_images_refs, and trustyai_operator_configmap fixtures, while service image tests would require different fixtures like trustyai_service_with_pvc_storage, model_namespace, and current_client_token.
tests/model_registry/rest_api/conftest.py (8)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:166-175
Timestamp: 2025-06-16T11:25:39.599Z
Learning: In tests/model_registry/rbac/conftest.py, predictable names are intentionally used for test resources (like RoleBindings and groups) instead of random names. This design choice prioritizes exposing cleanup failures from previous test runs through name collisions rather than masking such issues with random names. The philosophy is that test failures should be observable and informative to help debug underlying infrastructure or cleanup issues.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#338
File: tests/model_registry/rbac/test_mr_rbac.py:24-53
Timestamp: 2025-06-06T12:22:57.057Z
Learning: In the opendatahub-tests repository, prefer keeping test parameterization configurations inline rather than extracting them to separate variables/constants, as it makes triaging easier by avoiding the need to jump between different parts of the file to understand the test setup.
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.
Learnt from: adolfo-ab
PR: opendatahub-io/opendatahub-tests#334
File: tests/model_explainability/trustyai_service/test_trustyai_service.py:52-65
Timestamp: 2025-06-05T10:05:17.642Z
Learning: For TrustyAI image validation tests: operator image tests require admin_client, related_images_refs, and trustyai_operator_configmap fixtures, while service image tests would require different fixtures like trustyai_service_with_pvc_storage, model_namespace, and current_client_token.
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.705Z
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.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#409
File: tests/model_registry/negative_tests/test_db_migration.py:47-57
Timestamp: 2025-07-09T08:50:22.172Z
Learning: In negative tests for model registry database migration failures (like test_db_migration_negative), the model registry pod is expected to be in a failed state (not Running) when the database is dirty. The test fetches logs from the failed pod to verify the expected error message about dirty database version, so waiting for Running status would be inappropriate.
tests/model_registry/conftest.py (9)
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#401
File: tests/model_registry/rest_api/mariadb/conftest.py:89-110
Timestamp: 2025-07-04T00:17:47.799Z
Learning: In tests/model_registry/rest_api/mariadb/conftest.py, the model_registry_with_mariadb fixture should always use OAUTH_PROXY_CONFIG_DICT for the oauth_proxy parameter regardless of the is_model_registry_oauth parameter value, based on expected product behavior for MariaDB-backed ModelRegistry instances.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:166-175
Timestamp: 2025-06-16T11:25:39.599Z
Learning: In tests/model_registry/rbac/conftest.py, predictable names are intentionally used for test resources (like RoleBindings and groups) instead of random names. This design choice prioritizes exposing cleanup failures from previous test runs through name collisions rather than masking such issues with random names. The philosophy is that test failures should be observable and informative to help debug underlying infrastructure or cleanup issues.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/test_mr_rbac.py:64-77
Timestamp: 2025-06-16T11:26:53.789Z
Learning: In Model Registry RBAC tests, client instantiation tests are designed to verify the ability to create and use the MR python client, with actual API functionality testing covered by separate existing tests.
Learnt from: adolfo-ab
PR: opendatahub-io/opendatahub-tests#334
File: tests/model_explainability/trustyai_service/test_trustyai_service.py:52-65
Timestamp: 2025-06-05T10:05:17.642Z
Learning: For TrustyAI image validation tests: operator image tests require admin_client, related_images_refs, and trustyai_operator_configmap fixtures, while service image tests would require different fixtures like trustyai_service_with_pvc_storage, model_namespace, and current_client_token.
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.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#354
File: tests/model_registry/rbac/conftest.py:355-371
Timestamp: 2025-06-16T11:25:51.461Z
Learning: In the opendatahub-tests repository, the login_as_test_user fixture in tests/model_registry/rbac/conftest.py intentionally logs back in as the original admin user without providing a password using login_with_user_password. This behavior is acceptable in their testing environment.
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#338
File: tests/model_registry/rbac/test_mr_rbac.py:24-53
Timestamp: 2025-06-06T12:22:57.057Z
Learning: In the opendatahub-tests repository, prefer keeping test parameterization configurations inline rather than extracting them to separate variables/constants, as it makes triaging easier by avoiding the need to jump between different parts of the file to understand the test setup.
Learnt from: lugi0
PR: opendatahub-io/opendatahub-tests#296
File: tests/model_registry/rbac/test_mr_rbac_sa.py:0-0
Timestamp: 2025-05-07T10:40:15.681Z
Learning: The `build_mr_client_args` function in the Model Registry RBAC tests uses simple string splitting (`rest_endpoint.split(":")`) for endpoint parsing by design. This implementation is intentionally non-robust to serve as a detection mechanism for any unexpected changes to the endpoint format.
Learnt from: fege
PR: opendatahub-io/opendatahub-tests#409
File: tests/model_registry/negative_tests/test_db_migration.py:47-57
Timestamp: 2025-07-09T08:50:22.172Z
Learning: In negative tests for model registry database migration failures (like test_db_migration_negative), the model registry pod is expected to be in a failed state (not Running) when the database is dirty. The test fetches logs from the failed pod to verify the expected error message about dirty database version, so waiting for Running status would be inappropriate.
🧬 Code Graph Analysis (10)
tests/model_registry/negative_tests/test_db_migration.py (1)
tests/model_registry/conftest.py (1)
  • model_registry_instance (179-227)
tests/model_registry/image_validation/test_verify_rhoai_images.py (1)
tests/model_registry/conftest.py (1)
  • model_registry_instance (179-227)
tests/model_registry/python_client/test_model_registry_creation.py (1)
tests/model_registry/conftest.py (4)
  • model_registry_client (373-397)
  • registered_model (401-412)
  • model_registry_rest_url (498-500)
  • model_registry_rest_headers (504-509)
tests/model_registry/rbac/test_mr_rbac.py (4)
tests/model_registry/rbac/conftest.py (2)
  • test_idp_user (236-273)
  • login_as_test_user (356-370)
tests/model_registry/conftest.py (1)
  • model_registry_instance_rest_endpoint (254-264)
tests/model_registry/rbac/utils.py (1)
  • build_mr_client_args (17-38)
utilities/infra.py (1)
  • get_openshift_token (596-604)
tests/model_registry/constants.py (1)
utilities/constants.py (1)
  • ModelFormat (12-19)
tests/model_registry/rest_api/test_multple_mr.py (3)
tests/model_registry/rest_api/utils.py (3)
  • validate_resource_attributes (91-112)
  • get_register_model_data (254-262)
  • register_model_rest_api (55-88)
utilities/constants.py (2)
  • DscComponents (154-175)
  • ManagementState (160-162)
tests/model_registry/conftest.py (4)
  • model_registry_instance (179-227)
  • model_registry_namespace (58-59)
  • model_registry_rest_url (498-500)
  • model_registry_rest_headers (504-509)
tests/model_registry/rbac/test_mr_rbac_sa.py (3)
tests/model_registry/conftest.py (1)
  • model_registry_instance_rest_endpoint (254-264)
tests/model_registry/rbac/utils.py (1)
  • build_mr_client_args (17-38)
tests/model_registry/rbac/conftest.py (1)
  • sa_token (59-100)
tests/model_registry/utils.py (3)
tests/model_registry/exceptions.py (1)
  • ModelRegistryResourceNotFoundError (5-6)
tests/model_registry/rest_api/utils.py (1)
  • ModelRegistryV1Alpha1 (265-266)
utilities/constants.py (2)
  • Annotations (128-147)
  • KubernetesIo (129-133)
tests/model_registry/upgrade/test_model_registry_upgrade.py (3)
tests/model_registry/conftest.py (3)
  • model_registry_client (373-397)
  • registered_model (401-412)
  • model_registry_instance (179-227)
tests/model_registry/utils.py (1)
  • get_and_validate_registered_model (320-346)
tests/model_registry/rest_api/utils.py (1)
  • ModelRegistryV1Alpha1 (265-266)
tests/model_registry/conftest.py (4)
tests/model_registry/rest_api/utils.py (1)
  • ModelRegistryV1Alpha1 (265-266)
utilities/constants.py (2)
  • Labels (178-206)
  • Protocols (89-96)
tests/model_registry/utils.py (8)
  • get_endpoint_from_mr_service (61-65)
  • get_mr_service_by_label (34-58)
  • wait_for_pods_running (211-244)
  • get_mr_service_objects (376-408)
  • get_mr_pvc_objects (411-428)
  • get_mr_secret_objects (431-448)
  • get_mr_deployment_objects (451-481)
  • get_model_registry_objects (493-528)
tests/conftest.py (3)
  • admin_client (55-56)
  • teardown_resources (76-83)
  • current_client_token (71-72)
🔇 Additional comments (41)
tests/model_registry/utils.py (9)

6-11: LGTM: Import additions are appropriate.

The added imports for Deployment, PersistentVolumeClaim, and Secret are necessary for the new utility functions and align with the multi-instance resource creation approach.


17-23: LGTM: Constants import updated for multi-instance support.

The import changes from single-instance constants to base names and the addition of secret-related constants are consistent with the multi-instance refactoring.


376-408: LGTM: Service factory function is well-implemented.

The get_mr_service_objects() function correctly creates MySQL services with appropriate annotations and port configurations. The naming convention using base_name + index supports multi-instance testing.


411-428: LGTM: PVC factory function is correctly implemented.

The get_mr_pvc_objects() function creates PersistentVolumeClaims with appropriate access modes and sizing for MySQL data persistence.


431-448: LGTM: Secret factory function is properly configured.

The get_mr_secret_objects() function uses the imported constants for string data and annotations, ensuring consistency across the codebase.


451-481: LGTM: Deployment factory function is well-structured.

The get_mr_deployment_objects() function correctly references the corresponding secrets and uses the deployment template helper function. The resource lifecycle management with teardown flags is properly implemented.


484-490: LGTM: Standard labels helper provides consistency.

The get_mr_standard_labels() function ensures consistent Kubernetes labeling across all Model Registry resources.


493-528: LGTM: ModelRegistry factory function is comprehensive.

The get_model_registry_objects() function correctly handles both ModelRegistry and ModelRegistryV1Alpha1 classes, configures MySQL connection details, and supports optional SSL configuration parameters.


531-539: LGTM: MySQL configuration helper is well-structured.

The get_mysql_config() function creates the necessary MySQL connection configuration referencing the deployment service and using the constants for database credentials.

tests/model_registry/negative_tests/test_model_registry_creation_negative.py (2)

14-16: LGTM: Constants updated for multi-instance support.

The import changes from single-instance constants to base names align with the multi-instance refactoring approach throughout the codebase.


68-82: LGTM: Consistent use of base name constants.

The test correctly uses the updated base name constants in the MySQL configuration and ModelRegistry resource creation. This maintains consistency with the multi-instance naming convention.

tests/model_registry/negative_tests/test_db_migration.py (2)

2-2: LGTM: Type import updated for multi-instance support.

The addition of Any to the typing imports is necessary for the updated type annotation.


34-34: Retain model_registry_instance fixture for side effects
The model_registry_instance: list[Any] parameter is injected solely to invoke its fixture and set up the Model Registry before marking the database dirty and deleting the deployment. Although it isn’t referenced in the test body, its side effects are required for correct test setup. No changes needed.

Likely an incorrect or invalid review comment.

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

1-1: LGTM: Import addition is appropriate.

The copy import is necessary for the deep copying functionality in the new utility function.


12-12: LGTM: Updated import statement.

The import of MODEL_REGISTER_DATA is necessary for the new utility function.


254-262: LGTM: Model data factory function is well-implemented.

The get_register_model_data() function correctly creates multiple distinct model registration data entries by deep copying the base template and modifying the name and description fields. The use of copy.deepcopy() prevents unintended mutations of the original data.

tests/model_registry/image_validation/test_verify_rhoai_images.py (1)

2-2: LGTM: Type import updated for multi-instance support.

The addition of Any to the typing imports is necessary for the updated type annotation.

tests/model_registry/rbac/test_mr_rbac.py (2)

45-45: LGTM! Proper fixture dependency management.

Good addition of the model_registry_instance fixture dependency to ensure proper resource lifecycle management alongside the existing fixture.


51-51: Consistent multi-instance refactoring.

The changes correctly adapt to the new multi-instance fixture design by:

  • Updating parameter type from str to list[str]
  • Accessing the first element [0] for single-instance test logic
  • Maintaining backwards compatibility with existing test behavior

The pattern is applied consistently across all test methods in the class.

Also applies to: 58-58, 68-68, 82-82, 93-93, 106-106, 113-113, 125-125

tests/model_registry/constants.py (2)

3-3: LGTM! Cleaned up unused import.

Removing the unused Annotations import while keeping ModelFormat which is still used in line 17.


28-29: Well-designed multi-instance naming convention.

The refactoring from fixed names to base names with indexed suffixes supports the multi-instance architecture effectively:

  • MR_INSTANCE_BASE_NAME provides a consistent base for programmatic resource generation
  • MR_INSTANCE_NAME maintains backwards compatibility by defaulting to index 0
  • Same pattern applied consistently to database resource names

This approach enables both single-instance (backwards compatible) and multi-instance testing scenarios.

Also applies to: 39-40

tests/model_registry/python_client/test_model_registry_creation.py (2)

61-61: Consistent multi-instance adaptation.

The changes correctly adapt the test to work with the new multi-instance fixture:

  • Parameter type updated from ModelRegistryClient to list[ModelRegistryClient]
  • Accessing first element [0] for existing single-instance test logic
  • Test behavior remains unchanged

This follows the same pattern established across the test suite.

Also applies to: 64-64


130-130: Proper REST URL list handling.

The test correctly adapts to the new list[str] fixture signature for model_registry_rest_url and accesses the first element for the existing single-instance test logic.

Also applies to: 140-140

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

100-100: Proper multi-instance fixture adaptation.

The changes correctly adapt to the new multi-instance fixture design:

  • model_registry_instance is now a list, accessing first element [0]
  • Test logic remains unchanged - only the way the fixture is accessed has been updated
  • Consistent pattern applied across all affected test methods

This maintains backwards compatibility while supporting the new multi-instance architecture.

Also applies to: 107-107, 114-114

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

19-40: Comprehensive multi-instance test parameterization.

The parameterization correctly sets up multiple instances for all required fixtures:

  • Proper DSC component configuration for managed state
  • Consistent NUM_RESOURCES parameter across all fixtures
  • Correct use of indirect=True for fixture parameterization

This ensures that 3 instances of each resource type are created consistently.


50-57: Effective multiple instance validation.

The test correctly validates multiple Model Registry instances:

  • Iterates through the expected number of resources
  • Uses proper naming convention with base name + index
  • Validates each instance exists using ensure_exists=True
  • Includes logging for debugging

This provides good coverage for multi-instance resource creation.


59-74: Comprehensive multi-registry API testing.

The test thoroughly validates REST API functionality across multiple registries:

  • Generates unique test data for each registry using get_register_model_data
  • Tests registration against each registry endpoint
  • Validates all resource types (registered model, model version, model artifact)
  • Uses proper resource attribute validation

This ensures that each Model Registry instance is fully functional and independent.

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

43-43: LGTM! Parameter and fixture name updates are consistent.

The changes update parameter and fixture names from model_registry_mysql_config to model_registry_instance, which aligns with the broader refactoring to support multiple Model Registry instances. The test logic remains unchanged and the naming is more consistent.

Also applies to: 58-59, 90-90, 104-105

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

44-57: LGTM! Well-structured test constants added.

The new constants provide standardized test data for the expanded multi-instance testing scenarios. They follow the existing patterns with proper typing and clear naming conventions. These constants will help ensure consistency across multiple Model Registry instance tests.

tests/model_registry/upgrade/test_model_registry_upgrade.py (1)

34-34: LGTM! Consistent parameter type updates for multi-instance support.

The parameter type changes from single objects to lists are consistently applied across all test methods. The usage of [0] to access the first element is appropriate for upgrade tests that typically work with a single instance.

Also applies to: 52-53, 65-65, 75-75, 84-84

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

19-21: LGTM! Improved imports and constants usage.

The addition of get_mysql_config and get_mr_standard_labels imports along with the updated constant DB_BASE_RESOURCES_NAME aligns with the dynamic configuration approach and removes hard-coded values.

Also applies to: 24-24


47-47: LGTM! Consistent list parameter handling.

The fixture parameter types have been consistently updated to accept lists instead of single objects, and all usages properly access the first element [0]. This maintains backward compatibility while enabling multi-instance support.

Also applies to: 50-50, 59-59, 81-81, 118-118, 129-129


144-144: LGTM! Enhanced fixture with dynamic configuration.

The addition of the request parameter and dynamic MySQL configuration using get_mysql_config() is a significant improvement. The conditional SSL root certificate configuration and use of get_mr_standard_labels() makes the fixture more flexible and maintainable.

Also applies to: 162-175


244-244: LGTM! Proper deployment list handling.

The fixture correctly handles the list of deployments by accessing the first element and maintains consistency in variable usage throughout the patching logic.

Also applies to: 254-268

tests/model_registry/conftest.py (7)

1-2: Imports and constants are appropriate for multi-instance support.

The addition of ExitStack for managing multiple context managers and the new utility functions for creating resource objects align well with the multi-instance refactoring.

Also applies to: 27-34, 41-45


71-87: Multi-instance support implemented correctly for database service.

The fixture properly handles creating multiple services based on the num parameter and uses ExitStack to manage their contexts appropriately.


245-251: Correct implementation for multi-instance service retrieval.

The fixture properly handles multiple ModelRegistry instances and returns their corresponding services.


256-265: Multi-instance REST endpoint retrieval implemented correctly.

The fixture properly extracts REST endpoints from multiple services.


373-398: Multi-instance client creation implemented correctly.

The fixture properly creates a ModelRegistry client for each REST endpoint. The simple string splitting for endpoint parsing is intentional per the codebase design patterns.


443-443: Label selector updated correctly.

The fixture properly uses the new DB_RESOURCE_NAME constant for the label selector.


498-501: Multi-instance REST URL formatting implemented correctly.

The fixture properly formats multiple REST endpoints as HTTPS URLs.

self: Self,
admin_client: DynamicClient,
model_registry_instance: ModelRegistry,
model_registry_instance: list[Any],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify if model_registry_instance parameter is used.

The type annotation change from ModelRegistry to list[Any] aligns with the fixture changes, but the test doesn't appear to use the model_registry_instance parameter in its logic.


🏁 Script executed:

#!/bin/bash
# Check if model_registry_instance parameter is used in this test
rg -A 10 -B 5 "model_registry_instance" tests/model_registry/image_validation/test_verify_rhoai_images.py

Length of output: 819


Clarify model_registry_instance fixture usage

The model_registry_instance parameter isn’t referenced in the test body but is needed to spin up the ModelRegistry instance before its pods are validated. To prevent confusion (and linter “unused parameter” errors), please annotate it with a comment or a noqa directive.

• File: tests/model_registry/image_validation/test_verify_rhoai_images.py
Line 45
Current:
model_registry_instance: list[Any],
Suggested:
model_registry_instance: list[Any], # noqa: F841 – ensures registry instance is created for pod validation

🤖 Prompt for AI Agents
In tests/model_registry/image_validation/test_verify_rhoai_images.py at line 45,
the parameter model_registry_instance is not used in the test body but is
required to initialize the ModelRegistry instance. To avoid confusion and linter
warnings about unused variables, add a noqa directive comment to the parameter
line like this: model_registry_instance: list[Any],  # noqa: F841 – ensures
registry instance is created for pod validation.

@dbasunag dbasunag closed this Jul 11, 2025
@dbasunag dbasunag deleted the multi branch March 19, 2026 00:06
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.

1 participant