Skip to content

replacing patch way to ResourceEditor#519

Merged
dbasunag merged 4 commits intoopendatahub-io:mainfrom
mwaykole:kedafix
Aug 13, 2025
Merged

replacing patch way to ResourceEditor#519
dbasunag merged 4 commits intoopendatahub-io:mainfrom
mwaykole:kedafix

Conversation

@mwaykole
Copy link
Copy Markdown
Member

@mwaykole mwaykole commented Aug 13, 2025

Summary by CodeRabbit

  • Tests
    • Strengthened KEDA CPU autoscaling test by adding authentication to external metrics and switching to a more reliable resource update flow.
    • Improves test stability, reduces flakiness, and better reflects current autoscaling behavior.
    • Core validation steps remain the same; no changes to user-facing functionality.

Signed-off-by: Milind Waykole <mwaykole@redhat.com>
@mwaykole mwaykole requested a review from Raghul-M as a code owner August 13, 2025 09:25
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Aug 13, 2025

📝 Walkthrough

Walkthrough

Replaced JSON Patch updates with ResourceEditor-based updates in a KEDA scaling CPU test. The test now converts the InferenceService to dict, conditionally injects external authenticationRef settings into autoScaling.metrics, and applies the change via ResourceEditor. The rest of the test flow remains unchanged.

Changes

Cohort / File(s) Summary of changes
KEDA test update to use ResourceEditor
tests/model_serving/model_server/keda/test_isvc_keda_scaling_cpu.py
Switched from admin_client JSON Patch to ResourceEditor patches. Materialized InferenceService to dict, extracted spec.predictor.autoScaling.metrics, conditionally injected external.authenticationRef with authModes "bearer" and name "inference-prometheus-auth", and applied the update. No other test logic altered.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

❤️ Share
🪧 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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

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.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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

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

@mwaykole mwaykole self-assigned this Aug 13, 2025
@mwaykole mwaykole added Verified Verified pr in Jenkins and removed size/s labels Aug 13, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/model_serving/model_server/keda/test_isvc_keda_scaling_cpu.py (2)

85-97: RBAC/regression risk: patch now uses the unprivileged client.

Previously the JSON patch used admin_client; ResourceEditor operates with the client of the resource key you pass. Since stressed_ovms_keda_inference_service originates from the unprivileged_client fixture (see conftest), this change may fail under stricter RBAC.

If admin privileges are required here, patch via an admin-scoped resource object:

-                ResourceEditor(
-                    patches={
-                        stressed_ovms_keda_inference_service: {
+                admin_isvc = InferenceService(
+                    name=stressed_ovms_keda_inference_service.name,
+                    namespace=stressed_ovms_keda_inference_service.namespace,
+                    client=admin_client,
+                )
+                ResourceEditor(
+                    patches={
+                        admin_isvc: {
                             "spec": {
                                 "predictor": {
                                     "autoScaling": {
                                         "metrics": metrics,
                                     }
                                 }
                             }
                         }
                     }
                 ).update()

Follow-up:

  • Confirm the unprivileged SA has patch permission on InferenceServices; otherwise adopt the admin-scoped edit above.

76-84: Optional: Avoid relying on metrics[0] ordering.

If multiple metrics are configured, indexing [0] is brittle. Consider updating the first metric that has an external block:

Example (outside-of-diff illustration):
"""
for m in metrics:
if isinstance(m, dict) and isinstance(m.get("external"), dict):
m["external"]["authModes"] = "bearer"
m["external"]["authenticationRef"] = {"name": "inference-prometheus-auth"}
break
"""

This makes the code resilient to ordering changes from upstream helpers.

To be safe, please verify whether multiple metrics could be present in this test’s auto scaling config (create_keda_auto_scaling_config). If yes, prefer the looped approach above.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9f27359 and 2f6c8ff.

📒 Files selected for processing (1)
  • tests/model_serving/model_server/keda/test_isvc_keda_scaling_cpu.py (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: dbasunag
PR: opendatahub-io/opendatahub-tests#504
File: tests/model_registry/upgrade/conftest.py:20-30
Timestamp: 2025-08-11T12:14:34.102Z
Learning: In tests/model_registry/upgrade/conftest.py, when using ResourceEditor to patch DataScienceCluster resources with a partial components dictionary like `{DscComponents.MODELREGISTRY: {"managementState": ...}}`, the patch is applied correctly without overwriting other components in spec.components. ResourceEditor performs the appropriate merge operation for this resource type.
🧬 Code Graph Analysis (1)
tests/model_serving/model_server/keda/test_isvc_keda_scaling_cpu.py (1)
tests/model_serving/model_server/keda/conftest.py (1)
  • stressed_ovms_keda_inference_service (165-194)
🔇 Additional comments (2)
tests/model_serving/model_server/keda/test_isvc_keda_scaling_cpu.py (2)

2-2: Good switch to ResourceEditor.

Importing and using ResourceEditor improves readability and aligns with our test infra patterns for patching resources.


79-83: KEDA Prometheus trigger metadata fields are correct

Confirmed that in the Prometheus scaler spec:

  • authModes and authenticationRef are sibling fields.
  • authModes accepts a comma-separated string (e.g. "bearer").

The current test snippet correctly sets:

metrics[0]["external"]["authenticationRef"] = {
    "authModes": "bearer",
    "authenticationRef": {"name": "inference-prometheus-auth"},
}

…which matches the official KEDA documentation. No changes required.

Comment on lines +79 to 83
if metrics and isinstance(metrics[0], dict) and metrics[0].get("external") is not None:
metrics[0].setdefault("external", {})["authenticationRef"] = {
"authModes": "bearer",
"authenticationRef": {"name": "inference-prometheus-auth"},
}
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Aug 13, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Bug: authModes incorrectly nested under authenticationRef.

In the KEDA trigger spec, authModes and authenticationRef are sibling fields (under external), not nested. The current structure will produce an invalid spec.

Apply this diff to fix the structure and harden the type check:

-if metrics and isinstance(metrics[0], dict) and metrics[0].get("external") is not None:
-    metrics[0].setdefault("external", {})["authenticationRef"] = {
-        "authModes": "bearer",
-        "authenticationRef": {"name": "inference-prometheus-auth"},
-    }
+if metrics and isinstance(metrics[0], dict) and isinstance(metrics[0].get("external"), dict):
+    external = metrics[0]["external"]
+    external["authModes"] = "bearer"
+    external["authenticationRef"] = {"name": "inference-prometheus-auth"}
📝 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.

Suggested change
if metrics and isinstance(metrics[0], dict) and metrics[0].get("external") is not None:
metrics[0].setdefault("external", {})["authenticationRef"] = {
"authModes": "bearer",
"authenticationRef": {"name": "inference-prometheus-auth"},
}
if metrics and isinstance(metrics[0], dict) and isinstance(metrics[0].get("external"), dict):
external = metrics[0]["external"]
external["authModes"] = "bearer"
external["authenticationRef"] = {"name": "inference-prometheus-auth"}
🤖 Prompt for AI Agents
In tests/model_serving/model_server/keda/test_isvc_keda_scaling_cpu.py around
lines 79 to 83, the code nests authModes under authenticationRef and doesn't
robustly check external's type; update the block to first verify metrics and
that metrics[0].get("external") is a dict, then set external["authModes"] =
["bearer"] and external["authenticationRef"] = {"name":
"inference-prometheus-auth"} as sibling keys under external (not nested),
ensuring the correct list value for authModes and avoiding invalid spec shape.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@mwaykole check if this makes sense.

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.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Comment on lines +79 to 83
if metrics and isinstance(metrics[0], dict) and metrics[0].get("external") is not None:
metrics[0].setdefault("external", {})["authenticationRef"] = {
"authModes": "bearer",
"authenticationRef": {"name": "inference-prometheus-auth"},
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@mwaykole check if this makes sense.

@dbasunag dbasunag merged commit ddc5f02 into opendatahub-io:main Aug 13, 2025
9 checks passed
@github-actions
Copy link
Copy Markdown

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants