<?xml version="1.0" encoding="utf-8"?><testsuites name="pytest tests"><testsuite name="pytest" errors="5" failures="0" skipped="8" tests="82" time="184.061" timestamp="2026-11-03T21:57:19.050959+00:00" hostname="ai-gateway-controller-group66d259f44d8d6a06dca9f5d93a3a84d9-pod"><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_own_keys" time="93.424" /><testcase classname="tests.test_api_keys.TestAPIKeyAuthorization" name="test_admin_manage_other_users_keys" time="93.404" /><testcase classname="tests.test_api_keys.TestAPIKeyAuthorization" name="test_non_admin_cannot_access_other_users_keys" time="93.344" /><testcase classname="tests.test_api_keys.TestAPIKeyCRUD" name="test_revoke_api_key" time="93.423" /><testcase classname="tests.test_api_keys.TestAPIKeyCRUD" name="test_list_api_keys" time="93.582" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_dry_run_by_subscription" time="12.670" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_dry_run" time="0.712" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_by_subscription_forbidden_for_non_admin" time="0.141" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[exceeds-limit]" time="0.118" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[short-expiration]" time="0.119" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_invalid_api_key_rejected" time="0.128" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_no_auth_header_rejected" time="0.078" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_revoked_api_key_rejected" time="2.620" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_combined_user_and_subscription" time="15.912" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[at-limit]" time="0.144" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_by_subscription" time="13.551" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_double_revoke_returns_404" time="0.577" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_nonexistent_key_returns_404" time="0.126" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_then_create_new_key_works" time="0.610" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_individual_revoke_multiple_keys" time="0.739" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_keys_rejected_at_gateway" time="1.121" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_chat_completions" time="0.252" /><testcase classname="tests.test_api_keys.TestEphemeralKeyCleanup" name="test_cleanup_networkpolicy_exists" time="0.147" /><testcase classname="tests.test_api_keys.TestEphemeralKeyCleanup" name="test_create_ephemeral_key" time="0.396" /><testcase classname="tests.test_api_keys.TestEphemeralKeyCleanup" name="test_trigger_cleanup_preserves_active_keys" time="0.265"><skipped type="pytest.skip" message="Cannot find maas-api pod in odh-ai-gateway-infra: error: error executing jsonpath &quot;{.items[0].metadata.name}&quot;: Error executing template: array index out of bounds: index 0, length 0. Printing more information for debugging the template:&#10;&#09;template was:&#10;&#09;&#09;{.items[0].metadata.name}&#10;&#09;object given to jsonpath engine was:&#10;&#09;&#09;map[string]interface {}{&quot;apiVersion&quot;:&quot;v1&quot;, &quot;items&quot;:[]interface {}{}, &quot;kind&quot;:&quot;List&quot;, &quot;metadata&quot;:map[string]interface {}{&quot;resourceVersion&quot;:&quot;&quot;}}">/workspace/source/test/maas-e2e/test/e2e/tests/test_api_keys.py:1429: Cannot find maas-api pod in odh-ai-gateway-infra: error: error executing jsonpath "{.items[0].metadata.name}": Error executing template: array index out of bounds: index 0, length 0. Printing more information for debugging the template:
	template was:
		{.items[0].metadata.name}
	object given to jsonpath engine was:
		map[string]interface {}{"apiVersion":"v1", "items":[]interface {}{}, "kind":"List", "metadata":map[string]interface {}{"resourceVersion":""}}</skipped></testcase><testcase classname="tests.test_api_keys.TestEphemeralKeyCleanup" name="test_cronjob_exists_and_configured" time="0.140" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_degraded_subscription" time="12.292" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_active_subscription" time="12.240" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_other_user_forbidden" time="104.385" /><testcase classname="tests.test_api_keys.TestAPIKeyCRUD" name="test_create_api_key" time="104.545" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_missing_scope_returns_400" time="0.112" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_without_subscription_returns_all" time="0.770" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_admin_can_revoke_any_user" time="1.007" /><testcase classname="tests.test_api_keys.TestAPIKeyLabels" name="test_create_api_key_with_labels" time="0.221" /><testcase classname="tests.test_api_keys.TestAPIKeyLabels" name="test_labels_validation_errors" time="0.359" /><testcase classname="tests.test_api_keys.TestAPIKeyLabels" name="test_search_api_keys_by_labels" time="0.912" /><testcase classname="tests.test_api_keys.TestAPIKeyLabels" name="test_backward_compatibility_no_labels" time="0.225" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[within-limit]" time="0.467" /><testcase classname="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/maas-e2e/test/e2e/tests/test_namespace_scoping.py:247: test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true</skipped></testcase><testcase classname="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/maas-e2e/test/e2e/tests/test_namespace_scoping.py:324: test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true</skipped></testcase><testcase classname="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/maas-e2e/test/e2e/tests/test_namespace_scoping.py:382: test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true</skipped></testcase><testcase classname="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/maas-e2e/test/e2e/tests/test_namespace_scoping.py:456: test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true</skipped></testcase><testcase classname="tests.test_negative_security.TestAPIKeyManagementIsolation" name="test_api_key_cannot_mint_another_api_key" time="0.609" /><testcase classname="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/maas-e2e/test/e2e/tests/test_namespace_scoping.py:214: test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true</skipped></testcase><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[group-only]" time="0.825" /><testcase classname="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/maas-e2e/test/e2e/tests/test_namespace_scoping.py:287: test_namespace_scoping validates single-tenant dormant mode; skipped when ENABLE_TENANT_NAMESPACE_DISCOVERY=true</skipped></testcase><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[identity-envelope]" time="0.832" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[username-only]" time="0.766" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_model_access_success" time="0.641" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[keyname-only]" time="0.816" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[admin-scope]" time="0.922" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_injected_identity_headers_rejected_on_inference" time="0.403" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_duplicate_subscription_headers_ignored" time="9.565" /><testcase classname="tests.test_negative_security.TestMissingModelRef" name="test_subscription_with_nonexistent_model_ref" time="11.454" /><testcase classname="tests.test_negative_security.TestExpiredKeyRejection" name="test_expired_key_rejected_at_gateway" time="5.243" /><testcase classname="tests.test_negative_security.TestCrossModelAccess" name="test_key_cannot_access_model_outside_subscription" time="0.401" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_internal_endpoint_not_routable[api-keys-cleanup]" time="0.246" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_internal_endpoint_not_routable[api-keys-validate]" time="0.235" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_health_endpoint_accessible" time="0.068" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_v1_models_via_maas_api_prefix" time="0.334" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[without-expiration]" time="0.570" /><testcase classname="tests.test_subscription.TestAuthEnforcement" name="test_authorized_user_gets_200" time="0.777" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_failed_subscription" time="12.607" /><testcase classname="tests.test_subscription.TestAuthEnforcement" name="test_no_auth_gets_401" time="0.117" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_filters_by_subscription" time="28.954" /><testcase classname="tests.test_subscription.TestAuthEnforcement" name="test_invalid_token_gets_403" time="0.101" /><testcase classname="tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_uses_highest_priority_subscription" time="0.645" /><testcase classname="tests.test_subscription.TestSubscriptionEnforcement" name="test_subscribed_user_gets_200" time="0.356" /><testcase classname="tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_nonexistent_subscription_errors" time="10.380" /><testcase classname="tests.test_subscription.TestOrderingEdgeCases" name="test_subscription_before_auth_policy" time="15.261" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_internal_endpoint_not_routable[subscriptions-select]" time="0.241" /><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_both_access_and_subscription_gets_200" time="0.144"><error message="failed on setup with &quot;Failed: PREREQUISITE INVALID: MaaSModelRef 'simulator-w0-c0caef' not Ready (phase=Unhealthy, 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 'simulator-w0-c0caef' not Ready (phase=Unhealthy, endpoint=none). Wait for reconciliation or check controller logs.

