<?xml version="1.0" encoding="utf-8"?><testsuites name="pytest tests"><testsuite name="pytest" errors="0" failures="5" skipped="7" tests="91" time="888.485" timestamp="2026-07-27T19:27:05.158471+00:00" hostname="maas-group-test-5sph6-e2e-maas-openshift-pod"><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_create_api_key" time="0.094" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_list_api_keys" time="0.128" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_revoke_api_key" time="0.093" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyAuthorization" name="test_admin_manage_other_users_keys" time="0.131" /><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.242" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_other_user_forbidden" time="0.031" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_admin_can_revoke_any_user" time="0.090" /><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.031" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_exceeds_expiration_limit" time="0.033" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_without_expiration" time="0.029" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_with_short_expiration" time="0.029" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_model_access_success" time="0.089" /><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.022" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_revoked_api_key_rejected" time="2.121" /><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.107" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_nonexistent_key_returns_404" time="0.029" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_then_create_new_key_works" time="0.158" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_individual_revoke_multiple_keys" time="0.196" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_keys_rejected_at_gateway" time="0.300" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_cronjob_exists_and_configured" time="0.108" /><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.099" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_trigger_cleanup_preserves_active_keys" time="0.461" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_active_subscription" time="5.276" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_degraded_subscription" time="15.171" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_failed_subscription" time="5.276" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_pending_subscription" time="78.536" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_reject_key_for_unreconciled_subscription" time="18.493" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_filters_by_subscription" time="10.807" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_without_subscription_returns_all" time="0.186" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSAPIWatchNamespace" name="test_subscription_in_subscription_namespace_visible_to_api" time="0.001"><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.084" /><testcase classname="test.e2e.tests.test_negative_security.TestHeaderSpoofing" name="test_duplicate_subscription_headers_ignored" time="0.078" /><testcase classname="test.e2e.tests.test_negative_security.TestExpiredKeyRejection" name="test_expired_key_rejected_at_gateway" time="5.065" /><testcase classname="test.e2e.tests.test_negative_security.TestCrossModelAccess" name="test_key_cannot_access_model_outside_subscription" time="0.070" /><testcase classname="test.e2e.tests.test_negative_security.TestAuthPolicyRemoval" name="test_authpolicy_deletion_revokes_access" time="2.977" /><testcase classname="test.e2e.tests.test_negative_security.TestMissingModelRef" name="test_subscription_with_nonexistent_model_ref" time="1.031" /><testcase classname="test.e2e.tests.test_negative_security.TestMissingModelRef" name="test_authpolicy_with_nonexistent_model_ref" time="0.733" /><testcase classname="test.e2e.tests.test_negative_security.TestHeaderAbuse" name="test_special_characters_in_subscription_header" time="0.170" /><testcase classname="test.e2e.tests.test_negative_security.TestWebhookValidation" name="test_subscription_rejected_in_unlabeled_namespace" time="7.459" /><testcase classname="test.e2e.tests.test_negative_security.TestWebhookValidation" name="test_authpolicy_rejected_in_unlabeled_namespace" time="7.110" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_authorized_user_gets_200" time="0.076" /><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.075" /><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.315" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_with_explicit_simulator_subscription" time="0.063" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_nonexistent_subscription_errors" time="0.269" /><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="8.441" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_rate_limit_exhaustion_gets_429" time="19.842" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_models_endpoint_exempt_from_rate_limiting" time="18.874" /><testcase classname="test.e2e.tests.test_subscription.TestMultipleSubscriptionsPerModel" name="test_user_in_one_of_two_subscriptions_gets_200" time="4.429" /><testcase classname="test.e2e.tests.test_subscription.TestMultipleAuthPoliciesPerModel" name="test_two_auth_policies_or_logic" time="10.860" /><testcase classname="test.e2e.tests.test_subscription.TestMultipleAuthPoliciesPerModel" name="test_delete_one_auth_policy_other_still_works" time="12.582" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_delete_subscription_rebuilds_trlp" time="4.578" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_trlp_persists_during_multi_subscription_deletion" time="17.423" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_delete_last_subscription_denies_access" time="4.724" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_unconfigured_model_denied_by_gateway_auth" time="0.576" /><testcase classname="test.e2e.tests.test_subscription.TestOrderingEdgeCases" name="test_subscription_before_auth_policy" time="25.944" /><testcase classname="test.e2e.tests.test_subscription.TestManagedAnnotation" name="test_authpolicy_managed_false_prevents_update" time="4.263"><skipped type="pytest.skip" message="gateway-only mode: per-model AuthPolicy is not created">/workspace/source/test/e2e/tests/test_subscription.py:1054: 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="13.810" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_both_access_and_subscription_gets_200" time="5.732" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_access_but_no_subscription_gets_403" time="9.205" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_subscription_but_no_access_gets_403" time="5.596" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_single_subscription_auto_selects" time="13.676" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_multiple_subscriptions_separate_keys_gets_200" time="9.583" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_mint_api_key_denied_for_inaccessible_subscription" time="9.856" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_group_based_access_gets_200" time="9.140" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_group_based_auth_but_no_subscription_gets_403" time="9.260" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_group_based_subscription_but_no_auth_gets_403" time="5.312" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_subscription_active_status_with_valid_model" time="5.303" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_subscription_failed_status_with_missing_model" time="4.827" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_authpolicy_active_status_with_valid_model" time="4.781" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_authpolicy_failed_status_with_missing_model" time="8.458" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_subscription_degraded_status_with_partial_models" time="5.244" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_subscription_degraded_trlp_blocks_inference" time="113.664"><failure message="RuntimeError: Failed to create SA e2e-trlp-degraded-sa: error: failed to create serviceaccount: Post &quot;https://a30efdf3f8db34039b12307a75377ea8-4892054d1f42a133.elb.us-east-1.amazonaws.com:6443/api/v1/namespaces/llm/serviceaccounts?fieldManager=kubectl-create&amp;fieldValidation=Ignore&quot;: net/http: TLS handshake timeout">self = &lt;test_subscription.TestStatusReporting object at 0x7f45ede24d60&gt;

    def test_subscription_degraded_trlp_blocks_inference(self):
        """
        Test: Degraded subscription with TRLP not ready blocks inference.
    
        This test verifies that when a subscription enters Degraded phase due to
        TokenRateLimitPolicy not being ready (e.g., Kuadrant controller down),
        inference requests are blocked with appropriate error to prevent rate
        limits from being bypassed.
    
        Uses pre-deployed e2e-trlp-test-simulated model to avoid TRLP sharing with concurrent tests.
    
        Test flow:
        1. Scale down Kuadrant controller
        2. Create subscription with valid model - TRLP created but not accepted
        3. Wait for subscription to enter Degraded phase (TRLP ready=false)
        4. Create API key and verify inference is blocked (403 Forbidden)
        5. Scale Kuadrant controller back up
        6. Wait for subscription to reach Active phase (TRLP ready=true)
        7. Verify inference works (200 OK)
        """
        ns = _ns()
        subscription_name = "e2e-trlp-degraded-sub"
        auth_name = "e2e-trlp-degraded-auth"
        sa_name = "e2e-trlp-degraded-sa"
    
        try:
            # Step 1: Scale down Kuadrant controller BEFORE creating subscription
            log.info("Step 1: Scaling down Kuadrant controller...")
            _scale_kuadrant_controller_down()
    
            # Step 2: Create auth policy and subscription
            log.info("Step 2: Creating subscription with Kuadrant controller down...")
