Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils_unittest.py @ 37e62cb9

History | View | Annotate | Download (81.5 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
"""Script for unittesting the utils module"""
23 a8083063 Iustin Pop
24 a8083063 Iustin Pop
import unittest
25 a8083063 Iustin Pop
import os
26 a8083063 Iustin Pop
import time
27 a8083063 Iustin Pop
import tempfile
28 a8083063 Iustin Pop
import os.path
29 320b4e2d Alexander Schreiber
import os
30 6bb65e3a Guido Trotter
import stat
31 740c5aab Guido Trotter
import signal
32 2c30e9d7 Alexander Schreiber
import socket
33 eedbda4b Michael Hanselmann
import shutil
34 59072e7e Michael Hanselmann
import re
35 09352fa4 Iustin Pop
import select
36 d392fa34 Iustin Pop
import string
37 73027ed2 Michael Hanselmann
import fcntl
38 bdd5e420 Michael Hanselmann
import OpenSSL
39 27e46076 Michael Hanselmann
import warnings
40 27e46076 Michael Hanselmann
import distutils.version
41 1d466a4f Michael Hanselmann
import glob
42 232144d0 Guido Trotter
import errno
43 a8083063 Iustin Pop
44 a8083063 Iustin Pop
import ganeti
45 c9c4f19e Michael Hanselmann
import testutils
46 16abfbc2 Alexander Schreiber
from ganeti import constants
47 716a32cb Guido Trotter
from ganeti import compat
48 59072e7e Michael Hanselmann
from ganeti import utils
49 a5728081 Guido Trotter
from ganeti import errors
50 f93f2016 Michael Hanselmann
from ganeti import serializer
51 e5392d79 Iustin Pop
from ganeti.utils import IsProcessAlive, RunCmd, \
52 31e22135 Iustin Pop
     RemoveFile, MatchNameComponent, FormatUnit, \
53 a8083063 Iustin Pop
     ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \
54 899d2a81 Michael Hanselmann
     ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles, \
55 f65f63ef Iustin Pop
     SetEtcHostsEntry, RemoveEtcHostsEntry, FirstFree, OwnIpAddress, \
56 5b69bc7c Iustin Pop
     TailFile, ForceDictType, SafeEncode, IsNormAbsPath, FormatTime, \
57 e587b46a Guido Trotter
     UnescapeAndSplit, RunParts, PathJoin, HostInfo, ReadOneLineFile
58 f65f63ef Iustin Pop
59 b2a1f511 Iustin Pop
from ganeti.errors import LockError, UnitParseError, GenericError, \
60 26288e68 Iustin Pop
     ProgrammerError, OpPrereqError
61 a8083063 Iustin Pop
62 d9f311d7 Iustin Pop
63 a8083063 Iustin Pop
class TestIsProcessAlive(unittest.TestCase):
64 a8083063 Iustin Pop
  """Testing case for IsProcessAlive"""
65 740c5aab Guido Trotter
66 a8083063 Iustin Pop
  def testExists(self):
67 a8083063 Iustin Pop
    mypid = os.getpid()
68 a8083063 Iustin Pop
    self.assert_(IsProcessAlive(mypid),
69 a8083063 Iustin Pop
                 "can't find myself running")
70 a8083063 Iustin Pop
71 a8083063 Iustin Pop
  def testNotExisting(self):
72 09352fa4 Iustin Pop
    pid_non_existing = os.fork()
73 09352fa4 Iustin Pop
    if pid_non_existing == 0:
74 09352fa4 Iustin Pop
      os._exit(0)
75 09352fa4 Iustin Pop
    elif pid_non_existing < 0:
76 09352fa4 Iustin Pop
      raise SystemError("can't fork")
77 09352fa4 Iustin Pop
    os.waitpid(pid_non_existing, 0)
78 09352fa4 Iustin Pop
    self.assert_(not IsProcessAlive(pid_non_existing),
79 09352fa4 Iustin Pop
                 "nonexisting process detected")
80 a8083063 Iustin Pop
81 d9f311d7 Iustin Pop
82 a01b500b Michael Hanselmann
class TestGetProcStatusPath(unittest.TestCase):
83 a01b500b Michael Hanselmann
  def test(self):
84 a01b500b Michael Hanselmann
    self.assert_("/1234/" in utils._GetProcStatusPath(1234))
85 a01b500b Michael Hanselmann
    self.assertNotEqual(utils._GetProcStatusPath(1),
86 a01b500b Michael Hanselmann
                        utils._GetProcStatusPath(2))
87 a01b500b Michael Hanselmann
88 a01b500b Michael Hanselmann
89 a01b500b Michael Hanselmann
class TestIsProcessHandlingSignal(unittest.TestCase):
90 a01b500b Michael Hanselmann
  def setUp(self):
91 a01b500b Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
92 a01b500b Michael Hanselmann
93 a01b500b Michael Hanselmann
  def tearDown(self):
94 a01b500b Michael Hanselmann
    shutil.rmtree(self.tmpdir)
95 a01b500b Michael Hanselmann
96 a01b500b Michael Hanselmann
  def testParseSigsetT(self):
97 a01b500b Michael Hanselmann
    self.assertEqual(len(utils._ParseSigsetT("0")), 0)
98 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("1"), set([1]))
99 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("1000a"), set([2, 4, 17]))
100 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("810002"), set([2, 17, 24, ]))
101 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("0000000180000202"),
102 a01b500b Michael Hanselmann
                     set([2, 10, 32, 33]))
103 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("0000000180000002"),
104 a01b500b Michael Hanselmann
                     set([2, 32, 33]))
105 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("0000000188000002"),
106 a01b500b Michael Hanselmann
                     set([2, 28, 32, 33]))
107 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("000000004b813efb"),
108 a01b500b Michael Hanselmann
                     set([1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 17,
109 a01b500b Michael Hanselmann
                          24, 25, 26, 28, 31]))
110 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("ffffff"), set(range(1, 25)))
111 a01b500b Michael Hanselmann
112 a01b500b Michael Hanselmann
  def testGetProcStatusField(self):
113 a01b500b Michael Hanselmann
    for field in ["SigCgt", "Name", "FDSize"]:
114 a01b500b Michael Hanselmann
      for value in ["", "0", "cat", "  1234 KB"]:
115 a01b500b Michael Hanselmann
        pstatus = "\n".join([
116 a01b500b Michael Hanselmann
          "VmPeak: 999 kB",
117 a01b500b Michael Hanselmann
          "%s: %s" % (field, value),
118 a01b500b Michael Hanselmann
          "TracerPid: 0",
119 a01b500b Michael Hanselmann
          ])
120 a01b500b Michael Hanselmann
        result = utils._GetProcStatusField(pstatus, field)
121 a01b500b Michael Hanselmann
        self.assertEqual(result, value.strip())
122 a01b500b Michael Hanselmann
123 a01b500b Michael Hanselmann
  def test(self):
124 a01b500b Michael Hanselmann
    sp = utils.PathJoin(self.tmpdir, "status")
125 a01b500b Michael Hanselmann
126 a01b500b Michael Hanselmann
    utils.WriteFile(sp, data="\n".join([
127 a01b500b Michael Hanselmann
      "Name:   bash",
128 a01b500b Michael Hanselmann
      "State:  S (sleeping)",
129 a01b500b Michael Hanselmann
      "SleepAVG:       98%",
130 a01b500b Michael Hanselmann
      "Pid:    22250",
131 a01b500b Michael Hanselmann
      "PPid:   10858",
132 a01b500b Michael Hanselmann
      "TracerPid:      0",
133 a01b500b Michael Hanselmann
      "SigBlk: 0000000000010000",
134 a01b500b Michael Hanselmann
      "SigIgn: 0000000000384004",
135 a01b500b Michael Hanselmann
      "SigCgt: 000000004b813efb",
136 a01b500b Michael Hanselmann
      "CapEff: 0000000000000000",
137 a01b500b Michael Hanselmann
      ]))
138 a01b500b Michael Hanselmann
139 a01b500b Michael Hanselmann
    self.assert_(utils.IsProcessHandlingSignal(1234, 10, status_path=sp))
140 a01b500b Michael Hanselmann
141 a01b500b Michael Hanselmann
  def testNoSigCgt(self):
142 a01b500b Michael Hanselmann
    sp = utils.PathJoin(self.tmpdir, "status")
143 a01b500b Michael Hanselmann
144 a01b500b Michael Hanselmann
    utils.WriteFile(sp, data="\n".join([
145 a01b500b Michael Hanselmann
      "Name:   bash",
146 a01b500b Michael Hanselmann
      ]))
147 a01b500b Michael Hanselmann
148 a01b500b Michael Hanselmann
    self.assertRaises(RuntimeError, utils.IsProcessHandlingSignal,
149 a01b500b Michael Hanselmann
                      1234, 10, status_path=sp)
150 a01b500b Michael Hanselmann
151 a01b500b Michael Hanselmann
  def testNoSuchFile(self):
152 a01b500b Michael Hanselmann
    sp = utils.PathJoin(self.tmpdir, "notexist")
153 a01b500b Michael Hanselmann
154 a01b500b Michael Hanselmann
    self.assertFalse(utils.IsProcessHandlingSignal(1234, 10, status_path=sp))
155 a01b500b Michael Hanselmann
156 a01b500b Michael Hanselmann
  @staticmethod
157 a01b500b Michael Hanselmann
  def _TestRealProcess():
158 a01b500b Michael Hanselmann
    signal.signal(signal.SIGUSR1, signal.SIG_DFL)
159 a01b500b Michael Hanselmann
    if utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
160 a01b500b Michael Hanselmann
      raise Exception("SIGUSR1 is handled when it should not be")
161 a01b500b Michael Hanselmann
162 a01b500b Michael Hanselmann
    signal.signal(signal.SIGUSR1, lambda signum, frame: None)
163 a01b500b Michael Hanselmann
    if not utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
164 a01b500b Michael Hanselmann
      raise Exception("SIGUSR1 is not handled when it should be")
165 a01b500b Michael Hanselmann
166 a01b500b Michael Hanselmann
    signal.signal(signal.SIGUSR1, signal.SIG_IGN)
167 a01b500b Michael Hanselmann
    if utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
168 a01b500b Michael Hanselmann
      raise Exception("SIGUSR1 is not handled when it should be")
169 a01b500b Michael Hanselmann
170 a01b500b Michael Hanselmann
    signal.signal(signal.SIGUSR1, signal.SIG_DFL)
171 a01b500b Michael Hanselmann
    if utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
172 a01b500b Michael Hanselmann
      raise Exception("SIGUSR1 is handled when it should not be")
173 a01b500b Michael Hanselmann
174 a01b500b Michael Hanselmann
    return True
175 a01b500b Michael Hanselmann
176 a01b500b Michael Hanselmann
  def testRealProcess(self):
177 a01b500b Michael Hanselmann
    self.assert_(utils.RunInSeparateProcess(self._TestRealProcess))
178 a01b500b Michael Hanselmann
179 a01b500b Michael Hanselmann
180 af99afa6 Guido Trotter
class TestPidFileFunctions(unittest.TestCase):
181 d9f311d7 Iustin Pop
  """Tests for WritePidFile, RemovePidFile and ReadPidFile"""
182 af99afa6 Guido Trotter
183 af99afa6 Guido Trotter
  def setUp(self):
184 af99afa6 Guido Trotter
    self.dir = tempfile.mkdtemp()
185 af99afa6 Guido Trotter
    self.f_dpn = lambda name: os.path.join(self.dir, "%s.pid" % name)
186 53beffbb Iustin Pop
    utils.DaemonPidFileName = self.f_dpn
187 af99afa6 Guido Trotter
188 af99afa6 Guido Trotter
  def testPidFileFunctions(self):
189 d9f311d7 Iustin Pop
    pid_file = self.f_dpn('test')
190 af99afa6 Guido Trotter
    utils.WritePidFile('test')
191 d9f311d7 Iustin Pop
    self.failUnless(os.path.exists(pid_file),
192 d9f311d7 Iustin Pop
                    "PID file should have been created")
193 d9f311d7 Iustin Pop
    read_pid = utils.ReadPidFile(pid_file)
194 d9f311d7 Iustin Pop
    self.failUnlessEqual(read_pid, os.getpid())
195 d9f311d7 Iustin Pop
    self.failUnless(utils.IsProcessAlive(read_pid))
196 d9f311d7 Iustin Pop
    self.failUnlessRaises(GenericError, utils.WritePidFile, 'test')
197 d9f311d7 Iustin Pop
    utils.RemovePidFile('test')
198 d9f311d7 Iustin Pop
    self.failIf(os.path.exists(pid_file),
199 d9f311d7 Iustin Pop
                "PID file should not exist anymore")
200 d9f311d7 Iustin Pop
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
201 d9f311d7 Iustin Pop
                         "ReadPidFile should return 0 for missing pid file")
202 d9f311d7 Iustin Pop
    fh = open(pid_file, "w")
203 d9f311d7 Iustin Pop
    fh.write("blah\n")
204 d9f311d7 Iustin Pop
    fh.close()
205 d9f311d7 Iustin Pop
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
206 d9f311d7 Iustin Pop
                         "ReadPidFile should return 0 for invalid pid file")
207 af99afa6 Guido Trotter
    utils.RemovePidFile('test')
208 d9f311d7 Iustin Pop
    self.failIf(os.path.exists(pid_file),
209 d9f311d7 Iustin Pop
                "PID file should not exist anymore")
210 af99afa6 Guido Trotter
211 b2a1f511 Iustin Pop
  def testKill(self):
212 b2a1f511 Iustin Pop
    pid_file = self.f_dpn('child')
213 b2a1f511 Iustin Pop
    r_fd, w_fd = os.pipe()
214 b2a1f511 Iustin Pop
    new_pid = os.fork()
215 b2a1f511 Iustin Pop
    if new_pid == 0: #child
216 b2a1f511 Iustin Pop
      utils.WritePidFile('child')
217 b2a1f511 Iustin Pop
      os.write(w_fd, 'a')
218 b2a1f511 Iustin Pop
      signal.pause()
219 b2a1f511 Iustin Pop
      os._exit(0)
220 b2a1f511 Iustin Pop
      return
221 b2a1f511 Iustin Pop
    # else we are in the parent
222 b2a1f511 Iustin Pop
    # wait until the child has written the pid file
223 b2a1f511 Iustin Pop
    os.read(r_fd, 1)
224 b2a1f511 Iustin Pop
    read_pid = utils.ReadPidFile(pid_file)
225 b2a1f511 Iustin Pop
    self.failUnlessEqual(read_pid, new_pid)
226 b2a1f511 Iustin Pop
    self.failUnless(utils.IsProcessAlive(new_pid))
227 ff5251bc Iustin Pop
    utils.KillProcess(new_pid, waitpid=True)
228 b2a1f511 Iustin Pop
    self.failIf(utils.IsProcessAlive(new_pid))
229 b2a1f511 Iustin Pop
    utils.RemovePidFile('child')
230 b2a1f511 Iustin Pop
    self.failUnlessRaises(ProgrammerError, utils.KillProcess, 0)
231 b2a1f511 Iustin Pop
232 af99afa6 Guido Trotter
  def tearDown(self):
233 d9f311d7 Iustin Pop
    for name in os.listdir(self.dir):
234 d9f311d7 Iustin Pop
      os.unlink(os.path.join(self.dir, name))
235 af99afa6 Guido Trotter
    os.rmdir(self.dir)
236 af99afa6 Guido Trotter
237 a8083063 Iustin Pop
238 36117c2b Iustin Pop
class TestRunCmd(testutils.GanetiTestCase):
239 a8083063 Iustin Pop
  """Testing case for the RunCmd function"""
240 a8083063 Iustin Pop
241 a8083063 Iustin Pop
  def setUp(self):
242 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
243 a8083063 Iustin Pop
    self.magic = time.ctime() + " ganeti test"
244 51596eb2 Iustin Pop
    self.fname = self._CreateTempFile()
245 a8083063 Iustin Pop
246 a8083063 Iustin Pop
  def testOk(self):
247 31ee599c Michael Hanselmann
    """Test successful exit code"""
248 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c 'exit 0'")
249 a8083063 Iustin Pop
    self.assertEqual(result.exit_code, 0)
250 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
251 a8083063 Iustin Pop
252 a8083063 Iustin Pop
  def testFail(self):
253 a8083063 Iustin Pop
    """Test fail exit code"""
254 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c 'exit 1'")
255 a8083063 Iustin Pop
    self.assertEqual(result.exit_code, 1)
256 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
257 a8083063 Iustin Pop
258 a8083063 Iustin Pop
  def testStdout(self):
259 a8083063 Iustin Pop
    """Test standard output"""
260 a8083063 Iustin Pop
    cmd = 'echo -n "%s"' % self.magic
261 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd)
262 a8083063 Iustin Pop
    self.assertEqual(result.stdout, self.magic)
263 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd, output=self.fname)
264 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
265 36117c2b Iustin Pop
    self.assertFileContent(self.fname, self.magic)
266 a8083063 Iustin Pop
267 a8083063 Iustin Pop
  def testStderr(self):
268 a8083063 Iustin Pop
    """Test standard error"""
269 a8083063 Iustin Pop
    cmd = 'echo -n "%s"' % self.magic
270 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s' 1>&2" % cmd)
271 a8083063 Iustin Pop
    self.assertEqual(result.stderr, self.magic)
272 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s' 1>&2" % cmd, output=self.fname)
273 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
274 36117c2b Iustin Pop
    self.assertFileContent(self.fname, self.magic)
275 a8083063 Iustin Pop
276 a8083063 Iustin Pop
  def testCombined(self):
277 a8083063 Iustin Pop
    """Test combined output"""
278 a8083063 Iustin Pop
    cmd = 'echo -n "A%s"; echo -n "B%s" 1>&2' % (self.magic, self.magic)
279 36117c2b Iustin Pop
    expected = "A" + self.magic + "B" + self.magic
280 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd)
281 36117c2b Iustin Pop
    self.assertEqual(result.output, expected)
282 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd, output=self.fname)
283 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
284 36117c2b Iustin Pop
    self.assertFileContent(self.fname, expected)
285 a8083063 Iustin Pop
286 a8083063 Iustin Pop
  def testSignal(self):
287 01fd6005 Manuel Franceschini
    """Test signal"""
288 01fd6005 Manuel Franceschini
    result = RunCmd(["python", "-c", "import os; os.kill(os.getpid(), 15)"])
289 a8083063 Iustin Pop
    self.assertEqual(result.signal, 15)
290 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
291 a8083063 Iustin Pop
292 7fcf849f Iustin Pop
  def testListRun(self):
293 7fcf849f Iustin Pop
    """Test list runs"""
294 7fcf849f Iustin Pop
    result = RunCmd(["true"])
295 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
296 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 0)
297 7fcf849f Iustin Pop
    result = RunCmd(["/bin/sh", "-c", "exit 1"])
298 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
299 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 1)
300 7fcf849f Iustin Pop
    result = RunCmd(["echo", "-n", self.magic])
301 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
302 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 0)
303 7fcf849f Iustin Pop
    self.assertEqual(result.stdout, self.magic)
304 7fcf849f Iustin Pop
305 36117c2b Iustin Pop
  def testFileEmptyOutput(self):
306 36117c2b Iustin Pop
    """Test file output"""
307 36117c2b Iustin Pop
    result = RunCmd(["true"], output=self.fname)
308 36117c2b Iustin Pop
    self.assertEqual(result.signal, None)
309 36117c2b Iustin Pop
    self.assertEqual(result.exit_code, 0)
310 36117c2b Iustin Pop
    self.assertFileContent(self.fname, "")
311 36117c2b Iustin Pop
312 f6441c7c Iustin Pop
  def testLang(self):
313 f6441c7c Iustin Pop
    """Test locale environment"""
314 23f41a3e Michael Hanselmann
    old_env = os.environ.copy()
315 23f41a3e Michael Hanselmann
    try:
316 23f41a3e Michael Hanselmann
      os.environ["LANG"] = "en_US.UTF-8"
317 23f41a3e Michael Hanselmann
      os.environ["LC_ALL"] = "en_US.UTF-8"
318 23f41a3e Michael Hanselmann
      result = RunCmd(["locale"])
