<?xml version="1.0" encoding="utf-8"?><testsuites name="pytest tests"><testsuite name="pytest" errors="1" failures="4" skipped="7" tests="72" time="688.471" timestamp="2026-07-09T22:40:55.024105+00:00" hostname="maas-group-test-95pl6-e2e-maas-openshift-pod"><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_create_api_key" time="0.110" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_list_api_keys" time="0.144" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_revoke_api_key" time="0.094" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyAuthorization" name="test_admin_manage_other_users_keys" time="0.129" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyAuthorization" name="test_non_admin_cannot_access_other_users_keys" time="0.092" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_own_keys" time="0.268" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_other_user_forbidden" time="0.032" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_admin_can_revoke_any_user" time="0.098" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_within_expiration_limit" time="0.031" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_at_expiration_limit" time="0.033" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_exceeds_expiration_limit" time="0.036" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_without_expiration" time="0.032" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_with_short_expiration" time="0.031" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_model_access_success" time="0.119" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_invalid_api_key_rejected" time="0.029" /><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.131" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_chat_completions" time="0.036" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_double_revoke_returns_404" time="0.103" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_nonexistent_key_returns_404" time="0.032" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_then_create_new_key_works" time="0.168" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_individual_revoke_multiple_keys" time="0.195" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_keys_rejected_at_gateway" time="0.315" /><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.109" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_create_ephemeral_key" time="0.097" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_trigger_cleanup_preserves_active_keys" time="0.483" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_active_subscription" time="35.228" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_degraded_subscription" time="45.200" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_failed_subscription" time="45.326" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_pending_subscription" time="45.261" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_reject_key_for_unreconciled_subscription" time="19.180" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_filters_by_subscription" time="95.652" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_without_subscription_returns_all" time="0.196" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSAPIWatchNamespace" name="test_subscription_in_subscription_namespace_visible_to_api" time="0.000"><skipped type="pytest.skip" message="test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true">/workspace/source/test/e2e/tests/test_namespace_scoping.py:212: test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true</skipped></testcase><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSAPIWatchNamespace" name="test_subscription_in_another_namespace_not_visible_to_api" time="0.000"><skipped type="pytest.skip" message="test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true">/workspace/source/test/e2e/tests/test_namespace_scoping.py:245: test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true</skipped></testcase><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSControllerWatchNamespace" name="test_authpolicy_and_subscription_in_maas_subscription_namespace" time="0.000"><skipped type="pytest.skip" message="test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true">/workspace/source/test/e2e/tests/test_namespace_scoping.py:283: test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true</skipped></testcase><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSControllerWatchNamespace" name="test_authpolicy_and_subscription_in_another_namespace" time="0.000"><skipped type="pytest.skip" message="test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true">/workspace/source/test/e2e/tests/test_namespace_scoping.py:320: test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true</skipped></testcase><testcase classname="test.e2e.tests.test_namespace_scoping.TestModelRef" name="test_auth_policy_model_ref" time="0.000"><skipped type="pytest.skip" message="test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true">/workspace/source/test/e2e/tests/test_namespace_scoping.py:377: test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true</skipped></testcase><testcase classname="test.e2e.tests.test_namespace_scoping.TestModelRef" name="test_subscription_model_ref" time="0.000"><skipped type="pytest.skip" message="test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true">/workspace/source/test/e2e/tests/test_namespace_scoping.py:453: test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true</skipped></testcase><testcase classname="test.e2e.tests.test_negative_security.TestHeaderSpoofing" name="test_injected_identity_headers_ignored" time="0.092" /><testcase classname="test.e2e.tests.test_negative_security.TestHeaderSpoofing" name="test_duplicate_subscription_headers_ignored" time="0.072" /><testcase classname="test.e2e.tests.test_negative_security.TestExpiredKeyRejection" name="test_expired_key_rejected_at_gateway" time="5.077" /><testcase classname="test.e2e.tests.test_negative_security.TestCrossModelAccess" name="test_key_cannot_access_model_outside_subscription" time="0.069" /><testcase classname="test.e2e.tests.test_negative_security.TestAuthPolicyRemoval" name="test_authpolicy_deletion_revokes_access" time="0.809" /><testcase classname="test.e2e.tests.test_negative_security.TestMissingModelRef" name="test_subscription_with_nonexistent_model_ref" time="47.827" /><testcase classname="test.e2e.tests.test_negative_security.TestMissingModelRef" name="test_authpolicy_with_nonexistent_model_ref" time="0.703" /><testcase classname="test.e2e.tests.test_negative_security.TestHeaderAbuse" name="test_special_characters_in_subscription_header" time="0.201" /><testcase classname="test.e2e.tests.test_negative_security.TestWebhookValidation" name="test_subscription_rejected_in_unlabeled_namespace" time="6.207" /><testcase classname="test.e2e.tests.test_negative_security.TestWebhookValidation" name="test_authpolicy_rejected_in_unlabeled_namespace" time="6.312" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_authorized_user_gets_200" time="0.088" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_no_auth_gets_401" time="0.029" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_invalid_token_gets_403" time="0.047" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_wrong_group_gets_403" time="0.032" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_uses_highest_priority_subscription" time="17.258" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_with_explicit_simulator_subscription" time="0.068" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_nonexistent_subscription_errors" time="30.145" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_subscribed_user_gets_200" time="0.048" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_auth_pass_no_subscription_gets_403" time="8.429" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_rate_limit_exhaustion_gets_429" time="64.668"><failure message="AssertionError: Unexpected status 403 at request 1: subscription rate limiting policies are not ready">self = &lt;test_subscription.TestSubscriptionEnforcement object at 0x7f3fd54e3790&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()
            api_key = _create_api_key(
                oc_token,
                name=f"e2e-rate-limit-{uuid.uuid4().hex[:8]}",
                subscription=subscription_name,
            )
    
            # 4. Send requests to exhaust the limit
            rate_limited = False
            success_count = 0
    
            for i in range(total_requests):
                r = _inference(api_key, path=model_path, max_tokens=1)
                request_num = i + 1
                log.info(f"Request {request_num}/{total_requests}: {r.status_code}")
    
                if r.status_code == 200:
                    success_count += 1
                elif r.status_code == 429:
                    rate_limited = True
                    log.info(f"Rate limit exceeded after {success_count} successful requests")
    
                    # Verify it's a rate limit 429, not a subscription error
                    response_text = r.text.lower() if r.text else ""
                    # Rate limit 429s typically mention "rate", "limit", or "quota"
                    # Subscription 429s mention "subscription" without "rate"
                    is_rate_limit_error = any(keyword in response_text
                                             for keyword in ["rate", "limit", "quota", "too many"])
                    is_subscription_error = "subscription" in response_text and not is_rate_limit_error
    
                    assert is_rate_limit_error or not is_subscription_error, \
                        f"Expected rate limit 429, not subscription error. Response: {r.text[:500]}"
    
                    # Check for Retry-After header (optional but good practice)
                    retry_after = r.headers.get("Retry-After") or r.headers.get("retry-after")
                    if retry_after:
                        log.info(f"Retry-After header present: {retry_after}")
    
                    break
                else:
                    # Unexpected status code
