88use GuzzleHttp \Server \Server ;
99use PHPUnit \Framework \TestCase ;
1010use Runtime \Bref \Lambda \LambdaClient ;
11+ use Runtime \Bref \Timeout \LambdaTimeoutException ;
12+ use Runtime \Bref \Timeout \Timeout ;
1113
1214/**
1315 * Tests the communication between `LambdaClient` and the Lambda Runtime HTTP API.
@@ -189,9 +191,9 @@ public function handle($event, Context $context)
189191
190192 // Check the lambda result contains the error message
191193 $ error = json_decode ((string ) $ eventFailureLog ->getBody (), true );
192- $ this ->assertSame ('Error while calling the Lambda runtime API: The requested URL returned error: 400 Bad Request ' , $ error ['errorMessage ' ]);
194+ $ this ->assertStringContainsString ('Error while calling the Lambda runtime API: The requested URL returned error: 400 ' , $ error ['errorMessage ' ]);
193195
194- $ this ->assertErrorInLogs ('Exception ' , 'Error while calling the Lambda runtime API: The requested URL returned error: 400 Bad Request ' );
196+ $ this ->assertErrorInLogs ('Exception ' , 'Error while calling the Lambda runtime API: The requested URL returned error: 400 ' );
195197 }
196198
197199 public function test function results that cannot be encoded are reported as invocation errors ()
@@ -235,6 +237,28 @@ public function handle($event, Context $context)
235237 $ this ->assertInvocationResult (['foo ' => 'bar ' ]);
236238 }
237239
240+ public function testLambdaTimeoutsCanBeAnticipated ()
241+ {
242+ $ this ->givenAnEvent ([]);
243+
244+ $ start = microtime (true );
245+ $ this ->lambda ->processNextEvent (new class implements Handler {
246+ public function handle ($ event , Context $ context )
247+ {
248+ // This 10s sleep should be interrupted
249+ sleep (10 );
250+ }
251+ });
252+
253+ $ elapsedTime = microtime (true ) - $ start ;
254+ // The Lambda timeout was 2 seconds, we expect the Bref timeout to trigger 1 second before that: 1 second
255+ $ this ->assertEqualsWithDelta (1 , $ elapsedTime , 0.2 );
256+ Timeout::reset ();
257+
258+ $ this ->assertInvocationErrorResult (LambdaTimeoutException::class, 'Maximum AWS Lambda execution time reached ' );
259+ $ this ->assertErrorInLogs (LambdaTimeoutException::class, 'Maximum AWS Lambda execution time reached ' );
260+ }
261+
238262 /**
239263 * @param mixed $event
240264 */
@@ -246,6 +270,8 @@ private function givenAnEvent($event): void
246270 [
247271 'lambda-runtime-aws-request-id ' => '1 ' ,
248272 'lambda-runtime-invoked-function-arn ' => 'test-function-name ' ,
273+ // now + 2 seconds
274+ 'lambda-runtime-deadline-ms ' => intval ((microtime (true ) + 2 ) * 1000 ),
249275 ],
250276 json_encode ($ event )
251277 ),
@@ -312,7 +338,7 @@ private function assertErrorInLogs(string $errorClass, string $errorMessage): vo
312338 'stack ' ,
313339 ], array_keys ($ invocationResult ));
314340 $ this ->assertEquals ($ errorClass , $ invocationResult ['errorType ' ]);
315- $ this ->assertEquals ($ errorMessage , $ invocationResult ['errorMessage ' ]);
341+ $ this ->assertStringContainsString ($ errorMessage , $ invocationResult ['errorMessage ' ]);
316342 $ this ->assertIsArray ($ invocationResult ['stack ' ]);
317343 }
318344
0 commit comments