Revision 9dc47292 lib/cmdlib/test.py

b/lib/cmdlib/test.py
25 25
import shutil
26 26
import socket
27 27
import tempfile
28
import time
28 29

  
29 30
from ganeti import compat
30 31
from ganeti import constants
......
127 128
    self.needed_locks = {}
128 129
    self.needed_locks[locking.LEVEL_NODE] = self.op.on_node_uuids
129 130

  
130
  def _TestDelay(self):
131
    """Do the actual sleep.
131
  def _InterruptibleDelay(self):
132
    """Delays but provides the mechanisms necessary to interrupt the delay as
133
    needed.
134

  
135
    """
136
    socket_wrapper = TestSocketWrapper()
137
    sock, path = socket_wrapper.Create()
138

  
139
    self.Log(constants.ELOG_DELAY_TEST, (path,))
140

  
141
    try:
142
      sock.settimeout(self.op.duration)
143
      start = time.time()
144
      (conn, _) = sock.accept()
145
    except socket.timeout, _:
146
      # If we timed out, all is well
147
      return False
148
    finally:
149
      # Destroys the original socket, but the new connection is still usable
150
      socket_wrapper.Destroy()
151

  
152
    try:
153
      # Change to remaining time
154
      time_to_go = self.op.duration - (time.time() - start)
155
      self.Log(constants.ELOG_MESSAGE,
156
               "Received connection, time to go is %d" % time_to_go)
157
      if time_to_go < 0:
158
        time_to_go = 0
159
      # pylint: disable=E1101
160
      # Instance of '_socketobject' has no ... member
161
      conn.settimeout(time_to_go)
162
      conn.recv(1)
163
      # pylint: enable=E1101
164
    except socket.timeout, _:
165
      # A second timeout can occur if no data is sent
166
      return False
167
    finally:
168
      conn.close()
169

  
170
    self.Log(constants.ELOG_MESSAGE,
171
             "Interrupted, time spent waiting: %d" % (time.time() - start))
172

  
173
    # Reaching this point means we were interrupted
174
    return True
175

  
176
  def _UninterruptibleDelay(self):
177
    """Delays without allowing interruptions.
132 178

  
133 179
    """
134 180
    if self.op.on_node_uuids:
......
140 186
      if not utils.TestDelay(self.op.duration)[0]:
141 187
        raise errors.OpExecError("Error during master delay test")
142 188

  
189
  def _TestDelay(self):
190
    """Do the actual sleep.
191

  
192
    @rtype: bool
193
    @return: Whether the delay was interrupted
194

  
195
    """
196
    if self.op.interruptible:
197
      return self._InterruptibleDelay()
198
    else:
199
      self._UninterruptibleDelay()
200
      return False
201

  
143 202
  def Exec(self, feedback_fn):
144 203
    """Execute the test delay opcode, with the wanted repetitions.
145 204

  
146 205
    """
147 206
    if self.op.repeat == 0:
148
      self._TestDelay()
207
      i = self._TestDelay()
149 208
    else:
150 209
      top_value = self.op.repeat - 1
151 210
      for i in range(self.op.repeat):
152 211
        self.LogInfo("Test delay iteration %d/%d", i, top_value)
153
        self._TestDelay()
212
        # Break in case of interruption
213
        if self._TestDelay():
214
          break
154 215

  
155 216

  
156 217
class LUTestJqueue(NoHooksLU):

Also available in: Unified diff