MemcachedEngineTest.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. <?php
  2. /**
  3. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  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://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  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. * Class TestMemcachedEngine
  23. *
  24. */
  25. class TestMemcachedEngine extends MemcachedEngine
  26. {
  27. /**
  28. * public accessor to _parseServerString
  29. *
  30. * @param string $server
  31. * @return array
  32. */
  33. public function parseServerString($server)
  34. {
  35. return $this->_parseServerString($server);
  36. }
  37. public function setMemcached($memcached)
  38. {
  39. $this->_Memcached = $memcached;
  40. }
  41. public function getMemcached()
  42. {
  43. return $this->_Memcached;
  44. }
  45. }
  46. /**
  47. * MemcachedEngineTest class
  48. *
  49. */
  50. class MemcachedEngineTest extends TestCase
  51. {
  52. /**
  53. * setUp method
  54. *
  55. * @return void
  56. */
  57. public function setUp()
  58. {
  59. parent::setUp();
  60. $this->skipIf(!class_exists('Memcached'), 'Memcached is not installed or configured properly.');
  61. $socket = @fsockopen('127.0.0.1', 11211, $errno, $errstr, 1);
  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 non latin domains.
  400. *
  401. * @return void
  402. */
  403. public function testParseServerStringNonLatin()
  404. {
  405. $Memcached = new TestMemcachedEngine();
  406. $result = $Memcached->parseServerString('schülervz.net:13211');
  407. $this->assertEquals(['schülervz.net', '13211'], $result);
  408. $result = $Memcached->parseServerString('sülül:1111');
  409. $this->assertEquals(['sülül', '1111'], $result);
  410. }
  411. /**
  412. * test unix sockets.
  413. *
  414. * @return void
  415. */
  416. public function testParseServerStringUnix()
  417. {
  418. $Memcached = new TestMemcachedEngine();
  419. $result = $Memcached->parseServerString('unix:///path/to/memcachedd.sock');
  420. $this->assertEquals(['unix:///path/to/memcachedd.sock', 0], $result);
  421. }
  422. /**
  423. * testReadAndWriteCache method
  424. *
  425. * @return void
  426. */
  427. public function testReadAndWriteCache()
  428. {
  429. $this->_configCache(['duration' => 1]);
  430. $result = Cache::read('test', 'memcached');
  431. $expecting = '';
  432. $this->assertEquals($expecting, $result);
  433. $data = 'this is a test of the emergency broadcasting system';
  434. $result = Cache::write('test', $data, 'memcached');
  435. $this->assertTrue($result);
  436. $result = Cache::read('test', 'memcached');
  437. $expecting = $data;
  438. $this->assertEquals($expecting, $result);
  439. Cache::delete('test', 'memcached');
  440. }
  441. /**
  442. * testReadMany method
  443. *
  444. * @return void
  445. */
  446. public function testReadMany()
  447. {
  448. $this->_configCache(['duration' => 2]);
  449. $data = [
  450. 'App.falseTest' => false,
  451. 'App.trueTest' => true,
  452. 'App.nullTest' => null,
  453. 'App.zeroTest' => 0,
  454. 'App.zeroTest2' => '0'
  455. ];
  456. foreach ($data as $key => $value) {
  457. Cache::write($key, $value, 'memcached');
  458. }
  459. $read = Cache::readMany(array_merge(array_keys($data), ['App.doesNotExist']), 'memcached');
  460. $this->assertSame($read['App.falseTest'], false);
  461. $this->assertSame($read['App.trueTest'], true);
  462. $this->assertSame($read['App.nullTest'], null);
  463. $this->assertSame($read['App.zeroTest'], 0);
  464. $this->assertSame($read['App.zeroTest2'], '0');
  465. $this->assertSame($read['App.doesNotExist'], false);
  466. }
  467. /**
  468. * testWriteMany method
  469. *
  470. * @return void
  471. */
  472. public function testWriteMany()
  473. {
  474. $this->_configCache(['duration' => 2]);
  475. $data = [
  476. 'App.falseTest' => false,
  477. 'App.trueTest' => true,
  478. 'App.nullTest' => null,
  479. 'App.zeroTest' => 0,
  480. 'App.zeroTest2' => '0'
  481. ];
  482. Cache::writeMany($data, 'memcached');
  483. $this->assertSame(Cache::read('App.falseTest', 'memcached'), false);
  484. $this->assertSame(Cache::read('App.trueTest', 'memcached'), true);
  485. $this->assertSame(Cache::read('App.nullTest', 'memcached'), null);
  486. $this->assertSame(Cache::read('App.zeroTest', 'memcached'), 0);
  487. $this->assertSame(Cache::read('App.zeroTest2', 'memcached'), '0');
  488. }
  489. /**
  490. * testExpiry method
  491. *
  492. * @return void
  493. */
  494. public function testExpiry()
  495. {
  496. $this->_configCache(['duration' => 1]);
  497. $result = Cache::read('test', 'memcached');
  498. $this->assertFalse($result);
  499. $data = 'this is a test of the emergency broadcasting system';
  500. $result = Cache::write('other_test', $data, 'memcached');
  501. $this->assertTrue($result);
  502. sleep(2);
  503. $result = Cache::read('other_test', 'memcached');
  504. $this->assertFalse($result);
  505. $this->_configCache(['duration' => '+1 second']);
  506. $data = 'this is a test of the emergency broadcasting system';
  507. $result = Cache::write('other_test', $data, 'memcached');
  508. $this->assertTrue($result);
  509. sleep(3);
  510. $result = Cache::read('other_test', 'memcached');
  511. $this->assertFalse($result);
  512. $result = Cache::read('other_test', 'memcached');
  513. $this->assertFalse($result);
  514. $this->_configCache(['duration' => '+29 days']);
  515. $data = 'this is a test of the emergency broadcasting system';
  516. $result = Cache::write('long_expiry_test', $data, 'memcached');
  517. $this->assertTrue($result);
  518. sleep(2);
  519. $result = Cache::read('long_expiry_test', 'memcached');
  520. $expecting = $data;
  521. $this->assertEquals($expecting, $result);
  522. }
  523. /**
  524. * testDeleteCache method
  525. *
  526. * @return void
  527. */
  528. public function testDeleteCache()
  529. {
  530. $data = 'this is a test of the emergency broadcasting system';
  531. $result = Cache::write('delete_test', $data, 'memcached');
  532. $this->assertTrue($result);
  533. $result = Cache::delete('delete_test', 'memcached');
  534. $this->assertTrue($result);
  535. }
  536. /**
  537. * testDeleteMany method
  538. *
  539. * @return void
  540. */
  541. public function testDeleteMany()
  542. {
  543. $this->skipIf(defined('HHVM_VERSION'), 'HHVM does not implement deleteMulti');
  544. $this->_configCache();
  545. $data = [
  546. 'App.falseTest' => false,
  547. 'App.trueTest' => true,
  548. 'App.nullTest' => null,
  549. 'App.zeroTest' => 0,
  550. 'App.zeroTest2' => '0',
  551. ];
  552. foreach ($data as $key => $value) {
  553. Cache::write($key, $value, 'memcached');
  554. }
  555. Cache::write('App.keepTest', 'keepMe', 'memcached');
  556. Cache::deleteMany(array_merge(array_keys($data), ['App.doesNotExist']), 'memcached');
  557. $this->assertSame(Cache::read('App.falseTest', 'memcached'), false);
  558. $this->assertSame(Cache::read('App.trueTest', 'memcached'), false);
  559. $this->assertSame(Cache::read('App.nullTest', 'memcached'), false);
  560. $this->assertSame(Cache::read('App.zeroTest', 'memcached'), false);
  561. $this->assertSame(Cache::read('App.zeroTest2', 'memcached'), false);
  562. $this->assertSame(Cache::read('App.keepTest', 'memcached'), 'keepMe');
  563. }
  564. /**
  565. * testDecrement method
  566. *
  567. * @return void
  568. */
  569. public function testDecrement()
  570. {
  571. $result = Cache::write('test_decrement', 5, 'memcached');
  572. $this->assertTrue($result);
  573. $result = Cache::decrement('test_decrement', 1, 'memcached');
  574. $this->assertEquals(4, $result);
  575. $result = Cache::read('test_decrement', 'memcached');
  576. $this->assertEquals(4, $result);
  577. $result = Cache::decrement('test_decrement', 2, 'memcached');
  578. $this->assertEquals(2, $result);
  579. $result = Cache::read('test_decrement', 'memcached');
  580. $this->assertEquals(2, $result);
  581. Cache::delete('test_decrement', 'memcached');
  582. }
  583. /**
  584. * test decrementing compressed keys
  585. *
  586. * @return void
  587. */
  588. public function testDecrementCompressedKeys()
  589. {
  590. Cache::config('compressed_memcached', [
  591. 'engine' => 'Memcached',
  592. 'duration' => '+2 seconds',
  593. 'servers' => ['127.0.0.1:11211'],
  594. 'compress' => true
  595. ]);
  596. $result = Cache::write('test_decrement', 5, 'compressed_memcached');
  597. $this->assertTrue($result);
  598. $result = Cache::decrement('test_decrement', 1, 'compressed_memcached');
  599. $this->assertEquals(4, $result);
  600. $result = Cache::read('test_decrement', 'compressed_memcached');
  601. $this->assertEquals(4, $result);
  602. $result = Cache::decrement('test_decrement', 2, 'compressed_memcached');
  603. $this->assertEquals(2, $result);
  604. $result = Cache::read('test_decrement', 'compressed_memcached');
  605. $this->assertEquals(2, $result);
  606. Cache::delete('test_decrement', 'compressed_memcached');
  607. }
  608. /**
  609. * testIncrement method
  610. *
  611. * @return void
  612. */
  613. public function testIncrement()
  614. {
  615. $result = Cache::write('test_increment', 5, 'memcached');
  616. $this->assertTrue($result);
  617. $result = Cache::increment('test_increment', 1, 'memcached');
  618. $this->assertEquals(6, $result);
  619. $result = Cache::read('test_increment', 'memcached');
  620. $this->assertEquals(6, $result);
  621. $result = Cache::increment('test_increment', 2, 'memcached');
  622. $this->assertEquals(8, $result);
  623. $result = Cache::read('test_increment', 'memcached');
  624. $this->assertEquals(8, $result);
  625. Cache::delete('test_increment', 'memcached');
  626. }
  627. /**
  628. * test incrementing compressed keys
  629. *
  630. * @return void
  631. */
  632. public function testIncrementCompressedKeys()
  633. {
  634. Cache::config('compressed_memcached', [
  635. 'engine' => 'Memcached',
  636. 'duration' => '+2 seconds',
  637. 'servers' => ['127.0.0.1:11211'],
  638. 'compress' => true
  639. ]);
  640. $result = Cache::write('test_increment', 5, 'compressed_memcached');
  641. $this->assertTrue($result);
  642. $result = Cache::increment('test_increment', 1, 'compressed_memcached');
  643. $this->assertEquals(6, $result);
  644. $result = Cache::read('test_increment', 'compressed_memcached');
  645. $this->assertEquals(6, $result);
  646. $result = Cache::increment('test_increment', 2, 'compressed_memcached');
  647. $this->assertEquals(8, $result);
  648. $result = Cache::read('test_increment', 'compressed_memcached');
  649. $this->assertEquals(8, $result);
  650. Cache::delete('test_increment', 'compressed_memcached');
  651. }
  652. /**
  653. * test that configurations don't conflict, when a file engine is declared after a memcached one.
  654. *
  655. * @return void
  656. */
  657. public function testConfigurationConflict()
  658. {
  659. Cache::config('long_memcached', [
  660. 'engine' => 'Memcached',
  661. 'duration' => '+2 seconds',
  662. 'servers' => ['127.0.0.1:11211'],
  663. ]);
  664. Cache::config('short_memcached', [
  665. 'engine' => 'Memcached',
  666. 'duration' => '+1 seconds',
  667. 'servers' => ['127.0.0.1:11211'],
  668. ]);
  669. $this->assertTrue(Cache::write('duration_test', 'yay', 'long_memcached'));
  670. $this->assertTrue(Cache::write('short_duration_test', 'boo', 'short_memcached'));
  671. $this->assertEquals('yay', Cache::read('duration_test', 'long_memcached'), 'Value was not read %s');
  672. $this->assertEquals('boo', Cache::read('short_duration_test', 'short_memcached'), 'Value was not read %s');
  673. sleep(1);
  674. $this->assertEquals('yay', Cache::read('duration_test', 'long_memcached'), 'Value was not read %s');
  675. sleep(2);
  676. $this->assertFalse(Cache::read('short_duration_test', 'short_memcached'), 'Cache was not invalidated %s');
  677. $this->assertFalse(Cache::read('duration_test', 'long_memcached'), 'Value did not expire %s');
  678. Cache::delete('duration_test', 'long_memcached');
  679. Cache::delete('short_duration_test', 'short_memcached');
  680. }
  681. /**
  682. * test clearing memcached.
  683. *
  684. * @return void
  685. */
  686. public function testClear()
  687. {
  688. Cache::config('memcached2', [
  689. 'engine' => 'Memcached',
  690. 'prefix' => 'cake2_',
  691. 'duration' => 3600
  692. ]);
  693. Cache::write('some_value', 'cache1', 'memcached');
  694. $result = Cache::clear(true, 'memcached');
  695. $this->assertTrue($result);
  696. $this->assertEquals('cache1', Cache::read('some_value', 'memcached'));
  697. Cache::write('some_value', 'cache2', 'memcached2');
  698. $result = Cache::clear(false, 'memcached');
  699. $this->assertTrue($result);
  700. $this->assertFalse(Cache::read('some_value', 'memcached'));
  701. $this->assertEquals('cache2', Cache::read('some_value', 'memcached2'));
  702. Cache::clear(false, 'memcached2');
  703. }
  704. /**
  705. * test that a 0 duration can successfully write.
  706. *
  707. * @return void
  708. */
  709. public function testZeroDuration()
  710. {
  711. $this->_configCache(['duration' => 0]);
  712. $result = Cache::write('test_key', 'written!', 'memcached');
  713. $this->assertTrue($result);
  714. $result = Cache::read('test_key', 'memcached');
  715. $this->assertEquals('written!', $result);
  716. }
  717. /**
  718. * test that durations greater than 30 days never expire
  719. *
  720. * @return void
  721. */
  722. public function testLongDurationEqualToZero()
  723. {
  724. $memcached = new TestMemcachedEngine();
  725. $memcached->init(['prefix' => 'Foo_', 'compress' => false, 'duration' => 50 * DAY]);
  726. $mock = $this->getMock('Memcached');
  727. $memcached->setMemcached($mock);
  728. $mock->expects($this->once())
  729. ->method('set')
  730. ->with('Foo_key', 'value', 0);
  731. $value = 'value';
  732. $memcached->write('key', $value);
  733. }
  734. /**
  735. * Tests that configuring groups for stored keys return the correct values when read/written
  736. * Shows that altering the group value is equivalent to deleting all keys under the same
  737. * group
  738. *
  739. * @return void
  740. */
  741. public function testGroupReadWrite()
  742. {
  743. Cache::config('memcached_groups', [
  744. 'engine' => 'Memcached',
  745. 'duration' => 3600,
  746. 'groups' => ['group_a', 'group_b'],
  747. 'prefix' => 'test_'
  748. ]);
  749. Cache::config('memcached_helper', [
  750. 'engine' => 'Memcached',
  751. 'duration' => 3600,
  752. 'prefix' => 'test_'
  753. ]);
  754. $this->assertTrue(Cache::write('test_groups', 'value', 'memcached_groups'));
  755. $this->assertEquals('value', Cache::read('test_groups', 'memcached_groups'));
  756. Cache::increment('group_a', 1, 'memcached_helper');
  757. $this->assertFalse(Cache::read('test_groups', 'memcached_groups'));
  758. $this->assertTrue(Cache::write('test_groups', 'value2', 'memcached_groups'));
  759. $this->assertEquals('value2', Cache::read('test_groups', 'memcached_groups'));
  760. Cache::increment('group_b', 1, 'memcached_helper');
  761. $this->assertFalse(Cache::read('test_groups', 'memcached_groups'));
  762. $this->assertTrue(Cache::write('test_groups', 'value3', 'memcached_groups'));
  763. $this->assertEquals('value3', Cache::read('test_groups', 'memcached_groups'));
  764. }
  765. /**
  766. * Tests that deleteing from a groups-enabled config is possible
  767. *
  768. * @return void
  769. */
  770. public function testGroupDelete()
  771. {
  772. Cache::config('memcached_groups', [
  773. 'engine' => 'Memcached',
  774. 'duration' => 3600,
  775. 'groups' => ['group_a', 'group_b']
  776. ]);
  777. $this->assertTrue(Cache::write('test_groups', 'value', 'memcached_groups'));
  778. $this->assertEquals('value', Cache::read('test_groups', 'memcached_groups'));
  779. $this->assertTrue(Cache::delete('test_groups', 'memcached_groups'));
  780. $this->assertFalse(Cache::read('test_groups', 'memcached_groups'));
  781. }
  782. /**
  783. * Test clearing a cache group
  784. *
  785. * @return void
  786. */
  787. public function testGroupClear()
  788. {
  789. Cache::config('memcached_groups', [
  790. 'engine' => 'Memcached',
  791. 'duration' => 3600,
  792. 'groups' => ['group_a', 'group_b']
  793. ]);
  794. $this->assertTrue(Cache::write('test_groups', 'value', 'memcached_groups'));
  795. $this->assertTrue(Cache::clearGroup('group_a', 'memcached_groups'));
  796. $this->assertFalse(Cache::read('test_groups', 'memcached_groups'));
  797. $this->assertTrue(Cache::write('test_groups', 'value2', 'memcached_groups'));
  798. $this->assertTrue(Cache::clearGroup('group_b', 'memcached_groups'));
  799. $this->assertFalse(Cache::read('test_groups', 'memcached_groups'));
  800. }
  801. }