Skip to content

Commit b031041

Browse files
committed
update unified test runner
1 parent 6f44f72 commit b031041

File tree

4 files changed

+459
-4
lines changed

4 files changed

+459
-4
lines changed

src/libmongoc/tests/unified/operation.c

+285
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "operation.h"
1818

1919
#include "mongoc-array-private.h"
20+
#include "mongoc-bulkwrite.h"
2021
#include "mongoc-util-private.h" // hex_to_bin
2122
#include "result.h"
2223
#include "test-diagnostics.h"
@@ -221,6 +222,286 @@ operation_list_database_names (test_t *test, operation_t *op, result_t *result,
221222
return ret;
222223
}
223224

225+
static bool
226+
append_client_bulkwritemodel (mongoc_bulkwrite_t *bw, bson_t *model_wrapper, bson_error_t *error)
227+
{
228+
bool ok = false;
229+
// Example `model_wrapper`:
230+
// { "insertOne": { "namespace": "db.coll", "document": { "_id": 1 } }}
231+
char *namespace = NULL;
232+
bson_t *document = NULL;
233+
bson_t *filter = NULL;
234+
bson_t *update = NULL;
235+
bson_t *replacement = NULL;
236+
bson_t *collation = NULL;
237+
bson_val_t *hint = NULL;
238+
bool *upsert = NULL;
239+
bson_t *arrayFilters = NULL;
240+
bson_parser_t *parser = bson_parser_new ();
241+
242+
// Expect exactly one root key to identify the model (e.g. "insertOne"):
243+
if (bson_count_keys (model_wrapper) != 1) {
244+
test_set_error (error,
245+
"expected exactly one key in model, got %" PRIu32 " : %s",
246+
bson_count_keys (model_wrapper),
247+
tmp_json (model_wrapper));
248+
goto done;
249+
}
250+
bson_iter_t model_wrapper_iter;
251+
BSON_ASSERT (bson_iter_init (&model_wrapper_iter, model_wrapper));
252+
BSON_ASSERT (bson_iter_next (&model_wrapper_iter));
253+
const char *model_name = bson_iter_key (&model_wrapper_iter);
254+
bson_t model_bson;
255+
bson_iter_bson (&model_wrapper_iter, &model_bson);
256+
257+
if (0 == strcmp ("insertOne", model_name)) {
258+
// Parse an "insertOne".
259+
bson_parser_utf8 (parser, "namespace", &namespace);
260+
bson_parser_doc (parser, "document", &document);
261+
if (!bson_parser_parse (parser, &model_bson, error)) {
262+
goto done;
263+
}
264+
265+
if (!mongoc_bulkwrite_append_insertone (bw, namespace, document, NULL, error)) {
266+
goto done;
267+
}
268+
} else if (0 == strcmp ("updateOne", model_name)) {
269+
// Parse an "updateOne".
270+
bson_parser_utf8 (parser, "namespace", &namespace);
271+
bson_parser_doc (parser, "filter", &filter);
272+
bson_parser_array_or_doc (parser, "update", &update);
273+
bson_parser_array_optional (parser, "arrayFilters", &arrayFilters);
274+
bson_parser_doc_optional (parser, "collation", &collation);
275+
bson_parser_any_optional (parser, "hint", &hint);
276+
bson_parser_bool_optional (parser, "upsert", &upsert);
277+
if (!bson_parser_parse (parser, &model_bson, error)) {
278+
goto done;
279+
}
280+
281+
mongoc_bulkwrite_updateoneopts_t *opts = mongoc_bulkwrite_updateoneopts_new ();
282+
mongoc_bulkwrite_updateoneopts_set_arrayfilters (opts, arrayFilters);
283+
mongoc_bulkwrite_updateoneopts_set_collation (opts, collation);
284+
if (hint) {
285+
mongoc_bulkwrite_updateoneopts_set_hint (opts, bson_val_to_value (hint));
286+
}
287+
if (upsert) {
288+
mongoc_bulkwrite_updateoneopts_set_upsert (opts, *upsert);
289+
}
290+
291+
if (!mongoc_bulkwrite_append_updateone (bw, namespace, filter, update, opts, error)) {
292+
mongoc_bulkwrite_updateoneopts_destroy (opts);
293+
goto done;
294+
}
295+
mongoc_bulkwrite_updateoneopts_destroy (opts);
296+
} else if (0 == strcmp ("updateMany", model_name)) {
297+
// Parse an "updateMany".
298+
bson_parser_utf8 (parser, "namespace", &namespace);
299+
bson_parser_doc (parser, "filter", &filter);
300+
bson_parser_array_or_doc (parser, "update", &update);
301+
bson_parser_array_optional (parser, "arrayFilters", &arrayFilters);
302+
bson_parser_doc_optional (parser, "collation", &collation);
303+
bson_parser_any_optional (parser, "hint", &hint);
304+
bson_parser_bool_optional (parser, "upsert", &upsert);
305+
if (!bson_parser_parse (parser, &model_bson, error)) {
306+
goto done;
307+
}
308+
309+
mongoc_bulkwrite_updatemanyopts_t *opts = mongoc_bulkwrite_updatemanyopts_new ();
310+
mongoc_bulkwrite_updatemanyopts_set_arrayfilters (opts, arrayFilters);
311+
mongoc_bulkwrite_updatemanyopts_set_collation (opts, collation);
312+
if (hint) {
313+
mongoc_bulkwrite_updatemanyopts_set_hint (opts, bson_val_to_value (hint));
314+
}
315+
if (upsert) {
316+
mongoc_bulkwrite_updatemanyopts_set_upsert (opts, *upsert);
317+
}
318+
319+
if (!mongoc_bulkwrite_append_updatemany (bw, namespace, filter, update, opts, error)) {
320+
mongoc_bulkwrite_updatemanyopts_destroy (opts);
321+
goto done;
322+
}
323+
mongoc_bulkwrite_updatemanyopts_destroy (opts);
324+
} else if (0 == strcmp ("deleteOne", model_name)) {
325+
// Parse a "deleteOne".
326+
bson_parser_utf8 (parser, "namespace", &namespace);
327+
bson_parser_doc (parser, "filter", &filter);
328+
bson_parser_doc_optional (parser, "collation", &collation);
329+
bson_parser_any_optional (parser, "hint", &hint);
330+
if (!bson_parser_parse (parser, &model_bson, error)) {
331+
goto done;
332+
}
333+
334+
mongoc_bulkwrite_deleteoneopts_t *opts = mongoc_bulkwrite_deleteoneopts_new ();
335+
mongoc_bulkwrite_deleteoneopts_set_collation (opts, collation);
336+
if (hint) {
337+
mongoc_bulkwrite_deleteoneopts_set_hint (opts, bson_val_to_value (hint));
338+
}
339+
340+
if (!mongoc_bulkwrite_append_deleteone (bw, namespace, filter, opts, error)) {
341+
mongoc_bulkwrite_deleteoneopts_destroy (opts);
342+
goto done;
343+
}
344+
mongoc_bulkwrite_deleteoneopts_destroy (opts);
345+
} else if (0 == strcmp ("deleteMany", model_name)) {
346+
// Parse a "deleteMany".
347+
bson_parser_utf8 (parser, "namespace", &namespace);
348+
bson_parser_doc (parser, "filter", &filter);
349+
bson_parser_doc_optional (parser, "collation", &collation);
350+
bson_parser_any_optional (parser, "hint", &hint);
351+
if (!bson_parser_parse (parser, &model_bson, error)) {
352+
goto done;
353+
}
354+
355+
mongoc_bulkwrite_deletemanyopts_t *opts = mongoc_bulkwrite_deletemanyopts_new ();
356+
mongoc_bulkwrite_deletemanyopts_set_collation (opts, collation);
357+
if (hint) {
358+
mongoc_bulkwrite_deletemanyopts_set_hint (opts, bson_val_to_value (hint));
359+
}
360+
361+
if (!mongoc_bulkwrite_append_deletemany (bw, namespace, filter, opts, error)) {
362+
mongoc_bulkwrite_deletemanyopts_destroy (opts);
363+
goto done;
364+
}
365+
mongoc_bulkwrite_deletemanyopts_destroy (opts);
366+
} else if (0 == strcmp ("replaceOne", model_name)) {
367+
// Parse a "replaceOne".
368+
bson_parser_utf8 (parser, "namespace", &namespace);
369+
bson_parser_doc (parser, "filter", &filter);
370+
bson_parser_doc (parser, "replacement", &replacement);
371+
bson_parser_doc_optional (parser, "collation", &collation);
372+
bson_parser_bool_optional (parser, "upsert", &upsert);
373+
bson_parser_any_optional (parser, "hint", &hint);
374+
if (!bson_parser_parse (parser, &model_bson, error)) {
375+
goto done;
376+
}
377+
378+
mongoc_bulkwrite_replaceoneopts_t *opts = mongoc_bulkwrite_replaceoneopts_new ();
379+
mongoc_bulkwrite_replaceoneopts_set_arrayfilters (opts, arrayFilters);
380+
mongoc_bulkwrite_replaceoneopts_set_collation (opts, collation);
381+
if (hint) {
382+
mongoc_bulkwrite_replaceoneopts_set_hint (opts, bson_val_to_value (hint));
383+
}
384+
if (upsert) {
385+
mongoc_bulkwrite_replaceoneopts_set_upsert (opts, *upsert);
386+
}
387+
388+
if (!mongoc_bulkwrite_append_replaceone (bw, namespace, filter, replacement, opts, error)) {
389+
mongoc_bulkwrite_replaceoneopts_destroy (opts);
390+
goto done;
391+
}
392+
mongoc_bulkwrite_replaceoneopts_destroy (opts);
393+
} else {
394+
test_set_error (error, "unsupported model: %s", model_name);
395+
goto done;
396+
}
397+
398+
ok = true;
399+
done:
400+
bson_parser_destroy_with_parsed_fields (parser);
401+
return ok;
402+
}
403+
404+
static bool
405+
operation_client_bulkwrite (test_t *test, operation_t *op, result_t *result, bson_error_t *error)
406+
{
407+
bool ret = false;
408+
mongoc_client_t *client = NULL;
409+
mongoc_bulkwrite_t *bw = NULL;
410+
mongoc_bulkwriteopts_t *opts = mongoc_bulkwriteopts_new ();
411+
412+
client = entity_map_get_client (test->entity_map, op->object, error);
413+
if (!client) {
414+
goto done;
415+
}
416+
417+
int64_t nmodels = 0;
418+
419+
// Parse arguments.
420+
{
421+
bool parse_ok = false;
422+
bson_t *args_models = NULL;
423+
bool *args_verboseResults = NULL;
424+
bool *args_ordered = NULL;
425+
bson_t *args_comment = NULL;
426+
bool *args_bypassDocumentValidation = NULL;
427+
bson_t *args_let = NULL;
428+
mongoc_write_concern_t *args_wc = NULL;
429+
bson_parser_t *parser = bson_parser_new ();
430+
431+
bson_parser_array (parser, "models", &args_models);
432+
bson_parser_bool_optional (parser, "verboseResults", &args_verboseResults);
433+
bson_parser_bool_optional (parser, "ordered", &args_ordered);
434+
bson_parser_doc_optional (parser, "comment", &args_comment);
435+
bson_parser_bool_optional (parser, "bypassDocumentValidation", &args_bypassDocumentValidation);
436+
bson_parser_doc_optional (parser, "let", &args_let);
437+
bson_parser_write_concern_optional (parser, &args_wc);
438+
if (!bson_parser_parse (parser, op->arguments, error)) {
439+
goto parse_done;
440+
}
441+
if (args_verboseResults && *args_verboseResults) {
442+
mongoc_bulkwriteopts_set_verboseresults (opts, true);
443+
}
444+
if (args_ordered) {
445+
mongoc_bulkwriteopts_set_ordered (opts, *args_ordered);
446+
}
447+
if (args_comment) {
448+
mongoc_bulkwriteopts_set_comment (opts, args_comment);
449+
}
450+
if (args_bypassDocumentValidation) {
451+
mongoc_bulkwriteopts_set_bypassdocumentvalidation (opts, *args_bypassDocumentValidation);
452+
}
453+
if (args_let) {
454+
mongoc_bulkwriteopts_set_let (opts, args_let);
455+
}
456+
if (args_wc) {
457+
mongoc_bulkwriteopts_set_writeconcern (opts, args_wc);
458+
}
459+
460+
// Parse models.
461+
bson_iter_t args_models_iter;
462+
BSON_ASSERT (bson_iter_init (&args_models_iter, args_models));
463+
bw = mongoc_client_bulkwrite_new (client);
464+
while (bson_iter_next (&args_models_iter)) {
465+
nmodels++;
466+
bson_t model_wrapper;
467+
bson_iter_bson (&args_models_iter, &model_wrapper);
468+
if (!append_client_bulkwritemodel (bw, &model_wrapper, error)) {
469+
if (error->domain != TEST_ERROR_DOMAIN) {
470+
// Propagate error as a test result.
471+
result_from_val_and_reply (result, NULL, NULL, error);
472+
// Return with a success (to not abort test runner) and propagate
473+
// the error as a result.
474+
ret = true;
475+
*error = (bson_error_t){0};
476+
bson_parser_destroy_with_parsed_fields (parser);
477+
goto done;
478+
}
479+
goto parse_done;
480+
}
481+
}
482+
483+
parse_ok = true;
484+
parse_done:
485+
bson_parser_destroy_with_parsed_fields (parser);
486+
if (!parse_ok) {
487+
goto done;
488+
}
489+
}
490+
491+
// Do client bulk write.
492+
mongoc_bulkwrite_set_session (bw, op->session);
493+
mongoc_bulkwritereturn_t bwr = mongoc_bulkwrite_execute (bw, opts);
494+
495+
result_from_bulkwritereturn (result, bwr, nmodels);
496+
mongoc_bulkwriteexception_destroy (bwr.exc);
497+
mongoc_bulkwriteresult_destroy (bwr.res);
498+
ret = true;
499+
done:
500+
mongoc_bulkwriteopts_destroy (opts);
501+
mongoc_bulkwrite_destroy (bw);
502+
return ret;
503+
}
504+
224505
static bool
225506
operation_create_datakey (test_t *test, operation_t *op, result_t *result, bson_error_t *error)
226507
{
@@ -2609,6 +2890,9 @@ operation_start_transaction (test_t *test, operation_t *op, result_t *result, bs
26092890
bson_parser_read_concern_optional (bp, &rc);
26102891
bson_parser_write_concern_optional (bp, &wc);
26112892
bson_parser_read_prefs_optional (bp, &rp);
2893+
if (!bson_parser_parse (bp, op->arguments, error)) {
2894+
goto done;
2895+
}
26122896
if (rc) {
26132897
mongoc_transaction_opts_set_read_concern (opts, rc);
26142898
}
@@ -3520,6 +3804,7 @@ operation_run (test_t *test, bson_t *op_bson, bson_error_t *error)
35203804
{"createChangeStream", operation_create_change_stream},
35213805
{"listDatabases", operation_list_databases},
35223806
{"listDatabaseNames", operation_list_database_names},
3807+
{"clientBulkWrite", operation_client_bulkwrite},
35233808

35243809
/* ClientEncryption operations */
35253810
{"createDataKey", operation_create_datakey},

0 commit comments

Comments
 (0)