Skip to content
Tracon

RunStoreContract

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

Behavior tests for the IRunStore contract.

public abstract class RunStoreContract : TenantIsolationContract<IRunStore>, IAsyncLifetime, IAsyncDisposable
Inheritance
object ← StoreCancellationContract<IRunStore> ← TenantIsolationContract<IRunStore> ← RunStoreContract
Implements
IAsyncLifetime, IAsyncDisposable
Inherited Members
TenantIsolationContract<IRunStore>.TenantA, TenantIsolationContract<IRunStore>.TenantB, TenantIsolationContract<IRunStore>.UseAmbientTenant(MutableTenantContext), TenantIsolationContract<IRunStore>.SeedAsync(string, string, CancellationToken), TenantIsolationContract<IRunStore>.ExistsAsync(string, object), TenantIsolationContract<IRunStore>.CountAsync(string, CancellationToken), TenantIsolationContract<IRunStore>.TryDeleteAsync(string, object), TenantIsolationContract<IRunStore>.TryOverwriteAsync(string, string), TenantIsolationContract<IRunStore>.CancellableReadAsync(CancellationToken), TenantIsolationContract<IRunStore>.CancellableWriteAsync(CancellationToken), TenantIsolationContract<IRunStore>.WroteAnythingAsync(), TenantIsolationContract<IRunStore>.Tenant_cannot_read_another_tenants_record(), TenantIsolationContract<IRunStore>.Tenant_reads_its_own_record(), TenantIsolationContract<IRunStore>.Tenant_does_not_see_another_tenants_record_in_the_list(), TenantIsolationContract<IRunStore>.Tenant_cannot_delete_another_tenants_record(), TenantIsolationContract<IRunStore>.Same_name_lives_independently_across_two_tenants(), TenantIsolationContract<IRunStore>.AmbientTenant, StoreCancellationContract<IRunStore>.CreateStoreAsync(), StoreCancellationContract<IRunStore>.InitializeAsync(), StoreCancellationContract<IRunStore>.DisposeAsync(), StoreCancellationContract<IRunStore>.OnDisposeAsync(), StoreCancellationContract<IRunStore>.CancellableReadAsync(CancellationToken), StoreCancellationContract<IRunStore>.CancellableWriteAsync(CancellationToken), StoreCancellationContract<IRunStore>.WroteAnythingAsync(), StoreCancellationContract<IRunStore>.Canceled_token_throws_on_read(), StoreCancellationContract<IRunStore>.The_write_this_contract_checks_can_be_read_back(), StoreCancellationContract<IRunStore>.Canceled_token_throws_on_write_and_leaves_no_trace(), StoreCancellationContract<IRunStore>.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.

protected RunStoreContract()

A_label_key_without_a_value_matches_any_value_of_that_key()

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

Task

A_queued_workflow_row_keeps_its_workflow_session_and_attribution_when_it_starts()

Section titled “ A_queued_workflow_row_keeps_its_workflow_session_and_attribution_when_it_starts()”

A queued workflow row keeps what it was queued with when the engine starts the same run.

[Fact]
public Task A_queued_workflow_row_keeps_its_workflow_session_and_attribution_when_it_starts()

Task

The HTTP layer writes the queued row, where the caller is known; the workflow engine writes it again in a background worker, where the caller is not. The row must still name the workflow, its session and the caller.

A_run_promoted_from_Queued_to_Running_keeps_the_heartbeat_it_sent_while_it_waited()

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

Task

A_run_that_reports_only_a_cache_count_still_produces_a_usage_record()

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

Task

A_run_without_attribution_reads_back_as_null_not_as_an_empty_map()

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

Task

Section titled “ A_second_start_without_a_continuation_link_keeps_the_first_one()”

The continuation link survives the second start of the same run, like the attribution does.

[Fact]
public Task A_second_start_without_a_continuation_link_keeps_the_first_one()

Task

Workflow recovery writes the continuation’s row first, with the link, and the workflow engine then starts the same run again without knowing the link. A plain overwrite erased the chain, and the run that continued the work no longer pointed at the run it continued.

A_second_start_without_attribution_does_not_erase_the_first_one()

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

Task

A_tree_in_which_only_a_child_reported_still_has_a_tree_total()

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

Task

An_unknown_run_has_no_last_event_sequence()

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

Task

AppendEventAsync_does_not_write_with_the_wrong_expected_tenant()

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

Task

Applied_unit_prices_round_trip_and_do_not_enter_the_total()

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

Task

[Fact]
public Task Attribution_round_trips()