&gt;           sa_token = _create_sa_token(sa_name, namespace=MODEL_NAMESPACE)

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

sa_name = 'e2e-trlp-degraded-sa', namespace = 'llm', duration = '10m'

    def _create_sa_token(sa_name, namespace=None, duration="10m"):
        namespace = namespace or _ns()
        sa_result = subprocess.run(
            ["oc", "create", "sa", sa_name, "-n", namespace], capture_output=True, text=True
        )
        if sa_result.returncode != 0 and "already exists" not in sa_result.stderr:
&gt;           raise RuntimeError(f"Failed to create SA {sa_name}: {sa_result.stderr}")
E           RuntimeError: Failed to create SA e2e-trlp-degraded-sa: error: failed to create serviceaccount: Post "https://a30efdf3f8db34039b12307a75377ea8-4892054d1f42a133.elb.us-east-1.amazonaws.com:6443/api/v1/namespaces/llm/serviceaccounts?fieldManager=kubectl-create&amp;fieldValidation=Ignore": net/http: TLS handshake timeout

test/e2e/tests/test_helper.py:179: RuntimeError</failure></testcase><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_authpolicy_degraded_status_with_partial_models" time="28.612" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_subscription_status_transitions_on_model_deletion" time="173.054"><failure message="RuntimeError: Failed to get maassubscription/e2e-status-transition-sub in namespace 'models-as-a-service': Unable to connect to the server: net/http: TLS handshake timeout">self = &lt;test_subscription.TestStatusReporting object at 0x7f45ed8fa1c0&gt;

    def test_subscription_status_transitions_on_model_deletion(self):
        """
        Test: MaaSSubscription transitions from Active to Degraded/Failed when model is deleted.
    
        Creates a subscription with a temporary model, verifies Active status,
        then deletes the model and verifies status transitions appropriately.
        """
        ns = _ns()
        subscription_name = "e2e-status-transition-sub"
        auth_name = "e2e-status-transition-auth"
        model_name = "e2e-temp-model-status"
        sa_name = "e2e-status-transition-sa"
    
        try:
            _create_sa_token(sa_name, namespace=MODEL_NAMESPACE)
            sa_user = _sa_to_user(sa_name, namespace=MODEL_NAMESPACE)
    
            # Create a temporary model
            _create_test_maas_model(model_name, llmis_name=MODEL_REF, namespace=MODEL_NAMESPACE)
            _wait_reconcile()
    
            # Create auth policy and subscription for the model
            _create_test_auth_policy(auth_name, model_name, users=[sa_user])
            _create_test_subscription(subscription_name, model_name, users=[sa_user])
    
            _wait_for_maas_auth_policy_phase(auth_name)
