<?xml version="1.0" encoding="utf-8"?><testsuites name="pytest tests"><testsuite name="pytest" errors="10" failures="2" skipped="13" tests="181" time="2444.947" timestamp="2026-10-30T23:51:51.829546+00:00" hostname="ai-gateway-controller-groupfe292c655fda0d7c5cdc69e77d67a0c2-pod"><testcase classname="tests.test_api_keys.TestAPIKeyCRUD" name="test_revoke_api_key" time="233.483" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_by_subscription_forbidden_for_non_admin" time="0.442" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[within-limit]" time="0.347" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[at-limit]" time="0.313" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[exceeds-limit]" time="0.301" /><testcase classname="tests.test_api_keys.TestAPIKeyAuthorization" name="test_non_admin_cannot_access_other_users_keys" time="235.662" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[without-expiration]" time="0.385" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[short-expiration]" time="0.307" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_dry_run_by_subscription" time="17.048" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_model_access_success" time="0.600" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_invalid_api_key_rejected" time="0.235" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_revoked_api_key_rejected" time="3.099" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_chat_completions" time="0.290" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_double_revoke_returns_404" time="0.907" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_nonexistent_key_returns_404" time="0.312" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_then_create_new_key_works" time="1.412" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_individual_revoke_multiple_keys" time="1.823" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_keys_rejected_at_gateway" time="3.219" /><testcase classname="tests.test_api_keys.TestEphemeralKeyCleanup" name="test_cronjob_exists_and_configured" time="0.144" /><testcase classname="tests.test_api_keys.TestEphemeralKeyCleanup" name="test_cleanup_networkpolicy_exists" time="0.161" /><testcase classname="tests.test_api_keys.TestEphemeralKeyCleanup" name="test_create_ephemeral_key" time="1.165" /><testcase classname="tests.test_api_keys.TestEphemeralKeyCleanup" name="test_trigger_cleanup_preserves_active_keys" time="0.488"><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.TestAPIKeySubscriptionPhases" name="test_create_key_for_active_subscription" time="15.597" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_no_auth_header_rejected" time="0.232" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_failed_subscription" time="15.723" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_degraded_subscription" time="15.434" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_filters_by_subscription" time="31.962" /><testcase classname="tests.test_api_keys.TestAPIKeyCRUD" name="test_list_api_keys" time="274.829" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_by_subscription" time="18.692" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_without_subscription_returns_all" time="1.775" /><testcase classname="tests.test_api_keys.TestAPIKeyLabels" name="test_labels_validation_errors" time="1.119" /><testcase classname="tests.test_api_keys.TestAPIKeyLabels" name="test_backward_compatibility_no_labels" time="1.084" /><testcase classname="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/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_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_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_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="1.065" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[username-only]" time="1.771" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[group-only]" time="1.753" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[keyname-only]" time="1.796" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[identity-envelope]" time="1.679" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[admin-scope]" time="1.658" /><testcase classname="tests.test_api_keys.TestAPIKeyLabels" name="test_search_api_keys_by_labels" time="1.853" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_injected_identity_headers_rejected_on_inference" time="0.710" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_other_user_forbidden" time="294.725" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_missing_scope_returns_400" time="0.296" /><testcase classname="tests.test_negative_security.TestExpiredKeyRejection" name="test_expired_key_rejected_at_gateway" time="5.554" /><testcase classname="tests.test_negative_security.TestCrossModelAccess" name="test_key_cannot_access_model_outside_subscription" time="0.693" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_duplicate_subscription_headers_ignored" time="9.051" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_own_keys" time="297.982" /><testcase classname="tests.test_negative_security.TestMissingModelRef" name="test_authpolicy_with_nonexistent_model_ref" time="3.374" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_combined_user_and_subscription" time="19.160" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_internal_endpoint_not_routable[subscriptions-select]" time="0.376" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_internal_endpoint_not_routable[api-keys-validate]" time="0.359" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_health_endpoint_accessible" time="0.192" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_v1_models_via_maas_api_prefix" time="0.483" /><testcase classname="tests.test_subscription.TestAuthEnforcement" name="test_authorized_user_gets_200" time="0.600" /><testcase classname="tests.test_negative_security.TestMissingModelRef" name="test_subscription_with_nonexistent_model_ref" time="14.669" /><testcase classname="tests.test_api_keys.TestAPIKeyLabels" name="test_create_api_key_with_labels" time="0.914" /><testcase classname="tests.test_subscription.TestAuthEnforcement" name="test_no_auth_gets_401" time="0.206" /><testcase classname="tests.test_subscription.TestAuthEnforcement" name="test_wrong_group_gets_403" time="0.568" /><testcase classname="tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_uses_highest_priority_subscription" time="3.253" /><testcase classname="tests.test_negative_security.TestHeaderAbuse" name="test_special_characters_in_subscription_header" time="1.579" /><testcase classname="tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_with_explicit_simulator_subscription" time="11.483" /><testcase classname="tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_nonexistent_subscription_errors" time="23.718" /><testcase classname="tests.test_subscription.TestOrderingEdgeCases" name="test_subscription_before_auth_policy" time="18.787" /><testcase classname="tests.test_subscription.TestAuthEnforcement" name="test_invalid_token_gets_403" time="0.351" /><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_multiple_subscriptions_separate_keys_gets_200" time="28.643" /><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_both_access_and_subscription_gets_200" time="16.264" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_internal_endpoint_not_routable[api-keys-cleanup]" time="0.364" /><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_group_based_subscription_but_no_auth_gets_403" time="16.216" /><testcase classname="tests.test_api_keys.TestAPIKeyCRUD" name="test_create_api_key" time="323.447" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_admin_can_revoke_any_user" time="2.042" /><testcase classname="tests.test_api_keys.TestAPIKeyAuthorization" name="test_admin_manage_other_users_keys" time="326.121" /><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_subscription_but_no_access_gets_403" time="16.618" /><testcase classname="tests.test_subscription.TestSubscriptionEnforcement" name="test_subscribed_user_gets_200" time="0.466" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_dry_run" time="2.144" /><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_group_based_access_gets_200" time="15.928" /><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_mint_api_key_denied_for_inaccessible_subscription" time="27.195" /><testcase classname="tests.test_subscription.TestDegradedSubscriptionFiltering" name="test_models_endpoint_with_degraded_subscription_api_key" time="15.616" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_subscription_failed_status_with_missing_model" time="228.555" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_authpolicy_failed_status_with_missing_model" time="3.641" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptionsForModel" name="test_returns_subscriptions_for_model" time="39.760" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_subscription_degraded_status_with_partial_models" time="270.450" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_authpolicy_degraded_status_with_partial_models" time="258.949" /><testcase classname="tests.test_subscription.TestDegradedSubscriptionFiltering" name="test_degraded_healthy_model_allows_inference" time="15.696" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_subscription_active_status_with_valid_model" time="295.417" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_subscription_status_transitions_on_model_deletion" time="66.164" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptionsForModel" name="test_unknown_model_returns_empty" time="1.200" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_authpolicy_active_status_with_valid_model" time="275.100" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_empty_subscription_header_value" time="7.431" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_deduplication_same_model_multiple_refs" time="19.268" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptions" name="test_unauthenticated_returns_401[subscriptions-for-model]" time="245.600" /><testcase classname="tests.test_subscription_list_endpoints.TestSubscriptionModelAccessFiltering" name="test_filters_unauthorized_models" time="22.075" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptions" name="test_subscription_includes_model_refs" time="19.725" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptions" name="test_unauthenticated_returns_401[all-subscriptions]" time="250.286" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptions" name="test_model_ref_display_name_and_description_enriched" time="49.470" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptions" name="test_returns_accessible_subscriptions" time="7.752" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_user_token_returns_all_models" time="26.937" /><testcase classname="tests.test_subscription.TestDegradedSubscriptionFiltering" name="test_models_endpoint_with_degraded_subscription_kube_token" time="15.254" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_response_schema_and_metadata" time="6.731" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_multiple_distinct_models_in_subscription" time="25.427" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_api_key_with_deleted_subscription_403" time="44.044" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_user_token_with_subscription_header_filters" time="33.803" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_api_key_with_inaccessible_subscription_403" time="16.279" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_invalid_subscription_header_403" time="15.915" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_access_denied_to_subscription_403" time="40.350" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_api_key_ignores_subscription_header" time="29.842" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_service_account_token_multiple_subs_with_header" time="27.985" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_unauthenticated_request_401" time="0.263" /><testcase classname="tests.test_subscription_list_endpoints.TestSubscriptionModelAccessFiltering" name="test_omits_subscription_with_no_authorized_models" time="22.453" /><testcase classname="tests.test_smoke" name="test_chat_completions_gateway_alive" time="1.744" /><testcase classname="tests.test_smoke" name="test_chat_completions_streaming_sse" time="0.355" /><testcase classname="tests.test_smoke" name="test_legacy_completions_optionally" time="0.432" /><testcase classname="tests.test_tenant.TestTenantLifecycle" name="test_tenant_ready_and_phase_healthy" time="0.456" /><testcase classname="tests.test_tenant.TestTenantContract" name="test_status_has_phase_and_conditions" time="0.150" /><testcase classname="tests.test_tenant.TestTenantContract" name="test_conditions_use_kubernetes_metav1_shape" time="0.160" /><testcase classname="tests.test_tenant.TestTenantNoFalseOwnership" name="test_maas_user_crs_not_owned_by_tenant" time="0.463" /><testcase classname="tests.test_config_tenant.TestConfigAnchorPresence" name="test_cluster_config_default_exists" time="0.552" /><testcase classname="tests.test_config_tenant.TestConfigAnchorPresence" name="test_cluster_config_not_terminating" time="0.221" /><testcase classname="tests.test_config_tenant.TestConfigTenantOwnership" name="test_default_aitenant_lists_config_owner_reference" time="0.152" /><testcase classname="tests.test_config_tenant.TestConfigTenantOwnership" name="test_tenant_config_lists_config_owner_reference" time="0.156" /><testcase classname="tests.test_config_tenant.TestConfigTenantOwnership" name="test_maas_controller_deployment_does_not_list_config_owner_reference" time="0.170" /><testcase classname="tests.test_tenant_discovery" name="test_tenant_discovery_requires_auth" time="4.676" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_multiple_api_keys_different_subscriptions" time="29.905" /><testcase classname="tests.test_tenant_discovery" name="test_tenant_discovery_with_invalid_token" time="3.072" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_api_key_scoped_to_subscription" time="22.910" /><testcase classname="tests.test_tenant_discovery" name="test_tenant_discovery_gateway_matches_deployment" time="0.001"><skipped type="pytest.skip" message="Skipping when Gateway uses ClusterIP + OpenShift Route (unsupported configuration). This mixes incompatible routing paradigms. Gateway has no external hostname in spec.listeners, so /v1/tenants returns an error. Supported configuration: LoadBalancer service with hostname in spec.listeners.">/workspace/source/test/maas-e2e/test/e2e/tests/test_tenant_discovery.py:155: Skipping when Gateway uses ClusterIP + OpenShift Route (unsupported configuration). This mixes incompatible routing paradigms. Gateway has no external hostname in spec.listeners, so /v1/tenants returns an error. Supported configuration: LoadBalancer service with hostname in spec.listeners.</skipped></testcase><testcase classname="tests.test_tenant_discovery" name="test_tenant_discovery_not_exposed_through_gateway" time="0.194" /><testcase classname="tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_default_aitenant_bootstraps_maas_tenant_config_without_gateway_mutation" time="2.232" /><testcase classname="tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_aitenant_rejected_outside_ai_tenants_namespace" time="7.990" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_service_account_token_multiple_subs_no_header" time="35.399" /><testcase classname="tests.test_smoke" name="test_healthz_or_404" time="0.212" /><testcase classname="tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_aitenant_delete_cleans_maas_resources_and_preserves_user_objects" time="173.745" /><testcase classname="tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_aitenant_create_bootstrap_resources" time="165.073" /><testcase classname="tests.test_smoke" name="test_tokens_endpoint_replaced_by_api_keys" time="2.224"><failure message="AssertionError: Expected 401/404/405 (endpoint replaced), got 500: Internal Server Error.&#10;  &#10;assert 500 in (401, 404, 405)&#10; +  where 500 = &lt;Response [500]&gt;.status_code">maas_api_base_url = 'https://maas.apps.2d1e4b3b362c9776eaf8.prod.konflux-ocp-ci.dev/maas-api'

    def test_tokens_endpoint_replaced_by_api_keys(maas_api_base_url: str):
        """
        Verify /v1/tokens endpoint has been replaced by the API key system.
        The endpoint may return 401 (auth required), 404 (removed), or 405 (method not allowed).
        Any of these indicates the old token minting is no longer available.
        """
        url = f"{maas_api_base_url}/v1/tokens"
        r = requests.post(url, json={"expiration": "1m"}, timeout=20, verify=TLS_VERIFY)
        msg = f"[token] POST {url} (no auth) -&gt; {r.status_code}"
        log.info(msg)
        print(msg)
    
        # 401/404/405 all indicate the old token minting endpoint is gone/protected
