static void
test_find_and_modify_opts (void)
{
   mock_server_t *server;
   mongoc_client_t *client;
   mongoc_collection_t *collection;
   bson_error_t error;
   mongoc_find_and_modify_opts_t *opts;
   future_t *future;
   request_t *request;

   server = mock_server_with_autoismaster (0);
   mock_server_run (server);

   client = mongoc_client_new_from_uri (mock_server_get_uri (server));
   collection = mongoc_client_get_collection (client, "db", "collection");

   opts = mongoc_find_and_modify_opts_new ();
   assert (mongoc_find_and_modify_opts_set_max_time_ms (opts, 42));
   assert (mongoc_find_and_modify_opts_append (opts, tmp_bson ("{'foo': 1}")));

   future = future_collection_find_and_modify_with_opts (
      collection, tmp_bson ("{}"), opts, NULL, &error);
   request = mock_server_receives_command (
      server, "db", MONGOC_QUERY_NONE,
      "{'findAndModify': 'collection', 'maxTimeMS': 42, 'foo': 1}");
   mock_server_replies_ok_and_destroys (request);
   ASSERT_OR_PRINT (future_get_bool (future), error);

   future_destroy (future);
   mongoc_find_and_modify_opts_destroy (opts);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
   mock_server_destroy (server);
}
Esempio n. 2
0
static bool
bulk_update_one (mongoc_bulk_operation_t *bulk,
                 bson_error_t *error,
                 bson_t *cmd)
{
   BSON_APPEND_UTF8 (cmd, "update", "collection");
   return mongoc_bulk_operation_update_one_with_opts (
      bulk, tmp_bson ("{}"), tmp_bson ("{}"), NULL, error);
}
Esempio n. 3
0
static void
_test_collection_find_with_opts (test_collection_find_with_opts_t *test_data)
{
   BSON_ASSERT (test_data->expected_find_command);

   test_data->filter_bson = tmp_bson (test_data->filter);
   test_data->opts_bson = tmp_bson (test_data->opts);

   _test_collection_op_query (test_data);
   _test_collection_find_command (test_data);
}
Esempio n. 4
0
static future_t *
update_one (func_ctx_t *ctx, bson_t *cmd)
{
   BSON_APPEND_UTF8 (cmd, "update", "collection");
   BSON_ASSERT (!ctx->prefs);
   return future_collection_update_one (ctx->collection,
                                        tmp_bson ("{}"),
                                        tmp_bson ("{}"),
                                        ctx->opts,
                                        NULL,
                                        &ctx->error);
}
/* test that we add readConcern only inside $query, not outside it too */
static void
test_mongos_read_concern (void)
{
   mock_server_t *server;
   mongoc_client_t *client;
   mongoc_collection_t *collection;
   mongoc_read_prefs_t *prefs;
   mongoc_cursor_t *cursor;
   const bson_t *doc;
   future_t *future;
   request_t *request;

   server = mock_mongos_new (WIRE_VERSION_READ_CONCERN);
   mock_server_run (server);
   client = mongoc_client_new_from_uri (mock_server_get_uri (server));
   collection = mongoc_client_get_collection (client, "test", "test");
   prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY);
   cursor = mongoc_collection_find_with_opts (
      collection,
      tmp_bson ("{'a': 1}"),
      tmp_bson ("{'readConcern': {'level': 'foo'}}"),
      prefs);

   future = future_cursor_next (cursor, &doc);
   request = mock_server_receives_command (
      server,
      "test",
      MONGOC_QUERY_SLAVE_OK,
      "{"
      "  '$query': {"
      "    'find': 'test', 'filter': {}, 'readConcern': {'level': 'foo'}"
      "  },"
      "  '$readPreference': {"
      "    'mode': 'secondary'"
      "  },"
      "  'readConcern': {'$exists': false}"
      "}");

   mock_server_replies_to_find (
      request, MONGOC_QUERY_SLAVE_OK, 0, 1, "db.collection", "{}", true);

   /* mongoc_cursor_next returned true */
   BSON_ASSERT (future_get_bool (future));

   request_destroy (request);
   future_destroy (future);
   mongoc_cursor_destroy (cursor);
   mongoc_read_prefs_destroy (prefs);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
   mock_server_destroy (server);
}
Esempio n. 6
0
static bool
bulk_insert (mongoc_bulk_operation_t *bulk, bson_error_t *error, bson_t *cmd)
{
   BSON_APPEND_UTF8 (cmd, "insert", "collection");
   return mongoc_bulk_operation_insert_with_opts (
      bulk, tmp_bson ("{}"), NULL, error);
}
Esempio n. 7
0
static future_t *
create_index (func_ctx_t *ctx, bson_t *cmd)
{
   BSON_APPEND_UTF8 (cmd, "createIndexes", "collection");
   return future_collection_create_index_with_opts (
      ctx->collection, tmp_bson ("{}"), NULL, ctx->opts, NULL, &ctx->error);
}
Esempio n. 8
0
static future_t *
db_write_cmd (func_ctx_t *ctx, bson_t *cmd)
{
   BSON_APPEND_UTF8 (cmd, "foo", "db");
   return future_database_write_command_with_opts (
      ctx->db, tmp_bson ("{'foo': 'db'}"), ctx->opts, NULL, &ctx->error);
}
static void
_test_op_msg (const mongoc_uri_t *uri,
              mock_server_t *server,
              const char *query_in,
              mongoc_read_prefs_t *read_prefs,
              const char *expected_op_msg)
{
   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_msg (server, 0, tmp_bson (expected_op_msg));
   mock_server_replies_simple (request,
                               "{'ok': 1,"
                               " 'cursor': {"
                               "    'id': 0,"
                               "    'ns': 'db.collection',"
                               "    'firstBatch': [{'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);
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
static bool
bulk_remove_many (mongoc_bulk_operation_t *bulk,
                  bson_error_t *error,
                  bson_t *cmd)
{
   BSON_APPEND_UTF8 (cmd, "delete", "collection");
   return mongoc_bulk_operation_remove_many_with_opts (
      bulk, tmp_bson ("{}"), NULL, error);
}
/* direct connection to a secondary requires read pref primaryPreferred to
 * avoid "not master" error from server */
static void
_test_op_msg_direct_connection (bool is_mongos,
                                test_op_msg_direct_fn_t fn,
                                const char *expected_cmd)
{
   mock_server_t *server;
   mongoc_client_t *client;
   mongoc_collection_t *collection;
   mongoc_read_prefs_t *prefs = NULL;
   mongoc_cursor_t *cursor;
   const bson_t *doc;
   bson_t *cmd;
   future_t *future;
   request_t *request;
   const char *reply;
   int i;

   if (is_mongos) {
      server = mock_mongos_new (WIRE_VERSION_OP_MSG);
   } else {
      server = mock_server_with_autoismaster (WIRE_VERSION_OP_MSG);
   }

   mock_server_auto_endsessions (server);

   mock_server_run (server);
   client = mongoc_client_new_from_uri (mock_server_get_uri (server));
   collection = mongoc_client_get_collection (client, "db", "collection");

   for (i = 0; i < 2; i++) {
      if (i == 1) {
         /* user-supplied read preference primary makes no difference */
         prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
      }

      cursor = fn (collection, prefs);
      future = future_cursor_next (cursor, &doc);
      cmd = tmp_bson (expected_cmd);
      request = mock_server_receives_msg (server, 0, cmd);
      reply = "{'ok': 1,"
              " 'cursor': {"
              "    'id': 0,"
              "    'ns': 'db.collection',"
              "    'firstBatch': [{'a': 1}]}}";

      mock_server_replies_simple (request, reply);
      BSON_ASSERT (future_get_bool (future));
      future_destroy (future);
      request_destroy (request);
      mongoc_cursor_destroy (cursor);
      mongoc_read_prefs_destroy (prefs); /* null ok */
   }

   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
   mock_server_destroy (server);
}
Esempio n. 13
0
static future_t *
find (func_ctx_t *ctx, bson_t *cmd)
{
   BSON_APPEND_UTF8 (cmd, "find", "collection");
   ctx->cursor = mongoc_collection_find_with_opts (
      ctx->collection, tmp_bson ("{}"), ctx->opts, ctx->prefs);

   /* use ctx->data as the bson_t** out-param to mongoc_cursor_next () */
   return future_cursor_next (ctx->cursor, (const bson_t **) &ctx->data);
}
Esempio n. 14
0
static void
test_exhaust (void)
{
   mock_server_t *server;
   mongoc_client_t *client;
   mongoc_collection_t *collection;
   mongoc_cursor_t *cursor;
   request_t *request;
   future_t *future;
   const bson_t *doc;
   bson_error_t error;

   server = mock_server_with_autoismaster (WIRE_VERSION_FIND_CMD);
   mock_server_run (server);
   client = mongoc_client_new_from_uri (mock_server_get_uri (server));
   collection = mongoc_client_get_collection (client, "db", "collection");
   cursor = mongoc_collection_find_with_opts (collection,
                                              tmp_bson (NULL),
                                              NULL,
                                              tmp_bson ("{'exhaust': true}"));

   future = future_cursor_next (cursor, &doc);

   /* Find, getMore and killCursors commands spec: "The find command does not
    * support the exhaust flag from OP_QUERY. Drivers that support exhaust MUST
    * fallback to existing OP_QUERY wire protocol messages."
    */
   request = mock_server_receives_request (server);
   mock_server_replies_to_find (
      request, MONGOC_QUERY_SLAVE_OK | MONGOC_QUERY_EXHAUST,
      0, 0, "db.collection", "{}", false /* is_command */);

   ASSERT (future_get_bool (future));
   ASSERT_OR_PRINT (!mongoc_cursor_error (cursor, &error), error);

   request_destroy (request);
   future_destroy (future);
   mongoc_cursor_destroy (cursor);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
   mock_server_destroy (server);
}
Esempio n. 15
0
static future_t *
collection_write_cmd (func_ctx_t *ctx, bson_t *cmd)
{
   BSON_APPEND_UTF8 (cmd, "foo", "collection");
   return future_collection_write_command_with_opts (
      ctx->collection,
      tmp_bson ("{'foo': 'collection'}"),
      ctx->opts,
      NULL,
      &ctx->error);
}
Esempio n. 16
0
static future_t *
count_documents (func_ctx_t *ctx, bson_t *cmd)
{
   BSON_APPEND_UTF8 (cmd, "aggregate", "collection");
   return future_collection_count_documents (ctx->collection,
                                             tmp_bson ("{}"),
                                             ctx->opts,
                                             ctx->prefs,
                                             NULL,
                                             &ctx->error);
}
Esempio n. 17
0
static void
_test_topology_events (bool pooled)
{
   mongoc_client_t *client;
   mongoc_client_pool_t *pool = NULL;
   context_t context;
   bool r;
   bson_error_t error;
   bson_iter_t events_iter;
   bson_iter_t event_iter;
   uint32_t i;

   context_init (&context);

   if (pooled) {
      pool = test_framework_client_pool_new ();
      pool_set_topology_event_callbacks (pool, &context);
      client = mongoc_client_pool_pop (pool);
   } else {
      client = test_framework_client_new ();
      client_set_topology_event_callbacks (client, &context);
   }

   r = mongoc_client_command_simple (client, "admin", tmp_bson ("{'ping': 1}"),
                                     NULL, NULL, &error);
   ASSERT_OR_PRINT (r, error);

   if (pooled) {
      mongoc_client_pool_push (pool, client);
      mongoc_client_pool_destroy (pool);
   } else {
      mongoc_client_destroy (client);
   }

   /* first event is topology opening */
   bson_iter_init (&events_iter, &context.events);
   bson_iter_next (&events_iter);
   ASSERT (bson_iter_recurse (&events_iter, &event_iter));
   ASSERT (bson_iter_find (&event_iter, "topology_opening_event"));

   /* last event is topology closed */
   for (i = 1; i < context.n_events; i++) {
      ASSERT (bson_iter_next (&events_iter));
   }

   ASSERT (bson_iter_recurse (&events_iter, &event_iter));
   ASSERT (bson_iter_find (&event_iter, "topology_closed_event"));

   /* no more events */
   ASSERT (!bson_iter_next (&events_iter));

   context_destroy (&context);
}
Esempio n. 18
0
static future_t *
client_read_cmd (func_ctx_t *ctx, bson_t *cmd)
{
   BSON_APPEND_INT32 (cmd, "foo", 1);
   return future_client_read_command_with_opts (ctx->client,
                                                "db",
                                                tmp_bson ("{'foo': 1}"),
                                                ctx->prefs,
                                                ctx->opts,
                                                NULL,
                                                &ctx->error);
}
Esempio n. 19
0
static future_t *
aggregate_raw_pipeline (func_ctx_t *ctx, bson_t *cmd)
{
   BSON_APPEND_UTF8 (cmd, "aggregate", "collection");
   ctx->cursor = mongoc_collection_aggregate (ctx->collection,
                                              MONGOC_QUERY_NONE,
                                              tmp_bson ("[{'$out': 'foo'}]"),
                                              ctx->opts,
                                              ctx->prefs);

   /* use ctx->data as the bson_t** out-param to mongoc_cursor_next () */
   return future_cursor_next (ctx->cursor, (const bson_t **) &ctx->data);
}
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);
}
Esempio n. 21
0
static future_t *
insert_many (func_ctx_t *ctx, bson_t *cmd)
{
   BSON_APPEND_UTF8 (cmd, "insert", "collection");
   BSON_ASSERT (!ctx->prefs);
   /* the "array" of input documents must be a valid pointer, stage it here */
   ctx->data = tmp_bson ("{}");
   return future_collection_insert_many (ctx->collection,
                                         (const bson_t **) &ctx->data,
                                         1,
                                         ctx->opts,
                                         NULL,
                                         &ctx->error);
}
Esempio n. 22
0
/* add BSON we expect to be included in a command due to an inherited option.
 * e.g., when "count" inherits readConcern from the DB, it should include
 * readConcern: {level: 'database'} in the command body. */