&gt;           _wait_for_maas_subscription_phase(subscription_name)

test/e2e/tests/test_subscription.py:2122: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/e2e/tests/test_helper.py:819: in _wait_for_maas_subscription_phase
    cr = _get_cr("maassubscription", name, namespace)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

kind = 'maassubscription', name = 'e2e-status-transition-sub'
namespace = 'models-as-a-service'

    def _get_cr(kind, name, namespace=None):
        """Get a CR as dict, or None if not found. Retries on transient errors.
    
        Returns None only when the resource genuinely does not exist (server NotFound).
        Raises RuntimeError for other failures (RBAC, missing CRD, transport errors
        that persist after retries) so callers can distinguish infrastructure issues
        from true absence.
        """
        namespace = namespace or _ns()
        max_retries = 3
        retry_delay = 2
    
        for attempt in range(max_retries):
            result = subprocess.run(["oc", "get", kind, name, "-n", namespace, "-o", "json"], capture_output=True, text=True)
    
            if result.returncode == 0:
                return json.loads(result.stdout)
    
            if attempt &lt; max_retries - 1 and _is_transient_kubectl_error(result.stderr):
                log.warning(
                    f"Transient kubectl error getting {kind}/{name} (attempt {attempt + 1}/{max_retries}): {result.stderr.strip()}"
                )
                time.sleep(retry_delay * (attempt + 1))
                continue
    
            # Terminal failure — distinguish not-found from other errors
            if _is_not_found_error(result.stderr):
                return None
    
            log.error(
                f"Failed to get {kind}/{name} in namespace '{namespace}' after {attempt + 1} attempts. "
                f"Last error: {result.stderr.strip()}"
            )
