Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Acceptance test todos #3994

Merged
merged 4 commits into from Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,33 +1,96 @@
namespace ServiceControl.AcceptanceTesting
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using InfrastructureConfig;
using Microsoft.Extensions.DependencyInjection;
using NServiceBus;
using NServiceBus.AcceptanceTesting.Customization;
using NServiceBus.AcceptanceTesting.Support;
using NServiceBus.Configuration.AdvancedExtensibility;
using NServiceBus.Features;
using NServiceBus.Hosting.Helpers;

public static class EndpointConfigurationExtensions
{
public static void NoImmediateRetries(this EndpointConfiguration configuration)
// This logic has been adapted from Cores ScanTypesForTest to specialize it to the needs of ServiceControl
public static void ScanTypesForTest(this EndpointConfiguration config,
EndpointCustomizationConfiguration customizationConfiguration)
{
configuration.Recoverability().Immediate(x => x.NumberOfRetries(0));
// disable file system scanning for better performance
// note that this might cause issues when required assemblies are only being loaded at endpoint startup time
var assemblyScanner = new AssemblyScanner { ScanFileSystemAssemblies = false };

config.TypesToIncludeInScan(
assemblyScanner.GetScannableAssemblies().Assemblies
.Where(a => !a.FullName!.StartsWith("ServiceControl")) // this prevents handlers, custom checks etc from ServiceControl to be scanned
.Where(a => a != customizationConfiguration.BuilderType.Assembly) // exclude all types from test assembly by default
.SelectMany(a => a.GetTypes())
.Union(GetNestedTypeRecursive(customizationConfiguration.BuilderType.DeclaringType, customizationConfiguration.BuilderType))
.Union(customizationConfiguration.TypesToInclude)
.Except(customizationConfiguration.TypesToExclude)
.ToList());
return;

IEnumerable<Type> GetNestedTypeRecursive(Type rootType, Type builderType)
{
if (rootType == null)
{
throw new InvalidOperationException("Make sure you nest the endpoint infrastructure inside the TestFixture as nested classes");
}

yield return rootType;

if (typeof(IEndpointConfigurationFactory).IsAssignableFrom(rootType) && rootType != builderType)
{
yield break;
}

foreach (var nestedType in rootType.GetNestedTypes(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).SelectMany(t => GetNestedTypeRecursive(t, builderType)))
{
yield return nestedType;
}
}
}

public static void NoDelayedRetries(this EndpointConfiguration configuration)
public static async Task DefinePersistence(this EndpointConfiguration config, RunDescriptor runDescriptor, EndpointCustomizationConfiguration endpointCustomizationConfiguration)
mauroservienti marked this conversation as resolved.
Show resolved Hide resolved
{
configuration.Recoverability().Delayed(x => x.NumberOfRetries(0));
var persistenceConfiguration = new ConfigureEndpointInMemoryPersistence();
await persistenceConfiguration.Configure(endpointCustomizationConfiguration.EndpointName, config, runDescriptor.Settings, endpointCustomizationConfiguration.PublisherMetadata);
runDescriptor.OnTestCompleted(_ => persistenceConfiguration.Cleanup());
}

public static void RegisterComponentsAndInheritanceHierarchy(this EndpointConfiguration builder, RunDescriptor runDescriptor) => builder.RegisterComponents(services => { RegisterInheritanceHierarchyOfContextOnContainer(runDescriptor, services); });

static void RegisterInheritanceHierarchyOfContextOnContainer(RunDescriptor runDescriptor,
IServiceCollection services)
{
var type = runDescriptor.ScenarioContext.GetType();
while (type != typeof(object))
{
services.AddSingleton(type, runDescriptor.ScenarioContext);
type = type.BaseType;
}
}

public static void NoImmediateRetries(this EndpointConfiguration configuration)
=> configuration.Recoverability().Immediate(x => x.NumberOfRetries(0));

public static void NoDelayedRetries(this EndpointConfiguration configuration)
=> configuration.Recoverability().Delayed(x => x.NumberOfRetries(0));

public static void NoRetries(this EndpointConfiguration configuration)
{
configuration.NoDelayedRetries();
configuration.NoImmediateRetries();
}

public static void NoOutbox(this EndpointConfiguration configuration)
{
configuration.DisableFeature<Outbox>();
}
public static void NoOutbox(this EndpointConfiguration configuration) => configuration.DisableFeature<Outbox>();

public static RoutingSettings ConfigureRouting(this EndpointConfiguration configuration) =>
new RoutingSettings(configuration.GetSettings());
new(configuration.GetSettings());
}
}

This file was deleted.

