Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils.process_unittest.py @ 3b877f08

History | View | Annotate | Download (21 kB)

1 a4ccecf6 Michael Hanselmann
#!/usr/bin/python
2 a4ccecf6 Michael Hanselmann
#
3 a4ccecf6 Michael Hanselmann
4 a4ccecf6 Michael Hanselmann
# Copyright (C) 2011 Google Inc.
5 a4ccecf6 Michael Hanselmann
#
6 a4ccecf6 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 a4ccecf6 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 a4ccecf6 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 a4ccecf6 Michael Hanselmann
# (at your option) any later version.
10 a4ccecf6 Michael Hanselmann
#
11 a4ccecf6 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 a4ccecf6 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a4ccecf6 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a4ccecf6 Michael Hanselmann
# General Public License for more details.
15 a4ccecf6 Michael Hanselmann
#
16 a4ccecf6 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 a4ccecf6 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 a4ccecf6 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a4ccecf6 Michael Hanselmann
# 02110-1301, USA.
20 a4ccecf6 Michael Hanselmann
21 a4ccecf6 Michael Hanselmann
22 a4ccecf6 Michael Hanselmann
"""Script for testing ganeti.utils.process"""
23 a4ccecf6 Michael Hanselmann
24 a4ccecf6 Michael Hanselmann
import unittest
25 a4ccecf6 Michael Hanselmann
import tempfile
26 a4ccecf6 Michael Hanselmann
import shutil
27 a4ccecf6 Michael Hanselmann
import os
28 a4ccecf6 Michael Hanselmann
import stat
29 a4ccecf6 Michael Hanselmann
import time
30 a4ccecf6 Michael Hanselmann
import signal
31 a4ccecf6 Michael Hanselmann
32 a4ccecf6 Michael Hanselmann
from ganeti import constants
33 a4ccecf6 Michael Hanselmann
from ganeti import utils
34 a4ccecf6 Michael Hanselmann
from ganeti import errors
35 a4ccecf6 Michael Hanselmann
36 a4ccecf6 Michael Hanselmann
import testutils
37 a4ccecf6 Michael Hanselmann
38 a4ccecf6 Michael Hanselmann
39 a4ccecf6 Michael Hanselmann
class TestIsProcessAlive(unittest.TestCase):
40 a4ccecf6 Michael Hanselmann
  """Testing case for IsProcessAlive"""
41 a4ccecf6 Michael Hanselmann
42 a4ccecf6 Michael Hanselmann
  def testExists(self):
43 a4ccecf6 Michael Hanselmann
    mypid = os.getpid()
44 a4ccecf6 Michael Hanselmann
    self.assert_(utils.IsProcessAlive(mypid), "can't find myself running")
45 a4ccecf6 Michael Hanselmann
46 a4ccecf6 Michael Hanselmann
  def testNotExisting(self):
47 a4ccecf6 Michael Hanselmann
    pid_non_existing = os.fork()
48 a4ccecf6 Michael Hanselmann
    if pid_non_existing == 0:
49 a4ccecf6 Michael Hanselmann
      os._exit(0)
50 a4ccecf6 Michael Hanselmann
    elif pid_non_existing < 0:
51 a4ccecf6 Michael Hanselmann
      raise SystemError("can't fork")
52 a4ccecf6 Michael Hanselmann
    os.waitpid(pid_non_existing, 0)
53 a4ccecf6 Michael Hanselmann
    self.assertFalse(utils.IsProcessAlive(pid_non_existing),
54 a4ccecf6 Michael Hanselmann
                     "nonexisting process detected")
55 a4ccecf6 Michael Hanselmann
56 a4ccecf6 Michael Hanselmann
57 a4ccecf6 Michael Hanselmann
class TestGetProcStatusPath(unittest.TestCase):
58 a4ccecf6 Michael Hanselmann
  def test(self):
59 a4ccecf6 Michael Hanselmann
    self.assert_("/1234/" in utils.process._GetProcStatusPath(1234))
60 a4ccecf6 Michael Hanselmann
    self.assertNotEqual(utils.process._GetProcStatusPath(1),
61 a4ccecf6 Michael Hanselmann
                        utils.process._GetProcStatusPath(2))
62 a4ccecf6 Michael Hanselmann
63 a4ccecf6 Michael Hanselmann
64 a4ccecf6 Michael Hanselmann
class TestIsProcessHandlingSignal(unittest.TestCase):
65 a4ccecf6 Michael Hanselmann
  def setUp(self):
66 a4ccecf6 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
67 a4ccecf6 Michael Hanselmann
68 a4ccecf6 Michael Hanselmann
  def tearDown(self):
69 a4ccecf6 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
70 a4ccecf6 Michael Hanselmann
71 a4ccecf6 Michael Hanselmann
  def testParseSigsetT(self):
72 a4ccecf6 Michael Hanselmann
    parse_sigset_t_fn = utils.process._ParseSigsetT
73 a4ccecf6 Michael Hanselmann
    self.assertEqual(len(parse_sigset_t_fn("0")), 0)
74 a4ccecf6 Michael Hanselmann
    self.assertEqual(parse_sigset_t_fn("1"), set([1]))
75 a4ccecf6 Michael Hanselmann
    self.assertEqual(parse_sigset_t_fn("1000a"), set([2, 4, 17]))
76 a4ccecf6 Michael Hanselmann
    self.assertEqual(parse_sigset_t_fn("810002"), set([2, 17, 24, ]))
77 a4ccecf6 Michael Hanselmann
    self.assertEqual(parse_sigset_t_fn("0000000180000202"),
78 a4ccecf6 Michael Hanselmann
                     set([2, 10, 32, 33]))
79 a4ccecf6 Michael Hanselmann
    self.assertEqual(parse_sigset_t_fn("0000000180000002"),
80 a4ccecf6 Michael Hanselmann
                     set([2, 32, 33]))
81 a4ccecf6 Michael Hanselmann
    self.assertEqual(parse_sigset_t_fn("0000000188000002"),
82 a4ccecf6 Michael Hanselmann
                     set([2, 28, 32, 33]))
