From 0d75c4d0e3292ecb948511d725055f2022cca52e Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Fri, 21 Mar 2025 11:25:10 -0700 Subject: [PATCH] test: add exponential backoff retry for help command test --- tests/help/test_help.py | 54 +++++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/tests/help/test_help.py b/tests/help/test_help.py index 11102db28..a89c57073 100644 --- a/tests/help/test_help.py +++ b/tests/help/test_help.py @@ -1,5 +1,7 @@ import unittest +import time from unittest.mock import MagicMock +from requests.exceptions import ReadTimeout, ConnectionError import aider from aider.coders import Coder @@ -10,6 +12,40 @@ from aider.models import Model class TestHelp(unittest.TestCase): + @staticmethod + def retry_with_backoff(func, max_time=60, initial_delay=1, backoff_factor=2): + """ + Execute a function with exponential backoff retry logic. + + Args: + func: Function to execute + max_time: Maximum time in seconds to keep retrying + initial_delay: Initial delay between retries in seconds + backoff_factor: Multiplier for delay after each retry + + Returns: + The result of the function if successful + + Raises: + The last exception encountered if all retries fail + """ + start_time = time.time() + delay = initial_delay + last_exception = None + + while time.time() - start_time < max_time: + try: + return func() + except (ReadTimeout, ConnectionError) as e: + last_exception = e + time.sleep(delay) + delay = min(delay * backoff_factor, 15) # Cap max delay at 15 seconds + + # If we've exhausted our retry time, raise the last exception + if last_exception: + raise last_exception + raise Exception("Retry timeout exceeded but no exception was caught") + @classmethod def setUpClass(cls): io = InputOutput(pretty=False, yes=True) @@ -22,14 +58,18 @@ class TestHelp(unittest.TestCase): help_coder_run = MagicMock(return_value="") aider.coders.HelpCoder.run = help_coder_run - try: - commands.cmd_help("hi") - except aider.commands.SwitchCoder: - pass - else: - # If no exception was raised, fail the test - assert False, "SwitchCoder exception was not raised" + def run_help_command(): + try: + commands.cmd_help("hi") + except aider.commands.SwitchCoder: + pass + else: + # If no exception was raised, fail the test + assert False, "SwitchCoder exception was not raised" + # Use retry with backoff for the help command that loads models + cls.retry_with_backoff(run_help_command) + help_coder_run.assert_called_once() def test_init(self):