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);
}
}