83 a4ccecf6 Michael Hanselmann
    self.assertEqual(parse_sigset_t_fn("000000004b813efb"),
84 a4ccecf6 Michael Hanselmann
                     set([1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 17,
85 a4ccecf6 Michael Hanselmann
                          24, 25, 26, 28, 31]))
86 a4ccecf6 Michael Hanselmann
    self.assertEqual(parse_sigset_t_fn("ffffff"), set(range(1, 25)))
87 a4ccecf6 Michael Hanselmann
88 a4ccecf6 Michael Hanselmann
  def testGetProcStatusField(self):
89 a4ccecf6 Michael Hanselmann
    for field in ["SigCgt", "Name", "FDSize"]:
90 a4ccecf6 Michael Hanselmann
      for value in ["", "0", "cat", "  1234 KB"]:
91 a4ccecf6 Michael Hanselmann
        pstatus = "\n".join([
92 a4ccecf6 Michael Hanselmann
          "VmPeak: 999 kB",
93 a4ccecf6 Michael Hanselmann
          "%s: %s" % (field, value),
94 a4ccecf6 Michael Hanselmann
          "TracerPid: 0",
95 a4ccecf6 Michael Hanselmann
          ])
96 a4ccecf6 Michael Hanselmann
        result = utils.process._GetProcStatusField(pstatus, field)
97 a4ccecf6 Michael Hanselmann
        self.assertEqual(result, value.strip())
98 a4ccecf6 Michael Hanselmann
99 a4ccecf6 Michael Hanselmann
  def test(self):
100 a4ccecf6 Michael Hanselmann
    sp = utils.PathJoin(self.tmpdir, "status")
101 a4ccecf6 Michael Hanselmann
102 a4ccecf6 Michael Hanselmann
    utils.WriteFile(sp, data="\n".join([
103 a4ccecf6 Michael Hanselmann
      "Name:   bash",
104 a4ccecf6 Michael Hanselmann
      "State:  S (sleeping)",
105 a4ccecf6 Michael Hanselmann
      "SleepAVG:       98%",
106 a4ccecf6 Michael Hanselmann
      "Pid:    22250",
107 a4ccecf6 Michael Hanselmann
      "PPid:   10858",
108 a4ccecf6 Michael Hanselmann
      "TracerPid:      0",
109 a4ccecf6 Michael Hanselmann
      "SigBlk: 0000000000010000",
110 a4ccecf6 Michael Hanselmann
      "SigIgn: 0000000000384004",
111 a4ccecf6 Michael Hanselmann
      "SigCgt: 000000004b813efb",
112 a4ccecf6 Michael Hanselmann
      "CapEff: 0000000000000000",
113 a4ccecf6 Michael Hanselmann
      ]))
114 a4ccecf6 Michael Hanselmann
115 a4ccecf6 Michael Hanselmann
    self.assert_(utils.IsProcessHandlingSignal(1234, 10, status_path=sp))
116 a4ccecf6 Michael Hanselmann
117 a4ccecf6 Michael Hanselmann
  def testNoSigCgt(self):
118 a4ccecf6 Michael Hanselmann
    sp = utils.PathJoin(self.tmpdir, "status")
119 a4ccecf6 Michael Hanselmann
120 a4ccecf6 Michael Hanselmann
    utils.WriteFile(sp, data="\n".join([
121 a4ccecf6 Michael Hanselmann
      "Name:   bash",
122 a4ccecf6 Michael Hanselmann
      ]))
123 a4ccecf6 Michael Hanselmann
124 a4ccecf6 Michael Hanselmann
    self.assertRaises(RuntimeError, utils.IsProcessHandlingSignal,
125 a4ccecf6 Michael Hanselmann
                      1234, 10, status_path=sp)
126 a4ccecf6 Michael Hanselmann
127 a4ccecf6 Michael Hanselmann
  def testNoSuchFile(self):
128 a4ccecf6 Michael Hanselmann
    sp = utils.PathJoin(self.tmpdir, "notexist")
129 a4ccecf6 Michael Hanselmann
130 a4ccecf6 Michael Hanselmann
    self.assertFalse(utils.IsProcessHandlingSignal(1234, 10, status_path=sp))
131 a4ccecf6 Michael Hanselmann
132 a4ccecf6 Michael Hanselmann
  @staticmethod
133 a4ccecf6 Michael Hanselmann
  def _TestRealProcess():
134 a4ccecf6 Michael Hanselmann
    signal.signal(signal.SIGUSR1, signal.SIG_DFL)
135 a4ccecf6 Michael Hanselmann
    if utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
136 a4ccecf6 Michael Hanselmann
      raise Exception("SIGUSR1 is handled when it should not be")
137 a4ccecf6 Michael Hanselmann
138 a4ccecf6 Michael Hanselmann
    signal.signal(signal.SIGUSR1, lambda signum, frame: None)
139 a4ccecf6 Michael Hanselmann
    if not utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
140 a4ccecf6 Michael Hanselmann
      raise Exception("SIGUSR1 is not handled when it should be")
141 a4ccecf6 Michael Hanselmann
142 a4ccecf6 Michael Hanselmann
    signal.signal(signal.SIGUSR1, signal.SIG_IGN)
143 a4ccecf6 Michael Hanselmann
    if utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
144 a4ccecf6 Michael Hanselmann
      raise Exception("SIGUSR1 is not handled when it should be")
145 a4ccecf6 Michael Hanselmann
146 a4ccecf6 Michael Hanselmann
    signal.signal(signal.SIGUSR1, signal.SIG_DFL)
147 a4ccecf6 Michael Hanselmann
    if utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
148 a4ccecf6 Michael Hanselmann
      raise Exception("SIGUSR1 is handled when it should not be")
149 a4ccecf6 Michael Hanselmann
150 a4ccecf6 Michael Hanselmann
    return True
151 a4ccecf6 Michael Hanselmann
152 a4ccecf6 Michael Hanselmann
  def testRealProcess(self):
153 a4ccecf6 Michael Hanselmann
    self.assert_(utils.RunInSeparateProcess(self._TestRealProcess))
