Skip to content
Tracon

TraceStoreContract

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

Behavior tests for the ITraceStore contract.

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

Because span ids are derived from W3C ids, writing the same span twice must not produce a duplicate record; every implementation must satisfy this rule.

protected TraceStoreContract()

The tenant spans are written under. The store reads its own tenant context; if the write and read tenants do not match, the trace can never be found. This is why the value comes from the same source as the ambient tenant.

protected string TenantId { get; }

string

[Fact]
public Task Attributes_are_preserved()

Task

Calls one read method of the store with the given token.

protected override ValueTask CancellableReadAsync(CancellationToken cancellationToken)

cancellationToken CancellationToken

The token the store must observe.

ValueTask

The completion task; any result is discarded.

The listing hook is the read: it needs no key, so it can be called on an untouched store. A contract whose store has no listing endpoint – and whose TenantIsolationContract.CountAsync therefore makes no store call at all on an empty store – overrides this with its own read.

Calls one write method of the store with the given token.

protected override ValueTask CancellableWriteAsync(CancellationToken cancellationToken)

cancellationToken CancellationToken

The token the store must observe.

ValueTask

The completion task.

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.

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.

The span store has no listing endpoint; the count is reduced to how many of the runs seeded for that tenant are visible.

[Fact]
public Task Empty_set_is_not_written()

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.

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 write takes the tenant from the batch, the read from ITenantContext; if the two diverge, the trace can never be found.

Opens a run for spans to attach to.

protected abstract ValueTask SeedRunAsync(Guid runId)

runId Guid

The run id.

ValueTask

A completed task.

[Fact]
public Task Span_tree_round_trips()

Task

[Fact]
public Task Unrecorded_run_returns_empty()

Task

Writing_the_same_span_twice_does_not_create_a_duplicate()

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

Task

Reports whether StoreCancellationContract.CancellableWriteAsync left anything behind.

protected override ValueTask<bool> WroteAnythingAsync()

ValueTask<bool>

true if the store holds any record the write would have created.