diff --git a/lib/daemon.py b/lib/daemon.py index 0fba74db94a73dc838c6e9c50fcd432e7510f45f..ff7708972ea4d677d101c5e42e3324ae9aa044bf 100644 --- a/lib/daemon.py +++ b/lib/daemon.py @@ -166,7 +166,8 @@ class AsyncUDPSocket(asyncore.dispatcher): @return: True if some data has been handled, False otherwise """ - if utils.WaitForFdCondition(self, select.POLLIN, timeout) & select.POLLIN: + result = utils.WaitForFdCondition(self, select.POLLIN, timeout) + if result is not None and result & select.POLLIN: self.do_read() return True else: diff --git a/lib/utils.py b/lib/utils.py index c52e91ed29e00629c5f98dda298ec6280a34f1ea..c32ad206b0c42ca43674470e4824f22832403da6 100644 --- a/lib/utils.py +++ b/lib/utils.py @@ -1579,8 +1579,11 @@ def WaitForFdCondition(fdobj, event, timeout): """ if timeout is not None: retrywaiter = FdConditionWaiterHelper(timeout) - result = Retry(retrywaiter.Poll, RETRY_REMAINING_TIME, timeout, - args=(fdobj, event), wait_fn=retrywaiter.UpdateTimeout) + try: + result = Retry(retrywaiter.Poll, RETRY_REMAINING_TIME, timeout, + args=(fdobj, event), wait_fn=retrywaiter.UpdateTimeout) + except RetryTimeout: + result = None else: result = None while result is None: @@ -2606,6 +2609,9 @@ def Retry(fn, delay, timeout, args=None, wait_fn=time.sleep, return fn(*args) except RetryAgain: pass + except RetryTimeout: + raise errors.ProgrammerError("Nested retry loop detected that didn't" + " handle RetryTimeout") remaining_time = end_time - _time_fn() diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py index 17d10fea653bf2f643442a4c051df026ef6b0b4a..e8f14c3bfb6d4004ac19570200babbabfe66f968 100755 --- a/test/ganeti.utils_unittest.py +++ b/test/ganeti.utils_unittest.py @@ -1535,5 +1535,28 @@ class TestMakedirs(unittest.TestCase): self.assert_(os.path.isdir(path)) +class TestRetry(testutils.GanetiTestCase): + @staticmethod + def _RaiseRetryAgain(): + raise utils.RetryAgain() + + def _WrongNestedLoop(self): + return utils.Retry(self._RaiseRetryAgain, 0.01, 0.02) + + def testRaiseTimeout(self): + self.failUnlessRaises(utils.RetryTimeout, utils.Retry, + self._RaiseRetryAgain, 0.01, 0.02) + + def testComplete(self): + self.failUnlessEqual(utils.Retry(lambda: True, 0, 1), True) + + def testNestedLoop(self): + try: + self.failUnlessRaises(errors.ProgrammerError, utils.Retry, + self._WrongNestedLoop, 0, 1) + except utils.RetryTimeout: + self.fail("Didn't detect inner loop's exception") + + if __name__ == '__main__': testutils.GanetiTestProgram()