&gt;       assert r.status_code in (401, 404, 405), f"Expected 401/404/405 (endpoint replaced), got {r.status_code}: {r.text[:400]}"
E       AssertionError: Expected 401/404/405 (endpoint replaced), got 500: Internal Server Error.
E         
E       assert 500 in (401, 404, 405)
E        +  where 500 = &lt;Response [500]&gt;.status_code

test/maas-e2e/test/e2e/tests/test_smoke.py:50: AssertionError</failure></testcase><testcase classname="tests.test_tenant.TestTenantContract" name="test_spec_is_well_formed" time="0.470" /><testcase classname="tests.test_tenant_namespace_discovery.TestTenantNamespaceDiscovery" name="test_label_removal_stops_reconciliation" time="118.171" /><testcase classname="tests.test_smoke" name="test_models_catalog" time="0.747" /><testcase classname="tests.test_tenant_namespace_discovery.TestTenantNamespaceDiscovery" name="test_labeled_tenant_namespace_is_discovered" time="196.593" /><testcase classname="tests.test_tenant_namespace_discovery.TestTenantNamespaceDiscovery" name="test_dynamic_discovery_after_label_added" time="185.351" /><testcase classname="tests.test_tenant_discovery" name="test_tenant_discovery_authenticated" time="0.001"><skipped type="pytest.skip" message="Skipping when Gateway uses ClusterIP + OpenShift Route (unsupported configuration). This mixes incompatible routing paradigms. Gateway has no external hostname in spec.listeners, so /v1/tenants returns an error. Supported configuration: LoadBalancer service with hostname in spec.listeners.">/workspace/source/test/maas-e2e/test/e2e/tests/test_tenant_discovery.py:79: Skipping when Gateway uses ClusterIP + OpenShift Route (unsupported configuration). This mixes incompatible routing paradigms. Gateway has no external hostname in spec.listeners, so /v1/tenants returns an error. Supported configuration: LoadBalancer service with hostname in spec.listeners.</skipped></testcase><testcase classname="tests.test_tenant_namespace_discovery.TestTenantNamespaceDiscovery" name="test_tenant_admin_rbac_is_namespace_scoped" time="293.561" /><testcase classname="tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_aitenant_migrates_and_removes_legacy_tenant" time="172.772" /><testcase classname="tests.test_tenant_namespace_discovery.TestTenantNamespaceDiscovery" name="test_unlabeled_namespace_ignored" time="106.827" /><testcase classname="tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_aitenant_derives_non_default_tenant_namespace" time="169.892" /><testcase classname="tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_aitenant_delete_releases_tenantconfig_finalizer" time="174.370" /><testcase classname="tests.test_tenant_namespace_discovery.TestTenantNamespaceDiscovery" name="test_namespace_qualified_collision_prevention" time="206.066" /><testcase classname="tests.test_tenant_namespace_discovery.TestTenantNamespaceDiscovery" name="test_per_tenant_oidc_configuration" time="0.001"><skipped type="pytest.skip" message="OIDC_ISSUER_URL not set; per-tenant OIDC E2E requires external OIDC deploy">/workspace/source/test/maas-e2e/test/e2e/tests/test_tenant_namespace_discovery.py:190: OIDC_ISSUER_URL not set; per-tenant OIDC E2E requires external OIDC deploy</skipped></testcase><testcase classname="tests.test_tenant_namespace_discovery.TestTenantWebhookValidation" name="test_maasauthpolicy_rejected_without_tenant_config_cr" time="7.992" /><testcase classname="tests.test_gateway_scoped_authpolicy.TestGatewayAuthPolicyLifecycle" name="test_gateway_auth_rego_is_fixed_size" time="3.941" /><testcase classname="tests.test_gateway_scoped_authpolicy.TestGatewayAuthPolicyLifecycle" name="test_only_one_gateway_authpolicy_named_maas_gateway_auth" time="0.347" /><testcase classname="tests.test_gateway_scoped_authpolicy.TestGatewayAuthPolicyManagementEndpointAccess" name="test_management_rules_have_model_identity_guards" time="0.175" /><testcase classname="tests.test_gateway_scoped_authpolicy.TestGatewayAuthPolicyManagementEndpointAccess" name="test_gateway_default_auth_scoped_if_present" time="0.001"><skipped type="pytest.skip" message="legacy gateway-default-auth is scoped to the shared default gateway">/workspace/source/test/maas-e2e/test/e2e/tests/test_gateway_scoped_authpolicy.py:212: legacy gateway-default-auth is scoped to the shared default gateway</skipped></testcase><testcase classname="tests.test_multi_tenant_integration.TestMultiTenantIntegration" name="test_full_tenant_lifecycle_create_to_delete" time="739.215"><failure message="AssertionError: aitenant/e2e-mt-a251fdfb in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{&quot;apiVersion&quot;:&quot;maas.opendatahub.io/v1alpha1&quot;,&quot;kind&quot;:&quot;AITenant&quot;,&quot;metadata&quot;:{&quot;annotations&quot;:{},&quot;name&quot;:&quot;e2e-mt-a251fdfb&quot;,&quot;namespace&quot;:&quot;ai-tenants&quot;},&quot;spec&quot;:{&quot;gateway&quot;:{&quot;name&quot;:&quot;e2e-mt-a251fdfb&quot;}}}\n'}, 'creationTimestamp': '2026-10-31T00:14:00Z', 'finalizers': ['...&#10;[truncated; full report in element text]">self = &lt;test_multi_tenant_integration.TestMultiTenantIntegration object at 0x7f059df30bd0&gt;

    def test_full_tenant_lifecycle_create_to_delete(self):
        """7.1: Full tenant lifecycle from create through policy/subscription reconcile to delete."""
        case = new_discovery_case()
        role_name = f"aitenant-{case['tenant_label_name']}-tenant-admin"
        try:
            bootstrap_aitenant_tenant(case)
    
            tenant = wait_for_json(TENANT_CONFIG_KIND, TENANT_CR_NAME, case["tenant_ns"], timeout=180)
            tenant_labels = tenant["metadata"].get("labels") or {}
            tenant_annotations = tenant["metadata"].get("annotations") or {}
            assert tenant_labels[LABEL_MANAGED_BY_AITENANT] == "true"
            assert tenant_labels[LABEL_TENANT_NAME] == case["tenant_label_name"]
            assert tenant_labels[LABEL_TENANT_NAMESPACE] == case["tenant_ns"]
            assert tenant_annotations[ANNOTATION_AITENANT_NAME] == case["tenant_label_name"]
            assert tenant_annotations[ANNOTATION_AITENANT_NAMESPACE] == AITENANT_NAMESPACE
            aitenant = wait_for_json(AITENANT_KIND, case["tenant_label_name"], AITENANT_NAMESPACE, timeout=180)
            assert aitenant["status"]["gatewayRef"]["name"] == case["gateway_name"]
            assert get_json_or_none("role", role_name, case["tenant_ns"]) is not None
    
            model_name = f"e2e-lifecycle-model-{case['suffix']}"
            provision_tenant_model(model_name, case["tenant_ns"], case["gateway_name"])
    
            apply_maas_auth_policy(
                case["policy_name"],
                case["tenant_ns"],
                model_ref=model_name,
                model_namespace=case["tenant_ns"],
            )
            apply_maas_subscription(
                case["subscription_name"],
                case["tenant_ns"],
                model_ref=model_name,
                model_namespace=case["tenant_ns"],
            )
            wait_for_status_phase("maasauthpolicy", case["policy_name"], case["tenant_ns"], expected_phase="Active")
            wait_for_status_phase(
                "maassubscription",
                case["subscription_name"],
                case["tenant_ns"],
                expected_phase="Active",
            )
            wait_for_aitenant_cleanup_resources(case)
    
            # Bind the key to the tenant's subscription, then verify it remains
            # invalid after the tenant and its subscription are recreated.
            route = wait_for_route_admitted(f"{case['gateway_name']}-route")
            tenant_api_url = f"https://{route['spec']['host']}/maas-api"
            wait_for_deployment_available(f"maas-api-{case['tenant_label_name']}", timeout=180)
            key_response = create_api_key_at(
                tenant_api_url,
                _get_cluster_token(),
                f"e2e-aitenant-delete-{case['suffix']}",
                subscription=case["subscription_name"],
            )
            assert key_response.status_code in (200, 201), (
                f"failed to create tenant-scoped API key: {response_summary(key_response)}"
            )
            old_api_key = key_response.json().get("key")
            assert old_api_key, "tenant-scoped API key response did not include a key"
            validation = validate_api_key_at(
                tenant_internal_url(case["tenant_label_name"]),
                old_api_key,
            )
            assert validation.status_code == 200 and validation.json().get("valid") is True, (
                f"new tenant API key did not validate: status={validation.status_code} "
                f"body={validation.text}"
            )
    
            user_objects = apply_unrelated_tenant_objects(case)
    
            delete_best_effort(AITENANT_KIND, case["tenant_label_name"], AITENANT_NAMESPACE, timeout="180s")
            wait_for_not_found(TENANT_CONFIG_KIND, TENANT_CR_NAME, case["tenant_ns"], timeout=180)
            wait_for_not_found("maasauthpolicy", case["policy_name"], case["tenant_ns"], timeout=180)
            wait_for_not_found("maassubscription", case["subscription_name"], case["tenant_ns"], timeout=180)
            wait_for_not_found("role", role_name, case["tenant_ns"], timeout=180)
            namespace = wait_for_json(
                "namespace",
                case["tenant_ns"],
                predicate=lambda obj: LABEL_MANAGED_BY_AITENANT
                not in ((obj.get("metadata") or {}).get("labels") or {}),
                timeout=180,
            )
            namespace_metadata = namespace.get("metadata") or {}
            namespace_labels = namespace_metadata.get("labels") or {}
            namespace_annotations = namespace_metadata.get("annotations") or {}
            for key in (
                "app.kubernetes.io/managed-by",
                "app.kubernetes.io/part-of",
                LABEL_AI_GATEWAY_TENANT,
                LABEL_MANAGED_BY_AITENANT,
                LABEL_TENANT_NAME,
                LABEL_TENANT_NAMESPACE,
                "opendatahub.io/generated-namespace",
            ):
                assert key not in namespace_labels
            for key in (
                ANNOTATION_AITENANT_NAME,
                ANNOTATION_AITENANT_NAMESPACE,
                "maas.opendatahub.io/created-by-aitenant",
            ):
                assert key not in namespace_annotations
            assert get_json_or_none("secret", user_objects["secret"], case["tenant_ns"]) is not None
            assert get_json_or_none("rolebinding", user_objects["rolebinding"], case["tenant_ns"]) is not None
            wait_for_aitenant_cleanup_resources_deleted(case)
    
            # Recreate the same tenant name and verify the old key cannot be
            # used against the newly provisioned maas-api instance.
