<?xml version="1.0" encoding="utf-8"?><testsuites name="pytest tests"><testsuite name="pytest" errors="0" failures="5" skipped="0" tests="72" time="552.144" timestamp="2026-06-08T19:53:40.541409+00:00" hostname="maas-group-test-tzcc8-e2e-maas-openshift-pod"><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_create_api_key" time="0.117" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_list_api_keys" time="0.159" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_revoke_api_key" time="0.110" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyAuthorization" name="test_admin_manage_other_users_keys" time="0.164" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyAuthorization" name="test_non_admin_cannot_access_other_users_keys" time="0.106" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_own_keys" time="0.283" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_other_user_forbidden" time="0.035" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_admin_can_revoke_any_user" time="0.104" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_within_expiration_limit" time="0.036" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_at_expiration_limit" time="0.036" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_exceeds_expiration_limit" time="0.037" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_without_expiration" time="0.035" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_with_short_expiration" time="0.033" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_model_access_success" time="0.121" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_invalid_api_key_rejected" time="0.024" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_no_auth_header_rejected" time="0.023" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_revoked_api_key_rejected" time="2.148" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_chat_completions" time="0.033" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_double_revoke_returns_404" time="0.115" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_nonexistent_key_returns_404" time="0.035" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_then_create_new_key_works" time="0.166" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_individual_revoke_multiple_keys" time="0.216" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_keys_rejected_at_gateway" time="0.313" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_cronjob_exists_and_configured" time="0.118" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_cleanup_networkpolicy_exists" time="0.118" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_create_ephemeral_key" time="0.133" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_trigger_cleanup_preserves_active_keys" time="0.521" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_active_subscription" time="11.509" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_degraded_subscription" time="19.371" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_failed_subscription" time="19.417"><failure message="AssertionError: Expected 403 Forbidden for Failed subscription, got 500: &#10;assert 500 == 403&#10; +  where 500 = &lt;Response [500]&gt;.status_code">self = &lt;test_api_keys.TestAPIKeySubscriptionPhases object at 0x7fbb34e548b0&gt;

    def test_create_key_for_failed_subscription(self):
        """API key creation is rejected for Failed subscription to prevent key spam."""
        ns = _ns()
        subscription_name = "e2e-apikey-failed-sub"
        auth_name = "e2e-apikey-failed-auth"
        sa_name = "e2e-apikey-failed-sa"
    
        try:
            oc_token = _create_sa_token(sa_name, namespace=MODEL_NAMESPACE)
            sa_user = _sa_to_user(sa_name, namespace=MODEL_NAMESPACE)
    
            _create_test_auth_policy(auth_name, MODEL_REF, users=[sa_user])
            _create_test_subscription(subscription_name, MODEL_REF, users=[sa_user])
            _wait_reconcile(seconds=10)
    
            # Patch to Failed phase
            patch_data = {
                "status": {
                    "phase": "Failed",
                    "conditions": [{
                        "type": "Ready",
                        "status": "False",
                        "reason": "Failed",
                        "message": "Test scenario",
                        "lastTransitionTime": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
                    }],
                    "modelRefStatuses": [{
                        "name": MODEL_REF,
                        "namespace": MODEL_NAMESPACE,
                        "ready": False,
                        "reason": "ReconcileFailed",
                        "message": "Test failure"
                    }]
                }
            }
    
            cmd = [
                "kubectl", "patch", "maassubscription", subscription_name,
                "-n", ns, "--type=merge", "--subresource=status",
                "-p", json.dumps(patch_data)
            ]
            result = subprocess.run(cmd, capture_output=True, text=True)
            assert result.returncode == 0, f"Failed to patch: {result.stderr}"
    
            cr = _get_cr("maassubscription", subscription_name, namespace=ns)
            phase = cr.get("status", {}).get("phase")
            assert phase == "Failed", f"Expected Failed, got {phase}"
    
            # Create API key (should be rejected for Failed subscriptions)
            resp = _create_api_key_raw(
                oc_token,
                name="failed-sub-test",
                subscription=subscription_name
            )
&gt;           assert resp.status_code == 403, \
                f"Expected 403 Forbidden for Failed subscription, got {resp.status_code}: {resp.text}"
E               AssertionError: Expected 403 Forbidden for Failed subscription, got 500: 
E               assert 500 == 403
E                +  where 500 = &lt;Response [500]&gt;.status_code

