diff --git a/src/EventSourcingTests/Bugs/Bug_4619_archive_stream_explicit_column_list_after_column_add.cs b/src/EventSourcingTests/Bugs/Bug_4619_archive_stream_explicit_column_list_after_column_add.cs index 901e386736..4397bb22bf 100644 --- a/src/EventSourcingTests/Bugs/Bug_4619_archive_stream_explicit_column_list_after_column_add.cs +++ b/src/EventSourcingTests/Bugs/Bug_4619_archive_stream_explicit_column_list_after_column_add.cs @@ -36,23 +36,13 @@ namespace EventSourcingTests.Bugs; /// is robust to physical-order drift. /// /// -public class Bug_4619_archive_stream_explicit_column_list_after_column_add +public class Bug_4619_archive_stream_explicit_column_list_after_column_add: BugIntegrationContext { [Fact] public async Task archive_stream_succeeds_after_a_post_creation_column_add() { - var schema = $"bug4619_{Environment.ProcessId}_{Guid.NewGuid():N}".Substring(0, 32); - - await using (var conn = new NpgsqlConnection(ConnectionSource.ConnectionString)) - { - await conn.OpenAsync(); - try { await conn.DropSchemaAsync(schema); } catch { } - } - - using var store = DocumentStore.For(opts => + var store = StoreOptions(opts => { - opts.Connection(ConnectionSource.ConnectionString); - opts.DatabaseSchemaName = schema; opts.Events.AppendMode = EventAppendMode.QuickWithServerTimestamps; // UseArchivedStreamPartitioning routes archives through the bulk // function variant (writeWithPartitioning) — the broken positional @@ -85,8 +75,8 @@ public async Task archive_stream_succeeds_after_a_post_creation_column_add() await using (var conn = new NpgsqlConnection(ConnectionSource.ConnectionString)) { await conn.OpenAsync(); - await conn.CreateCommand($"alter table {schema}.mt_events drop column bdata").ExecuteNonQueryAsync(); - await conn.CreateCommand($"alter table {schema}.mt_events add column bdata bytea null").ExecuteNonQueryAsync(); + await conn.CreateCommand($"alter table {SchemaName}.mt_events drop column bdata").ExecuteNonQueryAsync(); + await conn.CreateCommand($"alter table {SchemaName}.mt_events add column bdata bytea null").ExecuteNonQueryAsync(); } // Archive — the positional INSERT inside mt_archive_stream would diff --git a/src/EventSourcingTests/Bugs/Bug_4625_bulk_insert_events_derives_aggregate_type_name.cs b/src/EventSourcingTests/Bugs/Bug_4625_bulk_insert_events_derives_aggregate_type_name.cs index 3c7359543a..980b3e9f57 100644 --- a/src/EventSourcingTests/Bugs/Bug_4625_bulk_insert_events_derives_aggregate_type_name.cs +++ b/src/EventSourcingTests/Bugs/Bug_4625_bulk_insert_events_derives_aggregate_type_name.cs @@ -33,22 +33,13 @@ namespace EventSourcingTests.Bugs; /// callers needing to reach for the internal set. /// /// -public class Bug_4625_bulk_insert_events_derives_aggregate_type_name +public class Bug_4625_bulk_insert_events_derives_aggregate_type_name: BugIntegrationContext { [Fact] public async Task BulkInsertEventsAsync_writes_mt_streams_type_from_AggregateType() { - var schema = $"bug4625_{Environment.ProcessId}_{Guid.NewGuid():N}".Substring(0, 32); - await using (var conn = new NpgsqlConnection(ConnectionSource.ConnectionString)) + var store = StoreOptions(opts => { - await conn.OpenAsync(); - try { await conn.DropSchemaAsync(schema); } catch { } - } - - using var store = DocumentStore.For(opts => - { - opts.Connection(ConnectionSource.ConnectionString); - opts.DatabaseSchemaName = schema; opts.Events.TenancyStyle = TenancyStyle.Conjoined; opts.Events.StreamIdentity = StreamIdentity.AsString; opts.Events.AppendMode = EventAppendMode.QuickWithServerTimestamps; @@ -71,7 +62,7 @@ public async Task BulkInsertEventsAsync_writes_mt_streams_type_from_AggregateTyp await using var conn2 = new NpgsqlConnection(ConnectionSource.ConnectionString); await conn2.OpenAsync(); await using var cmd = conn2.CreateCommand( - $"select type from {schema}.mt_streams where id = @id and tenant_id = @tid"); + $"select type from {SchemaName}.mt_streams where id = @id and tenant_id = @tid"); cmd.Parameters.AddWithValue("id", streamKey); cmd.Parameters.AddWithValue("tid", "alpha"); var typeName = (string?)await cmd.ExecuteScalarAsync(); @@ -91,17 +82,8 @@ public async Task bulk_inserted_stream_with_AggregateType_supports_subsequent_Ap // type was lost (NULL) can't take any further appends — the mandatory // guard fires on every subsequent operation. Post-fix, the bulk-inserted // stream's type IS set, so appends work. - var schema = $"bug4625b_{Environment.ProcessId}_{Guid.NewGuid():N}".Substring(0, 32); - await using (var conn = new NpgsqlConnection(ConnectionSource.ConnectionString)) - { - await conn.OpenAsync(); - try { await conn.DropSchemaAsync(schema); } catch { } - } - - using var store = DocumentStore.For(opts => + var store = StoreOptions(opts => { - opts.Connection(ConnectionSource.ConnectionString); - opts.DatabaseSchemaName = schema; opts.Events.TenancyStyle = TenancyStyle.Conjoined; opts.Events.StreamIdentity = StreamIdentity.AsString; opts.Events.AppendMode = EventAppendMode.QuickWithServerTimestamps; diff --git a/src/EventSourcingTests/Projections/MultiStreamProjections/CustomGroupers/Bug_4261_multistream_sample_coverage.cs b/src/EventSourcingTests/Projections/MultiStreamProjections/CustomGroupers/Bug_4261_multistream_sample_coverage.cs index 3c1564d535..f6f1255ad3 100644 --- a/src/EventSourcingTests/Projections/MultiStreamProjections/CustomGroupers/Bug_4261_multistream_sample_coverage.cs +++ b/src/EventSourcingTests/Projections/MultiStreamProjections/CustomGroupers/Bug_4261_multistream_sample_coverage.cs @@ -30,7 +30,7 @@ namespace EventSourcingTests.Projections.MultiStreamProjections.CustomGroupers; /// https://github.com/JasperFx/marten/discussions/3615. /// Pattern 3 should pass because the derived event carries the group key directly. /// -public partial class Bug_4261_multistream_sample_coverage +public partial class Bug_4261_multistream_sample_coverage: OneOffConfigurationsContext { private readonly ITestOutputHelper _output; @@ -44,10 +44,8 @@ public Bug_4261_multistream_sample_coverage(ITestOutputHelper output) [Fact] public async Task pattern1_async_same_batch_link_and_usage_is_applied_correctly() { - await using var store = DocumentStore.For(opts => + var store = StoreOptions(opts => { - opts.Connection(ConnectionSource.ConnectionString); - opts.DatabaseSchemaName = $"b4261_p1_net{Environment.Version.Major}"; opts.Events.StreamIdentity = StreamIdentity.AsString; opts.Events.AddEventType(typeof(P1.CustomerRegistered)); opts.Events.AddEventType(typeof(P1.CustomerLinkedToExternalAccount)); @@ -57,8 +55,6 @@ public async Task pattern1_async_same_batch_link_and_usage_is_applied_correctly( opts.Projections.Add(ProjectionLifecycle.Async); }); - await store.Advanced.Clean.CompletelyRemoveAllAsync(); - using var daemon = await store.BuildProjectionDaemonAsync(); await daemon.StartAllAsync(); @@ -93,10 +89,8 @@ public async Task pattern1_async_usage_before_link_in_separate_batches_works() { // Sanity baseline: when the link is committed first and the usage arrives // in a later batch, Pattern 1 should Just Work. - await using var store = DocumentStore.For(opts => + var store = StoreOptions(opts => { - opts.Connection(ConnectionSource.ConnectionString); - opts.DatabaseSchemaName = $"b4261_p1_seq_net{Environment.Version.Major}"; opts.Events.StreamIdentity = StreamIdentity.AsString; opts.Events.AddEventType(typeof(P1.CustomerRegistered)); opts.Events.AddEventType(typeof(P1.CustomerLinkedToExternalAccount)); @@ -106,8 +100,6 @@ public async Task pattern1_async_usage_before_link_in_separate_batches_works() opts.Projections.Add(ProjectionLifecycle.Async); }); - await store.Advanced.Clean.CompletelyRemoveAllAsync(); - using var daemon = await store.BuildProjectionDaemonAsync(); await daemon.StartAllAsync(); @@ -157,10 +149,8 @@ public async Task pattern2_async_same_batch_loses_usage_event_known_limitation() // // If a future engine change makes Pattern 2 work under same-batch ordering, // this test will fail and should be retired. - await using var store = DocumentStore.For(opts => + var store = StoreOptions(opts => { - opts.Connection(ConnectionSource.ConnectionString); - opts.DatabaseSchemaName = $"b4261_p2_net{Environment.Version.Major}"; opts.Events.StreamIdentity = StreamIdentity.AsString; opts.Events.AddEventType(typeof(P2.CustomerRegistered)); opts.Events.AddEventType(typeof(P2.CustomerLinkedToExternalAccount)); @@ -169,8 +159,6 @@ public async Task pattern2_async_same_batch_loses_usage_event_known_limitation() opts.Projections.Add(ProjectionLifecycle.Async); }); - await store.Advanced.Clean.CompletelyRemoveAllAsync(); - using var daemon = await store.BuildProjectionDaemonAsync(); await daemon.StartAllAsync(); @@ -204,10 +192,8 @@ public async Task pattern2_async_link_in_earlier_batch_then_usage_works() { // Sanity baseline: when the link arrives first and is already applied to the // projection, Pattern 2's containment query in a later batch finds the owner. - await using var store = DocumentStore.For(opts => + var store = StoreOptions(opts => { - opts.Connection(ConnectionSource.ConnectionString); - opts.DatabaseSchemaName = $"b4261_p2_seq_net{Environment.Version.Major}"; opts.Events.StreamIdentity = StreamIdentity.AsString; opts.Events.AddEventType(typeof(P2.CustomerRegistered)); opts.Events.AddEventType(typeof(P2.CustomerLinkedToExternalAccount)); @@ -216,8 +202,6 @@ public async Task pattern2_async_link_in_earlier_batch_then_usage_works() opts.Projections.Add(ProjectionLifecycle.Async); }); - await store.Advanced.Clean.CompletelyRemoveAllAsync(); - using var daemon = await store.BuildProjectionDaemonAsync(); await daemon.StartAllAsync(); @@ -259,10 +243,8 @@ public async Task pattern4_async_same_batch_link_and_usage_works() // to pick up link events that share the same daemon cycle as the usage // event. This is the recommended pattern when link+usage events can // appear in a single SaveChangesAsync. - await using var store = DocumentStore.For(opts => + var store = StoreOptions(opts => { - opts.Connection(ConnectionSource.ConnectionString); - opts.DatabaseSchemaName = $"b4261_p4_net{Environment.Version.Major}"; opts.Events.StreamIdentity = StreamIdentity.AsString; opts.Events.AddEventType(typeof(P4.CustomerRegistered)); opts.Events.AddEventType(typeof(P4.CustomerLinkedToExternalAccount)); @@ -272,8 +254,6 @@ public async Task pattern4_async_same_batch_link_and_usage_works() opts.Projections.Add(ProjectionLifecycle.Async); }); - await store.Advanced.Clean.CompletelyRemoveAllAsync(); - using var daemon = await store.BuildProjectionDaemonAsync(); await daemon.StartAllAsync(); @@ -304,10 +284,8 @@ public async Task pattern4_async_link_in_earlier_batch_then_usage_works() { // Baseline: Pattern 4 must also handle the case where the link event // was committed in a prior batch. The DB fallback covers that. - await using var store = DocumentStore.For(opts => + var store = StoreOptions(opts => { - opts.Connection(ConnectionSource.ConnectionString); - opts.DatabaseSchemaName = $"b4261_p4_seq_net{Environment.Version.Major}"; opts.Events.StreamIdentity = StreamIdentity.AsString; opts.Events.AddEventType(typeof(P4.CustomerRegistered)); opts.Events.AddEventType(typeof(P4.CustomerLinkedToExternalAccount)); @@ -317,8 +295,6 @@ public async Task pattern4_async_link_in_earlier_batch_then_usage_works() opts.Projections.Add(ProjectionLifecycle.Async); }); - await store.Advanced.Clean.CompletelyRemoveAllAsync(); - using var daemon = await store.BuildProjectionDaemonAsync(); await daemon.StartAllAsync(); @@ -357,17 +333,13 @@ public async Task pattern3_async_same_batch_is_correct_by_design() { // Pattern 3 keeps the grouping key (CustomerId) on the terminal event itself, // so same-batch ordering cannot create a race. - await using var store = DocumentStore.For(opts => + var store = StoreOptions(opts => { - opts.Connection(ConnectionSource.ConnectionString); - opts.DatabaseSchemaName = $"b4261_p3_net{Environment.Version.Major}"; opts.Events.AddEventType(typeof(P3.ShipmentBilled)); opts.Projections.Add(ProjectionLifecycle.Async); }); - await store.Advanced.Clean.CompletelyRemoveAllAsync(); - using var daemon = await store.BuildProjectionDaemonAsync(); await daemon.StartAllAsync(); diff --git a/src/EventSourcingTests/rebuild_concurrency_cap_resolution.cs b/src/EventSourcingTests/rebuild_concurrency_cap_resolution.cs index 6c61c4d76e..d4229484d5 100644 --- a/src/EventSourcingTests/rebuild_concurrency_cap_resolution.cs +++ b/src/EventSourcingTests/rebuild_concurrency_cap_resolution.cs @@ -12,29 +12,19 @@ namespace EventSourcingTests; // jasperfx#420 / marten#4710: resolution of the per-database rebuild concurrency cap // surfaced through IEventStore.MaxConcurrentRebuildsPerDatabase. -public class rebuild_concurrency_cap_resolution +public class rebuild_concurrency_cap_resolution: OneOffConfigurationsContext { - private static DocumentStore storeWith(Action configure) - { - return DocumentStore.For(opts => - { - opts.Connection(ConnectionSource.ConnectionString); - opts.DatabaseSchemaName = "rebuild_cap"; - configure(opts); - }); - } - [Fact] public void configured_value_wins_over_derived_default() { - using var store = storeWith(opts => opts.Projections.MaxConcurrentRebuildsPerDatabase = 3); + var store = SeparateStore(opts => opts.Projections.MaxConcurrentRebuildsPerDatabase = 3); ((IEventStore)store).MaxConcurrentRebuildsPerDatabase.ShouldBe(3); } [Fact] public void non_positive_configured_value_disables_the_cap() { - using var store = storeWith(opts => opts.Projections.MaxConcurrentRebuildsPerDatabase = 0); + var store = SeparateStore(opts => opts.Projections.MaxConcurrentRebuildsPerDatabase = 0); ((IEventStore)store).MaxConcurrentRebuildsPerDatabase.ShouldBeNull(); } @@ -46,11 +36,7 @@ public void derived_default_is_pool_size_over_eight_with_floor_of_one() MaxPoolSize = 64 }.ConnectionString; - using var store = DocumentStore.For(opts => - { - opts.Connection(connectionString); - opts.DatabaseSchemaName = "rebuild_cap"; - }); + var store = SeparateStore(opts => opts.Connection(connectionString)); ((IEventStore)store).MaxConcurrentRebuildsPerDatabase.ShouldBe(8); } @@ -63,11 +49,7 @@ public void derived_default_floors_at_one_for_tiny_pools() MaxPoolSize = 5 }.ConnectionString; - using var store = DocumentStore.For(opts => - { - opts.Connection(connectionString); - opts.DatabaseSchemaName = "rebuild_cap"; - }); + var store = SeparateStore(opts => opts.Connection(connectionString)); ((IEventStore)store).MaxConcurrentRebuildsPerDatabase.ShouldBe(1); } @@ -77,7 +59,7 @@ public async Task usage_descriptor_carries_the_effective_cap() { // jasperfx#434: CritterWatch#309's rebuild dispatcher reads the effective cap // off the EventStoreUsage descriptor rather than guessing. - using var store = storeWith(opts => opts.Projections.MaxConcurrentRebuildsPerDatabase = 6); + var store = SeparateStore(opts => opts.Projections.MaxConcurrentRebuildsPerDatabase = 6); var usage = await ((IEventStore)store).TryCreateUsage(CancellationToken.None);