ÿØÿà JPEG ÿþ;
Server IP : 68.65.120.201 / Your IP : 216.73.216.221 Web Server : LiteSpeed System : Linux server179.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64 User : taxhyuvu ( 2294) PHP Version : 8.1.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/taxhyuvu/www/vendor/google/apiclient/tests/Google/Task/ |
Upload File : |
<?php /* * Copyright 2014 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace Google\Tests\Task; use Google\Client; use Google\Task\Runner; use Google\Tests\BaseTest; use Google\Http\Request as GoogleRequest; use Google\Http\REST; use Google\Service\Exception as ServiceException; use Google\Task\Exception as TaskException; use GuzzleHttp\Message\Response as Guzzle5Response; use GuzzleHttp\Psr7; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use GuzzleHttp\Stream\Stream as Guzzle5Stream; use Prophecy\Argument; use Exception; class RunnerTest extends BaseTest { private $client; private $mockedCallsCount = 0; private $currentMockedCall = 0; private $mockedCalls = []; private $retryMap; private $retryConfig; protected function set_up() { $this->client = new Client(); } /** * @dataProvider defaultRestErrorProvider */ public function testRestRetryOffByDefault($errorCode, $errorBody = '{}') { $this->expectException(ServiceException::class); $this->setNextResponse($errorCode, $errorBody)->makeRequest(); } /** * @dataProvider defaultRestErrorProvider */ public function testOneRestRetryWithError($errorCode, $errorBody = '{}') { $this->expectException(ServiceException::class); $this->setRetryConfig(['retries' => 1]); $this->setNextResponses(2, $errorCode, $errorBody)->makeRequest(); } /** * @dataProvider defaultRestErrorProvider */ public function testMultipleRestRetriesWithErrors( $errorCode, $errorBody = '{}' ) { $this->expectException(ServiceException::class); $this->setRetryConfig(['retries' => 5]); $this->setNextResponses(6, $errorCode, $errorBody)->makeRequest(); } /** * @dataProvider defaultRestErrorProvider */ public function testOneRestRetryWithSuccess($errorCode, $errorBody = '{}') { $this->setRetryConfig(['retries' => 1]); $result = $this->setNextResponse($errorCode, $errorBody) ->setNextResponse(200, '{"success": true}') ->makeRequest(); $this->assertEquals('{"success": true}', (string) $result->getBody()); } /** * @dataProvider defaultRestErrorProvider */ public function testMultipleRestRetriesWithSuccess( $errorCode, $errorBody = '{}' ) { $this->setRetryConfig(['retries' => 5]); $result = $this->setNextResponses(2, $errorCode, $errorBody) ->setNextResponse(200, '{"success": true}') ->makeRequest(); $this->assertEquals('{"success": true}', (string) $result->getBody()); } /** * @dataProvider defaultRestErrorProvider */ public function testCustomRestRetryMapReplacesDefaults( $errorCode, $errorBody = '{}' ) { $this->expectException(ServiceException::class); $this->setRetryMap([]); $this->setRetryConfig(['retries' => 5]); $this->setNextResponse($errorCode, $errorBody)->makeRequest(); } public function testCustomRestRetryMapAddsNewHandlers() { $this->setRetryMap( ['403' => Runner::TASK_RETRY_ALWAYS] ); $this->setRetryConfig(['retries' => 5]); $result = $this->setNextResponses(2, 403) ->setNextResponse(200, '{"success": true}') ->makeRequest(); $this->assertEquals('{"success": true}', (string) $result->getBody()); } /** * @dataProvider customLimitsProvider */ public function testCustomRestRetryMapWithCustomLimits($limit) { $this->expectException(ServiceException::class); $this->setRetryMap( ['403' => $limit] ); $this->setRetryConfig(['retries' => 5]); $this->setNextResponses($limit + 1, 403)->makeRequest(); } /** * @dataProvider timeoutProvider */ public function testRestTimeouts($config, $minTime) { $this->setRetryConfig($config); $this->setNextResponses($config['retries'], 500) ->setNextResponse(200, '{"success": true}'); $this->assertTaskTimeGreaterThanOrEqual( $minTime, [$this, 'makeRequest'], $config['initial_delay'] / 10 ); } /** * @requires extension curl * @dataProvider defaultCurlErrorProvider */ public function testCurlRetryOffByDefault($errorCode, $errorMessage = '') { $this->expectException(ServiceException::class); $this->setNextResponseThrows($errorMessage, $errorCode)->makeRequest(); } /** * @requires extension curl * @dataProvider defaultCurlErrorProvider */ public function testOneCurlRetryWithError($errorCode, $errorMessage = '') { $this->expectException(ServiceException::class); $this->setRetryConfig(['retries' => 1]); $this->setNextResponsesThrow(2, $errorMessage, $errorCode)->makeRequest(); } /** * @requires extension curl * @dataProvider defaultCurlErrorProvider */ public function testMultipleCurlRetriesWithErrors( $errorCode, $errorMessage = '' ) { $this->expectException(ServiceException::class); $this->setRetryConfig(['retries' => 5]); $this->setNextResponsesThrow(6, $errorMessage, $errorCode)->makeRequest(); } /** * @requires extension curl * @dataProvider defaultCurlErrorProvider */ public function testOneCurlRetryWithSuccess($errorCode, $errorMessage = '') { $this->setRetryConfig(['retries' => 1]); $result = $this->setNextResponseThrows($errorMessage, $errorCode) ->setNextResponse(200, '{"success": true}') ->makeRequest(); $this->assertEquals('{"success": true}', (string) $result->getBody()); } /** * @requires extension curl * @dataProvider defaultCurlErrorProvider */ public function testMultipleCurlRetriesWithSuccess( $errorCode, $errorMessage = '' ) { $this->setRetryConfig(['retries' => 5]); $result = $this->setNextResponsesThrow(2, $errorMessage, $errorCode) ->setNextResponse(200, '{"success": true}') ->makeRequest(); $this->assertEquals('{"success": true}', (string) $result->getBody()); } /** * @requires extension curl * @dataProvider defaultCurlErrorProvider */ public function testCustomCurlRetryMapReplacesDefaults( $errorCode, $errorMessage = '' ) { $this->expectException(ServiceException::class); $this->setRetryMap([]); $this->setRetryConfig(['retries' => 5]); $this->setNextResponseThrows($errorMessage, $errorCode)->makeRequest(); } /** * @requires extension curl */ public function testCustomCurlRetryMapAddsNewHandlers() { $this->setRetryMap( [CURLE_COULDNT_RESOLVE_PROXY => Runner::TASK_RETRY_ALWAYS] ); $this->setRetryConfig(['retries' => 5]); $result = $this->setNextResponsesThrow(2, '', CURLE_COULDNT_RESOLVE_PROXY) ->setNextResponse(200, '{"success": true}') ->makeRequest(); $this->assertEquals('{"success": true}', (string) $result->getBody()); } /** * @requires extension curl * @dataProvider customLimitsProvider */ public function testCustomCurlRetryMapWithCustomLimits($limit) { $this->expectException(ServiceException::class); $this->setRetryMap( [CURLE_COULDNT_RESOLVE_PROXY => $limit] ); $this->setRetryConfig(['retries' => 5]); $this->setNextResponsesThrow($limit + 1, '', CURLE_COULDNT_RESOLVE_PROXY) ->makeRequest(); } /** * @requires extension curl * @dataProvider timeoutProvider */ public function testCurlTimeouts($config, $minTime) { $this->setRetryConfig($config); $this->setNextResponsesThrow($config['retries'], '', CURLE_GOT_NOTHING) ->setNextResponse(200, '{"success": true}'); $this->assertTaskTimeGreaterThanOrEqual( $minTime, [$this, 'makeRequest'], $config['initial_delay'] / 10 ); } /** * @dataProvider badTaskConfigProvider */ public function testBadTaskConfig($config, $message) { $this->expectException(TaskException::class); $this->expectExceptionMessage($message); $this->setRetryConfig($config); new Runner( $this->retryConfig, '', [$this, 'testBadTaskConfig'] ); } /** * @expectedExceptionMessage must be a valid callable */ public function testBadTaskCallback() { $this->expectException(TaskException::class); $config = []; new Runner($config, '', 5); } public function testTaskRetryOffByDefault() { $this->expectException(ServiceException::class); $this->setNextTaskAllowedRetries(Runner::TASK_RETRY_ALWAYS) ->runTask(); } public function testOneTaskRetryWithError() { $this->expectException(ServiceException::class); $this->setRetryConfig(['retries' => 1]); $this->setNextTasksAllowedRetries(2, Runner::TASK_RETRY_ALWAYS) ->runTask(); } public function testMultipleTaskRetriesWithErrors() { $this->expectException(ServiceException::class); $this->setRetryConfig(['retries' => 5]); $this->setNextTasksAllowedRetries(6, Runner::TASK_RETRY_ALWAYS) ->runTask(); } public function testOneTaskRetryWithSuccess() { $this->setRetryConfig(['retries' => 1]); $result = $this->setNextTaskAllowedRetries(Runner::TASK_RETRY_ALWAYS) ->setNextTaskReturnValue('success') ->runTask(); $this->assertEquals('success', $result); } public function testMultipleTaskRetriesWithSuccess() { $this->setRetryConfig(['retries' => 5]); $result = $this->setNextTasksAllowedRetries(2, Runner::TASK_RETRY_ALWAYS) ->setNextTaskReturnValue('success') ->runTask(); $this->assertEquals('success', $result); } /** * @dataProvider customLimitsProvider */ public function testTaskRetryWithCustomLimits($limit) { $this->expectException(ServiceException::class); $this->setRetryConfig(['retries' => 5]); $this->setNextTasksAllowedRetries($limit + 1, $limit) ->runTask(); } /** * @dataProvider timeoutProvider */ public function testTaskTimeouts($config, $minTime) { $this->setRetryConfig($config); $this->setNextTasksAllowedRetries($config['retries'], $config['retries'] + 1) ->setNextTaskReturnValue('success'); $this->assertTaskTimeGreaterThanOrEqual( $minTime, [$this, 'runTask'], $config['initial_delay'] / 10 ); } public function testTaskWithManualRetries() { $this->setRetryConfig(['retries' => 2]); $this->setNextTasksAllowedRetries(2, Runner::TASK_RETRY_ALWAYS); $task = new Runner( $this->retryConfig, '', [$this, 'runNextTask'] ); $this->assertTrue($task->canAttempt()); $this->assertTrue($task->attempt()); $this->assertTrue($task->canAttempt()); $this->assertTrue($task->attempt()); $this->assertTrue($task->canAttempt()); $this->assertTrue($task->attempt()); $this->assertFalse($task->canAttempt()); $this->assertFalse($task->attempt()); } /** * Provider for backoff configurations and expected minimum runtimes. * * @return array */ public function timeoutProvider() { $config = ['initial_delay' => .001, 'max_delay' => .01]; return [ [array_merge($config, ['retries' => 1]), .001], [array_merge($config, ['retries' => 2]), .0015], [array_merge($config, ['retries' => 3]), .00225], [array_merge($config, ['retries' => 4]), .00375], [array_merge($config, ['retries' => 5]), .005625] ]; } /** * Provider for custom retry limits. * * @return array */ public function customLimitsProvider() { return [ [Runner::TASK_RETRY_NEVER], [Runner::TASK_RETRY_ONCE], ]; } /** * Provider for invalid task configurations. * * @return array */ public function badTaskConfigProvider() { return [ [['initial_delay' => -1], 'must not be negative'], [['max_delay' => 0], 'must be greater than 0'], [['factor' => 0], 'must be greater than 0'], [['jitter' => 0], 'must be greater than 0'], [['retries' => -1], 'must not be negative'] ]; } /** * Provider for the default REST errors. * * @return array */ public function defaultRestErrorProvider() { return [ [500], [503], [403, '{"error":{"errors":[{"reason":"rateLimitExceeded"}]}}'], [403, '{"error":{"errors":[{"reason":"userRateLimitExceeded"}]}}'], ]; } /** * Provider for the default cURL errors. * * @return array */ public function defaultCurlErrorProvider() { return [ [6], // CURLE_COULDNT_RESOLVE_HOST [7], // CURLE_COULDNT_CONNECT [28], // CURLE_OPERATION_TIMEOUTED [35], // CURLE_SSL_CONNECT_ERROR [52], // CURLE_GOT_NOTHING ]; } /** * Assert the minimum amount of time required to run a task. * * NOTE: Intentionally crude for brevity. * * @param float $expected The expected minimum execution time * @param callable $callback The task to time * @param float $delta Allowable relative error * * @throws PHPUnit_Framework_ExpectationFailedException */ public static function assertTaskTimeGreaterThanOrEqual( $expected, $callback, $delta = 0.0 ) { $time = microtime(true); call_user_func($callback); self::assertThat( microtime(true) - $time, self::logicalOr( self::greaterThan($expected), self::equalTo($expected, $delta) ) ); } /** * Sets the task runner configurations. * * @param array $config The task runner configurations */ private function setRetryConfig(array $config) { $config += [ 'initial_delay' => .0001, 'max_delay' => .001, 'factor' => 2, 'jitter' => .5, 'retries' => 1 ]; $this->retryConfig = $config; } private function setRetryMap(array $retryMap) { $this->retryMap = $retryMap; } /** * Sets the next responses. * * @param integer $count The number of responses * @param string $code The response code * @param string $body The response body * @param array $headers The response headers * * @return TaskTest */ private function setNextResponses( $count, $code = '200', $body = '{}', array $headers = [] ) { while ($count-- > 0) { $this->setNextResponse($code, $body, $headers); } return $this; } /** * Sets the next response. * * @param string $code The response code * @param string $body The response body * @param array $headers The response headers * * @return TaskTest */ private function setNextResponse( $code = '200', $body = '{}', array $headers = [] ) { $this->mockedCalls[$this->mockedCallsCount++] = [ 'code' => (string) $code, 'headers' => $headers, 'body' => is_string($body) ? $body : json_encode($body) ]; return $this; } /** * Forces the next responses to throw an IO exception. * * @param integer $count The number of responses * @param string $message The exception messages * @param string $code The exception code * * @return TaskTest */ private function setNextResponsesThrow($count, $message, $code) { while ($count-- > 0) { $this->setNextResponseThrows($message, $code); } return $this; } /** * Forces the next response to throw an IO exception. * * @param string $message The exception messages * @param string $code The exception code * * @return TaskTest */ private function setNextResponseThrows($message, $code) { $this->mockedCalls[$this->mockedCallsCount++] = new ServiceException( $message, $code, null, [] ); return $this; } /** * Runs the defined request. * * @return array */ private function makeRequest() { $request = new Request('GET', '/test'); $http = $this->prophesize('GuzzleHttp\ClientInterface'); if ($this->isGuzzle5()) { $http->createRequest(Argument::any(), Argument::any(), Argument::any()) ->shouldBeCalledTimes($this->mockedCallsCount) ->willReturn(new \GuzzleHttp\Message\Request('GET', '/test')); $http->send(Argument::type('GuzzleHttp\Message\Request')) ->shouldBeCalledTimes($this->mockedCallsCount) ->will([$this, 'getNextMockedCall']); } else { $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) ->shouldBeCalledTimes($this->mockedCallsCount) ->will([$this, 'getNextMockedCall']); } return REST::execute($http->reveal(), $request, '', $this->retryConfig, $this->retryMap); } /** * Gets the next mocked response. * * @param GoogleRequest $request The mocked request * * @return GoogleRequest */ public function getNextMockedCall($request) { $current = $this->mockedCalls[$this->currentMockedCall++]; if ($current instanceof Exception) { throw $current; } if ($this->isGuzzle5()) { $stream = Guzzle5Stream::factory($current['body']); $response = new Guzzle5Response($current['code'], $current['headers'], $stream); } else { $stream = Psr7\Utils::streamFor($current['body']); $response = new Response($current['code'], $current['headers'], $stream); } return $response; } /** * Sets the next task return value. * * @param mixed $value The next return value * * @return TaskTest */ private function setNextTaskReturnValue($value) { $this->mockedCalls[$this->mockedCallsCount++] = $value; return $this; } /** * Sets the next exception `allowedRetries()` return value. * * @param boolean $allowedRetries The next `allowedRetries()` return value. * * @return TaskTest */ private function setNextTaskAllowedRetries($allowedRetries) { $this->mockedCalls[$this->mockedCallsCount++] = $allowedRetries; return $this; } /** * Sets multiple exception `allowedRetries()` return value. * * @param integer $count The number of `allowedRetries()` return values. * @param boolean $allowedRetries The `allowedRetries()` return value. * * @return TaskTest */ private function setNextTasksAllowedRetries($count, $allowedRetries) { while ($count-- > 0) { $this->setNextTaskAllowedRetries($allowedRetries); } return $this; } /** * Runs the defined task. * * @return mixed */ private function runTask() { $task = new Runner( $this->retryConfig, '', [$this, 'runNextTask'] ); if (null !== $this->retryMap) { $task->setRetryMap($this->retryMap); } $exception = $this->prophesize(ServiceException::class); $exceptionCount = 0; $exceptionCalls = []; for ($i = 0; $i < $this->mockedCallsCount; $i++) { if (is_int($this->mockedCalls[$i])) { $exceptionCalls[$exceptionCount++] = $this->mockedCalls[$i]; $this->mockedCalls[$i] = $exception->reveal(); } } $task->setRetryMap($exceptionCalls); return $task->run(); } /** * Gets the next task return value. * * @return mixed */ public function runNextTask() { $current = $this->mockedCalls[$this->currentMockedCall++]; if ($current instanceof Exception) { throw $current; } return $current; } }