154 a4ccecf6 Michael Hanselmann
155 a4ccecf6 Michael Hanselmann
156 a4ccecf6 Michael Hanselmann
class TestRunCmd(testutils.GanetiTestCase):
157 a4ccecf6 Michael Hanselmann
  """Testing case for the RunCmd function"""
158 a4ccecf6 Michael Hanselmann
159 a4ccecf6 Michael Hanselmann
  def setUp(self):
160 a4ccecf6 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
161 a4ccecf6 Michael Hanselmann
    self.magic = time.ctime() + " ganeti test"
162 a4ccecf6 Michael Hanselmann
    self.fname = self._CreateTempFile()
163 a4ccecf6 Michael Hanselmann
    self.fifo_tmpdir = tempfile.mkdtemp()
164 a4ccecf6 Michael Hanselmann
    self.fifo_file = os.path.join(self.fifo_tmpdir, "ganeti_test_fifo")
165 a4ccecf6 Michael Hanselmann
    os.mkfifo(self.fifo_file)
166 a4ccecf6 Michael Hanselmann
167 a4ccecf6 Michael Hanselmann
  def tearDown(self):
168 a4ccecf6 Michael Hanselmann
    shutil.rmtree(self.fifo_tmpdir)
169 a4ccecf6 Michael Hanselmann
    testutils.GanetiTestCase.tearDown(self)
170 a4ccecf6 Michael Hanselmann
171 a4ccecf6 Michael Hanselmann
  def testOk(self):
172 a4ccecf6 Michael Hanselmann
    """Test successful exit code"""
173 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd("/bin/sh -c 'exit 0'")
174 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.exit_code, 0)
175 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.output, "")
176 a4ccecf6 Michael Hanselmann
177 a4ccecf6 Michael Hanselmann
  def testFail(self):
178 a4ccecf6 Michael Hanselmann
    """Test fail exit code"""
179 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd("/bin/sh -c 'exit 1'")
180 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.exit_code, 1)
181 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.output, "")
182 a4ccecf6 Michael Hanselmann
183 a4ccecf6 Michael Hanselmann
  def testStdout(self):
184 a4ccecf6 Michael Hanselmann
    """Test standard output"""
185 a4ccecf6 Michael Hanselmann
    cmd = 'echo -n "%s"' % self.magic
186 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd("/bin/sh -c '%s'" % cmd)
187 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.stdout, self.magic)
188 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd("/bin/sh -c '%s'" % cmd, output=self.fname)
189 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.output, "")
190 a4ccecf6 Michael Hanselmann
    self.assertFileContent(self.fname, self.magic)
191 a4ccecf6 Michael Hanselmann
192 a4ccecf6 Michael Hanselmann
  def testStderr(self):
193 a4ccecf6 Michael Hanselmann
    """Test standard error"""
194 a4ccecf6 Michael Hanselmann
    cmd = 'echo -n "%s"' % self.magic
195 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd("/bin/sh -c '%s' 1>&2" % cmd)
196 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.stderr, self.magic)
197 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd("/bin/sh -c '%s' 1>&2" % cmd, output=self.fname)
198 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.output, "")
199 a4ccecf6 Michael Hanselmann
    self.assertFileContent(self.fname, self.magic)
200 a4ccecf6 Michael Hanselmann
201 a4ccecf6 Michael Hanselmann
  def testCombined(self):
202 a4ccecf6 Michael Hanselmann
    """Test combined output"""
203 a4ccecf6 Michael Hanselmann
    cmd = 'echo -n "A%s"; echo -n "B%s" 1>&2' % (self.magic, self.magic)
204 a4ccecf6 Michael Hanselmann
    expected = "A" + self.magic + "B" + self.magic
205 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd("/bin/sh -c '%s'" % cmd)
206 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.output, expected)
207 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd("/bin/sh -c '%s'" % cmd, output=self.fname)
208 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.output, "")
209 a4ccecf6 Michael Hanselmann
    self.assertFileContent(self.fname, expected)
210 a4ccecf6 Michael Hanselmann
211 a4ccecf6 Michael Hanselmann
  def testSignal(self):
212 a4ccecf6 Michael Hanselmann
    """Test signal"""
213 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd(["python", "-c",
214 a4ccecf6 Michael Hanselmann
                           "import os; os.kill(os.getpid(), 15)"])
215 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.signal, 15)
216 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.output, "")
217 a4ccecf6 Michael Hanselmann
218 a4ccecf6 Michael Hanselmann
  def testTimeoutClean(self):
219 a4ccecf6 Michael Hanselmann
    cmd = "trap 'exit 0' TERM; read < %s" % self.fifo_file
220 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd(["/bin/sh", "-c", cmd], timeout=0.2)
221 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.exit_code, 0)
222 a4ccecf6 Michael Hanselmann
223 a4ccecf6 Michael Hanselmann
  def testTimeoutKill(self):
224 a4ccecf6 Michael Hanselmann
    cmd = ["/bin/sh", "-c", "trap '' TERM; read < %s" % self.fifo_file]
225 a4ccecf6 Michael Hanselmann
    timeout = 0.2
226 a4ccecf6 Michael Hanselmann
    (out, err, status, ta) = \
227 a4ccecf6 Michael Hanselmann
      utils.process._RunCmdPipe(cmd, {}, False, "/", False,
228 7b0bf9cd Apollon Oikonomopoulos
                                timeout, None, _linger_timeout=0.2)
229 a4ccecf6 Michael Hanselmann
    self.assert_(status < 0)
230 a4ccecf6 Michael Hanselmann
    self.assertEqual(-status, signal.SIGKILL)
231 a4ccecf6 Michael Hanselmann
232 a4ccecf6 Michael Hanselmann
  def testTimeoutOutputAfterTerm(self):
233 a4ccecf6 Michael Hanselmann
    cmd = "trap 'echo sigtermed; exit 1' TERM; read < %s" % self.fifo_file
234 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd(["/bin/sh", "-c", cmd], timeout=0.2)
235 a4ccecf6 Michael Hanselmann
    self.assert_(result.failed)
236 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.stdout, "sigtermed\n")
237 a4ccecf6 Michael Hanselmann
238 a4ccecf6 Michael Hanselmann
  def testListRun(self):
