Skip to content

Commit

Permalink
table storage healthchecks
Browse files Browse the repository at this point in the history
  • Loading branch information
Oleksandr Kyselov committed Aug 8, 2024
1 parent fa8a0d1 commit 5665fdc
Showing 1 changed file with 57 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Azure;
using Azure.Data.Tables;
using Azure.Data.Tables.Models;
using Microsoft.AspNetCore.Mvc.RazorPages;
using NSubstitute;
using NSubstitute.ExceptionExtensions;

Expand Down Expand Up @@ -55,36 +56,26 @@ public async Task return_healthy_when_only_checking_healthy_service()
}

[Fact]
public async Task return_healthy_when_checking_healthy_service_and_table()
public async Task return_healthy_when_checking_healthy_service_table()
{
using var tokenSource = new CancellationTokenSource();

_tableServiceClient
.QueryAsync(filter: "false", cancellationToken: tokenSource.Token)
.Returns(AsyncPageable<TableItem>.FromPages(Array.Empty<Page<TableItem>>()));

_tableClient
.QueryAsync<TableEntity>(filter: "false", cancellationToken: tokenSource.Token)
.Returns(AsyncPageable<TableEntity>.FromPages(Array.Empty<Page<TableEntity>>()));

_options.TableName = TableName;
var actual = await _healthCheck.CheckHealthAsync(_context, tokenSource.Token);

_tableServiceClient
.Received(1)
.QueryAsync(filter: "false", cancellationToken: tokenSource.Token);

_tableClient
.Received(1)
.QueryAsync<TableEntity>(filter: "false", cancellationToken: tokenSource.Token);

actual.Status.ShouldBe(HealthStatus.Healthy);
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public async Task return_unhealthy_when_checking_unhealthy_service(bool checkTable)
[Fact]
public async Task return_unhealthy_when_checking_unhealthy_service()
{
using var tokenSource = new CancellationTokenSource();

Expand All @@ -103,7 +94,6 @@ public async Task return_unhealthy_when_checking_unhealthy_service(bool checkTab
.MoveNextAsync()
.ThrowsAsync(new RequestFailedException((int)HttpStatusCode.Unauthorized, "Unable to authorize access."));

_options.TableName = checkTable ? TableName : null;
var actual = await _healthCheck.CheckHealthAsync(_context, tokenSource.Token);

_tableServiceClient
Expand All @@ -129,47 +119,44 @@ await enumerator
}

[Fact]
public async Task return_unhealthy_when_checking_unhealthy_container()
public async Task return_unhealthy_when_checking_unhealthy_service_queue()
{
using var tokenSource = new CancellationTokenSource();

var pageable = Substitute.For<AsyncPageable<TableEntity>>();
var enumerator = Substitute.For<IAsyncEnumerator<TableEntity>>();

_tableServiceClient
.QueryAsync(filter: "false", cancellationToken: tokenSource.Token)
.Returns(AsyncPageable<TableItem>.FromPages(Array.Empty<Page<TableItem>>()));

_tableClient
.QueryAsync<TableEntity>(filter: "false", cancellationToken: tokenSource.Token)
.Returns(pageable);
.Throws(new RequestFailedException((int)HttpStatusCode.Unauthorized, "Unable to authorize access."));

pageable
.GetAsyncEnumerator(tokenSource.Token)
.Returns(enumerator);

enumerator
.MoveNextAsync()
.ThrowsAsync(new RequestFailedException((int)HttpStatusCode.NotFound, "Table not found"));

_options.TableName = TableName;
var actual = await _healthCheck.CheckHealthAsync(_context, tokenSource.Token);

_tableServiceClient
.Received(1)
.QueryAsync(filter: "false", cancellationToken: tokenSource.Token);

_tableClient
.Received(1)
.QueryAsync<TableEntity>(filter: "false", cancellationToken: tokenSource.Token);

pageable
.Received(1)
.GetAsyncEnumerator(tokenSource.Token);
actual.Status.ShouldBe(HealthStatus.Unhealthy);
actual
.Exception!.ShouldBeOfType<RequestFailedException>()
.Status.ShouldBe((int)HttpStatusCode.Unauthorized);
}

await enumerator
[Fact]
public async Task return_unhealthy_when_checking_unhealthy_table()
{
using var tokenSource = new CancellationTokenSource();

_tableClient
.QueryAsync<TableEntity>(filter: "false", cancellationToken: tokenSource.Token)
.Throws(new RequestFailedException((int)HttpStatusCode.NotFound, "Table not found"));

_options.TableName = TableName;
var actual = await _healthCheck.CheckHealthAsync(_context, tokenSource.Token);

_tableClient
.Received(1)
.MoveNextAsync();
.QueryAsync<TableEntity>(filter: "false", cancellationToken: tokenSource.Token);


actual.Status.ShouldBe(HealthStatus.Unhealthy);
actual
Expand All @@ -184,19 +171,15 @@ public async Task return_unhealthy_when_invoked_from_healthcheckservice()
.AddSingleton(_tableServiceClient)
.AddLogging()
.AddHealthChecks()
.AddAzureTable(optionsFactory: _ => new AzureTableServiceHealthCheckOptions() { TableName = TableName }, name: HealthCheckName)
.AddAzureTable(optionsFactory: _ => new AzureTableServiceHealthCheckOptions(), name: HealthCheckName)
.Services
.BuildServiceProvider();

var pageable = Substitute.For<AsyncPageable<TableEntity>>();
var enumerator = Substitute.For<IAsyncEnumerator<TableEntity>>();
var pageable = Substitute.For<AsyncPageable<TableItem>>();
var enumerator = Substitute.For<IAsyncEnumerator<TableItem>>();

_tableServiceClient
.QueryAsync(filter: "false", cancellationToken: Arg.Any<CancellationToken>())
.Returns(AsyncPageable<TableItem>.FromPages(Array.Empty<Page<TableItem>>()));

_tableClient
.QueryAsync<TableEntity>(filter: "false", cancellationToken: Arg.Any<CancellationToken>())
.Returns(pageable);

pageable
Expand All @@ -214,10 +197,6 @@ public async Task return_unhealthy_when_invoked_from_healthcheckservice()
.Received(1)
.QueryAsync(filter: "false", cancellationToken: Arg.Any<CancellationToken>());

_tableClient
.Received(1)
.QueryAsync<TableEntity>(filter: "false", cancellationToken: Arg.Any<CancellationToken>());

pageable
.Received(1)
.GetAsyncEnumerator(Arg.Any<CancellationToken>());
Expand All @@ -230,4 +209,32 @@ await enumerator
actual.Status.ShouldBe(HealthStatus.Unhealthy);
actual.Exception!.ShouldBeOfType<RequestFailedException>();
}


[Fact]
public async Task return_unhealthy_when_invoked_from_healthcheckservice_for_table()
{
using var provider = new ServiceCollection()
.AddSingleton(_tableServiceClient)
.AddLogging()
.AddHealthChecks()
.AddAzureTable(optionsFactory: _ => new AzureTableServiceHealthCheckOptions() { TableName = TableName }, name: HealthCheckName)
.Services
.BuildServiceProvider();

_tableClient
.QueryAsync<TableEntity>(filter: "false", cancellationToken: Arg.Any<CancellationToken>())
.Throws(new RequestFailedException((int)HttpStatusCode.NotFound, "Table not found"));

var service = provider.GetRequiredService<HealthCheckService>();
var report = await service.CheckHealthAsync();

_tableClient
.Received(1)
.QueryAsync<TableEntity>(filter: "false", cancellationToken: Arg.Any<CancellationToken>());

var actual = report.Entries[HealthCheckName];
actual.Status.ShouldBe(HealthStatus.Unhealthy);
actual.Exception!.ShouldBeOfType<RequestFailedException>();
}
}

0 comments on commit 5665fdc

Please sign in to comment.