Skip to content

tests(maas-billing): add user creation for tests#843

Merged
mwaykole merged 12 commits intoopendatahub-io:mainfrom
SB159:feature/user-creation-tests
Nov 26, 2025
Merged

tests(maas-billing): add user creation for tests#843
mwaykole merged 12 commits intoopendatahub-io:mainfrom
SB159:feature/user-creation-tests

Conversation

@SB159
Copy link
Copy Markdown
Contributor

@SB159 SB159 commented Nov 13, 2025

Description:

This PR adds temporary FREE and PREMIUM htpasswd users, groups, and the required OAuth update.
These will be used for the current end-to-end RBAC tests and future rate-limit, quota, and other MaaS Billing tests.

Changes:

  • Create temporary FREE and PREMIUM htpasswd users and groups.
  • Add a combined MaaS htpasswd IDP to OAuth.
  • Add an end-to-end test (TestMaasRBACE2E) covering admin, free, and premium users.
  • Validate:
    • token minting
    • /v1/models
    • /v1/chat/completions
  • Clean up temporary users and groups, and restore OAuth after tests.

Summary by CodeRabbit

  • Tests

    • Added end-to-end RBAC tests for admin/free/premium actors covering token issuance, model listing, and chat completions; verifies responses and flows.
    • Added fixtures and helpers for per-user credentials, htpasswd/OAuth lifecycle, per-actor tokens/headers, session flows, and group-based access provisioning.
  • Chores

    • Centralized OAuth deployment wait logic into shared utilities and adjusted original-user handling across test suites.

✏️ Tip: You can customize this high-level summary in your review settings.

@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

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

Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/utils.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/utils.py Outdated
@SB159 SB159 force-pushed the feature/user-creation-tests branch from 4aa7802 to 50c9d40 Compare November 13, 2025 20:35
@SB159 SB159 requested a review from mwaykole November 13, 2025 20:38
@SB159 SB159 marked this pull request as ready for review November 14, 2025 14:13
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 14, 2025

📝 Walkthrough

Walkthrough

Adds MaaS RBAC test scaffolding and e2e tests: new fixtures, constants, OAuth/htpasswd IDP lifecycle, per-user sessions and groups, token minting and header helpers, utilities to query /v1/models, and tests exercising /v1/models and /v1/chat/completions for admin/free/premium actors.

Changes

Cohort / File(s) Summary
MaaS RBAC conftest & fixtures
tests/model_serving/model_server/maas_billing/conftest.py
Adds MAAS_FREE_GROUP, MAAS_PREMIUM_GROUP and many pytest fixtures: maas_api_server_url, maas_user_credentials_both, maas_htpasswd_files, maas_htpasswd_oauth_idp, maas_rbac_idp_env, maas_free_user_session, maas_premium_user_session, maas_free_group, maas_premium_group, ocp_token_for_actor, maas_token_for_actor, maas_headers_for_actor, maas_models_response_for_actor. Refactors token logging to f-strings and centralizes model/header flows to support per-actor sessions.
MaaS RBAC end-to-end tests
tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.py
Adds TestMaasRBACE2E with tests test_mint_token_for_actors, test_models_visible_for_actors, test_chat_completions_for_actors. Introduces module constants MODELS_INFO, CHAT_COMPLETIONS and LOGGER. Tests acquire MaaS tokens, call /v1/models, and call /v1/chat/completions per actor.
MaaS OpenShift helpers
tests/model_serving/model_server/maas_billing/utils.py
Adds LOGGER, MODELS_INFO alias, create_maas_group context manager, build_maas_headers, and get_maas_models_response; updates imports (DynamicClient, Group, get_logger, RestHeader, OpenAIEnpoints) and typing to include Generator.
Global original_user fixture
tests/conftest.py
Adds session-scoped fixture original_user() that runs oc whoami, logs and returns the original OpenShift username.
Model registry conftest import change
tests/model_registry/conftest.py
Removes local original_user fixture and changes import of wait_for_oauth_openshift_deployment to come from utilities.general.
RBAC utils cleanup
tests/model_registry/rbac/utils.py
Removes wait_for_oauth_openshift_deployment() and related waiting/imports.
Deployment wait utility
utilities/general.py
Adds wait_for_oauth_openshift_deployment() to poll the oauth-openshift Deployment rollout conditions with logging and timeout.
Metadata / manifests (notes)
manifest_file, requirements.txt, pyproject.toml
References in summary to manifest/metadata updates; no specific file diffs provided here.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Check lifecycle and teardown of the OAuth/htpasswd IDP fixtures for race conditions and correct restoration.
  • Verify fixture scopes and ordering (session vs. function) to prevent user/token leakage.
  • Review token minting and oc token switching logic for correctness and privilege isolation.
  • Inspect polling/timeouts and condition checks in wait_for_oauth_openshift_deployment().

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 69.70% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'tests(maas-billing): add user creation for tests' accurately describes the main objectives of the PR, which focus on creating temporary users and groups for MaaS RBAC testing.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


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

10-11: Solid E2E flow; just a couple of small polish opportunities

The overall actor-parametrized flow (mint token → /v1/models/v1/chat/completions) looks good and gives useful debug context via logs and sliced response bodies.

