MemcachedEngineTest.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 2.5.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Cache\Engine;
  16. use Cake\Cache\Cache;
  17. use Cake\Cache\Engine\MemcachedEngine;
  18. use Cake\Core\Configure;
  19. use Cake\TestSuite\TestCase;
  20. use \Memcached;
  21. /**
  22. * TestMemcachedEngine
  23. */
  24. class TestMemcachedEngine extends MemcachedEngine
  25. {
  26. /**
  27. * public accessor to _parseServerString
  28. *
  29. * @param string $server
  30. * @return array
  31. */
  32. public function parseServerString($server)
  33. {
  34. return $this->_parseServerString($server);
  35. }
  36. public function setMemcached($memcached)
  37. {
  38. $this->_Memcached = $memcached;
  39. }
  40. public function getMemcached()
  41. {
  42. return $this->_Memcached;
  43. }
  44. }
  45. /**
  46. * MemcachedEngineTest class
  47. */
  48. class MemcachedEngineTest extends TestCase
  49. {
  50. /**
  51. * setUp method
  52. *
  53. * @return void
  54. */
  55. public function setUp()
  56. {
  57. parent::setUp();
  58. $this->skipIf(!class_exists('Memcached'), 'Memcached is not installed or configured properly.');
  59. // @codingStandardsIgnoreStart
  60. $socket = @fsockopen('127.0.0.1', 11211, $errno, $errstr, 1);
  61. // @codingStandardsIgnoreEnd
  62. $this->skipIf(!$socket, 'Memcached is not running.');
  63. fclose($socket);
  64. $this->_configCache();
  65. }
  66. /**
  67. * Helper method for testing.
  68. *
  69. * @param array $config
  70. * @return void
  71. */
  72. protected function _configCache($config = [])
  73. {
  74. $defaults = [
  75. 'className' => 'Memcached',
  76. 'prefix' => 'cake_',
  77. 'duration' => 3600
  78. ];
  79. Cache::drop('memcached');
  80. Cache::config('memcached', array_merge($defaults, $config));
  81. }
  82. /**
  83. * tearDown method
  84. *
  85. * @return void
  86. */
  87. public function tearDown()
  88. {
  89. parent::tearDown();
  90. Cache::drop('memcached');
  91. Cache::drop('memcached2');
  92. Cache::drop('memcached_groups');
  93. Cache::drop('memcached_helper');
  94. Cache::drop('compressed_memcached');
  95. Cache::drop('long_memcached');
  96. Cache::drop('short_memcached');
  97. }
  98. /**
  99. * testConfig method
  100. *
  101. * @return void
  102. */
  103. public function testConfig()
  104. {
  105. $config = Cache::engine('memcached')->config();
  106. unset($config['path']);
  107. $expecting = [
  108. 'prefix' => 'cake_',
  109. 'duration' => 3600,
  110. 'probability' => 100,
  111. 'servers' => ['127.0.0.1'],
  112. 'persistent' => false,
  113. 'compress' => false,
  114. 'username' => null,
  115. 'password' => null,
  116. 'groups' => [],
  117. 'serialize' => 'php',
  118. 'options' => [],
  119. 'host' => null,
  120. 'port' => null,
  121. ];
  122. $this->assertEquals($expecting, $config);
  123. }
  124. /**
  125. * testCompressionSetting method
  126. *
  127. * @return void
  128. */
  129. public function testCompressionSetting()
  130. {
  131. $Memcached = new TestMemcachedEngine();
  132. $Memcached->init([
  133. 'engine' => 'Memcached',
  134. 'servers' => ['127.0.0.1:11211'],
  135. 'compress' => false
  136. ]);
  137. $this->assertFalse($Memcached->getMemcached()->getOption(\Memcached::OPT_COMPRESSION));
  138. $MemcachedCompressed = new TestMemcachedEngine();
  139. $MemcachedCompressed->init([
  140. 'engine' => 'Memcached',
  141. 'servers' => ['127.0.0.1:11211'],
  142. 'compress' => true
  143. ]);
  144. $this->assertTrue($MemcachedCompressed->getMemcached()->getOption(\Memcached::OPT_COMPRESSION));
  145. }
  146. /**
  147. * test setting options
  148. *
  149. * @return void
  150. */
  151. public function testOptionsSetting()
  152. {
  153. $memcached = new TestMemcachedEngine();
  154. $memcached->init([
  155. 'engine' => 'Memcached',
  156. 'servers' => ['127.0.0.1:11211'],
  157. 'options' => [
  158. Memcached::OPT_BINARY_PROTOCOL => true
  159. ]
  160. ]);
  161. $this->assertEquals(1, $memcached->getMemcached()->getOption(Memcached::OPT_BINARY_PROTOCOL));
  162. }
  163. /**
  164. * test accepts only valid serializer engine
  165. *
  166. * @return void
  167. */
  168. public function testInvalidSerializerSetting()
  169. {
  170. $Memcached = new TestMemcachedEngine();
  171. $config = [
  172. 'className' => 'Memcached',
  173. 'servers' => ['127.0.0.1:11211'],
  174. 'persistent' => false,
  175. 'serialize' => 'invalid_serializer'
  176. ];
  177. $this->setExpectedException(
  178. 'InvalidArgumentException',
  179. 'invalid_serializer is not a valid serializer engine for Memcached'
  180. );
  181. $Memcached->init($config);
  182. }
  183. /**
  184. * testPhpSerializerSetting method
  185. *
  186. * @return void
  187. */
  188. public function testPhpSerializerSetting()
  189. {
  190. $Memcached = new TestMemcachedEngine();
  191. $config = [
  192. 'className' => 'Memcached',
  193. 'servers' => ['127.0.0.1:11211'],
  194. 'persistent' => false,
  195. 'serialize' => 'php'
  196. ];
  197. $Memcached->init($config);
  198. $this->assertEquals(Memcached::SERIALIZER_PHP, $Memcached->getMemcached()->getOption(Memcached::OPT_SERIALIZER));
  199. }
  200. /**
  201. * testJsonSerializerSetting method
  202. *
  203. * @return void
  204. */
  205. public function testJsonSerializerSetting()
  206. {
  207. $this->skipIf(
  208. !Memcached::HAVE_JSON,
  209. 'Memcached extension is not compiled with json support'
  210. );
  211. $Memcached = new TestMemcachedEngine();
  212. $config = [
  213. 'engine' => 'Memcached',
  214. 'servers' => ['127.0.0.1:11211'],
  215. 'persistent' => false,
  216. 'serialize' => 'json'
  217. ];
  218. $Memcached->init($config);
  219. $this->assertEquals(Memcached::SERIALIZER_JSON, $Memcached->getMemcached()->getOption(Memcached::OPT_SERIALIZER));
  220. }
  221. /**
  222. * testIgbinarySerializerSetting method
  223. *
  224. * @return void
  225. */
  226. public function testIgbinarySerializerSetting()
  227. {
  228. $this->skipIf(
  229. !Memcached::HAVE_IGBINARY,
  230. 'Memcached extension is not compiled with igbinary support'
  231. );
  232. $Memcached = new TestMemcachedEngine();
  233. $config = [
  234. 'engine' => 'Memcached',
  235. 'servers' => ['127.0.0.1:11211'],
  236. 'persistent' => false,
  237. 'serialize' => 'igbinary'
  238. ];
  239. $Memcached->init($config);
  240. $this->assertEquals(Memcached::SERIALIZER_IGBINARY, $Memcached->getMemcached()->getOption(Memcached::OPT_SERIALIZER));
  241. }
  242. /**
  243. * testMsgpackSerializerSetting method
  244. *
  245. * @return void
  246. */
  247. public function testMsgpackSerializerSetting()
  248. {
  249. $this->skipIf(
  250. !defined('Memcached::HAVE_MSGPACK') || !Memcached::HAVE_MSGPACK,
  251. 'Memcached extension is not compiled with msgpack support'
  252. );
  253. $Memcached = new TestMemcachedEngine();
  254. $config = [
  255. 'engine' => 'Memcached',
  256. 'servers' => ['127.0.0.1:11211'],
  257. 'persistent' => false,
  258. 'serialize' => 'msgpack'
  259. ];
  260. $Memcached->init($config);
  261. $this->assertEquals(Memcached::SERIALIZER_MSGPACK, $Memcached->getMemcached()->getOption(Memcached::OPT_SERIALIZER));
  262. }
  263. /**
  264. * testJsonSerializerThrowException method
  265. *
  266. * @return void
  267. */
  268. public function testJsonSerializerThrowException()
  269. {
  270. $this->skipIf(
  271. Memcached::HAVE_JSON,
  272. 'Memcached extension is compiled with json support'
  273. );
  274. $Memcached = new TestMemcachedEngine();
  275. $config = [
  276. 'className' => 'Memcached',
  277. 'servers' => ['127.0.0.1:11211'],
  278. 'persistent' => false,
  279. 'serialize' => 'json'
  280. ];
  281. $this->setExpectedException(
  282. 'InvalidArgumentException',
  283. 'Memcached extension is not compiled with json support'
  284. );
  285. $Memcached->init($config);
  286. }
  287. /**
  288. * testMsgpackSerializerThrowException method
  289. *
  290. * @return void
  291. */
  292. public function testMsgpackSerializerThrowException()
  293. {
  294. $this->skipIf(
  295. defined('Memcached::HAVE_MSGPACK') && Memcached::HAVE_MSGPACK,
  296. 'Memcached extension is compiled with msgpack support'
  297. );
  298. $Memcached = new TestMemcachedEngine();
  299. $config = [
  300. 'engine' => 'Memcached',
  301. 'servers' => ['127.0.0.1:11211'],
  302. 'persistent' => false,
  303. 'serialize' => 'msgpack'
  304. ];
  305. $this->setExpectedException(
  306. 'InvalidArgumentException',
  307. 'msgpack is not a valid serializer engine for Memcached'
  308. );
  309. $Memcached->init($config);
  310. }
  311. /**
  312. * testIgbinarySerializerThrowException method
  313. *
  314. * @return void
  315. */
  316. public function testIgbinarySerializerThrowException()
  317. {
  318. $this->skipIf(
  319. Memcached::HAVE_IGBINARY,
  320. 'Memcached extension is compiled with igbinary support'
  321. );
  322. $Memcached = new TestMemcachedEngine();
  323. $config = [
  324. 'engine' => 'Memcached',
  325. 'servers' => ['127.0.0.1:11211'],
  326. 'persistent' => false,
  327. 'serialize' => 'igbinary'
  328. ];
  329. $this->setExpectedException(
  330. 'InvalidArgumentException',
  331. 'Memcached extension is not compiled with igbinary support'
  332. );
  333. $Memcached->init($config);
  334. }
  335. /**
  336. * test using authentication without memcached installed with SASL support
  337. * throw an exception
  338. *
  339. * @expectedException \InvalidArgumentException
  340. * @expectedExceptionMessage Memcached extension is not build with SASL support
  341. * @return void
  342. */
  343. public function testSaslAuthException()
  344. {
  345. $MemcachedEngine = new TestMemcachedEngine();
  346. $config = [
  347. 'engine' => 'Memcached',
  348. 'servers' => ['127.0.0.1:11211'],
  349. 'persistent' => false,
  350. 'username' => 'test',
  351. 'password' => 'password'
  352. ];
  353. $MemcachedEngine->init($config);
  354. }
  355. /**
  356. * testConfig method
  357. *
  358. * @return void
  359. */
  360. public function testMultipleServers()
  361. {
  362. $servers = ['127.0.0.1:11211', '127.0.0.1:11222'];
  363. $available = true;
  364. $Memcached = new \Memcached();
  365. foreach ($servers as $server) {
  366. list($host, $port) = explode(':', $server);
  367. //@codingStandardsIgnoreStart
  368. if (!$Memcached->addServer($host, $port)) {
  369. $available = false;
  370. }
  371. //@codingStandardsIgnoreEnd
  372. }
  373. $this->skipIf(!$available, 'Need memcached servers at ' . implode(', ', $servers) . ' to run this test.');
  374. $Memcached = new MemcachedEngine();
  375. $Memcached->init(['engine' => 'Memcached', 'servers' => $servers]);
  376. $config = $Memcached->config();
  377. $this->assertEquals($config['servers'], $servers);
  378. Cache::drop('dual_server');
  379. }
  380. /**
  381. * test connecting to an ipv6 server.
  382. *
  383. * @return void
  384. */
  385. public function testConnectIpv6()
  386. {
  387. $Memcached = new MemcachedEngine();
  388. $result = $Memcached->init([
  389. 'prefix' => 'cake_',
  390. 'duration' => 200,
  391. 'engine' => 'Memcached',
  392. 'servers' => [
  393. '[::1]:11211'
  394. ]
  395. ]);
  396. $this->assertTrue($result);
  397. }
  398. /**
  399. * test domain starts with u
  400. *
  401. * @return void
  402. */
  403. public function testParseServerStringWithU()
  404. {
  405. $Memcached = new TestMemcachedEngine();
  406. $result = $Memcached->parseServerString('udomain.net:13211');
  407. $this->assertEquals(['udomain.net', '13211'], $result);
  408. }
  409. /**
  410. * test non latin domains.
  411. *
  412. * @return void
  413. */
  414. public function testParseServerStringNonLatin()
  415. {
  416. $Memcached = new TestMemcachedEngine();
  417. $result = $Memcached->parseServerString('schülervz.net:13211');
  418. $this->assertEquals(['schülervz.net', '13211'], $result);
  419. $result = $Memcached->parseServerString('sülül:1111');
  420. $this->assertEquals(['sülül', '1111'], $result);
  421. }
  422. /**
  423. * test unix sockets.
  424. *
  425. * @return void
  426. */
  427. public function testParseServerStringUnix()
  428. {
  429. $Memcached = new TestMemcachedEngine();
  430. $result = $Memcached->parseServerString('unix:///path/to/memcachedd.sock');
  431. $this->assertEquals(['/path/to/memcachedd.sock', 0], $result);
  432. }
  433. /**
  434. * testReadAndWriteCache method
  435. *
  436. * @return void
  437. */
  438. public function testReadAndWriteCache()
  439. {
  440. $this->_configCache(['duration' => 1]);
  441. $result = Cache::read('test', 'memcached');
  442. $expecting = '';
  443. $this->assertEquals($expecting, $result);
  444. $data = 'this is a test of the emergency broadcasting system';
  445. $result = Cache::write('test', $data, 'memcached');
  446. $this->assertTrue($result);
  447. $result = Cache::read('test', 'memcached');
  448. $expecting = $data;
  449. $this->assertEquals($expecting, $result);
  450. Cache::delete('test', 'memcached');
  451. }
  452. /**
  453. * testReadMany method
  454. *
  455. * @return void
  456. */
  457. public function testReadMany()
  458. {
  459. $this->_configCache(['duration' => 2]);
  460. $data = [
  461. 'App.falseTest' => false,
  462. 'App.trueTest' => true,
  463. 'App.nullTest' => null,
  464. 'App.zeroTest' => 0,
  465. 'App.zeroTest2' => '0'
  466. ];
  467. foreach ($data as $key => $value) {
  468. Cache::write($key, $value, 'memcached');
  469. }
  470. $read = Cache::readMany(array_merge(array_keys($data), ['App.doesNotExist']), 'memcached');
  471. $this->assertSame($read['App.falseTest'], false);
  472. $this->assertSame($read['App.trueTest'], true);
  473. $this->assertSame($read['App.nullTest'], null);
  474. $this->assertSame($read['App.zeroTest'], 0);
  475. $this->assertSame($read['App.zeroTest2'], '0');
  476. $this->assertSame($read['App.doesNotExist'], false);
  477. }
  478. /**
  479. * testWriteMany method
  480. *
  481. * @return void
  482. */
  483. public function testWriteMany()
  484. {
  485. $this->_configCache(['duration' => 2]);
  486. $data = [
  487. 'App.falseTest' => false,
  488. 'App.trueTest' => true,
  489. 'App.nullTest' => null,
  490. 'App.zeroTest' => 0,
  491. 'App.zeroTest2' => '0'
  492. ];
  493. Cache::writeMany($data, 'memcached');
  494. $this->assertSame(Cache::read('App.falseTest', 'memcached'), false);
  495. $this->assertSame(Cache::read('App.trueTest', 'memcached'), true);
  496. $this->assertSame(Cache::read('App.nullTest', 'memcached'), null);
  497. $this->assertSame(Cache::read('App.zeroTest', 'memcached'), 0);
  498. $this->assertSame(Cache::read('App.zeroTest2', 'memcached'), '0');
  499. }
  500. /**
  501. * testExpiry method
  502. *
  503. * @return void
  504. */
  505. public function testExpiry()
  506. {
  507. $this->_configCache(['duration' => 1]);
  508. $result = Cache::read('test', 'memcached');
  509. $this->assertFalse($result);
  510. $data = 'this is a test of the emergency broadcasting system';
  511. $result = Cache::write('other_test', $data, 'memcached');
  512. $this->assertTrue($result);
  513. sleep(2);
  514. $result = Cache::read('other_test', 'memcached');
  515. $this->assertFalse($result);
  516. $this->_configCache(['duration' => '+1 second']);
  517. $data = 'this is a test of the emergency broadcasting system';
  518. $result = Cache::write('other_test', $data, 'memcached');
  519. $this->assertTrue($result);
  520. sleep(3);
  521. $result = Cache::read('other_test', 'memcached');
  522. $this->assertFalse($result);
  523. $result = Cache::read('other_test', 'memcached');
  524. $this->assertFalse($result);
  525. $this->_configCache(['duration' => '+29 days']);
  526. $data = 'this is a test of the emergency broadcasting system';
  527. $result = Cache::write('long_expiry_test', $data, 'memcached');
  528. $this->assertTrue($result);
  529. sleep(2);
  530. $result = Cache::read('long_expiry_test', 'memcached');
  531. $expecting = $data;
  532. $this->assertEquals($expecting, $result);
  533. }
  534. /**
  535. * testDeleteCache method
  536. *
  537. * @return void
  538. */
  539. public function testDeleteCache()
  540. {
  541. $data = 'this is a test of the emergency broadcasting system';
  542. $result = Cache::write('delete_test', $data, 'memcached');
  543. $this->assertTrue($result);
  544. $result = Cache::delete('delete_test', 'memcached');
  545. $this->assertTrue($result);
  546. }
  547. /**
  548. * testDeleteMany method
  549. *
  550. * @return void
  551. */
  552. public function testDeleteMany()
  553. {
  554. $this->skipIf(defined('HHVM_VERSION'), 'HHVM does not implement deleteMulti');
  555. $this->_configCache();
  556. $data = [
  557. 'App.falseTest' => false,
  558. 'App.trueTest' => true,
  559. 'App.nullTest' => null,
  560. 'App.zeroTest' => 0,
  561. 'App.zeroTest2' => '0',
  562. ];
  563. foreach ($data as $key => $value) {
  564. Cache::write($key, $value, 'memcached');
  565. }
  566. Cache::write('App.keepTest', 'keepMe', 'memcached');
  567. Cache::deleteMany(array_merge(array_keys($data), ['App.doesNotExist']), 'memcached');
  568. $this->assertSame(Cache::read('App.falseTest', 'memcached'), false);
  569. $this->assertSame(Cache::read('App.trueTest', 'memcached'), false);
  570. $this->assertSame(Cache::read('App.nullTest', 'memcached'), false);
  571. $this->assertSame(Cache::read('App.zeroTest', 'memcached'), false);
  572. $this->assertSame(Cache::read('App.zeroTest2', 'memcached'), false);
  573. $this->assertSame(Cache::read('App.keepTest', 'memcached'), 'keepMe');
  574. }
  575. /**
  576. * testDecrement method
  577. *
  578. * @return void
  579. */
  580. public function testDecrement()
  581. {
  582. $result = Cache::write('test_decrement', 5, 'memcached');
  583. $this->assertTrue($result);
  584. $result = Cache::decrement('test_decrement', 1, 'memcached');
  585. $this->assertEquals(4, $result);
  586. $result = Cache::read('test_decrement', 'memcached');
  587. $this->assertEquals(4, $result);
  588. $result = Cache::decrement('test_decrement', 2, 'memcached');
  589. $this->assertEquals(2, $result);
  590. $result = Cache::read('test_decrement', 'memcached');
  591. $this->assertEquals(2, $result);
  592. Cache::delete('test_decrement', 'memcached');
  593. }
  594. /**
  595. * test decrementing compressed keys
  596. *
  597. * @return void
  598. */
  599. public function testDecrementCompressedKeys()
  600. {
  601. Cache::config('compressed_memcached', [
  602. 'engine' => 'Memcached',
  603. 'duration' => '+2 seconds',
  604. 'servers' => ['127.0.0.1:11211'],
  605. 'compress' => true
  606. ]);
  607. $result = Cache::write('test_decrement', 5, 'compressed_memcached');
  608. $this->assertTrue($result);
  609. $result = Cache::decrement('test_decrement', 1, 'compressed_memcached');
  610. $this->assertEquals(4, $result);
  611. $result = Cache::read('test_decrement', 'compressed_memcached');
  612. $this->assertEquals(4, $result);
  613. $result = Cache::decrement('test_decrement', 2, 'compressed_memcached');
  614. $this->assertEquals(2, $result);
  615. $result = Cache::read('test_decrement', 'compressed_memcached');
  616. $this->assertEquals(2, $result);
  617. Cache::delete('test_decrement', 'compressed_memcached');
  618. }
  619. /**
  620. * testIncrement method
  621. *
  622. * @return void
  623. */
  624. public function testIncrement()
  625. {
  626. $result = Cache::write('test_increment', 5, 'memcached');
  627. $this->assertTrue($result);
  628. $result = Cache::increment('test_increment', 1, 'memcached');
  629. $this->assertEquals(6, $result);
  630. $result = Cache::read('test_increment', 'memcached');
  631. $this->assertEquals(6, $result);
  632. $result = Cache::increment('test_increment', 2, 'memcached');
  633. $this->assertEquals(8, $result);
  634. $result = Cache::read('test_increment', 'memcached');
  635. $this->assertEquals(8, $result);
  636. Cache::delete('test_increment', 'memcached');
  637. }
  638. /**
  639. * test incrementing compressed keys
  640. *
  641. * @return void
  642. */
  643. public function testIncrementCompressedKeys()
  644. {
  645. Cache::config('compressed_memcached', [
  646. 'engine' => 'Memcached',
  647. 'duration' => '+2 seconds',
  648. 'servers' => ['127.0.0.1:11211'],
  649. 'compress' => true
  650. ]);
  651. $result = Cache::write('test_increment', 5, 'compressed_memcached');
  652. $this->assertTrue($result);
  653. $result = Cache::increment('test_increment', 1, 'compressed_memcached');
  654. $this->assertEquals(6, $result);
  655. $result = Cache::read('test_increment', 'compressed_memcached');
  656. $this->assertEquals(6, $result);
  657. $result = Cache::increment('test_increment', 2, 'compressed_memcached');
  658. $this->assertEquals(8, $result);
  659. $result = Cache::read('test_increment', 'compressed_memcached');
  660. $this->assertEquals(8, $result);
  661. Cache::delete('test_increment', 'compressed_memcached');
  662. }
  663. /**
  664. * test that configurations don't conflict, when a file engine is declared after a memcached one.
  665. *
  666. * @return void
  667. */
  668. public function testConfigurationConflict()
  669. {
  670. Cache::config('long_memcached', [
  671. 'engine' => 'Memcached',
  672. 'duration' => '+2 seconds',
  673. 'servers' => ['127.0.0.1:11211'],
  674. ]);
  675. Cache::config('short_memcached', [
  676. 'engine' => 'Memcached',
  677. 'duration' => '+1 seconds',
  678. 'servers' => ['127.0.0.1:11211'],
  679. ]);
  680. $this->assertTrue(Cache::write('duration_test', 'yay', 'long_memcached'));
  681. $this->assertTrue(Cache::write('short_duration_test', 'boo', 'short_memcached'));
  682. $this->assertEquals('yay', Cache::read('duration_test', 'long_memcached'), 'Value was not read %s');
  683. $this->assertEquals('boo', Cache::read('short_duration_test', 'short_memcached'), 'Value was not read %s');
  684. sleep(1);
  685. $this->assertEquals('yay', Cache::read('duration_test', 'long_memcached'), 'Value was not read %s');
  686. sleep(2);
  687. $this->assertFalse(Cache::read('short_duration_test', 'short_memcached'), 'Cache was not invalidated %s');
  688. $this->assertFalse(Cache::read('duration_test', 'long_memcached'), 'Value did not expire %s');
  689. Cache::delete('duration_test', 'long_memcached');
  690. Cache::delete('short_duration_test', 'short_memcached');
  691. }
  692. /**
  693. * test clearing memcached.
  694. *
  695. * @return void
  696. */
  697. public function testClear()
  698. {
  699. Cache::config('memcached2', [
  700. 'engine' => 'Memcached',
  701. 'prefix' => 'cake2_',
  702. 'duration' => 3600
  703. ]);
  704. Cache::write('some_value', 'cache1', 'memcached');
  705. $result = Cache::clear(true, 'memcached');
  706. $this->assertTrue($result);
  707. $this->assertEquals('cache1', Cache::read('some_value', 'memcached'));
  708. Cache::write('some_value', 'cache2', 'memcached2');
  709. $result = Cache::clear(false, 'memcached');
  710. $this->assertTrue($result);
  711. $this->assertFalse(Cache::read('some_value', 'memcached'));
  712. $this->assertEquals('cache2', Cache::read('some_value', 'memcached2'));
  713. Cache::clear(false, 'memcached2');
  714. }
  715. /**
  716. * test that a 0 duration can successfully write.
  717. *
  718. * @return void
  719. */
  720. public function testZeroDuration()
  721. {
  722. $this->_configCache(['duration' => 0]);
  723. $result = Cache::write('test_key', 'written!', 'memcached');
  724. $this->assertTrue($result);
  725. $result = Cache::read('test_key', 'memcached');
  726. $this->assertEquals('written!', $result);
  727. }
  728. /**
  729. * Tests that configuring groups for stored keys return the correct values when read/written
  730. * Shows that altering the group value is equivalent to deleting all keys under the same
  731. * group
  732. *
  733. * @return void
  734. */
  735. public function testGroupReadWrite()
  736. {
  737. Cache::config('memcached_groups', [
  738. 'engine' => 'Memcached',
  739. 'duration' => 3600,
  740. 'groups' => ['group_a', 'group_b'],
  741. 'prefix' => 'test_'
  742. ]);
  743. Cache::config('memcached_helper', [
  744. 'engine' => 'Memcached',
  745. 'duration' => 3600,
  746. 'prefix' => 'test_'
  747. ]);
  748. $this->assertTrue(Cache::write('test_groups', 'value', 'memcached_groups'));
  749. $this->assertEquals('value', Cache::read('test_groups', 'memcached_groups'));
  750. Cache::increment('group_a', 1, 'memcached_helper');
  751. $this->assertFalse(Cache::read('test_groups', 'memcached_groups'));
  752. $this->assertTrue(Cache::write('test_groups', 'value2', 'memcached_groups'));
  753. $this->assertEquals('value2', Cache::read('test_groups', 'memcached_groups'));
  754. Cache::increment('group_b', 1, 'memcached_helper');
  755. $this->assertFalse(Cache::read('test_groups', 'memcached_groups'));
  756. $this->assertTrue(Cache::write('test_groups', 'value3', 'memcached_groups'));
  757. $this->assertEquals('value3', Cache::read('test_groups', 'memcached_groups'));
  758. }
  759. /**
  760. * Tests that deleteing from a groups-enabled config is possible
  761. *
  762. * @return void
  763. */
  764. public function testGroupDelete()
  765. {
  766. Cache::config('memcached_groups', [
  767. 'engine' => 'Memcached',
  768. 'duration' => 3600,
  769. 'groups' => ['group_a', 'group_b']
  770. ]);
  771. $this->assertTrue(Cache::write('test_groups', 'value', 'memcached_groups'));
  772. $this->assertEquals('value', Cache::read('test_groups', 'memcached_groups'));
  773. $this->assertTrue(Cache::delete('test_groups', 'memcached_groups'));
  774. $this->assertFalse(Cache::read('test_groups', 'memcached_groups'));
  775. }
  776. /**
  777. * Test clearing a cache group
  778. *
  779. * @return void
  780. */
  781. public function testGroupClear()
  782. {
  783. Cache::config('memcached_groups', [
  784. 'engine' => 'Memcached',
  785. 'duration' => 3600,
  786. 'groups' => ['group_a', 'group_b']
  787. ]);
  788. $this->assertTrue(Cache::write('test_groups', 'value', 'memcached_groups'));
  789. $this->assertTrue(Cache::clearGroup('group_a', 'memcached_groups'));
  790. $this->assertFalse(Cache::read('test_groups', 'memcached_groups'));
  791. $this->assertTrue(Cache::write('test_groups', 'value2', 'memcached_groups'));
  792. $this->assertTrue(Cache::clearGroup('group_b', 'memcached_groups'));
  793. $this->assertFalse(Cache::read('test_groups', 'memcached_groups'));
  794. }
  795. /**
  796. * Test add
  797. *
  798. * @return void
  799. */
  800. public function testAdd()
  801. {
  802. Cache::delete('test_add_key', 'memcached');
  803. $result = Cache::add('test_add_key', 'test data', 'memcached');
  804. $this->assertTrue($result);
  805. $expected = 'test data';
  806. $result = Cache::read('test_add_key', 'memcached');
  807. $this->assertEquals($expected, $result);
  808. $result = Cache::add('test_add_key', 'test data 2', 'memcached');
  809. $this->assertFalse($result);
  810. }
  811. }