@@ -114,6 +114,163 @@ public function testConnectingFailsIfDnsUsesInvalidResolver()
114
114
Block \await ($ connector ->connect ('google.com:80 ' ), $ loop , self ::TIMEOUT );
115
115
}
116
116
117
+ public function testCancellingPendingConnectionWithoutTimeoutShouldNotCreateAnyGarbageReferences ()
118
+ {
119
+ if (class_exists ('React\Promise\When ' )) {
120
+ $ this ->markTestSkipped ('Not supported on legacy Promise v1 API ' );
121
+ }
122
+
123
+ $ loop = Factory::create ();
124
+ $ connector = new Connector ($ loop , array ('timeout ' => false ));
125
+
126
+ gc_collect_cycles ();
127
+ $ promise = $ connector ->connect ('8.8.8.8:80 ' );
128
+ $ promise ->cancel ();
129
+ unset($ promise );
130
+
131
+ $ this ->assertEquals (0 , gc_collect_cycles ());
132
+ }
133
+
134
+ public function testCancellingPendingConnectionShouldNotCreateAnyGarbageReferences ()
135
+ {
136
+ if (class_exists ('React\Promise\When ' )) {
137
+ $ this ->markTestSkipped ('Not supported on legacy Promise v1 API ' );
138
+ }
139
+
140
+ $ loop = Factory::create ();
141
+ $ connector = new Connector ($ loop );
142
+
143
+ gc_collect_cycles ();
144
+ $ promise = $ connector ->connect ('8.8.8.8:80 ' );
145
+ $ promise ->cancel ();
146
+ unset($ promise );
147
+
148
+ $ this ->assertEquals (0 , gc_collect_cycles ());
149
+ }
150
+
151
+ public function testWaitingForRejectedConnectionShouldNotCreateAnyGarbageReferences ()
152
+ {
153
+ if (class_exists ('React\Promise\When ' )) {
154
+ $ this ->markTestSkipped ('Not supported on legacy Promise v1 API ' );
155
+ }
156
+
157
+ $ loop = Factory::create ();
158
+ $ connector = new Connector ($ loop , array ('timeout ' => false ));
159
+
160
+ gc_collect_cycles ();
161
+
162
+ $ wait = true ;
163
+ $ promise = $ connector ->connect ('127.0.0.1:1 ' )->then (
164
+ null ,
165
+ function ($ e ) use (&$ wait ) {
166
+ $ wait = false ;
167
+ throw $ e ;
168
+ }
169
+ );
170
+
171
+ // run loop for short period to ensure we detect connection refused error
172
+ Block \sleep (0.01 , $ loop );
173
+ if ($ wait ) {
174
+ Block \sleep (0.2 , $ loop );
175
+ if ($ wait ) {
176
+ $ this ->fail ('Connection attempt did not fail ' );
177
+ }
178
+ }
179
+ unset($ promise );
180
+
181
+ $ this ->assertEquals (0 , gc_collect_cycles ());
182
+ }
183
+
184
+ /**
185
+ * @requires PHP 7
186
+ */
187
+ public function testWaitingForConnectionTimeoutShouldNotCreateAnyGarbageReferences ()
188
+ {
189
+ if (class_exists ('React\Promise\When ' )) {
190
+ $ this ->markTestSkipped ('Not supported on legacy Promise v1 API ' );
191
+ }
192
+
193
+ $ loop = Factory::create ();
194
+ $ connector = new Connector ($ loop , array ('timeout ' => 0.001 ));
195
+
196
+ gc_collect_cycles ();
197
+
198
+ $ wait = true ;
199
+ $ promise = $ connector ->connect ('google.com:80 ' )->then (
200
+ null ,
201
+ function ($ e ) use (&$ wait ) {
202
+ $ wait = false ;
203
+ throw $ e ;
204
+ }
205
+ );
206
+
207
+ // run loop for short period to ensure we detect connection timeout error
208
+ Block \sleep (0.01 , $ loop );
209
+ if ($ wait ) {
210
+ Block \sleep (0.2 , $ loop );
211
+ if ($ wait ) {
212
+ $ this ->fail ('Connection attempt did not fail ' );
213
+ }
214
+ }
215
+ unset($ promise );
216
+
217
+ $ this ->assertEquals (0 , gc_collect_cycles ());
218
+ }
219
+
220
+ public function testWaitingForInvalidDnsConnectionShouldNotCreateAnyGarbageReferences ()
221
+ {
222
+ if (class_exists ('React\Promise\When ' )) {
223
+ $ this ->markTestSkipped ('Not supported on legacy Promise v1 API ' );
224
+ }
225
+
226
+ $ loop = Factory::create ();
227
+ $ connector = new Connector ($ loop , array ('timeout ' => false ));
228
+
229
+ gc_collect_cycles ();
230
+
231
+ $ wait = true ;
232
+ $ promise = $ connector ->connect ('example.invalid:80 ' )->then (
233
+ null ,
234
+ function ($ e ) use (&$ wait ) {
235
+ $ wait = false ;
236
+ throw $ e ;
237
+ }
238
+ );
239
+
240
+ // run loop for short period to ensure we detect DNS error
241
+ Block \sleep (0.01 , $ loop );
242
+ if ($ wait ) {
243
+ Block \sleep (0.2 , $ loop );
244
+ if ($ wait ) {
245
+ $ this ->fail ('Connection attempt did not fail ' );
246
+ }
247
+ }
248
+ unset($ promise );
249
+
250
+ $ this ->assertEquals (0 , gc_collect_cycles ());
251
+ }
252
+
253
+ public function testWaitingForSuccessfullyClosedConnectionShouldNotCreateAnyGarbageReferences ()
254
+ {
255
+ if (class_exists ('React\Promise\When ' )) {
256
+ $ this ->markTestSkipped ('Not supported on legacy Promise v1 API ' );
257
+ }
258
+
259
+ $ loop = Factory::create ();
260
+ $ connector = new Connector ($ loop , array ('timeout ' => false ));
261
+
262
+ gc_collect_cycles ();
263
+ $ promise = $ connector ->connect ('google.com:80 ' )->then (
264
+ function ($ conn ) {
265
+ $ conn ->close ();
266
+ }
267
+ );
268
+ Block \await ($ promise , $ loop , self ::TIMEOUT );
269
+ unset($ promise );
270
+
271
+ $ this ->assertEquals (0 , gc_collect_cycles ());
272
+ }
273
+
117
274
public function testConnectingFailsIfTimeoutIsTooSmall ()
118
275
{
119
276
if (!function_exists ('stream_socket_enable_crypto ' )) {
0 commit comments