public async Task SetPassiveAsync_DestinationBecameUnhealthy_SetUnhealthyAndScheduleReactivation()
        {
            var destination = new DestinationInfo("destination0");

            destination.Health.Active  = DestinationHealth.Healthy;
            destination.Health.Passive = DestinationHealth.Healthy;
            var cluster = CreateCluster(passive: true, active: false, destination);

            using var timerFactory = new TestTimerFactory();
            var updater = new DestinationHealthUpdater(timerFactory, new Mock <ILogger <DestinationHealthUpdater> >().Object);

            await updater.SetPassiveAsync(cluster, destination, DestinationHealth.Unhealthy, TimeSpan.FromSeconds(2));

            timerFactory.VerifyTimer(0, 2000);
            Assert.Empty(cluster.DynamicState.HealthyDestinations);
            Assert.Equal(DestinationHealth.Healthy, destination.Health.Active);
            Assert.Equal(DestinationHealth.Unhealthy, destination.Health.Passive);

            timerFactory.FireAll();

            Assert.Equal(DestinationHealth.Healthy, destination.Health.Active);
            Assert.Equal(DestinationHealth.Unknown, destination.Health.Passive);
            Assert.Equal(1, cluster.DynamicState.HealthyDestinations.Count);
            Assert.Same(destination, cluster.DynamicState.HealthyDestinations[0]);
            timerFactory.AssertTimerDisposed(0);
        }
Пример #2
0
        public void ChangePeriod_TimerStartedPeriodChangedAfterFirstCall_PeriodChangedBeforeNextCall()
        {
            var entity = new Entity {
                Id = "entity0"
            };
            Entity lastInvokedEntity = null;
            var    timerFactory      = new TestTimerFactory();

            using var scheduler = new EntityActionScheduler <Entity>(e =>
            {
                lastInvokedEntity = e;
                return(Task.CompletedTask);
            }, autoStart: true, runOnce: false, timerFactory);

            scheduler.ScheduleEntity(entity, TimeSpan.FromMilliseconds(Period0));
            timerFactory.VerifyTimer(0, Period0);

            timerFactory.FireTimer(0);

            var newPeriod = TimeSpan.FromMilliseconds(Period1);

            scheduler.ChangePeriod(entity, newPeriod);

            timerFactory.VerifyTimer(0, Period1);
            Assert.Same(entity, lastInvokedEntity);
        }
    public async Task SetPassiveAsync_DestinationBecameUnhealthy_SetUnhealthyAndScheduleReactivation()
    {
        var destination = new DestinationState("destination0");

        destination.Health.Active  = DestinationHealth.Healthy;
        destination.Health.Passive = DestinationHealth.Healthy;
        var cluster = CreateCluster(passive: true, active: false, destination);

        using var timerFactory = new TestTimerFactory();
        var updater = new DestinationHealthUpdater(timerFactory, GetClusterUpdater(), new Mock <ILogger <DestinationHealthUpdater> >().Object);

        await updater.SetPassiveAsync(cluster, destination, DestinationHealth.Unhealthy, TimeSpan.FromSeconds(2));

        timerFactory.VerifyTimer(0, 2000);
        Assert.Empty(cluster.DestinationsState.AvailableDestinations);
        Assert.Equal(DestinationHealth.Healthy, destination.Health.Active);
        Assert.Equal(DestinationHealth.Unhealthy, destination.Health.Passive);

        timerFactory.FireAll();
        GC.KeepAlive(updater); // The timer does not keep a strong reference to the scheduler

        Assert.Equal(DestinationHealth.Healthy, destination.Health.Active);
        Assert.Equal(DestinationHealth.Unknown, destination.Health.Passive);
        Assert.Equal(1, cluster.DestinationsState.AvailableDestinations.Count);
        Assert.Same(destination, cluster.DestinationsState.AvailableDestinations[0]);
        timerFactory.AssertTimerDisposed(0);
    }
        public async Task SetPassiveAsync_HealthSateIsNotChanged_DoNothing(DestinationHealth health)
        {
            var destination = new DestinationInfo("destination0");

            destination.Health.Active  = DestinationHealth.Healthy;
            destination.Health.Passive = health;
            var cluster = CreateCluster(passive: true, active: false, destination);

            using var timerFactory = new TestTimerFactory();
            var updater = new DestinationHealthUpdater(timerFactory, new Mock <ILogger <DestinationHealthUpdater> >().Object);

            await updater.SetPassiveAsync(cluster, destination, health, TimeSpan.FromSeconds(2));

            Assert.Equal(0, timerFactory.Count);
            Assert.Equal(DestinationHealth.Healthy, destination.Health.Active);
            Assert.Equal(health, destination.Health.Passive);
        }
