#include "test.h" #include "mongo.h" #include #include #include "libmongo-private.h" void test_mongo_sync_reconnect (void) { mongo_sync_connection *conn, *o; GList *l; ok (mongo_sync_reconnect (NULL, FALSE) == NULL, "mongo_sync_reconnect() fails with a NULL connection"); cmp_ok (errno, "==", ENOTCONN, "errno is ENOTCONN"); conn = test_make_fake_sync_conn (-1, FALSE); ok (mongo_sync_reconnect (conn, FALSE) == NULL, "mongo_sync_reconnect() fails with a bogus FD"); cmp_ok (errno, "==", EHOSTUNREACH, "errno is EHOSTUNREACH"); mongo_sync_disconnect (conn); begin_network_tests (15); /* Connect & reconnect to master */ o = conn = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); ok ((conn = mongo_sync_reconnect (conn, TRUE)) != NULL, "mongo_sync_reconnect() works when reconnecting to self"); ok (o == conn, "Reconnect to an existing master results in the same object"); mongo_sync_disconnect (conn); /* Connect to master, kill FD, reconnect */ conn = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); mongo_sync_cmd_is_master (conn); shutdown (conn->super.fd, SHUT_RDWR); sleep (3); ok ((conn = mongo_sync_reconnect (conn, TRUE)) != NULL, "mongo_sync_reconnect() succeed when the connection drops"); mongo_sync_disconnect (conn); /* Connect, kill, reconnect; w/o knowing other hosts */ o = conn = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); shutdown (conn->super.fd, SHUT_RDWR); sleep (3); l = conn->rs.hosts; while (l) { g_free (l->data); l = g_list_delete_link (l, l); } conn->rs.hosts = NULL; l = conn->rs.seeds; while (l) { g_free (l->data); l = g_list_delete_link (l, l); } conn->rs.seeds = NULL; conn = mongo_sync_reconnect (conn, FALSE); ok (conn != o && conn == NULL, "mongo_sync_reconnect() fails if it can't reconnect anywhere"); mongo_sync_disconnect (o); /* Gracefully ignore unparsable hosts during reconnect */ o = conn = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); mongo_sync_cmd_is_master (conn); conn->rs.hosts = g_list_prepend (conn->rs.hosts, g_strdup ("invalid:-42")); shutdown (conn->super.fd, SHUT_RDWR); sleep (3); conn = mongo_sync_reconnect (conn, TRUE); ok (conn == o, "mongo_sync_reconnect() gracefully ignores unparsable hosts " "during reconnect"); mongo_sync_disconnect (conn); /* Ignore unreachable hosts during reconnect */ o = conn = mongo_sync_connect (config.primary_host, config.primary_port, TRUE); mongo_sync_cmd_is_master (conn); conn->rs.hosts = g_list_prepend (conn->rs.hosts, g_strdup ("example.com:27017")); shutdown (conn->super.fd, SHUT_RDWR); sleep (3); conn = mongo_sync_reconnect (conn, TRUE); ok (conn == o, "mongo_sync_reconnect() gracefully ignores unparsable hosts " "during reconnect"); mongo_sync_disconnect (conn); /* * Tests involving a secondary */ skip (!config.secondary_host, 9, "Secondary host not set up"); /* Connect to secondary & reconnect to master */ o = conn = mongo_sync_connect (config.secondary_host, config.secondary_port, TRUE); ok (conn != NULL, "Connecting to secondary"); ok (mongo_sync_cmd_is_master (conn) == FALSE, "Connected to a secondary"); ok ((conn = mongo_sync_reconnect (conn, TRUE)) != NULL, "Reconnecting from slave to master succeeds"); ok (conn == o, "Connection object updated in-place"); ok (mongo_sync_cmd_is_master (conn), "Correctly reconnected to master"); mongo_sync_disconnect (conn); /* Connect to secondary & reconnect to self */ o = conn = mongo_sync_connect (config.secondary_host, config.secondary_port, TRUE); ok (conn != NULL, "Connecting to secondary"); ok ((conn = mongo_sync_reconnect (conn, FALSE)) != NULL, "Reconnecting from slave to self succeeds"); ok (conn == o, "Connection object updated in-place"); ok (mongo_sync_cmd_is_master (conn) == FALSE, "Correctly reconnected to self"); mongo_sync_disconnect (conn); endskip; end_network_tests (); } RUN_TEST (19, mongo_sync_reconnect);