Skip to content
This repository was archived by the owner on Mar 16, 2021. It is now read-only.

Commit

Permalink
Fix a flaky test that depends on real system time
Browse files Browse the repository at this point in the history
  • Loading branch information
joelverhagen committed May 24, 2019
1 parent 9b4edff commit 3d2160d
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,11 @@
<Compile Include="Wrappers\IndexesOperationsWrapper.cs" />
<Compile Include="Wrappers\ISearchIndexClientWrapper.cs" />
<Compile Include="Wrappers\ISearchServiceClientWrapper.cs" />
<Compile Include="Wrappers\ISystemTime.cs" />
<Compile Include="Wrappers\SearchIndexClientWrapper.cs" />
<Compile Include="Wrappers\SearchServiceClientWrapper.cs" />
<Compile Include="SearchService\SearchServiceConfiguration.cs" />
<Compile Include="Wrappers\SystemTime.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MicroBuild.Core">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<SearchServiceConfiguration> _options;
private readonly ILogger<AuxiliaryFileReloader> _logger;

public AuxiliaryFileReloader(
IAuxiliaryDataCache cache,
ISystemTime systemTime,
IOptionsSnapshot<SearchServiceConfiguration> options,
ILogger<AuxiliaryFileReloader> 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));
}
Expand All @@ -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;
}
Expand All @@ -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);
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions src/NuGet.Services.AzureSearch/Wrappers/ISystemTime.cs
Original file line number Diff line number Diff line change
@@ -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
{
/// <summary>
/// A wrapper that allows for unit tests related to system time.
/// </summary>
public interface ISystemTime
{
Task Delay(TimeSpan delay);
Task Delay(TimeSpan delay, CancellationToken token);
}
}
22 changes: 22 additions & 0 deletions src/NuGet.Services.AzureSearch/Wrappers/SystemTime.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<CancellationToken>()), 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<TimeSpan>(), It.IsAny<CancellationToken>()), Times.Once);
}

[Fact]
Expand All @@ -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<CancellationToken>()), 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<TimeSpan>(), It.IsAny<CancellationToken>()), Times.Once);
}
}

public abstract class BaseFacts
{
protected readonly Mock<IAuxiliaryDataCache> _cache;
protected readonly Mock<ISystemTime> _systemTime;
protected readonly SearchServiceConfiguration _config;
protected readonly Mock<IOptionsSnapshot<SearchServiceConfiguration>> _options;
protected readonly RecordingLogger<AuxiliaryFileReloader> _logger;
Expand All @@ -98,6 +98,7 @@ public abstract class BaseFacts
public BaseFacts(ITestOutputHelper output)
{
_cache = new Mock<IAuxiliaryDataCache>();
_systemTime = new Mock<ISystemTime>();
_config = new SearchServiceConfiguration();
_options = new Mock<IOptionsSnapshot<SearchServiceConfiguration>>();
_logger = output.GetLogger<AuxiliaryFileReloader>();
Expand All @@ -114,6 +115,7 @@ public BaseFacts(ITestOutputHelper output)

_target = new AuxiliaryFileReloader(
_cache.Object,
_systemTime.Object,
_options.Object,
_logger);
}
Expand Down

0 comments on commit 3d2160d

Please sign in to comment.