Two minor nits:

  • CHAT_COMPLETIONS (Line 11) is unused in this module; consider dropping it to avoid linter noise.
  • For easier triage when one actor fails, consider including the actor kind in at least one assertion message or log (e.g., extend the mint or models failure message) so it’s obvious which role broke without digging into parametrization.

Also applies to: 31-91

tests/model_serving/model_server/maas_billing/utils.py (2)

142-179: Replace EN DASH in comment to satisfy Ruff and avoid odd characters

Ruff is flagging the comment on Line 162 due to the EN DASH character:

# Quick check first – if it's already Available=True

Switch that to a plain hyphen to keep the file ASCII-clean and silence RUF003:

# Quick check first - if it's already Available=True

181-203: Guard against empty users input in htpasswd helper

make_bcrypt_htpasswd_file_with_users assumes users is non-empty and immediately does users[0]. If it’s ever called with an empty list, it will raise IndexError in a non-obvious way.

Consider an explicit guard to fail fast with a clearer error:

 def make_bcrypt_htpasswd_file_with_users(users: list[tuple[str, str]]) -> Path:
@@
-    # First user: create (-c)
-    first_user, first_pass = users[0]
+    if not users:
+        raise ValueError("At least one (username, password) pair is required")
+
+    # First user: create (-c)
+    first_user, first_pass = users[0]
tests/model_serving/model_server/maas_billing/conftest.py (4)

109-176: API URL, original-user discovery, credentials, and htpasswd secret lifecycle look good

The scaffolding to discover the API server URL, capture the original user, generate randomized FREE/PREMIUM credentials, and manage the htpasswd secret lifecycle is clear and well-contained. Deleting any existing secret first and cleaning up both the Secret and temp file in finally is exactly what we want for test hygiene.

Only a minor optional tweak: you might want to pass check=True to the oc delete secret calls as well, to surface unexpected delete failures instead of silently continuing (the --ignore-not-found=true flag already protects the common “not found” case).


178-225: Consider BYOIDC gating and silencing ARG001 lint in maas_updated_oauth_config

The OAuth patch/restore flow with ResourceEditor and wait_for_oauth_openshift_deployment() is solid and the “drop prior maas-* IDPs” step is a nice safety net.

A few smaller points:

  • On BYOIDC clusters, this fixture will still patch OAuth even though the user-session fixtures later call pytest.skip. If you intend to fully avoid htpasswd-IDP tinkering on BYOIDC, consider injecting is_byoidc here and skipping early before any patching.
  • admin_client and maas_created_htpasswd_secret_both are intentionally unused but required to enforce fixture ordering. To keep Ruff happy (ARG001), you can either rename them to _admin_client / _maas_created_htpasswd_secret_both or add # noqa: ARG001 after their names.
  • Purely stylistic: updated_providers = [combined_idp, *current_idps] is slightly cleaner than list concatenation and would address RUF005 if you care about that hint.

227-303: User-session fixtures are sound; a couple of flakiness and lint nits

The FREE and PREMIUM UserTestSession fixtures are well-structured: they skip on BYOIDC, ensure the IDP is patched first, call wait_for_user_creation, restore the original login, and then clean up the user session in finally. Logging is informative and symmetric between free/premium.

Two things to consider:

  • wait_for_user_creation performs a single login attempt and raises on failure; depending on cluster behavior, that can be a bit brittle for newly created users. If you see flakiness around user readiness, you might want to introduce a small retry loop or reuse login_with_retry semantics here.
  • maas_updated_oauth_config is included purely to enforce fixture ordering and is never referenced in the body, which triggers ARG001. Renaming the parameter to _maas_updated_oauth_config (and likewise _maas_updated_oauth_config in both fixtures) is a simple way to keep the dependency while silencing the lint.

339-375: Actor token fixture wiring looks correct; TRY003 suggestion is optional

ocp_token_for_actor correctly:

  • Uses parametrization via request.param with a sane default of "admin",
  • Short-circuits to the existing admin client/token,
  • Switches logins for FREE/PREMIUM actors using login_with_retry,
  • And reliably restores the original user afterwards.

The ValueError(f"Unknown actor kind: {actor!r}") is fine in a test context; the TRY003 suggestion to move long messages into exception classes feels overkill here, so I’d keep it as-is unless your lint config enforces it strictly.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 150202b and 50c9d40.

📒 Files selected for processing (3)
  • tests/model_serving/model_server/maas_billing/conftest.py (2 hunks)
  • tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.py (1 hunks)
  • tests/model_serving/model_server/maas_billing/utils.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
tests/model_serving/model_server/maas_billing/utils.py (3)
utilities/llmd_utils.py (1)
  • get_llm_inference_url (344-390)
utilities/infra.py (1)
  • login_with_user_password (447-471)
tests/conftest.py (1)
  • admin_client (76-77)
tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.py (3)
utilities/plugins/constant.py (2)
  • RestHeader (10-11)
  • OpenAIEnpoints (1-7)
tests/model_serving/model_server/maas_billing/utils.py (1)
  • mint_token (81-98)
tests/model_serving/model_server/maas_billing/conftest.py (4)
  • request_session_http (40-45)
  • base_url (66-69)
  • model_url (73-80)
  • ocp_token_for_actor (340-375)
tests/model_serving/model_server/maas_billing/conftest.py (5)
utilities/general.py (1)
  • generate_random_name (319-344)
