Skip to content

Commit 8341b71

Browse files
committed
add test
1 parent 0e28b77 commit 8341b71

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

test/asynchronous/test_transactions.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import asyncio
1919
import sys
20+
import time
2021
from io import BytesIO
2122
from test.asynchronous.utils_spec_runner import AsyncSpecRunner
2223

@@ -37,7 +38,11 @@
3738
from bson.raw_bson import RawBSONDocument
3839
from pymongo import WriteConcern, _csot
3940
from pymongo.asynchronous import client_session
40-
from pymongo.asynchronous.client_session import TransactionOptions
41+
from pymongo.asynchronous.client_session import (
42+
_BACKOFF_MAX,
43+
TransactionOptions,
44+
_set_backoff_initial,
45+
)
4146
from pymongo.asynchronous.command_cursor import AsyncCommandCursor
4247
from pymongo.asynchronous.cursor import AsyncCursor
4348
from pymongo.errors import (
@@ -613,6 +618,42 @@ async def callback(session):
613618
await s.with_transaction(callback)
614619
self.assertFalse(s.in_transaction)
615620

621+
@async_client_context.require_test_commands
622+
@async_client_context.require_transactions
623+
async def test_transaction_backoff(self):
624+
client = async_client_context.client
625+
coll = client[self.db.name].test
626+
# set fail point to trigger transaction failure and trigger backoff
627+
await self.set_fail_point(
628+
{
629+
"configureFailPoint": "failCommand",
630+
"mode": {"times": 3},
631+
"data": {
632+
"failCommands": ["commitTransaction"],
633+
"errorCode": 24,
634+
},
635+
}
636+
)
637+
self.addAsyncCleanup(
638+
self.set_fail_point, {"configureFailPoint": "failCommand", "mode": "off"}
639+
)
640+
641+
start = time.monotonic()
642+
643+
async def callback(session):
644+
await coll.insert_one({}, session=session)
645+
646+
total_backoff = 0
647+
async with self.client.start_session() as s:
648+
await s.with_transaction(callback)
649+
self.assertEqual(len(s._transaction_retry_backoffs), 3)
650+
for backoff in s._transaction_retry_backoffs:
651+
self.assertGreater(backoff, 0)
652+
total_backoff += backoff
653+
654+
end = time.monotonic()
655+
self.assertGreaterEqual(end - start, total_backoff)
656+
616657

617658
class TestOptionsInsideTransactionProse(AsyncTransactionsBase):
618659
@async_client_context.require_transactions

test/test_transactions.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import asyncio
1919
import sys
20+
import time
2021
from io import BytesIO
2122
from test.utils_spec_runner import SpecRunner
2223

@@ -48,7 +49,11 @@
4849
from pymongo.read_concern import ReadConcern
4950
from pymongo.read_preferences import ReadPreference
5051
from pymongo.synchronous import client_session
51-
from pymongo.synchronous.client_session import TransactionOptions
52+
from pymongo.synchronous.client_session import (
53+
_BACKOFF_MAX,
54+
TransactionOptions,
55+
_set_backoff_initial,
56+
)
5257
from pymongo.synchronous.command_cursor import CommandCursor
5358
from pymongo.synchronous.cursor import Cursor
5459

@@ -601,6 +606,40 @@ def callback(session):
601606
s.with_transaction(callback)
602607
self.assertFalse(s.in_transaction)
603608

609+
@client_context.require_test_commands
610+
@client_context.require_transactions
611+
def test_transaction_backoff(self):
612+
client = client_context.client
613+
coll = client[self.db.name].test
614+
# set fail point to trigger transaction failure and trigger backoff
615+
self.set_fail_point(
616+
{
617+
"configureFailPoint": "failCommand",
618+
"mode": {"times": 3},
619+
"data": {
620+
"failCommands": ["commitTransaction"],
621+
"errorCode": 24,
622+
},
623+
}
624+
)
625+
self.addCleanup(self.set_fail_point, {"configureFailPoint": "failCommand", "mode": "off"})
626+
627+
start = time.monotonic()
628+
629+
def callback(session):
630+
coll.insert_one({}, session=session)
631+
632+
total_backoff = 0
633+
with self.client.start_session() as s:
634+
s.with_transaction(callback)
635+
self.assertEqual(len(s._transaction_retry_backoffs), 3)
636+
for backoff in s._transaction_retry_backoffs:
637+
self.assertGreater(backoff, 0)
638+
total_backoff += backoff
639+
640+
end = time.monotonic()
641+
self.assertGreaterEqual(end - start, total_backoff)
642+
604643

605644
class TestOptionsInsideTransactionProse(TransactionsBase):
606645
@client_context.require_transactions

0 commit comments

Comments
 (0)