diff --git a/src/NuGet.Services.AzureSearch/NuGet.Services.AzureSearch.csproj b/src/NuGet.Services.AzureSearch/NuGet.Services.AzureSearch.csproj
index 811747f86..805525192 100644
--- a/src/NuGet.Services.AzureSearch/NuGet.Services.AzureSearch.csproj
+++ b/src/NuGet.Services.AzureSearch/NuGet.Services.AzureSearch.csproj
@@ -192,9 +192,11 @@
+
+
diff --git a/src/NuGet.Services.AzureSearch/SearchService/AuxiliaryFileReloader.cs b/src/NuGet.Services.AzureSearch/SearchService/AuxiliaryFileReloader.cs
index 1aeda9382..a3948fe8f 100644
--- a/src/NuGet.Services.AzureSearch/SearchService/AuxiliaryFileReloader.cs
+++ b/src/NuGet.Services.AzureSearch/SearchService/AuxiliaryFileReloader.cs
@@ -6,21 +6,25 @@
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
+using NuGet.Services.AzureSearch.Wrappers;
namespace NuGet.Services.AzureSearch.SearchService
{
public class AuxiliaryFileReloader : IAuxiliaryFileReloader
{
private readonly IAuxiliaryDataCache _cache;
+ private readonly ISystemTime _systemTime;
private readonly IOptionsSnapshot _options;
private readonly ILogger _logger;
public AuxiliaryFileReloader(
IAuxiliaryDataCache cache,
+ ISystemTime systemTime,
IOptionsSnapshot options,
ILogger logger)
{
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
+ _systemTime = systemTime ?? throw new ArgumentNullException(nameof(systemTime));
_options = options ?? throw new ArgumentNullException(nameof(options));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
@@ -39,7 +43,7 @@ public async Task ReloadContinuouslyAsync(CancellationToken token)
}
catch (Exception ex)
{
- _logger.LogError((EventId)0, ex, "An exception was thrown while reloading the auxiliary data.");
+ _logger.LogError(0, ex, "An exception was thrown while reloading the auxiliary data.");
delay = _options.Value.AuxiliaryDataReloadFailureRetryFrequency;
}
@@ -52,7 +56,7 @@ public async Task ReloadContinuouslyAsync(CancellationToken token)
_logger.LogInformation(
"Waiting {Duration} before attempting to reload the auxiliary data again.",
delay);
- await Task.Delay(delay, token);
+ await _systemTime.Delay(delay, token);
}
}
}
diff --git a/src/NuGet.Services.AzureSearch/Wrappers/ISystemTime.cs b/src/NuGet.Services.AzureSearch/Wrappers/ISystemTime.cs
new file mode 100644
index 000000000..c30cb5f7f
--- /dev/null
+++ b/src/NuGet.Services.AzureSearch/Wrappers/ISystemTime.cs
@@ -0,0 +1,18 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace NuGet.Services.AzureSearch.Wrappers
+{
+ ///
+ /// A wrapper that allows for unit tests related to system time.
+ ///
+ public interface ISystemTime
+ {
+ Task Delay(TimeSpan delay);
+ Task Delay(TimeSpan delay, CancellationToken token);
+ }
+}
\ No newline at end of file
diff --git a/src/NuGet.Services.AzureSearch/Wrappers/SystemTime.cs b/src/NuGet.Services.AzureSearch/Wrappers/SystemTime.cs
new file mode 100644
index 000000000..f3e8e054e
--- /dev/null
+++ b/src/NuGet.Services.AzureSearch/Wrappers/SystemTime.cs
@@ -0,0 +1,22 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace NuGet.Services.AzureSearch.Wrappers
+{
+ public class SystemTime : ISystemTime
+ {
+ public async Task Delay(TimeSpan delay)
+ {
+ await Task.Delay(delay);
+ }
+
+ public async Task Delay(TimeSpan delay, CancellationToken token)
+ {
+ await Task.Delay(delay, token);
+ }
+ }
+}
diff --git a/tests/NuGet.Services.AzureSearch.Tests/SearchService/AuxiliaryFileReloaderFacts.cs b/tests/NuGet.Services.AzureSearch.Tests/SearchService/AuxiliaryFileReloaderFacts.cs
index 6423be8bf..0ae732af7 100644
--- a/tests/NuGet.Services.AzureSearch.Tests/SearchService/AuxiliaryFileReloaderFacts.cs
+++ b/tests/NuGet.Services.AzureSearch.Tests/SearchService/AuxiliaryFileReloaderFacts.cs
@@ -8,6 +8,7 @@
using Microsoft.Extensions.Options;
using Moq;
using NuGet.Services.AzureSearch.Support;
+using NuGet.Services.AzureSearch.Wrappers;
using Xunit;
using Xunit.Abstractions;
@@ -50,12 +51,11 @@ public async Task UsesReloadFrequencyOnSuccess()
_config.AuxiliaryDataReloadFrequency = TimeSpan.FromMilliseconds(100);
_config.AuxiliaryDataReloadFailureRetryFrequency = TimeSpan.Zero;
- var stopwatch = Stopwatch.StartNew();
await _target.ReloadContinuouslyAsync(_cts.Token);
- stopwatch.Stop();
_cache.Verify(x => x.TryLoadAsync(It.IsAny()), Times.Exactly(2));
- Assert.InRange(stopwatch.Elapsed, _config.AuxiliaryDataReloadFrequency, TimeSpan.FromHours(1));
+ _systemTime.Verify(x => x.Delay(_config.AuxiliaryDataReloadFrequency, _cts.Token), Times.Once);
+ _systemTime.Verify(x => x.Delay(It.IsAny(), It.IsAny()), Times.Once);
}
[Fact]
@@ -77,18 +77,18 @@ public async Task UsesReloadFailureRetryFrequencyOnSuccess()
_config.AuxiliaryDataReloadFrequency = TimeSpan.Zero;
_config.AuxiliaryDataReloadFailureRetryFrequency = TimeSpan.FromMilliseconds(100);
- var stopwatch = Stopwatch.StartNew();
await _target.ReloadContinuouslyAsync(_cts.Token);
- stopwatch.Stop();
_cache.Verify(x => x.TryLoadAsync(It.IsAny()), Times.Exactly(2));
- Assert.InRange(stopwatch.Elapsed, _config.AuxiliaryDataReloadFailureRetryFrequency, TimeSpan.FromHours(1));
+ _systemTime.Verify(x => x.Delay(_config.AuxiliaryDataReloadFailureRetryFrequency, _cts.Token), Times.Once);
+ _systemTime.Verify(x => x.Delay(It.IsAny(), It.IsAny()), Times.Once);
}
}
public abstract class BaseFacts
{
protected readonly Mock _cache;
+ protected readonly Mock _systemTime;
protected readonly SearchServiceConfiguration _config;
protected readonly Mock> _options;
protected readonly RecordingLogger _logger;
@@ -98,6 +98,7 @@ public abstract class BaseFacts
public BaseFacts(ITestOutputHelper output)
{
_cache = new Mock();
+ _systemTime = new Mock();
_config = new SearchServiceConfiguration();
_options = new Mock>();
_logger = output.GetLogger();
@@ -114,6 +115,7 @@ public BaseFacts(ITestOutputHelper output)
_target = new AuxiliaryFileReloader(
_cache.Object,
+ _systemTime.Object,
_options.Object,
_logger);
}