Task

Canceled_token_throws_on_the_first_step_of_the_event_stream()

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

Task

ClaimOrphanedRunsAsync_closes_a_Queued_row_whose_heartbeat_is_stale()

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

Task

ClaimOrphanedRunsAsync_does_not_touch_a_Queued_row_with_a_fresh_heartbeat()

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

Task

ClaimOrphanedRunsAsync_does_not_touch_a_Running_row_within_the_threshold()

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

Task

ClaimOrphanedRunsAsync_marks_a_stale_Running_row_as_Failed()

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

Task

ClaimOrphanedRunsAsync_never_touches_a_Queued_row_that_has_no_heartbeat()

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

Task

ClaimOrphanedRunsAsync_reports_ContinuedFromRunId_on_the_claimed_record()

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

Task

ClaimOrphanedRunsAsync_reports_the_kind_and_the_tree_position_on_the_claimed_record()

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

Task

CompleteRunAsync_does_not_close_with_the_wrong_expected_tenant()

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

Task

Completion_leaves_the_model_id_unchanged_when_no_override_is_given()

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

Task

Completion_leaves_the_model_provider_unchanged_when_no_override_is_given()

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

Task

Completion_overrides_the_model_id_when_a_fallback_answered()

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

Task

Completion_overrides_the_model_provider_when_a_fallback_answered()

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

Task

Completion_stores_error_class_and_fingerprint()

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

Task

[Fact]
public Task Completion_updates_the_summary()

Task

[Fact]
public Task ContinuedFromRunId_round_trips()

Task

Cost_does_not_exist_at_all_when_model_is_unknown()

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

Task

Cost_fields_are_null_but_source_is_written_as_unknown_when_pricing_is_undefined()

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

Task

[Fact]
public Task Cost_is_written_and_read_back()

Task

Cost_recalculation_updates_the_target_row()

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

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.

The score store that writes into the SAME backend as Store.

protected virtual ValueTask<IRunScoreStore?> CreateScoreStoreAsync()

ValueTask<IRunScoreStore?>

The score store, or null when the fixture has none.

IRunStore.GetExperimentResultsAsync averages the run_scores rows belonging to each run, but scores are written through a DIFFERENT interface. A fixture that cannot hand back a score store pointing at the same backend skips the scenarios that need one; every store in this repository overrides this.

Virtual and not abstract on purpose: this contract ships, and turning an existing contract class abstract would break every third-party store that already derives from it.

Custom_event_custom_type_round_trips_and_stays_null_for_every_other_type()

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

Task

[Fact]
public Task Empty_store_summary_returns_zero()

Task

Event_cannot_be_appended_to_a_nonexistent_run()

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

Task

[Fact]
public Task Event_fields_round_trip()

Task

[Fact]
public Task Events_are_read_in_sequence_order()

Task

Every_cost_total_includes_the_cache_charge()

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

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_results_are_summarized_per_arm()

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

Task

Experiment_results_average_a_run_level_score_written_with_an_empty_message_id()

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

Task

[Fact]
public Task Experiment_results_include_cost()

Task

Experiment_results_leave_a_message_level_score_out_of_the_average()

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

Task

Experiment_results_return_empty_for_an_experiment_with_no_traffic()

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

Task

Items_that_carried_no_amount_keep_their_count_and_a_null_amount()

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

Task

[Fact]
public Task List_returns_only_root_runs_by_default()

Task

No_cost_total_adds_amounts_in_two_currencies()

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

Task

Non_token_cost_is_a_total_of_its_own_and_never_a_term_of_the_token_cost()

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

Task

Non_token_cost_snapshot_round_trips_and_a_run_that_reported_nothing_has_none()

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

Task

[Fact]
public Task Nonexistent_run_cannot_be_completed()

Task

[Fact]
public Task Nonexistent_run_returns_empty_events()

Task

[Fact]
public Task Nonexistent_run_returns_null()

Task

[Fact]
public Task Parent_filter_overrides_root_filter()

Task

[Fact]
public Task Query_applies_paging()

Task

Query_by_continuation_does_not_return_another_tenants_run()

Section titled “ Query_by_continuation_does_not_return_another_tenants_run()”

The forward walk does not cross a tenant boundary.

[Fact]
public Task Query_by_continuation_does_not_return_another_tenants_run()

Task

Query_filters_by_a_label_key_and_value_together()

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

Task

[Fact]
public Task Query_filters_by_agent_name()

Task

[Fact]
public Task Query_filters_by_error_type()

Task

[Fact]
public Task Query_filters_by_start_time()