&gt;           bootstrap_aitenant_tenant(case)

test/maas-e2e/test/e2e/tests/test_multi_tenant_integration.py:189: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:1119: in bootstrap_aitenant_tenant
    wait_for_json(AITENANT_KIND, case["tenant_label_name"], AITENANT_NAMESPACE, predicate=aitenant_ready)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

kind = 'aitenant', name = 'e2e-mt-a251fdfb', namespace = 'ai-tenants'
predicate = &lt;function aitenant_ready at 0x7f059e2ee700&gt;, timeout = 180
interval = 5

    def wait_for_json(
        kind: str,
        name: str,
        namespace: Optional[str] = None,
        *,
        predicate=None,
        timeout: int = 180,
        interval: int = 5,
    ) -&gt; dict:
        deadline = time.time() + timeout
        last_obj = None
        while time.time() &lt; deadline:
            obj = get_json_or_none(kind, name, namespace)
            if obj is not None:
                last_obj = obj
                if predicate is None or predicate(obj):
                    return obj
            time.sleep(interval)
&gt;       raise AssertionError(
            f"{kind}/{name} in {namespace or '&lt;cluster&gt;'} did not satisfy condition. Last object: {last_obj}"
        )
E       AssertionError: aitenant/e2e-mt-a251fdfb in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{"apiVersion":"maas.opendatahub.io/v1alpha1","kind":"AITenant","metadata":{"annotations":{},"name":"e2e-mt-a251fdfb","namespace":"ai-tenants"},"spec":{"gateway":{"name":"e2e-mt-a251fdfb"}}}\n'}, 'creationTimestamp': '2026-10-31T00:14:00Z', 'finalizers': ['maas.opendatahub.io/aitenant-cleanup'], 'generation': 1, 'name': 'e2e-mt-a251fdfb', 'namespace': 'ai-tenants', 'resourceVersion': '63522', 'uid': '416ebef7-4bb7-4ba7-8a2e-fe05ff992b79'}, 'spec': {'gateway': {'name': 'e2e-mt-a251fdfb'}}, 'status': {'conditions': [{'lastTransitionTime': '2026-10-31T00:14:02Z', 'message': 'waiting for MaasTenantConfig to report Ready', 'observedGeneration': 1, 'reason': 'TenantConfigNotReady', 'status': 'False', 'type': 'Ready'}], 'gatewayRef': {'name': 'e2e-mt-a251fdfb', 'namespace': 'openshift-ingress'}, 'phase': 'Pending', 'tenantNamespace': 'ai-tenant-e2e-mt-a251fdfb'}}

