|
1 | 1 | #include <mongoc.h>
|
2 | 2 |
|
3 |
| -#include "mongoc-topology-scanner-private.h" |
| 3 | +#include "mongoc-util-private.h" |
| 4 | +#include "mongoc-client-private.h" |
| 5 | + |
4 | 6 | #include "mongoc-tests.h"
|
5 | 7 | #include "TestSuite.h"
|
6 | 8 | #include "mock_server/mock-server.h"
|
| 9 | +#include "mock_server/future.h" |
| 10 | +#include "mock_server/future-functions.h" |
7 | 11 |
|
8 | 12 | #undef MONGOC_LOG_DOMAIN
|
9 | 13 | #define MONGOC_LOG_DOMAIN "topology-scanner-test"
|
@@ -125,11 +129,172 @@ test_topology_scanner_ssl ()
|
125 | 129 | #endif
|
126 | 130 |
|
127 | 131 |
|
| 132 | +/* |
| 133 | + * Servers discovered by a scan should be checked during that scan, CDRIVER-751. |
| 134 | + */ |
| 135 | +void |
| 136 | +test_topology_scanner_discovery () |
| 137 | +{ |
| 138 | + mock_server_t *primary; |
| 139 | + mock_server_t *secondary; |
| 140 | + char *primary_response; |
| 141 | + char *secondary_response; |
| 142 | + mongoc_client_t *client; |
| 143 | + mongoc_topology_scanner_t *scanner; |
| 144 | + char *uri_str; |
| 145 | + mongoc_read_prefs_t *primary_pref; |
| 146 | + bson_error_t error; |
| 147 | + future_t *future; |
| 148 | + request_t *request; |
| 149 | + mongoc_server_description_t *sd; |
| 150 | + |
| 151 | + primary = mock_server_new (); |
| 152 | + secondary = mock_server_new (); |
| 153 | + mock_server_run (primary); |
| 154 | + mock_server_run (secondary); |
| 155 | + |
| 156 | + primary_response = bson_strdup_printf ( |
| 157 | + "{'ok': 1, " |
| 158 | + " 'ismaster': true," |
| 159 | + " 'setName': 'rs'," |
| 160 | + " 'hosts': ['%s', '%s']}", |
| 161 | + mock_server_get_host_and_port (primary), |
| 162 | + mock_server_get_host_and_port (secondary)); |
| 163 | + |
| 164 | + secondary_response = bson_strdup_printf ( |
| 165 | + "{'ok': 1, " |
| 166 | + " 'ismaster': false," |
| 167 | + " 'secondary': true," |
| 168 | + " 'setName': 'rs'," |
| 169 | + " 'hosts': ['%s', '%s']}", |
| 170 | + mock_server_get_host_and_port (primary), |
| 171 | + mock_server_get_host_and_port (secondary)); |
| 172 | + |
| 173 | + uri_str = bson_strdup_printf ("mongodb://%s/?replicaSet=rs", |
| 174 | + mock_server_get_host_and_port (primary)); |
| 175 | + client = mongoc_client_new (uri_str); |
| 176 | + scanner = client->topology->scanner; |
| 177 | + primary_pref = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); |
| 178 | + |
| 179 | + future = future_topology_select (client->topology, MONGOC_SS_READ, |
| 180 | + primary_pref, 15, &error); |
| 181 | + |
| 182 | + /* a single scan discovers *and* checks the secondary */ |
| 183 | + request = mock_server_receives_ismaster (primary); |
| 184 | + mock_server_replies_simple (request, primary_response); |
| 185 | + request_destroy (request); |
| 186 | + |
| 187 | + /* let client process that response */ |
| 188 | + _mongoc_usleep (250 * 1000); |
| 189 | + |
| 190 | + /* a check of the secondary is scheduled in this scan */ |
| 191 | + AWAIT (scanner->async->ncmds); |
| 192 | + |
| 193 | + request = mock_server_receives_ismaster (secondary); |
| 194 | + mock_server_replies_simple (request, secondary_response); |
| 195 | + /* scan completes */ |
| 196 | + AWAIT (!scanner->async->ncmds); |
| 197 | + ASSERT_OR_PRINT ((sd = future_get_mongoc_server_description_ptr (future)), |
| 198 | + error); |
| 199 | + |
| 200 | + mongoc_server_description_destroy (sd); |
| 201 | + request_destroy (request); |
| 202 | + mongoc_read_prefs_destroy (primary_pref); |
| 203 | + bson_free (secondary_response); |
| 204 | + bson_free (primary_response); |
| 205 | + bson_free (uri_str); |
| 206 | + mongoc_client_destroy (client); |
| 207 | + mock_server_destroy (secondary); |
| 208 | + mock_server_destroy (primary); |
| 209 | +} |
| 210 | + |
| 211 | + |
| 212 | +/* |
| 213 | + * Check that scanner doesn't spinlock if two primaries point at each other. |
| 214 | + */ |
| 215 | +void |
| 216 | +test_topology_scanner_oscillate () |
| 217 | +{ |
| 218 | + mock_server_t *server0; |
| 219 | + mock_server_t *server1; |
| 220 | + char *server0_response; |
| 221 | + char *server1_response; |
| 222 | + mongoc_client_t *client; |
| 223 | + mongoc_topology_scanner_t *scanner; |
| 224 | + char *uri_str; |
| 225 | + mongoc_read_prefs_t *primary_pref; |
| 226 | + bson_error_t error; |
| 227 | + future_t *future; |
| 228 | + request_t *request; |
| 229 | + |
| 230 | + server0 = mock_server_new (); |
| 231 | + server1 = mock_server_new (); |
| 232 | + mock_server_run (server0); |
| 233 | + mock_server_run (server1); |
| 234 | + |
| 235 | + /* server 0 says it's primary, but only server 1 is in the set */ |
| 236 | + server0_response = bson_strdup_printf ( |
| 237 | + "{'ok': 1, " |
| 238 | + " 'ismaster': true," |
| 239 | + " 'setName': 'rs'," |
| 240 | + " 'hosts': ['%s']}", |
| 241 | + mock_server_get_host_and_port (server1)); |
| 242 | + |
| 243 | + /* the opposite */ |
| 244 | + server1_response = bson_strdup_printf ( |
| 245 | + "{'ok': 1, " |
| 246 | + " 'ismaster': true," |
| 247 | + " 'setName': 'rs'," |
| 248 | + " 'hosts': ['%s']}", |
| 249 | + mock_server_get_host_and_port (server0)); |
| 250 | + |
| 251 | + /* start with server 0 */ |
| 252 | + uri_str = bson_strdup_printf ("mongodb://%s/?replicaSet=rs", |
| 253 | + mock_server_get_host_and_port (server0)); |
| 254 | + client = mongoc_client_new (uri_str); |
| 255 | + scanner = client->topology->scanner; |
| 256 | + primary_pref = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); |
| 257 | + |
| 258 | + assert (!scanner->async->ncmds); |
| 259 | + future = future_topology_select (client->topology, MONGOC_SS_READ, |
| 260 | + primary_pref, 15, &error); |
| 261 | + |
| 262 | + /* a single scan discovers servers 0 and 1 */ |
| 263 | + request = mock_server_receives_ismaster (server0); |
| 264 | + mock_server_replies_simple (request, server0_response); |
| 265 | + request_destroy (request); |
| 266 | + |
| 267 | + /* let client process that response */ |
| 268 | + _mongoc_usleep (250 * 1000); |
| 269 | + AWAIT (scanner->async->ncmds); |
| 270 | + |
| 271 | + request = mock_server_receives_ismaster (server1); |
| 272 | + mock_server_replies_simple (request, server1_response); |
| 273 | + AWAIT (!scanner->async->ncmds); |
| 274 | + |
| 275 | + assert (!future_get_mongoc_server_description_ptr (future)); |
| 276 | + request_destroy (request); |
| 277 | + mongoc_read_prefs_destroy (primary_pref); |
| 278 | + bson_free (server1_response); |
| 279 | + bson_free (server0_response); |
| 280 | + bson_free (uri_str); |
| 281 | + mongoc_client_destroy (client); |
| 282 | + mock_server_destroy (server1); |
| 283 | + mock_server_destroy (server0); |
| 284 | +} |
| 285 | + |
| 286 | + |
128 | 287 | void
|
129 | 288 | test_topology_scanner_install (TestSuite *suite)
|
130 | 289 | {
|
131 | 290 | TestSuite_Add (suite, "/TOPOLOGY/scanner", test_topology_scanner);
|
132 | 291 | #ifdef MONGOC_ENABLE_SSL
|
133 | 292 | TestSuite_Add (suite, "/TOPOLOGY/scanner_ssl", test_topology_scanner_ssl);
|
134 | 293 | #endif
|
| 294 | + TestSuite_Add (suite, "/TOPOLOGY/scanner_discovery", |
| 295 | + test_topology_scanner_discovery); |
| 296 | +/* |
| 297 | + TestSuite_Add (suite, "/TOPOLOGY/scanner_oscillate", |
| 298 | + test_topology_scanner_oscillate); |
| 299 | +*/ |
135 | 300 | }
|
0 commit comments