test/e2e/tests/test_api_keys.py:1276: AssertionError</failure></testcase><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_pending_subscription" time="19.439" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_reject_key_for_unreconciled_subscription" time="25.531" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_filters_by_subscription" time="10.280" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_without_subscription_returns_all" time="0.185" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSAPIWatchNamespace" name="test_subscription_in_subscription_namespace_visible_to_api" time="8.548" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSAPIWatchNamespace" name="test_subscription_in_another_namespace_not_visible_to_api" time="22.824" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSControllerWatchNamespace" name="test_authpolicy_and_subscription_in_maas_subscription_namespace" time="24.000" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSControllerWatchNamespace" name="test_authpolicy_and_subscription_in_another_namespace" time="30.021" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestModelRef" name="test_auth_policy_model_ref" time="31.173" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestModelRef" name="test_subscription_model_ref" time="30.926" /><testcase classname="test.e2e.tests.test_negative_security.TestHeaderSpoofing" name="test_injected_identity_headers_ignored" time="0.086" /><testcase classname="test.e2e.tests.test_negative_security.TestHeaderSpoofing" name="test_duplicate_subscription_headers_ignored" time="0.071" /><testcase classname="test.e2e.tests.test_negative_security.TestExpiredKeyRejection" name="test_expired_key_rejected_at_gateway" time="5.080" /><testcase classname="test.e2e.tests.test_negative_security.TestCrossModelAccess" name="test_key_cannot_access_model_outside_subscription" time="0.075" /><testcase classname="test.e2e.tests.test_negative_security.TestAuthPolicyRemoval" name="test_authpolicy_deletion_revokes_access" time="5.082" /><testcase classname="test.e2e.tests.test_negative_security.TestMissingModelRef" name="test_subscription_with_nonexistent_model_ref" time="1.030" /><testcase classname="test.e2e.tests.test_negative_security.TestMissingModelRef" name="test_authpolicy_with_nonexistent_model_ref" time="0.692" /><testcase classname="test.e2e.tests.test_negative_security.TestHeaderAbuse" name="test_special_characters_in_subscription_header" time="0.172" /><testcase classname="test.e2e.tests.test_negative_security.TestWebhookValidation" name="test_subscription_rejected_in_unlabeled_namespace" time="6.272" /><testcase classname="test.e2e.tests.test_negative_security.TestWebhookValidation" name="test_authpolicy_rejected_in_unlabeled_namespace" time="7.778" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_authorized_user_gets_200" time="0.086" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_no_auth_gets_401" time="0.023" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_invalid_token_gets_403" time="0.021" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_wrong_group_gets_403" time="0.027" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_uses_highest_priority_subscription" time="0.340" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_with_explicit_simulator_subscription" time="0.079" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_nonexistent_subscription_errors" time="0.267" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_subscribed_user_gets_200" time="0.040" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_auth_pass_no_subscription_gets_403" time="16.443" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_rate_limit_exhaustion_gets_429" time="24.939"><failure message="RuntimeError: Failed to create API key: 500">self = &lt;test_subscription.TestSubscriptionEnforcement object at 0x7fbb349edc40&gt;

    def test_rate_limit_exhaustion_gets_429(self):
        """
        Test that a user gets 429 when they actually exceed their token rate limit.
    
        This test creates a dedicated subscription with a very low token limit,
        sends enough requests to exhaust it, and verifies a 429 response.
    
        Uses the unconfigured model to avoid interfering with other tests.
        """
        # Use unconfigured model to isolate this test
        model_ref = UNCONFIGURED_MODEL_REF
        model_path = UNCONFIGURED_MODEL_PATH
    
        # Create unique subscription and auth policy names
        auth_policy_name = "e2e-rate-limit-test-auth"
        subscription_name = "e2e-rate-limit-test-subscription"
    
        # Low limit so we exhaust it quickly. Actual tokens consumed per
        # response are non-deterministic (max_tokens is a ceiling, not exact),
        # so we send enough requests to be confident we hit the limit without
        # asserting exactly when the 429 arrives.
        token_limit = 10
        window = "1m"
        total_requests = 15
    
        try:
            # 1. Create auth policy allowing system:authenticated
            _create_test_auth_policy(
                name=auth_policy_name,
                model_refs=[model_ref],
                groups=["system:authenticated"]
            )
            _wait_reconcile()
    
            # 2. Create subscription with low token limit
            _create_test_subscription(
                name=subscription_name,
                model_refs=[model_ref],
                groups=["system:authenticated"],
                token_limit=token_limit,
                window=window
            )
            _wait_reconcile()
    
            # Wait for TRLP to be created AND enforced by Kuadrant/Limitador.
            # Without this, requests bypass token rate limiting entirely.
            _wait_for_token_rate_limit_policy(model_ref, model_namespace=MODEL_NAMESPACE, timeout=90)
    
            # 3. API key must be minted for this subscription
            oc_token = _get_cluster_token()