utilities/user_utils.py (3)
  • UserTestSession (21-43)
  • wait_for_user_creation (76-93)
  • cleanup (39-43)
utilities/infra.py (2)
  • login_with_user_password (447-471)
  • get_openshift_token (603-617)
tests/model_serving/model_server/maas_billing/utils.py (4)
  • create_maas_group (124-139)
  • wait_for_oauth_openshift_deployment (142-178)
  • make_bcrypt_htpasswd_file_with_users (181-202)
  • login_with_retry (205-241)
tests/conftest.py (2)
  • admin_client (76-77)
  • is_byoidc (386-390)
🪛 Ruff (0.14.4)
tests/model_serving/model_server/maas_billing/utils.py

162-162: Comment contains ambiguous (EN DASH). Did you mean - (HYPHEN-MINUS)?

(RUF003)


222-222: Consider moving this statement to an else block

(TRY300)

tests/model_serving/model_server/maas_billing/conftest.py

180-180: Unused function argument: admin_client

(ARG001)


182-182: Unused function argument: maas_created_htpasswd_secret_both

(ARG001)


202-202: Consider [combined_idp, *current_idps] instead of concatenation

Replace with [combined_idp, *current_idps]

(RUF005)


233-233: Unused function argument: maas_updated_oauth_config

(ARG001)


272-272: Unused function argument: maas_updated_oauth_config

(ARG001)


366-366: Avoid specifying long messages outside the exception class

(TRY003)

🔇 Additional comments (1)
tests/model_serving/model_server/maas_billing/conftest.py (1)

305-337: Group fixtures using create_maas_group look clean

The maas_free_group and maas_premium_group fixtures nicely wrap create_maas_group, ensuring groups are created with the right users and cleaned up automatically at session end. Logging includes both group name and user, which will help during debugging.

No changes needed here from my side.

Comment thread tests/model_serving/model_server/maas_billing/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: 3

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 50c9d40 and 8e1dc2c.

📒 Files selected for processing (1)
  • tests/model_serving/model_server/maas_billing/utils.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/model_serving/model_server/maas_billing/utils.py (3)
utilities/llmd_utils.py (1)
  • get_llm_inference_url (344-390)
utilities/infra.py (1)
  • login_with_user_password (447-471)
tests/conftest.py (1)
  • admin_client (76-77)
🪛 Ruff (0.14.4)
tests/model_serving/model_server/maas_billing/utils.py

162-162: Comment contains ambiguous (EN DASH). Did you mean - (HYPHEN-MINUS)?

(RUF003)


229-229: Consider moving this statement to an else block

(TRY300)

🔇 Additional comments (4)
tests/model_serving/model_server/maas_billing/utils.py (4)

1-24: LGTM!

The new imports are appropriate and necessary for the OpenShift RBAC testing utilities introduced in this file.


123-140: LGTM!

The context manager correctly creates and yields an OpenShift Group, ensuring cleanup on exit. The use of wait_for_resource=True ensures the group is fully created before the test proceeds.


142-179: Well-structured OAuth deployment wait logic.

The function appropriately handles the common case (already Available) before entering a wait loop, and the 5-minute timeout is reasonable for OAuth rollouts.


221-229: Good fix: boolean return value is now properly checked.

The implementation correctly captures the boolean return from login_with_user_password and treats False as a failure, addressing the previous review comment.

Based on past review comments

Comment thread tests/model_serving/model_server/maas_billing/utils.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/utils.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/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

♻️ Duplicate comments (1)
tests/model_serving/model_server/maas_billing/utils.py (1)

162-162: Fix EN DASH character in comment.

The comment contains an EN DASH (–) instead of a HYPHEN-MINUS (-), which can cause encoding issues.

Apply this diff:

-    # Quick check first – if it's already Available=True
+    # Quick check first - if it's already Available=True

Based on coding guidelines

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e1dc2c and bf68a76.

📒 Files selected for processing (1)
  • tests/model_serving/model_server/maas_billing/utils.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/model_serving/model_server/maas_billing/utils.py (2)
utilities/infra.py (1)
  • login_with_user_password (447-471)
tests/conftest.py (1)
  • admin_client (76-77)
🪛 Ruff (0.14.4)
tests/model_serving/model_server/maas_billing/utils.py

162-162: Comment contains ambiguous (EN DASH). Did you mean - (HYPHEN-MINUS)?

(RUF003)


187-187: Avoid specifying long messages outside the exception class

(TRY003)


229-229: Consider moving this statement to an else block

(TRY300)


230-230: Do not catch blind exception: Exception

(BLE001)

🔇 Additional comments (3)
tests/model_serving/model_server/maas_billing/utils.py (3)

1-24: LGTM!

The imports are well-organized and necessary for the new MaaS RBAC utilities. Logger initialization follows best practices.


123-139: LGTM!

The context manager pattern is correctly implemented. Automatic cleanup on exit and logging provide good operational visibility for test scaffolding.


181-205: LGTM!

The function correctly handles multiple users with proper bcrypt hashing. Empty list validation prevents runtime errors, and the docstring appropriately documents the caller's cleanup responsibility. The use of shlex.split ensures command injection safety.

Comment thread tests/model_serving/model_server/maas_billing/utils.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
@mwaykole
Copy link
Copy Markdown
Member

mwaykole commented Nov 18, 2025

\lgtm

