Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue#369 add health probe for sub services #503

Merged
merged 3 commits into from
Mar 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public async Task UpdateShouldCreateNewEntity()
It.IsAny<int?>(),
It.IsAny<IEnumerable<string>>(),
It.IsAny<CancellationToken>()))
.Returns(Pageable<TableEntity>.FromPages(new[] {
.Returns(Pageable<TableEntity>.FromPages(new[] {
Page<TableEntity>.FromValues(new[]
{
new TableEntity(DeviceTagService.DefaultPartitionKey,tag.Name)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace AzureIoTHub.Portal.Server.Tests.Unit.ServicesHealthCheck
{
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using AzureIoTHub.Portal.Server.ServicesHealthCheck;
using Microsoft.Azure.Devices;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Moq;
using NUnit.Framework;

[TestFixture]
public class IoTHubHealthCheckTest
{
private MockRepository mockRepository;

private Mock<RegistryManager> mockRegistryManager;
private Mock<ServiceClient> mockServiceClient;

[SetUp]
public void SetUp()
{
this.mockRepository = new MockRepository(MockBehavior.Strict);

this.mockRegistryManager = this.mockRepository.Create<RegistryManager>();
this.mockServiceClient = this.mockRepository.Create<ServiceClient>();
}

private IoTHubHealthCheck CreateHealthCheck()
{
return new IoTHubHealthCheck(this.mockRegistryManager.Object, this.mockServiceClient.Object);
}

[Test]
public async Task CheckHealthAsyncStateUnderTestExpectedBehavior()
{
// Arrange
var healthService = CreateHealthCheck();

var mockServiceStat = this.mockRepository.Create<ServiceStatistics>();
var mockQuery = this.mockRepository.Create<IQuery>();

var healthCheckContext = new HealthCheckContext();
var token = new CancellationToken(canceled:false);

_ = mockQuery.Setup(c => c.GetNextAsJsonAsync())
.ReturnsAsync(new string[]
{
/*lang=json*/
"{ $0: 2}"
});

_ = this.mockServiceClient
.Setup(c => c.GetServiceStatisticsAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(mockServiceStat.Object);

_ = this.mockRegistryManager
.Setup(c => c.CreateQuery(It.Is<string>(x => x == "SELECT count() FROM devices")))
.Returns(mockQuery.Object);

// Act
var result = await healthService.CheckHealthAsync(healthCheckContext, token);

// Assert
Assert.IsNotNull(result);
Assert.AreEqual(HealthStatus.Healthy, result.Status);
}

[Test]
public async Task CheckHealthAsyncThrowExceptionReturnUnHealthy()
{
// Arrange
var healthService = CreateHealthCheck();

var mockServiceStat = this.mockRepository.Create<ServiceStatistics>();
var mockQuery = this.mockRepository.Create<IQuery>();

var healthRegistration = new HealthCheckRegistration(Guid.NewGuid().ToString(), healthService, HealthStatus.Unhealthy, new List<string>());

var healthCheckContext = new HealthCheckContext()
{
Registration = healthRegistration
};
var token = new CancellationToken(canceled:false);

_ = mockQuery.Setup(c => c.GetNextAsJsonAsync())
.ReturnsAsync(new string[]
{
/*lang=json*/
"{ $0: 2}"
});

_ = this.mockServiceClient
.Setup(c => c.GetServiceStatisticsAsync(It.IsAny<CancellationToken>()))
.Throws(exception: new SystemException("test"));

_ = this.mockRegistryManager
.Setup(c => c.CreateQuery(It.Is<string>(x => x == "SELECT count() FROM devices")))
.Returns(mockQuery.Object);

// Act
var result = await healthService.CheckHealthAsync(healthCheckContext, token);

// Assert
Assert.IsNotNull(result);
Assert.AreEqual(HealthStatus.Unhealthy, result.Status);
}

[Test]
public async Task CheckHealthAsyncWithNullQueryReturnUnHealthy()
{
// Arrange
var healthService = CreateHealthCheck();

var mockServiceStat = this.mockRepository.Create<ServiceStatistics>();
var mockQuery = this.mockRepository.Create<IQuery>();

var healthRegistration = new HealthCheckRegistration(Guid.NewGuid().ToString(), healthService, HealthStatus.Unhealthy, new List<string>());

var healthCheckContext = new HealthCheckContext()
{
Registration = healthRegistration
};
var token = new CancellationToken(canceled:false);

_ = mockQuery.Setup(c => c.GetNextAsJsonAsync())
.ReturnsAsync(new string[]
{
/*lang=json*/
"{ $0: 2}"
});

_ = this.mockServiceClient
.Setup(c => c.GetServiceStatisticsAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(mockServiceStat.Object);

_ = this.mockRegistryManager
.Setup(c => c.CreateQuery(It.Is<string>(x => x == "SELECT count() FROM devices")))
.Returns(value: null);

// Act
var result = await healthService.CheckHealthAsync(healthCheckContext, token);

// Assert
Assert.IsNotNull(result);
Assert.AreEqual(HealthStatus.Unhealthy, result.Status);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace AzureIoTHub.Portal.Server.Tests.Unit.ServicesHealthCheck
{
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using AzureIoTHub.Portal.Server.Managers;
using AzureIoTHub.Portal.Server.ServicesHealthCheck;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Moq;
using NUnit.Framework;

[TestFixture]
public class LoRaManagementKeyFacadeHealthCheckTest
{
private MockRepository mockRepository;
private Mock<ILoraDeviceMethodManager> mockoraDeviceMethodManager;

[SetUp]
public void SetUp()
{
this.mockRepository = new MockRepository(MockBehavior.Strict);

this.mockoraDeviceMethodManager = this.mockRepository.Create<ILoraDeviceMethodManager>();
}

private LoRaManagementKeyFacadeHealthCheck CreateService()
{
return new LoRaManagementKeyFacadeHealthCheck(this.mockoraDeviceMethodManager.Object);
}

[Test]
public async Task CheckHealthAsyncStateUnderTestReturnHealthy()
{
// Arrange
var healthService = CreateService();

var healthCheckContext = new HealthCheckContext();
var token = new CancellationToken(canceled:false);

var mockHttpMessage = this.mockRepository.Create<HttpResponseMessage>(System.Net.HttpStatusCode.OK);

_ = this.mockoraDeviceMethodManager
.Setup(c => c.CheckAzureFunctionReturn(It.IsAny<CancellationToken>()))
.ReturnsAsync(mockHttpMessage.Object);

// Act
var result = await healthService.CheckHealthAsync(healthCheckContext, token);

// Assert
Assert.IsNotNull(result);
Assert.AreEqual(HealthStatus.Healthy, result.Status);
}

[Test]
public async Task CheckHealthAsyncStateUnderTestReturnUnhealthy()
{
// Arrange
var healthService = CreateService();

var healthRegistration = new HealthCheckRegistration(Guid.NewGuid().ToString(), healthService, HealthStatus.Unhealthy, new List<string>());
var healthCheckContext = new HealthCheckContext()
{
Registration = healthRegistration
};
var token = new CancellationToken(canceled:false);

var mockHttpMessage = this.mockRepository.Create<HttpResponseMessage>(System.Net.HttpStatusCode.BadRequest);

_ = this.mockoraDeviceMethodManager
.Setup(c => c.CheckAzureFunctionReturn(It.IsAny<CancellationToken>()))
.ReturnsAsync(mockHttpMessage.Object);

// Act
var result = await healthService.CheckHealthAsync(healthCheckContext, token);

// Assert
Assert.IsNotNull(result);
Assert.AreEqual(HealthStatus.Unhealthy, result.Status);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright (c) CGI France. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace AzureIoTHub.Portal.Server.Tests.Unit.ServicesHealthCheck
{
using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using AzureIoTHub.Portal.Server.ServicesHealthCheck;
using AzureIoTHub.Portal.Server.Wrappers;
using Microsoft.Azure.Devices.Provisioning.Service;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Moq;
using NUnit.Framework;

[TestFixture]
public class ProvisioningServiceClientHealthCheckTest
{
private MockRepository mockRepository;
private Mock<IProvisioningServiceClient> mockDps;

[SetUp]
public void SetUp()
{
this.mockRepository = new MockRepository(MockBehavior.Strict);

this.mockDps = this.mockRepository.Create<IProvisioningServiceClient>();
}

private ProvisioningServiceClientHealthCheck CreateHealthService()
{
return new ProvisioningServiceClientHealthCheck(this.mockDps.Object);
}

//[Test]
//public async Task CheckHealthAsyncStateUnderTestReturnHealthy()
//{
// // Arrange
// var healthService = CreateHealthService();

// var healthCheckContext = new HealthCheckContext();
// var token = new CancellationToken(canceled:false);

// var attestation = new SymmetricKeyAttestation(GenerateKey(), GenerateKey());
// var enrollmentGroup = new EnrollmentGroup("enrollmentId", attestation);

// _ = this.mockDps
// .Setup(c => c.CreateOrUpdateEnrollmentGroupAsync(It.IsAny<EnrollmentGroup>()))
// .ReturnsAsync(enrollmentGroup);

// _ = this.mockDps
// .Setup(c => c.GetEnrollmentGroupAsync(It.IsAny<string>()))
// .ReturnsAsync(enrollmentGroup);

// _ = this.mockDps
// .Setup(c => c.DeleteEnrollmentGroupAsync(It.IsAny<EnrollmentGroup>(), It.IsAny<CancellationToken>()));

// // Act
// var result = await healthService.CheckHealthAsync(healthCheckContext, token);

// // Assert
// Assert.IsNotNull(result);
// Assert.AreEqual(HealthStatus.Healthy, result.Status);
//}

[Test]
public async Task CheckHealthAsyncStateUnderTestReturnUnhealthy()
{
// Arrange
var healthService = CreateHealthService();

var healthRegistration = new HealthCheckRegistration(Guid.NewGuid().ToString(), healthService, HealthStatus.Unhealthy, new List<string>());
var healthCheckContext = new HealthCheckContext()
{
Registration = healthRegistration
};
var token = new CancellationToken(canceled:false);

var attestation = new SymmetricKeyAttestation(GenerateKey(), GenerateKey());
var enrollmentGroup = new EnrollmentGroup("enrollmentId", attestation);

_ = this.mockDps
.Setup(c => c.CreateOrUpdateEnrollmentGroupAsync(It.IsAny<EnrollmentGroup>()))
.Throws(new Exception());

_ = this.mockDps
.Setup(c => c.GetEnrollmentGroupAsync(It.IsAny<string>()))
.ReturnsAsync(enrollmentGroup);

_ = this.mockDps
.Setup(c => c.DeleteEnrollmentGroupAsync(It.IsAny<EnrollmentGroup>(), It.IsAny<CancellationToken>()));

// Act
var result = await healthService.CheckHealthAsync(healthCheckContext, token);

// Assert
Assert.IsNotNull(result);
Assert.AreEqual(HealthStatus.Unhealthy, result.Status);
}

private static string GenerateKey()
{
const int length = 48;
var rnd = RandomNumberGenerator.GetBytes(length);

return Convert.ToBase64String(rnd);
}

}
}
Loading