&gt;                   raise AssertionError(f"Unexpected status {r.status_code} at request {request_num}: {r.text[:200]}")
E                   AssertionError: Unexpected status 403 at request 1: subscription rate limiting policies are not ready

test/e2e/tests/test_subscription.py:524: AssertionError</failure></testcase><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_models_endpoint_exempt_from_rate_limiting" time="52.110"><failure message="AssertionError: Expected to hit rate limit within 5 requests with 3 token limit, but got 5 successful requests without hitting limit&#10;assert False">self = &lt;test_subscription.TestSubscriptionEnforcement object at 0x7f3fd54e3160&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_for_maas_auth_policy_phase(auth_policy_name, timeout=90, require_auth_policies=False)
    
            # 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_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()
            api_key = _create_api_key(
                oc_token,
                name=f"e2e-models-exempt-{uuid.uuid4().hex[:8]}",
                subscription=subscription_name,
            )
    
            # 4. Exhaust the token limit
            # With 3 token limit and 5 requests, we're guaranteed to hit the limit
            # (each successful request consumes ≥1 token, so 5 requests &gt; 3 token limit)
            max_requests = 5
            success_count = 0
            rate_limited = False
    
            log.info(f"Exhausting token quota: sending up to {max_requests} requests")
            for i in range(max_requests):
                r = _inference(api_key, path=model_path)
                request_num = i + 1
                log.info(f"Request {request_num}: status {r.status_code}")
    
                if r.status_code == 200:
                    success_count += 1
                elif r.status_code == 429:
                    log.info(f"Rate limit hit after {success_count} successful requests")
                    rate_limited = True
                    break
                else:
                    # Unexpected status during exhaustion
                    log.warning(f"Unexpected status during quota exhaustion: {r.status_code}")
    
            # Verify we hit rate limit (otherwise test setup is broken)