&gt;           raise RuntimeError(
                f"Failed to get {kind}/{name} in namespace '{namespace}': {result.stderr.strip()}"
            )
E           RuntimeError: Failed to get maassubscription/e2e-status-transition-sub in namespace 'models-as-a-service': Unable to connect to the server: net/http: TLS handshake timeout

test/e2e/tests/test_helper.py:390: RuntimeError</failure></testcase><testcase classname="test.e2e.tests.test_subscription.TestDegradedSubscriptionFiltering" name="test_degraded_healthy_model_allows_inference" time="85.616"><failure message="RuntimeError: Failed to create SA e2e-degraded-healthy-inf-sa: error: failed to create serviceaccount: Post &quot;https://a30efdf3f8db34039b12307a75377ea8-4892054d1f42a133.elb.us-east-1.amazonaws.com:6443/api/v1/namespaces/llm/serviceaccounts?fieldManager=kubectl-create&amp;fieldValidation=Ignore&quot;: http2: client connection lost">self = &lt;test_subscription.TestDegradedSubscriptionFiltering object at 0x7f45eddeca00&gt;

    def test_degraded_healthy_model_allows_inference(self):
        """
        Test: Inference to healthy model in Degraded subscription succeeds.
    
        Setup:
        1. Create subscription with 1 valid + 1 missing model
        2. Controller sets phase=Degraded, modelRefStatuses shows mixed health
    
        Verify:
        - Subscription is Degraded with one ready=true, one ready=false
        - Inference to the valid model succeeds (200)
        """
        ns = _ns()
        subscription_name = "e2e-degraded-healthy-inf"
        auth_name = "e2e-degraded-healthy-inf-auth"
        sa_name = "e2e-degraded-healthy-inf-sa"
        missing_model = "nonexistent-model-inf"
    
        try:
&gt;           oc_token = _create_sa_token(sa_name, namespace=MODEL_NAMESPACE)

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

sa_name = 'e2e-degraded-healthy-inf-sa', namespace = 'llm', duration = '10m'

    def _create_sa_token(sa_name, namespace=None, duration="10m"):
        namespace = namespace or _ns()
        sa_result = subprocess.run(
            ["oc", "create", "sa", sa_name, "-n", namespace], capture_output=True, text=True
        )
        if sa_result.returncode != 0 and "already exists" not in sa_result.stderr:
&gt;           raise RuntimeError(f"Failed to create SA {sa_name}: {sa_result.stderr}")
E           RuntimeError: Failed to create SA e2e-degraded-healthy-inf-sa: error: failed to create serviceaccount: Post "https://a30efdf3f8db34039b12307a75377ea8-4892054d1f42a133.elb.us-east-1.amazonaws.com:6443/api/v1/namespaces/llm/serviceaccounts?fieldManager=kubectl-create&amp;fieldValidation=Ignore": http2: client connection lost

test/e2e/tests/test_helper.py:179: RuntimeError</failure></testcase><testcase classname="test.e2e.tests.test_subscription.TestDegradedSubscriptionFiltering" name="test_failed_subscription_blocks_inference" time="55.433"><failure message="RuntimeError: Failed to create SA e2e-failed-sub-inf-sa: error: failed to create serviceaccount: Post &quot;https://a30efdf3f8db34039b12307a75377ea8-4892054d1f42a133.elb.us-east-1.amazonaws.com:6443/api/v1/namespaces/llm/serviceaccounts?fieldManager=kubectl-create&amp;fieldValidation=Ignore&quot;: net/http: TLS handshake timeout">self = &lt;test_subscription.TestDegradedSubscriptionFiltering object at 0x7f45eddecf70&gt;

    def test_failed_subscription_blocks_inference(self):
        """
        Test: Failed subscription blocks inference via OPA rule.
    
        Setup:
        1. Create subscription with valid model (starts Active)
        2. Create API key
        3. Manually patch subscription to Failed phase
        4. Verify inference is rejected by OPA (403)
    
        Note: We use manual patching because naturally creating a Failed subscription
        requires only invalid models, which don't have routes (404 before OPA runs).
        """
        ns = _ns()
        subscription_name = "e2e-failed-sub-inf"
        auth_name = "e2e-failed-sub-inf-auth"
        sa_name = "e2e-failed-sub-inf-sa"
    
        try:
