[CDRIVER-3667] slaveOk should not be set set for TopologyType=single for a standalone Created: 12/May/20  Updated: 10/Feb/23

Status: Backlog
Project: C Driver
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Kevin Albertson Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Epic Link: CDRIVER-2733

 Description   

The server selection spec section "Topology type: Single" says:

  • Type Standalone: clients MUST NOT send the read preference to the server
  • For all other types, using OP_QUERY: clients MUST always set the slaveOK wire
    protocol flag on reads to ensure that any server type can handle the request.

As observed in tests of CDRIVER-3498, libmongoc sets slaveOk for a standalone in topology type single, which seems to differ slightly from the spec. This may not be harmful (as we have not observed any bad behavior due to this) but is still a deviation.

Here is a repro test:

static bool _auto_ok (request_t *request, void* unused) {
   if (0 == strcmp (request->command_name, "isMaster")) {
      return false;
   }
   mock_server_replies_simple (request, "{'ok': 1}");
   return true;
}
 
static void
test_read_prefs_bugs (void) {
   mock_server_t *server;
   mongoc_client_t *client;
 
   mongoc_read_prefs_t *read_prefs_primary;
   mongoc_uri_t *uri;
   bson_error_t error;
   bool ret;
   mongoc_server_description_t *sd;
 
   read_prefs_primary = mongoc_read_prefs_new (MONGOC_READ_PRIMARY);
 
   MONGOC_DEBUG ("Testing standalone");
 
   /* Use OP_QUERY */
   server = mock_server_with_autoismaster (WIRE_VERSION_OP_MSG - 1);
   mock_server_run (server);
   mock_server_autoresponds (server, _auto_ok, NULL, NULL);
 
   uri = mongoc_uri_copy (mock_server_get_uri (server));
   mongoc_uri_set_option_as_bool (uri, MONGOC_URI_DIRECTCONNECTION, true);
   client = mongoc_client_new_from_uri (uri);
 
   /* Test a command with primary read preference. */
   MONGOC_DEBUG ("primary read prefs");
   ret = mongoc_client_command_simple (client, "admin", tmp_bson("{'ping': 1}"), read_prefs_primary, NULL, NULL);
 
   ASSERT_OR_PRINT (ret, error);
 
   sd = mongoc_client_select_server (client, false, NULL, &error);
   ASSERT (client->topology->description.type  == MONGOC_TOPOLOGY_SINGLE);
   ASSERT (sd->type == MONGOC_SERVER_STANDALONE);
 
   mongoc_read_prefs_destroy (read_prefs_primary);
   mongoc_server_description_destroy (sd);
   mock_server_destroy (server);
   mongoc_client_destroy (client);
}

Using the test environment variable MONGOC_TEST_SERVER_LOG=stdout, this shows the SLAVE_OK flag sent:

> MONGOC_TEST_SERVER_LOG=stdout ./cmake-build/src/libmongoc/test-libmongoc --no-fork -l /ReadPrefs/bugs -d
Begin /ReadPrefs/bugs, seed 3107453679
2020/05/11 13:35:35.0641: [23125]:    DEBUG:       mongoc: Testing standalone
listening on port 50677
2020/05/11 13:35:35.0644: [23125]:    DEBUG:       mongoc: primary read prefs
 0.01  50678 -> server port 50677 (connected)
 0.02  50678 -> 50677 OP_QUERY admin.$cmd { "isMaster" : 1, "client" : { "driver" : { "name" : "mongoc", "version" : "1.17.0-pre" }, "os" : { "type" : "Darwin", "name" : "macOS", "version" : "18.7.0", "architecture" : "x86_64" }, "platform" : "cfg=0x0280cea0e9 posix=200112 stdc=201112 CC=clang 9.0.0 (git://github.com/llvm/llvm-project.git 0399d5a9682b3cef71c653373e38890c63c4c365)" }, "compression" : [  ] } flags=SLAVE_OK n_return=-1
 0.02  50678 <- 50677 OP_REPLY { "ok" : 1.0, "ismaster" : true, "minWireVersion" : 0, "maxWireVersion" : 5 }
 0.02  50678 -> 50677 OP_QUERY admin.$cmd { "ping" : 1 } flags=SLAVE_OK n_return=-1
 0.02  50678 <- 50677 OP_REPLY { "ok" : 1 }


Generated at Wed Feb 07 21:18:42 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.