Skip to content

test(maas): update subscription tests with new API key changes#1177

Merged
threcc merged 11 commits intoopendatahub-io:mainfrom
SB159:feature/multiple-auth-policies
Mar 9, 2026
Merged

test(maas): update subscription tests with new API key changes#1177
threcc merged 11 commits intoopendatahub-io:mainfrom
SB159:feature/multiple-auth-policies

Conversation

@SB159
Copy link
Copy Markdown
Contributor

@SB159 SB159 commented Mar 6, 2026

Pull Request

Summary

Updates maas multiple subscription tests to use the new API key based authentication flow.
Changes include:

  • Creating API keys via MaaS API (POST /v1/api-keys)
  • Using the generated API key for gateway inference requests
  • Updating multiple subscription test cases to match the new auth flow

Related Issues

How it has been tested

  • Locally
  • Jenkins

Additional Requirements

  • If this PR introduces a new test image, did you create a PR to mirror it in disconnected environment?
  • If this PR introduces new marker(s)/adds a new component, was relevant ticket created to update relevant Jenkins job?

Summary by CodeRabbit

  • Tests
    • Added API-key fixtures and helpers to create MaaS API keys and produce request headers for subscription tests.
    • Updated subscription access tests to use API-key-based headers instead of token-based headers.
    • Changed several test markers from sanity to smoke to better reflect scope and prioritization.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 6, 2026

The following are automatically added/executed:

  • PR size label.
  • Run pre-commit
  • Run tox
  • Add PR author as the PR assignee
  • Build image based on the PR

Available user actions:

  • To mark a PR as WIP, add /wip in a comment. To remove it from the PR comment /wip cancel to the PR.
  • To block merging of a PR, add /hold in a comment. To un-block merging of PR comment /hold cancel.
  • To mark a PR as approved, add /lgtm in a comment. To remove, add /lgtm cancel.
    lgtm label removed on each new commit push.
  • To mark PR as verified comment /verified to the PR, to un-verify comment /verified cancel to the PR.
    verified label removed on each new commit push.
  • To Cherry-pick a merged PR /cherry-pick <target_branch_name> to the PR. If <target_branch_name> is valid,
    and the current PR is merged, a cherry-picked PR would be created and linked to the current PR.
  • To build and push image to quay, add /build-push-pr-image in a comment. This would create an image with tag
    pr-<pr_number> to quay repository. This image tag, however would be deleted on PR merge or close action.
Supported labels

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 6, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds API-key based auth for MaaS gateway tests: new fixtures create plaintext MaaS API keys from OpenShift tokens and provide header dicts; a helper POST function to create API keys is added; tests switch from token-based header construction to the new API-key header fixture and adjust some test markers.

Changes

Cohort / File(s) Summary
Fixtures: API-key creation & headers
tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py
Adds maas_api_key_for_actor fixture that calls MaaS to create a plaintext API key (uses create_api_key) and returns the key string; adds maas_headers_for_actor_api_key fixture that yields a header dict built from that API key.
Utility: create API key
tests/model_serving/model_server/maas_billing/maas_subscription/utils.py
Adds create_api_key(base_url, ocp_user_token, request_session_http, api_key_name, ...) which POSTs {"name": api_key_name} to ${base_url}/v1/api-keys, parses JSON response (with fallback on decode error), returns (response, parsed_body); imports Response.
Tests: header usage & markers
tests/model_serving/model_server/maas_billing/maas_subscription/test_multiple_subscriptions_per_model.py
Replaces token-based header construction with maas_headers_for_actor_api_key in two tests (removed ocp_token_for_actor usage); changes several test markers from sanity to smoke.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Security findings (actionable)

  • Plaintext API key logged and returned from fixtures — sensitive secret exposure. Cite: CWE-532 (Insertion of Sensitive Information into Log File), CWE-522 (Insufficiently Protected Credentials). Action: stop logging raw API keys, do not return plaintext secrets from fixtures; instead expose a scoped auth wrapper or ephemeral token object that avoids printing/storage of the secret.
  • Fixtures expose API keys in test scope (in-memory return) — increases risk of accidental leak in test outputs or CI logs. Action: store secrets in a secure secrets manager or use short-lived tokens; ensure test runners redact secrets from logs and CI artifacts.
  • Response parsing swallows JSON decode errors and continues with empty dict — may mask API failures and lead to using empty or malformed auth values. Action: raise or fail the fixture/test on non-2xx responses or JSON decode errors so tests do not proceed with invalid credentials.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: updating MaaS subscription tests to use new API key-based authentication flow.
