public async Task Exchange_should_upload_monitor_healths_in_buckets()
        {
            SetupDefaultRegisterEndpointsMock();
            var identity = SetupDefaultEndpointIdentitiesMock().First();

            int bucketCount = 10;
            int bucketSize  = 10;
            var uploads     = new List <int>();

            var countdown = new AsyncCountdown(nameof(IHealthMonitorExchangeClient.UploadHealthAsync), bucketCount);

            SetupDefaultHealthUploadMock(x => { uploads.Add(x.Length); countdown.Decrement(); });

            var healths = PrepareEndpointHealths(bucketSize * bucketCount);

            using (var ex = CreateExchange(new DataExchangeConfig(bucketSize * bucketCount, bucketSize, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), EndpointMetadata.DefaultMonitorTag)))
            {
                foreach (var health in healths)
                {
                    ex.UpdateHealth(identity.Id, health);
                }

                await countdown.WaitAsync(TestMaxWaitTime);
            }

            Assert.Equal(new[] { bucketSize }, uploads.Distinct());
        }
Exemplo n.º 2
0
        public async Task Notifier_should_cancel_health_check_on_dispose()
        {
            SetupEndpointRegistration(Guid.NewGuid());
            SetupHealthCheckInterval(TimeSpan.FromMilliseconds(1));

            var notCancelled = false;
            var countdown    = new AsyncCountdown("healthCheck", 1);
            Func <CancellationToken, Task <EndpointHealth> > healthCheck = async token =>
            {
                countdown.Decrement();
                await Task.Delay(TestMaxTime, token);

                notCancelled = true;
                return(new EndpointHealth(HealthStatus.Healthy));
            };

            using (CreateNotifier(healthCheck))
                await countdown.WaitAsync(TestMaxTime);

            Assert.False(notCancelled);
        }
        public async Task Executor_should_immediately_break_the_loop_on_cancelation()
        {
            var timeCoordinator  = new Mock <ITimeCoordinator>();
            var countdown        = new AsyncCountdown("task", 1);
            var taskNotCancelled = false;

            using (var executor = ContinuousTaskExecutor <string> .StartExecutor(timeCoordinator.Object))
            {
                executor.TryRegisterTaskFor("task", async(item, token) =>
                {
                    countdown.Decrement();
                    await Task.Delay(_testTimeout, token);
                    taskNotCancelled = true;
                });

                await countdown.WaitAsync(_testTimeout);
            }

            Assert.False(taskNotCancelled, "Task was not cancelled");
            timeCoordinator.Verify(c => c.Delay(It.IsAny <TimeSpan>(), It.IsAny <CancellationToken>()), Times.Never, "Executor should not trigger any delay");
        }
