@@ -108,10 +108,23 @@ test_transactions_supported (void *ctx)
108
108
}
109
109
110
110
111
+ static bool
112
+ hangup_except_ismaster (request_t * request , void * data )
113
+ {
114
+ if (!bson_strcasecmp (request -> command_name , "ismaster" )) {
115
+ /* allow default response */
116
+ return false;
117
+ }
118
+
119
+ mock_server_hangs_up (request );
120
+ return true;
121
+ }
122
+
123
+
111
124
static void
112
- test_server_selection_error ( void )
125
+ _test_transient_txn_err ( bool hangup )
113
126
{
114
- mock_rs_t * rs ;
127
+ mock_server_t * server ;
115
128
mongoc_client_t * client ;
116
129
mongoc_client_session_t * session ;
117
130
mongoc_collection_t * collection ;
@@ -127,13 +140,14 @@ test_server_selection_error (void)
127
140
bson_t reply ;
128
141
bool r ;
129
142
130
- rs = mock_rs_with_autoismaster ( 7 /* wire version */ ,
131
- true /* has primary */ ,
132
- 0 /* secondaries */ ,
133
- 0 /* arbiters */ );
143
+ server = mock_server_new ();
144
+ mock_server_run ( server );
145
+ rs_response_to_ismaster (
146
+ server , 7 , true /* primary */ , false /* tags */ , server , NULL );
134
147
135
- mock_rs_run (rs );
136
- client = mongoc_client_new_from_uri (mock_rs_get_uri (rs ));
148
+ client = mongoc_client_new_from_uri (mock_server_get_uri (server ));
149
+ /* allow fast reconnect */
150
+ client -> topology -> min_heartbeat_frequency_msec = 0 ;
137
151
session = mongoc_client_start_session (client , NULL , & error );
138
152
ASSERT_OR_PRINT (session , error );
139
153
r = mongoc_client_session_start_transaction (session , NULL , & error );
@@ -142,8 +156,15 @@ test_server_selection_error (void)
142
156
ASSERT_OR_PRINT (r , error );
143
157
collection = mongoc_client_get_collection (client , "db" , "collection" );
144
158
145
- /* stop responding */
146
- mock_rs_destroy (rs );
159
+ if (hangup ) {
160
+ /* test that network errors have TransientTransactionError */
161
+ mock_server_autoresponds (server , hangup_except_ismaster , NULL , NULL );
162
+ } else {
163
+ /* test server selection errors have TransientTransactionError */
164
+ mock_server_destroy (server );
165
+ server = NULL ;
166
+ }
167
+
147
168
/* warnings when trying to abort the transaction and later, end sessions */
148
169
capture_logs (true);
149
170
@@ -157,81 +178,110 @@ test_server_selection_error (void)
157
178
} \
158
179
} while (0)
159
180
160
- #define TEST_SS_ERR (_expr ) \
181
+ #define TEST_CMD_ERR (_expr ) \
182
+ do { \
183
+ r = (_expr); \
184
+ BSON_ASSERT (!r); \
185
+ ASSERT_TRANSIENT_LABEL (&reply, _expr); \
186
+ bson_destroy (&reply); \
187
+ /* clean slate for next test */ \
188
+ memset (& reply , 0 , sizeof (reply )); \
189
+ } while (0 )
190
+
191
+
192
+ #define TEST_WRITE_ERR (_expr ) \
161
193
do { \
162
194
r = (_expr); \
163
- BSON_ASSERT (!r); \
164
195
ASSERT_TRANSIENT_LABEL (&reply, _expr); \
165
196
bson_destroy (&reply); \
166
197
/* clean slate for next test */ \
167
198
memset (& reply , 0 , sizeof (reply )); \
168
199
} while (0 )
169
200
170
- #define TEST_SS_ERR_CURSOR (_cursor_expr ) \
171
- do { \
172
- cursor = (_cursor_expr); \
173
- r = mongoc_cursor_next (cursor, &doc_out); \
174
- BSON_ASSERT (!r); \
175
- r = !mongoc_cursor_error_document (cursor, &error, &error_doc); \
176
- BSON_ASSERT (!r); \
177
- BSON_ASSERT (error_doc); \
178
- ASSERT_TRANSIENT_LABEL (error_doc, _cursor_expr); \
179
- mongoc_cursor_destroy (cursor); \
201
+ #define TEST_CURSOR_ERR (_cursor_expr ) \
202
+ do { \
203
+ cursor = (_cursor_expr); \
204
+ r = mongoc_cursor_next (cursor, &doc_out); \
205
+ BSON_ASSERT (!r); \
206
+ r = !mongoc_cursor_error_document (cursor, &error, &error_doc); \
207
+ BSON_ASSERT (!r); \
208
+ BSON_ASSERT (error_doc); \
209
+ ASSERT_TRANSIENT_LABEL (error_doc, _cursor_expr); \
210
+ mongoc_cursor_destroy (cursor); \
180
211
} while (0)
181
212
182
213
b = tmp_bson ("{'x': 1}" );
183
214
u = tmp_bson ("{'$inc': {'x': 1}}" );
184
215
185
- TEST_SS_ERR (mongoc_client_command_with_opts (
216
+ TEST_CMD_ERR (mongoc_client_command_with_opts (
186
217
client , "db" , b , NULL , & opts , & reply , NULL ));
187
- TEST_SS_ERR (mongoc_client_read_command_with_opts (
218
+ TEST_CMD_ERR (mongoc_client_read_command_with_opts (
188
219
client , "db" , b , NULL , & opts , & reply , NULL ));
189
- TEST_SS_ERR (mongoc_client_write_command_with_opts (
220
+ TEST_CMD_ERR (mongoc_client_write_command_with_opts (
190
221
client , "db" , b , & opts , & reply , NULL ));
191
- TEST_SS_ERR (mongoc_client_read_write_command_with_opts (
222
+ TEST_CMD_ERR (mongoc_client_read_write_command_with_opts (
192
223
client , "db" , b , NULL , & opts , & reply , NULL ));
193
- TEST_SS_ERR (
224
+ TEST_CMD_ERR (0 < mongoc_collection_count_documents (
225
+ collection , b , & opts , NULL , & reply , NULL ));
226
+
227
+ BEGIN_IGNORE_DEPRECATIONS ;
228
+ TEST_CMD_ERR (mongoc_collection_create_index_with_opts (
229
+ collection , b , NULL , & opts , & reply , NULL ));
230
+ END_IGNORE_DEPRECATIONS
231
+
232
+ fam = mongoc_find_and_modify_opts_new ();
233
+ mongoc_find_and_modify_opts_append (fam , & opts );
234
+ TEST_CMD_ERR (mongoc_collection_find_and_modify_with_opts (
235
+ collection , b , fam , & reply , NULL ));
236
+
237
+ TEST_WRITE_ERR (
194
238
mongoc_collection_insert_one (collection , b , & opts , & reply , NULL ));
195
- TEST_SS_ERR (mongoc_collection_insert_many (
239
+ TEST_WRITE_ERR (mongoc_collection_insert_many (
196
240
collection , (const bson_t * * ) & b , 1 , & opts , & reply , NULL ));
197
- TEST_SS_ERR (
241
+ TEST_WRITE_ERR (
198
242
mongoc_collection_update_one (collection , b , u , & opts , & reply , NULL ));
199
- TEST_SS_ERR (
243
+ TEST_WRITE_ERR (
200
244
mongoc_collection_update_many (collection , b , u , & opts , & reply , NULL ));
201
- TEST_SS_ERR (
245
+ TEST_WRITE_ERR (
202
246
mongoc_collection_replace_one (collection , b , b , & opts , & reply , NULL ));
203
- TEST_SS_ERR (
247
+ TEST_WRITE_ERR (
204
248
mongoc_collection_delete_one (collection , b , & opts , & reply , NULL ));
205
- TEST_SS_ERR (
249
+ TEST_WRITE_ERR (
206
250
mongoc_collection_delete_many (collection , b , & opts , & reply , NULL ));
207
- TEST_SS_ERR (0 < mongoc_collection_count_documents (
208
- collection , b , & opts , NULL , & reply , NULL ));
209
-
210
- TEST_SS_ERR_CURSOR (mongoc_collection_aggregate (
211
- collection , MONGOC_QUERY_NONE , tmp_bson ("[{}]" ), & opts , NULL ));
212
- TEST_SS_ERR_CURSOR (
213
- mongoc_collection_find_with_opts (collection , b , & opts , NULL ));
214
251
215
252
bulk = mongoc_collection_create_bulk_operation_with_opts (collection , & opts );
216
253
mongoc_bulk_operation_insert (bulk , b );
217
- TEST_SS_ERR (mongoc_bulk_operation_execute (bulk , & reply , NULL ));
254
+ TEST_WRITE_ERR (mongoc_bulk_operation_execute (bulk , & reply , NULL ));
218
255
219
- fam = mongoc_find_and_modify_opts_new ();
220
- mongoc_find_and_modify_opts_append (fam , & opts );
221
- TEST_SS_ERR (mongoc_collection_find_and_modify_with_opts (
222
- collection , b , fam , & reply , NULL ));
223
-
224
- BEGIN_IGNORE_DEPRECATIONS ;
225
- TEST_SS_ERR (mongoc_collection_create_index_with_opts (
226
- collection , b , NULL , & opts , & reply , NULL ));
227
- END_IGNORE_DEPRECATIONS
256
+ TEST_CURSOR_ERR (mongoc_collection_aggregate (
257
+ collection , MONGOC_QUERY_NONE , tmp_bson ("[{}]" ), & opts , NULL ));
258
+ TEST_CURSOR_ERR (
259
+ mongoc_collection_find_with_opts (collection , b , & opts , NULL ));
228
260
229
261
mongoc_find_and_modify_opts_destroy (fam );
230
262
mongoc_bulk_operation_destroy (bulk );
231
263
bson_destroy (& opts );
232
264
mongoc_collection_destroy (collection );
233
265
mongoc_client_session_destroy (session );
234
266
mongoc_client_destroy (client );
267
+
268
+ if (server ) {
269
+ mock_server_destroy (server );
270
+ }
271
+ }
272
+
273
+
274
+ static void
275
+ test_server_selection_error (void )
276
+ {
277
+ _test_transient_txn_err (false /* hangup */ );
278
+ }
279
+
280
+
281
+ static void
282
+ test_network_error (void )
283
+ {
284
+ _test_transient_txn_err (true /* hangup */ );
235
285
}
236
286
237
287
@@ -242,9 +292,7 @@ test_transactions_install (TestSuite *suite)
242
292
243
293
ASSERT (realpath (JSON_DIR "/transactions" , resolved ));
244
294
install_json_test_suite_with_check (
245
- suite ,
246
- resolved ,
247
- test_transactions_cb ,test_framework_skip_if_no_txns );
295
+ suite , resolved , test_transactions_cb , test_framework_skip_if_no_txns );
248
296
249
297
/* skip mongos for now - txn support coming in 4.1.0 */
250
298
TestSuite_AddFull (suite ,
@@ -259,4 +307,8 @@ test_transactions_install (TestSuite *suite)
259
307
"/transactions/server_selection_err" ,
260
308
test_server_selection_error ,
261
309
test_framework_skip_if_no_crypto );
310
+ TestSuite_AddMockServerTest (suite ,
311
+ "/transactions/network_err" ,
312
+ test_network_error ,
313
+ test_framework_skip_if_no_crypto );
262
314
}
0 commit comments