&gt;           api_key = _create_api_key(
                oc_token,
                name=f"e2e-rate-limit-{uuid.uuid4().hex[:8]}",
                subscription=subscription_name,
            )

test/e2e/tests/test_subscription.py:466: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

oc_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6ImFwUEg5UW83aUxQSkJtNlU1R1ZtR0I0NVRaSXJkaGlfQk9kc1RPQ1I3aXMifQ.eyJhdWQiOlsiaHR0cHM6Ly9wcm...XIdEBzUuvZE-Tql1LIYBRrvauRm-k5XtL2JYbM-S4n-wMJ8zwN6MQZtT6LgTSMrN8_XJquTw1sVGEyylSdYh_YvNpW5ICBGa0cFVNVDQns5Y6U3uKAzMbg'
name = 'e2e-rate-limit-cf0c1150'
subscription = 'e2e-rate-limit-test-subscription'

    def _create_api_key(oc_token: str, name: str = None, subscription: str = None) -&gt; str:
        """Create an API key using the MaaS API and return the plaintext key.
    
        Args:
            oc_token: OC token for authentication with maas-api
            name: Optional name for the key (auto-generated if not provided)
            subscription: Optional MaaSSubscription name to bind (highest-priority auto-bind if omitted)
    
        Returns:
            The plaintext API key (sk-oai-xxx format)
        """
        r = _create_api_key_raw(oc_token, name, subscription)
        if r.status_code not in (200, 201):
&gt;           raise RuntimeError(f"Failed to create API key: {r.status_code} {r.text}")
E           RuntimeError: Failed to create API key: 500

test/e2e/tests/test_helper.py:243: RuntimeError</failure></testcase><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_models_endpoint_exempt_from_rate_limiting" time="25.121"><failure message="RuntimeError: Failed to create API key: 500">self = &lt;test_subscription.TestSubscriptionEnforcement object at 0x7fbb349ed850&gt;

    def test_models_endpoint_exempt_from_rate_limiting(self):
        """
        Test that /v1/models endpoint remains accessible when token quota is exhausted.
    
        This verifies that users can discover model capabilities even when they've
        used all their inference tokens. The /v1/models endpoint is a discovery/metadata
        endpoint that does not consume tokens and should remain accessible.
    
        Ref: https://issues.redhat.com/browse/RHOAIENG-46770
    
        Test steps:
        1. Create subscription with very low token limit (15 tokens)
        2. Exhaust the limit with inference requests (5 requests × 3 tokens = 15)
        3. Verify inference requests get 429 (rate limited)
        4. Verify /v1/models endpoint still returns 200 (not rate limited)
        """
        # Use unconfigured model to isolate this test
        model_ref = UNCONFIGURED_MODEL_REF
        model_path = UNCONFIGURED_MODEL_PATH
    
        # Create unique subscription and auth policy names
        auth_policy_name = "e2e-models-exempt-test-auth"
        subscription_name = "e2e-models-exempt-test-subscription"
    
        # Very low limit for fast, deterministic test
        # With 3 token limit and max_tokens=1, we're guaranteed to exhaust quota within 5 requests
        # (even if each request uses exactly 1 token: 5 requests &gt; 3 token limit)
        token_limit = 3
        window = "1m"
        max_tokens = 1
    
        try:
            # 1. Create auth policy allowing system:authenticated
            _create_test_auth_policy(
                name=auth_policy_name,
                model_refs=[model_ref],
                groups=["system:authenticated"]
            )
            _wait_reconcile()
            _wait_for_maas_auth_policy_phase(auth_policy_name, timeout=90)
    
            # 2. Create subscription with low token limit
            _create_test_subscription(
                name=subscription_name,
                model_refs=[model_ref],
                groups=["system:authenticated"],
                token_limit=token_limit,
                window=window
            )
            _wait_reconcile()
            _wait_for_maas_subscription_phase(subscription_name, timeout=90)
    
            # Wait for TRLP to be created AND enforced by Kuadrant/Limitador
            _wait_for_token_rate_limit_policy(model_ref, model_namespace=MODEL_NAMESPACE, timeout=90)
    
            # 3. Create API key for this subscription
            oc_token = _get_cluster_token()