319 23f41a3e Michael Hanselmann
      for line in result.output.splitlines():
320 23f41a3e Michael Hanselmann
        key, value = line.split("=", 1)
321 23f41a3e Michael Hanselmann
        # Ignore these variables, they're overridden by LC_ALL
322 23f41a3e Michael Hanselmann
        if key == "LANG" or key == "LANGUAGE":
323 23f41a3e Michael Hanselmann
          continue
324 23f41a3e Michael Hanselmann
        self.failIf(value and value != "C" and value != '"C"',
325 23f41a3e Michael Hanselmann
            "Variable %s is set to the invalid value '%s'" % (key, value))
326 23f41a3e Michael Hanselmann
    finally:
327 23f41a3e Michael Hanselmann
      os.environ = old_env
328 f6441c7c Iustin Pop
329 8797df43 Iustin Pop
  def testDefaultCwd(self):
330 8797df43 Iustin Pop
    """Test default working directory"""
331 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"]).stdout.strip(), "/")
332 8797df43 Iustin Pop
333 8797df43 Iustin Pop
  def testCwd(self):
334 8797df43 Iustin Pop
    """Test default working directory"""
335 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd="/").stdout.strip(), "/")
336 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd="/tmp").stdout.strip(), "/tmp")
337 8797df43 Iustin Pop
    cwd = os.getcwd()
338 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd=cwd).stdout.strip(), cwd)
339 8797df43 Iustin Pop
340 bf4daac9 Guido Trotter
  def testResetEnv(self):
341 bf4daac9 Guido Trotter
    """Test environment reset functionality"""
342 bf4daac9 Guido Trotter
    self.failUnlessEqual(RunCmd(["env"], reset_env=True).stdout.strip(), "")
343 0babc371 Michael Hanselmann
    self.failUnlessEqual(RunCmd(["env"], reset_env=True,
344 0babc371 Michael Hanselmann
                                env={"FOO": "bar",}).stdout.strip(), "FOO=bar")
345 bf4daac9 Guido Trotter
346 a8083063 Iustin Pop
347 6bb65e3a Guido Trotter
class TestRunParts(unittest.TestCase):
348 6bb65e3a Guido Trotter
  """Testing case for the RunParts function"""
349 6bb65e3a Guido Trotter
350 6bb65e3a Guido Trotter
  def setUp(self):
351 6bb65e3a Guido Trotter
    self.rundir = tempfile.mkdtemp(prefix="ganeti-test", suffix=".tmp")
352 6bb65e3a Guido Trotter
353 6bb65e3a Guido Trotter
  def tearDown(self):
354 6bb65e3a Guido Trotter
    shutil.rmtree(self.rundir)
355 6bb65e3a Guido Trotter
356 6bb65e3a Guido Trotter
  def testEmpty(self):
357 6bb65e3a Guido Trotter
    """Test on an empty dir"""
358 6bb65e3a Guido Trotter
    self.failUnlessEqual(RunParts(self.rundir, reset_env=True), [])
359 6bb65e3a Guido Trotter
360 6bb65e3a Guido Trotter
  def testSkipWrongName(self):
361 6bb65e3a Guido Trotter
    """Test that wrong files are skipped"""
362 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test.dot")
363 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="")
364 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
365 6bb65e3a Guido Trotter
    relname = os.path.basename(fname)
366 6bb65e3a Guido Trotter
    self.failUnlessEqual(RunParts(self.rundir, reset_env=True),
367 6bb65e3a Guido Trotter
                         [(relname, constants.RUNPARTS_SKIP, None)])
368 6bb65e3a Guido Trotter
369 6bb65e3a Guido Trotter
  def testSkipNonExec(self):
370 6bb65e3a Guido Trotter
    """Test that non executable files are skipped"""
371 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
372 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="")
373 6bb65e3a Guido Trotter
    relname = os.path.basename(fname)
374 6bb65e3a Guido Trotter
    self.failUnlessEqual(RunParts(self.rundir, reset_env=True),
375 6bb65e3a Guido Trotter
                         [(relname, constants.RUNPARTS_SKIP, None)])
376 6bb65e3a Guido Trotter
377 6bb65e3a Guido Trotter
  def testError(self):
378 6bb65e3a Guido Trotter
    """Test error on a broken executable"""
379 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
380 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="")
381 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
382 6bb65e3a Guido Trotter
    (relname, status, error) = RunParts(self.rundir, reset_env=True)[0]
383 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(fname))
384 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_ERR)
385 6bb65e3a Guido Trotter
    self.failUnless(error)
386 6bb65e3a Guido Trotter
387 6bb65e3a Guido Trotter
  def testSorted(self):
388 6bb65e3a Guido Trotter
    """Test executions are sorted"""
389 6bb65e3a Guido Trotter
    files = []
390 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "64test"))
391 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "00test"))
392 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "42test"))
393 6bb65e3a Guido Trotter
394 6bb65e3a Guido Trotter
    for fname in files:
395 6bb65e3a Guido Trotter
      utils.WriteFile(fname, data="")
396 6bb65e3a Guido Trotter
397 6bb65e3a Guido Trotter
    results = RunParts(self.rundir, reset_env=True)
398 6bb65e3a Guido Trotter
399 6bb65e3a Guido Trotter
    for fname in sorted(files):
400 6bb65e3a Guido Trotter
      self.failUnlessEqual(os.path.basename(fname), results.pop(0)[0])
401 6bb65e3a Guido Trotter
402 6bb65e3a Guido Trotter
  def testOk(self):
403 6bb65e3a Guido Trotter
    """Test correct execution"""
404 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
405 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="#!/bin/sh\n\necho -n ciao")
406 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
407 6bb65e3a Guido Trotter
    (relname, status, runresult) = RunParts(self.rundir, reset_env=True)[0]
408 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(fname))
409 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
410 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.stdout, "ciao")
411 6bb65e3a Guido Trotter
412 6bb65e3a Guido Trotter
  def testRunFail(self):
413 6bb65e3a Guido Trotter
    """Test correct execution, with run failure"""
414 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
415 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="#!/bin/sh\n\nexit 1")
416 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
417 6bb65e3a Guido Trotter
    (relname, status, runresult) = RunParts(self.rundir, reset_env=True)[0]
418 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(fname))
419 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
420 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.exit_code, 1)
421 6bb65e3a Guido Trotter
    self.failUnless(runresult.failed)
422 6bb65e3a Guido Trotter
423 6bb65e3a Guido Trotter
  def testRunMix(self):
424 6bb65e3a Guido Trotter
    files = []
425 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "00test"))
426 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "42test"))
427 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "64test"))
428 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "99test"))
429 6bb65e3a Guido Trotter
430 6bb65e3a Guido Trotter
    files.sort()
431 6bb65e3a Guido Trotter
432 6bb65e3a Guido Trotter
    # 1st has errors in execution
433 6bb65e3a Guido Trotter
    utils.WriteFile(files[0], data="#!/bin/sh\n\nexit 1")
434 6bb65e3a Guido Trotter
    os.chmod(files[0], stat.S_IREAD | stat.S_IEXEC)
435 6bb65e3a Guido Trotter
436 6bb65e3a Guido Trotter
    # 2nd is skipped
437 6bb65e3a Guido Trotter
    utils.WriteFile(files[1], data="")
438 6bb65e3a Guido Trotter
439 6bb65e3a Guido Trotter
    # 3rd cannot execute properly
440 6bb65e3a Guido Trotter
    utils.WriteFile(files[2], data="")
441 6bb65e3a Guido Trotter
    os.chmod(files[2], stat.S_IREAD | stat.S_IEXEC)
442 6bb65e3a Guido Trotter
443 6bb65e3a Guido Trotter
    # 4th execs
444 6bb65e3a Guido Trotter
    utils.WriteFile(files[3], data="#!/bin/sh\n\necho -n ciao")
445 6bb65e3a Guido Trotter
    os.chmod(files[3], stat.S_IREAD | stat.S_IEXEC)
446 6bb65e3a Guido Trotter
447 6bb65e3a Guido Trotter
    results = RunParts(self.rundir, reset_env=True)
448 6bb65e3a Guido Trotter
449 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[0]
450 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[0]))
451 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
452 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.exit_code, 1)
453 6bb65e3a Guido Trotter
    self.failUnless(runresult.failed)
454 6bb65e3a Guido Trotter
455 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[1]
456 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[1]))
457 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_SKIP)
458 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult, None)
459 6bb65e3a Guido Trotter
460 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[2]
461 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[2]))
462 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_ERR)
463 6bb65e3a Guido Trotter
    self.failUnless(runresult)
464 6bb65e3a Guido Trotter
465 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[3]
466 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[3]))
467 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
468 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.output, "ciao")
469 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.exit_code, 0)
470 6bb65e3a Guido Trotter
    self.failUnless(not runresult.failed)
471 6bb65e3a Guido Trotter
472 a8083063 Iustin Pop
473 c1dd99d4 Michael Hanselmann
class TestStartDaemon(testutils.GanetiTestCase):
474 c1dd99d4 Michael Hanselmann
  def setUp(self):
475 c1dd99d4 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp(prefix="ganeti-test")
476 c1dd99d4 Michael Hanselmann
    self.tmpfile = os.path.join(self.tmpdir, "test")
477 c1dd99d4 Michael Hanselmann
478 c1dd99d4 Michael Hanselmann
  def tearDown(self):
479 c1dd99d4 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
480 c1dd99d4 Michael Hanselmann
481 c1dd99d4 Michael Hanselmann
  def testShell(self):
482 c1dd99d4 Michael Hanselmann
    utils.StartDaemon("echo Hello World > %s" % self.tmpfile)
483 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "Hello World")
484 c1dd99d4 Michael Hanselmann
485 c1dd99d4 Michael Hanselmann
  def testShellOutput(self):
486 c1dd99d4 Michael Hanselmann
    utils.StartDaemon("echo Hello World", output=self.tmpfile)
487 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "Hello World")
488 c1dd99d4 Michael Hanselmann
489 c1dd99d4 Michael Hanselmann
  def testNoShellNoOutput(self):
490 c1dd99d4 Michael Hanselmann
    utils.StartDaemon(["pwd"])
491 c1dd99d4 Michael Hanselmann
492 c1dd99d4 Michael Hanselmann
  def testNoShellNoOutputTouch(self):
493 c1dd99d4 Michael Hanselmann
    testfile = os.path.join(self.tmpdir, "check")
494 c1dd99d4 Michael Hanselmann
    self.failIf(os.path.exists(testfile))
495 c1dd99d4 Michael Hanselmann
    utils.StartDaemon(["touch", testfile])
496 c1dd99d4 Michael Hanselmann
    self._wait(testfile, 60.0, "")
497 c1dd99d4 Michael Hanselmann
498 c1dd99d4 Michael Hanselmann
  def testNoShellOutput(self):
499 c1dd99d4 Michael Hanselmann
    utils.StartDaemon(["pwd"], output=self.tmpfile)
500 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "/")
501 c1dd99d4 Michael Hanselmann
502 c1dd99d4 Michael Hanselmann
  def testNoShellOutputCwd(self):
503 c1dd99d4 Michael Hanselmann
    utils.StartDaemon(["pwd"], output=self.tmpfile, cwd=os.getcwd())
504 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, os.getcwd())
505 c1dd99d4 Michael Hanselmann
506 c1dd99d4 Michael Hanselmann
  def testShellEnv(self):
507 c1dd99d4 Michael Hanselmann
    utils.StartDaemon("echo \"$GNT_TEST_VAR\"", output=self.tmpfile,
508 c1dd99d4 Michael Hanselmann
                      env={ "GNT_TEST_VAR": "Hello World", })
509 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "Hello World")
510 c1dd99d4 Michael Hanselmann
511 c1dd99d4 Michael Hanselmann
  def testNoShellEnv(self):
512 c1dd99d4 Michael Hanselmann
    utils.StartDaemon(["printenv", "GNT_TEST_VAR"], output=self.tmpfile,
513 c1dd99d4 Michael Hanselmann
                      env={ "GNT_TEST_VAR": "Hello World", })
514 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "Hello World")
515 c1dd99d4 Michael Hanselmann
516 c1dd99d4 Michael Hanselmann
  def testOutputFd(self):
517 c1dd99d4 Michael Hanselmann
    fd = os.open(self.tmpfile, os.O_WRONLY | os.O_CREAT)
518 c1dd99d4 Michael Hanselmann
    try:
519 c1dd99d4 Michael Hanselmann
      utils.StartDaemon(["pwd"], output_fd=fd, cwd=os.getcwd())
520 c1dd99d4 Michael Hanselmann
    finally:
521 c1dd99d4 Michael Hanselmann
      os.close(fd)
522 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, os.getcwd())
523 c1dd99d4 Michael Hanselmann
524 c1dd99d4 Michael Hanselmann
  def testPid(self):
525 c1dd99d4 Michael Hanselmann
    pid = utils.StartDaemon("echo $$ > %s" % self.tmpfile)
526 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, str(pid))
527 c1dd99d4 Michael Hanselmann
528 c1dd99d4 Michael Hanselmann
  def testPidFile(self):
529 c1dd99d4 Michael Hanselmann
    pidfile = os.path.join(self.tmpdir, "pid")
530 c1dd99d4 Michael Hanselmann
    checkfile = os.path.join(self.tmpdir, "abort")
531 c1dd99d4 Michael Hanselmann
532 c1dd99d4 Michael Hanselmann
    pid = utils.StartDaemon("while sleep 5; do :; done", pidfile=pidfile,
533 c1dd99d4 Michael Hanselmann
                            output=self.tmpfile)
534 c1dd99d4 Michael Hanselmann
    try:
535 c1dd99d4 Michael Hanselmann
      fd = os.open(pidfile, os.O_RDONLY)
536 c1dd99d4 Michael Hanselmann
      try:
537 c1dd99d4 Michael Hanselmann
        # Check file is locked
538 c1dd99d4 Michael Hanselmann
        self.assertRaises(errors.LockError, utils.LockFile, fd)
539 c1dd99d4 Michael Hanselmann
540 c1dd99d4 Michael Hanselmann
        pidtext = os.read(fd, 100)
541 c1dd99d4 Michael Hanselmann
      finally:
542 c1dd99d4 Michael Hanselmann
        os.close(fd)
543 c1dd99d4 Michael Hanselmann
544 c1dd99d4 Michael Hanselmann
      self.assertEqual(int(pidtext.strip()), pid)
545 c1dd99d4 Michael Hanselmann
546 c1dd99d4 Michael Hanselmann
      self.assert_(utils.IsProcessAlive(pid))
547 c1dd99d4 Michael Hanselmann
    finally:
548 c1dd99d4 Michael Hanselmann
      # No matter what happens, kill daemon
549 c1dd99d4 Michael Hanselmann
      utils.KillProcess(pid, timeout=5.0, waitpid=False)
550 c1dd99d4 Michael Hanselmann
      self.failIf(utils.IsProcessAlive(pid))
551 c1dd99d4 Michael Hanselmann
552 c1dd99d4 Michael Hanselmann
    self.assertEqual(utils.ReadFile(self.tmpfile), "")
553 c1dd99d4 Michael Hanselmann
554 c1dd99d4 Michael Hanselmann
  def _wait(self, path, timeout, expected):
555 c1dd99d4 Michael Hanselmann
    # Due to the asynchronous nature of daemon processes, polling is necessary.
556 c1dd99d4 Michael Hanselmann
    # A timeout makes sure the test doesn't hang forever.
557 c1dd99d4 Michael Hanselmann
    def _CheckFile():
558 c1dd99d4 Michael Hanselmann
      if not (os.path.isfile(path) and
559 c1dd99d4 Michael Hanselmann
              utils.ReadFile(path).strip() == expected):
560 c1dd99d4 Michael Hanselmann
        raise utils.RetryAgain()
561 c1dd99d4 Michael Hanselmann
562 c1dd99d4 Michael Hanselmann
    try:
563 c1dd99d4 Michael Hanselmann
      utils.Retry(_CheckFile, (0.01, 1.5, 1.0), timeout)
564 c1dd99d4 Michael Hanselmann
    except utils.RetryTimeout:
565 c1dd99d4 Michael Hanselmann
      self.fail("Apparently the daemon didn't run in %s seconds and/or"
566 c1dd99d4 Michael Hanselmann
                " didn't write the correct output" % timeout)
567 c1dd99d4 Michael Hanselmann
568 c1dd99d4 Michael Hanselmann
  def testError(self):
569 c1dd99d4 Michael Hanselmann
    self.assertRaises(errors.OpExecError, utils.StartDaemon,
570 c1dd99d4 Michael Hanselmann
                      ["./does-NOT-EXIST/here/0123456789"])
571 c1dd99d4 Michael Hanselmann
    self.assertRaises(errors.OpExecError, utils.StartDaemon,
572 c1dd99d4 Michael Hanselmann
                      ["./does-NOT-EXIST/here/0123456789"],
573 c1dd99d4 Michael Hanselmann
                      output=os.path.join(self.tmpdir, "DIR/NOT/EXIST"))
574 c1dd99d4 Michael Hanselmann
    self.assertRaises(errors.OpExecError, utils.StartDaemon,
575 c1dd99d4 Michael Hanselmann
                      ["./does-NOT-EXIST/here/0123456789"],
576 c1dd99d4 Michael Hanselmann
                      cwd=os.path.join(self.tmpdir, "DIR/NOT/EXIST"))
577 c1dd99d4 Michael Hanselmann
    self.assertRaises(errors.OpExecError, utils.StartDaemon,
578 c1dd99d4 Michael Hanselmann
                      ["./does-NOT-EXIST/here/0123456789"],
579 c1dd99d4 Michael Hanselmann
                      output=os.path.join(self.tmpdir, "DIR/NOT/EXIST"))
580 c1dd99d4 Michael Hanselmann
581 c1dd99d4 Michael Hanselmann
    fd = os.open(self.tmpfile, os.O_WRONLY | os.O_CREAT)
582 c1dd99d4 Michael Hanselmann
    try:
583 c1dd99d4 Michael Hanselmann
      self.assertRaises(errors.ProgrammerError, utils.StartDaemon,
584 c1dd99d4 Michael Hanselmann
                        ["./does-NOT-EXIST/here/0123456789"],
585 c1dd99d4 Michael Hanselmann
                        output=self.tmpfile, output_fd=fd)
586 c1dd99d4 Michael Hanselmann
    finally:
587 c1dd99d4 Michael Hanselmann
      os.close(fd)
588 c1dd99d4 Michael Hanselmann
589 c1dd99d4 Michael Hanselmann
590 73027ed2 Michael Hanselmann
class TestSetCloseOnExecFlag(unittest.TestCase):
591 73027ed2 Michael Hanselmann
  """Tests for SetCloseOnExecFlag"""
592 73027ed2 Michael Hanselmann
593 73027ed2 Michael Hanselmann
  def setUp(self):
594 73027ed2 Michael Hanselmann
    self.tmpfile = tempfile.TemporaryFile()
595 73027ed2 Michael Hanselmann
596 73027ed2 Michael Hanselmann
  def testEnable(self):
597 73027ed2 Michael Hanselmann
    utils.SetCloseOnExecFlag(self.tmpfile.fileno(), True)
598 73027ed2 Michael Hanselmann
    self.failUnless(fcntl.fcntl(self.tmpfile.fileno(), fcntl.F_GETFD) &
599 73027ed2 Michael Hanselmann
                    fcntl.FD_CLOEXEC)
600 73027ed2 Michael Hanselmann
601 73027ed2 Michael Hanselmann
  def testDisable(self):
602 73027ed2 Michael Hanselmann
    utils.SetCloseOnExecFlag(self.tmpfile.fileno(), False)
603 73027ed2 Michael Hanselmann
    self.failIf(fcntl.fcntl(self.tmpfile.fileno(), fcntl.F_GETFD) &
604 73027ed2 Michael Hanselmann
                fcntl.FD_CLOEXEC)
605 73027ed2 Michael Hanselmann
606 73027ed2 Michael Hanselmann
607 287a1740 Michael Hanselmann
class TestSetNonblockFlag(unittest.TestCase):
608 287a1740 Michael Hanselmann
  def setUp(self):
609 287a1740 Michael Hanselmann
    self.tmpfile = tempfile.TemporaryFile()