239 a4ccecf6 Michael Hanselmann
    """Test list runs"""
240 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd(["true"])
241 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.signal, None)
242 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.exit_code, 0)
243 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd(["/bin/sh", "-c", "exit 1"])
244 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.signal, None)
245 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.exit_code, 1)
246 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd(["echo", "-n", self.magic])
247 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.signal, None)
248 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.exit_code, 0)
249 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.stdout, self.magic)
250 a4ccecf6 Michael Hanselmann
251 a4ccecf6 Michael Hanselmann
  def testFileEmptyOutput(self):
252 a4ccecf6 Michael Hanselmann
    """Test file output"""
253 a4ccecf6 Michael Hanselmann
    result = utils.RunCmd(["true"], output=self.fname)
254 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.signal, None)
255 a4ccecf6 Michael Hanselmann
    self.assertEqual(result.exit_code, 0)
256 a4ccecf6 Michael Hanselmann
    self.assertFileContent(self.fname, "")
257 a4ccecf6 Michael Hanselmann
258 a4ccecf6 Michael Hanselmann
  def testLang(self):
259 a4ccecf6 Michael Hanselmann
    """Test locale environment"""
260 a4ccecf6 Michael Hanselmann
    old_env = os.environ.copy()
261 a4ccecf6 Michael Hanselmann
    try:
262 a4ccecf6 Michael Hanselmann
      os.environ["LANG"] = "en_US.UTF-8"
263 a4ccecf6 Michael Hanselmann
      os.environ["LC_ALL"] = "en_US.UTF-8"
264 a4ccecf6 Michael Hanselmann
      result = utils.RunCmd(["locale"])
265 a4ccecf6 Michael Hanselmann
      for line in result.output.splitlines():
266 a4ccecf6 Michael Hanselmann
        key, value = line.split("=", 1)
267 a4ccecf6 Michael Hanselmann
        # Ignore these variables, they're overridden by LC_ALL
268 a4ccecf6 Michael Hanselmann
        if key == "LANG" or key == "LANGUAGE":
269 a4ccecf6 Michael Hanselmann
          continue
270 a4ccecf6 Michael Hanselmann
        self.failIf(value and value != "C" and value != '"C"',
271 a4ccecf6 Michael Hanselmann
            "Variable %s is set to the invalid value '%s'" % (key, value))
272 a4ccecf6 Michael Hanselmann
    finally:
273 a4ccecf6 Michael Hanselmann
      os.environ = old_env
274 a4ccecf6 Michael Hanselmann
275 a4ccecf6 Michael Hanselmann
  def testDefaultCwd(self):
276 a4ccecf6 Michael Hanselmann
    """Test default working directory"""
277 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(utils.RunCmd(["pwd"]).stdout.strip(), "/")
278 a4ccecf6 Michael Hanselmann
279 a4ccecf6 Michael Hanselmann
  def testCwd(self):
280 a4ccecf6 Michael Hanselmann
    """Test default working directory"""
281 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(utils.RunCmd(["pwd"], cwd="/").stdout.strip(), "/")
282 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(utils.RunCmd(["pwd"], cwd="/tmp").stdout.strip(),
283 a4ccecf6 Michael Hanselmann
                         "/tmp")
284 a4ccecf6 Michael Hanselmann
    cwd = os.getcwd()
285 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(utils.RunCmd(["pwd"], cwd=cwd).stdout.strip(), cwd)
286 a4ccecf6 Michael Hanselmann
287 a4ccecf6 Michael Hanselmann
  def testResetEnv(self):
288 a4ccecf6 Michael Hanselmann
    """Test environment reset functionality"""
289 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(utils.RunCmd(["env"], reset_env=True).stdout.strip(),
290 a4ccecf6 Michael Hanselmann
                         "")
291 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(utils.RunCmd(["env"], reset_env=True,
292 a4ccecf6 Michael Hanselmann
                                      env={"FOO": "bar",}).stdout.strip(),
293 a4ccecf6 Michael Hanselmann
                         "FOO=bar")
294 a4ccecf6 Michael Hanselmann
295 a4ccecf6 Michael Hanselmann
  def testNoFork(self):
296 a4ccecf6 Michael Hanselmann
    """Test that nofork raise an error"""
297 a4ccecf6 Michael Hanselmann
    self.assertFalse(utils.process._no_fork)
298 a4ccecf6 Michael Hanselmann
    utils.DisableFork()
299 a4ccecf6 Michael Hanselmann
    try:
300 a4ccecf6 Michael Hanselmann
      self.assertTrue(utils.process._no_fork)
301 a4ccecf6 Michael Hanselmann
      self.assertRaises(errors.ProgrammerError, utils.RunCmd, ["true"])
302 a4ccecf6 Michael Hanselmann
    finally:
303 a4ccecf6 Michael Hanselmann
      utils.process._no_fork = False
304 a4ccecf6 Michael Hanselmann
    self.assertFalse(utils.process._no_fork)
305 a4ccecf6 Michael Hanselmann
306 a4ccecf6 Michael Hanselmann
  def testWrongParams(self):
307 a4ccecf6 Michael Hanselmann
    """Test wrong parameters"""
308 a4ccecf6 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, utils.RunCmd, ["true"],
309 a4ccecf6 Michael Hanselmann
                      output="/dev/null", interactive=True)
310 a4ccecf6 Michael Hanselmann
311 7b0bf9cd Apollon Oikonomopoulos
  def testNocloseFds(self):
312 7b0bf9cd Apollon Oikonomopoulos
    """Test selective fd retention (noclose_fds)"""
313 7b0bf9cd Apollon Oikonomopoulos
    temp = open(self.fname, "r+")
314 7b0bf9cd Apollon Oikonomopoulos
    try:
315 7b0bf9cd Apollon Oikonomopoulos
      temp.write("test")
316 7b0bf9cd Apollon Oikonomopoulos
      temp.seek(0)
317 7b0bf9cd Apollon Oikonomopoulos
      cmd = "read -u %d; echo $REPLY" % temp.fileno()