Пример #5
0
        public void Schedule_AutoStartDisabledRunOnceEnabled_StartsManuallyAndRunsEachRegistrationOnlyOnce()
        {
            var entity0 = new Entity {
                Id = "entity0"
            };
            var entity1 = new Entity {
                Id = "entity1"
            };
            Entity lastInvokedEntity = null;
            var    timerFactory      = new TestTimerFactory();

            using var scheduler = new EntityActionScheduler <Entity>(e =>
            {
                lastInvokedEntity = e;
                return(Task.CompletedTask);
            }, autoStart: false, runOnce: true, timerFactory);

            scheduler.ScheduleEntity(entity0, TimeSpan.FromMilliseconds(Period0));
            scheduler.ScheduleEntity(entity1, TimeSpan.FromMilliseconds(Period1));
            Assert.Equal(2, timerFactory.Count);
            timerFactory.VerifyTimer(0, Timeout.Infinite);
            timerFactory.VerifyTimer(1, Timeout.Infinite);

            scheduler.Start();

            VerifyEntities(scheduler, entity0, entity1);
            Assert.Equal(2, timerFactory.Count);
            timerFactory.VerifyTimer(0, Period0);
            timerFactory.VerifyTimer(1, Period1);

            timerFactory.FireTimer(1);

            Assert.Same(entity1, lastInvokedEntity);

            VerifyEntities(scheduler, entity0);

            timerFactory.FireTimer(0);

            Assert.Same(entity0, lastInvokedEntity);

            Assert.False(scheduler.IsScheduled(entity0));
            Assert.False(scheduler.IsScheduled(entity1));
            timerFactory.AssertTimerDisposed(0);
            timerFactory.AssertTimerDisposed(1);
        }
        public async Task SetPassiveAsync_DestinationBecameHealthy_SetNewState()
        {
            var destination = new DestinationInfo("destination0");

            destination.Health.Active  = DestinationHealth.Healthy;
            destination.Health.Passive = DestinationHealth.Unhealthy;
            var cluster = CreateCluster(passive: true, active: false, destination);

            using var timerFactory = new TestTimerFactory();
            var updater = new DestinationHealthUpdater(timerFactory, new Mock <ILogger <DestinationHealthUpdater> >().Object);

            await updater.SetPassiveAsync(cluster, destination, DestinationHealth.Healthy, TimeSpan.FromSeconds(2));

            Assert.Equal(0, timerFactory.Count);
            Assert.Equal(DestinationHealth.Healthy, destination.Health.Active);
            Assert.Equal(DestinationHealth.Healthy, destination.Health.Passive);
            Assert.Equal(1, cluster.DynamicState.HealthyDestinations.Count);
            Assert.Same(destination, cluster.DynamicState.HealthyDestinations[0]);
        }
