Skip to content
Tracon

ExperimentStoreContract

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

Behavior tests for the IExperimentStore contract.

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

These tests run for every implementation. A behavior difference between the in-memory store and the PostgreSQL store is a bug; this class catches that difference.

protected ExperimentStoreContract()

Canary_policy_can_be_set_on_a_draft_experiment_too()

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

Task

[Fact]
public Task Canary_policy_is_cleared_with_null()

Task

[Fact]
public Task Canary_policy_is_set_and_read_back()

Task

Canary_ramp_is_rejected_on_a_non_running_experiment()

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

Task

Canary_ramp_updates_weights_on_a_running_experiment_and_stays_Running()

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

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.

Deleting_nonexistent_experiment_returns_false()

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

Task

[Fact]
public Task Draft_experiment_can_be_deleted()

Task

[Fact]
public Task Draft_experiment_can_be_updated()

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.

Experiment_lifecycle_does_not_leak_across_tenants()

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

Task

ListRunningWithCanaryAsync_returns_only_running_experiments_with_canary_defined()

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

Task

[Fact]
public Task Listing_returns_only_that_tenant()

Task

Non_running_experiment_cannot_be_stopped()

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

Task

Nonexistent_experiment_cannot_be_started()

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

Task

Returns_null_when_no_experiment_is_running()

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

Task

Rollback_stops_the_experiment_restores_weights_and_records_the_reason()

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

Task

[Fact]
public Task Running_experiment_cannot_be_deleted()

Task

[Fact]
public Task Running_experiment_cannot_be_updated()

Task

[Fact]
public Task Save_and_get_round_trips()

Task

Saving_a_draft_again_keeps_its_canary_policy()

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

Task

[Fact]
public Task Saving_never_writes_the_canary_policy()

Task

Second_start_for_same_agent_is_rejected()

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

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.

Setting_canary_policy_is_EXEMPT_from_the_draft_only_edit_restriction()

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

Task

Starting_returns_the_running_experiment()

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

Task

Stopping_stops_the_experiment_and_frees_the_running_slot()

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

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.