<?xml version="1.0" encoding="utf-8"?><testsuites name="pytest tests"><testsuite name="pytest" errors="3" failures="3" skipped="11" tests="150" time="628.086" timestamp="2026-10-29T22:52:22.423373+00:00" hostname="ai-gateway-controller-groupc82835412bb67e1e3f8c030979c21664-pod"><testcase classname="tests.test_api_keys.TestAPIKeyCRUD" name="test_list_api_keys" time="105.599" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_by_subscription" time="16.485" /><testcase classname="tests.test_api_keys.TestAPIKeyAuthorization" name="test_admin_manage_other_users_keys" time="115.120" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_dry_run" time="0.742" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_other_user_forbidden" time="116.042" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[at-limit]" time="0.259" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_missing_scope_returns_400" time="0.183" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[exceeds-limit]" time="0.168" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[without-expiration]" time="0.132" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_own_keys" time="117.200" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[short-expiration]" time="0.144" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_invalid_api_key_rejected" time="0.070" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_model_access_success" time="0.252" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_revoked_api_key_rejected" time="2.389" /><testcase classname="tests.test_api_keys.TestAPIKeyAuthorization" name="test_non_admin_cannot_access_other_users_keys" time="116.935" /><testcase classname="tests.test_api_keys.TestAPIKeyModelInference" name="test_no_auth_header_rejected" time="0.054" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_double_revoke_returns_404" time="0.315" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_dry_run_by_subscription" time="14.674" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_nonexistent_key_returns_404" time="0.087" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_individual_revoke_multiple_keys" time="0.559" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_keys_rejected_at_gateway" time="0.753" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_combined_user_and_subscription" time="13.816" /><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.300" /><testcase classname="tests.test_api_keys.TestEphemeralKeyCleanup" name="test_trigger_cleanup_preserves_active_keys" time="0.237"><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.TestAPIKeyModelInference" name="test_api_key_chat_completions" time="0.191" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_active_subscription" time="14.240" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_degraded_subscription" time="14.624" /><testcase classname="tests.test_api_keys.TestAPIKeyExpiration" name="test_expiration_policy_boundaries[within-limit]" time="0.103" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_without_subscription_returns_all" time="0.858" /><testcase classname="tests.test_api_keys.TestAPIKeyLabels" name="test_create_api_key_with_labels" time="0.325" /><testcase classname="tests.test_api_keys.TestAPIKeyLabels" name="test_search_api_keys_by_labels" time="0.511" /><testcase classname="tests.test_api_keys.TestAPIKeyLabels" name="test_labels_validation_errors" time="0.372" /><testcase classname="tests.test_api_keys.TestAPIKeyLabels" name="test_backward_compatibility_no_labels" time="0.551" /><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="0.542" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[username-only]" time="0.891" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[group-only]" time="2.180" /><testcase classname="tests.test_api_keys.TestAPIKeyCRUD" name="test_revoke_api_key" time="128.609" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[keyname-only]" time="0.814" /><testcase classname="tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_by_subscription_forbidden_for_non_admin" time="0.130" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[admin-scope]" time="0.963" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_forged_identity_headers_rejected_on_key_mint[identity-envelope]" time="0.689" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_injected_identity_headers_rejected_on_inference" time="0.360" /><testcase classname="tests.test_negative_security.TestHeaderSpoofing" name="test_duplicate_subscription_headers_ignored" time="8.477" /><testcase classname="tests.test_negative_security.TestExpiredKeyRejection" name="test_expired_key_rejected_at_gateway" time="5.181" /><testcase classname="tests.test_api_keys.TestEphemeralKeyCleanup" name="test_cronjob_exists_and_configured" time="0.468" /><testcase classname="tests.test_negative_security.TestMissingModelRef" name="test_authpolicy_with_nonexistent_model_ref" time="3.096" /><testcase classname="tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_then_create_new_key_works" time="0.761" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_internal_endpoint_not_routable[subscriptions-select]" time="0.198" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_internal_endpoint_not_routable[api-keys-cleanup]" time="0.196" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_internal_endpoint_not_routable[api-keys-validate]" time="0.195" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_health_endpoint_accessible" time="0.027" /><testcase classname="tests.test_negative_security.TestInternalEndpointIsolation" name="test_v1_models_via_maas_api_prefix" time="0.267" /><testcase classname="tests.test_subscription.TestAuthEnforcement" name="test_authorized_user_gets_200" time="0.177" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_failed_subscription" time="12.433" /><testcase classname="tests.test_subscription.TestAuthEnforcement" name="test_no_auth_gets_401" time="0.040" /><testcase classname="tests.test_subscription.TestAuthEnforcement" name="test_wrong_group_gets_403" time="0.059" /><testcase classname="tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_filters_by_subscription" time="27.100" /><testcase classname="tests.test_negative_security.TestHeaderAbuse" name="test_special_characters_in_subscription_header" time="0.609" /><testcase classname="tests.test_subscription.TestSubscriptionEnforcement" name="test_subscribed_user_gets_200" time="0.371" /><testcase classname="tests.test_negative_security.TestMissingModelRef" name="test_subscription_with_nonexistent_model_ref" time="13.674" /><testcase classname="tests.test_subscription.TestOrderingEdgeCases" name="test_subscription_before_auth_policy" time="15.143" /><testcase classname="tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_uses_highest_priority_subscription" time="2.663" /><testcase classname="tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_with_explicit_simulator_subscription" time="8.953" /><testcase classname="tests.test_negative_security.TestCrossModelAccess" name="test_key_cannot_access_model_outside_subscription" time="0.309" /><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_subscription_but_no_access_gets_403" time="20.388" /><testcase classname="tests.test_api_keys.TestAPIKeyCRUD" name="test_create_api_key" time="144.986" /><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_both_access_and_subscription_gets_200" time="0.151"><error message="failed on setup with &quot;Failed: PREREQUISITE INVALID: MaaSModelRef 'simulator-w4-dd3ff3' 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-w4-dd3ff3' 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="0.000"><error message="failed on setup with &quot;Failed: PREREQUISITE INVALID: MaaSModelRef 'simulator-w4-dd3ff3' 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-w4-dd3ff3' 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_subscription_but_no_auth_gets_403" time="0.000"><error message="failed on setup with &quot;Failed: PREREQUISITE INVALID: MaaSModelRef 'simulator-w4-dd3ff3' 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-w4-dd3ff3' 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_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_admin_can_revoke_any_user" time="1.295" /><testcase classname="tests.test_subscription.TestAuthEnforcement" name="test_invalid_token_gets_403" time="0.098" /><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_mint_api_key_denied_for_inaccessible_subscription" time="24.086" /><testcase classname="tests.test_subscription.TestManagedAnnotation" name="test_authpolicy_managed_false_prevents_update" time="0.311"><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.TestManagedAnnotation" name="test_trlp_managed_false_prevents_update" time="309.317"><failure message="TimeoutError: TokenRateLimitPolicy maas-trlp-simulator-w5-5bf55a was not created and enforced in e2e-models-e2e-worker-w5-5bf55a within 300s: generation=3, observedGeneration=3, Enforced={'lastTransitionTime': '2026-10-29T22:54:16Z', 'message': 'TokenRateLimitPolicy waiting for the following components to sync: [Limitador]', 'reason': 'Unknown', 'status': 'False', 'type': 'Enforced'}, includes_subscription=True">self = &lt;test_subscription.TestManagedAnnotation object at 0x7fb45c39f4d0&gt;

    def test_trlp_managed_false_prevents_update(self):
        """TokenRateLimitPolicy annotated with opendatahub.io/managed=false must not
        have its spec updated when the parent MaaSSubscription is modified."""
        ns = _ns()
        trlp_ns = MODEL_NAMESPACE
        parent_snapshot = None
        try:
            # 1. Verify the TRLP exists
            trlp = _get_cr("tokenratelimitpolicy", TRLP_NAME, trlp_ns)
            assert trlp, f"TokenRateLimitPolicy {TRLP_NAME} not found in {trlp_ns}"
    
            # 2. Snapshot the parent MaaSSubscription for cleanup
            parent_snapshot = _snapshot_cr(
                "maassubscription", SIMULATOR_SUBSCRIPTION, ns
            )
            assert parent_snapshot, (
                f"MaaSSubscription {SIMULATOR_SUBSCRIPTION} not found in {ns}"
            )
    
            # 3. Annotate the TRLP with managed=false
            _annotate(
                "tokenratelimitpolicy",
                TRLP_NAME,
                f"{MANAGED_ANNOTATION}=false",
                trlp_ns,
            )
            log.info(
                "Annotated TokenRateLimitPolicy %s with %s=false",
                TRLP_NAME,
                MANAGED_ANNOTATION,
            )
    
            # 4. Re-read the TRLP to capture baseline spec (post-annotation)
            trlp_baseline = _get_cr("tokenratelimitpolicy", TRLP_NAME, trlp_ns)
            assert trlp_baseline, (
                f"TokenRateLimitPolicy {TRLP_NAME} disappeared after annotation"
            )
            baseline_spec = trlp_baseline["spec"]
    
            # 5. Modify the parent MaaSSubscription (change the token rate limit value)
            modified_parent = copy.deepcopy(parent_snapshot)
            model_refs = modified_parent["spec"].get("modelRefs", [])
            assert model_refs, (
                f"MaaSSubscription {SIMULATOR_SUBSCRIPTION} has no modelRefs"
            )
            for ref in model_refs:
                if ref.get("name") == MODEL_REF:
                    limits = ref.get("tokenRateLimits", [])
                    assert limits, f"modelRef {MODEL_REF} has no tokenRateLimits"
                    limits[0]["limit"] = limits[0]["limit"] + 99999
                    break
            else:
                pytest.fail(
                    f"modelRef {MODEL_REF} not found in MaaSSubscription {SIMULATOR_SUBSCRIPTION}"
                )
            _apply_cr(modified_parent)
            log.info(
                "Modified parent MaaSSubscription %s (changed token rate limit)",
                SIMULATOR_SUBSCRIPTION,
            )
    
            # 6. Wait for the controller to reconcile the edited spec
            modified = _get_cr("maassubscription", SIMULATOR_SUBSCRIPTION, ns)
            assert modified, (
                f"MaaSSubscription {SIMULATOR_SUBSCRIPTION} disappeared after update"
            )
            reconciled = _wait_for_subscription_generation_observed(
                SIMULATOR_SUBSCRIPTION,
                modified["metadata"]["generation"],
                namespace=ns,
            )
            # An unchanged TRLP only proves managed=false if the reconcile got
            # to the TRLP step: the model was valid and the step did not fail.
            # Degraded is expected while Kuadrant has not enforced the policy.
            status = reconciled.get("status", {})
            model_ready = any(
                s.get("name") == MODEL_REF and s.get("ready") is True
                for s in status.get("modelRefStatuses", [])
            )
            assert model_ready and status.get("phase") in ("Active", "Degraded"), (
                f"MaaSSubscription {SIMULATOR_SUBSCRIPTION} reconciled without "
                f"reaching the TRLP step: {status}"
            )
    
            # 7. Re-read the TRLP and compare spec
            trlp_after = _get_cr("tokenratelimitpolicy", TRLP_NAME, trlp_ns)
            assert trlp_after, (
                f"TokenRateLimitPolicy {TRLP_NAME} disappeared after parent update"
            )
            after_spec = trlp_after["spec"]
    
            assert baseline_spec == after_spec, (
                f"TokenRateLimitPolicy spec changed despite {MANAGED_ANNOTATION}=false.\n"
                f"Before: {json.dumps(baseline_spec, indent=2)}\n"
                f"After:  {json.dumps(after_spec, indent=2)}"
            )
            log.info(
                "TokenRateLimitPolicy spec unchanged after parent modification — managed=false respected"
            )
    
        finally:
            # Remove the annotation (best-effort so parent restore still runs)
            try:
                _annotate(
                    "tokenratelimitpolicy", TRLP_NAME, f"{MANAGED_ANNOTATION}-", trlp_ns
                )
                log.info(
                    "Removed %s annotation from TokenRateLimitPolicy %s",
                    MANAGED_ANNOTATION,
                    TRLP_NAME,
                )
            except subprocess.CalledProcessError:
                log.warning(
                    "Failed to remove %s annotation from TokenRateLimitPolicy %s (may not exist)",
                    MANAGED_ANNOTATION,
                    TRLP_NAME,
                )
    
            # Restore the parent MaaSSubscription
            if parent_snapshot:
                _apply_cr(parent_snapshot)
                log.info(
                    "Restored parent MaaSSubscription %s from snapshot",
                    SIMULATOR_SUBSCRIPTION,
                )
