Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.utils.retry_unittest.py @ 32265e72

History | View | Annotate | Download (7.1 kB)

1
#!/usr/bin/python
2
#
3

    
4
# Copyright (C) 2011 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""Script for testing ganeti.utils.retry"""
23

    
24
import unittest
25

    
26
from ganeti import constants
27
from ganeti import errors
28
from ganeti import utils
29

    
30
import testutils
31

    
32

    
33
class TestRetry(testutils.GanetiTestCase):
34
  def setUp(self):
35
    testutils.GanetiTestCase.setUp(self)
36
    self.retries = 0
37
    self.called = 0
38
    self.time = 1379601882.0
39
    self.time_for_time_fn = 0
40
    self.time_for_retry_and_succeed = 0
41

    
42
  def _time_fn(self):
43
    self.time += self.time_for_time_fn
44
    return self.time
45

    
46
  def _wait_fn(self, delay):
47
    self.time += delay
48

    
49
  @staticmethod
50
  def _RaiseRetryAgain():
51
    raise utils.RetryAgain()
52

    
53
  @staticmethod
54
  def _RaiseRetryAgainWithArg(args):
55
    raise utils.RetryAgain(*args)
56

    
57
  def _WrongNestedLoop(self):
58
    return utils.Retry(self._RaiseRetryAgain, 0.01, 0.02)
59

    
60
  def _RetryAndSucceed(self, retries):
61
    self.time += self.time_for_retry_and_succeed
62
    if self.retries < retries:
63
      self.retries += 1
64
      raise utils.RetryAgain()
65
    else:
66
      return True
67

    
68
  def _SimpleRetryAndSucceed(self, retries):
69
    self.called += 1
70
    if self.retries < retries:
71
      self.retries += 1
72
      return False
73
    else:
74
      return True
75

    
76
  def testRaiseTimeout(self):
77
    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
78
                          self._RaiseRetryAgain, 0.01, 0.02,
79
                          wait_fn = self._wait_fn, _time_fn = self._time_fn)
80
    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
81
                          self._RetryAndSucceed, 0.01, 0, args=[1],
82
                          wait_fn = self._wait_fn, _time_fn = self._time_fn)
83
    self.failUnlessEqual(self.retries, 1)
84

    
85
  def testComplete(self):
86
    self.failUnlessEqual(utils.Retry(lambda: True, 0, 1,
87
                                     wait_fn = self._wait_fn,
88
                                     _time_fn = self._time_fn),
89
                         True)
90
    self.failUnlessEqual(utils.Retry(self._RetryAndSucceed, 0, 1, args=[2],
91
                                     wait_fn = self._wait_fn,
92
                                     _time_fn = self._time_fn),
93
                         True)
94
    self.failUnlessEqual(self.retries, 2)
95

    
96
  def testCompleteNontrivialTimes(self):
97
    self.time_for_time_fn = 0.01
98
    self.time_for_retry_and_succeed = 0.1
99
    self.failUnlessEqual(utils.Retry(self._RetryAndSucceed, 0, 1, args=[2],
100
                                     wait_fn = self._wait_fn,
101
                                     _time_fn = self._time_fn),
102
                         True)
103
    self.failUnlessEqual(self.retries, 2)
104

    
105
  def testNestedLoop(self):
106
    try:
107
      self.failUnlessRaises(errors.ProgrammerError, utils.Retry,
108
                            self._WrongNestedLoop, 0, 1,
109
                            wait_fn = self._wait_fn, _time_fn = self._time_fn)
110
    except utils.RetryTimeout:
111
      self.fail("Didn't detect inner loop's exception")
112

    
113
  def testTimeoutArgument(self):
114
    retry_arg="my_important_debugging_message"
115
    try:
116
      utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02, args=[[retry_arg]],
117
                  wait_fn = self._wait_fn, _time_fn = self._time_fn)
118
    except utils.RetryTimeout, err:
119
      self.failUnlessEqual(err.args, (retry_arg, ))
120
    else:
121
      self.fail("Expected timeout didn't happen")
122

    
123
  def testTimeout(self):
124
    self.time_for_time_fn = 0.01
125
    self.time_for_retry_and_succeed = 10
126
    try:
127
      utils.Retry(self._RetryAndSucceed, 1, 18, args=[2],
128
                  wait_fn = self._wait_fn, _time_fn = self._time_fn)
129
    except utils.RetryTimeout, err:
130
      self.failUnlessEqual(err.args, ())
131
    else:
132
      self.fail("Expected timeout didn't happen")
133

    
134
  def testNoTimeout(self):
135
    self.time_for_time_fn = 0.01
136
    self.time_for_retry_and_succeed = 8
137
    self.failUnlessEqual(
138
      utils.Retry(self._RetryAndSucceed, 1, 18, args=[2],
139
                  wait_fn = self._wait_fn, _time_fn = self._time_fn),
140
      True)
141

    
142
  def testRaiseInnerWithExc(self):
143
    retry_arg="my_important_debugging_message"
144
    try:
145
      try:
146
        utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02,
147
                    args=[[errors.GenericError(retry_arg, retry_arg)]],
148
                    wait_fn = self._wait_fn, _time_fn = self._time_fn)
149
      except utils.RetryTimeout, err:
150
        err.RaiseInner()
151
      else:
152
        self.fail("Expected timeout didn't happen")
153
    except errors.GenericError, err:
154
      self.failUnlessEqual(err.args, (retry_arg, retry_arg))
155
    else:
156
      self.fail("Expected GenericError didn't happen")
157

    
158
  def testRaiseInnerWithMsg(self):
159
    retry_arg="my_important_debugging_message"
160
    try:
161
      try:
162
        utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02,
163
                    args=[[retry_arg, retry_arg]],
164
                    wait_fn = self._wait_fn, _time_fn = self._time_fn)
165
      except utils.RetryTimeout, err:
166
        err.RaiseInner()
167
      else:
168
        self.fail("Expected timeout didn't happen")
169
    except utils.RetryTimeout, err:
170
      self.failUnlessEqual(err.args, (retry_arg, retry_arg))
171
    else:
172
      self.fail("Expected RetryTimeout didn't happen")
173

    
174
  def testSimpleRetry(self):
175
    self.assertFalse(utils.SimpleRetry(True, lambda: False, 0.01, 0.02,
176
                                       wait_fn = self._wait_fn,
177
                                       _time_fn = self._time_fn))
178
    self.assertFalse(utils.SimpleRetry(lambda x: x, lambda: False, 0.01, 0.02,
179
                                       wait_fn = self._wait_fn,
180
                                       _time_fn = self._time_fn))
181
    self.assertTrue(utils.SimpleRetry(True, lambda: True, 0, 1,
182
                                      wait_fn = self._wait_fn,
183
                                      _time_fn = self._time_fn))
184
    self.assertTrue(utils.SimpleRetry(lambda x: x, lambda: True, 0, 1,
185
                                      wait_fn = self._wait_fn,
186
                                      _time_fn = self._time_fn))
187
    self.assertTrue(utils.SimpleRetry(True, self._SimpleRetryAndSucceed, 0, 1,
188
                                      args=[1], wait_fn = self._wait_fn,
189
                                      _time_fn = self._time_fn))
190
    self.assertEqual(self.retries, 1)
191
    self.assertEqual(self.called, 2)
192
    self.called = self.retries = 0
193
    self.assertTrue(utils.SimpleRetry(True, self._SimpleRetryAndSucceed, 0, 1,
194
                                      args=[2], wait_fn = self._wait_fn,
195
                                      _time_fn = self._time_fn))
196
    self.assertEqual(self.called, 3)
197

    
198

    
199
if __name__ == "__main__":
200
  testutils.GanetiTestProgram()