|
20 | 20 | import sys |
21 | 21 | import time |
22 | 22 | from io import BytesIO |
| 23 | +from unittest.mock import patch |
23 | 24 |
|
24 | 25 | import pymongo |
25 | 26 | from gridfs.asynchronous.grid_file import AsyncGridFS, AsyncGridFSBucket |
@@ -654,66 +655,57 @@ async def callback(session): |
654 | 655 | async def test_4_retry_backoff_is_enforced(self): |
655 | 656 | client = async_client_context.client |
656 | 657 | coll = client[self.db.name].test |
657 | | - # patch random to make it deterministic -- once to effectively have |
658 | | - # no backoff and the second time with "max" backoff (always waiting the longest |
659 | | - # possible time) |
660 | | - _original_random_random = random.random |
661 | | - |
662 | | - def always_one(): |
663 | | - return 1 |
664 | | - |
665 | | - def always_zero(): |
666 | | - return 0 |
667 | | - |
668 | | - random.random = always_zero |
669 | | - # set fail point to trigger transaction failure and trigger backoff |
670 | | - await self.set_fail_point( |
671 | | - { |
672 | | - "configureFailPoint": "failCommand", |
673 | | - "mode": {"times": 13}, |
674 | | - "data": { |
675 | | - "failCommands": ["commitTransaction"], |
676 | | - "errorCode": 251, |
677 | | - }, |
678 | | - } |
679 | | - ) |
680 | | - self.addAsyncCleanup( |
681 | | - self.set_fail_point, {"configureFailPoint": "failCommand", "mode": "off"} |
682 | | - ) |
683 | | - |
684 | | - async def callback(session): |
685 | | - await coll.insert_one({}, session=session) |
686 | | - |
687 | | - start = time.monotonic() |
688 | | - async with self.client.start_session() as s: |
689 | | - await s.with_transaction(callback) |
690 | | - end = time.monotonic() |
691 | | - no_backoff_time = end - start |
692 | | - |
693 | | - random.random = always_one |
694 | | - # set fail point to trigger transaction failure and trigger backoff |
695 | | - await self.set_fail_point( |
696 | | - { |
697 | | - "configureFailPoint": "failCommand", |
698 | | - "mode": { |
699 | | - "times": 13 |
700 | | - }, # sufficiently high enough such that the time effect of backoff is noticeable |
701 | | - "data": { |
702 | | - "failCommands": ["commitTransaction"], |
703 | | - "errorCode": 251, |
704 | | - }, |
705 | | - } |
706 | | - ) |
707 | | - self.addAsyncCleanup( |
708 | | - self.set_fail_point, {"configureFailPoint": "failCommand", "mode": "off"} |
709 | | - ) |
710 | | - start = time.monotonic() |
711 | | - async with self.client.start_session() as s: |
712 | | - await s.with_transaction(callback) |
713 | | - end = time.monotonic() |
714 | | - self.assertLess(abs(end - start - (no_backoff_time + 2.2)), 1) # sum of 13 backoffs is 2.2 |
| 658 | + end = start = no_backoff_time = 0 |
| 659 | + |
| 660 | + # Make random.random always return 0 (no backoff) |
| 661 | + with patch.object(random, "random", return_value=0): |
| 662 | + # set fail point to trigger transaction failure and trigger backoff |
| 663 | + await self.set_fail_point( |
| 664 | + { |
| 665 | + "configureFailPoint": "failCommand", |
| 666 | + "mode": {"times": 13}, |
| 667 | + "data": { |
| 668 | + "failCommands": ["commitTransaction"], |
| 669 | + "errorCode": 251, |
| 670 | + }, |
| 671 | + } |
| 672 | + ) |
| 673 | + self.addAsyncCleanup( |
| 674 | + self.set_fail_point, {"configureFailPoint": "failCommand", "mode": "off"} |
| 675 | + ) |
715 | 676 |
|
716 | | - random.random = _original_random_random |
| 677 | + async def callback(session): |
| 678 | + await coll.insert_one({}, session=session) |
| 679 | + |
| 680 | + start = time.monotonic() |
| 681 | + async with self.client.start_session() as s: |
| 682 | + await s.with_transaction(callback) |
| 683 | + end = time.monotonic() |
| 684 | + no_backoff_time = end - start |
| 685 | + |
| 686 | + # Make random.random always return 1 (max backoff) |
| 687 | + with patch.object(random, "random", return_value=1): |
| 688 | + # set fail point to trigger transaction failure and trigger backoff |
| 689 | + await self.set_fail_point( |
| 690 | + { |
| 691 | + "configureFailPoint": "failCommand", |
| 692 | + "mode": { |
| 693 | + "times": 13 |
| 694 | + }, # sufficiently high enough such that the time effect of backoff is noticeable |
| 695 | + "data": { |
| 696 | + "failCommands": ["commitTransaction"], |
| 697 | + "errorCode": 251, |
| 698 | + }, |
| 699 | + } |
| 700 | + ) |
| 701 | + self.addAsyncCleanup( |
| 702 | + self.set_fail_point, {"configureFailPoint": "failCommand", "mode": "off"} |
| 703 | + ) |
| 704 | + start = time.monotonic() |
| 705 | + async with self.client.start_session() as s: |
| 706 | + await s.with_transaction(callback) |
| 707 | + end = time.monotonic() |
| 708 | + self.assertLess(abs(end - start - (no_backoff_time + 2.2)), 1) # sum of 5 backoffs is 2.2 |
717 | 709 |
|
718 | 710 |
|
719 | 711 | class TestOptionsInsideTransactionProse(AsyncTransactionsBase): |
|
0 commit comments