From 44c47601ed1a4b90723beada2b7f87a7ca2205e9 Mon Sep 17 00:00:00 2001 From: Yenfry Herrera Feliz Date: Thu, 22 Aug 2024 13:59:38 -0400 Subject: [PATCH] fix: error matcher on booleans (#2986) --- .../fix-waiter-matcher-boolean.json | 7 ++ src/Waiter.php | 6 ++ tests/WaiterTest.php | 101 ++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 .changes/nextrelease/fix-waiter-matcher-boolean.json diff --git a/.changes/nextrelease/fix-waiter-matcher-boolean.json b/.changes/nextrelease/fix-waiter-matcher-boolean.json new file mode 100644 index 0000000000..b3be5f5401 --- /dev/null +++ b/.changes/nextrelease/fix-waiter-matcher-boolean.json @@ -0,0 +1,7 @@ +[ + { + "type": "bugfix", + "category": "Waiter", + "description": "Updates waiter error matching logic for boolean valuesq" + } +] diff --git a/src/Waiter.php b/src/Waiter.php index 74b2480131..16b86fb2fb 100644 --- a/src/Waiter.php +++ b/src/Waiter.php @@ -256,6 +256,12 @@ private function matchesStatus($result, array $acceptor) */ private function matchesError($result, array $acceptor) { + // If expected is true then the $result should be an instance of + // AwsException, otherwise it should not. + if (isset($acceptor['expected']) && is_bool($acceptor['expected'])) { + return $acceptor['expected'] === ($result instanceof AwsException); + } + if ($result instanceof AwsException) { return $result->isConnectionError() || $result->getAwsErrorCode() == $acceptor['expected']; diff --git a/tests/WaiterTest.php b/tests/WaiterTest.php index f106017cab..509ba921d1 100644 --- a/tests/WaiterTest.php +++ b/tests/WaiterTest.php @@ -6,8 +6,10 @@ use Aws\DynamoDb\DynamoDbClient; use Aws\Exception\AwsException; use Aws\Result; +use Aws\S3\S3Client; use Aws\Waiter; use GuzzleHttp\Exception\ConnectException; +use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Promise; use GuzzleHttp\Promise\FulfilledPromise; use GuzzleHttp\Promise\RejectedPromise; @@ -400,4 +402,103 @@ private function getMockResult($data = []) return new Result($data + ['@metadata' => ['statusCode' => 200]]); } + + + /** + * Tests the waiter expects not error. + * This means the operation should succeed. + * + * @return void + */ + public function testWaiterMatcherExpectNoError(): void + { + $client = new S3Client([ + 'region' => 'us-east-2', + 'http_handler' => function (RequestInterface $_) { + $responseBody = << +EOXML; + return new Response(200, [], $responseBody); + } + ]); + $commandArgs = [ + 'Bucket' => 'fuzz', + 'Key' => 'bazz' + ]; + $waiterConfig = [ + 'delay' => 5, + 'operation' => 'headObject', + 'maxAttempts' => 20, + 'acceptors' => [ + [ + 'expected' => false, + 'matcher' => 'error', + 'state' => 'success' + ] + ] + ]; + $waiter = new Waiter( + $client, + 'foo', + $commandArgs, + $waiterConfig + ); + $waiter->promise() + ->then(function (CommandInterface $_) { + $this->assertTrue(true); // Waiter succeeded + })->wait(); + } + + /** + * Tests the waiter should receive an error. + * This means the operation should fail. + * + * @return void + */ + public function testWaiterMatcherExpectsAnyError(): void + { + $client = new S3Client([ + 'region' => 'us-east-2', + 'http_handler' => function (RequestInterface $request) { + $responseBody = << +EOXML; + $response = new Response(200, [], $responseBody); + return new RejectedPromise([ + 'connection_error' => true, + 'exception' => new RequestException( + 'Error', + $request, + $response + ), + ]); + } + ]); + $commandArgs = [ + 'Bucket' => 'fuzz', + 'Key' => 'bazz' + ]; + $waiterConfig = [ + 'delay' => 5, + 'operation' => 'headObject', + 'maxAttempts' => 20, + 'acceptors' => [ + [ + 'expected' => true, + 'matcher' => 'error', + 'state' => 'success' + ] + ] + ]; + $waiter = new Waiter( + $client, + 'foo', + $commandArgs, + $waiterConfig + ); + $waiter->promise() + ->then(function (CommandInterface $_) { + $this->assertTrue(true); // Waiter succeeded + })->wait(); + } }