8000 bug #58818 [Messenger] silence PHP warnings issued by `Redis::connect… · symfony/symfony@fde6ae9 · GitHub
[go: up one dir, main page]

Skip to content

Commit fde6ae9

Browse files
bug #58818 [Messenger] silence PHP warnings issued by Redis::connect() (xabbuh)
This PR was merged into the 5.4 branch. Discussion 8000 ---------- [Messenger] silence PHP warnings issued by `Redis::connect()` | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | | License | MIT `Redis::connect()` may issue a warning when the host cannot be resolved (see https://github.com/symfony/symfony/actions/runs/11755592846/job/32750804715?pr=58370#step:8:2535) Commits ------- 8ca27e1 silence PHP warnings issued by Redis::connect()
2 parents 31bd807 + 8ca27e1 commit fde6ae9

File tree

2 files changed

+68
-32
lines changed

2 files changed

+68
-32
lines changed

src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/ConnectionTest.php

Lines changed: 53 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ public function testFromDsn()
3737
new Connection(['stream' => 'queue', 'delete_after_ack' => true], [
3838
'host' => 'localhost',
3939
'port' => 6379,
40-
], [], $this->createMock(\Redis::class)),
41-
Connection::fromDsn('redis://localhost/queue?delete_after_ack=1', [], $this->createMock(\Redis::class))
40+
], [], $this->createRedisMock()),
41+
Connection::fromDsn('redis://localhost/queue?delete_after_ack=1', [], $this->createRedisMock())
4242
);
4343
}
4444

@@ -48,24 +48,24 @@ public function testFromDsnOnUnixSocket()
4848
new Connection(['stream' => 'queue', 'delete_after_ack' => true], [
4949
'host' => '/var/run/redis/redis.sock',
5050
'port' => 0,
51-
], [], $redis = $this->createMock(\Redis::class)),
52-
Connection::fromDsn('redis:///var/run/redis/redis.sock', ['stream' => 'queue', 'delete_after_ack' => true], $redis)
51+
], [], $this->createRedisMock()),
52+
Connection::fromDsn('redis:///var/run/redis/redis.sock', ['stream' => 'queue', 'delete_after_ack' => true], $this->createRedisMock())
5353
);
5454
}
5555

5656
public function testFromDsnWithOptions()
5757
{
5858
$this->assertEquals(
59-
Connection::fromDsn('redis://localhost', ['stream' => 'queue', 'group' => 'group1', 'consumer' => 'consumer1', 'auto_setup' => false, 'serializer' => 2, 'delete_after_ack' => true], $this->createMock(\Redis::class)),
60-
Connection::fromDsn('redis://localhost/queue/group1/consumer1?serializer=2&auto_setup=0&delete_after_ack=1', [], $this->createMock(\Redis::class))
59+
Connection::fromDsn('redis://localhost', ['stream' => 'queue', 'group' => 'group1', 'consumer' => 'consumer1', 'auto_setup' => false, 'serializer' => 2, 'delete_after_ack' => true], $this->createRedisMock()),
60+
Connection::fromDsn('redis://localhost/queue/group1/consumer1?serializer=2&auto_setup=0&delete_after_ack=1', [], $this->createRedisMock())
6161
);
6262
}
6363

6464
public function testFromDsnWithOptionsAndTrailingSlash()
6565
{
6666
$this->assertEquals(
67-
Connection::fromDsn('redis://localhost/', ['stream' => 'queue', 'group' => 'group1', 'consumer' => 'consumer1', 'auto_setup' => false, 'serializer' => 2, 'delete_after_ack' => true], $this->createMock(\Redis::class)),
68-
Connection::fromDsn('redis://localhost/queue/group1/consumer1?serializer=2&auto_setup=0&delete_after_ack=1', [], $this->createMock(\Redis::class))
67+
Connection::fromDsn('redis://localhost/', ['stream' => 'queue', 'group' => 'group1', 'consumer' => 'consumer1', 'auto_setup' => false, 'serializer' => 2, 'delete_after_ack' => true], $this->createRedisMock()),
68+
Connection::fromDsn('redis://localhost/queue/group1/consumer1?serializer=2&auto_setup=0&delete_after_ack=1', [], $this->createRedisMock())
6969
);
7070
}
7171

