...
1description: transactions are correctly pinned to connections for load-balanced clusters
2
3schemaVersion: '1.3'
4
5runOnRequirements:
6 - topologies: [ load-balanced ]
7
8createEntities:
9 - client:
10 id: &client0 client0
11 useMultipleMongoses: true
12 observeEvents:
13 # Do not observe commandSucceededEvent or commandFailedEvent because we cannot guarantee success or failure of
14 # commands like commitTransaction and abortTransaction in a multi-mongos load-balanced setup.
15 - commandStartedEvent
16 - connectionReadyEvent
17 - connectionClosedEvent
18 - connectionCheckedOutEvent
19 - connectionCheckedInEvent
20 - session:
21 id: &session0 session0
22 client: *client0
23 - database:
24 id: &database0 database0
25 client: *client0
26 databaseName: &database0Name database0Name
27 - collection:
28 id: &collection0 collection0
29 database: *database0
30 collectionName: &collection0Name coll0
31
32initialData:
33 - collectionName: *collection0Name
34 databaseName: *database0Name
35 documents:
36 - { _id: 1 }
37 - { _id: 2 }
38 - { _id: 3 }
39
40_yamlAnchors:
41 documents:
42 - &insertDocument
43 _id: 4
44
45tests:
46 - description: sessions are reused in LB mode
47 operations:
48 - &nonTransactionalInsert
49 name: insertOne
50 object: *collection0
51 arguments:
52 document: { x: 1 }
53 - *nonTransactionalInsert
54 - name: assertSameLsidOnLastTwoCommands
55 object: testRunner
56 arguments:
57 client: *client0
58
59 - description: all operations go to the same mongos
60 operations:
61 - &startTransaction
62 name: startTransaction
63 object: *session0
64 - &transactionalInsert
65 name: insertOne
66 object: *collection0
67 arguments:
68 document: { x: 1 }
69 session: *session0
70 - &assertConnectionPinned
71 name: assertNumberConnectionsCheckedOut
72 object: testRunner
73 arguments:
74 client: *client0
75 connections: 1
76 - *transactionalInsert
77 - *transactionalInsert
78 - *transactionalInsert
79 - *transactionalInsert
80 - *transactionalInsert
81 - *assertConnectionPinned
82 - &commitTransaction
83 name: commitTransaction
84 object: *session0
85 expectEvents:
86 - client: *client0
87 events:
88 - &insertStarted
89 commandStartedEvent:
90 commandName: insert
91 - *insertStarted
92 - *insertStarted
93 - *insertStarted
94 - *insertStarted
95 - *insertStarted
96 - &commitStarted
97 commandStartedEvent:
98 commandName: commitTransaction
99 - client: *client0
100 eventType: cmap
101 events:
102 # The connection is never checked back in.
103 - connectionReadyEvent: {}
104 - connectionCheckedOutEvent: {}
105
106 - description: transaction can be committed multiple times
107 operations:
108 - *startTransaction
109 - *transactionalInsert
110 - *assertConnectionPinned
111 - *commitTransaction
112 - *assertConnectionPinned
113 - *commitTransaction
114 - *commitTransaction
115 - *commitTransaction
116 - *assertConnectionPinned
117 expectEvents:
118 - client: *client0
119 events:
120 - *insertStarted
121 - *commitStarted
122 - *commitStarted
123 - *commitStarted
124 - *commitStarted
125 - client: *client0
126 eventType: cmap
127 events:
128 - connectionReadyEvent: {}
129 - connectionCheckedOutEvent: {}
130
131 - description: pinned connection is not released after a non-transient CRUD error
132 operations:
133 - name: failPoint
134 object: testRunner
135 arguments:
136 client: *client0
137 failPoint:
138 configureFailPoint: failCommand
139 mode: { times: 1 }
140 data:
141 failCommands: [ insert ]
142 errorCode: &nonTransientErrorCode 51 # ManualInterventionRequired
143 - *startTransaction
144 - name: insertOne
145 object: *collection0
146 arguments:
147 document: { x: 1 }
148 session: *session0
149 expectError: &nonTransientExpectedError
150 errorCode: *nonTransientErrorCode
151 errorLabelsOmit: [ TransientTransactionError ]
152 - *assertConnectionPinned
153 expectEvents:
154 - client: *client0
155 events:
156 - *insertStarted
157 - client: *client0
158 eventType: cmap
159 events:
160 # Events for setting the fail point.
161 - connectionReadyEvent: {}
162 - connectionCheckedOutEvent: {}
163 - connectionCheckedInEvent: {}
164 # Events for the transactional insert.
165 - connectionCheckedOutEvent: {}
166
167 - description: pinned connection is not released after a non-transient commit error
168 operations:
169 - name: failPoint
170 object: testRunner
171 arguments:
172 client: *client0
173 failPoint:
174 configureFailPoint: failCommand
175 mode: { times: 1 }
176 data:
177 failCommands: [ commitTransaction ]
178 errorCode: *nonTransientErrorCode
179 - *startTransaction
180 - *transactionalInsert
181 - name: commitTransaction
182 object: *session0
183 expectError: *nonTransientExpectedError
184 - *assertConnectionPinned
185 expectEvents:
186 - client: *client0
187 events:
188 - *insertStarted
189 - *commitStarted
190 - client: *client0
191 eventType: cmap
192 events:
193 # Events for setting the fail point.
194 - connectionReadyEvent: {}
195 - connectionCheckedOutEvent: {}
196 - connectionCheckedInEvent: {}
197 # Events for the transactional insert and commit.
198 - connectionCheckedOutEvent: {}
199
200 # Errors during abort are different than errors during commit and CRUD operations because the pinned connection is
201 # always released after abort.
202 - description: pinned connection is released after a non-transient abort error
203 operations:
204 - name: failPoint
205 object: testRunner
206 arguments:
207 client: *client0
208 failPoint:
209 configureFailPoint: failCommand
210 mode: { times: 1 }
211 data:
212 failCommands: [ abortTransaction ]
213 errorCode: &nonTransientErrorCode 51 # ManualInterventionRequired
214 - *startTransaction
215 - *transactionalInsert
216 - name: abortTransaction
217 object: *session0
218 - &assertConnectionNotPinned
219 name: assertNumberConnectionsCheckedOut
220 object: testRunner
221 arguments:
222 client: *client0
223 connections: 0
224 expectEvents:
225 - client: *client0
226 events:
227 - *insertStarted
228 - &abortStarted
229 commandStartedEvent:
230 commandName: abortTransaction
231 - client: *client0
232 eventType: cmap
233 events:
234 # Events for setting the fail point.
235 - connectionReadyEvent: {}
236 - connectionCheckedOutEvent: {}
237 - connectionCheckedInEvent: {}
238 # Events for the transactional insert and abort.
239 - connectionCheckedOutEvent: {}
240 - connectionCheckedInEvent: {}
241
242 - description: pinned connection is released after a transient non-network CRUD error
243 runOnRequirements:
244 - serverless: forbid # (CLOUDP-88216) Serverless does not append error labels to errors triggered by failpoints.
245 operations:
246 - name: failPoint
247 object: testRunner
248 arguments:
249 client: *client0
250 failPoint:
251 configureFailPoint: failCommand
252 mode: { times: 1 }
253 data:
254 failCommands: [ insert ]
255 errorCode: &transientErrorCode 24 # LockTimeout
256 - *startTransaction
257 - <<: *transactionalInsert
258 expectError: &transientExpectedServerError
259 errorCode: *transientErrorCode
260 errorLabelsContain: [ TransientTransactionError ]
261 - *assertConnectionNotPinned
262 - name: abortTransaction
263 object: *session0
264 - *assertConnectionNotPinned
265 expectEvents:
266 - client: *client0
267 events:
268 - *insertStarted
269 - *abortStarted
270 - client: *client0
271 eventType: cmap
272 events:
273 # Events for setting the failpoint.
274 - connectionReadyEvent: {}
275 - connectionCheckedOutEvent: {}
276 - connectionCheckedInEvent: {}
277 # Events for the insert.
278 - connectionCheckedOutEvent: {}
279 - connectionCheckedInEvent: {}
280 # Events for abortTransction.
281 - connectionCheckedOutEvent: {}
282 - connectionCheckedInEvent: {}
283
284 - description: pinned connection is released after a transient network CRUD error
285 runOnRequirements:
286 - serverless: forbid # (CLOUDP-88216) Serverless does not append error labels to errors triggered by failpoints.
287 operations:
288 - name: failPoint
289 object: testRunner
290 arguments:
291 client: *client0
292 failPoint:
293 configureFailPoint: failCommand
294 mode: { times: 1 }
295 data:
296 failCommands: [ insert ]
297 closeConnection: true
298 - *startTransaction
299 - <<: *transactionalInsert
300 expectError: &transientExpectedNetworkError
301 isClientError: true
302 errorLabelsContain: [ TransientTransactionError ]
303 - *assertConnectionNotPinned
304 - name: abortTransaction
305 object: *session0
306 - *assertConnectionNotPinned
307 expectEvents:
308 - client: *client0
309 events:
310 - *insertStarted
311 - *abortStarted
312 - client: *client0
313 eventType: cmap
314 events:
315 # Events for setting the failpoint.
316 - connectionReadyEvent: {}
317 - connectionCheckedOutEvent: {}
318 - connectionCheckedInEvent: {}
319 # Events for the insert.
320 - connectionCheckedOutEvent: {}
321 - connectionCheckedInEvent: {}
322 - connectionClosedEvent:
323 reason: error
324 # Events for abortTransaction
325 - connectionReadyEvent: {}
326 - connectionCheckedOutEvent: {}
327 - connectionCheckedInEvent: {}
328
329 - description: pinned connection is released after a transient non-network commit error
330 runOnRequirements:
331 - serverless: forbid # (CLOUDP-88216) Serverless does not append error labels to errors triggered by failpoints.
332 operations:
333 - name: failPoint
334 object: testRunner
335 arguments:
336 client: *client0
337 failPoint:
338 configureFailPoint: failCommand
339 mode: { times: 1 }
340 data:
341 failCommands: [ commitTransaction ]
342 errorCode: *transientErrorCode
343 - *startTransaction
344 - *transactionalInsert
345 - <<: *commitTransaction
346 expectError: *transientExpectedServerError
347 - *assertConnectionNotPinned
348 expectEvents:
349 - client: *client0
350 events:
351 - *insertStarted
352 - *commitStarted
353 - client: *client0
354 eventType: cmap
355 events:
356 # Events for setting the failpoint.
357 - connectionReadyEvent: {}
358 - connectionCheckedOutEvent: {}
359 - connectionCheckedInEvent: {}
360 # Events for the insert.
361 - connectionCheckedOutEvent: {}
362 # Events for commitTransaction.
363 - connectionCheckedInEvent: {}
364
365 - description: pinned connection is released after a transient network commit error
366 operations:
367 - name: failPoint
368 object: testRunner
369 arguments:
370 client: *client0
371 failPoint:
372 configureFailPoint: failCommand
373 mode: { times: 1 }
374 data:
375 failCommands: [ commitTransaction ]
376 closeConnection: true
377 - *startTransaction
378 - *transactionalInsert
379 - <<: *commitTransaction
380 # Ignore the result and error because the operation might fail if it targets a new mongos that isn't aware of
381 # the transaction or the server-side reaper thread closes the transaction first. We only want to assert that
382 # the operation is retried, which is done via monitoring expectations, so the exact result/error is not
383 # necessary.
384 ignoreResultAndError: true
385 - *assertConnectionNotPinned
386 expectEvents:
387 - client: *client0
388 events:
389 - *insertStarted
390 - *commitStarted
391 # The commit will be automatically retried.
392 - *commitStarted
393 - client: *client0
394 eventType: cmap
395 events:
396 # Events for setting the failpoint.
397 - connectionReadyEvent: {}
398 - connectionCheckedOutEvent: {}
399 - connectionCheckedInEvent: {}
400 # Events for the insert.
401 - connectionCheckedOutEvent: {}
402 # Events for the first commitTransaction.
403 - connectionCheckedInEvent: {}
404 - connectionClosedEvent:
405 reason: error
406 # Events for the commitTransaction retry.
407 - connectionReadyEvent: {}
408 - connectionCheckedOutEvent: {}
409 - connectionCheckedInEvent: {}
410
411 - description: pinned connection is released after a transient non-network abort error
412 operations:
413 - name: failPoint
414 object: testRunner
415 arguments:
416 client: *client0
417 failPoint:
418 configureFailPoint: failCommand
419 mode: { times: 1 }
420 data:
421 failCommands: [ abortTransaction ]
422 errorCode: *transientErrorCode
423 - *startTransaction
424 - *transactionalInsert
425 - name: abortTransaction
426 object: *session0
427 - *assertConnectionNotPinned
428 expectEvents:
429 - client: *client0
430 events:
431 - *insertStarted
432 - *abortStarted
433 - client: *client0
434 eventType: cmap
435 events:
436 # Events for setting the failpoint.
437 - connectionReadyEvent: {}
438 - connectionCheckedOutEvent: {}
439 - connectionCheckedInEvent: {}
440 # Events for the insert.
441 - connectionCheckedOutEvent: {}
442 # Events for abortTransaction.
443 - connectionCheckedInEvent: {}
444
445 - description: pinned connection is released after a transient network abort error
446 operations:
447 - name: failPoint
448 object: testRunner
449 arguments:
450 client: *client0
451 failPoint:
452 configureFailPoint: failCommand
453 mode: { times: 1 }
454 data:
455 failCommands: [ abortTransaction ]
456 closeConnection: true
457 - *startTransaction
458 - *transactionalInsert
459 - name: abortTransaction
460 object: *session0
461 - *assertConnectionNotPinned
462 expectEvents:
463 - client: *client0
464 events:
465 - *insertStarted
466 - *abortStarted
467 # The abort will be automatically retried.
468 - *abortStarted
469 - client: *client0
470 eventType: cmap
471 events:
472 # Events for setting the failpoint.
473 - connectionReadyEvent: {}
474 - connectionCheckedOutEvent: {}
475 - connectionCheckedInEvent: {}
476 # Events for the insert.
477 - connectionCheckedOutEvent: {}
478 # Events for the first abortTransaction.
479 - connectionCheckedInEvent: {}
480 - connectionClosedEvent:
481 reason: error
482 # Events for the abortTransaction retry.
483 - connectionReadyEvent: {}
484 - connectionCheckedOutEvent: {}
485 - connectionCheckedInEvent: {}
486
487 - description: pinned connection is released on successful abort
488 operations:
489 - *startTransaction
490 - *transactionalInsert
491 - name: abortTransaction
492 object: *session0
493 - *assertConnectionNotPinned
494 expectEvents:
495 - client: *client0
496 events:
497 - *insertStarted
498 - *abortStarted
499 - client: *client0
500 eventType: cmap
501 events:
502 # The insert will create and pin a connection. The abort will use it and then unpin.
503 - connectionReadyEvent: {}
504 - connectionCheckedOutEvent: {}
505 - connectionCheckedInEvent: {}
506
507 - description: pinned connection is returned when a new transaction is started
508 operations:
509 - *startTransaction
510 - *transactionalInsert
511 - *commitTransaction
512 - *assertConnectionPinned
513 - *startTransaction
514 - *assertConnectionNotPinned # startTransaction will unpin the connection.
515 - *transactionalInsert
516 - *assertConnectionPinned # The first operation in the new transaction will pin the connection again.
517 - *commitTransaction
518 expectEvents:
519 - client: *client0
520 events:
521 - *insertStarted
522 - *commitStarted
523 - *insertStarted
524 - *commitStarted
525 - client: *client0
526 eventType: cmap
527 events:
528 # Events for the first insert and commit.
529 - connectionReadyEvent: {}
530 - connectionCheckedOutEvent: {}
531 # Events for startTransaction.
532 - connectionCheckedInEvent: {}
533 # Events for the second insert and commit.
534 - connectionCheckedOutEvent: {}
535
536 - description: pinned connection is returned when a non-transaction operation uses the session
537 operations:
538 - *startTransaction
539 - *transactionalInsert
540 - *commitTransaction
541 - *assertConnectionPinned
542 - *transactionalInsert
543 # The insert is a non-transactional operation that uses the session, so it unpins the connection.
544 - *assertConnectionNotPinned
545 expectEvents:
546 - client: *client0
547 events:
548 - *insertStarted
549 - *commitStarted
550 - *insertStarted
551 - client: *client0
552 eventType: cmap
553 events:
554 # Events for the first insert and commit.
555 - connectionReadyEvent: {}
556 - connectionCheckedOutEvent: {}
557 # Events for the second insert.
558 - connectionCheckedInEvent: {}
559 - connectionCheckedOutEvent: {}
560 - connectionCheckedInEvent: {}
561
562 - description: a connection can be shared by a transaction and a cursor
563 operations:
564 - *startTransaction
565 - *transactionalInsert
566 - *assertConnectionPinned
567 - name: createFindCursor
568 object: *collection0
569 arguments:
570 filter: {}
571 batchSize: 2
572 session: *session0
573 saveResultAsEntity: &cursor0 cursor0
574 - *assertConnectionPinned
575 - name: close
576 object: *cursor0
577 - *assertConnectionPinned
578 # Abort the transaction to ensure that the connection is unpinned.
579 - name: abortTransaction
580 object: *session0
581 - *assertConnectionNotPinned
582 expectEvents:
583 - client: *client0
584 events:
585 - *insertStarted
586 - commandStartedEvent:
587 commandName: find
588 - commandStartedEvent:
589 commandName: killCursors
590 - *abortStarted
591 - client: *client0
592 eventType: cmap
593 events:
594 # Events for the insert, find, and killCursors.
595 - connectionReadyEvent: {}
596 - connectionCheckedOutEvent: {}
597 # Events for abortTransaction.
598 - connectionCheckedInEvent: {}
View as plain text