610 287a1740 Michael Hanselmann
611 287a1740 Michael Hanselmann
  def testEnable(self):
612 287a1740 Michael Hanselmann
    utils.SetNonblockFlag(self.tmpfile.fileno(), True)
613 287a1740 Michael Hanselmann
    self.failUnless(fcntl.fcntl(self.tmpfile.fileno(), fcntl.F_GETFL) &
614 287a1740 Michael Hanselmann
                    os.O_NONBLOCK)
615 287a1740 Michael Hanselmann
616 287a1740 Michael Hanselmann
  def testDisable(self):
617 287a1740 Michael Hanselmann
    utils.SetNonblockFlag(self.tmpfile.fileno(), False)
618 287a1740 Michael Hanselmann
    self.failIf(fcntl.fcntl(self.tmpfile.fileno(), fcntl.F_GETFL) &
619 287a1740 Michael Hanselmann
                os.O_NONBLOCK)
620 287a1740 Michael Hanselmann
621 287a1740 Michael Hanselmann
622 a8083063 Iustin Pop
class TestRemoveFile(unittest.TestCase):
623 a8083063 Iustin Pop
  """Test case for the RemoveFile function"""
624 a8083063 Iustin Pop
625 a8083063 Iustin Pop
  def setUp(self):
626 a8083063 Iustin Pop
    """Create a temp dir and file for each case"""
627 a8083063 Iustin Pop
    self.tmpdir = tempfile.mkdtemp('', 'ganeti-unittest-')
628 a8083063 Iustin Pop
    fd, self.tmpfile = tempfile.mkstemp('', '', self.tmpdir)
629 a8083063 Iustin Pop
    os.close(fd)
630 a8083063 Iustin Pop
631 a8083063 Iustin Pop
  def tearDown(self):
632 a8083063 Iustin Pop
    if os.path.exists(self.tmpfile):
633 a8083063 Iustin Pop
      os.unlink(self.tmpfile)
634 a8083063 Iustin Pop
    os.rmdir(self.tmpdir)
635 a8083063 Iustin Pop
636 a8083063 Iustin Pop
  def testIgnoreDirs(self):
637 a8083063 Iustin Pop
    """Test that RemoveFile() ignores directories"""
638 a8083063 Iustin Pop
    self.assertEqual(None, RemoveFile(self.tmpdir))
639 a8083063 Iustin Pop
640 a8083063 Iustin Pop
  def testIgnoreNotExisting(self):
641 a8083063 Iustin Pop
    """Test that RemoveFile() ignores non-existing files"""
642 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
643 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
644 a8083063 Iustin Pop
645 a8083063 Iustin Pop
  def testRemoveFile(self):
646 a8083063 Iustin Pop
    """Test that RemoveFile does remove a file"""
647 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
648 a8083063 Iustin Pop
    if os.path.exists(self.tmpfile):
649 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % self.tmpfile)
650 a8083063 Iustin Pop
651 a8083063 Iustin Pop
  def testRemoveSymlink(self):
652 a8083063 Iustin Pop
    """Test that RemoveFile does remove symlinks"""
653 a8083063 Iustin Pop
    symlink = self.tmpdir + "/symlink"
654 a8083063 Iustin Pop
    os.symlink("no-such-file", symlink)
655 a8083063 Iustin Pop
    RemoveFile(symlink)
656 a8083063 Iustin Pop
    if os.path.exists(symlink):
657 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % symlink)
658 a8083063 Iustin Pop
    os.symlink(self.tmpfile, symlink)
659 a8083063 Iustin Pop
    RemoveFile(symlink)
660 a8083063 Iustin Pop
    if os.path.exists(symlink):
661 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % symlink)
662 a8083063 Iustin Pop
663 a8083063 Iustin Pop
664 6e797216 Michael Hanselmann
class TestRename(unittest.TestCase):
665 6e797216 Michael Hanselmann
  """Test case for RenameFile"""
666 6e797216 Michael Hanselmann
667 6e797216 Michael Hanselmann
  def setUp(self):
668 6e797216 Michael Hanselmann
    """Create a temporary directory"""
669 6e797216 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
670 6e797216 Michael Hanselmann
    self.tmpfile = os.path.join(self.tmpdir, "test1")
671 6e797216 Michael Hanselmann
672 6e797216 Michael Hanselmann
    # Touch the file
673 6e797216 Michael Hanselmann
    open(self.tmpfile, "w").close()
674 6e797216 Michael Hanselmann
675 6e797216 Michael Hanselmann
  def tearDown(self):
676 6e797216 Michael Hanselmann
    """Remove temporary directory"""
677 6e797216 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
678 6e797216 Michael Hanselmann
679 6e797216 Michael Hanselmann
  def testSimpleRename1(self):
680 6e797216 Michael Hanselmann
    """Simple rename 1"""
681 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"))
682 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "xyz")))
683 6e797216 Michael Hanselmann
684 6e797216 Michael Hanselmann
  def testSimpleRename2(self):
685 6e797216 Michael Hanselmann
    """Simple rename 2"""
686 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"),
687 6e797216 Michael Hanselmann
                     mkdir=True)
688 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "xyz")))
689 6e797216 Michael Hanselmann
690 6e797216 Michael Hanselmann
  def testRenameMkdir(self):
691 6e797216 Michael Hanselmann
    """Rename with mkdir"""
692 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "test/xyz"),
693 6e797216 Michael Hanselmann
                     mkdir=True)
694 a426508d Michael Hanselmann
    self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test")))
695 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "test/xyz")))
696 a426508d Michael Hanselmann
697 a426508d Michael Hanselmann
    utils.RenameFile(os.path.join(self.tmpdir, "test/xyz"),
698 a426508d Michael Hanselmann
                     os.path.join(self.tmpdir, "test/foo/bar/baz"),
699 a426508d Michael Hanselmann
                     mkdir=True)
700 a426508d Michael Hanselmann
    self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test")))
701 a426508d Michael Hanselmann
    self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test/foo/bar")))
702 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "test/foo/bar/baz")))
703 6e797216 Michael Hanselmann
704 6e797216 Michael Hanselmann
705 a8083063 Iustin Pop
class TestMatchNameComponent(unittest.TestCase):
706 a8083063 Iustin Pop
  """Test case for the MatchNameComponent function"""
707 a8083063 Iustin Pop
708 a8083063 Iustin Pop
  def testEmptyList(self):
709 a8083063 Iustin Pop
    """Test that there is no match against an empty list"""
710 a8083063 Iustin Pop
711 a8083063 Iustin Pop
    self.failUnlessEqual(MatchNameComponent("", []), None)
712 a8083063 Iustin Pop
    self.failUnlessEqual(MatchNameComponent("test", []), None)
713 a8083063 Iustin Pop
714 a8083063 Iustin Pop
  def testSingleMatch(self):
715 a8083063 Iustin Pop
    """Test that a single match is performed correctly"""
716 a8083063 Iustin Pop
    mlist = ["test1.example.com", "test2.example.com", "test3.example.com"]
717 a8083063 Iustin Pop
    for key in "test2", "test2.example", "test2.example.com":
718 a8083063 Iustin Pop
      self.failUnlessEqual(MatchNameComponent(key, mlist), mlist[1])
719 a8083063 Iustin Pop
720 a8083063 Iustin Pop
  def testMultipleMatches(self):
721 a8083063 Iustin Pop
    """Test that a multiple match is returned as None"""
722 a8083063 Iustin Pop
    mlist = ["test1.example.com", "test1.example.org", "test1.example.net"]
723 a8083063 Iustin Pop
    for key in "test1", "test1.example":
724 a8083063 Iustin Pop
      self.failUnlessEqual(MatchNameComponent(key, mlist), None)
725 a8083063 Iustin Pop
726 3a541d90 Iustin Pop
  def testFullMatch(self):
727 3a541d90 Iustin Pop
    """Test that a full match is returned correctly"""
728 3a541d90 Iustin Pop
    key1 = "test1"
729 3a541d90 Iustin Pop
    key2 = "test1.example"
730 3a541d90 Iustin Pop
    mlist = [key2, key2 + ".com"]
731 3a541d90 Iustin Pop
    self.failUnlessEqual(MatchNameComponent(key1, mlist), None)
732 3a541d90 Iustin Pop
    self.failUnlessEqual(MatchNameComponent(key2, mlist), key2)
733 3a541d90 Iustin Pop
734 256eb94b Guido Trotter
  def testCaseInsensitivePartialMatch(self):
735 256eb94b Guido Trotter
    """Test for the case_insensitive keyword"""
736 256eb94b Guido Trotter
    mlist = ["test1.example.com", "test2.example.net"]
737 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("test2", mlist, case_sensitive=False),
738 256eb94b Guido Trotter
                     "test2.example.net")
739 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Test2", mlist, case_sensitive=False),
740 256eb94b Guido Trotter
                     "test2.example.net")
741 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("teSt2", mlist, case_sensitive=False),
742 256eb94b Guido Trotter
                     "test2.example.net")
743 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("TeSt2", mlist, case_sensitive=False),
744 256eb94b Guido Trotter
                     "test2.example.net")
745 256eb94b Guido Trotter
746 256eb94b Guido Trotter
747 256eb94b Guido Trotter
  def testCaseInsensitiveFullMatch(self):
748 256eb94b Guido Trotter
    mlist = ["ts1.ex", "ts1.ex.org", "ts2.ex", "Ts2.ex"]
749 256eb94b Guido Trotter
    # Between the two ts1 a full string match non-case insensitive should work
750 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Ts1", mlist, case_sensitive=False),
751 256eb94b Guido Trotter
                     None)
752 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Ts1.ex", mlist, case_sensitive=False),
753 256eb94b Guido Trotter
                     "ts1.ex")
754 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("ts1.ex", mlist, case_sensitive=False),
755 256eb94b Guido Trotter
                     "ts1.ex")
756 256eb94b Guido Trotter
    # Between the two ts2 only case differs, so only case-match works
757 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("ts2.ex", mlist, case_sensitive=False),
758 256eb94b Guido Trotter
                     "ts2.ex")
759 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Ts2.ex", mlist, case_sensitive=False),
760 256eb94b Guido Trotter
                     "Ts2.ex")
761 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("TS2.ex", mlist, case_sensitive=False),
762 256eb94b Guido Trotter
                     None)
763 256eb94b Guido Trotter
764 a8083063 Iustin Pop
765 b774bb10 Michael Hanselmann
class TestReadFile(testutils.GanetiTestCase):
766 b774bb10 Michael Hanselmann
767 b774bb10 Michael Hanselmann
  def testReadAll(self):
768 b774bb10 Michael Hanselmann
    data = utils.ReadFile(self._TestDataFilename("cert1.pem"))
769 b774bb10 Michael Hanselmann
    self.assertEqual(len(data), 814)
770 b774bb10 Michael Hanselmann
771 716a32cb Guido Trotter
    h = compat.md5_hash()
772 b774bb10 Michael Hanselmann
    h.update(data)
773 b774bb10 Michael Hanselmann
    self.assertEqual(h.hexdigest(), "a491efb3efe56a0535f924d5f8680fd4")
774 b774bb10 Michael Hanselmann
775 b774bb10 Michael Hanselmann
  def testReadSize(self):
776 b774bb10 Michael Hanselmann
    data = utils.ReadFile(self._TestDataFilename("cert1.pem"),
777 b774bb10 Michael Hanselmann
                          size=100)
778 b774bb10 Michael Hanselmann
    self.assertEqual(len(data), 100)
779 b774bb10 Michael Hanselmann
780 716a32cb Guido Trotter
    h = compat.md5_hash()
781 b774bb10 Michael Hanselmann
    h.update(data)
782 b774bb10 Michael Hanselmann
    self.assertEqual(h.hexdigest(), "893772354e4e690b9efd073eed433ce7")
783 b774bb10 Michael Hanselmann
784 b774bb10 Michael Hanselmann
  def testError(self):
785 b774bb10 Michael Hanselmann
    self.assertRaises(EnvironmentError, utils.ReadFile,
786 582ed043 Guido Trotter
                      "/dev/null/does-not-exist")
787 b774bb10 Michael Hanselmann
788 b774bb10 Michael Hanselmann
789 e587b46a Guido Trotter
class TestReadOneLineFile(testutils.GanetiTestCase):
790 b774bb10 Michael Hanselmann
791 e587b46a Guido Trotter
  def setUp(self):
792 e587b46a Guido Trotter
    testutils.GanetiTestCase.setUp(self)
793 b774bb10 Michael Hanselmann
794 e587b46a Guido Trotter
  def testDefault(self):
795 e587b46a Guido Trotter
    data = ReadOneLineFile(self._TestDataFilename("cert1.pem"))
796 e587b46a Guido Trotter
    self.assertEqual(len(data), 27)
797 e587b46a Guido Trotter
    self.assertEqual(data, "-----BEGIN CERTIFICATE-----")
798 b774bb10 Michael Hanselmann
799 e587b46a Guido Trotter
  def testNotStrict(self):
800 e587b46a Guido Trotter
    data = ReadOneLineFile(self._TestDataFilename("cert1.pem"), strict=False)
801 e587b46a Guido Trotter
    self.assertEqual(len(data), 27)
802 e587b46a Guido Trotter
    self.assertEqual(data, "-----BEGIN CERTIFICATE-----")
803 b774bb10 Michael Hanselmann
804 e587b46a Guido Trotter
  def testStrictFailure(self):
805 e587b46a Guido Trotter
    self.assertRaises(errors.GenericError, ReadOneLineFile,
806 e587b46a Guido Trotter
                      self._TestDataFilename("cert1.pem"), strict=True)
807 b774bb10 Michael Hanselmann
808 e587b46a Guido Trotter
  def testLongLine(self):
809 e587b46a Guido Trotter
    dummydata = (1024 * "Hello World! ")
810 e587b46a Guido Trotter
    myfile = self._CreateTempFile()
811 e587b46a Guido Trotter
    utils.WriteFile(myfile, data=dummydata)
812 e587b46a Guido Trotter
    datastrict = ReadOneLineFile(myfile, strict=True)
813 e587b46a Guido Trotter
    datalax = ReadOneLineFile(myfile, strict=False)
814 e587b46a Guido Trotter
    self.assertEqual(dummydata, datastrict)
815 e587b46a Guido Trotter
    self.assertEqual(dummydata, datalax)
816 e587b46a Guido Trotter
817 e587b46a Guido Trotter
  def testNewline(self):
818 e587b46a Guido Trotter
    myfile = self._CreateTempFile()
819 e587b46a Guido Trotter
    myline = "myline"
820 e587b46a Guido Trotter
    for nl in ["", "\n", "\r\n"]:
821 e587b46a Guido Trotter
      dummydata = "%s%s" % (myline, nl)
822 e587b46a Guido Trotter
      utils.WriteFile(myfile, data=dummydata)
823 e587b46a Guido Trotter
      datalax = ReadOneLineFile(myfile, strict=False)
824 e587b46a Guido Trotter
      self.assertEqual(myline, datalax)
825 e587b46a Guido Trotter
      datastrict = ReadOneLineFile(myfile, strict=True)
826 e587b46a Guido Trotter
      self.assertEqual(myline, datastrict)
827 e587b46a Guido Trotter
828 e587b46a Guido Trotter
  def testWhitespaceAndMultipleLines(self):
829 e587b46a Guido Trotter
    myfile = self._CreateTempFile()
830 e587b46a Guido Trotter
    for nl in ["", "\n", "\r\n"]:
831 e587b46a Guido Trotter
      for ws in [" ", "\t", "\t\t  \t", "\t "]:
832 e587b46a Guido Trotter
        dummydata = (1024 * ("Foo bar baz %s%s" % (ws, nl)))
833 e587b46a Guido Trotter
        utils.WriteFile(myfile, data=dummydata)
834 e587b46a Guido Trotter
        datalax = ReadOneLineFile(myfile, strict=False)
835 e587b46a Guido Trotter
        if nl:
836 e587b46a Guido Trotter
          self.assert_(set("\r\n") & set(dummydata))
837 e587b46a Guido Trotter
          self.assertRaises(errors.GenericError, ReadOneLineFile,
838 e587b46a Guido Trotter
                            myfile, strict=True)
839 e587b46a Guido Trotter
          explen = len("Foo bar baz ") + len(ws)
840 e587b46a Guido Trotter
          self.assertEqual(len(datalax), explen)
841 e587b46a Guido Trotter
          self.assertEqual(datalax, dummydata[:explen])
842 e587b46a Guido Trotter
          self.assertFalse(set("\r\n") & set(datalax))
843 e587b46a Guido Trotter
        else:
844 e587b46a Guido Trotter
          datastrict = ReadOneLineFile(myfile, strict=True)
845 e587b46a Guido Trotter
          self.assertEqual(dummydata, datastrict)
846 e587b46a Guido Trotter
          self.assertEqual(dummydata, datalax)
847 e587b46a Guido Trotter
848 e587b46a Guido Trotter
  def testEmptylines(self):
849 e587b46a Guido Trotter
    myfile = self._CreateTempFile()
850 e587b46a Guido Trotter
    myline = "myline"
851 e587b46a Guido Trotter
    for nl in ["\n", "\r\n"]:
852 e587b46a Guido Trotter
      for ol in ["", "otherline"]:
853 e587b46a Guido Trotter
        dummydata = "%s%s%s%s%s%s" % (nl, nl, myline, nl, ol, nl)
854 e587b46a Guido Trotter
        utils.WriteFile(myfile, data=dummydata)
855 e587b46a Guido Trotter
        self.assert_(set("\r\n") & set(dummydata))
856 e587b46a Guido Trotter
        datalax = ReadOneLineFile(myfile, strict=False)
857 e587b46a Guido Trotter
        self.assertEqual(myline, datalax)
858 e587b46a Guido Trotter
        if ol:
859 e587b46a Guido Trotter
          self.assertRaises(errors.GenericError, ReadOneLineFile,
860 e587b46a Guido Trotter
                            myfile, strict=True)
861 e587b46a Guido Trotter
        else:
862 e587b46a Guido Trotter
          datastrict = ReadOneLineFile(myfile, strict=True)
863 e587b46a Guido Trotter
          self.assertEqual(myline, datastrict)
864 b774bb10 Michael Hanselmann
865 b774bb10 Michael Hanselmann
866 1d466a4f Michael Hanselmann
class TestTimestampForFilename(unittest.TestCase):
867 1d466a4f Michael Hanselmann
  def test(self):
868 1d466a4f Michael Hanselmann
    self.assert_("." not in utils.TimestampForFilename())
869 1d466a4f Michael Hanselmann
    self.assert_(":" not in utils.TimestampForFilename())
870 1d466a4f Michael Hanselmann
871 1d466a4f Michael Hanselmann
872 1d466a4f Michael Hanselmann
class TestCreateBackup(testutils.GanetiTestCase):
873 1d466a4f Michael Hanselmann
  def setUp(self):
874 1d466a4f Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
875 1d466a4f Michael Hanselmann
876 1d466a4f Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
877 1d466a4f Michael Hanselmann
878 1d466a4f Michael Hanselmann
  def tearDown(self):
879 1d466a4f Michael Hanselmann
    testutils.GanetiTestCase.tearDown(self)
880 1d466a4f Michael Hanselmann
881 1d466a4f Michael Hanselmann
    shutil.rmtree(self.tmpdir)
882 1d466a4f Michael Hanselmann
883 1d466a4f Michael Hanselmann
  def testEmpty(self):
884 1d466a4f Michael Hanselmann
    filename = utils.PathJoin(self.tmpdir, "config.data")
885 1d466a4f Michael Hanselmann
    utils.WriteFile(filename, data="")
886 1d466a4f Michael Hanselmann
    bname = utils.CreateBackup(filename)
887 1d466a4f Michael Hanselmann
    self.assertFileContent(bname, "")
888 1d466a4f Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 2)
889 1d466a4f Michael Hanselmann
    utils.CreateBackup(filename)
890 1d466a4f Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 3)
891 1d466a4f Michael Hanselmann
    utils.CreateBackup(filename)
892 1d466a4f Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 4)
893 1d466a4f Michael Hanselmann
894 1d466a4f Michael Hanselmann
    fifoname = utils.PathJoin(self.tmpdir, "fifo")
895 1d466a4f Michael Hanselmann
    os.mkfifo(fifoname)
