21
21
class PHPRedisMutexTest extends \PHPUnit_Framework_TestCase
22
22
{
23
23
/**
24
- * @var Redis The Redis API.
24
+ * @var Redis[]
25
25
*/
26
- private $ redis ;
27
-
26
+ private $ connections = [] ;
27
+
28
28
/**
29
29
* @var PHPRedisMutex The SUT.
30
30
*/
@@ -34,31 +34,53 @@ protected function setUp()
34
34
{
35
35
parent ::setUp ();
36
36
37
- $ this ->redis = new Redis ();
38
-
39
37
$ uris = explode (", " , getenv ("REDIS_URIS " ) ?: "redis://localhost " );
40
- $ uri = parse_url ($ uris [0 ]);
41
- if (!empty ($ uri ["port " ])) {
42
- $ this ->redis ->connect ($ uri ["host " ], $ uri ["port " ]);
43
- } else {
44
- $ this ->redis ->connect ($ uri ["host " ]);
38
+
39
+ foreach ($ uris as $ redisUri ) {
40
+ $ uri = parse_url ($ redisUri );
41
+
42
+ $ connection = new Redis ();
43
+
44
+ if (!empty ($ uri ["port " ])) {
45
+ $ connection ->connect ($ uri ["host " ], $ uri ["port " ]);
46
+ } else {
47
+ $ connection ->connect ($ uri ["host " ]);
48
+ }
49
+
50
+ $ connection ->flushAll (); // Clear any existing locks.
51
+
52
+ $ this ->connections [] = $ connection ;
45
53
}
46
54
47
- $ this ->redis ->flushAll (); // Clear any existing locks.
55
+ $ this ->mutex = new PHPRedisMutex ($ this ->connections , "test " );
56
+ }
57
+
58
+ private function closeMajorityConnections ()
59
+ {
60
+ $ numberToClose = ceil (count ($ this ->connections ) / 2 );
61
+
62
+ foreach (array_rand ($ this ->connections , $ numberToClose ) as $ keyToClose ) {
63
+ $ this ->connections [$ keyToClose ]->close ();
64
+ }
65
+ }
66
+
67
+ private function closeMinortyConnections ()
68
+ {
69
+ $ numberToClose = ceil (count ($ this ->connections ) / 2 ) - 1 ;
48
70
49
- $ this ->mutex = new PHPRedisMutex ([$ this ->redis ], "test " );
71
+ foreach ((array ) array_rand ($ this ->connections , $ numberToClose ) as $ keyToClose ) {
72
+ $ this ->connections [$ keyToClose ]->close ();
73
+ }
50
74
}
51
75
52
76
/**
53
- * Tests add() fails.
54
- *
55
- * @test
56
77
* @expectedException \malkusch\lock\exception\LockAcquireException
57
78
* @expectedExceptionCode \malkusch\lock\exception\MutexException::REDIS_NOT_ENOUGH_SERVERS
58
79
*/
59
80
public function testAddFails ()
60
81
{
61
- $ this ->redis ->close ();
82
+ $ this ->closeMajorityConnections ();
83
+
62
84
$ this ->mutex ->synchronized (function () {
63
85
$ this ->fail ("Code execution is not expected " );
64
86
});
@@ -73,21 +95,40 @@ public function testAddFails()
73
95
public function testEvalScriptFails ()
74
96
{
75
97
$ this ->mutex ->synchronized (function () {
76
- $ this ->redis -> close ();
98
+ $ this ->closeMajorityConnections ();
77
99
});
78
100
}
79
101
80
102
/**
81
103
* @param $serialization
82
104
* @dataProvider dpSerializationModes
83
105
*/
84
- public function testSyncronizedWorks ($ serialization )
106
+ public function testSynchronizedWorks ($ serialization )
85
107
{
86
- $ this ->redis ->setOption (Redis::OPT_SERIALIZER , $ serialization );
108
+ foreach ($ this ->connections as $ connection ) {
109
+ $ connection ->setOption (Redis::OPT_SERIALIZER , $ serialization );
110
+ }
87
111
88
- $ this ->mutex ->synchronized (function () {
89
- $ this ->assertTrue (true );
90
- });
112
+ $ this ->assertNull ($ this ->mutex ->synchronized (function () {
113
+ return null ;
114
+ }));
115
+ }
116
+
117
+ public function testResistantToPartialClusterFailuresForAcquiringLock ()
118
+ {
119
+ $ this ->closeMinortyConnections ();
120
+
121
+ $ this ->assertNull ($ this ->mutex ->synchronized (function () {
122
+ return null ;
123
+ }));
124
+ }
125
+
126
+ public function testResistantToPartialClusterFailuresForReleasingLock ()
127
+ {
128
+ $ this ->assertNull ($ this ->mutex ->synchronized (function () {
129
+ $ this ->closeMinortyConnections ();
130
+ return null ;
131
+ }));
91
132
}
92
133
93
134
public function dpSerializationModes ()
0 commit comments