<?xml version="1.0" encoding="utf-8"?><testsuites name="pytest tests"><testsuite name="pytest" errors="0" failures="4" skipped="3" tests="154" time="1336.995" timestamp="2026-06-14T23:04:06.036288+00:00" hostname="maas-group-test-svnt7-e2e-maas-openshift-pod"><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_create_api_key" time="0.103" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_list_api_keys" time="0.134" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyCRUD" name="test_revoke_api_key" time="0.096" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyAuthorization" name="test_admin_manage_other_users_keys" time="0.133" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyAuthorization" name="test_non_admin_cannot_access_other_users_keys" time="0.091" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_own_keys" time="0.287" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_other_user_forbidden" time="0.032" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyBulkOperations" name="test_bulk_revoke_admin_can_revoke_any_user" time="0.093" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_within_expiration_limit" time="0.032" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_at_expiration_limit" time="0.030" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_exceeds_expiration_limit" time="0.030" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_without_expiration" time="0.031" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyExpiration" name="test_create_key_with_short_expiration" time="0.033" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_model_access_success" time="0.112" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_invalid_api_key_rejected" time="0.023" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_no_auth_header_rejected" time="0.019" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_revoked_api_key_rejected" time="2.131" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyModelInference" name="test_api_key_chat_completions" time="0.030" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_double_revoke_returns_404" time="0.098" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_nonexistent_key_returns_404" time="0.031" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_then_create_new_key_works" time="0.158" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_individual_revoke_multiple_keys" time="0.197" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeyRevocationE2E" name="test_revoke_keys_rejected_at_gateway" time="0.310" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_cronjob_exists_and_configured" time="0.108" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_cleanup_networkpolicy_exists" time="0.104" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_create_ephemeral_key" time="0.104" /><testcase classname="test.e2e.tests.test_api_keys.TestEphemeralKeyCleanup" name="test_trigger_cleanup_preserves_active_keys" time="0.447" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_active_subscription" time="9.226" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_degraded_subscription" time="19.144" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_failed_subscription" time="19.259" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_create_key_for_pending_subscription" time="19.291" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionPhases" name="test_reject_key_for_unreconciled_subscription" time="24.383" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_filters_by_subscription" time="10.129" /><testcase classname="test.e2e.tests.test_api_keys.TestAPIKeySubscriptionFilter" name="test_search_without_subscription_returns_all" time="0.183" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSAPIWatchNamespace" name="test_subscription_in_subscription_namespace_visible_to_api" time="8.512" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSAPIWatchNamespace" name="test_subscription_in_another_namespace_not_visible_to_api" time="27.768" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSControllerWatchNamespace" name="test_authpolicy_and_subscription_in_maas_subscription_namespace" time="24.063" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestMaaSControllerWatchNamespace" name="test_authpolicy_and_subscription_in_another_namespace" time="35.202" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestModelRef" name="test_auth_policy_model_ref" time="30.871" /><testcase classname="test.e2e.tests.test_namespace_scoping.TestModelRef" name="test_subscription_model_ref" time="30.787" /><testcase classname="test.e2e.tests.test_negative_security.TestHeaderSpoofing" name="test_injected_identity_headers_ignored" time="0.089" /><testcase classname="test.e2e.tests.test_negative_security.TestHeaderSpoofing" name="test_duplicate_subscription_headers_ignored" time="0.075" /><testcase classname="test.e2e.tests.test_negative_security.TestExpiredKeyRejection" name="test_expired_key_rejected_at_gateway" time="5.092" /><testcase classname="test.e2e.tests.test_negative_security.TestCrossModelAccess" name="test_key_cannot_access_model_outside_subscription" time="0.071" /><testcase classname="test.e2e.tests.test_negative_security.TestAuthPolicyRemoval" name="test_authpolicy_deletion_revokes_access" time="0.776" /><testcase classname="test.e2e.tests.test_negative_security.TestMissingModelRef" name="test_subscription_with_nonexistent_model_ref" time="0.990" /><testcase classname="test.e2e.tests.test_negative_security.TestMissingModelRef" name="test_authpolicy_with_nonexistent_model_ref" time="0.640" /><testcase classname="test.e2e.tests.test_negative_security.TestHeaderAbuse" name="test_special_characters_in_subscription_header" time="0.163" /><testcase classname="test.e2e.tests.test_negative_security.TestWebhookValidation" name="test_subscription_rejected_in_unlabeled_namespace" time="5.915" /><testcase classname="test.e2e.tests.test_negative_security.TestWebhookValidation" name="test_authpolicy_rejected_in_unlabeled_namespace" time="5.862" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_authorized_user_gets_200" time="0.079" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_no_auth_gets_401" time="0.020" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_invalid_token_gets_403" time="0.043" /><testcase classname="test.e2e.tests.test_subscription.TestAuthEnforcement" name="test_wrong_group_gets_403" time="0.023" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_uses_highest_priority_subscription" time="0.308" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_with_explicit_simulator_subscription" time="0.062" /><testcase classname="test.e2e.tests.test_subscription.TestAPIKeySubscriptionBinding" name="test_create_api_key_nonexistent_subscription_errors" time="0.248" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_subscribed_user_gets_200" time="0.032" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_auth_pass_no_subscription_gets_403" time="16.407" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_rate_limit_exhaustion_gets_429" time="25.578" /><testcase classname="test.e2e.tests.test_subscription.TestSubscriptionEnforcement" name="test_models_endpoint_exempt_from_rate_limiting" time="25.243" /><testcase classname="test.e2e.tests.test_subscription.TestMultipleSubscriptionsPerModel" name="test_user_in_one_of_two_subscriptions_gets_200" time="8.386" /><testcase classname="test.e2e.tests.test_subscription.TestMultipleAuthPoliciesPerModel" name="test_two_auth_policies_or_logic" time="16.778" /><testcase classname="test.e2e.tests.test_subscription.TestMultipleAuthPoliciesPerModel" name="test_delete_one_auth_policy_other_still_works" time="24.538" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_delete_subscription_rebuilds_trlp" time="8.531" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_trlp_persists_during_multi_subscription_deletion" time="33.311" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_delete_last_subscription_denies_access" time="8.597" /><testcase classname="test.e2e.tests.test_subscription.TestCascadeDeletion" name="test_unconfigured_model_denied_by_gateway_auth" time="0.468" /><testcase classname="test.e2e.tests.test_subscription.TestOrderingEdgeCases" name="test_subscription_before_auth_policy" time="29.677" /><testcase classname="test.e2e.tests.test_subscription.TestManagedAnnotation" name="test_authpolicy_managed_false_prevents_update" time="8.230"><skipped type="pytest.skip" message="gateway-only mode: per-model AuthPolicy is not created">/workspace/source/test/e2e/tests/test_subscription.py:1040: gateway-only mode: per-model AuthPolicy is not created</skipped></testcase><testcase classname="test.e2e.tests.test_subscription.TestManagedAnnotation" name="test_trlp_managed_false_prevents_update" time="20.667" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_both_access_and_subscription_gets_200" time="9.619" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_access_but_no_subscription_gets_403" time="17.155" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_with_subscription_but_no_access_gets_403" time="9.565" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_single_subscription_auto_selects" time="17.497" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_multiple_subscriptions_separate_keys_gets_200" time="17.451" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_mint_api_key_denied_for_inaccessible_subscription" time="17.681" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_group_based_access_gets_200" time="17.089" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_group_based_auth_but_no_subscription_gets_403" time="17.190" /><testcase classname="test.e2e.tests.test_subscription.TestE2ESubscriptionFlow" name="test_e2e_group_based_subscription_but_no_auth_gets_403" time="9.275" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_subscription_active_status_with_valid_model" time="9.166" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_subscription_failed_status_with_missing_model" time="8.776" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_authpolicy_active_status_with_valid_model" time="8.738" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_authpolicy_failed_status_with_missing_model" time="8.747" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_subscription_degraded_status_with_partial_models" time="9.088" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_subscription_degraded_trlp_blocks_inference" time="93.113" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_authpolicy_degraded_status_with_partial_models" time="8.747" /><testcase classname="test.e2e.tests.test_subscription.TestStatusReporting" name="test_subscription_status_transitions_on_model_deletion" time="20.054" /><testcase classname="test.e2e.tests.test_subscription.TestDegradedSubscriptionFiltering" name="test_degraded_healthy_model_allows_inference" time="19.175" /><testcase classname="test.e2e.tests.test_subscription.TestDegradedSubscriptionFiltering" name="test_failed_subscription_blocks_inference" time="19.456" /><testcase classname="test.e2e.tests.test_subscription.TestDegradedSubscriptionFiltering" name="test_models_endpoint_with_degraded_subscription_api_key" time="19.216" /><testcase classname="test.e2e.tests.test_subscription.TestDegradedSubscriptionFiltering" name="test_models_endpoint_with_degraded_subscription_kube_token" time="19.222" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_single_subscription_auto_select" time="42.150" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_explicit_subscription_header" time="16.728" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_empty_subscription_header_value" time="8.427" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_models_filtered_by_subscription" time="8.789" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_deduplication_same_model_multiple_refs" time="17.169" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_different_modelrefs_same_model_id" time="17.198" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_multiple_distinct_models_in_subscription" time="21.416"><failure message="AssertionError: Expected to find both distinct models {'test/e2e-distinct-model', 'test/e2e-distinct-model-2'}, but got {'test/e2e-distinct-model'}&#10;assert {'test/e2e-distinct-model'} == {'test/e2e-di...inct-model-2'}&#10;  &#10;  Extra items in the right set:&#10;  'test/e2e-distinct-model-2'&#10;  &#10;  Full diff:&#10;    {&#10;        'test/e2e-distinct-model',&#10;  -     'test/e2e-distinct-model-2',&#10;    }">self = &lt;test_models_endpoint.TestModelsEndpoint object at 0x7eff74d187c0&gt;

    def test_multiple_distinct_models_in_subscription(self):
        """
        Test 8: Multiple distinct models should return exactly 2 entries (1 per unique ID).
    
        Uses pre-deployed models (both known to not have backend duplication issues):
        - DISTINCT_MODEL_REF (simulated-distinct) serving "test/e2e-distinct-model"
        - DISTINCT_MODEL_2_REF (simulated-distinct-2) serving "test/e2e-distinct-model-2"
    
        Creates a subscription with both models. The API should return exactly 2 entries
        (one for each distinct model ID), with no duplicates.
    
        This test validates that when backend models don't have duplication bugs, the
        API correctly returns one entry per distinct model ID.
        """
        log.info("Test 8: Multiple distinct models should return 2 entries")
    
        sa_name = "e2e-models-distinct-sa"
        sa_ns = "default"
        maas_ns = _ns()
        subscription_name = "e2e-distinct-models-subscription"
        auth_policy_name = "e2e-distinct-models-auth"
        api_key = None
    
        try:
            # Create SA
            sa_token = _create_sa_token(sa_name, namespace=sa_ns)
            sa_user = _sa_to_user(sa_name, namespace=sa_ns)
    
            # Create auth policy with both distinct models
            log.info(f"Creating auth policy with {DISTINCT_MODEL_REF} and {DISTINCT_MODEL_2_REF}")
            auth_policy_cr = {
                "apiVersion": "maas.opendatahub.io/v1alpha1",
                "kind": "MaaSAuthPolicy",
                "metadata": {
                    "name": auth_policy_name,
                    "namespace": maas_ns,
                },
                "spec": {
                    "modelRefs": [
                        {"name": DISTINCT_MODEL_REF, "namespace": MODEL_NAMESPACE},
                        {"name": DISTINCT_MODEL_2_REF, "namespace": MODEL_NAMESPACE},
                    ],
                    "subjects": {
                        "users": [sa_user],
                        "groups": [],
                    },
                },
            }
            subprocess.run(
                ["oc", "apply", "-f", "-"],
                input=json.dumps(auth_policy_cr),
                text=True,
                check=True,
            )
    
            # Create subscription with both distinct models
            log.info(f"Creating subscription with {DISTINCT_MODEL_REF} and {DISTINCT_MODEL_2_REF}")
            subscription_cr = {
                "apiVersion": "maas.opendatahub.io/v1alpha1",
                "kind": "MaaSSubscription",
                "metadata": {
                    "name": subscription_name,
                    "namespace": maas_ns,
                },
                "spec": {
                    "owner": {
                        "users": [sa_user],
                        "groups": [],
                    },
                    "modelRefs": [
                        {
                            "name": DISTINCT_MODEL_REF,
                            "namespace": MODEL_NAMESPACE,
                            "tokenRateLimits": [{"limit": 100, "window": "1m"}],
                        },
                        {
                            "name": DISTINCT_MODEL_2_REF,
                            "namespace": MODEL_NAMESPACE,
                            "tokenRateLimits": [{"limit": 100, "window": "1m"}],
                        },
                    ],
                },
            }
            subprocess.run(
                ["oc", "apply", "-f", "-"],
                input=json.dumps(subscription_cr),
                text=True,
                check=True,
            )
    
            # Wait for subscription to reconcile before creating API key
            _wait_for_maas_subscription_phase(subscription_name, namespace=maas_ns)
    
            # Create API key bound to our test subscription
            api_key = _create_api_key(sa_token, name="e2e-distinct-models-test-key", subscription=subscription_name)
    
            _wait_reconcile()
    
            # Query /v1/models (use retry helper for gateway/Authorino propagation)
            log.info(f"Querying /v1/models with subscription: {subscription_name}")
            r = _request_with_gateway_retry(
                requests.get,
                f"{_maas_api_url()}/v1/models",
                headers={
                    "Authorization": f"Bearer {api_key}",
                    "x-maas-subscription": subscription_name,
                },
            )
    
            assert r.status_code == 200, f"Expected 200, got {r.status_code}: {r.text}"
            data = r.json()
            models = data.get("data") or []
    
            assert isinstance(models, list), "Models should be a list"
    
            # Get model IDs from response
            model_ids = [m["id"] for m in models]
            unique_ids = set(model_ids)
    
            log.info(f"#x1F4CA API Response: {len(models)} total model(s), {len(unique_ids)} unique ID(s)")
            log.info(f"   Model IDs: {model_ids}")
            log.info(f"   Unique IDs: {unique_ids}")
            log.info(f"   Subscription had: 2 modelRefs ({DISTINCT_MODEL_REF}, {DISTINCT_MODEL_2_REF})")
    
            # Verify we got BOTH expected model IDs
            expected_ids = {DISTINCT_MODEL_ID, DISTINCT_MODEL_2_ID}
