Skip to content

Commit 79ad44f

Browse files
committed
CDRIVER-735 show that aggregate ignores wire version
1 parent 4ef8b38 commit 79ad44f

File tree

5 files changed

+249
-1
lines changed

5 files changed

+249
-1
lines changed

build/generate-future-functions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@
109109
param("bson_ptr", "reply"),
110110
param("bson_error_ptr", "error")]),
111111

112+
future_function("mongoc_cursor_ptr",
113+
"mongoc_collection_aggregate",
114+
[param("mongoc_collection_ptr", "collection"),
115+
param("mongoc_query_flags_t", "flags"),
116+
param("const_bson_ptr", "pipeline"),
117+
param("const_bson_ptr", "options"),
118+
param("const_mongoc_read_prefs_ptr", "read_prefs")]),
119+
112120
future_function("bool",
113121
"mongoc_collection_insert_bulk",
114122
[param("mongoc_collection_ptr", "collection"),

tests/mock_server/future-functions.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,35 @@ background_mongoc_client_command_simple (void *data)
8282
return NULL;
8383
}
8484

85+
static void *
86+
background_mongoc_collection_aggregate (void *data)
87+
{
88+
future_t *future = (future_t *) data;
89+
90+
/* copy the future so we can unlock it while calling
91+
* mongoc_collection_aggregate
92+
*/
93+
future_t *copy = future_new_copy (future);
94+
future_value_t return_value;
95+
96+
return_value.type = future_value_mongoc_cursor_ptr_type;
97+
98+
future_value_set_mongoc_cursor_ptr (
99+
&return_value,
100+
mongoc_collection_aggregate (
101+
future_value_get_mongoc_collection_ptr (future_get_param(copy, 0)),
102+
future_value_get_mongoc_query_flags_t (future_get_param(copy, 1)),
103+
future_value_get_const_bson_ptr (future_get_param(copy, 2)),
104+
future_value_get_const_bson_ptr (future_get_param(copy, 3)),
105+
future_value_get_const_mongoc_read_prefs_ptr (future_get_param(copy, 4))
106+
));
107+
108+
future_destroy (copy);
109+
future_resolve (future, return_value);
110+
111+
return NULL;
112+
}
113+
85114
static void *
86115
background_mongoc_collection_insert_bulk (void *data)
87116
{
@@ -299,6 +328,36 @@ future_client_command_simple (
299328
return future;
300329
}
301330

331+
future_t *
332+
future_collection_aggregate (
333+
mongoc_collection_ptr collection,
334+
mongoc_query_flags_t flags,
335+
const_bson_ptr pipeline,
336+
const_bson_ptr options,
337+
const_mongoc_read_prefs_ptr read_prefs)
338+
{
339+
future_t *future = future_new (future_value_mongoc_cursor_ptr_type,
340+
5);
341+
342+
future_value_set_mongoc_collection_ptr (
343+
future_get_param (future, 0), collection);
344+
345+
future_value_set_mongoc_query_flags_t (
346+
future_get_param (future, 1), flags);
347+
348+
future_value_set_const_bson_ptr (
349+
future_get_param (future, 2), pipeline);
350+
351+
future_value_set_const_bson_ptr (
352+
future_get_param (future, 3), options);
353+
354+
future_value_set_const_mongoc_read_prefs_ptr (
355+
future_get_param (future, 4), read_prefs);
356+
357+
future_start (future, background_mongoc_collection_aggregate);
358+
return future;
359+
}
360+
302361
future_t *
303362
future_collection_insert_bulk (
304363
mongoc_collection_ptr collection,

tests/mock_server/future-functions.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@ future_client_command_simple (
3535
);
3636

3737

38+
future_t *
39+
future_collection_aggregate (
40+
41+
mongoc_collection_ptr collection,
42+
mongoc_query_flags_t flags,
43+
const_bson_ptr pipeline,
44+
const_bson_ptr options,
45+
const_mongoc_read_prefs_ptr read_prefs
46+
);
47+
48+
3849
future_t *
3950
future_collection_insert_bulk (
4051

tests/mock_server/mock-server.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ mock_server_t *
151151
mock_server_with_autoismaster (int32_t max_wire_version)
152152
{
153153
mock_server_t *server = mock_server_new ();
154+
155+
/* TODO: max_wire_version 0 is special */
154156
char *ismaster = bson_strdup_printf ("{'ok': 1.0,"
155157
" 'ismaster': true,"
156158
" 'minWireVersion': 0,"

tests/test-mongoc-collection.c

Lines changed: 169 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1286,6 +1286,136 @@ test_aggregate (void)
12861286
}
12871287

12881288

1289+
typedef struct {
1290+
bool with_batch_size;
1291+
bool with_options;
1292+
} test_aggregate_context_t;
1293+
1294+
1295+
static const char *
1296+
options_json (test_aggregate_context_t *c)
1297+
{
1298+
if (c->with_batch_size && c->with_options) {
1299+
return "{'foo': 1, 'batchSize': 11}";
1300+
} else if (c->with_batch_size) {
1301+
return "{'batchSize': 11}";
1302+
} else if (c->with_options) {
1303+
return "{'foo': 1}";
1304+
} else {
1305+
return "{}";
1306+
}
1307+
}
1308+
1309+
1310+
static void
1311+
test_aggregate_legacy (void *data)
1312+
{
1313+
test_aggregate_context_t *context = (test_aggregate_context_t *) data;
1314+
mock_server_t *server;
1315+
mongoc_client_t *client;
1316+
mongoc_collection_t *collection;
1317+
future_t *future;
1318+
request_t *request;
1319+
mongoc_cursor_t *cursor;
1320+
const bson_t *doc;
1321+
1322+
/* wire protocol version 0 */
1323+
server = mock_server_with_autoismaster (0);
1324+
mock_server_run (server);
1325+
client = mongoc_client_new_from_uri (mock_server_get_uri (server));
1326+
collection = mongoc_client_get_collection (client, "db", "collection");
1327+
1328+
cursor = mongoc_collection_aggregate (
1329+
collection,
1330+
MONGOC_QUERY_NONE,
1331+
tmp_bson ("[{'a': 1}]"),
1332+
tmp_bson (options_json (context)),
1333+
NULL);
1334+
1335+
future = future_cursor_next (cursor, &doc);
1336+
1337+
/* no "cursor" argument */
1338+
request = mock_server_receives_command (
1339+
server, "db", MONGOC_QUERY_NONE,
1340+
"{'aggregate': 'collection',"
1341+
" 'pipeline': [{'a': 1}]},"
1342+
" 'cursor': {'$exists': false} %s",
1343+
context->with_options ? ", 'foo': 1" : "");
1344+
1345+
mock_server_replies_simple (request, "{'ok': 1, 'result': [{'_id': 123}]}");
1346+
assert (future_get_bool (future));
1347+
ASSERT_MATCH (doc, "{'_id': 123}");
1348+
1349+
/* cursor is completed */
1350+
assert (!mongoc_cursor_next (cursor, &doc));
1351+
1352+
mongoc_cursor_destroy (cursor);
1353+
request_destroy (request);
1354+
future_destroy (future);
1355+
mongoc_collection_destroy (collection);
1356+
mongoc_client_destroy (client);
1357+
mock_server_destroy (server);
1358+
}
1359+
1360+
1361+
static void
1362+
test_aggregate_modern (void *data)
1363+
{
1364+
test_aggregate_context_t *context = (test_aggregate_context_t *) data;
1365+
mock_server_t *server;
1366+
mongoc_client_t *client;
1367+
mongoc_collection_t *collection;
1368+
future_t *future;
1369+
request_t *request;
1370+
mongoc_cursor_t *cursor;
1371+
const bson_t *doc;
1372+
1373+
/* wire protocol version 1 */
1374+
server = mock_server_with_autoismaster (1);
1375+
mock_server_run (server);
1376+
client = mongoc_client_new_from_uri (mock_server_get_uri (server));
1377+
collection = mongoc_client_get_collection (client, "db", "collection");
1378+
1379+
future = future_collection_aggregate (
1380+
collection,
1381+
MONGOC_QUERY_NONE,
1382+
tmp_bson ("[{'a': 1}]"),
1383+
tmp_bson (options_json (context)),
1384+
NULL);
1385+
1386+
/* "cursor" argument always sent if wire version >= 1 */
1387+
request = mock_server_receives_command (
1388+
server, "db", MONGOC_QUERY_NONE,
1389+
"{'aggregate': 'collection',"
1390+
" 'pipeline': [{'a': 1}],"
1391+
" 'cursor': %s %s}",
1392+
context->with_batch_size ? "{'batchSize': 11}" : "{'$empty': true}",
1393+
context->with_options ? ", 'foo': 1" : "");
1394+
1395+
mock_server_replies_simple (request,
1396+
"{'ok': 1,"
1397+
" 'cursor': {"
1398+
" 'id': 0,"
1399+
" 'ns': 'db.collection',"
1400+
" 'firstBatch': [{'_id': 123}]"
1401+
"}}");
1402+
1403+
assert ((cursor = future_get_mongoc_cursor_ptr (future)));
1404+
assert (mongoc_cursor_next (cursor, &doc));
1405+
ASSERT_MATCH (doc, "{'_id': 123}");
1406+
1407+
/* cursor is completed */
1408+
assert (!mongoc_cursor_next (cursor, &doc));
1409+
1410+
mongoc_cursor_destroy (cursor);
1411+
request_destroy (request);
1412+
future_destroy (future);
1413+
mongoc_collection_destroy (collection);
1414+
mongoc_client_destroy (client);
1415+
mock_server_destroy (server);
1416+
}
1417+
1418+
12891419
static void
12901420
test_validate (void)
12911421
{
@@ -1747,9 +1877,48 @@ test_get_index_info (void)
17471877
mongoc_client_destroy (client);
17481878
}
17491879

1880+
1881+
static void
1882+
test_aggregate_install (TestSuite *suite) {
1883+
static test_aggregate_context_t test_aggregate_contexts[2][2][2];
1884+
1885+
int wire_version, with_batch_size, with_options;
1886+
char *legacy_or_modern;
1887+
TestFuncWC func;
1888+
char *name;
1889+
test_aggregate_context_t *context;
1890+
1891+
for (wire_version = 0; wire_version < 2; wire_version++) {
1892+
for (with_batch_size = 0; with_batch_size < 2; with_batch_size++) {
1893+
for (with_options = 0; with_options < 2; with_options++) {
1894+
legacy_or_modern = wire_version ? "legacy" : "modern";
1895+
func = wire_version ? test_aggregate_legacy : test_aggregate_modern;
1896+
1897+
context = &test_aggregate_contexts
1898+
[wire_version][with_batch_size][with_options];
1899+
1900+
context->with_batch_size = (bool) with_batch_size;
1901+
context->with_options = (bool) with_options;
1902+
1903+
name = bson_strdup_printf (
1904+
"/Collection/aggregate/%s/%s/%s",
1905+
legacy_or_modern,
1906+
context->with_batch_size ? "batch_size" : "no_batch_size",
1907+
context->with_options ? "with_options" : "no_options");
1908+
1909+
TestSuite_AddWC (suite, name, func, NULL, (void *) context);
1910+
bson_free (name);
1911+
}
1912+
}
1913+
}
1914+
}
1915+
1916+
17501917
void
17511918
test_collection_install (TestSuite *suite)
17521919
{
1920+
test_aggregate_install (suite);
1921+
17531922
TestSuite_Add (suite, "/Collection/insert_bulk", test_insert_bulk);
17541923

17551924
TestSuite_Add (suite,
@@ -1787,7 +1956,6 @@ test_collection_install (TestSuite *suite)
17871956
TestSuite_Add (suite, "/Collection/count_with_opts", test_count_with_opts);
17881957
TestSuite_Add (suite, "/Collection/drop", test_drop);
17891958
TestSuite_Add (suite, "/Collection/aggregate", test_aggregate);
1790-
TestSuite_Add (suite, "/Collection/validate", test_validate);
17911959
TestSuite_Add (suite, "/Collection/rename", test_rename);
17921960
TestSuite_Add (suite, "/Collection/stats", test_stats);
17931961
TestSuite_Add (suite, "/Collection/find_and_modify", test_find_and_modify);

0 commit comments

Comments
 (0)