@@ -67,7 +67,7 @@ pub trait FileUploader: Sync + Send {
67
67
68
68
#[ cfg( test) ]
69
69
mod tests {
70
- use std:: { path:: PathBuf , time:: Instant } ;
70
+ use std:: { path:: PathBuf , sync :: Mutex , time:: Instant } ;
71
71
72
72
use super :: * ;
73
73
use anyhow:: anyhow;
@@ -172,39 +172,53 @@ mod tests {
172
172
173
173
#[ tokio:: test]
174
174
async fn should_delay_between_retries ( ) {
175
- let mut uploader = MockTestFileUploader :: new ( ) ;
175
+ struct FileUploaderAssertDelay {
176
+ delay_ms : u64 ,
177
+ last_attempt_start_time : Mutex < Option < Instant > > ,
178
+ }
176
179
177
- let delay = Duration :: from_millis ( 50 ) ;
178
- uploader
179
- . expect_retry_policy ( )
180
- . returning ( move || FileUploadRetryPolicy {
181
- attempts : 4 ,
182
- delay_between_attempts : delay,
183
- } ) ;
180
+ #[ async_trait]
181
+ impl FileUploader for FileUploaderAssertDelay {
182
+ async fn upload_without_retry ( & self , _filepath : & Path ) -> StdResult < FileUri > {
183
+ let mut last_attempt_start_time = self . last_attempt_start_time . lock ( ) . unwrap ( ) ;
184
+ if let Some ( last_start_attempt) = * last_attempt_start_time {
185
+ let duration = last_start_attempt. elapsed ( ) ;
186
+ let expected_delay_greater_than_or_equal = Duration :: from_millis ( self . delay_ms ) ;
187
+ assert ! (
188
+ duration >= expected_delay_greater_than_or_equal,
189
+ "duration should be greater than or equal to {}ms but was {}ms" ,
190
+ expected_delay_greater_than_or_equal. as_millis( ) ,
191
+ duration. as_millis( )
192
+ ) ;
193
+ let expected_delay_less_than = Duration :: from_millis ( 2 * self . delay_ms ) ;
194
+ assert ! (
195
+ duration < expected_delay_less_than,
196
+ "duration should be less than {}ms but was {}ms" ,
197
+ expected_delay_less_than. as_millis( ) ,
198
+ duration. as_millis( )
199
+ ) ;
200
+ }
201
+ * last_attempt_start_time = Some ( Instant :: now ( ) ) ;
184
202
185
- uploader
186
- . expect_upload_without_retry ( )
187
- . times ( 4 )
188
- . returning ( move |_| Err ( anyhow ! ( "Failure while uploading..." ) ) ) ;
203
+ Err ( anyhow:: anyhow!( "Upload failed" ) )
204
+ }
205
+
206
+ fn retry_policy ( & self ) -> FileUploadRetryPolicy {
207
+ FileUploadRetryPolicy {
208
+ attempts : 4 ,
209
+ delay_between_attempts : Duration :: from_millis ( self . delay_ms ) ,
210
+ }
211
+ }
212
+ }
213
+
214
+ let uploader = FileUploaderAssertDelay {
215
+ delay_ms : 50 ,
216
+ last_attempt_start_time : Mutex :: new ( None ) ,
217
+ } ;
189
218
190
- let start = Instant :: now ( ) ;
191
219
uploader
192
220
. upload ( & PathBuf :: from ( "file_to_upload" ) )
193
221
. await
194
222
. expect_err ( "An error should be returned when all retries are done" ) ;
195
- let duration = start. elapsed ( ) ;
196
-
197
- assert ! (
198
- duration >= delay * 3 ,
199
- "Duration should be at least 3 times the delay ({}ms) but was {}ms" ,
200
- delay. as_millis( ) * 3 ,
201
- duration. as_millis( )
202
- ) ;
203
- assert ! (
204
- duration < delay * 4 ,
205
- "Duration should be less than 4 times the delay ({}ms) but was {}ms" ,
206
- delay. as_millis( ) * 4 ,
207
- duration. as_millis( )
208
- ) ;
209
223
}
210
224
}
0 commit comments