test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:288: AssertionError</failure></testcase><testcase classname="tests.test_tenant_namespace_discovery.TestLegacyDefaultNamespaceStillWorks" name="test_models_as_a_service_namespace_reconciles" time="57.612" /><testcase classname="tests.test_multi_tenant_integration.TestMultiTenantIntegration" name="test_same_named_resources_across_tenants" time="211.454" /><testcase classname="tests.test_tenant_namespace_discovery.TestTenantWebhookValidation" name="test_maassubscription_rejected_without_tenant_config_cr" time="6.822" /><testcase classname="tests.test_tenant_discovery_isolation" name="test_tenant_discovery_each_tenant_returns_own_gateway" time="264.046"><skipped type="pytest.skip" message="Skipping when Gateway uses ClusterIP + OpenShift Route (unsupported configuration). This mixes incompatible routing paradigms. Gateway has no external hostname in spec.listeners, so /v1/tenants returns an error. Supported configuration: LoadBalancer service with hostname in spec.listeners.">/workspace/source/test/maas-e2e/test/e2e/tests/test_tenant_discovery_isolation.py:228: Skipping when Gateway uses ClusterIP + OpenShift Route (unsupported configuration). This mixes incompatible routing paradigms. Gateway has no external hostname in spec.listeners, so /v1/tenants returns an error. Supported configuration: LoadBalancer service with hostname in spec.listeners.</skipped></testcase><testcase classname="tests.test_gateway_scoped_authpolicy.TestGatewayAuthPolicyStructure" name="test_gateway_auth_policy_contract" time="0.506" /><testcase classname="tests.test_multi_tenant_integration.TestMultiTenantIntegration" name="test_tenant_namespace_label_change_triggers_reconciliation" time="122.859" /><testcase classname="tests.test_multi_tenant_maas_api.TestPerTenantMaaSAPI" name="test_aitenant_creates_dedicated_maas_api_infrastructure" time="306.277" /><testcase classname="tests.test_multi_tenant_maas_api.TestPerTenantMaaSAPI" name="test_tenant_name_environment_variable_set" time="349.519" /><testcase classname="tests.test_tenant_discovery_isolation" name="test_tenant_discovery_same_tenant_access" time="319.526"><skipped type="pytest.skip" message="Skipping when Gateway uses ClusterIP + OpenShift Route (unsupported configuration). This mixes incompatible routing paradigms. Gateway has no external hostname in spec.listeners, so /v1/tenants returns an error. Supported configuration: LoadBalancer service with hostname in spec.listeners.">/workspace/source/test/maas-e2e/test/e2e/tests/test_tenant_discovery_isolation.py:93: Skipping when Gateway uses ClusterIP + OpenShift Route (unsupported configuration). This mixes incompatible routing paradigms. Gateway has no external hostname in spec.listeners, so /v1/tenants returns an error. Supported configuration: LoadBalancer service with hostname in spec.listeners.</skipped></testcase><testcase classname="tests.test_tenant_model_inference.TestTenantModelInference" name="test_inference_succeeds_through_tenant_gateway[tenant_b]" time="211.462"><error message="failed on setup with &quot;AssertionError: aitenant/e2e-inf-a-348a33 in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{&quot;apiVersion&quot;:&quot;maas.opendatahub.io/v1alpha1&quot;,&quot;kind&quot;:&quot;AITenant&quot;,&quot;metadata&quot;:{&quot;annotations&quot;:{},&quot;name&quot;:&quot;e2e-inf-a-348a33&quot;,&quot;namespace&quot;:&quot;ai-tenants&quot;},&quot;spec&quot;:{&quot;gateway&quot;:{&quot;name&quot;:&quot;e2e-inf-a-348a33&quot;}}}\n'}, 'creationTimestamp': '2026-10-31T00:...&#10;[truncated; full report in element text]">@pytest.fixture(scope="module")
    def tenant_inference_cases():
        """Set up two tenants with models for inference testing."""
        require_aitenant_crd()
        case_a = new_named_tenant_case("e2e-inf-a")
        case_b = new_named_tenant_case("e2e-inf-b")
    
        try:
            # Bootstrap tenants
            for case in (case_a, case_b):
&gt;               bootstrap_aitenant_tenant(case)

test/maas-e2e/test/e2e/tests/test_tenant_model_inference.py:153: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:1119: in bootstrap_aitenant_tenant
    wait_for_json(AITENANT_KIND, case["tenant_label_name"], AITENANT_NAMESPACE, predicate=aitenant_ready)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

kind = 'aitenant', name = 'e2e-inf-a-348a33', namespace = 'ai-tenants'
predicate = &lt;function aitenant_ready at 0x7fba6cde3560&gt;, timeout = 180
interval = 5

    def wait_for_json(
        kind: str,
        name: str,
        namespace: Optional[str] = None,
        *,
        predicate=None,
        timeout: int = 180,
        interval: int = 5,
    ) -&gt; dict:
        deadline = time.time() + timeout
        last_obj = None
        while time.time() &lt; deadline:
            obj = get_json_or_none(kind, name, namespace)
            if obj is not None:
                last_obj = obj
                if predicate is None or predicate(obj):
                    return obj
            time.sleep(interval)
&gt;       raise AssertionError(
            f"{kind}/{name} in {namespace or '&lt;cluster&gt;'} did not satisfy condition. Last object: {last_obj}"
        )
E       AssertionError: aitenant/e2e-inf-a-348a33 in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{"apiVersion":"maas.opendatahub.io/v1alpha1","kind":"AITenant","metadata":{"annotations":{},"name":"e2e-inf-a-348a33","namespace":"ai-tenants"},"spec":{"gateway":{"name":"e2e-inf-a-348a33"}}}\n'}, 'creationTimestamp': '2026-10-31T00:13:48Z', 'finalizers': ['maas.opendatahub.io/aitenant-cleanup'], 'generation': 1, 'name': 'e2e-inf-a-348a33', 'namespace': 'ai-tenants', 'resourceVersion': '63143', 'uid': 'dc780ccd-6ab0-4393-89cb-10d4fe63c3b7'}, 'spec': {'gateway': {'name': 'e2e-inf-a-348a33'}}, 'status': {'conditions': [{'lastTransitionTime': '2026-10-31T00:13:50Z', 'message': 'waiting for MaasTenantConfig to report Ready', 'observedGeneration': 1, 'reason': 'TenantConfigNotReady', 'status': 'False', 'type': 'Ready'}], 'gatewayRef': {'name': 'e2e-inf-a-348a33', 'namespace': 'openshift-ingress'}, 'phase': 'Pending', 'tenantNamespace': 'ai-tenant-e2e-inf-a-348a33'}}

test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:288: AssertionError</error></testcase><testcase classname="tests.test_tenant_model_inference.TestTenantModelInference" name="test_auth_envoyfilters_select_their_gateway_workloads" time="0.000"><error message="failed on setup with &quot;AssertionError: aitenant/e2e-inf-a-348a33 in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{&quot;apiVersion&quot;:&quot;maas.opendatahub.io/v1alpha1&quot;,&quot;kind&quot;:&quot;AITenant&quot;,&quot;metadata&quot;:{&quot;annotations&quot;:{},&quot;name&quot;:&quot;e2e-inf-a-348a33&quot;,&quot;namespace&quot;:&quot;ai-tenants&quot;},&quot;spec&quot;:{&quot;gateway&quot;:{&quot;name&quot;:&quot;e2e-inf-a-348a33&quot;}}}\n'}, 'creationTimestamp': '2026-10-31T00:...&#10;[truncated; full report in element text]">@pytest.fixture(scope="module")
    def tenant_inference_cases():
        """Set up two tenants with models for inference testing."""
        require_aitenant_crd()
        case_a = new_named_tenant_case("e2e-inf-a")
        case_b = new_named_tenant_case("e2e-inf-b")
    
        try:
            # Bootstrap tenants
            for case in (case_a, case_b):
&gt;               bootstrap_aitenant_tenant(case)

test/maas-e2e/test/e2e/tests/test_tenant_model_inference.py:153: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:1119: in bootstrap_aitenant_tenant
    wait_for_json(AITENANT_KIND, case["tenant_label_name"], AITENANT_NAMESPACE, predicate=aitenant_ready)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

kind = 'aitenant', name = 'e2e-inf-a-348a33', namespace = 'ai-tenants'
predicate = &lt;function aitenant_ready at 0x7fba6cde3560&gt;, timeout = 180
interval = 5

    def wait_for_json(
        kind: str,
        name: str,
        namespace: Optional[str] = None,
        *,
        predicate=None,
        timeout: int = 180,
        interval: int = 5,
    ) -&gt; dict:
        deadline = time.time() + timeout
        last_obj = None
        while time.time() &lt; deadline:
            obj = get_json_or_none(kind, name, namespace)
            if obj is not None:
                last_obj = obj
                if predicate is None or predicate(obj):
                    return obj
            time.sleep(interval)
&gt;       raise AssertionError(
            f"{kind}/{name} in {namespace or '&lt;cluster&gt;'} did not satisfy condition. Last object: {last_obj}"
        )
