MemcachedEngineTest.php 27 KB

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