Task

[Fact]
public Task Query_filters_by_status()

Task

Query_filters_by_the_run_a_continuation_continues()

Section titled “ Query_filters_by_the_run_a_continuation_continues()”

A chain is walked forward by asking for the runs that continue a given run.

[Fact]
public Task Query_filters_by_the_run_a_continuation_continues()

Task

[Fact]
public Task Query_filters_by_user()

Task

Query_session_filter_with_includeChildren_also_returns_child_runs()

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

Task

[Fact]
public Task Query_sorts_newest_first()

Task

RecordToolInvocationAsync_does_not_write_with_the_wrong_expected_tenant()

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

Task

[Fact]
public Task Reusing_a_sequence_number_is_rejected()

Task

Run_record_is_stamped_with_the_current_tenant()

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

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.

The tenant is not a parameter on the interface; it is read from ITenantContext. Each hook therefore sets the current tenant first.

StartRunAsync_return_value_carries_the_coalesced_attribution()

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

Task

StartRunAsync_upserts_when_called_twice_with_the_same_id()

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

Task

Statistics_break_down_by_label_and_the_rows_do_not_partition_the_runs()

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

Task

[Fact]
public Task Statistics_break_down_by_user()

Task

Statistics_narrow_to_one_label_when_asked()

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

Task

Statistics_narrow_to_one_user_when_asked()

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

Task

Statistics_total_the_token_breakdown_beside_the_input_and_output_totals()

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

Task

Summary_aggregates_cost_and_reports_the_undefined_count()

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

Task

[Fact]
public Task Summary_aggregates_statuses_and_tokens()

Task

Summary_and_time_series_do_not_leak_across_tenants()

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

Task

Summary_computes_breakdown_by_error_class()

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

Task

Summary_computes_error_rate_only_over_completed_runs()

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

Task

[Fact]
public Task Summary_computes_version_breakdown()

Task

[Fact]
public Task Summary_excludes_eval_runs()

Task

[Fact]
public Task Summary_filters_by_agent_name()

Task

[Fact]
public Task Summary_filters_by_start_time()

Task

[Fact]
public Task Summary_limits_agent_breakdown()

Task

Summary_returns_at_most_three_failure_clusters_per_class()

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

Task

Summary_returns_no_error_rate_when_no_run_has_completed()

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

Task

Summary_rows_with_no_error_class_appear_in_the_unknown_bucket()

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

Task

Summary_sorts_agent_breakdown_by_run_count()

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

Task

The_cache_charge_round_trips_and_counts_toward_the_total()

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

Task

The_largest_total_a_run_writes_fits_the_snapshot_column()

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

Task

A run that is retried keeps its identity, so the second attempt must continue the event stream instead of restarting it.

[Fact]
public Task The_last_event_sequence_is_readable()

Task

Without it the writer restarted at zero on every lease takeover, hit the unique (run_id, seq) key, disabled itself for the rest of the run, and then skipped the completion write. The job reported Completed while the run stayed in RunStatus.Running forever. A store answers this question so the writer never has to guess.

The_token_breakdown_round_trips_and_stays_null_when_it_was_never_reported()

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

Task

[Fact]
public Task Time_series_does_not_exclude_eval_runs()

Task

[Fact]
public Task Time_series_fills_empty_buckets()

Task

Time_series_throws_when_the_bucket_limit_is_exceeded()

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

Task

[Fact]
public Task Token_info_stays_null_when_absent()

Task

TouchHeartbeatAsync_refreshed_row_is_not_considered_orphaned()

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

Task

TouchHeartbeatAsync_silently_skips_a_nonexistent_or_non_Running_id()

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

Task

Tree_cost_adds_the_cache_charge_of_every_run_in_the_tree()

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

Task

Tree_cost_is_not_summed_with_its_own_cost_separate_fields()

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

Task

[Fact]
public Task Tree_fields_round_trip()

Task

Tree_non_token_cost_adds_every_run_in_the_tree_once()

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

Task

Tree_query_returns_the_root_and_all_its_descendants()

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

Task

Tree_total_combines_tokens_of_root_and_descendants()

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

Task

Tree_total_stays_null_when_no_tokens_are_reported()

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

Task

Tree_usage_sums_the_breakdown_across_child_runs()

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

Task

Unit_prices_stay_null_when_the_model_price_is_unknown()

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

Task

UpdateRunCostAsync_does_not_update_with_the_wrong_expected_tenant()

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

Task

[Fact]
public Task Workflow_run_lives_in_the_same_table()

Task