&gt;               _wait_for_subscription_inference_ready(
                    SIMULATOR_SUBSCRIPTION,
                    MODEL_REF,
                    model_namespace=MODEL_NAMESPACE,
                )

test/maas-e2e/test/e2e/tests/test_subscription.py:1789: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/maas-e2e/test/e2e/tests/test_helper.py:1781: in _wait_for_subscription_inference_ready
    _wait_for_token_rate_limit_policy(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

model_ref = 'simulator-w5-5bf55a'
model_namespace = 'e2e-models-e2e-worker-w5-5bf55a', timeout = 300
subscription_name = 'simulator-subscription'
subscription_namespace = 'ai-tenant-e2e-worker-w5-5bf55a'

    def _wait_for_token_rate_limit_policy(
        model_ref, model_namespace=MODEL_NAMESPACE, timeout=60, *, subscription_name=None, subscription_namespace=None
    ):
        """Wait for the current TokenRateLimitPolicy generation to be enforced.
    
        If a subscription is supplied, wait until the policy includes it. This
        prevents accepting the old policy before the controller updates its spec.
    
        Args:
            model_ref: Name of the model (e.g., "e2e-distinct-simulated")
            model_namespace: Namespace where the TRLP should be created (default: MODEL_NAMESPACE)
            timeout: Maximum wait time in seconds (default: 60)
            subscription_name: Subscription that the policy must include, if supplied
            subscription_namespace: Subscription namespace (defaults to _ns())
    
        Raises:
            TimeoutError: If TRLP isn't created and enforced within timeout
        """
        trlp_name = f"maas-trlp-{model_ref}"
        expected_subscription = (
            f"{subscription_namespace or _ns()}/{subscription_name}" if subscription_name else None
        )
        last_snapshot = "not found"
        deadline = time.time() + timeout
        log.info(f"Waiting for TokenRateLimitPolicy {trlp_name} in {model_namespace} (timeout: {timeout}s)...")
    
        while time.time() &lt; deadline:
            result = subprocess.run(
                ["oc", "get", "tokenratelimitpolicy", trlp_name, "-n", model_namespace, "-o", "json"],
                capture_output=True,
                text=True,
                timeout=30,
            )
            if result.returncode == 0:
                try:
                    trlp = json.loads(result.stdout)
                    metadata = trlp.get("metadata", {})
                    status = trlp.get("status", {})
                    generation = metadata.get("generation")
                    observed = status.get("observedGeneration")
                    conditions = status.get("conditions", [])
                    enforced = next((c for c in conditions if c.get("type") == "Enforced"), None)
                    subscriptions = {
                        name.strip()
                        for name in metadata.get("annotations", {}).get(
                            "maas.opendatahub.io/subscriptions", ""
                        ).split(",")
                    }
                    includes_subscription = expected_subscription is None or expected_subscription in subscriptions
                    last_snapshot = (
                        f"generation={generation}, observedGeneration={observed}, "
                        f"Enforced={enforced}, includes_subscription={includes_subscription}"
                    )
                    if (
                        enforced and enforced.get("status") == "True"
                        and generation is not None and observed == generation
                        and includes_subscription
                    ):
                        log.info(f"TokenRateLimitPolicy {trlp_name} generation {generation} is enforced")
                        return
                    log.debug(f"TokenRateLimitPolicy {trlp_name} is not ready: {last_snapshot}")
                except (json.JSONDecodeError, KeyError) as e:
                    log.debug(f"Failed to parse TRLP status: {e}")
            elif _is_not_found_error(result.stderr):
                log.debug(f"TokenRateLimitPolicy {trlp_name} not found yet...")
            elif _is_transient_kubectl_error(result.stderr):
                log.debug(
                    f"Transient error while reading TokenRateLimitPolicy {trlp_name}: {result.stderr.strip()}"
                )
            else:
                raise RuntimeError(
                    f"Failed to get TokenRateLimitPolicy {trlp_name} in namespace '{model_namespace}': "
                    f"{result.stderr.strip()}"
                )
            time.sleep(3)
    
&gt;       raise TimeoutError(
            f"TokenRateLimitPolicy {trlp_name} was not created and enforced in {model_namespace} within {timeout}s: {last_snapshot}"
        )
E       TimeoutError: TokenRateLimitPolicy maas-trlp-simulator-w5-5bf55a was not created and enforced in e2e-models-e2e-worker-w5-5bf55a within 300s: generation=3, observedGeneration=3, Enforced={'lastTransitionTime': '2026-10-29T22:54:16Z', 'message': 'TokenRateLimitPolicy waiting for the following components to sync: [Limitador]', 'reason': 'Unknown', 'status': 'False', 'type': 'Enforced'}, includes_subscription=True

test/maas-e2e/test/e2e/tests/test_helper.py:1538: TimeoutError</failure></testcase><testcase classname="tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_multiple_subscriptions_separate_keys_gets_200" time="205.729"><failure message="TimeoutError: TokenRateLimitPolicy maas-trlp-simulator-w1-20f88f was not created and enforced in e2e-models-e2e-worker-w1-20f88f within 180s: generation=5, observedGeneration=5, Enforced={'lastTransitionTime': '2026-10-29T22:54:06Z', 'message': 'TokenRateLimitPolicy waiting for the following components to sync: [Limitador]', 'reason': 'Unknown', 'status': 'False', 'type': 'Enforced'}, includes_subscription=True">self = &lt;test_subscription.TestE2ESubscriptionFlow object at 0x7f394e508790&gt;

    def test_e2e_multiple_subscriptions_separate_keys_gets_200(self):
        """
        User with two subscriptions for the same model: mint one API key per subscription;
        each key succeeds on inference without x-maas-subscription.
        """
        ns = _ns()
        auth_policy_name = "e2e-test-auth-multi-sub-valid"
        subscription_1 = "e2e-test-subscription-free"
        subscription_2 = "e2e-test-subscription-premium"
        sa_name = "e2e-sa-multi-sub-valid"
    
        try:
            # Create service account and get OC token for maas-api
            oc_token = _create_sa_token(sa_name, namespace=ns)
            sa_user = _sa_to_user(sa_name, namespace=ns)
    
            # Create test resources with 2 subscriptions for the same user
            _create_test_auth_policy(auth_policy_name, MODEL_REF, users=[sa_user])
            _create_test_subscription(subscription_1, MODEL_REF, users=[sa_user], token_limit=100)
            _create_test_subscription(subscription_2, MODEL_REF, users=[sa_user], token_limit=1000)
    
            _wait_for_maas_auth_policy_phase(auth_policy_name, require_enforced=False)
&gt;           _wait_for_subscription_inference_ready(
                subscription_1,
                MODEL_REF,
                model_namespace=MODEL_NAMESPACE,
                timeout=180,
            )

test/maas-e2e/test/e2e/tests/test_subscription.py:2089: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
test/maas-e2e/test/e2e/tests/test_helper.py:1781: in _wait_for_subscription_inference_ready
    _wait_for_token_rate_limit_policy(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

model_ref = 'simulator-w1-20f88f'
model_namespace = 'e2e-models-e2e-worker-w1-20f88f', timeout = 180
subscription_name = 'e2e-test-subscription-free'
subscription_namespace = 'ai-tenant-e2e-worker-w1-20f88f'

    def _wait_for_token_rate_limit_policy(
        model_ref, model_namespace=MODEL_NAMESPACE, timeout=60, *, subscription_name=None, subscription_namespace=None
    ):
        """Wait for the current TokenRateLimitPolicy generation to be enforced.
    
        If a subscription is supplied, wait until the policy includes it. This
        prevents accepting the old policy before the controller updates its spec.
    
        Args:
            model_ref: Name of the model (e.g., "e2e-distinct-simulated")
            model_namespace: Namespace where the TRLP should be created (default: MODEL_NAMESPACE)
            timeout: Maximum wait time in seconds (default: 60)
            subscription_name: Subscription that the policy must include, if supplied
            subscription_namespace: Subscription namespace (defaults to _ns())
    
        Raises:
            TimeoutError: If TRLP isn't created and enforced within timeout
        """
        trlp_name = f"maas-trlp-{model_ref}"
        expected_subscription = (
            f"{subscription_namespace or _ns()}/{subscription_name}" if subscription_name else None
        )
        last_snapshot = "not found"
        deadline = time.time() + timeout
        log.info(f"Waiting for TokenRateLimitPolicy {trlp_name} in {model_namespace} (timeout: {timeout}s)...")
    
        while time.time() &lt; deadline:
            result = subprocess.run(
                ["oc", "get", "tokenratelimitpolicy", trlp_name, "-n", model_namespace, "-o", "json"],
                capture_output=True,
                text=True,
                timeout=30,
            )
            if result.returncode == 0:
                try:
                    trlp = json.loads(result.stdout)
                    metadata = trlp.get("metadata", {})
                    status = trlp.get("status", {})
                    generation = metadata.get("generation")
                    observed = status.get("observedGeneration")
                    conditions = status.get("conditions", [])
                    enforced = next((c for c in conditions if c.get("type") == "Enforced"), None)
                    subscriptions = {
                        name.strip()
                        for name in metadata.get("annotations", {}).get(
                            "maas.opendatahub.io/subscriptions", ""
                        ).split(",")
                    }
                    includes_subscription = expected_subscription is None or expected_subscription in subscriptions
                    last_snapshot = (
                        f"generation={generation}, observedGeneration={observed}, "
                        f"Enforced={enforced}, includes_subscription={includes_subscription}"
                    )
                    if (
                        enforced and enforced.get("status") == "True"
                        and generation is not None and observed == generation
                        and includes_subscription
                    ):
                        log.info(f"TokenRateLimitPolicy {trlp_name} generation {generation} is enforced")
                        return
                    log.debug(f"TokenRateLimitPolicy {trlp_name} is not ready: {last_snapshot}")
                except (json.JSONDecodeError, KeyError) as e:
                    log.debug(f"Failed to parse TRLP status: {e}")
            elif _is_not_found_error(result.stderr):
                log.debug(f"TokenRateLimitPolicy {trlp_name} not found yet...")
            elif _is_transient_kubectl_error(result.stderr):
                log.debug(
                    f"Transient error while reading TokenRateLimitPolicy {trlp_name}: {result.stderr.strip()}"
                )
            else:
                raise RuntimeError(
                    f"Failed to get TokenRateLimitPolicy {trlp_name} in namespace '{model_namespace}': "
                    f"{result.stderr.strip()}"
                )
            time.sleep(3)
    
&gt;       raise TimeoutError(
            f"TokenRateLimitPolicy {trlp_name} was not created and enforced in {model_namespace} within {timeout}s: {last_snapshot}"
        )
E       TimeoutError: TokenRateLimitPolicy maas-trlp-simulator-w1-20f88f was not created and enforced in e2e-models-e2e-worker-w1-20f88f within 180s: generation=5, observedGeneration=5, Enforced={'lastTransitionTime': '2026-10-29T22:54:06Z', 'message': 'TokenRateLimitPolicy waiting for the following components to sync: [Limitador]', 'reason': 'Unknown', 'status': 'False', 'type': 'Enforced'}, includes_subscription=True

test/maas-e2e/test/e2e/tests/test_helper.py:1538: TimeoutError</failure></testcase><testcase classname="tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_nonexistent_subscription_errors" time="10.788" /><testcase classname="tests.test_subscription.TestDegradedSubscriptionFiltering" name="test_models_endpoint_with_degraded_subscription_kube_token" time="14.093" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_subscription_active_status_with_valid_model" time="107.928" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_authpolicy_active_status_with_valid_model" time="96.742" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_authpolicy_degraded_status_with_partial_models" time="101.657" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_authpolicy_failed_status_with_missing_model" time="3.336" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_subscription_status_transitions_on_model_deletion" time="28.576" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptions" name="test_subscription_includes_model_refs" time="16.411" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_subscription_failed_status_with_missing_model" time="11.268" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptions" name="test_model_ref_display_name_and_description_enriched" time="12.704" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptions" name="test_unauthenticated_returns_401[all-subscriptions]" time="79.457" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptions" name="test_unauthenticated_returns_401[subscriptions-for-model]" time="0.059" /><testcase classname="tests.test_subscription.TestStatusReporting" name="test_subscription_degraded_status_with_partial_models" time="108.964" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptionsForModel" name="test_unknown_model_returns_empty" time="5.592" /><testcase classname="tests.test_subscription_list_endpoints.TestSubscriptionModelAccessFiltering" name="test_omits_subscription_with_no_authorized_models" time="14.343" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_empty_subscription_header_value" time="6.206" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_deduplication_same_model_multiple_refs" time="25.699" /><testcase classname="tests.test_subscription_list_endpoints.TestSubscriptionModelAccessFiltering" name="test_filters_unauthorized_models" time="14.331" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptions" name="test_returns_accessible_subscriptions" time="5.692" /><testcase classname="tests.test_subscription_list_endpoints.TestListSubscriptionsForModel" name="test_returns_subscriptions_for_model" time="31.108" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_multiple_distinct_models_in_subscription" time="14.997" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_response_schema_and_metadata" time="5.997" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_api_key_with_inaccessible_subscription_403" time="12.672" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_user_token_with_subscription_header_filters" time="17.619" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_user_token_returns_all_models" time="25.387" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_api_key_with_deleted_subscription_403" time="43.504" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_access_denied_to_subscription_403" time="31.368" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_invalid_subscription_header_403" time="16.218" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_api_key_ignores_subscription_header" time="25.675" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_service_account_token_multiple_subs_with_header" time="54.609" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_api_key_scoped_to_subscription" time="30.984" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_service_account_token_multiple_subs_no_header" time="30.641" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_unauthenticated_request_401" time="0.091" /><testcase classname="tests.test_smoke" name="test_chat_completions_gateway_alive" time="0.680" /><testcase classname="tests.test_smoke" name="test_chat_completions_streaming_sse" time="0.230" /><testcase classname="tests.test_smoke" name="test_legacy_completions_optionally" time="0.156" /><testcase classname="tests.test_tenant.TestTenantLifecycle" name="test_tenant_ready_and_phase_healthy" time="0.460" /><testcase classname="tests.test_models_endpoint.TestModelsEndpoint" name="test_multiple_api_keys_different_subscriptions" time="42.307" /><testcase classname="tests.test_tenant.TestTenantContract" name="test_status_has_phase_and_conditions" time="0.145" /><testcase classname="tests.test_tenant.TestTenantContract" name="test_conditions_use_kubernetes_metav1_shape" time="0.150" /><testcase classname="tests.test_tenant.TestTenantNoFalseOwnership" name="test_maas_user_crs_not_owned_by_tenant" time="0.467" /><testcase classname="tests.test_config_tenant.TestConfigAnchorPresence" name="test_cluster_config_default_exists" time="0.570" /><testcase classname="tests.test_config_tenant.TestConfigAnchorPresence" name="test_cluster_config_not_terminating" time="0.197" /><testcase classname="tests.test_config_tenant.TestConfigTenantOwnership" name="test_default_aitenant_lists_config_owner_reference" time="0.159" /><testcase classname="tests.test_config_tenant.TestConfigTenantOwnership" name="test_tenant_config_lists_config_owner_reference" time="0.158" /><testcase classname="tests.test_config_tenant.TestConfigTenantOwnership" name="test_maas_controller_deployment_does_not_list_config_owner_reference" time="0.171" /><testcase classname="tests.test_tenant_discovery" name="test_tenant_discovery_requires_auth" time="4.727" /><testcase classname="tests.test_smoke" name="test_healthz_or_404" time="0.036" /><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_discovery" name="test_tenant_discovery_gateway_matches_deployment" time="0.000"><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.038" /><testcase classname="tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_default_aitenant_bootstraps_maas_tenant_config_without_gateway_mutation" time="2.183" /><testcase classname="tests.test_tenant_discovery" name="test_tenant_discovery_with_invalid_token" time="1.961" /><testcase classname="tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_aitenant_rejected_outside_ai_tenants_namespace" time="8.351" /><testcase classname="tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_aitenant_create_bootstrap_resources" time="60.740" /><testcase classname="tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_aitenant_migrates_and_removes_legacy_tenant" time="78.799" /><testcase classname="tests.test_subscription.TestDegradedSubscriptionFiltering" name="test_models_endpoint_with_degraded_subscription_api_key" time="14.572" /><testcase classname="tests.test_smoke" name="test_models_catalog" time="0.148" /><testcase classname="tests.test_tenant_namespace_discovery.TestTenantNamespaceDiscovery" name="test_label_removal_stops_reconciliation" time="117.809" /><testcase classname="tests.test_smoke" name="test_tokens_endpoint_replaced_by_api_keys" time="2.065"><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.677b11485a60f69c1844.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_namespace_discovery.TestTenantNamespaceDiscovery" name="test_labeled_tenant_namespace_is_discovered" time="103.137" /><testcase classname="tests.test_tenant_namespace_discovery.TestTenantNamespaceDiscovery" name="test_dynamic_discovery_after_label_added" time="142.333" /><testcase classname="tests.test_tenant.TestTenantContract" name="test_spec_is_well_formed" time="47.979" /><testcase classname="tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_aitenant_delete_cleans_maas_resources_and_preserves_user_objects" time="113.323" /><testcase classname="tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_aitenant_derives_non_default_tenant_namespace" time="103.907" /><testcase classname="tests.test_subscription.TestDegradedSubscriptionFiltering" name="test_degraded_healthy_model_allows_inference" time="54.318" /><testcase classname="tests.test_tenant_namespace_discovery.TestTenantNamespaceDiscovery" name="test_per_tenant_oidc_configuration" time="49.976"><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.TestTenantNamespaceDiscovery" name="test_unlabeled_namespace_ignored" time="142.982" /></testsuite></testsuites>