Skip to content

Commit 47df741

Browse files
committed
RetryAction test cases
1 parent b0a3c3e commit 47df741

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

libraries/botframework-connector/botframework/connector/retry_action.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
14
import asyncio
25
import random
3-
import time
46

57

68
class RetryAction:
@@ -21,10 +23,8 @@ async def run_async(
2123
and retry_exception_handler(ex, current_retry_count) == 429
2224
):
2325
await RetryAction._wait_with_jitter(delay)
24-
delay *= current_retry_count
25-
current_retry_count += 1
26-
else:
27-
break
26+
delay *= 2 # Exponential backoff
27+
current_retry_count += 1
2828
raise Exception(f"Failed after {max_retries} retries", errors)
2929

3030
@staticmethod
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
import asyncio
5+
import aiounittest
6+
from botframework.connector import RetryAction
7+
8+
class TestRetryAction(aiounittest.AsyncTestCase):
9+
def setUp(self):
10+
self.loop = asyncio.get_event_loop()
11+
12+
def test_retry_action_fails_after_max_retries(self):
13+
async def failing_task(retry_count):
14+
raise Exception(f"error {retry_count}")
15+
16+
with self.assertRaises(Exception) as context:
17+
self.loop.run_until_complete(
18+
RetryAction.run_async(failing_task, max_retries=3)
19+
)
20+
self.assertEqual(context.exception.args[0], "Failed after 3 retries")
21+
self.assertEqual(len(context.exception.args[1]), 3)
22+
23+
def test_retry_action_retries_and_succeeds(self):
24+
async def task(retry_count):
25+
if retry_count < 3:
26+
raise Exception(f"error {retry_count}")
27+
return "success"
28+
29+
result = self.loop.run_until_complete(
30+
RetryAction.run_async(task, max_retries=3)
31+
)
32+
self.assertEqual(result, "success")
33+
34+
def test_retry_action_with_jitter_delay(self):
35+
async def task(retry_count):
36+
if retry_count < 2:
37+
raise Exception("retry error")
38+
return "success"
39+
40+
async def mock_sleep(duration):
41+
pass
42+
43+
original_sleep = asyncio.sleep
44+
asyncio.sleep = mock_sleep
45+
46+
try:
47+
result = self.loop.run_until_complete(
48+
RetryAction.run_async(task, max_retries=3, initial_delay=100)
49+
)
50+
self.assertEqual(result, "success")
51+
finally:
52+
asyncio.sleep = original_sleep

0 commit comments

Comments
 (0)