&gt;           assert unique_ids == expected_ids, \
                f"Expected to find both distinct models {expected_ids}, but got {unique_ids}"
E               AssertionError: Expected to find both distinct models {'test/e2e-distinct-model', 'test/e2e-distinct-model-2'}, but got {'test/e2e-distinct-model'}
E               assert {'test/e2e-distinct-model'} == {'test/e2e-di...inct-model-2'}
E                 
E                 Extra items in the right set:
E                 'test/e2e-distinct-model-2'
E                 
E                 Full diff:
E                   {
E                       'test/e2e-distinct-model',
E                 -     'test/e2e-distinct-model-2',
E                   }

test/e2e/tests/test_models_endpoint.py:1053: AssertionError</failure></testcase><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_user_token_returns_all_models" time="12.265" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_user_token_with_subscription_header_filters" time="17.051" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_empty_model_list" time="10.955" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_response_schema_matches_openapi" time="8.402" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_model_metadata_preserved" time="8.395" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_api_key_scoped_to_subscription" time="17.207" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_api_key_with_deleted_subscription_403" time="25.196" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_api_key_with_inaccessible_subscription_403" time="17.364" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_invalid_subscription_header_403" time="17.018" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_access_denied_to_subscription_403" time="17.682" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_api_key_ignores_subscription_header" time="22.167" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_multiple_api_keys_different_subscriptions" time="20.193"><failure message="AssertionError: Key2 should see test/e2e-distinct-model-2 from e2e-multi-keys-sub2&#10;assert 'test/e2e-distinct-model-2' in set()">self = &lt;test_models_endpoint.TestModelsEndpoint object at 0x7eff7528dca0&gt;

    def test_multiple_api_keys_different_subscriptions(self):
        """
        Test: Multiple API keys each bound to different subscriptions.
    
        Creates two API keys from the same user, each explicitly bound to a different
        subscription. Verifies each key returns only its bound subscription's models.
    
        Expected: Each API key returns models only from its bound subscription.
        """
        sa_name = "e2e-multi-keys-sa"
        sa_ns = "default"
        maas_ns = _ns()
        sub1_name = "e2e-multi-keys-sub1"
        sub2_name = "e2e-multi-keys-sub2"
        auth1_name = "e2e-multi-keys-auth1"
        auth2_name = "e2e-multi-keys-auth2"
        api_key1 = None
        api_key2 = None
    
        try:
            # Create SA
            sa_token = _create_sa_token(sa_name, namespace=sa_ns)
            sa_user = _sa_to_user(sa_name, namespace=sa_ns)
    
            # Create two subscriptions with different models
            log.info(f"Creating subscription 1 with {DISTINCT_MODEL_REF}")
            _create_test_auth_policy(auth1_name, DISTINCT_MODEL_REF, users=[sa_user])
            _create_test_subscription(sub1_name, DISTINCT_MODEL_REF, users=[sa_user])
    
            log.info(f"Creating subscription 2 with {DISTINCT_MODEL_2_REF}")
            _create_test_auth_policy(auth2_name, DISTINCT_MODEL_2_REF, users=[sa_user])
            _create_test_subscription(sub2_name, DISTINCT_MODEL_2_REF, users=[sa_user])
    
            # Wait for both subscriptions to reconcile before creating API keys
            _wait_for_maas_subscription_phase(sub1_name, namespace=maas_ns)
            _wait_for_maas_subscription_phase(sub2_name, namespace=maas_ns)
    
            # Create two API keys, each bound to a different subscription
            log.info(f"Creating API key 1 bound to {sub1_name}")
            api_key1_response = _request_with_gateway_retry(
                requests.post,
                f"{_maas_api_url()}/v1/api-keys",
                headers={"Authorization": f"Bearer {sa_token}", "Content-Type": "application/json"},
                json={"name": "key1", "subscription": sub1_name},
            )
            assert api_key1_response.status_code in (200, 201)
            api_key1 = api_key1_response.json().get("key")
            bound_sub1 = api_key1_response.json().get("subscription")
            assert bound_sub1 == sub1_name, f"Key 1 should be bound to {sub1_name}, got {bound_sub1}"
    
            log.info(f"Creating API key 2 bound to {sub2_name}")
            api_key2_response = _request_with_gateway_retry(
                requests.post,
                f"{_maas_api_url()}/v1/api-keys",
                headers={"Authorization": f"Bearer {sa_token}", "Content-Type": "application/json"},
                json={"name": "key2", "subscription": sub2_name},
            )
            assert api_key2_response.status_code in (200, 201)
            api_key2 = api_key2_response.json().get("key")
            bound_sub2 = api_key2_response.json().get("subscription")
            assert bound_sub2 == sub2_name, f"Key 2 should be bound to {sub2_name}, got {bound_sub2}"
    
            _wait_reconcile()
    
            # Test key1 - should return models from sub1 only
            log.info(f"Testing API key 1 (bound to {sub1_name})")
            r1 = requests.get(
                f"{_maas_api_url()}/v1/models",
                headers={"Authorization": f"Bearer {api_key1}"},
                timeout=TIMEOUT,
                verify=TLS_VERIFY,
            )
            assert r1.status_code == 200, f"Expected 200 for key1, got {r1.status_code}: {r1.text}"
            models1 = r1.json().get("data") or []
            model_ids1 = {m["id"] for m in models1}
    
            assert DISTINCT_MODEL_ID in model_ids1, f"Key1 should see {DISTINCT_MODEL_ID} from {sub1_name}"
            assert DISTINCT_MODEL_2_ID not in model_ids1, f"Key1 should NOT see {DISTINCT_MODEL_2_ID} from {sub2_name}"
    
            # Test key2 - should return models from sub2 only
            log.info(f"Testing API key 2 (bound to {sub2_name})")
            r2 = requests.get(
                f"{_maas_api_url()}/v1/models",
                headers={"Authorization": f"Bearer {api_key2}"},
                timeout=TIMEOUT,
                verify=TLS_VERIFY,
            )
            assert r2.status_code == 200, f"Expected 200 for key2, got {r2.status_code}: {r2.text}"
            models2 = r2.json().get("data") or []
            model_ids2 = {m["id"] for m in models2}
    