Description check ✅ Passed The description includes required sections with substantive content covering Summary, Related Issues, and testing status; however, Related Issues section is empty and GitHub issue/JIRA links are missing.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • 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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
tests/model_serving/model_server/maas_billing/maas_subscription/test_multiple_subscriptions_per_model.py (1)

102-102: Remove commented-out dead code.

-        # ocp_token_for_actor: str,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@tests/model_serving/model_server/maas_billing/maas_subscription/test_multiple_subscriptions_per_model.py`
at line 102, Remove the dead commented-out parameter line "ocp_token_for_actor:
str," from the test file (found in
tests/model_serving/model_server/maas_billing/maas_subscription/test_multiple_subscriptions_per_model.py)
— locate the commented line near the test function(s) that reference multiple
subscriptions and simply delete the commented code to clean up the test; no
behavior changes are needed.
tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py (1)

1-1: Remove or clarify vague # temporary comment.

This comment provides no context. Either remove it or explain what is temporary and why.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py`
at line 1, The lone vague comment "# temporary" in conftest.py should be removed
or replaced with a clear explanatory TODO: either delete it if nothing is
temporary, or replace it with a descriptive comment explaining what is
temporary, why, expected lifespan, and next action (e.g., "TODO: temporary stub
for X until Y is implemented — remove after PR `#123`; owner: `@username`; created:
YYYY-MM-DD"). Ensure the updated comment appears near the related test/setup
code in conftest.py so future readers understand context.
tests/model_serving/model_server/maas_billing/maas_subscription/utils.py (1)

210-214: Use LOGGER.exception to preserve traceback on JSON decode failure.

LOGGER.error discards the exception context. Switch to LOGGER.exception so the traceback is logged, aiding debugging when the API returns malformed responses.

Proposed fix
     try:
         parsed_body: dict[str, Any] = json.loads(response.text)
     except json.JSONDecodeError:
-        LOGGER.error(f"Unable to parse API key response: {response.text}")
+        LOGGER.exception(f"Unable to parse API key response: {response.text}")
         parsed_body = {}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/model_serving/model_server/maas_billing/maas_subscription/utils.py`
around lines 210 - 214, The JSON decode failure handler in the try/except around
json.loads(response.text) currently calls LOGGER.error and loses exception
context; change LOGGER.error(f"Unable to parse API key response:
{response.text}") to LOGGER.exception("Unable to parse API key response",
exc_info=True) or simply LOGGER.exception(f"Unable to parse API key response:
{response.text}") in the except block so the traceback is preserved when parsing
in this function (the block that sets parsed_body: dict[str, Any] =
json.loads(response.text)); leave parsed_body = {} behavior intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@tests/model_serving/model_server/maas_billing/maas_subscription/test_multiple_subscriptions_per_model.py`:
- Line 145: Replace the `@pytest.mark.smoke` marker used on the MaaS subscription
access-control tests in this test class with `@pytest.mark.sanity` because these
tests validate specific subscription behavior (service account authorization)
rather than core build-stability functionality; locate the pytest decorators in
the test class and change each `@pytest.mark.smoke` to `@pytest.mark.sanity` for the
tests that verify unauthorized subscription usage (and the other similar tests
in the same class).

---

Nitpick comments:
In `@tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py`:
- Line 1: The lone vague comment "# temporary" in conftest.py should be removed
or replaced with a clear explanatory TODO: either delete it if nothing is
temporary, or replace it with a descriptive comment explaining what is
temporary, why, expected lifespan, and next action (e.g., "TODO: temporary stub
for X until Y is implemented — remove after PR `#123`; owner: `@username`; created:
YYYY-MM-DD"). Ensure the updated comment appears near the related test/setup
code in conftest.py so future readers understand context.

In
`@tests/model_serving/model_server/maas_billing/maas_subscription/test_multiple_subscriptions_per_model.py`:
- Line 102: Remove the dead commented-out parameter line "ocp_token_for_actor:
str," from the test file (found in
tests/model_serving/model_server/maas_billing/maas_subscription/test_multiple_subscriptions_per_model.py)
— locate the commented line near the test function(s) that reference multiple
subscriptions and simply delete the commented code to clean up the test; no
behavior changes are needed.