test/maas-e2e/test/e2e/tests/test_subscription.py:1832: Failed</error></testcase><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_subscription_but_no_access_gets_403" time="0.000"><error message="failed on setup with &quot;Failed: PREREQUISITE INVALID: MaaSModelRef 'simulator-w0-c0caef' not Ready (phase=Unhealthy, 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 'simulator-w0-c0caef' not Ready (phase=Unhealthy, endpoint=none). Wait for reconciliation or check controller logs.

test/maas-e2e/test/e2e/tests/test_subscription.py:1832: Failed</error></testcase><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_multiple_subscriptions_separate_keys_gets_200" time="0.000"><error message="failed on setup with &quot;Failed: PREREQUISITE INVALID: MaaSModelRef 'simulator-w0-c0caef' not Ready (phase=Unhealthy, 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 'simulator-w0-c0caef' not Ready (phase=Unhealthy, endpoint=none). Wait for reconciliation or check controller logs.

test/maas-e2e/test/e2e/tests/test_subscription.py:1832: Failed</error></testcase><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_mint_api_key_denied_for_inaccessible_subscription" time="0.001"><error message="failed on setup with &quot;Failed: PREREQUISITE INVALID: MaaSModelRef 'simulator-w0-c0caef' not Ready (phase=Unhealthy, 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 'simulator-w0-c0caef' not Ready (phase=Unhealthy, endpoint=none). Wait for reconciliation or check controller logs.

test/maas-e2e/test/e2e/tests/test_subscription.py:1832: Failed</error></testcase><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_group_based_access_gets_200" time="36.266"><error message="failed on setup with &quot;Failed: PREREQUISITE INVALID: MaaSModelRef 'simulator-w0-c0caef' not Ready (phase=Unhealthy, 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 'simulator-w0-c0caef' not Ready (phase=Unhealthy, endpoint=none). Wait for reconciliation or check controller logs.

test/maas-e2e/test/e2e/tests/test_subscription.py:1832: Failed</error></testcase><testcase classname="tests.test_negative_security.TestMissingModelRef" name="test_authpolicy_with_nonexistent_model_ref" time="35.880" /><testcase classname="tests.test_negative_security.TestHeaderAbuse" name="test_special_characters_in_subscription_header" time="36.363" /><testcase classname="tests.test_subscription.TestManagedAnnotation" name="test_authpolicy_managed_false_prevents_update" time="31.022"><skipped type="pytest.skip" message="gateway-only mode: per-model AuthPolicy is not created">/workspace/source/test/maas-e2e/test/e2e/tests/test_subscription.py:1580: gateway-only mode: per-model AuthPolicy is not created</skipped></testcase><testcase classname="tests.test_subscription.TestAuthEnforcement" name="test_wrong_group_gets_403" time="34.255" /><testcase classname="tests.test_subscription.TestManagedAnnotation" name="test_trlp_managed_false_prevents_update" time="46.028" /><testcase classname="tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_with_explicit_simulator_subscription" time="43.770" /></testsuite></testsuites>