Revision d6491981 test/ganeti.utils.process_unittest.py

b/test/ganeti.utils.process_unittest.py
27 27
import os
28 28
import stat
29 29
import time
30
import select
30 31
import signal
31 32

  
32 33
from ganeti import constants
......
153 154
    self.assert_(utils.RunInSeparateProcess(self._TestRealProcess))
154 155

  
155 156

  
157
class _PostforkProcessReadyHelper:
158
  """A helper to use with _postfork_fn in RunCmd.
159

  
160
  It makes sure a process has reached a certain state by reading from a fifo.
161

  
162
  @ivar write_fd: The fd number to write to
163

  
164
  """
165
  def __init__(self, timeout):
166
    """Initialize the helper.
167

  
168
    @param fifo_dir: The dir where we can create the fifo
169
    @param timeout: The time in seconds to wait before giving up
170

  
171
    """
172
    self.timeout = timeout
173
    (self.read_fd, self.write_fd) = os.pipe()
174

  
175
  def Ready(self, pid):
176
    """Waits until the process is ready.
177

  
178
    @param pid: The pid of the process
179

  
180
    """
181
    (read_ready, _, _) = select.select([self.read_fd], [], [], self.timeout)
182

  
183
    if not read_ready:
184
      # We hit the timeout
185
      raise AssertionError("Timeout %d reached while waiting for process %d"
186
                           " to become ready" % (self.timeout, pid))
187

  
188
  def Cleanup(self):
189
    """Cleans up the helper.
190

  
191
    """
192
    os.close(self.read_fd)
193
    os.close(self.write_fd)
194

  
195

  
156 196
class TestRunCmd(testutils.GanetiTestCase):
157 197
  """Testing case for the RunCmd function"""
158 198

  
......
164 204
    self.fifo_file = os.path.join(self.fifo_tmpdir, "ganeti_test_fifo")
165 205
    os.mkfifo(self.fifo_file)
166 206

  
207
    # If the process is not ready after 20 seconds we have bigger issues
208
    self.proc_ready_helper = _PostforkProcessReadyHelper(20)
209

  
167 210
  def tearDown(self):
211
    self.proc_ready_helper.Cleanup()
168 212
    shutil.rmtree(self.fifo_tmpdir)
169 213
    testutils.GanetiTestCase.tearDown(self)
170 214

  
......
216 260
    self.assertEqual(result.output, "")
217 261

  
218 262
  def testTimeoutClean(self):
219
    cmd = "trap 'exit 0' TERM; read < %s" % self.fifo_file
220
    result = utils.RunCmd(["/bin/sh", "-c", cmd], timeout=0.2)
263
    cmd = ("trap 'exit 0' TERM; echo >&%d; read < %s" %
264
           (self.proc_ready_helper.write_fd, self.fifo_file))
265
    result = utils.RunCmd(["/bin/sh", "-c", cmd], timeout=0.2,
266
                          noclose_fds=[self.proc_ready_helper.write_fd],
267
                          _postfork_fn=self.proc_ready_helper.Ready)
221 268
    self.assertEqual(result.exit_code, 0)
222 269

  
223 270
  def testTimeoutKill(self):
224
    cmd = ["/bin/sh", "-c", "trap '' TERM; read < %s" % self.fifo_file]
271
    cmd = ["/bin/sh", "-c", "trap '' TERM; echo >&%d; read < %s" %
272
           (self.proc_ready_helper.write_fd, self.fifo_file)]
225 273
    timeout = 0.2
226 274
    (out, err, status, ta) = \
227 275
      utils.process._RunCmdPipe(cmd, {}, False, "/", False,
228
                                timeout, None, _linger_timeout=0.2)
276
                                timeout, [self.proc_ready_helper.write_fd],
277
                                _linger_timeout=0.2,
278
                                _postfork_fn=self.proc_ready_helper.Ready)
229 279
    self.assert_(status < 0)
230 280
    self.assertEqual(-status, signal.SIGKILL)
231 281

  
232 282
  def testTimeoutOutputAfterTerm(self):
233
    cmd = "trap 'echo sigtermed; exit 1' TERM; read < %s" % self.fifo_file
234
    result = utils.RunCmd(["/bin/sh", "-c", cmd], timeout=0.2)
283
    cmd = ("trap 'echo sigtermed; exit 1' TERM; echo >&%d; read < %s" %
284
           (self.proc_ready_helper.write_fd, self.fifo_file))
285
    result = utils.RunCmd(["/bin/sh", "-c", cmd], timeout=0.2,
286
                          noclose_fds=[self.proc_ready_helper.write_fd],
287
                          _postfork_fn=self.proc_ready_helper.Ready)
235 288
    self.assert_(result.failed)
236 289
    self.assertEqual(result.stdout, "sigtermed\n")
237 290

  

Also available in: Unified diff