Skip to content

Commit 058a1b9

Browse files
jmikolakevinAlbs
andauthored
CDRIVER-3892 expose reason documents fail validation (#802)
This implements the second prose test from the CRUD spec and relocates the first prose test, which was originally added in CDRIVER-3575. Co-authored-by: Kevin Albertson <[email protected]>
1 parent d261727 commit 058a1b9

File tree

4 files changed

+131
-46
lines changed

4 files changed

+131
-46
lines changed

src/libmongoc/tests/test-libmongoc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2477,6 +2477,7 @@ WIRE_VERSION_CHECKS (6)
24772477
WIRE_VERSION_CHECKS (7)
24782478
WIRE_VERSION_CHECKS (8)
24792479
WIRE_VERSION_CHECKS (9)
2480+
WIRE_VERSION_CHECKS (13)
24802481

24812482
int
24822483
test_framework_skip_if_no_dual_ip_hostname (void)

src/libmongoc/tests/test-libmongoc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ WIRE_VERSION_CHECK_DECLS (6)
188188
WIRE_VERSION_CHECK_DECLS (7)
189189
WIRE_VERSION_CHECK_DECLS (8)
190190
WIRE_VERSION_CHECK_DECLS (9)
191+
WIRE_VERSION_CHECK_DECLS (13)
191192

192193
#undef WIRE_VERSION_CHECK_DECLS
193194

src/libmongoc/tests/test-mongoc-crud.c

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,137 @@ test_all_spec_tests (TestSuite *suite)
5151
suite, resolved, &test_crud_cb, TestSuite_CheckLive);
5252
}
5353

54+
static void
55+
prose_test_1 (void *ctx)
56+
{
57+
mongoc_client_t *client;
58+
mongoc_collection_t *coll;
59+
bool ret;
60+
bson_t reply;
61+
bson_error_t error;
62+
63+
client = test_framework_new_default_client ();
64+
coll = get_test_collection (client, "coll");
65+
66+
ret = mongoc_client_command_simple (
67+
client,
68+
"admin",
69+
tmp_bson ("{'configureFailPoint': 'failCommand', 'mode': {'times': 1}, "
70+
" 'data': {'failCommands': ['insert'], 'writeConcernError': {"
71+
" 'code': 100, 'codeName': 'UnsatisfiableWriteConcern', "
72+
" 'errmsg': 'Not enough data-bearing nodes', "
73+
" 'errInfo': {'writeConcern': {'w': 2, 'wtimeout': 0, "
74+
" 'provenance': 'clientSupplied'}}}}}"),
75+
NULL,
76+
NULL,
77+
&error);
78+
ASSERT_OR_PRINT (ret, error);
79+
80+
ret = mongoc_collection_insert_one (
81+
coll, tmp_bson ("{'x':1}"), NULL /* opts */, &reply, &error);
82+
ASSERT (!ret);
83+
84+
/* libmongoc does not model WriteConcernError, so we only assert that the
85+
* "errInfo" field set in configureFailPoint matches that in the result */
86+
ASSERT_MATCH (&reply,
87+
"{'writeConcernErrors': [{'errInfo': {'writeConcern': {"
88+
"'w': 2, 'wtimeout': 0, 'provenance': 'clientSupplied'}}}]}");
89+
90+
bson_destroy (&reply);
91+
mongoc_collection_destroy (coll);
92+
mongoc_client_destroy (client);
93+
}
94+
95+
typedef struct {
96+
bool has_reply;
97+
bson_t reply;
98+
} prose_test_2_apm_ctx_t;
99+
100+
static void
101+
prose_test_2_command_succeeded (const mongoc_apm_command_succeeded_t *event)
102+
{
103+
if (!strcmp (mongoc_apm_command_succeeded_get_command_name (event),
104+
"insert")) {
105+
prose_test_2_apm_ctx_t *ctx =
106+
mongoc_apm_command_succeeded_get_context (event);
107+
ASSERT (!ctx->has_reply);
108+
ctx->has_reply = true;
109+
bson_copy_to (mongoc_apm_command_succeeded_get_reply (event),
110+
&ctx->reply);
111+
}
112+
}
113+
114+
static void
115+
prose_test_2 (void *ctx)
116+
{
117+
mongoc_client_t *client;
118+
mongoc_database_t *db;
119+
mongoc_collection_t *coll, *coll_created;
120+
mongoc_apm_callbacks_t *callbacks;
121+
prose_test_2_apm_ctx_t apm_ctx = {0};
122+
bool ret;
123+
bson_t reply, reply_errInfo, observed_errInfo;
124+
bson_error_t error = {0};
125+
126+
client = test_framework_new_default_client ();
127+
db = get_test_database (client);
128+
coll = get_test_collection (client, "coll");
129+
130+
/* don't care if ns not found. */
131+
(void) mongoc_collection_drop (coll, NULL);
132+
133+
coll_created = mongoc_database_create_collection (
134+
db,
135+
mongoc_collection_get_name (coll),
136+
tmp_bson ("{'validator': {'x': {'$type': 'string'}}}"),
137+
&error);
138+
ASSERT_OR_PRINT (coll_created, error);
139+
mongoc_collection_destroy (coll_created);
140+
141+
callbacks = mongoc_apm_callbacks_new ();
142+
mongoc_apm_set_command_succeeded_cb (callbacks,
143+
prose_test_2_command_succeeded);
144+
mongoc_client_set_apm_callbacks (client, callbacks, (void *) &apm_ctx);
145+
mongoc_apm_callbacks_destroy (callbacks);
146+
147+
ret = mongoc_collection_insert_one (
148+
coll, tmp_bson ("{'x':1}"), NULL /* opts */, &reply, &error);
149+
ASSERT (!ret);
150+
151+
/* Assert that the WriteError's code is DocumentValidationFailure */
152+
ASSERT_MATCH (&reply, "{'writeErrors': [{'code': 121}]}");
153+
154+
/* libmongoc does not model WriteError, so we only assert that the observed
155+
* "errInfo" field matches that in the result */
156+
ASSERT (apm_ctx.has_reply);
157+
bson_lookup_doc (&apm_ctx.reply, "writeErrors.0.errInfo", &observed_errInfo);
158+
bson_lookup_doc (&reply, "writeErrors.0.errInfo", &reply_errInfo);
159+
ASSERT (bson_compare (&reply_errInfo, &observed_errInfo) == 0);
160+
161+
bson_destroy (&apm_ctx.reply);
162+
bson_destroy (&reply);
163+
mongoc_collection_destroy (coll);
164+
mongoc_database_destroy (db);
165+
mongoc_client_destroy (client);
166+
}
167+
54168
void
55169
test_crud_install (TestSuite *suite)
56170
{
57171
test_all_spec_tests (suite);
172+
173+
TestSuite_AddFull (suite,
174+
"/crud/prose_test_1",
175+
prose_test_1,
176+
NULL, /* dtor */
177+
NULL, /* ctx */
178+
test_framework_skip_if_no_failpoint,
179+
test_framework_skip_if_max_wire_version_less_than_7);
180+
181+
TestSuite_AddFull (suite,
182+
"/crud/prose_test_2",
183+
prose_test_2,
184+
NULL, /* dtor */
185+
NULL, /* ctx */
186+
test_framework_skip_if_max_wire_version_less_than_13);
58187
}

