Add test for Model Registry RBAC for SA token#296
Add test for Model Registry RBAC for SA token#296dbasunag merged 5 commits intoopendatahub-io:mainfrom
Conversation
|
""" WalkthroughThe changes introduce comprehensive RBAC (Role-Based Access Control) testing for the Model Registry using Kubernetes ServiceAccounts. New fixtures and utility functions are added to manage test namespaces, ServiceAccounts, RBAC roles, and role bindings. Tests verify access denial and granting scenarios. An unused import is removed, and utility functions for naming are introduced. Changes
Sequence Diagram(s)sequenceDiagram
participant Test as Test Method
participant Fixtures as Pytest Fixtures
participant K8s as Kubernetes API
participant Client as ModelRegistryClient
Test->>Fixtures: Request test namespace, ServiceAccount, Role, RoleBinding
Fixtures->>K8s: Create Namespace
Fixtures->>K8s: Create ServiceAccount in Namespace
Fixtures->>K8s: Create Role and RoleBinding (if access granted test)
Fixtures->>K8s: Retrieve ServiceAccount token
Test->>Client: Attempt connection with token
alt Access Denied
Client-->>Test: Raise Forbidden Error (403)
else Access Granted
Client-->>Test: Connection Succeeds
end
Test->>Fixtures: Teardown resources
Fixtures->>K8s: Delete RoleBinding, Role, ServiceAccount, Namespace
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
The following are automatically added/executed:
Available user actions:
Supported labels{'/wip', '/lgtm', '/hold', '/verified'} |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (7)
conftest.py (2)
112-114: Typo fixed – thanks, but description still ambiguousYou corrected “Comma-separated” (good) but the phrase
"Comma-separated str; specify inference service deployment modes tests to run in upgrade tests."
is grammatically off and a bit hard to parse. Consider something like:- help="Comma-separated str; specify inference service deployment modes tests to run in upgrade tests. " + help="Comma-separated list of deployment modes to execute during upgrade tests " + "(e.g. 'serverless,model_mesh'). If omitted, all modes will be tested."
133-139: Redundantdefault=Falseand missingdestclarification
action="store_true"already sets the default toFalse, so the explicit
default=Falseis unnecessary (and slightly misleading if you later decide to
change the default). Also note that pytest converts--foo-barinto the
destinationfoo_bar. You access the flag later via the raw option string,
which works, but is less discoverable than using the canonical dest name
(cluster_sanity_continue_on_failure). Proposed minimal clean-up:- cluster_sanity_group.addoption( - "--cluster-sanity-continue-on-failure", - action="store_true", - default=False, - help="If set, log a warning on cluster sanity failure but continue running tests. " - "Default is to skip tests on failure.", - ) + cluster_sanity_group.addoption( + "--cluster-sanity-continue-on-failure", + action="store_true", + help="Continue running the suite even if cluster-sanity checks fail " + "(logs a warning instead of aborting).", + )utilities/infra.py (1)
887-899: Early-exit path ignoresjunitxml_propertyWhen
--cluster-sanity-skip-checkis supplied we return early, but the JUnit
report still claims the check passed (nothing is recorded). If you rely on
those properties downstream you may want to note that the check was skipped:if request.session.config.getoption(skip_check_opt): LOGGER.warning(f"Skipping cluster sanity check entirely due to {skip_check_opt} flag.") + if junitxml_property: + junitxml_property("cluster_sanity_check_skipped", True) # type: ignore[call-arg] returntests/model_registry/rbac/test_mr_rbac_sa.py (2)
89-97:ForbiddenExceptionassertions may raise AttributeError
mr_openapi.exceptions.ForbiddenExceptiondoesn’t guarantee.bodyor
.status. Safer pattern:with pytest.raises(ForbiddenException) as exc: ModelRegistryClient(**client_args) err: ForbiddenException = exc.value status = getattr(err, "status", None) assert status == 403, f"Expected 403, got {status}"Otherwise the test itself can error instead of failing gracefully.
130-140: Success path does not verify functionalityYou assert that the client initialises, but not that it can perform a simple
action (e.g.mr_client_success.list_models()orget_version()). A bad
token may still allow instantiation but fail on the first API call. Consider
adding one lightweight call to guarantee real access.tests/model_registry/conftest.py (2)
377-378: Remove unused variablesresanderrRuff correctly flags these as unused. They can simply be replaced with
_
place-holders:- res, out, err = run_command(command=shlex.split(cmd), verify_stderr=False, check=True) + _, out, _ = run_command(command=shlex.split(cmd), verify_stderr=False, check=True)🧰 Tools
🪛 Ruff (0.8.2)
377-377: Local variable
resis assigned to but never usedRemove assignment to unused variable
res(F841)
377-377: Local variable
erris assigned to but never usedRemove assignment to unused variable
err(F841)
328-341: Genericexcept Exceptionhides real failure reasonCatching all exceptions then calling
pytest.failthrows away the original
traceback, making debugging harder. Narrow the except clause to the expected
timeout/error type (e.g.TimeoutExpiredError) or re-raise after logging.- except Exception: - LOGGER.error(...) - pytest.fail(...) + except TimeoutExpiredError: + LOGGER.error(...) + pytest.fail(...)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
conftest.py(2 hunks)tests/model_registry/conftest.py(5 hunks)tests/model_registry/rbac/test_mr_rbac_sa.py(1 hunks)utilities/infra.py(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
utilities/infra.py (2)
tests/conftest.py (3)
nodes(496-497)dsci_resource(334-335)dsc_resource(339-340)utilities/exceptions.py (1)
ResourceNotReadyError(99-100)
tests/model_registry/rbac/test_mr_rbac_sa.py (2)
utilities/constants.py (3)
DscComponents(146-164)Protocols(87-94)ManagementState(151-153)tests/model_registry/conftest.py (2)
sa_token(365-393)model_registry_instance_rest_endpoint(197-200)
tests/model_registry/conftest.py (1)
tests/conftest.py (1)
admin_client(50-51)
🪛 Ruff (0.8.2)
tests/model_registry/conftest.py
377-377: Local variable res is assigned to but never used
Remove assignment to unused variable res
(F841)
377-377: Local variable err is assigned to but never used
Remove assignment to unused variable err
(F841)
Signed-off-by: lugi0 <lgiorgi@redhat.com>
Signed-off-by: lugi0 <lgiorgi@redhat.com>
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 3
🧹 Nitpick comments (5)
tests/model_registry/utils.py (3)
243-246: Docstring parameter name & typo – fixlengthspelling
ength (int, optional): …is missing the leading “l”.
The name should match the actual parameter (length) so IDEs and doc generators display correct information.- ength (int, optional): The desired length for the UUID-derived suffix. + length (int, optional): The desired length for the UUID-derived suffix.
254-256: Raise message refers to a non-existent variableThe error text mentions
suffix_length, but the function argument islength. This can mislead callers and automated linters.- raise ValueError("suffix_length must be an integer between 1 and 32.") + raise ValueError("length must be an integer between 1 and 32.")
258-262: Kubernetes naming limits not enforcedA generated resource name may exceed 63 characters (
prefix+ “-” +length).
Consider guarding against this to avoid422 Unprocessable Entityerrors when the name is used for a Kubernetes object.+ full_name = f"{prefix}-{suffix}" + if len(full_name) > 63: + raise ValueError( + f"Resulting name '{full_name}' is {len(full_name)} chars – " + "Kubernetes resource names must be ≤ 63." + ) + return full_name - - return f"{prefix}-{suffix}"tests/model_registry/rbac/conftest.py (2)
60-64: Unused variablesres,err– silence Ruff F841The result and stderr are captured but never referenced.
Either log them or replace with “_” to indicate intentional discard.- res, out, err = run_command(command=shlex.split(cmd), verify_stderr=False, check=True, timeout=30) - token = out.strip() + _, out, _ = run_command( + command=shlex.split(cmd), + verify_stderr=False, + check=True, + timeout=30, + ) + token = out.strip()🧰 Tools
🪛 Ruff (0.8.2)
62-62: Local variable
resis assigned to but never usedRemove assignment to unused variable
res(F841)
62-62: Local variable
erris assigned to but never usedRemove assignment to unused variable
err(F841)
147-157: Possible 63-character overflow onbinding_name
binding_name = f"{mr_access_role.name}-binding"can easily exceed K8s limits when the role name itself is already near 63 chars, causing RoleBinding creation to fail.Consider truncating and/or hashing:
-from tests.model_registry.utils import generate_random_name +from hashlib import sha1 + +hash_suffix = sha1(mr_access_role.name.encode()).hexdigest()[:6] +binding_name = f"{mr_access_role.name[:55]}-{hash_suffix}"
🛑 Comments failed to post (3)
tests/model_registry/utils.py (1)
265-266: 🛠️ Refactor suggestion
Incorrect use of
str.strip()– may remove unintended characters
file_path.strip(".py")removes any combination of the characters “.”, “p”, “y” from both ends of the string, not the “.py” suffix specifically.
Useremovesuffix(".py")(3.9+) orPath(file_path).stemto avoid accidental truncation.-from tests.model_registry.utils import generate_random_name, generate_namespace_name +# NOTE: use Path and removesuffix to safely drop '.py' +from pathlib import Path + +def generate_namespace_name(file_path: str) -> str: + """Generate a DNS-1123-compliant namespace from a test file path.""" + name = ( + Path(file_path).name.removesuffix(".py") + .replace("/", "-") + .replace("_", "-") + ) + return name[-63:].split("-", 1)[-1]Committable suggestion skipped: line range outside the PR's diff.
tests/model_registry/rbac/conftest.py (2)
27-33: 🛠️ Refactor suggestion
Path split may raise
IndexErrorin nested/invoked contexts
request.fspath.strpath.split(f"{os.path.dirname(__file__)}/")[1]assumes the test file path always contains the current directory as a separator and that the split returns ≥ 2 parts.
In parametrised, symlinked or external-execution scenarios this breaks.Recommend using
Path.relative_tooros.path.relpathwith robust fallback:-from os.path import dirname -test_file = Path(request.fspath).relative_to(dirname(__file__)).as_posix() -ns_name = generate_namespace_name(file_path=test_file) +test_file = os.path.relpath(request.fspath.strpath, start=os.path.dirname(__file__)) +ns_name = generate_namespace_name(test_file)Committable suggestion skipped: line range outside the PR's diff.
70-93:
⚠️ Potential issueOverly broad
except Exceptionhides programming errorsCatching the base
Exceptionmasks unexpected issues (e.g.,TypeError,AttributeError).
Catch the specific exceptions raised byrun_command(CalledProcessError,TimeoutExpired,FileNotFoundError) and let everything else propagate.- except Exception as e: # Catch all exceptions from the try block + except (subprocess.CalledProcessError, subprocess.TimeoutExpired, FileNotFoundError) as e:📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.except (subprocess.CalledProcessError, subprocess.TimeoutExpired, FileNotFoundError) as e: error_type = type(e).__name__ log_message = ( f"Failed during token retrieval for SA '{sa_name}' in namespace '{namespace}'. " f"Error Type: {error_type}, Message: {str(e)}" ) if isinstance(e, subprocess.CalledProcessError): # Add specific details for CalledProcessError # run_command already logs the error if log_errors=True and returncode !=0, # but we can add context here. stderr_from_exception = e.stderr.strip() if e.stderr else "N/A" log_message += f". Exit Code: {e.returncode}. Stderr from exception: {stderr_from_exception}" elif isinstance(e, subprocess.TimeoutExpired): timeout_value = getattr(e, "timeout", "N/A") log_message += f". Command timed out after {timeout_value} seconds." elif isinstance(e, FileNotFoundError): # This occurs if 'oc' is not found. # e.filename usually holds the name of the file that was not found. command_not_found = e.filename if hasattr(e, "filename") and e.filename else shlex.split(cmd)[0] log_message += f". Command '{command_not_found}' not found. Is it installed and in PATH?" LOGGER.error(log_message, exc_info=True) # exc_info=True adds stack trace to the log raise
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
tests/model_registry/rbac/conftest.py (1)
50-93: Robust token retrieval with comprehensive error handlingThe
sa_tokenfixture includes detailed error handling for different failure scenarios, making troubleshooting easier. However, there are unused variables in the command execution that should be addressed.On line 62, variables
resanderrare assigned but never used. Consider using underscore notation for these unused variables:- res, out, err = run_command(command=shlex.split(cmd), verify_stderr=False, check=True, timeout=30) + _, out, _ = run_command(command=shlex.split(cmd), verify_stderr=False, check=True, timeout=30)🧰 Tools
🪛 Ruff (0.8.2)
62-62: Local variable
resis assigned to but never usedRemove assignment to unused variable
res(F841)
62-62: Local variable
erris assigned to but never usedRemove assignment to unused variable
err(F841)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
tests/model_registry/conftest.py(0 hunks)tests/model_registry/rbac/conftest.py(1 hunks)tests/model_registry/rbac/test_mr_rbac_sa.py(1 hunks)tests/model_registry/utils.py(2 hunks)
💤 Files with no reviewable changes (1)
- tests/model_registry/conftest.py
🚧 Files skipped from review as they are similar to previous changes (2)
- tests/model_registry/utils.py
- tests/model_registry/rbac/test_mr_rbac_sa.py
🧰 Additional context used
🧬 Code Graph Analysis (1)
tests/model_registry/rbac/conftest.py (3)
tests/model_registry/utils.py (2)
generate_random_name(235-262)generate_namespace_name(265-266)tests/conftest.py (1)
admin_client(50-51)tests/model_registry/conftest.py (1)
model_registry_namespace(49-50)
🪛 Ruff (0.8.2)
tests/model_registry/rbac/conftest.py
62-62: Local variable res is assigned to but never used
Remove assignment to unused variable res
(F841)
62-62: Local variable err is assigned to but never used
Remove assignment to unused variable err
(F841)
🔇 Additional comments (6)
tests/model_registry/rbac/conftest.py (6)
1-15: Clean and comprehensive importsThe imports cover all necessary dependencies for Kubernetes resource management, command execution, and logging. The code properly leverages existing utilities like
generate_random_nameandgenerate_namespace_name.
21-34: Well-implemented namespace fixture with proper cleanupThe
sa_namespacefixture correctly generates a namespace name based on the test file path and uses a context manager to ensure automatic cleanup after tests. The implementation includes appropriate waiting for the namespace to become active and comprehensive logging.
36-48: Good service account creation and cleanup patternThe
service_accountfixture follows best practices by using a context manager for lifecycle management and waiting for resource readiness. The random name generation helps ensure test isolation.
98-135: Well-defined role with appropriate permissionsThe
mr_access_rolefixture creates a role with minimal permissions (only "get" access to a specific service). The use of labels for tracking and the descriptive naming strategy make this easy to understand and debug.
137-177: Correct role binding implementation with group-based accessThe
mr_access_role_bindingfixture properly links the role to all service accounts in the test namespace using a group binding. This approach is more flexible than binding to a specific service account. The consistent use of labeling and resource management aligns with the rest of the fixtures.
1-177: Overall well-structured test fixtures with good isolationThe overall implementation of these fixtures provides a solid foundation for RBAC testing. The consistent function-level scope ensures each test runs with a fresh environment, and the use of context managers guarantees proper cleanup. The detailed logging throughout will be valuable for troubleshooting test failures.
🧰 Tools
🪛 Ruff (0.8.2)
62-62: Local variable
resis assigned to but never usedRemove assignment to unused variable
res(F841)
62-62: Local variable
erris assigned to but never usedRemove assignment to unused variable
err(F841)
Signed-off-by: lugi0 <lgiorgi@redhat.com>
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
tests/model_registry/rbac/conftest.py (1)
63-63: Remove unused variables from run_command assignmentThe variables
resanderrare assigned but never used in the function.- res, out, err = run_command(command=shlex.split(cmd), verify_stderr=False, check=True, timeout=30) + _, out, _ = run_command(command=shlex.split(cmd), verify_stderr=False, check=True, timeout=30)🧰 Tools
🪛 Ruff (0.8.2)
63-63: Local variable
resis assigned to but never usedRemove assignment to unused variable
res(F841)
63-63: Local variable
erris assigned to but never usedRemove assignment to unused variable
err(F841)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
tests/model_registry/rbac/conftest.py(1 hunks)tests/model_registry/utils.py(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- tests/model_registry/utils.py
🧰 Additional context used
🧬 Code Graph Analysis (1)
tests/model_registry/rbac/conftest.py (3)
tests/model_registry/utils.py (2)
generate_random_name(235-262)generate_namespace_name(265-266)tests/conftest.py (1)
admin_client(50-51)tests/model_registry/conftest.py (1)
model_registry_namespace(49-50)
🪛 Ruff (0.8.2)
tests/model_registry/rbac/conftest.py
63-63: Local variable res is assigned to but never used
Remove assignment to unused variable res
(F841)
63-63: Local variable err is assigned to but never used
Remove assignment to unused variable err
(F841)
🔇 Additional comments (6)
tests/model_registry/rbac/conftest.py (6)
1-19: Well-structured imports and constants setupThe imports are comprehensive and well-organized, covering all necessary Kubernetes resources and utility functions. The constant for token duration is appropriately defined with a descriptive name.
21-35: Good test isolation with namespace fixtureThe
sa_namespacefixture follows best practices for test isolation by creating a temporary namespace with automatic cleanup via context manager. The use ofgenerate_namespace_nameto derive names from test file paths ensures uniqueness and traceability.
37-49: Well-implemented ServiceAccount fixtureThe
service_accountfixture correctly creates a test ServiceAccount with a randomly generated name, proper scoping, and automatic cleanup. This provides good isolation for RBAC testing.
51-94: Comprehensive error handling in token retrievalThe
sa_tokenfixture has excellent error handling for different failure scenarios (command errors, timeouts, missing binaries). The detailed error logging with context and stack traces will be valuable for debugging test failures.🧰 Tools
🪛 Ruff (0.8.2)
63-63: Local variable
resis assigned to but never usedRemove assignment to unused variable
res(F841)
63-63: Local variable
erris assigned to but never usedRemove assignment to unused variable
err(F841)
96-136: Well-defined RBAC Role fixtureThe
mr_access_rolefixture creates a properly scoped Role with specific permissions limited to the model registry service. The use of a context manager ensures cleanup, and the labels provide good traceability.
138-178: Properly configured RoleBinding fixtureThe
mr_access_role_bindingfixture correctly links the Role to all ServiceAccounts in the test namespace through the group binding. The logging provides clear visibility into the binding creation and cleanup process.
Signed-off-by: lugi0 <lgiorgi@redhat.com>
|
/verified |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
tests/model_registry/rbac/conftest.py (1)
51-94: Remove unused variables from run_commandThe error handling in the sa_token fixture is comprehensive, but there are unused variables in the run_command call.
- res, out, err = run_command(command=shlex.split(cmd), verify_stderr=False, check=True, timeout=30) + _, out, _ = run_command(command=shlex.split(cmd), verify_stderr=False, check=True, timeout=30)Or if you need to preserve the variables for future use:
- res, out, err = run_command(command=shlex.split(cmd), verify_stderr=False, check=True, timeout=30) + result, out, error = run_command(command=shlex.split(cmd), verify_stderr=False, check=True, timeout=30) # Use result and error variables somewhere🧰 Tools
🪛 Ruff (0.8.2)
63-63: Local variable
resis assigned to but never usedRemove assignment to unused variable
res(F841)
63-63: Local variable
erris assigned to but never usedRemove assignment to unused variable
err(F841)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
tests/model_registry/rbac/conftest.py(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
tests/model_registry/rbac/conftest.py (3)
tests/model_registry/utils.py (2)
generate_random_name(235-262)generate_namespace_name(265-266)tests/conftest.py (1)
admin_client(50-51)tests/model_registry/conftest.py (1)
model_registry_namespace(49-50)
🪛 Ruff (0.8.2)
tests/model_registry/rbac/conftest.py
63-63: Local variable res is assigned to but never used
Remove assignment to unused variable res
(F841)
63-63: Local variable err is assigned to but never used
Remove assignment to unused variable err
(F841)
🔇 Additional comments (7)
tests/model_registry/rbac/conftest.py (7)
1-15: Good organization of importsThe imports are well-organized with standard library imports first, followed by Kubernetes-related imports, and finally project-specific utilities and constants. This follows Python best practices for import organization.
17-18: Constants naming follows conventionGood practice using uppercase for the DEFAULT_TOKEN_DURATION constant, and setting up a module-level logger with a proper name.
21-35: Well-implemented namespace fixture with automatic cleanupThe sa_namespace fixture is well-designed with:
- Appropriate function scope
- Dynamic namespace naming based on test file path
- Context manager for automatic cleanup
- Status verification with timeout
- Clear logging at each step
This ensures test isolation and proper resource management.
37-49: Good service account setup with dependency on namespaceThe service_account fixture correctly depends on sa_namespace and follows the same pattern of using a context manager for cleanup, with proper logging and random name generation.
71-93: Excellent error handling implementationThe error handling is very thorough, with:
- Type-specific error messages for different exception types
- Detailed context for each error type
- Proper logging with stack traces
- Appropriate re-raising of exceptions
This will greatly help with debugging test failures.
99-136: Well-structured role creation with appropriate permissionsThe mr_access_role fixture:
- Creates a role with a clear naming convention
- Properly scopes permissions using resourceNames to limit to the specific MR instance
- Uses appropriate labels for tracking test resources
- Correctly uses the model_registry_namespace from the imported fixture
- Implements automatic cleanup via context manager
This follows security best practices by granting minimal necessary permissions.
138-177: Properly implemented role binding with group-based accessThe mr_access_role_binding fixture correctly:
- Creates a binding between the role and all service accounts in the test namespace
- Uses the Group kind with system:serviceaccounts prefix (Kubernetes best practice)
- Includes proper labels for resource tracking
- Waits for the resource to be fully created
- Uses a context manager for cleanup
This approach allows multiple service accounts in the namespace to receive the role, which is more flexible than individual bindings.
|
/verified |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
tests/model_registry/rbac/conftest.py(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
tests/model_registry/rbac/conftest.py (3)
tests/model_registry/utils.py (2)
generate_random_name(235-262)generate_namespace_name(265-266)tests/conftest.py (1)
admin_client(50-51)tests/model_registry/conftest.py (1)
model_registry_namespace(49-50)
🪛 Ruff (0.8.2)
tests/model_registry/rbac/conftest.py
59-59: Local variable res is assigned to but never used
Remove assignment to unused variable res
(F841)
59-59: Local variable err is assigned to but never used
Remove assignment to unused variable err
(F841)
🔇 Additional comments (6)
tests/model_registry/rbac/conftest.py (6)
1-15: Well-structured import section with appropriate dependencies.The imports are well-organized and include all necessary modules for Kubernetes resource management, command execution, and utility functions. Good job on importing the specific utility functions
generate_random_nameandgenerate_namespace_namefrom the existing utilities module.
21-33: Good implementation of namespace fixture with proper cleanup.The
sa_namespacefixture effectively:
- Creates an isolated test namespace with a deterministic name based on the test file path
- Uses context manager pattern for automatic cleanup
- Appropriately waits for the namespace to become active with a reasonable timeout
- Includes helpful logging for troubleshooting
This provides a clean environment for each test and ensures proper resource cleanup.
35-45: Clean ServiceAccount fixture with appropriate error handling.The implementation properly generates a random name with a useful prefix, creates the account within the test namespace, and ensures resource readiness before returning. The function-scoped fixture correctly ties the ServiceAccount's lifecycle to the namespace.
67-89: Excellent error handling with detailed logging.This comprehensive error handling is a great practice. The code:
- Handles different exception types with specific contextual information
- Provides detailed error messages with context about which resource failed
- Includes stack traces in logs for debugging
- Properly propagates exceptions after logging
This will make troubleshooting much easier if token retrieval fails.
95-132: Well-structured Role fixture with proper resource configuration.The
mr_access_rolefixture correctly:
- Creates a named role in the model registry namespace
- Defines precise RBAC rules limiting access to only the specific model registry service
- Includes appropriate labels for tracking and management
- Uses context manager for automatic cleanup
- Provides detailed logging throughout the resource lifecycle
The granular permission (only "get" on the specific service) follows security best practices by granting minimal permissions.
134-173: Complete RoleBinding implementation with appropriate subject configuration.The
mr_access_role_bindingfixture properly:
- Creates a binding with a descriptive name derived from the role
- Correctly links to all service accounts in the test namespace via group binding
- Includes the same labels as the role for consistency
- Uses context manager for automatic cleanup
- Provides clear logging of the binding details
Binding to the service account group rather than individual accounts is an efficient approach.
| "apiGroups": [""], | ||
| "resources": ["services"], | ||
| "resourceNames": [MR_INSTANCE_NAME], # Grant access only to the specific MR service object | ||
| "verbs": ["get"], |
There was a problem hiding this comment.
should we pass the verbs as input param so to have more flexibility?
There was a problem hiding this comment.
in our case we only really care about get on the MR Instance, so I don't think it's really needed. If we were to generalize this to create any Role then I'd agree with you
| subjects_name=f"system:serviceaccounts:{sa_namespace.name}", | ||
| subjects_api_group="rbac.authorization.k8s.io", # This is the default apiGroup for Group kind | ||
| # Role reference parameters | ||
| role_ref_kind="Role", |
There was a problem hiding this comment.
since we are passing already mr_access_role we could use it mr_access_role.kind
There was a problem hiding this comment.
yes, good idea. if you rebase in your PR can you add it?
|
Status of building tag latest: success. |
Docstrings generation was requested by @lugi0. * #296 (comment) The following files were modified: * `tests/model_registry/rbac/conftest.py` * `tests/model_registry/rbac/test_mr_rbac_sa.py` * `tests/model_registry/utils.py`
|
Note Generated docstrings for this pull request at #298 |
* feat: add RBAC test for SA token Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: address review comments Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: incorporate coderabbit suggestions Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: remove unneeded variable Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: remove excessive logs Signed-off-by: lugi0 <lgiorgi@redhat.com> --------- Signed-off-by: lugi0 <lgiorgi@redhat.com>
* feat: add RBAC test for SA token Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: address review comments Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: incorporate coderabbit suggestions Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: remove unneeded variable Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: remove excessive logs Signed-off-by: lugi0 <lgiorgi@redhat.com> --------- Signed-off-by: lugi0 <lgiorgi@redhat.com>
* updates to test_registering_model() based on previous review comments * [do-not-review]must-gather collection at failure point updates! 1176505 updates! 12d9c08 updates! 12d9c08 updates! 65e0213 * [ModelRegistry] ensure RunAsUser and RunAsGroup are not set explicitly (#226) updates! 4813f2b updates! 20cd457 updates! b126825 updates! 809cca7 * Lock file maintenance (#241) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * RHOAIENG-22058: chore(workbenches): add test_create_simple_notebook to smoke (#238) * Remove uv cache from dockerfile to support running in envs like openshift-ci (#239) * Create size-labeler.yml * Delete .github/workflows/size-labeler.yml * model mesh - add auth tests * xx * fix: remove uv cache from dockerfile * `is_managed_cluster` fix condition (#243) * Create size-labeler.yml * Delete .github/workflows/size-labeler.yml * model mesh - add auth tests * xx * fix: replace iter with list * fix: add logger info * RHOAIENG-22057: fix(workbenches): correct the check for spawned workbench (#242) There can only ever be a single workbench pod started. Co-authored-by: Luca Giorgi <lgiorgi@redhat.com> * RHOAIENG-22057: fix(workbenches): check for internal image registry and adjust the image path accordingly (#244) * now yielding TimeoutSampler get_pods_by_isvc_label func output and handling raised ResourceNotFoundError (#237) Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * [model server] add auth test to upgrade (#245) * Create size-labeler.yml * Delete .github/workflows/size-labeler.yml * model mesh - add auth tests * xx * feat: add auth test to upgrade * feat: add auth test to upgrade feat: add auth test to upgrade * fix: dsci name in func * [pre-commit.ci] pre-commit autoupdate (#246) updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.4 → v0.11.5](astral-sh/ruff-pre-commit@v0.11.4...v0.11.5) - [github.com/gitleaks/gitleaks: v8.24.2 → v8.24.3](gitleaks/gitleaks@v8.24.2...v8.24.3) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> * Fix add-remove-labels workflow (#249) * Add Cluster sanity checks before test execution (#235) * Create size-labeler.yml * Delete .github/workflows/size-labeler.yml * model mesh - add auth tests * xx * feat: cluster sanity * feat: cluster sanity * feat: cluster sanity * feat: cluster sanity add readme * fix: tix str typo * fix: address comments * fix: address review comments * fix: address comment * fix: use dsci from global config * fix: remove duplicate fixture * add labeler to add labels to prs based on areas impacted (#248) * on rebase clean commented-by- labels (#251) * [model registry] update namespace code and rearrange tests (#247) * updates to test_registering_model() based on previous review comments * update namespace code and rearrange tests * remove unnecessary argument from function call (#255) * on rebase clean commented-by- labels * remove unnecessary argument from function call * feat: add ocp_interop marker (#260) * Lock file maintenance (#259) * Lock file maintenance * fix: add marshmallow version --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: rnetser <rnetser@redhat.com> * [pre-commit.ci] pre-commit autoupdate (#263) updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.5 → v0.11.6](astral-sh/ruff-pre-commit@v0.11.5...v0.11.6) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> * feat: add upgrade tests (#258) * Remove flake8 ignore list (#265) * fix: remove flake8 ignore * fix: remove flake8 ignore * [model server] Remove pod pre-checks for image pull and fix `TestServerlessScaleToZero` (#256) * fix: update tests * fix: update tests * fix: update tests * fix: save test dep name * fix: minio mm external route * fix: address comemnt * fix: address comemnt * fix: address comemnt * Update python-dependencies (major) (#267) * Update python-dependencies * fix: marshmellow version --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: rnetser <rnetser@redhat.com> * Adding Test For InferenceService Zero Initial Scale (#262) * adding test for zero initial scale Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fixing precommit error Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * using label_selectors when getting deployment Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * adding argument names to func call and running pre-commit on all files Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * fixing bug in ovms_kserve_inference_service function that was preventing isvcs from being created with 0 min-replicas Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> --------- Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat: move interop marker (#268) * feat: Add upgrade tests for TrustyAIService (#250) * feat: Add upgrade tests for TrustyAIService * Move upgrade README.md to docs/UPGRADE.md * fix: reuse kwargs in TrustyAIService fixture * fix: address comments, reuse kwargs, add docstrings --------- Co-authored-by: Ruth Netser <rnetser@redhat.com> * Fix ns deletion logic (#272) * fix: fix resource deletion fixture logic * fix: fix resource deletion fixture logic * feat: fail on missing operators (#257) * fix: update tests * fix: update tests * feat: fail on missing operators * fix: rename to dependent * fix: address comment * fix: add log on failure * fix: type in raise * fix: remove MR check * fix: remove MR check * fix: use package scope * Add basic InferenceGraph deployment check (#233) * Add basic InferenceGraph deployment check This adds a test that deploys an InferenceGraph (IG), sends an inference request to the IG and verifies that the request succeeds. The deployed InferenceGraph is based on the example on the KServe documentation available in the following URL: https://kserve.github.io/website/0.15/modelserving/inference_graph/image_pipeline/. The example was adapted to run in openvino (which is a supported server in ODH), rather than TorchServe. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Use cloud storage in InferenceGraph test Use cloud storage for the models, instead of OCI * Feedback: Ruth * Feedback: Ruth * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Apply Ruth suggestions Acknowledgement to @rnester for these changes. * More feedback: Ruth * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> * fix: address 503 (#274) * [model server] Move to using unprivileged_client in tests (#273) * feat: use unprivileged_client * feat: use unprivileged_client * feat: use unprivileged_client * feat: use unprivileged_client * feat: use unprivileged_client * feat: use unprivileged_client * fix: unpri selection * Update MinIo pod privileges to run on ocp 4.19 (#277) * fix: add securityContext for minio pod * fix: minio on 4.19 * [model server] add multi node args check (#276) * feat: add multi node args * feat: add multi node args * fix: add wait on delete * fix: update new test * [pre-commit.ci] pre-commit autoupdate (#279) updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.6 → v0.11.7](astral-sh/ruff-pre-commit@v0.11.6...v0.11.7) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> * `verify_no_failed_pods` - exclude container failures when model mesh deployment (#278) * fix: mm container * fix: update condition * feat: add test for incorrect DB TLS config in Trusty AI (#221) * feat: add test for incorrect DB TLS config in Trusty AI * refactor: remove unused method from utils * feat: move TrustyAI test to own file * refactor: change name of db fixtures and deduplicate code * TrustyAI Service creation code refactor into own method * Move db secret setter to utils * Remove test from test_fairness as test moved to own file * docs: add description to TrustyAI invalid DB TLS config test * fix: check TrustyAIService container for Terminated status in lastStatus * fix: change name of terminal_state getter function * fix: change to a valid certificate and check for service failure * fix: address PR 221 reviewer feedback * revert wait_for_pods to wait_for_mariadb_pods * improve error checking logic * remove un-necessary wrapper function * docs: add docstring to create_trustyai_service method * docs: add docstring to trustyai_service_with_invalid_db_cert * fix: fix invalid return type for trustyai_db_ca_secret * feat: use retry decorator in validate trustyai_service_db_conn_failure method * fix: remove unnecessary return from validate db_conn_failure method * docs: add spacing between lines of docstring * refactor: create constants trustyai metrics and db storage config * refactor: address reviewer feedback - change docstring to correct formatting - remove len(0) check - no templating for error text * fix: use regex instead of in operator to check for error condition * docs: add correct formatting to docstrings * fix: use namespace.name instead of namespace in Pod.get * fix: remove \s from regex to check for spaces * refactor: add Raises section in docstring and use single string for pytest.fail * feat: use raise instead of pytest.fail - create new exception TooManyPodsError - create new exception UnexpectedFailureError - replace pytest.fail with raise and handle exceptions in retry - * fix: change default of teardown to True in TrustyAIService * docs: correct typo in trustyai docstring * docs: fix raises in docs and fix formatting * fix: fix create_trustyai_service namespace args issue * docs: add default for name arg in create tai svc func * [model server] Fix runtime request.param name to use external route (#280) * fix: fix param name * fix: fix param name * feat: add certs when sending requests to TrustyAIService (#266) * Wait for pods to be in running state before attempting to create ModelRegistry (#270) * on rebase clean commented-by- labels * Wait for pods to be in running state before attempting to create ModelRegistry * Address Exception in thread Thread-1 (_monitor) error (#286) * chore(deps): lock file maintenance (#287) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * [pre-commit.ci] pre-commit autoupdate (#292) updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.7 → v0.11.8](astral-sh/ruff-pre-commit@v0.11.7...v0.11.8) - [github.com/gitleaks/gitleaks: v8.24.3 → v8.25.1](gitleaks/gitleaks@v8.24.3...v8.25.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Wait for dsc and dsci ready state in cluster_sanity check (#293) * fix(workbenches): implement get_username for OpenShift <=4.14 (#275) Turns out SelfSubjectReview is only available starting OpenShift 4.15. fixup incorporate User resource * RedHatQE/openshift-python-wrapper#2387 fixup incorporate SelfSubjectReview resource * RedHatQE/openshift-python-wrapper#2389 Co-authored-by: Debarati Basu-Nag <dbasunag@redhat.com> * replace the bot account with one owned by testdevops (#291) * Fix for post upgarde operator check (#297) Signed-off-by: Milind Waykole <mwaykole@mwaykole-thinkpadp1gen4i.bengluru.csb> Co-authored-by: Milind Waykole <mwaykole@mwaykole-thinkpadp1gen4i.bengluru.csb> * Add test for Model Registry RBAC for SA token (#296) * feat: add RBAC test for SA token Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: address review comments Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: incorporate coderabbit suggestions Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: remove unneeded variable Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: remove excessive logs Signed-off-by: lugi0 <lgiorgi@redhat.com> --------- Signed-off-by: lugi0 <lgiorgi@redhat.com> * Support /build-push-pr-image comment to push image to quay for testing via jenkins (#290) updates! 678b389 * Add tests for model_artifact update validations (#284) * Add tests for model_artifact update validations * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * updates fixing pre-commit * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * update package * minor updates * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * address review comments updates! 50ec24b updates! f3a6c3e updates! 792156f updates! 399aa10 updates! 5080e3b updates! c34f4e7 updates! a1d7baa --------- Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> Signed-off-by: Milind Waykole <mwaykole@mwaykole-thinkpadp1gen4i.bengluru.csb> Signed-off-by: lugi0 <lgiorgi@redhat.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jiri Daněk <jdanek@redhat.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> Co-authored-by: Luca Giorgi <lgiorgi@redhat.com> Co-authored-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Adolfo Aguirrezabal <aaguirre@redhat.com> Co-authored-by: Edgar Hernández <ehernand@redhat.com> Co-authored-by: Shelton Cyril <sheltoncyril@gmail.com> Co-authored-by: Milind Waykole <mwaykole@redhat.com> Co-authored-by: Milind Waykole <mwaykole@mwaykole-thinkpadp1gen4i.bengluru.csb>
* updates to test_registering_model() based on previous review comments * [do-not-review]must-gather collection at failure point updates! 1176505 updates! 12d9c08 updates! 12d9c08 updates! 65e0213 * [ModelRegistry] ensure RunAsUser and RunAsGroup are not set explicitly (#226) updates! 4813f2b updates! 20cd457 updates! b126825 updates! 809cca7 * Lock file maintenance (#241) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * RHOAIENG-22058: chore(workbenches): add test_create_simple_notebook to smoke (#238) * Remove uv cache from dockerfile to support running in envs like openshift-ci (#239) * Create size-labeler.yml * Delete .github/workflows/size-labeler.yml * model mesh - add auth tests * xx * fix: remove uv cache from dockerfile * `is_managed_cluster` fix condition (#243) * Create size-labeler.yml * Delete .github/workflows/size-labeler.yml * model mesh - add auth tests * xx * fix: replace iter with list * fix: add logger info * RHOAIENG-22057: fix(workbenches): correct the check for spawned workbench (#242) There can only ever be a single workbench pod started. Co-authored-by: Luca Giorgi <lgiorgi@redhat.com> * RHOAIENG-22057: fix(workbenches): check for internal image registry and adjust the image path accordingly (#244) * now yielding TimeoutSampler get_pods_by_isvc_label func output and handling raised ResourceNotFoundError (#237) Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * [model server] add auth test to upgrade (#245) * Create size-labeler.yml * Delete .github/workflows/size-labeler.yml * model mesh - add auth tests * xx * feat: add auth test to upgrade * feat: add auth test to upgrade feat: add auth test to upgrade * fix: dsci name in func * [pre-commit.ci] pre-commit autoupdate (#246) updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.4 → v0.11.5](astral-sh/ruff-pre-commit@v0.11.4...v0.11.5) - [github.com/gitleaks/gitleaks: v8.24.2 → v8.24.3](gitleaks/gitleaks@v8.24.2...v8.24.3) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> * Fix add-remove-labels workflow (#249) * Add Cluster sanity checks before test execution (#235) * Create size-labeler.yml * Delete .github/workflows/size-labeler.yml * model mesh - add auth tests * xx * feat: cluster sanity * feat: cluster sanity * feat: cluster sanity * feat: cluster sanity add readme * fix: tix str typo * fix: address comments * fix: address review comments * fix: address comment * fix: use dsci from global config * fix: remove duplicate fixture * add labeler to add labels to prs based on areas impacted (#248) * on rebase clean commented-by- labels (#251) * [model registry] update namespace code and rearrange tests (#247) * updates to test_registering_model() based on previous review comments * update namespace code and rearrange tests * remove unnecessary argument from function call (#255) * on rebase clean commented-by- labels * remove unnecessary argument from function call * feat: add ocp_interop marker (#260) * Lock file maintenance (#259) * Lock file maintenance * fix: add marshmallow version --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: rnetser <rnetser@redhat.com> * [pre-commit.ci] pre-commit autoupdate (#263) updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.5 → v0.11.6](astral-sh/ruff-pre-commit@v0.11.5...v0.11.6) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> * feat: add upgrade tests (#258) * Remove flake8 ignore list (#265) * fix: remove flake8 ignore * fix: remove flake8 ignore * [model server] Remove pod pre-checks for image pull and fix `TestServerlessScaleToZero` (#256) * fix: update tests * fix: update tests * fix: update tests * fix: save test dep name * fix: minio mm external route * fix: address comemnt * fix: address comemnt * fix: address comemnt * Update python-dependencies (major) (#267) * Update python-dependencies * fix: marshmellow version --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: rnetser <rnetser@redhat.com> * Adding Test For InferenceService Zero Initial Scale (#262) * adding test for zero initial scale Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fixing precommit error Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * using label_selectors when getting deployment Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * adding argument names to func call and running pre-commit on all files Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * fixing bug in ovms_kserve_inference_service function that was preventing isvcs from being created with 0 min-replicas Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> --------- Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat: move interop marker (#268) * feat: Add upgrade tests for TrustyAIService (#250) * feat: Add upgrade tests for TrustyAIService * Move upgrade README.md to docs/UPGRADE.md * fix: reuse kwargs in TrustyAIService fixture * fix: address comments, reuse kwargs, add docstrings --------- Co-authored-by: Ruth Netser <rnetser@redhat.com> * Fix ns deletion logic (#272) * fix: fix resource deletion fixture logic * fix: fix resource deletion fixture logic * feat: fail on missing operators (#257) * fix: update tests * fix: update tests * feat: fail on missing operators * fix: rename to dependent * fix: address comment * fix: add log on failure * fix: type in raise * fix: remove MR check * fix: remove MR check * fix: use package scope * Add basic InferenceGraph deployment check (#233) * Add basic InferenceGraph deployment check This adds a test that deploys an InferenceGraph (IG), sends an inference request to the IG and verifies that the request succeeds. The deployed InferenceGraph is based on the example on the KServe documentation available in the following URL: https://kserve.github.io/website/0.15/modelserving/inference_graph/image_pipeline/. The example was adapted to run in openvino (which is a supported server in ODH), rather than TorchServe. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Use cloud storage in InferenceGraph test Use cloud storage for the models, instead of OCI * Feedback: Ruth * Feedback: Ruth * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Apply Ruth suggestions Acknowledgement to @rnester for these changes. * More feedback: Ruth * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> * fix: address 503 (#274) * [model server] Move to using unprivileged_client in tests (#273) * feat: use unprivileged_client * feat: use unprivileged_client * feat: use unprivileged_client * feat: use unprivileged_client * feat: use unprivileged_client * feat: use unprivileged_client * fix: unpri selection * Update MinIo pod privileges to run on ocp 4.19 (#277) * fix: add securityContext for minio pod * fix: minio on 4.19 * [model server] add multi node args check (#276) * feat: add multi node args * feat: add multi node args * fix: add wait on delete * fix: update new test * [pre-commit.ci] pre-commit autoupdate (#279) updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.6 → v0.11.7](astral-sh/ruff-pre-commit@v0.11.6...v0.11.7) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> * `verify_no_failed_pods` - exclude container failures when model mesh deployment (#278) * fix: mm container * fix: update condition * feat: add test for incorrect DB TLS config in Trusty AI (#221) * feat: add test for incorrect DB TLS config in Trusty AI * refactor: remove unused method from utils * feat: move TrustyAI test to own file * refactor: change name of db fixtures and deduplicate code * TrustyAI Service creation code refactor into own method * Move db secret setter to utils * Remove test from test_fairness as test moved to own file * docs: add description to TrustyAI invalid DB TLS config test * fix: check TrustyAIService container for Terminated status in lastStatus * fix: change name of terminal_state getter function * fix: change to a valid certificate and check for service failure * fix: address PR 221 reviewer feedback * revert wait_for_pods to wait_for_mariadb_pods * improve error checking logic * remove un-necessary wrapper function * docs: add docstring to create_trustyai_service method * docs: add docstring to trustyai_service_with_invalid_db_cert * fix: fix invalid return type for trustyai_db_ca_secret * feat: use retry decorator in validate trustyai_service_db_conn_failure method * fix: remove unnecessary return from validate db_conn_failure method * docs: add spacing between lines of docstring * refactor: create constants trustyai metrics and db storage config * refactor: address reviewer feedback - change docstring to correct formatting - remove len(0) check - no templating for error text * fix: use regex instead of in operator to check for error condition * docs: add correct formatting to docstrings * fix: use namespace.name instead of namespace in Pod.get * fix: remove \s from regex to check for spaces * refactor: add Raises section in docstring and use single string for pytest.fail * feat: use raise instead of pytest.fail - create new exception TooManyPodsError - create new exception UnexpectedFailureError - replace pytest.fail with raise and handle exceptions in retry - * fix: change default of teardown to True in TrustyAIService * docs: correct typo in trustyai docstring * docs: fix raises in docs and fix formatting * fix: fix create_trustyai_service namespace args issue * docs: add default for name arg in create tai svc func * [model server] Fix runtime request.param name to use external route (#280) * fix: fix param name * fix: fix param name * feat: add certs when sending requests to TrustyAIService (#266) * Wait for pods to be in running state before attempting to create ModelRegistry (#270) * on rebase clean commented-by- labels * Wait for pods to be in running state before attempting to create ModelRegistry * Address Exception in thread Thread-1 (_monitor) error (opendatahub-io#286) * chore(deps): lock file maintenance (opendatahub-io#287) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * [pre-commit.ci] pre-commit autoupdate (opendatahub-io#292) updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.7 → v0.11.8](astral-sh/ruff-pre-commit@v0.11.7...v0.11.8) - [github.com/gitleaks/gitleaks: v8.24.3 → v8.25.1](gitleaks/gitleaks@v8.24.3...v8.25.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Wait for dsc and dsci ready state in cluster_sanity check (opendatahub-io#293) * fix(workbenches): implement get_username for OpenShift <=4.14 (#275) Turns out SelfSubjectReview is only available starting OpenShift 4.15. fixup incorporate User resource * RedHatQE/openshift-python-wrapper#2387 fixup incorporate SelfSubjectReview resource * RedHatQE/openshift-python-wrapper#2389 Co-authored-by: Debarati Basu-Nag <dbasunag@redhat.com> * replace the bot account with one owned by testdevops (opendatahub-io#291) * Fix for post upgarde operator check (opendatahub-io#297) Signed-off-by: Milind Waykole <mwaykole@mwaykole-thinkpadp1gen4i.bengluru.csb> Co-authored-by: Milind Waykole <mwaykole@mwaykole-thinkpadp1gen4i.bengluru.csb> * Add test for Model Registry RBAC for SA token (opendatahub-io#296) * feat: add RBAC test for SA token Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: address review comments Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: incorporate coderabbit suggestions Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: remove unneeded variable Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: remove excessive logs Signed-off-by: lugi0 <lgiorgi@redhat.com> --------- Signed-off-by: lugi0 <lgiorgi@redhat.com> * Support /build-push-pr-image comment to push image to quay for testing via jenkins (opendatahub-io#290) updates! 678b389 * Add tests for model_artifact update validations (#284) * Add tests for model_artifact update validations * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * updates fixing pre-commit * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * update package * minor updates * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * address review comments updates! 50ec24b updates! f3a6c3e updates! 792156f updates! 399aa10 updates! 5080e3b updates! c34f4e7 updates! a1d7baa --------- Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> Signed-off-by: Milind Waykole <mwaykole@mwaykole-thinkpadp1gen4i.bengluru.csb> Signed-off-by: lugi0 <lgiorgi@redhat.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jiri Daněk <jdanek@redhat.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> Co-authored-by: Luca Giorgi <lgiorgi@redhat.com> Co-authored-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Adolfo Aguirrezabal <aaguirre@redhat.com> Co-authored-by: Edgar Hernández <ehernand@redhat.com> Co-authored-by: Shelton Cyril <sheltoncyril@gmail.com> Co-authored-by: Milind Waykole <mwaykole@redhat.com> Co-authored-by: Milind Waykole <mwaykole@mwaykole-thinkpadp1gen4i.bengluru.csb>
* updates to test_registering_model() based on previous review comments * [do-not-review]must-gather collection at failure point updates! 1176505 updates! 12d9c08 updates! 12d9c08 updates! 65e0213 * [ModelRegistry] ensure RunAsUser and RunAsGroup are not set explicitly (opendatahub-io#226) updates! 4813f2b updates! 20cd457 updates! b126825 updates! 809cca7 * Lock file maintenance (opendatahub-io#241) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * RHOAIENG-22058: chore(workbenches): add test_create_simple_notebook to smoke (opendatahub-io#238) * Remove uv cache from dockerfile to support running in envs like openshift-ci (opendatahub-io#239) * Create size-labeler.yml * Delete .github/workflows/size-labeler.yml * model mesh - add auth tests * xx * fix: remove uv cache from dockerfile * `is_managed_cluster` fix condition (opendatahub-io#243) * Create size-labeler.yml * Delete .github/workflows/size-labeler.yml * model mesh - add auth tests * xx * fix: replace iter with list * fix: add logger info * RHOAIENG-22057: fix(workbenches): correct the check for spawned workbench (opendatahub-io#242) There can only ever be a single workbench pod started. Co-authored-by: Luca Giorgi <lgiorgi@redhat.com> * RHOAIENG-22057: fix(workbenches): check for internal image registry and adjust the image path accordingly (opendatahub-io#244) * now yielding TimeoutSampler get_pods_by_isvc_label func output and handling raised ResourceNotFoundError (opendatahub-io#237) Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * [model server] add auth test to upgrade (opendatahub-io#245) * Create size-labeler.yml * Delete .github/workflows/size-labeler.yml * model mesh - add auth tests * xx * feat: add auth test to upgrade * feat: add auth test to upgrade feat: add auth test to upgrade * fix: dsci name in func * [pre-commit.ci] pre-commit autoupdate (opendatahub-io#246) updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.4 → v0.11.5](astral-sh/ruff-pre-commit@v0.11.4...v0.11.5) - [github.com/gitleaks/gitleaks: v8.24.2 → v8.24.3](gitleaks/gitleaks@v8.24.2...v8.24.3) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> * Fix add-remove-labels workflow (opendatahub-io#249) * Add Cluster sanity checks before test execution (opendatahub-io#235) * Create size-labeler.yml * Delete .github/workflows/size-labeler.yml * model mesh - add auth tests * xx * feat: cluster sanity * feat: cluster sanity * feat: cluster sanity * feat: cluster sanity add readme * fix: tix str typo * fix: address comments * fix: address review comments * fix: address comment * fix: use dsci from global config * fix: remove duplicate fixture * add labeler to add labels to prs based on areas impacted (opendatahub-io#248) * on rebase clean commented-by- labels (opendatahub-io#251) * [model registry] update namespace code and rearrange tests (opendatahub-io#247) * updates to test_registering_model() based on previous review comments * update namespace code and rearrange tests * remove unnecessary argument from function call (opendatahub-io#255) * on rebase clean commented-by- labels * remove unnecessary argument from function call * feat: add ocp_interop marker (opendatahub-io#260) * Lock file maintenance (opendatahub-io#259) * Lock file maintenance * fix: add marshmallow version --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: rnetser <rnetser@redhat.com> * [pre-commit.ci] pre-commit autoupdate (opendatahub-io#263) updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.5 → v0.11.6](astral-sh/ruff-pre-commit@v0.11.5...v0.11.6) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> * feat: add upgrade tests (opendatahub-io#258) * Remove flake8 ignore list (opendatahub-io#265) * fix: remove flake8 ignore * fix: remove flake8 ignore * [model server] Remove pod pre-checks for image pull and fix `TestServerlessScaleToZero` (opendatahub-io#256) * fix: update tests * fix: update tests * fix: update tests * fix: save test dep name * fix: minio mm external route * fix: address comemnt * fix: address comemnt * fix: address comemnt * Update python-dependencies (major) (opendatahub-io#267) * Update python-dependencies * fix: marshmellow version --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: rnetser <rnetser@redhat.com> * Adding Test For InferenceService Zero Initial Scale (opendatahub-io#262) * adding test for zero initial scale Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fixing precommit error Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * using label_selectors when getting deployment Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * adding argument names to func call and running pre-commit on all files Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> * fixing bug in ovms_kserve_inference_service function that was preventing isvcs from being created with 0 min-replicas Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> --------- Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat: move interop marker (opendatahub-io#268) * feat: Add upgrade tests for TrustyAIService (opendatahub-io#250) * feat: Add upgrade tests for TrustyAIService * Move upgrade README.md to docs/UPGRADE.md * fix: reuse kwargs in TrustyAIService fixture * fix: address comments, reuse kwargs, add docstrings --------- Co-authored-by: Ruth Netser <rnetser@redhat.com> * Fix ns deletion logic (opendatahub-io#272) * fix: fix resource deletion fixture logic * fix: fix resource deletion fixture logic * feat: fail on missing operators (opendatahub-io#257) * fix: update tests * fix: update tests * feat: fail on missing operators * fix: rename to dependent * fix: address comment * fix: add log on failure * fix: type in raise * fix: remove MR check * fix: remove MR check * fix: use package scope * Add basic InferenceGraph deployment check (opendatahub-io#233) * Add basic InferenceGraph deployment check This adds a test that deploys an InferenceGraph (IG), sends an inference request to the IG and verifies that the request succeeds. The deployed InferenceGraph is based on the example on the KServe documentation available in the following URL: https://kserve.github.io/website/0.15/modelserving/inference_graph/image_pipeline/. The example was adapted to run in openvino (which is a supported server in ODH), rather than TorchServe. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Use cloud storage in InferenceGraph test Use cloud storage for the models, instead of OCI * Feedback: Ruth * Feedback: Ruth * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Apply Ruth suggestions Acknowledgement to @rnester for these changes. * More feedback: Ruth * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> * fix: address 503 (opendatahub-io#274) * [model server] Move to using unprivileged_client in tests (opendatahub-io#273) * feat: use unprivileged_client * feat: use unprivileged_client * feat: use unprivileged_client * feat: use unprivileged_client * feat: use unprivileged_client * feat: use unprivileged_client * fix: unpri selection * Update MinIo pod privileges to run on ocp 4.19 (opendatahub-io#277) * fix: add securityContext for minio pod * fix: minio on 4.19 * [model server] add multi node args check (opendatahub-io#276) * feat: add multi node args * feat: add multi node args * fix: add wait on delete * fix: update new test * [pre-commit.ci] pre-commit autoupdate (opendatahub-io#279) updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.6 → v0.11.7](astral-sh/ruff-pre-commit@v0.11.6...v0.11.7) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> * `verify_no_failed_pods` - exclude container failures when model mesh deployment (opendatahub-io#278) * fix: mm container * fix: update condition * feat: add test for incorrect DB TLS config in Trusty AI (opendatahub-io#221) * feat: add test for incorrect DB TLS config in Trusty AI * refactor: remove unused method from utils * feat: move TrustyAI test to own file * refactor: change name of db fixtures and deduplicate code * TrustyAI Service creation code refactor into own method * Move db secret setter to utils * Remove test from test_fairness as test moved to own file * docs: add description to TrustyAI invalid DB TLS config test * fix: check TrustyAIService container for Terminated status in lastStatus * fix: change name of terminal_state getter function * fix: change to a valid certificate and check for service failure * fix: address PR 221 reviewer feedback * revert wait_for_pods to wait_for_mariadb_pods * improve error checking logic * remove un-necessary wrapper function * docs: add docstring to create_trustyai_service method * docs: add docstring to trustyai_service_with_invalid_db_cert * fix: fix invalid return type for trustyai_db_ca_secret * feat: use retry decorator in validate trustyai_service_db_conn_failure method * fix: remove unnecessary return from validate db_conn_failure method * docs: add spacing between lines of docstring * refactor: create constants trustyai metrics and db storage config * refactor: address reviewer feedback - change docstring to correct formatting - remove len(0) check - no templating for error text * fix: use regex instead of in operator to check for error condition * docs: add correct formatting to docstrings * fix: use namespace.name instead of namespace in Pod.get * fix: remove \s from regex to check for spaces * refactor: add Raises section in docstring and use single string for pytest.fail * feat: use raise instead of pytest.fail - create new exception TooManyPodsError - create new exception UnexpectedFailureError - replace pytest.fail with raise and handle exceptions in retry - * fix: change default of teardown to True in TrustyAIService * docs: correct typo in trustyai docstring * docs: fix raises in docs and fix formatting * fix: fix create_trustyai_service namespace args issue * docs: add default for name arg in create tai svc func * [model server] Fix runtime request.param name to use external route (opendatahub-io#280) * fix: fix param name * fix: fix param name * feat: add certs when sending requests to TrustyAIService (opendatahub-io#266) * Wait for pods to be in running state before attempting to create ModelRegistry (opendatahub-io#270) * on rebase clean commented-by- labels * Wait for pods to be in running state before attempting to create ModelRegistry * Address Exception in thread Thread-1 (_monitor) error (opendatahub-io#286) * chore(deps): lock file maintenance (opendatahub-io#287) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * [pre-commit.ci] pre-commit autoupdate (opendatahub-io#292) updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.7 → v0.11.8](astral-sh/ruff-pre-commit@v0.11.7...v0.11.8) - [github.com/gitleaks/gitleaks: v8.24.3 → v8.25.1](gitleaks/gitleaks@v8.24.3...v8.25.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * Wait for dsc and dsci ready state in cluster_sanity check (opendatahub-io#293) * fix(workbenches): implement get_username for OpenShift <=4.14 (opendatahub-io#275) Turns out SelfSubjectReview is only available starting OpenShift 4.15. fixup incorporate User resource * RedHatQE/openshift-python-wrapper#2387 fixup incorporate SelfSubjectReview resource * RedHatQE/openshift-python-wrapper#2389 Co-authored-by: Debarati Basu-Nag <dbasunag@redhat.com> * replace the bot account with one owned by testdevops (opendatahub-io#291) * Fix for post upgarde operator check (opendatahub-io#297) Signed-off-by: Milind Waykole <mwaykole@mwaykole-thinkpadp1gen4i.bengluru.csb> Co-authored-by: Milind Waykole <mwaykole@mwaykole-thinkpadp1gen4i.bengluru.csb> * Add test for Model Registry RBAC for SA token (opendatahub-io#296) * feat: add RBAC test for SA token Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: address review comments Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: incorporate coderabbit suggestions Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: remove unneeded variable Signed-off-by: lugi0 <lgiorgi@redhat.com> * fix: remove excessive logs Signed-off-by: lugi0 <lgiorgi@redhat.com> --------- Signed-off-by: lugi0 <lgiorgi@redhat.com> * Support /build-push-pr-image comment to push image to quay for testing via jenkins (opendatahub-io#290) updates! 678b389 * Add tests for model_artifact update validations (opendatahub-io#284) * Add tests for model_artifact update validations * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * updates fixing pre-commit * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * update package * minor updates * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * address review comments updates! 50ec24b updates! f3a6c3e updates! 792156f updates! 399aa10 updates! 5080e3b updates! c34f4e7 updates! a1d7baa --------- Signed-off-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> Signed-off-by: Milind Waykole <mwaykole@mwaykole-thinkpadp1gen4i.bengluru.csb> Signed-off-by: lugi0 <lgiorgi@redhat.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jiri Daněk <jdanek@redhat.com> Co-authored-by: Ruth Netser <rnetser@redhat.com> Co-authored-by: Luca Giorgi <lgiorgi@redhat.com> Co-authored-by: Brett Thompson <196701379+brettmthompson@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Adolfo Aguirrezabal <aaguirre@redhat.com> Co-authored-by: Edgar Hernández <ehernand@redhat.com> Co-authored-by: Shelton Cyril <sheltoncyril@gmail.com> Co-authored-by: Milind Waykole <mwaykole@redhat.com> Co-authored-by: Milind Waykole <mwaykole@mwaykole-thinkpadp1gen4i.bengluru.csb>
Description
How Has This Been Tested?
Merge criteria:
Summary by CodeRabbit
New Features
Bug Fixes