&gt;           api_key = _create_api_key(
                oc_token,
                name=f"e2e-models-exempt-{uuid.uuid4().hex[:8]}",
                subscription=subscription_name,
            )

test/e2e/tests/test_subscription.py:587: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

oc_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6ImFwUEg5UW83aUxQSkJtNlU1R1ZtR0I0NVRaSXJkaGlfQk9kc1RPQ1I3aXMifQ.eyJhdWQiOlsiaHR0cHM6Ly9wcm...XIdEBzUuvZE-Tql1LIYBRrvauRm-k5XtL2JYbM-S4n-wMJ8zwN6MQZtT6LgTSMrN8_XJquTw1sVGEyylSdYh_YvNpW5ICBGa0cFVNVDQns5Y6U3uKAzMbg'
name = 'e2e-models-exempt-5dc8dd01'
subscription = 'e2e-models-exempt-test-subscription'

    def _create_api_key(oc_token: str, name: str = None, subscription: str = None) -&gt; str:
        """Create an API key using the MaaS API and return the plaintext key.
    
        Args:
            oc_token: OC token for authentication with maas-api
            name: Optional name for the key (auto-generated if not provided)
            subscription: Optional MaaSSubscription name to bind (highest-priority auto-bind if omitted)
    
        Returns:
            The plaintext API key (sk-oai-xxx format)
        """
        r = _create_api_key_raw(oc_token, name, subscription)
        if r.status_code not in (200, 201):
&gt;           raise RuntimeError(f"Failed to create API key: {r.status_code} {r.text}")
E           RuntimeError: Failed to create API key: 500

test/e2e/tests/test_helper.py:243: RuntimeError</failure></testcase><testcase classname="test.e2e.tests.test_subscription.TestMultipleSubscriptionsPerModel" name="test_user_in_one_of_two_subscriptions_gets_200" time="41.122" /><testcase classname="test.e2e.tests.test_subscription.TestMultipleAuthPoliciesPerModel" name="test_two_auth_policies_or_logic" time="16.862" /><testcase classname="test.e2e.tests.test_subscription.TestMultipleAuthPoliciesPerModel" name="test_delete_one_auth_policy_other_still_works" time="24.561" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_delete_subscription_rebuilds_trlp" time="8.543" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_trlp_persists_during_multi_subscription_deletion" time="33.382" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_delete_last_subscription_denies_access" time="8.532" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_unconfigured_model_denied_by_gateway_auth" time="0.484" /><testcase classname="test.e2e.tests.test_subscription.TestOrderingEdgeCases" name="test_subscription_before_auth_policy" time="16.659"><failure message="RuntimeError: Failed to create API key: 500">self = &lt;test_subscription.TestOrderingEdgeCases object at 0x7fbb349ed580&gt;

    def test_subscription_before_auth_policy(self):
        """Create subscription first, then auth policy -&gt; should work once both exist."""
        ns = _ns()
        try:
            # Subscription CR must exist before minting a key bound to it
            _apply_cr({
                "apiVersion": "maas.opendatahub.io/v1alpha1",
                "kind": "MaaSSubscription",
                "metadata": {"name": "e2e-ordering-sub", "namespace": ns},
                "spec": {
                    "owner": {"groups": [{"name": "system:authenticated"}]},
                    "modelRefs": [{"name": PREMIUM_MODEL_REF, "namespace": MODEL_NAMESPACE, "tokenRateLimits": [{"limit": 100, "window": "1m"}]}],
                },
            })
            _wait_reconcile()
            _wait_for_maas_subscription_phase("e2e-ordering-sub", namespace=ns, timeout=90)
    
&gt;           api_key = _create_api_key(
                _get_cluster_token(),
                name=f"e2e-ordering-{uuid.uuid4().hex[:8]}",
                subscription="e2e-ordering-sub",
            )

test/e2e/tests/test_subscription.py:985: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

