Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.utils.retry_unittest.py @ 14933c17

History | View | Annotate | Download (7.1 kB)

1 79d22269 Michael Hanselmann
#!/usr/bin/python
2 79d22269 Michael Hanselmann
#
3 79d22269 Michael Hanselmann
4 79d22269 Michael Hanselmann
# Copyright (C) 2011 Google Inc.
5 79d22269 Michael Hanselmann
#
6 79d22269 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 79d22269 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 79d22269 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 79d22269 Michael Hanselmann
# (at your option) any later version.
10 79d22269 Michael Hanselmann
#
11 79d22269 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 79d22269 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 79d22269 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 79d22269 Michael Hanselmann
# General Public License for more details.
15 79d22269 Michael Hanselmann
#
16 79d22269 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 79d22269 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 79d22269 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 79d22269 Michael Hanselmann
# 02110-1301, USA.
20 79d22269 Michael Hanselmann
21 79d22269 Michael Hanselmann
22 79d22269 Michael Hanselmann
"""Script for testing ganeti.utils.retry"""
23 79d22269 Michael Hanselmann
24 79d22269 Michael Hanselmann
import unittest
25 79d22269 Michael Hanselmann
26 79d22269 Michael Hanselmann
from ganeti import constants
27 79d22269 Michael Hanselmann
from ganeti import errors
28 79d22269 Michael Hanselmann
from ganeti import utils
29 79d22269 Michael Hanselmann
30 79d22269 Michael Hanselmann
import testutils
31 79d22269 Michael Hanselmann
32 79d22269 Michael Hanselmann
33 79d22269 Michael Hanselmann
class TestRetry(testutils.GanetiTestCase):
34 79d22269 Michael Hanselmann
  def setUp(self):
35 79d22269 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
36 79d22269 Michael Hanselmann
    self.retries = 0
37 c7d3a832 Iustin Pop
    self.called = 0
38 38d1ee54 Klaus Aehlig
    self.time = 1379601882.0
39 32265e72 Klaus Aehlig
    self.time_for_time_fn = 0
40 32265e72 Klaus Aehlig
    self.time_for_retry_and_succeed = 0
41 38d1ee54 Klaus Aehlig
42 38d1ee54 Klaus Aehlig
  def _time_fn(self):
43 32265e72 Klaus Aehlig
    self.time += self.time_for_time_fn
44 38d1ee54 Klaus Aehlig
    return self.time
45 38d1ee54 Klaus Aehlig
46 38d1ee54 Klaus Aehlig
  def _wait_fn(self, delay):
47 38d1ee54 Klaus Aehlig
    self.time += delay
48 79d22269 Michael Hanselmann
49 79d22269 Michael Hanselmann
  @staticmethod
50 79d22269 Michael Hanselmann
  def _RaiseRetryAgain():
51 79d22269 Michael Hanselmann
    raise utils.RetryAgain()
52 79d22269 Michael Hanselmann
53 79d22269 Michael Hanselmann
  @staticmethod
54 79d22269 Michael Hanselmann
  def _RaiseRetryAgainWithArg(args):
55 79d22269 Michael Hanselmann
    raise utils.RetryAgain(*args)
56 79d22269 Michael Hanselmann
57 79d22269 Michael Hanselmann
  def _WrongNestedLoop(self):
58 79d22269 Michael Hanselmann
    return utils.Retry(self._RaiseRetryAgain, 0.01, 0.02)
59 79d22269 Michael Hanselmann
60 79d22269 Michael Hanselmann
  def _RetryAndSucceed(self, retries):
61 32265e72 Klaus Aehlig
    self.time += self.time_for_retry_and_succeed
62 79d22269 Michael Hanselmann
    if self.retries < retries:
63 79d22269 Michael Hanselmann
      self.retries += 1
64 79d22269 Michael Hanselmann
      raise utils.RetryAgain()
65 79d22269 Michael Hanselmann
    else:
66 79d22269 Michael Hanselmann
      return True
67 79d22269 Michael Hanselmann
68 c7d3a832 Iustin Pop
  def _SimpleRetryAndSucceed(self, retries):
69 c7d3a832 Iustin Pop
    self.called += 1
70 c7d3a832 Iustin Pop
    if self.retries < retries:
71 c7d3a832 Iustin Pop
      self.retries += 1
72 c7d3a832 Iustin Pop
      return False
73 c7d3a832 Iustin Pop
    else:
74 c7d3a832 Iustin Pop
      return True
75 c7d3a832 Iustin Pop
76 79d22269 Michael Hanselmann
  def testRaiseTimeout(self):
77 79d22269 Michael Hanselmann
    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
78 38d1ee54 Klaus Aehlig
                          self._RaiseRetryAgain, 0.01, 0.02,
79 38d1ee54 Klaus Aehlig
                          wait_fn = self._wait_fn, _time_fn = self._time_fn)
80 79d22269 Michael Hanselmann
    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
81 38d1ee54 Klaus Aehlig
                          self._RetryAndSucceed, 0.01, 0, args=[1],
82 38d1ee54 Klaus Aehlig
                          wait_fn = self._wait_fn, _time_fn = self._time_fn)
