Skip to content
Tracon

QuotaStoreContract

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

Behavior tests for the IQuotaStore contract.

public abstract class QuotaStoreContract : TenantIsolationContract<IQuotaStore>, IAsyncLifetime, IAsyncDisposable

objectTenantIsolationContract<IQuotaStore>QuotaStoreContract

IAsyncLifetime, IAsyncDisposable

TenantIsolationContract<IQuotaStore>.TenantA, TenantIsolationContract<IQuotaStore>.TenantB, TenantIsolationContract<IQuotaStore>.CreateStoreAsync(), TenantIsolationContract<IQuotaStore>.UseAmbientTenant(MutableTenantContext), TenantIsolationContract<IQuotaStore>.InitializeAsync(), TenantIsolationContract<IQuotaStore>.DisposeAsync(), TenantIsolationContract<IQuotaStore>.OnDisposeAsync(), TenantIsolationContract<IQuotaStore>.SeedAsync(string, string), TenantIsolationContract<IQuotaStore>.ExistsAsync(string, object), TenantIsolationContract<IQuotaStore>.CountAsync(string), TenantIsolationContract<IQuotaStore>.TryDeleteAsync(string, object), TenantIsolationContract<IQuotaStore>.TryOverwriteAsync(string, string), TenantIsolationContract<IQuotaStore>.Tenant_cannot_read_another_tenants_record(), TenantIsolationContract<IQuotaStore>.Tenant_reads_its_own_record(), TenantIsolationContract<IQuotaStore>.Tenant_does_not_see_another_tenants_record_in_the_list(), TenantIsolationContract<IQuotaStore>.Tenant_cannot_delete_another_tenants_record(), TenantIsolationContract<IQuotaStore>.Same_name_lives_independently_across_two_tenants(), TenantIsolationContract<IQuotaStore>.AmbientTenant, TenantIsolationContract<IQuotaStore>.Store, object.GetType(), object.MemberwiseClone(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()

The in-memory store and the PostgreSQL store must pass the same scenarios. Two rules are especially critical: scope uniqueness (COALESCE(agent_name, '')) and the atomicity of usage increments (ON CONFLICT DO UPDATE).

protected QuotaStoreContract()
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 287)]
public Task A_different_metric_is_a_separate_claim()

Task

A_different_tenants_identically_shaped_claim_is_independent()

Section titled “ A_different_tenants_identically_shaped_claim_is_independent()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 334)]
public Task A_different_tenants_identically_shaped_claim_is_independent()

Task

A_different_threshold_percent_is_a_separate_claim()

Section titled “ A_different_threshold_percent_is_a_separate_claim()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 296)]
public Task A_different_threshold_percent_is_a_separate_claim()

Task

A_new_period_starts_with_no_claim_even_if_the_previous_period_already_has_one()

Section titled “ A_new_period_starts_with_no_claim_even_if_the_previous_period_already_has_one()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 305)]
public Task A_new_period_starts_with_no_claim_even_if_the_previous_period_already_has_one()

Task

A_threshold_already_claimed_in_this_period_is_not_claimed_again()

Section titled “ A_threshold_already_claimed_in_this_period_is_not_claimed_again()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 271)]
public Task A_threshold_already_claimed_in_this_period_is_not_claimed_again()

Task

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 118)]
public Task Another_tenants_rule_is_not_visible()

Task

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 255)]
public Task Another_tenants_usage_is_not_visible()

Task

Claim_fails_when_the_usage_row_does_not_exist_yet()

Section titled “ Claim_fails_when_the_usage_row_does_not_exist_yet()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 283)]
public Task Claim_fails_when_the_usage_row_does_not_exist_yet()

Task

Concurrent_claims_of_the_same_threshold_let_only_one_caller_win()

Section titled “ Concurrent_claims_of_the_same_threshold_let_only_one_caller_win()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 322)]
public Task Concurrent_claims_of_the_same_threshold_let_only_one_caller_win()

Task

Concurrent_increments_lose_no_increment()

Section titled “ Concurrent_increments_lose_no_increment()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 176)]
public Task Concurrent_increments_lose_no_increment()

Task

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 161)]
public Task Consecutive_usage_accumulates()

Task

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

protected override ValueTask<int> CountAsync(string tenantId)

tenantId string

The reading tenant.

ValueTask<int>

The number of records seen.

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 127)]
public Task Deleted_rule_is_not_read_back()

Task

Deleting_a_nonexistent_rule_returns_false()

Section titled “ Deleting_a_nonexistent_rule_returns_false()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 136)]
public Task Deleting_a_nonexistent_rule_returns_false()

Task

Different_agent_becomes_a_separate_rule()

Section titled “ Different_agent_becomes_a_separate_rule()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 100)]
public Task Different_agent_becomes_a_separate_rule()

Task

Different_period_becomes_a_separate_rule()

Section titled “ Different_period_becomes_a_separate_rule()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 109)]
public Task Different_period_becomes_a_separate_rule()

Task

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 71)]
public Task Empty_limits_are_preserved_as_null()

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.

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 263)]
public Task First_claim_of_a_threshold_succeeds()

Task

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 57)]
public Task Saved_rule_is_read_back()

Task

Saving_the_same_scope_a_second_time_overwrites_it()

Section titled “ Saving_the_same_scope_a_second_time_overwrites_it()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 84)]
public Task Saving_the_same_scope_a_second_time_overwrites_it()

Task

Writes a sample record for the given tenant.

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

tenantId string

The tenant that owns the record.

name string

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

ValueTask<object>

The key to use for reading the record back.

Separate_period_keeps_a_separate_counter()

Section titled “ Separate_period_keeps_a_separate_counter()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 210)]
public Task Separate_period_keeps_a_separate_counter()

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.

Usage_increments_both_the_agent_and_tenant_counters()

Section titled “ Usage_increments_both_the_agent_and_tenant_counters()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 140)]
public Task Usage_increments_both_the_agent_and_tenant_counters()

Task

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 231)]
public Task Usage_is_filtered_by_agent_name()

Task

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 244)]
public Task Usage_is_filtered_by_period()

Task

Usage_with_undefined_price_does_not_break_the_cost_total()

Section titled “ Usage_with_undefined_price_does_not_break_the_cost_total()”
[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/QuotaStoreContract.cs", 194)]
public Task Usage_with_undefined_price_does_not_break_the_cost_total()

Task