@@ -40,7 +40,6 @@ public async Task ReadingEmptySessionDoesNotCreateCookie()
40
40
} )
41
41
. ConfigureServices ( services =>
42
42
{
43
- services . AddMemoryCache ( ) ;
44
43
services . AddDistributedMemoryCache ( ) ;
45
44
services . AddSession ( ) ;
46
45
} ) ;
@@ -72,7 +71,6 @@ public async Task SettingAValueCausesTheCookieToBeCreated()
72
71
} )
73
72
. ConfigureServices ( services =>
74
73
{
75
- services . AddMemoryCache ( ) ;
76
74
services . AddDistributedMemoryCache ( ) ;
77
75
services . AddSession ( ) ;
78
76
} ) ;
@@ -111,9 +109,7 @@ public async Task SessionCanBeAccessedOnTheNextRequest()
111
109
} )
112
110
. ConfigureServices ( services =>
113
111
{
114
- services . AddMemoryCache ( ) ;
115
112
services . AddDistributedMemoryCache ( ) ;
116
-
117
113
services . AddSession ( ) ;
118
114
} ) ;
119
115
@@ -166,9 +162,7 @@ public async Task RemovedItemCannotBeAccessedAgain()
166
162
. ConfigureServices (
167
163
services =>
168
164
{
169
- services . AddMemoryCache ( ) ;
170
165
services . AddDistributedMemoryCache ( ) ;
171
-
172
166
services . AddSession ( ) ;
173
167
} ) ;
174
168
@@ -219,9 +213,7 @@ public async Task ClearedItemsCannotBeAccessedAgain()
219
213
} )
220
214
. ConfigureServices ( services =>
221
215
{
222
- services . AddMemoryCache ( ) ;
223
216
services . AddDistributedMemoryCache ( ) ;
224
-
225
217
services . AddSession ( ) ;
226
218
} ) ;
227
219
@@ -258,10 +250,7 @@ public async Task SessionStart_LogsInformation()
258
250
. ConfigureServices ( services =>
259
251
{
260
252
services . AddSingleton ( typeof ( ILoggerFactory ) , loggerFactory ) ;
261
-
262
- services . AddMemoryCache ( ) ;
263
253
services . AddDistributedMemoryCache ( ) ;
264
-
265
254
services . AddSession ( ) ;
266
255
} ) ;
267
256
@@ -310,10 +299,7 @@ public async Task ExpiredSession_LogsWarning()
310
299
. ConfigureServices ( services =>
311
300
{
312
301
services . AddSingleton ( typeof ( ILoggerFactory ) , loggerFactory ) ;
313
-
314
- services . AddMemoryCache ( ) ;
315
302
services . AddDistributedMemoryCache ( ) ;
316
-
317
303
services . AddSession ( o => o . IdleTimeout = TimeSpan . FromMilliseconds ( 30 ) ) ;
318
304
} ) ;
319
305
@@ -373,10 +359,7 @@ public async Task RefreshesSession_WhenSessionData_IsNotModified()
373
359
. ConfigureServices ( services =>
374
360
{
375
361
services . AddSingleton ( typeof ( ILoggerFactory ) , new NullLoggerFactory ( ) ) ;
376
-
377
- services . AddMemoryCache ( ) ;
378
362
services . AddDistributedMemoryCache ( ) ;
379
-
380
363
services . AddSession ( o => o . IdleTimeout = TimeSpan . FromMinutes ( 20 ) ) ;
381
364
services . Configure < MemoryCacheOptions > ( o => o . Clock = clock ) ;
382
365
} ) ;
@@ -426,9 +409,7 @@ public async Task SessionFeature_IsUnregistered_WhenResponseGoingOut()
426
409
} )
427
410
. ConfigureServices ( services =>
428
411
{
429
- services . AddMemoryCache ( ) ;
430
412
services . AddDistributedMemoryCache ( ) ;
431
-
432
413
services . AddSession ( ) ;
433
414
} ) ;
434
415
@@ -471,9 +452,7 @@ public async Task SessionFeature_IsUnregistered_WhenResponseGoingOut_AndAnUnhand
471
452
} )
472
453
. ConfigureServices ( services =>
473
454
{
474
- services . AddMemoryCache ( ) ;
475
455
services . AddDistributedMemoryCache ( ) ;
476
-
477
456
services . AddSession ( ) ;
478
457
} ) ;
479
458
@@ -502,9 +481,7 @@ public async Task SessionKeys_AreCaseSensitive()
502
481
} )
503
482
. ConfigureServices ( services =>
504
483
{
505
- services . AddMemoryCache ( ) ;
506
484
services . AddDistributedMemoryCache ( ) ;
507
-
508
485
services . AddSession ( ) ;
509
486
} ) ;
510
487
@@ -516,61 +493,185 @@ public async Task SessionKeys_AreCaseSensitive()
516
493
}
517
494
}
518
495
519
- private class TestClock : ISystemClock
496
+ [ Fact ]
497
+ public async Task SessionLogsCacheReadException ( )
520
498
{
521
- public TestClock ( )
499
+ var sink = new TestSink ( ) ;
500
+ var loggerFactory = new TestLoggerFactory ( sink , enabled : true ) ;
501
+ var builder = new WebHostBuilder ( )
502
+ . Configure ( app =>
503
+ {
504
+ app . UseSession ( ) ;
505
+ app . Run ( context =>
506
+ {
507
+ byte [ ] value ;
508
+ Assert . False ( context . Session . TryGetValue ( "key" , out value ) ) ;
509
+ Assert . Equal ( default ( byte [ ] ) , value ) ;
510
+ Assert . Equal ( default ( string ) , context . Session . Id ) ;
511
+ Assert . Equal ( default ( IEnumerable < string > ) , context . Session . Keys ) ;
512
+ return Task . FromResult ( 0 ) ;
513
+ } ) ;
514
+ } )
515
+ . ConfigureServices ( services =>
516
+ {
517
+ services . AddSingleton ( typeof ( ILoggerFactory ) , loggerFactory ) ;
518
+ services . AddSingleton < IDistributedCache > ( new UnreliableCache ( new MemoryCache ( new MemoryCacheOptions ( ) ) )
519
+ {
520
+ DisableGet = true
521
+ } ) ;
522
+ services . AddSession ( ) ;
523
+ } ) ;
524
+
525
+ using ( var server = new TestServer ( builder ) )
522
526
{
523
- UtcNow = new DateTimeOffset ( 2013 , 1 , 1 , 1 , 0 , 0 , TimeSpan . Zero ) ;
524
- }
527
+ var client = server . CreateClient ( ) ;
528
+ var response = await client . GetAsync ( string . Empty ) ;
529
+ response . EnsureSuccessStatusCode ( ) ;
525
530
526
- public DateTimeOffset UtcNow { get ; private set ; }
531
+ var sessionLogMessages = sink . Writes . OnlyMessagesFromSource < DistributedSession > ( ) . ToArray ( ) ;
527
532
528
- public void Add ( TimeSpan timespan )
529
- {
530
- UtcNow = UtcNow . Add ( timespan ) ;
533
+ Assert . Equal ( 1 , sessionLogMessages . Length ) ;
534
+ Assert . Contains ( "Session cache read exception" , sessionLogMessages [ 0 ] . State . ToString ( ) ) ;
535
+ Assert . Equal ( LogLevel . Error , sessionLogMessages [ 0 ] . LogLevel ) ;
531
536
}
532
537
}
533
538
534
- private class TestDistributedCache : IDistributedCache
539
+ [ Fact ]
540
+ public async Task SessionLogsCacheWriteException ( )
535
541
{
536
- public byte [ ] Get ( string key )
542
+ var sink = new TestSink ( ) ;
543
+ var loggerFactory = new TestLoggerFactory ( sink , enabled : true ) ;
544
+ var builder = new WebHostBuilder ( )
545
+ . Configure ( app =>
546
+ {
547
+ app . UseSession ( ) ;
548
+ app . Run ( context =>
549
+ {
550
+ context . Session . SetInt32 ( "key" , 0 ) ;
551
+ return Task . FromResult ( 0 ) ;
552
+ } ) ;
553
+ } )
554
+ . ConfigureServices ( services =>
555
+ {
556
+ services . AddSingleton ( typeof ( ILoggerFactory ) , loggerFactory ) ;
557
+ services . AddSingleton < IDistributedCache > ( new UnreliableCache ( new MemoryCache ( new MemoryCacheOptions ( ) ) )
558
+ {
559
+ DisableSetAsync = true
560
+ } ) ;
561
+ services . AddSession ( ) ;
562
+ } ) ;
563
+
564
+ using ( var server = new TestServer ( builder ) )
537
565
{
538
- throw new NotImplementedException ( ) ;
566
+ var client = server . CreateClient ( ) ;
567
+ var response = await client . GetAsync ( string . Empty ) ;
568
+ response . EnsureSuccessStatusCode ( ) ;
569
+
570
+ var sessionLogMessages = sink . Writes . OnlyMessagesFromSource < DistributedSession > ( ) . ToArray ( ) ;
571
+
572
+ Assert . Equal ( 2 , sessionLogMessages . Length ) ;
573
+ Assert . Contains ( "Session started" , sessionLogMessages [ 0 ] . State . ToString ( ) ) ;
574
+ Assert . Equal ( LogLevel . Information , sessionLogMessages [ 0 ] . LogLevel ) ;
575
+ Assert . Contains ( "Session cache write exception" , sessionLogMessages [ 1 ] . State . ToString ( ) ) ;
576
+ Assert . Equal ( LogLevel . Error , sessionLogMessages [ 1 ] . LogLevel ) ;
539
577
}
578
+ }
579
+
580
+ [ Fact ]
581
+ public async Task SessionLogsCacheRefreshException ( )
582
+ {
583
+ var sink = new TestSink ( ) ;
584
+ var loggerFactory = new TestLoggerFactory ( sink , enabled : true ) ;
585
+ var builder = new WebHostBuilder ( )
586
+ . Configure ( app =>
587
+ {
588
+ app . UseSession ( ) ;
589
+ app . Run ( context =>
590
+ {
591
+ // The middleware calls context.Session.CommitAsync() once per request
592
+ return Task . FromResult ( 0 ) ;
593
+ } ) ;
594
+ } )
595
+ . ConfigureServices ( services =>
596
+ {
597
+ services . AddSingleton ( typeof ( ILoggerFactory ) , loggerFactory ) ;
598
+ services . AddSingleton < IDistributedCache > ( new UnreliableCache ( new MemoryCache ( new MemoryCacheOptions ( ) ) )
599
+ {
600
+ DisableRefreshAsync = true
601
+ } ) ;
602
+ services . AddSession ( ) ;
603
+ } ) ;
540
604
541
- public Task < byte [ ] > GetAsync ( string key )
605
+ using ( var server = new TestServer ( builder ) )
542
606
{
543
- throw new NotImplementedException ( ) ;
607
+ var client = server . CreateClient ( ) ;
608
+ var response = await client . GetAsync ( string . Empty ) ;
609
+ response . EnsureSuccessStatusCode ( ) ;
610
+
611
+ var sessionLogMessages = sink . Writes . OnlyMessagesFromSource < DistributedSession > ( ) . ToArray ( ) ;
612
+
613
+ Assert . Equal ( 1 , sessionLogMessages . Length ) ;
614
+ Assert . Contains ( "Session cache refresh exception" , sessionLogMessages [ 0 ] . State . ToString ( ) ) ;
615
+ Assert . Equal ( LogLevel . Error , sessionLogMessages [ 0 ] . LogLevel ) ;
544
616
}
617
+ }
545
618
546
- public void Refresh ( string key )
619
+ private class TestClock : ISystemClock
620
+ {
621
+ public TestClock ( )
547
622
{
548
- throw new NotImplementedException ( ) ;
623
+ UtcNow = new DateTimeOffset ( 2013 , 1 , 1 , 1 , 0 , 0 , TimeSpan . Zero ) ;
549
624
}
550
625
551
- public Task RefreshAsync ( string key )
626
+ public DateTimeOffset UtcNow { get ; private set ; }
627
+
628
+ public void Add ( TimeSpan timespan )
552
629
{
553
- throw new NotImplementedException ( ) ;
630
+ UtcNow = UtcNow . Add ( timespan ) ;
554
631
}
632
+ }
633
+
634
+ private class UnreliableCache : IDistributedCache
635
+ {
636
+ private readonly MemoryDistributedCache _cache ;
637
+
638
+ public bool DisableGet { get ; set ; }
639
+ public bool DisableSetAsync { get ; set ; }
640
+ public bool DisableRefreshAsync { get ; set ; }
555
641
556
- public void Remove ( string key )
642
+ public UnreliableCache ( IMemoryCache memoryCache )
557
643
{
558
- throw new NotImplementedException ( ) ;
644
+ _cache = new MemoryDistributedCache ( memoryCache ) ;
559
645
}
560
646
561
- public Task RemoveAsync ( string key )
647
+ public byte [ ] Get ( string key )
562
648
{
563
- throw new NotImplementedException ( ) ;
649
+ if ( DisableGet )
650
+ {
651
+ throw new InvalidOperationException ( ) ;
652
+ }
653
+ return _cache . Get ( key ) ;
564
654
}
565
-
566
- public void Set ( string key , byte [ ] value , DistributedCacheEntryOptions options )
655
+ public Task < byte [ ] > GetAsync ( string key ) => _cache . GetAsync ( key ) ;
656
+ public void Refresh ( string key ) => _cache . Refresh ( key ) ;
657
+ public Task RefreshAsync ( string key )
567
658
{
568
- throw new NotImplementedException ( ) ;
659
+ if ( DisableRefreshAsync )
660
+ {
661
+ throw new InvalidOperationException ( ) ;
662
+ }
663
+ return _cache . RefreshAsync ( key ) ;
569
664
}
570
-
665
+ public void Remove ( string key ) => _cache . Remove ( key ) ;
666
+ public Task RemoveAsync ( string key ) => _cache . RemoveAsync ( key ) ;
667
+ public void Set ( string key , byte [ ] value , DistributedCacheEntryOptions options ) => _cache . Set ( key , value , options ) ;
571
668
public Task SetAsync ( string key , byte [ ] value , DistributedCacheEntryOptions options )
572
669
{
573
- throw new NotImplementedException ( ) ;
670
+ if ( DisableSetAsync )
671
+ {
672
+ throw new InvalidOperationException ( ) ;
673
+ }
674
+ return _cache . SetAsync ( key , value , options ) ;
574
675
}
575
676
}
576
677
}
0 commit comments