83 79d22269 Michael Hanselmann
    self.failUnlessEqual(self.retries, 1)
84 79d22269 Michael Hanselmann
85 79d22269 Michael Hanselmann
  def testComplete(self):
86 38d1ee54 Klaus Aehlig
    self.failUnlessEqual(utils.Retry(lambda: True, 0, 1,
87 38d1ee54 Klaus Aehlig
                                     wait_fn = self._wait_fn,
88 38d1ee54 Klaus Aehlig
                                     _time_fn = self._time_fn),
89 38d1ee54 Klaus Aehlig
                         True)
90 38d1ee54 Klaus Aehlig
    self.failUnlessEqual(utils.Retry(self._RetryAndSucceed, 0, 1, args=[2],
91 38d1ee54 Klaus Aehlig
                                     wait_fn = self._wait_fn,
92 38d1ee54 Klaus Aehlig
                                     _time_fn = self._time_fn),
93 79d22269 Michael Hanselmann
                         True)
94 79d22269 Michael Hanselmann
    self.failUnlessEqual(self.retries, 2)
95 79d22269 Michael Hanselmann
96 32265e72 Klaus Aehlig
  def testCompleteNontrivialTimes(self):
97 32265e72 Klaus Aehlig
    self.time_for_time_fn = 0.01
98 32265e72 Klaus Aehlig
    self.time_for_retry_and_succeed = 0.1
99 32265e72 Klaus Aehlig
    self.failUnlessEqual(utils.Retry(self._RetryAndSucceed, 0, 1, args=[2],
100 32265e72 Klaus Aehlig
                                     wait_fn = self._wait_fn,
101 32265e72 Klaus Aehlig
                                     _time_fn = self._time_fn),
102 32265e72 Klaus Aehlig
                         True)
103 32265e72 Klaus Aehlig
    self.failUnlessEqual(self.retries, 2)
104 32265e72 Klaus Aehlig
105 79d22269 Michael Hanselmann
  def testNestedLoop(self):
106 79d22269 Michael Hanselmann
    try:
107 79d22269 Michael Hanselmann
      self.failUnlessRaises(errors.ProgrammerError, utils.Retry,
108 38d1ee54 Klaus Aehlig
                            self._WrongNestedLoop, 0, 1,
109 38d1ee54 Klaus Aehlig
                            wait_fn = self._wait_fn, _time_fn = self._time_fn)
110 79d22269 Michael Hanselmann
    except utils.RetryTimeout:
111 79d22269 Michael Hanselmann
      self.fail("Didn't detect inner loop's exception")
112 79d22269 Michael Hanselmann
113 79d22269 Michael Hanselmann
  def testTimeoutArgument(self):
114 79d22269 Michael Hanselmann
    retry_arg="my_important_debugging_message"
115 79d22269 Michael Hanselmann
    try:
116 38d1ee54 Klaus Aehlig
      utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02, args=[[retry_arg]],
117 38d1ee54 Klaus Aehlig
                  wait_fn = self._wait_fn, _time_fn = self._time_fn)
118 79d22269 Michael Hanselmann
    except utils.RetryTimeout, err:
119 79d22269 Michael Hanselmann
      self.failUnlessEqual(err.args, (retry_arg, ))
120 79d22269 Michael Hanselmann
    else:
121 79d22269 Michael Hanselmann
      self.fail("Expected timeout didn't happen")
122 79d22269 Michael Hanselmann
123 32265e72 Klaus Aehlig
  def testTimeout(self):
124 32265e72 Klaus Aehlig
    self.time_for_time_fn = 0.01
125 32265e72 Klaus Aehlig
    self.time_for_retry_and_succeed = 10
126 32265e72 Klaus Aehlig
    try:
127 32265e72 Klaus Aehlig
      utils.Retry(self._RetryAndSucceed, 1, 18, args=[2],
128 32265e72 Klaus Aehlig
                  wait_fn = self._wait_fn, _time_fn = self._time_fn)
129 32265e72 Klaus Aehlig
    except utils.RetryTimeout, err:
130 32265e72 Klaus Aehlig
      self.failUnlessEqual(err.args, ())
131 32265e72 Klaus Aehlig
    else:
132 32265e72 Klaus Aehlig
      self.fail("Expected timeout didn't happen")
133 32265e72 Klaus Aehlig
134 32265e72 Klaus Aehlig
  def testNoTimeout(self):
135 32265e72 Klaus Aehlig
    self.time_for_time_fn = 0.01
136 32265e72 Klaus Aehlig
    self.time_for_retry_and_succeed = 8
137 32265e72 Klaus Aehlig
    self.failUnlessEqual(
138 32265e72 Klaus Aehlig
      utils.Retry(self._RetryAndSucceed, 1, 18, args=[2],
139 32265e72 Klaus Aehlig
                  wait_fn = self._wait_fn, _time_fn = self._time_fn),
140 32265e72 Klaus Aehlig
      True)
141 32265e72 Klaus Aehlig
142 79d22269 Michael Hanselmann
  def testRaiseInnerWithExc(self):
