PhpRedisCacheLockTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php
  2. namespace Illuminate\Tests\Integration\Cache;
  3. use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis;
  4. use Illuminate\Support\Facades\Cache;
  5. use Orchestra\Testbench\TestCase;
  6. use Redis;
  7. class PhpRedisCacheLockTest extends TestCase
  8. {
  9. use InteractsWithRedis;
  10. protected function setUp(): void
  11. {
  12. parent::setUp();
  13. $this->setUpRedis();
  14. }
  15. protected function tearDown(): void
  16. {
  17. parent::tearDown();
  18. $this->tearDownRedis();
  19. }
  20. public function testRedisLockCanBeAcquiredAndReleasedWithoutSerializationAndCompression()
  21. {
  22. $this->app['config']->set('database.redis.client', 'phpredis');
  23. $this->app['config']->set('cache.stores.redis.connection', 'default');
  24. $this->app['config']->set('cache.stores.redis.lock_connection', 'default');
  25. /** @var \Illuminate\Cache\RedisStore $store */
  26. $store = Cache::store('redis');
  27. /** @var \Redis $client */
  28. $client = $store->lockConnection()->client();
  29. $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);
  30. $store->lock('foo')->forceRelease();
  31. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  32. $lock = $store->lock('foo', 10);
  33. $this->assertTrue($lock->get());
  34. $this->assertFalse($store->lock('foo', 10)->get());
  35. $lock->release();
  36. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  37. }
  38. public function testRedisLockCanBeAcquiredAndReleasedWithPhpSerialization()
  39. {
  40. $this->app['config']->set('database.redis.client', 'phpredis');
  41. $this->app['config']->set('cache.stores.redis.connection', 'default');
  42. $this->app['config']->set('cache.stores.redis.lock_connection', 'default');
  43. /** @var \Illuminate\Cache\RedisStore $store */
  44. $store = Cache::store('redis');
  45. /** @var \Redis $client */
  46. $client = $store->lockConnection()->client();
  47. $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
  48. $store->lock('foo')->forceRelease();
  49. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  50. $lock = $store->lock('foo', 10);
  51. $this->assertTrue($lock->get());
  52. $this->assertFalse($store->lock('foo', 10)->get());
  53. $lock->release();
  54. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  55. }
  56. public function testRedisLockCanBeAcquiredAndReleasedWithJsonSerialization()
  57. {
  58. $this->app['config']->set('database.redis.client', 'phpredis');
  59. $this->app['config']->set('cache.stores.redis.connection', 'default');
  60. $this->app['config']->set('cache.stores.redis.lock_connection', 'default');
  61. /** @var \Illuminate\Cache\RedisStore $store */
  62. $store = Cache::store('redis');
  63. /** @var \Redis $client */
  64. $client = $store->lockConnection()->client();
  65. $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_JSON);
  66. $store->lock('foo')->forceRelease();
  67. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  68. $lock = $store->lock('foo', 10);
  69. $this->assertTrue($lock->get());
  70. $this->assertFalse($store->lock('foo', 10)->get());
  71. $lock->release();
  72. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  73. }
  74. public function testRedisLockCanBeAcquiredAndReleasedWithIgbinarySerialization()
  75. {
  76. if (! defined('Redis::SERIALIZER_IGBINARY')) {
  77. $this->markTestSkipped('Redis extension is not configured to support the igbinary serializer.');
  78. }
  79. $this->app['config']->set('database.redis.client', 'phpredis');
  80. $this->app['config']->set('cache.stores.redis.connection', 'default');
  81. $this->app['config']->set('cache.stores.redis.lock_connection', 'default');
  82. /** @var \Illuminate\Cache\RedisStore $store */
  83. $store = Cache::store('redis');
  84. /** @var \Redis $client */
  85. $client = $store->lockConnection()->client();
  86. $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_IGBINARY);
  87. $store->lock('foo')->forceRelease();
  88. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  89. $lock = $store->lock('foo', 10);
  90. $this->assertTrue($lock->get());
  91. $this->assertFalse($store->lock('foo', 10)->get());
  92. $lock->release();
  93. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  94. }
  95. public function testRedisLockCanBeAcquiredAndReleasedWithMsgpackSerialization()
  96. {
  97. if (! defined('Redis::SERIALIZER_MSGPACK')) {
  98. $this->markTestSkipped('Redis extension is not configured to support the msgpack serializer.');
  99. }
  100. $this->app['config']->set('database.redis.client', 'phpredis');
  101. $this->app['config']->set('cache.stores.redis.connection', 'default');
  102. $this->app['config']->set('cache.stores.redis.lock_connection', 'default');
  103. /** @var \Illuminate\Cache\RedisStore $store */
  104. $store = Cache::store('redis');
  105. /** @var \Redis $client */
  106. $client = $store->lockConnection()->client();
  107. $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_MSGPACK);
  108. $store->lock('foo')->forceRelease();
  109. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  110. $lock = $store->lock('foo', 10);
  111. $this->assertTrue($lock->get());
  112. $this->assertFalse($store->lock('foo', 10)->get());
  113. $lock->release();
  114. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  115. }
  116. /**
  117. * @requires extension lzf
  118. */
  119. public function testRedisLockCanBeAcquiredAndReleasedWithLzfCompression()
  120. {
  121. if (! defined('Redis::COMPRESSION_LZF')) {
  122. $this->markTestSkipped('Redis extension is not configured to support the lzf compression.');
  123. }
  124. $this->app['config']->set('database.redis.client', 'phpredis');
  125. $this->app['config']->set('cache.stores.redis.connection', 'default');
  126. $this->app['config']->set('cache.stores.redis.lock_connection', 'default');
  127. /** @var \Illuminate\Cache\RedisStore $store */
  128. $store = Cache::store('redis');
  129. /** @var \Redis $client */
  130. $client = $store->lockConnection()->client();
  131. $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);
  132. $client->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_LZF);
  133. $store->lock('foo')->forceRelease();
  134. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  135. $lock = $store->lock('foo', 10);
  136. $this->assertTrue($lock->get());
  137. $this->assertFalse($store->lock('foo', 10)->get());
  138. $lock->release();
  139. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  140. }
  141. /**
  142. * @requires extension zstd
  143. */
  144. public function testRedisLockCanBeAcquiredAndReleasedWithZstdCompression()
  145. {
  146. if (! defined('Redis::COMPRESSION_ZSTD')) {
  147. $this->markTestSkipped('Redis extension is not configured to support the zstd compression.');
  148. }
  149. $this->app['config']->set('database.redis.client', 'phpredis');
  150. $this->app['config']->set('cache.stores.redis.connection', 'default');
  151. $this->app['config']->set('cache.stores.redis.lock_connection', 'default');
  152. /** @var \Illuminate\Cache\RedisStore $store */
  153. $store = Cache::store('redis');
  154. /** @var \Redis $client */
  155. $client = $store->lockConnection()->client();
  156. $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);
  157. $client->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_ZSTD);
  158. $client->setOption(Redis::OPT_COMPRESSION_LEVEL, Redis::COMPRESSION_ZSTD_DEFAULT);
  159. $store->lock('foo')->forceRelease();
  160. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  161. $lock = $store->lock('foo', 10);
  162. $this->assertTrue($lock->get());
  163. $this->assertFalse($store->lock('foo', 10)->get());
  164. $lock->release();
  165. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  166. $client->setOption(Redis::OPT_COMPRESSION_LEVEL, Redis::COMPRESSION_ZSTD_MIN);
  167. $store->lock('foo')->forceRelease();
  168. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  169. $lock = $store->lock('foo', 10);
  170. $this->assertTrue($lock->get());
  171. $this->assertFalse($store->lock('foo', 10)->get());
  172. $lock->release();
  173. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  174. $client->setOption(Redis::OPT_COMPRESSION_LEVEL, Redis::COMPRESSION_ZSTD_MAX);
  175. $store->lock('foo')->forceRelease();
  176. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  177. $lock = $store->lock('foo', 10);
  178. $this->assertTrue($lock->get());
  179. $this->assertFalse($store->lock('foo', 10)->get());
  180. $lock->release();
  181. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  182. }
  183. /**
  184. * @requires extension lz4
  185. */
  186. public function testRedisLockCanBeAcquiredAndReleasedWithLz4Compression()
  187. {
  188. if (! defined('Redis::COMPRESSION_LZ4')) {
  189. $this->markTestSkipped('Redis extension is not configured to support the lz4 compression.');
  190. }
  191. $this->app['config']->set('database.redis.client', 'phpredis');
  192. $this->app['config']->set('cache.stores.redis.connection', 'default');
  193. $this->app['config']->set('cache.stores.redis.lock_connection', 'default');
  194. /** @var \Illuminate\Cache\RedisStore $store */
  195. $store = Cache::store('redis');
  196. /** @var \Redis $client */
  197. $client = $store->lockConnection()->client();
  198. $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);
  199. $client->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_LZ4);
  200. $client->setOption(Redis::OPT_COMPRESSION_LEVEL, 1);
  201. $store->lock('foo')->forceRelease();
  202. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  203. $lock = $store->lock('foo', 10);
  204. $this->assertTrue($lock->get());
  205. $this->assertFalse($store->lock('foo', 10)->get());
  206. $lock->release();
  207. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  208. $client->setOption(Redis::OPT_COMPRESSION_LEVEL, 3);
  209. $store->lock('foo')->forceRelease();
  210. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  211. $lock = $store->lock('foo', 10);
  212. $this->assertTrue($lock->get());
  213. $this->assertFalse($store->lock('foo', 10)->get());
  214. $lock->release();
  215. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  216. $client->setOption(Redis::OPT_COMPRESSION_LEVEL, 12);
  217. $store->lock('foo')->forceRelease();
  218. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  219. $lock = $store->lock('foo', 10);
  220. $this->assertTrue($lock->get());
  221. $this->assertFalse($store->lock('foo', 10)->get());
  222. $lock->release();
  223. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  224. }
  225. /**
  226. * @requires extension Lzf
  227. */
  228. public function testRedisLockCanBeAcquiredAndReleasedWithSerializationAndCompression()
  229. {
  230. if (! defined('Redis::COMPRESSION_LZF')) {
  231. $this->markTestSkipped('Redis extension is not configured to support the lzf compression.');
  232. }
  233. $this->app['config']->set('database.redis.client', 'phpredis');
  234. $this->app['config']->set('cache.stores.redis.connection', 'default');
  235. $this->app['config']->set('cache.stores.redis.lock_connection', 'default');
  236. /** @var \Illuminate\Cache\RedisStore $store */
  237. $store = Cache::store('redis');
  238. /** @var \Redis $client */
  239. $client = $store->lockConnection()->client();
  240. $client->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
  241. $client->setOption(Redis::OPT_COMPRESSION, Redis::COMPRESSION_LZF);
  242. $store->lock('foo')->forceRelease();
  243. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  244. $lock = $store->lock('foo', 10);
  245. $this->assertTrue($lock->get());
  246. $this->assertFalse($store->lock('foo', 10)->get());
  247. $lock->release();
  248. $this->assertNull($store->lockConnection()->get($store->getPrefix().'foo'));
  249. }
  250. }