318 7b0bf9cd Apollon Oikonomopoulos
      result = utils.RunCmd(["/bin/bash", "-c", cmd])
319 7b0bf9cd Apollon Oikonomopoulos
      self.assertEqual(result.stdout.strip(), "")
320 7b0bf9cd Apollon Oikonomopoulos
      temp.seek(0)
321 7b0bf9cd Apollon Oikonomopoulos
      result = utils.RunCmd(["/bin/bash", "-c", cmd],
322 7b0bf9cd Apollon Oikonomopoulos
                            noclose_fds=[temp.fileno()])
323 7b0bf9cd Apollon Oikonomopoulos
      self.assertEqual(result.stdout.strip(), "test")
324 7b0bf9cd Apollon Oikonomopoulos
    finally:
325 7b0bf9cd Apollon Oikonomopoulos
      temp.close()
326 7b0bf9cd Apollon Oikonomopoulos
327 a4ccecf6 Michael Hanselmann
328 a4ccecf6 Michael Hanselmann
class TestRunParts(testutils.GanetiTestCase):
329 a4ccecf6 Michael Hanselmann
  """Testing case for the RunParts function"""
330 a4ccecf6 Michael Hanselmann
331 a4ccecf6 Michael Hanselmann
  def setUp(self):
332 a4ccecf6 Michael Hanselmann
    self.rundir = tempfile.mkdtemp(prefix="ganeti-test", suffix=".tmp")
333 a4ccecf6 Michael Hanselmann
334 a4ccecf6 Michael Hanselmann
  def tearDown(self):
335 a4ccecf6 Michael Hanselmann
    shutil.rmtree(self.rundir)
336 a4ccecf6 Michael Hanselmann
337 a4ccecf6 Michael Hanselmann
  def testEmpty(self):
338 a4ccecf6 Michael Hanselmann
    """Test on an empty dir"""
339 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(utils.RunParts(self.rundir, reset_env=True), [])
340 a4ccecf6 Michael Hanselmann
341 a4ccecf6 Michael Hanselmann
  def testSkipWrongName(self):
342 a4ccecf6 Michael Hanselmann
    """Test that wrong files are skipped"""
343 a4ccecf6 Michael Hanselmann
    fname = os.path.join(self.rundir, "00test.dot")
344 a4ccecf6 Michael Hanselmann
    utils.WriteFile(fname, data="")
345 a4ccecf6 Michael Hanselmann
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
346 a4ccecf6 Michael Hanselmann
    relname = os.path.basename(fname)
347 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(utils.RunParts(self.rundir, reset_env=True),
348 a4ccecf6 Michael Hanselmann
                         [(relname, constants.RUNPARTS_SKIP, None)])
349 a4ccecf6 Michael Hanselmann
350 a4ccecf6 Michael Hanselmann
  def testSkipNonExec(self):
351 a4ccecf6 Michael Hanselmann
    """Test that non executable files are skipped"""
352 a4ccecf6 Michael Hanselmann
    fname = os.path.join(self.rundir, "00test")
353 a4ccecf6 Michael Hanselmann
    utils.WriteFile(fname, data="")
354 a4ccecf6 Michael Hanselmann
    relname = os.path.basename(fname)
355 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(utils.RunParts(self.rundir, reset_env=True),
356 a4ccecf6 Michael Hanselmann
                         [(relname, constants.RUNPARTS_SKIP, None)])
357 a4ccecf6 Michael Hanselmann
358 a4ccecf6 Michael Hanselmann
  def testError(self):
359 a4ccecf6 Michael Hanselmann
    """Test error on a broken executable"""
360 a4ccecf6 Michael Hanselmann
    fname = os.path.join(self.rundir, "00test")
361 a4ccecf6 Michael Hanselmann
    utils.WriteFile(fname, data="")
362 a4ccecf6 Michael Hanselmann
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
363 a4ccecf6 Michael Hanselmann
    (relname, status, error) = utils.RunParts(self.rundir, reset_env=True)[0]
364 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(relname, os.path.basename(fname))
365 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(status, constants.RUNPARTS_ERR)
366 a4ccecf6 Michael Hanselmann
    self.failUnless(error)
367 a4ccecf6 Michael Hanselmann
368 a4ccecf6 Michael Hanselmann
  def testSorted(self):
369 a4ccecf6 Michael Hanselmann
    """Test executions are sorted"""
370 a4ccecf6 Michael Hanselmann
    files = []
371 a4ccecf6 Michael Hanselmann
    files.append(os.path.join(self.rundir, "64test"))
372 a4ccecf6 Michael Hanselmann
    files.append(os.path.join(self.rundir, "00test"))
373 a4ccecf6 Michael Hanselmann
    files.append(os.path.join(self.rundir, "42test"))
374 a4ccecf6 Michael Hanselmann
375 a4ccecf6 Michael Hanselmann
    for fname in files:
376 a4ccecf6 Michael Hanselmann
      utils.WriteFile(fname, data="")
377 a4ccecf6 Michael Hanselmann
378 a4ccecf6 Michael Hanselmann
    results = utils.RunParts(self.rundir, reset_env=True)
379 a4ccecf6 Michael Hanselmann
380 a4ccecf6 Michael Hanselmann
    for fname in sorted(files):
381 a4ccecf6 Michael Hanselmann
      self.failUnlessEqual(os.path.basename(fname), results.pop(0)[0])
382 a4ccecf6 Michael Hanselmann
383 a4ccecf6 Michael Hanselmann
  def testOk(self):
384 a4ccecf6 Michael Hanselmann
    """Test correct execution"""
385 a4ccecf6 Michael Hanselmann
    fname = os.path.join(self.rundir, "00test")
386 a4ccecf6 Michael Hanselmann
    utils.WriteFile(fname, data="#!/bin/sh\n\necho -n ciao")
387 a4ccecf6 Michael Hanselmann
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
388 a4ccecf6 Michael Hanselmann
    (relname, status, runresult) = \
389 a4ccecf6 Michael Hanselmann
      utils.RunParts(self.rundir, reset_env=True)[0]