896 1d466a4f Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, utils.CreateBackup, fifoname)
897 1d466a4f Michael Hanselmann
898 1d466a4f Michael Hanselmann
  def testContent(self):
899 1d466a4f Michael Hanselmann
    bkpcount = 0
900 1d466a4f Michael Hanselmann
    for data in ["", "X", "Hello World!\n" * 100, "Binary data\0\x01\x02\n"]:
901 1d466a4f Michael Hanselmann
      for rep in [1, 2, 10, 127]:
902 1d466a4f Michael Hanselmann
        testdata = data * rep
903 1d466a4f Michael Hanselmann
904 1d466a4f Michael Hanselmann
        filename = utils.PathJoin(self.tmpdir, "test.data_")
905 1d466a4f Michael Hanselmann
        utils.WriteFile(filename, data=testdata)
906 1d466a4f Michael Hanselmann
        self.assertFileContent(filename, testdata)
907 1d466a4f Michael Hanselmann
908 1d466a4f Michael Hanselmann
        for _ in range(3):
909 1d466a4f Michael Hanselmann
          bname = utils.CreateBackup(filename)
910 1d466a4f Michael Hanselmann
          bkpcount += 1
911 1d466a4f Michael Hanselmann
          self.assertFileContent(bname, testdata)
912 1d466a4f Michael Hanselmann
          self.assertEqual(len(glob.glob("%s*" % filename)), 1 + bkpcount)
913 1d466a4f Michael Hanselmann
914 1d466a4f Michael Hanselmann
915 a8083063 Iustin Pop
class TestFormatUnit(unittest.TestCase):
916 a8083063 Iustin Pop
  """Test case for the FormatUnit function"""
917 a8083063 Iustin Pop
918 a8083063 Iustin Pop
  def testMiB(self):
919 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1, 'h'), '1M')
920 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(100, 'h'), '100M')
921 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1023, 'h'), '1023M')
922 9fbfbb7b Iustin Pop
923 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1, 'm'), '1')
924 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(100, 'm'), '100')
925 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1023, 'm'), '1023')
926 9fbfbb7b Iustin Pop
927 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'm'), '1024')
928 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'm'), '1536')
929 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'm'), '17133')
930 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'm'), '1048575')
931 a8083063 Iustin Pop
932 a8083063 Iustin Pop
  def testGiB(self):
933 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'h'), '1.0G')
934 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'h'), '1.5G')
935 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'h'), '16.7G')
936 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'h'), '1024.0G')
937 9fbfbb7b Iustin Pop
938 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'g'), '1.0')
939 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'g'), '1.5')
940 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'g'), '16.7')
941 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'g'), '1024.0')
942 9fbfbb7b Iustin Pop
943 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 'g'), '1024.0')
944 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 'g'), '5120.0')
945 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 'g'), '29829.0')
946 a8083063 Iustin Pop
947 a8083063 Iustin Pop
  def testTiB(self):
948 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 'h'), '1.0T')
949 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 'h'), '5.0T')
950 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 'h'), '29.1T')
951 a8083063 Iustin Pop
952 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 't'), '1.0')
953 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 't'), '5.0')
954 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 't'), '29.1')
955 a8083063 Iustin Pop
956 a8083063 Iustin Pop
class TestParseUnit(unittest.TestCase):
957 a8083063 Iustin Pop
  """Test case for the ParseUnit function"""
958 a8083063 Iustin Pop
959 a8083063 Iustin Pop
  SCALES = (('', 1),
960 a8083063 Iustin Pop
            ('M', 1), ('G', 1024), ('T', 1024 * 1024),
961 a8083063 Iustin Pop
            ('MB', 1), ('GB', 1024), ('TB', 1024 * 1024),
962 a8083063 Iustin Pop
            ('MiB', 1), ('GiB', 1024), ('TiB', 1024 * 1024))
963 a8083063 Iustin Pop
964 a8083063 Iustin Pop
  def testRounding(self):
965 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0'), 0)
966 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1'), 4)
967 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2'), 4)
968 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('3'), 4)
969 a8083063 Iustin Pop
970 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('124'), 124)
971 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('125'), 128)
972 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('126'), 128)
973 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('127'), 128)
974 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('128'), 128)
975 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('129'), 132)
976 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('130'), 132)
977 a8083063 Iustin Pop
978 a8083063 Iustin Pop
  def testFloating(self):
979 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0'), 0)
980 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0.5'), 4)
981 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.75'), 4)
982 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.99'), 4)
983 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2.00'), 4)
984 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2.01'), 4)
985 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('3.99'), 4)
986 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('4.00'), 4)
987 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('4.01'), 8)
988 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.5G'), 1536)
989 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.8G'), 1844)
990 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('8.28T'), 8682212)
991 a8083063 Iustin Pop
992 a8083063 Iustin Pop
  def testSuffixes(self):
993 a8083063 Iustin Pop
    for sep in ('', ' ', '   ', "\t", "\t "):
994 a8083063 Iustin Pop
      for suffix, scale in TestParseUnit.SCALES:
995 a8083063 Iustin Pop
        for func in (lambda x: x, str.lower, str.upper):
996 667479d5 Michael Hanselmann
          self.assertEqual(ParseUnit('1024' + sep + func(suffix)),
997 667479d5 Michael Hanselmann
                           1024 * scale)
998 a8083063 Iustin Pop
999 a8083063 Iustin Pop
  def testInvalidInput(self):
1000 a8083063 Iustin Pop
    for sep in ('-', '_', ',', 'a'):
1001 a8083063 Iustin Pop
      for suffix, _ in TestParseUnit.SCALES:
1002 a8083063 Iustin Pop
        self.assertRaises(UnitParseError, ParseUnit, '1' + sep + suffix)
1003 a8083063 Iustin Pop
1004 a8083063 Iustin Pop
    for suffix, _ in TestParseUnit.SCALES:
1005 a8083063 Iustin Pop
      self.assertRaises(UnitParseError, ParseUnit, '1,3' + suffix)
1006 a8083063 Iustin Pop
1007 a8083063 Iustin Pop
1008 c9c4f19e Michael Hanselmann
class TestSshKeys(testutils.GanetiTestCase):
1009 a8083063 Iustin Pop
  """Test case for the AddAuthorizedKey function"""
1010 a8083063 Iustin Pop
1011 a8083063 Iustin Pop
  KEY_A = 'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a'
1012 a8083063 Iustin Pop
  KEY_B = ('command="/usr/bin/fooserver -t --verbose",from="1.2.3.4" '
1013 a8083063 Iustin Pop
           'ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b')
1014 a8083063 Iustin Pop
1015 ebe8ef17 Michael Hanselmann
  def setUp(self):
1016 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
1017 51596eb2 Iustin Pop
    self.tmpname = self._CreateTempFile()
1018 51596eb2 Iustin Pop
    handle = open(self.tmpname, 'w')
1019 a8083063 Iustin Pop
    try:
1020 51596eb2 Iustin Pop
      handle.write("%s\n" % TestSshKeys.KEY_A)
1021 51596eb2 Iustin Pop
      handle.write("%s\n" % TestSshKeys.KEY_B)
1022 51596eb2 Iustin Pop
    finally:
1023 51596eb2 Iustin Pop
      handle.close()
1024 a8083063 Iustin Pop
1025 a8083063 Iustin Pop
  def testAddingNewKey(self):
1026 ebe8ef17 Michael Hanselmann
    AddAuthorizedKey(self.tmpname, 'ssh-dss AAAAB3NzaC1kc3MAAACB root@test')
1027 a8083063 Iustin Pop
1028 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1029 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
1030 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
1031 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
1032 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1kc3MAAACB root@test\n")
1033 a8083063 Iustin Pop
1034 f89f17a8 Michael Hanselmann
  def testAddingAlmostButNotCompletelyTheSameKey(self):
1035 ebe8ef17 Michael Hanselmann
    AddAuthorizedKey(self.tmpname,
1036 ebe8ef17 Michael Hanselmann
        'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test')
1037 ebe8ef17 Michael Hanselmann
1038 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1039 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
1040 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
1041 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
1042 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test\n")
1043 a8083063 Iustin Pop
1044 a8083063 Iustin Pop
  def testAddingExistingKeyWithSomeMoreSpaces(self):
1045 ebe8ef17 Michael Hanselmann
    AddAuthorizedKey(self.tmpname,
1046 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
1047 a8083063 Iustin Pop
1048 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1049 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
1050 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
1051 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
1052 a8083063 Iustin Pop
1053 a8083063 Iustin Pop
  def testRemovingExistingKeyWithSomeMoreSpaces(self):
1054 ebe8ef17 Michael Hanselmann
    RemoveAuthorizedKey(self.tmpname,
1055 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
1056 a8083063 Iustin Pop
1057 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1058 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
1059 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
1060 a8083063 Iustin Pop
1061 a8083063 Iustin Pop
  def testRemovingNonExistingKey(self):
1062 ebe8ef17 Michael Hanselmann
    RemoveAuthorizedKey(self.tmpname,
1063 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3Nsdfj230xxjxJjsjwjsjdjU   root@test')
1064 a8083063 Iustin Pop
1065 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1066 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
1067 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
1068 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
1069 a8083063 Iustin Pop
1070 a8083063 Iustin Pop
1071 c9c4f19e Michael Hanselmann
class TestEtcHosts(testutils.GanetiTestCase):
1072 899d2a81 Michael Hanselmann
  """Test functions modifying /etc/hosts"""
1073 899d2a81 Michael Hanselmann
1074 ebe8ef17 Michael Hanselmann
  def setUp(self):
1075 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
1076 51596eb2 Iustin Pop
    self.tmpname = self._CreateTempFile()
1077 51596eb2 Iustin Pop
    handle = open(self.tmpname, 'w')
1078 899d2a81 Michael Hanselmann
    try:
1079 51596eb2 Iustin Pop
      handle.write('# This is a test file for /etc/hosts\n')
1080 51596eb2 Iustin Pop
      handle.write('127.0.0.1\tlocalhost\n')
1081 51596eb2 Iustin Pop
      handle.write('192.168.1.1 router gw\n')
1082 51596eb2 Iustin Pop
    finally:
1083 51596eb2 Iustin Pop
      handle.close()
1084 899d2a81 Michael Hanselmann
1085 9440aeab Michael Hanselmann
  def testSettingNewIp(self):
1086 ebe8ef17 Michael Hanselmann
    SetEtcHostsEntry(self.tmpname, '1.2.3.4', 'myhost.domain.tld', ['myhost'])
1087 899d2a81 Michael Hanselmann
1088 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1089 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1090 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
1091 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router gw\n"
1092 ebe8ef17 Michael Hanselmann
      "1.2.3.4\tmyhost.domain.tld myhost\n")
1093 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1094 899d2a81 Michael Hanselmann
1095 9440aeab Michael Hanselmann
  def testSettingExistingIp(self):
1096 ebe8ef17 Michael Hanselmann
    SetEtcHostsEntry(self.tmpname, '192.168.1.1', 'myhost.domain.tld',
1097 ebe8ef17 Michael Hanselmann
                     ['myhost'])
1098 899d2a81 Michael Hanselmann
1099 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1100 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1101 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
1102 ebe8ef17 Michael Hanselmann
      "192.168.1.1\tmyhost.domain.tld myhost\n")
1103 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1104 899d2a81 Michael Hanselmann
1105 7fbb1f65 Michael Hanselmann
  def testSettingDuplicateName(self):
1106 7fbb1f65 Michael Hanselmann
    SetEtcHostsEntry(self.tmpname, '1.2.3.4', 'myhost', ['myhost'])
1107 7fbb1f65 Michael Hanselmann
1108 7fbb1f65 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1109 7fbb1f65 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1110 7fbb1f65 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
1111 7fbb1f65 Michael Hanselmann
      "192.168.1.1 router gw\n"
1112 7fbb1f65 Michael Hanselmann
      "1.2.3.4\tmyhost\n")
1113 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1114 7fbb1f65 Michael Hanselmann
1115 899d2a81 Michael Hanselmann
  def testRemovingExistingHost(self):
1116 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'router')
1117 899d2a81 Michael Hanselmann
1118 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1119 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1120 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
1121 ebe8ef17 Michael Hanselmann
      "192.168.1.1 gw\n")
1122 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1123 899d2a81 Michael Hanselmann
1124 899d2a81 Michael Hanselmann
  def testRemovingSingleExistingHost(self):
1125 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'localhost')
1126 899d2a81 Michael Hanselmann
1127 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1128 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1129 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router gw\n")
1130 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1131 899d2a81 Michael Hanselmann
1132 899d2a81 Michael Hanselmann
  def testRemovingNonExistingHost(self):
1133 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'myhost')
1134 899d2a81 Michael Hanselmann
1135 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1136 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1137 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
1138 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router gw\n")
1139 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1140 899d2a81 Michael Hanselmann
1141 9440aeab Michael Hanselmann
  def testRemovingAlias(self):
1142 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'gw')
1143 9440aeab Michael Hanselmann
1144 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1145 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1146 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
1147 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router\n")
1148 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1149 9440aeab Michael Hanselmann
1150 899d2a81 Michael Hanselmann
1151 a8083063 Iustin Pop
class TestShellQuoting(unittest.TestCase):
1152 a8083063 Iustin Pop
  """Test case for shell quoting functions"""
1153 a8083063 Iustin Pop
1154 a8083063 Iustin Pop
  def testShellQuote(self):
1155 a8083063 Iustin Pop
    self.assertEqual(ShellQuote('abc'), "abc")
1156 a8083063 Iustin Pop
    self.assertEqual(ShellQuote('ab"c'), "'ab\"c'")
1157 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a'bc"), "'a'\\''bc'")
1158 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a b c"), "'a b c'")
1159 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a b\\ c"), "'a b\\ c'")
1160 a8083063 Iustin Pop
1161 a8083063 Iustin Pop
  def testShellQuoteArgs(self):
1162 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b', 'c']), "a b c")
1163 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b"', 'c']), "a 'b\"' c")
1164 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b\'', 'c']), "a 'b'\\\''' c")
1165 a8083063 Iustin Pop
1166 a8083063 Iustin Pop
1167 2c30e9d7 Alexander Schreiber
class TestTcpPing(unittest.TestCase):
1168 2c30e9d7 Alexander Schreiber
  """Testcase for TCP version of ping - against listen(2)ing port"""
1169 2c30e9d7 Alexander Schreiber
1170 2c30e9d7 Alexander Schreiber
  def setUp(self):
1171 2c30e9d7 Alexander Schreiber
    self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1172 16abfbc2 Alexander Schreiber
    self.listener.bind((constants.LOCALHOST_IP_ADDRESS, 0))
1173 2c30e9d7 Alexander Schreiber
    self.listenerport = self.listener.getsockname()[1]
1174 2c30e9d7 Alexander Schreiber
    self.listener.listen(1)
1175 2c30e9d7 Alexander Schreiber
1176 2c30e9d7 Alexander Schreiber
  def tearDown(self):
1177 2c30e9d7 Alexander Schreiber
    self.listener.shutdown(socket.SHUT_RDWR)
1178 2c30e9d7 Alexander Schreiber
    del self.listener
1179 2c30e9d7 Alexander Schreiber
    del self.listenerport
1180 2c30e9d7 Alexander Schreiber
1181 2c30e9d7 Alexander Schreiber
  def testTcpPingToLocalHostAccept(self):
1182 16abfbc2 Alexander Schreiber
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
1183 2c30e9d7 Alexander Schreiber
                         self.listenerport,
1184 2c30e9d7 Alexander Schreiber
                         timeout=10,
1185 b15d625f Iustin Pop
                         live_port_needed=True,
1186 b15d625f Iustin Pop
                         source=constants.LOCALHOST_IP_ADDRESS,
1187 b15d625f Iustin Pop
                         ),
1188 2c30e9d7 Alexander Schreiber
                 "failed to connect to test listener")
1189 2c30e9d7 Alexander Schreiber
1190 b15d625f Iustin Pop
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
1191 b15d625f Iustin Pop
                         self.listenerport,
1192 b15d625f Iustin Pop
                         timeout=10,
1193 b15d625f Iustin Pop
                         live_port_needed=True,
1194 b15d625f Iustin Pop
                         ),
1195 b15d625f Iustin Pop
                 "failed to connect to test listener (no source)")
1196 b15d625f Iustin Pop
1197 2c30e9d7 Alexander Schreiber
1198 2c30e9d7 Alexander Schreiber
class TestTcpPingDeaf(unittest.TestCase):
1199 2c30e9d7 Alexander Schreiber
  """Testcase for TCP version of ping - against non listen(2)ing port"""
1200 2c30e9d7 Alexander Schreiber
1201 2c30e9d7 Alexander Schreiber
  def setUp(self):
1202 2c30e9d7 Alexander Schreiber
    self.deaflistener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1203 16abfbc2 Alexander Schreiber
    self.deaflistener.bind((constants.LOCALHOST_IP_ADDRESS, 0))
1204 2c30e9d7 Alexander Schreiber
    self.deaflistenerport = self.deaflistener.getsockname()[1]
1205 2c30e9d7 Alexander Schreiber
1206 2c30e9d7 Alexander Schreiber
  def tearDown(self):
1207 2c30e9d7 Alexander Schreiber
    del self.deaflistener
1208 2c30e9d7 Alexander Schreiber
    del self.deaflistenerport
1209 2c30e9d7 Alexander Schreiber
1210 2c30e9d7 Alexander Schreiber
  def testTcpPingToLocalHostAcceptDeaf(self):
1211 16abfbc2 Alexander Schreiber
    self.failIf(TcpPing(constants.LOCALHOST_IP_ADDRESS,
1212 2c30e9d7 Alexander Schreiber
                        self.deaflistenerport,
1213 16abfbc2 Alexander Schreiber
                        timeout=constants.TCP_PING_TIMEOUT,
1214 b15d625f Iustin Pop
                        live_port_needed=True,
1215 b15d625f Iustin Pop
                        source=constants.LOCALHOST_IP_ADDRESS,
1216 b15d625f Iustin Pop
                        ), # need successful connect(2)
1217 2c30e9d7 Alexander Schreiber
                "successfully connected to deaf listener")
1218 2c30e9d7 Alexander Schreiber
1219 b15d625f Iustin Pop
    self.failIf(TcpPing(constants.LOCALHOST_IP_ADDRESS,
1220 b15d625f Iustin Pop
                        self.deaflistenerport,
1221 b15d625f Iustin Pop
                        timeout=constants.TCP_PING_TIMEOUT,
1222 b15d625f Iustin Pop
                        live_port_needed=True,
1223 b15d625f Iustin Pop
                        ), # need successful connect(2)
1224 b15d625f Iustin Pop
                "successfully connected to deaf listener (no source addr)")
1225 b15d625f Iustin Pop
1226 2c30e9d7 Alexander Schreiber
  def testTcpPingToLocalHostNoAccept(self):
1227 16abfbc2 Alexander Schreiber
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
1228 2c30e9d7 Alexander Schreiber
                         self.deaflistenerport,
1229 16abfbc2 Alexander Schreiber
                         timeout=constants.TCP_PING_TIMEOUT,
1230 b15d625f Iustin Pop
                         live_port_needed=False,
1231 b15d625f Iustin Pop
                         source=constants.LOCALHOST_IP_ADDRESS,
1232 b15d625f Iustin Pop
                         ), # ECONNREFUSED is OK
1233 2c30e9d7 Alexander Schreiber
                 "failed to ping alive host on deaf port")
1234 2c30e9d7 Alexander Schreiber
1235 b15d625f Iustin Pop
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
1236 b15d625f Iustin Pop
                         self.deaflistenerport,
1237 b15d625f Iustin Pop
                         timeout=constants.TCP_PING_TIMEOUT,
1238 b15d625f Iustin Pop
                         live_port_needed=False,
1239 b15d625f Iustin Pop
                         ), # ECONNREFUSED is OK
1240 b15d625f Iustin Pop
                 "failed to ping alive host on deaf port (no source addr)")
1241 b15d625f Iustin Pop
1242 2c30e9d7 Alexander Schreiber
1243 caad16e2 Iustin Pop
class TestOwnIpAddress(unittest.TestCase):
1244 caad16e2 Iustin Pop
  """Testcase for OwnIpAddress"""
