PluginProbe
Authorizer / 2.8.3
Authorizer v2.8.3
3.15.3 3.15.2 3.15.1 3.15.0 3.14.3 3.14.4 3.14.2 3.14.1 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.9.0 2.9.1 2.9.10 2.9.11 2.9.12 2.9.13 2.9.2 2.9.3 2.9.6 All 126 releases
authorizer / vendor / google-api-php-client / tests / general / TaskTest.php

TaskTest.php in Authorizer 2.8.3, at vendor/google-api-php-client/tests/general/TaskTest.php

766 lines 19.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * Copyright 2014 Google Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 class TaskTest extends PHPUnit_Framework_TestCase
19 {
20 private $client;
21
22 private $mockedCallsCount = 0;
23 private $currentMockedCall = 0;
24 private $mockedCalls = array();
25
26 protected function setUp()
27 {
28 $this->client = new Google_Client();
29 }
30
31 /**
32 * @dataProvider defaultRestErrorProvider
33 * @expectedException Google_Service_Exception
34 */
35 public function testRestRetryOffByDefault($errorCode, $errorBody = '{}')
36 {
37 $this->setNextResponse($errorCode, $errorBody)->makeRequest();
38 }
39
40 /**
41 * @dataProvider defaultRestErrorProvider
42 * @expectedException Google_Service_Exception
43 */
44 public function testOneRestRetryWithError($errorCode, $errorBody = '{}')
45 {
46 $this->setTaskConfig(array('retries' => 1));
47 $this->setNextResponses(2, $errorCode, $errorBody)->makeRequest();
48 }
49
50 /**
51 * @dataProvider defaultRestErrorProvider
52 * @expectedException Google_Service_Exception
53 */
54 public function testMultipleRestRetriesWithErrors(
55 $errorCode,
56 $errorBody = '{}'
57 ) {
58 $this->setTaskConfig(array('retries' => 5));
59 $this->setNextResponses(6, $errorCode, $errorBody)->makeRequest();
60 }
61
62 /**
63 * @dataProvider defaultRestErrorProvider
64 */
65 public function testOneRestRetryWithSuccess($errorCode, $errorBody = '{}')
66 {
67 $this->setTaskConfig(array('retries' => 1));
68 $result = $this->setNextResponse($errorCode, $errorBody)
69 ->setNextResponse(200, '{"success": true}')
70 ->makeRequest();
71
72 $this->assertEquals(array("success" => true), $result);
73 }
74
75 /**
76 * @dataProvider defaultRestErrorProvider
77 */
78 public function testMultipleRestRetriesWithSuccess(
79 $errorCode,
80 $errorBody = '{}'
81 ) {
82 $this->setTaskConfig(array('retries' => 5));
83 $result = $this->setNextResponses(2, $errorCode, $errorBody)
84 ->setNextResponse(200, '{"success": true}')
85 ->makeRequest();
86
87 $this->assertEquals(array("success" => true), $result);
88 }
89
90 /**
91 * @dataProvider defaultRestErrorProvider
92 * @expectedException Google_Service_Exception
93 */
94 public function testCustomRestRetryMapReplacesDefaults(
95 $errorCode,
96 $errorBody = '{}'
97 ) {
98 $this->client->setClassConfig(
99 'Google_Service_Exception',
100 array('retry_map' => array())
101 );
102
103 $this->setTaskConfig(array('retries' => 5));
104 $this->setNextResponse($errorCode, $errorBody)->makeRequest();
105 }
106
107 public function testCustomRestRetryMapAddsNewHandlers()
108 {
109 $this->client->setClassConfig(
110 'Google_Service_Exception',
111 array('retry_map' => array('403' => Google_Config::TASK_RETRY_ALWAYS))
112 );
113
114 $this->setTaskConfig(array('retries' => 5));
115 $result = $this->setNextResponses(2, 403)
116 ->setNextResponse(200, '{"success": true}')
117 ->makeRequest();
118
119 $this->assertEquals(array("success" => true), $result);
120 }
121
122 /**
123 * @expectedException Google_Service_Exception
124 * @dataProvider customLimitsProvider
125 */
126 public function testCustomRestRetryMapWithCustomLimits($limit)
127 {
128 $this->client->setClassConfig(
129 'Google_Service_Exception',
130 array('retry_map' => array('403' => $limit))
131 );
132
133 $this->setTaskConfig(array('retries' => 5));
134 $this->setNextResponses($limit + 1, 403)->makeRequest();
135 }
136
137 /**
138 * @dataProvider timeoutProvider
139 */
140 public function testRestTimeouts($config, $minTime)
141 {
142 $this->setTaskConfig($config);
143 $this->setNextResponses($config['retries'], 500)
144 ->setNextResponse(200, '{"success": true}');
145
146 $this->assertTaskTimeGreaterThanOrEqual(
147 $minTime,
148 array($this, 'makeRequest'),
149 $config['initial_delay'] / 10
150 );
151 }
152
153 /**
154 * @requires extension curl
155 * @dataProvider defaultCurlErrorProvider
156 * @expectedException Google_IO_Exception
157 */
158 public function testCurlRetryOffByDefault($errorCode, $errorMessage = '')
159 {
160 $this->setNextResponseThrows($errorMessage, $errorCode)->makeRequest();
161 }
162
163 /**
164 * @requires extension curl
165 * @dataProvider defaultCurlErrorProvider
166 * @expectedException Google_IO_Exception
167 */
168 public function testOneCurlRetryWithError($errorCode, $errorMessage = '')
169 {
170 $this->setTaskConfig(array('retries' => 1));
171 $this->setNextResponsesThrow(2, $errorMessage, $errorCode)->makeRequest();
172 }
173
174 /**
175 * @requires extension curl
176 * @dataProvider defaultCurlErrorProvider
177 * @expectedException Google_IO_Exception
178 */
179 public function testMultipleCurlRetriesWithErrors(
180 $errorCode,
181 $errorMessage = ''
182 ) {
183 $this->setTaskConfig(array('retries' => 5));
184 $this->setNextResponsesThrow(6, $errorMessage, $errorCode)->makeRequest();
185 }
186
187 /**
188 * @requires extension curl
189 * @dataProvider defaultCurlErrorProvider
190 */
191 public function testOneCurlRetryWithSuccess($errorCode, $errorMessage = '')
192 {
193 $this->setTaskConfig(array('retries' => 1));
194 $result = $this->setNextResponseThrows($errorMessage, $errorCode)
195 ->setNextResponse(200, '{"success": true}')
196 ->makeRequest();
197
198 $this->assertEquals(array("success" => true), $result);
199 }
200
201 /**
202 * @requires extension curl
203 * @dataProvider defaultCurlErrorProvider
204 */
205 public function testMultipleCurlRetriesWithSuccess(
206 $errorCode,
207 $errorMessage = ''
208 ) {
209 $this->setTaskConfig(array('retries' => 5));
210 $result = $this->setNextResponsesThrow(2, $errorMessage, $errorCode)
211 ->setNextResponse(200, '{"success": true}')
212 ->makeRequest();
213
214 $this->assertEquals(array("success" => true), $result);
215 }
216
217 /**
218 * @requires extension curl
219 * @dataProvider defaultCurlErrorProvider
220 * @expectedException Google_IO_Exception
221 */
222 public function testCustomCurlRetryMapReplacesDefaults(
223 $errorCode,
224 $errorMessage = ''
225 ) {
226 $this->client->setClassConfig(
227 'Google_IO_Exception',
228 array('retry_map' => array())
229 );
230
231 $this->setTaskConfig(array('retries' => 5));
232 $this->setNextResponseThrows($errorMessage, $errorCode)->makeRequest();
233 }
234
235 /**
236 * @requires extension curl
237 */
238 public function testCustomCurlRetryMapAddsNewHandlers()
239 {
240 $this->client->setClassConfig(
241 'Google_IO_Exception',
242 array('retry_map' => array(
243 CURLE_COULDNT_RESOLVE_PROXY => Google_Config::TASK_RETRY_ALWAYS
244 ))
245 );
246
247 $this->setTaskConfig(array('retries' => 5));
248 $result = $this->setNextResponsesThrow(2, '', CURLE_COULDNT_RESOLVE_PROXY)
249 ->setNextResponse(200, '{"success": true}')
250 ->makeRequest();
251
252 $this->assertEquals(array("success" => true), $result);
253 }
254
255 /**
256 * @requires extension curl
257 * @expectedException Google_IO_Exception
258 * @dataProvider customLimitsProvider
259 */
260 public function testCustomCurlRetryMapWithCustomLimits($limit)
261 {
262 $this->client->setClassConfig(
263 'Google_IO_Exception',
264 array('retry_map' => array(
265 CURLE_COULDNT_RESOLVE_PROXY => $limit
266 ))
267 );
268
269 $this->setTaskConfig(array('retries' => 5));
270 $this->setNextResponsesThrow($limit + 1, '', CURLE_COULDNT_RESOLVE_PROXY)
271 ->makeRequest();
272 }
273
274 /**
275 * @requires extension curl
276 * @dataProvider timeoutProvider
277 */
278 public function testCurlTimeouts($config, $minTime)
279 {
280 $this->setTaskConfig($config);
281 $this->setNextResponsesThrow($config['retries'], '', CURLE_GOT_NOTHING)
282 ->setNextResponse(200, '{"success": true}');
283
284 $this->assertTaskTimeGreaterThanOrEqual(
285 $minTime,
286 array($this, 'makeRequest'),
287 $config['initial_delay'] / 10
288 );
289 }
290
291 /**
292 * @dataProvider badTaskConfigProvider
293 */
294 public function testBadTaskConfig($config, $message)
295 {
296 $this->setExpectedException('Google_Task_Exception', $message);
297 $this->setTaskConfig($config);
298
299 new Google_Task_Runner(
300 $this->client,
301 '',
302 array($this, 'testBadTaskConfig')
303 );
304 }
305
306 /**
307 * @expectedException Google_Task_Exception
308 * @expectedExceptionMessage must be a valid callable
309 */
310 public function testBadTaskCallback()
311 {
312 new Google_Task_Runner($this->client, '', 5);
313 }
314
315 /**
316 * @expectedException Google_IO_Exception
317 */
318 public function testTaskRetryOffByDefault()
319 {
320 $this->setNextTaskAllowedRetries(Google_Config::TASK_RETRY_ALWAYS)
321 ->runTask();
322 }
323
324 /**
325 * @expectedException Google_IO_Exception
326 */
327 public function testOneTaskRetryWithError()
328 {
329 $this->setTaskConfig(array('retries' => 1));
330 $this->setNextTasksAllowedRetries(2, Google_Config::TASK_RETRY_ALWAYS)
331 ->runTask();
332 }
333
334 /**
335 * @expectedException Google_IO_Exception
336 */
337 public function testMultipleTaskRetriesWithErrors()
338 {
339 $this->setTaskConfig(array('retries' => 5));
340 $this->setNextTasksAllowedRetries(6, Google_Config::TASK_RETRY_ALWAYS)
341 ->runTask();
342 }
343
344 public function testOneTaskRetryWithSuccess()
345 {
346 $this->setTaskConfig(array('retries' => 1));
347 $result = $this->setNextTaskAllowedRetries(Google_Config::TASK_RETRY_ALWAYS)
348 ->setNextTaskReturnValue('success')
349 ->runTask();
350
351 $this->assertEquals('success', $result);
352 }
353
354 public function testMultipleTaskRetriesWithSuccess()
355 {
356 $this->setTaskConfig(array('retries' => 5));
357 $result = $this->setNextTasksAllowedRetries(2, Google_Config::TASK_RETRY_ALWAYS)
358 ->setNextTaskReturnValue('success')
359 ->runTask();
360
361 $this->assertEquals('success', $result);
362 }
363
364 /**
365 * @expectedException Google_IO_Exception
366 * @dataProvider customLimitsProvider
367 */
368 public function testTaskRetryWithCustomLimits($limit)
369 {
370 $this->setTaskConfig(array('retries' => 5));
371 $this->setNextTasksAllowedRetries($limit + 1, $limit)
372 ->runTask();
373 }
374
375 /**
376 * @dataProvider timeoutProvider
377 */
378 public function testTaskTimeouts($config, $minTime)
379 {
380 $this->setTaskConfig($config);
381 $this->setNextTasksAllowedRetries($config['retries'], $config['retries'] + 1)
382 ->setNextTaskReturnValue('success');
383
384 $this->assertTaskTimeGreaterThanOrEqual(
385 $minTime,
386 array($this, 'runTask'),
387 $config['initial_delay'] / 10
388 );
389 }
390
391 public function testTaskWithManualRetries()
392 {
393 $this->setTaskConfig(array('retries' => 2));
394 $this->setNextTasksAllowedRetries(2, Google_Config::TASK_RETRY_ALWAYS);
395
396 $task = new Google_Task_Runner(
397 $this->client,
398 '',
399 array($this, 'runNextTask')
400 );
401
402 $this->assertTrue($task->canAttmpt());
403 $this->assertTrue($task->attempt());
404
405 $this->assertTrue($task->canAttmpt());
406 $this->assertTrue($task->attempt());
407
408 $this->assertTrue($task->canAttmpt());
409 $this->assertTrue($task->attempt());
410
411 $this->assertFalse($task->canAttmpt());
412 $this->assertFalse($task->attempt());
413 }
414
415 /**
416 * Provider for backoff configurations and expected minimum runtimes.
417 *
418 * @return array
419 */
420 public function timeoutProvider()
421 {
422 $config = array('initial_delay' => .001, 'max_delay' => .01);
423
424 return array(
425 array(array_merge($config, array('retries' => 1)), .001),
426 array(array_merge($config, array('retries' => 2)), .0015),
427 array(array_merge($config, array('retries' => 3)), .00225),
428 array(array_merge($config, array('retries' => 4)), .00375),
429 array(array_merge($config, array('retries' => 5)), .005625)
430 );
431 }
432
433 /**
434 * Provider for custom retry limits.
435 *
436 * @return array
437 */
438 public function customLimitsProvider()
439 {
440 return array(
441 array(Google_Config::TASK_RETRY_NEVER),
442 array(Google_Config::TASK_RETRY_ONCE),
443 );
444 }
445
446 /**
447 * Provider for invalid task configurations.
448 *
449 * @return array
450 */
451 public function badTaskConfigProvider()
452 {
453 return array(
454 array(array('initial_delay' => -1), 'must not be negative'),
455 array(array('max_delay' => 0), 'must be greater than 0'),
456 array(array('factor' => 0), 'must be greater than 0'),
457 array(array('jitter' => 0), 'must be greater than 0'),
458 array(array('retries' => -1), 'must not be negative')
459 );
460 }
461
462 /**
463 * Provider for the default REST errors.
464 *
465 * @return array
466 */
467 public function defaultRestErrorProvider()
468 {
469 return array(
470 array(500),
471 array(503),
472 array(403, '{"error":{"errors":[{"reason":"rateLimitExceeded"}]}}'),
473 array(403, '{"error":{"errors":[{"reason":"userRateLimitExceeded"}]}}'),
474 );
475 }
476
477 /**
478 * Provider for the default cURL errors.
479 *
480 * @return array
481 */
482 public function defaultCurlErrorProvider()
483 {
484 return array(
485 array(6), // CURLE_COULDNT_RESOLVE_HOST
486 array(7), // CURLE_COULDNT_CONNECT
487 array(28), // CURLE_OPERATION_TIMEOUTED
488 array(35), // CURLE_SSL_CONNECT_ERROR
489 array(52), // CURLE_GOT_NOTHING
490 );
491 }
492
493 /**
494 * Assert the minimum amount of time required to run a task.
495 *
496 * NOTE: Intentionally crude for brevity.
497 *
498 * @param float $expected The expected minimum execution time
499 * @param callable $callback The task to time
500 * @param float $delta Allowable relative error
501 *
502 * @throws PHPUnit_Framework_ExpectationFailedException
503 */
504 public static function assertTaskTimeGreaterThanOrEqual(
505 $expected,
506 $callback,
507 $delta = 0.0
508 ) {
509 $time = microtime(true);
510
511 call_user_func($callback);
512
513 self::assertThat(
514 microtime(true) - $time,
515 self::logicalOr(
516 self::greaterThan($expected),
517 self::equalTo($expected, $delta)
518 )
519 );
520 }
521
522 /**
523 * Sets the task runner configurations.
524 *
525 * @param array $config The task runner configurations
526 */
527 private function setTaskConfig(array $config)
528 {
529 $config += array(
530 'initial_delay' => .0001,
531 'max_delay' => .001,
532 'factor' => 2,
533 'jitter' => .5,
534 'retries' => 1
535 );
536 $this->client->setClassConfig('Google_Task_Runner', $config);
537 }
538
539 /**
540 * Sets the next responses.
541 *
542 * @param integer $count The number of responses
543 * @param string $code The response code
544 * @param string $body The response body
545 * @param array $headers The response headers
546 *
547 * @return TaskTest
548 */
549 private function setNextResponses(
550 $count,
551 $code = '200',
552 $body = '{}',
553 array $headers = array()
554 ) {
555 while ($count-- > 0) {
556 $this->setNextResponse($code, $body, $headers);
557 }
558
559 return $this;
560 }
561
562 /**
563 * Sets the next response.
564 *
565 * @param string $code The response code
566 * @param string $body The response body
567 * @param array $headers The response headers
568 *
569 * @return TaskTest
570 */
571 private function setNextResponse(
572 $code = '200',
573 $body = '{}',
574 array $headers = array()
575 ) {
576 $this->mockedCalls[$this->mockedCallsCount++] = array(
577 'code' => (string) $code,
578 'headers' => $headers,
579 'body' => is_string($body) ? $body : json_encode($body)
580 );
581
582 return $this;
583 }
584
585 /**
586 * Forces the next responses to throw an IO exception.
587 *
588 * @param integer $count The number of responses
589 * @param string $message The exception messages
590 * @param string $code The exception code
591 *
592 * @return TaskTest
593 */
594 private function setNextResponsesThrow($count, $message, $code)
595 {
596 while ($count-- > 0) {
597 $this->setNextResponseThrows($message, $code);
598 }
599
600 return $this;
601 }
602
603 /**
604 * Forces the next response to throw an IO exception.
605 *
606 * @param string $message The exception messages
607 * @param string $code The exception code
608 *
609 * @return TaskTest
610 */
611 private function setNextResponseThrows($message, $code)
612 {
613 $map = $this->client->getClassConfig('Google_IO_Exception', 'retry_map');
614 $this->mockedCalls[$this->mockedCallsCount++] = new Google_IO_Exception(
615 $message,
616 $code,
617 null,
618 $map
619 );
620
621 return $this;
622 }
623
624 /**
625 * Runs the defined request.
626 *
627 * @return array
628 */
629 private function makeRequest()
630 {
631 $request = new Google_Http_Request('/test');
632
633 $io = $this->getMockBuilder('Google_IO_Abstract')
634 ->disableOriginalConstructor()
635 ->setMethods(array('makeRequest'))
636 ->getMockForAbstractClass();
637
638 $io->expects($this->exactly($this->mockedCallsCount))
639 ->method('makeRequest')
640 ->will($this->returnCallback(array($this, 'getNextMockedCall')));
641
642 $this->client->setIo($io);
643
644 return Google_Http_REST::execute($this->client, $request);
645 }
646
647 /**
648 * Gets the next mocked response.
649 *
650 * @param Google_Http_Request $request The mocked request
651 *
652 * @return Google_Http_Request
653 */
654 public function getNextMockedCall($request)
655 {
656 $current = $this->mockedCalls[$this->currentMockedCall++];
657
658 if ($current instanceof Exception) {
659 throw $current;
660 }
661
662 $request->setResponseHttpCode($current['code']);
663 $request->setResponseHeaders($current['headers']);
664 $request->setResponseBody($current['body']);
665
666 return $request;
667 }
668
669 /**
670 * Sets the next task return value.
671 *
672 * @param mixed $value The next return value
673 *
674 * @return TaskTest
675 */
676 private function setNextTaskReturnValue($value)
677 {
678 $this->mockedCalls[$this->mockedCallsCount++] = $value;
679 return $this;
680 }
681
682 /**
683 * Sets the next exception `allowedRetries()` return value.
684 *
685 * @param boolean $allowedRetries The next `allowedRetries()` return value.
686 *
687 * @return TaskTest
688 */
689 private function setNextTaskAllowedRetries($allowedRetries)
690 {
691 $this->mockedCalls[$this->mockedCallsCount++] = $allowedRetries;
692 return $this;
693 }
694
695 /**
696 * Sets multiple exception `allowedRetries()` return value.
697 *
698 * @param integer $count The number of `allowedRetries()` return values.
699 * @param boolean $allowedRetries The `allowedRetries()` return value.
700 *
701 * @return TaskTest
702 */
703 private function setNextTasksAllowedRetries($count, $allowedRetries)
704 {
705 while ($count-- > 0) {
706 $this->setNextTaskAllowedRetries($allowedRetries);
707 }
708
709 return $this;
710 }
711
712 /**
713 * Runs the defined task.
714 *
715 * @return mixed
716 */
717 private function runTask()
718 {
719 $task = new Google_Task_Runner(
720 $this->client,
721 '',
722 array($this, 'runNextTask')
723 );
724
725 $exception = $this->getMockBuilder('Google_IO_Exception')
726 ->disableOriginalConstructor()
727 ->setMethods(array('allowedRetries'))
728 ->getMock();
729 $exceptionCount = 0;
730 $exceptionCalls = array();
731
732 for ($i = 0; $i < $this->mockedCallsCount; $i++) {
733 if (is_int($this->mockedCalls[$i])) {
734 $exceptionCalls[$exceptionCount++] = $this->mockedCalls[$i];
735 $this->mockedCalls[$i] = $exception;
736 }
737 }
738
739 $exception->expects($this->exactly($exceptionCount))
740 ->method('allowedRetries')
741 ->will(
742 new PHPUnit_Framework_MockObject_Stub_ConsecutiveCalls(
743 $exceptionCalls
744 )
745 );
746
747 return $task->run();
748 }
749
750 /**
751 * Gets the next task return value.
752 *
753 * @return mixed
754 */
755 public function runNextTask()
756 {
757 $current = $this->mockedCalls[$this->currentMockedCall++];
758
759 if ($current instanceof Exception) {
760 throw $current;
761 }
762
763 return $current;
764 }
765 }
766