E       AssertionError: aitenant/e2e-inf-a-348a33 in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{"apiVersion":"maas.opendatahub.io/v1alpha1","kind":"AITenant","metadata":{"annotations":{},"name":"e2e-inf-a-348a33","namespace":"ai-tenants"},"spec":{"gateway":{"name":"e2e-inf-a-348a33"}}}\n'}, 'creationTimestamp': '2026-10-31T00:13:48Z', 'finalizers': ['maas.opendatahub.io/aitenant-cleanup'], 'generation': 1, 'name': 'e2e-inf-a-348a33', 'namespace': 'ai-tenants', 'resourceVersion': '63143', 'uid': 'dc780ccd-6ab0-4393-89cb-10d4fe63c3b7'}, 'spec': {'gateway': {'name': 'e2e-inf-a-348a33'}}, 'status': {'conditions': [{'lastTransitionTime': '2026-10-31T00:13:50Z', 'message': 'waiting for MaasTenantConfig to report Ready', 'observedGeneration': 1, 'reason': 'TenantConfigNotReady', 'status': 'False', 'type': 'Ready'}], 'gatewayRef': {'name': 'e2e-inf-a-348a33', 'namespace': 'openshift-ingress'}, 'phase': 'Pending', 'tenantNamespace': 'ai-tenant-e2e-inf-a-348a33'}}

test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:288: AssertionError</error></testcase><testcase classname="tests.test_tenant_model_inference.TestTenantGatewayNegativeSecurity" name="test_missing_api_key_denied_on_tenant_gateway[tenant_b]" time="0.000"><error message="failed on setup with &quot;AssertionError: aitenant/e2e-inf-a-348a33 in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{&quot;apiVersion&quot;:&quot;maas.opendatahub.io/v1alpha1&quot;,&quot;kind&quot;:&quot;AITenant&quot;,&quot;metadata&quot;:{&quot;annotations&quot;:{},&quot;name&quot;:&quot;e2e-inf-a-348a33&quot;,&quot;namespace&quot;:&quot;ai-tenants&quot;},&quot;spec&quot;:{&quot;gateway&quot;:{&quot;name&quot;:&quot;e2e-inf-a-348a33&quot;}}}\n'}, 'creationTimestamp': '2026-10-31T00:...&#10;[truncated; full report in element text]">@pytest.fixture(scope="module")
    def tenant_inference_cases():
        """Set up two tenants with models for inference testing."""
        require_aitenant_crd()
        case_a = new_named_tenant_case("e2e-inf-a")
        case_b = new_named_tenant_case("e2e-inf-b")
    
        try:
            # Bootstrap tenants
            for case in (case_a, case_b):
&gt;               bootstrap_aitenant_tenant(case)

test/maas-e2e/test/e2e/tests/test_tenant_model_inference.py:153: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:1119: in bootstrap_aitenant_tenant
    wait_for_json(AITENANT_KIND, case["tenant_label_name"], AITENANT_NAMESPACE, predicate=aitenant_ready)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

kind = 'aitenant', name = 'e2e-inf-a-348a33', namespace = 'ai-tenants'
predicate = &lt;function aitenant_ready at 0x7fba6cde3560&gt;, timeout = 180
interval = 5

    def wait_for_json(
        kind: str,
        name: str,
        namespace: Optional[str] = None,
        *,
        predicate=None,
        timeout: int = 180,
        interval: int = 5,
    ) -&gt; dict:
        deadline = time.time() + timeout
        last_obj = None
        while time.time() &lt; deadline:
            obj = get_json_or_none(kind, name, namespace)
            if obj is not None:
                last_obj = obj
                if predicate is None or predicate(obj):
                    return obj
            time.sleep(interval)
&gt;       raise AssertionError(
            f"{kind}/{name} in {namespace or '&lt;cluster&gt;'} did not satisfy condition. Last object: {last_obj}"
        )
E       AssertionError: aitenant/e2e-inf-a-348a33 in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{"apiVersion":"maas.opendatahub.io/v1alpha1","kind":"AITenant","metadata":{"annotations":{},"name":"e2e-inf-a-348a33","namespace":"ai-tenants"},"spec":{"gateway":{"name":"e2e-inf-a-348a33"}}}\n'}, 'creationTimestamp': '2026-10-31T00:13:48Z', 'finalizers': ['maas.opendatahub.io/aitenant-cleanup'], 'generation': 1, 'name': 'e2e-inf-a-348a33', 'namespace': 'ai-tenants', 'resourceVersion': '63143', 'uid': 'dc780ccd-6ab0-4393-89cb-10d4fe63c3b7'}, 'spec': {'gateway': {'name': 'e2e-inf-a-348a33'}}, 'status': {'conditions': [{'lastTransitionTime': '2026-10-31T00:13:50Z', 'message': 'waiting for MaasTenantConfig to report Ready', 'observedGeneration': 1, 'reason': 'TenantConfigNotReady', 'status': 'False', 'type': 'Ready'}], 'gatewayRef': {'name': 'e2e-inf-a-348a33', 'namespace': 'openshift-ingress'}, 'phase': 'Pending', 'tenantNamespace': 'ai-tenant-e2e-inf-a-348a33'}}

test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:288: AssertionError</error></testcase><testcase classname="tests.test_tenant_model_inference.TestTenantGatewayNegativeSecurity" name="test_invalid_api_key_denied_on_tenant_gateway[tenant_a]" time="0.000"><error message="failed on setup with &quot;AssertionError: aitenant/e2e-inf-a-348a33 in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{&quot;apiVersion&quot;:&quot;maas.opendatahub.io/v1alpha1&quot;,&quot;kind&quot;:&quot;AITenant&quot;,&quot;metadata&quot;:{&quot;annotations&quot;:{},&quot;name&quot;:&quot;e2e-inf-a-348a33&quot;,&quot;namespace&quot;:&quot;ai-tenants&quot;},&quot;spec&quot;:{&quot;gateway&quot;:{&quot;name&quot;:&quot;e2e-inf-a-348a33&quot;}}}\n'}, 'creationTimestamp': '2026-10-31T00:...&#10;[truncated; full report in element text]">@pytest.fixture(scope="module")
    def tenant_inference_cases():
        """Set up two tenants with models for inference testing."""
        require_aitenant_crd()
        case_a = new_named_tenant_case("e2e-inf-a")
        case_b = new_named_tenant_case("e2e-inf-b")
    
        try:
            # Bootstrap tenants
            for case in (case_a, case_b):
&gt;               bootstrap_aitenant_tenant(case)

test/maas-e2e/test/e2e/tests/test_tenant_model_inference.py:153: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:1119: in bootstrap_aitenant_tenant
    wait_for_json(AITENANT_KIND, case["tenant_label_name"], AITENANT_NAMESPACE, predicate=aitenant_ready)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

kind = 'aitenant', name = 'e2e-inf-a-348a33', namespace = 'ai-tenants'
predicate = &lt;function aitenant_ready at 0x7fba6cde3560&gt;, timeout = 180
interval = 5

    def wait_for_json(
        kind: str,
        name: str,
        namespace: Optional[str] = None,
        *,
        predicate=None,
        timeout: int = 180,
        interval: int = 5,
    ) -&gt; dict:
        deadline = time.time() + timeout
        last_obj = None
        while time.time() &lt; deadline:
            obj = get_json_or_none(kind, name, namespace)
            if obj is not None:
                last_obj = obj
                if predicate is None or predicate(obj):
                    return obj
            time.sleep(interval)
&gt;       raise AssertionError(
            f"{kind}/{name} in {namespace or '&lt;cluster&gt;'} did not satisfy condition. Last object: {last_obj}"
        )
E       AssertionError: aitenant/e2e-inf-a-348a33 in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{"apiVersion":"maas.opendatahub.io/v1alpha1","kind":"AITenant","metadata":{"annotations":{},"name":"e2e-inf-a-348a33","namespace":"ai-tenants"},"spec":{"gateway":{"name":"e2e-inf-a-348a33"}}}\n'}, 'creationTimestamp': '2026-10-31T00:13:48Z', 'finalizers': ['maas.opendatahub.io/aitenant-cleanup'], 'generation': 1, 'name': 'e2e-inf-a-348a33', 'namespace': 'ai-tenants', 'resourceVersion': '63143', 'uid': 'dc780ccd-6ab0-4393-89cb-10d4fe63c3b7'}, 'spec': {'gateway': {'name': 'e2e-inf-a-348a33'}}, 'status': {'conditions': [{'lastTransitionTime': '2026-10-31T00:13:50Z', 'message': 'waiting for MaasTenantConfig to report Ready', 'observedGeneration': 1, 'reason': 'TenantConfigNotReady', 'status': 'False', 'type': 'Ready'}], 'gatewayRef': {'name': 'e2e-inf-a-348a33', 'namespace': 'openshift-ingress'}, 'phase': 'Pending', 'tenantNamespace': 'ai-tenant-e2e-inf-a-348a33'}}