1245 caad16e2 Iustin Pop
1246 caad16e2 Iustin Pop
  def testOwnLoopback(self):
1247 caad16e2 Iustin Pop
    """check having the loopback ip"""
1248 caad16e2 Iustin Pop
    self.failUnless(OwnIpAddress(constants.LOCALHOST_IP_ADDRESS),
1249 caad16e2 Iustin Pop
                    "Should own the loopback address")
1250 caad16e2 Iustin Pop
1251 caad16e2 Iustin Pop
  def testNowOwnAddress(self):
1252 caad16e2 Iustin Pop
    """check that I don't own an address"""
1253 caad16e2 Iustin Pop
1254 a3a5f850 Iustin Pop
    # Network 192.0.2.0/24 is reserved for test/documentation as per
1255 a3a5f850 Iustin Pop
    # RFC 5735, so we *should* not have an address of this range... if
1256 caad16e2 Iustin Pop
    # this fails, we should extend the test to multiple addresses
1257 caad16e2 Iustin Pop
    DST_IP = "192.0.2.1"
1258 caad16e2 Iustin Pop
    self.failIf(OwnIpAddress(DST_IP), "Should not own IP address %s" % DST_IP)
1259 caad16e2 Iustin Pop
1260 caad16e2 Iustin Pop
1261 f93f2016 Michael Hanselmann
def _GetSocketCredentials(path):
1262 f93f2016 Michael Hanselmann
  """Connect to a Unix socket and return remote credentials.
1263 f93f2016 Michael Hanselmann

1264 f93f2016 Michael Hanselmann
  """
1265 f93f2016 Michael Hanselmann
  sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
1266 f93f2016 Michael Hanselmann
  try:
1267 f93f2016 Michael Hanselmann
    sock.settimeout(10)
1268 f93f2016 Michael Hanselmann
    sock.connect(path)
1269 f93f2016 Michael Hanselmann
    return utils.GetSocketCredentials(sock)
1270 f93f2016 Michael Hanselmann
  finally:
1271 f93f2016 Michael Hanselmann
    sock.close()
1272 f93f2016 Michael Hanselmann
1273 f93f2016 Michael Hanselmann
1274 f93f2016 Michael Hanselmann
class TestGetSocketCredentials(unittest.TestCase):
1275 f93f2016 Michael Hanselmann
  def setUp(self):
1276 f93f2016 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
1277 f93f2016 Michael Hanselmann
    self.sockpath = utils.PathJoin(self.tmpdir, "sock")
1278 f93f2016 Michael Hanselmann
1279 f93f2016 Michael Hanselmann
    self.listener = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
1280 f93f2016 Michael Hanselmann
    self.listener.settimeout(10)
1281 f93f2016 Michael Hanselmann
    self.listener.bind(self.sockpath)
1282 f93f2016 Michael Hanselmann
    self.listener.listen(1)
1283 f93f2016 Michael Hanselmann
1284 f93f2016 Michael Hanselmann
  def tearDown(self):
1285 f93f2016 Michael Hanselmann
    self.listener.shutdown(socket.SHUT_RDWR)
1286 f93f2016 Michael Hanselmann
    self.listener.close()
1287 f93f2016 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
1288 f93f2016 Michael Hanselmann
1289 f93f2016 Michael Hanselmann
  def test(self):
1290 f93f2016 Michael Hanselmann
    (c2pr, c2pw) = os.pipe()
1291 f93f2016 Michael Hanselmann
1292 f93f2016 Michael Hanselmann
    # Start child process
1293 f93f2016 Michael Hanselmann
    child = os.fork()
1294 f93f2016 Michael Hanselmann
    if child == 0:
1295 f93f2016 Michael Hanselmann
      try:
1296 f93f2016 Michael Hanselmann
        data = serializer.DumpJson(_GetSocketCredentials(self.sockpath))
1297 f93f2016 Michael Hanselmann
1298 f93f2016 Michael Hanselmann
        os.write(c2pw, data)
1299 f93f2016 Michael Hanselmann
        os.close(c2pw)
1300 f93f2016 Michael Hanselmann
1301 f93f2016 Michael Hanselmann
        os._exit(0)
1302 f93f2016 Michael Hanselmann
      finally:
1303 f93f2016 Michael Hanselmann
        os._exit(1)
1304 f93f2016 Michael Hanselmann
1305 f93f2016 Michael Hanselmann
    os.close(c2pw)
1306 f93f2016 Michael Hanselmann
1307 f93f2016 Michael Hanselmann
    # Wait for one connection
1308 f93f2016 Michael Hanselmann
    (conn, _) = self.listener.accept()
1309 f93f2016 Michael Hanselmann
    conn.recv(1)
1310 f93f2016 Michael Hanselmann
    conn.close()
1311 f93f2016 Michael Hanselmann
1312 f93f2016 Michael Hanselmann
    # Wait for result
1313 f93f2016 Michael Hanselmann
    result = os.read(c2pr, 4096)
1314 f93f2016 Michael Hanselmann
    os.close(c2pr)
1315 f93f2016 Michael Hanselmann
1316 f93f2016 Michael Hanselmann
    # Check child's exit code
1317 f93f2016 Michael Hanselmann
    (_, status) = os.waitpid(child, 0)
1318 f93f2016 Michael Hanselmann
    self.assertFalse(os.WIFSIGNALED(status))
1319 f93f2016 Michael Hanselmann
    self.assertEqual(os.WEXITSTATUS(status), 0)
1320 f93f2016 Michael Hanselmann
1321 f93f2016 Michael Hanselmann
    # Check result
1322 f93f2016 Michael Hanselmann
    (pid, uid, gid) = serializer.LoadJson(result)
1323 f93f2016 Michael Hanselmann
    self.assertEqual(pid, os.getpid())
1324 f93f2016 Michael Hanselmann
    self.assertEqual(uid, os.getuid())
1325 f93f2016 Michael Hanselmann
    self.assertEqual(gid, os.getgid())
1326 f93f2016 Michael Hanselmann
1327 f93f2016 Michael Hanselmann
1328 eedbda4b Michael Hanselmann
class TestListVisibleFiles(unittest.TestCase):
1329 eedbda4b Michael Hanselmann
  """Test case for ListVisibleFiles"""
1330 eedbda4b Michael Hanselmann
1331 eedbda4b Michael Hanselmann
  def setUp(self):
1332 eedbda4b Michael Hanselmann
    self.path = tempfile.mkdtemp()
1333 eedbda4b Michael Hanselmann
1334 eedbda4b Michael Hanselmann
  def tearDown(self):
1335 eedbda4b Michael Hanselmann
    shutil.rmtree(self.path)
1336 eedbda4b Michael Hanselmann
1337 57d56130 Guido Trotter
  def _CreateFiles(self, files):
1338 eedbda4b Michael Hanselmann
    for name in files:
1339 57d56130 Guido Trotter
      utils.WriteFile(os.path.join(self.path, name), data="test")
1340 eedbda4b Michael Hanselmann
1341 57d56130 Guido Trotter
  def _test(self, files, expected):
1342 57d56130 Guido Trotter
    self._CreateFiles(files)
1343 eedbda4b Michael Hanselmann
    found = ListVisibleFiles(self.path)
1344 b5b8309d Guido Trotter
    self.assertEqual(set(found), set(expected))
1345 eedbda4b Michael Hanselmann
1346 eedbda4b Michael Hanselmann
  def testAllVisible(self):
1347 eedbda4b Michael Hanselmann
    files = ["a", "b", "c"]
1348 eedbda4b Michael Hanselmann
    expected = files
1349 eedbda4b Michael Hanselmann
    self._test(files, expected)
1350 eedbda4b Michael Hanselmann
1351 eedbda4b Michael Hanselmann
  def testNoneVisible(self):
1352 eedbda4b Michael Hanselmann
    files = [".a", ".b", ".c"]
1353 eedbda4b Michael Hanselmann
    expected = []
1354 eedbda4b Michael Hanselmann
    self._test(files, expected)
1355 eedbda4b Michael Hanselmann
1356 eedbda4b Michael Hanselmann
  def testSomeVisible(self):
1357 eedbda4b Michael Hanselmann
    files = ["a", "b", ".c"]
1358 eedbda4b Michael Hanselmann
    expected = ["a", "b"]
1359 eedbda4b Michael Hanselmann
    self._test(files, expected)
1360 eedbda4b Michael Hanselmann
1361 04a69a18 Iustin Pop
  def testNonAbsolutePath(self):
1362 04a69a18 Iustin Pop
    self.failUnlessRaises(errors.ProgrammerError, ListVisibleFiles, "abc")
1363 04a69a18 Iustin Pop
1364 04a69a18 Iustin Pop
  def testNonNormalizedPath(self):
1365 04a69a18 Iustin Pop
    self.failUnlessRaises(errors.ProgrammerError, ListVisibleFiles,
1366 04a69a18 Iustin Pop
                          "/bin/../tmp")
1367 04a69a18 Iustin Pop
1368 eedbda4b Michael Hanselmann
1369 24818e8f Michael Hanselmann
class TestNewUUID(unittest.TestCase):
1370 24818e8f Michael Hanselmann
  """Test case for NewUUID"""
1371 59072e7e Michael Hanselmann
1372 59072e7e Michael Hanselmann
  _re_uuid = re.compile('^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-'
1373 59072e7e Michael Hanselmann
                        '[a-f0-9]{4}-[a-f0-9]{12}$')
1374 59072e7e Michael Hanselmann
1375 59072e7e Michael Hanselmann
  def runTest(self):
1376 24818e8f Michael Hanselmann
    self.failUnless(self._re_uuid.match(utils.NewUUID()))
1377 59072e7e Michael Hanselmann
1378 59072e7e Michael Hanselmann
1379 f7414041 Michael Hanselmann
class TestUniqueSequence(unittest.TestCase):
1380 f7414041 Michael Hanselmann
  """Test case for UniqueSequence"""
1381 f7414041 Michael Hanselmann
1382 f7414041 Michael Hanselmann
  def _test(self, input, expected):
1383 f7414041 Michael Hanselmann
    self.assertEqual(utils.UniqueSequence(input), expected)
1384 f7414041 Michael Hanselmann
1385 f7414041 Michael Hanselmann
  def runTest(self):
1386 f7414041 Michael Hanselmann
    # Ordered input
1387 f7414041 Michael Hanselmann
    self._test([1, 2, 3], [1, 2, 3])
1388 f7414041 Michael Hanselmann
    self._test([1, 1, 2, 2, 3, 3], [1, 2, 3])
1389 f7414041 Michael Hanselmann
    self._test([1, 2, 2, 3], [1, 2, 3])
1390 f7414041 Michael Hanselmann
    self._test([1, 2, 3, 3], [1, 2, 3])
1391 f7414041 Michael Hanselmann
1392 f7414041 Michael Hanselmann
    # Unordered input
1393 f7414041 Michael Hanselmann
    self._test([1, 2, 3, 1, 2, 3], [1, 2, 3])
1394 f7414041 Michael Hanselmann
    self._test([1, 1, 2, 3, 3, 1, 2], [1, 2, 3])
1395 f7414041 Michael Hanselmann
1396 f7414041 Michael Hanselmann
    # Strings
1397 f7414041 Michael Hanselmann
    self._test(["a", "a"], ["a"])
1398 f7414041 Michael Hanselmann
    self._test(["a", "b"], ["a", "b"])
1399 f7414041 Michael Hanselmann
    self._test(["a", "b", "a"], ["a", "b"])
1400 f7414041 Michael Hanselmann
1401 a87b4824 Michael Hanselmann
1402 7b4126b7 Iustin Pop
class TestFirstFree(unittest.TestCase):
1403 7b4126b7 Iustin Pop
  """Test case for the FirstFree function"""
1404 7b4126b7 Iustin Pop
1405 7b4126b7 Iustin Pop
  def test(self):
1406 7b4126b7 Iustin Pop
    """Test FirstFree"""
1407 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([0, 1, 3]), 2)
1408 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([]), None)
1409 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([3, 4, 6]), 0)
1410 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([3, 4, 6], base=3), 5)
1411 7b4126b7 Iustin Pop
    self.failUnlessRaises(AssertionError, FirstFree, [0, 3, 4, 6], base=3)
1412 f7414041 Michael Hanselmann
1413 a87b4824 Michael Hanselmann
1414 f65f63ef Iustin Pop
class TestTailFile(testutils.GanetiTestCase):
1415 f65f63ef Iustin Pop
  """Test case for the TailFile function"""
1416 f65f63ef Iustin Pop
1417 f65f63ef Iustin Pop
  def testEmpty(self):
1418 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1419 f65f63ef Iustin Pop
    self.failUnlessEqual(TailFile(fname), [])
1420 f65f63ef Iustin Pop
    self.failUnlessEqual(TailFile(fname, lines=25), [])
1421 f65f63ef Iustin Pop
1422 f65f63ef Iustin Pop
  def testAllLines(self):
1423 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1424 f65f63ef Iustin Pop
    for i in range(30):
1425 f65f63ef Iustin Pop
      fname = self._CreateTempFile()
1426 f65f63ef Iustin Pop
      fd = open(fname, "w")
1427 f65f63ef Iustin Pop
      fd.write("\n".join(data[:i]))
1428 f65f63ef Iustin Pop
      if i > 0:
1429 f65f63ef Iustin Pop
        fd.write("\n")
1430 f65f63ef Iustin Pop
      fd.close()
1431 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[:i])
1432 f65f63ef Iustin Pop
1433 f65f63ef Iustin Pop
  def testPartialLines(self):
1434 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1435 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1436 f65f63ef Iustin Pop
    fd = open(fname, "w")
1437 f65f63ef Iustin Pop
    fd.write("\n".join(data))
1438 f65f63ef Iustin Pop
    fd.write("\n")
1439 f65f63ef Iustin Pop
    fd.close()
1440 f65f63ef Iustin Pop
    for i in range(1, 30):
1441 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[-i:])
1442 f65f63ef Iustin Pop
1443 f65f63ef Iustin Pop
  def testBigFile(self):
1444 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1445 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1446 f65f63ef Iustin Pop
    fd = open(fname, "w")
1447 f65f63ef Iustin Pop
    fd.write("X" * 1048576)
1448 f65f63ef Iustin Pop
    fd.write("\n")
1449 f65f63ef Iustin Pop
    fd.write("\n".join(data))
1450 f65f63ef Iustin Pop
    fd.write("\n")
1451 f65f63ef Iustin Pop
    fd.close()
1452 f65f63ef Iustin Pop
    for i in range(1, 30):
1453 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[-i:])
1454 f65f63ef Iustin Pop
1455 f65f63ef Iustin Pop
1456 b4478d34 Michael Hanselmann
class _BaseFileLockTest:
1457 a87b4824 Michael Hanselmann
  """Test case for the FileLock class"""
1458 a87b4824 Michael Hanselmann
1459 a87b4824 Michael Hanselmann
  def testSharedNonblocking(self):
1460 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1461 a87b4824 Michael Hanselmann
    self.lock.Close()
1462 a87b4824 Michael Hanselmann
1463 a87b4824 Michael Hanselmann
  def testExclusiveNonblocking(self):
1464 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1465 a87b4824 Michael Hanselmann
    self.lock.Close()
1466 a87b4824 Michael Hanselmann
1467 a87b4824 Michael Hanselmann
  def testUnlockNonblocking(self):
1468 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1469 a87b4824 Michael Hanselmann
    self.lock.Close()
1470 a87b4824 Michael Hanselmann
1471 a87b4824 Michael Hanselmann
  def testSharedBlocking(self):
1472 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=True)
1473 a87b4824 Michael Hanselmann
    self.lock.Close()
1474 a87b4824 Michael Hanselmann
1475 a87b4824 Michael Hanselmann
  def testExclusiveBlocking(self):
1476 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=True)
1477 a87b4824 Michael Hanselmann
    self.lock.Close()
1478 a87b4824 Michael Hanselmann
1479 a87b4824 Michael Hanselmann
  def testUnlockBlocking(self):
1480 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=True)
1481 a87b4824 Michael Hanselmann
    self.lock.Close()
1482 a87b4824 Michael Hanselmann
1483 a87b4824 Michael Hanselmann
  def testSharedExclusiveUnlock(self):
1484 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1485 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1486 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1487 a87b4824 Michael Hanselmann
    self.lock.Close()
1488 a87b4824 Michael Hanselmann
1489 a87b4824 Michael Hanselmann
  def testExclusiveSharedUnlock(self):
1490 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1491 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1492 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1493 a87b4824 Michael Hanselmann
    self.lock.Close()
1494 a87b4824 Michael Hanselmann
1495 b4478d34 Michael Hanselmann
  def testSimpleTimeout(self):
1496 b4478d34 Michael Hanselmann
    # These will succeed on the first attempt, hence a short timeout
1497 b4478d34 Michael Hanselmann
    self.lock.Shared(blocking=True, timeout=10.0)
1498 b4478d34 Michael Hanselmann
    self.lock.Exclusive(blocking=False, timeout=10.0)
1499 b4478d34 Michael Hanselmann
    self.lock.Unlock(blocking=True, timeout=10.0)
1500 b4478d34 Michael Hanselmann
    self.lock.Close()
1501 b4478d34 Michael Hanselmann
1502 b4478d34 Michael Hanselmann
  @staticmethod
1503 b4478d34 Michael Hanselmann
  def _TryLockInner(filename, shared, blocking):
1504 b4478d34 Michael Hanselmann
    lock = utils.FileLock.Open(filename)
1505 b4478d34 Michael Hanselmann
1506 b4478d34 Michael Hanselmann
    if shared:
1507 b4478d34 Michael Hanselmann
      fn = lock.Shared
1508 b4478d34 Michael Hanselmann
    else:
1509 b4478d34 Michael Hanselmann
      fn = lock.Exclusive
1510 b4478d34 Michael Hanselmann
1511 b4478d34 Michael Hanselmann
    try:
1512 b4478d34 Michael Hanselmann
      # The timeout doesn't really matter as the parent process waits for us to
1513 b4478d34 Michael Hanselmann
      # finish anyway.
1514 b4478d34 Michael Hanselmann
      fn(blocking=blocking, timeout=0.01)
1515 b4478d34 Michael Hanselmann
    except errors.LockError, err:
1516 b4478d34 Michael Hanselmann
      return False
1517 b4478d34 Michael Hanselmann
1518 b4478d34 Michael Hanselmann
    return True
1519 b4478d34 Michael Hanselmann
1520 b4478d34 Michael Hanselmann
  def _TryLock(self, *args):
1521 b4478d34 Michael Hanselmann
    return utils.RunInSeparateProcess(self._TryLockInner, self.tmpfile.name,
1522 b4478d34 Michael Hanselmann
                                      *args)
1523 b4478d34 Michael Hanselmann
1524 b4478d34 Michael Hanselmann
  def testTimeout(self):
1525 b4478d34 Michael Hanselmann
    for blocking in [True, False]:
1526 b4478d34 Michael Hanselmann
      self.lock.Exclusive(blocking=True)
1527 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(False, blocking))
1528 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(True, blocking))
1529 b4478d34 Michael Hanselmann
1530 b4478d34 Michael Hanselmann
      self.lock.Shared(blocking=True)
1531 b4478d34 Michael Hanselmann
      self.assert_(self._TryLock(True, blocking))
1532 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(False, blocking))
1533 b4478d34 Michael Hanselmann
1534 a87b4824 Michael Hanselmann
  def testCloseShared(self):
1535 a87b4824 Michael Hanselmann
    self.lock.Close()
1536 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Shared, blocking=False)
1537 a87b4824 Michael Hanselmann
1538 a87b4824 Michael Hanselmann
  def testCloseExclusive(self):
1539 a87b4824 Michael Hanselmann
    self.lock.Close()
1540 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Exclusive, blocking=False)
1541 a87b4824 Michael Hanselmann
1542 a87b4824 Michael Hanselmann
  def testCloseUnlock(self):
1543 a87b4824 Michael Hanselmann
    self.lock.Close()
1544 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Unlock, blocking=False)
1545 a87b4824 Michael Hanselmann
1546 a87b4824 Michael Hanselmann
1547 b4478d34 Michael Hanselmann
class TestFileLockWithFilename(testutils.GanetiTestCase, _BaseFileLockTest):
1548 b4478d34 Michael Hanselmann
  TESTDATA = "Hello World\n" * 10