@@ -79,6 +79,9 @@ public function testFromDsnWithTls()
7979
->method('connect')
8080
->with('tls://127.0.0.1', 6379)
8181
->willReturn(true);
82+
$redis->expects($this->any())
83+
->method('isConnected')
84+
->willReturnOnConsecutiveCalls(false, true);
8285

8386
Connection::fromDsn('redis://127.0.0.1?tls=1', [], $redis);
8487
}
@@ -93,6 +96,9 @@ public function testFromDsnWithTlsOption()
9396
->method('connect')
9497
->with('tls://127.0.0.1', 6379)
9598
->willReturn(true);
99+
$redis->expects($this->any())
100+
->method('isConnected')
101+
->willReturnOnConsecutiveCalls(false, true);
96102

97103
Connection::fromDsn('redis://127.0.0.1', ['tls' => true], $redis);
98104
}
@@ -104,6 +110,9 @@ public function testFromDsnWithRedissScheme()
104110
->method('connect')
105111
->with('tls://127.0.0.1', 6379)
106112
->willReturn(true);
113+
$redis->expects($this->any())
114+
->method('isConnected')
115+
->willReturnOnConsecutiveCalls(false, true);
107116

108117
Connection::fromDsn('rediss://127.0.0.1?delete_after_ack=true', [], $redis);
109118
}
@@ -116,21 +125,21 @@ public function testFromDsnWithQueryOptions()
116125
'port' => 6379,
117126
], [
118127
'serializer' => 2,
119-
], $this->createMock(\Redis::class)),
120-
Connection::fromDsn('redis://localhost/queue/group1/consumer1?serializer=2&delete_after_ack=1', [], $this->createMock(\Redis::class))
128+
], $this->createRedisMock()),
129+
Connection::fromDsn('redis://localhost/queue/group1/consumer1?serializer=2&delete_after_ack=1', [], $this->createRedisMock())
121130
);
122131
}
123132

124133
public function testFromDsnWithMixDsnQueryOptions()
125134
{
126135
$this->assertEquals(
127-
Connection::fromDsn('redis://localhost/queue/group1?serializer=2', ['consumer' => 'specific-consumer', 'delete_after_ack' => true], $this->createMock(\Redis::class)),
128-
Connection::fromDsn('redis://localhost/queue/group1/specific-consumer?serializer=2&delete_after_ack=1', [], $this->createMock(\Redis::class))
136+
Connection::fromDsn('redis://localhost/queue/group1?serializer=2', ['consumer' => 'specific-consumer', 'delete_after_ack' => true], $this->createRedisMock()),
137+
Connection::fromDsn('redis://localhost/queue/group1/specific-consumer?serializer=2&delete_after_ack=1', [], $this->createRedisMock())
129138
);
130139

131140
$this->assertEquals(
132-
Connection::fromDsn('redis://localhost/queue/group1/consumer1', ['consumer' => 'specific-consumer', 'delete_after_ack' => true], $this->createMock(\Redis::class)),
133-
Connection::fromDsn('redis://localhost/queue/group1/consumer1', ['delete_after_ack' => true], $this->createMock(\Redis::class))
141+
Connection::fromDsn('redis://localhost/queue/group1/consumer1', ['consumer' => 'specific-consumer', 'delete_after_ack' => true], $this->createRedisMock()),
142+
Connection::fromDsn('redis://localhost/queue/group1/consumer1', ['delete_after_ack' => true], $this->createRedisMock())
134143
);
135144
}
136145

@@ -140,7 +149,7 @@ public function testFromDsnWithMixDsnQueryOptions()
140149
public function testDeprecationIfInvalidOptionIsPassedWithDsn()
141150
{
142151
$this->expectDeprecation('Since symfony/messenger 5.1: Invalid option(s) "foo" passed to the Redis Messenger transport. Passing invalid options is deprecated.');
143-
Connection::fromDsn('redis://localhost/queue?foo=bar', [], $this->createMock(\Redis::class));
152+
Connection::fromDsn('redis://localhost/queue?foo=bar', [], $this->createRedisMock());
144153
}
145154

