diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs index 13f7703b43..39b6bf46e3 100644 --- a/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs +++ b/src/ServiceControl.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -1,6 +1,11 @@ namespace ServiceControl.AcceptanceTests.TestSupport { + using System.IO; + using AcceptanceTesting; + using Microsoft.Extensions.DependencyInjection; using NServiceBus; + using NServiceBus.AcceptanceTesting; + using NServiceBus.Configuration.AdvancedExtensibility; public static class EndpointConfigurationExtensions { @@ -8,5 +13,25 @@ public static void ReportSuccessfulRetriesToServiceControl(this EndpointConfigur { configuration.Pipeline.Register(typeof(ReportSuccessfulRetryToServiceControl), "Simulate that the audit instance detects and reports successfull retries"); } + + public static void CustomizeServiceControlEndpointTesting(this EndpointConfiguration configuration, ScenarioContext context) + { + configuration.GetSettings().Set("SC.ScenarioContext", context); + configuration.GetSettings().Set(context); + + configuration.RegisterComponents(r => + { + r.AddSingleton(context.GetType(), context); + r.AddSingleton(typeof(ScenarioContext), context); + }); + + configuration.Pipeline.Register(); + configuration.Pipeline.Register(); + configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); + configuration.Pipeline.Register(new DiscardMessagesBehavior(context), "Discards messages based on session ID"); + + var assemblyScanner = configuration.AssemblyScanner(); + assemblyScanner.ExcludeAssemblies(Path.GetFileName(typeof(ServiceControlComponentRunner).Assembly.Location)); + } } } \ No newline at end of file diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/HttpClientServiceCollectionExtensions.cs b/src/ServiceControl.AcceptanceTests/TestSupport/HttpClientServiceCollectionExtensions.cs index 50226fef9e..d82ed852a3 100644 --- a/src/ServiceControl.AcceptanceTests/TestSupport/HttpClientServiceCollectionExtensions.cs +++ b/src/ServiceControl.AcceptanceTests/TestSupport/HttpClientServiceCollectionExtensions.cs @@ -8,7 +8,7 @@ namespace ServiceControl.AcceptanceTests.RavenDB.Shared; static class HttpClientServiceCollectionExtensions { - public static void OverrideHttpClientDefaults(this IServiceCollection services, Settings settings) + public static void AddHttpClientDefaultsOverrides(this IServiceCollection services, Settings settings) { services.AddKeyedSingleton>("Forwarding", (provider, _) => () => provider.GetRequiredService().CreateHandler()); services.AddSingleton(p => new HttpMessageInvoker(p.GetRequiredKeyedService>("Forwarding")())); diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs b/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs index 071df639ef..2c9a1d47b1 100644 --- a/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs +++ b/src/ServiceControl.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs @@ -103,23 +103,7 @@ async Task InitializeServiceControl(ScenarioContext context) } var configuration = new EndpointConfiguration(instanceName); - - configuration.GetSettings().Set("SC.ScenarioContext", context); - configuration.GetSettings().Set(context); - - configuration.RegisterComponents(r => - { - r.AddSingleton(context.GetType(), context); - r.AddSingleton(typeof(ScenarioContext), context); - }); - - configuration.Pipeline.Register(); - configuration.Pipeline.Register(); - configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); - configuration.Pipeline.Register(new DiscardMessagesBehavior(context), "Discards messages based on session ID"); - - var assemblyScanner = configuration.AssemblyScanner(); - assemblyScanner.ExcludeAssemblies(Path.GetFileName(typeof(ServiceControlComponentRunner).Assembly.Location)); + configuration.CustomizeServiceControlEndpointTesting(context); customConfiguration(configuration); @@ -136,25 +120,7 @@ async Task InitializeServiceControl(ScenarioContext context) }); hostBuilder.AddServiceControl(settings, configuration, loggingSettings); - // Do not register additional test controllers or hosted services here. Instead, in the test that needs them, use (for example): - // CustomizeHostBuilder = builder => builder.ConfigureServices((hostContext, services) => services.AddHostedService()); - hostBuilder.Logging.AddScenarioContextLogging(); - - // TODO: the following four lines could go into a AddServiceControlTesting() extension - hostBuilder.WebHost.UseTestServer(options => options.BaseAddress = new Uri(settings.RootUrl)); - hostBuilder.Services.AddSingleton(); - - // This facilitates receiving the test server anywhere where DI is available - hostBuilder.Services.AddSingleton(provider => (TestServer)provider.GetRequiredService()); - - // By default ASP.NET Core uses entry point assembly to discover controllers from. When running - // inside a test runner the runner exe becomes the entry point which obviously has no controllers in it ;) - // so we are explicitly registering all necessary application parts. - var addControllers = hostBuilder.Services.AddControllers(); - addControllers.AddApplicationPart(typeof(WebApiHostBuilderExtensions).Assembly); - addControllers.AddApplicationPart(typeof(AcceptanceTest).Assembly); - - hostBuilder.Services.OverrideHttpClientDefaults(settings); + hostBuilder.AddServiceControlTesting(settings); hostBuilderCustomization(hostBuilder); diff --git a/src/ServiceControl.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs b/src/ServiceControl.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs new file mode 100644 index 0000000000..5660b837a3 --- /dev/null +++ b/src/ServiceControl.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs @@ -0,0 +1,35 @@ +namespace ServiceControl.AcceptanceTests.RavenDB.Shared; + +using System; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using ServiceBus.Management.Infrastructure.Settings; +using TestSupport; + +static class WebApplicationBuilderExtensions +{ + public static void AddServiceControlTesting(this WebApplicationBuilder hostBuilder, Settings settings) + { + // Do not register additional test controllers or hosted services here. Instead, in the test that needs them, use (for example): + // CustomizeHostBuilder = builder => builder.ConfigureServices((hostContext, services) => services.AddHostedService()); + hostBuilder.Logging.AddScenarioContextLogging(); + + hostBuilder.WebHost.UseTestServer(options => options.BaseAddress = new Uri(settings.RootUrl)); + hostBuilder.Services.AddSingleton(); + + // This facilitates receiving the test server anywhere where DI is available + hostBuilder.Services.AddSingleton(provider => (TestServer)provider.GetRequiredService()); + + // By default, ASP.NET Core uses the entry point assembly to discover controllers. When running + // inside a test runner the runner exe becomes the entry point which obviously has no controllers in it ;) + // so we are explicitly registering all necessary application parts. + var addControllers = hostBuilder.Services.AddControllers(); + addControllers.AddApplicationPart(typeof(Settings).Assembly); + addControllers.AddApplicationPart(typeof(AcceptanceTest).Assembly); + + hostBuilder.Services.AddHttpClientDefaultsOverrides(settings); + } +} \ No newline at end of file diff --git a/src/ServiceControl.Audit.AcceptanceTests/AcceptanceTest.cs b/src/ServiceControl.Audit.AcceptanceTests/AcceptanceTest.cs index 1aac200db2..a7033e35bf 100644 --- a/src/ServiceControl.Audit.AcceptanceTests/AcceptanceTest.cs +++ b/src/ServiceControl.Audit.AcceptanceTests/AcceptanceTest.cs @@ -32,8 +32,6 @@ protected AcceptanceTest() public HttpClient HttpClient => serviceControlRunnerBehavior.HttpClient; public JsonSerializerOptions SerializerOptions => serviceControlRunnerBehavior.SerializerOptions; - - // TODO Check why this is necessary and if it can be removed protected IServiceProvider ServiceProvider => serviceControlRunnerBehavior.ServiceProvider; [SetUp] diff --git a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs new file mode 100644 index 0000000000..7525f93e11 --- /dev/null +++ b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -0,0 +1,31 @@ +namespace ServiceControl.Audit.AcceptanceTests.TestSupport; + +using System.IO; +using AcceptanceTesting; +using Microsoft.Extensions.DependencyInjection; +using NServiceBus; +using NServiceBus.AcceptanceTesting; +using NServiceBus.Configuration.AdvancedExtensibility; + +static class EndpointConfigurationExtensions +{ + public static void CustomizeServiceControlAuditEndpointTesting(this EndpointConfiguration configuration, ScenarioContext context) + { + configuration.GetSettings().Set("SC.ScenarioContext", context); + configuration.GetSettings().Set(context); + + configuration.RegisterComponents(r => + { + r.AddSingleton(context.GetType(), context); + r.AddSingleton(typeof(ScenarioContext), context); + }); + + configuration.Pipeline.Register(); + configuration.Pipeline.Register(); + configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); + configuration.Pipeline.Register(new DiscardMessagesBehavior(context), "Discards messages based on session ID"); + + var assemblyScanner = configuration.AssemblyScanner(); + assemblyScanner.ExcludeAssemblies(Path.GetFileName(typeof(ServiceControlComponentRunner).Assembly.Location)); + } +} \ No newline at end of file diff --git a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentBehavior.cs b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentBehavior.cs index 2d77d430e5..b95cdd3d62 100644 --- a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentBehavior.cs +++ b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentBehavior.cs @@ -11,35 +11,26 @@ namespace ServiceControl.Audit.AcceptanceTests.TestSupport using NServiceBus.AcceptanceTesting.Support; using ServiceControl.Audit.Infrastructure.Settings; - class ServiceControlComponentBehavior : IComponentBehavior, IAcceptanceTestInfrastructureProvider + class ServiceControlComponentBehavior( + ITransportIntegration transportToUse, + AcceptanceTestStorageConfiguration persistenceToUse, + Action setSettings, + Action customConfiguration, + Action> setStorageConfiguration, + Action hostBuilderCustomization) + : IComponentBehavior, IAcceptanceTestInfrastructureProvider { - public ServiceControlComponentBehavior(ITransportIntegration transportToUse, AcceptanceTestStorageConfiguration persistenceToUse, Action setSettings, Action customConfiguration, Action> setStorageConfiguration, Action hostBuilderCustomization) - { - this.customConfiguration = customConfiguration; - this.persistenceToUse = persistenceToUse; - this.setSettings = setSettings; - this.setStorageConfiguration = setStorageConfiguration; - this.hostBuilderCustomization = hostBuilderCustomization; - transportIntegration = transportToUse; - } - public HttpClient HttpClient => runner.HttpClient; public JsonSerializerOptions SerializerOptions => runner.SerializerOptions; public IServiceProvider ServiceProvider => runner.ServiceProvider; public async Task CreateRunner(RunDescriptor run) { - runner = new ServiceControlComponentRunner(transportIntegration, persistenceToUse, setSettings, customConfiguration, setStorageConfiguration, hostBuilderCustomization); + runner = new ServiceControlComponentRunner(transportToUse, persistenceToUse, setSettings, customConfiguration, setStorageConfiguration, hostBuilderCustomization); await runner.Initialize(run); return runner; } - ITransportIntegration transportIntegration; - AcceptanceTestStorageConfiguration persistenceToUse; - Action setSettings; - Action customConfiguration; ServiceControlComponentRunner runner; - Action> setStorageConfiguration; - Action hostBuilderCustomization; } } \ No newline at end of file diff --git a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs index c71afd3a12..afcb194f79 100644 --- a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs +++ b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs @@ -25,22 +25,15 @@ namespace ServiceControl.Audit.AcceptanceTests.TestSupport using NServiceBus.AcceptanceTesting.Support; using NServiceBus.Configuration.AdvancedExtensibility; - public class ServiceControlComponentRunner : ComponentRunner, IAcceptanceTestInfrastructureProvider + public class ServiceControlComponentRunner( + ITransportIntegration transportToUse, + AcceptanceTestStorageConfiguration persistenceToUse, + Action setSettings, + Action customConfiguration, + Action> setStorageConfiguration, + Action hostBuilderCustomization) + : ComponentRunner, IAcceptanceTestInfrastructureProvider { - public ServiceControlComponentRunner(ITransportIntegration transportToUse, - AcceptanceTestStorageConfiguration persistenceToUse, Action setSettings, - Action customConfiguration, - Action> setStorageConfiguration, - Action hostBuilderCustomization) - { - this.transportToUse = transportToUse; - this.persistenceToUse = persistenceToUse; - this.customConfiguration = customConfiguration; - this.setStorageConfiguration = setStorageConfiguration; - this.setSettings = setSettings; - this.hostBuilderCustomization = hostBuilderCustomization; - } - public override string Name { get; } = $"{nameof(ServiceControlComponentRunner)}"; public HttpClient HttpClient { get; private set; } public JsonSerializerOptions SerializerOptions => Infrastructure.WebApi.SerializerOptions.Default; @@ -109,23 +102,7 @@ async Task InitializeServiceControl(ScenarioContext context) } var configuration = new EndpointConfiguration(instanceName); - - configuration.GetSettings().Set("SC.ScenarioContext", context); - configuration.GetSettings().Set(context); - - configuration.RegisterComponents(r => - { - r.AddSingleton(context.GetType(), context); - r.AddSingleton(typeof(ScenarioContext), context); - }); - - configuration.Pipeline.Register(); - configuration.Pipeline.Register(); - configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); - configuration.Pipeline.Register(new DiscardMessagesBehavior(context), "Discards messages based on session ID"); - - var assemblyScanner = configuration.AssemblyScanner(); - assemblyScanner.ExcludeAssemblies(Path.GetFileName(typeof(ServiceControlComponentRunner).Assembly.Location)); + configuration.CustomizeServiceControlAuditEndpointTesting(context); customConfiguration(configuration); @@ -153,28 +130,13 @@ async Task InitializeServiceControl(ScenarioContext context) return criticalErrorContext.Stop(cancellationToken); }, settings, configuration, loggingSettings); - // Do not register additional test controllers or hosted services here. Instead, in the test that needs them, use (for example): - // CustomizeHostBuilder = builder => builder.ConfigureServices((hostContext, services) => services.AddHostedService()); - hostBuilder.Logging.AddScenarioContextLogging(); - - // TODO: the following four lines could go into a AddServiceControlAuditTesting() extension - hostBuilder.WebHost.UseTestServer(options => options.BaseAddress = new Uri(settings.RootUrl)); - // This facilitates receiving the test server anywhere where DI is available - hostBuilder.Services.AddSingleton(provider => (TestServer)provider.GetRequiredService()); - - // By default ASP.NET Core uses entry point assembly to discover controllers from. When running - // inside a test runner the runner exe becomes the entry point which obviously has no controllers in it ;) - // so we are explicitly registering all necessary application parts. - var addControllers = hostBuilder.Services.AddControllers(); - addControllers.AddApplicationPart(typeof(WebApiHostBuilderExtensions).Assembly); - addControllers.AddApplicationPart(typeof(FailedAuditsController).Assembly); + hostBuilder.AddServiceControlAuditTesting(settings); hostBuilderCustomization(hostBuilder); host = hostBuilder.Build(); host.UseServiceControlAudit(); await host.StartAsync(); - // TODO We can probably remove this by switching over to the hostBuilderCustomization ServiceProvider = host.Services; InstanceTestServer = host.GetTestServer(); HttpClient = InstanceTestServer.CreateClient(); @@ -191,12 +153,6 @@ public override async Task Stop(CancellationToken cancellationToken = default) } } - ITransportIntegration transportToUse; - AcceptanceTestStorageConfiguration persistenceToUse; - Action setSettings; - Action customConfiguration; - Action> setStorageConfiguration; - Action hostBuilderCustomization; string instanceName = Settings.DEFAULT_SERVICE_NAME; WebApplication host; Settings settings; diff --git a/src/ServiceControl.Audit.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs new file mode 100644 index 0000000000..da69c2d069 --- /dev/null +++ b/src/ServiceControl.Audit.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs @@ -0,0 +1,31 @@ +namespace ServiceControl.Audit.AcceptanceTests.TestSupport; + +using System; +using Auditing; +using Infrastructure.Settings; +using Infrastructure.WebApi; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; + +static class WebApplicationBuilderExtensions +{ + public static void AddServiceControlAuditTesting(this WebApplicationBuilder hostBuilder, Settings settings) + { + // Do not register additional test controllers or hosted services here. Instead, in the test that needs them, use (for example): + // CustomizeHostBuilder = builder => builder.ConfigureServices((hostContext, services) => services.AddHostedService()); + hostBuilder.Logging.AddScenarioContextLogging(); + + hostBuilder.WebHost.UseTestServer(options => options.BaseAddress = new Uri(settings.RootUrl)); + // This facilitates receiving the test server anywhere where DI is available + hostBuilder.Services.AddSingleton(provider => (TestServer)provider.GetRequiredService()); + + // By default, ASP.NET Core uses the entry point assembly to discover controllers. When running + // inside a test runner the runner exe becomes the entry point which obviously has no controllers in it ;) + // so we are explicitly registering all necessary application parts. + var addControllers = hostBuilder.Services.AddControllers(); + addControllers.AddApplicationPart(typeof(Settings).Assembly); + addControllers.AddApplicationPart(typeof(AcceptanceTest).Assembly); + } +} \ No newline at end of file diff --git a/src/ServiceControl.Audit/Infrastructure/WebApi/WebApiHostBuilderExtensions.cs b/src/ServiceControl.Audit/Infrastructure/WebApi/WebApplicationBuilderExtensions.cs similarity index 96% rename from src/ServiceControl.Audit/Infrastructure/WebApi/WebApiHostBuilderExtensions.cs rename to src/ServiceControl.Audit/Infrastructure/WebApi/WebApplicationBuilderExtensions.cs index 7a6955e4ba..c29674b888 100644 --- a/src/ServiceControl.Audit/Infrastructure/WebApi/WebApiHostBuilderExtensions.cs +++ b/src/ServiceControl.Audit/Infrastructure/WebApi/WebApplicationBuilderExtensions.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; - static class WebApiHostBuilderExtensions + static class WebApplicationBuilderExtensions { public static void AddWebApi(this WebApplicationBuilder builder, string rootUrl) { diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/AcceptanceTest.cs b/src/ServiceControl.Monitoring.AcceptanceTests/AcceptanceTest.cs index 4b20fc1d21..beff1f693f 100644 --- a/src/ServiceControl.Monitoring.AcceptanceTests/AcceptanceTest.cs +++ b/src/ServiceControl.Monitoring.AcceptanceTests/AcceptanceTest.cs @@ -62,16 +62,11 @@ public void Teardown() Trace.Listeners.Remove(textWriterTraceListener); } - protected IScenarioWithEndpointBehavior Define() where T : ScenarioContext, new() - { - return Define(c => { }); - } + protected IScenarioWithEndpointBehavior Define() where T : ScenarioContext, new() => Define(c => { }); - protected IScenarioWithEndpointBehavior Define(Action contextInitializer) where T : ScenarioContext, new() - { - return Scenario.Define(contextInitializer) + protected IScenarioWithEndpointBehavior Define(Action contextInitializer) where T : ScenarioContext, new() => + Scenario.Define(contextInitializer) .WithComponent(serviceControlRunnerBehavior); - } protected Action CustomConfiguration = _ => { }; protected Action SetSettings = _ => { }; diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs new file mode 100644 index 0000000000..a995c4e850 --- /dev/null +++ b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/EndpointConfigurationExtensions.cs @@ -0,0 +1,31 @@ +namespace ServiceControl.Monitoring.AcceptanceTests.TestSupport; + +using System.IO; +using AcceptanceTesting; +using Microsoft.Extensions.DependencyInjection; +using NServiceBus; +using NServiceBus.AcceptanceTesting; +using NServiceBus.Configuration.AdvancedExtensibility; + +static class EndpointConfigurationExtensions +{ + public static void CustomizeServiceControlMonitoringEndpointTesting(this EndpointConfiguration configuration, ScenarioContext context) + { + configuration.GetSettings().Set("SC.ScenarioContext", context); + configuration.GetSettings().Set(context); + + configuration.RegisterComponents(r => + { + r.AddSingleton(context.GetType(), context); + r.AddSingleton(typeof(ScenarioContext), context); + }); + + configuration.Pipeline.Register(); + configuration.Pipeline.Register(); + configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); + configuration.Pipeline.Register(new DiscardMessagesBehavior(context), "Discards messages based on session ID"); + + var assemblyScanner = configuration.AssemblyScanner(); + assemblyScanner.ExcludeAssemblies(Path.GetFileName(typeof(ServiceControlComponentRunner).Assembly.Location)); + } +} \ No newline at end of file diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs index 461e7c01aa..1562db183b 100644 --- a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs +++ b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/ServiceControlComponentRunner.cs @@ -20,15 +20,12 @@ namespace ServiceControl.Monitoring.AcceptanceTests.TestSupport using NServiceBus.Configuration.AdvancedExtensibility; using NServiceBus.Logging; - class ServiceControlComponentRunner : ComponentRunner, IAcceptanceTestInfrastructureProvider + class ServiceControlComponentRunner( + ITransportIntegration transportToUse, + Action setSettings, + Action customConfiguration) + : ComponentRunner, IAcceptanceTestInfrastructureProvider { - public ServiceControlComponentRunner(ITransportIntegration transportToUse, Action setSettings, Action customConfiguration) - { - this.transportToUse = transportToUse; - this.customConfiguration = customConfiguration; - this.setSettings = setSettings; - } - public override string Name { get; } = $"{nameof(ServiceControlComponentRunner)}"; public HttpClient HttpClient { get; private set; } public JsonSerializerOptions SerializerOptions => Infrastructure.SerializerOptions.Default; @@ -39,7 +36,7 @@ async Task InitializeServiceControl(ScenarioContext context) { settings = new Settings { - EndpointName = instanceName, + EndpointName = Settings.DEFAULT_ENDPOINT_NAME, TransportType = transportToUse.TypeName, ConnectionString = transportToUse.ConnectionString, HttpHostName = "localhost", @@ -77,33 +74,18 @@ async Task InitializeServiceControl(ScenarioContext context) setSettings(settings); - using (new DiagnosticTimer($"Creating infrastructure for {instanceName}")) + using (new DiagnosticTimer($"Creating infrastructure for {settings.EndpointName}")) { var setupCommand = new SetupCommand(); await setupCommand.Execute(settings); } - var configuration = new EndpointConfiguration(instanceName); - - configuration.GetSettings().Set("SC.ScenarioContext", context); - configuration.GetSettings().Set(context); - - configuration.RegisterComponents(r => - { - r.AddSingleton(context.GetType(), context); - r.AddSingleton(typeof(ScenarioContext), context); - }); - - configuration.Pipeline.Register(); - configuration.Pipeline.Register(); - configuration.Pipeline.Register(new StampDispatchBehavior(context), "Stamps outgoing messages with session ID"); - configuration.Pipeline.Register(new DiscardMessagesBehavior(context), "Discards messages based on session ID"); - - configuration.AssemblyScanner().ExcludeAssemblies(typeof(ServiceControlComponentRunner).Assembly.GetName().Name); + var configuration = new EndpointConfiguration(settings.EndpointName); + configuration.CustomizeServiceControlMonitoringEndpointTesting(context); customConfiguration(configuration); - using (new DiagnosticTimer($"Starting host for {instanceName}")) + using (new DiagnosticTimer($"Starting host for {settings.EndpointName}")) { var logPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); Directory.CreateDirectory(logPath); @@ -126,30 +108,19 @@ async Task InitializeServiceControl(ScenarioContext context) return criticalErrorContext.Stop(cancellationToken); }, settings, configuration); - hostBuilder.Logging.AddScenarioContextLogging(); - - hostBuilder.WebHost.UseTestServer(options => options.BaseAddress = new Uri(settings.RootUrl)); - // This facilitates receiving the test server anywhere where DI is available - hostBuilder.Services.AddKeyedSingleton(instanceName, - (provider, _) => (TestServer)provider.GetRequiredService()); - - // By default ASP.NET Core uses entry point assembly to discover controllers from. When running - // inside a test runner the runner exe becomes the entry point which obviously has no controllers in it ;) - // so we are explicitly registering all necessary application parts. - var addControllers = hostBuilder.Services.AddControllers(); - addControllers.AddApplicationPart(typeof(WebApplicationBuilderExtensions).Assembly); + hostBuilder.AddServiceControlMonitoringTesting(settings); host = hostBuilder.Build(); host.UseServiceControlMonitoring(); await host.StartAsync(); - HttpClient = host.Services.GetRequiredKeyedService(instanceName).CreateClient(); + HttpClient = host.Services.GetRequiredKeyedService(settings.EndpointName).CreateClient(); } } public override async Task Stop(CancellationToken cancellationToken = default) { - using (new DiagnosticTimer($"Test TearDown for {instanceName}")) + using (new DiagnosticTimer($"Test TearDown for {settings.EndpointName}")) { await host.StopAsync(cancellationToken); HttpClient.Dispose(); @@ -157,10 +128,6 @@ public override async Task Stop(CancellationToken cancellationToken = default) } } - ITransportIntegration transportToUse; - Action setSettings; - Action customConfiguration; - string instanceName = Settings.DEFAULT_ENDPOINT_NAME; WebApplication host; Settings settings; } diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs new file mode 100644 index 0000000000..925156a0bb --- /dev/null +++ b/src/ServiceControl.Monitoring.AcceptanceTests/TestSupport/WebApplicationBuilderExtensions.cs @@ -0,0 +1,28 @@ +namespace ServiceControl.Monitoring.AcceptanceTests.TestSupport; + +using System; +using Infrastructure; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting.Server; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; + +static class WebApplicationBuilderExtensions +{ + public static void AddServiceControlMonitoringTesting(this WebApplicationBuilder hostBuilder, Settings settings) + { + hostBuilder.Logging.AddScenarioContextLogging(); + + hostBuilder.WebHost.UseTestServer(options => options.BaseAddress = new Uri(settings.RootUrl)); + // This facilitates receiving the test server anywhere where DI is available + hostBuilder.Services.AddKeyedSingleton(settings.EndpointName, + (provider, _) => (TestServer)provider.GetRequiredService()); + + // By default, ASP.NET Core uses the entry point assembly to discover controllers. When running + // inside a test runner the runner exe becomes the entry point which obviously has no controllers in it ;) + // so we are explicitly registering all necessary application parts. + var addControllers = hostBuilder.Services.AddControllers(); + addControllers.AddApplicationPart(typeof(Settings).Assembly); + addControllers.AddApplicationPart(typeof(AcceptanceTest).Assembly); + } +} \ No newline at end of file diff --git a/src/ServiceControl.Monitoring.AcceptanceTests/When_querying_queue_length_data.cs b/src/ServiceControl.Monitoring.AcceptanceTests/When_querying_queue_length_data.cs index c050b129b4..31e560f980 100644 --- a/src/ServiceControl.Monitoring.AcceptanceTests/When_querying_queue_length_data.cs +++ b/src/ServiceControl.Monitoring.AcceptanceTests/When_querying_queue_length_data.cs @@ -24,7 +24,6 @@ public async Task Should_report_via_http() MonitoredEndpointInstance instance1 = null; MonitoredEndpointInstance instance2 = null; - await Define() .WithEndpoint(c => {