1+ using System ;
2+ using System . Threading ;
3+ using System . Threading . Tasks ;
4+ using Eocron . DependencyInjection . Interceptors ;
5+ using FluentAssertions ;
6+ using Moq ;
7+ using NUnit . Framework ;
8+
9+ namespace Eocron . DependencyInjection . Tests . DependencyInjectionTests
10+ {
11+ public class CacheTests : BaseDependencyInjectionTests
12+ {
13+ [ Test ]
14+ public async Task AbsoluteExpirationErrorNotCached ( )
15+ {
16+ Instance . Setup ( x => x . WorkWithResultAsync ( It . IsAny < int > ( ) , It . IsAny < CancellationToken > ( ) ) )
17+ . ThrowsAsync ( new InvalidOperationException ( ) ) ;
18+
19+ var proxy = CreateTestObject ( x => x . AddAbsoluteTimeoutCache ( Expiration , ( method , args ) => args [ 0 ] ) ) ;
20+
21+ var func = async ( ) => await proxy . WorkWithResultAsync ( 1 , Ct ) ;
22+ await func . Should ( ) . ThrowAsync < InvalidOperationException > ( ) ;
23+ await func . Should ( ) . ThrowAsync < InvalidOperationException > ( ) ;
24+ await func . Should ( ) . ThrowAsync < InvalidOperationException > ( ) ;
25+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . IsAny < int > ( ) , It . IsAny < CancellationToken > ( ) ) , Times . Exactly ( 3 ) ) ;
26+ }
27+
28+ [ Test ]
29+ public async Task SlidingExpirationErrorNotCached ( )
30+ {
31+ Instance . Setup ( x => x . WorkWithResultAsync ( It . IsAny < int > ( ) , It . IsAny < CancellationToken > ( ) ) )
32+ . ThrowsAsync ( new InvalidOperationException ( ) ) ;
33+
34+ var proxy = CreateTestObject ( x => x . AddSlidingTimeoutCache ( Expiration , ( method , args ) => args [ 0 ] ) ) ;
35+
36+ var func = async ( ) => await proxy . WorkWithResultAsync ( 1 , Ct ) ;
37+ await func . Should ( ) . ThrowAsync < InvalidOperationException > ( ) ;
38+ await func . Should ( ) . ThrowAsync < InvalidOperationException > ( ) ;
39+ await func . Should ( ) . ThrowAsync < InvalidOperationException > ( ) ;
40+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . IsAny < int > ( ) , It . IsAny < CancellationToken > ( ) ) , Times . Exactly ( 3 ) ) ;
41+ }
42+
43+ [ Test ]
44+ public async Task AbsoluteExpiration ( )
45+ {
46+ Instance . Setup ( x => x . WorkWithResultAsync ( It . Is < int > ( i=> i == 1 ) , It . IsAny < CancellationToken > ( ) ) ) . ReturnsAsync ( 1 ) ;
47+ Instance . Setup ( x => x . WorkWithResultAsync ( It . Is < int > ( i=> i == 2 ) , It . IsAny < CancellationToken > ( ) ) ) . ReturnsAsync ( 2 ) ;
48+
49+ var proxy = CreateTestObject ( x => x . AddAbsoluteTimeoutCache ( Expiration , ( method , args ) => args [ 0 ] ) ) ;
50+
51+ //first pass
52+ await Parallel . ForAsync ( 0 , 100 , async ( _ , _ ) =>
53+ {
54+ ( await proxy . WorkWithResultAsync ( 1 , Ct ) ) . Should ( ) . Be ( 1 ) ;
55+ } ) ;
56+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 1 ) , It . IsAny < CancellationToken > ( ) ) , Times . Exactly ( 1 ) ) ;
57+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 2 ) , It . IsAny < CancellationToken > ( ) ) , Times . Never ) ;
58+
59+ await Task . Delay ( Expiration ) ;
60+
61+ //second pass
62+ await Parallel . ForAsync ( 0 , 100 , async ( _ , _ ) =>
63+ {
64+ ( await proxy . WorkWithResultAsync ( 1 , Ct ) ) . Should ( ) . Be ( 1 ) ;
65+ } ) ;
66+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 1 ) , It . IsAny < CancellationToken > ( ) ) , Times . Exactly ( 2 ) ) ;
67+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 2 ) , It . IsAny < CancellationToken > ( ) ) , Times . Never ) ;
68+ }
69+
70+ [ Test ]
71+ public async Task SlidingExpiration ( )
72+ {
73+ Instance . Setup ( x => x . WorkWithResultAsync ( It . Is < int > ( i=> i == 1 ) , It . IsAny < CancellationToken > ( ) ) ) . ReturnsAsync ( 1 ) ;
74+ Instance . Setup ( x => x . WorkWithResultAsync ( It . Is < int > ( i=> i == 2 ) , It . IsAny < CancellationToken > ( ) ) ) . ReturnsAsync ( 2 ) ;
75+
76+ var proxy = CreateTestObject ( x => x . AddSlidingTimeoutCache ( Expiration , ( method , args ) => args [ 0 ] ) ) ;
77+
78+ //first pass
79+ await Parallel . ForAsync ( 0 , 100 , async ( _ , _ ) =>
80+ {
81+ ( await proxy . WorkWithResultAsync ( 1 , Ct ) ) . Should ( ) . Be ( 1 ) ;
82+ } ) ;
83+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 1 ) , It . IsAny < CancellationToken > ( ) ) , Times . Exactly ( 1 ) ) ;
84+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 2 ) , It . IsAny < CancellationToken > ( ) ) , Times . Never ) ;
85+
86+ await Task . Delay ( Expiration ) ;
87+
88+ //second pass
89+ await Parallel . ForAsync ( 0 , 100 , async ( _ , _ ) =>
90+ {
91+ ( await proxy . WorkWithResultAsync ( 1 , Ct ) ) . Should ( ) . Be ( 1 ) ;
92+ } ) ;
93+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 1 ) , It . IsAny < CancellationToken > ( ) ) , Times . Exactly ( 2 ) ) ;
94+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 2 ) , It . IsAny < CancellationToken > ( ) ) , Times . Never ) ;
95+ }
96+
97+ [ Test ]
98+ public async Task SlidingExpirationOverlap ( )
99+ {
100+ Instance . Setup ( x => x . WorkWithResultAsync ( It . Is < int > ( i=> i == 1 ) , It . IsAny < CancellationToken > ( ) ) ) . ReturnsAsync ( 1 ) ;
101+ Instance . Setup ( x => x . WorkWithResultAsync ( It . Is < int > ( i=> i == 2 ) , It . IsAny < CancellationToken > ( ) ) ) . ReturnsAsync ( 2 ) ;
102+
103+ var proxy = CreateTestObject ( x => x . AddSlidingTimeoutCache ( Expiration , ( method , args ) => args [ 0 ] ) ) ;
104+
105+ //first pass
106+ await Parallel . ForAsync ( 0 , 100 , async ( _ , _ ) =>
107+ {
108+ ( await proxy . WorkWithResultAsync ( 1 , Ct ) ) . Should ( ) . Be ( 1 ) ;
109+ } ) ;
110+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 1 ) , It . IsAny < CancellationToken > ( ) ) , Times . Exactly ( 1 ) ) ;
111+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 2 ) , It . IsAny < CancellationToken > ( ) ) , Times . Never ) ;
112+
113+ await Task . Delay ( Expiration / 2 ) ;
114+
115+ //second pass
116+ await Parallel . ForAsync ( 0 , 100 , async ( _ , _ ) =>
117+ {
118+ ( await proxy . WorkWithResultAsync ( 1 , Ct ) ) . Should ( ) . Be ( 1 ) ;
119+ } ) ;
120+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 1 ) , It . IsAny < CancellationToken > ( ) ) , Times . Exactly ( 1 ) ) ;
121+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 2 ) , It . IsAny < CancellationToken > ( ) ) , Times . Never ) ;
122+
123+ await Task . Delay ( Expiration / 2 ) ;
124+
125+ //third pass
126+ await Parallel . ForAsync ( 0 , 100 , async ( _ , _ ) =>
127+ {
128+ ( await proxy . WorkWithResultAsync ( 1 , Ct ) ) . Should ( ) . Be ( 1 ) ;
129+ } ) ;
130+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 1 ) , It . IsAny < CancellationToken > ( ) ) , Times . Exactly ( 1 ) ) ;
131+ Instance . Verify ( x=> x . WorkWithResultAsync ( It . Is < int > ( i=> i == 2 ) , It . IsAny < CancellationToken > ( ) ) , Times . Never ) ;
132+ }
133+ public TimeSpan Expiration = TimeSpan . FromSeconds ( 3 ) ;
134+ }
135+ }
0 commit comments