390 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(relname, os.path.basename(fname))
391 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
392 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(runresult.stdout, "ciao")
393 a4ccecf6 Michael Hanselmann
394 a4ccecf6 Michael Hanselmann
  def testRunFail(self):
395 a4ccecf6 Michael Hanselmann
    """Test correct execution, with run failure"""
396 a4ccecf6 Michael Hanselmann
    fname = os.path.join(self.rundir, "00test")
397 a4ccecf6 Michael Hanselmann
    utils.WriteFile(fname, data="#!/bin/sh\n\nexit 1")
398 a4ccecf6 Michael Hanselmann
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
399 a4ccecf6 Michael Hanselmann
    (relname, status, runresult) = \
400 a4ccecf6 Michael Hanselmann
      utils.RunParts(self.rundir, reset_env=True)[0]
401 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(relname, os.path.basename(fname))
402 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
403 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(runresult.exit_code, 1)
404 a4ccecf6 Michael Hanselmann
    self.failUnless(runresult.failed)
405 a4ccecf6 Michael Hanselmann
406 a4ccecf6 Michael Hanselmann
  def testRunMix(self):
407 a4ccecf6 Michael Hanselmann
    files = []
408 a4ccecf6 Michael Hanselmann
    files.append(os.path.join(self.rundir, "00test"))
409 a4ccecf6 Michael Hanselmann
    files.append(os.path.join(self.rundir, "42test"))
410 a4ccecf6 Michael Hanselmann
    files.append(os.path.join(self.rundir, "64test"))
411 a4ccecf6 Michael Hanselmann
    files.append(os.path.join(self.rundir, "99test"))
412 a4ccecf6 Michael Hanselmann
413 a4ccecf6 Michael Hanselmann
    files.sort()
414 a4ccecf6 Michael Hanselmann
415 a4ccecf6 Michael Hanselmann
    # 1st has errors in execution
416 a4ccecf6 Michael Hanselmann
    utils.WriteFile(files[0], data="#!/bin/sh\n\nexit 1")
417 a4ccecf6 Michael Hanselmann
    os.chmod(files[0], stat.S_IREAD | stat.S_IEXEC)
418 a4ccecf6 Michael Hanselmann
419 a4ccecf6 Michael Hanselmann
    # 2nd is skipped
420 a4ccecf6 Michael Hanselmann
    utils.WriteFile(files[1], data="")
421 a4ccecf6 Michael Hanselmann
422 a4ccecf6 Michael Hanselmann
    # 3rd cannot execute properly
423 a4ccecf6 Michael Hanselmann
    utils.WriteFile(files[2], data="")
424 a4ccecf6 Michael Hanselmann
    os.chmod(files[2], stat.S_IREAD | stat.S_IEXEC)
425 a4ccecf6 Michael Hanselmann
426 a4ccecf6 Michael Hanselmann
    # 4th execs
427 a4ccecf6 Michael Hanselmann
    utils.WriteFile(files[3], data="#!/bin/sh\n\necho -n ciao")
428 a4ccecf6 Michael Hanselmann
    os.chmod(files[3], stat.S_IREAD | stat.S_IEXEC)
429 a4ccecf6 Michael Hanselmann
430 a4ccecf6 Michael Hanselmann
    results = utils.RunParts(self.rundir, reset_env=True)
431 a4ccecf6 Michael Hanselmann
432 a4ccecf6 Michael Hanselmann
    (relname, status, runresult) = results[0]
433 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(relname, os.path.basename(files[0]))
434 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
435 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(runresult.exit_code, 1)
436 a4ccecf6 Michael Hanselmann
    self.failUnless(runresult.failed)
437 a4ccecf6 Michael Hanselmann
438 a4ccecf6 Michael Hanselmann
    (relname, status, runresult) = results[1]
439 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(relname, os.path.basename(files[1]))
440 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(status, constants.RUNPARTS_SKIP)
441 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(runresult, None)
442 a4ccecf6 Michael Hanselmann
443 a4ccecf6 Michael Hanselmann
    (relname, status, runresult) = results[2]
444 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(relname, os.path.basename(files[2]))
445 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(status, constants.RUNPARTS_ERR)
446 a4ccecf6 Michael Hanselmann
    self.failUnless(runresult)
447 a4ccecf6 Michael Hanselmann
448 a4ccecf6 Michael Hanselmann
    (relname, status, runresult) = results[3]
449 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(relname, os.path.basename(files[3]))
450 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
451 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(runresult.output, "ciao")
452 a4ccecf6 Michael Hanselmann
    self.failUnlessEqual(runresult.exit_code, 0)
453 a4ccecf6 Michael Hanselmann
    self.failUnless(not runresult.failed)
454 a4ccecf6 Michael Hanselmann
455 a4ccecf6 Michael Hanselmann
  def testMissingDirectory(self):
456 a4ccecf6 Michael Hanselmann
    nosuchdir = utils.PathJoin(self.rundir, "no/such/directory")
457 a4ccecf6 Michael Hanselmann
    self.assertEqual(utils.RunParts(nosuchdir), [])
458 a4ccecf6 Michael Hanselmann
459 a4ccecf6 Michael Hanselmann
460 a4ccecf6 Michael Hanselmann
class TestStartDaemon(testutils.GanetiTestCase):
461 a4ccecf6 Michael Hanselmann
  def setUp(self):
462 a4ccecf6 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp(prefix="ganeti-test")
463 a4ccecf6 Michael Hanselmann
    self.tmpfile = os.path.join(self.tmpdir, "test")
464 a4ccecf6 Michael Hanselmann
465 a4ccecf6 Michael Hanselmann
  def tearDown(self):
466 a4ccecf6 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
467 a4ccecf6 Michael Hanselmann
468 a4ccecf6 Michael Hanselmann
  def testShell(self):
469 a4ccecf6 Michael Hanselmann
    utils.StartDaemon("echo Hello World > %s" % self.tmpfile)
470 a4ccecf6 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "Hello World")
471 a4ccecf6 Michael Hanselmann
472 a4ccecf6 Michael Hanselmann
  def testShellOutput(self):
473 a4ccecf6 Michael Hanselmann
    utils.StartDaemon("echo Hello World", output=self.tmpfile)
