@@ -97,7 +97,7 @@ public function testRetriesExhaustedThrowsLastException(): void
97
97
public function testRetriesOnTypesenseClientError (): void
98
98
{
99
99
$ callCount = 0 ;
100
- $ expectedCalls = 3 ;
100
+ $ expectedCalls = 1 ;
101
101
102
102
$ httpClient = $ this ->createMock (ClientInterface::class);
103
103
$ httpClient ->method ('sendRequest ' )
@@ -129,9 +129,11 @@ public function testRetriesOnTypesenseClientError(): void
129
129
130
130
$ apiCall = new ApiCall ($ config );
131
131
132
- $ result = $ apiCall ->get ('/test ' , []);
132
+ try {
133
+ $ apiCall ->get ('/test ' , []);
134
+ } catch (ServerError $ e ) {
135
+ }
133
136
134
- $ this ->assertEquals (['success ' => true ], $ result );
135
137
$ this ->assertEquals ($ expectedCalls , $ callCount );
136
138
}
137
139
@@ -406,4 +408,60 @@ public function test408ErrorsAreSkippedAndRetryingContinues(): void
406
408
$ this ->assertEquals (['success ' => true ], $ result );
407
409
$ this ->assertEquals (2 , $ callCount );
408
410
}
411
+
412
+ public function testDoesNotSleepOnFinalRetryAttempt (): void
413
+ {
414
+ $ callCount = 0 ;
415
+ $ retryIntervalSeconds = 0.1 ;
416
+
417
+ $ httpClient = $ this ->createMock (ClientInterface::class);
418
+ $ httpClient ->method ('sendRequest ' )
419
+ ->willReturnCallback (function () use (&$ callCount ) {
420
+ $ callCount ++;
421
+
422
+ $ response = $ this ->createMock (ResponseInterface::class);
423
+ $ response ->method ('getStatusCode ' )->willReturn (500 );
424
+ throw new HttpException ('Server error ' , $ this ->createMock (RequestInterface::class), $ response );
425
+ });
426
+
427
+ $ config = new Configuration ([
428
+ 'api_key ' => 'test-key ' ,
429
+ 'nodes ' => [
430
+ ['host ' => 'node1 ' , 'port ' => 8108 , 'protocol ' => 'http ' ]
431
+ ],
432
+ 'num_retries ' => 2 ,
433
+ 'retry_interval_seconds ' => $ retryIntervalSeconds ,
434
+ 'client ' => $ httpClient
435
+ ]);
436
+
437
+ $ apiCall = new ApiCall ($ config );
438
+
439
+ $ startTime = microtime (true );
440
+
441
+ try {
442
+ $ apiCall ->get ('/test ' , []);
443
+ } catch (ServerError $ e ) {
444
+ }
445
+
446
+ $ endTime = microtime (true );
447
+ $ actualDuration = $ endTime - $ startTime ;
448
+
449
+ // 2 sleep intervals (between 1st->2nd and 2nd->3rd attempts)
450
+ // no sleep after the final (3rd) attempt
451
+ $ expectedDuration = $ retryIntervalSeconds * 2 ;
452
+
453
+ $ tolerance = 0.05 ;
454
+
455
+ $ this ->assertEquals (3 , $ callCount , 'Should make exactly 3 attempts ' );
456
+ $ this ->assertLessThan (
457
+ $ expectedDuration + $ tolerance ,
458
+ $ actualDuration ,
459
+ "Execution took too long ( {$ actualDuration }s), suggesting sleep was called on final attempt "
460
+ );
461
+ $ this ->assertGreaterThan (
462
+ $ expectedDuration - $ tolerance ,
463
+ $ actualDuration ,
464
+ "Execution was too fast ( {$ actualDuration }s), suggesting sleep intervals were skipped "
465
+ );
466
+ }
409
467
}
0 commit comments