Skip to content

Commit 6b0efaf

Browse files
committed
[redis] Add unit and func tests, fix bugs.
1 parent ea9676c commit 6b0efaf

14 files changed

+745
-231
lines changed

Diff for: PRedis.php

+18-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ public function lpush($key, $value)
3737
public function brpop($key, $timeout)
3838
{
3939
try {
40-
return $this->brpop($key, (int) $timeout / 1000);
40+
if ($result = $this->redis->brpop($key, $timeout)) {
41+
return $result[1];
42+
}
4143
} catch (PRedisServerException $e) {
4244
throw new ServerException('brpop command has failed', null, $e);
4345
}
@@ -48,19 +50,33 @@ public function brpop($key, $timeout)
4850
*/
4951
public function rpop($key)
5052
{ try {
51-
return $this->rpop($key);
53+
return $this->redis->rpop($key);
5254
} catch (PRedisServerException $e) {
5355
throw new ServerException('rpop command has failed', null, $e);
5456
}
5557
}
5658

59+
/**
60+
* {@inheritdoc}
61+
*/
5762
public function connect()
5863
{
5964
$this->redis->connect();
6065
}
6166

67+
/**
68+
* {@inheritdoc}
69+
*/
6270
public function disconnect()
6371
{
6472
$this->redis->disconnect();
6573
}
74+
75+
/**
76+
* {@inheritdoc}
77+
*/
78+
public function del($key)
79+
{
80+
$this->redis->del([$key]);
81+
}
6682
}

Diff for: PhpRedis.php

+15-4
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,10 @@ class PhpRedis implements Redis
1414
private $config;
1515