143 79d22269 Michael Hanselmann
    retry_arg="my_important_debugging_message"
144 79d22269 Michael Hanselmann
    try:
145 79d22269 Michael Hanselmann
      try:
146 79d22269 Michael Hanselmann
        utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02,
147 38d1ee54 Klaus Aehlig
                    args=[[errors.GenericError(retry_arg, retry_arg)]],
148 38d1ee54 Klaus Aehlig
                    wait_fn = self._wait_fn, _time_fn = self._time_fn)
149 79d22269 Michael Hanselmann
      except utils.RetryTimeout, err:
150 79d22269 Michael Hanselmann
        err.RaiseInner()
151 79d22269 Michael Hanselmann
      else:
152 79d22269 Michael Hanselmann
        self.fail("Expected timeout didn't happen")
153 79d22269 Michael Hanselmann
    except errors.GenericError, err:
154 79d22269 Michael Hanselmann
      self.failUnlessEqual(err.args, (retry_arg, retry_arg))
155 79d22269 Michael Hanselmann
    else:
156 79d22269 Michael Hanselmann
      self.fail("Expected GenericError didn't happen")
157 79d22269 Michael Hanselmann
158 79d22269 Michael Hanselmann
  def testRaiseInnerWithMsg(self):
159 79d22269 Michael Hanselmann
    retry_arg="my_important_debugging_message"
160 79d22269 Michael Hanselmann
    try:
161 79d22269 Michael Hanselmann
      try:
162 79d22269 Michael Hanselmann
        utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02,
163 38d1ee54 Klaus Aehlig
                    args=[[retry_arg, retry_arg]],
164 38d1ee54 Klaus Aehlig
                    wait_fn = self._wait_fn, _time_fn = self._time_fn)
165 79d22269 Michael Hanselmann
      except utils.RetryTimeout, err:
166 79d22269 Michael Hanselmann
        err.RaiseInner()
167 79d22269 Michael Hanselmann
      else:
168 79d22269 Michael Hanselmann
        self.fail("Expected timeout didn't happen")
169 79d22269 Michael Hanselmann
    except utils.RetryTimeout, err:
170 79d22269 Michael Hanselmann
      self.failUnlessEqual(err.args, (retry_arg, retry_arg))
171 79d22269 Michael Hanselmann
    else:
172 79d22269 Michael Hanselmann
      self.fail("Expected RetryTimeout didn't happen")
173 79d22269 Michael Hanselmann
174 c7d3a832 Iustin Pop
  def testSimpleRetry(self):
175 38d1ee54 Klaus Aehlig
    self.assertFalse(utils.SimpleRetry(True, lambda: False, 0.01, 0.02,
176 38d1ee54 Klaus Aehlig
                                       wait_fn = self._wait_fn,
177 38d1ee54 Klaus Aehlig
                                       _time_fn = self._time_fn))
178 38d1ee54 Klaus Aehlig
    self.assertFalse(utils.SimpleRetry(lambda x: x, lambda: False, 0.01, 0.02,
179 38d1ee54 Klaus Aehlig
                                       wait_fn = self._wait_fn,
180 38d1ee54 Klaus Aehlig
                                       _time_fn = self._time_fn))
181 38d1ee54 Klaus Aehlig
    self.assertTrue(utils.SimpleRetry(True, lambda: True, 0, 1,
182 38d1ee54 Klaus Aehlig
                                      wait_fn = self._wait_fn,
183 38d1ee54 Klaus Aehlig
                                      _time_fn = self._time_fn))
184 38d1ee54 Klaus Aehlig
    self.assertTrue(utils.SimpleRetry(lambda x: x, lambda: True, 0, 1,
185 38d1ee54 Klaus Aehlig
                                      wait_fn = self._wait_fn,
186 38d1ee54 Klaus Aehlig
                                      _time_fn = self._time_fn))
187 38d1ee54 Klaus Aehlig
    self.assertTrue(utils.SimpleRetry(True, self._SimpleRetryAndSucceed, 0, 1,
188 38d1ee54 Klaus Aehlig
                                      args=[1], wait_fn = self._wait_fn,
189 38d1ee54 Klaus Aehlig
                                      _time_fn = self._time_fn))
190 c7d3a832 Iustin Pop
    self.assertEqual(self.retries, 1)
191 c7d3a832 Iustin Pop
    self.assertEqual(self.called, 2)
192 c7d3a832 Iustin Pop
    self.called = self.retries = 0
193 38d1ee54 Klaus Aehlig
    self.assertTrue(utils.SimpleRetry(True, self._SimpleRetryAndSucceed, 0, 1,
194 38d1ee54 Klaus Aehlig
                                      args=[2], wait_fn = self._wait_fn,
195 38d1ee54 Klaus Aehlig
                                      _time_fn = self._time_fn))
196 c7d3a832 Iustin Pop
    self.assertEqual(self.called, 3)
197 c7d3a832 Iustin Pop
198 79d22269 Michael Hanselmann
199 79d22269 Michael Hanselmann
if __name__ == "__main__":
200 79d22269 Michael Hanselmann
  testutils.GanetiTestProgram()