Skip to content
Tracon

AuditLogContract

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

Behavior tests for the IAuditLog contract.

public abstract class AuditLogContract : TenantIsolationContract<IAuditLog>, IAsyncLifetime, IAsyncDisposable

objectTenantIsolationContract<IAuditLog>AuditLogContract

IAsyncLifetime, IAsyncDisposable

TenantIsolationContract<IAuditLog>.TenantA, TenantIsolationContract<IAuditLog>.TenantB, TenantIsolationContract<IAuditLog>.CreateStoreAsync(), TenantIsolationContract<IAuditLog>.UseAmbientTenant(MutableTenantContext), TenantIsolationContract<IAuditLog>.InitializeAsync(), TenantIsolationContract<IAuditLog>.DisposeAsync(), TenantIsolationContract<IAuditLog>.OnDisposeAsync(), TenantIsolationContract<IAuditLog>.SeedAsync(string, string), TenantIsolationContract<IAuditLog>.ExistsAsync(string, object), TenantIsolationContract<IAuditLog>.CountAsync(string), TenantIsolationContract<IAuditLog>.TryDeleteAsync(string, object), TenantIsolationContract<IAuditLog>.TryOverwriteAsync(string, string), TenantIsolationContract<IAuditLog>.Tenant_cannot_read_another_tenants_record(), TenantIsolationContract<IAuditLog>.Tenant_reads_its_own_record(), TenantIsolationContract<IAuditLog>.Tenant_does_not_see_another_tenants_record_in_the_list(), TenantIsolationContract<IAuditLog>.Tenant_cannot_delete_another_tenants_record(), TenantIsolationContract<IAuditLog>.Same_name_lives_independently_across_two_tenants(), TenantIsolationContract<IAuditLog>.AmbientTenant, TenantIsolationContract<IAuditLog>.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.

protected AuditLogContract()

The log under test.

protected IAuditLog Log { get; }

IAuditLog

The fully qualified audit_log table reference this provider’s raw SQL should use.

protected virtual string QualifiedAuditLogTable { get; }

string

Whether this store’s backing state can be tampered with directly (SQL providers only).

protected virtual bool SupportsRawTamper { get; }

bool

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

Task

Concurrent_writes_for_one_tenant_produce_a_single_valid_chain()

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

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.

Deleting_a_row_directly_is_detected_as_a_gap()

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

Task

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/AuditLogContract.cs", 87)]
public Task Entries_are_returned_newest_to_oldest()

Task

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/AuditLogContract.cs", 117)]
public Task Entry_with_unknown_actor_carries_null()

Task

Runs raw SQL against the backing store. Only called when AuditLogContract.SupportsRawTamper is true.

protected virtual ValueTask ExecuteRawAsync(string sql)

sql string

ValueTask

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.

First_entry_of_a_tenant_carries_no_previous_hash()

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

Task

Formats an id for embedding in raw SQL. A provider that stores a Guid as text and compares case-sensitively (SQLite, in uppercase) must override the default (lowercase Guid.ToString).

protected virtual string FormatIdForRawSql(Guid id)

id Guid

string

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/AuditLogContract.cs", 102)]
public Task Limit_constrains_the_result()

Task

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/AuditLogContract.cs", 60)]
public Task No_leakage_between_tenants()

Task

Null_tenant_follows_the_ambient_tenant_when_it_changes()

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

Task

Null_tenant_resolves_to_the_ambient_tenant_and_does_not_leak_others()

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

Task

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/AuditLogContract.cs", 272)]
public Task Second_entry_links_to_the_first()

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.

The audit trail entry carries its own TenantId field and the query filters by AuditQuery.TenantId; it is not read from the tenant context.

Tampering_a_row_directly_is_detected_as_broken()

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

Task

Two_tenants_chains_verify_independently()

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

Task

VerifyChainAsync_reports_valid_for_a_normally_written_chain()

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

Task

VerifyChainAsync_with_null_tenant_checks_the_ambient_tenants_own_chain()

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

Task

[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/AuditLogContract.cs", 40)]
public Task Written_entry_round_trips()

Task