You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
71 lines
2.6 KiB
71 lines
2.6 KiB
using Bit.Infrastructure.EntityFramework; |
|
using Microsoft.Extensions.Caching.Distributed; |
|
using Microsoft.Extensions.Time.Testing; |
|
using Xunit; |
|
|
|
namespace Bit.Infrastructure.IntegrationTest; |
|
|
|
public class DistributedCacheTests |
|
{ |
|
[DatabaseTheory, DatabaseData(UseFakeTimeProvider = true)] |
|
public async Task Simple_NotExpiredItem_StartsScan(IDistributedCache cache, TimeProvider timeProvider) |
|
{ |
|
if (cache is not EntityFrameworkCache efCache) |
|
{ |
|
// We don't write the SqlServer cache implementation so we don't need to test it |
|
// also it doesn't use TimeProvider under the hood so we'd have to delay the test |
|
// for 30 minutes to get it to work. So just skip it. |
|
return; |
|
} |
|
|
|
var fakeTimeProvider = (FakeTimeProvider)timeProvider; |
|
|
|
cache.Set("test-key", "some-value"u8.ToArray(), new DistributedCacheEntryOptions |
|
{ |
|
SlidingExpiration = TimeSpan.FromMinutes(20), |
|
}); |
|
|
|
// Should have expired and not be returned |
|
var firstValue = cache.Get("test-key"); |
|
|
|
// Scan for expired items is supposed to run every 30 minutes |
|
fakeTimeProvider.Advance(TimeSpan.FromMinutes(31)); |
|
|
|
var secondValue = cache.Get("test-key"); |
|
|
|
// This should have forced the EF cache to start a scan task |
|
Assert.NotNull(efCache.scanTask); |
|
// We don't want the scan task to throw an exception, unwrap it. |
|
await efCache.scanTask; |
|
|
|
Assert.NotNull(firstValue); |
|
Assert.Null(secondValue); |
|
} |
|
|
|
[DatabaseTheory, DatabaseData(UseFakeTimeProvider = true)] |
|
public async Task ParallelReadsAndWrites_Work(IDistributedCache cache, TimeProvider timeProvider) |
|
{ |
|
var fakeTimeProvider = (FakeTimeProvider)timeProvider; |
|
|
|
await Parallel.ForEachAsync(Enumerable.Range(1, 100), async (index, _) => |
|
{ |
|
await cache.SetAsync($"test-{index}", "some-value"u8.ToArray(), new DistributedCacheEntryOptions |
|
{ |
|
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(index), |
|
}); |
|
}); |
|
|
|
await Parallel.ForEachAsync(Enumerable.Range(1, 100), async (index, _) => |
|
{ |
|
var value = await cache.GetAsync($"test-{index}"); |
|
Assert.NotNull(value); |
|
}); |
|
} |
|
|
|
[DatabaseTheory, DatabaseData] |
|
public async Task MultipleWritesOnSameKey_ShouldNotThrow(IDistributedCache cache) |
|
{ |
|
await cache.SetAsync("test-duplicate", "some-value"u8.ToArray(), TestContext.Current.CancellationToken); |
|
await cache.SetAsync("test-duplicate", "some-value"u8.ToArray(), TestContext.Current.CancellationToken); |
|
} |
|
}
|
|
|