summaryrefslogtreecommitdiffstats
path: root/includes/google-api-php-client-master/tests/general/TaskTest.php
diff options
context:
space:
mode:
authorBlueRaja <BlueRaja.admin@gmail.com>2015-05-07 23:14:47 -0500
committerBlueRaja <BlueRaja.admin@gmail.com>2015-05-07 23:14:47 -0500
commit3dc3919ce1b5336861979cde56884842615c967b (patch)
treef0a2418290cecd15f20c834bb071ffa9f3694b09 /includes/google-api-php-client-master/tests/general/TaskTest.php
parent29e872fbc6c552ef02208fe9fa5416b69773aa38 (diff)
parentc517b645c8723b5f4d20cbb91cbc4b9f45579cbb (diff)
downloadpathery-3dc3919ce1b5336861979cde56884842615c967b.tar.xz
Merge branch 'master' of git.raylu.net:pathery
Diffstat (limited to 'includes/google-api-php-client-master/tests/general/TaskTest.php')
-rw-r--r--includes/google-api-php-client-master/tests/general/TaskTest.php765
1 files changed, 765 insertions, 0 deletions
diff --git a/includes/google-api-php-client-master/tests/general/TaskTest.php b/includes/google-api-php-client-master/tests/general/TaskTest.php
new file mode 100644
index 0000000..4aca138
--- /dev/null
+++ b/includes/google-api-php-client-master/tests/general/TaskTest.php
@@ -0,0 +1,765 @@
+<?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.
+ */
+
+class TaskTest extends PHPUnit_Framework_TestCase
+{
+ private $client;
+
+ private $mockedCallsCount = 0;
+ private $currentMockedCall = 0;
+ private $mockedCalls = array();
+
+ protected function setUp()
+ {
+ $this->client = new Google_Client();
+ }
+
+ /**
+ * @dataProvider defaultRestErrorProvider
+ * @expectedException Google_Service_Exception
+ */
+ public function testRestRetryOffByDefault($errorCode, $errorBody = '{}')
+ {
+ $this->setNextResponse($errorCode, $errorBody)->makeRequest();
+ }
+
+ /**
+ * @dataProvider defaultRestErrorProvider
+ * @expectedException Google_Service_Exception
+ */
+ public function testOneRestRetryWithError($errorCode, $errorBody = '{}')
+ {
+ $this->setTaskConfig(array('retries' => 1));
+ $this->setNextResponses(2, $errorCode, $errorBody)->makeRequest();
+ }
+
+ /**
+ * @dataProvider defaultRestErrorProvider
+ * @expectedException Google_Service_Exception
+ */
+ public function testMultipleRestRetriesWithErrors(
+ $errorCode,
+ $errorBody = '{}'
+ ) {
+ $this->setTaskConfig(array('retries' => 5));
+ $this->setNextResponses(6, $errorCode, $errorBody)->makeRequest();
+ }
+
+ /**
+ * @dataProvider defaultRestErrorProvider
+ */
+ public function testOneRestRetryWithSuccess($errorCode, $errorBody = '{}')
+ {
+ $this->setTaskConfig(array('retries' => 1));
+ $result = $this->setNextResponse($errorCode, $errorBody)
+ ->setNextResponse(200, '{"success": true}')
+ ->makeRequest();
+
+ $this->assertEquals(array("success" => true), $result);
+ }
+
+ /**
+ * @dataProvider defaultRestErrorProvider
+ */
+ public function testMultipleRestRetriesWithSuccess(
+ $errorCode,
+ $errorBody = '{}'
+ ) {
+ $this->setTaskConfig(array('retries' => 5));
+ $result = $this->setNextResponses(2, $errorCode, $errorBody)
+ ->setNextResponse(200, '{"success": true}')
+ ->makeRequest();
+
+ $this->assertEquals(array("success" => true), $result);
+ }
+
+ /**
+ * @dataProvider defaultRestErrorProvider
+ * @expectedException Google_Service_Exception
+ */
+ public function testCustomRestRetryMapReplacesDefaults(
+ $errorCode,
+ $errorBody = '{}'
+ ) {
+ $this->client->setClassConfig(
+ 'Google_Service_Exception',
+ array('retry_map' => array())
+ );
+
+ $this->setTaskConfig(array('retries' => 5));
+ $this->setNextResponse($errorCode, $errorBody)->makeRequest();
+ }
+
+ public function testCustomRestRetryMapAddsNewHandlers()
+ {
+ $this->client->setClassConfig(
+ 'Google_Service_Exception',
+ array('retry_map' => array('403' => Google_Config::TASK_RETRY_ALWAYS))
+ );
+
+ $this->setTaskConfig(array('retries' => 5));
+ $result = $this->setNextResponses(2, 403)
+ ->setNextResponse(200, '{"success": true}')
+ ->makeRequest();
+
+ $this->assertEquals(array("success" => true), $result);
+ }
+
+ /**
+ * @expectedException Google_Service_Exception
+ * @dataProvider customLimitsProvider
+ */
+ public function testCustomRestRetryMapWithCustomLimits($limit)
+ {
+ $this->client->setClassConfig(
+ 'Google_Service_Exception',
+ array('retry_map' => array('403' => $limit))
+ );
+
+ $this->setTaskConfig(array('retries' => 5));
+ $this->setNextResponses($limit + 1, 403)->makeRequest();
+ }
+
+ /**
+ * @dataProvider timeoutProvider
+ */
+ public function testRestTimeouts($config, $minTime)
+ {
+ $this->setTaskConfig($config);
+ $this->setNextResponses($config['retries'], 500)
+ ->setNextResponse(200, '{"success": true}');
+
+ $this->assertTaskTimeGreaterThanOrEqual(
+ $minTime,
+ array($this, 'makeRequest'),
+ $config['initial_delay'] / 10
+ );
+ }
+
+ /**
+ * @requires extension curl
+ * @dataProvider defaultCurlErrorProvider
+ * @expectedException Google_IO_Exception
+ */
+ public function testCurlRetryOffByDefault($errorCode, $errorMessage = '')
+ {
+ $this->setNextResponseThrows($errorMessage, $errorCode)->makeRequest();
+ }
+
+ /**
+ * @requires extension curl
+ * @dataProvider defaultCurlErrorProvider
+ * @expectedException Google_IO_Exception
+ */
+ public function testOneCurlRetryWithError($errorCode, $errorMessage = '')
+ {
+ $this->setTaskConfig(array('retries' => 1));
+ $this->setNextResponsesThrow(2, $errorMessage, $errorCode)->makeRequest();
+ }
+
+ /**
+ * @requires extension curl
+ * @dataProvider defaultCurlErrorProvider
+ * @expectedException Google_IO_Exception
+ */
+ public function testMultipleCurlRetriesWithErrors(
+ $errorCode,
+ $errorMessage = ''
+ ) {
+ $this->setTaskConfig(array('retries' => 5));
+ $this->setNextResponsesThrow(6, $errorMessage, $errorCode)->makeRequest();
+ }
+
+ /**
+ * @requires extension curl
+ * @dataProvider defaultCurlErrorProvider
+ */
+ public function testOneCurlRetryWithSuccess($errorCode, $errorMessage = '')
+ {
+ $this->setTaskConfig(array('retries' => 1));
+ $result = $this->setNextResponseThrows($errorMessage, $errorCode)
+ ->setNextResponse(200, '{"success": true}')
+ ->makeRequest();
+
+ $this->assertEquals(array("success" => true), $result);
+ }
+
+ /**
+ * @requires extension curl
+ * @dataProvider defaultCurlErrorProvider
+ */
+ public function testMultipleCurlRetriesWithSuccess(
+ $errorCode,
+ $errorMessage = ''
+ ) {
+ $this->setTaskConfig(array('retries' => 5));
+ $result = $this->setNextResponsesThrow(2, $errorMessage, $errorCode)
+ ->setNextResponse(200, '{"success": true}')
+ ->makeRequest();
+
+ $this->assertEquals(array("success" => true), $result);
+ }
+
+ /**
+ * @requires extension curl
+ * @dataProvider defaultCurlErrorProvider
+ * @expectedException Google_IO_Exception
+ */
+ public function testCustomCurlRetryMapReplacesDefaults(
+ $errorCode,
+ $errorMessage = ''
+ ) {
+ $this->client->setClassConfig(
+ 'Google_IO_Exception',
+ array('retry_map' => array())
+ );
+
+ $this->setTaskConfig(array('retries' => 5));
+ $this->setNextResponseThrows($errorMessage, $errorCode)->makeRequest();
+ }
+
+ /**
+ * @requires extension curl
+ */
+ public function testCustomCurlRetryMapAddsNewHandlers()
+ {
+ $this->client->setClassConfig(
+ 'Google_IO_Exception',
+ array('retry_map' => array(
+ CURLE_COULDNT_RESOLVE_PROXY => Google_Config::TASK_RETRY_ALWAYS
+ ))
+ );
+
+ $this->setTaskConfig(array('retries' => 5));
+ $result = $this->setNextResponsesThrow(2, '', CURLE_COULDNT_RESOLVE_PROXY)
+ ->setNextResponse(200, '{"success": true}')
+ ->makeRequest();
+
+ $this->assertEquals(array("success" => true), $result);
+ }
+
+ /**
+ * @requires extension curl
+ * @expectedException Google_IO_Exception
+ * @dataProvider customLimitsProvider
+ */
+ public function testCustomCurlRetryMapWithCustomLimits($limit)
+ {
+ $this->client->setClassConfig(
+ 'Google_IO_Exception',
+ array('retry_map' => array(
+ CURLE_COULDNT_RESOLVE_PROXY => $limit
+ ))
+ );
+
+ $this->setTaskConfig(array('retries' => 5));
+ $this->setNextResponsesThrow($limit + 1, '', CURLE_COULDNT_RESOLVE_PROXY)
+ ->makeRequest();
+ }
+
+ /**
+ * @requires extension curl
+ * @dataProvider timeoutProvider
+ */
+ public function testCurlTimeouts($config, $minTime)
+ {
+ $this->setTaskConfig($config);
+ $this->setNextResponsesThrow($config['retries'], '', CURLE_GOT_NOTHING)
+ ->setNextResponse(200, '{"success": true}');
+
+ $this->assertTaskTimeGreaterThanOrEqual(
+ $minTime,
+ array($this, 'makeRequest'),
+ $config['initial_delay'] / 10
+ );
+ }
+
+ /**
+ * @dataProvider badTaskConfigProvider
+ */
+ public function testBadTaskConfig($config, $message)
+ {
+ $this->setExpectedException('Google_Task_Exception', $message);
+ $this->setTaskConfig($config);
+
+ new Google_Task_Runner(
+ $this->client,
+ '',
+ array($this, 'testBadTaskConfig')
+ );
+ }
+
+ /**
+ * @expectedException Google_Task_Exception
+ * @expectedExceptionMessage must be a valid callable
+ */
+ public function testBadTaskCallback()
+ {
+ new Google_Task_Runner($this->client, '', 5);
+ }
+
+ /**
+ * @expectedException Google_IO_Exception
+ */
+ public function testTaskRetryOffByDefault()
+ {
+ $this->setNextTaskAllowedRetries(Google_Config::TASK_RETRY_ALWAYS)
+ ->runTask();
+ }
+
+ /**
+ * @expectedException Google_IO_Exception
+ */
+ public function testOneTaskRetryWithError()
+ {
+ $this->setTaskConfig(array('retries' => 1));
+ $this->setNextTasksAllowedRetries(2, Google_Config::TASK_RETRY_ALWAYS)
+ ->runTask();
+ }
+
+ /**
+ * @expectedException Google_IO_Exception
+ */
+ public function testMultipleTaskRetriesWithErrors()
+ {
+ $this->setTaskConfig(array('retries' => 5));
+ $this->setNextTasksAllowedRetries(6, Google_Config::TASK_RETRY_ALWAYS)
+ ->runTask();
+ }
+
+ public function testOneTaskRetryWithSuccess()
+ {
+ $this->setTaskConfig(array('retries' => 1));
+ $result = $this->setNextTaskAllowedRetries(Google_Config::TASK_RETRY_ALWAYS)
+ ->setNextTaskReturnValue('success')
+ ->runTask();
+
+ $this->assertEquals('success', $result);
+ }
+
+ public function testMultipleTaskRetriesWithSuccess()
+ {
+ $this->setTaskConfig(array('retries' => 5));
+ $result = $this->setNextTasksAllowedRetries(2, Google_Config::TASK_RETRY_ALWAYS)
+ ->setNextTaskReturnValue('success')
+ ->runTask();
+
+ $this->assertEquals('success', $result);
+ }
+
+ /**
+ * @expectedException Google_IO_Exception
+ * @dataProvider customLimitsProvider
+ */
+ public function testTaskRetryWithCustomLimits($limit)
+ {
+ $this->setTaskConfig(array('retries' => 5));
+ $this->setNextTasksAllowedRetries($limit + 1, $limit)
+ ->runTask();
+ }
+
+ /**
+ * @dataProvider timeoutProvider
+ */
+ public function testTaskTimeouts($config, $minTime)
+ {
+ $this->setTaskConfig($config);
+ $this->setNextTasksAllowedRetries($config['retries'], $config['retries'] + 1)
+ ->setNextTaskReturnValue('success');
+
+ $this->assertTaskTimeGreaterThanOrEqual(
+ $minTime,
+ array($this, 'runTask'),
+ $config['initial_delay'] / 10
+ );
+ }
+
+ public function testTaskWithManualRetries()
+ {
+ $this->setTaskConfig(array('retries' => 2));
+ $this->setNextTasksAllowedRetries(2, Google_Config::TASK_RETRY_ALWAYS);
+
+ $task = new Google_Task_Runner(
+ $this->client,
+ '',
+ array($this, 'runNextTask')
+ );
+
+ $this->assertTrue($task->canAttmpt());
+ $this->assertTrue($task->attempt());
+
+ $this->assertTrue($task->canAttmpt());
+ $this->assertTrue($task->attempt());
+
+ $this->assertTrue($task->canAttmpt());
+ $this->assertTrue($task->attempt());
+
+ $this->assertFalse($task->canAttmpt());
+ $this->assertFalse($task->attempt());
+ }
+
+ /**
+ * Provider for backoff configurations and expected minimum runtimes.
+ *
+ * @return array
+ */
+ public function timeoutProvider()
+ {
+ $config = array('initial_delay' => .001, 'max_delay' => .01);
+
+ return array(
+ array(array_merge($config, array('retries' => 1)), .001),
+ array(array_merge($config, array('retries' => 2)), .0015),
+ array(array_merge($config, array('retries' => 3)), .00225),
+ array(array_merge($config, array('retries' => 4)), .00375),
+ array(array_merge($config, array('retries' => 5)), .005625)
+ );
+ }
+
+ /**
+ * Provider for custom retry limits.
+ *
+ * @return array
+ */
+ public function customLimitsProvider()
+ {
+ return array(
+ array(Google_Config::TASK_RETRY_NEVER),
+ array(Google_Config::TASK_RETRY_ONCE),
+ );
+ }
+
+ /**
+ * Provider for invalid task configurations.
+ *
+ * @return array
+ */
+ public function badTaskConfigProvider()
+ {
+ return array(
+ array(array('initial_delay' => -1), 'must not be negative'),
+ array(array('max_delay' => 0), 'must be greater than 0'),
+ array(array('factor' => 0), 'must be greater than 0'),
+ array(array('jitter' => 0), 'must be greater than 0'),
+ array(array('retries' => -1), 'must not be negative')
+ );
+ }
+
+ /**
+ * Provider for the default REST errors.
+ *
+ * @return array
+ */
+ public function defaultRestErrorProvider()
+ {
+ return array(
+ array(500),
+ array(503),
+ array(403, '{"error":{"errors":[{"reason":"rateLimitExceeded"}]}}'),
+ array(403, '{"error":{"errors":[{"reason":"userRateLimitExceeded"}]}}'),
+ );
+ }
+
+ /**
+ * Provider for the default cURL errors.
+ *
+ * @return array
+ */
+ public function defaultCurlErrorProvider()
+ {
+ return array(
+ array(6), // CURLE_COULDNT_RESOLVE_HOST
+ array(7), // CURLE_COULDNT_CONNECT
+ array(28), // CURLE_OPERATION_TIMEOUTED
+ array(35), // CURLE_SSL_CONNECT_ERROR
+ array(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 setTaskConfig(array $config)
+ {
+ $config += array(
+ 'initial_delay' => .0001,
+ 'max_delay' => .001,
+ 'factor' => 2,
+ 'jitter' => .5,
+ 'retries' => 1
+ );
+ $this->client->setClassConfig('Google_Task_Runner', $config);
+ }
+
+ /**
+ * 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 = array()
+ ) {
+ 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 = array()
+ ) {
+ $this->mockedCalls[$this->mockedCallsCount++] = array(
+ '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)
+ {
+ $map = $this->client->getClassConfig('Google_IO_Exception', 'retry_map');
+ $this->mockedCalls[$this->mockedCallsCount++] = new Google_IO_Exception(
+ $message,
+ $code,
+ null,
+ $map
+ );
+
+ return $this;
+ }
+
+ /**
+ * Runs the defined request.
+ *
+ * @return array
+ */
+ private function makeRequest()
+ {
+ $request = new Google_Http_Request('/test');
+
+ $io = $this->getMockBuilder('Google_IO_Abstract')
+ ->disableOriginalConstructor()
+ ->setMethods(array('makeRequest'))
+ ->getMockForAbstractClass();
+
+ $io->expects($this->exactly($this->mockedCallsCount))
+ ->method('makeRequest')
+ ->will($this->returnCallback(array($this, 'getNextMockedCall')));
+
+ $this->client->setIo($io);
+
+ return Google_Http_REST::execute($this->client, $request);
+ }
+
+ /**
+ * Gets the next mocked response.
+ *
+ * @param Google_Http_Request $request The mocked request
+ *
+ * @return Google_Http_Request
+ */
+ public function getNextMockedCall($request)
+ {
+ $current = $this->mockedCalls[$this->currentMockedCall++];
+
+ if ($current instanceof Exception) {
+ throw $current;
+ }
+
+ $request->setResponseHttpCode($current['code']);
+ $request->setResponseHeaders($current['headers']);
+ $request->setResponseBody($current['body']);
+
+ return $request;
+ }
+
+ /**
+ * 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 Google_Task_Runner(
+ $this->client,
+ '',
+ array($this, 'runNextTask')
+ );
+
+ $exception = $this->getMockBuilder('Google_IO_Exception')
+ ->disableOriginalConstructor()
+ ->setMethods(array('allowedRetries'))
+ ->getMock();
+ $exceptionCount = 0;
+ $exceptionCalls = array();
+
+ for ($i = 0; $i < $this->mockedCallsCount; $i++) {
+ if (is_int($this->mockedCalls[$i])) {
+ $exceptionCalls[$exceptionCount++] = $this->mockedCalls[$i];
+ $this->mockedCalls[$i] = $exception;
+ }
+ }
+
+ $exception->expects($this->exactly($exceptionCount))
+ ->method('allowedRetries')
+ ->will(
+ new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls(
+ $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;
+ }
+}