.NET API
RunScoreStoreContract
Tracon.Testing.Contracts.Xunit.dllBehavior tests for the IRunScoreStore contract.
public abstract class RunScoreStoreContract : TenantIsolationContract<IRunScoreStore>, IAsyncLifetime, IAsyncDisposableInheritance
Section titled “Inheritance”object ← TenantIsolationContract<IRunScoreStore> ← RunScoreStoreContract
Implements
Section titled “Implements”IAsyncLifetime, IAsyncDisposable
Inherited Members
Section titled “Inherited Members”TenantIsolationContract<IRunScoreStore>.TenantA, TenantIsolationContract<IRunScoreStore>.TenantB, TenantIsolationContract<IRunScoreStore>.CreateStoreAsync(), TenantIsolationContract<IRunScoreStore>.UseAmbientTenant(MutableTenantContext), TenantIsolationContract<IRunScoreStore>.InitializeAsync(), TenantIsolationContract<IRunScoreStore>.DisposeAsync(), TenantIsolationContract<IRunScoreStore>.OnDisposeAsync(), TenantIsolationContract<IRunScoreStore>.SeedAsync(string, string), TenantIsolationContract<IRunScoreStore>.ExistsAsync(string, object), TenantIsolationContract<IRunScoreStore>.CountAsync(string), TenantIsolationContract<IRunScoreStore>.TryDeleteAsync(string, object), TenantIsolationContract<IRunScoreStore>.TryOverwriteAsync(string, string), TenantIsolationContract<IRunScoreStore>.Tenant_cannot_read_another_tenants_record(), TenantIsolationContract<IRunScoreStore>.Tenant_reads_its_own_record(), TenantIsolationContract<IRunScoreStore>.Tenant_does_not_see_another_tenants_record_in_the_list(), TenantIsolationContract<IRunScoreStore>.Tenant_cannot_delete_another_tenants_record(), TenantIsolationContract<IRunScoreStore>.Same_name_lives_independently_across_two_tenants(), TenantIsolationContract<IRunScoreStore>.AmbientTenant, TenantIsolationContract<IRunScoreStore>.Store, object.GetType(), object.MemberwiseClone(), object.ToString(), object.Equals(object?), object.Equals(object?, object?), object.ReferenceEquals(object?, object?), object.GetHashCode()
Remarks
Section titled “Remarks”The in-memory store and the three SQL providers must pass the same scenarios. Critical rule: when the same author writes the same RunScore.Name onto the same target (a run or a message) a second time, the row is updated, not duplicated – a different name opens a new row, and neither rule applies when the author is empty (an anonymous setup).
Constructors
Section titled “Constructors”RunScoreStoreContract()
Section titled “ RunScoreStoreContract()”protected RunScoreStoreContract()Methods
Section titled “Methods”A_categorical_score_carrying_a_numeric_value_is_REJECTED()
Section titled “ A_categorical_score_carrying_a_numeric_value_is_REJECTED()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 186)]public Task A_categorical_score_carrying_a_numeric_value_is_REJECTED()Returns
Section titled “Returns”A_categorical_score_is_stored_as_text()
Section titled “ A_categorical_score_is_stored_as_text()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 166)]public Task A_categorical_score_is_stored_as_text()Returns
Section titled “Returns”A_decimal_value_is_NOT_rounded()
Section titled “ A_decimal_value_is_NOT_rounded()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 128)]public Task A_decimal_value_is_NOT_rounded()Returns
Section titled “Returns”A_null_value_is_counted_but_does_not_enter_the_average()
Section titled “ A_null_value_is_counted_but_does_not_enter_the_average()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 406)]public Task A_null_value_is_counted_but_does_not_enter_the_average()Returns
Section titled “Returns”A_null_value_means_NO_MEASUREMENT_not_zero()
Section titled “ A_null_value_means_NO_MEASUREMENT_not_zero()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 156)]public Task A_null_value_means_NO_MEASUREMENT_not_zero()Returns
Section titled “Returns”A_numeric_score_carrying_a_text_value_is_REJECTED()
Section titled “ A_numeric_score_carrying_a_text_value_is_REJECTED()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 195)]public Task A_numeric_score_carrying_a_text_value_is_REJECTED()Returns
Section titled “Returns”A_whole_number_value_is_read_back_as_a_number_not_an_integer()
Section titled “ A_whole_number_value_is_read_back_as_a_number_not_an_integer()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 144)]public Task A_whole_number_value_is_read_back_as_a_number_not_an_integer()Returns
Section titled “Returns”An_empty_match_returns_empty_lists_not_null()
Section titled “ An_empty_match_returns_empty_lists_not_null()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 579)]public Task An_empty_match_returns_empty_lists_not_null()Returns
Section titled “Returns”An_empty_string_Author_is_excluded_from_the_author_breakdown_like_no_author()
Section titled “ An_empty_string_Author_is_excluded_from_the_author_breakdown_like_no_author()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 565)]public Task An_empty_string_Author_is_excluded_from_the_author_breakdown_like_no_author()Returns
Section titled “Returns”An_empty_string_MessageId_is_treated_the_same_as_no_message()
Section titled “ An_empty_string_MessageId_is_treated_the_same_as_no_message()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 547)]public Task An_empty_string_MessageId_is_treated_the_same_as_no_message()Returns
Section titled “Returns”An_illegal_name_is_REJECTED(string)
Section titled “ An_illegal_name_is_REJECTED(string)”[Theory("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 204)][InlineData(new object?[] { "has space" })][InlineData(new object?[] { "" })][InlineData(new object?[] { "naïve" })][InlineData(new object?[] { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" })]public Task An_illegal_name_is_REJECTED(string name)Parameters
Section titled “Parameters”name string
Returns
Section titled “Returns”Another_tenants_score_cannot_be_deleted()
Section titled “ Another_tenants_score_cannot_be_deleted()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 327)]public Task Another_tenants_score_cannot_be_deleted()Returns
Section titled “Returns”Another_tenants_score_is_not_visible()
Section titled “ Another_tenants_score_is_not_visible()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 303)]public Task Another_tenants_score_is_not_visible()Returns
Section titled “Returns”Another_tenants_score_never_enters_the_summary()
Section titled “ Another_tenants_score_never_enters_the_summary()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 358)]public Task Another_tenants_score_never_enters_the_summary()Returns
Section titled “Returns”Author_breakdown_excludes_scores_with_no_author()
Section titled “ Author_breakdown_excludes_scores_with_no_author()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 487)]public Task Author_breakdown_excludes_scores_with_no_author()Returns
Section titled “Returns”Canceled_token_throws()
Section titled “ Canceled_token_throws()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 682)]public Task Canceled_token_throws()Returns
Section titled “Returns”Categorical_scores_report_category_counts_not_an_average()
Section titled “ Categorical_scores_report_category_counts_not_an_average()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 422)]public Task Categorical_scores_report_category_counts_not_an_average()Returns
Section titled “Returns”Category_cardinality_beyond_MaxRows_is_truncated_and_reported()
Section titled “ Category_cardinality_beyond_MaxRows_is_truncated_and_reported()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 463)]public Task Category_cardinality_beyond_MaxRows_is_truncated_and_reported()Returns
Section titled “Returns”Concurrent_writes_of_the_SAME_name_leave_exactly_one_row()
Section titled “ Concurrent_writes_of_the_SAME_name_leave_exactly_one_row()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 217)]public Task Concurrent_writes_of_the_SAME_name_leave_exactly_one_row()Returns
Section titled “Returns”Remarks
Section titled “Remarks”A uniqueness key that does not match shows up first as a race: two writers each miss the other’s row and both insert.
Concurrent_writes_with_null_and_empty_MessageId_leave_exactly_one_row()
Section titled “ Concurrent_writes_with_null_and_empty_MessageId_leave_exactly_one_row()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 235)]public Task Concurrent_writes_with_null_and_empty_MessageId_leave_exactly_one_row()Returns
Section titled “Returns”Remarks
Section titled “Remarks”A NULL RunScore.MessageId and an empty ONE both mean “the whole run” (RunScoreStoreContract.Score_with_no_message_id_belongs_to_the_whole_run), so a concurrent write of one shape racing a write of the OTHER shape must still collapse to a single row – not two, one per shape.
CountAsync(string)
Section titled “ CountAsync(string)”Reports how many records the given tenant sees through the listing endpoint.
protected override ValueTask<int> CountAsync(string tenantId)Parameters
Section titled “Parameters”tenantId string
The reading tenant.
Returns
Section titled “Returns”The number of records seen.
Deleting_a_nonexistent_score_returns_false()
Section titled “ Deleting_a_nonexistent_score_returns_false()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 339)]public Task Deleting_a_nonexistent_score_returns_false()Returns
Section titled “Returns”Different_authors_score_the_same_target_independently()
Section titled “ Different_authors_score_the_same_target_independently()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 267)]public Task Different_authors_score_the_same_target_independently()Returns
Section titled “Returns”Different_kinds_of_the_same_name_are_not_averaged_together()
Section titled “ Different_kinds_of_the_same_name_are_not_averaged_together()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 371)]public Task Different_kinds_of_the_same_name_are_not_averaged_together()Returns
Section titled “Returns”Different_messages_are_scored_independently()
Section titled “ Different_messages_are_scored_independently()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 278)]public Task Different_messages_are_scored_independently()Returns
Section titled “Returns”Empty_author_makes_EVERY_call_open_a_new_row()
Section titled “ Empty_author_makes_EVERY_call_open_a_new_row()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 290)]public Task Empty_author_makes_EVERY_call_open_a_new_row()Returns
Section titled “Returns”ExistsAsync(string, object)
Section titled “ ExistsAsync(string, object)”Reports whether the record is visible from the given tenant’s viewpoint.
protected override ValueTask<bool> ExistsAsync(string tenantId, object key)Parameters
Section titled “Parameters”tenantId string
The reading tenant.
key object
The key returned by TenantIsolationContract.SeedAsync.
Returns
Section titled “Returns”true if the record is visible.
Hour_buckets_group_scores_within_the_same_hour()
Section titled “ Hour_buckets_group_scores_within_the_same_hour()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 617)]public Task Hour_buckets_group_scores_within_the_same_hour()Returns
Section titled “Returns”MessageId_is_never_a_breakdown_dimension()
Section titled “ MessageId_is_never_a_breakdown_dimension()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 501)]public Task MessageId_is_never_a_breakdown_dimension()Returns
Section titled “Returns”Repeated_writes_of_the_SAME_name_leave_exactly_one_row()
Section titled “ Repeated_writes_of_the_SAME_name_leave_exactly_one_row()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 251)]public Task Repeated_writes_of_the_SAME_name_leave_exactly_one_row()Returns
Section titled “Returns”Same_author_scoring_the_same_target_twice_UPDATES_the_row()
Section titled “ Same_author_scoring_the_same_target_twice_UPDATES_the_row()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 80)]public Task Same_author_scoring_the_same_target_twice_UPDATES_the_row()Returns
Section titled “Returns”Same_author_scoring_the_same_target_under_a_DIFFERENT_name_opens_a_new_row()
Section titled “ Same_author_scoring_the_same_target_under_a_DIFFERENT_name_opens_a_new_row()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 95)]public Task Same_author_scoring_the_same_target_under_a_DIFFERENT_name_opens_a_new_row()Returns
Section titled “Returns”Score_is_deleted()
Section titled “ Score_is_deleted()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 315)]public Task Score_is_deleted()Returns
Section titled “Returns”Score_with_no_message_id_belongs_to_the_whole_run()
Section titled “ Score_with_no_message_id_belongs_to_the_whole_run()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 70)]public Task Score_with_no_message_id_belongs_to_the_whole_run()Returns
Section titled “Returns”Scores_are_grouped_into_time_buckets_and_empty_buckets_are_omitted()
Section titled “ Scores_are_grouped_into_time_buckets_and_empty_buckets_are_omitted()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 591)]public Task Scores_are_grouped_into_time_buckets_and_empty_buckets_are_omitted()Returns
Section titled “Returns”SeedAsync(string, string)
Section titled “ SeedAsync(string, string)”Writes a sample record for the given tenant.
protected override ValueTask<object> SeedAsync(string tenantId, string name)Parameters
Section titled “Parameters”tenantId string
The tenant that owns the record.
name string
The name distinguishing the record. The same name may be used by two tenants.
Returns
Section titled “Returns”The key to use for reading the record back.
Remarks
Section titled “Remarks”A score is attached to a run; the distinguishing key is the run id. Two tenants use the same run id: if isolation leaked, tenant B would see tenant A’s score.
Summary_can_be_read_while_a_score_is_being_written()
Section titled “ Summary_can_be_read_while_a_score_is_being_written()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 692)]public Task Summary_can_be_read_while_a_score_is_being_written()Returns
Section titled “Returns”Target_Message_excludes_run_level_scores()
Section titled “ Target_Message_excludes_run_level_scores()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 533)]public Task Target_Message_excludes_run_level_scores()Returns
Section titled “Returns”Target_Run_excludes_message_level_scores()
Section titled “ Target_Run_excludes_message_level_scores()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 519)]public Task Target_Run_excludes_message_level_scores()Returns
Section titled “Returns”TryDeleteAsync(string, object)
Section titled “ TryDeleteAsync(string, object)”Attempts to delete the record on behalf of the given tenant.
protected override ValueTask<bool?> TryDeleteAsync(string tenantId, object key)Parameters
Section titled “Parameters”tenantId string
The tenant attempting the delete.
key object
The key returned by TenantIsolationContract.SeedAsync.
Returns
Section titled “Returns”true if the delete succeeded, false if the record was not found; null if the store does not offer deletion.
Updating_ONE_name_leaves_the_authors_other_names_untouched()
Section titled “ Updating_ONE_name_leaves_the_authors_other_names_untouched()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 112)]public Task Updating_ONE_name_leaves_the_authors_other_names_untouched()Returns
Section titled “Returns”Week_buckets_start_on_Monday_and_group_the_whole_week()
Section titled “ Week_buckets_start_on_Monday_and_group_the_whole_week()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 650)]public Task Week_buckets_start_on_Monday_and_group_the_whole_week()Returns
Section titled “Returns”Remarks
Section titled “Remarks”The week bucket is the riskiest of the three: each of the four
implementations (three SQL dialects plus the in-memory store) computes
“the preceding Monday” with a DIFFERENT formula (see
RunScoreBucketing.Truncate’s remarks and each provider’s
SelectRunScoreSeries query). This test is what proves they agree.
Written_score_is_read_back()
Section titled “ Written_score_is_read_back()”[Fact("/Users/farukatasoy/Desktop/projects/Tracon/src/Tracon.Testing.Contracts.Xunit/Contracts/RunScoreStoreContract.cs", 48)]public Task Written_score_is_read_back()