1549 b4478d34 Michael Hanselmann
1550 b4478d34 Michael Hanselmann
  def setUp(self):
1551 b4478d34 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
1552 b4478d34 Michael Hanselmann
1553 b4478d34 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1554 b4478d34 Michael Hanselmann
    utils.WriteFile(self.tmpfile.name, data=self.TESTDATA)
1555 b4478d34 Michael Hanselmann
    self.lock = utils.FileLock.Open(self.tmpfile.name)
1556 b4478d34 Michael Hanselmann
1557 b4478d34 Michael Hanselmann
    # Ensure "Open" didn't truncate file
1558 b4478d34 Michael Hanselmann
    self.assertFileContent(self.tmpfile.name, self.TESTDATA)
1559 b4478d34 Michael Hanselmann
1560 b4478d34 Michael Hanselmann
  def tearDown(self):
1561 b4478d34 Michael Hanselmann
    self.assertFileContent(self.tmpfile.name, self.TESTDATA)
1562 b4478d34 Michael Hanselmann
1563 b4478d34 Michael Hanselmann
    testutils.GanetiTestCase.tearDown(self)
1564 b4478d34 Michael Hanselmann
1565 b4478d34 Michael Hanselmann
1566 b4478d34 Michael Hanselmann
class TestFileLockWithFileObject(unittest.TestCase, _BaseFileLockTest):
1567 b4478d34 Michael Hanselmann
  def setUp(self):
1568 b4478d34 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1569 b4478d34 Michael Hanselmann
    self.lock = utils.FileLock(open(self.tmpfile.name, "w"), self.tmpfile.name)
1570 b4478d34 Michael Hanselmann
1571 b4478d34 Michael Hanselmann
1572 739be818 Michael Hanselmann
class TestTimeFunctions(unittest.TestCase):
1573 739be818 Michael Hanselmann
  """Test case for time functions"""
1574 739be818 Michael Hanselmann
1575 739be818 Michael Hanselmann
  def runTest(self):
1576 739be818 Michael Hanselmann
    self.assertEqual(utils.SplitTime(1), (1, 0))
1577 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(1.5), (1, 500000))
1578 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(1218448917.4809151), (1218448917, 480915))
1579 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.48012), (123, 480120))
1580 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9996), (123, 999600))
1581 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9995), (123, 999500))
1582 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9994), (123, 999400))
1583 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.999999999), (123, 999999))
1584 45bc5e4a Michael Hanselmann
1585 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.SplitTime, -1)
1586 739be818 Michael Hanselmann
1587 739be818 Michael Hanselmann
    self.assertEqual(utils.MergeTime((1, 0)), 1.0)
1588 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.MergeTime((1, 500000)), 1.5)
1589 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.MergeTime((1218448917, 500000)), 1218448917.5)
1590 739be818 Michael Hanselmann
1591 4d4a651d Michael Hanselmann
    self.assertEqual(round(utils.MergeTime((1218448917, 481000)), 3),
1592 4d4a651d Michael Hanselmann
                     1218448917.481)
1593 45bc5e4a Michael Hanselmann
    self.assertEqual(round(utils.MergeTime((1, 801000)), 3), 1.801)
1594 739be818 Michael Hanselmann
1595 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, -1))
1596 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, 1000000))
1597 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, 9999999))
1598 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (-1, 0))
1599 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (-9999, 0))
1600 739be818 Michael Hanselmann
1601 739be818 Michael Hanselmann
1602 a2d2e1a7 Iustin Pop
class FieldSetTestCase(unittest.TestCase):
1603 a2d2e1a7 Iustin Pop
  """Test case for FieldSets"""
1604 a2d2e1a7 Iustin Pop
1605 a2d2e1a7 Iustin Pop
  def testSimpleMatch(self):
1606 a2d2e1a7 Iustin Pop
    f = utils.FieldSet("a", "b", "c", "def")
1607 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("a"))
1608 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("d"), "Substring matched")
1609 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("defghi"), "Prefix string matched")
1610 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["b", "c"]))
1611 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["a", "b", "c", "def"]))
1612 a2d2e1a7 Iustin Pop
    self.failUnless(f.NonMatching(["a", "d"]))
1613 a2d2e1a7 Iustin Pop
1614 a2d2e1a7 Iustin Pop
  def testRegexMatch(self):
1615 a2d2e1a7 Iustin Pop
    f = utils.FieldSet("a", "b([0-9]+)", "c")
1616 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("b1"))
1617 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("b99"))
1618 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("b/1"))
1619 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["b12", "c"]))
1620 a2d2e1a7 Iustin Pop
    self.failUnless(f.NonMatching(["a", "1"]))
1621 a2d2e1a7 Iustin Pop
1622 a5728081 Guido Trotter
class TestForceDictType(unittest.TestCase):
1623 a5728081 Guido Trotter
  """Test case for ForceDictType"""
1624 a5728081 Guido Trotter
1625 a5728081 Guido Trotter
  def setUp(self):
1626 a5728081 Guido Trotter
    self.key_types = {
1627 a5728081 Guido Trotter
      'a': constants.VTYPE_INT,
1628 a5728081 Guido Trotter
      'b': constants.VTYPE_BOOL,
1629 a5728081 Guido Trotter
      'c': constants.VTYPE_STRING,
1630 a5728081 Guido Trotter
      'd': constants.VTYPE_SIZE,
1631 a5728081 Guido Trotter
      }
1632 a5728081 Guido Trotter
1633 a5728081 Guido Trotter
  def _fdt(self, dict, allowed_values=None):
1634 a5728081 Guido Trotter
    if allowed_values is None:
1635 a5728081 Guido Trotter
      ForceDictType(dict, self.key_types)
1636 a5728081 Guido Trotter
    else:
1637 a5728081 Guido Trotter
      ForceDictType(dict, self.key_types, allowed_values=allowed_values)
1638 a5728081 Guido Trotter
1639 a5728081 Guido Trotter
    return dict
1640 a5728081 Guido Trotter
1641 a5728081 Guido Trotter
  def testSimpleDict(self):
1642 a5728081 Guido Trotter
    self.assertEqual(self._fdt({}), {})
1643 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': 1}), {'a': 1})
1644 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': '1'}), {'a': 1})
1645 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': 1, 'b': 1}), {'a':1, 'b': True})
1646 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 1, 'c': 'foo'}), {'b': True, 'c': 'foo'})
1647 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 1, 'c': False}), {'b': True, 'c': ''})
1648 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'false'}), {'b': False})
1649 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'False'}), {'b': False})
1650 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'true'}), {'b': True})
1651 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'True'}), {'b': True})
1652 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'d': '4'}), {'d': 4})
1653 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'d': '4M'}), {'d': 4})
1654 a5728081 Guido Trotter
1655 a5728081 Guido Trotter
  def testErrors(self):
1656 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'a': 'astring'})
1657 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'c': True})
1658 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': 'astring'})
1659 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': '4 L'})
1660 a5728081 Guido Trotter
1661 a2d2e1a7 Iustin Pop
1662 05489142 Guido Trotter
class TestIsNormAbsPath(unittest.TestCase):
1663 c1dd99d4 Michael Hanselmann
  """Testing case for IsNormAbsPath"""
1664 da961187 Guido Trotter
1665 da961187 Guido Trotter
  def _pathTestHelper(self, path, result):
1666 da961187 Guido Trotter
    if result:
1667 da961187 Guido Trotter
      self.assert_(IsNormAbsPath(path),
1668 17c61836 Guido Trotter
          "Path %s should result absolute and normalized" % path)
1669 da961187 Guido Trotter
    else:
1670 da961187 Guido Trotter
      self.assert_(not IsNormAbsPath(path),
1671 17c61836 Guido Trotter
          "Path %s should not result absolute and normalized" % path)
1672 da961187 Guido Trotter
1673 da961187 Guido Trotter
  def testBase(self):
1674 da961187 Guido Trotter
    self._pathTestHelper('/etc', True)
1675 da961187 Guido Trotter
    self._pathTestHelper('/srv', True)
1676 da961187 Guido Trotter
    self._pathTestHelper('etc', False)
1677 da961187 Guido Trotter
    self._pathTestHelper('/etc/../root', False)
1678 da961187 Guido Trotter
    self._pathTestHelper('/etc/', False)
1679 da961187 Guido Trotter
1680 af0413bb Guido Trotter
1681 d392fa34 Iustin Pop
class TestSafeEncode(unittest.TestCase):
1682 d392fa34 Iustin Pop
  """Test case for SafeEncode"""
1683 d392fa34 Iustin Pop
1684 d392fa34 Iustin Pop
  def testAscii(self):
1685 d392fa34 Iustin Pop
    for txt in [string.digits, string.letters, string.punctuation]:
1686 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1687 d392fa34 Iustin Pop
1688 d392fa34 Iustin Pop
  def testDoubleEncode(self):
1689 d392fa34 Iustin Pop
    for i in range(255):
1690 d392fa34 Iustin Pop
      txt = SafeEncode(chr(i))
1691 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1692 d392fa34 Iustin Pop
1693 d392fa34 Iustin Pop
  def testUnicode(self):
1694 d392fa34 Iustin Pop
    # 1024 is high enough to catch non-direct ASCII mappings
1695 d392fa34 Iustin Pop
    for i in range(1024):
1696 d392fa34 Iustin Pop
      txt = SafeEncode(unichr(i))
1697 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1698 d392fa34 Iustin Pop
1699 d392fa34 Iustin Pop
1700 3b813dd2 Iustin Pop
class TestFormatTime(unittest.TestCase):
1701 3b813dd2 Iustin Pop
  """Testing case for FormatTime"""
1702 3b813dd2 Iustin Pop
1703 3b813dd2 Iustin Pop
  def testNone(self):
1704 3b813dd2 Iustin Pop
    self.failUnlessEqual(FormatTime(None), "N/A")
1705 3b813dd2 Iustin Pop
1706 3b813dd2 Iustin Pop
  def testInvalid(self):
1707 3b813dd2 Iustin Pop
    self.failUnlessEqual(FormatTime(()), "N/A")
1708 3b813dd2 Iustin Pop
1709 3b813dd2 Iustin Pop
  def testNow(self):
1710 3b813dd2 Iustin Pop
    # tests that we accept time.time input
1711 3b813dd2 Iustin Pop
    FormatTime(time.time())
1712 3b813dd2 Iustin Pop
    # tests that we accept int input
1713 3b813dd2 Iustin Pop
    FormatTime(int(time.time()))
1714 3b813dd2 Iustin Pop
1715 3b813dd2 Iustin Pop
1716 eb58f7bd Michael Hanselmann
class RunInSeparateProcess(unittest.TestCase):
1717 eb58f7bd Michael Hanselmann
  def test(self):
1718 eb58f7bd Michael Hanselmann
    for exp in [True, False]:
1719 eb58f7bd Michael Hanselmann
      def _child():
1720 eb58f7bd Michael Hanselmann
        return exp
1721 eb58f7bd Michael Hanselmann
1722 eb58f7bd Michael Hanselmann
      self.assertEqual(exp, utils.RunInSeparateProcess(_child))
1723 eb58f7bd Michael Hanselmann
1724 bdefe5dd Michael Hanselmann
  def testArgs(self):
1725 bdefe5dd Michael Hanselmann
    for arg in [0, 1, 999, "Hello World", (1, 2, 3)]:
1726 bdefe5dd Michael Hanselmann
      def _child(carg1, carg2):
1727 bdefe5dd Michael Hanselmann
        return carg1 == "Foo" and carg2 == arg
1728 bdefe5dd Michael Hanselmann
1729 bdefe5dd Michael Hanselmann
      self.assert_(utils.RunInSeparateProcess(_child, "Foo", arg))
1730 bdefe5dd Michael Hanselmann
1731 eb58f7bd Michael Hanselmann
  def testPid(self):
1732 eb58f7bd Michael Hanselmann
    parent_pid = os.getpid()
1733 eb58f7bd Michael Hanselmann
1734 eb58f7bd Michael Hanselmann
    def _check():
1735 eb58f7bd Michael Hanselmann
      return os.getpid() == parent_pid
1736 eb58f7bd Michael Hanselmann
1737 eb58f7bd Michael Hanselmann
    self.failIf(utils.RunInSeparateProcess(_check))
1738 eb58f7bd Michael Hanselmann
1739 eb58f7bd Michael Hanselmann
  def testSignal(self):
1740 eb58f7bd Michael Hanselmann
    def _kill():
1741 eb58f7bd Michael Hanselmann
      os.kill(os.getpid(), signal.SIGTERM)
1742 eb58f7bd Michael Hanselmann
1743 eb58f7bd Michael Hanselmann
    self.assertRaises(errors.GenericError,
1744 eb58f7bd Michael Hanselmann
                      utils.RunInSeparateProcess, _kill)
1745 eb58f7bd Michael Hanselmann
1746 eb58f7bd Michael Hanselmann
  def testException(self):
1747 eb58f7bd Michael Hanselmann
    def _exc():
1748 eb58f7bd Michael Hanselmann
      raise errors.GenericError("This is a test")
1749 eb58f7bd Michael Hanselmann
1750 eb58f7bd Michael Hanselmann
    self.assertRaises(errors.GenericError,
1751 eb58f7bd Michael Hanselmann
                      utils.RunInSeparateProcess, _exc)
1752 eb58f7bd Michael Hanselmann
1753 eb58f7bd Michael Hanselmann
1754 fabee4b2 Michael Hanselmann
class TestFingerprintFile(unittest.TestCase):
1755 fabee4b2 Michael Hanselmann
  def setUp(self):
1756 fabee4b2 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1757 fabee4b2 Michael Hanselmann
1758 fabee4b2 Michael Hanselmann
  def test(self):
1759 fabee4b2 Michael Hanselmann
    self.assertEqual(utils._FingerprintFile(self.tmpfile.name),
1760 fabee4b2 Michael Hanselmann
                     "da39a3ee5e6b4b0d3255bfef95601890afd80709")
1761 fabee4b2 Michael Hanselmann
1762 fabee4b2 Michael Hanselmann
    utils.WriteFile(self.tmpfile.name, data="Hello World\n")
1763 fabee4b2 Michael Hanselmann
    self.assertEqual(utils._FingerprintFile(self.tmpfile.name),
1764 fabee4b2 Michael Hanselmann
                     "648a6a6ffffdaa0badb23b8baf90b6168dd16b3a")
1765 fabee4b2 Michael Hanselmann
1766 fabee4b2 Michael Hanselmann
1767 5b69bc7c Iustin Pop
class TestUnescapeAndSplit(unittest.TestCase):
1768 5b69bc7c Iustin Pop
  """Testing case for UnescapeAndSplit"""
1769 5b69bc7c Iustin Pop
1770 5b69bc7c Iustin Pop
  def setUp(self):
1771 5b69bc7c Iustin Pop
    # testing more that one separator for regexp safety
1772 5b69bc7c Iustin Pop
    self._seps = [",", "+", "."]
1773 5b69bc7c Iustin Pop
1774 5b69bc7c Iustin Pop
  def testSimple(self):
1775 5b69bc7c Iustin Pop
    a = ["a", "b", "c", "d"]
1776 5b69bc7c Iustin Pop
    for sep in self._seps:
1777 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), a)
1778 5b69bc7c Iustin Pop
1779 5b69bc7c Iustin Pop
  def testEscape(self):
1780 5b69bc7c Iustin Pop
    for sep in self._seps:
1781 5b69bc7c Iustin Pop
      a = ["a", "b\\" + sep + "c", "d"]
1782 5b69bc7c Iustin Pop
      b = ["a", "b" + sep + "c", "d"]
1783 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1784 5b69bc7c Iustin Pop
1785 5b69bc7c Iustin Pop
  def testDoubleEscape(self):
1786 5b69bc7c Iustin Pop
    for sep in self._seps:
1787 5b69bc7c Iustin Pop
      a = ["a", "b\\\\", "c", "d"]
1788 5b69bc7c Iustin Pop
      b = ["a", "b\\", "c", "d"]
1789 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1790 5b69bc7c Iustin Pop
1791 5b69bc7c Iustin Pop
  def testThreeEscape(self):
1792 5b69bc7c Iustin Pop
    for sep in self._seps:
1793 5b69bc7c Iustin Pop
      a = ["a", "b\\\\\\" + sep + "c", "d"]
1794 5b69bc7c Iustin Pop
      b = ["a", "b\\" + sep + "c", "d"]
1795 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1796 5b69bc7c Iustin Pop
1797 5b69bc7c Iustin Pop
1798 bdd5e420 Michael Hanselmann
class TestGenerateSelfSignedX509Cert(unittest.TestCase):
1799 a55474c7 Michael Hanselmann
  def setUp(self):
1800 a55474c7 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
1801 a55474c7 Michael Hanselmann
1802 a55474c7 Michael Hanselmann
  def tearDown(self):
1803 a55474c7 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
1804 a55474c7 Michael Hanselmann
1805 bdd5e420 Michael Hanselmann
  def _checkRsaPrivateKey(self, key):
1806 a55474c7 Michael Hanselmann
    lines = key.splitlines()
1807 bdd5e420 Michael Hanselmann
    return ("-----BEGIN RSA PRIVATE KEY-----" in lines and
1808 bdd5e420 Michael Hanselmann
            "-----END RSA PRIVATE KEY-----" in lines)
1809 a55474c7 Michael Hanselmann
1810 bdd5e420 Michael Hanselmann
  def _checkCertificate(self, cert):
1811 a55474c7 Michael Hanselmann
    lines = cert.splitlines()
1812 bdd5e420 Michael Hanselmann
    return ("-----BEGIN CERTIFICATE-----" in lines and
1813 bdd5e420 Michael Hanselmann
            "-----END CERTIFICATE-----" in lines)
1814 a55474c7 Michael Hanselmann
1815 bdd5e420 Michael Hanselmann
  def test(self):
1816 bdd5e420 Michael Hanselmann
    for common_name in [None, ".", "Ganeti", "node1.example.com"]:
1817 bdd5e420 Michael Hanselmann
      (key_pem, cert_pem) = utils.GenerateSelfSignedX509Cert(common_name, 300)
1818 bdd5e420 Michael Hanselmann
      self._checkRsaPrivateKey(key_pem)
1819 bdd5e420 Michael Hanselmann
      self._checkCertificate(cert_pem)
1820 bdd5e420 Michael Hanselmann
1821 bdd5e420 Michael Hanselmann
      key = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,
1822 bdd5e420 Michael Hanselmann
                                           key_pem)
1823 bdd5e420 Michael Hanselmann
      self.assert_(key.bits() >= 1024)
1824 bdd5e420 Michael Hanselmann
      self.assertEqual(key.bits(), constants.RSA_KEY_BITS)
1825 bdd5e420 Michael Hanselmann
      self.assertEqual(key.type(), OpenSSL.crypto.TYPE_RSA)
1826 bdd5e420 Michael Hanselmann
1827 bdd5e420 Michael Hanselmann
      x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
1828 bdd5e420 Michael Hanselmann
                                             cert_pem)
1829 bdd5e420 Michael Hanselmann
      self.failIf(x509.has_expired())
1830 bdd5e420 Michael Hanselmann
      self.assertEqual(x509.get_issuer().CN, common_name)
1831 bdd5e420 Michael Hanselmann
      self.assertEqual(x509.get_subject().CN, common_name)
1832 bdd5e420 Michael Hanselmann
      self.assertEqual(x509.get_pubkey().bits(), constants.RSA_KEY_BITS)
1833 bdd5e420 Michael Hanselmann
1834 bdd5e420 Michael Hanselmann
  def testLegacy(self):
1835 a55474c7 Michael Hanselmann
    cert1_filename = os.path.join(self.tmpdir, "cert1.pem")
1836 a55474c7 Michael Hanselmann
1837 a55474c7 Michael Hanselmann
    utils.GenerateSelfSignedSslCert(cert1_filename, validity=1)
1838 a55474c7 Michael Hanselmann
1839 a55474c7 Michael Hanselmann
    cert1 = utils.ReadFile(cert1_filename)
1840 a55474c7 Michael Hanselmann
1841 bdd5e420 Michael Hanselmann
    self.assert_(self._checkRsaPrivateKey(cert1))