&gt;           assert DISTINCT_MODEL_2_ID in model_ids2, f"Key2 should see {DISTINCT_MODEL_2_ID} from {sub2_name}"
E           AssertionError: Key2 should see test/e2e-distinct-model-2 from e2e-multi-keys-sub2
E           assert 'test/e2e-distinct-model-2' in set()

test/e2e/tests/test_models_endpoint.py:1918: AssertionError</failure></testcase><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_service_account_token_multiple_subs_no_header" time="12.216"><failure message="AssertionError: Should see test/e2e-distinct-model-2 from e2e-sa-multi-no-hdr-sub2 (user access)&#10;assert 'test/e2e-distinct-model-2' in {'facebook/opt-125m', 'test/e2e-distinct-model'}">self = &lt;test_models_endpoint.TestModelsEndpoint object at 0x7eff752f27c0&gt;

    def test_service_account_token_multiple_subs_no_header(self):
        """
        Test: K8s token with access to multiple subscriptions returns all models (no header).
    
        Creates a service account with access to two subscriptions (via group and user).
        When querying without x-maas-subscription header, should return models from
        all accessible subscriptions.
    
        Expected: HTTP 200 with models from both subscriptions.
        """
        sa_name = "e2e-sa-multi-subs-no-header"
        sa_ns = "default"
        maas_ns = _ns()
        sub1_name = "e2e-sa-multi-no-hdr-sub1"
        sub2_name = "e2e-sa-multi-no-hdr-sub2"
        auth1_name = "e2e-sa-multi-no-hdr-auth1"
        auth2_name = "e2e-sa-multi-no-hdr-auth2"
    
        try:
            # Create SA
            sa_token = _create_sa_token(sa_name, namespace=sa_ns)
            sa_user = _sa_to_user(sa_name, namespace=sa_ns)
    
            # Create two subscriptions with different models
            # Sub1: Access via system:authenticated group
            log.info(f"Creating subscription 1 with {DISTINCT_MODEL_REF} (group: system:authenticated)")
            _create_test_auth_policy(auth1_name, DISTINCT_MODEL_REF, groups=["system:authenticated"])
            _create_test_subscription(sub1_name, DISTINCT_MODEL_REF, groups=["system:authenticated"])
    
            # Sub2: Access via specific user
            log.info(f"Creating subscription 2 with {DISTINCT_MODEL_2_REF} (user: {sa_user})")
            _create_test_auth_policy(auth2_name, DISTINCT_MODEL_2_REF, users=[sa_user])
            _create_test_subscription(sub2_name, DISTINCT_MODEL_2_REF, users=[sa_user])
    
            _wait_for_maas_auth_policy_phase(auth1_name)
            _wait_for_maas_auth_policy_phase(auth2_name)
            _wait_for_maas_subscription_phase(sub1_name)
            _wait_for_maas_subscription_phase(sub2_name)
    
            # Query with K8s token (no header)
            log.info("Querying /v1/models with K8s token (no header) - should return models from both subscriptions")
            r = _request_with_gateway_retry(
                requests.get,
                f"{_maas_api_url()}/v1/models",
                headers={"Authorization": f"Bearer {sa_token}"},
            )
    
            assert r.status_code == 200, f"Expected 200, got {r.status_code}: {r.text}"
            data = r.json()
            models = data.get("data") or []
            model_ids = {m["id"] for m in models}
    
            # Should see models from BOTH subscriptions
            assert DISTINCT_MODEL_ID in model_ids, \
                f"Should see {DISTINCT_MODEL_ID} from {sub1_name} (group access)"