Пример #7
0
        public void Schedule_AutoStartEnabledRunOnceDisabled_StartsAutomaticallyAndRunsIndefinitely()
        {
            var entity0 = new Entity {
                Id = "entity0"
            };
            var entity1 = new Entity {
                Id = "entity1"
            };
            var    timerFactory      = new TestTimerFactory();
            Entity lastInvokedEntity = null;

            using var scheduler = new EntityActionScheduler <Entity>(e =>
            {
                lastInvokedEntity = e;
                return(Task.CompletedTask);
            }, autoStart: true, runOnce: false, timerFactory);

            scheduler.ScheduleEntity(entity0, TimeSpan.FromMilliseconds(20000));
            scheduler.ScheduleEntity(entity1, TimeSpan.FromMilliseconds(10000));

            VerifyEntities(scheduler, entity0, entity1);
            Assert.Equal(2, timerFactory.Count);
            timerFactory.VerifyTimer(0, Period0);
            timerFactory.VerifyTimer(1, Period1);

            timerFactory.FireTimer(1);
            Assert.Same(entity1, lastInvokedEntity);

            timerFactory.FireTimer(0);
            Assert.Same(entity0, lastInvokedEntity);

            timerFactory.FireTimer(1);
            Assert.Same(entity1, lastInvokedEntity);

            timerFactory.FireTimer(0);
            Assert.Same(entity0, lastInvokedEntity);

            VerifyEntities(scheduler, entity0, entity1);
            Assert.Equal(2, timerFactory.Count);
            timerFactory.VerifyTimer(0, Period0);
            timerFactory.VerifyTimer(1, Period1);
        }
        public void Schedule_DestinationIsAlreadyHealthy_DoNothing()
        {
            var destination = new DestinationInfo("destination0");

            destination.Health.Active  = DestinationHealth.Unhealthy;
            destination.Health.Passive = DestinationHealth.Unhealthy;
            using var timerFactory     = new TestTimerFactory();
            var scheduler = new ReactivationScheduler(timerFactory, new Mock <ILogger <ReactivationScheduler> >().Object);

            Assert.Equal(DestinationHealth.Unhealthy, destination.Health.Active);
            Assert.Equal(DestinationHealth.Unhealthy, destination.Health.Passive);

            scheduler.Schedule(destination, TimeSpan.FromSeconds(2));

            destination.Health.Passive = DestinationHealth.Healthy;

            timerFactory.FireAll();

            Assert.Equal(DestinationHealth.Healthy, destination.Health.Passive);
            timerFactory.AssertTimerDisposed(0);
        }
        public void Schedule_ReactivationPeriodElapsed_SetPassiveHealthToUnknown()
        {
            var destination = new DestinationInfo("destination0");

            destination.DynamicState = new DestinationDynamicState(new CompositeDestinationHealth(DestinationHealth.Unhealthy, DestinationHealth.Unhealthy));
            using var timerFactory   = new TestTimerFactory();
            var scheduler = new ReactivationScheduler(timerFactory, new Mock <ILogger <ReactivationScheduler> >().Object);

            Assert.Equal(DestinationHealth.Unhealthy, destination.DynamicState.Health.Active);
            Assert.Equal(DestinationHealth.Unhealthy, destination.DynamicState.Health.Passive);

            var reactivationPeriod = TimeSpan.FromSeconds(2);

            scheduler.Schedule(destination, reactivationPeriod);

            timerFactory.FireAndWaitAll();

            timerFactory.VerifyTimer(0, 2000);
            Assert.Equal(DestinationHealth.Unhealthy, destination.DynamicState.Health.Active);
            Assert.Equal(DestinationHealth.Unknown, destination.DynamicState.Health.Passive);
        }
Пример #10
0
        public void Unschedule_EntityUnscheduledAfterFirstCall_CallbackInvokedOnlyOnce()
        {
            var entity0 = new Entity {
                Id = "entity0"
            };
            var entity1 = new Entity {
                Id = "entity1"
            };
            Entity lastInvokedEntity = null;
            var    timerFactory      = new TestTimerFactory();

            using var scheduler = new EntityActionScheduler <Entity>(e =>
            {
                lastInvokedEntity = e;
                return(Task.CompletedTask);
            }, autoStart: true, runOnce: false, timerFactory);

            scheduler.ScheduleEntity(entity0, TimeSpan.FromMilliseconds(Period0));
            scheduler.ScheduleEntity(entity1, TimeSpan.FromMilliseconds(Period1));

            VerifyEntities(scheduler, entity0, entity1);

            timerFactory.FireTimer(1);

            Assert.Same(entity1, lastInvokedEntity);

            timerFactory.FireTimer(0);

            Assert.Same(entity0, lastInvokedEntity);

            scheduler.UnscheduleEntity(entity1);
            VerifyEntities(scheduler, entity0);
            timerFactory.AssertTimerDisposed(1);

            timerFactory.FireTimer(0);

            Assert.Same(entity0, lastInvokedEntity);

            VerifyEntities(scheduler, entity0);
        }
Пример #11
0
        public void Schedule_ReactivationPeriodElapsedTwice_ReactivateDestinationOnlyOnce()
        {
            var destination = new DestinationInfo("destination0");

            destination.Health.Active  = DestinationHealth.Unhealthy;
            destination.Health.Passive = DestinationHealth.Unhealthy;
            using var timerFactory     = new TestTimerFactory();
            var scheduler = new ReactivationScheduler(timerFactory, new Mock <ILogger <ReactivationScheduler> >().Object);

            Assert.Equal(DestinationHealth.Unhealthy, destination.Health.Active);
            Assert.Equal(DestinationHealth.Unhealthy, destination.Health.Passive);

            var reactivationPeriod = TimeSpan.FromSeconds(2);

            scheduler.Schedule(destination, reactivationPeriod);

            timerFactory.FireAndWaitAll();

            timerFactory.VerifyTimer(0, 2000);
            Assert.Equal(1, timerFactory.Count);
            Assert.Equal(DestinationHealth.Unknown, destination.Health.Passive);
            Assert.Throws <ObjectDisposedException>(() => timerFactory.FireTimer(0));
        }