static string GetEndpointNameForRun(RunDescriptor runDescriptor, EndpointBehaviour endpointBehaviour) { var endpointName = Conventions.EndpointNamingConvention(endpointBehaviour.EndpointBuilderType) + "." + runDescriptor.Key; return(endpointName); }
static async Task PerformScenarios(RunDescriptor runDescriptor, IEnumerable <ActiveRunner> runners, Func <bool> done) { var cts = new CancellationTokenSource(); var endpoints = runners.Select(r => r.Instance).ToList(); // ReSharper disable once LoopVariableIsNeverChangedInsideLoop try { await StartEndpoints(endpoints, cts).ConfigureAwait(false); runDescriptor.ScenarioContext.EndpointsStarted = true; await ExecuteWhens(endpoints, cts).ConfigureAwait(false); var startTime = DateTime.UtcNow; var maxTime = runDescriptor.Settings.TestExecutionTimeout ?? TimeSpan.FromSeconds(90); while (!done() && !cts.Token.IsCancellationRequested) { if (DateTime.UtcNow - startTime > maxTime) { ThrowOnFailedMessages(runDescriptor, endpoints); throw new ScenarioException(GenerateTestTimedOutMessage(maxTime)); } await Task.Delay(1).ConfigureAwait(false); } } finally { await StopEndpoints(endpoints, runDescriptor.ScenarioContext).ConfigureAwait(false); } ThrowOnFailedMessages(runDescriptor, endpoints); }
static void PerformScenarios(RunDescriptor runDescriptor, IEnumerable <ActiveRunner> runners, Func <bool> done) { var endpoints = runners.Select(r => r.Instance).ToList(); StartEndpoints(endpoints); runDescriptor.ScenarioContext.EndpointsStarted = true; var startTime = DateTime.UtcNow; var maxTime = runDescriptor.TestExecutionTimeout; Task.WaitAll(endpoints.Select(endpoint => Task.Factory.StartNew(() => SpinWait.SpinUntil(done, maxTime))).Cast <Task>().ToArray(), maxTime); try { if ((DateTime.UtcNow - startTime) > maxTime) { throw new ScenarioException(GenerateTestTimedOutMessage(endpoints, maxTime)); } } finally { StopEndpoints(endpoints); } }
static List <ActiveRunner> InitializeRunners(RunDescriptor runDescriptor, IList <EndpointBehaviour> behaviorDescriptors) { var runners = new List <ActiveRunner>(); var routingTable = CreateRoutingTable(runDescriptor, behaviorDescriptors); foreach (var behaviorDescriptor in behaviorDescriptors) { var endpointName = GetEndpointNameForRun(runDescriptor, behaviorDescriptor); var runner = PrepareRunner(endpointName, behaviorDescriptor); var result = runner.Instance.Initialize(runDescriptor, behaviorDescriptor, routingTable, endpointName); // Extend the lease to the timeout value specified. ILease serverLease = (ILease)RemotingServices.GetLifetimeService(runner.Instance); // Add the execution time + additional time for the endpoints to be able to stop gracefully var totalLifeTime = runDescriptor.TestExecutionTimeout.Add(TimeSpan.FromMinutes(2)); serverLease.Renew(totalLifeTime); if (result.Failed) { throw new ScenarioException(string.Format("Endpoint {0} failed to initialize - {1}", runner.Instance.Name(), result.ExceptionMessage)); } runners.Add(runner); } return(runners); }
public RunDescriptorsBuilder For(params RunDescriptor[] descriptorsToAdd) { var toAdd = descriptorsToAdd.Where(r => r != null).ToList(); if (!toAdd.Any()) { emptyPermutationFound = true; } if (!descriptors.Any()) { descriptors = toAdd; return(this); } var result = new List <RunDescriptor>(); foreach (var existingDescriptor in descriptors) { foreach (var descriptorToAdd in toAdd) { var nd = new RunDescriptor(existingDescriptor); nd.Merge(descriptorToAdd); result.Add(nd); } } descriptors = result; return(this); }
static void PerformScenarios(RunDescriptor runDescriptor, IEnumerable <ActiveRunner> runners, Func <bool> done) { var endpoints = runners.Select(r => r.Instance).ToList(); try { StartEndpoints(endpoints); runDescriptor.ScenarioContext.EndpointsStarted = true; var maxTime = runDescriptor.TestExecutionTimeout; ExecuteWhens(maxTime, endpoints); var timedOut = false; Task.Run(() => timedOut = !SpinWait.SpinUntil(done, maxTime)).Wait(); if (timedOut) { throw new ScenarioException(GenerateTestTimedOutMessage(maxTime)); } } finally { StopEndpoints(endpoints); } }
public static async Task Run(RunDescriptor runDescriptor, List <EndpointBehavior> behaviorDescriptors, Func <ScenarioContext, bool> done) { Console.WriteLine("Started test @ {0}", DateTime.Now.ToString(CultureInfo.InvariantCulture)); ContextAppenderFactory.SetContext(runDescriptor.ScenarioContext); var runResult = await PerformTestRun(behaviorDescriptors, runDescriptor, done).ConfigureAwait(false); ContextAppenderFactory.SetContext(null); Console.WriteLine("Finished test @ {0}", DateTime.Now.ToString(CultureInfo.InvariantCulture)); var runSummary = new RunSummary { Result = runResult, RunDescriptor = runDescriptor, Endpoints = behaviorDescriptors }; DisplayRunResult(runSummary); if (runSummary.Result.Failed) { throw runSummary.Result.Exception; } }
public Configure GetConfiguration(RunDescriptor runDescriptor, EndpointConfiguration endpointConfiguration, IConfigurationSource configSource) { var settings = runDescriptor.Settings; var types = GetTypesScopedByTestClass(endpointConfiguration); var transportToUse = AcceptanceTest.GetTransportIntegrationFromEnvironmentVar(); SetupLogging(endpointConfiguration); Configure.Features.Enable<Sagas>(); Configure.ScaleOut(_ => _.UseSingleBrokerQueue()); AddMoreConfig(); var config = Configure.With(types) .DefiningEventsAs(t => typeof(IEvent).IsAssignableFrom(t) || IsExternalContract(t)) .DefineEndpointName(endpointConfiguration.EndpointName) .CustomConfigurationSource(configSource) .DefineBuilder(settings.GetOrNull("Builder")); SetSerializer(config); config .DefineTransport(transportToUse) .InMemorySagaPersister() .UseInMemoryTimeoutPersister(); if (transportToUse == null || transportToUse is MsmqTransportIntegration || transportToUse is SqlServerTransportIntegration || transportToUse is AzureStorageQueuesTransportIntegration) { config.InMemorySubscriptionStorage(); } return config.UnicastBus(); }
public Configure GetConfiguration(RunDescriptor runDescriptor, EndpointConfiguration endpointConfiguration, IConfigurationSource configSource) { Configure.ScaleOut(_ => _.UseSingleBrokerQueue()); new Bootstrapper(); //We need this hack here because by default we include all assemblies minus Plugins but for these tests we need to exclude other tests! for (var index = 0; index < Configure.TypesToScan.Count;) { var type = Configure.TypesToScan[index]; if (type.Assembly != Assembly.GetExecutingAssembly()) { index++; continue; } if (!(type.DeclaringType == endpointConfiguration.BuilderType.DeclaringType || type.DeclaringType == endpointConfiguration.BuilderType)) { Configure.TypesToScan.RemoveAt(index); } else { index++; } } LogManager.Configuration = SetupLogging(endpointConfiguration); return Configure.Instance; }
static async Task PerformScenarios(RunDescriptor runDescriptor, IEnumerable <ActiveRunner> runners, Func <Task <bool> > done) { var endpoints = runners.Select(r => r.Instance).ToList(); try { await StartEndpoints(endpoints).ConfigureAwait(false); runDescriptor.ScenarioContext.EndpointsStarted = true; var maxTime = runDescriptor.TestExecutionTimeout; await ExecuteWhens(maxTime, endpoints).ConfigureAwait(false); var startTime = DateTime.UtcNow; while (!await done().ConfigureAwait(false)) { if (!Debugger.IsAttached) { if (DateTime.UtcNow - startTime > maxTime) { throw new ScenarioException(GenerateTestTimedOutMessage(maxTime)); } } await Task.Delay(500).ConfigureAwait(false); // slow down to prevent hammering of SC APIs await Task.Yield(); // yield to give some freedom } } finally { await StopEndpoints(endpoints).ConfigureAwait(false); } }
static List <ActiveRunner> InitializeRunners(RunDescriptor runDescriptor, IList <EndpointBehavior> behaviorDescriptors) { var runners = new List <ActiveRunner>(); var routingTable = CreateRoutingTable(behaviorDescriptors); foreach (var behaviorDescriptor in behaviorDescriptors) { var endpointName = GetEndpointNameForRun(behaviorDescriptor); if (endpointName.Length > 77) { throw new Exception($"Endpoint name '{endpointName}' is larger than 77 characters and will cause issues with MSMQ queue names. Please rename your test class or endpoint!"); } var runner = PrepareRunner(endpointName); var result = runner.Instance.Initialize(runDescriptor, behaviorDescriptor, routingTable, endpointName); if (result.Failed) { throw new ScenarioException($"Endpoint {runner.Instance.Name()} failed to initialize", result.Exception); } runners.Add(runner); } return(runners); }
public Result Initialize(RunDescriptor run, EndpointBehavior endpointBehavior, IDictionary <Type, string> routingTable, string endpointName) { try { behavior = endpointBehavior; scenarioContext = run.ScenarioContext; configuration = ((IEndpointConfigurationFactory)Activator.CreateInstance(endpointBehavior.EndpointBuilderType)) .Get(); configuration.EndpointName = endpointName; //apply custom config settings busConfiguration = configuration.GetConfiguration(run, routingTable); endpointBehavior.CustomConfig.ForEach(customAction => customAction(busConfiguration)); bus = configuration.GetBus() ?? Bus.Create(busConfiguration); var transportDefinition = ((UnicastBus)bus).Settings.Get <TransportDefinition>(); scenarioContext.HasNativePubSubSupport = transportDefinition.HasNativePubSubSupport; return(Result.Success()); } catch (Exception ex) { Logger.Error($"Failed to initialize endpoint {endpointName}", ex); return(Result.Failure(ex)); } }
public BusConfiguration GetConfiguration(RunDescriptor runDescriptor, EndpointConfiguration endpointConfiguration, IConfigurationSource configSource, Action<BusConfiguration> configurationBuilderCustomization) { var settings = runDescriptor.Settings; var types = GetTypesToUse(endpointConfiguration); var config = new BusConfiguration(); config.EndpointName(endpointConfiguration.EndpointName); config.TypesToScan(types); config.CustomConfigurationSource(configSource); config.UsePersistence<InMemoryPersistence>(); config.PurgeOnStartup(true); // Plugin a behavior that listens for subscription messages config.Pipeline.Register<SubscriptionBehavior.Registration>(); config.RegisterComponents(c => c.ConfigureComponent<SubscriptionBehavior>(DependencyLifecycle.InstancePerCall)); // Important: you need to make sure that the correct ScenarioContext class is available to your endpoints and tests config.RegisterComponents(r => { r.RegisterSingleton(runDescriptor.ScenarioContext.GetType(), runDescriptor.ScenarioContext); r.RegisterSingleton(typeof(ScenarioContext), runDescriptor.ScenarioContext); }); // Call extra custom action if provided if (configurationBuilderCustomization != null) { configurationBuilderCustomization(config); } return config; }
public Configure GetConfiguration(RunDescriptor runDescriptor, EndpointConfiguration endpointConfiguration, IConfigurationSource configSource) { var settings = runDescriptor.Settings; var types = GetTypesToUse(endpointConfiguration); var transportToUse = settings.GetOrNull("Transport"); SetupLogging(endpointConfiguration); Configure.Features.Enable<Sagas>(); var config = Configure.With(types) .DefineEndpointName(endpointConfiguration.EndpointName) .DefineBuilder(settings.GetOrNull("Builder")) .CustomConfigurationSource(configSource) .DefineSerializer(settings.GetOrNull("Serializer")) .DefineTransport(transportToUse) .InMemorySagaPersister(); if (transportToUse == null || transportToUse.Contains("Msmq") || transportToUse.Contains("SqlServer") || transportToUse.Contains("RabbitMq")) config.UseInMemoryTimeoutPersister(); if (transportToUse == null || transportToUse.Contains("Msmq") || transportToUse.Contains("SqlServer")) config.InMemorySubscriptionStorage(); config.InMemorySagaPersister(); return config.UnicastBus(); }
public Configure GetConfiguration(RunDescriptor runDescriptor, EndpointConfiguration endpointConfiguration, IConfigurationSource configSource) { Configure.Serialization.Xml(); return Configure.With(AllAssemblies.Except(Assembly.GetExecutingAssembly().FullName)) .DefaultBuilder() .UseTransport<Msmq>() .UnicastBus(); }
public Result Initialize(RunDescriptor run, EndpointBehaviour endpointBehaviour, IDictionary<Type, string> routingTable, string endpointName) { try { behaviour = endpointBehaviour; scenarioContext = run.ScenarioContext; configuration = ((IEndpointConfigurationFactory)Activator.CreateInstance(endpointBehaviour.EndpointBuilderType)).Get(); configuration.EndpointName = endpointName; if (!string.IsNullOrEmpty(configuration.CustomMachineName)) { NServiceBus.Support.RuntimeEnvironment.MachineNameAction = () => configuration.CustomMachineName; } //apply custom config settings endpointBehaviour.CustomConfig.ForEach(customAction => customAction(config)); config = configuration.GetConfiguration(run, routingTable); if (scenarioContext != null) { config.Configurer.RegisterSingleton(scenarioContext.GetType(), scenarioContext); scenarioContext.ContextPropertyChanged += scenarioContext_ContextPropertyChanged; } bus = config.CreateBus(); Configure.Instance.ForInstallationOn<Windows>().Install(); Task.Factory.StartNew(() => { while (!stopped) { contextChanged.WaitOne(TimeSpan.FromSeconds(5)); //we spin around each 5 s since the callback mechanism seems to be shaky lock (behaviour) { foreach (var when in behaviour.Whens) { if (executedWhens.Contains(when.Id)) continue; if(when.ExecuteAction(scenarioContext, bus)) executedWhens.Add(when.Id); } } } }); return Result.Success(); } catch (Exception ex) { Logger.Error("Failed to initalize endpoint " + endpointName, ex); return Result.Failure(ex); } }
public void Merge(RunDescriptor descriptorToAdd) { Key += "." + descriptorToAdd.Key; foreach (var setting in descriptorToAdd.Settings) { Settings[setting.Key] = setting.Value; } }
static IDictionary <Type, string> CreateRoutingTable(RunDescriptor runDescriptor, IEnumerable <EndpointBehaviour> behaviorDescriptors) { var routingTable = new Dictionary <Type, string>(); foreach (var behaviorDescriptor in behaviorDescriptors) { routingTable[behaviorDescriptor.EndpointBuilderType] = GetEndpointNameForRun(runDescriptor, behaviorDescriptor); } return(routingTable); }
static void ThrowOnFailedMessages(RunDescriptor runDescriptor, List <EndpointRunner> endpoints) { var unexpectedFailedMessages = runDescriptor.ScenarioContext.FailedMessages .Where(kvp => endpoints.Single(e => e.Name() == kvp.Key).FailOnErrorMessage) .SelectMany(kvp => kvp.Value) .ToList(); if (unexpectedFailedMessages.Any()) { throw new MessagesFailedException(unexpectedFailedMessages, runDescriptor.ScenarioContext); } }
static async Task PerformScenarios(RunDescriptor runDescriptor, EndpointRunner[] runners, Func <bool> done) { using (var cts = new CancellationTokenSource()) { // ReSharper disable once LoopVariableIsNeverChangedInsideLoop try { await StartEndpoints(runners, cts).ConfigureAwait(false); runDescriptor.ScenarioContext.EndpointsStarted = true; await ExecuteWhens(runners, cts).ConfigureAwait(false); var startTime = DateTime.UtcNow; var maxTime = runDescriptor.Settings.TestExecutionTimeout ?? TimeSpan.FromSeconds(90); while (!done() && !cts.Token.IsCancellationRequested) { if (!Debugger.IsAttached) { if (DateTime.UtcNow - startTime > maxTime) { ThrowOnFailedMessages(runDescriptor, runners); throw new TimeoutException(GenerateTestTimedOutMessage(maxTime)); } } await Task.Yield(); } startTime = DateTime.UtcNow; var unfinishedFailedMessagesMaxWaitTime = TimeSpan.FromSeconds(30); while (runDescriptor.ScenarioContext.UnfinishedFailedMessages.Values.Any(x => x)) { if (DateTime.UtcNow - startTime > unfinishedFailedMessagesMaxWaitTime) { throw new Exception("Some failed messages were not handled by the recoverability feature."); } await Task.Yield(); } } finally { await StopEndpoints(runners).ConfigureAwait(false); } ThrowOnFailedMessages(runDescriptor, runners); } }
public async Task Initialize(RunDescriptor run, EndpointBehavior endpointBehavior, IDictionary <Type, string> routingTable, string endpointName) { try { behavior = endpointBehavior; scenarioContext = run.ScenarioContext; runSettings = run.Settings; var endpointConfigurationFactory = (IEndpointConfigurationFactory)Activator.CreateInstance(endpointBehavior.EndpointBuilderType); endpointConfigurationFactory.ScenarioContext = run.ScenarioContext; configuration = endpointConfigurationFactory.Get(); configuration.EndpointName = endpointName; if (!string.IsNullOrEmpty(configuration.CustomMachineName)) { RuntimeEnvironment.MachineNameAction = () => configuration.CustomMachineName; } //apply custom config settings if (configuration.GetConfiguration == null) { throw new Exception($"Missing EndpointSetup<T> in the constructor of {endpointName} endpoint."); } endpointConfiguration = await configuration.GetConfiguration(run, routingTable).ConfigureAwait(false); RegisterInheritanceHierarchyOfContextInSettings(scenarioContext); endpointBehavior.CustomConfig.ForEach(customAction => customAction(endpointConfiguration, scenarioContext)); if (configuration.SendOnly) { endpointConfiguration.SendOnly(); } startable = await Endpoint.Create(endpointConfiguration).ConfigureAwait(false); if (!configuration.SendOnly) { var transportInfrastructure = endpointConfiguration.GetSettings().Get <TransportInfrastructure>(); scenarioContext.HasNativePubSubSupport = transportInfrastructure.OutboundRoutingPolicy.Publishes == OutboundRoutingType.Multicast; } } catch (Exception ex) { Logger.Error("Failed to initialize endpoint " + endpointName, ex); throw; } }
static async Task <ComponentRunner[]> InitializeRunners(RunDescriptor runDescriptor, List <IComponentBehavior> endpointBehaviors) { var runnerInitializations = endpointBehaviors.Select(endpointBehavior => endpointBehavior.CreateRunner(runDescriptor)).ToArray(); try { var x = await Task.WhenAll(runnerInitializations).ConfigureAwait(false); return(x); } catch (Exception e) { TestContext.WriteLine(e); throw; } }
public static async Task <RunSummary> Run(RunDescriptor runDescriptor, List <IComponentBehavior> behaviorDescriptors, Func <ScenarioContext, Task <bool> > done) { TestContext.WriteLine("current context: " + runDescriptor.ScenarioContext.GetType().FullName); TestContext.WriteLine("Started test @ {0}", DateTime.Now.ToString(CultureInfo.InvariantCulture)); var runResult = await PerformTestRun(behaviorDescriptors, runDescriptor, done).ConfigureAwait(false); TestContext.WriteLine("Finished test @ {0}", DateTime.Now.ToString(CultureInfo.InvariantCulture)); return(new RunSummary { Result = runResult, RunDescriptor = runDescriptor, Endpoints = behaviorDescriptors }); }
public async Task Initialize(RunDescriptor run, EndpointBehavior endpointBehavior, IDictionary<Type, string> routingTable, string endpointName) { try { behavior = endpointBehavior; scenarioContext = run.ScenarioContext; runSettings = run.Settings; var endpointConfigurationFactory = (IEndpointConfigurationFactory)Activator.CreateInstance(endpointBehavior.EndpointBuilderType); endpointConfigurationFactory.ScenarioContext = run.ScenarioContext; configuration = endpointConfigurationFactory.Get(); configuration.EndpointName = endpointName; if (!string.IsNullOrEmpty(configuration.CustomMachineName)) { RuntimeEnvironment.MachineNameAction = () => configuration.CustomMachineName; } //apply custom config settings if (configuration.GetConfiguration == null) { throw new Exception($"Missing EndpointSetup<T> in the constructor of {endpointName} endpoint."); } endpointConfiguration = await configuration.GetConfiguration(run, routingTable).ConfigureAwait(false); RegisterInheritanceHierarchyOfContextInSettings(scenarioContext); endpointBehavior.CustomConfig.ForEach(customAction => customAction(endpointConfiguration, scenarioContext)); if (configuration.SendOnly) { endpointConfiguration.SendOnly(); } startable = await Endpoint.Create(endpointConfiguration).ConfigureAwait(false); if (!configuration.SendOnly) { var transportInfrastructure = endpointConfiguration.GetSettings().Get<TransportInfrastructure>(); scenarioContext.HasNativePubSubSupport = transportInfrastructure.OutboundRoutingPolicy.Publishes == OutboundRoutingType.Multicast; } } catch (Exception ex) { Logger.Error("Failed to initialize endpoint " + endpointName, ex); throw; } }
public async Task <ComponentRunner> CreateRunner(RunDescriptor run) { var endpointName = Conventions.EndpointNamingConvention(EndpointBuilder.GetType()); var runner = new EndpointRunner(createInstanceCallback, startInstanceCallback, DoNotFailOnErrorMessages); try { await runner.Initialize(run, this, endpointName).ConfigureAwait(false); } catch (Exception) { TestContext.WriteLine($"Endpoint {runner.Name} failed to initialize"); throw; } return(runner); }
static void ThrowOnFailedMessages(RunDescriptor runDescriptor, EndpointRunner[] endpoints) { var unexpectedFailedMessages = runDescriptor.ScenarioContext.FailedMessages .Where(kvp => endpoints.Single(e => e.Name() == kvp.Key).FailOnErrorMessage) .SelectMany(kvp => kvp.Value) .ToList(); if (unexpectedFailedMessages.Any()) { foreach (var failedMessage in unexpectedFailedMessages) { Console.WriteLine($"Message: {failedMessage.MessageId} failed to process and was moved to the error queue: {failedMessage.Exception}"); } throw new MessagesFailedException(unexpectedFailedMessages, runDescriptor.ScenarioContext); } }
public static async Task <RunSummary> Run(RunDescriptor runDescriptor, List <IComponentBehavior> behaviorDescriptors, Func <ScenarioContext, bool> done) { Console.WriteLine("Started test @ {0}", DateTime.Now.ToString(CultureInfo.InvariantCulture)); ContextAppenderFactory.SetContext(runDescriptor.ScenarioContext); var runResult = await PerformTestRun(behaviorDescriptors, runDescriptor, done).ConfigureAwait(false); ContextAppenderFactory.SetContext(null); Console.WriteLine("Finished test @ {0}", DateTime.Now.ToString(CultureInfo.InvariantCulture)); return(new RunSummary { Result = runResult, RunDescriptor = runDescriptor, Endpoints = behaviorDescriptors }); }
public Configure GetConfiguration(RunDescriptor runDescriptor, EndpointConfiguration endpointConfiguration, IConfigurationSource configSource) { Configure.ScaleOut(_ => _.UseSingleBrokerQueue()); var configure = Configure.With(GetTypesScopedByTestClass(endpointConfiguration)); var transportToUse = AcceptanceTest.GetTransportIntegrationFromEnvironmentVar(); Action action = transportToUse.OnEndpointShutdown; SettingsHolder.Set("CleanupTransport", action); new Bootstrapper(configure: configure); LogManager.Configuration = SetupLogging(endpointConfiguration); return Configure.Instance; }
static async Task <ActiveRunner[]> InitializeRunners(RunDescriptor runDescriptor, List <EndpointBehavior> endpointBehaviors) { var routingTable = CreateRoutingTable(endpointBehaviors); var runnerInitializations = endpointBehaviors.Select(async endpointBehavior => { var endpointName = GetEndpointNameForRun(endpointBehavior); if (endpointName.Length > 77) { throw new Exception($"Endpoint name '{endpointName}' is larger than 77 characters and will cause issues with MSMQ queue names. Rename the test class or endpoint."); } var runner = new ActiveRunner { Instance = new EndpointRunner(), EndpointName = endpointName }; try { await runner.Instance.Initialize(runDescriptor, endpointBehavior, routingTable, endpointName).ConfigureAwait(false); } catch (Exception) { Console.WriteLine($"Endpoint {runner.Instance.Name()} failed to initialize"); throw; } return(runner); }); try { var x = await Task.WhenAll(runnerInitializations).ConfigureAwait(false); return(x); } catch (Exception e) { Console.WriteLine(e); throw; } }
public async Task <ComponentRunner> CreateRunner(RunDescriptor run) { var endpointName = Conventions.EndpointNamingConvention(EndpointBuilderType); if (endpointName.Length > 77) { throw new Exception($"Endpoint name '{endpointName}' is larger than 77 characters and will cause issues with MSMQ queue names. Rename the test class or endpoint."); } var runner = new EndpointRunner(DoNotFailOnErrorMessages); try { await runner.Initialize(run, this, endpointName).ConfigureAwait(false); } catch (Exception) { TestContext.WriteLine($"Endpoint {runner.Name} failed to initialize"); throw; } return(runner); }
public Configure GetConfiguration(RunDescriptor runDescriptor, EndpointConfiguration endpointConfiguration, IConfigurationSource configSource) { var settings = runDescriptor.Settings; var types = GetTypesToUse(endpointConfiguration); var transportToUse = AcceptanceTest.GetTransportIntegrationFromEnvironmentVar(); SetupLogging(endpointConfiguration); Configure.Features.Enable<Sagas>(); Configure.ScaleOut(_ => _.UseSingleBrokerQueue()); AddMoreConfig(); var config = Configure.With(types) .DefineEndpointName(endpointConfiguration.EndpointName) .CustomConfigurationSource(configSource) .DefineBuilder(settings.GetOrNull("Builder")) .DefineSerializer(settings.GetOrNull("Serializer")) .DefineTransport(transportToUse) .InMemorySagaPersister(); if (transportToUse == null || transportToUse is MsmqTransportIntegration || transportToUse is SqlServerTransportIntegration || transportToUse is RabbitMqTransportIntegration) { config.UseInMemoryTimeoutPersister(); } if (transportToUse == null || transportToUse is MsmqTransportIntegration || transportToUse is SqlServerTransportIntegration) { config.InMemorySubscriptionStorage(); } config.InMemorySagaPersister(); return config.UnicastBus(); }
public async Task Initialize(RunDescriptor run, EndpointBehavior endpointBehavior, string endpointName) { ScenarioContext.CurrentEndpoint = endpointName; try { behavior = endpointBehavior; scenarioContext = run.ScenarioContext; endpointBehavior.EndpointBuilder.ScenarioContext = run.ScenarioContext; configuration = endpointBehavior.EndpointBuilder.Get(); configuration.EndpointName = endpointName; if (!string.IsNullOrEmpty(configuration.CustomMachineName)) { RuntimeEnvironment.MachineNameAction = () => configuration.CustomMachineName; } //apply custom config settings if (configuration.GetConfiguration == null) { throw new Exception($"Missing EndpointSetup<T> in the constructor of {endpointName} endpoint."); } var endpointConfiguration = await configuration.GetConfiguration(run).ConfigureAwait(false); RegisterInheritanceHierarchyOfContextInSettings(scenarioContext, endpointConfiguration); TrackFailingMessages(endpointName, endpointConfiguration); endpointBehavior.CustomConfig.ForEach(customAction => customAction(endpointConfiguration, scenarioContext)); startable = await createCallback(endpointConfiguration).ConfigureAwait(false); var transportDefinition = endpointConfiguration.GetSettings().Get <TransportDefinition>(); scenarioContext.HasNativePubSubSupport = transportDefinition.SupportsPublishSubscribe; } catch (Exception ex) { Logger.Error("Failed to initialize endpoint " + endpointName, ex); throw; } }
public static async Task Run(RunDescriptor runDescriptor, IList <EndpointBehavior> behaviorDescriptors, Func <ScenarioContext, Task <bool> > done) { Console.Out.WriteLine($"{runDescriptor.Key} - Started @ {DateTime.Now}"); var runResult = await PerformTestRun(behaviorDescriptors, runDescriptor, done) .ConfigureAwait(false); Console.Out.WriteLine($"{runDescriptor.Key} - Finished @ {DateTime.Now}"); var result = new RunSummary { Result = runResult, RunDescriptor = runDescriptor, Endpoints = behaviorDescriptors }; DisplayRunResult(result); if (result.Result.Failed) { throw new Exception("Test run failed due to one or more exception", result.Result.Exception); } }
static List <ActiveRunner> InitializeRunners(RunDescriptor runDescriptor, IList <EndpointBehavior> behaviorDescriptors) { var runners = new List <ActiveRunner>(); var routingTable = CreateRoutingTable(behaviorDescriptors); foreach (var behaviorDescriptor in behaviorDescriptors) { var endpointName = GetEndpointNameForRun(behaviorDescriptor); if (endpointName.Length > 77) { throw new Exception(string.Format("Endpoint name '{0}' is larger than 77 characters and will cause issues with MSMQ queue names. Please rename your test class or endpoint!", endpointName)); } var runner = PrepareRunner(endpointName, behaviorDescriptor.AppConfig, runDescriptor.UseSeparateAppdomains); var result = runner.Instance.Initialize(runDescriptor, behaviorDescriptor, routingTable, endpointName); if (runDescriptor.UseSeparateAppdomains) { // Extend the lease to the timeout value specified. var serverLease = (ILease)RemotingServices.GetLifetimeService(runner.Instance); // Add the execution time + additional time for the endpoints to be able to stop gracefully var totalLifeTime = runDescriptor.TestExecutionTimeout.Add(TimeSpan.FromMinutes(2)); serverLease.Renew(totalLifeTime); } if (result.Failed) { throw new ScenarioException(string.Format("Endpoint {0} failed to initialize", runner.Instance.Name()), result.Exception); } runners.Add(runner); } return(runners); }
static async Task<RunResult> PerformTestRun(List<EndpointBehavior> behaviorDescriptors, List<IScenarioVerification> shoulds, RunDescriptor runDescriptor, Func<ScenarioContext, bool> done) { var runResult = new RunResult { ScenarioContext = runDescriptor.ScenarioContext }; var runTimer = new Stopwatch(); runTimer.Start(); try { var endpoints = await InitializeRunners(runDescriptor, behaviorDescriptors).ConfigureAwait(false); runResult.ActiveEndpoints = endpoints.Select(r => r.EndpointName).ToList(); await PerformScenarios(runDescriptor, endpoints, () => done(runDescriptor.ScenarioContext)).ConfigureAwait(false); runTimer.Stop(); foreach (var v in shoulds.Where(s => s.ContextType == runDescriptor.ScenarioContext.GetType())) { v.Verify(runDescriptor.ScenarioContext); } } catch (Exception ex) { runResult.Failed = true; runResult.Exception = ex; } runResult.TotalTime = runTimer.Elapsed; return runResult; }
static async Task PerformScenarios(RunDescriptor runDescriptor, IEnumerable<ActiveRunner> runners, Func<bool> done) { using (var cts = new CancellationTokenSource()) { var endpoints = runners.Select(r => r.Instance).ToList(); // ReSharper disable once LoopVariableIsNeverChangedInsideLoop try { await StartEndpoints(endpoints, cts).ConfigureAwait(false); runDescriptor.ScenarioContext.EndpointsStarted = true; await ExecuteWhens(endpoints, cts).ConfigureAwait(false); var startTime = DateTime.UtcNow; var maxTime = runDescriptor.Settings.TestExecutionTimeout ?? TimeSpan.FromSeconds(90); while (!done() && !cts.Token.IsCancellationRequested) { if (DateTime.UtcNow - startTime > maxTime) { ThrowOnFailedMessages(runDescriptor, endpoints); throw new TimeoutException(GenerateTestTimedOutMessage(maxTime)); } await Task.Delay(1).ConfigureAwait(false); } startTime = DateTime.UtcNow; var unfinishedFailedMessagesMaxWaitTime = TimeSpan.FromSeconds(30); while (runDescriptor.ScenarioContext.UnfinishedFailedMessages.Values.Any(x => x)) { if (DateTime.UtcNow - startTime > unfinishedFailedMessagesMaxWaitTime) { throw new Exception("Some failed messages were not handled by the recoverability feature."); } await Task.Delay(1).ConfigureAwait(false); } } finally { await StopEndpoints(endpoints).ConfigureAwait(false); } ThrowOnFailedMessages(runDescriptor, endpoints); } }
public Result Initialize(RunDescriptor run, EndpointBehavior endpointBehavior, IDictionary<Type, string> routingTable, string endpointName) { try { behavior = endpointBehavior; scenarioContext = run.ScenarioContext; configuration = ((IEndpointConfigurationFactory) Activator.CreateInstance(endpointBehavior.EndpointBuilderType)) .Get(); configuration.EndpointName = endpointName; if (!string.IsNullOrEmpty(configuration.CustomMachineName)) { RuntimeEnvironment.MachineNameAction = () => configuration.CustomMachineName; } //apply custom config settings endpointBehavior.CustomConfig.ForEach(customAction => customAction(config)); config = configuration.GetConfiguration(run, routingTable); if (scenarioContext != null) { config.Configurer.RegisterSingleton(scenarioContext.GetType(), scenarioContext); scenarioContext.ContextPropertyChanged += scenarioContext_ContextPropertyChanged; } bus = config.CreateBus(); Configure.Instance.ForInstallationOn<Windows>().Install(); stopToken = stopSource.Token; if (behavior.Whens.Count == 0) { executeWhens = Task.FromResult(0); } else { executeWhens = Task.Factory.StartNew(async () => { var executedWhens = new List<Guid>(); while (!stopToken.IsCancellationRequested) { if (executedWhens.Count == behavior.Whens.Count) { break; } //we spin around each 5s since the callback mechanism seems to be shaky await contextChanged.WaitAsync(TimeSpan.FromSeconds(5), stopToken); if (stopToken.IsCancellationRequested) break; foreach (var when in behavior.Whens) { if (executedWhens.Contains(when.Id)) { continue; } if (when.ExecuteAction(scenarioContext, bus)) { executedWhens.Add(when.Id); } } } }, stopToken).Unwrap(); } return Result.Success(); } catch (Exception ex) { Logger.Error("Failed to initialize endpoint " + endpointName, ex); return Result.Failure(ex); } }
public RunDescriptor(RunDescriptor template) { Settings = template.Settings.ToDictionary(entry => entry.Key, entry => entry.Value); Key = template.Key; }
static List<ActiveRunner> InitializeRunners(RunDescriptor runDescriptor, IList<EndpointBehavior> behaviorDescriptors) { var runners = new List<ActiveRunner>(); var routingTable = CreateRoutingTable(behaviorDescriptors); foreach (var behaviorDescriptor in behaviorDescriptors) { var endpointName = GetEndpointNameForRun(behaviorDescriptor); if (endpointName.Length > 77) { throw new Exception(string.Format("Endpoint name '{0}' is larger than 77 characters and will cause issues with MSMQ queue names. Please rename your test class or endpoint!",endpointName)); } var runner = PrepareRunner(endpointName, behaviorDescriptor.AppConfig, runDescriptor.UseSeparateAppdomains); var result = runner.Instance.Initialize(runDescriptor, behaviorDescriptor, routingTable, endpointName); if (runDescriptor.UseSeparateAppdomains) { // Extend the lease to the timeout value specified. var serverLease = (ILease)RemotingServices.GetLifetimeService(runner.Instance); // Add the execution time + additional time for the endpoints to be able to stop gracefully var totalLifeTime = runDescriptor.TestExecutionTimeout.Add(TimeSpan.FromMinutes(2)); serverLease.Renew(totalLifeTime); } if (result.Failed) { throw new ScenarioException(string.Format("Endpoint {0} failed to initialize", runner.Instance.Name()), result.Exception); } runners.Add(runner); } return runners; }
static RunResult PerformTestRun(IList<EndpointBehaviour> behaviorDescriptors, IList<IScenarioVerification> shoulds, RunDescriptor runDescriptor, Func<ScenarioContext, bool> done) { var runResult = new RunResult { ScenarioContext = runDescriptor.ScenarioContext }; var runTimer = new Stopwatch(); runTimer.Start(); try { List<ActiveRunner> runners = InitializeRunners(runDescriptor, behaviorDescriptors); try { runResult.ActiveEndpoints = runners.Select(r => r.EndpointName).ToList(); PerformScenarios(runDescriptor,runners, () => done(runDescriptor.ScenarioContext)); } finally { UnloadAppDomains(runners); } runTimer.Stop(); Parallel.ForEach(runners, runner => shoulds.Where(s => s.ContextType == runDescriptor.ScenarioContext.GetType()).ToList() .ForEach(v => v.Verify(runDescriptor.ScenarioContext))); } catch (Exception ex) { runResult.Failed = true; runResult.Exception = ex; } runResult.TotalTime = runTimer.Elapsed; return runResult; }
static List<ActiveRunner> InitializeRunners(RunDescriptor runDescriptor, IList<EndpointBehaviour> behaviorDescriptors) { var runners = new List<ActiveRunner>(); var routingTable = CreateRoutingTable(runDescriptor, behaviorDescriptors); foreach (var behaviorDescriptor in behaviorDescriptors) { var endpointName = GetEndpointNameForRun(runDescriptor, behaviorDescriptor); var runner = PrepareRunner(endpointName, behaviorDescriptor.AppConfig); var result = runner.Instance.Initialize(runDescriptor, behaviorDescriptor, routingTable, endpointName); // Extend the lease to the timeout value specified. ILease serverLease = (ILease)RemotingServices.GetLifetimeService(runner.Instance); // Add the execution time + additional time for the endpoints to be able to stop gracefully var totalLifeTime = runDescriptor.TestExecutionTimeout.Add(TimeSpan.FromMinutes(2)); serverLease.Renew(totalLifeTime); if (result.Failed) { throw new ScenarioException(string.Format("Endpoint {0} failed to initialize - {1}", runner.Instance.Name(), result.ExceptionMessage)); } runners.Add(runner); } return runners; }
static IDictionary<Type, string> CreateRoutingTable(RunDescriptor runDescriptor, IEnumerable<EndpointBehaviour> behaviorDescriptors) { var routingTable = new Dictionary<Type, string>(); foreach (var behaviorDescriptor in behaviorDescriptors) { routingTable[behaviorDescriptor.EndpointBuilderType] = GetEndpointNameForRun(runDescriptor, behaviorDescriptor); } return routingTable; }
static string GetEndpointNameForRun(RunDescriptor runDescriptor, EndpointBehaviour endpointBehaviour) { var endpointName = Conventions.EndpointNamingConvention(endpointBehaviour.EndpointBuilderType) + "." + runDescriptor.Key; return endpointName; }
protected bool Equals(RunDescriptor other) { return(string.Equals(Key, other.Key)); }
static void PerformScenarios(RunDescriptor runDescriptor,IEnumerable<ActiveRunner> runners, Func<bool> done) { var endpoints = runners.Select(r => r.Instance).ToList(); StartEndpoints(endpoints); runDescriptor.ScenarioContext.EndpointsStarted = true; var startTime = DateTime.UtcNow; var maxTime = runDescriptor.TestExecutionTimeout; Task.WaitAll(endpoints.Select(endpoint => Task.Factory.StartNew(() => SpinWait.SpinUntil(done, maxTime))).Cast<Task>().ToArray(), maxTime); try { if ((DateTime.UtcNow - startTime) > maxTime) { throw new ScenarioException(GenerateTestTimedOutMessage(endpoints, maxTime)); } } finally { StopEndpoints(endpoints); } }
static async Task<ActiveRunner[]> InitializeRunners(RunDescriptor runDescriptor, List<EndpointBehavior> endpointBehaviors) { var routingTable = CreateRoutingTable(endpointBehaviors); var runnerInitializations = endpointBehaviors.Select(async endpointBehavior => { var endpointName = GetEndpointNameForRun(endpointBehavior); if (endpointName.Length > 77) { throw new Exception($"Endpoint name '{endpointName}' is larger than 77 characters and will cause issues with MSMQ queue names. Rename the test class or endpoint."); } var runner = new ActiveRunner { Instance = new EndpointRunner(), EndpointName = endpointName }; try { await runner.Instance.Initialize(runDescriptor, endpointBehavior, routingTable, endpointName).ConfigureAwait(false); } catch (Exception) { Console.WriteLine($"Endpoint {runner.Instance.Name()} failed to initialize"); throw; } return runner; }); try { var x = await Task.WhenAll(runnerInitializations).ConfigureAwait(false); return x; } catch (Exception e) { Console.WriteLine(e); throw; } }
static RunResult PerformTestRun(IList <EndpointBehavior> behaviorDescriptors, IList <IScenarioVerification> shoulds, RunDescriptor runDescriptor, Func <ScenarioContext, bool> done, Func <Exception, bool> allowedExceptions) { var runResult = new RunResult { ScenarioContext = runDescriptor.ScenarioContext }; var runTimer = new Stopwatch(); runTimer.Start(); try { var runners = InitializeRunners(runDescriptor, behaviorDescriptors); try { runResult.ActiveEndpoints = runners.Select(r => r.EndpointName).ToList(); PerformScenarios(runDescriptor, runners, () => { if (!string.IsNullOrEmpty(runDescriptor.ScenarioContext.Exceptions)) { var ex = new Exception(runDescriptor.ScenarioContext.Exceptions); if (!allowedExceptions(ex)) { throw new Exception("Failures in endpoints"); } } return(done(runDescriptor.ScenarioContext)); }); } finally { if (runDescriptor.UseSeparateAppdomains) { UnloadAppDomains(runners); } } runTimer.Stop(); Parallel.ForEach(runners, runner => { foreach (var v in shoulds.Where(s => s.ContextType == runDescriptor.ScenarioContext.GetType())) { v.Verify(runDescriptor.ScenarioContext); } }); } catch (Exception ex) { runResult.Failed = true; runResult.Exception = ex; } runResult.TotalTime = runTimer.Elapsed; return(runResult); }
static RunResult PerformTestRun(IList <EndpointBehaviour> behaviorDescriptors, IList <IScenarioVerification> shoulds, RunDescriptor runDescriptor, Func <ScenarioContext, bool> done) { var runResult = new RunResult { ScenarioContext = runDescriptor.ScenarioContext }; var runTimer = new Stopwatch(); runTimer.Start(); try { List <ActiveRunner> runners = InitializeRunners(runDescriptor, behaviorDescriptors); try { runResult.ActiveEndpoints = runners.Select(r => r.EndpointName).ToList(); PerformScenarios(runDescriptor, runners, () => done(runDescriptor.ScenarioContext)); } finally { UnloadAppDomains(runners); } runTimer.Stop(); Parallel.ForEach(runners, runner => shoulds.Where(s => s.ContextType == runDescriptor.ScenarioContext.GetType()).ToList() .ForEach(v => v.Verify(runDescriptor.ScenarioContext))); } catch (Exception ex) { runResult.Failed = true; runResult.Exception = ex; } runResult.TotalTime = runTimer.Elapsed; return(runResult); }
static void ThrowOnFailedMessages(RunDescriptor runDescriptor, List<EndpointRunner> endpoints) { var unexpectedFailedMessages = runDescriptor.ScenarioContext.FailedMessages .Where(kvp => endpoints.Single(e => e.Name() == kvp.Key).FailOnErrorMessage) .SelectMany(kvp => kvp.Value) .ToList(); if (unexpectedFailedMessages.Any()) { throw new MessagesFailedException(unexpectedFailedMessages, runDescriptor.ScenarioContext); } }
static RunResult PerformTestRun(IList<EndpointBehavior> behaviorDescriptors, IList<IScenarioVerification> shoulds, RunDescriptor runDescriptor, Func<ScenarioContext, bool> done, Func<Exception, bool> allowedExceptions) { var runResult = new RunResult { ScenarioContext = runDescriptor.ScenarioContext }; var runTimer = new Stopwatch(); runTimer.Start(); try { var runners = InitializeRunners(runDescriptor, behaviorDescriptors); try { runResult.ActiveEndpoints = runners.Select(r => r.EndpointName).ToList(); PerformScenarios(runDescriptor, runners, () => { if (!string.IsNullOrEmpty(runDescriptor.ScenarioContext.Exceptions)) { var ex = new Exception(runDescriptor.ScenarioContext.Exceptions); if (!allowedExceptions(ex)) { throw new Exception("Failures in endpoints"); } } return done(runDescriptor.ScenarioContext); }); } finally { if (runDescriptor.UseSeparateAppdomains) { UnloadAppDomains(runners); } } runTimer.Stop(); Parallel.ForEach(runners, runner => { foreach (var v in shoulds.Where(s => s.ContextType == runDescriptor.ScenarioContext.GetType())) { v.Verify(runDescriptor.ScenarioContext); } }); } catch (Exception ex) { runResult.Failed = true; runResult.Exception = ex; } runResult.TotalTime = runTimer.Elapsed; return runResult; }
protected bool Equals(RunDescriptor other) { return string.Equals(Key, other.Key); }
static async Task <RunResult> PerformTestRun(List <IComponentBehavior> behaviorDescriptors, RunDescriptor runDescriptor, Func <ScenarioContext, Task <bool> > done) { var runResult = new RunResult { ScenarioContext = runDescriptor.ScenarioContext }; var runTimer = new Stopwatch(); runTimer.Start(); try { var endpoints = await InitializeRunners(runDescriptor, behaviorDescriptors).ConfigureAwait(false); runResult.ActiveEndpoints = endpoints.Select(r => r.Name); await PerformScenarios(runDescriptor, endpoints, () => done(runDescriptor.ScenarioContext)).ConfigureAwait(false); runTimer.Stop(); } catch (Exception ex) { runResult.Failed = true; runResult.Exception = ExceptionDispatchInfo.Capture(ex); } runResult.TotalTime = runTimer.Elapsed; return(runResult); }
public Result Initialize(RunDescriptor run, EndpointBehavior endpointBehavior, IDictionary<Type, string> routingTable, string endpointName) { try { runDescriptor = run; behavior = endpointBehavior; scenarioContext = run.ScenarioContext; configuration = ((IEndpointConfigurationFactory)Activator.CreateInstance(endpointBehavior.EndpointBuilderType)) .Get(); configuration.EndpointName = endpointName; if (!string.IsNullOrEmpty(configuration.CustomMachineName)) { RuntimeEnvironment.MachineNameAction = () => configuration.CustomMachineName; } //apply custom config settings var busConfiguration = configuration.GetConfiguration(run, routingTable); scenarioContext.ContextPropertyChanged += scenarioContext_ContextPropertyChanged; endpointBehavior.CustomConfig.ForEach(customAction => customAction(busConfiguration)); if (configuration.SendOnly) { sendOnlyBus = Bus.CreateSendOnly(busConfiguration); } else { bus = Bus.Create(busConfiguration); var transportDefinition = ((UnicastBus)bus).Settings.Get<TransportDefinition>(); scenarioContext.HasNativePubSubSupport = transportDefinition.HasNativePubSubSupport; } executeWhens = Task.Factory.StartNew(() => { while (!stopped) { //we spin around each 5s since the callback mechanism seems to be shaky contextChanged.Wait(TimeSpan.FromSeconds(5)); lock (behavior) { foreach (var when in behavior.Whens) { if (executedWhens.Contains(when.Id)) { continue; } if (when.ExecuteAction(scenarioContext, bus)) { executedWhens.Add(when.Id); } } } } }); return Result.Success(); } catch (Exception ex) { Logger.Error("Failed to initialize endpoint " + endpointName, ex); return Result.Failure(ex); } }