void
add_expected_opt (opt_source_t opt_source, opt_type_t opt_type, bson_t *cmd)
{
   const char *source_name;
   bson_t *opt;

   if (opt_source & OPT_SOURCE_FUNC) {
      source_name = "function";
   } else if (opt_source & OPT_SOURCE_COLL) {
      source_name = "collection";
   } else if (opt_source & OPT_SOURCE_DB) {
      source_name = "database";
   } else if (opt_source & OPT_SOURCE_CLIENT) {
      source_name = "client";
   } else {
      MONGOC_ERROR ("opt_json called with OPT_SOURCE_NONE");
      abort ();
   }

   switch (opt_type) {
   case OPT_READ_CONCERN:
      opt = tmp_bson ("{'readConcern': {'level': '%s'}}", source_name);
      break;
   case OPT_WRITE_CONCERN:
      opt = tmp_bson ("{'writeConcern': {'w': '%s'}}", source_name);
      break;
   case OPT_READ_PREFS:
      opt = tmp_bson (
         "{'$readPreference': {'mode': 'secondary', 'tags': [{'%s': 'yes'}]}}",
         source_name);
      break;
   default:
      abort ();
   }

   bson_concat (cmd, opt);
}
static void
test_write_concern_append (void)
{
   mongoc_write_concern_t *wc;
   bson_t *cmd;

   cmd = tmp_bson ("{'foo': 1}");
   capture_logs (true);

   /* cannot append invalid writeConcern */
   wc = NULL;
   assert (!mongoc_write_concern_append (wc, cmd));

   /* append valid writeConcern */
   wc = mongoc_write_concern_new ();
   mongoc_write_concern_set_w (wc, 1);
   assert (mongoc_write_concern_append (wc, cmd));

   ASSERT (match_bson (cmd,
                       tmp_bson ("{'foo': 1, 'writeConcern': {'w': 1}}"),
                       true));

   mongoc_write_concern_destroy (wc);
}
Esempio n. 24
0
static future_t *
find_and_modify (func_ctx_t *ctx, bson_t *cmd)
{
   mongoc_find_and_modify_opts_t *fam;

   BSON_APPEND_UTF8 (cmd, "findAndModify", "collection");
   fam = mongoc_find_and_modify_opts_new ();
   bson_concat (&fam->extra, ctx->opts);

   /* destroy the mongoc_find_and_modify_opts_t later */
   ctx->data = fam;
   ctx->destructor = find_and_modify_cleanup;

   return future_collection_find_and_modify_with_opts (
      ctx->collection, tmp_bson ("{}"), fam, NULL, &ctx->error);
}
Esempio n. 25
0
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);
}
Esempio n. 26
0
static void
test_topology_events_disabled (void)
{
   mongoc_client_t *client;
   context_t context;
   bool r;
   bson_error_t error;
   bson_iter_t events_iter;
   bson_iter_t event_iter;
   uint32_t i;

   context_init (&context);

   client = test_framework_client_new ();
   client_set_topology_event_callbacks (client, &context);

   r = mongoc_client_command_simple (
      client, "admin", tmp_bson ("{'ping': 1}"), NULL, NULL, &error);
   ASSERT_OR_PRINT (r, error);

   /* disable callbacks before destroying so we don't see a topology closed
    * event */
   mongoc_client_set_apm_callbacks (client, NULL, NULL);
   mongoc_client_destroy (client);

   /* first event is topology opening */
   bson_iter_init (&events_iter, &context.events);
   bson_iter_next (&events_iter);
   ASSERT (bson_iter_recurse (&events_iter, &event_iter));
   ASSERT (bson_iter_find (&event_iter, "topology_opening_event"));

   /* move forward to the last event */
   for (i = 1; i < context.n_events; i++) {
      ASSERT (bson_iter_next (&events_iter));
   }

   /* verify we didn't receive a topology closed event */
   ASSERT (bson_iter_recurse (&events_iter, &event_iter));
   ASSERT (!bson_iter_find (&event_iter, "topology_closed_event"));

   /* no more events */
   ASSERT (!bson_iter_next (&events_iter));

   context_destroy (&context);
}
static void
test_read_concern_append (void)
{
   mongoc_read_concern_t *rc;
   bson_t *cmd;

   cmd = tmp_bson ("{'foo': 1}");

   /* append default readConcern */
   rc = mongoc_read_concern_new ();
   ASSERT (mongoc_read_concern_is_default (rc));
   ASSERT_MATCH (cmd, "{'foo': 1, 'readConcern': {'$exists': false}}");

   /* append readConcern with level */
   mongoc_read_concern_set_level (rc, MONGOC_READ_CONCERN_LEVEL_LOCAL);
   ASSERT (mongoc_read_concern_append (rc, cmd));

   ASSERT_MATCH (cmd, "{'foo': 1, 'readConcern': {'level': 'local'}}");

   mongoc_read_concern_destroy (rc);
}
Esempio n. 28
0
static void
test_command_name (void)
{
   bson_t *commands[] = {
      tmp_bson ("{'foo': 1}"),
      tmp_bson ("{'query': {'foo': 1}}"),
      tmp_bson ("{'query': {'foo': 1}, '$readPreference': 1}"),
      tmp_bson ("{'$query': {'foo': 1}}"),
      tmp_bson ("{'$query': {'foo': 1}, '$readPreference': 1}"),
      tmp_bson ("{'$readPreference': 1, '$query': {'foo': 1}}"),
   };

   size_t i;

   for (i = 0; i < sizeof (commands) / sizeof (bson_t *); i++) {
      ASSERT_CMPSTR ("foo", _mongoc_get_command_name (commands[i]));
   }
}
Esempio n. 29
0
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);
}
static void
test_find_and_modify_collation (int wire)
{
   mock_server_t *server;
   mongoc_client_t *client;
   mongoc_collection_t *collection;
   bson_error_t error;
   mongoc_find_and_modify_opts_t *opts;
   future_t *future;
   request_t *request;
   bson_t *collation;

   server = mock_server_with_autoismaster (wire);
   mock_server_run (server);

   client = mongoc_client_new_from_uri (mock_server_get_uri (server));
   collection = mongoc_client_get_collection (client, "db", "collection");


   collation = BCON_NEW ("collation",
                         "{",
                         "locale",
                         BCON_UTF8 ("en_US"),
                         "caseFirst",
                         BCON_UTF8 ("lower"),
                         "}");
   opts = mongoc_find_and_modify_opts_new ();
   mongoc_find_and_modify_opts_append (opts, collation);

   if (wire >= WIRE_VERSION_COLLATION) {
      future = future_collection_find_and_modify_with_opts (
         collection, tmp_bson ("{}"), opts, NULL, &error);

      request = mock_server_receives_command (
         server,
         "db",
         MONGOC_QUERY_NONE,
         "{'findAndModify': 'collection',"
         " 'collation': { 'locale': 'en_US', 'caseFirst': 'lower'}"
         "}");
      mock_server_replies_ok_and_destroys (request);
      ASSERT_OR_PRINT (future_get_bool (future), error);
      future_destroy (future);
   } else {
      bool ok = mongoc_collection_find_and_modify_with_opts (
         collection, tmp_bson ("{}"), opts, NULL, &error);

      ASSERT_ERROR_CONTAINS (error,
                             MONGOC_ERROR_COMMAND,
                             MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION,
                             "The selected server does not support collation");
      ASSERT (!ok);
   }

   bson_destroy (collation);
   mongoc_find_and_modify_opts_destroy (opts);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);

   mock_server_destroy (server);
}