Skip to content
Tracon

SessionStoreContract

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

Behavior tests for the ISessionStore contract.

public abstract class SessionStoreContract : TenantIsolationContract<ISessionStore>, IAsyncLifetime, IAsyncDisposable
Inheritance
object ← StoreCancellationContract<ISessionStore> ← TenantIsolationContract<ISessionStore> ← SessionStoreContract
Implements
IAsyncLifetime, IAsyncDisposable
Inherited Members
TenantIsolationContract<ISessionStore>.TenantA, TenantIsolationContract<ISessionStore>.TenantB, TenantIsolationContract<ISessionStore>.UseAmbientTenant(MutableTenantContext), TenantIsolationContract<ISessionStore>.SeedAsync(string, string, CancellationToken), TenantIsolationContract<ISessionStore>.ExistsAsync(string, object), TenantIsolationContract<ISessionStore>.CountAsync(string, CancellationToken), TenantIsolationContract<ISessionStore>.TryDeleteAsync(string, object), TenantIsolationContract<ISessionStore>.TryOverwriteAsync(string, string), TenantIsolationContract<ISessionStore>.CancellableReadAsync(CancellationToken), TenantIsolationContract<ISessionStore>.CancellableWriteAsync(CancellationToken), TenantIsolationContract<ISessionStore>.WroteAnythingAsync(), TenantIsolationContract<ISessionStore>.Tenant_cannot_read_another_tenants_record(), TenantIsolationContract<ISessionStore>.Tenant_reads_its_own_record(), TenantIsolationContract<ISessionStore>.Tenant_does_not_see_another_tenants_record_in_the_list(), TenantIsolationContract<ISessionStore>.Tenant_cannot_delete_another_tenants_record(), TenantIsolationContract<ISessionStore>.Same_name_lives_independently_across_two_tenants(), TenantIsolationContract<ISessionStore>.AmbientTenant, StoreCancellationContract<ISessionStore>.CreateStoreAsync(), StoreCancellationContract<ISessionStore>.InitializeAsync(), StoreCancellationContract<ISessionStore>.DisposeAsync(), StoreCancellationContract<ISessionStore>.OnDisposeAsync(), StoreCancellationContract<ISessionStore>.CancellableReadAsync(CancellationToken), StoreCancellationContract<ISessionStore>.CancellableWriteAsync(CancellationToken), StoreCancellationContract<ISessionStore>.WroteAnythingAsync(), StoreCancellationContract<ISessionStore>.Canceled_token_throws_on_read(), StoreCancellationContract<ISessionStore>.The_write_this_contract_checks_can_be_read_back(), StoreCancellationContract<ISessionStore>.Canceled_token_throws_on_write_and_leaves_no_trace(), StoreCancellationContract<ISessionStore>.Store, object.GetType(), object.MemberwiseClone(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()

Session state is opaque; the store must return the content back exactly, without interpreting it.

protected SessionStoreContract()

A_later_write_that_carries_no_owner_does_not_CLEAR_the_stored_one()

Section titled “ A_later_write_that_carries_no_owner_does_not_CLEAR_the_stored_one()”
[Fact]
public Task A_later_write_that_carries_no_owner_does_not_CLEAR_the_stored_one()

Task

A_session_saved_without_StateMafVersion_reads_back_null()

Section titled “ A_session_saved_without_StateMafVersion_reads_back_null()”
[Fact]
public Task A_session_saved_without_StateMafVersion_reads_back_null()

Task

A_session_saved_without_an_owner_reads_back_null()

Section titled “ A_session_saved_without_an_owner_reads_back_null()”
[Fact]
public Task A_session_saved_without_an_owner_reads_back_null()

Task

[Fact]
public Task An_owned_session_round_trips_its_owner()

Task

An_owner_at_the_maximum_allowed_length_round_trips_whole()

Section titled “ An_owner_at_the_maximum_allowed_length_round_trips_whole()”
[Fact]
public Task An_owner_at_the_maximum_allowed_length_round_trips_whole()

Task

An_unowned_session_can_still_be_given_an_owner()

Section titled “ An_unowned_session_can_still_be_given_an_owner()”
[Fact]
public Task An_unowned_session_can_still_be_given_an_owner()

Task

Reports how many records the given tenant sees through the listing endpoint.

protected override ValueTask<int> CountAsync(string tenantId, CancellationToken cancellationToken)

tenantId string

The reading tenant.

cancellationToken CancellationToken

The token every store call inside the hook must be handed; see TenantIsolationContract.SeedAsync.

ValueTask<int>

The number of records seen.

[Fact]
public Task Delete_removes_the_record()

Task

Reports whether the record is visible from the given tenant’s viewpoint.

protected override ValueTask<bool> ExistsAsync(string tenantId, object key)

tenantId string

The reading tenant.

key object

The key returned by TenantIsolationContract.SeedAsync.

ValueTask<bool>

true if the record is visible.

GetOwnerTenantIdAsync_returns_null_for_a_never_used_id()

Section titled “ GetOwnerTenantIdAsync_returns_null_for_a_never_used_id()”
[Fact]
public Task GetOwnerTenantIdAsync_returns_null_for_a_never_used_id()

Task

GetOwnerTenantIdAsync_returns_the_real_owner_independent_of_the_ambient_tenant()

Section titled “ GetOwnerTenantIdAsync_returns_the_real_owner_independent_of_the_ambient_tenant()”
[Fact]
public Task GetOwnerTenantIdAsync_returns_the_real_owner_independent_of_the_ambient_tenant()

Task

[Fact]
public Task Nonexistent_session_returns_null()

Task

[Fact]
public Task Query_applies_paging()

Task

Query_applies_the_owner_filter_BEFORE_paging()

Section titled “ Query_applies_the_owner_filter_BEFORE_paging()”
[Fact]
public Task Query_applies_the_owner_filter_BEFORE_paging()

Task

[Fact]
public Task Query_filters_by_agent_name()

Task

Query_filters_by_owner_and_never_returns_an_unowned_row()

Section titled “ Query_filters_by_owner_and_never_returns_an_unowned_row()”
[Fact]
public Task Query_filters_by_owner_and_never_returns_an_unowned_row()

Task

Query_starts_with_the_most_recently_updated()

Section titled “ Query_starts_with_the_most_recently_updated()”
[Fact]
public Task Query_starts_with_the_most_recently_updated()

Task

SaveAsync_advances_the_version_so_a_stale_update_cannot_match_it()

Section titled “ SaveAsync_advances_the_version_so_a_stale_update_cannot_match_it()”
[Fact]
public Task SaveAsync_advances_the_version_so_a_stale_update_cannot_match_it()

Task

Saving_with_the_same_id_overwrites_the_record_and_keeps_the_creation_time()

Section titled “ Saving_with_the_same_id_overwrites_the_record_and_keeps_the_creation_time()”
[Fact]
public Task Saving_with_the_same_id_overwrites_the_record_and_keeps_the_creation_time()

Task

SeedAsync(string, string, CancellationToken)

Section titled “ SeedAsync(string, string, CancellationToken)”

Writes a sample record for the given tenant.

protected override ValueTask<object> SeedAsync(string tenantId, string name, CancellationToken cancellationToken)

tenantId string

The tenant that owns the record.

name string

The name distinguishing the record. The same name may be used by two tenants.

cancellationToken CancellationToken

The token every store call inside the hook must be handed. The cancellation contract calls this hook with a token that is already cancelled, so a hook that drops the token reports a store as sound when it is not.

ValueTask<object>

The key to use for reading the record back.

The tenant is not a parameter in the interface; it is read from ITenantContext. That is why every hook sets the current tenant first.

Session_state_round_trips_without_corruption()

Section titled “ Session_state_round_trips_without_corruption()”
[Fact]
public Task Session_state_round_trips_without_corruption()

Task

StateSchemaVersion_and_StateMafVersion_round_trip()

Section titled “ StateSchemaVersion_and_StateMafVersion_round_trip()”
[Fact]
public Task StateSchemaVersion_and_StateMafVersion_round_trip()

Task

The_same_owner_stays_separate_in_two_tenants()

Section titled “ The_same_owner_stays_separate_in_two_tenants()”
[Fact]
public Task The_same_owner_stays_separate_in_two_tenants()

Task

TryCreateAsync_only_one_concurrent_call_with_the_same_id_wins()

Section titled “ TryCreateAsync_only_one_concurrent_call_with_the_same_id_wins()”
[Fact]
public Task TryCreateAsync_only_one_concurrent_call_with_the_same_id_wins()

Task

TryCreateAsync_returns_false_and_does_not_overwrite_for_an_existing_id()

Section titled “ TryCreateAsync_returns_false_and_does_not_overwrite_for_an_existing_id()”
[Fact]
public Task TryCreateAsync_returns_false_and_does_not_overwrite_for_an_existing_id()

Task

TryCreateAsync_returns_true_and_saves_for_a_new_id()

Section titled “ TryCreateAsync_returns_true_and_saves_for_a_new_id()”
[Fact]
public Task TryCreateAsync_returns_true_and_saves_for_a_new_id()

Task

TryCreateAsync_same_id_wins_independently_in_two_tenants()

Section titled “ TryCreateAsync_same_id_wins_independently_in_two_tenants()”
[Fact]
public Task TryCreateAsync_same_id_wins_independently_in_two_tenants()

Task

TryCreateAsync_stamps_the_first_version()

Section titled “ TryCreateAsync_stamps_the_first_version()”
[Fact]
public Task TryCreateAsync_stamps_the_first_version()

Task

Attempts to delete the record on behalf of the given tenant.

protected override ValueTask<bool?> TryDeleteAsync(string tenantId, object key)

tenantId string

The tenant attempting the delete.

key object

The key returned by TenantIsolationContract.SeedAsync.

ValueTask<bool?>

true if the delete succeeded, false if the record was not found; null if the store does not offer deletion.

TryUpdateAsync_cannot_reach_another_tenants_record()

Section titled “ TryUpdateAsync_cannot_reach_another_tenants_record()”
[Fact]
public Task TryUpdateAsync_cannot_reach_another_tenants_record()

Task

TryUpdateAsync_only_one_concurrent_call_from_the_same_version_wins()

Section titled “ TryUpdateAsync_only_one_concurrent_call_from_the_same_version_wins()”
[Fact]
public Task TryUpdateAsync_only_one_concurrent_call_from_the_same_version_wins()

Task

TryUpdateAsync_refuses_a_stale_version_and_leaves_the_record_alone()

Section titled “ TryUpdateAsync_refuses_a_stale_version_and_leaves_the_record_alone()”
[Fact]
public Task TryUpdateAsync_refuses_a_stale_version_and_leaves_the_record_alone()

Task

TryUpdateAsync_replaces_the_record_and_advances_the_version()

Section titled “ TryUpdateAsync_replaces_the_record_and_advances_the_version()”
[Fact]
public Task TryUpdateAsync_replaces_the_record_and_advances_the_version()

Task

TryUpdateAsync_returns_false_for_an_id_that_does_not_exist()

Section titled “ TryUpdateAsync_returns_false_for_an_id_that_does_not_exist()”
[Fact]
public Task TryUpdateAsync_returns_false_for_an_id_that_does_not_exist()

Task

TryUpdateAsync_writes_the_records_own_tenant_not_the_ambient_one()

Section titled “ TryUpdateAsync_writes_the_records_own_tenant_not_the_ambient_one()”
[Fact]
public Task TryUpdateAsync_writes_the_records_own_tenant_not_the_ambient_one()

Task