src/libmongoc/tests/test-mongoc-read-write-concern.c

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -230,45 +230,6 @@ test_rw_concern_document (bson_t *scenario)
230230
}
231231
}
232232

233-
static void
234-
errinfo_propagated (void *unused)
235-
{
236-
mongoc_client_t *client;
237-
bool ret;
238-
bson_error_t error;
239-
mongoc_collection_t *coll;
240-
bson_t reply;
241-
const char *failpoint =
242-
"{'configureFailPoint':'failCommand','data':{'failCommands':['insert'],'"
243-
"writeConcernError':{'code':100,'codeName':'UnsatisfiableWriteConcern','"
244-
"errmsg':'Not enough data-bearing "
245-
"nodes','errInfo':{'writeConcern':{'w':2,'wtimeout':0,'provenance':'"
246-
"clientSupplied'}}}},'mode':{'times':1}}";
247-
248-
249-
client = test_framework_new_default_client ();
250-
ret = mongoc_client_command_simple (client,
251-
"admin",
252-
tmp_bson (failpoint),
253-
NULL /* read prefs */,
254-
NULL /* reply */,
255-
&error);
256-
ASSERT_OR_PRINT (ret, error);
257-
coll = get_test_collection (client, "rwc_errinfo");
258-
ret = mongoc_collection_insert_one (
259-
coll, tmp_bson ("{'x': 1}"), NULL /* opts */, &reply, &error);
260-
BSON_ASSERT (!ret);
261-
assert_match_bson (&reply,
262-
tmp_bson ("{'writeConcernErrors': [ { 'errInfo' : { "
263-
"'writeConcern' : { 'w' : 2, 'wtimeout' : 0, "
264-
"'provenance' : 'clientSupplied' } } } ] }"),
265-
false);
266-
267-
bson_destroy (&reply);
268-
mongoc_collection_destroy (coll);
269-
mongoc_client_destroy (client);
270-
}
271-
272233
void
273234
test_read_write_concern_install (TestSuite *suite)
274235
{
@@ -281,11 +242,4 @@ test_read_write_concern_install (TestSuite *suite)
281242
test_framework_resolve_path (JSON_DIR "/read_write_concern/document",
282243
resolved);
283244
install_json_test_suite (suite, resolved, &test_rw_concern_document);
284-
TestSuite_AddFull (suite,
285-
"/read_write_concern/errinfo_propagated",
286-
errinfo_propagated,
287-
NULL /* dtor */,
288-
NULL /* ctx */,
289-
test_framework_skip_if_max_wire_version_less_than_7,
290-
test_framework_skip_if_no_failpoint);
291245
}

0 commit comments

Comments
 (0)