&gt;           assert rate_limited, \
                f"Expected to hit rate limit within {max_requests} requests with {token_limit} token limit, " \
                f"but got {success_count} successful requests without hitting limit"
E               AssertionError: Expected to hit rate limit within 5 requests with 3 token limit, but got 5 successful requests without hitting limit
E               assert False

test/e2e/tests/test_subscription.py:633: AssertionError</failure></testcase><testcase classname="test.e2e.tests.test_subscription.TestMultipleSubscriptionsPerModel" name="test_user_in_one_of_two_subscriptions_gets_200" time="4.300" /><testcase classname="test.e2e.tests.test_subscription.TestMultipleAuthPoliciesPerModel" name="test_two_auth_policies_or_logic" time="8.650"><failure message="RuntimeError: Failed to create API key: 400 {&quot;code&quot;:&quot;subscription_not_ready&quot;,&quot;error&quot;:&quot;subscription is unreconciled (no status.phase set)&quot;}">self = &lt;test_subscription.TestMultipleAuthPoliciesPerModel object at 0x7f3fd54e3280&gt;

    def test_two_auth_policies_or_logic(self):
        """Two auth policies for the premium model with OR logic: user matching either gets access."""
        ns = _ns()
        try:
            # Create a 2nd auth policy that allows system:authenticated (user's actual group)
            _apply_cr({
                "apiVersion": "maas.opendatahub.io/v1alpha1",
                "kind": "MaaSAuthPolicy",
                "metadata": {"name": "e2e-premium-sa-auth", "namespace": ns},
                "spec": {
                    "modelRefs": [{"name": PREMIUM_MODEL_REF, "namespace": MODEL_NAMESPACE}],
                    "subjects": {"groups": [{"name": "system:authenticated"}]},
                },
            })
            # Create a subscription for system:authenticated on premium model
            _apply_cr({
                "apiVersion": "maas.opendatahub.io/v1alpha1",
                "kind": "MaaSSubscription",
                "metadata": {"name": "e2e-premium-sa-sub", "namespace": ns},
                "spec": {
                    "owner": {"groups": [{"name": "system:authenticated"}]},
                    "modelRefs": [{"name": PREMIUM_MODEL_REF, "namespace": MODEL_NAMESPACE, "tokenRateLimits": [{"limit": 100, "window": "1m"}]}],
                },
            })
            _wait_reconcile()
    
            # Key must be minted for the premium subscription
&gt;           api_key = _create_api_key(
                _get_cluster_token(),
                name=f"e2e-premium-sa-{uuid.uuid4().hex[:8]}",
                subscription="e2e-premium-sa-sub",
            )

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

oc_token = 'eyJhbGciOiJSUzI1NiIsImtpZCI6Ii1HM2xfQkVab0c5RzluZ3NjWXlJRzlsU2lpaG12QkF5aFVKMjZGdnp3UUEifQ.eyJhdWQiOlsiaHR0cHM6Ly9wcm...PW6vp7gYb_Je8OcAgH5tiFkPd5GGPO2vUuhVKI6eoOMr0a1yN3olDmZZQOM15NGzLNjuqXFtrEoBf5ugs6w6-TtcMBKp-Hw1eQBpuf_fdhM1Jfw-BhaRXw'
name = 'e2e-premium-sa-3af9a85a', subscription = 'e2e-premium-sa-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: 400 {"code":"subscription_not_ready","error":"subscription is unreconciled (no status.phase set)"}

