@@ -69,7 +69,7 @@ public void InjectFault_With_Context_Should_not_execute_user_delegate_async()
6969 var policy = MonkeyPolicy . InjectFaultAsync (
7070 new Exception ( "test" ) ,
7171 0.6 ,
72- async ( ctx ) =>
72+ async ( ctx , ct ) =>
7373 {
7474 return await Task . FromResult ( ( bool ) ctx [ "ShouldFail" ] ) ;
7575 } ) ;
@@ -89,7 +89,7 @@ public void InjectFault_With_Context_Should_execute_user_delegate_async()
8989 var policy = MonkeyPolicy . InjectFaultAsync (
9090 new Exception ( "test" ) ,
9191 0.4 ,
92- async ( ctx ) =>
92+ async ( ctx , ct ) =>
9393 {
9494 return await Task . FromResult ( ( bool ) ctx [ "ShouldFail" ] ) ;
9595 } ) ;
@@ -108,7 +108,7 @@ public void InjectFault_With_Context_Should_execute_user_delegate_async_with_ena
108108 var policy = MonkeyPolicy . InjectFaultAsync (
109109 new Exception ( "test" ) ,
110110 0.6 ,
111- async ( ctx ) =>
111+ async ( ctx , ct ) =>
112112 {
113113 return await Task . FromResult ( ( bool ) ctx [ "ShouldFail" ] ) ;
114114 } ) ;
@@ -128,8 +128,8 @@ public void InjectFault_should_throw_if_injection_rate_is_out_of_range_too_low()
128128 Context context = new Context ( ) ;
129129
130130 Func < Context , CancellationToken , Task < Exception > > fault = ( ctx , cts ) => Task . FromResult ( new Exception ( ) ) ;
131- Func < Context , Task < bool > > enabled = ( ctx ) => Task . FromResult ( true ) ;
132- Func < Context , Task < Double > > injectionRate = ( ctx ) => Task . FromResult ( - 0.1 ) ;
131+ Func < Context , CancellationToken , Task < bool > > enabled = ( ctx , ct ) => Task . FromResult ( true ) ;
132+ Func < Context , CancellationToken , Task < Double > > injectionRate = ( ctx , ct ) => Task . FromResult ( - 0.1 ) ;
133133 var policy = MonkeyPolicy . InjectFaultAsync ( fault , injectionRate , enabled ) ;
134134
135135 Func < Context , Task > actionAsync = ( _ ) => { executed = true ; return TaskHelper . EmptyTask ; } ;
@@ -144,8 +144,8 @@ public void InjectFault_should_throw_if_injection_rate_is_out_of_range_too_high(
144144 Context context = new Context ( ) ;
145145
146146 Func < Context , CancellationToken , Task < Exception > > fault = ( ctx , cts ) => Task . FromResult ( new Exception ( ) ) ;
147- Func < Context , Task < bool > > enabled = ( ctx ) => Task . FromResult ( true ) ;
148- Func < Context , Task < Double > > injectionRate = ( ctx ) => Task . FromResult ( 1.01 ) ;
147+ Func < Context , CancellationToken , Task < bool > > enabled = ( ctx , ct ) => Task . FromResult ( true ) ;
148+ Func < Context , CancellationToken , Task < Double > > injectionRate = ( ctx , ct ) => Task . FromResult ( 1.01 ) ;
149149 var policy = MonkeyPolicy . InjectFaultAsync ( fault , injectionRate , enabled ) ;
150150
151151 Func < Context , Task > actionAsync = ( _ ) => { executed = true ; return TaskHelper . EmptyTask ; } ;
@@ -160,8 +160,8 @@ public void InjectFault_With_Context_Should_not_execute_user_delegate_async_basi
160160 Context context = new Context ( ) ;
161161
162162 Func < Context , CancellationToken , Task < Exception > > fault = ( ctx , cts ) => Task . FromResult ( new Exception ( ) ) ;
163- Func < Context , Task < bool > > enabled = ( ctx ) => Task . FromResult ( true ) ;
164- Func < Context , Task < Double > > injectionRate = ( ctx ) => Task . FromResult ( 0.6 ) ;
163+ Func < Context , CancellationToken , Task < bool > > enabled = ( ctx , ct ) => Task . FromResult ( true ) ;
164+ Func < Context , CancellationToken , Task < Double > > injectionRate = ( ctx , ct ) => Task . FromResult ( 0.6 ) ;
165165 var policy = MonkeyPolicy . InjectFaultAsync ( fault , injectionRate , enabled ) ;
166166
167167 Func < Context , Task > actionAsync = ( _ ) => { executed = true ; return TaskHelper . EmptyTask ; } ;
@@ -190,7 +190,7 @@ public void InjectFault_With_Context_Should_not_execute_user_delegate_async_with
190190 return Task . FromResult ( new Exception ( ) ) ;
191191 } ;
192192
193- Func < Context , Task < Double > > injectionRate = ( ctx ) =>
193+ Func < Context , CancellationToken , Task < Double > > injectionRate = ( ctx , ct ) =>
194194 {
195195 double rate = 0 ;
196196 if ( ctx [ "InjectionRate" ] != null )
@@ -201,7 +201,7 @@ public void InjectFault_With_Context_Should_not_execute_user_delegate_async_with
201201 return Task . FromResult ( rate ) ;
202202 } ;
203203
204- Func < Context , Task < bool > > enabled = ( ctx ) =>
204+ Func < Context , CancellationToken , Task < bool > > enabled = ( ctx , ct ) =>
205205 {
206206 return Task . FromResult ( ( bool ) ctx [ "ShouldFail" ] ) ;
207207 } ;
@@ -214,5 +214,225 @@ public void InjectFault_With_Context_Should_not_execute_user_delegate_async_with
214214 executed . Should ( ) . BeFalse ( ) ;
215215 }
216216 #endregion
217+
218+ #region Cancellable scenarios
219+
220+ [ Fact ]
221+ public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_before_to_start_execution ( )
222+ {
223+ string failureMessage = "Failure Message" ;
224+ Boolean executed = false ;
225+ Context context = new Context ( ) ;
226+ context [ "ShouldFail" ] = true ;
227+ context [ "Message" ] = failureMessage ;
228+ context [ "InjectionRate" ] = 0.6 ;
229+ Func < Context , CancellationToken , Task > actionAsync = ( ctx , ct ) =>
230+ {
231+ executed = true ;
232+ return TaskHelper . EmptyTask ;
233+ } ;
234+
235+ Func < Context , CancellationToken , Task < Exception > > fault = ( ctx , cts ) =>
236+ {
237+ if ( ctx [ "Message" ] != null )
238+ {
239+ Exception ex = new InvalidOperationException ( ctx [ "Message" ] . ToString ( ) ) ;
240+ return Task . FromResult ( ex ) ;
241+ }
242+
243+ return Task . FromResult ( new Exception ( ) ) ;
244+ } ;
245+
246+ Func < Context , CancellationToken , Task < Double > > injectionRate = ( ctx , ct ) =>
247+ {
248+ double rate = 0 ;
249+ if ( ctx [ "InjectionRate" ] != null )
250+ {
251+ rate = ( double ) ctx [ "InjectionRate" ] ;
252+ }
253+
254+ return Task . FromResult ( rate ) ;
255+ } ;
256+
257+ Func < Context , CancellationToken , Task < bool > > enabled = ( ctx , ct ) =>
258+ {
259+ return Task . FromResult ( ( bool ) ctx [ "ShouldFail" ] ) ;
260+ } ;
261+
262+ var policy = MonkeyPolicy . InjectFaultAsync ( fault , injectionRate , enabled ) ;
263+ using ( CancellationTokenSource cts = new CancellationTokenSource ( ) )
264+ {
265+ cts . Cancel ( ) ;
266+
267+ policy . Awaiting ( async x => await x . ExecuteAsync ( actionAsync , context , cts . Token ) )
268+ . ShouldThrow < OperationCanceledException > ( ) ;
269+ }
270+
271+ executed . Should ( ) . BeFalse ( ) ;
272+ }
273+
274+ [ Fact ]
275+ public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_enabled_config_delegate ( )
276+ {
277+ string failureMessage = "Failure Message" ;
278+ Boolean executed = false ;
279+ Context context = new Context ( ) ;
280+ context [ "ShouldFail" ] = true ;
281+ context [ "Message" ] = failureMessage ;
282+ context [ "InjectionRate" ] = 0.6 ;
283+ Func < Context , CancellationToken , Task > actionAsync = ( ctx , ct ) =>
284+ {
285+ executed = true ;
286+ return TaskHelper . EmptyTask ;
287+ } ;
288+
289+ Func < Context , CancellationToken , Task < Exception > > fault = ( ctx , cts ) =>
290+ {
291+ if ( ctx [ "Message" ] != null )
292+ {
293+ Exception ex = new InvalidOperationException ( ctx [ "Message" ] . ToString ( ) ) ;
294+ return Task . FromResult ( ex ) ;
295+ }
296+
297+ return Task . FromResult ( new Exception ( ) ) ;
298+ } ;
299+
300+ Func < Context , CancellationToken , Task < Double > > injectionRate = ( ctx , ct ) =>
301+ {
302+ double rate = 0 ;
303+ if ( ctx [ "InjectionRate" ] != null )
304+ {
305+ rate = ( double ) ctx [ "InjectionRate" ] ;
306+ }
307+
308+ return Task . FromResult ( rate ) ;
309+ } ;
310+
311+ using ( CancellationTokenSource cts = new CancellationTokenSource ( ) )
312+ {
313+ Func < Context , CancellationToken , Task < bool > > enabled = ( ctx , ct ) =>
314+ {
315+ cts . Cancel ( ) ;
316+ return Task . FromResult ( ( bool ) ctx [ "ShouldFail" ] ) ;
317+ } ;
318+
319+ var policy = MonkeyPolicy . InjectFaultAsync ( fault , injectionRate , enabled ) ;
320+
321+ policy . Awaiting ( async x => await x . ExecuteAsync ( actionAsync , context , cts . Token ) )
322+ . ShouldThrow < OperationCanceledException > ( ) ;
323+ }
324+
325+ executed . Should ( ) . BeFalse ( ) ;
326+ }
327+
328+ [ Fact ]
329+ public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_injectionrate_config_delegate ( )
330+ {
331+ string failureMessage = "Failure Message" ;
332+ Boolean executed = false ;
333+ Context context = new Context ( ) ;
334+ context [ "ShouldFail" ] = true ;
335+ context [ "Message" ] = failureMessage ;
336+ context [ "InjectionRate" ] = 0.6 ;
337+ Func < Context , CancellationToken , Task > actionAsync = ( ctx , ct ) =>
338+ {
339+ executed = true ;
340+ return TaskHelper . EmptyTask ;
341+ } ;
342+
343+ Func < Context , CancellationToken , Task < Exception > > fault = ( ctx , cts ) =>
344+ {
345+ if ( ctx [ "Message" ] != null )
346+ {
347+ Exception ex = new InvalidOperationException ( ctx [ "Message" ] . ToString ( ) ) ;
348+ return Task . FromResult ( ex ) ;
349+ }
350+
351+ return Task . FromResult ( new Exception ( ) ) ;
352+ } ;
353+
354+ using ( CancellationTokenSource cts = new CancellationTokenSource ( ) )
355+ {
356+ Func < Context , CancellationToken , Task < bool > > enabled = ( ctx , ct ) =>
357+ {
358+ return Task . FromResult ( ( bool ) ctx [ "ShouldFail" ] ) ;
359+ } ;
360+
361+ Func < Context , CancellationToken , Task < Double > > injectionRate = ( ctx , ct ) =>
362+ {
363+ double rate = 0 ;
364+ if ( ctx [ "InjectionRate" ] != null )
365+ {
366+ rate = ( double ) ctx [ "InjectionRate" ] ;
367+ }
368+
369+ cts . Cancel ( ) ;
370+ return Task . FromResult ( rate ) ;
371+ } ;
372+
373+ var policy = MonkeyPolicy . InjectFaultAsync ( fault , injectionRate , enabled ) ;
374+
375+ policy . Awaiting ( async x => await x . ExecuteAsync ( actionAsync , context , cts . Token ) )
376+ . ShouldThrow < OperationCanceledException > ( ) ;
377+ }
378+
379+ executed . Should ( ) . BeFalse ( ) ;
380+ }
381+
382+ [ Fact ]
383+ public void InjectFault_With_Context_Should_not_execute_user_delegate_if_user_cancelationtoken_cancelled_on_fault_config_delegate ( )
384+ {
385+ string failureMessage = "Failure Message" ;
386+ Boolean executed = false ;
387+ Context context = new Context ( ) ;
388+ context [ "ShouldFail" ] = true ;
389+ context [ "Message" ] = failureMessage ;
390+ context [ "InjectionRate" ] = 0.6 ;
391+ Func < Context , CancellationToken , Task > actionAsync = ( ctx , ct ) =>
392+ {
393+ executed = true ;
394+ return TaskHelper . EmptyTask ;
395+ } ;
396+
397+ using ( CancellationTokenSource cts = new CancellationTokenSource ( ) )
398+ {
399+ Func < Context , CancellationToken , Task < bool > > enabled = ( ctx , ct ) =>
400+ {
401+ return Task . FromResult ( ( bool ) ctx [ "ShouldFail" ] ) ;
402+ } ;
403+
404+ Func < Context , CancellationToken , Task < Double > > injectionRate = ( ctx , ct ) =>
405+ {
406+ double rate = 0 ;
407+ if ( ctx [ "InjectionRate" ] != null )
408+ {
409+ rate = ( double ) ctx [ "InjectionRate" ] ;
410+ }
411+
412+ return Task . FromResult ( rate ) ;
413+ } ;
414+
415+ Func < Context , CancellationToken , Task < Exception > > fault = ( ctx , ct ) =>
416+ {
417+ cts . Cancel ( ) ;
418+ if ( ctx [ "Message" ] != null )
419+ {
420+ Exception ex = new InvalidOperationException ( ctx [ "Message" ] . ToString ( ) ) ;
421+ return Task . FromResult ( ex ) ;
422+ }
423+
424+ return Task . FromResult ( new Exception ( ) ) ;
425+ } ;
426+
427+ var policy = MonkeyPolicy . InjectFaultAsync ( fault , injectionRate , enabled ) ;
428+
429+ policy . Awaiting ( async x => await x . ExecuteAsync ( actionAsync , context , cts . Token ) )
430+ . ShouldThrow < OperationCanceledException > ( ) ;
431+ }
432+
433+ executed . Should ( ) . BeFalse ( ) ;
434+ }
435+
436+ #endregion
217437 }
218438}
0 commit comments