1842 bdd5e420 Michael Hanselmann
    self.assert_(self._checkCertificate(cert1))
1843 a55474c7 Michael Hanselmann
1844 a55474c7 Michael Hanselmann
1845 4bb678e9 Iustin Pop
class TestPathJoin(unittest.TestCase):
1846 4bb678e9 Iustin Pop
  """Testing case for PathJoin"""
1847 4bb678e9 Iustin Pop
1848 4bb678e9 Iustin Pop
  def testBasicItems(self):
1849 4bb678e9 Iustin Pop
    mlist = ["/a", "b", "c"]
1850 4bb678e9 Iustin Pop
    self.failUnlessEqual(PathJoin(*mlist), "/".join(mlist))
1851 4bb678e9 Iustin Pop
1852 4bb678e9 Iustin Pop
  def testNonAbsPrefix(self):
1853 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "a", "b")
1854 4bb678e9 Iustin Pop
1855 4bb678e9 Iustin Pop
  def testBackTrack(self):
1856 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "/a", "b/../c")
1857 4bb678e9 Iustin Pop
1858 4bb678e9 Iustin Pop
  def testMultiAbs(self):
1859 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "/a", "/b")
1860 4bb678e9 Iustin Pop
1861 4bb678e9 Iustin Pop
1862 26288e68 Iustin Pop
class TestHostInfo(unittest.TestCase):
1863 26288e68 Iustin Pop
  """Testing case for HostInfo"""
1864 26288e68 Iustin Pop
1865 26288e68 Iustin Pop
  def testUppercase(self):
1866 26288e68 Iustin Pop
    data = "AbC.example.com"
1867 26288e68 Iustin Pop
    self.failUnlessEqual(HostInfo.NormalizeName(data), data.lower())
1868 26288e68 Iustin Pop
1869 26288e68 Iustin Pop
  def testTooLongName(self):
1870 26288e68 Iustin Pop
    data = "a.b." + "c" * 255
1871 26288e68 Iustin Pop
    self.failUnlessRaises(OpPrereqError, HostInfo.NormalizeName, data)
1872 26288e68 Iustin Pop
1873 26288e68 Iustin Pop
  def testTrailingDot(self):
1874 26288e68 Iustin Pop
    data = "a.b.c"
1875 26288e68 Iustin Pop
    self.failUnlessEqual(HostInfo.NormalizeName(data + "."), data)
1876 26288e68 Iustin Pop
1877 26288e68 Iustin Pop
  def testInvalidName(self):
1878 26288e68 Iustin Pop
    data = [
1879 26288e68 Iustin Pop
      "a b",
1880 26288e68 Iustin Pop
      "a/b",
1881 26288e68 Iustin Pop
      ".a.b",
1882 26288e68 Iustin Pop
      "a..b",
1883 26288e68 Iustin Pop
      ]
1884 26288e68 Iustin Pop
    for value in data:
1885 26288e68 Iustin Pop
      self.failUnlessRaises(OpPrereqError, HostInfo.NormalizeName, value)
1886 26288e68 Iustin Pop
1887 26288e68 Iustin Pop
  def testValidName(self):
1888 26288e68 Iustin Pop
    data = [
1889 26288e68 Iustin Pop
      "a.b",
1890 26288e68 Iustin Pop
      "a-b",
1891 26288e68 Iustin Pop
      "a_b",
1892 26288e68 Iustin Pop
      "a.b.c",
1893 26288e68 Iustin Pop
      ]
1894 26288e68 Iustin Pop
    for value in data:
1895 26288e68 Iustin Pop
      HostInfo.NormalizeName(value)
1896 26288e68 Iustin Pop
1897 26288e68 Iustin Pop
1898 28f34048 Michael Hanselmann
class TestValidateServiceName(unittest.TestCase):
1899 28f34048 Michael Hanselmann
  def testValid(self):
1900 28f34048 Michael Hanselmann
    testnames = [
1901 28f34048 Michael Hanselmann
      0, 1, 2, 3, 1024, 65000, 65534, 65535,
1902 28f34048 Michael Hanselmann
      "ganeti",
1903 28f34048 Michael Hanselmann
      "gnt-masterd",
1904 28f34048 Michael Hanselmann
      "HELLO_WORLD_SVC",
1905 28f34048 Michael Hanselmann
      "hello.world.1",
1906 28f34048 Michael Hanselmann
      "0", "80", "1111", "65535",
1907 28f34048 Michael Hanselmann
      ]
1908 28f34048 Michael Hanselmann
1909 28f34048 Michael Hanselmann
    for name in testnames:
1910 28f34048 Michael Hanselmann
      self.assertEqual(utils.ValidateServiceName(name), name)
1911 28f34048 Michael Hanselmann
1912 28f34048 Michael Hanselmann
  def testInvalid(self):
1913 28f34048 Michael Hanselmann
    testnames = [
1914 28f34048 Michael Hanselmann
      -15756, -1, 65536, 133428083,
1915 28f34048 Michael Hanselmann
      "", "Hello World!", "!", "'", "\"", "\t", "\n", "`",
1916 28f34048 Michael Hanselmann
      "-8546", "-1", "65536",
1917 28f34048 Michael Hanselmann
      (129 * "A"),
1918 28f34048 Michael Hanselmann
      ]
1919 28f34048 Michael Hanselmann
1920 28f34048 Michael Hanselmann
    for name in testnames:
1921 28f34048 Michael Hanselmann
      self.assertRaises(OpPrereqError, utils.ValidateServiceName, name)
1922 28f34048 Michael Hanselmann
1923 28f34048 Michael Hanselmann
1924 27e46076 Michael Hanselmann
class TestParseAsn1Generalizedtime(unittest.TestCase):
1925 27e46076 Michael Hanselmann
  def test(self):
1926 27e46076 Michael Hanselmann
    # UTC
1927 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("19700101000000Z"), 0)
1928 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100222174152Z"),
1929 27e46076 Michael Hanselmann
                     1266860512)
1930 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20380119031407Z"),
1931 27e46076 Michael Hanselmann
                     (2**31) - 1)
1932 27e46076 Michael Hanselmann
1933 27e46076 Michael Hanselmann
    # With offset
1934 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100222174152+0000"),
1935 27e46076 Michael Hanselmann
                     1266860512)
1936 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100223131652+0000"),
1937 27e46076 Michael Hanselmann
                     1266931012)
1938 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100223051808-0800"),
1939 27e46076 Michael Hanselmann
                     1266931088)
1940 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100224002135+1100"),
1941 27e46076 Michael Hanselmann
                     1266931295)
1942 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("19700101000000-0100"),
1943 27e46076 Michael Hanselmann
                     3600)
1944 27e46076 Michael Hanselmann
1945 27e46076 Michael Hanselmann
    # Leap seconds are not supported by datetime.datetime
1946 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1947 27e46076 Michael Hanselmann
                      "19841231235960+0000")
1948 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1949 27e46076 Michael Hanselmann
                      "19920630235960+0000")
1950 27e46076 Michael Hanselmann
1951 27e46076 Michael Hanselmann
    # Errors
1952 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime, "")
1953 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime, "invalid")
1954 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1955 27e46076 Michael Hanselmann
                      "20100222174152")
1956 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1957 27e46076 Michael Hanselmann
                      "Mon Feb 22 17:47:02 UTC 2010")
1958 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1959 27e46076 Michael Hanselmann
                      "2010-02-22 17:42:02")
1960 27e46076 Michael Hanselmann
1961 27e46076 Michael Hanselmann
1962 27e46076 Michael Hanselmann
class TestGetX509CertValidity(testutils.GanetiTestCase):
1963 27e46076 Michael Hanselmann
  def setUp(self):
1964 27e46076 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
1965 27e46076 Michael Hanselmann
1966 27e46076 Michael Hanselmann
    pyopenssl_version = distutils.version.LooseVersion(OpenSSL.__version__)
1967 27e46076 Michael Hanselmann
1968 27e46076 Michael Hanselmann
    # Test whether we have pyOpenSSL 0.7 or above
1969 27e46076 Michael Hanselmann
    self.pyopenssl0_7 = (pyopenssl_version >= "0.7")
1970 27e46076 Michael Hanselmann
1971 27e46076 Michael Hanselmann
    if not self.pyopenssl0_7:
1972 27e46076 Michael Hanselmann
      warnings.warn("This test requires pyOpenSSL 0.7 or above to"
1973 27e46076 Michael Hanselmann
                    " function correctly")
1974 27e46076 Michael Hanselmann
1975 27e46076 Michael Hanselmann
  def _LoadCert(self, name):
1976 27e46076 Michael Hanselmann
    return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
1977 27e46076 Michael Hanselmann
                                           self._ReadTestData(name))
1978 27e46076 Michael Hanselmann
1979 27e46076 Michael Hanselmann
  def test(self):
1980 27e46076 Michael Hanselmann
    validity = utils.GetX509CertValidity(self._LoadCert("cert1.pem"))
1981 27e46076 Michael Hanselmann
    if self.pyopenssl0_7:
1982 27e46076 Michael Hanselmann
      self.assertEqual(validity, (1266919967, 1267524767))
1983 27e46076 Michael Hanselmann
    else:
1984 27e46076 Michael Hanselmann
      self.assertEqual(validity, (None, None))
1985 27e46076 Michael Hanselmann
1986 26288e68 Iustin Pop
1987 68857643 Michael Hanselmann
class TestSignX509Certificate(unittest.TestCase):
1988 68857643 Michael Hanselmann
  KEY = "My private key!"
1989 68857643 Michael Hanselmann
  KEY_OTHER = "Another key"
1990 68857643 Michael Hanselmann
1991 68857643 Michael Hanselmann
  def test(self):
1992 68857643 Michael Hanselmann
    # Generate certificate valid for 5 minutes
1993 68857643 Michael Hanselmann
    (_, cert_pem) = utils.GenerateSelfSignedX509Cert(None, 300)
1994 68857643 Michael Hanselmann
1995 68857643 Michael Hanselmann
    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
1996 68857643 Michael Hanselmann
                                           cert_pem)
1997 68857643 Michael Hanselmann
1998 68857643 Michael Hanselmann
    # No signature at all
1999 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError,
2000 68857643 Michael Hanselmann
                      utils.LoadSignedX509Certificate, cert_pem, self.KEY)
2001 68857643 Michael Hanselmann
2002 68857643 Michael Hanselmann
    # Invalid input
2003 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
2004 68857643 Michael Hanselmann
                      "", self.KEY)
2005 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
2006 68857643 Michael Hanselmann
                      "X-Ganeti-Signature: \n", self.KEY)
2007 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
2008 68857643 Michael Hanselmann
                      "X-Ganeti-Sign: $1234$abcdef\n", self.KEY)
2009 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
2010 68857643 Michael Hanselmann
                      "X-Ganeti-Signature: $1234567890$abcdef\n", self.KEY)
2011 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
2012 68857643 Michael Hanselmann
                      "X-Ganeti-Signature: $1234$abc\n\n" + cert_pem, self.KEY)
2013 68857643 Michael Hanselmann
2014 68857643 Michael Hanselmann
    # Invalid salt
2015 68857643 Michael Hanselmann
    for salt in list("-_@$,:;/\\ \t\n"):
2016 68857643 Michael Hanselmann
      self.assertRaises(errors.GenericError, utils.SignX509Certificate,
2017 68857643 Michael Hanselmann
                        cert_pem, self.KEY, "foo%sbar" % salt)
2018 68857643 Michael Hanselmann
2019 68857643 Michael Hanselmann
    for salt in ["HelloWorld", "salt", string.letters, string.digits,
2020 68857643 Michael Hanselmann
                 utils.GenerateSecret(numbytes=4),
2021 68857643 Michael Hanselmann
                 utils.GenerateSecret(numbytes=16),
2022 68857643 Michael Hanselmann
                 "{123:456}".encode("hex")]:
2023 68857643 Michael Hanselmann
      signed_pem = utils.SignX509Certificate(cert, self.KEY, salt)
2024 68857643 Michael Hanselmann
2025 68857643 Michael Hanselmann
      self._Check(cert, salt, signed_pem)
2026 68857643 Michael Hanselmann
2027 68857643 Michael Hanselmann
      self._Check(cert, salt, "X-Another-Header: with a value\n" + signed_pem)
2028 68857643 Michael Hanselmann
      self._Check(cert, salt, (10 * "Hello World!\n") + signed_pem)
2029 68857643 Michael Hanselmann
      self._Check(cert, salt, (signed_pem + "\n\na few more\n"
2030 68857643 Michael Hanselmann
                               "lines----\n------ at\nthe end!"))
2031 68857643 Michael Hanselmann
2032 68857643 Michael Hanselmann
  def _Check(self, cert, salt, pem):
2033 68857643 Michael Hanselmann
    (cert2, salt2) = utils.LoadSignedX509Certificate(pem, self.KEY)
2034 68857643 Michael Hanselmann
    self.assertEqual(salt, salt2)
2035 68857643 Michael Hanselmann
    self.assertEqual(cert.digest("sha1"), cert2.digest("sha1"))
2036 68857643 Michael Hanselmann
2037 68857643 Michael Hanselmann
    # Other key
2038 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
2039 68857643 Michael Hanselmann
                      pem, self.KEY_OTHER)
2040 68857643 Michael Hanselmann
2041 68857643 Michael Hanselmann
2042 76e5f8b5 Michael Hanselmann
class TestMakedirs(unittest.TestCase):
2043 76e5f8b5 Michael Hanselmann
  def setUp(self):
2044 76e5f8b5 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
2045 76e5f8b5 Michael Hanselmann
2046 76e5f8b5 Michael Hanselmann
  def tearDown(self):
2047 76e5f8b5 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
2048 76e5f8b5 Michael Hanselmann
2049 76e5f8b5 Michael Hanselmann
  def testNonExisting(self):
2050 76e5f8b5 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "foo")
2051 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
2052 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
2053 76e5f8b5 Michael Hanselmann
2054 76e5f8b5 Michael Hanselmann
  def testExisting(self):
2055 76e5f8b5 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "foo")
2056 76e5f8b5 Michael Hanselmann
    os.mkdir(path)
2057 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
2058 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
2059 76e5f8b5 Michael Hanselmann
2060 76e5f8b5 Michael Hanselmann
  def testRecursiveNonExisting(self):
2061 76e5f8b5 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "foo/bar/baz")
2062 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
2063 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
2064 76e5f8b5 Michael Hanselmann
2065 76e5f8b5 Michael Hanselmann
  def testRecursiveExisting(self):
2066 76e5f8b5 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "B/moo/xyz")
2067 76e5f8b5 Michael Hanselmann
    self.assert_(not os.path.exists(path))
2068 76e5f8b5 Michael Hanselmann
    os.mkdir(utils.PathJoin(self.tmpdir, "B"))
2069 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
2070 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
2071 76e5f8b5 Michael Hanselmann
2072 76e5f8b5 Michael Hanselmann
2073 1b429e2a Iustin Pop
class TestRetry(testutils.GanetiTestCase):
2074 45cc4913 Guido Trotter
  def setUp(self):
2075 45cc4913 Guido Trotter
    testutils.GanetiTestCase.setUp(self)
2076 45cc4913 Guido Trotter
    self.retries = 0
2077 45cc4913 Guido Trotter
2078 1b429e2a Iustin Pop
  @staticmethod
2079 1b429e2a Iustin Pop
  def _RaiseRetryAgain():
2080 1b429e2a Iustin Pop
    raise utils.RetryAgain()
2081 1b429e2a Iustin Pop
2082 506be7c5 Guido Trotter
  @staticmethod
2083 506be7c5 Guido Trotter
  def _RaiseRetryAgainWithArg(args):
2084 506be7c5 Guido Trotter
    raise utils.RetryAgain(*args)
2085 506be7c5 Guido Trotter
2086 1b429e2a Iustin Pop
  def _WrongNestedLoop(self):
2087 1b429e2a Iustin Pop
    return utils.Retry(self._RaiseRetryAgain, 0.01, 0.02)
2088 1b429e2a Iustin Pop
2089 45cc4913 Guido Trotter
  def _RetryAndSucceed(self, retries):
2090 45cc4913 Guido Trotter
    if self.retries < retries:
2091 45cc4913 Guido Trotter
      self.retries += 1
2092 45cc4913 Guido Trotter
      raise utils.RetryAgain()
2093 45cc4913 Guido Trotter
    else:
2094 45cc4913 Guido Trotter
      return True
2095 45cc4913 Guido Trotter
2096 1b429e2a Iustin Pop
  def testRaiseTimeout(self):
2097 1b429e2a Iustin Pop
    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
2098 1b429e2a Iustin Pop
                          self._RaiseRetryAgain, 0.01, 0.02)
2099 45cc4913 Guido Trotter
    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
2100 45cc4913 Guido Trotter
                          self._RetryAndSucceed, 0.01, 0, args=[1])
2101 45cc4913 Guido Trotter
    self.failUnlessEqual(self.retries, 1)
2102 1b429e2a Iustin Pop
2103 1b429e2a Iustin Pop
  def testComplete(self):
2104 1b429e2a Iustin Pop
    self.failUnlessEqual(utils.Retry(lambda: True, 0, 1), True)
2105 45cc4913 Guido Trotter
    self.failUnlessEqual(utils.Retry(self._RetryAndSucceed, 0, 1, args=[2]),
2106 45cc4913 Guido Trotter
                         True)
2107 45cc4913 Guido Trotter
    self.failUnlessEqual(self.retries, 2)
2108 1b429e2a Iustin Pop
2109 1b429e2a Iustin Pop
  def testNestedLoop(self):
2110 1b429e2a Iustin Pop
    try:
2111 1b429e2a Iustin Pop
      self.failUnlessRaises(errors.ProgrammerError, utils.Retry,
2112 1b429e2a Iustin Pop
                            self._WrongNestedLoop, 0, 1)
2113 1b429e2a Iustin Pop
    except utils.RetryTimeout:
2114 1b429e2a Iustin Pop
      self.fail("Didn't detect inner loop's exception")
2115 1b429e2a Iustin Pop
2116 506be7c5 Guido Trotter
  def testTimeoutArgument(self):
2117 506be7c5 Guido Trotter
    retry_arg="my_important_debugging_message"
2118 506be7c5 Guido Trotter
    try:
2119 506be7c5 Guido Trotter
      utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02, args=[[retry_arg]])
2120 506be7c5 Guido Trotter
    except utils.RetryTimeout, err:
2121 506be7c5 Guido Trotter
      self.failUnlessEqual(err.args, (retry_arg, ))
2122 506be7c5 Guido Trotter
    else:
2123 506be7c5 Guido Trotter
      self.fail("Expected timeout didn't happen")
2124 506be7c5 Guido Trotter
2125 506be7c5 Guido Trotter
  def testRaiseInnerWithExc(self):
2126 506be7c5 Guido Trotter
    retry_arg="my_important_debugging_message"
2127 506be7c5 Guido Trotter
    try:
2128 506be7c5 Guido Trotter
      try:
2129 506be7c5 Guido Trotter
        utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02,
2130 506be7c5 Guido Trotter
                    args=[[errors.GenericError(retry_arg, retry_arg)]])
2131 506be7c5 Guido Trotter
      except utils.RetryTimeout, err:
2132 506be7c5 Guido Trotter
        err.RaiseInner()
2133 506be7c5 Guido Trotter
      else:
2134 506be7c5 Guido Trotter
        self.fail("Expected timeout didn't happen")
2135 506be7c5 Guido Trotter
    except errors.GenericError, err:
2136 506be7c5 Guido Trotter
      self.failUnlessEqual(err.args, (retry_arg, retry_arg))
2137 506be7c5 Guido Trotter
    else:
2138 506be7c5 Guido Trotter
      self.fail("Expected GenericError didn't happen")
2139 506be7c5 Guido Trotter
2140 506be7c5 Guido Trotter
  def testRaiseInnerWithMsg(self):
2141 506be7c5 Guido Trotter
    retry_arg="my_important_debugging_message"
2142 506be7c5 Guido Trotter
    try:
2143 506be7c5 Guido Trotter
      try:
2144 506be7c5 Guido Trotter
        utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02,
2145 506be7c5 Guido Trotter
                    args=[[retry_arg, retry_arg]])
