PageRenderTime 47ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/api/vendor/guzzle/guzzle/tests/Guzzle/Tests/Plugin/Cache/DefaultRevalidationTest.php

https://gitlab.com/x33n/respond
PHP | 246 lines | 204 code | 20 blank | 22 comment | 3 complexity | 3c26d26006a2f21abd807f56fa04cb4c MD5 | raw file
  1. <?php
  2. namespace Guzzle\Tests\Plugin\Cache;
  3. use Guzzle\Http\Client;
  4. use Guzzle\Http\ClientInterface;
  5. use Guzzle\Http\Exception\BadResponseException;
  6. use Guzzle\Http\Exception\CurlException;
  7. use Guzzle\Http\Message\Request;
  8. use Guzzle\Http\Message\Response;
  9. use Guzzle\Http\Message\RequestFactory;
  10. use Guzzle\Plugin\Cache\CachePlugin;
  11. use Guzzle\Cache\DoctrineCacheAdapter;
  12. use Doctrine\Common\Cache\ArrayCache;
  13. use Guzzle\Plugin\Cache\DefaultCacheStorage;
  14. use Guzzle\Plugin\Mock\MockPlugin;
  15. use Guzzle\Tests\Http\Server;
  16. /**
  17. * @covers Guzzle\Plugin\Cache\DefaultRevalidation
  18. * @group server
  19. */
  20. class DefaultRevalidationTest extends \Guzzle\Tests\GuzzleTestCase
  21. {
  22. protected function getHttpDate($time)
  23. {
  24. return gmdate(ClientInterface::HTTP_DATE, strtotime($time));
  25. }
  26. /**
  27. * Data provider to test cache revalidation
  28. *
  29. * @return array
  30. */
  31. public function cacheRevalidationDataProvider()
  32. {
  33. return array(
  34. // Forces revalidation that passes
  35. array(
  36. true,
  37. "Pragma: no-cache\r\n\r\n",
  38. "HTTP/1.1 200 OK\r\nDate: " . $this->getHttpDate('-100 hours') . "\r\nContent-Length: 4\r\n\r\nData",
  39. "HTTP/1.1 304 NOT MODIFIED\r\nCache-Control: max-age=2000000\r\nContent-Length: 0\r\n\r\n",
  40. ),
  41. // Forces revalidation that overwrites what is in cache
  42. array(
  43. false,
  44. "\r\n",
  45. "HTTP/1.1 200 OK\r\nCache-Control: must-revalidate, no-cache\r\nDate: " . $this->getHttpDate('-10 hours') . "\r\nContent-Length: 4\r\n\r\nData",
  46. "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nDatas",
  47. "HTTP/1.1 200 OK\r\nContent-Length: 5\r\nDate: " . $this->getHttpDate('now') . "\r\n\r\nDatas"
  48. ),
  49. // Throws an exception during revalidation
  50. array(
  51. false,
  52. "\r\n",
  53. "HTTP/1.1 200 OK\r\nCache-Control: no-cache\r\nDate: " . $this->getHttpDate('-3 hours') . "\r\n\r\nData",
  54. "HTTP/1.1 500 INTERNAL SERVER ERROR\r\nContent-Length: 0\r\n\r\n"
  55. ),
  56. // ETag mismatch
  57. array(
  58. false,
  59. "\r\n",
  60. "HTTP/1.1 200 OK\r\nCache-Control: no-cache\r\nETag: \"123\"\r\nDate: " . $this->getHttpDate('-10 hours') . "\r\n\r\nData",
  61. "HTTP/1.1 304 NOT MODIFIED\r\nETag: \"123456\"\r\n\r\n",
  62. ),
  63. );
  64. }
  65. /**
  66. * @dataProvider cacheRevalidationDataProvider
  67. */
  68. public function testRevalidatesResponsesAgainstOriginServer($can, $request, $response, $validate = null, $result = null)
  69. {
  70. // Send some responses to the test server for cache validation
  71. $server = $this->getServer();
  72. $server->flush();
  73. if ($validate) {
  74. $server->enqueue($validate);
  75. }
  76. $request = RequestFactory::getInstance()->fromMessage("GET / HTTP/1.1\r\nHost: 127.0.0.1:" . $server->getPort() . "\r\n" . $request);
  77. $response = Response::fromMessage($response);
  78. $request->setClient(new Client());
  79. $plugin = new CachePlugin(new DoctrineCacheAdapter(new ArrayCache()));
  80. $this->assertEquals(
  81. $can,
  82. $plugin->canResponseSatisfyRequest($request, $response),
  83. '-> ' . $request . "\n" . $response
  84. );
  85. if ($result) {
  86. $result = Response::fromMessage($result);
  87. $result->removeHeader('Date');
  88. $request->getResponse()->removeHeader('Date');
  89. $request->getResponse()->removeHeader('Connection');
  90. // Get rid of dates
  91. $this->assertEquals((string) $result, (string) $request->getResponse());
  92. }
  93. if ($validate) {
  94. $this->assertEquals(1, count($server->getReceivedRequests()));
  95. }
  96. }
  97. public function testHandles404RevalidationResponses()
  98. {
  99. $request = new Request('GET', 'http://foo.com');
  100. $request->setClient(new Client());
  101. $badResponse = new Response(404, array(), 'Oh no!');
  102. $badRequest = clone $request;
  103. $badRequest->setResponse($badResponse, true);
  104. $response = new Response(200, array(), 'foo');
  105. // Seed the cache
  106. $s = new DefaultCacheStorage(new DoctrineCacheAdapter(new ArrayCache()));
  107. $s->cache($request, $response);
  108. $this->assertNotNull($s->fetch($request));
  109. $rev = $this->getMockBuilder('Guzzle\Plugin\Cache\DefaultRevalidation')
  110. ->setConstructorArgs(array($s))
  111. ->setMethods(array('createRevalidationRequest'))
  112. ->getMock();
  113. $rev->expects($this->once())
  114. ->method('createRevalidationRequest')
  115. ->will($this->returnValue($badRequest));
  116. try {
  117. $rev->revalidate($request, $response);
  118. $this->fail('Should have thrown an exception');
  119. } catch (BadResponseException $e) {
  120. $this->assertSame($badResponse, $e->getResponse());
  121. $this->assertNull($s->fetch($request));
  122. }
  123. }
  124. public function testCanRevalidateWithPlugin()
  125. {
  126. $this->getServer()->flush();
  127. $this->getServer()->enqueue(array(
  128. "HTTP/1.1 200 OK\r\n" .
  129. "Date: Mon, 12 Nov 2012 03:06:37 GMT\r\n" .
  130. "Cache-Control: private, s-maxage=0, max-age=0, must-revalidate\r\n" .
  131. "Last-Modified: Mon, 12 Nov 2012 02:53:38 GMT\r\n" .
  132. "Content-Length: 2\r\n\r\nhi",
  133. "HTTP/1.0 304 Not Modified\r\n" .
  134. "Date: Mon, 12 Nov 2012 03:06:38 GMT\r\n" .
  135. "Content-Type: text/html; charset=UTF-8\r\n" .
  136. "Last-Modified: Mon, 12 Nov 2012 02:53:38 GMT\r\n" .
  137. "Age: 6302\r\n\r\n",
  138. "HTTP/1.0 304 Not Modified\r\n" .
  139. "Date: Mon, 12 Nov 2012 03:06:38 GMT\r\n" .
  140. "Content-Type: text/html; charset=UTF-8\r\n" .
  141. "Last-Modified: Mon, 12 Nov 2012 02:53:38 GMT\r\n" .
  142. "Age: 6302\r\n\r\n",
  143. ));
  144. $client = new Client($this->getServer()->getUrl());
  145. $client->addSubscriber(new CachePlugin());
  146. $this->assertEquals(200, $client->get()->send()->getStatusCode());
  147. $this->assertEquals(200, $client->get()->send()->getStatusCode());
  148. $this->assertEquals(200, $client->get()->send()->getStatusCode());
  149. $this->assertEquals(3, count($this->getServer()->getReceivedRequests()));
  150. }
  151. public function testCanHandleRevalidationFailures()
  152. {
  153. $client = new Client($this->getServer()->getUrl());
  154. $lm = gmdate('c', time() - 60);
  155. $mock = new MockPlugin(array(
  156. new Response(200, array(
  157. 'Date' => $lm,
  158. 'Cache-Control' => 'max-age=100, must-revalidate, stale-if-error=9999',
  159. 'Last-Modified' => $lm,
  160. 'Content-Length' => 2
  161. ), 'hi'),
  162. new CurlException('Bleh')
  163. ));
  164. $client->addSubscriber(new CachePlugin());
  165. $client->addSubscriber($mock);
  166. $client->get()->send();
  167. $response = $client->get()->send();
  168. $this->assertEquals(200, $response->getStatusCode());
  169. $this->assertEquals('hi', $response->getBody(true));
  170. $this->assertEquals(2, count($mock->getReceivedRequests()));
  171. $this->assertEquals(0, count($mock->getQueue()));
  172. }
  173. public function testCanHandleStaleIfErrorWhenRevalidating()
  174. {
  175. $lm = gmdate('c', time() - 60);
  176. $mock = new MockPlugin(array(
  177. new Response(200, array(
  178. 'Date' => $lm,
  179. 'Cache-Control' => 'must-revalidate, max-age=0, stale-if-error=1200',
  180. 'Last-Modified' => $lm,
  181. 'Content-Length' => 2
  182. ), 'hi'),
  183. new CurlException('Oh no!')
  184. ));
  185. $cache = new CachePlugin();
  186. $client = new Client('http://www.example.com');
  187. $client->addSubscriber($cache);
  188. $client->addSubscriber($mock);
  189. $this->assertEquals(200, $client->get()->send()->getStatusCode());
  190. $response = $client->get()->send();
  191. $this->assertEquals(200, $response->getStatusCode());
  192. $this->assertCount(0, $mock);
  193. $this->assertEquals('HIT from GuzzleCache', (string) $response->getHeader('X-Cache-Lookup'));
  194. $this->assertEquals('HIT_ERROR from GuzzleCache', (string) $response->getHeader('X-Cache'));
  195. }
  196. /**
  197. * @group issue-437
  198. */
  199. public function testDoesNotTouchClosureListeners()
  200. {
  201. $this->getServer()->flush();
  202. $this->getServer()->enqueue(array(
  203. "HTTP/1.1 200 OK\r\n" .
  204. "Date: Mon, 12 Nov 2012 03:06:37 GMT\r\n" .
  205. "Cache-Control: private, s-maxage=0, max-age=0, must-revalidate\r\n" .
  206. "Last-Modified: Mon, 12 Nov 2012 02:53:38 GMT\r\n" .
  207. "Content-Length: 2\r\n\r\nhi",
  208. "HTTP/1.0 304 Not Modified\r\n" .
  209. "Date: Mon, 12 Nov 2012 03:06:38 GMT\r\n" .
  210. "Content-Type: text/html; charset=UTF-8\r\n" .
  211. "Last-Modified: Mon, 12 Nov 2012 02:53:38 GMT\r\n" .
  212. "Age: 6302\r\n\r\n",
  213. "HTTP/1.0 304 Not Modified\r\n" .
  214. "Date: Mon, 12 Nov 2012 03:06:38 GMT\r\n" .
  215. "Content-Type: text/html; charset=UTF-8\r\n" .
  216. "Last-Modified: Mon, 12 Nov 2012 02:53:38 GMT\r\n" .
  217. "Age: 6302\r\n\r\n",
  218. ));
  219. $client = new Client($this->getServer()->getUrl());
  220. $client->addSubscriber(new CachePlugin());
  221. $client->getEventDispatcher()->addListener('command.after_send', function(){});
  222. $this->assertEquals(200, $client->get()->send()->getStatusCode());
  223. $this->assertEquals(200, $client->get()->send()->getStatusCode());
  224. $this->assertEquals(200, $client->get()->send()->getStatusCode());
  225. }
  226. }