Exemplo n.º 4
0
        public async Task Manager_should_delete_old_stats()
        {
            const int expectedRepeats = 3;

            var age            = TimeSpan.FromHours(1);
            var utcNow         = DateTime.UtcNow;
            var asyncCountdown = new AsyncCountdown("delete old stats", expectedRepeats);
            var asyncCounter   = new AsyncCounter();

            var monitorSettings = new Mock <IMonitorSettings>();

            monitorSettings.Setup(s => s.StatsHistoryMaxAge).Returns(age);

            var timeCoordinator = new Mock <ITimeCoordinator>();

            timeCoordinator.Setup(c => c.UtcNow).Returns(utcNow);

            var endpointMetricsCoordinator = new Mock <IEndpointMetricsForwarderCoordinator>();

            var repository = new Mock <IEndpointStatsRepository>();

            repository.Setup(r => r.DeleteStatisticsOlderThan(utcNow - age, It.IsAny <int>())).Returns(() =>
            {
                asyncCountdown.Decrement();
                asyncCounter.Increment();

                const int deletedItemsCount = 127;
                return(asyncCounter.Value >= expectedRepeats ? 0 : deletedItemsCount);
            });

            using (new EndpointStatsManager(repository.Object, monitorSettings.Object, timeCoordinator.Object, endpointMetricsCoordinator.Object))
                await asyncCountdown.WaitAsync(MaxTestTime);

            await Task.Delay(TimeSpan.FromMilliseconds(500));

            //it should stop calling cleanup when there are no more items to be cleaned
            Assert.Equal(expectedRepeats, asyncCounter.Value);
        }
        public async Task Exchange_should_retry_health_update_send_in_case_of_errors()
        {
            var count     = 10;
            var countdown = new AsyncCountdown(nameof(IHealthMonitorExchangeClient.UploadHealthAsync), count);

            SetupDefaultRegisterEndpointsMock();
            var identity = SetupDefaultEndpointIdentitiesMock().First();

            var attempts = 10;

            SetupDefaultHealthUploadMock(updates =>
            {
                if (attempts-- > 0)
                {
                    throw new Exception();
                }

                foreach (var update in updates)
                {
                    countdown.Decrement();
                }
            });


            var config = new DataExchangeConfig(100, count, TimeSpan.FromMilliseconds(1), TimeSpan.FromSeconds(1), EndpointMetadata.DefaultMonitorTag);

            var healths = PrepareEndpointHealths(count);

            using (var ex = CreateExchange(config))
            {
                foreach (var health in healths)
                {
                    ex.UpdateHealth(identity.Id, health);
                }

                await countdown.WaitAsync(TestMaxWaitTime);
            }
        }
        public async Task Exchange_should_retry_health_update_send_until_disposal()
        {
            var countdown = new AsyncCountdown(nameof(IHealthMonitorExchangeClient.UploadHealthAsync), 10);

            SetupDefaultRegisterEndpointsMock();
            var identity = SetupDefaultEndpointIdentitiesMock().First();

            int calls = 0;

            SetupDefaultHealthUploadMock(x =>
            {
                Interlocked.Increment(ref calls);
                countdown.Decrement();
                if (calls > 1)
                {
                    throw new InvalidOperationException();
                }
            });

            var healths = PrepareEndpointHealths(2);

            using (var ex = CreateExchange(new DataExchangeConfig(100, 1, TimeSpan.FromMilliseconds(1), TimeSpan.FromSeconds(1), EndpointMetadata.DefaultMonitorTag)))
            {
                foreach (var health in healths)
                {
                    ex.UpdateHealth(identity.Id, health);
                }
                await countdown.WaitAsync(TestMaxWaitTime);
            }

            var capturedCalls = calls;

            Assert.True(capturedCalls > 0, "capturedCalls>0");

            await Task.Delay(PostRunDelay);

            Assert.Equal(capturedCalls, calls);
        }
        public async Task Executor_should_cancel_all_tasks_on_disposal_and_report_all_finished()
        {
            var task1NotCancelled = false;
            var task2NotCancelled = false;
            var task1             = "task1";
            var task2             = "task2";
            var task1Ran          = new AsyncCountdown(task1, 1);
            var task2Ran          = new AsyncCountdown(task2, 1);
            var completed         = new ConcurrentQueue <string>();

            using (var executor = ContinuousTaskExecutor <string> .StartExecutor(Mock.Of <ITimeCoordinator>()))
            {
                executor.FinishedTaskFor += item => completed.Enqueue(item);

                executor.TryRegisterTaskFor(task1, async(item, token) =>
                {
                    task1Ran.Decrement();
                    await Task.Delay(_testTimeout, token);
                    task1NotCancelled = true;
                });
                executor.TryRegisterTaskFor(task2, async(item, token) =>
                {
                    task2Ran.Decrement();
                    await Task.Delay(_testTimeout, token);
                    task2NotCancelled = true;
                });

                await task1Ran.WaitAsync(_testTimeout);

                await task2Ran.WaitAsync(_testTimeout);
            }
            Assert.False(task1NotCancelled, "task1NotCancelled");
            Assert.False(task2NotCancelled, "task2NotCancelled");

            CollectionAssert.AreEquivalent(new[] { task1, task2 }, completed);
        }
        public async Task Manager_should_delete_old_stats()
        {
            var age            = TimeSpan.FromHours(1);
            var utcNow         = DateTime.UtcNow;
            var asyncCountdown = new AsyncCountdown("delete old stats", 1);

            var monitorSettings = new Mock <IMonitorSettings>();

            monitorSettings.Setup(s => s.StatsHistoryMaxAge).Returns(age);

            var timeCoordinator = new Mock <ITimeCoordinator>();

            timeCoordinator.Setup(c => c.UtcNow).Returns(utcNow);

            var endpointMetricsCoordinator = new Mock <IEndpointMetricsForwarderCoordinator>();

            var repository = new Mock <IEndpointStatsRepository>();

            repository.Setup(r => r.DeleteStatisticsOlderThan(utcNow - age)).Callback(() => asyncCountdown.Decrement());

            using (new EndpointStatsManager(repository.Object, monitorSettings.Object, timeCoordinator.Object, endpointMetricsCoordinator.Object))
                await asyncCountdown.WaitAsync(MaxTestTime);
        }