1616
/**
17-
* @param \Redis $redis
1817
* @param array $config
1918
*/
20-
public function __construct(\Redis $redis, array $config)
19+
public function __construct(array $config)
2120
{
22-
$this->redis = $redis;
23-
2421
$this->config = array_replace([
2522
'host' => null,
2623
'port' => null,
@@ -59,6 +56,9 @@ public function rpop($key)
5956
return $this->redis->rPop($key);
6057
}
6158

59+
/**
60+
* {@inheritdoc}
61+
*/
6262
public function connect()
6363
{
6464
if (false == $this->redis) {
@@ -84,10 +84,21 @@ public function connect()
8484
return $this->redis;
8585
}
8686

87+
/**
88+
* {@inheritdoc}
89+
*/
8790
public function disconnect()
8891
{
8992
if ($this->redis) {
9093
$this->redis->close();
9194
}
9295
}
96+
97+
/**
98+
* {@inheritdoc}
99+
*/
100+
public function del($key)
101+
{
102+
$this->redis->del($key);
103+
}
93104
}

Diff for: Redis.php

+5
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,9 @@ public function rpop($key);
2929
public function connect();
3030

3131
public function disconnect();
32+
33+
/**
34+
* @param string $key
35+
*/
36+
public function del($key);
3237
}

Diff for: RedisConnectionFactory.php

+10-9
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,7 @@ public function createContext()
6363
{
6464
if ($this->config['lazy']) {
6565
return new RedisContext(function () {
66-
$redis = $this->createRedis();
67-
$redis->connect();
68-
69-
return $redis;
66+
return $this->createRedis();
7067
});
7168
}
7269

@@ -78,12 +75,16 @@ public function createContext()
7875
*/
7976
private function createRedis()
8077
{
81-
if ('phpredis' == $this->config['vendor'] && false == $this->redis) {
82-
$this->redis = new PhpRedis(new \Redis(), $this->config);
83-
}
78+
if (false == $this->redis) {
79+
if ('phpredis' == $this->config['vendor'] && false == $this->redis) {
80+
$this->redis = new PhpRedis($this->config);
81+
}
82+
83+
if ('predis' == $this->config['vendor'] && false == $this->redis) {
84+
$this->redis = new PRedis(new Client($this->config, ['exceptions' => true]));
85+
}
8486

85-
if ('predis' == $this->config['vendor'] && false == $this->redis) {
86-
$this->redis = new PRedis(new Client($this->config, ['exceptions' => true]));
87+
$this->redis->connect();
8788
}
8889

8990
return $this->redis;

Diff for: RedisContext.php

+23-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
use Enqueue\Psr\InvalidDestinationException;
66
use Enqueue\Psr\PsrContext;
77
use Enqueue\Psr\PsrDestination;
8+
use Enqueue\Psr\PsrQueue;
9+
use Enqueue\Psr\PsrTopic;
810

911
class RedisContext implements PsrContext
1012
{
@@ -68,6 +70,26 @@ public function createQueue($queueName)
6870
return new RedisDestination($queueName);
6971
}
7072

73+
/**
74+
* @param RedisDestination|PsrQueue $queue
75+
*/
76+
public function deleteQueue(PsrQueue $queue)
77+
{
78+
InvalidDestinationException::assertDestinationInstanceOf($queue, RedisDestination::class);
79+
80+
$this->getRedis()->del($queue->getName());
81+
}
82+
83+
/**
84+
* @param RedisDestination|PsrTopic $topic
85+
*/
86+
public function deleteTopic(PsrTopic $topic)
87+
{
88+
InvalidDestinationException::assertDestinationInstanceOf($topic, RedisDestination::class);
89+
90+
$this->getRedis()->del($topic->getName());
91+
}
92+
7193
/**
7294
* {@inheritdoc}
7395
*/
@@ -102,7 +124,7 @@ public function createConsumer(PsrDestination $destination)
102124

103125
public function close()
104126
{
105-
$this->getRedis()->close();
127+
$this->getRedis()->disconnect();
106128
}
107129

108130
/**

Diff for: Tests/Functional/CommonUseCasesTrait.php

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<?php
2+
3+
namespace Enqueue\Redis\Tests\Functional;
4+
5+
use Enqueue\Redis\RedisContext;
6+
use Enqueue\Redis\RedisMessage;
7+
8+
trait CommonUseCasesTrait
9+
{
10+
public function testWaitsForTwoSecondsAndReturnNullOnReceive()
11+
{
12+
$queue = $this->getContext()->createQueue('enqueue.test_queue');
13+
14+
$startAt = microtime(true);
15+
16+
$consumer = $this->getContext()->createConsumer($queue);
17+
$message = $consumer->receive(2000);
18+
19+
$endAt = microtime(true);
20+
21+
$this->assertNull($message);
22+
23+
$this->assertGreaterThan(1.5, $endAt - $startAt);
24+
$this->assertLessThan(2.5, $endAt - $startAt);
25+
}
26+
27+
public function testReturnNullImmediatelyOnReceiveNoWait()
28+
{
29+
$queue = $this->getContext()->createQueue('enqueue.test_queue');
30+
31+
$startAt = microtime(true);
32+
33+
$consumer = $this->getContext()->createConsumer($queue);
34+
$message = $consumer->receiveNoWait();
35+
36+
$endAt = microtime(true);
37+
38+
$this->assertNull($message);
39+
40+
$this->assertLessThan(0.5, $endAt - $startAt);
41+
}
42+
43+
public function testProduceAndReceiveOneMessageSentDirectlyToQueue()
44+
{
45+
$queue = $this->getContext()->createQueue('enqueue.test_queue');
46+
47+
$message = $this->getContext()->createMessage(
48+
__METHOD__,
49+
['FooProperty' => 'FooVal'],
50+
['BarHeader' => 'BarVal']
51+
);
52+
53+
$producer = $this->getContext()->createProducer();
54+
$producer->send($queue, $message);
55+
56+
$consumer = $this->getContext()->createConsumer($queue);
57+
$message = $consumer->receive(1000);
58+
59+
$this->assertInstanceOf(RedisMessage::class, $message);
60+
$consumer->acknowledge($message);
61+
62+
$this->assertEquals(__METHOD__, $message->getBody());
63+
$this->assertEquals(['FooProperty' => 'FooVal'], $message->getProperties());
64+
$this->assertEquals(['BarHeader' => 'BarVal'], $message->getHeaders());
65+
}
66+
67+
public function testProduceAndReceiveOneMessageSentDirectlyToTopic()
68+
{
69+
$topic = $this->getContext()->createTopic('enqueue.test_topic');
70+
71+
$message = $this->getContext()->createMessage(__METHOD__);
72+
73+
$producer = $this->getContext()->createProducer();
74+
$producer->send($topic, $message);
75+
76+
$consumer = $this->getContext()->createConsumer($topic);
77+
$message = $consumer->receive(1000);
78+
79+
$this->assertInstanceOf(RedisMessage::class, $message);
80+
$consumer->acknowledge($message);
81+
82+
$this->assertEquals(__METHOD__, $message->getBody());
83+
}
84+
85+
public function testConsumerReceiveMessageWithZeroTimeout()
86+
{
87+
$topic = $this->getContext()->createTopic('enqueue.test_topic');
88+
89+
$consumer = $this->getContext()->createConsumer($topic);
90+
91+
//guard
92+
$this->assertNull($consumer->receive(1000));
93+
94+
$message = $this->getContext()->createMessage(__METHOD__);
95+
96+
$producer = $this->getContext()->createProducer();
97+
$producer->send($topic, $message);
98+
usleep(100);
99+
$actualMessage = $consumer->receive(0);
100+
101+
$this->assertInstanceOf(RedisMessage::class, $actualMessage);
102+
$consumer->acknowledge($message);
103+
104+
$this->assertEquals(__METHOD__, $message->getBody());
105+
}
106+
107+
public function testShouldReceiveMessagesInExpectedOrder()
108+
{
109+
$queue = $this->getContext()->createQueue('enqueue.test_queue');
110+
111+
$producer = $this->getContext()->createProducer();
112+
$producer->send($queue, $this->getContext()->createMessage(1));
113+
$producer->send($queue, $this->getContext()->createMessage(2));
114+
$producer->send($queue, $this->getContext()->createMessage(3));
115+
116+
$consumer = $this->getContext()->createConsumer($queue);
117+
118+
$this->assertSame(1, $consumer->receiveNoWait()->getBody());
119+
$this->assertSame(2, $consumer->receiveNoWait()->getBody());
120+
$this->assertSame(3, $consumer->receiveNoWait()->getBody());
121+
}
122+
123+
/**
124+
* @return RedisContext
125+
*/
126+
abstract protected function getContext();
127+
}

Diff for: Tests/Functional/PRedisCommonUseCasesTest.php

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Enqueue\Redis\Tests\Functional;
4+
5+
use Enqueue\Redis\RedisContext;
6+
use Enqueue\Test\RedisExtension;
7+
use PHPUnit\Framework\TestCase;
8+
9+
/**
10+
* @group functional
11+
*/
12+
class PRedisCommonUseCasesTest extends TestCase
13+
{
14+
use RedisExtension;
15+
use CommonUseCasesTrait;
16+
17+
/**
18+
* @var RedisContext
19+
*/
20+
private $context;
21+
22+
public function setUp()
23+
{
24+
$this->context = $this->buildPRedisContext();
25+
26+
$this->context->deleteQueue($this->context->createQueue('enqueue.test_queue'));
27+
$this->context->deleteTopic($this->context->createTopic('enqueue.test_topic'));
28+
}
29+
30+
public function tearDown()
31+
{
32+
$this->context->close();
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
protected function getContext()
39+
{
40+
return $this->context;
41+
}
42+
}

Diff for: Tests/Functional/PhpRedisCommonUseCasesTest.php

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Enqueue\Redis\Tests\Functional;
4+
5+
use Enqueue\Redis\RedisContext;
6+
use Enqueue\Test\RedisExtension;
7+
use PHPUnit\Framework\TestCase;
8+
9+
/**
10+
* @group functional
11+
*/
12+
class PhpRedisCommonUseCasesTest extends TestCase
13+
{
14+
use RedisExtension;
15+
use CommonUseCasesTrait;
16+
17+
/**
18+
* @var RedisContext
19+
*/
20+
private $context;
21+
22+
public function setUp()
23+
{
24+
$this->context = $this->buildPhpRedisContext();
25+
26+
$this->context->deleteQueue($this->context->createQueue('enqueue.test_queue'));
27+
$this->context->deleteTopic($this->context->createTopic('enqueue.test_topic'));
28+
}
29+
30+
public function tearDown()
31+
{
32+
$this->context->close();
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
protected function getContext()
39+
{
40+
return $this->context;
41+
}
42+
}

0 commit comments

Comments
 (0)