&gt;           oc_token = _create_sa_token(sa_name, namespace=MODEL_NAMESPACE)

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

sa_name = 'e2e-failed-sub-inf-sa', namespace = 'llm', duration = '10m'

    def _create_sa_token(sa_name, namespace=None, duration="10m"):
        namespace = namespace or _ns()
        sa_result = subprocess.run(
            ["oc", "create", "sa", sa_name, "-n", namespace], capture_output=True, text=True
        )
        if sa_result.returncode != 0 and "already exists" not in sa_result.stderr:
&gt;           raise RuntimeError(f"Failed to create SA {sa_name}: {sa_result.stderr}")
E           RuntimeError: Failed to create SA e2e-failed-sub-inf-sa: error: failed to create serviceaccount: Post "https://a30efdf3f8db34039b12307a75377ea8-4892054d1f42a133.elb.us-east-1.amazonaws.com:6443/api/v1/namespaces/llm/serviceaccounts?fieldManager=kubectl-create&amp;fieldValidation=Ignore": net/http: TLS handshake timeout

test/e2e/tests/test_helper.py:179: RuntimeError</failure></testcase><testcase classname="test.e2e.tests.test_subscription.TestDegradedSubscriptionFiltering" name="test_models_endpoint_with_degraded_subscription_api_key" time="13.657"><failure message="RuntimeError: Failed to create SA e2e-degraded-models-apikey-sa: error: failed to create serviceaccount: Post &quot;https://a30efdf3f8db34039b12307a75377ea8-4892054d1f42a133.elb.us-east-1.amazonaws.com:6443/api/v1/namespaces/llm/serviceaccounts?fieldManager=kubectl-create&amp;fieldValidation=Ignore&quot;: dial tcp 100.56.45.196:6443: connect: connection refused">self = &lt;test_subscription.TestDegradedSubscriptionFiltering object at 0x7f45eddec5b0&gt;

    def test_models_endpoint_with_degraded_subscription_api_key(self):
        """
        Test: /v1/models with API key bound to Degraded subscription.
    
        Verify behavior when querying models list with a Degraded subscription.
        Current implementation may succeed (showing valid models) or fail depending
        on selector implementation.
        """
        ns = _ns()
        subscription_name = "e2e-degraded-models-apikey"
        auth_name = "e2e-degraded-models-apikey-auth"
        sa_name = "e2e-degraded-models-apikey-sa"
        missing_model = "nonexistent-model-apikey"
    
        try:
&gt;           oc_token = _create_sa_token(sa_name, namespace=MODEL_NAMESPACE)

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

sa_name = 'e2e-degraded-models-apikey-sa', namespace = 'llm', duration = '10m'

    def _create_sa_token(sa_name, namespace=None, duration="10m"):
        namespace = namespace or _ns()
        sa_result = subprocess.run(
            ["oc", "create", "sa", sa_name, "-n", namespace], capture_output=True, text=True
        )
        if sa_result.returncode != 0 and "already exists" not in sa_result.stderr:
&gt;           raise RuntimeError(f"Failed to create SA {sa_name}: {sa_result.stderr}")
E           RuntimeError: Failed to create SA e2e-degraded-models-apikey-sa: error: failed to create serviceaccount: Post "https://a30efdf3f8db34039b12307a75377ea8-4892054d1f42a133.elb.us-east-1.amazonaws.com:6443/api/v1/namespaces/llm/serviceaccounts?fieldManager=kubectl-create&amp;fieldValidation=Ignore": dial tcp 100.56.45.196:6443: connect: connection refused

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