@@ -331,7 +331,7 @@ public async Task SessionStart_LogsInformation()
331
331
}
332
332
333
333
[ Fact ]
334
- public async Task ExpiredSession_LogsWarning ( )
334
+ public async Task ExpiredSession_LogsInfo ( )
335
335
{
336
336
var sink = new TestSink (
337
337
TestSink . EnableWithTypeName < DistributedSession > ,
@@ -388,7 +388,7 @@ public async Task ExpiredSession_LogsWarning()
388
388
Assert . Contains ( "expired" , sessionLogMessages [ 2 ] . State . ToString ( ) ) ;
389
389
Assert . Equal ( LogLevel . Information , sessionLogMessages [ 0 ] . LogLevel ) ;
390
390
Assert . Equal ( LogLevel . Debug , sessionLogMessages [ 1 ] . LogLevel ) ;
391
- Assert . Equal ( LogLevel . Warning , sessionLogMessages [ 2 ] . LogLevel ) ;
391
+ Assert . Equal ( LogLevel . Information , sessionLogMessages [ 2 ] . LogLevel ) ;
392
392
}
393
393
394
394
[ Fact ]
@@ -603,7 +603,90 @@ public async Task SessionLogsCacheReadException()
603
603
}
604
604
605
605
[ Fact ]
606
- public async Task SessionLogsCacheWriteException ( )
606
+ public async Task SessionLogsCacheLoadAsyncException ( )
607
+ {
608
+ var sink = new TestSink (
609
+ TestSink . EnableWithTypeName < DistributedSession > ,
610
+ TestSink . EnableWithTypeName < DistributedSession > ) ;
611
+ var loggerFactory = new TestLoggerFactory ( sink , enabled : true ) ;
612
+ var builder = new WebHostBuilder ( )
613
+ . Configure ( app =>
614
+ {
615
+ app . UseSession ( ) ;
616
+ app . Run ( async context =>
617
+ {
618
+ await Assert . ThrowsAsync < InvalidOperationException > ( ( ) => context . Session . LoadAsync ( ) ) ;
619
+ Assert . False ( context . Session . IsAvailable ) ;
620
+ Assert . Equal ( string . Empty , context . Session . Id ) ;
621
+ Assert . False ( context . Session . Keys . Any ( ) ) ;
622
+ } ) ;
623
+ } )
624
+ . ConfigureServices ( services =>
625
+ {
626
+ services . AddSingleton ( typeof ( ILoggerFactory ) , loggerFactory ) ;
627
+ services . AddSingleton < IDistributedCache > ( new UnreliableCache ( new MemoryCache ( new MemoryCacheOptions ( ) ) )
628
+ {
629
+ DisableGet = true
630
+ } ) ;
631
+ services . AddSession ( ) ;
632
+ } ) ;
633
+
634
+ using ( var server = new TestServer ( builder ) )
635
+ {
636
+ var client = server . CreateClient ( ) ;
637
+ var response = await client . GetAsync ( string . Empty ) ;
638
+ response . EnsureSuccessStatusCode ( ) ;
639
+ }
640
+
641
+ var sessionLogMessages = sink . Writes ;
642
+
643
+ Assert . Single ( sessionLogMessages ) ;
644
+ Assert . Contains ( "Session cache read exception" , sessionLogMessages [ 0 ] . State . ToString ( ) ) ;
645
+ Assert . Equal ( LogLevel . Error , sessionLogMessages [ 0 ] . LogLevel ) ;
646
+ }
647
+
648
+ [ Fact ]
649
+ public async Task SessionLoadAsyncCanceledException ( )
650
+ {
651
+ var sink = new TestSink (
652
+ TestSink . EnableWithTypeName < DistributedSession > ,
653
+ TestSink . EnableWithTypeName < DistributedSession > ) ;
654
+ var loggerFactory = new TestLoggerFactory ( sink , enabled : true ) ;
655
+ var builder = new WebHostBuilder ( )
656
+ . Configure ( app =>
657
+ {
658
+ app . UseSession ( ) ;
659
+ app . Run ( async context =>
660
+ {
661
+ var cts = new CancellationTokenSource ( ) ;
662
+ var token = cts . Token ;
663
+ cts . Cancel ( ) ;
664
+ await Assert . ThrowsAsync < OperationCanceledException > ( ( ) => context . Session . LoadAsync ( token ) ) ;
665
+ } ) ;
666
+ } )
667
+ . ConfigureServices ( services =>
668
+ {
669
+ services . AddSingleton ( typeof ( ILoggerFactory ) , loggerFactory ) ;
670
+ services . AddSingleton < IDistributedCache > ( new UnreliableCache ( new MemoryCache ( new MemoryCacheOptions ( ) ) )
671
+ {
672
+ DelayGetAsync = true
673
+ } ) ;
674
+ services . AddSession ( ) ;
675
+ } ) ;
676
+
677
+ using ( var server = new TestServer ( builder ) )
678
+ {
679
+ var client = server . CreateClient ( ) ;
680
+ var response = await client . GetAsync ( string . Empty ) ;
681
+ response . EnsureSuccessStatusCode ( ) ;
682
+ }
683
+
684
+ var sessionLogMessages = sink . Writes ;
685
+ Assert . Empty ( sessionLogMessages ) ;
686
+ }
687
+
688
+ [ Fact ]
689
+ public async Task SessionLogsCacheCommitException ( )
607
690
{
608
691
var sink = new TestSink (
609
692
writeContext =>
@@ -655,6 +738,116 @@ public async Task SessionLogsCacheWriteException()
655
738
Assert . Equal ( LogLevel . Error , sessionMiddlewareLogMessage . LogLevel ) ;
656
739
}
657
740
741
+ [ Fact ]
742
+ public async Task SessionLogsCacheCommitTimeoutException ( )
743
+ {
744
+ var sink = new TestSink (
745
+ writeContext =>
746
+ {
747
+ return writeContext . LoggerName . Equals ( typeof ( SessionMiddleware ) . FullName )
748
+ || writeContext . LoggerName . Equals ( typeof ( DistributedSession ) . FullName ) ;
749
+ } ,
750
+ beginScopeContext =>
751
+ {
752
+ return beginScopeContext . LoggerName . Equals ( typeof ( SessionMiddleware ) . FullName )
753
+ || beginScopeContext . LoggerName . Equals ( typeof ( DistributedSession ) . FullName ) ;
754
+ } ) ;
755
+ var loggerFactory = new TestLoggerFactory ( sink , enabled : true ) ;
756
+ var builder = new WebHostBuilder ( )
757
+ . Configure ( app =>
758
+ {
759
+ app . UseSession ( new SessionOptions ( )
760
+ {
761
+ IOTimeout = TimeSpan . FromSeconds ( 0.5 )
762
+ } ) ;
763
+ app . Run ( context =>
764
+ {
765
+ context . Session . SetInt32 ( "key" , 0 ) ;
766
+ return Task . FromResult ( 0 ) ;
767
+ } ) ;
768
+ } )
769
+ . ConfigureServices ( services =>
770
+ {
771
+ services . AddSingleton ( typeof ( ILoggerFactory ) , loggerFactory ) ;
772
+ services . AddSingleton < IDistributedCache > ( new UnreliableCache ( new MemoryCache ( new MemoryCacheOptions ( ) ) )
773
+ {
774
+ DelaySetAsync = true
775
+ } ) ;
776
+ services . AddSession ( ) ;
777
+ } ) ;
778
+
779
+ using ( var server = new TestServer ( builder ) )
780
+ {
781
+ var client = server . CreateClient ( ) ;
782
+ var response = await client . GetAsync ( string . Empty ) ;
783
+ response . EnsureSuccessStatusCode ( ) ;
784
+ }
785
+
786
+ var sessionLogMessages = sink . Writes . Where ( message => message . LoggerName . Equals ( typeof ( DistributedSession ) . FullName , StringComparison . Ordinal ) ) . ToList ( ) ;
787
+
788
+ Assert . Contains ( "Session started" , sessionLogMessages [ 0 ] . State . ToString ( ) ) ;
789
+ Assert . Equal ( LogLevel . Information , sessionLogMessages [ 0 ] . LogLevel ) ;
790
+
791
+ var sessionMiddlewareLogs = sink . Writes . Where ( message => message . LoggerName . Equals ( typeof ( SessionMiddleware ) . FullName , StringComparison . Ordinal ) ) . ToList ( ) ;
792
+
793
+ Assert . Contains ( "Committing the session was canceled." , sessionMiddlewareLogs [ 0 ] . State . ToString ( ) ) ;
794
+ Assert . Equal ( LogLevel . Information , sessionMiddlewareLogs [ 0 ] . LogLevel ) ;
795
+ }
796
+
797
+ [ Fact ]
798
+ public async Task SessionLogsCacheCommitCanceledException ( )
799
+ {
800
+ var sink = new TestSink (
801
+ writeContext =>
802
+ {
803
+ return writeContext . LoggerName . Equals ( typeof ( SessionMiddleware ) . FullName )
804
+ || writeContext . LoggerName . Equals ( typeof ( DistributedSession ) . FullName ) ;
805
+ } ,
806
+ beginScopeContext =>
807
+ {
808
+ return beginScopeContext . LoggerName . Equals ( typeof ( SessionMiddleware ) . FullName )
809
+ || beginScopeContext . LoggerName . Equals ( typeof ( DistributedSession ) . FullName ) ;
810
+ } ) ;
811
+ var loggerFactory = new TestLoggerFactory ( sink , enabled : true ) ;
812
+ var builder = new WebHostBuilder ( )
813
+ . Configure ( app =>
814
+ {
815
+ app . UseSession ( ) ;
816
+ app . Run ( async context =>
817
+ {
818
+ context . Session . SetInt32 ( "key" , 0 ) ;
819
+ var cts = new CancellationTokenSource ( ) ;
820
+ var token = cts . Token ;
821
+ cts . Cancel ( ) ;
822
+ await Assert . ThrowsAsync < OperationCanceledException > ( ( ) => context . Session . CommitAsync ( token ) ) ;
823
+ context . RequestAborted = token ;
824
+ } ) ;
825
+ } )
826
+ . ConfigureServices ( services =>
827
+ {
828
+ services . AddSingleton ( typeof ( ILoggerFactory ) , loggerFactory ) ;
829
+ services . AddSingleton < IDistributedCache > ( new UnreliableCache ( new MemoryCache ( new MemoryCacheOptions ( ) ) )
830
+ {
831
+ DelaySetAsync = true
832
+ } ) ;
833
+ services . AddSession ( ) ;
834
+ } ) ;
835
+
836
+ using ( var server = new TestServer ( builder ) )
837
+ {
838
+ var client = server . CreateClient ( ) ;
839
+ var response = await client . GetAsync ( string . Empty ) ;
840
+ response . EnsureSuccessStatusCode ( ) ;
841
+ }
842
+
843
+ Assert . Empty ( sink . Writes . Where ( message => message . LoggerName . Equals ( typeof ( DistributedSession ) . FullName , StringComparison . Ordinal ) ) ) ;
844
+
845
+ var sessionMiddlewareLogs = sink . Writes . Where ( message => message . LoggerName . Equals ( typeof ( SessionMiddleware ) . FullName , StringComparison . Ordinal ) ) . ToList ( ) ;
846
+
847
+ Assert . Contains ( "Committing the session was canceled." , sessionMiddlewareLogs [ 0 ] . State . ToString ( ) ) ;
848
+ Assert . Equal ( LogLevel . Information , sessionMiddlewareLogs [ 0 ] . LogLevel ) ;
849
+ }
850
+
658
851
[ Fact ]
659
852
public async Task SessionLogsCacheRefreshException ( )
660
853
{
@@ -718,6 +911,9 @@ private class UnreliableCache : IDistributedCache
718
911
public bool DisableGet { get ; set ; }
719
912
public bool DisableSetAsync { get ; set ; }
720
913
public bool DisableRefreshAsync { get ; set ; }
914
+ public bool DelayGetAsync { get ; set ; }
915
+ public bool DelaySetAsync { get ; set ; }
916
+ public bool DelayRefreshAsync { get ; set ; }
721
917
722
918
public UnreliableCache ( IMemoryCache memoryCache )
723
919
{
@@ -732,25 +928,54 @@ public byte[] Get(string key)
732
928
}
733
929
return _cache . Get ( key ) ;
734
930
}
735
- public Task < byte [ ] > GetAsync ( string key , CancellationToken token = default ( CancellationToken ) ) => _cache . GetAsync ( key ) ;
931
+
932
+ public Task < byte [ ] > GetAsync ( string key , CancellationToken token = default ( CancellationToken ) )
933
+ {
934
+ if ( DisableGet )
935
+ {
936
+ throw new InvalidOperationException ( ) ;
937
+ }
938
+ if ( DelayGetAsync )
939
+ {
940
+ token . WaitHandle . WaitOne ( TimeSpan . FromSeconds ( 10 ) ) ;
941
+ token . ThrowIfCancellationRequested ( ) ;
942
+ }
943
+ return _cache . GetAsync ( key , token ) ;
944
+ }
945
+
736
946
public void Refresh ( string key ) => _cache . Refresh ( key ) ;
947
+
737
948
public Task RefreshAsync ( string key , CancellationToken token = default ( CancellationToken ) )
738
949
{
739
950
if ( DisableRefreshAsync )
740
951
{
741
952
throw new InvalidOperationException ( ) ;
742
953
}
954
+ if ( DelayRefreshAsync )
955
+ {
956
+ token . WaitHandle . WaitOne ( TimeSpan . FromSeconds ( 10 ) ) ;
957
+ token . ThrowIfCancellationRequested ( ) ;
958
+ }
743
959
return _cache . RefreshAsync ( key ) ;
744
960
}
961
+
745
962
public void Remove ( string key ) => _cache . Remove ( key ) ;
963
+
746
964
public Task RemoveAsync ( string key , CancellationToken token = default ( CancellationToken ) ) => _cache . RemoveAsync ( key ) ;
965
+
747
966
public void Set ( string key , byte [ ] value , DistributedCacheEntryOptions options ) => _cache . Set ( key , value , options ) ;
967
+
748
968
public Task SetAsync ( string key , byte [ ] value , DistributedCacheEntryOptions options , CancellationToken token = default ( CancellationToken ) )
749
969
{
750
970
if ( DisableSetAsync )
751
971
{
752
972
throw new InvalidOperationException ( ) ;
753
973
}
974
+ if ( DelaySetAsync )
975
+ {
976
+ token . WaitHandle . WaitOne ( TimeSpan . FromSeconds ( 10 ) ) ;
977
+ token . ThrowIfCancellationRequested ( ) ;
978
+ }
754
979
return _cache . SetAsync ( key , value , options ) ;
755
980
}
756
981
}
0 commit comments