@@ -44,6 +44,68 @@ public void WhenMinPoolSizeIsSet_NewPoolFillsToMin()
4444 Task . Delay ( 1000 ) . Wait ( ) ;
4545
4646 Assert . AreEqual ( 10 , pool . PoolSize ) ;
47+ Assert . AreEqual ( 10 , pool . Available ) ;
48+ }
49+
50+ [ Test ]
51+ public void WhenMinPoolSizeIsSet_ButThereIsChanceOfFailure_PoolSizeMatchesAvailableCount ( )
52+ {
53+ var parameters = new TestConnectionParameters
54+ {
55+ MinPoolSize = 10
56+ } ;
57+ var pool = new ConnectionPool ( parameters , new SequenceSuccessImmediateConnectionFactory ( true , false ) ) ;
58+
59+ Task . Delay ( 1000 ) . Wait ( ) ;
60+
61+ Assert . AreEqual ( 10 , pool . PoolSize ) ;
62+ Assert . AreEqual ( 10 , pool . Available ) ;
63+ }
64+
65+ [ Test ]
66+ public void RemoveAndReplace_ReplacesToMin ( )
67+ {
68+ var parameters = new TestConnectionParameters
69+ {
70+ MinPoolSize = 10
71+ } ;
72+ var pool = new ConnectionPool ( parameters , new ImmediateConnectionFactory ( ) ) ;
73+
74+ Task . Delay ( 1000 ) . Wait ( ) ;
75+
76+ Assert . AreEqual ( 10 , pool . PoolSize ) ;
77+ Assert . AreEqual ( 10 , pool . Available ) ;
78+
79+ var c = pool . Reserve ( null ) ;
80+ c . IsDoomed = true ;
81+ pool . Release ( c ) ;
82+ Task . Delay ( 1000 ) . Wait ( ) ;
83+
84+ Assert . AreEqual ( 10 , pool . PoolSize ) ;
85+ Assert . AreEqual ( 10 , pool . Available ) ;
86+ }
87+
88+ [ Test ]
89+ public void RemoveAndReplace_ButThereIsReplacementFailure_DoesNotReplace ( )
90+ {
91+ var parameters = new TestConnectionParameters
92+ {
93+ MinPoolSize = 2
94+ } ;
95+ var pool = new ConnectionPool ( parameters , new SequenceSuccessImmediateConnectionFactory ( true , true , false ) ) ;
96+
97+ Task . Delay ( 1000 ) . Wait ( ) ;
98+
99+ Assert . AreEqual ( 2 , pool . PoolSize ) ;
100+ Assert . AreEqual ( 2 , pool . Available ) ;
101+
102+ var c = pool . Reserve ( null ) ;
103+ c . IsDoomed = true ;
104+ pool . Release ( c ) ;
105+ Task . Delay ( 1000 ) . Wait ( ) ;
106+
107+ Assert . AreEqual ( 1 , pool . PoolSize ) ;
108+ Assert . AreEqual ( 1 , pool . Available ) ;
47109 }
48110
49111 [ Test ]
@@ -57,11 +119,12 @@ public void WhenChangeDatabaseThrows_PoolDoesNotLeak()
57119
58120 var pool = new ConnectionPool ( parameters , new ImmediateConnectionFactory ( changeDatabaseThrows : true ) ) ;
59121
60- for ( int i = 0 ; i < 5 ; i ++ )
122+ for ( int i = 0 ; i < 5 ; i ++ )
61123 {
62124 Assert . Throws < AseException > ( ( ) => pool . Reserve ( null ) ) ;
63125 }
64126 Assert . AreEqual ( 0 , pool . PoolSize ) ;
127+ Assert . AreEqual ( 0 , pool . Available ) ;
65128 }
66129
67130 [ Test ]
@@ -78,7 +141,10 @@ public void NewOpenCall_TimesOut_ShouldThrow()
78141 Assert . Throws < AseException > ( ( ) => pool . Reserve ( null ) ) ;
79142
80143 Assert . AreEqual ( 1 , pool . PoolSize ) ;
144+ Assert . AreEqual ( 0 , pool . Available ) ;
81145 pool . Release ( c1 ) ;
146+ Assert . AreEqual ( 1 , pool . PoolSize ) ;
147+ Assert . AreEqual ( 1 , pool . Available ) ;
82148 }
83149
84150 /// <summary>
@@ -127,7 +193,7 @@ public void PoolSpam_Waves(short size, int waves)
127193 ExceptionDispatchInfo . Capture ( ae . InnerException ?? ae ) . Throw ( ) ;
128194 throw ;
129195 }
130-
196+
131197 connections = reserveTask . Result ;
132198 }
133199
@@ -185,6 +251,35 @@ public async Task<IInternalConnection> GetNewConnection(CancellationToken token,
185251 }
186252 }
187253
254+ private class SequenceSuccessImmediateConnectionFactory : IInternalConnectionFactory
255+ {
256+ private int _idxNext ;
257+ private readonly bool [ ] _sequence ;
258+
259+ public SequenceSuccessImmediateConnectionFactory ( params bool [ ] sequence )
260+ {
261+ _idxNext = 0 ;
262+ _sequence = sequence ?? new [ ] { true , false } ;
263+ }
264+
265+ private bool IsSuccessful ( )
266+ {
267+ var next = _sequence [ _idxNext ] ;
268+ _idxNext = ( _idxNext + 1 ) % _sequence . Length ;
269+ return next ;
270+ }
271+
272+ public async Task < IInternalConnection > GetNewConnection ( CancellationToken token , IInfoMessageEventNotifier eventNotifier )
273+ {
274+ if ( IsSuccessful ( ) )
275+ {
276+ return await Task . FromResult < IInternalConnection > ( new DoNothingInternalConnection ( ) ) ;
277+ }
278+
279+ throw new Exception ( ) ;
280+ }
281+ }
282+
188283 [ SuppressMessage ( "ReSharper" , "UnassignedGetOnlyAutoProperty" ) ]
189284 [ SuppressMessage ( "ReSharper" , "UnusedMember.Local" ) ]
190285 private class DoNothingInternalConnection : IInternalConnection
0 commit comments