test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:288: AssertionError</error></testcase><testcase classname="tests.test_tenant_model_inference.TestTenantGatewayNegativeSecurity" name="test_invalid_api_key_denied_on_tenant_gateway[tenant_b]" time="135.586"><error message="failed on setup with &quot;AssertionError: aitenant/e2e-inf-a-348a33 in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{&quot;apiVersion&quot;:&quot;maas.opendatahub.io/v1alpha1&quot;,&quot;kind&quot;:&quot;AITenant&quot;,&quot;metadata&quot;:{&quot;annotations&quot;:{},&quot;name&quot;:&quot;e2e-inf-a-348a33&quot;,&quot;namespace&quot;:&quot;ai-tenants&quot;},&quot;spec&quot;:{&quot;gateway&quot;:{&quot;name&quot;:&quot;e2e-inf-a-348a33&quot;}}}\n'}, 'creationTimestamp': '2026-10-31T00:...&#10;[truncated; full report in element text]">@pytest.fixture(scope="module")
    def tenant_inference_cases():
        """Set up two tenants with models for inference testing."""
        require_aitenant_crd()
        case_a = new_named_tenant_case("e2e-inf-a")
        case_b = new_named_tenant_case("e2e-inf-b")
    
        try:
            # Bootstrap tenants
            for case in (case_a, case_b):
&gt;               bootstrap_aitenant_tenant(case)

test/maas-e2e/test/e2e/tests/test_tenant_model_inference.py:153: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:1119: in bootstrap_aitenant_tenant
    wait_for_json(AITENANT_KIND, case["tenant_label_name"], AITENANT_NAMESPACE, predicate=aitenant_ready)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

kind = 'aitenant', name = 'e2e-inf-a-348a33', namespace = 'ai-tenants'
predicate = &lt;function aitenant_ready at 0x7fba6cde3560&gt;, timeout = 180
interval = 5

    def wait_for_json(
        kind: str,
        name: str,
        namespace: Optional[str] = None,
        *,
        predicate=None,
        timeout: int = 180,
        interval: int = 5,
    ) -&gt; dict:
        deadline = time.time() + timeout
        last_obj = None
        while time.time() &lt; deadline:
            obj = get_json_or_none(kind, name, namespace)
            if obj is not None:
                last_obj = obj
                if predicate is None or predicate(obj):
                    return obj
            time.sleep(interval)
&gt;       raise AssertionError(
            f"{kind}/{name} in {namespace or '&lt;cluster&gt;'} did not satisfy condition. Last object: {last_obj}"
        )
E       AssertionError: aitenant/e2e-inf-a-348a33 in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{"apiVersion":"maas.opendatahub.io/v1alpha1","kind":"AITenant","metadata":{"annotations":{},"name":"e2e-inf-a-348a33","namespace":"ai-tenants"},"spec":{"gateway":{"name":"e2e-inf-a-348a33"}}}\n'}, 'creationTimestamp': '2026-10-31T00:13:48Z', 'finalizers': ['maas.opendatahub.io/aitenant-cleanup'], 'generation': 1, 'name': 'e2e-inf-a-348a33', 'namespace': 'ai-tenants', 'resourceVersion': '63143', 'uid': 'dc780ccd-6ab0-4393-89cb-10d4fe63c3b7'}, 'spec': {'gateway': {'name': 'e2e-inf-a-348a33'}}, 'status': {'conditions': [{'lastTransitionTime': '2026-10-31T00:13:50Z', 'message': 'waiting for MaasTenantConfig to report Ready', 'observedGeneration': 1, 'reason': 'TenantConfigNotReady', 'status': 'False', 'type': 'Ready'}], 'gatewayRef': {'name': 'e2e-inf-a-348a33', 'namespace': 'openshift-ingress'}, 'phase': 'Pending', 'tenantNamespace': 'ai-tenant-e2e-inf-a-348a33'}}

test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:288: AssertionError</error></testcase><testcase classname="tests.test_multi_tenant_maas_api.TestPerTenantMaaSAPI" name="test_service_routing_isolation" time="214.006"><error message="failed on setup with &quot;AssertionError: aitenant/e2e-api-a-c9c21e in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{&quot;apiVersion&quot;:&quot;maas.opendatahub.io/v1alpha1&quot;,&quot;kind&quot;:&quot;AITenant&quot;,&quot;metadata&quot;:{&quot;annotations&quot;:{},&quot;name&quot;:&quot;e2e-api-a-c9c21e&quot;,&quot;namespace&quot;:&quot;ai-tenants&quot;},&quot;spec&quot;:{&quot;gateway&quot;:{&quot;name&quot;:&quot;e2e-api-a-c9c21e&quot;}}}\n'}, 'creationTimestamp': '2026-10-31T00:...&#10;[truncated; full report in element text]">@pytest.fixture(scope="module")
    def tenant_cases():
        require_aitenant_crd()
        case_a = new_named_tenant_case("e2e-api-a")
        case_b = new_named_tenant_case("e2e-api-b")
        try:
            for case in (case_a, case_b):
&gt;               bootstrap_aitenant_tenant(case)

test/maas-e2e/test/e2e/tests/test_multi_tenant_maas_api.py:58: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:1119: in bootstrap_aitenant_tenant
    wait_for_json(AITENANT_KIND, case["tenant_label_name"], AITENANT_NAMESPACE, predicate=aitenant_ready)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

kind = 'aitenant', name = 'e2e-api-a-c9c21e', namespace = 'ai-tenants'
predicate = &lt;function aitenant_ready at 0x7ff89c0932e0&gt;, timeout = 180
interval = 5

    def wait_for_json(
        kind: str,
        name: str,
        namespace: Optional[str] = None,
        *,
        predicate=None,
        timeout: int = 180,
        interval: int = 5,
    ) -&gt; dict:
        deadline = time.time() + timeout
        last_obj = None
        while time.time() &lt; deadline:
            obj = get_json_or_none(kind, name, namespace)
            if obj is not None:
                last_obj = obj
                if predicate is None or predicate(obj):
                    return obj
            time.sleep(interval)
&gt;       raise AssertionError(
            f"{kind}/{name} in {namespace or '&lt;cluster&gt;'} did not satisfy condition. Last object: {last_obj}"
        )
E       AssertionError: aitenant/e2e-api-a-c9c21e in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{"apiVersion":"maas.opendatahub.io/v1alpha1","kind":"AITenant","metadata":{"annotations":{},"name":"e2e-api-a-c9c21e","namespace":"ai-tenants"},"spec":{"gateway":{"name":"e2e-api-a-c9c21e"}}}\n'}, 'creationTimestamp': '2026-10-31T00:14:24Z', 'finalizers': ['maas.opendatahub.io/aitenant-cleanup'], 'generation': 1, 'name': 'e2e-api-a-c9c21e', 'namespace': 'ai-tenants', 'resourceVersion': '64426', 'uid': '7c4c6580-0ca5-4bc6-b150-9fa8071fad63'}, 'spec': {'gateway': {'name': 'e2e-api-a-c9c21e'}}, 'status': {'conditions': [{'lastTransitionTime': '2026-10-31T00:14:26Z', 'message': 'waiting for MaasTenantConfig to report Ready', 'observedGeneration': 1, 'reason': 'TenantConfigNotReady', 'status': 'False', 'type': 'Ready'}], 'gatewayRef': {'name': 'e2e-api-a-c9c21e', 'namespace': 'openshift-ingress'}, 'phase': 'Pending', 'tenantNamespace': 'ai-tenant-e2e-api-a-c9c21e'}}

test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:288: AssertionError</error></testcase><testcase classname="tests.test_tenant_discovery_isolation" name="test_tenant_discovery_cross_tenant_isolation" time="531.134"><error message="failed on setup with &quot;AssertionError: aitenant/e2e-shared-b-w4-4a3dba in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{&quot;apiVersion&quot;:&quot;maas.opendatahub.io/v1alpha1&quot;,&quot;kind&quot;:&quot;AITenant&quot;,&quot;metadata&quot;:{&quot;annotations&quot;:{},&quot;name&quot;:&quot;e2e-shared-b-w4-4a3dba&quot;,&quot;namespace&quot;:&quot;ai-tenants&quot;},&quot;spec&quot;:{&quot;gateway&quot;:{&quot;name&quot;:&quot;e2e-shared-b-w4-4a3dba&quot;}}}\n'}, 'creationTimestamp...&#10;[truncated; full report in element text]">gateway_host = 'maas.apps.2d1e4b3b362c9776eaf8.prod.konflux-ocp-ci.dev'
is_https = True

    @pytest.fixture(scope="session")
    def shared_test_tenants(gateway_host: str, is_https: bool):
        """
        Shared tenant infrastructure for multi-tenant tests.
    
        Creates two AITenant instances (tenant-a, tenant-b) that persist for the
        entire test session. Tests requiring multiple tenants should use this fixture
        instead of creating their own tenants.
    
        Each tenant gets its own Gateway with a unique route hostname.
    
        Returns:
            tuple: (tenant_a_dict, tenant_b_dict) with keys:
                - name: tenant label name (e.g., "e2e-shared-a-abc123")
                - namespace: tenant namespace (e.g., "ai-tenant-e2e-shared-a-abc123")
                - base_url: maas-api URL for this tenant (derived from tenant's gateway route)
                - gateway_name: name of the Gateway CR for this tenant
                - suffix: 6-character hex suffix for unique resource names
                - policy_name: default auth policy name for this tenant
                - subscription_name: default subscription name for this tenant
    
        Requires:
            - AITenant CRD installed
            - Tenant namespace discovery enabled on maas-controller
        """
        from multitenancy_helpers import (
            require_aitenant_crd,
            new_named_tenant_case,
            bootstrap_aitenant_tenant,
            cleanup_discovery_case,
            wait_for_route_admitted,
            wait_for_deployment_available,
            tenant_b_external_oidc_from_env,
        )
    
        require_aitenant_crd()
    
        worker = _xdist_worker_suffix()
        case_a = new_named_tenant_case(f"e2e-shared-a-{worker}")
        case_b = new_named_tenant_case(f"e2e-shared-b-{worker}")
    
        try:
            # Bootstrap both tenants (creates gateway + AITenant CR)
            bootstrap_aitenant_tenant(case_a)
