.NET API
IdempotencyStoreContract
Tracon.Testing.Contracts.Xunit.dllBehavior tests for the IIdempotencyStore contract.
public abstract class IdempotencyStoreContract : StoreCancellationContract<IIdempotencyStore>, IAsyncLifetime, IAsyncDisposable- Inheritance
- object ← StoreCancellationContract<IIdempotencyStore> ← IdempotencyStoreContract
- Implements
- IAsyncLifetime, IAsyncDisposable
- Inherited Members
- StoreCancellationContract<IIdempotencyStore>.CreateStoreAsync(), StoreCancellationContract<IIdempotencyStore>.InitializeAsync(), StoreCancellationContract<IIdempotencyStore>.DisposeAsync(), StoreCancellationContract<IIdempotencyStore>.OnDisposeAsync(), StoreCancellationContract<IIdempotencyStore>.CancellableReadAsync(CancellationToken), StoreCancellationContract<IIdempotencyStore>.CancellableWriteAsync(CancellationToken), StoreCancellationContract<IIdempotencyStore>.WroteAnythingAsync(), StoreCancellationContract<IIdempotencyStore>.Canceled_token_throws_on_read(), StoreCancellationContract<IIdempotencyStore>.The_write_this_contract_checks_can_be_read_back(), StoreCancellationContract<IIdempotencyStore>.Canceled_token_throws_on_write_and_leaves_no_trace(), StoreCancellationContract<IIdempotencyStore>.Store, object.GetType(), object.MemberwiseClone(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()
Remarks
Section titled “Remarks”The in-memory store and the three SQL providers must pass the same scenarios.
The tenant id is passed explicitly to every call (not through
the ambient ITenantContext) — the contract therefore does
not rely on the generic CRUD shape of
Storage.TenantIsolationContract and derives from
Storage.StoreCancellationContract directly; the same pattern
as SingletonLeaseStoreContract.
Constructors
Section titled “Constructors”IdempotencyStoreContract()
Section titled “ IdempotencyStoreContract()”protected IdempotencyStoreContract()Methods
Section titled “Methods”CancellableReadAsync(CancellationToken)
Section titled “ CancellableReadAsync(CancellationToken)”Calls one read method of the store with the given token.
protected override ValueTask CancellableReadAsync(CancellationToken cancellationToken)Parameters
Section titled “Parameters”cancellationToken CancellationToken
The token the store must observe.
Returns
Section titled “Returns”The completion task; any result is discarded.
Remarks
Section titled “Remarks”A reservation for a key that already exists is the read path: it reports the stored state instead of opening a new slot.
CancellableWriteAsync(CancellationToken)
Section titled “ CancellableWriteAsync(CancellationToken)”Calls one write method of the store with the given token.
protected override ValueTask CancellableWriteAsync(CancellationToken cancellationToken)Parameters
Section titled “Parameters”cancellationToken CancellationToken
The token the store must observe.
Returns
Section titled “Returns”The completion task.
Remarks
Section titled “Remarks”The write must be one StoreCancellationContract.WroteAnythingAsync can see. A write this contract cannot read back proves nothing about side effects, which is why StoreCancellationContract.The_write_this_contract_checks_can_be_read_back runs the same pair with a live token and requires the read to find it.
Completed_key_also_returns_the_stored_HTTP_headers()
Section titled “ Completed_key_also_returns_the_stored_HTTP_headers()”[Fact]public Task Completed_key_also_returns_the_stored_HTTP_headers()Returns
Section titled “Returns”Completed_key_returns_an_empty_dictionary_when_there_are_NO_headers()
Section titled “ Completed_key_returns_an_empty_dictionary_when_there_are_NO_headers()”[Fact]public Task Completed_key_returns_an_empty_dictionary_when_there_are_NO_headers()Returns
Section titled “Returns”Completed_key_returns_the_stored_response_with_the_same_fingerprint()
Section titled “ Completed_key_returns_the_stored_response_with_the_same_fingerprint()”[Fact]public Task Completed_key_returns_the_stored_response_with_the_same_fingerprint()Returns
Section titled “Returns”Completed_key_with_a_DIFFERENT_fingerprint_returns_FingerprintMismatch()
Section titled “ Completed_key_with_a_DIFFERENT_fingerprint_returns_FingerprintMismatch()”[Fact]public Task Completed_key_with_a_DIFFERENT_fingerprint_returns_FingerprintMismatch()Returns
Section titled “Returns”Completed_record_does_NOT_affect_another_tenant()
Section titled “ Completed_record_does_NOT_affect_another_tenant()”[Fact]public Task Completed_record_does_NOT_affect_another_tenant()Returns
Section titled “Returns”Concurrent_reservation_of_the_same_key_only_one_gets_Reserved()
Section titled “ Concurrent_reservation_of_the_same_key_only_one_gets_Reserved()”[Fact]public Task Concurrent_reservation_of_the_same_key_only_one_gets_Reserved()Returns
Section titled “Returns”Key_in_progress_returns_InProgress_on_second_reservation()
Section titled “ Key_in_progress_returns_InProgress_on_second_reservation()”[Fact]public Task Key_in_progress_returns_InProgress_on_second_reservation()Returns
Section titled “Returns”New_key_returns_Reserved()
Section titled “ New_key_returns_Reserved()”[Fact]public Task New_key_returns_Reserved()Returns
Section titled “Returns”Released_key_can_be_reserved_again()
Section titled “ Released_key_can_be_reserved_again()”[Fact]public Task Released_key_can_be_reserved_again()Returns
Section titled “Returns”Same_key_lives_independently_in_two_tenants()
Section titled “ Same_key_lives_independently_in_two_tenants()”[Fact]public Task Same_key_lives_independently_in_two_tenants()Returns
Section titled “Returns”WroteAnythingAsync()
Section titled “ WroteAnythingAsync()”Reports whether StoreCancellationContract.CancellableWriteAsync left anything behind.
protected override ValueTask<bool> WroteAnythingAsync()Returns
Section titled “Returns”true if the store holds any record the write would have created.
Remarks
Section titled “Remarks”A key nothing ever reserved comes back IdempotencyState.Reserved – a fresh slot. Any other state means the cancelled call wrote a row.