oc_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6ImFwUEg5UW83aUxQSkJtNlU1R1ZtR0I0NVRaSXJkaGlfQk9kc1RPQ1I3aXMifQ.eyJhdWQiOlsiaHR0cHM6Ly9wcm...XIdEBzUuvZE-Tql1LIYBRrvauRm-k5XtL2JYbM-S4n-wMJ8zwN6MQZtT6LgTSMrN8_XJquTw1sVGEyylSdYh_YvNpW5ICBGa0cFVNVDQns5Y6U3uKAzMbg'
name = 'e2e-ordering-5375db6a', subscription = 'e2e-ordering-sub'

    def _create_api_key(oc_token: str, name: str = None, subscription: str = None) -&gt; str:
        """Create an API key using the MaaS API and return the plaintext key.
    
        Args:
            oc_token: OC token for authentication with maas-api
            name: Optional name for the key (auto-generated if not provided)
            subscription: Optional MaaSSubscription name to bind (highest-priority auto-bind if omitted)
    
        Returns:
            The plaintext API key (sk-oai-xxx format)
        """
        r = _create_api_key_raw(oc_token, name, subscription)
        if r.status_code not in (200, 201):
&gt;           raise RuntimeError(f"Failed to create API key: {r.status_code} {r.text}")
E           RuntimeError: Failed to create API key: 500

test/e2e/tests/test_helper.py:243: RuntimeError</failure></testcase><testcase classname="test.e2e.tests.test_subscription.TestManagedAnnotation" name="test_authpolicy_managed_false_prevents_update" time="21.420" /><testcase classname="test.e2e.tests.test_subscription.TestManagedAnnotation" name="test_trlp_managed_false_prevents_update" time="17.637" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_both_access_and_subscription_gets_200" time="9.951"><failure message="RuntimeError: Failed to create API key: 500">self = &lt;test_subscription.TestE2ESubscriptionFlow object at 0x7fbb34e9e730&gt;

    def test_e2e_with_both_access_and_subscription_gets_200(self):
        """
        Full E2E test: Create MaaSModelRef, MaaSAuthPolicy, and MaaSSubscription from scratch.
        API key with both access and subscription should get 200 OK.
    
        This is the comprehensive test that validates the complete E2E flow including
        MaaSModelRef creation and reconciliation. Other tests use existing models for speed.
        """
        ns = _ns()
        model_ref = "e2e-test-model-success"
        auth_policy_name = "e2e-test-auth-success"
        subscription_name = "e2e-test-subscription-success"
        sa_name = "e2e-sa-success"
    
        try:
            # Create service account and get OC token for maas-api
            oc_token = _create_sa_token(sa_name, namespace=ns)
            sa_user = _sa_to_user(sa_name, namespace=ns)
    
            # Create model and governance resources together so the model
            # can reach Ready (requires MaaSSubscription + MaaSAuthPolicy).
            _create_test_maas_model(model_ref)
            _create_test_auth_policy(auth_policy_name, model_ref, users=[sa_user])
            _create_test_subscription(subscription_name, model_ref, users=[sa_user])
    
            endpoint = _wait_for_maas_model_ready(model_ref, timeout=120)
    
            # Extract path from endpoint (e.g., https://maas.../llm/facebook-opt-125m-simulated -&gt; /llm/facebook-opt-125m-simulated)
            model_path = urlparse(endpoint).path
    
            # API key bound to this subscription at mint (inference does not send x-maas-subscription)
&gt;           api_key = _create_api_key(
                oc_token, name=f"{sa_name}-key", subscription=subscription_name
            )

test/e2e/tests/test_subscription.py:1320: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

oc_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6ImFwUEg5UW83aUxQSkJtNlU1R1ZtR0I0NVRaSXJkaGlfQk9kc1RPQ1I3aXMifQ.eyJhdWQiOlsiaHR0cHM6Ly9wcm..._4HrOiG53Y80sA_aET1ghrkXjdu7OmhZR4w7GT0gX3hj4QCVtKaTZpLWImzG6cC_GY8EZdBH6JP-4CuEJ45CsmQ92_CstIe2gNdymq_OL_T2eTY8oOeQvA'
name = 'e2e-sa-success-key', subscription = 'e2e-test-subscription-success'

    def _create_api_key(oc_token: str, name: str = None, subscription: str = None) -&gt; str:
        """Create an API key using the MaaS API and return the plaintext key.
    
        Args:
            oc_token: OC token for authentication with maas-api
            name: Optional name for the key (auto-generated if not provided)
            subscription: Optional MaaSSubscription name to bind (highest-priority auto-bind if omitted)
    
        Returns:
            The plaintext API key (sk-oai-xxx format)
        """
        r = _create_api_key_raw(oc_token, name, subscription)
        if r.status_code not in (200, 201):
&gt;           raise RuntimeError(f"Failed to create API key: {r.status_code} {r.text}")
E           RuntimeError: Failed to create API key: 500

test/e2e/tests/test_helper.py:243: RuntimeError</failure></testcase></testsuite></testsuites>