static void _test_find_command (const mongoc_uri_t *uri, mock_server_t *server, const char *query_in, mongoc_read_prefs_t *read_prefs, mongoc_query_flags_t expected_find_cmd_query_flags, const char *expected_find_cmd) { mongoc_client_t *client; mongoc_collection_t *collection; mongoc_cursor_t *cursor; const bson_t *doc; bson_t b = BSON_INITIALIZER; future_t *future; request_t *request; client = mongoc_client_new_from_uri (uri); collection = mongoc_client_get_collection (client, "test", "test"); mongoc_collection_set_read_prefs (collection, read_prefs); cursor = mongoc_collection_find (collection, MONGOC_QUERY_NONE, 0, 1, 0, tmp_bson (query_in), NULL, read_prefs); future = future_cursor_next (cursor, &doc); request = mock_server_receives_command ( server, "test", expected_find_cmd_query_flags, expected_find_cmd); mock_server_replies (request, MONGOC_REPLY_NONE, /* flags */ 0, /* cursorId */ 0, /* startingFrom */ 1, /* numberReturned */ "{'ok': 1," " 'cursor': {" " 'id': 0," " 'ns': 'db.collection'," " 'firstBatch': [{'a': 1}]}}"); /* mongoc_cursor_next returned true */ assert (future_get_bool (future)); request_destroy (request); future_destroy (future); mongoc_cursor_destroy (cursor); mongoc_collection_destroy (collection); mongoc_client_destroy (client); bson_destroy (&b); }
static void _test_op_query (const mongoc_uri_t *uri, mock_server_t *server, const char *query_in, mongoc_read_prefs_t *read_prefs, mongoc_query_flags_t expected_query_flags, const char *expected_query) { mongoc_client_t *client; mongoc_collection_t *collection; mongoc_cursor_t *cursor; const bson_t *doc; bson_t b = BSON_INITIALIZER; future_t *future; request_t *request; client = mongoc_client_new_from_uri (uri); collection = mongoc_client_get_collection (client, "test", "test"); cursor = mongoc_collection_find (collection, MONGOC_QUERY_NONE, 0, 1, 0, tmp_bson (query_in), NULL, read_prefs); future = future_cursor_next (cursor, &doc); request = mock_server_receives_query ( server, "test.test", expected_query_flags, 0, 1, expected_query, NULL); mock_server_replies (request, MONGOC_REPLY_NONE, /* flags */ 0, /* cursorId */ 0, /* startingFrom */ 1, /* numberReturned */ "{'a': 1}"); /* mongoc_cursor_next returned true */ BSON_ASSERT (future_get_bool (future)); request_destroy (request); future_destroy (future); mongoc_cursor_destroy (cursor); mongoc_collection_destroy (collection); mongoc_client_destroy (client); bson_destroy (&b); }
void mock_server_replies_to_find (request_t *request, mongoc_query_flags_t flags, int64_t cursor_id, int32_t number_returned, const char *ns, const char *reply_json, bool is_command) { char *find_reply; char db[MONGOC_NAMESPACE_MAX]; _mongoc_get_db_name (ns, db); /* minimal validation, we're not testing query / find cmd here */ if (request->is_command && !is_command) { MONGOC_ERROR ("expected query, got command"); abort (); } if (!request->is_command && is_command) { MONGOC_ERROR ("expected command, got query"); abort (); } if (!request_matches_flags (request, flags)) { abort (); } if (is_command) { find_reply = bson_strdup_printf ( "{'ok': 1," " 'cursor': {" " 'id': {'$numberLong': '%" PRId64 "'}," " 'ns': '%s'," " 'firstBatch': [%s]}}", cursor_id, ns, reply_json); mock_server_replies_simple (request, find_reply); bson_free (find_reply); } else { mock_server_replies (request, MONGOC_REPLY_NONE, cursor_id, 0, number_returned, reply_json); } }
static void _test_command_simple (const mongoc_uri_t *uri, mock_server_t *server, const char *command, mongoc_read_prefs_t *read_prefs, mongoc_query_flags_t expected_query_flags, const char *expected_query) { mongoc_client_t *client; mongoc_collection_t *collection; bson_t b = BSON_INITIALIZER; future_t *future; request_t *request; client = mongoc_client_new_from_uri (uri); collection = mongoc_client_get_collection (client, "test", "test"); mongoc_collection_set_read_prefs (collection, read_prefs); future = future_client_command_simple (client, "test", tmp_bson (command), read_prefs, NULL, NULL); request = mock_server_receives_command ( server, "test", expected_query_flags, expected_query); mock_server_replies (request, MONGOC_REPLY_NONE, /* flags */ 0, /* cursorId */ 0, /* startingFrom */ 1, /* numberReturned */ "{'ok': 1}"); /* mongoc_cursor_next returned true */ assert (future_get_bool (future)); request_destroy (request); future_destroy (future); mongoc_collection_destroy (collection); mongoc_client_destroy (client); bson_destroy (&b); }
static bool auto_ismaster (request_t *request, void *data) { const char *response_json = (const char *) data; char *quotes_replaced; bson_t response; bson_error_t error; if (!request->is_command || strcasecmp (request->command_name, "ismaster")) { return false; } quotes_replaced = single_quotes_to_double (response_json); if (!bson_init_from_json (&response, quotes_replaced, -1, &error)) { fprintf (stderr, "%s\n", error.message); fflush (stderr); abort (); } if (mock_server_get_rand_delay (request->server)) { _mongoc_usleep ((int64_t) (rand () % 10) * 1000); } mock_server_replies (request, MONGOC_REPLY_NONE, 0, 0, 1, response_json); bson_destroy (&response); bson_free (quotes_replaced); request_destroy (request); return true; }
void mock_server_replies_ok_and_destroys (request_t *request) { mock_server_replies (request, MONGOC_REPLY_NONE, 0, 0, 1, "{'ok': 1}"); request_destroy (request); }
void mock_server_replies_simple (request_t *request, const char *docs_json) { mock_server_replies (request, MONGOC_REPLY_NONE, 0, 0, 1, docs_json); }
static void _test_heartbeat_events (bool pooled, bool succeeded) { context_t context; mock_server_t *server; mongoc_uri_t *uri; mongoc_client_t *client; mongoc_client_pool_t *pool = NULL; future_t *future; request_t *request; char *expected_json; bson_error_t error; context_init (&context); /* auto-respond to "foo" command */ server = mock_server_new (); mock_server_run (server); mock_server_autoresponds (server, responder, NULL, NULL); uri = mongoc_uri_copy (mock_server_get_uri (server)); mongoc_uri_set_option_as_int32 (uri, "serverSelectionTimeoutMS", 400); if (pooled) { pool = mongoc_client_pool_new (uri); pool_set_heartbeat_event_callbacks (pool, &context); client = mongoc_client_pool_pop (pool); } else { client = mongoc_client_new_from_uri (uri); client_set_heartbeat_event_callbacks (client, &context); } /* trigger "ismaster" handshake */ future = future_client_command_simple ( client, "admin", tmp_bson ("{'foo': 1}"), NULL, NULL, &error); /* topology scanner calls ismaster once */ request = mock_server_receives_ismaster (server); if (succeeded) { mock_server_replies ( request, MONGOC_REPLY_NONE, 0, 0, 1, "{'ok': 1, 'minWireVersion': 2, 'maxWireVersion': 5}"); request_destroy (request); } else { mock_server_hangs_up (request); request_destroy (request); } /* pooled client opens new socket, handshakes it by calling ismaster again */ if (pooled && succeeded) { request = mock_server_receives_ismaster (server); mock_server_replies ( request, MONGOC_REPLY_NONE, 0, 0, 1, "{'ok': 1, 'minWireVersion': 2, 'maxWireVersion': 5}"); request_destroy (request); } if (succeeded) { /* "foo" command succeeds */ ASSERT_OR_PRINT (future_get_bool (future), error); } else { ASSERT (!future_get_bool (future)); } if (pooled) { mongoc_client_pool_push (pool, client); mongoc_client_pool_destroy (pool); } else { mongoc_client_destroy (client); } /* even if pooled, only topology scanner sends events, so we get one pair */ if (succeeded) { expected_json = bson_strdup_printf ( "{'0': {'heartbeat_started_event': {'host': '%s'}}," " '1': {'heartbeat_succeeded_event': {'host': '%s'}}}", mock_server_get_host_and_port (server), mock_server_get_host_and_port (server)); } else { expected_json = bson_strdup_printf ( "{'0': {'heartbeat_started_event': {'host': '%s'}}," " '1': {'heartbeat_failed_event': {'host': '%s'}}}", mock_server_get_host_and_port (server), mock_server_get_host_and_port (server)); } check_json_apm_events (&context.events, tmp_bson (expected_json)); future_destroy (future); bson_free (expected_json); mongoc_uri_destroy (uri); mock_server_destroy (server); context_destroy (&context); }
void mock_server_replies_simple (request_t *request, const char *docs_json) { mock_server_replies (request, 0, 0, 0, 1, docs_json); }