opencas-test-framework/connection/utils/retry.py
Katarzyna Treder 5409fa9a40 Move retry to connection utils
Signed-off-by: Katarzyna Treder <katarzyna.treder@h-partners.com>
2024-12-10 12:54:18 +01:00

58 lines
1.9 KiB
Python

#
# Copyright(c) 2021 Intel Corporation
# SPDX-License-Identifier: BSD-3-Clause
#
from datetime import datetime, timedelta
from functools import partial
from core.test_run import TestRun
class Retry:
"""
The Retry class implements methods designed to retry execution until desired result.
The func parameter is meant to be a method. If this method needs args/kwargs, they should be
encapsulated with the method, i.e. using a partial function (an example of this is contained
within run_command_until_success())
"""
@classmethod
def run_command_until_success(
cls, command: str, retries: int = None, timeout: timedelta = None
):
# encapsulate method and args/kwargs as a partial function
func = partial(TestRun.executor.run_expect_success, command)
return cls.run_while_exception(func, retries=retries, timeout=timeout)
@classmethod
def run_while_exception(cls, func, retries: int = None, timeout: timedelta = None):
result = None
def wrapped_func():
nonlocal result
try:
result = func()
return True
except:
return False
cls.run_while_false(wrapped_func, retries=retries, timeout=timeout)
return result
@classmethod
def run_while_false(cls, func, retries: int = None, timeout: timedelta = None):
if retries is None and timeout is None:
raise AttributeError("At least one stop condition is required for Retry calls!")
start = datetime.now()
retry_calls = 0
result = func()
while not result:
result = func()
retry_calls += 1
if result \
or (timeout is not None and datetime.now() - start > timeout) \
or (retries is not None and retry_calls == retries):
break
return result