Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils_unittest.py @ 28f34048

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