@@ -38,7 +38,7 @@ public void AwaitCondition(Func<bool> conditionIsFulfilled, CancellationToken ca
38
38
AwaitConditionAsync ( async ( ) => conditionIsFulfilled ( ) , cancellationToken )
39
39
. WaitAndUnwrapException ( ) ;
40
40
}
41
-
41
+
42
42
public async Task AwaitConditionAsync ( Func < Task < bool > > conditionIsFulfilled , CancellationToken cancellationToken = default )
43
43
{
44
44
var maxDur = RemainingOrDefault ;
@@ -71,15 +71,15 @@ public void AwaitCondition(Func<bool> conditionIsFulfilled, TimeSpan? max, Cance
71
71
AwaitConditionAsync ( async ( ) => conditionIsFulfilled ( ) , max , cancellationToken )
72
72
. WaitAndUnwrapException ( cancellationToken ) ;
73
73
}
74
-
74
+
75
75
public async Task AwaitConditionAsync ( Func < Task < bool > > conditionIsFulfilled , TimeSpan ? max , CancellationToken cancellationToken = default )
76
76
{
77
77
var maxDur = RemainingOrDilated ( max ) ;
78
78
var interval = new TimeSpan ( maxDur . Ticks / 10 ) ;
79
79
var logger = _testState . TestKitSettings . LogTestKitCalls ? _testState . Log : null ;
80
80
await InternalAwaitConditionAsync ( conditionIsFulfilled , maxDur , interval , ( format , args ) => _assertions . Fail ( format , args ) , logger , cancellationToken ) ;
81
81
}
82
-
82
+
83
83
/// <summary>
84
84
/// <para>Await until the given condition evaluates to <c>true</c> or the timeout
85
85
/// expires, whichever comes first.</para>
@@ -105,7 +105,7 @@ public void AwaitCondition(Func<bool> conditionIsFulfilled, TimeSpan? max, strin
105
105
AwaitConditionAsync ( async ( ) => conditionIsFulfilled ( ) , max , message , cancellationToken )
106
106
. WaitAndUnwrapException ( ) ;
107
107
}
108
-
108
+
109
109
public async Task AwaitConditionAsync ( Func < Task < bool > > conditionIsFulfilled , TimeSpan ? max , string message , CancellationToken cancellationToken = default )
110
110
{
111
111
var maxDur = RemainingOrDilated ( max ) ;
@@ -143,16 +143,16 @@ public async Task AwaitConditionAsync(Func<Task<bool>> conditionIsFulfilled, Tim
143
143
/// <param name="message">The message used if the timeout expires.</param>
144
144
/// <param name="cancellationToken"></param>
145
145
public void AwaitCondition ( Func < bool > conditionIsFulfilled , TimeSpan ? max , TimeSpan ? interval , string message = null , CancellationToken cancellationToken = default )
146
- {
146
+ {
147
147
AwaitConditionAsync ( async ( ) => conditionIsFulfilled ( ) , max , interval , message , cancellationToken )
148
148
. WaitAndUnwrapException ( cancellationToken ) ;
149
149
}
150
-
150
+
151
151
public async Task AwaitConditionAsync ( Func < Task < bool > > conditionIsFulfilled , TimeSpan ? max , TimeSpan ? interval , string message = null , CancellationToken cancellationToken = default )
152
152
{
153
153
var maxDur = RemainingOrDilated ( max ) ;
154
154
var logger = _testState . TestKitSettings . LogTestKitCalls ? _testState . Log : null ;
155
- await InternalAwaitConditionAsync ( conditionIsFulfilled , maxDur , interval ,
155
+ await InternalAwaitConditionAsync ( conditionIsFulfilled , maxDur , interval ,
156
156
( format , args ) => AssertionsFail ( format , args , message ) , logger , cancellationToken ) ;
157
157
}
158
158
@@ -179,7 +179,7 @@ public bool AwaitConditionNoThrow(Func<bool> conditionIsFulfilled, TimeSpan max,
179
179
return AwaitConditionNoThrowAsync ( async ( ) => conditionIsFulfilled ( ) , max , interval , cancellationToken )
180
180
. WaitAndUnwrapException ( cancellationToken ) ;
181
181
}
182
-
182
+
183
183
public Task < bool > AwaitConditionNoThrowAsync ( Func < Task < bool > > conditionIsFulfilled , TimeSpan max , TimeSpan ? interval = null , CancellationToken cancellationToken = default )
184
184
{
185
185
var intervalDur = interval . GetValueOrDefault ( TimeSpan . FromMilliseconds ( 100 ) ) ;
@@ -218,7 +218,7 @@ protected static bool InternalAwaitCondition(Func<bool> conditionIsFulfilled, Ti
218
218
{
219
219
return InternalAwaitCondition ( conditionIsFulfilled , max , interval , fail , null , cancellationToken ) ;
220
220
}
221
-
221
+
222
222
protected static Task < bool > InternalAwaitConditionAsync ( Func < Task < bool > > conditionIsFulfilled , TimeSpan max , TimeSpan ? interval , Action < string , object [ ] > fail
223
223
, CancellationToken cancellationToken = default )
224
224
{
@@ -258,7 +258,7 @@ protected static bool InternalAwaitCondition(Func<bool> conditionIsFulfilled, Ti
258
258
{
259
259
return InternalAwaitConditionAsync ( async ( ) => conditionIsFulfilled ( ) , max , interval , fail , logger , cancellationToken )
260
260
. WaitAndUnwrapException ( cancellationToken ) ;
261
-
261
+
262
262
}
263
263
264
264
protected static async Task < bool > InternalAwaitConditionAsync ( Func < Task < bool > > conditionIsFulfilled , TimeSpan max , TimeSpan ? interval , Action < string , object [ ] > fail , ILoggingAdapter logger , CancellationToken cancellationToken = default )
@@ -293,10 +293,59 @@ protected static async Task<bool> InternalAwaitConditionAsync(Func<Task<bool>> c
293
293
return true ;
294
294
}
295
295
296
- private static void ConditionalLog ( ILoggingAdapter logger , string format , params object [ ] args )
296
+ protected void AwaitCond ( Func < bool > p , TimeSpan ? max = null , TimeSpan ? interval = null , string message = "" )
297
297
{
298
- if ( logger != null )
299
- logger . Debug ( format , args ) ;
298
+ if ( interval == null ) interval = TimeSpan . FromMilliseconds ( 100 ) ;
299
+
300
+ var dilatedMax = RemainingOrDilated ( max ) ;
301
+ var stop = Now + dilatedMax ;
302
+
303
+ void Poll ( TimeSpan t )
304
+ {
305
+ if ( ! p ( ) )
306
+ {
307
+ _assertions . AssertTrue ( Now < stop , $ "timeout { dilatedMax } expired: { message } ") ;
308
+ Thread . Sleep ( t ) ;
309
+ Poll ( ( stop - Now ) . Min ( interval . Value ) ) ;
310
+ }
311
+ }
312
+
313
+ Poll ( dilatedMax . Min ( interval . Value ) ) ;
300
314
}
315
+
316
+ protected void Within ( TimeSpan max , Action f ) =>
317
+ Within ( TimeSpan . Zero , max , f ) ;
318
+
319
+ protected void Within ( TimeSpan min , TimeSpan max , Action f )
320
+ {
321
+ var dilatedMax = Dilated ( max ) ;
322
+ var start = Now ;
323
+ var rem = _testState . End . HasValue ? _testState . End . Value - start : Timeout . InfiniteTimeSpan ;
324
+ _assertions . AssertTrue ( rem . IsInfiniteTimeout ( ) || rem >= min , "Required min time {0} not possible, only {1} left." , min , rem ) ;
325
+
326
+ _testState . LastWasNoMsg = false ;
327
+
328
+ var maxDiff = dilatedMax . Min ( rem ) ;
329
+ var prevEnd = _testState . End ;
330
+ _testState . End = start + maxDiff ;
331
+
332
+ try
333
+ {
334
+ f ( ) ;
335
+ }
336
+ finally
337
+ {
338
+ _testState . End = prevEnd ;
339
+ }
340
+
341
+ var diff = Now - start ;
342
+ _assertions . AssertTrue ( min <= diff , $ "block took { diff } , should at least have been { min } ") ;
343
+ if ( ! _testState . LastWasNoMsg )
344
+ {
345
+ _assertions . AssertTrue ( diff <= maxDiff , $ "block took { diff } , exceeding { maxDiff } ") ;
346
+ }
347
+ }
348
+
349
+ private static void ConditionalLog ( ILoggingAdapter logger , string format , params object [ ] args ) => logger ? . Info ( format , args ) ;
301
350
}
302
351
}
0 commit comments