static bool hangup (request_t *request, void *ctx) { mock_server_hangs_up (request); request_destroy (request); return true; }
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_ok_and_destroys (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_ok_and_destroys (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); }
/* Test the case where we can't prevent the metadata doc being too big * and so we just don't send it */ static void test_mongoc_metadata_cannot_send (void) { mock_server_t *server; mongoc_uri_t *uri; mongoc_client_t *client; mongoc_client_pool_t *pool; request_t *request; const char *const server_reply = "{'ok': 1, 'ismaster': true}"; const bson_t *request_doc; char big_string[METADATA_MAX_SIZE]; mongoc_metadata_t *md; _reset_metadata (); /* Mess with our global metadata struct so the metadata doc will be * way too big */ memset (big_string, 'a', METADATA_MAX_SIZE - 1); big_string[METADATA_MAX_SIZE - 1] = '\0'; md = _mongoc_metadata_get (); bson_free (md->os_name); md->os_name = bson_strdup (big_string); server = mock_server_new (); mock_server_run (server); uri = mongoc_uri_copy (mock_server_get_uri (server)); mongoc_uri_set_option_as_int32 (uri, "heartbeatFrequencyMS", 500); pool = mongoc_client_pool_new (uri); /* Pop a client to trigger the topology scanner */ client = mongoc_client_pool_pop (pool); request = mock_server_receives_ismaster (server); /* Make sure the isMaster request DOESN'T have a metadata field: */ ASSERT (request); request_doc = request_get_doc (request, 0); ASSERT (request_doc); ASSERT (bson_has_field (request_doc, "isMaster")); ASSERT (!bson_has_field (request_doc, METADATA_FIELD)); mock_server_replies_simple (request, server_reply); request_destroy (request); /* Cause failure on client side */ request = mock_server_receives_ismaster (server); ASSERT (request); mock_server_hangs_up (request); request_destroy (request); /* Make sure the isMaster request still DOESN'T have a metadata field * on subsequent heartbeats. */ request = mock_server_receives_ismaster (server); ASSERT (request); request_doc = request_get_doc (request, 0); ASSERT (request_doc); ASSERT (bson_has_field (request_doc, "isMaster")); ASSERT (!bson_has_field (request_doc, METADATA_FIELD)); mock_server_replies_simple (request, server_reply); request_destroy (request); /* cleanup */ mongoc_client_pool_push (pool, client); mongoc_client_pool_destroy (pool); mongoc_uri_destroy (uri); mock_server_destroy (server); /* Reset again so the next tests don't have a metadata doc which * is too big */ _reset_metadata (); }