&gt;           bootstrap_aitenant_tenant(
                case_b, external_oidc=tenant_b_external_oidc_from_env()
            )

test/maas-e2e/test/e2e/tests/conftest.py:527: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:1119: in bootstrap_aitenant_tenant
    wait_for_json(AITENANT_KIND, case["tenant_label_name"], AITENANT_NAMESPACE, predicate=aitenant_ready)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

kind = 'aitenant', name = 'e2e-shared-b-w4-4a3dba', namespace = 'ai-tenants'
predicate = &lt;function aitenant_ready at 0x7fa4caa76700&gt;, timeout = 180
interval = 5

    def wait_for_json(
        kind: str,
        name: str,
        namespace: Optional[str] = None,
        *,
        predicate=None,
        timeout: int = 180,
        interval: int = 5,
    ) -&gt; dict:
        deadline = time.time() + timeout
        last_obj = None
        while time.time() &lt; deadline:
            obj = get_json_or_none(kind, name, namespace)
            if obj is not None:
                last_obj = obj
                if predicate is None or predicate(obj):
                    return obj
            time.sleep(interval)
&gt;       raise AssertionError(
            f"{kind}/{name} in {namespace or '&lt;cluster&gt;'} did not satisfy condition. Last object: {last_obj}"
        )
E       AssertionError: aitenant/e2e-shared-b-w4-4a3dba in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{"apiVersion":"maas.opendatahub.io/v1alpha1","kind":"AITenant","metadata":{"annotations":{},"name":"e2e-shared-b-w4-4a3dba","namespace":"ai-tenants"},"spec":{"gateway":{"name":"e2e-shared-b-w4-4a3dba"}}}\n'}, 'creationTimestamp': '2026-10-31T00:11:35Z', 'finalizers': ['maas.opendatahub.io/aitenant-cleanup'], 'generation': 1, 'name': 'e2e-shared-b-w4-4a3dba', 'namespace': 'ai-tenants', 'resourceVersion': '59927', 'uid': '35609ad1-0459-43a6-861a-ed8f2daaf41c'}, 'spec': {'gateway': {'name': 'e2e-shared-b-w4-4a3dba'}}, 'status': {'conditions': [{'lastTransitionTime': '2026-10-31T00:11:36Z', 'message': 'waiting for MaasTenantConfig to report Ready', 'observedGeneration': 1, 'reason': 'TenantConfigNotReady', 'status': 'False', 'type': 'Ready'}], 'gatewayRef': {'name': 'e2e-shared-b-w4-4a3dba', 'namespace': 'openshift-ingress'}, 'phase': 'Pending', 'tenantNamespace': 'ai-tenant-e2e-shared-b-w4-4a3dba'}}

test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:288: AssertionError</error></testcase><testcase classname="tests.test_tenant_discovery_isolation" name="test_tenant_discovery_unauthorized_access" time="532.392"><error message="failed on setup with &quot;AssertionError: aitenant/e2e-shared-b-w3-d9e782 in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{&quot;apiVersion&quot;:&quot;maas.opendatahub.io/v1alpha1&quot;,&quot;kind&quot;:&quot;AITenant&quot;,&quot;metadata&quot;:{&quot;annotations&quot;:{},&quot;name&quot;:&quot;e2e-shared-b-w3-d9e782&quot;,&quot;namespace&quot;:&quot;ai-tenants&quot;},&quot;spec&quot;:{&quot;gateway&quot;:{&quot;name&quot;:&quot;e2e-shared-b-w3-d9e782&quot;}}}\n'}, 'creationTimestamp...&#10;[truncated; full report in element text]">gateway_host = 'maas.apps.2d1e4b3b362c9776eaf8.prod.konflux-ocp-ci.dev'
is_https = True

    @pytest.fixture(scope="session")
    def shared_test_tenants(gateway_host: str, is_https: bool):
        """
        Shared tenant infrastructure for multi-tenant tests.
    
        Creates two AITenant instances (tenant-a, tenant-b) that persist for the
        entire test session. Tests requiring multiple tenants should use this fixture
        instead of creating their own tenants.
    
        Each tenant gets its own Gateway with a unique route hostname.
    
        Returns:
            tuple: (tenant_a_dict, tenant_b_dict) with keys:
                - name: tenant label name (e.g., "e2e-shared-a-abc123")
                - namespace: tenant namespace (e.g., "ai-tenant-e2e-shared-a-abc123")
                - base_url: maas-api URL for this tenant (derived from tenant's gateway route)
                - gateway_name: name of the Gateway CR for this tenant
                - suffix: 6-character hex suffix for unique resource names
                - policy_name: default auth policy name for this tenant
                - subscription_name: default subscription name for this tenant
    
        Requires:
            - AITenant CRD installed
            - Tenant namespace discovery enabled on maas-controller
        """
        from multitenancy_helpers import (
            require_aitenant_crd,
            new_named_tenant_case,
            bootstrap_aitenant_tenant,
            cleanup_discovery_case,
            wait_for_route_admitted,
            wait_for_deployment_available,
            tenant_b_external_oidc_from_env,
        )
    
        require_aitenant_crd()
    
        worker = _xdist_worker_suffix()
        case_a = new_named_tenant_case(f"e2e-shared-a-{worker}")
        case_b = new_named_tenant_case(f"e2e-shared-b-{worker}")
    
        try:
            # Bootstrap both tenants (creates gateway + AITenant CR)
            bootstrap_aitenant_tenant(case_a)
&gt;           bootstrap_aitenant_tenant(
                case_b, external_oidc=tenant_b_external_oidc_from_env()
            )

test/maas-e2e/test/e2e/tests/conftest.py:527: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:1119: in bootstrap_aitenant_tenant
    wait_for_json(AITENANT_KIND, case["tenant_label_name"], AITENANT_NAMESPACE, predicate=aitenant_ready)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

kind = 'aitenant', name = 'e2e-shared-b-w3-d9e782', namespace = 'ai-tenants'
predicate = &lt;function aitenant_ready at 0x7f42dbb9a700&gt;, timeout = 180
interval = 5

    def wait_for_json(
        kind: str,
        name: str,
        namespace: Optional[str] = None,
        *,
        predicate=None,
        timeout: int = 180,
        interval: int = 5,
    ) -&gt; dict:
        deadline = time.time() + timeout
        last_obj = None
        while time.time() &lt; deadline:
            obj = get_json_or_none(kind, name, namespace)
            if obj is not None:
                last_obj = obj
                if predicate is None or predicate(obj):
                    return obj
            time.sleep(interval)
&gt;       raise AssertionError(
            f"{kind}/{name} in {namespace or '&lt;cluster&gt;'} did not satisfy condition. Last object: {last_obj}"
        )
E       AssertionError: aitenant/e2e-shared-b-w3-d9e782 in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{"apiVersion":"maas.opendatahub.io/v1alpha1","kind":"AITenant","metadata":{"annotations":{},"name":"e2e-shared-b-w3-d9e782","namespace":"ai-tenants"},"spec":{"gateway":{"name":"e2e-shared-b-w3-d9e782"}}}\n'}, 'creationTimestamp': '2026-10-31T00:12:42Z', 'finalizers': ['maas.opendatahub.io/aitenant-cleanup'], 'generation': 1, 'name': 'e2e-shared-b-w3-d9e782', 'namespace': 'ai-tenants', 'resourceVersion': '61683', 'uid': '781c57d7-2e97-4a2a-a92e-3ba944d8a72a'}, 'spec': {'gateway': {'name': 'e2e-shared-b-w3-d9e782'}}, 'status': {'conditions': [{'lastTransitionTime': '2026-10-31T00:12:45Z', 'message': 'waiting for MaasTenantConfig to report Ready', 'observedGeneration': 1, 'reason': 'TenantConfigNotReady', 'status': 'False', 'type': 'Ready'}], 'gatewayRef': {'name': 'e2e-shared-b-w3-d9e782', 'namespace': 'openshift-ingress'}, 'phase': 'Pending', 'tenantNamespace': 'ai-tenant-e2e-shared-b-w3-d9e782'}}

