CacheTest.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. <?php
  2. /**
  3. * Lithium: the most rad php framework
  4. *
  5. * @copyright Copyright 2013, Union of RAD (http://union-of-rad.org)
  6. * @license http://opensource.org/licenses/bsd-license.php The BSD License
  7. */
  8. namespace lithium\tests\cases\storage;
  9. use SplFileInfo;
  10. use lithium\core\Libraries;
  11. use lithium\storage\Cache;
  12. class CacheTest extends \lithium\test\Unit {
  13. public function setUp() {
  14. Cache::reset();
  15. }
  16. public function tearDown() {
  17. Cache::reset();
  18. }
  19. protected function _checkPath() {
  20. $resources = Libraries::get(true, 'resources');
  21. if (is_writable($resources) && !is_dir("{$resources}/tmp/cache")) {
  22. mkdir("{$resources}/tmp/cache", 0777, true);
  23. }
  24. $directory = new SplFileInfo("{$resources}/tmp/cache");
  25. return ($directory->isDir() && $directory->isReadable() && $directory->isWritable());
  26. }
  27. public function testBasicCacheConfig() {
  28. $result = Cache::config();
  29. $this->assertFalse($result);
  30. $config = array('default' => array('adapter' => '\some\adapter', 'filters' => array()));
  31. $result = Cache::config($config);
  32. $this->assertNull($result);
  33. $expected = $config;
  34. $result = Cache::config();
  35. $this->assertEqual($expected, $result);
  36. $result = Cache::reset();
  37. $this->assertNull($result);
  38. $config = array('default' => array('adapter' => '\some\adapter', 'filters' => array()));
  39. Cache::config($config);
  40. $result = Cache::config();
  41. $expected = $config;
  42. $this->assertEqual($expected, $result);
  43. $result = Cache::reset();
  44. $this->assertNull($result);
  45. $config = array('default' => array(
  46. 'adapter' => '\some\adapter',
  47. 'filters' => array('Filter1', 'Filter2')
  48. ));
  49. Cache::config($config);
  50. $result = Cache::config();
  51. $expected = $config;
  52. $this->assertEqual($expected, $result);
  53. }
  54. public function testkeyNoContext() {
  55. $key = 'this is a cache key';
  56. $result = Cache::key($key);
  57. $expected = 'this is a cache key';
  58. $this->assertIdentical($expected, $result);
  59. $key = '1120-cache éë';
  60. $result = Cache::key($key);
  61. $expected = '1120-cache éë';
  62. $this->assertIdentical($expected, $result);
  63. }
  64. public function testKeyWithLambda() {
  65. $key = function() {
  66. return 'lambda_key';
  67. };
  68. $result = Cache::key($key);
  69. $expected = 'lambda_key';
  70. $this->assertIdentical($expected, $result);
  71. $key = function() {
  72. return 'lambda key';
  73. };
  74. $result = Cache::key($key);
  75. $expected = 'lambda key';
  76. $this->assertIdentical($expected, $result);
  77. $key = function($data = array()) {
  78. $defaults = array('foo' => 'foo', 'bar' => 'bar');
  79. $data += $defaults;
  80. return 'composed_key_with_' . $data['foo'] . '_' . $data['bar'];
  81. };
  82. $result = Cache::key($key, array('foo' => 'boo', 'bar' => 'far'));
  83. $expected = 'composed_key_with_boo_far';
  84. $this->assertIdentical($expected, $result);
  85. }
  86. public function testKeyWithClosure() {
  87. $value = 5;
  88. $key = function() use ($value) {
  89. return "closure key {$value}";
  90. };
  91. $result = Cache::key($key);
  92. $expected = 'closure key 5';
  93. $this->assertIdentical($expected, $result);
  94. $reference = 'mutable';
  95. $key = function () use (&$reference) {
  96. $reference .= ' key';
  97. return $reference;
  98. };
  99. $result = Cache::key($key);
  100. $expected = 'mutable key';
  101. $this->assertIdentical($expected, $result);
  102. $this->assertIdentical('mutable key', $reference);
  103. }
  104. public function testKeyWithClosureAndArguments() {
  105. $value = 'closure argument';
  106. $key = function($value) {
  107. return $value;
  108. };
  109. $result = Cache::key($key($value));
  110. $expected = 'closure argument';
  111. $this->assertIdentical($expected, $result);
  112. }
  113. public function testCacheWrite() {
  114. $config = array('default' => array(
  115. 'adapter' => 'Memory', 'filters' => array()
  116. ));
  117. Cache::config($config);
  118. $result = Cache::config();
  119. $expected = $config;
  120. $this->assertEqual($expected, $result);
  121. $result = Cache::write('default', 'some_key', 'some_data', '+1 minute');
  122. $this->assertTrue($result);
  123. $result = Cache::write('non_existing', 'key_value', 'data', '+1 minute');
  124. $this->assertFalse($result);
  125. }
  126. public function testCacheWriteMultipleItems() {
  127. $config = array('default' => array(
  128. 'adapter' => 'Memory', 'filters' => array(), 'strategies' => array()
  129. ));
  130. Cache::config($config);
  131. $result = Cache::config();
  132. $expected = $config;
  133. $this->assertEqual($expected, $result);
  134. $data = array(
  135. 'key1' => 'value1',
  136. 'key2' => 'value2',
  137. 'key3' => 'value3'
  138. );
  139. $result = Cache::write('default', $data, '+1 minute');
  140. $this->assertTrue($result);
  141. }
  142. public function testCacheReadMultipleItems() {
  143. $config = array('default' => array(
  144. 'adapter' => 'Memory', 'filters' => array(), 'strategies' => array()
  145. ));
  146. Cache::config($config);
  147. $result = Cache::config();
  148. $expected = $config;
  149. $this->assertEqual($expected, $result);
  150. $data = array(
  151. 'read1' => 'value1',
  152. 'read2' => 'value2',
  153. 'read3' => 'value3'
  154. );
  155. $result = Cache::write('default', $data, '+1 minute');
  156. $this->assertTrue($result);
  157. $keys = array_keys($data);
  158. $result = Cache::read('default', $keys);
  159. $this->assertEqual($data, $result);
  160. }
  161. public function testCacheReadWithConditions() {
  162. $config = array('default' => array('adapter' => 'Memory', 'filters' => array()));
  163. Cache::config($config);
  164. $result = Cache::config();
  165. $expected = $config;
  166. $this->assertEqual($expected, $result);
  167. $result = Cache::read('default', 'some_key', array('conditions' => function() {
  168. return false;
  169. }));
  170. $this->assertFalse($result);
  171. $conditions = function() use (&$config) {
  172. return (isset($config['default']));
  173. };
  174. Cache::write('default', 'some_key', 'some value', '+1 minute');
  175. $result = Cache::read('default', 'some_key', compact('conditions'));
  176. $this->assertTrue($result);
  177. $this->assertFalse(Cache::read('non_existing', 'key_value', compact('conditions')));
  178. }
  179. public function testCacheIncrementDecrementWithConditions() {
  180. $config = array('default' => array(
  181. 'adapter' => 'Memory', 'filters' => array()
  182. ));
  183. Cache::config($config);
  184. $result = Cache::config();
  185. $expected = $config;
  186. $this->assertEqual($expected, $result);
  187. $conditions = function() {
  188. return false;
  189. };
  190. $result = Cache::increment('default', 'some_key', 1, compact('conditions'));
  191. $this->assertFalse($result);
  192. $conditions = function() use (&$config) {
  193. return (isset($config['default']));
  194. };
  195. Cache::write('default', 'some_key', 1, '+1 minute');
  196. $result = Cache::increment('default', 'some_key', 1, compact('conditions'));
  197. $this->assertEqual(2, $result);
  198. $conditions = function() {
  199. return false;
  200. };
  201. $result = Cache::decrement('default', 'decrement_some_key', 1, compact('conditions'));
  202. $this->assertFalse($result);
  203. $conditions = function() use (&$config) {
  204. return (isset($config['default']));
  205. };
  206. Cache::write('default', 'decrement_some_key', 1, '+1 minute');
  207. $result = Cache::decrement('default', 'decrement_some_key', 1, compact('conditions'));
  208. $this->assertEqual(0, $result);
  209. }
  210. public function testCacheWriteWithConditions() {
  211. $config = array('default' => array(
  212. 'adapter' => 'Memory', 'filters' => array()
  213. ));
  214. Cache::config($config);
  215. $result = Cache::config();
  216. $expected = $config;
  217. $this->assertEqual($expected, $result);
  218. $conditions = function() {
  219. return false;
  220. };
  221. $result = Cache::write(
  222. 'default', 'some_key', 'some_data', '+1 minute', compact('conditions')
  223. );
  224. $this->assertFalse($result);
  225. $conditions = function() use (&$config) {
  226. return (isset($config['default']));
  227. };
  228. $result = Cache::write(
  229. 'default', 'some_key', 'some_data', '+1 minute', compact('conditions')
  230. );
  231. $this->assertTrue($result);
  232. $result = Cache::write(
  233. 'non_existing', 'key_value', 'data', '+1 minute', compact('conditions')
  234. );
  235. $this->assertFalse($result);
  236. }
  237. public function testCacheReadThroughWrite() {
  238. $config = array('default' => array(
  239. 'adapter' => 'Memory', 'filters' => array()
  240. ));
  241. Cache::config($config);
  242. $result = Cache::config();
  243. $expected = $config;
  244. $this->assertEqual($expected, $result);
  245. $write = function() {
  246. return array('+1 minute' => 'read-through write');
  247. };
  248. $this->assertNull(Cache::read('default', 'read_through'));
  249. $result = Cache::read('default', 'read_through', compact('write'));
  250. $this->assertIdentical('read-through write', $result);
  251. $result = Cache::read('default', 'read_through');
  252. $this->assertIdentical('read-through write', $result);
  253. $write = array('+1 minute' => 'string read-through write');
  254. $result = Cache::read('default', 'string_read_through', compact('write'));
  255. $this->assertIdentical('string read-through write', $result);
  256. $result = Cache::read('default', 'string_read_through');
  257. $this->assertIdentical('string read-through write', $result);
  258. $this->assertNull(Cache::read('default', 'string_read_through_2'));
  259. $result = Cache::read('default', 'string_read_through_2', array('write' => array(
  260. '+1 minute' => function() {
  261. return 'read-through write 2';
  262. }
  263. )));
  264. $this->assertIdentical('read-through write 2', $result);
  265. }
  266. public function testCacheReadAndWrite() {
  267. $config = array('default' => array(
  268. 'adapter' => 'Memory', 'filters' => array()
  269. ));
  270. Cache::config($config);
  271. $result = Cache::config();
  272. $expected = $config;
  273. $this->assertEqual($expected, $result);
  274. $result = Cache::read('non_existing', 'key_value');
  275. $this->assertFalse($result);
  276. $result = Cache::write('default', 'keyed', 'some data', '+1 minute');
  277. $this->assertTrue($result);
  278. $result = Cache::read('default', 'keyed');
  279. $expected = 'some data';
  280. $this->assertEqual($expected, $result);
  281. $result = Cache::write('default', 'another', array('data' => 'take two'), '+1 minute');
  282. $this->assertTrue($result);
  283. $result = Cache::read('default', 'another');
  284. $expected = array('data' => 'take two');
  285. $this->assertEqual($expected, $result);
  286. $result = Cache::write(
  287. 'default', 'another', (object) array('data' => 'take two'), '+1 minute'
  288. );
  289. $this->assertTrue($result);
  290. $result = Cache::read('default', 'another');
  291. $expected = (object) array('data' => 'take two');
  292. $this->assertEqual($expected, $result);
  293. }
  294. public function testCacheReadAndWriteWithConditions() {
  295. $config = array('default' => array(
  296. 'adapter' => 'Memory', 'filters' => array()
  297. ));
  298. Cache::config($config);
  299. $result = Cache::config();
  300. $expected = $config;
  301. $this->assertEqual($expected, $result);
  302. $conditions = function() use (&$config) {
  303. return (isset($config['default']));
  304. };
  305. $result = Cache::read('non_existing', 'key_value', compact('conditions'));
  306. $this->assertFalse($result);
  307. $result = Cache::read('default', 'key_value', compact('conditions'));
  308. $this->assertFalse($result);
  309. $result = Cache::write('default', 'keyed', 'some data', '+1 minute', compact('conditions'));
  310. $this->assertTrue($result);
  311. $conditions = function() {
  312. return false;
  313. };
  314. $result = Cache::write('default', 'keyed', 'some data', '+1 minute', compact('conditions'));
  315. $this->assertFalse($result);
  316. }
  317. public function testCacheWriteAndDelete() {
  318. $config = array('default' => array(
  319. 'adapter' => 'Memory', 'filters' => array()
  320. ));
  321. Cache::config($config);
  322. $result = Cache::config();
  323. $expected = $config;
  324. $this->assertEqual($expected, $result);
  325. $result = Cache::delete('non_existing', 'key_value');
  326. $this->assertFalse($result);
  327. $result = Cache::write('default', 'to delete', 'dead data', '+1 minute');
  328. $this->assertTrue($result);
  329. $result = Cache::delete('default', 'to delete');
  330. $this->assertTrue($result);
  331. $this->assertFalse(Cache::read('default', 'to delete'));
  332. }
  333. public function testCacheWriteAndDeleteWithConditions() {
  334. $config = array('default' => array(
  335. 'adapter' => 'Memory', 'filters' => array()
  336. ));
  337. Cache::config($config);
  338. $result = Cache::config();
  339. $expected = $config;
  340. $this->assertEqual($expected, $result);
  341. $conditions = function() use (&$config) {
  342. return (isset($config['default']));
  343. };
  344. $result = Cache::delete('non_existing', 'key_value', compact('conditions'));
  345. $this->assertFalse($result);
  346. $result = Cache::write('default', 'to delete', 'dead data', '+1 minute');
  347. $this->assertTrue($result);
  348. $result = Cache::delete('default', 'to delete', array(
  349. 'conditions' => function() {
  350. return false;
  351. }
  352. ));
  353. $this->assertFalse($result);
  354. $result = Cache::delete('default', 'to delete', compact('conditions'));
  355. $this->assertTrue($result);
  356. }
  357. public function testCacheWriteAndClear() {
  358. $config = array('default' => array(
  359. 'adapter' => 'Memory', 'filters' => array()
  360. ));
  361. Cache::config($config);
  362. $result = Cache::config();
  363. $expected = $config;
  364. $this->assertEqual($expected, $result);
  365. $result = Cache::clear('non_existing');
  366. $this->assertFalse($result);
  367. $result = Cache::write('default', 'to delete', 'dead data', '+1 minute');
  368. $this->assertTrue($result);
  369. $result = Cache::clear('default');
  370. $this->assertTrue($result);
  371. $result = Cache::read('default', 'to delete');
  372. $this->assertFalse($result);
  373. }
  374. public function testClean() {
  375. $config = array('default' => array(
  376. 'adapter' => 'Memory', 'filters' => array()
  377. ));
  378. Cache::config($config);
  379. $result = Cache::config();
  380. $expected = $config;
  381. $this->assertEqual($expected, $result);
  382. $result = Cache::clean('non_existing');
  383. $this->assertFalse($result);
  384. $result = Cache::clean('default');
  385. $this->assertFalse($result);
  386. }
  387. public function testReset() {
  388. $config = array('default' => array(
  389. 'adapter' => 'Memory', 'filters' => array()
  390. ));
  391. Cache::config($config);
  392. $result = Cache::config();
  393. $expected = $config;
  394. $this->assertEqual($expected, $result);
  395. $result = Cache::reset();
  396. $this->assertNull($result);
  397. $result = Cache::config();
  398. $this->assertFalse($result);
  399. }
  400. public function testIncrement() {
  401. $config = array('default' => array(
  402. 'adapter' => 'Memory', 'filters' => array()
  403. ));
  404. Cache::config($config);
  405. $result = Cache::config();
  406. $expected = $config;
  407. $this->assertEqual($expected, $result);
  408. $result = Cache::increment('does_not_exist', 'inc');
  409. $this->assertFalse($result);
  410. $result = Cache::write('default', 'increment', 5, '+1 minute');
  411. $this->assertTrue($result);
  412. $result = Cache::increment('default', 'increment');
  413. $this->assertTrue($result);
  414. $result = Cache::read('default', 'increment');
  415. $this->assertEqual(6, $result);
  416. }
  417. public function testDecrement() {
  418. $config = array('default' => array(
  419. 'adapter' => 'Memory', 'filters' => array()
  420. ));
  421. Cache::config($config);
  422. $result = Cache::config();
  423. $expected = $config;
  424. $this->assertEqual($expected, $result);
  425. $result = Cache::decrement('does_not_exist', 'dec');
  426. $this->assertFalse($result);
  427. $result = Cache::write('default', 'decrement', 5, '+1 minute');
  428. $this->assertTrue($result);
  429. $result = Cache::decrement('default', 'decrement');
  430. $this->assertTrue($result);
  431. $result = Cache::read('default', 'decrement');
  432. $this->assertEqual(4, $result);
  433. }
  434. public function testNonPortableCacheAdapterMethod() {
  435. $config = array('default' => array(
  436. 'adapter' => 'Memory', 'filters' => array()
  437. ));
  438. Cache::config($config);
  439. $result = Cache::config();
  440. $expected = $config;
  441. $this->assertEqual($expected, $result);
  442. }
  443. public function testIntegrationFileAdapterCacheConfig() {
  444. $result = Cache::config();
  445. $this->assertFalse($result);
  446. $config = array('default' => array('adapter' => 'File', 'filters' => array()));
  447. Cache::config($config);
  448. $this->assertEqual($config, Cache::config());
  449. }
  450. public function testIntegrationFileAdapterWrite() {
  451. $resources = Libraries::get(true, 'resources');
  452. $path = "{$resources}/tmp/cache";
  453. $this->skipIf(!$this->_checkPath(), "{$path} does not have the proper permissions.");
  454. $config = array('default' => compact('path') + array(
  455. 'adapter' => 'File',
  456. 'filters' => array()
  457. ));
  458. Cache::config($config);
  459. $result = Cache::write('default', 'key', 'value', '+1 minute');
  460. $this->assertTrue($result);
  461. $time = time() + 60;
  462. $result = file_get_contents("{$path}/key");
  463. $expected = "{:expiry:$time}\nvalue";
  464. $this->assertEqual($result, $expected);
  465. $result = unlink("{$path}/key");
  466. $this->assertTrue($result);
  467. $this->assertFalse(file_exists("{$path}/key"));
  468. }
  469. public function testIntegrationFileAdapterWithStrategies() {
  470. $resources = Libraries::get(true, 'resources');
  471. $path = "{$resources}/tmp/cache";
  472. $this->skipIf(!$this->_checkPath(), "{$path} does not have the proper permissions.");
  473. $config = array('default' => compact('path') + array(
  474. 'adapter' => 'File',
  475. 'filters' => array(),
  476. 'strategies' => array('Serializer')
  477. ));
  478. Cache::config($config);
  479. $data = array('some' => 'data');
  480. $result = Cache::write('default', 'key', $data, '+1 minute');
  481. $this->assertTrue($result);
  482. $time = time() + 60;
  483. $result = file_get_contents("{$path}/key");
  484. $expected = "{:expiry:$time}\na:1:{s:4:\"some\";s:4:\"data\";}";
  485. $this->assertEqual($result, $expected);
  486. $result = Cache::read('default', 'key');
  487. $this->assertEqual($data, $result);
  488. $result = unlink("{$path}/key");
  489. $this->assertTrue($result);
  490. $this->assertFalse(file_exists("{$path}/key"));
  491. }
  492. public function testIntegrationFileAdapterMultipleStrategies() {
  493. $resources = Libraries::get(true, 'resources');
  494. $path = "{$resources}/tmp/cache";
  495. $this->skipIf(!$this->_checkPath(), "{$path} does not have the proper permissions.");
  496. $config = array('default' => compact('path') + array(
  497. 'adapter' => 'File',
  498. 'filters' => array(),
  499. 'strategies' => array('Serializer', 'Base64')
  500. ));
  501. Cache::config($config);
  502. $data = array('some' => 'data');
  503. $result = Cache::write('default', 'key', $data, '+1 minute');
  504. $this->assertTrue($result);
  505. $time = time() + 60;
  506. $result = file_get_contents("{$path}/key");
  507. $expected = "{:expiry:$time}\nYToxOntzOjQ6InNvbWUiO3M6NDoiZGF0YSI7fQ==";
  508. $this->assertEqual($result, $expected);
  509. $result = Cache::read('default', 'key');
  510. $this->assertEqual($data, $result);
  511. $result = unlink("{$path}/key");
  512. $this->assertTrue($result);
  513. $this->assertFalse(file_exists("{$path}/key"));
  514. }
  515. }
  516. ?>