Skip to content
Tracon

SkillScriptGrantContract

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

Behavior tests for the ISkillScriptGrantStore contract.

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

Every implementation must pass the same scenarios; in particular, the “the narrower grant wins over the broader one” rule and the fact that a revoked grant never comes back must behave identically.

protected SkillScriptGrantContract()

A grant pins the content it authorizes; every read returns the pinned hash.

[Fact]
public Task Content_hash_round_trips()

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.

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]
public Task Expired_grant_is_not_returned()

Task

[Fact]
public Task Grant_does_not_leak_across_tenants()

Task

Granting_again_replaces_the_content_hash()

Section titled “ Granting_again_replaces_the_content_hash()”

Granting the same skill and script again pins the new content. An upsert whose update branch forgot the hash would keep authorizing the previous content.

[Fact]
public Task Granting_again_replaces_the_content_hash()

Task

Granting_the_same_grant_twice_leaves_a_single_record()

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

Task

A grant that pins nothing stays that way: it authorizes scripts on disk only, and a store must not invent a value for it.

[Fact]
public Task Null_content_hash_round_trips()

Task

Racing_grants_and_revocations_leave_one_record_for_the_key()

Section titled “ Racing_grants_and_revocations_leave_one_record_for_the_key()”

Grants and revocations of one key racing each other never leave two records for the key, and a grant written after the race is the one in force.

[Fact]
public Task Racing_grants_and_revocations_leave_one_record_for_the_key()

Task

[Fact]
public Task Revoked_grant_can_be_granted_again()

Task

[Fact]
public Task Revoked_grant_is_invalid()

Task

A grant is never deleted: revoking stamps the revocation time and the record stays listed, so who granted what and when it was withdrawn stays answerable.

[Fact]
public Task Revoked_grant_stays_listed()

Task

Script_specific_grant_wins_over_the_skill_wide_grant()

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

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.

[Fact]
public Task Skill_wide_grant_covers_every_script()

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.

A grant is not deleted, it is revoked.