test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:288: AssertionError</error></testcase><testcase classname="tests.test_multi_tenant_integration.TestMultiTenantIntegration" name="test_default_tenant_unaffected_by_multitenancy_enablement" time="193.850" /><testcase classname="tests.test_tenant_model_inference.TestTenantModelInference" name="test_model_routes_through_tenant_gateway" time="520.028"><error message="failed on setup with &quot;AssertionError: aitenant/e2e-inf-b-460d4e in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{&quot;apiVersion&quot;:&quot;maas.opendatahub.io/v1alpha1&quot;,&quot;kind&quot;:&quot;AITenant&quot;,&quot;metadata&quot;:{&quot;annotations&quot;:{},&quot;name&quot;:&quot;e2e-inf-b-460d4e&quot;,&quot;namespace&quot;:&quot;ai-tenants&quot;},&quot;spec&quot;:{&quot;gateway&quot;:{&quot;name&quot;:&quot;e2e-inf-b-460d4e&quot;}}}\n'}, 'creationTimestamp': '2026-10-31T00:...&#10;[truncated; full report in element text]">@pytest.fixture(scope="module")
    def tenant_inference_cases():
        """Set up two tenants with models for inference testing."""
        require_aitenant_crd()
        case_a = new_named_tenant_case("e2e-inf-a")
        case_b = new_named_tenant_case("e2e-inf-b")
    
        try:
            # Bootstrap tenants
            for case in (case_a, case_b):
&gt;               bootstrap_aitenant_tenant(case)

test/maas-e2e/test/e2e/tests/test_tenant_model_inference.py:153: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:1119: in bootstrap_aitenant_tenant
    wait_for_json(AITENANT_KIND, case["tenant_label_name"], AITENANT_NAMESPACE, predicate=aitenant_ready)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

kind = 'aitenant', name = 'e2e-inf-b-460d4e', namespace = 'ai-tenants'
predicate = &lt;function aitenant_ready at 0x7fb922b92700&gt;, timeout = 180
interval = 5

    def wait_for_json(
        kind: str,
        name: str,
        namespace: Optional[str] = None,
        *,
        predicate=None,
        timeout: int = 180,
        interval: int = 5,
    ) -&gt; dict:
        deadline = time.time() + timeout
        last_obj = None
        while time.time() &lt; deadline:
            obj = get_json_or_none(kind, name, namespace)
            if obj is not None:
                last_obj = obj
                if predicate is None or predicate(obj):
                    return obj
            time.sleep(interval)
&gt;       raise AssertionError(
            f"{kind}/{name} in {namespace or '&lt;cluster&gt;'} did not satisfy condition. Last object: {last_obj}"
        )
E       AssertionError: aitenant/e2e-inf-b-460d4e in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{"apiVersion":"maas.opendatahub.io/v1alpha1","kind":"AITenant","metadata":{"annotations":{},"name":"e2e-inf-b-460d4e","namespace":"ai-tenants"},"spec":{"gateway":{"name":"e2e-inf-b-460d4e"}}}\n'}, 'creationTimestamp': '2026-10-31T00:14:03Z', 'finalizers': ['maas.opendatahub.io/aitenant-cleanup'], 'generation': 1, 'name': 'e2e-inf-b-460d4e', 'namespace': 'ai-tenants', 'resourceVersion': '63778', 'uid': '14a59a9f-1570-4ead-9fde-1aaa305ab394'}, 'spec': {'gateway': {'name': 'e2e-inf-b-460d4e'}}, 'status': {'conditions': [{'lastTransitionTime': '2026-10-31T00:14:06Z', 'message': 'waiting for MaasTenantConfig to report Ready', 'observedGeneration': 1, 'reason': 'TenantConfigNotReady', 'status': 'False', 'type': 'Ready'}], 'gatewayRef': {'name': 'e2e-inf-b-460d4e', 'namespace': 'openshift-ingress'}, 'phase': 'Pending', 'tenantNamespace': 'ai-tenant-e2e-inf-b-460d4e'}}

test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:288: AssertionError</error></testcase><testcase classname="tests.test_tenant_model_inference.TestTenantModelInference" name="test_inference_succeeds_through_tenant_gateway[tenant_a]" time="226.130"><error message="failed on setup with &quot;AssertionError: aitenant/e2e-inf-b-460d4e in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{&quot;apiVersion&quot;:&quot;maas.opendatahub.io/v1alpha1&quot;,&quot;kind&quot;:&quot;AITenant&quot;,&quot;metadata&quot;:{&quot;annotations&quot;:{},&quot;name&quot;:&quot;e2e-inf-b-460d4e&quot;,&quot;namespace&quot;:&quot;ai-tenants&quot;},&quot;spec&quot;:{&quot;gateway&quot;:{&quot;name&quot;:&quot;e2e-inf-b-460d4e&quot;}}}\n'}, 'creationTimestamp': '2026-10-31T00:...&#10;[truncated; full report in element text]">@pytest.fixture(scope="module")
    def tenant_inference_cases():
        """Set up two tenants with models for inference testing."""
        require_aitenant_crd()
        case_a = new_named_tenant_case("e2e-inf-a")
        case_b = new_named_tenant_case("e2e-inf-b")
    
        try:
            # Bootstrap tenants
            for case in (case_a, case_b):
&gt;               bootstrap_aitenant_tenant(case)

test/maas-e2e/test/e2e/tests/test_tenant_model_inference.py:153: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:1119: in bootstrap_aitenant_tenant
    wait_for_json(AITENANT_KIND, case["tenant_label_name"], AITENANT_NAMESPACE, predicate=aitenant_ready)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

kind = 'aitenant', name = 'e2e-inf-b-460d4e', namespace = 'ai-tenants'
predicate = &lt;function aitenant_ready at 0x7fb922b92700&gt;, timeout = 180
interval = 5

    def wait_for_json(
        kind: str,
        name: str,
        namespace: Optional[str] = None,
        *,
        predicate=None,
        timeout: int = 180,
        interval: int = 5,
    ) -&gt; dict:
        deadline = time.time() + timeout
        last_obj = None
        while time.time() &lt; deadline:
            obj = get_json_or_none(kind, name, namespace)
            if obj is not None:
                last_obj = obj
                if predicate is None or predicate(obj):
                    return obj
            time.sleep(interval)
&gt;       raise AssertionError(
            f"{kind}/{name} in {namespace or '&lt;cluster&gt;'} did not satisfy condition. Last object: {last_obj}"
        )
E       AssertionError: aitenant/e2e-inf-b-460d4e in ai-tenants did not satisfy condition. Last object: {'apiVersion': 'maas.opendatahub.io/v1alpha1', 'kind': 'AITenant', 'metadata': {'annotations': {'kubectl.kubernetes.io/last-applied-configuration': '{"apiVersion":"maas.opendatahub.io/v1alpha1","kind":"AITenant","metadata":{"annotations":{},"name":"e2e-inf-b-460d4e","namespace":"ai-tenants"},"spec":{"gateway":{"name":"e2e-inf-b-460d4e"}}}\n'}, 'creationTimestamp': '2026-10-31T00:14:03Z', 'finalizers': ['maas.opendatahub.io/aitenant-cleanup'], 'generation': 1, 'name': 'e2e-inf-b-460d4e', 'namespace': 'ai-tenants', 'resourceVersion': '63778', 'uid': '14a59a9f-1570-4ead-9fde-1aaa305ab394'}, 'spec': {'gateway': {'name': 'e2e-inf-b-460d4e'}}, 'status': {'conditions': [{'lastTransitionTime': '2026-10-31T00:14:06Z', 'message': 'waiting for MaasTenantConfig to report Ready', 'observedGeneration': 1, 'reason': 'TenantConfigNotReady', 'status': 'False', 'type': 'Ready'}], 'gatewayRef': {'name': 'e2e-inf-b-460d4e', 'namespace': 'openshift-ingress'}, 'phase': 'Pending', 'tenantNamespace': 'ai-tenant-e2e-inf-b-460d4e'}}

test/maas-e2e/test/e2e/tests/multitenancy_helpers.py:288: AssertionError</error></testcase><testcase classname="tests.test_multi_tenant_maas_api.TestPerTenantMaaSAPI" name="test_httproute_tenant_attachment" time="645.050" /><testcase classname="tests.test_multi_tenant_maas_api.TestPerTenantMaaSAPI" name="test_default_and_multiple_tenants_coexist" time="615.436" /><testcase classname="tests.test_tenant_model_inference.TestTenantGatewayNegativeSecurity" name="test_missing_api_key_denied_on_tenant_gateway[tenant_a]" time="806.879" /><testcase classname="tests.test_tenant_model_inference.TestTenantModelInference" name="test_tenant_isolation_cross_gateway_blocked" time="782.301" /></testsuite></testsuites>