@@ -97,7 +97,7 @@ impl FileDownloader for RetryDownloader {
97
97
#[ cfg( test) ]
98
98
mod tests {
99
99
100
- use std:: time:: Instant ;
100
+ use std:: { sync :: Mutex , time:: Instant } ;
101
101
102
102
use mithril_common:: entities:: FileUri ;
103
103
@@ -227,22 +227,59 @@ mod tests {
227
227
228
228
#[ tokio:: test]
229
229
async fn should_delay_between_retries ( ) {
230
- let mock_file_downloader = MockFileDownloaderBuilder :: default ( )
231
- . with_file_uri ( "http://whatever/00001.tar.gz" )
232
- . with_compression ( None )
233
- . with_failure ( )
234
- . with_times ( 4 )
235
- . build ( ) ;
236
- let delay = Duration :: from_millis ( 50 ) ;
230
+ struct FileDownloaderAssertDelay {
231
+ expected_delay_greater_than_or_equal : Duration ,
232
+ expected_delay_less_than : Duration ,
233
+ last_attempt_start_time : Mutex < Option < Instant > > ,
234
+ }
235
+
236
+ #[ async_trait]
237
+ impl FileDownloader for FileDownloaderAssertDelay {
238
+ async fn download_unpack (
239
+ & self ,
240
+ _location : & FileDownloaderUri ,
241
+ _file_size : u64 ,
242
+ _target_dir : & Path ,
243
+ _compression_algorithm : Option < CompressionAlgorithm > ,
244
+ _download_event_type : DownloadEvent ,
245
+ ) -> StdResult < ( ) > {
246
+ let mut last_attempt_start_time = self . last_attempt_start_time . lock ( ) . unwrap ( ) ;
247
+ if let Some ( last_start_attempt) = * last_attempt_start_time {
248
+ let duration = last_start_attempt. elapsed ( ) ;
249
+ assert ! (
250
+ duration >= self . expected_delay_greater_than_or_equal,
251
+ "duration should be greater than or equal to {}ms but was {}ms" ,
252
+ self . expected_delay_greater_than_or_equal. as_millis( ) ,
253
+ duration. as_millis( )
254
+ ) ;
255
+ assert ! (
256
+ duration < self . expected_delay_less_than,
257
+ "duration should be less than {}ms but was {}ms" ,
258
+ self . expected_delay_less_than. as_millis( ) ,
259
+ duration. as_millis( )
260
+ ) ;
261
+ }
262
+ * last_attempt_start_time = Some ( Instant :: now ( ) ) ;
263
+
264
+ Err ( anyhow:: anyhow!( "Download failed" ) )
265
+ }
266
+ }
267
+
268
+ let delay_ms = 50 ;
269
+ let mock_file_downloader = Arc :: new ( FileDownloaderAssertDelay {
270
+ expected_delay_greater_than_or_equal : Duration :: from_millis ( delay_ms) ,
271
+ expected_delay_less_than : Duration :: from_millis ( 2 * delay_ms) ,
272
+ last_attempt_start_time : Mutex :: new ( None ) ,
273
+ } ) ;
274
+
237
275
let retry_downloader = RetryDownloader :: new (
238
- Arc :: new ( mock_file_downloader) ,
276
+ mock_file_downloader. clone ( ) ,
239
277
FileDownloadRetryPolicy {
240
278
attempts : 4 ,
241
- delay_between_attempts : delay ,
279
+ delay_between_attempts : Duration :: from_millis ( delay_ms ) ,
242
280
} ,
243
281
) ;
244
282
245
- let start = Instant :: now ( ) ;
246
283
retry_downloader
247
284
. download_unpack (
248
285
& FileDownloaderUri :: FileUri ( FileUri ( "http://whatever/00001.tar.gz" . to_string ( ) ) ) ,
@@ -256,19 +293,5 @@ mod tests {
256
293
)
257
294
. await
258
295
. expect_err ( "An error should be returned when all download attempts fail" ) ;
259
- let duration = start. elapsed ( ) ;
260
-
261
- assert ! (
262
- duration >= delay * 3 ,
263
- "Duration should be at least 3 times the delay ({}ms) but was {}ms" ,
264
- delay. as_millis( ) * 3 ,
265
- duration. as_millis( )
266
- ) ;
267
- assert ! (
268
- duration < delay * 4 ,
269
- "Duration should be less than 4 times the delay ({}ms) but was {}ms" ,
270
- delay. as_millis( ) * 4 ,
271
- duration. as_millis( )
272
- ) ;
273
296
}
274
297
}
0 commit comments