474 a4ccecf6 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "Hello World")
475 a4ccecf6 Michael Hanselmann
476 a4ccecf6 Michael Hanselmann
  def testNoShellNoOutput(self):
477 a4ccecf6 Michael Hanselmann
    utils.StartDaemon(["pwd"])
478 a4ccecf6 Michael Hanselmann
479 a4ccecf6 Michael Hanselmann
  def testNoShellNoOutputTouch(self):
480 a4ccecf6 Michael Hanselmann
    testfile = os.path.join(self.tmpdir, "check")
481 a4ccecf6 Michael Hanselmann
    self.failIf(os.path.exists(testfile))
482 a4ccecf6 Michael Hanselmann
    utils.StartDaemon(["touch", testfile])
483 a4ccecf6 Michael Hanselmann
    self._wait(testfile, 60.0, "")
484 a4ccecf6 Michael Hanselmann
485 a4ccecf6 Michael Hanselmann
  def testNoShellOutput(self):
486 a4ccecf6 Michael Hanselmann
    utils.StartDaemon(["pwd"], output=self.tmpfile)
487 a4ccecf6 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "/")
488 a4ccecf6 Michael Hanselmann
489 a4ccecf6 Michael Hanselmann
  def testNoShellOutputCwd(self):
490 a4ccecf6 Michael Hanselmann
    utils.StartDaemon(["pwd"], output=self.tmpfile, cwd=os.getcwd())
491 a4ccecf6 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, os.getcwd())
492 a4ccecf6 Michael Hanselmann
493 a4ccecf6 Michael Hanselmann
  def testShellEnv(self):
494 a4ccecf6 Michael Hanselmann
    utils.StartDaemon("echo \"$GNT_TEST_VAR\"", output=self.tmpfile,
495 a4ccecf6 Michael Hanselmann
                      env={ "GNT_TEST_VAR": "Hello World", })
496 a4ccecf6 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "Hello World")
497 a4ccecf6 Michael Hanselmann
498 a4ccecf6 Michael Hanselmann
  def testNoShellEnv(self):
499 a4ccecf6 Michael Hanselmann
    utils.StartDaemon(["printenv", "GNT_TEST_VAR"], output=self.tmpfile,
500 a4ccecf6 Michael Hanselmann
                      env={ "GNT_TEST_VAR": "Hello World", })
501 a4ccecf6 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "Hello World")
502 a4ccecf6 Michael Hanselmann
503 a4ccecf6 Michael Hanselmann
  def testOutputFd(self):
504 a4ccecf6 Michael Hanselmann
    fd = os.open(self.tmpfile, os.O_WRONLY | os.O_CREAT)
505 a4ccecf6 Michael Hanselmann
    try:
506 a4ccecf6 Michael Hanselmann
      utils.StartDaemon(["pwd"], output_fd=fd, cwd=os.getcwd())
507 a4ccecf6 Michael Hanselmann
    finally:
508 a4ccecf6 Michael Hanselmann
      os.close(fd)
509 a4ccecf6 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, os.getcwd())
510 a4ccecf6 Michael Hanselmann
511 a4ccecf6 Michael Hanselmann
  def testPid(self):
512 a4ccecf6 Michael Hanselmann
    pid = utils.StartDaemon("echo $$ > %s" % self.tmpfile)
513 a4ccecf6 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, str(pid))
514 a4ccecf6 Michael Hanselmann
515 a4ccecf6 Michael Hanselmann
  def testPidFile(self):
516 a4ccecf6 Michael Hanselmann
    pidfile = os.path.join(self.tmpdir, "pid")
517 a4ccecf6 Michael Hanselmann
    checkfile = os.path.join(self.tmpdir, "abort")
518 a4ccecf6 Michael Hanselmann
519 a4ccecf6 Michael Hanselmann
    pid = utils.StartDaemon("while sleep 5; do :; done", pidfile=pidfile,
520 a4ccecf6 Michael Hanselmann
                            output=self.tmpfile)
521 a4ccecf6 Michael Hanselmann
    try:
522 a4ccecf6 Michael Hanselmann
      fd = os.open(pidfile, os.O_RDONLY)
523 a4ccecf6 Michael Hanselmann
      try:
524 a4ccecf6 Michael Hanselmann
        # Check file is locked
525 a4ccecf6 Michael Hanselmann
        self.assertRaises(errors.LockError, utils.LockFile, fd)
526 a4ccecf6 Michael Hanselmann
527 a4ccecf6 Michael Hanselmann
        pidtext = os.read(fd, 100)
528 a4ccecf6 Michael Hanselmann
      finally:
529 a4ccecf6 Michael Hanselmann
        os.close(fd)
530 a4ccecf6 Michael Hanselmann
531 a4ccecf6 Michael Hanselmann
      self.assertEqual(int(pidtext.strip()), pid)
532 a4ccecf6 Michael Hanselmann
533 a4ccecf6 Michael Hanselmann
      self.assert_(utils.IsProcessAlive(pid))
534 a4ccecf6 Michael Hanselmann
    finally:
535 a4ccecf6 Michael Hanselmann
      # No matter what happens, kill daemon
536 a4ccecf6 Michael Hanselmann
      utils.KillProcess(pid, timeout=5.0, waitpid=False)
537 a4ccecf6 Michael Hanselmann
      self.failIf(utils.IsProcessAlive(pid))
538 a4ccecf6 Michael Hanselmann
539 a4ccecf6 Michael Hanselmann
    self.assertEqual(utils.ReadFile(self.tmpfile), "")
540 a4ccecf6 Michael Hanselmann
541 a4ccecf6 Michael Hanselmann
  def _wait(self, path, timeout, expected):
542 a4ccecf6 Michael Hanselmann
    # Due to the asynchronous nature of daemon processes, polling is necessary.
543 a4ccecf6 Michael Hanselmann
    # A timeout makes sure the test doesn't hang forever.
544 a4ccecf6 Michael Hanselmann
    def _CheckFile():
545 a4ccecf6 Michael Hanselmann
      if not (os.path.isfile(path) and
546 a4ccecf6 Michael Hanselmann
              utils.ReadFile(path).strip() == expected):