&gt;           assert DISTINCT_MODEL_2_ID in model_ids, \
                f"Should see {DISTINCT_MODEL_2_ID} from {sub2_name} (user access)"
E               AssertionError: Should see test/e2e-distinct-model-2 from e2e-sa-multi-no-hdr-sub2 (user access)
E               assert 'test/e2e-distinct-model-2' in {'facebook/opt-125m', 'test/e2e-distinct-model'}

test/e2e/tests/test_models_endpoint.py:1986: AssertionError</failure></testcase><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_service_account_token_multiple_subs_with_header" time="12.243"><failure message="AssertionError: Should see test/e2e-distinct-model-2 from e2e-sa-multi-hdr-sub2&#10;assert 'test/e2e-distinct-model-2' in set()">self = &lt;test_models_endpoint.TestModelsEndpoint object at 0x7eff74d18af0&gt;

    def test_service_account_token_multiple_subs_with_header(self):
        """
        Test: K8s token with access to multiple subscriptions filters by header.
    
        Creates a service account with access to two subscriptions. When querying
        with x-maas-subscription header, should return models from only the specified
        subscription.
    
        Expected: HTTP 200 with models from only the specified subscription.
        """
        sa_name = "e2e-sa-multi-subs-with-header"
        sa_ns = "default"
        maas_ns = _ns()
        sub1_name = "e2e-sa-multi-hdr-sub1"
        sub2_name = "e2e-sa-multi-hdr-sub2"
        auth1_name = "e2e-sa-multi-hdr-auth1"
        auth2_name = "e2e-sa-multi-hdr-auth2"
    
        try:
            # Create SA
            sa_token = _create_sa_token(sa_name, namespace=sa_ns)
            sa_user = _sa_to_user(sa_name, namespace=sa_ns)
    
            # Create two subscriptions with different models
            log.info(f"Creating subscription 1 with {DISTINCT_MODEL_REF}")
            _create_test_auth_policy(auth1_name, DISTINCT_MODEL_REF, users=[sa_user])
            _create_test_subscription(sub1_name, DISTINCT_MODEL_REF, users=[sa_user])
    
            log.info(f"Creating subscription 2 with {DISTINCT_MODEL_2_REF}")
            _create_test_auth_policy(auth2_name, DISTINCT_MODEL_2_REF, users=[sa_user])
            _create_test_subscription(sub2_name, DISTINCT_MODEL_2_REF, users=[sa_user])
    
            _wait_for_maas_auth_policy_phase(auth1_name)
            _wait_for_maas_auth_policy_phase(auth2_name)
            _wait_for_maas_subscription_phase(sub1_name)
            _wait_for_maas_subscription_phase(sub2_name)
    
            # Query with K8s token and header specifying sub1
            log.info(f"Querying /v1/models with K8s token and header: {sub1_name}")
            r1 = _request_with_gateway_retry(
                requests.get,
                f"{_maas_api_url()}/v1/models",
                headers={
                    "Authorization": f"Bearer {sa_token}",
                    "x-maas-subscription": sub1_name,
                },
            )
    
            assert r1.status_code == 200, f"Expected 200, got {r1.status_code}: {r1.text}"
            models1 = r1.json().get("data") or []
            model_ids1 = {m["id"] for m in models1}
    
            # Should see only models from sub1
            assert DISTINCT_MODEL_ID in model_ids1, f"Should see {DISTINCT_MODEL_ID} from {sub1_name}"
            assert DISTINCT_MODEL_2_ID not in model_ids1, f"Should NOT see {DISTINCT_MODEL_2_ID} from {sub2_name}"
    
            # Query with K8s token and header specifying sub2
            log.info(f"Querying /v1/models with K8s token and header: {sub2_name}")
            r2 = _request_with_gateway_retry(
                requests.get,
                f"{_maas_api_url()}/v1/models",
                headers={
                    "Authorization": f"Bearer {sa_token}",
                    "x-maas-subscription": sub2_name,
                },
            )
    
            assert r2.status_code == 200, f"Expected 200, got {r2.status_code}: {r2.text}"
            models2 = r2.json().get("data") or []
            model_ids2 = {m["id"] for m in models2}
    
            # Should see only models from sub2