test/e2e/tests/test_helper.py:276: RuntimeError</failure></testcase><testcase classname="test.e2e.tests.test_subscription.TestMultipleAuthPoliciesPerModel" name="test_delete_one_auth_policy_other_still_works" time="12.540" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_delete_subscription_rebuilds_trlp" time="4.414" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_trlp_persists_during_multi_subscription_deletion" time="12.368"><failure message="AssertionError: Second subscription limit key 'models-as-a-service-e2e-second-sub-facebook-opt-125m-simulated-tokens' not found in TRLP. Available keys: ['models-as-a-service-simulator-subscription-facebook-opt-125m-simulated-tokens']&#10;assert 'models-as-a-service-e2e-second-sub-facebook-opt-125m-simulated-tokens' in {'models-as-a-service-simulator-subscription-facebook-opt-125m-simulated-tokens': {'counters': [{'expression': 'auth.identity.userid'}], 'rates': [{'limit': 100, 'window': '1m'}], 'when': [{'predicate': 'auth.identity.selected_subscription_key == &quot;models-as-a-service/simulator-subscription@llm/facebook-opt-125m-simulated&quot; &amp;&amp; !request.path.endsWith(&quot;/v1/models&quot;)'}]}}">self = &lt;test_subscription.TestCascadeDeletion object at 0x7f3fd5518730&gt;

    def test_trlp_persists_during_multi_subscription_deletion(self):
        """Validate CWE-693/CWE-400 fix: TRLP rebuilt in-place during deletion.
    
        Tests the fix for the security vulnerability where deleting one subscription
        would delete the entire TokenRateLimitPolicy, disabling rate limiting for
        ALL subscriptions to that model and creating a window for unthrottled requests.
    
        The fix ensures:
        1. TRLP is rebuilt in-place when a subscription is deleted (not deleted entirely)
        2. TRLP contains only remaining subscriptions after deletion
        3. TRLP is deleted only when no subscriptions remain
    
        This prevents the rate-limit protection gap (CWE-693: Protection Mechanism
        Failure, CWE-400: Uncontrolled Resource Consumption).
        """
        ns = _ns()
        trlp_ns = MODEL_NAMESPACE
        trlp_name = TRLP_NAME
    
        # Snapshot original subscription for restoration
        original_sub = _snapshot_cr("maassubscription", SIMULATOR_SUBSCRIPTION, ns)
        assert original_sub, f"Pre-existing {SIMULATOR_SUBSCRIPTION} not found"
    
        try:
            # Step 1: Create a second subscription for the same model
            log.info("Creating second subscription for the same model...")
            _apply_cr({
                "apiVersion": "maas.opendatahub.io/v1alpha1",
                "kind": "MaaSSubscription",
                "metadata": {"name": "e2e-second-sub", "namespace": ns},
                "spec": {
                    "owner": {"groups": [{"name": "system:authenticated"}]},
                    "modelRefs": [{
                        "name": MODEL_REF,
                        "namespace": MODEL_NAMESPACE,
                        "tokenRateLimits": [{"limit": 75, "window": "1m"}]
                    }],
                },
            })
            _wait_reconcile()
    
            # Step 2: Verify TRLP exists and contains both subscriptions
            log.info("Verifying TRLP contains both subscriptions...")
            trlp_with_both = _get_cr("tokenratelimitpolicy", trlp_name, trlp_ns)
            assert trlp_with_both, f"TRLP {trlp_name} not found in {trlp_ns} after creating 2nd subscription"
    
            # Verify both subscriptions are in the TRLP limits
            limits = trlp_with_both.get("spec", {}).get("limits", {})
            assert limits, f"TRLP {trlp_name} has no limits defined"
    
            # Look for both subscription references in TRLP limits
            # Format: {namespace}-{subscription-name}-{model-name}-tokens
            simulator_limit_key = f"{ns.replace('/', '-')}-{SIMULATOR_SUBSCRIPTION}-{MODEL_REF}-tokens"
            second_limit_key = f"{ns.replace('/', '-')}-e2e-second-sub-{MODEL_REF}-tokens"
    
            assert simulator_limit_key in limits, \
                f"Original subscription limit key '{simulator_limit_key}' not found in TRLP. Available keys: {list(limits.keys())}"
