DurationLimiterTest.php 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <?php
  2. namespace Illuminate\Tests\Redis;
  3. use Illuminate\Contracts\Redis\LimiterTimeoutException;
  4. use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis;
  5. use Illuminate\Redis\Limiters\DurationLimiter;
  6. use PHPUnit\Framework\TestCase;
  7. use Throwable;
  8. class DurationLimiterTest extends TestCase
  9. {
  10. use InteractsWithRedis;
  11. protected function setUp(): void
  12. {
  13. parent::setUp();
  14. $this->setUpRedis();
  15. }
  16. protected function tearDown(): void
  17. {
  18. parent::tearDown();
  19. $this->tearDownRedis();
  20. }
  21. public function testItLocksTasksWhenNoSlotAvailable()
  22. {
  23. $store = [];
  24. (new DurationLimiter($this->redis(), 'key', 2, 2))->block(0, function () use (&$store) {
  25. $store[] = 1;
  26. });
  27. (new DurationLimiter($this->redis(), 'key', 2, 2))->block(0, function () use (&$store) {
  28. $store[] = 2;
  29. });
  30. try {
  31. (new DurationLimiter($this->redis(), 'key', 2, 2))->block(0, function () use (&$store) {
  32. $store[] = 3;
  33. });
  34. } catch (Throwable $e) {
  35. $this->assertInstanceOf(LimiterTimeoutException::class, $e);
  36. }
  37. $this->assertEquals([1, 2], $store);
  38. sleep(2);
  39. (new DurationLimiter($this->redis(), 'key', 2, 2))->block(0, function () use (&$store) {
  40. $store[] = 3;
  41. });
  42. $this->assertEquals([1, 2, 3], $store);
  43. }
  44. public function testItFailsImmediatelyOrRetriesForAWhileBasedOnAGivenTimeout()
  45. {
  46. $store = [];
  47. (new DurationLimiter($this->redis(), 'key', 1, 1))->block(2, function () use (&$store) {
  48. $store[] = 1;
  49. });
  50. try {
  51. (new DurationLimiter($this->redis(), 'key', 1, 1))->block(0, function () use (&$store) {
  52. $store[] = 2;
  53. });
  54. } catch (Throwable $e) {
  55. $this->assertInstanceOf(LimiterTimeoutException::class, $e);
  56. }
  57. (new DurationLimiter($this->redis(), 'key', 1, 1))->block(2, function () use (&$store) {
  58. $store[] = 3;
  59. });
  60. $this->assertEquals([1, 3], $store);
  61. }
  62. public function testItReturnsTheCallbackResult()
  63. {
  64. $limiter = new DurationLimiter($this->redis(), 'key', 1, 1);
  65. $result = $limiter->block(1, function () {
  66. return 'foo';
  67. });
  68. $this->assertSame('foo', $result);
  69. }
  70. private function redis()
  71. {
  72. return $this->redis['phpredis']->connection();
  73. }
  74. }