From a6cdef88f81bd3e2570c0c88eb0a674142396fe6 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Mon, 6 Nov 2023 16:48:46 -0800 Subject: [PATCH] Automatically retry flaky tests See #19795 --- test/common.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/test/common.py b/test/common.py index 1a516d0ce37b5..51f7048896a75 100644 --- a/test/common.py +++ b/test/common.py @@ -146,11 +146,26 @@ def decorated(self, *args, **kwargs): return decorated -def flaky(note=''): +def flaky(note='', retries=3): assert not callable(note) + if EMTEST_SKIP_FLAKY: return unittest.skip(note) - return lambda f: f + + def decorated(f): + @wraps(f) + def modified(*args, **kwargs): + for i in range(retries): + try: + return f(*args, **kwargs) + except AssertionError as exc: + preserved_exc = exc + logging.info(f'Retrying flaky test (attempt {i}/{retries} failed): {exc}') + raise AssertionError('Flaky test has failed too many times') from preserved_exc + + return modified + + return decorated def disabled(note=''): @@ -288,6 +303,7 @@ def with_env_modify(updates): assert not callable(updates) def decorated(f): + @wraps(f) def modified(self, *args, **kwargs): with env_modify(updates): return f(self, *args, **kwargs)