In `@tests/model_serving/model_server/maas_billing/maas_subscription/utils.py`:
- Around line 210-214: The JSON decode failure handler in the try/except around
json.loads(response.text) currently calls LOGGER.error and loses exception
context; change LOGGER.error(f"Unable to parse API key response:
{response.text}") to LOGGER.exception("Unable to parse API key response",
exc_info=True) or simply LOGGER.exception(f"Unable to parse API key response:
{response.text}") in the except block so the traceback is preserved when parsing
in this function (the block that sets parsed_body: dict[str, Any] =
json.loads(response.text)); leave parsed_body = {} behavior intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 19640a29-bc47-4c0a-a5b8-88c3bfee54ff

📥 Commits

Reviewing files that changed from the base of the PR and between 24e100f and ad38dcc.

📒 Files selected for processing (3)
  • tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py
  • tests/model_serving/model_server/maas_billing/maas_subscription/test_multiple_subscriptions_per_model.py
  • tests/model_serving/model_server/maas_billing/maas_subscription/utils.py

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

Caution

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

⚠️ Outside diff range comments (1)
tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py (1)

1-15: ⚠️ Potential issue | 🔴 Critical

Critical: Import Any and Generator from typing before pytest imports this module.

Annotations at lines 35, 63, 89, 111, 134, 159, 181, 210, and 315 use Generator and Any from the typing module, but neither is imported. Python evaluates type annotations during module import, causing test collection to fail with NameError: name 'Generator' is not defined.

Fix
+from typing import Any, Generator
+
 import pytest
 import requests
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py`
around lines 1 - 15, The module-level type annotations use Generator and Any but
those names are not imported, causing import-time NameError during pytest
collection; fix by adding an import for them (e.g. from typing import Any,
Generator) at the top of conftest.py before any pytest-related imports or,
alternatively, enable postponed evaluation of annotations (from __future__
import annotations) — ensure the import appears before fixtures/functions that
reference Generator/Any so annotations resolve during module import (look for
the fixture and function annotations in this file where Generator and Any are
used).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py`:
- Around line 284-298: The fixture leaks plaintext credentials by logging
response.text, printing the full response body on assertion failure, and
emitting an 8-char API key prefix; update the code around LOGGER.info, the
assertion that prints body, and the api_key handling so that secrets are never
logged: stop using response.text or body in logs or assertion messages, validate
api_key with isinstance(api_key, str) and api_key.startswith("sk-") but on
failure only include non-sensitive metadata (e.g., response.status_code and safe
indicators like body present/absent or key length), and change the final
LOGGER.info to redact the key (e.g., log only "created api-key
name={api_key_name} key_redacted" or a fixed-length masked string) while keeping
the variable names api_key, body, response, LOGGER, and api_key_name for
locating the changes.

---

Outside diff comments:
In `@tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py`:
- Around line 1-15: The module-level type annotations use Generator and Any but
those names are not imported, causing import-time NameError during pytest
collection; fix by adding an import for them (e.g. from typing import Any,
Generator) at the top of conftest.py before any pytest-related imports or,
alternatively, enable postponed evaluation of annotations (from __future__
import annotations) — ensure the import appears before fixtures/functions that
reference Generator/Any so annotations resolve during module import (look for
the fixture and function annotations in this file where Generator and Any are
used).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: aaf2117f-b1a4-4e8c-8ef4-43a1f8633e63

📥 Commits

Reviewing files that changed from the base of the PR and between ad38dcc and 87af29b.

📒 Files selected for processing (1)
  • tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py

Comment thread tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py`:
- Around line 279-285: The create_api_key() function currently logs the full
response.text (including plaintext API keys) on success and error; update the
logging in create_api_key() to avoid leaking credentials by logging only the
HTTP status code and a redacted body—parse response.json() (if JSON), replace
the api key field (e.g., keys named "key" or values matching /^sk-/) with a
fixed token like "<REDACTED>", and use LOGGER.info/LOGGER.error to output the
status and the redacted JSON instead of response.text; apply the same redaction
logic for both the success path and the error path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: f2b83775-631a-47f6-9309-802934bb36cd

📥 Commits

Reviewing files that changed from the base of the PR and between 87af29b and e9de670.

📒 Files selected for processing (1)
  • tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py

Comment thread tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py Outdated
threcc
threcc previously approved these changes Mar 6, 2026
@threcc threcc enabled auto-merge (squash) March 6, 2026 18:22
Comment thread tests/model_serving/model_server/maas_billing/maas_subscription/utils.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/maas_subscription/utils.py Outdated
auto-merge was automatically disabled March 9, 2026 15:40

Head branch was pushed to by a user without write access

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 (1)
tests/model_serving/model_server/maas_billing/maas_subscription/utils.py (1)

201-205: Use LOGGER.exception() to capture traceback in error handler.

When catching an exception, exception() automatically includes the stack trace which aids debugging JSON parse failures.

Proposed fix
     try:
         parsed_body: dict[str, Any] = json.loads(response.text)
     except json.JSONDecodeError:
-        LOGGER.error(f"Unable to parse API key response: {response.text}")
+        LOGGER.exception("Unable to parse API key response")
         parsed_body = {}

Note: Also avoid logging response.text here as it may contain sensitive data on partial success scenarios.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/model_serving/model_server/maas_billing/maas_subscription/utils.py`
around lines 201 - 205, The JSON parse error handler in utils.py uses
LOGGER.error and logs response.text; change this to call
LOGGER.exception("Unable to parse API key response") so the traceback is
captured, and remove logging of response.text to avoid exposing sensitive data;
keep the except block setting parsed_body = {} and reference the
json.loads(response.text) call and the except json.JSONDecodeError handler to
locate the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/model_serving/model_server/maas_billing/maas_subscription/utils.py`:
- Line 199: The current LOGGER.info in create_api_key logs the full
response.text (which contains the plaintext API key) exposing credentials;
change the logging in the create_api_key function to never include response.text
or any raw credential, instead log only non-sensitive metadata (e.g.,
api_keys_url and response.status_code) and if you must surface a key, log a
masked form (e.g., show only last 4 chars) or an existence boolean; reference
LOGGER, create_api_key, api_keys_url and response when making this change.

---

Nitpick comments:
In `@tests/model_serving/model_server/maas_billing/maas_subscription/utils.py`:
- Around line 201-205: The JSON parse error handler in utils.py uses
LOGGER.error and logs response.text; change this to call
LOGGER.exception("Unable to parse API key response") so the traceback is
captured, and remove logging of response.text to avoid exposing sensitive data;
keep the except block setting parsed_body = {} and reference the
json.loads(response.text) call and the except json.JSONDecodeError handler to
locate the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 87383e10-b3a3-4657-92c0-9174efdb995a

📥 Commits

Reviewing files that changed from the base of the PR and between e9de670 and a9e3f3e.

📒 Files selected for processing (2)
  • tests/model_serving/model_server/maas_billing/maas_subscription/test_multiple_subscriptions_per_model.py
  • tests/model_serving/model_server/maas_billing/maas_subscription/utils.py

Comment thread tests/model_serving/model_server/maas_billing/maas_subscription/utils.py Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/model_serving/model_server/maas_billing/maas_subscription/utils.py`:
- Around line 189-207: The current code swallows non-JSON or error responses and
returns (response, {}) which lets fixtures proceed without a valid API key;
update the post-call handling (around the POST to api_keys_url and the
parsed_body/result return) to: check response.status_code for success (e.g. 2xx)
and attempt to parse JSON, and if parsing fails or parsed_body does not contain
a usable parsed_body["key"], log an error with response.status_code and
response.text and raise an exception (or return an explicit failure) instead of
returning (response, {}); reference the variables and logger in this block
(request_session_http.post, api_keys_url, ocp_user_token, api_key_name, LOGGER,
parsed_body, response) so callers fail fast when key creation fails.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 65c01054-29b9-4168-acfa-de704f299542

📥 Commits

Reviewing files that changed from the base of the PR and between a9e3f3e and aa345d0.

📒 Files selected for processing (1)
  • tests/model_serving/model_server/maas_billing/maas_subscription/utils.py

Comment thread tests/model_serving/model_server/maas_billing/maas_subscription/conftest.py Outdated
@github-actions github-actions bot added size/m and removed size/l labels Mar 9, 2026
@SB159 SB159 requested a review from dbasunag March 9, 2026 17:08
@threcc threcc merged commit 4cd216a into opendatahub-io:main Mar 9, 2026
8 checks passed
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 9, 2026

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