@@ -21,19 +21,24 @@ class MemcachedAdapterTest extends AdapterTestCase
21
21
'testDefaultLifeTime ' => 'Testing expiration slows down the test suite ' ,
22
22
);
23
23
24
- private static $ client ;
24
+ protected static $ client ;
25
+
26
+ protected static function getClientDefaultServer ()
27
+ {
28
+ return sprintf (
29
+ 'memcached://%s:%d ' ,
30
+ getenv ('MEMCACHED_HOST ' ) ?: '127.0.0.1 ' ,
31
+ getenv ('MEMCACHED_PORT ' ) ?: 11211
32
+ );
33
+ }
25
34
26
35
public static function setupBeforeClass ()
27
36
{
28
37
if (!MemcachedAdapter::isSupported ()) {
29
38
self ::markTestSkipped ('Extension memcached >=2.2.0 required. ' );
30
39
}
31
40
32
- self ::$ client = new \Memcached ();
33
- self ::$ client ->addServers (array (array (
34
- getenv ('MEMCACHED_HOST ' ) ?: '127.0.0.1 ' ,
35
- getenv ('MEMCACHED_PORT ' ) ?: 11211 ,
36
- )));
41
+ static ::$ client = static ::getClientFromAdapter (MemcachedAdapter::create (static ::getClientDefaultServer ()));
37
42
38
43
parent ::setupBeforeClass ();
39
44
}
@@ -47,4 +52,170 @@ public function testIsSupported()
47
52
{
48
53
$ this ->assertTrue (MemcachedAdapter::isSupported ());
49
54
}
55
+
56
+ public function testIgnoreDuplicateServerRegistrations ()
57
+ {
58
+ $ client = static ::getClientFromAdapter ($ adapter = MemcachedAdapter::create (null ));
59
+
60
+ $ this ->assertCount (0 , $ client ->getServerList (), 'Passing "null" DSN should result in no registered servers. ' );
61
+
62
+ for ($ i = 0 ; $ i < 5 ; ++$ i ) {
63
+ $ adapter ->setup (array (static ::getClientDefaultServer ()));
64
+ $ this ->assertCount (1 , $ client ->getServerList (), 'Duplicate server registrations should be ignored. ' );
65
+ }
66
+ }
67
+
68
+ /**
69
+ * @dataProvider provideValidServerConfigData
70
+ */
71
+ public function testValidServerConfig ($ dsn )
72
+ {
73
+ $ servers = static ::getClientFromAdapter (MemcachedAdapter::create ($ dsn ))->getServerList ();
74
+
75
+ $ this ->assertCount (1 , $ servers ,
76
+ sprintf ('Passed DSN should result in single server registration matching "%s". ' , $ dsn ));
77
+
78
+ $ params = parse_url ($ dsn );
79
+ $ server = $ servers [0 ];
80
+
81
+ $ this ->assertSame ($ server ['host ' ], isset ($ params ['host ' ]) ? $ params ['host ' ] : '127.0.0.1 ' ,
82
+ sprintf ('Registered server should match host from passed DSN "%s". ' , $ dsn ));
83
+ $ this ->assertSame ($ server ['port ' ], isset ($ params ['port ' ]) ? $ params ['port ' ] : 11211 ,
84
+ sprintf ('Registered server should match port from passed DSN "%s". ' , $ dsn ));
85
+ }
86
+
87
+ public function provideValidServerConfigData ()
88
+ {
89
+ $ data = array (
90
+ array ('memcached: ' ),
91
+ array ('memcached:?weight=50 ' ),
92
+ array ('memcached://127.0.0.1 ' ),
93
+ array ('memcached://127.0.0.1:11211 ' ),
94
+ array ('memcached://127.0.0.1?weight=50 ' ),
95
+ array ('memcached://127.0.0.1:11211?weight=50 ' ),
96
+ array ('memcached://127.0.0.1:11211?weight=50&extra-query=is-ignored ' ),
97
+ );
98
+
99
+ for ($ i = 1 ; $ i <= 65535 ; $ i = $ i + random_int (8000 , 12000 )) {
100
+ $ data [] = array (sprintf ('memcached://127.0.0.1:%d ' , $ i ));
101
+ $ data [] = array (sprintf ('memcached://127.0.0.1:11211?weight=%d ' , max (floor (100 * $ i / 65535 ), 1 )));
102
+ }
103
+
104
+ return $ data ;
105
+ }
106
+
107
+ /**
108
+ * @dataProvider provideNotValidServerConfigData
109
+ * @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException
110
+ * @expectedExceptionMessageRegExp {Invalid Memcached DSN:}
111
+ */
112
+ public function testNotValidServerConfig ($ dsn )
113
+ {
114
+ MemcachedAdapter::create ($ dsn );
115
+ }
116
+
117
+ public function provideNotValidServerConfigData ()
118
+ {
119
+ $ data = array (
120
+ array ('http://google.com/?bad-scheme=wont+work ' ),
121
+ array (
'redis://[email protected] /13 ' ),
122
+ );
123
+
124
+ for ($ i = 1 ; $ i <= 5 ; ++$ i ) {
125
+ $ data [] = array (sprintf ('http://%1$d.%1$d.%1$d.%1$d ' , random_int (255 , 2550 )));
126
+ $ data [] = array (sprintf ('http://%1$d.%1$d.%1$d.%1$d ' , random_int (-2550 , 0 )));
127
+ $ data [] = array (sprintf ('%s://127.0.0.1 ' , str_repeat (chr (random_int (97 , 122 )), random_int (1 , 10 ))));
128
+ }
129
+
130
+ for ($ i = 65536 ; $ i < 65535 * 2 ; $ i = $ i + random_int (8000 , 12000 )) {
131
+ $ data [] = array (sprintf ('memcached://127.0.0.1:%d ' , $ i ));
132
+ }
133
+
134
+ return $ data ;
135
+ }
136
+
137
+ /**
138
+ * @dataProvider provideValidServerOptionsData
139
+ */
140
+ public function testValidServerOptions ($ assignments , $ constants , $ expectations , $ messages )
141
+ {
142
+ $ client = static ::getClientFromAdapter (MemcachedAdapter::create (null , $ assignments ));
143
+
144
+ for ($ i = 0 ; $ i < count ($ assignments ); ++$ i ) {
145
+ $ this ->assertSame ($ expectations [$ i ], $ client ->getOption ($ constants [$ i ]), $ messages [$ i ]);
146
+ }
147
+ }
148
+
149
+ public function provideValidServerOptionsData ()
150
+ {
151
+ $ expectationCollection = array (1 , true , \Memcached::SERIALIZER_IGBINARY , 30 );
152
+ $ expectsAltsCollection = array (true , 1 , 'SERIALIZER_IGBINARY ' , '30 ' );
153
+
154
+ $ constantStrCollection = array ('OPT_LIBKETAMA_COMPATIBLE ' , 'OPT_COMPRESSION ' , 'OPT_SERIALIZER ' , 'OPT_RETRY_TIMEOUT ' );
155
+ $ constantIntCollection = array (\Memcached::OPT_LIBKETAMA_COMPATIBLE , \Memcached::OPT_COMPRESSION , \Memcached::OPT_SERIALIZER , \Memcached::OPT_RETRY_TIMEOUT );
156
+
157
+ $ messages = array ();
158
+ for ($ i = 0 ; $ i < count ($ expectationCollection ); ++$ i ) {
159
+ $ messages [] = sprintf ('Memcached client option "%s:%d" expected value "%s:%s". ' , $ constantStrCollection [$ i ],
160
+ $ constantIntCollection [$ i ], gettype ($ expectationCollection [$ i ]), var_export ($ expectationCollection [$ i ], true ));
161
+ }
162
+
163
+ $ assignmentSet = array (
164
+ array (
165
+ $ constantStrCollection [0 ] => $ expectationCollection [0 ], // unresolved constant type string and resolved constant value
166
+ $ constantStrCollection [1 ] => $ expectationCollection [1 ], // unresolved constant type string and resolved constant value
167
+ $ constantStrCollection [2 ] => $ expectationCollection [2 ], // unresolved constant type string and resolved constant value
168
+ $ constantStrCollection [3 ] => $ expectationCollection [3 ], // unresolved constant type string and resolved constant value
169
+ ),
170
+ array (
171
+ $ constantIntCollection [0 ] => $ expectationCollection [0 ], // resolved constant type and resolved constant value
172
+ $ constantIntCollection [1 ] => $ expectationCollection [1 ], // resolved constant type and resolved constant value
173
+ $ constantIntCollection [2 ] => $ expectationCollection [2 ], // resolved constant type and resolved constant value
174
+ $ constantIntCollection [3 ] => $ expectationCollection [3 ], // resolved constant type and resolved constant value
175
+ ),
176
+ array (
177
+ $ constantIntCollection [0 ] => $ expectsAltsCollection [0 ], // resolved constant type and equivalent constant value "true" to expected "1"
178
+ $ constantStrCollection [1 ] => $ expectsAltsCollection [1 ], // unresolved constant type string and equivalent constant value "1" to expected "true"
179
+ $ constantIntCollection [2 ] => $ expectsAltsCollection [2 ], // resolved constant type and unresolved constant value string
180
+ $ constantStrCollection [3 ] => $ expectsAltsCollection [3 ], // unresolved constant type string and equivalent constant value "string:30" to expected "int:30"
181
+ ),
182
+ );
183
+
184
+ return array_map (function ($ assignments ) use ($ constantIntCollection , $ expectationCollection , $ messages ) {
185
+ return array ($ assignments , $ constantIntCollection , $ expectationCollection , $ messages );
186
+ }, $ assignmentSet );
187
+ }
188
+
189
+ /**
190
+ * @dataProvider provideInvalidServerOptionsData
191
+ * @expectedException \PHPUnit_Framework_Error_Warning
192
+ */
193
+ public function testInvalidServerOptions (array $ options )
194
+ {
195
+ if (defined ('HHVM_VERSION ' )) {
196
+ $ this ->markTestSkipped ('HHVM ext-memcached silently ignores invalid passed options. ' );
197
+ }
198
+
199
+ MemcachedAdapter::create (null , $ options );
200
+ }
201
+
202
+ public function provideInvalidServerOptionsData ()
203
+ {
204
+ return array (
205
+ array (array (-10000000 => 'OPT_DISTRIBUTION ' )),
206
+ array (array ('OPT_SERIALIZER ' => 'OPT_DISTRIBUTION ' )),
207
+ );
208
+ }
209
+
210
+ /**
211
+ * @return \Memcached
212
+ */
213
+ private static function getClientFromAdapter (MemcachedAdapter $ adapter )
214
+ {
215
+ $ r = new \ReflectionObject ($ adapter );
216
+ $ p = $ r ->getProperty ('client ' );
217
+ $ p ->setAccessible (true );
218
+
219
+ return $ p ->getValue ($ adapter );
220
+ }
50
221
}
0 commit comments