&gt;           assert DISTINCT_MODEL_2_ID in model_ids2, f"Should see {DISTINCT_MODEL_2_ID} from {sub2_name}"
E           AssertionError: Should see test/e2e-distinct-model-2 from e2e-sa-multi-hdr-sub2
E           assert 'test/e2e-distinct-model-2' in set()

test/e2e/tests/test_models_endpoint.py:2071: AssertionError</failure></testcase><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_unauthenticated_request_401" time="0.046" /><testcase classname="test.e2e.tests.test_models_endpoint.TestModelsEndpoint" name="test_central_models_endpoint_exempt_from_rate_limiting" time="25.557" /><testcase classname="test.e2e.tests.test_external_models.TestExternalModelDiscovery" name="test_maasmodelref_created" time="3.036" /><testcase classname="test.e2e.tests.test_external_models.TestExternalModelDiscovery" name="test_reconciler_created_httproute" time="0.106" /><testcase classname="test.e2e.tests.test_external_models.TestExternalModelDiscovery" name="test_reconciler_created_backend_service" time="0.113" /><testcase classname="test.e2e.tests.test_external_models.TestExternalModelAuth" name="test_invalid_key_returns_401" time="0.044" /><testcase classname="test.e2e.tests.test_external_models.TestExternalModelAuth" name="test_no_key_returns_401" time="0.019" /><testcase classname="test.e2e.tests.test_external_models.TestExternalModelEgress" name="test_request_forwarded_returns_200" time="0.046" /><testcase classname="test.e2e.tests.test_external_models.TestExternalModelCleanup" name="test_delete_removes_httproute" time="37.495" /><testcase classname="test.e2e.tests.test_tenant.TestTenantLifecycle" name="test_tenant_ready_and_phase_healthy" time="0.309" /><testcase classname="test.e2e.tests.test_tenant.TestTenantLifecycle" name="test_payload_processing_deployed_with_active_tenant" time="0.106"><skipped type="pytest.skip" message="Tenant not Active (e.g. Degraded); payload-processing not asserted">/workspace/source/test/e2e/tests/test_tenant.py:127: Tenant not Active (e.g. Degraded); payload-processing not asserted</skipped></testcase><testcase classname="test.e2e.tests.test_tenant.TestTenantContract" name="test_status_has_phase_and_conditions" time="0.103" /><testcase classname="test.e2e.tests.test_tenant.TestTenantContract" name="test_spec_is_well_formed" time="0.102" /><testcase classname="test.e2e.tests.test_tenant.TestTenantContract" name="test_conditions_use_kubernetes_metav1_shape" time="0.105" /><testcase classname="test.e2e.tests.test_tenant.TestTenantNoFalseOwnership" name="test_maas_user_crs_not_owned_by_tenant" time="0.313" /><testcase classname="test.e2e.tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_aitenant_create_bootstrap_resources" time="12.630" /><testcase classname="test.e2e.tests.test_aitenant_lifecycle.TestAITenantLifecycle" name="test_aitenant_delete_cleans_up_bootstrap_resources" time="13.356" /><testcase classname="test.e2e.tests.test_config_tenant.TestConfigAnchorPresence" name="test_cluster_config_default_exists" time="0.376" /><testcase classname="test.e2e.tests.test_config_tenant.TestConfigAnchorPresence" name="test_cluster_config_not_terminating" time="0.129" /><testcase classname="test.e2e.tests.test_config_tenant.TestConfigTenantOwnership" name="test_tenant_lists_config_owner_reference" time="0.105" /><testcase classname="test.e2e.tests.test_config_tenant.TestConfigTenantOwnership" name="test_maas_controller_deployment_lists_config_owner_reference" time="0.110" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCTokenFlow" name="test_oidc_token_can_create_api_key" time="0.115" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCTokenFlow" name="test_invalid_oidc_token_gets_401" time="0.094" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCTokenFlow" name="test_empty_bearer_token_gets_401" time="0.024" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCTokenFlow" name="test_no_auth_header_gets_401" time="0.024" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCTokenClaims" name="test_token_contains_groups_claim" time="0.066" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCTokenClaims" name="test_token_contains_preferred_username" time="0.059" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCTokenClaims" name="test_different_users_have_different_groups" time="0.158" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCMultiUser" name="test_bob_sre_can_mint_api_key" time="0.122" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCMultiUser" name="test_wrong_password_gets_rejected" time="0.055" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCMultiUser" name="test_nonexistent_user_gets_rejected" time="0.062" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCModelAccess" name="test_minted_api_key_can_list_models_and_infer" time="0.168" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCModelAccess" name="test_revoked_api_key_cannot_access_models" time="3.157" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCModelAccess" name="test_oidc_user_without_group_access_gets_empty_list" time="0.000"><skipped type="pytest.skip" message="OIDC_USERNAME_NO_ACCESS and OIDC_PASSWORD_NO_ACCESS not configured">/workspace/source/test/e2e/tests/test_external_oidc.py:426: OIDC_USERNAME_NO_ACCESS and OIDC_PASSWORD_NO_ACCESS not configured</skipped></testcase><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCMultiTenant" name="test_tenant_b_token_rejected_by_maas" time="0.134" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCMultiTenant" name="test_tenant_a_users_are_isolated" time="0.183" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCAPIKeyLifecycle" name="test_create_and_revoke_api_key" time="0.156" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCHeaderInjection" name="test_injected_username_header_ignored" time="0.123" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCHeaderInjection" name="test_injected_group_header_does_not_escalate" time="0.145" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCHeaderInjection" name="test_injected_subscription_header_ignored" time="0.155" /><testcase classname="test.e2e.tests.test_external_oidc.TestOIDCHeaderInjection" name="test_injected_username_on_oidc_token_ignored" time="0.085" /></testsuite></testsuites>