Skip to content
Draft
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 @@ -17,23 +17,34 @@
[TestFixture]
public class HeartbeatEndpointSettingsSyncHostedServiceTests
{

static async Task WaitUntilAsync(Func<bool> condition, TimeSpan? timeout = null)
{
var deadline = DateTime.UtcNow + (timeout ?? TimeSpan.FromSeconds(10));
while (!condition() && DateTime.UtcNow < deadline)
{
await Task.Delay(20);
}
}

[Test]
public async Task Should_handle_cancellation_token_gracefully()
{
using var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
CancellationToken token = tokenSource.Token;
var fakeTimeProvider = new FakeTimeProvider();
var mockEndpointInstanceMonitoring = new MockEndpointInstanceMonitoring([]);
var service = new HeartbeatEndpointSettingsSyncHostedService(
new MockMonitoringDataStore([]),
new MockEndpointSettingsStore([]),
new MockEndpointInstanceMonitoring([]), new Settings { TrackInstancesInitialValue = true },
mockEndpointInstanceMonitoring, new Settings { TrackInstancesInitialValue = true },
fakeTimeProvider, NullLogger<HeartbeatEndpointSettingsSyncHostedService>.Instance)
{
DelayStart = TimeSpan.Zero
};

await service.StartAsync(token);
await Task.Delay(TimeSpan.FromSeconds(2), token);
await WaitUntilAsync(() => mockEndpointInstanceMonitoring.GetEndpointsCallCount >= 1);
await service.StopAsync(token);

Assert.That(service.ExecuteTask?.IsCompletedSuccessfully, Is.True);
Expand All @@ -59,7 +70,7 @@ public async Task Should_delete_settings_from_endpoints_that_are_no_longer_live(
};

await service.StartAsync(token);
await Task.Delay(TimeSpan.FromSeconds(2), token);
await WaitUntilAsync(() => mockEndpointSettingsStore.Deleted.Count >= 2);
await service.StopAsync(token);

Assert.That(mockEndpointSettingsStore.Deleted.Count, Is.EqualTo(2));
Expand All @@ -86,7 +97,7 @@ public async Task Should_set_the_default_for_settings_if_does_not_exist_already(
};

await service.StartAsync(token);
await Task.Delay(TimeSpan.FromSeconds(2), token);
await WaitUntilAsync(() => mockEndpointSettingsStore.Updated.Count >= 1);
await service.StopAsync(token);

Assert.That(mockEndpointSettingsStore.Updated.Count, Is.EqualTo(1));
Expand All @@ -106,19 +117,20 @@ public async Task Should_not_set_the_default_if_already_exists()
var mockEndpointSettingsStore = new MockEndpointSettingsStore([
new EndpointSettings { Name = string.Empty, TrackInstances = expectedTrackInstancesInitialValue }
]);
var mockEndpointInstanceMonitoring = new MockEndpointInstanceMonitoring([]);
var service = new HeartbeatEndpointSettingsSyncHostedService(
new MockMonitoringDataStore(
[]),
mockEndpointSettingsStore,
new MockEndpointInstanceMonitoring([]),
mockEndpointInstanceMonitoring,
new Settings { TrackInstancesInitialValue = expectedTrackInstancesInitialValue },
fakeTimeProvider, NullLogger<HeartbeatEndpointSettingsSyncHostedService>.Instance)
{
DelayStart = TimeSpan.Zero
};

await service.StartAsync(token);
await Task.Delay(TimeSpan.FromSeconds(2), token);
await WaitUntilAsync(() => mockEndpointInstanceMonitoring.GetEndpointsCallCount >= 1);
await service.StopAsync(token);

Assert.That(mockEndpointSettingsStore.Updated.Count, Is.EqualTo(0));
Expand Down Expand Up @@ -158,7 +170,7 @@ public async Task
};

await service.StartAsync(token);
await Task.Delay(TimeSpan.FromSeconds(2), token);
await WaitUntilAsync(() => mockMonitoringDataStore.Deleted.Count >= 2);
await service.StopAsync(token);

Assert.That(mockMonitoringDataStore.Deleted.Count, Is.EqualTo(2));
Expand Down Expand Up @@ -197,7 +209,7 @@ public async Task
};

await service.StartAsync(token);
await Task.Delay(TimeSpan.FromSeconds(2), token);
await WaitUntilAsync(() => mockEndpointInstanceMonitoring.GetEndpointsCallCount >= 1);
await service.StopAsync(token);

Assert.That(mockMonitoringDataStore.Deleted.Count, Is.EqualTo(0));
Expand All @@ -220,7 +232,16 @@ public void DetectEndpointFromPersistentStore(EndpointDetails endpointDetails, b

public Task EndpointDetected(EndpointDetails newEndpointDetails, CancellationToken cancellationToken = default) => throw new NotImplementedException();

public EndpointsView[] GetEndpoints() => endpointsViews;
public EndpointsView[] GetEndpoints()
{
GetEndpointsCallCount++;
return endpointsViews;
}

// GetEndpoints() is called by PurgeMonitoringDataThatDoesNotNeedToBeTracked, which runs
// at the end of each sync cycle. Waiting for this to be invoked gives a deterministic
// signal that a full sync cycle has completed, without relying on a fixed wall-clock delay.
public int GetEndpointsCallCount { get; private set; }

public List<KnownEndpointsView> GetKnownEndpoints() => throw new NotImplementedException();

Expand Down
Loading