forked from zzzprojects/System.Linq.Dynamic.Core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathThreadSafeSlidingCacheTests.cs
More file actions
152 lines (114 loc) · 5.1 KB
/
ThreadSafeSlidingCacheTests.cs
File metadata and controls
152 lines (114 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
using System.Linq.Dynamic.Core.Util;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Xunit;
namespace System.Linq.Dynamic.Core.Tests.Util
{
public class ThreadSafeSlidingCacheTests
{
[Fact]
public void ThreadSafeSlidingCache_CacheOperations()
{
var mockDateTime = new MockDateTimeProvider();
// Arrange
var cache = new ThreadSafeSlidingCache<int, string>(
TimeSpan.FromSeconds(1),
dateTimeProvider: mockDateTime);
// Add
cache.AddOrUpdate(1, "one");
cache.AddOrUpdate(2, "two");
cache.AddOrUpdate(3, "three");
// Replace
cache.AddOrUpdate(1, "oneone");
Assert.True(cache.Count == 3, $"Expected 3 items in the cache, only had {cache.Count}");
// Test retrieval
Assert.True(cache.TryGetValue(1, out var value1), $"Expected to find the value, but did not");
Assert.True(cache.TryGetValue(2, out var value2), $"Expected to find the value, but did not");
Assert.True(cache.TryGetValue(3, out var value3), $"Expected to find the value, but did not");
// Test Removal
cache.Remove(1);
Assert.True(cache.Count == 2, $"Expected 2 items in the cache, only had {cache.Count}");
}
[Fact]
public void ThreadSafeSlidingCache_TestExpire()
{
var mockDateTime = new MockDateTimeProvider();
// Arrange
var cache = new ThreadSafeSlidingCache<int, string>(TimeSpan.FromMinutes(10),
dateTimeProvider: mockDateTime);
// Act
cache.AddOrUpdate(1, "one");
mockDateTime.UtcNow = mockDateTime.UtcNow.AddMinutes(11);
if (cache.TryGetValue(1, out var value))
{
Assert.True(false, $"Expected to not find the value, but found {value}");
}
}
[Fact]
public async Task ThreadSafeSlidingCache_TestAutoExpire()
{
var mockDateTime = new MockDateTimeProvider();
// Arrange
var cache = new ThreadSafeSlidingCache<int, string>(TimeSpan.FromMinutes(10),
dateTimeProvider: mockDateTime);
// Act
cache.AddOrUpdate(1, "one");
// Ensure one item is in the cache
Assert.True(cache.Count == 1, $"Expected 1 items in the cache, only had {cache.Count}");
// move the time forward
mockDateTime.UtcNow = mockDateTime.UtcNow.AddMinutes(11);
// Trigger the cleanup, asking for non-existing key
cache.TryGetValue(10, out var _);
// Since the cache cleanup is triggered by a Task and not on the same thread,
// give it a moment for the cleanup to happen
await Task.Delay(10);
// Ensure one item is in the cache
Assert.True(cache.Count == 0, $"Expected 0 items in the cache, only had {cache.Count}");
}
[Fact]
public async Task ThreadSafeSlidingCache_TestNull()
{
// Arrange
var cache = new ThreadSafeSlidingCache<Expression, string>(TimeSpan.FromMinutes(10));
// Expect an ArgumentNullException
var exception = Assert.Throws<ArgumentNullException>(() => {
cache.AddOrUpdate(null, "one");
});
}
[Fact]
public async Task ThreadSafeSlidingCache_TestMinNumberBeforeTests()
{
// Arrange
var mockDateTime = new MockDateTimeProvider();
// Arrange
var cache = new ThreadSafeSlidingCache<int, string>(
TimeSpan.FromMinutes(10),
minCacheItemsBeforeCleanup: 2,
dateTimeProvider: mockDateTime);
// Act
cache.AddOrUpdate(1, "one");
// Ensure one item is in the cache
Assert.True(cache.Count == 1, $"Expected 1 items in the cache, only had {cache.Count}");
// move the time forward
mockDateTime.UtcNow = mockDateTime.UtcNow.AddMinutes(11);
// Trigger the cleanup, asking for non-existing key
cache.TryGetValue(10, out var _);
// Since the cache cleanup is triggered by a Task and not on the same thread,
// give it a moment for the cleanup to happen
await Task.Delay(10);
// Ensure one item is in the cache
Assert.True(cache.Count == 1, $"Expected 1 items in the cache, only had {cache.Count}");
// Act
cache.AddOrUpdate(2, "two");
// Since the cache cleanup is triggered by a Task and not on the same thread,
// give it a moment for the cleanup to happen
await Task.Delay(10);
// Ensure one item is in the cache
Assert.True(cache.Count == 1, $"Expected 1 items in the cache, had {cache.Count}");
}
private class MockDateTimeProvider : IDateTimeUtils
{
public DateTime UtcNow { get; set; } = DateTime.UtcNow;
}
}
}