| import os |
| import unittest |
| |
| import common |
| |
| EMTEST_RETRY_COUNT = int(os.getenv('EMTEST_RETRY_COUNT', '0')) |
| |
| |
| class RetryableTestCase(unittest.TestCase): |
| """Alternative TestCase that supports retrying. |
| |
| This class patches in to the Python unittest TestCase object to incorporate |
| support for an environment variable EMTEST_RETRY_COUNT=x, which enables a |
| failed test to be automatically re-run to test if the failure might have been |
| due to an instability. |
| """ |
| |
| def run(self, result=None): |
| retries_left = EMTEST_RETRY_COUNT |
| |
| num_fails = len(result.failures) |
| num_errors = len(result.errors) |
| |
| while retries_left >= 0: |
| super().run(result) |
| |
| # The test passed if it didn't accumulate an error. |
| if len(result.failures) == num_fails and len(result.errors) == num_errors: |
| return |
| |
| retries_left -= 1 |
| if retries_left >= 0: |
| if len(result.failures) != num_fails: |
| err = result.failures.pop(-1) |
| elif len(result.errors) != num_errors: |
| err = result.errors.pop(-1) |
| else: |
| raise Exception('Internal error in RetryableTestCase: did not detect an error') |
| |
| common.record_flaky_test(self.id(), EMTEST_RETRY_COUNT - retries_left, EMTEST_RETRY_COUNT, err[1]) |