@@ -1,28 +1,23 @@
namespace ServiceControl.AcceptanceTesting.EndpointTemplates
{
using System;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Threading.Tasks;
using AcceptanceTesting;
using NServiceBus;
using NServiceBus.AcceptanceTesting;
using NServiceBus.AcceptanceTesting.Customization;
using NServiceBus.AcceptanceTesting.Support;
using NServiceBus.Configuration.AdvancedExtensibility;
using NServiceBus.Features;
using ServiceControl.AcceptanceTesting.InfrastructureConfig;

public class DefaultServerBase<TBootstrapper> : IEndpointSetupTemplate
public abstract class DefaultServerBase(IConfigureEndpointTestExecution endpointTestExecutionConfiguration)
: IEndpointSetupTemplate
{
public DefaultServerBase() : this(new ConfigureEndpointLearningTransport())
protected DefaultServerBase() : this(new ConfigureEndpointLearningTransport())
{
}

public DefaultServerBase(IConfigureEndpointTestExecution endpointTestExecutionConfiguration) => this.endpointTestExecutionConfiguration = endpointTestExecutionConfiguration;

public async Task<EndpointConfiguration> GetConfiguration(RunDescriptor runDescriptor, EndpointCustomizationConfiguration endpointCustomizations, Func<EndpointConfiguration, Task> configurationBuilderCustomization)
public virtual async Task<EndpointConfiguration> GetConfiguration(RunDescriptor runDescriptor, EndpointCustomizationConfiguration endpointCustomizations, Func<EndpointConfiguration, Task> configurationBuilderCustomization)
{
ServicePointManager.DefaultConnectionLimit = 100;

Expand All @@ -41,8 +36,6 @@ public async Task<EndpointConfiguration> GetConfiguration(RunDescriptor runDescr
endpointConfiguration.RegisterComponentsAndInheritanceHierarchy(runDescriptor);
await endpointConfiguration.DefinePersistence(runDescriptor, endpointCustomizations);

typeof(ScenarioContext).GetProperty("CurrentEndpoint", BindingFlags.Static | BindingFlags.NonPublic).SetValue(runDescriptor.ScenarioContext, endpointCustomizations.EndpointName);

endpointConfiguration.UseSerialization<NewtonsoftJsonSerializer>();

endpointConfiguration.Pipeline.Register<TraceIncomingBehavior.Registration>();
Expand All @@ -57,20 +50,13 @@ public async Task<EndpointConfiguration> GetConfiguration(RunDescriptor runDescr
await configurationBuilderCustomization(endpointConfiguration);

// scan types at the end so that all types used by the configuration have been loaded into the AppDomain
endpointConfiguration.TypesToIncludeInScan(endpointCustomizations.GetTypesScopedByTestClass<TBootstrapper>().Concat(new[]
{
typeof(TraceIncomingBehavior), typeof(TraceOutgoingBehavior)
}).ToList());
endpointConfiguration.ScanTypesForTest(endpointCustomizations);

return endpointConfiguration;
}

static bool IsExternalContract(Type t)
{
return t.Namespace != null && t.Namespace.StartsWith("ServiceControl.Contracts")
&& t.Assembly.GetName().Name == "ServiceControl.Contracts";
}

IConfigureEndpointTestExecution endpointTestExecutionConfiguration;
static bool IsExternalContract(Type t) =>
t.Namespace != null && t.Namespace.StartsWith("ServiceControl.Contracts")
&& t.Assembly.GetName().Name == "ServiceControl.Contracts";
}
}
@@ -0,0 +1,18 @@
namespace ServiceControl.AcceptanceTesting.EndpointTemplates
{
using System;
using System.Threading.Tasks;
using NServiceBus;
using NServiceBus.AcceptanceTesting.Support;

public class DefaultServerWithAudit : DefaultServerBase
{
public override Task<EndpointConfiguration> GetConfiguration(RunDescriptor runDescriptor, EndpointCustomizationConfiguration endpointConfiguration, Func<EndpointConfiguration, Task> configurationBuilderCustomization) =>
base.GetConfiguration(runDescriptor, endpointConfiguration, async builder =>
{
builder.AuditProcessedMessagesTo("audit");

await configurationBuilderCustomization(builder);
});
}
}
@@ -0,0 +1,19 @@
namespace ServiceControl.AcceptanceTesting.EndpointTemplates
{
using System;
using System.Threading.Tasks;
using NServiceBus;
using NServiceBus.AcceptanceTesting.Support;
using NServiceBus.Features;

public class DefaultServerWithoutAudit : DefaultServerBase
{
public override Task<EndpointConfiguration> GetConfiguration(RunDescriptor runDescriptor, EndpointCustomizationConfiguration endpointConfiguration, Func<EndpointConfiguration, Task> configurationBuilderCustomization) =>
base.GetConfiguration(runDescriptor, endpointConfiguration, async b =>
{
b.DisableFeature<Audit>();

await configurationBuilderCustomization(b);
});
}
}

This file was deleted.