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