public async Task Invoke_SuccessfulFlow_CallNext(AffinityStatus status, string foundDestinationId)
        {
            var cluster           = GetCluster();
            var foundDestinations = foundDestinationId != null?Destinations.Where(d => d.DestinationId == foundDestinationId).ToArray() : null;

            var          invokedMode  = string.Empty;
            const string expectedMode = "Mode-B";
            var          providers    = RegisterAffinityProviders(
                true,
                Destinations,
                cluster.ClusterId,
                ("Mode-A", AffinityStatus.DestinationNotFound, (RuntimeModel.DestinationInfo[])null, (Action <ISessionAffinityProvider>)(p => throw new InvalidOperationException($"Provider {p.Mode} call is not expected."))),
                (expectedMode, status, foundDestinations, p => invokedMode = p.Mode));
            var nextInvoked = false;
            var middleware  = new AffinitizedDestinationLookupMiddleware(c => {
                nextInvoked = true;
                return(Task.CompletedTask);
            },
                                                                         providers.Select(p => p.Object), new IAffinityFailurePolicy[0],
                                                                         GetOperationLogger(false),
                                                                         new Mock <ILogger <AffinitizedDestinationLookupMiddleware> >().Object);
            var context = new DefaultHttpContext();

            context.Features.Set(cluster);
            var destinationFeature = GetDestinationsFeature(Destinations);

            context.Features.Set(destinationFeature);

            await middleware.Invoke(context);

            Assert.Equal(expectedMode, invokedMode);
            Assert.True(nextInvoked);
            providers[0].VerifyGet(p => p.Mode, Times.Once);
            providers[0].VerifyNoOtherCalls();
            providers[1].VerifyAll();

            if (foundDestinationId != null)
            {
                Assert.Equal(1, destinationFeature.Destinations.Count);
                Assert.Equal(foundDestinationId, destinationFeature.Destinations[0].DestinationId);
            }
            else
            {
                Assert.Same(Destinations, destinationFeature.Destinations);
            }
        }
        public async Task Invoke_ErrorFlow_CallFailurePolicy(AffinityStatus affinityStatus, bool keepProcessing)
        {
            var          cluster         = GetCluster();
            var          providers       = RegisterAffinityProviders(true, Destinations, cluster.ClusterId, ("Mode-B", affinityStatus, null, _ => { }));
            var          invokedPolicy   = string.Empty;
            const string expectedPolicy  = "Policy-1";
            var          failurePolicies = RegisterFailurePolicies(
                affinityStatus,
                ("Policy-0", false, p => throw new InvalidOperationException($"Policy {p.Name} call is not expected.")),
                (expectedPolicy, keepProcessing, p => invokedPolicy = p.Name));
            var nextInvoked = false;
            var logger      = AffinityTestHelper.GetLogger <AffinitizedDestinationLookupMiddleware>();
            var middleware  = new AffinitizedDestinationLookupMiddleware(c => {
                nextInvoked = true;
                return(Task.CompletedTask);
            },
                                                                         providers.Select(p => p.Object), failurePolicies.Select(p => p.Object),
                                                                         GetOperationLogger(true),
                                                                         logger.Object);
            var context = new DefaultHttpContext();

            context.Features.Set(cluster);
            var destinationFeature = GetDestinationsFeature(Destinations);

            context.Features.Set(destinationFeature);

            await middleware.Invoke(context);

            Assert.Equal(expectedPolicy, invokedPolicy);
            Assert.Equal(keepProcessing, nextInvoked);
            failurePolicies[0].VerifyGet(p => p.Name, Times.Once);
            failurePolicies[0].VerifyNoOtherCalls();
            failurePolicies[1].VerifyAll();
            if (!keepProcessing)
            {
                logger.Verify(
                    l => l.Log(LogLevel.Warning, EventIds.AffinityResolutionFailedForCluster, It.IsAny <It.IsAnyType>(), null, (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()),
                    Times.Once);
            }
        }