146155
public function testRedisClusterInstanceIsSupported()
@@ -151,7 +160,7 @@ public function testRedisClusterInstanceIsSupported()
151160

152161
public function testKeepGettingPendingMessages()
153162
{
154-
$redis = $this->createMock(\Redis::class);
163+
$redis = $this->createRedisMock();
155164

156165
$redis->expects($this->exactly(3))->method('xreadgroup')
157166
->with('symfony', 'consumer', ['queue' => 0], 1, 1)
@@ -170,7 +179,7 @@ public function testKeepGettingPendingMessages()
170179
*/
171180
public function testAuth($expected, string $dsn)
172181
{
173-
$redis = $this->createMock(\Redis::class);
182+
$redis = $this->createRedisMock();
174183

175184
$redis->expects($this->exactly(1))->method('auth')
176185
->with($expected)
@@ -190,7 +199,7 @@ public static function provideAuthDsn(): \Generator
190199

191200
public function testAuthFromOptions()
192201
{
193-
$redis = $this->createMock(\Redis::class);
202+
$redis = $this->createRedisMock();
194203

195204
$redis->expects($this->exactly(1))->method('auth')
196205
->with('password')
@@ -201,7 +210,7 @@ public function testAuthFromOptions()
201210

202211
public function testAuthFromOptionsAndDsn()
203212
{
204-
$redis = $this->createMock(\Redis::class);
213+
$redis = $this->createRedisMock();
205214

206215
$redis->expects($this->exactly(1))->method('auth')
207216
->with('password2')
@@ -212,7 +221,7 @@ public function testAuthFromOptionsAndDsn()
212221

213222
public function testNoAuthWithEmptyPassword()
214223
{
215-
$redis = $this->createMock(\Redis::class);
224+
$redis = $this->createRedisMock();
216225

217226
$redis->expects($this->exactly(0))->method('auth')
218227
->with('')
@@ -223,7 +232,7 @@ public function testNoAuthWithEmptyPassword()
223232

224233
public function testAuthZeroPassword()
225234
{
226-
$redis = $this->createMock(\Redis::class);
235+
$redis = $this->createRedisMock();
227236

228237
$redis->expects($this->exactly(1))->method('auth')
229238
->with('0')
@@ -236,7 +245,7 @@ public function testFailedAuth()
236245
{
237246
$this->expectException(\InvalidArgumentException::class);
238247
$this->expectExceptionMessage('Redis connection ');
239-
$redis = $this->createMock(\Redis::class);
248+
$redis = $this->createRedisMock();
240249

241250
$redis->expects($this->exactly(1))->method('auth')
242251
->with('password')
@@ -247,7 +256,7 @@ public function testFailedAuth()
247256

248257
public function testGetPendingMessageFirst()
249258
{
250-
$redis = $this->createMock(\Redis::class);
259+
$redis = $this->createRedisMock();
251260

252261
$redis->expects($this->exactly(1))->method('xreadgroup')
253262
->with('symfony', 'consumer', ['queue' => '0'], 1, 1)
@@ -269,7 +278,7 @@ public function testGetPendingMessageFirst()
269278

270279
public function testClaimAbandonedMessageWithRaceCondition()
271280
{
272-
$redis = $this->createMock(\Redis::class);
281+
$redis = $this->createRedisMock();
273282

274283
$redis->expects($this->exactly(3))->method('xreadgroup')
275284
->willReturnCallback(function (...$args) {
@@ -305,7 +314,7 @@ public function testClaimAbandonedMessageWithRaceCondition()
305314

306315
public function testClaimAbandonedMessage()
307316
{
308-
$redis = $this->createMock(\Redis::class);
317+
$redis = $this->createRedisMock();
309318

310319
$redis->expects($this->exactly(2))->method('xreadgroup')
311320
->willReturnCallback(function (...$args) {
@@ -341,7 +350,7 @@ public function testUnexpectedRedisError()
341350
{
342351
$this->expectException(TransportException::class);
343352
$this->expectExceptionMessage('Redis error happens');
344-
$redis = $this->createMock(\Redis::class);
353+
$redis = $this->createRedisMock();
345354
$redis->expects($this->once())->method('xreadgroup')->willReturn(false);
346355
$redis->expects($this->once())->method('getLastError')->willReturn('Redis error happens');
347356

@@ -351,7 +360,7 @@ public function testUnexpectedRedisError()
351360

352361
public function testMaxEntries()
353362
{
354-
$redis = $this->createMock(\Redis::class);
363+
$redis = $this->createRedisMock();
355364

356365
$redis->expects($this->exactly(1))->method('xadd')
357366
->with('queue', '*', ['message' => '{"body":"1","headers":[]}'], 20000, true)
@@ -363,7 +372,7 @@ public function testMaxEntries()
363372

364373
public function testDeleteAfterAck()
365374
{
366-
$redis = $this->createMock(\Redis::class);
375+
$redis = $this->createRedisMock();
367376

368377
$redis->expects($this->exactly(1))->method('xack')
369378
->with('queue', 'symfony', ['1'])
@@ -383,12 +392,12 @@ public function testLegacyOmitDeleteAfterAck()
383392
{
384393
$this->expectDeprecation('Since symfony/redis-messenger 5.4: Not setting the "delete_after_ack" boolean option explicitly is deprecated, its default value will change to true in 6.0.');
385394

386-
Connection::fromDsn('redis://localhost/queue', [], $this->createMock(\Redis::class));
395+
Connection::fromDsn('redis://localhost/queue', [], $this->createRedisMock(\Redis::class));
387396
}
388397

389398
public function testDeleteAfterReject()
390399
{
391-
$redis = $this->createMock(\Redis::class);
400+
$redis = $this->createRedisMock();
392401

393402
$redis->expects($this->exactly(1))->method('xack')
394403
->with('queue', 'symfony', ['1'])
@@ -403,7 +412,7 @@ public function testDeleteAfterReject()
403412

404413
public function testLastErrorGetsCleared()
405414
{
406-
$redis = $this->createMock(\Redis::class);
415+
$redis = $this->createRedisMock();
407416

408417
$redis->expects($this->once())->method('xadd')->willReturn('0');
409418
$redis->expects($this->once())->method('xack')->willReturn(0);
@@ -427,4 +436,17 @@ public function testLastErrorGetsCleared()
427436

428437
$this->assertSame('xack error', $e->getMessage());
429438
}
439+
440+
private function createRedisMock(): \Redis
441+
{
442+
$redis = $this->createMock(\Redis::class);
443+
$redis->expects($this->any())
444+
->method('connect')
445+
->willReturn(true);
446+
$redis->expects($this->any())
447+
->method('isConnected')
448+
->willReturnOnConsecutiveCalls(false, true);
449+
450+
return $redis;
451+
}
430452
}

src/Symfony/Component/Messenger/Bridge/Redis/Transport/Connection.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,21 @@ private static function initializeRedis(\Redis $redis, string $host, int $port,
121121
return $redis;
122122
}
123123

124-
$redis->connect($host, $port);
124+
@$redis->connect($host, $port);
125+
126+
$error = null;
127+
set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
128+
129+
try {
130+
$isConnected = $redis->isConnected();
131+
} finally {
132+
restore_error_handler();
133+
}
134+
135+
if (!$isConnected) {
136+
throw new InvalidArgumentException('Redis connection failed: '.(preg_match('/^Redis::p?connect\(\): (.*)/', $error ?? $redis->getLastError() ?? '', $matches) ? \sprintf(' (%s)', $matches[1]) : ''));
137+
}
138+
125139
$redis->setOption(\Redis::OPT_SERIALIZER, $serializer);
126140

127141
if (null !== $auth && !$redis->auth($auth)) {

0 commit comments

Comments
 (0)
0