rhods-ci-bot
rhods-ci-bot previously approved these changes Nov 18, 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: 0

🧹 Nitpick comments (4)
tests/model_serving/model_server/maas_billing/conftest.py (4)

187-187: Consider iterable unpacking for better readability.

Ruff suggests using iterable unpacking instead of list concatenation.

Apply this diff:

-        updated_identity_providers = existing_identity_providers + [maas_identity_provider]
+        updated_identity_providers = [*existing_identity_providers, maas_identity_provider]

252-253: Redundant BYOIDC check (optional simplification).

The is_byoidc check here is now redundant since maas_rbac_idp_env (a dependency) already skips when is_byoidc is True. Pytest will never execute this fixture on BYOIDC clusters. However, this defensive check is harmless and may improve code clarity.


294-295: Redundant BYOIDC check (optional simplification).

Same as maas_free_user_session: this is_byoidc check is redundant since maas_rbac_idp_env already handles it. The check is harmless and may be kept for clarity.


389-389: Optional: Extract exception message to constant (nitpick).

Ruff suggests avoiding inline long messages in exceptions for better maintainability, though this is a very minor style issue.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74e24b8 and 32bc7cf.

📒 Files selected for processing (1)
  • tests/model_serving/model_server/maas_billing/conftest.py (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/model_serving/model_server/maas_billing/conftest.py (6)
utilities/plugins/constant.py (2)
  • RestHeader (10-11)
  • OpenAIEnpoints (1-7)
utilities/general.py (2)
  • generate_random_name (320-345)
  • wait_for_oauth_openshift_deployment (473-491)
utilities/infra.py (2)
  • login_with_user_password (449-473)
  • get_openshift_token (605-619)
tests/model_serving/model_server/maas_billing/utils.py (1)
  • detect_scheme_via_llmisvc (53-66)
tests/conftest.py (3)
  • admin_client (78-79)
  • is_byoidc (387-391)
  • original_user (788-791)
tests/model_registry/conftest.py (1)
  • api_server_url (537-542)
🪛 Gitleaks (8.29.0)
tests/model_serving/model_server/maas_billing/conftest.py

[high] 163-163: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 Ruff (0.14.5)
tests/model_serving/model_server/maas_billing/conftest.py

187-187: Consider iterable unpacking instead of concatenation

Replace with iterable unpacking

(RUF005)


389-389: Avoid specifying long messages outside the exception class

(TRY003)

🔇 Additional comments (13)
tests/model_serving/model_server/maas_billing/conftest.py (13)

3-18: LGTM!

The imports are well-organized and all are used by the new MaaS RBAC fixtures.


34-35: LGTM!

Good practice to define group names as constants for consistency across fixtures.


108-114: LGTM!

Standard pattern for obtaining the cluster API server URL via the Infrastructure resource.


117-132: LGTM!

Good use of randomized credentials to prevent conflicts across test runs, with clear naming conventions.


148-149: LGTM!

The is_byoidc check at the fixture entry point correctly prevents any OAuth or Secret modifications on OIDC clusters, addressing the previous review feedback.


195-226: LGTM!

Excellent use of context managers (Secret and ResourceEditor) to ensure proper resource lifecycle management. The teardown logic gracefully handles timeout scenarios and includes comprehensive verification that the temporary IDP is removed.


262-284: LGTM!

Proper user creation flow with wait verification, session management, and cleanup in the finally block.


304-326: LGTM!

Consistent implementation with maas_free_user_session, including proper wait verification and cleanup.


329-342: LGTM!

Clean use of the create_maas_group context manager for proper group lifecycle management.


344-357: LGTM!

Consistent implementation with maas_free_group, properly managing the premium-tier group lifecycle.


359-409: LGTM!

The actor-switching logic is correct, properly handling admin/free/premium users with appropriate login/token retrieval and guaranteed restoration of the original user context in the finally block.


411-436: LGTM!

Straightforward MaaS token minting with proper error checking and logging.


168-172: The htpasswd concatenation logic is correct; no changes needed.

Based on verification:

  1. Apache htpasswd format: The standard htpasswd command outputs entries as username:hashedpassword without trailing newlines, which matches the assumption in the code.

  2. Concatenation is valid: Combining free_bytes + b"\n" + premium_bytes produces the correct multi-entry htpasswd format when both entries lack trailing newlines.

  3. Verified by downstream usage: The fixture maas_rbac_idp_env feeds this concatenated htpasswd to downstream fixtures (maas_free_user_session, maas_premium_user_session) that authenticate users via wait_for_user_creation(). If concatenation was malformed, these would fail. No evidence of such failures exists.

  4. No fragility observed: The implementation correctly handles the standard htpasswd output format.

Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/conftest.py
Comment thread tests/model_serving/model_server/maas_billing/conftest.py
Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/conftest.py
Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.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: 0

🧹 Nitpick comments (5)
tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.py (2)

31-37: Use ocp_token_for_actor to satisfy Ruff and assert OCP token shape

ocp_token_for_actor is currently unused, triggering Ruff ARG002, even though the fixture is important. You can make the intent explicit and keep lint clean by asserting it is a non-empty string:

     def test_mint_token_for_actors(
         self,
         ocp_token_for_actor,
         maas_token_for_actor: str,
     ) -> None:
-        LOGGER.info(f"MaaS RBAC: using already minted MaaS token length={len(maas_token_for_actor)}")
+        assert isinstance(ocp_token_for_actor, str) and ocp_token_for_actor, "empty OCP token for actor"
+        LOGGER.info(f"MaaS RBAC: using already minted MaaS token length={len(maas_token_for_actor)}")

This keeps the fixture meaningful at the test level and fixes the ARG002 warning.


67-80: Confirm payload format for MaaS /v1/chat/completionsprompt vs messages

The test is sending payload = {"model": model_id, "prompt": "Hello", "max_tokens": 16} to endpoint /v1/chat/completions.

OpenAI-compatible /v1/chat/completions endpoints require messages (an array of message objects with role and content fields). The payload uses prompt instead, which is the field for completions (non-chat) endpoints.

This same pattern appears in both test_maas_rbac_e2e.py (line 72) and test_maas_endpoints.py (line 40), and the response handling expects standard OpenAI response format (choices[0].message).

Action: Verify whether MaaS has a custom API contract that accepts prompt for chat/completions, or if the payload should be corrected to use messages=[{"role": "user", "content": "Hello"}].

tests/model_serving/model_server/maas_billing/conftest.py (3)

132-166: Adjust maas_htpasswd_files type hints to reflect Path objects

create_htpasswd_file returns a filesystem path that you later call .unlink() on, so the first and third tuple elements are Path-like, not str. Updating the annotation will make this clearer to readers and type-checkers:

-from typing import Generator
+from typing import Generator
+from pathlib import Path
...
-@pytest.fixture(scope="session")
-def maas_htpasswd_files(
-    maas_user_credentials_both: dict[str, str],
-) -> Generator[tuple[str, str, str, str], None, None]:
+@pytest.fixture(scope="session")
+def maas_htpasswd_files(
+    maas_user_credentials_both: dict[str, str],
+) -> Generator[tuple[Path, str, Path, str], None, None]:

The rest of the implementation (including .unlink(missing_ok=True)) then matches the annotation.


249-255: Make side-effect dependency on maas_htpasswd_oauth_idp explicit

maas_rbac_idp_env intentionally doesn’t use maas_htpasswd_oauth_idp directly, relying on its side effects (Secret + OAuth IDP lifecycle). This shows up as an unused-arg warning.

You can make that intent explicit and silence ARG001 by binding it to _:

 @pytest.fixture(scope="session")
 def maas_rbac_idp_env(
     maas_htpasswd_oauth_idp,
     maas_user_credentials_both: dict[str, str],
 ):
-
-    return maas_user_credentials_both
+    # Ensure MaaS htpasswd Secret and OAuth IDP are set up before using credentials
+    _ = maas_htpasswd_oauth_idp
+    return maas_user_credentials_both

423-448: Align maas_token_for_actor docstring with its actual scope/behavior

The docstring says:

“Mint a MaaS token once per actor … and reuse it across all tests in the class instance.”

But the fixture has default function scope and depends on ocp_token_for_actor (also function-scoped), so a fresh token is minted per test per actor.

Either:

  • Update the docstring to something like “Mint a MaaS token for the current actor per test”, or
  • If you really want per-actor reuse, you’d need to rework the fixture graph to use a broader scope (e.g., class/session) consistently for both ocp_token_for_actor and maas_token_for_actor.

Given the complexity of widening scopes around login state, just fixing the docstring is likely the safest, low-risk change.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32bc7cf and bdf574b.

📒 Files selected for processing (3)
  • tests/model_serving/model_server/maas_billing/conftest.py (3 hunks)
  • tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.py (1 hunks)
  • tests/model_serving/model_server/maas_billing/utils.py (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/model_serving/model_server/maas_billing/utils.py (3)
utilities/plugins/constant.py (2)
  • RestHeader (10-11)
  • OpenAIEnpoints (1-7)
tests/conftest.py (1)
  • admin_client (78-79)
tests/model_serving/model_server/maas_billing/conftest.py (1)
  • base_url (64-67)
🪛 Gitleaks (8.29.0)
tests/model_serving/model_server/maas_billing/conftest.py

[high] 151-151: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 Ruff (0.14.5)
tests/model_serving/model_server/maas_billing/conftest.py

214-214: Consider [*existing_idps, maas_idp] instead of concatenation

Replace with [*existing_idps, maas_idp]

(RUF005)


251-251: Unused function argument: maas_htpasswd_oauth_idp

(ARG001)


401-401: Avoid specifying long messages outside the exception class

(TRY003)

tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.py

33-33: Unused method argument: ocp_token_for_actor

(ARG002)

🔇 Additional comments (1)
tests/model_serving/model_server/maas_billing/utils.py (1)

118-154: New MaaS helpers look correct and improve reuse

create_maas_group, build_maas_headers, and get_maas_models_response encapsulate common MaaS RBAC plumbing cleanly (group lifecycle, standard headers, /v1/models calls) and are used consistently from the fixtures. No changes needed here.

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

🧹 Nitpick comments (7)
tests/model_serving/model_server/maas_billing/conftest.py (7)

132-165: Type hint mismatch for file paths.

The return type annotation says tuple[str, str, str, str], but create_htpasswd_file likely returns Path objects (given the .unlink() call on lines 164-165). Consider updating the type hint:

 @pytest.fixture(scope="session")
 def maas_htpasswd_files(
     maas_user_credentials_both: dict[str, str],
-) -> Generator[tuple[str, str, str, str], None, None]:
+) -> Generator[tuple[Path, str, Path, str], None, None]:

And add from pathlib import Path to the imports.


214-214: Prefer iterable unpacking over list concatenation.

Per static analysis (RUF005), using iterable unpacking is more idiomatic Python:

-    updated_idps = existing_idps + [maas_idp]
+    updated_idps = [*existing_idps, maas_idp]

265-266: Redundant is_byoidc check.

This skip is redundant since maas_rbac_idp_env (a transitive dependency via fixture chain) already performs the BYOIDC skip. The code will never reach this point on BYOIDC clusters. Consider removing for clarity:

-    if is_byoidc:
-        pytest.skip("Working on OIDC support for tests that use htpasswd IDP for MaaS")
-    else:
-        username = maas_rbac_idp_env["free_user"]
+    username = maas_rbac_idp_env["free_user"]

Then dedent the remaining code block accordingly.


303-345: Consider consolidating duplicate user session logic.

maas_free_user_session and maas_premium_user_session share ~90% identical code. A parameterized helper function could reduce duplication:

def _create_user_session(
    user_type: str,
    credentials: dict[str, str],
    original_user: str,
    api_server_url: str,
) -> Generator[UserTestSession, None, None]:
    # Shared logic here
    ...

However, keeping them separate may be intentional for clarity in test fixture dependencies.


406-407: Consider a more descriptive exception or accept the inline message.

Static analysis (TRY003) flags the long message outside exception class, but for test code, this inline message is clear and acceptable. If you prefer consistency, you could define a custom exception:

The current implementation is fine for test code - this is a minor style preference.


429-454: Docstring/scope mismatch.

The docstring says "reuse it across all tests in the class instance," but the fixture has no explicit scope (defaults to function), meaning a new token is minted per test. Either:

  1. Add scope="class" if reuse is intended:
-@pytest.fixture
+@pytest.fixture(scope="class")
 def maas_token_for_actor(
  1. Or update the docstring to reflect per-test behavior.

463-474: Consider adding return type hint.

The maas_models_response_for_actor fixture lacks a return type annotation. Consider adding it for clarity:

 @pytest.fixture
 def maas_models_response_for_actor(
     request_session_http: requests.Session,
     base_url: str,
     maas_headers_for_actor: dict,
-):
+) -> requests.Response:
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bdf574b and 12d2f24.

📒 Files selected for processing (1)
  • tests/model_serving/model_server/maas_billing/conftest.py (3 hunks)
🧰 Additional context used
🪛 Gitleaks (8.29.0)
tests/model_serving/model_server/maas_billing/conftest.py

[high] 151-151: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 Ruff (0.14.5)
tests/model_serving/model_server/maas_billing/conftest.py

214-214: Consider [*existing_idps, maas_idp] instead of concatenation

Replace with [*existing_idps, maas_idp]

(RUF005)


251-251: Unused function argument: maas_htpasswd_oauth_idp

(ARG001)


407-407: Avoid specifying long messages outside the exception class

(TRY003)

🔇 Additional comments (8)
tests/model_serving/model_server/maas_billing/conftest.py (8)

1-35: Imports and constants look good.

Module-level constants for group names and OpenAI endpoints are appropriately scoped. The imports are well-organized for the fixture dependencies.


37-43: LGTM - session management is correct.

The fixture properly yields the session and closes it in teardown. Note that verify=False disables SSL verification, which is acceptable for internal test environments.


46-60: Token minting fixture is well-structured.

Good validation of response status and token format. The 30-minute token lifetime is appropriate for test duration.


63-79: URL fixtures are correct.

The URL construction logic is sound. Note the scope difference: base_url is module-scoped while model_url is session-scoped - ensure this is intentional based on test requirements.


81-102: Header and models fixtures are clean.

Good use of utility functions for building headers and fetching models. Assertions provide clear failure messages.


105-130: API server URL and credential fixtures are well-designed.

Good use of randomized suffixes to prevent test collisions. The credential dictionary structure is clear and comprehensive.

Note: The Gitleaks warning on line 151 is a false positive - these are dynamically generated test credentials, not exposed secrets.


249-256: Dependency injection pattern is correct.

The maas_htpasswd_oauth_idp parameter appears unused (ARG001), but this is intentional - it ensures the OAuth IDP is configured before returning credentials. This is a valid pytest pattern for fixture ordering.


348-375: Group fixtures are clean and well-structured.

Good use of context managers for automatic teardown. The logging provides clear traceability.

Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/conftest.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.py Outdated
Comment thread tests/model_serving/model_server/maas_billing/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: 0

🧹 Nitpick comments (6)
tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.py (3)

1-15: MODELS_INFO/CHAT_COMPLETIONS constants are currently unused in this module

Right now this file relies on model_url and other fixtures for URLs, so MODELS_INFO and CHAT_COMPLETIONS defined here are unused. You could either remove them or wire them into future assertions to keep the module free of dead code.


31-37: Remove or underscore the unused ocp_token_for_actor argument

In test_mint_token_for_actors, ocp_token_for_actor is not used directly; the test only logs the already‑minted MaaS token. Since maas_token_for_actor already depends on ocp_token_for_actor, you can safely drop this parameter (or rename it to _ocp_token_for_actor and reference it once) to avoid the Ruff ARG002 warning.

For example:

-    def test_mint_token_for_actors(
-        self,
-        ocp_token_for_actor,
-        maas_token_for_actor: str,
-    ) -> None:
+    def test_mint_token_for_actors(
+        self,
+        maas_token_for_actor: str,
+    ) -> None:

47-83: Chat completions test exercises key happy-path behavior

The flow of reusing the models fixture, taking the first id, POSTing to /v1/chat/completions, and asserting status_code == 200 plus non‑empty choices is clear and matches the intended E2E coverage. If you want stronger guarantees later, you could also validate shape of choices[0] (e.g., presence of message/content), but it’s not required for this PR.

tests/model_serving/model_server/maas_billing/conftest.py (3)

166-237: OAuth/Secret IDP fixture has solid gating and teardown; minor style nit

The maas_htpasswd_oauth_idp fixture cleanly:

  • Skips entirely on BYOIDC clusters.
  • Combines htpasswd entries, creates the Secret, and patches oauth/cluster via ResourceEditor.
  • Waits for oauth-openshift rollout both after patch and after teardown.

That covers the main correctness and cleanup concerns for the temporary MaaS HTPasswd IDP. If you care about Ruff RUF005, you could optionally switch

updated_idps = existing_idps + [maas_idp]

to

updated_idps = [*existing_idps, maas_idp]

but that’s purely stylistic.


239-246: Clarify intentionally unused maas_htpasswd_oauth_idp dependency

maas_rbac_idp_env takes maas_htpasswd_oauth_idp only for its side effects and doesn’t use the value, which is fine, but triggers Ruff ARG001.

You can make that intent explicit and silence the warning by underscoring the parameter:

- def maas_rbac_idp_env(
-    maas_htpasswd_oauth_idp,
-    maas_user_credentials_both: dict[str, str],
-):
+ def maas_rbac_idp_env(
+    _maas_htpasswd_oauth_idp,
+    maas_user_credentials_both: dict[str, str],
+):

Behavior stays the same.


415-441: Align maas_token_for_actor fixture scope with its docstring

The docstring says:

Mint a MaaS token once per actor (admin / free / premium) and reuse it across all tests in the class instance.

But the fixture currently uses the default function scope, so it will mint a new token for each test invocation per actor. To match the documented behavior (and the way minted_token works), consider making it a class‑scope fixture:

-@pytest.fixture
+@pytest.fixture(scope="class")
 def maas_token_for_actor(
     request_session_http: requests.Session,
     base_url: str,
     ocp_token_for_actor: str,
 ) -> str:

That will mint one token per actor per test class, and the existing usages will continue to work unchanged.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 12d2f24 and f236d1f.

📒 Files selected for processing (3)
  • tests/model_serving/model_server/maas_billing/conftest.py (3 hunks)
  • tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.py (1 hunks)
  • tests/model_serving/model_server/maas_billing/utils.py (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
tests/model_serving/model_server/maas_billing/utils.py (2)
utilities/plugins/constant.py (2)
  • RestHeader (10-11)
  • OpenAIEnpoints (1-7)
tests/model_serving/model_server/maas_billing/conftest.py (1)
  • base_url (64-67)
tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.py (2)
utilities/plugins/constant.py (1)
  • OpenAIEnpoints (1-7)
tests/model_serving/model_server/maas_billing/conftest.py (6)
  • ocp_token_for_actor (369-412)
  • maas_token_for_actor (416-440)
  • maas_models_response_for_actor (450-460)
  • request_session_http (38-43)
  • model_url (71-78)
  • maas_headers_for_actor (444-446)
tests/model_serving/model_server/maas_billing/conftest.py (6)
utilities/plugins/constant.py (1)
  • OpenAIEnpoints (1-7)
utilities/general.py (1)
  • generate_random_name (320-345)
utilities/user_utils.py (4)
  • UserTestSession (20-43)
  • wait_for_user_creation (76-94)
  • create_htpasswd_file (46-68)
  • cleanup (39-43)
utilities/infra.py (2)
  • login_with_user_password (449-473)
  • get_openshift_token (605-619)
tests/model_serving/model_server/maas_billing/utils.py (7)
  • detect_scheme_via_llmisvc (55-68)
  • host_from_ingress_domain (22-27)
  • mint_token (76-93)
  • llmis_name (102-115)
  • create_maas_group (119-134)
  • build_maas_headers (137-142)
  • get_maas_models_response (145-162)
tests/conftest.py (3)
  • admin_client (78-79)
  • is_byoidc (387-391)
  • original_user (788-791)
🪛 Gitleaks (8.29.0)
tests/model_serving/model_server/maas_billing/conftest.py

[high] 149-149: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 Ruff (0.14.5)
tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.py

33-33: Unused method argument: ocp_token_for_actor

(ARG002)

tests/model_serving/model_server/maas_billing/conftest.py

212-212: Consider [*existing_idps, maas_idp] instead of concatenation

Replace with [*existing_idps, maas_idp]

(RUF005)


241-241: Unused function argument: maas_htpasswd_oauth_idp

(ARG001)


393-393: Avoid specifying long messages outside the exception class

(TRY003)

🔇 Additional comments (14)
tests/model_serving/model_server/maas_billing/utils.py (3)

12-20: Logging, constants, and maas_auth_headers docstring look consistent

Module‑level LOGGER/MODELS_INFO and the clarified maas_auth_headers docstring are straightforward and match how the rest of the MaaS utilities are structured. No issues here.

Also applies to: 71-73


118-135: create_maas_group context manager is a clean abstraction

Using the Group context manager with wait_for_resource=True and yielding the resource gives you automatic teardown and keeps the fixtures in conftest.py simple. This is a good encapsulation for the RBAC test setup.


137-143: Header builder and /v1/models helper are well-factored

build_maas_headers centralizes the MaaS Authorization + common headers, and get_maas_models_response wraps /v1/models with logging and a strict 200 assert, which is appropriate for tests. This aligns with how the fixtures reuse them and avoids duplicated HTTP logic.

Also applies to: 145-162

tests/model_serving/model_server/maas_billing/test_maas_rbac_e2e.py (2)

17-29: Class-level parametrization and group fixtures are wired correctly

Using class‑level parametrize over ACTORS plus maas_free_group / maas_premium_group fixtures gives you a clear matrix over admin/free/premium behavior with minimal boilerplate in each test. The docstring accurately describes the flows covered.


38-46: /v1/models visibility test is minimal but sufficient

Reusing maas_models_response_for_actor and asserting that data is a non‑empty list keeps this test focused on “can this actor see any models” without duplicating HTTP logic. Looks good as a first‑pass RBAC check.

tests/model_serving/model_server/maas_billing/conftest.py (9)

46-61: Minted token fixture logging change is fine

The updated f-string logging in minted_token keeps behavior the same while improving readability. Status checks and token validation still look correct for reuse across a test class.


81-101: maas_headers and maas_models correctly reuse shared helpers

Switching maas_headers to build_maas_headers and maas_models to get_maas_models_response removes duplicated HTTP/header logic and centralizes the /v1/models status check. The additional models non‑empty assert in maas_models is appropriate for tests.


103-127: API server URL + randomized MaaS user/IDP naming look good

maas_api_server_url using Infrastructure(..., name="cluster") and status.apiServerURL is a reasonable way to derive the login URL. The randomized usernames/passwords/IDP/Secret in maas_user_credentials_both via generate_random_name() should avoid collisions across runs while still being readable.


130-164: htpasswd temp-file lifecycle is handled correctly

maas_htpasswd_files creates per-user htpasswd files for FREE and PREMIUM users and ensures they are unlinked in the finally block. Returning both paths and base64 contents gives flexibility to fixtures that either need the file or the encoded payload.


248-291: FREE user session fixture correctly waits, restores, and cleans up

maas_free_user_session does the right things: waits for the user to become usable, restores the original login, encapsulates state in UserTestSession, and calls cleanup() in a finally block. The BYOIDC skip at the top also ensures this path isn’t exercised on incompatible clusters.


293-335: PREMIUM user session mirrors FREE session behavior

maas_premium_user_session mirrors the FREE path with the same wait/restore/cleanup pattern, which keeps the behavior consistent across tiers. No issues from a correctness or teardown perspective.


338-365: Group fixtures correctly encapsulate RBAC groups per tier

maas_free_group and maas_premium_group use create_maas_group with the appropriate constants and users, and yield just the group name. This keeps group creation/cleanup centralized and avoids leaving extra groups behind.


368-413: Actor-specific OCP token fixture behavior is sound

ocp_token_for_actor cleanly:

  • Falls back to "admin" when no param is provided.
  • Uses the dynamic client for admin tokens.
  • Logs in as free/premium via login_with_user_password, asserts success, yields a token from the current context, and logs back in as the original user with an assertion.

This provides a clear abstraction per actor while restoring the original identity afterwards.


443-460: Per-actor headers and models response fixtures are clean wrappers

maas_headers_for_actor and maas_models_response_for_actor nicely layer on top of build_maas_headers and get_maas_models_response, keeping tests focused on behavior rather than plumbing. The docstring on maas_models_response_for_actor clarifies that it returns a validated response, which matches its implementation.

Comment thread tests/conftest.py
@mwaykole mwaykole enabled auto-merge (squash) November 26, 2025 14:24
@mwaykole mwaykole merged commit 4c8b808 into opendatahub-io:main Nov 26, 2025
8 checks passed
@github-actions
Copy link
Copy Markdown

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

SB159 added a commit to SB159/opendatahub-tests that referenced this pull request Dec 2, 2025
* User creation for e2e test

* Addressed review comments

* Updated utils

* Updated helpers

* Address review comments for MaaS RBAC tests

* maas-billing: updated user creation process

* maas-billing: updated conftest

* maas-billing: refactor RBAC fixtures

* maas-billing: address review comment remaining)

* maas-billing: address review comments

---------

Co-authored-by: Debarati Basu-Nag <dbasunag@redhat.com>
mwaykole pushed a commit to mwaykole/opendatahub-tests that referenced this pull request Jan 23, 2026
* User creation for e2e test

* Addressed review comments

* Updated utils

* Updated helpers

* Address review comments for MaaS RBAC tests

* maas-billing: updated user creation process

* maas-billing: updated conftest

* maas-billing: refactor RBAC fixtures

* maas-billing: address review comment remaining)

* maas-billing: address review comments

---------

Co-authored-by: Debarati Basu-Nag <dbasunag@redhat.com>
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