コード例 #1
0
 public void Dispose_should_mark_endpoint_disposed()
 {
     var endpoint = new Endpoint(Guid.Empty, MonitorMock.Mock("monitor"), "address", "name", "group");
     Assert.False(endpoint.IsDisposed);
     endpoint.Dispose();
     Assert.True(endpoint.IsDisposed);
 }
コード例 #2
0
        private async Task<EndpointHealth> PerformHealthCheck(CancellationToken cancellationToken, Endpoint endpoint)
        {
            var checkTimeUtc = DateTime.UtcNow;
            var timer = new Stopwatch();
            try
            {
                using (var timeoutToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                {
                    timer.Start();
                    var timeoutTask = ConfigureTimeoutTask(endpoint, cancellationToken);
                    var healthTask = endpoint.Monitor.CheckHealthAsync(endpoint.Address, timeoutToken.Token);
                    var healthResult = await Task.WhenAny(healthTask, timeoutTask);
                    timer.Stop();

                    await CancelHealthTaskIfNeeded(healthTask, timeoutToken);

                    return FromResult(checkTimeUtc, timer.Elapsed, healthResult.Result);
                }
            }
            catch (OperationCanceledException)
            {
                throw;
            }
            catch (AggregateException e)
            {
                if (e.InnerExceptions.First() is OperationCanceledException)
                    throw;
                return FromException(checkTimeUtc, timer.Elapsed, e.InnerExceptions.First());
            }
            catch (Exception e)
            {
                return FromException(checkTimeUtc, timer.Elapsed, e);
            }
        }
コード例 #3
0
 public async Task<EndpointHealth> CheckHealth(Endpoint endpoint, CancellationToken cancellationToken)
 {
     Logger.DebugFormat("Checking health of {0}...", endpoint);
     var endpointHealth = await PerformHealthCheck(cancellationToken, endpoint);
     _statsManager.RecordEndpointStatistics(endpoint.Id, endpointHealth);
     LogHealthStatus(endpoint, endpointHealth);
     return endpointHealth;
 }
コード例 #4
0
 public HealthSamplerTests()
 {
     _settings = new Mock<IMonitorSettings>();
     _statsManager = new Mock<IEndpointStatsManager>();
     _sampler = new HealthSampler(_settings.Object, _statsManager.Object);
     _monitor = new Mock<IHealthMonitor>();
     _endpoint = new Endpoint(Guid.NewGuid(), _monitor.Object, "address", "name", "group");
 }
コード例 #5
0
        public void Endpoint_should_be_created_with_last_modified_time_set()
        {
            var expectedLastModifiedTime = DateTime.UtcNow;
            _timeCoordinator.Setup(c => c.UtcNow).Returns(expectedLastModifiedTime);
            var endpoint = new Endpoint(_timeCoordinator.Object, new EndpointIdentity(Guid.NewGuid(), "monitor", "address"), new EndpointMetadata("name", "group", null, EndpointMetadata.DefaultMonitorTag, DateTime.UtcNow, DateTime.UtcNow));


            Assert.Equal(expectedLastModifiedTime, endpoint.LastModifiedTimeUtc);
        }
コード例 #6
0
        public void EndpointRegistry_should_load_endpoints_from_repository()
        {
            var endpoint = new Endpoint(_timeCoordinator.Object, new EndpointIdentity(Guid.NewGuid(), "monitor", "address"), new EndpointMetadata("name", "group", new[] { "t1", "t2" }, EndpointMetadata.DefaultMonitorTag, DateTime.UtcNow, DateTime.UtcNow));
            _configurationStore.Setup(s => s.LoadEndpoints()).Returns(new[] { endpoint });

            var registry = new EndpointRegistry(_healthMonitorTypeRegistry.Object, _configurationStore.Object, _statsManager.Object, _timeCoordinator.Object);

            Assert.Same(endpoint, registry.GetById(endpoint.Identity.Id));
        }
コード例 #7
0
        public void EndpointRegistry_should_load_endpoints_from_store()
        {
            var endpoint = new Endpoint(Guid.NewGuid(), MonitorMock.Mock("monitor"), "address", "name", "group");
            _configurationStore.Setup(s => s.LoadEndpoints(_monitorRegistry.Object)).Returns(new[] { endpoint });

            var registry = new EndpointRegistry(_monitorRegistry.Object, _configurationStore.Object,_statsRepository.Object);

            Assert.Same(endpoint, registry.GetById(endpoint.Id));
        }
コード例 #8
0
 private async Task<Endpoint> CreateTaskFor(Endpoint endpoint)
 {
     await Task.Yield();
     while (!_cancellation.IsCancellationRequested && !endpoint.IsDisposed)
     {
         await endpoint.CheckHealth(_cancellation.Token,_settings);
         await Task.Delay(_settings.HealthCheckInterval);
     }
     return endpoint;
 }
        public EndpointMetricsForwarderCoordinatorTest()
        {
            var endpointId = Guid.NewGuid();
            var health = new EndpointHealth(DateTime.UtcNow, TimeSpan.FromSeconds(1), EndpointStatus.Healthy);
            _endpoint = new Endpoint(TimeCoordinatorMock.Get().Object, new EndpointIdentity(endpointId, "type", "Address"), new EndpointMetadata("Name", "Group", null, EndpointMetadata.DefaultMonitorTag, DateTime.UtcNow, DateTime.UtcNow));
            _endpoint.UpdateHealth(health);

            _forwarder = new Mock<IEndpointMetricsForwarder>();
            _duplicateForwarder = new Mock<IEndpointMetricsForwarder>();
        }
コード例 #10
0
 public void CheckHealth_should_update_the_endpoint_with_its_health_status()
 {
     var endpoint = new Endpoint(Guid.Empty, MonitorMock.Mock("monitor"), "address", "name", "group");
     var sampler = new Mock<IHealthSampler>();
     var token = new CancellationToken();
     var result = new EndpointHealth(DateTime.UtcNow, TimeSpan.Zero, EndpointStatus.Healthy);
     sampler.Setup(s => s.CheckHealth(endpoint, token)).Returns(Task.FromResult(result));
     endpoint.CheckHealth(sampler.Object, token).Wait();
     Assert.Same(result, endpoint.Health);
 }
コード例 #11
0
 public void SaveEndpoint(Endpoint endpoint)
 {
     using (var conn = _db.OpenConnection())
     using (var tx = conn.BeginTransaction())
     {
         if (conn.Execute("update EndpointConfig set MonitorType=@MonitorType, Address=@Address, GroupName=@Group, Name=@Name where Id=@Id", new { endpoint.MonitorType, endpoint.Address, endpoint.Group, endpoint.Name, endpoint.Id }, tx) == 0)
             conn.Execute("insert into EndpointConfig (MonitorType, Address, GroupName, Name, Id) values(@MonitorType,@Address,@Group,@Name,@Id)", new { endpoint.MonitorType, endpoint.Address, endpoint.Group, endpoint.Name, endpoint.Id }, tx);
         tx.Commit();
     }
 }
コード例 #12
0
 private static Mock<IHealthSampler> SetupSampler(Endpoint endpoint, ManualResetEventSlim manualReset)
 {
     var sampler = new Mock<IHealthSampler>();
     sampler
         .Setup(s => s.CheckHealth(endpoint, It.IsAny<CancellationToken>()))
         .Returns(async (Endpoint e, CancellationToken ct) =>
         {
             await Task.Run(() => manualReset.Wait(ct));
             return null;
         });
     return sampler;
 }
コード例 #13
0
        public void UpdateHealth_should_update_health_and_last_modified_time()
        {
            var endpoint = new Endpoint(_timeCoordinator.Object, new EndpointIdentity(Guid.NewGuid(), "monitor", "address"), new EndpointMetadata("name", "group", null, EndpointMetadata.DefaultMonitorTag, DateTime.UtcNow, DateTime.UtcNow));
            var health = new EndpointHealth(DateTime.UtcNow, TimeSpan.Zero, EndpointStatus.Healthy);

            var expectedLastModifiedTime = DateTime.UtcNow;
            _timeCoordinator.Setup(c => c.UtcNow).Returns(expectedLastModifiedTime);

            endpoint.UpdateHealth(health);
            Assert.Same(health, endpoint.Health);

            Assert.Equal(expectedLastModifiedTime, endpoint.LastModifiedTimeUtc);
        }
コード例 #14
0
        public void GetEndpoint_should_return_endpoint_information()
        {
            Guid id = Guid.NewGuid();
            var endpoint = new Endpoint(id, MonitorMock.Mock("monitor"), "address", "name", "group");
            _endpointRegistry.Setup(r => r.GetById(id)).Returns(endpoint);

            var result = _controller.GetEndpoint(id) as OkNegotiatedContentResult<EndpointDetails>;
            Assert.NotNull(result);
            AssertEndpoint(endpoint, result.Content);
            Assert.Equal(EndpointStatus.NotRun, result.Content.Status);
            Assert.Equal(null, result.Content.LastCheckUtc);
            Assert.Equal(null, result.Content.LastResponseTime);
            Assert.Equal(new Dictionary<string, string>(), result.Content.Details);
        }
コード例 #15
0
        public void UpdateMetadata_should_update_metadata_and_last_modified_time()
        {
            var endpoint = new Endpoint(_timeCoordinator.Object, new EndpointIdentity(Guid.NewGuid(), "monitor", "address"), new EndpointMetadata("name", "group", new[] { "t1" }, EndpointMetadata.DefaultMonitorTag, DateTime.UtcNow, DateTime.UtcNow));

            var expectedLastModifiedTime = DateTime.UtcNow;
            _timeCoordinator.Setup(c => c.UtcNow).Returns(expectedLastModifiedTime);

            endpoint.UpdateMetadata("new group", "new name", new[] { "t1", "t2" }, EndpointMetadata.DefaultMonitorTag);

            Assert.Equal("new group", endpoint.Metadata.Group);
            Assert.Equal("new name", endpoint.Metadata.Name);
            Assert.Equal(new[] { "t1", "t2" }, endpoint.Metadata.Tags);

            Assert.Equal(expectedLastModifiedTime, endpoint.LastModifiedTimeUtc);
        }
コード例 #16
0
        public void RecordEndpointStatistics_should_save_statistics()
        {
            var repository = new Mock<IEndpointStatsRepository>();
            var monitorSettings = new Mock<IMonitorSettings>();
            var endpointMetricsCoordinator = new Mock<IEndpointMetricsForwarderCoordinator>();

            var endpointHealth = new EndpointHealth(DateTime.UtcNow, TimeSpan.Zero, EndpointStatus.Offline);
            var endpointId = Guid.NewGuid();
            var endpoint = new Endpoint(TimeCoordinatorMock.Get().Object, new EndpointIdentity(endpointId, "type", "address"), new EndpointMetadata("name", "group", null, EndpointMetadata.DefaultMonitorTag, DateTime.UtcNow, DateTime.UtcNow));

            using (var manager = new EndpointStatsManager(repository.Object, monitorSettings.Object, TimeCoordinatorMock.Get().Object, endpointMetricsCoordinator.Object))
            {
                manager.RecordEndpointStatistics(endpoint.Identity, endpoint.Metadata, endpointHealth);
            }

            repository.Verify(r => r.InsertEndpointStatistics(endpointId, endpointHealth));
        }
コード例 #17
0
        public void UpdateHealth_should_not_update_health_if_already_have_more_recent_result()
        {
            var expectedLastModifiedTime1 = DateTime.UtcNow;
            var expectedLastModifiedTime2 = DateTime.UtcNow.AddMinutes(1);

            var endpoint = new Endpoint(_timeCoordinator.Object, new EndpointIdentity(Guid.NewGuid(), "monitor", "address"), new EndpointMetadata("name", "group", null, EndpointMetadata.DefaultMonitorTag, DateTime.UtcNow, DateTime.UtcNow));
            var newHealth = new EndpointHealth(DateTime.UtcNow, TimeSpan.Zero, EndpointStatus.Healthy);
            var oldHealth = new EndpointHealth(DateTime.UtcNow.AddSeconds(-1), TimeSpan.Zero, EndpointStatus.Healthy);

            _timeCoordinator.Setup(c => c.UtcNow).Returns(expectedLastModifiedTime1);
            endpoint.UpdateHealth(newHealth);

            _timeCoordinator.Setup(c => c.UtcNow).Returns(expectedLastModifiedTime2);
            endpoint.UpdateHealth(oldHealth);

            Assert.Same(newHealth, endpoint.Health);
            Assert.Equal(expectedLastModifiedTime1, endpoint.LastModifiedTimeUtc);
        }
コード例 #18
0
        public void CheckHealth_should_update_the_endpoint_with_its_health_status(HealthStatus healthStatus)
        {
            var tokenSource = new CancellationTokenSource();
            var healthInfo = new HealthInfo(healthStatus, TimeSpan.FromSeconds(1), new Dictionary<string, string> { { "property1", "value1" }, { "property2", "value2" } });
            var monitor = MonitorMock.GetMock("monitor");
            monitor.Setup(x => x.CheckHealthAsync("address", It.IsAny<CancellationToken>())).Returns(Task.FromResult(healthInfo));

            var endpoint = new Endpoint(Guid.NewGuid(), monitor.Object, "address", "name", "group");

            endpoint.CheckHealth(tokenSource.Token, MonitorSettingsHelper.ConfigureDefaultSettings()).Wait();

            var health = endpoint.Health;
            Assert.NotNull(health);
            Assert.Equal(healthInfo.ResponseTime, health.ResponseTime);
            Assert.Equal(healthInfo.Status.ToString(), health.Status.ToString());
            Assert.True(DateTime.UtcNow - health.CheckTimeUtc < TimeSpan.FromMilliseconds(500), "CheckTimeUtc should be captured");
            Assert.Equal(healthInfo.Details, health.Details);
        }
コード例 #19
0
 public EndpointDetails(Endpoint endpoint)
 {
     Id = endpoint.Id;
     Name = endpoint.Name;
     Address = endpoint.Address;
     MonitorType = endpoint.MonitorType;
     Group = endpoint.Group;
     if (endpoint.Health != null)
     {
         Status = endpoint.Health.Status;
         LastCheckUtc = endpoint.Health.CheckTimeUtc;
         LastResponseTime = endpoint.Health.ResponseTime;
         Details = endpoint.Health.Details.ToDictionary(p => p.Key, p => p.Value);
     }
     else
     {
         Details = new Dictionary<string, string>();
         Status = EndpointStatus.NotRun;
     }
 }
コード例 #20
0
        public void CheckHealth_should_update_the_endpoint_with_Faulty_status_if_monitor_fails()
        {
            var tokenSource = new CancellationTokenSource();
            var monitor = MonitorMock.GetMock("monitor");
            var exception = new Exception("some error");
            monitor.Setup(x => x.CheckHealthAsync("address", It.IsAny<CancellationToken>())).Throws(exception);

            var endpoint = new Endpoint(Guid.NewGuid(), monitor.Object, "address", "name", "group");
            endpoint.CheckHealth(tokenSource.Token, MonitorSettingsHelper.ConfigureDefaultSettings()).Wait();

            var expectedDetails = new Dictionary<string, string>
            {
                { "reason", exception.Message },
                { "exception", exception.ToString() }
            };

            var health = endpoint.Health;
            Assert.NotNull(health);
            Assert.Equal(EndpointStatus.Faulty, health.Status);
            Assert.True(DateTime.UtcNow - health.CheckTimeUtc < TimeSpan.FromMilliseconds(500), "CheckTimeUtc should be captured");
            Assert.Equal(TimeSpan.Zero, health.ResponseTime);
            Assert.Equal(expectedDetails, health.Details);
        }
コード例 #21
0
        private async Task<HealthInfo> ConfigureTimeoutTask(Endpoint endpoint, CancellationToken cancellationToken)
        {
            if (RequiresShortTimeout(endpoint))
            {
                await Task.Delay(_settings.ShortTimeOut, cancellationToken);
                return new HealthInfo(HealthStatus.TimedOut, TimeoutDetails);
            }

            await Task.Delay(_settings.FailureTimeOut, cancellationToken);
            return new HealthInfo(HealthStatus.Faulty, TimeoutDetails);
        }
コード例 #22
0
 private async Task<Endpoint> CreateTaskFor(Endpoint endpoint)
 {
     await Task.Delay(GetRandomizedDelay());
     while (!_cancellation.IsCancellationRequested && !endpoint.IsDisposed)
     {
         var delay = Task.Delay(_settings.HealthCheckInterval);
         await endpoint.CheckHealth(_sampler, _cancellation.Token);
         await delay;
     }
     return endpoint;
 }
コード例 #23
0
 private void HandleNewEndpoint(Endpoint endpoint)
 {
     if (_tasks.TryAdd(endpoint, CreateTaskFor(endpoint)))
         _onNewTask.Set();
 }
コード例 #24
0
        public void GetEndpoint_should_return_endpoint_information_with_details(HealthStatus status)
        {
            Guid id = Guid.NewGuid();
            var monitor = MonitorMock.GetMock("monitor");
            var healthInfo = new HealthInfo(status, TimeSpan.FromSeconds(2), new Dictionary<string, string> { { "a", "b" }, { "c", "d" } });
            monitor.Setup(p => p.CheckHealthAsync("address", It.IsAny<CancellationToken>())).Returns(Task.FromResult(healthInfo));

            var endpoint = new Endpoint(id, monitor.Object, "address", "name", "group");
            endpoint.CheckHealth(new CancellationToken(), MonitorSettingsHelper.ConfigureDefaultSettings()).Wait();
            _endpointRegistry.Setup(r => r.GetById(id)).Returns(endpoint);

            var result = _controller.GetEndpoint(id) as OkNegotiatedContentResult<EndpointDetails>;
            Assert.NotNull(result);
            AssertEndpoint(endpoint, result.Content);

            Assert.Equal(status.ToString(), result.Content.Status.ToString());
            Assert.NotNull(result.Content.LastCheckUtc);
            Assert.Equal(healthInfo.ResponseTime, result.Content.LastResponseTime);
            Assert.Equal(healthInfo.Details, result.Content.Details);
        }
コード例 #25
0
 private static bool RequiresShortTimeout(Endpoint endpoint)
 {
     return endpoint.Health == null ||
            (endpoint.Health.Status == EndpointStatus.Healthy || endpoint.Health.Status == EndpointStatus.NotRun ||
             endpoint.Health.Status == EndpointStatus.Offline || endpoint.Health.Status == EndpointStatus.NotExists);
 }
コード例 #26
0
 private static void AssertEndpoint(Endpoint expected, EndpointDetails actual)
 {
     Assert.Equal(expected.MonitorType, actual.MonitorType);
     Assert.Equal(expected.Address, actual.Address);
     Assert.Equal(expected.Name, actual.Name);
     Assert.Equal(expected.Group, actual.Group);
     Assert.Equal(expected.Id, actual.Id);
 }
コード例 #27
0
 private static void LogHealthStatus(Endpoint endpoint, EndpointHealth endpointHealth)
 {
     switch (endpointHealth.Status)
     {
         case EndpointStatus.TimedOut:
         case EndpointStatus.Unhealthy:
             Logger.WarnFormat("Status of {0}: Status={1}, ResponseTime={2}", endpoint, endpointHealth.Status, endpointHealth.ResponseTime);
             break;
         case EndpointStatus.Faulty:
             Logger.ErrorFormat("Status of {0}: Status={1}, ResponseTime={2}, Details={3}", endpoint, endpointHealth.Status, endpointHealth.ResponseTime, endpointHealth.PrettyFormatDetails());
             break;
         default:
             Logger.InfoFormat("Status of {0}: Status={1}, ResponseTime={2}", endpoint, endpointHealth.Status, endpointHealth.ResponseTime);
             break;
     }
 }
コード例 #28
0
        private Func<Endpoint, CancellationToken, Task> CaptureGuardTask(Endpoint endpoint)
        {
            _endpointRegistry.Setup(r => r.Endpoints).Returns(Enumerable.Repeat(endpoint, 1));

            Func<Endpoint, CancellationToken, Task> capturedTaskFactory = null;
            _taskExecutor.Setup(e => e.TryRegisterTaskFor(endpoint, It.IsAny<Func<Endpoint, CancellationToken, Task>>()))
                .Returns((Endpoint e, Func<Endpoint, CancellationToken, Task> taskFactory) =>
                {
                    capturedTaskFactory = taskFactory;
                    return true;
                });

            using (CreateGuard()) { }
            Assert.True(capturedTaskFactory != null, "It should capture monitor task");
            return capturedTaskFactory;
        }
コード例 #29
0
 private void VerifyTaskWasRegisteredForEndpointInGuard(Endpoint endpoint, Func<Times> times)
 {
     _taskExecutor.Verify(e => e.TryRegisterTaskFor(endpoint, It.IsAny<Func<Endpoint, CancellationToken, Task>>()), times);
 }
コード例 #30
0
 private TimeSpan GetTimeSpanSinceLastEndpointUpdate(Endpoint endpoint)
 {
     return _timeCoordinator.Object.UtcNow - (endpoint.Health?.CheckTimeUtc ?? endpoint.LastModifiedTimeUtc);
 }