Skip to content

Commit d30565a

Browse files
authored
Queue Integration Tests with Redis Cluster (#54218)
* InteractsWithRedis can provide config for cluster * Set RedisManager instance in InteractsWithRedis * RedisQueueTest uses default queue name from config * InteractsWithRedis in RateLimitedWithRedisTest * docker-compose example for local redis cluster * Queue Integration Tests with Redis Cluster
1 parent debc214 commit d30565a

File tree

5 files changed

+196
-52
lines changed

5 files changed

+196
-52
lines changed

.github/workflows/queues.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,54 @@ jobs:
127127
REDIS_CLIENT: ${{ matrix.client }}
128128
QUEUE_CONNECTION: redis
129129

130+
redis-cluster:
131+
runs-on: ubuntu-24.04
132+
133+
strategy:
134+
fail-fast: true
135+
matrix:
136+
client: ['phpredis', 'predis']
137+
138+
name: Redis Cluster (${{ matrix.client}}) Driver
139+
140+
steps:
141+
- name: Checkout code
142+
uses: actions/checkout@v4
143+
144+
- name: Setup PHP
145+
uses: shivammathur/setup-php@v2
146+
with:
147+
php-version: 8.2
148+
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, pdo_mysql, :php-psr
149+
tools: composer:v2
150+
coverage: none
151+
152+
- name: Set Framework version
153+
run: composer config version "11.x-dev"
154+
155+
- name: Install dependencies
156+
uses: nick-fields/retry@v3
157+
with:
158+
timeout_minutes: 5
159+
max_attempts: 5
160+
command: composer update --prefer-stable --prefer-dist --no-interaction --no-progress
161+
162+
- name: Create Redis Cluster
163+
run: |
164+
sudo apt-get install -y redis-server
165+
sudo service redis-server stop
166+
redis-server --daemonize yes --port 7000 --appendonly yes --cluster-enabled yes --cluster-config-file nodes-7000.conf
167+
redis-server --daemonize yes --port 7001 --appendonly yes --cluster-enabled yes --cluster-config-file nodes-7001.conf
168+
redis-server --daemonize yes --port 7002 --appendonly yes --cluster-enabled yes --cluster-config-file nodes-7002.conf
169+
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 --cluster-replicas 0 --cluster-yes
170+
171+
- name: Execute tests
172+
run: vendor/bin/phpunit tests/Integration/Queue
173+
env:
174+
REDIS_CLIENT: ${{ matrix.client }}
175+
REDIS_CLUSTER_HOSTS_AND_PORTS: 127.0.0.1:7000,127.0.0.1:7001,127.0.0.1:7002
176+
REDIS_QUEUE: '{default}'
177+
130178
beanstalkd:
131179
runs-on: ubuntu-24.04
132180

docker-compose.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,29 @@ services:
5151
ports:
5252
- "6379:6379"
5353
restart: always
54+
# redis-cluster-0:
55+
# image: redis:7.0-alpine
56+
# ports:
57+
# - "7000:7000"
58+
# restart: always
59+
# command: redis-server --port 7000 --appendonly yes --cluster-enabled yes
60+
# redis-cluster-1:
61+
# image: redis:7.0-alpine
62+
# ports:
63+
# - "7001:7001"
64+
# restart: always
65+
# command: redis-server --port 7001 --appendonly yes --cluster-enabled yes
66+
# redis-cluster-2:
67+
# image: redis:7.0-alpine
68+
# ports:
69+
# - "7002:7002"
70+
# restart: always
71+
# command: redis-server --port 7002 --appendonly yes --cluster-enabled yes
72+
# redis-cluster-creator:
73+
# image: redis:7.0-alpine
74+
# depends_on:
75+
# - redis-cluster-0
76+
# - redis-cluster-1
77+
# - redis-cluster-2
78+
# command: sh -c 'redis-cli --cluster create redis-cluster-0:7000 redis-cluster-1:7001 redis-cluster-2:7002 --cluster-replicas 0 --cluster-yes || true'
79+
# restart: no

src/Illuminate/Foundation/Testing/Concerns/InteractsWithRedis.php

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Illuminate\Foundation\Testing\Concerns;
44

55
use Exception;
6+
use Illuminate\Contracts\Redis\Factory as Redis;
67
use Illuminate\Foundation\Application;
78
use Illuminate\Redis\RedisManager;
89
use Illuminate\Support\Env;
@@ -43,30 +44,58 @@ public function setUpRedis()
4344
$port = Env::get('REDIS_PORT', 6379);
4445

4546
foreach (static::redisDriverProvider() as $driver) {
46-
$this->redis[$driver[0]] = new RedisManager($app, $driver[0], [
47-
'cluster' => false,
48-
'options' => [
49-
'prefix' => 'test_',
50-
],
51-
'default' => [
52-
'host' => $host,
53-
'port' => $port,
54-
'database' => 5,
55-
'timeout' => 0.5,
56-
'name' => 'default',
57-
],
58-
]);
47+
if (Env::get('REDIS_CLUSTER_HOSTS_AND_PORTS')) {
48+
$config = [
49+
'options' => [
50+
'cluster' => 'redis',
51+
'prefix' => 'test_',
52+
],
53+
'clusters' => [
54+
'default' => array_map(
55+
static fn ($hostAndPort) => [
56+
'host' => explode(':', $hostAndPort)[0],
57+
'port' => explode(':', $hostAndPort)[1],
58+
],
59+
explode(',', Env::get('REDIS_CLUSTER_HOSTS_AND_PORTS')),
60+
),
61+
],
62+
];
63+
} else {
64+
$config = [
65+
'options' => [
66+
'prefix' => 'test_',
67+
],
68+
'default' => [
69+
'host' => $host,
70+
'port' => $port,
71+
'database' => 5,
72+
'timeout' => 0.5,
73+
'name' => 'default',
74+
],
75+
'cache' => [
76+
'host' => $host,
77+
'port' => $port,
78+
'database' => 6,
79+
'timeout' => 0.5,
80+
],
81+
];
82+
}
83+
$this->redis[$driver[0]] = new RedisManager($app, $driver[0], $config);
5984
}
6085

86+
$defaultDriver = Env::get('REDIS_CLIENT', 'phpredis');
87+
6188
try {
62-
$this->redis['phpredis']->connection()->flushdb();
89+
$this->redis[$defaultDriver]->connection()->flushdb();
6390
} catch (Exception) {
6491
if ($host === '127.0.0.1' && $port === 6379 && Env::get('REDIS_HOST') === null) {
6592
static::$connectionFailedOnceWithDefaultsSkip = true;
6693

6794
$this->markTestSkipped('Trying default host/port failed, please set environment variable REDIS_HOST & REDIS_PORT to enable '.__CLASS__);
6895
}
6996
}
97+
98+
$app->instance('redis', $this->redis[$defaultDriver]);
7099
}
71100

72101
/**

tests/Integration/Queue/RateLimitedWithRedisTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Illuminate\Cache\RateLimiting\Limit;
99
use Illuminate\Contracts\Queue\Job;
1010
use Illuminate\Contracts\Redis\Factory as Redis;
11+
use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis;
1112
use Illuminate\Queue\CallQueuedHandler;
1213
use Illuminate\Queue\InteractsWithQueue;
1314
use Illuminate\Queue\Middleware\RateLimitedWithRedis;
@@ -21,6 +22,22 @@
2122
#[RequiresPhpExtension('redis')]
2223
class RateLimitedWithRedisTest extends TestCase
2324
{
25+
use InteractsWithRedis;
26+
27+
protected function setUp(): void
28+
{
29+
parent::setUp();
30+
31+
$this->setUpRedis();
32+
}
33+
34+
protected function tearDown(): void
35+
{
36+
$this->tearDownRedis();
37+
38+
parent::tearDown();
39+
}
40+
2441
public function testUnlimitedJobsAreExecuted()
2542
{
2643
$rateLimiter = $this->app->make(RateLimiter::class);

0 commit comments

Comments
 (0)