2146 506be7c5 Guido Trotter
      except utils.RetryTimeout, err:
2147 506be7c5 Guido Trotter
        err.RaiseInner()
2148 506be7c5 Guido Trotter
      else:
2149 506be7c5 Guido Trotter
        self.fail("Expected timeout didn't happen")
2150 506be7c5 Guido Trotter
    except utils.RetryTimeout, err:
2151 506be7c5 Guido Trotter
      self.failUnlessEqual(err.args, (retry_arg, retry_arg))
2152 506be7c5 Guido Trotter
    else:
2153 506be7c5 Guido Trotter
      self.fail("Expected RetryTimeout didn't happen")
2154 506be7c5 Guido Trotter
2155 1b429e2a Iustin Pop
2156 339be5a8 Michael Hanselmann
class TestLineSplitter(unittest.TestCase):
2157 339be5a8 Michael Hanselmann
  def test(self):
2158 339be5a8 Michael Hanselmann
    lines = []
2159 339be5a8 Michael Hanselmann
    ls = utils.LineSplitter(lines.append)
2160 339be5a8 Michael Hanselmann
    ls.write("Hello World\n")
2161 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
2162 339be5a8 Michael Hanselmann
    ls.write("Foo\n Bar\r\n ")
2163 339be5a8 Michael Hanselmann
    ls.write("Baz")
2164 339be5a8 Michael Hanselmann
    ls.write("Moo")
2165 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
2166 339be5a8 Michael Hanselmann
    ls.flush()
2167 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["Hello World", "Foo", " Bar"])
2168 339be5a8 Michael Hanselmann
    ls.close()
2169 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["Hello World", "Foo", " Bar", " BazMoo"])
2170 339be5a8 Michael Hanselmann
2171 339be5a8 Michael Hanselmann
  def _testExtra(self, line, all_lines, p1, p2):
2172 339be5a8 Michael Hanselmann
    self.assertEqual(p1, 999)
2173 339be5a8 Michael Hanselmann
    self.assertEqual(p2, "extra")
2174 339be5a8 Michael Hanselmann
    all_lines.append(line)
2175 339be5a8 Michael Hanselmann
2176 339be5a8 Michael Hanselmann
  def testExtraArgsNoFlush(self):
2177 339be5a8 Michael Hanselmann
    lines = []
2178 339be5a8 Michael Hanselmann
    ls = utils.LineSplitter(self._testExtra, lines, 999, "extra")
2179 339be5a8 Michael Hanselmann
    ls.write("\n\nHello World\n")
2180 339be5a8 Michael Hanselmann
    ls.write("Foo\n Bar\r\n ")
2181 339be5a8 Michael Hanselmann
    ls.write("")
2182 339be5a8 Michael Hanselmann
    ls.write("Baz")
2183 339be5a8 Michael Hanselmann
    ls.write("Moo\n\nx\n")
2184 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
2185 339be5a8 Michael Hanselmann
    ls.close()
2186 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["", "", "Hello World", "Foo", " Bar", " BazMoo",
2187 339be5a8 Michael Hanselmann
                             "", "x"])
2188 339be5a8 Michael Hanselmann
2189 339be5a8 Michael Hanselmann
2190 debed9ae Michael Hanselmann
class TestReadLockedPidFile(unittest.TestCase):
2191 debed9ae Michael Hanselmann
  def setUp(self):
2192 debed9ae Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
2193 debed9ae Michael Hanselmann
2194 debed9ae Michael Hanselmann
  def tearDown(self):
2195 debed9ae Michael Hanselmann
    shutil.rmtree(self.tmpdir)
2196 debed9ae Michael Hanselmann
2197 debed9ae Michael Hanselmann
  def testNonExistent(self):
2198 debed9ae Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "nonexist")
2199 debed9ae Michael Hanselmann
    self.assert_(utils.ReadLockedPidFile(path) is None)
2200 debed9ae Michael Hanselmann
2201 debed9ae Michael Hanselmann
  def testUnlocked(self):
2202 debed9ae Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "pid")
2203 debed9ae Michael Hanselmann
    utils.WriteFile(path, data="123")
2204 debed9ae Michael Hanselmann
    self.assert_(utils.ReadLockedPidFile(path) is None)
2205 debed9ae Michael Hanselmann
2206 debed9ae Michael Hanselmann
  def testLocked(self):
2207 debed9ae Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "pid")
2208 debed9ae Michael Hanselmann
    utils.WriteFile(path, data="123")
2209 debed9ae Michael Hanselmann
2210 debed9ae Michael Hanselmann
    fl = utils.FileLock.Open(path)
2211 debed9ae Michael Hanselmann
    try:
2212 debed9ae Michael Hanselmann
      fl.Exclusive(blocking=True)
2213 debed9ae Michael Hanselmann
2214 debed9ae Michael Hanselmann
      self.assertEqual(utils.ReadLockedPidFile(path), 123)
2215 debed9ae Michael Hanselmann
    finally:
2216 debed9ae Michael Hanselmann
      fl.Close()
2217 debed9ae Michael Hanselmann
2218 debed9ae Michael Hanselmann
    self.assert_(utils.ReadLockedPidFile(path) is None)
2219 debed9ae Michael Hanselmann
2220 debed9ae Michael Hanselmann
  def testError(self):
2221 debed9ae Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "foobar", "pid")
2222 debed9ae Michael Hanselmann
    utils.WriteFile(utils.PathJoin(self.tmpdir, "foobar"), data="")
2223 debed9ae Michael Hanselmann
    # open(2) should return ENOTDIR
2224 debed9ae Michael Hanselmann
    self.assertRaises(EnvironmentError, utils.ReadLockedPidFile, path)
2225 debed9ae Michael Hanselmann
2226 debed9ae Michael Hanselmann
2227 24d70417 Michael Hanselmann
class TestCertVerification(testutils.GanetiTestCase):
2228 24d70417 Michael Hanselmann
  def setUp(self):
2229 24d70417 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
2230 24d70417 Michael Hanselmann
2231 24d70417 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
2232 24d70417 Michael Hanselmann
2233 24d70417 Michael Hanselmann
  def tearDown(self):
2234 24d70417 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
2235 24d70417 Michael Hanselmann
2236 24d70417 Michael Hanselmann
  def testVerifyCertificate(self):
2237 24d70417 Michael Hanselmann
    cert_pem = utils.ReadFile(self._TestDataFilename("cert1.pem"))
2238 24d70417 Michael Hanselmann
    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
2239 24d70417 Michael Hanselmann
                                           cert_pem)
2240 24d70417 Michael Hanselmann
2241 24d70417 Michael Hanselmann
    # Not checking return value as this certificate is expired
2242 24d70417 Michael Hanselmann
    utils.VerifyX509Certificate(cert, 30, 7)
2243 24d70417 Michael Hanselmann
2244 24d70417 Michael Hanselmann
2245 24d70417 Michael Hanselmann
class TestVerifyCertificateInner(unittest.TestCase):
2246 24d70417 Michael Hanselmann
  def test(self):
2247 24d70417 Michael Hanselmann
    vci = utils._VerifyCertificateInner
2248 24d70417 Michael Hanselmann
2249 24d70417 Michael Hanselmann
    # Valid
2250 24d70417 Michael Hanselmann
    self.assertEqual(vci(False, 1263916313, 1298476313, 1266940313, 30, 7),
2251 24d70417 Michael Hanselmann
                     (None, None))
2252 24d70417 Michael Hanselmann
2253 24d70417 Michael Hanselmann
    # Not yet valid
2254 24d70417 Michael Hanselmann
    (errcode, msg) = vci(False, 1266507600, 1267544400, 1266075600, 30, 7)
2255 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_WARNING)
2256 24d70417 Michael Hanselmann
2257 24d70417 Michael Hanselmann
    # Expiring soon
2258 24d70417 Michael Hanselmann
    (errcode, msg) = vci(False, 1266507600, 1267544400, 1266939600, 30, 7)
2259 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2260 24d70417 Michael Hanselmann
2261 24d70417 Michael Hanselmann
    (errcode, msg) = vci(False, 1266507600, 1267544400, 1266939600, 30, 1)
2262 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_WARNING)
2263 24d70417 Michael Hanselmann
2264 24d70417 Michael Hanselmann
    (errcode, msg) = vci(False, 1266507600, None, 1266939600, 30, 7)
2265 24d70417 Michael Hanselmann
    self.assertEqual(errcode, None)
2266 24d70417 Michael Hanselmann
2267 24d70417 Michael Hanselmann
    # Expired
2268 24d70417 Michael Hanselmann
    (errcode, msg) = vci(True, 1266507600, 1267544400, 1266939600, 30, 7)
2269 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2270 24d70417 Michael Hanselmann
2271 24d70417 Michael Hanselmann
    (errcode, msg) = vci(True, None, 1267544400, 1266939600, 30, 7)
2272 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2273 24d70417 Michael Hanselmann
2274 24d70417 Michael Hanselmann
    (errcode, msg) = vci(True, 1266507600, None, 1266939600, 30, 7)
2275 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2276 24d70417 Michael Hanselmann
2277 24d70417 Michael Hanselmann
    (errcode, msg) = vci(True, None, None, 1266939600, 30, 7)
2278 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2279 24d70417 Michael Hanselmann
2280 24d70417 Michael Hanselmann
2281 615aaaba Michael Hanselmann
class TestHmacFunctions(unittest.TestCase):
2282 615aaaba Michael Hanselmann
  # Digests can be checked with "openssl sha1 -hmac $key"
2283 615aaaba Michael Hanselmann
  def testSha1Hmac(self):
2284 615aaaba Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("", ""),
2285 615aaaba Michael Hanselmann
                     "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d")
2286 615aaaba Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("3YzMxZWE", "Hello World"),
2287 615aaaba Michael Hanselmann
                     "ef4f3bda82212ecb2f7ce868888a19092481f1fd")
2288 615aaaba Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("TguMTA2K", ""),
2289 615aaaba Michael Hanselmann
                     "f904c2476527c6d3e6609ab683c66fa0652cb1dc")
2290 615aaaba Michael Hanselmann
2291 615aaaba Michael Hanselmann
    longtext = 1500 * "The quick brown fox jumps over the lazy dog\n"
2292 615aaaba Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("3YzMxZWE", longtext),
2293 615aaaba Michael Hanselmann
                     "35901b9a3001a7cdcf8e0e9d7c2e79df2223af54")
2294 615aaaba Michael Hanselmann
2295 3718bf6d Michael Hanselmann
  def testSha1HmacSalt(self):
2296 3718bf6d Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("TguMTA2K", "", salt="abc0"),
2297 3718bf6d Michael Hanselmann
                     "4999bf342470eadb11dfcd24ca5680cf9fd7cdce")
2298 3718bf6d Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("TguMTA2K", "", salt="abc9"),
2299 3718bf6d Michael Hanselmann
                     "17a4adc34d69c0d367d4ffbef96fd41d4df7a6e8")
2300 3718bf6d Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("3YzMxZWE", "Hello World", salt="xyz0"),
2301 3718bf6d Michael Hanselmann
                     "7f264f8114c9066afc9bb7636e1786d996d3cc0d")
2302 3718bf6d Michael Hanselmann
2303 615aaaba Michael Hanselmann
  def testVerifySha1Hmac(self):
2304 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("", "", ("fbdb1d1b18aa6c08324b"
2305 615aaaba Michael Hanselmann
                                               "7d64b71fb76370690e1d")))
2306 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("TguMTA2K", "",
2307 615aaaba Michael Hanselmann
                                      ("f904c2476527c6d3e660"
2308 615aaaba Michael Hanselmann
                                       "9ab683c66fa0652cb1dc")))
2309 615aaaba Michael Hanselmann
2310 615aaaba Michael Hanselmann
    digest = "ef4f3bda82212ecb2f7ce868888a19092481f1fd"
2311 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World", digest))
2312 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World",
2313 615aaaba Michael Hanselmann
                                      digest.lower()))
2314 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World",
2315 615aaaba Michael Hanselmann
                                      digest.upper()))
2316 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World",
2317 615aaaba Michael Hanselmann
                                      digest.title()))
2318 615aaaba Michael Hanselmann
2319 3718bf6d Michael Hanselmann
  def testVerifySha1HmacSalt(self):
2320 3718bf6d Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("TguMTA2K", "",
2321 3718bf6d Michael Hanselmann
                                      ("17a4adc34d69c0d367d4"
2322 3718bf6d Michael Hanselmann
                                       "ffbef96fd41d4df7a6e8"),
2323 3718bf6d Michael Hanselmann
                                      salt="abc9"))
2324 3718bf6d Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World",
2325 3718bf6d Michael Hanselmann
                                      ("7f264f8114c9066afc9b"
2326 3718bf6d Michael Hanselmann
                                       "b7636e1786d996d3cc0d"),
2327 3718bf6d Michael Hanselmann
                                      salt="xyz0"))
2328 3718bf6d Michael Hanselmann
2329 615aaaba Michael Hanselmann
2330 232144d0 Guido Trotter
class TestIgnoreSignals(unittest.TestCase):
2331 232144d0 Guido Trotter
  """Test the IgnoreSignals decorator"""
2332 232144d0 Guido Trotter
2333 232144d0 Guido Trotter
  @staticmethod
2334 232144d0 Guido Trotter
  def _Raise(exception):
2335 232144d0 Guido Trotter
    raise exception
2336 232144d0 Guido Trotter
2337 232144d0 Guido Trotter
  @staticmethod
2338 232144d0 Guido Trotter
  def _Return(rval):
2339 232144d0 Guido Trotter
    return rval
2340 232144d0 Guido Trotter
2341 232144d0 Guido Trotter
  def testIgnoreSignals(self):
2342 232144d0 Guido Trotter
    sock_err_intr = socket.error(errno.EINTR, "Message")
2343 232144d0 Guido Trotter
    sock_err_inval = socket.error(errno.EINVAL, "Message")
2344 232144d0 Guido Trotter
2345 232144d0 Guido Trotter
    env_err_intr = EnvironmentError(errno.EINTR, "Message")
2346 232144d0 Guido Trotter
    env_err_inval = EnvironmentError(errno.EINVAL, "Message")
2347 232144d0 Guido Trotter
2348 232144d0 Guido Trotter
    self.assertRaises(socket.error, self._Raise, sock_err_intr)
2349 232144d0 Guido Trotter
    self.assertRaises(socket.error, self._Raise, sock_err_inval)
2350 232144d0 Guido Trotter
    self.assertRaises(EnvironmentError, self._Raise, env_err_intr)
2351 232144d0 Guido Trotter
    self.assertRaises(EnvironmentError, self._Raise, env_err_inval)
2352 232144d0 Guido Trotter
2353 232144d0 Guido Trotter
    self.assertEquals(utils.IgnoreSignals(self._Raise, sock_err_intr), None)
2354 232144d0 Guido Trotter
    self.assertEquals(utils.IgnoreSignals(self._Raise, env_err_intr), None)
2355 232144d0 Guido Trotter
    self.assertRaises(socket.error, utils.IgnoreSignals, self._Raise,
2356 232144d0 Guido Trotter
                      sock_err_inval)
2357 232144d0 Guido Trotter
    self.assertRaises(EnvironmentError, utils.IgnoreSignals, self._Raise,
2358 232144d0 Guido Trotter
                      env_err_inval)
2359 232144d0 Guido Trotter
2360 232144d0 Guido Trotter
    self.assertEquals(utils.IgnoreSignals(self._Return, True), True)
2361 232144d0 Guido Trotter
    self.assertEquals(utils.IgnoreSignals(self._Return, 33), 33)
2362 232144d0 Guido Trotter
2363 232144d0 Guido Trotter
2364 b73360e3 Balazs Lecz
class TestEnsureDirs(unittest.TestCase):
2365 b73360e3 Balazs Lecz
  """Tests for EnsureDirs"""
2366 b73360e3 Balazs Lecz
2367 b73360e3 Balazs Lecz
  def setUp(self):
2368 b73360e3 Balazs Lecz
    self.dir = tempfile.mkdtemp()
2369 b73360e3 Balazs Lecz
    self.old_umask = os.umask(0777)
2370 b73360e3 Balazs Lecz
2371 b73360e3 Balazs Lecz
  def testEnsureDirs(self):
2372 b73360e3 Balazs Lecz
    utils.EnsureDirs([
2373 b73360e3 Balazs Lecz
        (utils.PathJoin(self.dir, "foo"), 0777),
2374 b73360e3 Balazs Lecz
        (utils.PathJoin(self.dir, "bar"), 0000),
2375 b73360e3 Balazs Lecz
        ])
2376 b73360e3 Balazs Lecz
    self.assertEquals(os.stat(utils.PathJoin(self.dir, "foo"))[0] & 0777, 0777)
2377 b73360e3 Balazs Lecz
    self.assertEquals(os.stat(utils.PathJoin(self.dir, "bar"))[0] & 0777, 0000)
2378 b73360e3 Balazs Lecz
2379 b73360e3 Balazs Lecz
  def tearDown(self):
2380 b73360e3 Balazs Lecz
    os.rmdir(utils.PathJoin(self.dir, "foo"))
2381 b73360e3 Balazs Lecz
    os.rmdir(utils.PathJoin(self.dir, "bar"))
2382 b73360e3 Balazs Lecz
    os.rmdir(self.dir)
2383 b73360e3 Balazs Lecz
    os.umask(self.old_umask)
2384 b73360e3 Balazs Lecz
2385 f8ea4ada Michael Hanselmann
2386 f8ea4ada Michael Hanselmann
class TestFormatSeconds(unittest.TestCase):
2387 f8ea4ada Michael Hanselmann
  def test(self):
2388 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(1), "1s")
2389 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(3600), "1h 0m 0s")
2390 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(3599), "59m 59s")
2391 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(7200), "2h 0m 0s")
2392 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(7201), "2h 0m 1s")
2393 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(7281), "2h 1m 21s")
2394 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(29119), "8h 5m 19s")
2395 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(19431228), "224d 21h 33m 48s")
2396 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(-1), "-1s")
2397 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(-282), "-282s")
2398 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(-29119), "-29119s")
2399 f8ea4ada Michael Hanselmann
2400 f8ea4ada Michael Hanselmann
  def testFloat(self):
2401 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(1.3), "1s")
2402 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(1.9), "2s")
2403 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(3912.12311), "1h 5m 12s")
2404 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(3912.8), "1h 5m 13s")
2405 f8ea4ada Michael Hanselmann
2406 f8ea4ada Michael Hanselmann
2407 560cbec1 Michael Hanselmann
class RunIgnoreProcessNotFound(unittest.TestCase):
2408 560cbec1 Michael Hanselmann
  @staticmethod
2409 560cbec1 Michael Hanselmann
  def _WritePid(fd):
2410 560cbec1 Michael Hanselmann
    os.write(fd, str(os.getpid()))
2411 560cbec1 Michael Hanselmann
    os.close(fd)
2412 560cbec1 Michael Hanselmann
    return True
2413 560cbec1 Michael Hanselmann
2414 560cbec1 Michael Hanselmann
  def test(self):
2415 560cbec1 Michael Hanselmann
    (pid_read_fd, pid_write_fd) = os.pipe()
2416 560cbec1 Michael Hanselmann
2417 560cbec1 Michael Hanselmann
    # Start short-lived process which writes its PID to pipe
2418 560cbec1 Michael Hanselmann
    self.assert_(utils.RunInSeparateProcess(self._WritePid, pid_write_fd))
2419 560cbec1 Michael Hanselmann
    os.close(pid_write_fd)
2420 560cbec1 Michael Hanselmann
2421 560cbec1 Michael Hanselmann
    # Read PID from pipe
2422 560cbec1 Michael Hanselmann
    pid = int(os.read(pid_read_fd, 1024))
2423 560cbec1 Michael Hanselmann
    os.close(pid_read_fd)
2424 560cbec1 Michael Hanselmann
2425 560cbec1 Michael Hanselmann
    # Try to send signal to process which exited recently
2426 560cbec1 Michael Hanselmann
    self.assertFalse(utils.IgnoreProcessNotFound(os.kill, pid, 0))
2427 560cbec1 Michael Hanselmann
2428 560cbec1 Michael Hanselmann
2429 a8083063 Iustin Pop
if __name__ == '__main__':
2430 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()