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