mirror of
https://github.com/bitwarden/server.git
synced 2024-12-01 13:43:23 +01:00
0d3a7b3dd5
* Sql-backed IDistributedCache * sqlserver cache table * remove unused using * setup EF entity * cache indexes * add back cipher * revert SetupEntityFramework change * ef cache * EntityFrameworkCache * IServiceScopeFactory for db context * implement EntityFrameworkCache * move to _serviceScopeFactory * move to config file * ef migrations * fixes * datetime and error codes * revert migrations * migrations * format * static and namespace fix * use time provider * Move SQL migration and remove EF one for the moment * Add clean migration of just the new table * Formatting * Test Custom `IDistributedCache` Implementation * Add Back Logging * Remove Double Logging * Skip Test When Not EntityFrameworkCache * Format --------- Co-authored-by: Matt Bishop <mbishop@bitwarden.com> Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com>
72 lines
2.6 KiB
C#
72 lines
2.6 KiB
C#
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());
|
|
await cache.SetAsync("test-duplicate", "some-value"u8.ToArray());
|
|
}
|
|
}
|