547 a4ccecf6 Michael Hanselmann
        raise utils.RetryAgain()
548 a4ccecf6 Michael Hanselmann
549 a4ccecf6 Michael Hanselmann
    try:
550 a4ccecf6 Michael Hanselmann
      utils.Retry(_CheckFile, (0.01, 1.5, 1.0), timeout)
551 a4ccecf6 Michael Hanselmann
    except utils.RetryTimeout:
552 a4ccecf6 Michael Hanselmann
      self.fail("Apparently the daemon didn't run in %s seconds and/or"
553 a4ccecf6 Michael Hanselmann
                " didn't write the correct output" % timeout)
554 a4ccecf6 Michael Hanselmann
555 a4ccecf6 Michael Hanselmann
  def testError(self):
556 a4ccecf6 Michael Hanselmann
    self.assertRaises(errors.OpExecError, utils.StartDaemon,
557 a4ccecf6 Michael Hanselmann
                      ["./does-NOT-EXIST/here/0123456789"])
558 a4ccecf6 Michael Hanselmann
    self.assertRaises(errors.OpExecError, utils.StartDaemon,
559 a4ccecf6 Michael Hanselmann
                      ["./does-NOT-EXIST/here/0123456789"],
560 a4ccecf6 Michael Hanselmann
                      output=os.path.join(self.tmpdir, "DIR/NOT/EXIST"))
561 a4ccecf6 Michael Hanselmann
    self.assertRaises(errors.OpExecError, utils.StartDaemon,
562 a4ccecf6 Michael Hanselmann
                      ["./does-NOT-EXIST/here/0123456789"],
563 a4ccecf6 Michael Hanselmann
                      cwd=os.path.join(self.tmpdir, "DIR/NOT/EXIST"))
564 a4ccecf6 Michael Hanselmann
    self.assertRaises(errors.OpExecError, utils.StartDaemon,
565 a4ccecf6 Michael Hanselmann
                      ["./does-NOT-EXIST/here/0123456789"],
566 a4ccecf6 Michael Hanselmann
                      output=os.path.join(self.tmpdir, "DIR/NOT/EXIST"))
567 a4ccecf6 Michael Hanselmann
568 a4ccecf6 Michael Hanselmann
    fd = os.open(self.tmpfile, os.O_WRONLY | os.O_CREAT)
569 a4ccecf6 Michael Hanselmann
    try:
570 a4ccecf6 Michael Hanselmann
      self.assertRaises(errors.ProgrammerError, utils.StartDaemon,
571 a4ccecf6 Michael Hanselmann
                        ["./does-NOT-EXIST/here/0123456789"],
572 a4ccecf6 Michael Hanselmann
                        output=self.tmpfile, output_fd=fd)
573 a4ccecf6 Michael Hanselmann
    finally:
574 a4ccecf6 Michael Hanselmann
      os.close(fd)
575 a4ccecf6 Michael Hanselmann
576 a4ccecf6 Michael Hanselmann
577 a4ccecf6 Michael Hanselmann
class RunInSeparateProcess(unittest.TestCase):
578 a4ccecf6 Michael Hanselmann
  def test(self):
579 a4ccecf6 Michael Hanselmann
    for exp in [True, False]:
580 a4ccecf6 Michael Hanselmann
      def _child():
581 a4ccecf6 Michael Hanselmann
        return exp
582 a4ccecf6 Michael Hanselmann
583 a4ccecf6 Michael Hanselmann
      self.assertEqual(exp, utils.RunInSeparateProcess(_child))
584 a4ccecf6 Michael Hanselmann
585 a4ccecf6 Michael Hanselmann
  def testArgs(self):
586 a4ccecf6 Michael Hanselmann
    for arg in [0, 1, 999, "Hello World", (1, 2, 3)]:
587 a4ccecf6 Michael Hanselmann
      def _child(carg1, carg2):
588 a4ccecf6 Michael Hanselmann
        return carg1 == "Foo" and carg2 == arg
589 a4ccecf6 Michael Hanselmann
590 a4ccecf6 Michael Hanselmann
      self.assert_(utils.RunInSeparateProcess(_child, "Foo", arg))
591 a4ccecf6 Michael Hanselmann
592 a4ccecf6 Michael Hanselmann
  def testPid(self):
593 a4ccecf6 Michael Hanselmann
    parent_pid = os.getpid()
594 a4ccecf6 Michael Hanselmann
595 a4ccecf6 Michael Hanselmann
    def _check():
596 a4ccecf6 Michael Hanselmann
      return os.getpid() == parent_pid
597 a4ccecf6 Michael Hanselmann
598 a4ccecf6 Michael Hanselmann
    self.failIf(utils.RunInSeparateProcess(_check))
599 a4ccecf6 Michael Hanselmann
600 a4ccecf6 Michael Hanselmann
  def testSignal(self):
601 a4ccecf6 Michael Hanselmann
    def _kill():
602 a4ccecf6 Michael Hanselmann
      os.kill(os.getpid(), signal.SIGTERM)
603 a4ccecf6 Michael Hanselmann
604 a4ccecf6 Michael Hanselmann
    self.assertRaises(errors.GenericError,
605 a4ccecf6 Michael Hanselmann
                      utils.RunInSeparateProcess, _kill)
606 a4ccecf6 Michael Hanselmann
607 a4ccecf6 Michael Hanselmann
  def testException(self):
608 a4ccecf6 Michael Hanselmann
    def _exc():
609 a4ccecf6 Michael Hanselmann
      raise errors.GenericError("This is a test")
610 a4ccecf6 Michael Hanselmann
611 a4ccecf6 Michael Hanselmann
    self.assertRaises(errors.GenericError,
612 a4ccecf6 Michael Hanselmann
                      utils.RunInSeparateProcess, _exc)
613 a4ccecf6 Michael Hanselmann
614 a4ccecf6 Michael Hanselmann
615 a4ccecf6 Michael Hanselmann
if __name__ == "__main__":
616 a4ccecf6 Michael Hanselmann
  testutils.GanetiTestProgram()