&gt;           assert second_limit_key in limits, \
                f"Second subscription limit key '{second_limit_key}' not found in TRLP. Available keys: {list(limits.keys())}"
E               AssertionError: Second subscription limit key 'models-as-a-service-e2e-second-sub-facebook-opt-125m-simulated-tokens' not found in TRLP. Available keys: ['models-as-a-service-simulator-subscription-facebook-opt-125m-simulated-tokens']
E               assert 'models-as-a-service-e2e-second-sub-facebook-opt-125m-simulated-tokens' in {'models-as-a-service-simulator-subscription-facebook-opt-125m-simulated-tokens': {'counters': [{'expression': 'auth.identity.userid'}], 'rates': [{'limit': 100, 'window': '1m'}], 'when': [{'predicate': 'auth.identity.selected_subscription_key == "models-as-a-service/simulator-subscription@llm/facebook-opt-125m-simulated" &amp;&amp; !request.path.endsWith("/v1/models")'}]}}

test/e2e/tests/test_subscription.py:859: AssertionError</failure></testcase><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_delete_last_subscription_denies_access" time="34.791" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_unconfigured_model_denied_by_gateway_auth" time="0.531" /><testcase classname="test.e2e.tests.test_subscription.TestOrderingEdgeCases" name="test_subscription_before_auth_policy" time="64.718" /><testcase classname="test.e2e.tests.test_subscription.TestManagedAnnotation" name="test_authpolicy_managed_false_prevents_update" time="4.245"><skipped type="pytest.skip" message="gateway-only mode: per-model AuthPolicy is not created">/workspace/source/test/e2e/tests/test_subscription.py:1056: gateway-only mode: per-model AuthPolicy is not created</skipped></testcase><testcase classname="test.e2e.tests.test_subscription.TestManagedAnnotation" name="test_trlp_managed_false_prevents_update" time="9.517" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_both_access_and_subscription_gets_200" time="0.118"><error message="failed on setup with &quot;Failed: PREREQUISITE INVALID: MaaSModelRef 'facebook-opt-125m-simulated' not Ready (phase=Pending, endpoint=none). Wait for reconciliation or check controller logs.&quot;">cls = &lt;class 'test_subscription.TestE2ESubscriptionFlow'&gt;

    @classmethod
    def setup_class(cls):
        """Validate test environment prerequisites before running any tests.
    
        This validates that expected resources exist and are in the correct state.
        Tests will FAIL (not skip) if prerequisites are missing, ensuring CI catches issues.
        """
        log.info("=" * 60)
        log.info("Validating E2E Test Prerequisites")
        log.info("=" * 60)
    
        # Validate MODEL_REF exists and is Ready
        model = _get_cr("maasmodelref", MODEL_REF, MODEL_NAMESPACE)
        if not model:
            pytest.fail(f"PREREQUISITE MISSING: MaaSModelRef '{MODEL_REF}' not found. "
                       f"Ensure prow setup has created the model.")
    
        phase = model.get("status", {}).get("phase")
        endpoint = model.get("status", {}).get("endpoint")
        if phase != "Ready" or not endpoint:
&gt;           pytest.fail(f"PREREQUISITE INVALID: MaaSModelRef '{MODEL_REF}' not Ready "
                       f"(phase={phase}, endpoint={endpoint or 'none'}). "
                       f"Wait for reconciliation or check controller logs.")
E           Failed: PREREQUISITE INVALID: MaaSModelRef 'facebook-opt-125m-simulated' not Ready (phase=Pending, endpoint=none). Wait for reconciliation or check controller logs.

test/e2e/tests/test_subscription.py:1282: Failed</error></testcase></testsuite></testsuites>