Skip to content

Commit e24dd09

Browse files
committed
CDRIVER-721 test reconnection
Also implement mock_server_quit.
1 parent c4ca642 commit e24dd09

File tree

4 files changed

+110
-27
lines changed

4 files changed

+110
-27
lines changed

tests/mock-server.c

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@ struct _mock_server_t
3737

3838
mongoc_thread_t main_thread;
3939
mongoc_cond_t cond;
40+
mongoc_cond_t stopped_condition;
4041
mongoc_mutex_t mutex;
4142
bool using_main_thread;
4243

4344
const char *address;
45+
mongoc_array_t streams; /* mongoc_stream_t pointers */
4446

4547
uint16_t port;
4648
mongoc_socket_t *sock;
@@ -55,6 +57,9 @@ struct _mock_server_t
5557

5658
const char *setName;
5759
const mongoc_host_list_t *hosts;
60+
61+
bool stopping;
62+
bool stopped;
5863
};
5964

6065

@@ -223,6 +228,7 @@ handle_command (mock_server_t *server,
223228
static void *
224229
mock_server_worker (void *data)
225230
{
231+
size_t streams_buffer_pos;
226232
mongoc_buffer_t buffer;
227233
mongoc_stream_t *stream;
228234
mock_server_t *server;
@@ -238,6 +244,11 @@ mock_server_worker (void *data)
238244
server = closure[0];
239245
stream = closure[1];
240246

247+
mongoc_mutex_lock (&server->mutex);
248+
streams_buffer_pos = server->streams.len;
249+
_mongoc_array_append_val (&server->streams, stream);
250+
mongoc_mutex_unlock (&server->mutex);
251+
241252
_mongoc_buffer_init(&buffer, NULL, 0, NULL, NULL);
242253

243254
again:
@@ -284,6 +295,15 @@ mock_server_worker (void *data)
284295
GOTO (again);
285296

286297
failure:
298+
mongoc_mutex_lock (&server->mutex);
299+
if (!server->stopping) {
300+
_mongoc_array_index (&server->streams,
301+
mongoc_stream_t *,
302+
streams_buffer_pos) = NULL;
303+
}
304+
305+
mongoc_mutex_unlock (&server->mutex);
306+
287307
mongoc_stream_close (stream);
288308
mongoc_stream_destroy (stream);
289309
bson_free(closure);
@@ -324,6 +344,7 @@ mock_server_new_rs (const char *address,
324344
server->handler = handler ? handler : dummy_handler;
325345
server->handler_data = handler_data;
326346
server->sock = NULL;
347+
_mongoc_array_init (&server->streams, sizeof (mongoc_stream_t *));
327348
server->address = address;
328349
server->port = port;
329350

@@ -338,6 +359,10 @@ mock_server_new_rs (const char *address,
338359

339360
mongoc_mutex_init (&server->mutex);
340361
mongoc_cond_init (&server->cond);
362+
mongoc_cond_init (&server->stopped_condition);
363+
364+
server->stopping = false;
365+
server->stopped = false;
341366

342367
return server;
343368
}
@@ -403,22 +428,31 @@ mock_server_run (mock_server_t *server)
403428
mongoc_mutex_unlock (&server->mutex);
404429

405430
for (;;) {
406-
csock = mongoc_socket_accept (server->sock, -1);
407-
if (!csock) {
408-
perror ("Failed to accept client socket");
431+
mongoc_mutex_lock (&server->mutex);
432+
if (server->stopping) {
433+
mongoc_mutex_unlock (&server->mutex);
409434
break;
410435
}
436+
mongoc_mutex_unlock (&server->mutex);
411437

412-
stream = mongoc_stream_socket_new (csock);
413-
closure = bson_malloc0 (sizeof(void*) * 2);
414-
closure[0] = server;
415-
closure[1] = stream;
438+
csock = mongoc_socket_accept (server->sock,
439+
bson_get_monotonic_time () + 1000 * 1000);
440+
if (csock) {
441+
stream = mongoc_stream_socket_new (csock);
442+
closure = bson_malloc0 (sizeof (void *) * 2);
443+
closure[0] = server;
444+
closure[1] = stream;
416445

417-
mongoc_thread_create (&thread, mock_server_worker, closure);
446+
mongoc_thread_create (&thread, mock_server_worker, closure);
447+
}
418448
}
419449

450+
mongoc_mutex_lock (&server->mutex);
420451
mongoc_socket_close (server->sock);
421452
server->sock = NULL;
453+
server->stopped = true;
454+
mongoc_cond_signal (&server->stopped_condition);
455+
mongoc_mutex_unlock (&server->mutex);
422456

423457
return 0;
424458
}
@@ -450,22 +484,36 @@ mock_server_run_in_thread (mock_server_t *server)
450484

451485

452486
void
453-
mock_server_quit (mock_server_t *server,
454-
int code)
487+
mock_server_quit (mock_server_t *server)
455488
{
489+
size_t i;
490+
mongoc_stream_t *stream;
491+
456492
bson_return_if_fail(server);
457493

458-
/*
459-
* TODO: Exit server loop.
460-
*/
494+
mongoc_mutex_lock (&server->mutex);
495+
assert (!server->stopping);
496+
assert (!server->stopped);
497+
server->stopping = true;
498+
assert (0 == mongoc_socket_close (server->sock)); /* success */
499+
for (i = 0; i < server->streams.len; i++) {
500+
stream = _mongoc_array_index (&server->streams, mongoc_stream_t *, i);
501+
if (stream) {
502+
assert (0 == mongoc_stream_close (stream)); /* success */
503+
}
504+
}
505+
mongoc_cond_wait (&server->stopped_condition, &server->mutex);
506+
mongoc_mutex_unlock (&server->mutex);
461507
}
462508

463509

464510
void
465511
mock_server_destroy (mock_server_t *server)
466512
{
467513
if (server) {
514+
_mongoc_array_destroy (&server->streams);
468515
mongoc_cond_destroy (&server->cond);
516+
mongoc_cond_destroy (&server->stopped_condition);
469517
mongoc_mutex_destroy (&server->mutex);
470518
bson_free(server);
471519
}

tests/mock-server.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ void mock_server_reply_simple (mock_server_t *server,
5858
const bson_t *doc);
5959
int mock_server_run (mock_server_t *server);
6060
void mock_server_run_in_thread (mock_server_t *server);
61-
void mock_server_quit (mock_server_t *server,
62-
int code);
61+
void mock_server_quit (mock_server_t *server);
6362
void mock_server_destroy (mock_server_t *server);
6463

6564

tests/test-mongoc-client.c

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ test_wire_version (void)
231231

232232
mongoc_cursor_destroy (cursor);
233233
mongoc_collection_destroy (collection);
234-
mock_server_quit (server, 0);
234+
mock_server_quit (server);
235235
mongoc_client_destroy (client);
236236
bson_free (uristr);
237237
}
@@ -373,7 +373,7 @@ test_mongoc_client_read_prefs (void)
373373
mongoc_cursor_destroy (cursor);
374374
mongoc_collection_destroy (collection);
375375
mongoc_client_destroy (client);
376-
mock_server_quit (server, 0);
376+
mock_server_quit (server);
377377
bson_destroy (&b);
378378
bson_free (uristr);
379379
}
@@ -504,10 +504,17 @@ test_unavailable_seeds(void)
504504
}
505505

506506

507+
typedef enum {
508+
NO_CONNECT,
509+
CONNECT,
510+
RECONNECT
511+
} connection_option_t;
512+
513+
507514
/* CDRIVER-721 catch errors in _mongoc_cluster_destroy */
508515
static void
509516
test_seed_list (bool rs,
510-
bool connect)
517+
connection_option_t connection_option)
511518
{
512519
uint16_t port;
513520
char *uri_str;
@@ -531,7 +538,7 @@ test_seed_list (bool rs,
531538

532539
mock_server_run_in_thread (server);
533540

534-
for (i = 0; i < 10; i++) {
541+
for (i = 0; i < 12; i++) {
535542
suppress_one_message ();
536543
}
537544

@@ -542,12 +549,25 @@ test_seed_list (bool rs,
542549
assert (client->cluster.nodes[i].valid);
543550
}
544551

545-
if (connect) {
552+
expected_nodes_len = rs ? 1 : 4;
553+
554+
if (connection_option != NO_CONNECT) {
546555
/* only localhost:port responds, nodes_len is set to 1 */
547556
assert (_mongoc_client_warm_up (client, &error));
548557

549558
/* a mongos load-balanced connection never removes down nodes */
550-
expected_nodes_len = rs ? 1 : 4;
559+
ASSERT_CMPINT (expected_nodes_len, ==, client->cluster.nodes_len);
560+
for (i = 0; i < expected_nodes_len; i++) {
561+
assert (client->cluster.nodes[i].valid);
562+
}
563+
}
564+
565+
if (connection_option == RECONNECT) {
566+
for (i = 0; i < 12; i++) {
567+
suppress_one_message ();
568+
}
569+
570+
assert (_mongoc_cluster_reconnect (&client->cluster, &error));
551571
ASSERT_CMPINT (expected_nodes_len, ==, client->cluster.nodes_len);
552572
for (i = 0; i < expected_nodes_len; i++) {
553573
assert (client->cluster.nodes[i].valid);
@@ -557,7 +577,7 @@ test_seed_list (bool rs,
557577
/* testing for crashes like CDRIVER-721 */
558578
mongoc_client_destroy (client);
559579

560-
mock_server_quit (server, 0);
580+
mock_server_quit (server);
561581
mock_server_destroy (server);
562582
mongoc_uri_destroy (uri);
563583
bson_free (uri_str);
@@ -567,28 +587,42 @@ test_seed_list (bool rs,
567587
static void
568588
test_rs_seeds_no_connect (void)
569589
{
570-
test_seed_list (true, false);
590+
test_seed_list (true, NO_CONNECT);
571591
}
572592

573593

574594
static void
575595
test_rs_seeds_connect (void)
576596
{
577-
test_seed_list (true, true);
597+
test_seed_list (true, CONNECT);
598+
}
599+
600+
601+
static void
602+
test_rs_seeds_reconnect (void)
603+
{
604+
test_seed_list (true, RECONNECT);
578605
}
579606

580607

581608
static void
582609
test_mongos_seeds_no_connect (void)
583610
{
584-
test_seed_list (false, false);
611+
test_seed_list (false, NO_CONNECT);
585612
}
586613

587614

588615
static void
589616
test_mongos_seeds_connect (void)
590617
{
591-
test_seed_list (false, true);
618+
test_seed_list (false, CONNECT);
619+
}
620+
621+
622+
static void
623+
test_mongos_seeds_reconnect (void)
624+
{
625+
test_seed_list (false, RECONNECT);
592626
}
593627

594628

@@ -833,8 +867,10 @@ test_client_install (TestSuite *suite)
833867
TestSuite_Add (suite, "/Client/unavailable_seeds", test_unavailable_seeds);
834868
TestSuite_Add (suite, "/Client/rs_seeds_no_connect", test_rs_seeds_no_connect);
835869
TestSuite_Add (suite, "/Client/rs_seeds_connect", test_rs_seeds_connect);
870+
TestSuite_Add (suite, "/Client/rs_seeds_reconnect", test_rs_seeds_reconnect);
836871
TestSuite_Add (suite, "/Client/mongos_seeds_no_connect", test_mongos_seeds_no_connect);
837872
TestSuite_Add (suite, "/Client/mongos_seeds_connect", test_mongos_seeds_connect);
873+
TestSuite_Add (suite, "/Client/mongos_seeds_reconnect", test_mongos_seeds_reconnect);
838874
TestSuite_Add (suite, "/Client/exhaust_cursor", test_exhaust_cursor);
839875
TestSuite_Add (suite, "/Client/server_status", test_server_status);
840876
}

tests/test-mongoc-database.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ test_get_collection_names_error (void)
441441

442442
mongoc_database_destroy (database);
443443
mongoc_client_destroy (client);
444-
mock_server_quit (server, 0);
444+
mock_server_quit (server);
445445
bson_destroy (&b);
446446
bson_free (uristr);
447447
}

0 commit comments

Comments
 (0)