Skip to content
Tracon

ModelProviderCredentialContract

Namespace Tracon.Testing.Contracts.Providers · Assembly Tracon.Testing.Contracts.Xunit.dll

Behavior tests for a provider that honors a per-tenant credential (BYOK).

public abstract class ModelProviderCredentialContract : ModelProviderContract, IAsyncLifetime, IAsyncDisposable

objectModelProviderContractModelProviderCredentialContract

IAsyncLifetime, IAsyncDisposable

ModelProviderContract.CreateProviderAsync(), ModelProviderContract.InitializeAsync(), ModelProviderContract.DisposeAsync(), ModelProviderContract.OnDisposeAsync(), ModelProviderContract.Binding(string?, string?), ModelProviderContract.Provider_name_is_not_empty(), ModelProviderContract.Catalog_model_names_are_unique_and_not_empty(), ModelProviderContract.Create_chat_client_returns_a_client_for_the_setup_time_credential(), ModelProviderContract.Create_chat_client_returns_a_raw_client_that_builds_no_tool_call_loop(), ModelProviderContract.Create_chat_client_accepts_a_binding_whose_provider_name_differs_in_case(), ModelProviderContract.A_model_the_catalog_does_not_list_is_not_rejected(), ModelProviderContract.Concurrent_create_chat_client_calls_all_return_a_client(), ModelProviderContract.A_client_that_is_never_disposed_does_not_stop_the_provider(), ModelProviderContract.Provider, ModelProviderContract.UnknownModelName, object.GetType(), object.MemberwiseClone(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()

Honoring ModelProviderCredential is optional. A provider that offers it implements ITenantCredentialModelProvider. Deriving this class verifies that explicit capability. A provider that does not offer BYOK does not derive this class and records that as a ContractCoverage exemption.

Like ModelProviderContract, nothing here performs a model call: the observable consequences of a credential are which client object gets built, not what the network returns.

protected ModelProviderCredentialContract()

A credential this provider can build a client from. It is never used against a real endpoint, so any syntactically valid key works.

protected abstract ModelProviderCredential Credential { get; }

ModelProviderCredential

A second credential that differs from ModelProviderCredentialContract.Credential, used to prove that two tenants do not collapse onto one client.

protected virtual ModelProviderCredential OtherCredential { get; }

ModelProviderCredential

A_tenant_credential_is_applied_to_the_returned_client()

Section titled “ A_tenant_credential_is_applied_to_the_returned_client()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/Providers/ModelProviderCredentialContract.cs", 63)]
public void A_tenant_credential_is_applied_to_the_returned_client()

A_tenant_credential_produces_a_different_client_than_the_setup_time_one()

Section titled “ A_tenant_credential_produces_a_different_client_than_the_setup_time_one()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/Providers/ModelProviderCredentialContract.cs", 77)]
public void A_tenant_credential_produces_a_different_client_than_the_setup_time_one()

The key never falls back to the setup-time key: a tenant that supplied a credential is billed on it, or the call fails. Handing back the setup-time client would silently bill the wrong tenant, and distinct instances are the observable consequence of not doing that.

An_endpoint_override_on_a_tenant_credential_is_accepted()

Section titled “ An_endpoint_override_on_a_tenant_credential_is_accepted()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/Providers/ModelProviderCredentialContract.cs", 132)]
public void An_endpoint_override_on_a_tenant_credential_is_accepted()

An endpoint override is accepted; which address the resulting client uses is not observable without a network call, so this asserts acceptance only. Note that the endpoint — unlike the key — may fall back to the setup-time address when a tenant overrides only the key.

AssertCredentialIsApplied(IChatClient, ModelProviderCredential)

Section titled “ AssertCredentialIsApplied(IChatClient, ModelProviderCredential)”

Verifies that a returned client will use credential for its provider request.

protected abstract void AssertCredentialIsApplied(IChatClient client, ModelProviderCredential credential)

client IChatClient

The client returned for the tenant credential.

credential ModelProviderCredential

The tenant credential supplied to the provider.

This is provider-specific by design. The shared AI.IChatClient surface cannot expose an API key safely, so a provider must prove the credential at its own observable boundary, such as a recording transport or a vendor request factory. Checking only client identity is insufficient: a new wrapper could be created while it still sends the setup-time key.

Concurrent_resolution_of_one_credential_stays_stable()

Section titled “ Concurrent_resolution_of_one_credential_stays_stable()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/Providers/ModelProviderCredentialContract.cs", 108)]
public Task Concurrent_resolution_of_one_credential_stays_stable()

Task

A per-credential client cache is normally a Concurrent.ConcurrentDictionary, whose GetOrAdd may run its factory more than once for the same key when threads race, discarding the extra results. Building a client twice must therefore be harmless, and resolution must stay stable under concurrency.

Create_chat_client_with_a_tenant_credential_returns_a_client()

Section titled “ Create_chat_client_with_a_tenant_credential_returns_a_client()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/Providers/ModelProviderCredentialContract.cs", 59)]
public void Create_chat_client_with_a_tenant_credential_returns_a_client()

Provider_declares_the_tenant_credential_capability()

Section titled “ Provider_declares_the_tenant_credential_capability()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/Providers/ModelProviderCredentialContract.cs", 55)]
public void Provider_declares_the_tenant_credential_capability()

Two_different_credentials_do_not_share_one_client()

Section titled “ Two_different_credentials_do_not_share_one_client()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/Providers/ModelProviderCredentialContract.cs", 91)]
public void Two_different_credentials_do_not_share_one_client()

The credential, not the tenant, is the identity boundary: two distinct credentials must not resolve to one client, or one tenant’s key would serve another’s traffic.