Open Monograph Press  3.3.0
BackoffPluginTest.php
1 <?php
2 
4 
20 
26 {
27  protected $retried;
28 
29  public function setUp()
30  {
31  $this->retried = false;
32  }
33 
34  public static function getSubscribedEvents()
35  {
36  return array(BackoffPlugin::RETRY_EVENT => 'onRequestRetry');
37  }
38 
39  public function onRequestRetry(Event $event)
40  {
41  $this->retried = $event;
42  }
43 
44  public function testHasEventList()
45  {
46  $this->assertEquals(1, count(BackoffPlugin::getAllEvents()));
47  }
48 
50  {
51  $plugin = BackoffPlugin::getExponentialBackoff(3, array(204), array(10));
52  $this->assertInstanceOf('Guzzle\Plugin\Backoff\BackoffPlugin', $plugin);
53  $strategy = $this->readAttribute($plugin, 'strategy');
54  $this->assertInstanceOf('Guzzle\Plugin\Backoff\TruncatedBackoffStrategy', $strategy);
55  $this->assertEquals(3, $this->readAttribute($strategy, 'max'));
56  $strategy = $this->readAttribute($strategy, 'next');
57  $this->assertInstanceOf('Guzzle\Plugin\Backoff\HttpBackoffStrategy', $strategy);
58  $this->assertEquals(array(204 => true), $this->readAttribute($strategy, 'errorCodes'));
59  $strategy = $this->readAttribute($strategy, 'next');
60  $this->assertInstanceOf('Guzzle\Plugin\Backoff\CurlBackoffStrategy', $strategy);
61  $this->assertEquals(array(10 => true), $this->readAttribute($strategy, 'errorCodes'));
62  $strategy = $this->readAttribute($strategy, 'next');
63  $this->assertInstanceOf('Guzzle\Plugin\Backoff\ExponentialBackoffStrategy', $strategy);
64  }
65 
67  {
68  $request = new Request('GET', 'http://www.example.com');
69  $request->setState('transfer');
70 
71  $mock = $this->getMockBuilder('Guzzle\Plugin\Backoff\BackoffStrategyInterface')
72  ->setMethods(array('getBackoffPeriod'))
73  ->getMockForAbstractClass();
74 
75  $mock->expects($this->once())
76  ->method('getBackoffPeriod')
77  ->will($this->returnValue(false));
78 
79  $plugin = new BackoffPlugin($mock);
80  $plugin->addSubscriber($this);
81  $plugin->onRequestSent(new Event(array('request' => $request)));
82  $this->assertFalse($this->retried);
83  }
84 
85  public function testUpdatesRequestForRetry()
86  {
87  $request = new Request('GET', 'http://www.example.com');
88  $request->setState('transfer');
89  $response = new Response(500);
90  $handle = $this->getMockBuilder('Guzzle\Http\Curl\CurlHandle')->disableOriginalConstructor()->getMock();
91  $e = new CurlException();
92  $e->setCurlHandle($handle);
93 
94  $plugin = new BackoffPlugin(new ConstantBackoffStrategy(10));
95  $plugin->addSubscriber($this);
96 
97  $event = new Event(array(
98  'request' => $request,
99  'response' => $response,
100  'exception' => $e
101  ));
102 
103  $plugin->onRequestSent($event);
104  $this->assertEquals(array(
105  'request' => $request,
106  'response' => $response,
107  'handle' => $handle,
108  'retries' => 1,
109  'delay' => 10
110  ), $this->readAttribute($this->retried, 'context'));
111 
112  $plugin->onRequestSent($event);
113  $this->assertEquals(array(
114  'request' => $request,
115  'response' => $response,
116  'handle' => $handle,
117  'retries' => 2,
118  'delay' => 10
119  ), $this->readAttribute($this->retried, 'context'));
120  }
121 
123  {
124  $request = new Request('GET', 'http://www.foo.com');
125  $plugin = new BackoffPlugin(new ConstantBackoffStrategy(10));
126  $plugin->onRequestPoll(new Event(array('request' => $request)));
127  }
128 
129  public function testRetriesRequests()
130  {
131  // Create a script to return several 500 and 503 response codes
132  $this->getServer()->flush();
133  $this->getServer()->enqueue(array(
134  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
135  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
136  "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata"
137  ));
138 
139  $plugin = new BackoffPlugin(
141  new HttpBackoffStrategy(null,
142  new CurlBackoffStrategy(null,
143  new ConstantBackoffStrategy(0.05)
144  )
145  )
146  )
147  );
148 
149  $client = new Client($this->getServer()->getUrl());
150  $client->getEventDispatcher()->addSubscriber($plugin);
151  $request = $client->get();
152  $request->send();
153 
154  // Make sure it eventually completed successfully
155  $this->assertEquals(200, $request->getResponse()->getStatusCode());
156  $this->assertEquals('data', $request->getResponse()->getBody(true));
157 
158  // Check that three requests were made to retry this request
159  $this->assertEquals(3, count($this->getServer()->getReceivedRequests(false)));
160  $this->assertEquals(2, $request->getParams()->get(BackoffPlugin::RETRY_PARAM));
161  }
162 
166  public function testFailsOnTruncation()
167  {
168  $this->getServer()->flush();
169  $this->getServer()->enqueue(array(
170  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
171  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n"
172  ));
173 
174  $plugin = new BackoffPlugin(
176  new HttpBackoffStrategy(null,
177  new ConstantBackoffStrategy(0.05)
178  )
179  )
180  );
181 
182  $client = new Client($this->getServer()->getUrl());
183  $client->addSubscriber($plugin);
184  $client->get()->send();
185  }
186 
188  {
189  // Create a script to return several 500 and 503 response codes
190  $this->getServer()->flush();
191  $this->getServer()->enqueue(array(
192  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
193  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
194  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
195  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
196  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
197  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
198  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
199  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
200  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
201  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
202  "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata",
203  "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata",
204  "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata",
205  "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata",
206  "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata"
207  ));
208 
209  $plugin = new BackoffPlugin(
210  new HttpBackoffStrategy(null,
212  new CurlBackoffStrategy(null,
213  new ConstantBackoffStrategy(0.1)
214  )
215  )
216  )
217  );
218  $client = new Client($this->getServer()->getUrl());
219  $client->getEventDispatcher()->addSubscriber($plugin);
220  $requests = array();
221  for ($i = 0; $i < 5; $i++) {
222  $requests[] = $client->get();
223  }
224  $client->send($requests);
225 
226  $this->assertEquals(15, count($this->getServer()->getReceivedRequests(false)));
227  }
228 
234  {
235  $this->getServer()->flush();
236  $this->getServer()->enqueue(array(
237  "HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\n\r\n",
238  "HTTP/1.1 200 OK\r\nContent-Length: 4\r\n\r\ndata"
239  ));
240  // Need to sleep for some time ensure that the polling works correctly in the observer
241  $plugin = new BackoffPlugin(new HttpBackoffStrategy(null,
243  new ConstantBackoffStrategy(0.5))));
244 
245  $client = new Client($this->getServer()->getUrl());
246  $client->getEventDispatcher()->addSubscriber($plugin);
247  $request = $client->get();
248  $request->send();
249  // Make sure it eventually completed successfully
250  $this->assertEquals('data', $request->getResponse()->getBody(true));
251  // Check that two requests were made to retry this request
252  $this->assertEquals(2, count($this->getServer()->getReceivedRequests(false)));
253  }
254 
256  {
257  // Create a request with a body
258  $request = new EntityEnclosingRequest('PUT', 'http://www.example.com');
259  $request->setBody('abc');
260  // Set the retry time to be something that will be retried always
261  $request->getParams()->set(BackoffPlugin::DELAY_PARAM, 2);
262  // Seek to the end of the stream
263  $request->getBody()->seek(3);
264  $this->assertEquals('', $request->getBody()->read(1));
265  // Create a plugin that does not delay when retrying
266  $plugin = new BackoffPlugin(new ConstantBackoffStrategy(0));
267  $plugin->onRequestPoll($this->getMockEvent($request));
268  // Ensure that the stream was seeked to 0
269  $this->assertEquals('a', $request->getBody()->read(1));
270  }
271 
273  {
274  // Create a request with a body
275  $request = new EntityEnclosingRequest('PUT', 'http://www.example.com');
276  $request->getParams()->set(BackoffPlugin::DELAY_PARAM, 2);
277  $plugin = new BackoffPlugin(new ConstantBackoffStrategy(0));
278  $plugin->onRequestPoll($this->getMockEvent($request));
279  }
280 
281  protected function getMockEvent(RequestInterface $request)
282  {
283  // Create a mock curl multi object
284  $multi = $this->getMockBuilder('Guzzle\Http\Curl\CurlMulti')
285  ->setMethods(array('remove', 'add'))
286  ->getMock();
287 
288  // Create an event that is expected for the Poll event
289  $event = new Event(array(
290  'request' => $request,
291  'curl_multi' => $multi
292  ));
293  $event->setName(CurlMultiInterface::POLLING_REQUEST);
294 
295  return $event;
296  }
297 }
Guzzle\Plugin\Backoff\BackoffPlugin\getExponentialBackoff
static getExponentialBackoff( $maxRetries=3, array $httpCodes=null, array $curlCodes=null)
Definition: BackoffPlugin.php:46
Guzzle\Http\Exception\CurlException
Definition: CurlException.php:10
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\setUp
setUp()
Definition: BackoffPluginTest.php:29
Guzzle\Http\Message\RequestInterface
Definition: lib/vendor/guzzle/guzzle/src/Guzzle/Http/Message/RequestInterface.php:16
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\testFailsOnTruncation
testFailsOnTruncation()
Definition: BackoffPluginTest.php:166
Guzzle\Http\Curl\CurlMultiInterface\POLLING_REQUEST
const POLLING_REQUEST
Definition: CurlMultiInterface.php:14
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\testDoesNotSeekOnRequestsWithNoBodyWhenRetrying
testDoesNotSeekOnRequestsWithNoBodyWhenRetrying()
Definition: BackoffPluginTest.php:272
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\testSeeksToBeginningOfRequestBodyWhenRetrying
testSeeksToBeginningOfRequestBodyWhenRetrying()
Definition: BackoffPluginTest.php:255
Guzzle\Plugin\Backoff\BackoffPlugin\getAllEvents
static getAllEvents()
Definition: BackoffPlugin.php:60
Guzzle\Tests\GuzzleTestCase
Definition: GuzzleTestCase.php:22
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\testCreatesDefaultExponentialBackoffPlugin
testCreatesDefaultExponentialBackoffPlugin()
Definition: BackoffPluginTest.php:49
Symfony\Component\EventDispatcher\EventSubscriberInterface
Definition: lib/vendor/symfony/event-dispatcher/EventSubscriberInterface.php:25
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\testRetriesRequestsWhenInParallel
testRetriesRequestsWhenInParallel()
Definition: BackoffPluginTest.php:187
Guzzle\Http\Message\Response
Definition: paymethod/paypal/lib/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Response.php:17
Guzzle\Plugin\Backoff\BackoffPlugin\RETRY_EVENT
const RETRY_EVENT
Definition: BackoffPlugin.php:20
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\getMockEvent
getMockEvent(RequestInterface $request)
Definition: BackoffPluginTest.php:281
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\testRetriesRequests
testRetriesRequests()
Definition: BackoffPluginTest.php:129
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\$retried
$retried
Definition: BackoffPluginTest.php:27
Guzzle\Plugin\Backoff\BackoffPlugin
Definition: BackoffPlugin.php:16
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\testUpdatesRequestForRetry
testUpdatesRequestForRetry()
Definition: BackoffPluginTest.php:85
Guzzle\Common\Event
Definition: lib/vendor/guzzle/guzzle/src/Guzzle/Common/Event.php:10
Guzzle\Plugin\Backoff\ConstantBackoffStrategy
Definition: ConstantBackoffStrategy.php:14
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\testHasEventList
testHasEventList()
Definition: BackoffPluginTest.php:44
Guzzle\Http\Message\Request
Definition: paymethod/paypal/lib/vendor/guzzle/guzzle/src/Guzzle/Http/Message/Request.php:25
Guzzle\Http\Message\EntityEnclosingRequest
Definition: EntityEnclosingRequest.php:14
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\testDoesNothingWhenNotRetryingAndPollingRequest
testDoesNothingWhenNotRetryingAndPollingRequest()
Definition: BackoffPluginTest.php:122
Guzzle\Plugin\Backoff\BackoffPlugin\RETRY_PARAM
const RETRY_PARAM
Definition: BackoffPlugin.php:19
Guzzle\Plugin\Backoff\TruncatedBackoffStrategy
Definition: TruncatedBackoffStrategy.php:12
Guzzle\Http\Curl\CurlMultiInterface
Definition: CurlMultiInterface.php:12
Guzzle\Http\Client
Definition: paymethod/paypal/lib/vendor/guzzle/guzzle/src/Guzzle/Http/Client.php:24
Guzzle\Http\Curl\CurlMulti
Definition: CurlMulti.php:16
Guzzle\Plugin\Backoff\HttpBackoffStrategy
Definition: HttpBackoffStrategy.php:14
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\testDoesNotRetryUnlessStrategyReturnsNumber
testDoesNotRetryUnlessStrategyReturnsNumber()
Definition: BackoffPluginTest.php:66
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest
Definition: BackoffPluginTest.php:25
Guzzle\Plugin\Backoff\BackoffPlugin\DELAY_PARAM
const DELAY_PARAM
Definition: BackoffPlugin.php:18
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\onRequestRetry
onRequestRetry(Event $event)
Definition: BackoffPluginTest.php:39
Guzzle\Plugin\Backoff\CurlBackoffStrategy
Definition: CurlBackoffStrategy.php:13
Guzzle\Tests\GuzzleTestCase\getServer
static getServer()
Definition: GuzzleTestCase.php:36
Guzzle\Tests\Plugin\Backoff
Definition: AbstractBackoffStrategyTest.php:3
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\testRetriesPooledRequestsUsingDelayAndPollingEvent
testRetriesPooledRequestsUsingDelayAndPollingEvent()
Definition: BackoffPluginTest.php:233
Guzzle\Tests\Plugin\Backoff\BackoffPluginTest\getSubscribedEvents
static getSubscribedEvents()
Definition: BackoffPluginTest.php:34