20
20
21
21
import static org .junit .jupiter .api .Assertions .assertEquals ;
22
22
import static org .junit .jupiter .api .Assertions .assertFalse ;
23
+ import static org .junit .jupiter .api .Assertions .assertNull ;
23
24
import static org .junit .jupiter .api .Assertions .assertNotNull ;
24
25
import static org .junit .jupiter .api .Assertions .assertThrows ;
25
26
import static org .junit .jupiter .api .Assertions .assertTrue ;
@@ -215,19 +216,27 @@ public void run() {
215
216
216
217
/**
217
218
* Test concurrent operations, reconnects and close.
219
+ *
218
220
* Expected situation is nothing gets stuck.
221
+ *
222
+ * The test sets SO_LINGER to 0 for outgoing connections to avoid producing
223
+ * many TIME_WAIT sockets, because an available port range can be
224
+ * exhausted.
219
225
*/
220
226
@ Test
221
227
public void testLongParallelCloseReconnects () {
222
228
int numThreads = 4 ;
223
229
int numClients = 4 ;
224
230
int timeBudget = 30 *1000 ;
225
231
232
+ SocketChannelProvider provider = new TestSocketChannelProvider (host ,
233
+ port , RESTART_TIMEOUT ).setSoLinger (0 );
234
+
226
235
final AtomicReferenceArray <TarantoolClient > clients =
227
236
new AtomicReferenceArray <TarantoolClient >(numClients );
228
237
229
238
for (int idx = 0 ; idx < clients .length (); idx ++) {
230
- clients .set (idx , makeClient ());
239
+ clients .set (idx , makeClient (provider ));
231
240
}
232
241
233
242
final Random rnd = new Random ();
@@ -256,7 +265,7 @@ public void run() {
256
265
257
266
cli .close ();
258
267
259
- TarantoolClient next = makeClient ();
268
+ TarantoolClient next = makeClient (provider );
260
269
if (!clients .compareAndSet (idx , cli , next )) {
261
270
next .close ();
262
271
}
@@ -284,7 +293,9 @@ public void run() {
284
293
fail (e );
285
294
}
286
295
if (deadline > System .currentTimeMillis ()) {
287
- System .out .println ("" + (deadline - System .currentTimeMillis ())/1000 + "s remains." );
296
+ System .out .println ("testLongParallelCloseReconnects: " +
297
+ (deadline - System .currentTimeMillis ()) / 1000 +
298
+ "s remain" );
288
299
}
289
300
}
290
301
@@ -302,4 +313,46 @@ public void run() {
302
313
303
314
assertTrue (cnt .get () > threads .length );
304
315
}
316
+
317
+ /**
318
+ * Verify that we don't exceed a file descriptor limit (and so likely don't
319
+ * leak file descriptors) when trying to connect to an existing node with
320
+ * wrong authentification credentials.
321
+ *
322
+ * The test sets SO_LINGER to 0 for outgoing connections to avoid producing
323
+ * many TIME_WAIT sockets, because an available port range can be
324
+ * exhausted.
325
+ */
326
+ @ Test
327
+ public void testReconnectWrongAuth () throws Exception {
328
+ SocketChannelProvider provider = new TestSocketChannelProvider (host ,
329
+ port , RESTART_TIMEOUT ).setSoLinger (0 );
330
+ TarantoolClientConfig config = makeClientConfig ();
331
+ config .initTimeoutMillis = 100 ;
332
+ config .password = config .password + 'x' ;
333
+ for (int i = 0 ; i < 100 ; ++i ) {
334
+ if (i % 10 == 0 )
335
+ System .out .println ("testReconnectWrongAuth: " + (100 - i ) +
336
+ " iterations remain" );
337
+ CommunicationException e = assertThrows (CommunicationException .class ,
338
+ new Executable () {
339
+ @ Override
340
+ public void execute () throws Throwable {
341
+ client = new TarantoolClientImpl (provider , config );
342
+ }
343
+ }
344
+ );
345
+ assertEquals (e .getMessage (), "100ms is exceeded when waiting " +
346
+ "for client initialization. You could configure init " +
347
+ "timeout in TarantoolConfig" );
348
+ }
349
+
350
+ /*
351
+ * Verify we don't exceed a file descriptor limit. If we exceed it, a
352
+ * client will not able to connect to tarantool.
353
+ */
354
+ TarantoolClient client = makeClient ();
355
+ client .syncOps ().ping ();
356
+ client .close ();
357
+ }
305
358
}
0 commit comments