Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils_unittest.py @ c74cda62

History | View | Annotate | Download (83.2 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a744b676 Manuel Franceschini
# Copyright (C) 2006, 2007, 2010 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 a744b676 Manuel Franceschini
import distutils.version
25 a744b676 Manuel Franceschini
import errno
26 a744b676 Manuel Franceschini
import fcntl
27 a744b676 Manuel Franceschini
import glob
28 a8083063 Iustin Pop
import os
29 a8083063 Iustin Pop
import os.path
30 a744b676 Manuel Franceschini
import re
31 a744b676 Manuel Franceschini
import shutil
32 740c5aab Guido Trotter
import signal
33 2c30e9d7 Alexander Schreiber
import socket
34 a744b676 Manuel Franceschini
import stat
35 d392fa34 Iustin Pop
import string
36 a744b676 Manuel Franceschini
import tempfile
37 a744b676 Manuel Franceschini
import time
38 a744b676 Manuel Franceschini
import unittest
39 27e46076 Michael Hanselmann
import warnings
40 a744b676 Manuel Franceschini
import OpenSSL
41 858905fb Michael Hanselmann
from cStringIO import StringIO
42 a8083063 Iustin Pop
43 c9c4f19e Michael Hanselmann
import testutils
44 16abfbc2 Alexander Schreiber
from ganeti import constants
45 716a32cb Guido Trotter
from ganeti import compat
46 59072e7e Michael Hanselmann
from ganeti import utils
47 a5728081 Guido Trotter
from ganeti import errors
48 a744b676 Manuel Franceschini
from ganeti.utils import RunCmd, RemoveFile, MatchNameComponent, FormatUnit, \
49 a744b676 Manuel Franceschini
     ParseUnit, ShellQuote, ShellQuoteArgs, ListVisibleFiles, FirstFree, \
50 a744b676 Manuel Franceschini
     TailFile, SafeEncode, FormatTime, UnescapeAndSplit, RunParts, PathJoin, \
51 a744b676 Manuel Franceschini
     ReadOneLineFile, SetEtcHostsEntry, RemoveEtcHostsEntry
52 a8083063 Iustin Pop
53 d9f311d7 Iustin Pop
54 a8083063 Iustin Pop
class TestIsProcessAlive(unittest.TestCase):
55 a8083063 Iustin Pop
  """Testing case for IsProcessAlive"""
56 740c5aab Guido Trotter
57 a8083063 Iustin Pop
  def testExists(self):
58 a8083063 Iustin Pop
    mypid = os.getpid()
59 a744b676 Manuel Franceschini
    self.assert_(utils.IsProcessAlive(mypid), "can't find myself running")
60 a8083063 Iustin Pop
61 a8083063 Iustin Pop
  def testNotExisting(self):
62 09352fa4 Iustin Pop
    pid_non_existing = os.fork()
63 09352fa4 Iustin Pop
    if pid_non_existing == 0:
64 09352fa4 Iustin Pop
      os._exit(0)
65 09352fa4 Iustin Pop
    elif pid_non_existing < 0:
66 09352fa4 Iustin Pop
      raise SystemError("can't fork")
67 09352fa4 Iustin Pop
    os.waitpid(pid_non_existing, 0)
68 a744b676 Manuel Franceschini
    self.assertFalse(utils.IsProcessAlive(pid_non_existing),
69 158206e0 Manuel Franceschini
                     "nonexisting process detected")
70 a8083063 Iustin Pop
71 d9f311d7 Iustin Pop
72 a01b500b Michael Hanselmann
class TestGetProcStatusPath(unittest.TestCase):
73 a01b500b Michael Hanselmann
  def test(self):
74 a01b500b Michael Hanselmann
    self.assert_("/1234/" in utils._GetProcStatusPath(1234))
75 a01b500b Michael Hanselmann
    self.assertNotEqual(utils._GetProcStatusPath(1),
76 a01b500b Michael Hanselmann
                        utils._GetProcStatusPath(2))
77 a01b500b Michael Hanselmann
78 a01b500b Michael Hanselmann
79 a01b500b Michael Hanselmann
class TestIsProcessHandlingSignal(unittest.TestCase):
80 a01b500b Michael Hanselmann
  def setUp(self):
81 a01b500b Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
82 a01b500b Michael Hanselmann
83 a01b500b Michael Hanselmann
  def tearDown(self):
84 a01b500b Michael Hanselmann
    shutil.rmtree(self.tmpdir)
85 a01b500b Michael Hanselmann
86 a01b500b Michael Hanselmann
  def testParseSigsetT(self):
87 a01b500b Michael Hanselmann
    self.assertEqual(len(utils._ParseSigsetT("0")), 0)
88 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("1"), set([1]))
89 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("1000a"), set([2, 4, 17]))
90 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("810002"), set([2, 17, 24, ]))
91 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("0000000180000202"),
92 a01b500b Michael Hanselmann
                     set([2, 10, 32, 33]))
93 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("0000000180000002"),
94 a01b500b Michael Hanselmann
                     set([2, 32, 33]))
95 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("0000000188000002"),
96 a01b500b Michael Hanselmann
                     set([2, 28, 32, 33]))
97 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("000000004b813efb"),
98 a01b500b Michael Hanselmann
                     set([1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 17,
99 a01b500b Michael Hanselmann
                          24, 25, 26, 28, 31]))
100 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("ffffff"), set(range(1, 25)))
101 a01b500b Michael Hanselmann
102 a01b500b Michael Hanselmann
  def testGetProcStatusField(self):
103 a01b500b Michael Hanselmann
    for field in ["SigCgt", "Name", "FDSize"]:
104 a01b500b Michael Hanselmann
      for value in ["", "0", "cat", "  1234 KB"]:
105 a01b500b Michael Hanselmann
        pstatus = "\n".join([
106 a01b500b Michael Hanselmann
          "VmPeak: 999 kB",
107 a01b500b Michael Hanselmann
          "%s: %s" % (field, value),
108 a01b500b Michael Hanselmann
          "TracerPid: 0",
109 a01b500b Michael Hanselmann
          ])
110 a01b500b Michael Hanselmann
        result = utils._GetProcStatusField(pstatus, field)
111 a01b500b Michael Hanselmann
        self.assertEqual(result, value.strip())
112 a01b500b Michael Hanselmann
113 a01b500b Michael Hanselmann
  def test(self):
114 a744b676 Manuel Franceschini
    sp = PathJoin(self.tmpdir, "status")
115 a01b500b Michael Hanselmann
116 a01b500b Michael Hanselmann
    utils.WriteFile(sp, data="\n".join([
117 a01b500b Michael Hanselmann
      "Name:   bash",
118 a01b500b Michael Hanselmann
      "State:  S (sleeping)",
119 a01b500b Michael Hanselmann
      "SleepAVG:       98%",
120 a01b500b Michael Hanselmann
      "Pid:    22250",
121 a01b500b Michael Hanselmann
      "PPid:   10858",
122 a01b500b Michael Hanselmann
      "TracerPid:      0",
123 a01b500b Michael Hanselmann
      "SigBlk: 0000000000010000",
124 a01b500b Michael Hanselmann
      "SigIgn: 0000000000384004",
125 a01b500b Michael Hanselmann
      "SigCgt: 000000004b813efb",
126 a01b500b Michael Hanselmann
      "CapEff: 0000000000000000",
127 a01b500b Michael Hanselmann
      ]))
128 a01b500b Michael Hanselmann
129 a01b500b Michael Hanselmann
    self.assert_(utils.IsProcessHandlingSignal(1234, 10, status_path=sp))
130 a01b500b Michael Hanselmann
131 a01b500b Michael Hanselmann
  def testNoSigCgt(self):
132 a744b676 Manuel Franceschini
    sp = PathJoin(self.tmpdir, "status")
133 a01b500b Michael Hanselmann
134 a01b500b Michael Hanselmann
    utils.WriteFile(sp, data="\n".join([
135 a01b500b Michael Hanselmann
      "Name:   bash",
136 a01b500b Michael Hanselmann
      ]))
137 a01b500b Michael Hanselmann
138 a01b500b Michael Hanselmann
    self.assertRaises(RuntimeError, utils.IsProcessHandlingSignal,
139 a01b500b Michael Hanselmann
                      1234, 10, status_path=sp)
140 a01b500b Michael Hanselmann
141 a01b500b Michael Hanselmann
  def testNoSuchFile(self):
142 a744b676 Manuel Franceschini
    sp = PathJoin(self.tmpdir, "notexist")
143 a01b500b Michael Hanselmann
144 a01b500b Michael Hanselmann
    self.assertFalse(utils.IsProcessHandlingSignal(1234, 10, status_path=sp))
145 a01b500b Michael Hanselmann
146 a01b500b Michael Hanselmann
  @staticmethod
147 a01b500b Michael Hanselmann
  def _TestRealProcess():
148 a01b500b Michael Hanselmann
    signal.signal(signal.SIGUSR1, signal.SIG_DFL)
149 a01b500b Michael Hanselmann
    if utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
150 a01b500b Michael Hanselmann
      raise Exception("SIGUSR1 is handled when it should not be")
151 a01b500b Michael Hanselmann
152 a01b500b Michael Hanselmann
    signal.signal(signal.SIGUSR1, lambda signum, frame: None)
153 a01b500b Michael Hanselmann
    if not utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
154 a01b500b Michael Hanselmann
      raise Exception("SIGUSR1 is not handled when it should be")
155 a01b500b Michael Hanselmann
156 a01b500b Michael Hanselmann
    signal.signal(signal.SIGUSR1, signal.SIG_IGN)
157 a01b500b Michael Hanselmann
    if utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
158 a01b500b Michael Hanselmann
      raise Exception("SIGUSR1 is not handled when it should be")
159 a01b500b Michael Hanselmann
160 a01b500b Michael Hanselmann
    signal.signal(signal.SIGUSR1, signal.SIG_DFL)
161 a01b500b Michael Hanselmann
    if utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
162 a01b500b Michael Hanselmann
      raise Exception("SIGUSR1 is handled when it should not be")
163 a01b500b Michael Hanselmann
164 a01b500b Michael Hanselmann
    return True
165 a01b500b Michael Hanselmann
166 a01b500b Michael Hanselmann
  def testRealProcess(self):
167 a01b500b Michael Hanselmann
    self.assert_(utils.RunInSeparateProcess(self._TestRealProcess))
168 a01b500b Michael Hanselmann
169 a01b500b Michael Hanselmann
170 af99afa6 Guido Trotter
class TestPidFileFunctions(unittest.TestCase):
171 d9f311d7 Iustin Pop
  """Tests for WritePidFile, RemovePidFile and ReadPidFile"""
172 af99afa6 Guido Trotter
173 af99afa6 Guido Trotter
  def setUp(self):
174 af99afa6 Guido Trotter
    self.dir = tempfile.mkdtemp()
175 af99afa6 Guido Trotter
    self.f_dpn = lambda name: os.path.join(self.dir, "%s.pid" % name)
176 53beffbb Iustin Pop
    utils.DaemonPidFileName = self.f_dpn
177 af99afa6 Guido Trotter
178 af99afa6 Guido Trotter
  def testPidFileFunctions(self):
179 d9f311d7 Iustin Pop
    pid_file = self.f_dpn('test')
180 5c4d37f9 Iustin Pop
    fd = utils.WritePidFile(self.f_dpn('test'))
181 d9f311d7 Iustin Pop
    self.failUnless(os.path.exists(pid_file),
182 d9f311d7 Iustin Pop
                    "PID file should have been created")
183 d9f311d7 Iustin Pop
    read_pid = utils.ReadPidFile(pid_file)
184 d9f311d7 Iustin Pop
    self.failUnlessEqual(read_pid, os.getpid())
185 d9f311d7 Iustin Pop
    self.failUnless(utils.IsProcessAlive(read_pid))
186 5c4d37f9 Iustin Pop
    self.failUnlessRaises(errors.LockError, utils.WritePidFile,
187 5c4d37f9 Iustin Pop
                          self.f_dpn('test'))
188 5c4d37f9 Iustin Pop
    os.close(fd)
189 d9f311d7 Iustin Pop
    utils.RemovePidFile('test')
190 d9f311d7 Iustin Pop
    self.failIf(os.path.exists(pid_file),
191 d9f311d7 Iustin Pop
                "PID file should not exist anymore")
192 d9f311d7 Iustin Pop
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
193 d9f311d7 Iustin Pop
                         "ReadPidFile should return 0 for missing pid file")
194 d9f311d7 Iustin Pop
    fh = open(pid_file, "w")
195 d9f311d7 Iustin Pop
    fh.write("blah\n")
196 d9f311d7 Iustin Pop
    fh.close()
197 d9f311d7 Iustin Pop
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
198 d9f311d7 Iustin Pop
                         "ReadPidFile should return 0 for invalid pid file")
199 5c4d37f9 Iustin Pop
    # but now, even with the file existing, we should be able to lock it
200 5c4d37f9 Iustin Pop
    fd = utils.WritePidFile(self.f_dpn('test'))
201 5c4d37f9 Iustin Pop
    os.close(fd)
202 af99afa6 Guido Trotter
    utils.RemovePidFile('test')
203 d9f311d7 Iustin Pop
    self.failIf(os.path.exists(pid_file),
204 d9f311d7 Iustin Pop
                "PID file should not exist anymore")
205 af99afa6 Guido Trotter
206 b2a1f511 Iustin Pop
  def testKill(self):
207 b2a1f511 Iustin Pop
    pid_file = self.f_dpn('child')
208 b2a1f511 Iustin Pop
    r_fd, w_fd = os.pipe()
209 b2a1f511 Iustin Pop
    new_pid = os.fork()
210 b2a1f511 Iustin Pop
    if new_pid == 0: #child
211 5c4d37f9 Iustin Pop
      utils.WritePidFile(self.f_dpn('child'))
212 b2a1f511 Iustin Pop
      os.write(w_fd, 'a')
213 b2a1f511 Iustin Pop
      signal.pause()
214 b2a1f511 Iustin Pop
      os._exit(0)
215 b2a1f511 Iustin Pop
      return
216 b2a1f511 Iustin Pop
    # else we are in the parent
217 b2a1f511 Iustin Pop
    # wait until the child has written the pid file
218 b2a1f511 Iustin Pop
    os.read(r_fd, 1)
219 b2a1f511 Iustin Pop
    read_pid = utils.ReadPidFile(pid_file)
220 b2a1f511 Iustin Pop
    self.failUnlessEqual(read_pid, new_pid)
221 b2a1f511 Iustin Pop
    self.failUnless(utils.IsProcessAlive(new_pid))
222 ff5251bc Iustin Pop
    utils.KillProcess(new_pid, waitpid=True)
223 b2a1f511 Iustin Pop
    self.failIf(utils.IsProcessAlive(new_pid))
224 b2a1f511 Iustin Pop
    utils.RemovePidFile('child')
225 a744b676 Manuel Franceschini
    self.failUnlessRaises(errors.ProgrammerError, utils.KillProcess, 0)
226 b2a1f511 Iustin Pop
227 af99afa6 Guido Trotter
  def tearDown(self):
228 d9f311d7 Iustin Pop
    for name in os.listdir(self.dir):
229 d9f311d7 Iustin Pop
      os.unlink(os.path.join(self.dir, name))
230 af99afa6 Guido Trotter
    os.rmdir(self.dir)
231 af99afa6 Guido Trotter
232 a8083063 Iustin Pop
233 36117c2b Iustin Pop
class TestRunCmd(testutils.GanetiTestCase):
234 a8083063 Iustin Pop
  """Testing case for the RunCmd function"""
235 a8083063 Iustin Pop
236 a8083063 Iustin Pop
  def setUp(self):
237 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
238 a8083063 Iustin Pop
    self.magic = time.ctime() + " ganeti test"
239 51596eb2 Iustin Pop
    self.fname = self._CreateTempFile()
240 c74cda62 René Nussbaumer
    self.fifo_tmpdir = tempfile.mkdtemp()
241 c74cda62 René Nussbaumer
    self.fifo_file = os.path.join(self.fifo_tmpdir, "ganeti_test_fifo")
242 c74cda62 René Nussbaumer
    os.mkfifo(self.fifo_file)
243 c74cda62 René Nussbaumer
244 c74cda62 René Nussbaumer
  def tearDown(self):
245 c74cda62 René Nussbaumer
    shutil.rmtree(self.fifo_tmpdir)
246 a8083063 Iustin Pop
247 a8083063 Iustin Pop
  def testOk(self):
248 31ee599c Michael Hanselmann
    """Test successful exit code"""
249 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c 'exit 0'")
250 a8083063 Iustin Pop
    self.assertEqual(result.exit_code, 0)
251 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
252 a8083063 Iustin Pop
253 a8083063 Iustin Pop
  def testFail(self):
254 a8083063 Iustin Pop
    """Test fail exit code"""
255 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c 'exit 1'")
256 a8083063 Iustin Pop
    self.assertEqual(result.exit_code, 1)
257 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
258 a8083063 Iustin Pop
259 a8083063 Iustin Pop
  def testStdout(self):
260 a8083063 Iustin Pop
    """Test standard output"""
261 a8083063 Iustin Pop
    cmd = 'echo -n "%s"' % self.magic
262 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd)
263 a8083063 Iustin Pop
    self.assertEqual(result.stdout, self.magic)
264 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd, output=self.fname)
265 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
266 36117c2b Iustin Pop
    self.assertFileContent(self.fname, self.magic)
267 a8083063 Iustin Pop
268 a8083063 Iustin Pop
  def testStderr(self):
269 a8083063 Iustin Pop
    """Test standard error"""
270 a8083063 Iustin Pop
    cmd = 'echo -n "%s"' % self.magic
271 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s' 1>&2" % cmd)
272 a8083063 Iustin Pop
    self.assertEqual(result.stderr, self.magic)
273 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s' 1>&2" % cmd, output=self.fname)
274 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
275 36117c2b Iustin Pop
    self.assertFileContent(self.fname, self.magic)
276 a8083063 Iustin Pop
277 a8083063 Iustin Pop
  def testCombined(self):
278 a8083063 Iustin Pop
    """Test combined output"""
279 a8083063 Iustin Pop
    cmd = 'echo -n "A%s"; echo -n "B%s" 1>&2' % (self.magic, self.magic)
280 36117c2b Iustin Pop
    expected = "A" + self.magic + "B" + self.magic
281 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd)
282 36117c2b Iustin Pop
    self.assertEqual(result.output, expected)
283 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd, output=self.fname)
284 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
285 36117c2b Iustin Pop
    self.assertFileContent(self.fname, expected)
286 a8083063 Iustin Pop
287 a8083063 Iustin Pop
  def testSignal(self):
288 01fd6005 Manuel Franceschini
    """Test signal"""
289 01fd6005 Manuel Franceschini
    result = RunCmd(["python", "-c", "import os; os.kill(os.getpid(), 15)"])
290 a8083063 Iustin Pop
    self.assertEqual(result.signal, 15)
291 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
292 a8083063 Iustin Pop
293 c74cda62 René Nussbaumer
  def testTimeoutClean(self):
294 c74cda62 René Nussbaumer
    cmd = "trap 'exit 0' TERM; read < %s" % self.fifo_file
295 c74cda62 René Nussbaumer
    result = RunCmd(["/bin/sh", "-c", cmd], timeout=0.2)
296 c74cda62 René Nussbaumer
    self.assertEqual(result.exit_code, 0)
297 c74cda62 René Nussbaumer
298 c74cda62 René Nussbaumer
  def testTimeoutCleanInteractive(self):
299 c74cda62 René Nussbaumer
    cmd = "trap 'exit 0' TERM; read"
300 c74cda62 René Nussbaumer
    result = RunCmd(["/bin/sh", "-c", cmd], interactive=True, timeout=0.2)
301 c74cda62 René Nussbaumer
    self.assertEqual(result.exit_code, 0)
302 c74cda62 René Nussbaumer
303 c74cda62 René Nussbaumer
  def testTimeoutNonClean(self):
304 c74cda62 René Nussbaumer
    for exit_code in (1, 10, 17, 29):
305 c74cda62 René Nussbaumer
      cmd = "trap 'exit %i' TERM; read" % exit_code
306 c74cda62 René Nussbaumer
      result = RunCmd(["/bin/sh", "-c", cmd], interactive=True, timeout=0.2)
307 c74cda62 René Nussbaumer
      self.assert_(result.failed)
308 c74cda62 René Nussbaumer
      self.assertEqual(result.exit_code, exit_code)
309 c74cda62 René Nussbaumer
310 c74cda62 René Nussbaumer
  def testTimeoutKill(self):
311 c74cda62 René Nussbaumer
    cmd = "trap '' TERM; read < %s" % self.fifo_file
312 c74cda62 René Nussbaumer
    timeout = 0.2
313 c74cda62 René Nussbaumer
    strcmd = utils.ShellQuoteArgs(["/bin/sh", "-c", cmd])
314 c74cda62 René Nussbaumer
    out, err, status, ta = utils._RunCmdPipe(strcmd, {}, True, "/", False,
315 c74cda62 René Nussbaumer
                                             timeout, _linger_timeout=0.2)
316 c74cda62 René Nussbaumer
    self.assert_(status < 0)
317 c74cda62 René Nussbaumer
    self.assertEqual(-status, signal.SIGKILL)
318 c74cda62 René Nussbaumer
319 c74cda62 René Nussbaumer
  def testTimeoutOutputAfterTerm(self):
320 c74cda62 René Nussbaumer
    cmd = "trap 'echo sigtermed; exit 1' TERM; read < %s" % self.fifo_file
321 c74cda62 René Nussbaumer
    result = RunCmd(["/bin/sh", "-c", cmd], timeout=0.2)
322 c74cda62 René Nussbaumer
    self.assert_(result.failed)
323 c74cda62 René Nussbaumer
    self.assertEqual(result.stdout, "sigtermed\n")
324 c74cda62 René Nussbaumer
325 7fcf849f Iustin Pop
  def testListRun(self):
326 7fcf849f Iustin Pop
    """Test list runs"""
327 7fcf849f Iustin Pop
    result = RunCmd(["true"])
328 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
329 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 0)
330 7fcf849f Iustin Pop
    result = RunCmd(["/bin/sh", "-c", "exit 1"])
331 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
332 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 1)
333 7fcf849f Iustin Pop
    result = RunCmd(["echo", "-n", self.magic])
334 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
335 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 0)
336 7fcf849f Iustin Pop
    self.assertEqual(result.stdout, self.magic)
337 7fcf849f Iustin Pop
338 36117c2b Iustin Pop
  def testFileEmptyOutput(self):
339 36117c2b Iustin Pop
    """Test file output"""
340 36117c2b Iustin Pop
    result = RunCmd(["true"], output=self.fname)
341 36117c2b Iustin Pop
    self.assertEqual(result.signal, None)
342 36117c2b Iustin Pop
    self.assertEqual(result.exit_code, 0)
343 36117c2b Iustin Pop
    self.assertFileContent(self.fname, "")
344 36117c2b Iustin Pop
345 f6441c7c Iustin Pop
  def testLang(self):
346 f6441c7c Iustin Pop
    """Test locale environment"""
347 23f41a3e Michael Hanselmann
    old_env = os.environ.copy()
348 23f41a3e Michael Hanselmann
    try:
349 23f41a3e Michael Hanselmann
      os.environ["LANG"] = "en_US.UTF-8"
350 23f41a3e Michael Hanselmann
      os.environ["LC_ALL"] = "en_US.UTF-8"
351 23f41a3e Michael Hanselmann
      result = RunCmd(["locale"])
352 23f41a3e Michael Hanselmann
      for line in result.output.splitlines():
353 23f41a3e Michael Hanselmann
        key, value = line.split("=", 1)
354 23f41a3e Michael Hanselmann
        # Ignore these variables, they're overridden by LC_ALL
355 23f41a3e Michael Hanselmann
        if key == "LANG" or key == "LANGUAGE":
356 23f41a3e Michael Hanselmann
          continue
357 23f41a3e Michael Hanselmann
        self.failIf(value and value != "C" and value != '"C"',
358 23f41a3e Michael Hanselmann
            "Variable %s is set to the invalid value '%s'" % (key, value))
359 23f41a3e Michael Hanselmann
    finally:
360 23f41a3e Michael Hanselmann
      os.environ = old_env
361 f6441c7c Iustin Pop
362 8797df43 Iustin Pop
  def testDefaultCwd(self):
363 8797df43 Iustin Pop
    """Test default working directory"""
364 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"]).stdout.strip(), "/")
365 8797df43 Iustin Pop
366 8797df43 Iustin Pop
  def testCwd(self):
367 8797df43 Iustin Pop
    """Test default working directory"""
368 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd="/").stdout.strip(), "/")
369 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd="/tmp").stdout.strip(), "/tmp")
370 8797df43 Iustin Pop
    cwd = os.getcwd()
371 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd=cwd).stdout.strip(), cwd)
372 8797df43 Iustin Pop
373 bf4daac9 Guido Trotter
  def testResetEnv(self):
374 bf4daac9 Guido Trotter
    """Test environment reset functionality"""
375 bf4daac9 Guido Trotter
    self.failUnlessEqual(RunCmd(["env"], reset_env=True).stdout.strip(), "")
376 0babc371 Michael Hanselmann
    self.failUnlessEqual(RunCmd(["env"], reset_env=True,
377 0babc371 Michael Hanselmann
                                env={"FOO": "bar",}).stdout.strip(), "FOO=bar")
378 bf4daac9 Guido Trotter
379 a8083063 Iustin Pop
380 6bb65e3a Guido Trotter
class TestRunParts(unittest.TestCase):
381 6bb65e3a Guido Trotter
  """Testing case for the RunParts function"""
382 6bb65e3a Guido Trotter
383 6bb65e3a Guido Trotter
  def setUp(self):
384 6bb65e3a Guido Trotter
    self.rundir = tempfile.mkdtemp(prefix="ganeti-test", suffix=".tmp")
385 6bb65e3a Guido Trotter
386 6bb65e3a Guido Trotter
  def tearDown(self):
387 6bb65e3a Guido Trotter
    shutil.rmtree(self.rundir)
388 6bb65e3a Guido Trotter
389 6bb65e3a Guido Trotter
  def testEmpty(self):
390 6bb65e3a Guido Trotter
    """Test on an empty dir"""
391 6bb65e3a Guido Trotter
    self.failUnlessEqual(RunParts(self.rundir, reset_env=True), [])
392 6bb65e3a Guido Trotter
393 6bb65e3a Guido Trotter
  def testSkipWrongName(self):
394 6bb65e3a Guido Trotter
    """Test that wrong files are skipped"""
395 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test.dot")
396 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="")
397 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
398 6bb65e3a Guido Trotter
    relname = os.path.basename(fname)
399 6bb65e3a Guido Trotter
    self.failUnlessEqual(RunParts(self.rundir, reset_env=True),
400 6bb65e3a Guido Trotter
                         [(relname, constants.RUNPARTS_SKIP, None)])
401 6bb65e3a Guido Trotter
402 6bb65e3a Guido Trotter
  def testSkipNonExec(self):
403 6bb65e3a Guido Trotter
    """Test that non executable files are skipped"""
404 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
405 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="")
406 6bb65e3a Guido Trotter
    relname = os.path.basename(fname)
407 6bb65e3a Guido Trotter
    self.failUnlessEqual(RunParts(self.rundir, reset_env=True),
408 6bb65e3a Guido Trotter
                         [(relname, constants.RUNPARTS_SKIP, None)])
409 6bb65e3a Guido Trotter
410 6bb65e3a Guido Trotter
  def testError(self):
411 6bb65e3a Guido Trotter
    """Test error on a broken executable"""
412 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
413 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="")
414 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
415 6bb65e3a Guido Trotter
    (relname, status, error) = RunParts(self.rundir, reset_env=True)[0]
416 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(fname))
417 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_ERR)
418 6bb65e3a Guido Trotter
    self.failUnless(error)
419 6bb65e3a Guido Trotter
420 6bb65e3a Guido Trotter
  def testSorted(self):
421 6bb65e3a Guido Trotter
    """Test executions are sorted"""
422 6bb65e3a Guido Trotter
    files = []
423 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "64test"))
424 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "00test"))
425 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "42test"))
426 6bb65e3a Guido Trotter
427 6bb65e3a Guido Trotter
    for fname in files:
428 6bb65e3a Guido Trotter
      utils.WriteFile(fname, data="")
429 6bb65e3a Guido Trotter
430 6bb65e3a Guido Trotter
    results = RunParts(self.rundir, reset_env=True)
431 6bb65e3a Guido Trotter
432 6bb65e3a Guido Trotter
    for fname in sorted(files):
433 6bb65e3a Guido Trotter
      self.failUnlessEqual(os.path.basename(fname), results.pop(0)[0])
434 6bb65e3a Guido Trotter
435 6bb65e3a Guido Trotter
  def testOk(self):
436 6bb65e3a Guido Trotter
    """Test correct execution"""
437 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
438 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="#!/bin/sh\n\necho -n ciao")
439 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
440 6bb65e3a Guido Trotter
    (relname, status, runresult) = RunParts(self.rundir, reset_env=True)[0]
441 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(fname))
442 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
443 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.stdout, "ciao")
444 6bb65e3a Guido Trotter
445 6bb65e3a Guido Trotter
  def testRunFail(self):
446 6bb65e3a Guido Trotter
    """Test correct execution, with run failure"""
447 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
448 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="#!/bin/sh\n\nexit 1")
449 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
450 6bb65e3a Guido Trotter
    (relname, status, runresult) = RunParts(self.rundir, reset_env=True)[0]
451 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(fname))
452 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
453 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.exit_code, 1)
454 6bb65e3a Guido Trotter
    self.failUnless(runresult.failed)
455 6bb65e3a Guido Trotter
456 6bb65e3a Guido Trotter
  def testRunMix(self):
457 6bb65e3a Guido Trotter
    files = []
458 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "00test"))
459 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "42test"))
460 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "64test"))
461 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "99test"))
462 6bb65e3a Guido Trotter
463 6bb65e3a Guido Trotter
    files.sort()
464 6bb65e3a Guido Trotter
465 6bb65e3a Guido Trotter
    # 1st has errors in execution
466 6bb65e3a Guido Trotter
    utils.WriteFile(files[0], data="#!/bin/sh\n\nexit 1")
467 6bb65e3a Guido Trotter
    os.chmod(files[0], stat.S_IREAD | stat.S_IEXEC)
468 6bb65e3a Guido Trotter
469 6bb65e3a Guido Trotter
    # 2nd is skipped
470 6bb65e3a Guido Trotter
    utils.WriteFile(files[1], data="")
471 6bb65e3a Guido Trotter
472 6bb65e3a Guido Trotter
    # 3rd cannot execute properly
473 6bb65e3a Guido Trotter
    utils.WriteFile(files[2], data="")
474 6bb65e3a Guido Trotter
    os.chmod(files[2], stat.S_IREAD | stat.S_IEXEC)
475 6bb65e3a Guido Trotter
476 6bb65e3a Guido Trotter
    # 4th execs
477 6bb65e3a Guido Trotter
    utils.WriteFile(files[3], data="#!/bin/sh\n\necho -n ciao")
478 6bb65e3a Guido Trotter
    os.chmod(files[3], stat.S_IREAD | stat.S_IEXEC)
479 6bb65e3a Guido Trotter
480 6bb65e3a Guido Trotter
    results = RunParts(self.rundir, reset_env=True)
481 6bb65e3a Guido Trotter
482 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[0]
483 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[0]))
484 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
485 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.exit_code, 1)
486 6bb65e3a Guido Trotter
    self.failUnless(runresult.failed)
487 6bb65e3a Guido Trotter
488 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[1]
489 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[1]))
490 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_SKIP)
491 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult, None)
492 6bb65e3a Guido Trotter
493 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[2]
494 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[2]))
495 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_ERR)
496 6bb65e3a Guido Trotter
    self.failUnless(runresult)
497 6bb65e3a Guido Trotter
498 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[3]
499 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[3]))
500 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
501 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.output, "ciao")
502 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.exit_code, 0)
503 6bb65e3a Guido Trotter
    self.failUnless(not runresult.failed)
504 6bb65e3a Guido Trotter
505 a8083063 Iustin Pop
506 c1dd99d4 Michael Hanselmann
class TestStartDaemon(testutils.GanetiTestCase):
507 c1dd99d4 Michael Hanselmann
  def setUp(self):
508 c1dd99d4 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp(prefix="ganeti-test")
509 c1dd99d4 Michael Hanselmann
    self.tmpfile = os.path.join(self.tmpdir, "test")
510 c1dd99d4 Michael Hanselmann
511 c1dd99d4 Michael Hanselmann
  def tearDown(self):
512 c1dd99d4 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
513 c1dd99d4 Michael Hanselmann
514 c1dd99d4 Michael Hanselmann
  def testShell(self):
515 c1dd99d4 Michael Hanselmann
    utils.StartDaemon("echo Hello World > %s" % self.tmpfile)
516 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "Hello World")
517 c1dd99d4 Michael Hanselmann
518 c1dd99d4 Michael Hanselmann
  def testShellOutput(self):
519 c1dd99d4 Michael Hanselmann
    utils.StartDaemon("echo Hello World", output=self.tmpfile)
520 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "Hello World")
521 c1dd99d4 Michael Hanselmann
522 c1dd99d4 Michael Hanselmann
  def testNoShellNoOutput(self):
523 c1dd99d4 Michael Hanselmann
    utils.StartDaemon(["pwd"])
524 c1dd99d4 Michael Hanselmann
525 c1dd99d4 Michael Hanselmann
  def testNoShellNoOutputTouch(self):
526 c1dd99d4 Michael Hanselmann
    testfile = os.path.join(self.tmpdir, "check")
527 c1dd99d4 Michael Hanselmann
    self.failIf(os.path.exists(testfile))
528 c1dd99d4 Michael Hanselmann
    utils.StartDaemon(["touch", testfile])
529 c1dd99d4 Michael Hanselmann
    self._wait(testfile, 60.0, "")
530 c1dd99d4 Michael Hanselmann
531 c1dd99d4 Michael Hanselmann
  def testNoShellOutput(self):
532 c1dd99d4 Michael Hanselmann
    utils.StartDaemon(["pwd"], output=self.tmpfile)
533 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "/")
534 c1dd99d4 Michael Hanselmann
535 c1dd99d4 Michael Hanselmann
  def testNoShellOutputCwd(self):
536 c1dd99d4 Michael Hanselmann
    utils.StartDaemon(["pwd"], output=self.tmpfile, cwd=os.getcwd())
537 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, os.getcwd())
538 c1dd99d4 Michael Hanselmann
539 c1dd99d4 Michael Hanselmann
  def testShellEnv(self):
540 c1dd99d4 Michael Hanselmann
    utils.StartDaemon("echo \"$GNT_TEST_VAR\"", output=self.tmpfile,
541 c1dd99d4 Michael Hanselmann
                      env={ "GNT_TEST_VAR": "Hello World", })
542 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "Hello World")
543 c1dd99d4 Michael Hanselmann
544 c1dd99d4 Michael Hanselmann
  def testNoShellEnv(self):
545 c1dd99d4 Michael Hanselmann
    utils.StartDaemon(["printenv", "GNT_TEST_VAR"], output=self.tmpfile,
546 c1dd99d4 Michael Hanselmann
                      env={ "GNT_TEST_VAR": "Hello World", })
547 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, "Hello World")
548 c1dd99d4 Michael Hanselmann
549 c1dd99d4 Michael Hanselmann
  def testOutputFd(self):
550 c1dd99d4 Michael Hanselmann
    fd = os.open(self.tmpfile, os.O_WRONLY | os.O_CREAT)
551 c1dd99d4 Michael Hanselmann
    try:
552 c1dd99d4 Michael Hanselmann
      utils.StartDaemon(["pwd"], output_fd=fd, cwd=os.getcwd())
553 c1dd99d4 Michael Hanselmann
    finally:
554 c1dd99d4 Michael Hanselmann
      os.close(fd)
555 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, os.getcwd())
556 c1dd99d4 Michael Hanselmann
557 c1dd99d4 Michael Hanselmann
  def testPid(self):
558 c1dd99d4 Michael Hanselmann
    pid = utils.StartDaemon("echo $$ > %s" % self.tmpfile)
559 c1dd99d4 Michael Hanselmann
    self._wait(self.tmpfile, 60.0, str(pid))
560 c1dd99d4 Michael Hanselmann
561 c1dd99d4 Michael Hanselmann
  def testPidFile(self):
562 c1dd99d4 Michael Hanselmann
    pidfile = os.path.join(self.tmpdir, "pid")
563 c1dd99d4 Michael Hanselmann
    checkfile = os.path.join(self.tmpdir, "abort")
564 c1dd99d4 Michael Hanselmann
565 c1dd99d4 Michael Hanselmann
    pid = utils.StartDaemon("while sleep 5; do :; done", pidfile=pidfile,
566 c1dd99d4 Michael Hanselmann
                            output=self.tmpfile)
567 c1dd99d4 Michael Hanselmann
    try:
568 c1dd99d4 Michael Hanselmann
      fd = os.open(pidfile, os.O_RDONLY)
569 c1dd99d4 Michael Hanselmann
      try:
570 c1dd99d4 Michael Hanselmann
        # Check file is locked
571 c1dd99d4 Michael Hanselmann
        self.assertRaises(errors.LockError, utils.LockFile, fd)
572 c1dd99d4 Michael Hanselmann
573 c1dd99d4 Michael Hanselmann
        pidtext = os.read(fd, 100)
574 c1dd99d4 Michael Hanselmann
      finally:
575 c1dd99d4 Michael Hanselmann
        os.close(fd)
576 c1dd99d4 Michael Hanselmann
577 c1dd99d4 Michael Hanselmann
      self.assertEqual(int(pidtext.strip()), pid)
578 c1dd99d4 Michael Hanselmann
579 c1dd99d4 Michael Hanselmann
      self.assert_(utils.IsProcessAlive(pid))
580 c1dd99d4 Michael Hanselmann
    finally:
581 c1dd99d4 Michael Hanselmann
      # No matter what happens, kill daemon
582 c1dd99d4 Michael Hanselmann
      utils.KillProcess(pid, timeout=5.0, waitpid=False)
583 c1dd99d4 Michael Hanselmann
      self.failIf(utils.IsProcessAlive(pid))
584 c1dd99d4 Michael Hanselmann
585 c1dd99d4 Michael Hanselmann
    self.assertEqual(utils.ReadFile(self.tmpfile), "")
586 c1dd99d4 Michael Hanselmann
587 c1dd99d4 Michael Hanselmann
  def _wait(self, path, timeout, expected):
588 c1dd99d4 Michael Hanselmann
    # Due to the asynchronous nature of daemon processes, polling is necessary.
589 c1dd99d4 Michael Hanselmann
    # A timeout makes sure the test doesn't hang forever.
590 c1dd99d4 Michael Hanselmann
    def _CheckFile():
591 c1dd99d4 Michael Hanselmann
      if not (os.path.isfile(path) and
592 c1dd99d4 Michael Hanselmann
              utils.ReadFile(path).strip() == expected):
593 c1dd99d4 Michael Hanselmann
        raise utils.RetryAgain()
594 c1dd99d4 Michael Hanselmann
595 c1dd99d4 Michael Hanselmann
    try:
596 c1dd99d4 Michael Hanselmann
      utils.Retry(_CheckFile, (0.01, 1.5, 1.0), timeout)
597 c1dd99d4 Michael Hanselmann
    except utils.RetryTimeout:
598 c1dd99d4 Michael Hanselmann
      self.fail("Apparently the daemon didn't run in %s seconds and/or"
599 c1dd99d4 Michael Hanselmann
                " didn't write the correct output" % timeout)
600 c1dd99d4 Michael Hanselmann
601 c1dd99d4 Michael Hanselmann
  def testError(self):
602 c1dd99d4 Michael Hanselmann
    self.assertRaises(errors.OpExecError, utils.StartDaemon,
603 c1dd99d4 Michael Hanselmann
                      ["./does-NOT-EXIST/here/0123456789"])
604 c1dd99d4 Michael Hanselmann
    self.assertRaises(errors.OpExecError, utils.StartDaemon,
605 c1dd99d4 Michael Hanselmann
                      ["./does-NOT-EXIST/here/0123456789"],
606 c1dd99d4 Michael Hanselmann
                      output=os.path.join(self.tmpdir, "DIR/NOT/EXIST"))
607 c1dd99d4 Michael Hanselmann
    self.assertRaises(errors.OpExecError, utils.StartDaemon,
608 c1dd99d4 Michael Hanselmann
                      ["./does-NOT-EXIST/here/0123456789"],
609 c1dd99d4 Michael Hanselmann
                      cwd=os.path.join(self.tmpdir, "DIR/NOT/EXIST"))
610 c1dd99d4 Michael Hanselmann
    self.assertRaises(errors.OpExecError, utils.StartDaemon,
611 c1dd99d4 Michael Hanselmann
                      ["./does-NOT-EXIST/here/0123456789"],
612 c1dd99d4 Michael Hanselmann
                      output=os.path.join(self.tmpdir, "DIR/NOT/EXIST"))
613 c1dd99d4 Michael Hanselmann
614 c1dd99d4 Michael Hanselmann
    fd = os.open(self.tmpfile, os.O_WRONLY | os.O_CREAT)
615 c1dd99d4 Michael Hanselmann
    try:
616 c1dd99d4 Michael Hanselmann
      self.assertRaises(errors.ProgrammerError, utils.StartDaemon,
617 c1dd99d4 Michael Hanselmann
                        ["./does-NOT-EXIST/here/0123456789"],
618 c1dd99d4 Michael Hanselmann
                        output=self.tmpfile, output_fd=fd)
619 c1dd99d4 Michael Hanselmann
    finally:
620 c1dd99d4 Michael Hanselmann
      os.close(fd)
621 c1dd99d4 Michael Hanselmann
622 c1dd99d4 Michael Hanselmann
623 73027ed2 Michael Hanselmann
class TestSetCloseOnExecFlag(unittest.TestCase):
624 73027ed2 Michael Hanselmann
  """Tests for SetCloseOnExecFlag"""
625 73027ed2 Michael Hanselmann
626 73027ed2 Michael Hanselmann
  def setUp(self):
627 73027ed2 Michael Hanselmann
    self.tmpfile = tempfile.TemporaryFile()
628 73027ed2 Michael Hanselmann
629 73027ed2 Michael Hanselmann
  def testEnable(self):
630 73027ed2 Michael Hanselmann
    utils.SetCloseOnExecFlag(self.tmpfile.fileno(), True)
631 73027ed2 Michael Hanselmann
    self.failUnless(fcntl.fcntl(self.tmpfile.fileno(), fcntl.F_GETFD) &
632 73027ed2 Michael Hanselmann
                    fcntl.FD_CLOEXEC)
633 73027ed2 Michael Hanselmann
634 73027ed2 Michael Hanselmann
  def testDisable(self):
635 73027ed2 Michael Hanselmann
    utils.SetCloseOnExecFlag(self.tmpfile.fileno(), False)
636 73027ed2 Michael Hanselmann
    self.failIf(fcntl.fcntl(self.tmpfile.fileno(), fcntl.F_GETFD) &
637 73027ed2 Michael Hanselmann
                fcntl.FD_CLOEXEC)
638 73027ed2 Michael Hanselmann
639 73027ed2 Michael Hanselmann
640 287a1740 Michael Hanselmann
class TestSetNonblockFlag(unittest.TestCase):
641 287a1740 Michael Hanselmann
  def setUp(self):
642 287a1740 Michael Hanselmann
    self.tmpfile = tempfile.TemporaryFile()
643 287a1740 Michael Hanselmann
644 287a1740 Michael Hanselmann
  def testEnable(self):
645 287a1740 Michael Hanselmann
    utils.SetNonblockFlag(self.tmpfile.fileno(), True)
646 287a1740 Michael Hanselmann
    self.failUnless(fcntl.fcntl(self.tmpfile.fileno(), fcntl.F_GETFL) &
647 287a1740 Michael Hanselmann
                    os.O_NONBLOCK)
648 287a1740 Michael Hanselmann
649 287a1740 Michael Hanselmann
  def testDisable(self):
650 287a1740 Michael Hanselmann
    utils.SetNonblockFlag(self.tmpfile.fileno(), False)
651 287a1740 Michael Hanselmann
    self.failIf(fcntl.fcntl(self.tmpfile.fileno(), fcntl.F_GETFL) &
652 287a1740 Michael Hanselmann
                os.O_NONBLOCK)
653 287a1740 Michael Hanselmann
654 287a1740 Michael Hanselmann
655 a8083063 Iustin Pop
class TestRemoveFile(unittest.TestCase):
656 a8083063 Iustin Pop
  """Test case for the RemoveFile function"""
657 a8083063 Iustin Pop
658 a8083063 Iustin Pop
  def setUp(self):
659 a8083063 Iustin Pop
    """Create a temp dir and file for each case"""
660 a8083063 Iustin Pop
    self.tmpdir = tempfile.mkdtemp('', 'ganeti-unittest-')
661 a8083063 Iustin Pop
    fd, self.tmpfile = tempfile.mkstemp('', '', self.tmpdir)
662 a8083063 Iustin Pop
    os.close(fd)
663 a8083063 Iustin Pop
664 a8083063 Iustin Pop
  def tearDown(self):
665 a8083063 Iustin Pop
    if os.path.exists(self.tmpfile):
666 a8083063 Iustin Pop
      os.unlink(self.tmpfile)
667 a8083063 Iustin Pop
    os.rmdir(self.tmpdir)
668 a8083063 Iustin Pop
669 a8083063 Iustin Pop
  def testIgnoreDirs(self):
670 a8083063 Iustin Pop
    """Test that RemoveFile() ignores directories"""
671 a8083063 Iustin Pop
    self.assertEqual(None, RemoveFile(self.tmpdir))
672 a8083063 Iustin Pop
673 a8083063 Iustin Pop
  def testIgnoreNotExisting(self):
674 a8083063 Iustin Pop
    """Test that RemoveFile() ignores non-existing files"""
675 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
676 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
677 a8083063 Iustin Pop
678 a8083063 Iustin Pop
  def testRemoveFile(self):
679 a8083063 Iustin Pop
    """Test that RemoveFile does remove a file"""
680 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
681 a8083063 Iustin Pop
    if os.path.exists(self.tmpfile):
682 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % self.tmpfile)
683 a8083063 Iustin Pop
684 a8083063 Iustin Pop
  def testRemoveSymlink(self):
685 a8083063 Iustin Pop
    """Test that RemoveFile does remove symlinks"""
686 a8083063 Iustin Pop
    symlink = self.tmpdir + "/symlink"
687 a8083063 Iustin Pop
    os.symlink("no-such-file", symlink)
688 a8083063 Iustin Pop
    RemoveFile(symlink)
689 a8083063 Iustin Pop
    if os.path.exists(symlink):
690 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % symlink)
691 a8083063 Iustin Pop
    os.symlink(self.tmpfile, symlink)
692 a8083063 Iustin Pop
    RemoveFile(symlink)
693 a8083063 Iustin Pop
    if os.path.exists(symlink):
694 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % symlink)
695 a8083063 Iustin Pop
696 a8083063 Iustin Pop
697 6e797216 Michael Hanselmann
class TestRename(unittest.TestCase):
698 6e797216 Michael Hanselmann
  """Test case for RenameFile"""
699 6e797216 Michael Hanselmann
700 6e797216 Michael Hanselmann
  def setUp(self):
701 6e797216 Michael Hanselmann
    """Create a temporary directory"""
702 6e797216 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
703 6e797216 Michael Hanselmann
    self.tmpfile = os.path.join(self.tmpdir, "test1")
704 6e797216 Michael Hanselmann
705 6e797216 Michael Hanselmann
    # Touch the file
706 6e797216 Michael Hanselmann
    open(self.tmpfile, "w").close()
707 6e797216 Michael Hanselmann
708 6e797216 Michael Hanselmann
  def tearDown(self):
709 6e797216 Michael Hanselmann
    """Remove temporary directory"""
710 6e797216 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
711 6e797216 Michael Hanselmann
712 6e797216 Michael Hanselmann
  def testSimpleRename1(self):
713 6e797216 Michael Hanselmann
    """Simple rename 1"""
714 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"))
715 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "xyz")))
716 6e797216 Michael Hanselmann
717 6e797216 Michael Hanselmann
  def testSimpleRename2(self):
718 6e797216 Michael Hanselmann
    """Simple rename 2"""
719 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"),
720 6e797216 Michael Hanselmann
                     mkdir=True)
721 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "xyz")))
722 6e797216 Michael Hanselmann
723 6e797216 Michael Hanselmann
  def testRenameMkdir(self):
724 6e797216 Michael Hanselmann
    """Rename with mkdir"""
725 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "test/xyz"),
726 6e797216 Michael Hanselmann
                     mkdir=True)
727 a426508d Michael Hanselmann
    self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test")))
728 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "test/xyz")))
729 a426508d Michael Hanselmann
730 a426508d Michael Hanselmann
    utils.RenameFile(os.path.join(self.tmpdir, "test/xyz"),
731 a426508d Michael Hanselmann
                     os.path.join(self.tmpdir, "test/foo/bar/baz"),
732 a426508d Michael Hanselmann
                     mkdir=True)
733 a426508d Michael Hanselmann
    self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test")))
734 a426508d Michael Hanselmann
    self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test/foo/bar")))
735 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "test/foo/bar/baz")))
736 6e797216 Michael Hanselmann
737 6e797216 Michael Hanselmann
738 a8083063 Iustin Pop
class TestMatchNameComponent(unittest.TestCase):
739 a8083063 Iustin Pop
  """Test case for the MatchNameComponent function"""
740 a8083063 Iustin Pop
741 a8083063 Iustin Pop
  def testEmptyList(self):
742 a8083063 Iustin Pop
    """Test that there is no match against an empty list"""
743 a8083063 Iustin Pop
744 a8083063 Iustin Pop
    self.failUnlessEqual(MatchNameComponent("", []), None)
745 a8083063 Iustin Pop
    self.failUnlessEqual(MatchNameComponent("test", []), None)
746 a8083063 Iustin Pop
747 a8083063 Iustin Pop
  def testSingleMatch(self):
748 a8083063 Iustin Pop
    """Test that a single match is performed correctly"""
749 a8083063 Iustin Pop
    mlist = ["test1.example.com", "test2.example.com", "test3.example.com"]
750 a8083063 Iustin Pop
    for key in "test2", "test2.example", "test2.example.com":
751 a8083063 Iustin Pop
      self.failUnlessEqual(MatchNameComponent(key, mlist), mlist[1])
752 a8083063 Iustin Pop
753 a8083063 Iustin Pop
  def testMultipleMatches(self):
754 a8083063 Iustin Pop
    """Test that a multiple match is returned as None"""
755 a8083063 Iustin Pop
    mlist = ["test1.example.com", "test1.example.org", "test1.example.net"]
756 a8083063 Iustin Pop
    for key in "test1", "test1.example":
757 a8083063 Iustin Pop
      self.failUnlessEqual(MatchNameComponent(key, mlist), None)
758 a8083063 Iustin Pop
759 3a541d90 Iustin Pop
  def testFullMatch(self):
760 3a541d90 Iustin Pop
    """Test that a full match is returned correctly"""
761 3a541d90 Iustin Pop
    key1 = "test1"
762 3a541d90 Iustin Pop
    key2 = "test1.example"
763 3a541d90 Iustin Pop
    mlist = [key2, key2 + ".com"]
764 3a541d90 Iustin Pop
    self.failUnlessEqual(MatchNameComponent(key1, mlist), None)
765 3a541d90 Iustin Pop
    self.failUnlessEqual(MatchNameComponent(key2, mlist), key2)
766 3a541d90 Iustin Pop
767 256eb94b Guido Trotter
  def testCaseInsensitivePartialMatch(self):
768 256eb94b Guido Trotter
    """Test for the case_insensitive keyword"""
769 256eb94b Guido Trotter
    mlist = ["test1.example.com", "test2.example.net"]
770 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("test2", mlist, case_sensitive=False),
771 256eb94b Guido Trotter
                     "test2.example.net")
772 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Test2", mlist, case_sensitive=False),
773 256eb94b Guido Trotter
                     "test2.example.net")
774 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("teSt2", mlist, case_sensitive=False),
775 256eb94b Guido Trotter
                     "test2.example.net")
776 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("TeSt2", mlist, case_sensitive=False),
777 256eb94b Guido Trotter
                     "test2.example.net")
778 256eb94b Guido Trotter
779 256eb94b Guido Trotter
780 256eb94b Guido Trotter
  def testCaseInsensitiveFullMatch(self):
781 256eb94b Guido Trotter
    mlist = ["ts1.ex", "ts1.ex.org", "ts2.ex", "Ts2.ex"]
782 256eb94b Guido Trotter
    # Between the two ts1 a full string match non-case insensitive should work
783 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Ts1", mlist, case_sensitive=False),
784 256eb94b Guido Trotter
                     None)
785 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Ts1.ex", mlist, case_sensitive=False),
786 256eb94b Guido Trotter
                     "ts1.ex")
787 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("ts1.ex", mlist, case_sensitive=False),
788 256eb94b Guido Trotter
                     "ts1.ex")
789 256eb94b Guido Trotter
    # Between the two ts2 only case differs, so only case-match works
790 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("ts2.ex", mlist, case_sensitive=False),
791 256eb94b Guido Trotter
                     "ts2.ex")
792 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Ts2.ex", mlist, case_sensitive=False),
793 256eb94b Guido Trotter
                     "Ts2.ex")
794 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("TS2.ex", mlist, case_sensitive=False),
795 256eb94b Guido Trotter
                     None)
796 256eb94b Guido Trotter
797 a8083063 Iustin Pop
798 b774bb10 Michael Hanselmann
class TestReadFile(testutils.GanetiTestCase):
799 b774bb10 Michael Hanselmann
800 b774bb10 Michael Hanselmann
  def testReadAll(self):
801 b774bb10 Michael Hanselmann
    data = utils.ReadFile(self._TestDataFilename("cert1.pem"))
802 b774bb10 Michael Hanselmann
    self.assertEqual(len(data), 814)
803 b774bb10 Michael Hanselmann
804 716a32cb Guido Trotter
    h = compat.md5_hash()
805 b774bb10 Michael Hanselmann
    h.update(data)
806 b774bb10 Michael Hanselmann
    self.assertEqual(h.hexdigest(), "a491efb3efe56a0535f924d5f8680fd4")
807 b774bb10 Michael Hanselmann
808 b774bb10 Michael Hanselmann
  def testReadSize(self):
809 b774bb10 Michael Hanselmann
    data = utils.ReadFile(self._TestDataFilename("cert1.pem"),
810 b774bb10 Michael Hanselmann
                          size=100)
811 b774bb10 Michael Hanselmann
    self.assertEqual(len(data), 100)
812 b774bb10 Michael Hanselmann
813 716a32cb Guido Trotter
    h = compat.md5_hash()
814 b774bb10 Michael Hanselmann
    h.update(data)
815 b774bb10 Michael Hanselmann
    self.assertEqual(h.hexdigest(), "893772354e4e690b9efd073eed433ce7")
816 b774bb10 Michael Hanselmann
817 b774bb10 Michael Hanselmann
  def testError(self):
818 b774bb10 Michael Hanselmann
    self.assertRaises(EnvironmentError, utils.ReadFile,
819 582ed043 Guido Trotter
                      "/dev/null/does-not-exist")
820 b774bb10 Michael Hanselmann
821 b774bb10 Michael Hanselmann
822 e587b46a Guido Trotter
class TestReadOneLineFile(testutils.GanetiTestCase):
823 b774bb10 Michael Hanselmann
824 e587b46a Guido Trotter
  def setUp(self):
825 e587b46a Guido Trotter
    testutils.GanetiTestCase.setUp(self)
826 b774bb10 Michael Hanselmann
827 e587b46a Guido Trotter
  def testDefault(self):
828 e587b46a Guido Trotter
    data = ReadOneLineFile(self._TestDataFilename("cert1.pem"))
829 e587b46a Guido Trotter
    self.assertEqual(len(data), 27)
830 e587b46a Guido Trotter
    self.assertEqual(data, "-----BEGIN CERTIFICATE-----")
831 b774bb10 Michael Hanselmann
832 e587b46a Guido Trotter
  def testNotStrict(self):
833 e587b46a Guido Trotter
    data = ReadOneLineFile(self._TestDataFilename("cert1.pem"), strict=False)
834 e587b46a Guido Trotter
    self.assertEqual(len(data), 27)
835 e587b46a Guido Trotter
    self.assertEqual(data, "-----BEGIN CERTIFICATE-----")
836 b774bb10 Michael Hanselmann
837 e587b46a Guido Trotter
  def testStrictFailure(self):
838 e587b46a Guido Trotter
    self.assertRaises(errors.GenericError, ReadOneLineFile,
839 e587b46a Guido Trotter
                      self._TestDataFilename("cert1.pem"), strict=True)
840 b774bb10 Michael Hanselmann
841 e587b46a Guido Trotter
  def testLongLine(self):
842 e587b46a Guido Trotter
    dummydata = (1024 * "Hello World! ")
843 e587b46a Guido Trotter
    myfile = self._CreateTempFile()
844 e587b46a Guido Trotter
    utils.WriteFile(myfile, data=dummydata)
845 e587b46a Guido Trotter
    datastrict = ReadOneLineFile(myfile, strict=True)
846 e587b46a Guido Trotter
    datalax = ReadOneLineFile(myfile, strict=False)
847 e587b46a Guido Trotter
    self.assertEqual(dummydata, datastrict)
848 e587b46a Guido Trotter
    self.assertEqual(dummydata, datalax)
849 e587b46a Guido Trotter
850 e587b46a Guido Trotter
  def testNewline(self):
851 e587b46a Guido Trotter
    myfile = self._CreateTempFile()
852 e587b46a Guido Trotter
    myline = "myline"
853 e587b46a Guido Trotter
    for nl in ["", "\n", "\r\n"]:
854 e587b46a Guido Trotter
      dummydata = "%s%s" % (myline, nl)
855 e587b46a Guido Trotter
      utils.WriteFile(myfile, data=dummydata)
856 e587b46a Guido Trotter
      datalax = ReadOneLineFile(myfile, strict=False)
857 e587b46a Guido Trotter
      self.assertEqual(myline, datalax)
858 e587b46a Guido Trotter
      datastrict = ReadOneLineFile(myfile, strict=True)
859 e587b46a Guido Trotter
      self.assertEqual(myline, datastrict)
860 e587b46a Guido Trotter
861 e587b46a Guido Trotter
  def testWhitespaceAndMultipleLines(self):
862 e587b46a Guido Trotter
    myfile = self._CreateTempFile()
863 e587b46a Guido Trotter
    for nl in ["", "\n", "\r\n"]:
864 e587b46a Guido Trotter
      for ws in [" ", "\t", "\t\t  \t", "\t "]:
865 e587b46a Guido Trotter
        dummydata = (1024 * ("Foo bar baz %s%s" % (ws, nl)))
866 e587b46a Guido Trotter
        utils.WriteFile(myfile, data=dummydata)
867 e587b46a Guido Trotter
        datalax = ReadOneLineFile(myfile, strict=False)
868 e587b46a Guido Trotter
        if nl:
869 e587b46a Guido Trotter
          self.assert_(set("\r\n") & set(dummydata))
870 e587b46a Guido Trotter
          self.assertRaises(errors.GenericError, ReadOneLineFile,
871 e587b46a Guido Trotter
                            myfile, strict=True)
872 e587b46a Guido Trotter
          explen = len("Foo bar baz ") + len(ws)
873 e587b46a Guido Trotter
          self.assertEqual(len(datalax), explen)
874 e587b46a Guido Trotter
          self.assertEqual(datalax, dummydata[:explen])
875 e587b46a Guido Trotter
          self.assertFalse(set("\r\n") & set(datalax))
876 e587b46a Guido Trotter
        else:
877 e587b46a Guido Trotter
          datastrict = ReadOneLineFile(myfile, strict=True)
878 e587b46a Guido Trotter
          self.assertEqual(dummydata, datastrict)
879 e587b46a Guido Trotter
          self.assertEqual(dummydata, datalax)
880 e587b46a Guido Trotter
881 e587b46a Guido Trotter
  def testEmptylines(self):
882 e587b46a Guido Trotter
    myfile = self._CreateTempFile()
883 e587b46a Guido Trotter
    myline = "myline"
884 e587b46a Guido Trotter
    for nl in ["\n", "\r\n"]:
885 e587b46a Guido Trotter
      for ol in ["", "otherline"]:
886 e587b46a Guido Trotter
        dummydata = "%s%s%s%s%s%s" % (nl, nl, myline, nl, ol, nl)
887 e587b46a Guido Trotter
        utils.WriteFile(myfile, data=dummydata)
888 e587b46a Guido Trotter
        self.assert_(set("\r\n") & set(dummydata))
889 e587b46a Guido Trotter
        datalax = ReadOneLineFile(myfile, strict=False)
890 e587b46a Guido Trotter
        self.assertEqual(myline, datalax)
891 e587b46a Guido Trotter
        if ol:
892 e587b46a Guido Trotter
          self.assertRaises(errors.GenericError, ReadOneLineFile,
893 e587b46a Guido Trotter
                            myfile, strict=True)
894 e587b46a Guido Trotter
        else:
895 e587b46a Guido Trotter
          datastrict = ReadOneLineFile(myfile, strict=True)
896 e587b46a Guido Trotter
          self.assertEqual(myline, datastrict)
897 b774bb10 Michael Hanselmann
898 b774bb10 Michael Hanselmann
899 1d466a4f Michael Hanselmann
class TestTimestampForFilename(unittest.TestCase):
900 1d466a4f Michael Hanselmann
  def test(self):
901 1d466a4f Michael Hanselmann
    self.assert_("." not in utils.TimestampForFilename())
902 1d466a4f Michael Hanselmann
    self.assert_(":" not in utils.TimestampForFilename())
903 1d466a4f Michael Hanselmann
904 1d466a4f Michael Hanselmann
905 1d466a4f Michael Hanselmann
class TestCreateBackup(testutils.GanetiTestCase):
906 1d466a4f Michael Hanselmann
  def setUp(self):
907 1d466a4f Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
908 1d466a4f Michael Hanselmann
909 1d466a4f Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
910 1d466a4f Michael Hanselmann
911 1d466a4f Michael Hanselmann
  def tearDown(self):
912 1d466a4f Michael Hanselmann
    testutils.GanetiTestCase.tearDown(self)
913 1d466a4f Michael Hanselmann
914 1d466a4f Michael Hanselmann
    shutil.rmtree(self.tmpdir)
915 1d466a4f Michael Hanselmann
916 1d466a4f Michael Hanselmann
  def testEmpty(self):
917 a744b676 Manuel Franceschini
    filename = PathJoin(self.tmpdir, "config.data")
918 1d466a4f Michael Hanselmann
    utils.WriteFile(filename, data="")
919 1d466a4f Michael Hanselmann
    bname = utils.CreateBackup(filename)
920 1d466a4f Michael Hanselmann
    self.assertFileContent(bname, "")
921 1d466a4f Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 2)
922 1d466a4f Michael Hanselmann
    utils.CreateBackup(filename)
923 1d466a4f Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 3)
924 1d466a4f Michael Hanselmann
    utils.CreateBackup(filename)
925 1d466a4f Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 4)
926 1d466a4f Michael Hanselmann
927 a744b676 Manuel Franceschini
    fifoname = PathJoin(self.tmpdir, "fifo")
928 1d466a4f Michael Hanselmann
    os.mkfifo(fifoname)
929 1d466a4f Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, utils.CreateBackup, fifoname)
930 1d466a4f Michael Hanselmann
931 1d466a4f Michael Hanselmann
  def testContent(self):
932 1d466a4f Michael Hanselmann
    bkpcount = 0
933 1d466a4f Michael Hanselmann
    for data in ["", "X", "Hello World!\n" * 100, "Binary data\0\x01\x02\n"]:
934 1d466a4f Michael Hanselmann
      for rep in [1, 2, 10, 127]:
935 1d466a4f Michael Hanselmann
        testdata = data * rep
936 1d466a4f Michael Hanselmann
937 a744b676 Manuel Franceschini
        filename = PathJoin(self.tmpdir, "test.data_")
938 1d466a4f Michael Hanselmann
        utils.WriteFile(filename, data=testdata)
939 1d466a4f Michael Hanselmann
        self.assertFileContent(filename, testdata)
940 1d466a4f Michael Hanselmann
941 1d466a4f Michael Hanselmann
        for _ in range(3):
942 1d466a4f Michael Hanselmann
          bname = utils.CreateBackup(filename)
943 1d466a4f Michael Hanselmann
          bkpcount += 1
944 1d466a4f Michael Hanselmann
          self.assertFileContent(bname, testdata)
945 1d466a4f Michael Hanselmann
          self.assertEqual(len(glob.glob("%s*" % filename)), 1 + bkpcount)
946 1d466a4f Michael Hanselmann
947 1d466a4f Michael Hanselmann
948 a8083063 Iustin Pop
class TestFormatUnit(unittest.TestCase):
949 a8083063 Iustin Pop
  """Test case for the FormatUnit function"""
950 a8083063 Iustin Pop
951 a8083063 Iustin Pop
  def testMiB(self):
952 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1, 'h'), '1M')
953 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(100, 'h'), '100M')
954 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1023, 'h'), '1023M')
955 9fbfbb7b Iustin Pop
956 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1, 'm'), '1')
957 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(100, 'm'), '100')
958 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1023, 'm'), '1023')
959 9fbfbb7b Iustin Pop
960 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'm'), '1024')
961 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'm'), '1536')
962 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'm'), '17133')
963 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'm'), '1048575')
964 a8083063 Iustin Pop
965 a8083063 Iustin Pop
  def testGiB(self):
966 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'h'), '1.0G')
967 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'h'), '1.5G')
968 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'h'), '16.7G')
969 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'h'), '1024.0G')
970 9fbfbb7b Iustin Pop
971 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'g'), '1.0')
972 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'g'), '1.5')
973 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'g'), '16.7')
974 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'g'), '1024.0')
975 9fbfbb7b Iustin Pop
976 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 'g'), '1024.0')
977 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 'g'), '5120.0')
978 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 'g'), '29829.0')
979 a8083063 Iustin Pop
980 a8083063 Iustin Pop
  def testTiB(self):
981 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 'h'), '1.0T')
982 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 'h'), '5.0T')
983 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 'h'), '29.1T')
984 a8083063 Iustin Pop
985 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 't'), '1.0')
986 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 't'), '5.0')
987 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 't'), '29.1')
988 a8083063 Iustin Pop
989 a744b676 Manuel Franceschini
990 a8083063 Iustin Pop
class TestParseUnit(unittest.TestCase):
991 a8083063 Iustin Pop
  """Test case for the ParseUnit function"""
992 a8083063 Iustin Pop
993 a8083063 Iustin Pop
  SCALES = (('', 1),
994 a8083063 Iustin Pop
            ('M', 1), ('G', 1024), ('T', 1024 * 1024),
995 a8083063 Iustin Pop
            ('MB', 1), ('GB', 1024), ('TB', 1024 * 1024),
996 a8083063 Iustin Pop
            ('MiB', 1), ('GiB', 1024), ('TiB', 1024 * 1024))
997 a8083063 Iustin Pop
998 a8083063 Iustin Pop
  def testRounding(self):
999 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0'), 0)
1000 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1'), 4)
1001 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2'), 4)
1002 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('3'), 4)
1003 a8083063 Iustin Pop
1004 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('124'), 124)
1005 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('125'), 128)
1006 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('126'), 128)
1007 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('127'), 128)
1008 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('128'), 128)
1009 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('129'), 132)
1010 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('130'), 132)
1011 a8083063 Iustin Pop
1012 a8083063 Iustin Pop
  def testFloating(self):
1013 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0'), 0)
1014 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0.5'), 4)
1015 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.75'), 4)
1016 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.99'), 4)
1017 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2.00'), 4)
1018 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2.01'), 4)
1019 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('3.99'), 4)
1020 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('4.00'), 4)
1021 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('4.01'), 8)
1022 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.5G'), 1536)
1023 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.8G'), 1844)
1024 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('8.28T'), 8682212)
1025 a8083063 Iustin Pop
1026 a8083063 Iustin Pop
  def testSuffixes(self):
1027 a8083063 Iustin Pop
    for sep in ('', ' ', '   ', "\t", "\t "):
1028 a8083063 Iustin Pop
      for suffix, scale in TestParseUnit.SCALES:
1029 a8083063 Iustin Pop
        for func in (lambda x: x, str.lower, str.upper):
1030 667479d5 Michael Hanselmann
          self.assertEqual(ParseUnit('1024' + sep + func(suffix)),
1031 667479d5 Michael Hanselmann
                           1024 * scale)
1032 a8083063 Iustin Pop
1033 a8083063 Iustin Pop
  def testInvalidInput(self):
1034 a8083063 Iustin Pop
    for sep in ('-', '_', ',', 'a'):
1035 a8083063 Iustin Pop
      for suffix, _ in TestParseUnit.SCALES:
1036 a744b676 Manuel Franceschini
        self.assertRaises(errors.UnitParseError, ParseUnit, '1' + sep + suffix)
1037 a8083063 Iustin Pop
1038 a8083063 Iustin Pop
    for suffix, _ in TestParseUnit.SCALES:
1039 a744b676 Manuel Franceschini
      self.assertRaises(errors.UnitParseError, ParseUnit, '1,3' + suffix)
1040 a8083063 Iustin Pop
1041 a8083063 Iustin Pop
1042 31155d60 Balazs Lecz
class TestParseCpuMask(unittest.TestCase):
1043 31155d60 Balazs Lecz
  """Test case for the ParseCpuMask function."""
1044 31155d60 Balazs Lecz
1045 31155d60 Balazs Lecz
  def testWellFormed(self):
1046 31155d60 Balazs Lecz
    self.assertEqual(utils.ParseCpuMask(""), [])
1047 31155d60 Balazs Lecz
    self.assertEqual(utils.ParseCpuMask("1"), [1])
1048 31155d60 Balazs Lecz
    self.assertEqual(utils.ParseCpuMask("0-2,4,5-5"), [0,1,2,4,5])
1049 31155d60 Balazs Lecz
1050 31155d60 Balazs Lecz
  def testInvalidInput(self):
1051 31155d60 Balazs Lecz
    self.assertRaises(errors.ParseError,
1052 31155d60 Balazs Lecz
                      utils.ParseCpuMask,
1053 31155d60 Balazs Lecz
                      "garbage")
1054 31155d60 Balazs Lecz
    self.assertRaises(errors.ParseError,
1055 31155d60 Balazs Lecz
                      utils.ParseCpuMask,
1056 31155d60 Balazs Lecz
                      "0,")
1057 31155d60 Balazs Lecz
    self.assertRaises(errors.ParseError,
1058 31155d60 Balazs Lecz
                      utils.ParseCpuMask,
1059 31155d60 Balazs Lecz
                      "0-1-2")
1060 31155d60 Balazs Lecz
    self.assertRaises(errors.ParseError,
1061 31155d60 Balazs Lecz
                      utils.ParseCpuMask,
1062 31155d60 Balazs Lecz
                      "2-1")
1063 31155d60 Balazs Lecz
1064 c9c4f19e Michael Hanselmann
class TestSshKeys(testutils.GanetiTestCase):
1065 a8083063 Iustin Pop
  """Test case for the AddAuthorizedKey function"""
1066 a8083063 Iustin Pop
1067 a8083063 Iustin Pop
  KEY_A = 'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a'
1068 926feaf1 Manuel Franceschini
  KEY_B = ('command="/usr/bin/fooserver -t --verbose",from="198.51.100.4" '
1069 a8083063 Iustin Pop
           'ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b')
1070 a8083063 Iustin Pop
1071 ebe8ef17 Michael Hanselmann
  def setUp(self):
1072 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
1073 51596eb2 Iustin Pop
    self.tmpname = self._CreateTempFile()
1074 51596eb2 Iustin Pop
    handle = open(self.tmpname, 'w')
1075 a8083063 Iustin Pop
    try:
1076 51596eb2 Iustin Pop
      handle.write("%s\n" % TestSshKeys.KEY_A)
1077 51596eb2 Iustin Pop
      handle.write("%s\n" % TestSshKeys.KEY_B)
1078 51596eb2 Iustin Pop
    finally:
1079 51596eb2 Iustin Pop
      handle.close()
1080 a8083063 Iustin Pop
1081 a8083063 Iustin Pop
  def testAddingNewKey(self):
1082 a744b676 Manuel Franceschini
    utils.AddAuthorizedKey(self.tmpname,
1083 a744b676 Manuel Franceschini
                           'ssh-dss AAAAB3NzaC1kc3MAAACB root@test')
1084 a8083063 Iustin Pop
1085 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1086 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
1087 926feaf1 Manuel Franceschini
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
1088 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
1089 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1kc3MAAACB root@test\n")
1090 a8083063 Iustin Pop
1091 f89f17a8 Michael Hanselmann
  def testAddingAlmostButNotCompletelyTheSameKey(self):
1092 a744b676 Manuel Franceschini
    utils.AddAuthorizedKey(self.tmpname,
1093 ebe8ef17 Michael Hanselmann
        'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test')
1094 ebe8ef17 Michael Hanselmann
1095 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1096 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
1097 926feaf1 Manuel Franceschini
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
1098 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
1099 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test\n")
1100 a8083063 Iustin Pop
1101 a8083063 Iustin Pop
  def testAddingExistingKeyWithSomeMoreSpaces(self):
1102 a744b676 Manuel Franceschini
    utils.AddAuthorizedKey(self.tmpname,
1103 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
1104 a8083063 Iustin Pop
1105 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1106 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
1107 926feaf1 Manuel Franceschini
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
1108 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
1109 a8083063 Iustin Pop
1110 a8083063 Iustin Pop
  def testRemovingExistingKeyWithSomeMoreSpaces(self):
1111 a744b676 Manuel Franceschini
    utils.RemoveAuthorizedKey(self.tmpname,
1112 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
1113 a8083063 Iustin Pop
1114 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1115 926feaf1 Manuel Franceschini
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
1116 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
1117 a8083063 Iustin Pop
1118 a8083063 Iustin Pop
  def testRemovingNonExistingKey(self):
1119 a744b676 Manuel Franceschini
    utils.RemoveAuthorizedKey(self.tmpname,
1120 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3Nsdfj230xxjxJjsjwjsjdjU   root@test')
1121 a8083063 Iustin Pop
1122 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1123 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
1124 926feaf1 Manuel Franceschini
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
1125 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
1126 a8083063 Iustin Pop
1127 a8083063 Iustin Pop
1128 c9c4f19e Michael Hanselmann
class TestEtcHosts(testutils.GanetiTestCase):
1129 899d2a81 Michael Hanselmann
  """Test functions modifying /etc/hosts"""
1130 899d2a81 Michael Hanselmann
1131 ebe8ef17 Michael Hanselmann
  def setUp(self):
1132 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
1133 51596eb2 Iustin Pop
    self.tmpname = self._CreateTempFile()
1134 51596eb2 Iustin Pop
    handle = open(self.tmpname, 'w')
1135 899d2a81 Michael Hanselmann
    try:
1136 51596eb2 Iustin Pop
      handle.write('# This is a test file for /etc/hosts\n')
1137 51596eb2 Iustin Pop
      handle.write('127.0.0.1\tlocalhost\n')
1138 926feaf1 Manuel Franceschini
      handle.write('192.0.2.1 router gw\n')
1139 51596eb2 Iustin Pop
    finally:
1140 51596eb2 Iustin Pop
      handle.close()
1141 899d2a81 Michael Hanselmann
1142 9440aeab Michael Hanselmann
  def testSettingNewIp(self):
1143 926feaf1 Manuel Franceschini
    SetEtcHostsEntry(self.tmpname, '198.51.100.4', 'myhost.example.com',
1144 926feaf1 Manuel Franceschini
                     ['myhost'])
1145 899d2a81 Michael Hanselmann
1146 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1147 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1148 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
1149 926feaf1 Manuel Franceschini
      "192.0.2.1 router gw\n"
1150 926feaf1 Manuel Franceschini
      "198.51.100.4\tmyhost.example.com myhost\n")
1151 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1152 899d2a81 Michael Hanselmann
1153 9440aeab Michael Hanselmann
  def testSettingExistingIp(self):
1154 926feaf1 Manuel Franceschini
    SetEtcHostsEntry(self.tmpname, '192.0.2.1', 'myhost.example.com',
1155 ebe8ef17 Michael Hanselmann
                     ['myhost'])
1156 899d2a81 Michael Hanselmann
1157 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1158 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1159 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
1160 926feaf1 Manuel Franceschini
      "192.0.2.1\tmyhost.example.com myhost\n")
1161 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1162 899d2a81 Michael Hanselmann
1163 7fbb1f65 Michael Hanselmann
  def testSettingDuplicateName(self):
1164 926feaf1 Manuel Franceschini
    SetEtcHostsEntry(self.tmpname, '198.51.100.4', 'myhost', ['myhost'])
1165 7fbb1f65 Michael Hanselmann
1166 7fbb1f65 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1167 7fbb1f65 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1168 7fbb1f65 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
1169 926feaf1 Manuel Franceschini
      "192.0.2.1 router gw\n"
1170 926feaf1 Manuel Franceschini
      "198.51.100.4\tmyhost\n")
1171 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1172 7fbb1f65 Michael Hanselmann
1173 899d2a81 Michael Hanselmann
  def testRemovingExistingHost(self):
1174 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'router')
1175 899d2a81 Michael Hanselmann
1176 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1177 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1178 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
1179 926feaf1 Manuel Franceschini
      "192.0.2.1 gw\n")
1180 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1181 899d2a81 Michael Hanselmann
1182 899d2a81 Michael Hanselmann
  def testRemovingSingleExistingHost(self):
1183 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'localhost')
1184 899d2a81 Michael Hanselmann
1185 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1186 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1187 926feaf1 Manuel Franceschini
      "192.0.2.1 router gw\n")
1188 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1189 899d2a81 Michael Hanselmann
1190 899d2a81 Michael Hanselmann
  def testRemovingNonExistingHost(self):
1191 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'myhost')
1192 899d2a81 Michael Hanselmann
1193 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1194 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1195 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
1196 926feaf1 Manuel Franceschini
      "192.0.2.1 router gw\n")
1197 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1198 899d2a81 Michael Hanselmann
1199 9440aeab Michael Hanselmann
  def testRemovingAlias(self):
1200 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'gw')
1201 9440aeab Michael Hanselmann
1202 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
1203 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
1204 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
1205 926feaf1 Manuel Franceschini
      "192.0.2.1 router\n")
1206 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
1207 9440aeab Michael Hanselmann
1208 899d2a81 Michael Hanselmann
1209 1b045f5d Balazs Lecz
class TestGetMounts(unittest.TestCase):
1210 1b045f5d Balazs Lecz
  """Test case for GetMounts()."""
1211 1b045f5d Balazs Lecz
1212 1b045f5d Balazs Lecz
  TESTDATA = (
1213 1b045f5d Balazs Lecz
    "rootfs /     rootfs rw 0 0\n"
1214 1b045f5d Balazs Lecz
    "none   /sys  sysfs  rw,nosuid,nodev,noexec,relatime 0 0\n"
1215 1b045f5d Balazs Lecz
    "none   /proc proc   rw,nosuid,nodev,noexec,relatime 0 0\n")
1216 1b045f5d Balazs Lecz
1217 1b045f5d Balazs Lecz
  def setUp(self):
1218 1b045f5d Balazs Lecz
    self.tmpfile = tempfile.NamedTemporaryFile()
1219 1b045f5d Balazs Lecz
    utils.WriteFile(self.tmpfile.name, data=self.TESTDATA)
1220 1b045f5d Balazs Lecz
1221 1b045f5d Balazs Lecz
  def testGetMounts(self):
1222 1b045f5d Balazs Lecz
    self.assertEqual(utils.GetMounts(filename=self.tmpfile.name),
1223 1b045f5d Balazs Lecz
      [
1224 1b045f5d Balazs Lecz
        ("rootfs", "/", "rootfs", "rw"),
1225 1b045f5d Balazs Lecz
        ("none", "/sys", "sysfs", "rw,nosuid,nodev,noexec,relatime"),
1226 1b045f5d Balazs Lecz
        ("none", "/proc", "proc", "rw,nosuid,nodev,noexec,relatime"),
1227 1b045f5d Balazs Lecz
      ])
1228 1b045f5d Balazs Lecz
1229 1b045f5d Balazs Lecz
1230 a8083063 Iustin Pop
class TestShellQuoting(unittest.TestCase):
1231 a8083063 Iustin Pop
  """Test case for shell quoting functions"""
1232 a8083063 Iustin Pop
1233 a8083063 Iustin Pop
  def testShellQuote(self):
1234 a8083063 Iustin Pop
    self.assertEqual(ShellQuote('abc'), "abc")
1235 a8083063 Iustin Pop
    self.assertEqual(ShellQuote('ab"c'), "'ab\"c'")
1236 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a'bc"), "'a'\\''bc'")
1237 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a b c"), "'a b c'")
1238 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a b\\ c"), "'a b\\ c'")
1239 a8083063 Iustin Pop
1240 a8083063 Iustin Pop
  def testShellQuoteArgs(self):
1241 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b', 'c']), "a b c")
1242 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b"', 'c']), "a 'b\"' c")
1243 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b\'', 'c']), "a 'b'\\\''' c")
1244 a8083063 Iustin Pop
1245 a8083063 Iustin Pop
1246 eedbda4b Michael Hanselmann
class TestListVisibleFiles(unittest.TestCase):
1247 eedbda4b Michael Hanselmann
  """Test case for ListVisibleFiles"""
1248 eedbda4b Michael Hanselmann
1249 eedbda4b Michael Hanselmann
  def setUp(self):
1250 eedbda4b Michael Hanselmann
    self.path = tempfile.mkdtemp()
1251 eedbda4b Michael Hanselmann
1252 eedbda4b Michael Hanselmann
  def tearDown(self):
1253 eedbda4b Michael Hanselmann
    shutil.rmtree(self.path)
1254 eedbda4b Michael Hanselmann
1255 57d56130 Guido Trotter
  def _CreateFiles(self, files):
1256 eedbda4b Michael Hanselmann
    for name in files:
1257 57d56130 Guido Trotter
      utils.WriteFile(os.path.join(self.path, name), data="test")
1258 eedbda4b Michael Hanselmann
1259 57d56130 Guido Trotter
  def _test(self, files, expected):
1260 57d56130 Guido Trotter
    self._CreateFiles(files)
1261 eedbda4b Michael Hanselmann
    found = ListVisibleFiles(self.path)
1262 b5b8309d Guido Trotter
    self.assertEqual(set(found), set(expected))
1263 eedbda4b Michael Hanselmann
1264 eedbda4b Michael Hanselmann
  def testAllVisible(self):
1265 eedbda4b Michael Hanselmann
    files = ["a", "b", "c"]
1266 eedbda4b Michael Hanselmann
    expected = files
1267 eedbda4b Michael Hanselmann
    self._test(files, expected)
1268 eedbda4b Michael Hanselmann
1269 eedbda4b Michael Hanselmann
  def testNoneVisible(self):
1270 eedbda4b Michael Hanselmann
    files = [".a", ".b", ".c"]
1271 eedbda4b Michael Hanselmann
    expected = []
1272 eedbda4b Michael Hanselmann
    self._test(files, expected)
1273 eedbda4b Michael Hanselmann
1274 eedbda4b Michael Hanselmann
  def testSomeVisible(self):
1275 eedbda4b Michael Hanselmann
    files = ["a", "b", ".c"]
1276 eedbda4b Michael Hanselmann
    expected = ["a", "b"]
1277 eedbda4b Michael Hanselmann
    self._test(files, expected)
1278 eedbda4b Michael Hanselmann
1279 04a69a18 Iustin Pop
  def testNonAbsolutePath(self):
1280 04a69a18 Iustin Pop
    self.failUnlessRaises(errors.ProgrammerError, ListVisibleFiles, "abc")
1281 04a69a18 Iustin Pop
1282 04a69a18 Iustin Pop
  def testNonNormalizedPath(self):
1283 04a69a18 Iustin Pop
    self.failUnlessRaises(errors.ProgrammerError, ListVisibleFiles,
1284 04a69a18 Iustin Pop
                          "/bin/../tmp")
1285 04a69a18 Iustin Pop
1286 eedbda4b Michael Hanselmann
1287 24818e8f Michael Hanselmann
class TestNewUUID(unittest.TestCase):
1288 24818e8f Michael Hanselmann
  """Test case for NewUUID"""
1289 59072e7e Michael Hanselmann
1290 59072e7e Michael Hanselmann
  def runTest(self):
1291 05636402 Guido Trotter
    self.failUnless(utils.UUID_RE.match(utils.NewUUID()))
1292 59072e7e Michael Hanselmann
1293 59072e7e Michael Hanselmann
1294 f7414041 Michael Hanselmann
class TestUniqueSequence(unittest.TestCase):
1295 f7414041 Michael Hanselmann
  """Test case for UniqueSequence"""
1296 f7414041 Michael Hanselmann
1297 f7414041 Michael Hanselmann
  def _test(self, input, expected):
1298 f7414041 Michael Hanselmann
    self.assertEqual(utils.UniqueSequence(input), expected)
1299 f7414041 Michael Hanselmann
1300 f7414041 Michael Hanselmann
  def runTest(self):
1301 f7414041 Michael Hanselmann
    # Ordered input
1302 f7414041 Michael Hanselmann
    self._test([1, 2, 3], [1, 2, 3])
1303 f7414041 Michael Hanselmann
    self._test([1, 1, 2, 2, 3, 3], [1, 2, 3])
1304 f7414041 Michael Hanselmann
    self._test([1, 2, 2, 3], [1, 2, 3])
1305 f7414041 Michael Hanselmann
    self._test([1, 2, 3, 3], [1, 2, 3])
1306 f7414041 Michael Hanselmann
1307 f7414041 Michael Hanselmann
    # Unordered input
1308 f7414041 Michael Hanselmann
    self._test([1, 2, 3, 1, 2, 3], [1, 2, 3])
1309 f7414041 Michael Hanselmann
    self._test([1, 1, 2, 3, 3, 1, 2], [1, 2, 3])
1310 f7414041 Michael Hanselmann
1311 f7414041 Michael Hanselmann
    # Strings
1312 f7414041 Michael Hanselmann
    self._test(["a", "a"], ["a"])
1313 f7414041 Michael Hanselmann
    self._test(["a", "b"], ["a", "b"])
1314 f7414041 Michael Hanselmann
    self._test(["a", "b", "a"], ["a", "b"])
1315 f7414041 Michael Hanselmann
1316 a87b4824 Michael Hanselmann
1317 7b4126b7 Iustin Pop
class TestFirstFree(unittest.TestCase):
1318 7b4126b7 Iustin Pop
  """Test case for the FirstFree function"""
1319 7b4126b7 Iustin Pop
1320 7b4126b7 Iustin Pop
  def test(self):
1321 7b4126b7 Iustin Pop
    """Test FirstFree"""
1322 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([0, 1, 3]), 2)
1323 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([]), None)
1324 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([3, 4, 6]), 0)
1325 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([3, 4, 6], base=3), 5)
1326 7b4126b7 Iustin Pop
    self.failUnlessRaises(AssertionError, FirstFree, [0, 3, 4, 6], base=3)
1327 f7414041 Michael Hanselmann
1328 a87b4824 Michael Hanselmann
1329 f65f63ef Iustin Pop
class TestTailFile(testutils.GanetiTestCase):
1330 f65f63ef Iustin Pop
  """Test case for the TailFile function"""
1331 f65f63ef Iustin Pop
1332 f65f63ef Iustin Pop
  def testEmpty(self):
1333 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1334 f65f63ef Iustin Pop
    self.failUnlessEqual(TailFile(fname), [])
1335 f65f63ef Iustin Pop
    self.failUnlessEqual(TailFile(fname, lines=25), [])
1336 f65f63ef Iustin Pop
1337 f65f63ef Iustin Pop
  def testAllLines(self):
1338 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1339 f65f63ef Iustin Pop
    for i in range(30):
1340 f65f63ef Iustin Pop
      fname = self._CreateTempFile()
1341 f65f63ef Iustin Pop
      fd = open(fname, "w")
1342 f65f63ef Iustin Pop
      fd.write("\n".join(data[:i]))
1343 f65f63ef Iustin Pop
      if i > 0:
1344 f65f63ef Iustin Pop
        fd.write("\n")
1345 f65f63ef Iustin Pop
      fd.close()
1346 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[:i])
1347 f65f63ef Iustin Pop
1348 f65f63ef Iustin Pop
  def testPartialLines(self):
1349 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1350 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1351 f65f63ef Iustin Pop
    fd = open(fname, "w")
1352 f65f63ef Iustin Pop
    fd.write("\n".join(data))
1353 f65f63ef Iustin Pop
    fd.write("\n")
1354 f65f63ef Iustin Pop
    fd.close()
1355 f65f63ef Iustin Pop
    for i in range(1, 30):
1356 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[-i:])
1357 f65f63ef Iustin Pop
1358 f65f63ef Iustin Pop
  def testBigFile(self):
1359 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1360 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1361 f65f63ef Iustin Pop
    fd = open(fname, "w")
1362 f65f63ef Iustin Pop
    fd.write("X" * 1048576)
1363 f65f63ef Iustin Pop
    fd.write("\n")
1364 f65f63ef Iustin Pop
    fd.write("\n".join(data))
1365 f65f63ef Iustin Pop
    fd.write("\n")
1366 f65f63ef Iustin Pop
    fd.close()
1367 f65f63ef Iustin Pop
    for i in range(1, 30):
1368 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[-i:])
1369 f65f63ef Iustin Pop
1370 f65f63ef Iustin Pop
1371 b4478d34 Michael Hanselmann
class _BaseFileLockTest:
1372 a87b4824 Michael Hanselmann
  """Test case for the FileLock class"""
1373 a87b4824 Michael Hanselmann
1374 a87b4824 Michael Hanselmann
  def testSharedNonblocking(self):
1375 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1376 a87b4824 Michael Hanselmann
    self.lock.Close()
1377 a87b4824 Michael Hanselmann
1378 a87b4824 Michael Hanselmann
  def testExclusiveNonblocking(self):
1379 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1380 a87b4824 Michael Hanselmann
    self.lock.Close()
1381 a87b4824 Michael Hanselmann
1382 a87b4824 Michael Hanselmann
  def testUnlockNonblocking(self):
1383 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1384 a87b4824 Michael Hanselmann
    self.lock.Close()
1385 a87b4824 Michael Hanselmann
1386 a87b4824 Michael Hanselmann
  def testSharedBlocking(self):
1387 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=True)
1388 a87b4824 Michael Hanselmann
    self.lock.Close()
1389 a87b4824 Michael Hanselmann
1390 a87b4824 Michael Hanselmann
  def testExclusiveBlocking(self):
1391 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=True)
1392 a87b4824 Michael Hanselmann
    self.lock.Close()
1393 a87b4824 Michael Hanselmann
1394 a87b4824 Michael Hanselmann
  def testUnlockBlocking(self):
1395 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=True)
1396 a87b4824 Michael Hanselmann
    self.lock.Close()
1397 a87b4824 Michael Hanselmann
1398 a87b4824 Michael Hanselmann
  def testSharedExclusiveUnlock(self):
1399 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1400 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1401 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1402 a87b4824 Michael Hanselmann
    self.lock.Close()
1403 a87b4824 Michael Hanselmann
1404 a87b4824 Michael Hanselmann
  def testExclusiveSharedUnlock(self):
1405 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1406 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1407 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1408 a87b4824 Michael Hanselmann
    self.lock.Close()
1409 a87b4824 Michael Hanselmann
1410 b4478d34 Michael Hanselmann
  def testSimpleTimeout(self):
1411 b4478d34 Michael Hanselmann
    # These will succeed on the first attempt, hence a short timeout
1412 b4478d34 Michael Hanselmann
    self.lock.Shared(blocking=True, timeout=10.0)
1413 b4478d34 Michael Hanselmann
    self.lock.Exclusive(blocking=False, timeout=10.0)
1414 b4478d34 Michael Hanselmann
    self.lock.Unlock(blocking=True, timeout=10.0)
1415 b4478d34 Michael Hanselmann
    self.lock.Close()
1416 b4478d34 Michael Hanselmann
1417 b4478d34 Michael Hanselmann
  @staticmethod
1418 b4478d34 Michael Hanselmann
  def _TryLockInner(filename, shared, blocking):
1419 b4478d34 Michael Hanselmann
    lock = utils.FileLock.Open(filename)
1420 b4478d34 Michael Hanselmann
1421 b4478d34 Michael Hanselmann
    if shared:
1422 b4478d34 Michael Hanselmann
      fn = lock.Shared
1423 b4478d34 Michael Hanselmann
    else:
1424 b4478d34 Michael Hanselmann
      fn = lock.Exclusive
1425 b4478d34 Michael Hanselmann
1426 b4478d34 Michael Hanselmann
    try:
1427 b4478d34 Michael Hanselmann
      # The timeout doesn't really matter as the parent process waits for us to
1428 b4478d34 Michael Hanselmann
      # finish anyway.
1429 b4478d34 Michael Hanselmann
      fn(blocking=blocking, timeout=0.01)
1430 b4478d34 Michael Hanselmann
    except errors.LockError, err:
1431 b4478d34 Michael Hanselmann
      return False
1432 b4478d34 Michael Hanselmann
1433 b4478d34 Michael Hanselmann
    return True
1434 b4478d34 Michael Hanselmann
1435 b4478d34 Michael Hanselmann
  def _TryLock(self, *args):
1436 b4478d34 Michael Hanselmann
    return utils.RunInSeparateProcess(self._TryLockInner, self.tmpfile.name,
1437 b4478d34 Michael Hanselmann
                                      *args)
1438 b4478d34 Michael Hanselmann
1439 b4478d34 Michael Hanselmann
  def testTimeout(self):
1440 b4478d34 Michael Hanselmann
    for blocking in [True, False]:
1441 b4478d34 Michael Hanselmann
      self.lock.Exclusive(blocking=True)
1442 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(False, blocking))
1443 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(True, blocking))
1444 b4478d34 Michael Hanselmann
1445 b4478d34 Michael Hanselmann
      self.lock.Shared(blocking=True)
1446 b4478d34 Michael Hanselmann
      self.assert_(self._TryLock(True, blocking))
1447 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(False, blocking))
1448 b4478d34 Michael Hanselmann
1449 a87b4824 Michael Hanselmann
  def testCloseShared(self):
1450 a87b4824 Michael Hanselmann
    self.lock.Close()
1451 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Shared, blocking=False)
1452 a87b4824 Michael Hanselmann
1453 a87b4824 Michael Hanselmann
  def testCloseExclusive(self):
1454 a87b4824 Michael Hanselmann
    self.lock.Close()
1455 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Exclusive, blocking=False)
1456 a87b4824 Michael Hanselmann
1457 a87b4824 Michael Hanselmann
  def testCloseUnlock(self):
1458 a87b4824 Michael Hanselmann
    self.lock.Close()
1459 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Unlock, blocking=False)
1460 a87b4824 Michael Hanselmann
1461 a87b4824 Michael Hanselmann
1462 b4478d34 Michael Hanselmann
class TestFileLockWithFilename(testutils.GanetiTestCase, _BaseFileLockTest):
1463 b4478d34 Michael Hanselmann
  TESTDATA = "Hello World\n" * 10
1464 b4478d34 Michael Hanselmann
1465 b4478d34 Michael Hanselmann
  def setUp(self):
1466 b4478d34 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
1467 b4478d34 Michael Hanselmann
1468 b4478d34 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1469 b4478d34 Michael Hanselmann
    utils.WriteFile(self.tmpfile.name, data=self.TESTDATA)
1470 b4478d34 Michael Hanselmann
    self.lock = utils.FileLock.Open(self.tmpfile.name)
1471 b4478d34 Michael Hanselmann
1472 b4478d34 Michael Hanselmann
    # Ensure "Open" didn't truncate file
1473 b4478d34 Michael Hanselmann
    self.assertFileContent(self.tmpfile.name, self.TESTDATA)
1474 b4478d34 Michael Hanselmann
1475 b4478d34 Michael Hanselmann
  def tearDown(self):
1476 b4478d34 Michael Hanselmann
    self.assertFileContent(self.tmpfile.name, self.TESTDATA)
1477 b4478d34 Michael Hanselmann
1478 b4478d34 Michael Hanselmann
    testutils.GanetiTestCase.tearDown(self)
1479 b4478d34 Michael Hanselmann
1480 b4478d34 Michael Hanselmann
1481 b4478d34 Michael Hanselmann
class TestFileLockWithFileObject(unittest.TestCase, _BaseFileLockTest):
1482 b4478d34 Michael Hanselmann
  def setUp(self):
1483 b4478d34 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1484 b4478d34 Michael Hanselmann
    self.lock = utils.FileLock(open(self.tmpfile.name, "w"), self.tmpfile.name)
1485 b4478d34 Michael Hanselmann
1486 b4478d34 Michael Hanselmann
1487 739be818 Michael Hanselmann
class TestTimeFunctions(unittest.TestCase):
1488 739be818 Michael Hanselmann
  """Test case for time functions"""
1489 739be818 Michael Hanselmann
1490 739be818 Michael Hanselmann
  def runTest(self):
1491 739be818 Michael Hanselmann
    self.assertEqual(utils.SplitTime(1), (1, 0))
1492 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(1.5), (1, 500000))
1493 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(1218448917.4809151), (1218448917, 480915))
1494 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.48012), (123, 480120))
1495 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9996), (123, 999600))
1496 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9995), (123, 999500))
1497 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9994), (123, 999400))
1498 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.999999999), (123, 999999))
1499 45bc5e4a Michael Hanselmann
1500 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.SplitTime, -1)
1501 739be818 Michael Hanselmann
1502 739be818 Michael Hanselmann
    self.assertEqual(utils.MergeTime((1, 0)), 1.0)
1503 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.MergeTime((1, 500000)), 1.5)
1504 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.MergeTime((1218448917, 500000)), 1218448917.5)
1505 739be818 Michael Hanselmann
1506 4d4a651d Michael Hanselmann
    self.assertEqual(round(utils.MergeTime((1218448917, 481000)), 3),
1507 4d4a651d Michael Hanselmann
                     1218448917.481)
1508 45bc5e4a Michael Hanselmann
    self.assertEqual(round(utils.MergeTime((1, 801000)), 3), 1.801)
1509 739be818 Michael Hanselmann
1510 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, -1))
1511 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, 1000000))
1512 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, 9999999))
1513 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (-1, 0))
1514 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (-9999, 0))
1515 739be818 Michael Hanselmann
1516 739be818 Michael Hanselmann
1517 a2d2e1a7 Iustin Pop
class FieldSetTestCase(unittest.TestCase):
1518 a2d2e1a7 Iustin Pop
  """Test case for FieldSets"""
1519 a2d2e1a7 Iustin Pop
1520 a2d2e1a7 Iustin Pop
  def testSimpleMatch(self):
1521 a2d2e1a7 Iustin Pop
    f = utils.FieldSet("a", "b", "c", "def")
1522 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("a"))
1523 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("d"), "Substring matched")
1524 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("defghi"), "Prefix string matched")
1525 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["b", "c"]))
1526 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["a", "b", "c", "def"]))
1527 a2d2e1a7 Iustin Pop
    self.failUnless(f.NonMatching(["a", "d"]))
1528 a2d2e1a7 Iustin Pop
1529 a2d2e1a7 Iustin Pop
  def testRegexMatch(self):
1530 a2d2e1a7 Iustin Pop
    f = utils.FieldSet("a", "b([0-9]+)", "c")
1531 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("b1"))
1532 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("b99"))
1533 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("b/1"))
1534 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["b12", "c"]))
1535 a2d2e1a7 Iustin Pop
    self.failUnless(f.NonMatching(["a", "1"]))
1536 a2d2e1a7 Iustin Pop
1537 a5728081 Guido Trotter
class TestForceDictType(unittest.TestCase):
1538 a5728081 Guido Trotter
  """Test case for ForceDictType"""
1539 a5728081 Guido Trotter
1540 a5728081 Guido Trotter
  def setUp(self):
1541 a5728081 Guido Trotter
    self.key_types = {
1542 a5728081 Guido Trotter
      'a': constants.VTYPE_INT,
1543 a5728081 Guido Trotter
      'b': constants.VTYPE_BOOL,
1544 a5728081 Guido Trotter
      'c': constants.VTYPE_STRING,
1545 a5728081 Guido Trotter
      'd': constants.VTYPE_SIZE,
1546 59525e1f Michael Hanselmann
      "e": constants.VTYPE_MAYBE_STRING,
1547 a5728081 Guido Trotter
      }
1548 a5728081 Guido Trotter
1549 a5728081 Guido Trotter
  def _fdt(self, dict, allowed_values=None):
1550 a5728081 Guido Trotter
    if allowed_values is None:
1551 a744b676 Manuel Franceschini
      utils.ForceDictType(dict, self.key_types)
1552 a5728081 Guido Trotter
    else:
1553 a744b676 Manuel Franceschini
      utils.ForceDictType(dict, self.key_types, allowed_values=allowed_values)
1554 a5728081 Guido Trotter
1555 a5728081 Guido Trotter
    return dict
1556 a5728081 Guido Trotter
1557 a5728081 Guido Trotter
  def testSimpleDict(self):
1558 a5728081 Guido Trotter
    self.assertEqual(self._fdt({}), {})
1559 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': 1}), {'a': 1})
1560 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': '1'}), {'a': 1})
1561 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': 1, 'b': 1}), {'a':1, 'b': True})
1562 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 1, 'c': 'foo'}), {'b': True, 'c': 'foo'})
1563 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 1, 'c': False}), {'b': True, 'c': ''})
1564 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'false'}), {'b': False})
1565 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'False'}), {'b': False})
1566 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'true'}), {'b': True})
1567 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'True'}), {'b': True})
1568 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'d': '4'}), {'d': 4})
1569 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'d': '4M'}), {'d': 4})
1570 59525e1f Michael Hanselmann
    self.assertEqual(self._fdt({"e": None, }), {"e": None, })
1571 59525e1f Michael Hanselmann
    self.assertEqual(self._fdt({"e": "Hello World", }), {"e": "Hello World", })
1572 59525e1f Michael Hanselmann
    self.assertEqual(self._fdt({"e": False, }), {"e": '', })
1573 a5728081 Guido Trotter
1574 a5728081 Guido Trotter
  def testErrors(self):
1575 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'a': 'astring'})
1576 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'c': True})
1577 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': 'astring'})
1578 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': '4 L'})
1579 59525e1f Michael Hanselmann
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {"e": object(), })
1580 59525e1f Michael Hanselmann
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {"e": [], })
1581 a5728081 Guido Trotter
1582 a2d2e1a7 Iustin Pop
1583 05489142 Guido Trotter
class TestIsNormAbsPath(unittest.TestCase):
1584 c1dd99d4 Michael Hanselmann
  """Testing case for IsNormAbsPath"""
1585 da961187 Guido Trotter
1586 da961187 Guido Trotter
  def _pathTestHelper(self, path, result):
1587 da961187 Guido Trotter
    if result:
1588 a744b676 Manuel Franceschini
      self.assert_(utils.IsNormAbsPath(path),
1589 17c61836 Guido Trotter
          "Path %s should result absolute and normalized" % path)
1590 da961187 Guido Trotter
    else:
1591 a744b676 Manuel Franceschini
      self.assertFalse(utils.IsNormAbsPath(path),
1592 17c61836 Guido Trotter
          "Path %s should not result absolute and normalized" % path)
1593 da961187 Guido Trotter
1594 da961187 Guido Trotter
  def testBase(self):
1595 da961187 Guido Trotter
    self._pathTestHelper('/etc', True)
1596 da961187 Guido Trotter
    self._pathTestHelper('/srv', True)
1597 da961187 Guido Trotter
    self._pathTestHelper('etc', False)
1598 da961187 Guido Trotter
    self._pathTestHelper('/etc/../root', False)
1599 da961187 Guido Trotter
    self._pathTestHelper('/etc/', False)
1600 da961187 Guido Trotter
1601 af0413bb Guido Trotter
1602 d392fa34 Iustin Pop
class TestSafeEncode(unittest.TestCase):
1603 d392fa34 Iustin Pop
  """Test case for SafeEncode"""
1604 d392fa34 Iustin Pop
1605 d392fa34 Iustin Pop
  def testAscii(self):
1606 d392fa34 Iustin Pop
    for txt in [string.digits, string.letters, string.punctuation]:
1607 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1608 d392fa34 Iustin Pop
1609 d392fa34 Iustin Pop
  def testDoubleEncode(self):
1610 d392fa34 Iustin Pop
    for i in range(255):
1611 d392fa34 Iustin Pop
      txt = SafeEncode(chr(i))
1612 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1613 d392fa34 Iustin Pop
1614 d392fa34 Iustin Pop
  def testUnicode(self):
1615 d392fa34 Iustin Pop
    # 1024 is high enough to catch non-direct ASCII mappings
1616 d392fa34 Iustin Pop
    for i in range(1024):
1617 d392fa34 Iustin Pop
      txt = SafeEncode(unichr(i))
1618 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1619 d392fa34 Iustin Pop
1620 d392fa34 Iustin Pop
1621 3b813dd2 Iustin Pop
class TestFormatTime(unittest.TestCase):
1622 3b813dd2 Iustin Pop
  """Testing case for FormatTime"""
1623 3b813dd2 Iustin Pop
1624 3b813dd2 Iustin Pop
  def testNone(self):
1625 3b813dd2 Iustin Pop
    self.failUnlessEqual(FormatTime(None), "N/A")
1626 3b813dd2 Iustin Pop
1627 3b813dd2 Iustin Pop
  def testInvalid(self):
1628 3b813dd2 Iustin Pop
    self.failUnlessEqual(FormatTime(()), "N/A")
1629 3b813dd2 Iustin Pop
1630 3b813dd2 Iustin Pop
  def testNow(self):
1631 3b813dd2 Iustin Pop
    # tests that we accept time.time input
1632 3b813dd2 Iustin Pop
    FormatTime(time.time())
1633 3b813dd2 Iustin Pop
    # tests that we accept int input
1634 3b813dd2 Iustin Pop
    FormatTime(int(time.time()))
1635 3b813dd2 Iustin Pop
1636 3b813dd2 Iustin Pop
1637 eb58f7bd Michael Hanselmann
class RunInSeparateProcess(unittest.TestCase):
1638 eb58f7bd Michael Hanselmann
  def test(self):
1639 eb58f7bd Michael Hanselmann
    for exp in [True, False]:
1640 eb58f7bd Michael Hanselmann
      def _child():
1641 eb58f7bd Michael Hanselmann
        return exp
1642 eb58f7bd Michael Hanselmann
1643 eb58f7bd Michael Hanselmann
      self.assertEqual(exp, utils.RunInSeparateProcess(_child))
1644 eb58f7bd Michael Hanselmann
1645 bdefe5dd Michael Hanselmann
  def testArgs(self):
1646 bdefe5dd Michael Hanselmann
    for arg in [0, 1, 999, "Hello World", (1, 2, 3)]:
1647 bdefe5dd Michael Hanselmann
      def _child(carg1, carg2):
1648 bdefe5dd Michael Hanselmann
        return carg1 == "Foo" and carg2 == arg
1649 bdefe5dd Michael Hanselmann
1650 bdefe5dd Michael Hanselmann
      self.assert_(utils.RunInSeparateProcess(_child, "Foo", arg))
1651 bdefe5dd Michael Hanselmann
1652 eb58f7bd Michael Hanselmann
  def testPid(self):
1653 eb58f7bd Michael Hanselmann
    parent_pid = os.getpid()
1654 eb58f7bd Michael Hanselmann
1655 eb58f7bd Michael Hanselmann
    def _check():
1656 eb58f7bd Michael Hanselmann
      return os.getpid() == parent_pid
1657 eb58f7bd Michael Hanselmann
1658 eb58f7bd Michael Hanselmann
    self.failIf(utils.RunInSeparateProcess(_check))
1659 eb58f7bd Michael Hanselmann
1660 eb58f7bd Michael Hanselmann
  def testSignal(self):
1661 eb58f7bd Michael Hanselmann
    def _kill():
1662 eb58f7bd Michael Hanselmann
      os.kill(os.getpid(), signal.SIGTERM)
1663 eb58f7bd Michael Hanselmann
1664 eb58f7bd Michael Hanselmann
    self.assertRaises(errors.GenericError,
1665 eb58f7bd Michael Hanselmann
                      utils.RunInSeparateProcess, _kill)
1666 eb58f7bd Michael Hanselmann
1667 eb58f7bd Michael Hanselmann
  def testException(self):
1668 eb58f7bd Michael Hanselmann
    def _exc():
1669 eb58f7bd Michael Hanselmann
      raise errors.GenericError("This is a test")
1670 eb58f7bd Michael Hanselmann
1671 eb58f7bd Michael Hanselmann
    self.assertRaises(errors.GenericError,
1672 eb58f7bd Michael Hanselmann
                      utils.RunInSeparateProcess, _exc)
1673 eb58f7bd Michael Hanselmann
1674 eb58f7bd Michael Hanselmann
1675 fabee4b2 Michael Hanselmann
class TestFingerprintFile(unittest.TestCase):
1676 fabee4b2 Michael Hanselmann
  def setUp(self):
1677 fabee4b2 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1678 fabee4b2 Michael Hanselmann
1679 fabee4b2 Michael Hanselmann
  def test(self):
1680 fabee4b2 Michael Hanselmann
    self.assertEqual(utils._FingerprintFile(self.tmpfile.name),
1681 fabee4b2 Michael Hanselmann
                     "da39a3ee5e6b4b0d3255bfef95601890afd80709")
1682 fabee4b2 Michael Hanselmann
1683 fabee4b2 Michael Hanselmann
    utils.WriteFile(self.tmpfile.name, data="Hello World\n")
1684 fabee4b2 Michael Hanselmann
    self.assertEqual(utils._FingerprintFile(self.tmpfile.name),
1685 fabee4b2 Michael Hanselmann
                     "648a6a6ffffdaa0badb23b8baf90b6168dd16b3a")
1686 fabee4b2 Michael Hanselmann
1687 fabee4b2 Michael Hanselmann
1688 5b69bc7c Iustin Pop
class TestUnescapeAndSplit(unittest.TestCase):
1689 5b69bc7c Iustin Pop
  """Testing case for UnescapeAndSplit"""
1690 5b69bc7c Iustin Pop
1691 5b69bc7c Iustin Pop
  def setUp(self):
1692 5b69bc7c Iustin Pop
    # testing more that one separator for regexp safety
1693 5b69bc7c Iustin Pop
    self._seps = [",", "+", "."]
1694 5b69bc7c Iustin Pop
1695 5b69bc7c Iustin Pop
  def testSimple(self):
1696 5b69bc7c Iustin Pop
    a = ["a", "b", "c", "d"]
1697 5b69bc7c Iustin Pop
    for sep in self._seps:
1698 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), a)
1699 5b69bc7c Iustin Pop
1700 5b69bc7c Iustin Pop
  def testEscape(self):
1701 5b69bc7c Iustin Pop
    for sep in self._seps:
1702 5b69bc7c Iustin Pop
      a = ["a", "b\\" + sep + "c", "d"]
1703 5b69bc7c Iustin Pop
      b = ["a", "b" + sep + "c", "d"]
1704 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1705 5b69bc7c Iustin Pop
1706 5b69bc7c Iustin Pop
  def testDoubleEscape(self):
1707 5b69bc7c Iustin Pop
    for sep in self._seps:
1708 5b69bc7c Iustin Pop
      a = ["a", "b\\\\", "c", "d"]
1709 5b69bc7c Iustin Pop
      b = ["a", "b\\", "c", "d"]
1710 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1711 5b69bc7c Iustin Pop
1712 5b69bc7c Iustin Pop
  def testThreeEscape(self):
1713 5b69bc7c Iustin Pop
    for sep in self._seps:
1714 5b69bc7c Iustin Pop
      a = ["a", "b\\\\\\" + sep + "c", "d"]
1715 5b69bc7c Iustin Pop
      b = ["a", "b\\" + sep + "c", "d"]
1716 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1717 5b69bc7c Iustin Pop
1718 5b69bc7c Iustin Pop
1719 bdd5e420 Michael Hanselmann
class TestGenerateSelfSignedX509Cert(unittest.TestCase):
1720 a55474c7 Michael Hanselmann
  def setUp(self):
1721 a55474c7 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
1722 a55474c7 Michael Hanselmann
1723 a55474c7 Michael Hanselmann
  def tearDown(self):
1724 a55474c7 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
1725 a55474c7 Michael Hanselmann
1726 bdd5e420 Michael Hanselmann
  def _checkRsaPrivateKey(self, key):
1727 a55474c7 Michael Hanselmann
    lines = key.splitlines()
1728 bdd5e420 Michael Hanselmann
    return ("-----BEGIN RSA PRIVATE KEY-----" in lines and
1729 bdd5e420 Michael Hanselmann
            "-----END RSA PRIVATE KEY-----" in lines)
1730 a55474c7 Michael Hanselmann
1731 bdd5e420 Michael Hanselmann
  def _checkCertificate(self, cert):
1732 a55474c7 Michael Hanselmann
    lines = cert.splitlines()
1733 bdd5e420 Michael Hanselmann
    return ("-----BEGIN CERTIFICATE-----" in lines and
1734 bdd5e420 Michael Hanselmann
            "-----END CERTIFICATE-----" in lines)
1735 a55474c7 Michael Hanselmann
1736 bdd5e420 Michael Hanselmann
  def test(self):
1737 bdd5e420 Michael Hanselmann
    for common_name in [None, ".", "Ganeti", "node1.example.com"]:
1738 bdd5e420 Michael Hanselmann
      (key_pem, cert_pem) = utils.GenerateSelfSignedX509Cert(common_name, 300)
1739 bdd5e420 Michael Hanselmann
      self._checkRsaPrivateKey(key_pem)
1740 bdd5e420 Michael Hanselmann
      self._checkCertificate(cert_pem)
1741 bdd5e420 Michael Hanselmann
1742 bdd5e420 Michael Hanselmann
      key = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,
1743 bdd5e420 Michael Hanselmann
                                           key_pem)
1744 bdd5e420 Michael Hanselmann
      self.assert_(key.bits() >= 1024)
1745 bdd5e420 Michael Hanselmann
      self.assertEqual(key.bits(), constants.RSA_KEY_BITS)
1746 bdd5e420 Michael Hanselmann
      self.assertEqual(key.type(), OpenSSL.crypto.TYPE_RSA)
1747 bdd5e420 Michael Hanselmann
1748 bdd5e420 Michael Hanselmann
      x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
1749 bdd5e420 Michael Hanselmann
                                             cert_pem)
1750 bdd5e420 Michael Hanselmann
      self.failIf(x509.has_expired())
1751 bdd5e420 Michael Hanselmann
      self.assertEqual(x509.get_issuer().CN, common_name)
1752 bdd5e420 Michael Hanselmann
      self.assertEqual(x509.get_subject().CN, common_name)
1753 bdd5e420 Michael Hanselmann
      self.assertEqual(x509.get_pubkey().bits(), constants.RSA_KEY_BITS)
1754 bdd5e420 Michael Hanselmann
1755 bdd5e420 Michael Hanselmann
  def testLegacy(self):
1756 a55474c7 Michael Hanselmann
    cert1_filename = os.path.join(self.tmpdir, "cert1.pem")
1757 a55474c7 Michael Hanselmann
1758 a55474c7 Michael Hanselmann
    utils.GenerateSelfSignedSslCert(cert1_filename, validity=1)
1759 a55474c7 Michael Hanselmann
1760 a55474c7 Michael Hanselmann
    cert1 = utils.ReadFile(cert1_filename)
1761 a55474c7 Michael Hanselmann
1762 bdd5e420 Michael Hanselmann
    self.assert_(self._checkRsaPrivateKey(cert1))
1763 bdd5e420 Michael Hanselmann
    self.assert_(self._checkCertificate(cert1))
1764 a55474c7 Michael Hanselmann
1765 a55474c7 Michael Hanselmann
1766 4bb678e9 Iustin Pop
class TestPathJoin(unittest.TestCase):
1767 4bb678e9 Iustin Pop
  """Testing case for PathJoin"""
1768 4bb678e9 Iustin Pop
1769 4bb678e9 Iustin Pop
  def testBasicItems(self):
1770 4bb678e9 Iustin Pop
    mlist = ["/a", "b", "c"]
1771 4bb678e9 Iustin Pop
    self.failUnlessEqual(PathJoin(*mlist), "/".join(mlist))
1772 4bb678e9 Iustin Pop
1773 4bb678e9 Iustin Pop
  def testNonAbsPrefix(self):
1774 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "a", "b")
1775 4bb678e9 Iustin Pop
1776 4bb678e9 Iustin Pop
  def testBackTrack(self):
1777 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "/a", "b/../c")
1778 4bb678e9 Iustin Pop
1779 4bb678e9 Iustin Pop
  def testMultiAbs(self):
1780 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "/a", "/b")
1781 4bb678e9 Iustin Pop
1782 4bb678e9 Iustin Pop
1783 28f34048 Michael Hanselmann
class TestValidateServiceName(unittest.TestCase):
1784 28f34048 Michael Hanselmann
  def testValid(self):
1785 28f34048 Michael Hanselmann
    testnames = [
1786 28f34048 Michael Hanselmann
      0, 1, 2, 3, 1024, 65000, 65534, 65535,
1787 28f34048 Michael Hanselmann
      "ganeti",
1788 28f34048 Michael Hanselmann
      "gnt-masterd",
1789 28f34048 Michael Hanselmann
      "HELLO_WORLD_SVC",
1790 28f34048 Michael Hanselmann
      "hello.world.1",
1791 28f34048 Michael Hanselmann
      "0", "80", "1111", "65535",
1792 28f34048 Michael Hanselmann
      ]
1793 28f34048 Michael Hanselmann
1794 28f34048 Michael Hanselmann
    for name in testnames:
1795 28f34048 Michael Hanselmann
      self.assertEqual(utils.ValidateServiceName(name), name)
1796 28f34048 Michael Hanselmann
1797 28f34048 Michael Hanselmann
  def testInvalid(self):
1798 28f34048 Michael Hanselmann
    testnames = [
1799 28f34048 Michael Hanselmann
      -15756, -1, 65536, 133428083,
1800 28f34048 Michael Hanselmann
      "", "Hello World!", "!", "'", "\"", "\t", "\n", "`",
1801 28f34048 Michael Hanselmann
      "-8546", "-1", "65536",
1802 28f34048 Michael Hanselmann
      (129 * "A"),
1803 28f34048 Michael Hanselmann
      ]
1804 28f34048 Michael Hanselmann
1805 28f34048 Michael Hanselmann
    for name in testnames:
1806 a744b676 Manuel Franceschini
      self.assertRaises(errors.OpPrereqError, utils.ValidateServiceName, name)
1807 28f34048 Michael Hanselmann
1808 28f34048 Michael Hanselmann
1809 27e46076 Michael Hanselmann
class TestParseAsn1Generalizedtime(unittest.TestCase):
1810 27e46076 Michael Hanselmann
  def test(self):
1811 27e46076 Michael Hanselmann
    # UTC
1812 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("19700101000000Z"), 0)
1813 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100222174152Z"),
1814 27e46076 Michael Hanselmann
                     1266860512)
1815 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20380119031407Z"),
1816 27e46076 Michael Hanselmann
                     (2**31) - 1)
1817 27e46076 Michael Hanselmann
1818 27e46076 Michael Hanselmann
    # With offset
1819 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100222174152+0000"),
1820 27e46076 Michael Hanselmann
                     1266860512)
1821 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100223131652+0000"),
1822 27e46076 Michael Hanselmann
                     1266931012)
1823 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100223051808-0800"),
1824 27e46076 Michael Hanselmann
                     1266931088)
1825 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100224002135+1100"),
1826 27e46076 Michael Hanselmann
                     1266931295)
1827 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("19700101000000-0100"),
1828 27e46076 Michael Hanselmann
                     3600)
1829 27e46076 Michael Hanselmann
1830 27e46076 Michael Hanselmann
    # Leap seconds are not supported by datetime.datetime
1831 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1832 27e46076 Michael Hanselmann
                      "19841231235960+0000")
1833 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1834 27e46076 Michael Hanselmann
                      "19920630235960+0000")
1835 27e46076 Michael Hanselmann
1836 27e46076 Michael Hanselmann
    # Errors
1837 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime, "")
1838 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime, "invalid")
1839 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1840 27e46076 Michael Hanselmann
                      "20100222174152")
1841 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1842 27e46076 Michael Hanselmann
                      "Mon Feb 22 17:47:02 UTC 2010")
1843 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1844 27e46076 Michael Hanselmann
                      "2010-02-22 17:42:02")
1845 27e46076 Michael Hanselmann
1846 27e46076 Michael Hanselmann
1847 27e46076 Michael Hanselmann
class TestGetX509CertValidity(testutils.GanetiTestCase):
1848 27e46076 Michael Hanselmann
  def setUp(self):
1849 27e46076 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
1850 27e46076 Michael Hanselmann
1851 27e46076 Michael Hanselmann
    pyopenssl_version = distutils.version.LooseVersion(OpenSSL.__version__)
1852 27e46076 Michael Hanselmann
1853 27e46076 Michael Hanselmann
    # Test whether we have pyOpenSSL 0.7 or above
1854 27e46076 Michael Hanselmann
    self.pyopenssl0_7 = (pyopenssl_version >= "0.7")
1855 27e46076 Michael Hanselmann
1856 27e46076 Michael Hanselmann
    if not self.pyopenssl0_7:
1857 27e46076 Michael Hanselmann
      warnings.warn("This test requires pyOpenSSL 0.7 or above to"
1858 27e46076 Michael Hanselmann
                    " function correctly")
1859 27e46076 Michael Hanselmann
1860 27e46076 Michael Hanselmann
  def _LoadCert(self, name):
1861 27e46076 Michael Hanselmann
    return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
1862 27e46076 Michael Hanselmann
                                           self._ReadTestData(name))
1863 27e46076 Michael Hanselmann
1864 27e46076 Michael Hanselmann
  def test(self):
1865 27e46076 Michael Hanselmann
    validity = utils.GetX509CertValidity(self._LoadCert("cert1.pem"))
1866 27e46076 Michael Hanselmann
    if self.pyopenssl0_7:
1867 27e46076 Michael Hanselmann
      self.assertEqual(validity, (1266919967, 1267524767))
1868 27e46076 Michael Hanselmann
    else:
1869 27e46076 Michael Hanselmann
      self.assertEqual(validity, (None, None))
1870 27e46076 Michael Hanselmann
1871 26288e68 Iustin Pop
1872 68857643 Michael Hanselmann
class TestSignX509Certificate(unittest.TestCase):
1873 68857643 Michael Hanselmann
  KEY = "My private key!"
1874 68857643 Michael Hanselmann
  KEY_OTHER = "Another key"
1875 68857643 Michael Hanselmann
1876 68857643 Michael Hanselmann
  def test(self):
1877 68857643 Michael Hanselmann
    # Generate certificate valid for 5 minutes
1878 68857643 Michael Hanselmann
    (_, cert_pem) = utils.GenerateSelfSignedX509Cert(None, 300)
1879 68857643 Michael Hanselmann
1880 68857643 Michael Hanselmann
    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
1881 68857643 Michael Hanselmann
                                           cert_pem)
1882 68857643 Michael Hanselmann
1883 68857643 Michael Hanselmann
    # No signature at all
1884 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError,
1885 68857643 Michael Hanselmann
                      utils.LoadSignedX509Certificate, cert_pem, self.KEY)
1886 68857643 Michael Hanselmann
1887 68857643 Michael Hanselmann
    # Invalid input
1888 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
1889 68857643 Michael Hanselmann
                      "", self.KEY)
1890 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
1891 68857643 Michael Hanselmann
                      "X-Ganeti-Signature: \n", self.KEY)
1892 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
1893 68857643 Michael Hanselmann
                      "X-Ganeti-Sign: $1234$abcdef\n", self.KEY)
1894 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
1895 68857643 Michael Hanselmann
                      "X-Ganeti-Signature: $1234567890$abcdef\n", self.KEY)
1896 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
1897 68857643 Michael Hanselmann
                      "X-Ganeti-Signature: $1234$abc\n\n" + cert_pem, self.KEY)
1898 68857643 Michael Hanselmann
1899 68857643 Michael Hanselmann
    # Invalid salt
1900 68857643 Michael Hanselmann
    for salt in list("-_@$,:;/\\ \t\n"):
1901 68857643 Michael Hanselmann
      self.assertRaises(errors.GenericError, utils.SignX509Certificate,
1902 68857643 Michael Hanselmann
                        cert_pem, self.KEY, "foo%sbar" % salt)
1903 68857643 Michael Hanselmann
1904 68857643 Michael Hanselmann
    for salt in ["HelloWorld", "salt", string.letters, string.digits,
1905 68857643 Michael Hanselmann
                 utils.GenerateSecret(numbytes=4),
1906 68857643 Michael Hanselmann
                 utils.GenerateSecret(numbytes=16),
1907 68857643 Michael Hanselmann
                 "{123:456}".encode("hex")]:
1908 68857643 Michael Hanselmann
      signed_pem = utils.SignX509Certificate(cert, self.KEY, salt)
1909 68857643 Michael Hanselmann
1910 68857643 Michael Hanselmann
      self._Check(cert, salt, signed_pem)
1911 68857643 Michael Hanselmann
1912 68857643 Michael Hanselmann
      self._Check(cert, salt, "X-Another-Header: with a value\n" + signed_pem)
1913 68857643 Michael Hanselmann
      self._Check(cert, salt, (10 * "Hello World!\n") + signed_pem)
1914 68857643 Michael Hanselmann
      self._Check(cert, salt, (signed_pem + "\n\na few more\n"
1915 68857643 Michael Hanselmann
                               "lines----\n------ at\nthe end!"))
1916 68857643 Michael Hanselmann
1917 68857643 Michael Hanselmann
  def _Check(self, cert, salt, pem):
1918 68857643 Michael Hanselmann
    (cert2, salt2) = utils.LoadSignedX509Certificate(pem, self.KEY)
1919 68857643 Michael Hanselmann
    self.assertEqual(salt, salt2)
1920 68857643 Michael Hanselmann
    self.assertEqual(cert.digest("sha1"), cert2.digest("sha1"))
1921 68857643 Michael Hanselmann
1922 68857643 Michael Hanselmann
    # Other key
1923 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
1924 68857643 Michael Hanselmann
                      pem, self.KEY_OTHER)
1925 68857643 Michael Hanselmann
1926 68857643 Michael Hanselmann
1927 76e5f8b5 Michael Hanselmann
class TestMakedirs(unittest.TestCase):
1928 76e5f8b5 Michael Hanselmann
  def setUp(self):
1929 76e5f8b5 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
1930 76e5f8b5 Michael Hanselmann
1931 76e5f8b5 Michael Hanselmann
  def tearDown(self):
1932 76e5f8b5 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
1933 76e5f8b5 Michael Hanselmann
1934 76e5f8b5 Michael Hanselmann
  def testNonExisting(self):
1935 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "foo")
1936 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
1937 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
1938 76e5f8b5 Michael Hanselmann
1939 76e5f8b5 Michael Hanselmann
  def testExisting(self):
1940 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "foo")
1941 76e5f8b5 Michael Hanselmann
    os.mkdir(path)
1942 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
1943 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
1944 76e5f8b5 Michael Hanselmann
1945 76e5f8b5 Michael Hanselmann
  def testRecursiveNonExisting(self):
1946 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "foo/bar/baz")
1947 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
1948 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
1949 76e5f8b5 Michael Hanselmann
1950 76e5f8b5 Michael Hanselmann
  def testRecursiveExisting(self):
1951 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "B/moo/xyz")
1952 158206e0 Manuel Franceschini
    self.assertFalse(os.path.exists(path))
1953 a744b676 Manuel Franceschini
    os.mkdir(PathJoin(self.tmpdir, "B"))
1954 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
1955 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
1956 76e5f8b5 Michael Hanselmann
1957 76e5f8b5 Michael Hanselmann
1958 1b429e2a Iustin Pop
class TestRetry(testutils.GanetiTestCase):
1959 45cc4913 Guido Trotter
  def setUp(self):
1960 45cc4913 Guido Trotter
    testutils.GanetiTestCase.setUp(self)
1961 45cc4913 Guido Trotter
    self.retries = 0
1962 45cc4913 Guido Trotter
1963 1b429e2a Iustin Pop
  @staticmethod
1964 1b429e2a Iustin Pop
  def _RaiseRetryAgain():
1965 1b429e2a Iustin Pop
    raise utils.RetryAgain()
1966 1b429e2a Iustin Pop
1967 506be7c5 Guido Trotter
  @staticmethod
1968 506be7c5 Guido Trotter
  def _RaiseRetryAgainWithArg(args):
1969 506be7c5 Guido Trotter
    raise utils.RetryAgain(*args)
1970 506be7c5 Guido Trotter
1971 1b429e2a Iustin Pop
  def _WrongNestedLoop(self):
1972 1b429e2a Iustin Pop
    return utils.Retry(self._RaiseRetryAgain, 0.01, 0.02)
1973 1b429e2a Iustin Pop
1974 45cc4913 Guido Trotter
  def _RetryAndSucceed(self, retries):
1975 45cc4913 Guido Trotter
    if self.retries < retries:
1976 45cc4913 Guido Trotter
      self.retries += 1
1977 45cc4913 Guido Trotter
      raise utils.RetryAgain()
1978 45cc4913 Guido Trotter
    else:
1979 45cc4913 Guido Trotter
      return True
1980 45cc4913 Guido Trotter
1981 1b429e2a Iustin Pop
  def testRaiseTimeout(self):
1982 1b429e2a Iustin Pop
    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
1983 1b429e2a Iustin Pop
                          self._RaiseRetryAgain, 0.01, 0.02)
1984 45cc4913 Guido Trotter
    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
1985 45cc4913 Guido Trotter
                          self._RetryAndSucceed, 0.01, 0, args=[1])
1986 45cc4913 Guido Trotter
    self.failUnlessEqual(self.retries, 1)
1987 1b429e2a Iustin Pop
1988 1b429e2a Iustin Pop
  def testComplete(self):
1989 1b429e2a Iustin Pop
    self.failUnlessEqual(utils.Retry(lambda: True, 0, 1), True)
1990 45cc4913 Guido Trotter
    self.failUnlessEqual(utils.Retry(self._RetryAndSucceed, 0, 1, args=[2]),
1991 45cc4913 Guido Trotter
                         True)
1992 45cc4913 Guido Trotter
    self.failUnlessEqual(self.retries, 2)
1993 1b429e2a Iustin Pop
1994 1b429e2a Iustin Pop
  def testNestedLoop(self):
1995 1b429e2a Iustin Pop
    try:
1996 1b429e2a Iustin Pop
      self.failUnlessRaises(errors.ProgrammerError, utils.Retry,
1997 1b429e2a Iustin Pop
                            self._WrongNestedLoop, 0, 1)
1998 1b429e2a Iustin Pop
    except utils.RetryTimeout:
1999 1b429e2a Iustin Pop
      self.fail("Didn't detect inner loop's exception")
2000 1b429e2a Iustin Pop
2001 506be7c5 Guido Trotter
  def testTimeoutArgument(self):
2002 506be7c5 Guido Trotter
    retry_arg="my_important_debugging_message"
2003 506be7c5 Guido Trotter
    try:
2004 506be7c5 Guido Trotter
      utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02, args=[[retry_arg]])
2005 506be7c5 Guido Trotter
    except utils.RetryTimeout, err:
2006 506be7c5 Guido Trotter
      self.failUnlessEqual(err.args, (retry_arg, ))
2007 506be7c5 Guido Trotter
    else:
2008 506be7c5 Guido Trotter
      self.fail("Expected timeout didn't happen")
2009 506be7c5 Guido Trotter
2010 506be7c5 Guido Trotter
  def testRaiseInnerWithExc(self):
2011 506be7c5 Guido Trotter
    retry_arg="my_important_debugging_message"
2012 506be7c5 Guido Trotter
    try:
2013 506be7c5 Guido Trotter
      try:
2014 506be7c5 Guido Trotter
        utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02,
2015 506be7c5 Guido Trotter
                    args=[[errors.GenericError(retry_arg, retry_arg)]])
2016 506be7c5 Guido Trotter
      except utils.RetryTimeout, err:
2017 506be7c5 Guido Trotter
        err.RaiseInner()
2018 506be7c5 Guido Trotter
      else:
2019 506be7c5 Guido Trotter
        self.fail("Expected timeout didn't happen")
2020 506be7c5 Guido Trotter
    except errors.GenericError, err:
2021 506be7c5 Guido Trotter
      self.failUnlessEqual(err.args, (retry_arg, retry_arg))
2022 506be7c5 Guido Trotter
    else:
2023 506be7c5 Guido Trotter
      self.fail("Expected GenericError didn't happen")
2024 506be7c5 Guido Trotter
2025 506be7c5 Guido Trotter
  def testRaiseInnerWithMsg(self):
2026 506be7c5 Guido Trotter
    retry_arg="my_important_debugging_message"
2027 506be7c5 Guido Trotter
    try:
2028 506be7c5 Guido Trotter
      try:
2029 506be7c5 Guido Trotter
        utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02,
2030 506be7c5 Guido Trotter
                    args=[[retry_arg, retry_arg]])
2031 506be7c5 Guido Trotter
      except utils.RetryTimeout, err:
2032 506be7c5 Guido Trotter
        err.RaiseInner()
2033 506be7c5 Guido Trotter
      else:
2034 506be7c5 Guido Trotter
        self.fail("Expected timeout didn't happen")
2035 506be7c5 Guido Trotter
    except utils.RetryTimeout, err:
2036 506be7c5 Guido Trotter
      self.failUnlessEqual(err.args, (retry_arg, retry_arg))
2037 506be7c5 Guido Trotter
    else:
2038 506be7c5 Guido Trotter
      self.fail("Expected RetryTimeout didn't happen")
2039 506be7c5 Guido Trotter
2040 1b429e2a Iustin Pop
2041 339be5a8 Michael Hanselmann
class TestLineSplitter(unittest.TestCase):
2042 339be5a8 Michael Hanselmann
  def test(self):
2043 339be5a8 Michael Hanselmann
    lines = []
2044 339be5a8 Michael Hanselmann
    ls = utils.LineSplitter(lines.append)
2045 339be5a8 Michael Hanselmann
    ls.write("Hello World\n")
2046 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
2047 339be5a8 Michael Hanselmann
    ls.write("Foo\n Bar\r\n ")
2048 339be5a8 Michael Hanselmann
    ls.write("Baz")
2049 339be5a8 Michael Hanselmann
    ls.write("Moo")
2050 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
2051 339be5a8 Michael Hanselmann
    ls.flush()
2052 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["Hello World", "Foo", " Bar"])
2053 339be5a8 Michael Hanselmann
    ls.close()
2054 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["Hello World", "Foo", " Bar", " BazMoo"])
2055 339be5a8 Michael Hanselmann
2056 339be5a8 Michael Hanselmann
  def _testExtra(self, line, all_lines, p1, p2):
2057 339be5a8 Michael Hanselmann
    self.assertEqual(p1, 999)
2058 339be5a8 Michael Hanselmann
    self.assertEqual(p2, "extra")
2059 339be5a8 Michael Hanselmann
    all_lines.append(line)
2060 339be5a8 Michael Hanselmann
2061 339be5a8 Michael Hanselmann
  def testExtraArgsNoFlush(self):
2062 339be5a8 Michael Hanselmann
    lines = []
2063 339be5a8 Michael Hanselmann
    ls = utils.LineSplitter(self._testExtra, lines, 999, "extra")
2064 339be5a8 Michael Hanselmann
    ls.write("\n\nHello World\n")
2065 339be5a8 Michael Hanselmann
    ls.write("Foo\n Bar\r\n ")
2066 339be5a8 Michael Hanselmann
    ls.write("")
2067 339be5a8 Michael Hanselmann
    ls.write("Baz")
2068 339be5a8 Michael Hanselmann
    ls.write("Moo\n\nx\n")
2069 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
2070 339be5a8 Michael Hanselmann
    ls.close()
2071 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["", "", "Hello World", "Foo", " Bar", " BazMoo",
2072 339be5a8 Michael Hanselmann
                             "", "x"])
2073 339be5a8 Michael Hanselmann
2074 339be5a8 Michael Hanselmann
2075 debed9ae Michael Hanselmann
class TestReadLockedPidFile(unittest.TestCase):
2076 debed9ae Michael Hanselmann
  def setUp(self):
2077 debed9ae Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
2078 debed9ae Michael Hanselmann
2079 debed9ae Michael Hanselmann
  def tearDown(self):
2080 debed9ae Michael Hanselmann
    shutil.rmtree(self.tmpdir)
2081 debed9ae Michael Hanselmann
2082 debed9ae Michael Hanselmann
  def testNonExistent(self):
2083 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "nonexist")
2084 debed9ae Michael Hanselmann
    self.assert_(utils.ReadLockedPidFile(path) is None)
2085 debed9ae Michael Hanselmann
2086 debed9ae Michael Hanselmann
  def testUnlocked(self):
2087 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "pid")
2088 debed9ae Michael Hanselmann
    utils.WriteFile(path, data="123")
2089 debed9ae Michael Hanselmann
    self.assert_(utils.ReadLockedPidFile(path) is None)
2090 debed9ae Michael Hanselmann
2091 debed9ae Michael Hanselmann
  def testLocked(self):
2092 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "pid")
2093 debed9ae Michael Hanselmann
    utils.WriteFile(path, data="123")
2094 debed9ae Michael Hanselmann
2095 debed9ae Michael Hanselmann
    fl = utils.FileLock.Open(path)
2096 debed9ae Michael Hanselmann
    try:
2097 debed9ae Michael Hanselmann
      fl.Exclusive(blocking=True)
2098 debed9ae Michael Hanselmann
2099 debed9ae Michael Hanselmann
      self.assertEqual(utils.ReadLockedPidFile(path), 123)
2100 debed9ae Michael Hanselmann
    finally:
2101 debed9ae Michael Hanselmann
      fl.Close()
2102 debed9ae Michael Hanselmann
2103 debed9ae Michael Hanselmann
    self.assert_(utils.ReadLockedPidFile(path) is None)
2104 debed9ae Michael Hanselmann
2105 debed9ae Michael Hanselmann
  def testError(self):
2106 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "foobar", "pid")
2107 a744b676 Manuel Franceschini
    utils.WriteFile(PathJoin(self.tmpdir, "foobar"), data="")
2108 debed9ae Michael Hanselmann
    # open(2) should return ENOTDIR
2109 debed9ae Michael Hanselmann
    self.assertRaises(EnvironmentError, utils.ReadLockedPidFile, path)
2110 debed9ae Michael Hanselmann
2111 debed9ae Michael Hanselmann
2112 24d70417 Michael Hanselmann
class TestCertVerification(testutils.GanetiTestCase):
2113 24d70417 Michael Hanselmann
  def setUp(self):
2114 24d70417 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
2115 24d70417 Michael Hanselmann
2116 24d70417 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
2117 24d70417 Michael Hanselmann
2118 24d70417 Michael Hanselmann
  def tearDown(self):
2119 24d70417 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
2120 24d70417 Michael Hanselmann
2121 24d70417 Michael Hanselmann
  def testVerifyCertificate(self):
2122 24d70417 Michael Hanselmann
    cert_pem = utils.ReadFile(self._TestDataFilename("cert1.pem"))
2123 24d70417 Michael Hanselmann
    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
2124 24d70417 Michael Hanselmann
                                           cert_pem)
2125 24d70417 Michael Hanselmann
2126 24d70417 Michael Hanselmann
    # Not checking return value as this certificate is expired
2127 24d70417 Michael Hanselmann
    utils.VerifyX509Certificate(cert, 30, 7)
2128 24d70417 Michael Hanselmann
2129 24d70417 Michael Hanselmann
2130 24d70417 Michael Hanselmann
class TestVerifyCertificateInner(unittest.TestCase):
2131 24d70417 Michael Hanselmann
  def test(self):
2132 24d70417 Michael Hanselmann
    vci = utils._VerifyCertificateInner
2133 24d70417 Michael Hanselmann
2134 24d70417 Michael Hanselmann
    # Valid
2135 24d70417 Michael Hanselmann
    self.assertEqual(vci(False, 1263916313, 1298476313, 1266940313, 30, 7),
2136 24d70417 Michael Hanselmann
                     (None, None))
2137 24d70417 Michael Hanselmann
2138 24d70417 Michael Hanselmann
    # Not yet valid
2139 24d70417 Michael Hanselmann
    (errcode, msg) = vci(False, 1266507600, 1267544400, 1266075600, 30, 7)
2140 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_WARNING)
2141 24d70417 Michael Hanselmann
2142 24d70417 Michael Hanselmann
    # Expiring soon
2143 24d70417 Michael Hanselmann
    (errcode, msg) = vci(False, 1266507600, 1267544400, 1266939600, 30, 7)
2144 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2145 24d70417 Michael Hanselmann
2146 24d70417 Michael Hanselmann
    (errcode, msg) = vci(False, 1266507600, 1267544400, 1266939600, 30, 1)
2147 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_WARNING)
2148 24d70417 Michael Hanselmann
2149 24d70417 Michael Hanselmann
    (errcode, msg) = vci(False, 1266507600, None, 1266939600, 30, 7)
2150 24d70417 Michael Hanselmann
    self.assertEqual(errcode, None)
2151 24d70417 Michael Hanselmann
2152 24d70417 Michael Hanselmann
    # Expired
2153 24d70417 Michael Hanselmann
    (errcode, msg) = vci(True, 1266507600, 1267544400, 1266939600, 30, 7)
2154 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2155 24d70417 Michael Hanselmann
2156 24d70417 Michael Hanselmann
    (errcode, msg) = vci(True, None, 1267544400, 1266939600, 30, 7)
2157 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2158 24d70417 Michael Hanselmann
2159 24d70417 Michael Hanselmann
    (errcode, msg) = vci(True, 1266507600, None, 1266939600, 30, 7)
2160 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2161 24d70417 Michael Hanselmann
2162 24d70417 Michael Hanselmann
    (errcode, msg) = vci(True, None, None, 1266939600, 30, 7)
2163 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2164 24d70417 Michael Hanselmann
2165 24d70417 Michael Hanselmann
2166 615aaaba Michael Hanselmann
class TestHmacFunctions(unittest.TestCase):
2167 615aaaba Michael Hanselmann
  # Digests can be checked with "openssl sha1 -hmac $key"
2168 615aaaba Michael Hanselmann
  def testSha1Hmac(self):
2169 615aaaba Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("", ""),
2170 615aaaba Michael Hanselmann
                     "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d")
2171 615aaaba Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("3YzMxZWE", "Hello World"),
2172 615aaaba Michael Hanselmann
                     "ef4f3bda82212ecb2f7ce868888a19092481f1fd")
2173 615aaaba Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("TguMTA2K", ""),
2174 615aaaba Michael Hanselmann
                     "f904c2476527c6d3e6609ab683c66fa0652cb1dc")
2175 615aaaba Michael Hanselmann
2176 615aaaba Michael Hanselmann
    longtext = 1500 * "The quick brown fox jumps over the lazy dog\n"
2177 615aaaba Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("3YzMxZWE", longtext),
2178 615aaaba Michael Hanselmann
                     "35901b9a3001a7cdcf8e0e9d7c2e79df2223af54")
2179 615aaaba Michael Hanselmann
2180 3718bf6d Michael Hanselmann
  def testSha1HmacSalt(self):
2181 3718bf6d Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("TguMTA2K", "", salt="abc0"),
2182 3718bf6d Michael Hanselmann
                     "4999bf342470eadb11dfcd24ca5680cf9fd7cdce")
2183 3718bf6d Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("TguMTA2K", "", salt="abc9"),
2184 3718bf6d Michael Hanselmann
                     "17a4adc34d69c0d367d4ffbef96fd41d4df7a6e8")
2185 3718bf6d Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("3YzMxZWE", "Hello World", salt="xyz0"),
2186 3718bf6d Michael Hanselmann
                     "7f264f8114c9066afc9bb7636e1786d996d3cc0d")
2187 3718bf6d Michael Hanselmann
2188 615aaaba Michael Hanselmann
  def testVerifySha1Hmac(self):
2189 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("", "", ("fbdb1d1b18aa6c08324b"
2190 615aaaba Michael Hanselmann
                                               "7d64b71fb76370690e1d")))
2191 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("TguMTA2K", "",
2192 615aaaba Michael Hanselmann
                                      ("f904c2476527c6d3e660"
2193 615aaaba Michael Hanselmann
                                       "9ab683c66fa0652cb1dc")))
2194 615aaaba Michael Hanselmann
2195 615aaaba Michael Hanselmann
    digest = "ef4f3bda82212ecb2f7ce868888a19092481f1fd"
2196 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World", digest))
2197 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World",
2198 615aaaba Michael Hanselmann
                                      digest.lower()))
2199 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World",
2200 615aaaba Michael Hanselmann
                                      digest.upper()))
2201 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World",
2202 615aaaba Michael Hanselmann
                                      digest.title()))
2203 615aaaba Michael Hanselmann
2204 3718bf6d Michael Hanselmann
  def testVerifySha1HmacSalt(self):
2205 3718bf6d Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("TguMTA2K", "",
2206 3718bf6d Michael Hanselmann
                                      ("17a4adc34d69c0d367d4"
2207 3718bf6d Michael Hanselmann
                                       "ffbef96fd41d4df7a6e8"),
2208 3718bf6d Michael Hanselmann
                                      salt="abc9"))
2209 3718bf6d Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World",
2210 3718bf6d Michael Hanselmann
                                      ("7f264f8114c9066afc9b"
2211 3718bf6d Michael Hanselmann
                                       "b7636e1786d996d3cc0d"),
2212 3718bf6d Michael Hanselmann
                                      salt="xyz0"))
2213 3718bf6d Michael Hanselmann
2214 615aaaba Michael Hanselmann
2215 232144d0 Guido Trotter
class TestIgnoreSignals(unittest.TestCase):
2216 232144d0 Guido Trotter
  """Test the IgnoreSignals decorator"""
2217 232144d0 Guido Trotter
2218 232144d0 Guido Trotter
  @staticmethod
2219 232144d0 Guido Trotter
  def _Raise(exception):
2220 232144d0 Guido Trotter
    raise exception
2221 232144d0 Guido Trotter
2222 232144d0 Guido Trotter
  @staticmethod
2223 232144d0 Guido Trotter
  def _Return(rval):
2224 232144d0 Guido Trotter
    return rval
2225 232144d0 Guido Trotter
2226 232144d0 Guido Trotter
  def testIgnoreSignals(self):
2227 232144d0 Guido Trotter
    sock_err_intr = socket.error(errno.EINTR, "Message")
2228 232144d0 Guido Trotter
    sock_err_inval = socket.error(errno.EINVAL, "Message")
2229 232144d0 Guido Trotter
2230 232144d0 Guido Trotter
    env_err_intr = EnvironmentError(errno.EINTR, "Message")
2231 232144d0 Guido Trotter
    env_err_inval = EnvironmentError(errno.EINVAL, "Message")
2232 232144d0 Guido Trotter
2233 232144d0 Guido Trotter
    self.assertRaises(socket.error, self._Raise, sock_err_intr)
2234 232144d0 Guido Trotter
    self.assertRaises(socket.error, self._Raise, sock_err_inval)
2235 232144d0 Guido Trotter
    self.assertRaises(EnvironmentError, self._Raise, env_err_intr)
2236 232144d0 Guido Trotter
    self.assertRaises(EnvironmentError, self._Raise, env_err_inval)
2237 232144d0 Guido Trotter
2238 232144d0 Guido Trotter
    self.assertEquals(utils.IgnoreSignals(self._Raise, sock_err_intr), None)
2239 232144d0 Guido Trotter
    self.assertEquals(utils.IgnoreSignals(self._Raise, env_err_intr), None)
2240 232144d0 Guido Trotter
    self.assertRaises(socket.error, utils.IgnoreSignals, self._Raise,
2241 232144d0 Guido Trotter
                      sock_err_inval)
2242 232144d0 Guido Trotter
    self.assertRaises(EnvironmentError, utils.IgnoreSignals, self._Raise,
2243 232144d0 Guido Trotter
                      env_err_inval)
2244 232144d0 Guido Trotter
2245 232144d0 Guido Trotter
    self.assertEquals(utils.IgnoreSignals(self._Return, True), True)
2246 232144d0 Guido Trotter
    self.assertEquals(utils.IgnoreSignals(self._Return, 33), 33)
2247 232144d0 Guido Trotter
2248 232144d0 Guido Trotter
2249 b73360e3 Balazs Lecz
class TestEnsureDirs(unittest.TestCase):
2250 b73360e3 Balazs Lecz
  """Tests for EnsureDirs"""
2251 b73360e3 Balazs Lecz
2252 b73360e3 Balazs Lecz
  def setUp(self):
2253 b73360e3 Balazs Lecz
    self.dir = tempfile.mkdtemp()
2254 b73360e3 Balazs Lecz
    self.old_umask = os.umask(0777)
2255 b73360e3 Balazs Lecz
2256 b73360e3 Balazs Lecz
  def testEnsureDirs(self):
2257 b73360e3 Balazs Lecz
    utils.EnsureDirs([
2258 a744b676 Manuel Franceschini
        (PathJoin(self.dir, "foo"), 0777),
2259 a744b676 Manuel Franceschini
        (PathJoin(self.dir, "bar"), 0000),
2260 b73360e3 Balazs Lecz
        ])
2261 a744b676 Manuel Franceschini
    self.assertEquals(os.stat(PathJoin(self.dir, "foo"))[0] & 0777, 0777)
2262 a744b676 Manuel Franceschini
    self.assertEquals(os.stat(PathJoin(self.dir, "bar"))[0] & 0777, 0000)
2263 b73360e3 Balazs Lecz
2264 b73360e3 Balazs Lecz
  def tearDown(self):
2265 a744b676 Manuel Franceschini
    os.rmdir(PathJoin(self.dir, "foo"))
2266 a744b676 Manuel Franceschini
    os.rmdir(PathJoin(self.dir, "bar"))
2267 b73360e3 Balazs Lecz
    os.rmdir(self.dir)
2268 b73360e3 Balazs Lecz
    os.umask(self.old_umask)
2269 b73360e3 Balazs Lecz
2270 f8ea4ada Michael Hanselmann
2271 f8ea4ada Michael Hanselmann
class TestFormatSeconds(unittest.TestCase):
2272 f8ea4ada Michael Hanselmann
  def test(self):
2273 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(1), "1s")
2274 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(3600), "1h 0m 0s")
2275 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(3599), "59m 59s")
2276 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(7200), "2h 0m 0s")
2277 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(7201), "2h 0m 1s")
2278 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(7281), "2h 1m 21s")
2279 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(29119), "8h 5m 19s")
2280 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(19431228), "224d 21h 33m 48s")
2281 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(-1), "-1s")
2282 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(-282), "-282s")
2283 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(-29119), "-29119s")
2284 f8ea4ada Michael Hanselmann
2285 f8ea4ada Michael Hanselmann
  def testFloat(self):
2286 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(1.3), "1s")
2287 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(1.9), "2s")
2288 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(3912.12311), "1h 5m 12s")
2289 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(3912.8), "1h 5m 13s")
2290 f8ea4ada Michael Hanselmann
2291 f8ea4ada Michael Hanselmann
2292 9dc71d5a Michael Hanselmann
class TestIgnoreProcessNotFound(unittest.TestCase):
2293 560cbec1 Michael Hanselmann
  @staticmethod
2294 560cbec1 Michael Hanselmann
  def _WritePid(fd):
2295 560cbec1 Michael Hanselmann
    os.write(fd, str(os.getpid()))
2296 560cbec1 Michael Hanselmann
    os.close(fd)
2297 560cbec1 Michael Hanselmann
    return True
2298 560cbec1 Michael Hanselmann
2299 560cbec1 Michael Hanselmann
  def test(self):
2300 560cbec1 Michael Hanselmann
    (pid_read_fd, pid_write_fd) = os.pipe()
2301 560cbec1 Michael Hanselmann
2302 560cbec1 Michael Hanselmann
    # Start short-lived process which writes its PID to pipe
2303 560cbec1 Michael Hanselmann
    self.assert_(utils.RunInSeparateProcess(self._WritePid, pid_write_fd))
2304 560cbec1 Michael Hanselmann
    os.close(pid_write_fd)
2305 560cbec1 Michael Hanselmann
2306 560cbec1 Michael Hanselmann
    # Read PID from pipe
2307 560cbec1 Michael Hanselmann
    pid = int(os.read(pid_read_fd, 1024))
2308 560cbec1 Michael Hanselmann
    os.close(pid_read_fd)
2309 560cbec1 Michael Hanselmann
2310 560cbec1 Michael Hanselmann
    # Try to send signal to process which exited recently
2311 560cbec1 Michael Hanselmann
    self.assertFalse(utils.IgnoreProcessNotFound(os.kill, pid, 0))
2312 560cbec1 Michael Hanselmann
2313 560cbec1 Michael Hanselmann
2314 858905fb Michael Hanselmann
class TestShellWriter(unittest.TestCase):
2315 858905fb Michael Hanselmann
  def test(self):
2316 858905fb Michael Hanselmann
    buf = StringIO()
2317 858905fb Michael Hanselmann
    sw = utils.ShellWriter(buf)
2318 858905fb Michael Hanselmann
    sw.Write("#!/bin/bash")
2319 858905fb Michael Hanselmann
    sw.Write("if true; then")
2320 858905fb Michael Hanselmann
    sw.IncIndent()
2321 858905fb Michael Hanselmann
    try:
2322 858905fb Michael Hanselmann
      sw.Write("echo true")
2323 858905fb Michael Hanselmann
2324 858905fb Michael Hanselmann
      sw.Write("for i in 1 2 3")
2325 858905fb Michael Hanselmann
      sw.Write("do")
2326 858905fb Michael Hanselmann
      sw.IncIndent()
2327 858905fb Michael Hanselmann
      try:
2328 858905fb Michael Hanselmann
        self.assertEqual(sw._indent, 2)
2329 858905fb Michael Hanselmann
        sw.Write("date")
2330 858905fb Michael Hanselmann
      finally:
2331 858905fb Michael Hanselmann
        sw.DecIndent()
2332 858905fb Michael Hanselmann
      sw.Write("done")
2333 858905fb Michael Hanselmann
    finally:
2334 858905fb Michael Hanselmann
      sw.DecIndent()
2335 858905fb Michael Hanselmann
    sw.Write("echo %s", utils.ShellQuote("Hello World"))
2336 858905fb Michael Hanselmann
    sw.Write("exit 0")
2337 858905fb Michael Hanselmann
2338 858905fb Michael Hanselmann
    self.assertEqual(sw._indent, 0)
2339 858905fb Michael Hanselmann
2340 858905fb Michael Hanselmann
    output = buf.getvalue()
2341 858905fb Michael Hanselmann
2342 858905fb Michael Hanselmann
    self.assert_(output.endswith("\n"))
2343 858905fb Michael Hanselmann
2344 858905fb Michael Hanselmann
    lines = output.splitlines()
2345 858905fb Michael Hanselmann
    self.assertEqual(len(lines), 9)
2346 858905fb Michael Hanselmann
    self.assertEqual(lines[0], "#!/bin/bash")
2347 858905fb Michael Hanselmann
    self.assert_(re.match(r"^\s+date$", lines[5]))
2348 858905fb Michael Hanselmann
    self.assertEqual(lines[7], "echo 'Hello World'")
2349 858905fb Michael Hanselmann
2350 858905fb Michael Hanselmann
  def testEmpty(self):
2351 858905fb Michael Hanselmann
    buf = StringIO()
2352 858905fb Michael Hanselmann
    sw = utils.ShellWriter(buf)
2353 858905fb Michael Hanselmann
    sw = None
2354 858905fb Michael Hanselmann
    self.assertEqual(buf.getvalue(), "")
2355 858905fb Michael Hanselmann
2356 858905fb Michael Hanselmann
2357 750022e0 Michael Hanselmann
class TestCommaJoin(unittest.TestCase):
2358 750022e0 Michael Hanselmann
  def test(self):
2359 750022e0 Michael Hanselmann
    self.assertEqual(utils.CommaJoin([]), "")
2360 750022e0 Michael Hanselmann
    self.assertEqual(utils.CommaJoin([1, 2, 3]), "1, 2, 3")
2361 750022e0 Michael Hanselmann
    self.assertEqual(utils.CommaJoin(["Hello"]), "Hello")
2362 750022e0 Michael Hanselmann
    self.assertEqual(utils.CommaJoin(["Hello", "World"]), "Hello, World")
2363 750022e0 Michael Hanselmann
    self.assertEqual(utils.CommaJoin(["Hello", "World", 99]),
2364 750022e0 Michael Hanselmann
                     "Hello, World, 99")
2365 750022e0 Michael Hanselmann
2366 750022e0 Michael Hanselmann
2367 691c81b7 Michael Hanselmann
class TestFindMatch(unittest.TestCase):
2368 691c81b7 Michael Hanselmann
  def test(self):
2369 691c81b7 Michael Hanselmann
    data = {
2370 691c81b7 Michael Hanselmann
      "aaaa": "Four A",
2371 691c81b7 Michael Hanselmann
      "bb": {"Two B": True},
2372 691c81b7 Michael Hanselmann
      re.compile(r"^x(foo|bar|bazX)([0-9]+)$"): (1, 2, 3),
2373 691c81b7 Michael Hanselmann
      }
2374 691c81b7 Michael Hanselmann
2375 691c81b7 Michael Hanselmann
    self.assertEqual(utils.FindMatch(data, "aaaa"), ("Four A", []))
2376 691c81b7 Michael Hanselmann
    self.assertEqual(utils.FindMatch(data, "bb"), ({"Two B": True}, []))
2377 691c81b7 Michael Hanselmann
2378 691c81b7 Michael Hanselmann
    for i in ["foo", "bar", "bazX"]:
2379 691c81b7 Michael Hanselmann
      for j in range(1, 100, 7):
2380 691c81b7 Michael Hanselmann
        self.assertEqual(utils.FindMatch(data, "x%s%s" % (i, j)),
2381 691c81b7 Michael Hanselmann
                         ((1, 2, 3), [i, str(j)]))
2382 691c81b7 Michael Hanselmann
2383 691c81b7 Michael Hanselmann
  def testNoMatch(self):
2384 691c81b7 Michael Hanselmann
    self.assert_(utils.FindMatch({}, "") is None)
2385 691c81b7 Michael Hanselmann
    self.assert_(utils.FindMatch({}, "foo") is None)
2386 691c81b7 Michael Hanselmann
    self.assert_(utils.FindMatch({}, 1234) is None)
2387 691c81b7 Michael Hanselmann
2388 691c81b7 Michael Hanselmann
    data = {
2389 691c81b7 Michael Hanselmann
      "X": "Hello World",
2390 691c81b7 Michael Hanselmann
      re.compile("^(something)$"): "Hello World",
2391 691c81b7 Michael Hanselmann
      }
2392 691c81b7 Michael Hanselmann
2393 691c81b7 Michael Hanselmann
    self.assert_(utils.FindMatch(data, "") is None)
2394 691c81b7 Michael Hanselmann
    self.assert_(utils.FindMatch(data, "Hello World") is None)
2395 691c81b7 Michael Hanselmann
2396 691c81b7 Michael Hanselmann
2397 9e100285 Iustin Pop
class TestFileID(testutils.GanetiTestCase):
2398 9e100285 Iustin Pop
  def testEquality(self):
2399 9e100285 Iustin Pop
    name = self._CreateTempFile()
2400 9e100285 Iustin Pop
    oldi = utils.GetFileID(path=name)
2401 9e100285 Iustin Pop
    self.failUnless(utils.VerifyFileID(oldi, oldi))
2402 9e100285 Iustin Pop
2403 9e100285 Iustin Pop
  def testUpdate(self):
2404 9e100285 Iustin Pop
    name = self._CreateTempFile()
2405 9e100285 Iustin Pop
    oldi = utils.GetFileID(path=name)
2406 9e100285 Iustin Pop
    os.utime(name, None)
2407 9e100285 Iustin Pop
    fd = os.open(name, os.O_RDWR)
2408 9e100285 Iustin Pop
    try:
2409 9e100285 Iustin Pop
      newi = utils.GetFileID(fd=fd)
2410 9e100285 Iustin Pop
      self.failUnless(utils.VerifyFileID(oldi, newi))
2411 9e100285 Iustin Pop
      self.failUnless(utils.VerifyFileID(newi, oldi))
2412 9e100285 Iustin Pop
    finally:
2413 9e100285 Iustin Pop
      os.close(fd)
2414 9e100285 Iustin Pop
2415 4138d39f Iustin Pop
  def testWriteFile(self):
2416 4138d39f Iustin Pop
    name = self._CreateTempFile()
2417 4138d39f Iustin Pop
    oldi = utils.GetFileID(path=name)
2418 4138d39f Iustin Pop
    mtime = oldi[2]
2419 4138d39f Iustin Pop
    os.utime(name, (mtime + 10, mtime + 10))
2420 4138d39f Iustin Pop
    self.assertRaises(errors.LockError, utils.SafeWriteFile, name,
2421 4138d39f Iustin Pop
                      oldi, data="")
2422 4138d39f Iustin Pop
    os.utime(name, (mtime - 10, mtime - 10))
2423 4138d39f Iustin Pop
    utils.SafeWriteFile(name, oldi, data="")
2424 4138d39f Iustin Pop
    oldi = utils.GetFileID(path=name)
2425 4138d39f Iustin Pop
    mtime = oldi[2]
2426 4138d39f Iustin Pop
    os.utime(name, (mtime + 10, mtime + 10))
2427 4138d39f Iustin Pop
    # this doesn't raise, since we passed None
2428 4138d39f Iustin Pop
    utils.SafeWriteFile(name, None, data="")
2429 4138d39f Iustin Pop
2430 9e100285 Iustin Pop
2431 e6784773 René Nussbaumer
class TimeMock:
2432 e6784773 René Nussbaumer
  def __init__(self, values):
2433 e6784773 René Nussbaumer
    self.values = values
2434 e6784773 René Nussbaumer
2435 e6784773 René Nussbaumer
  def __call__(self):
2436 e6784773 René Nussbaumer
    return self.values.pop(0)
2437 e6784773 René Nussbaumer
2438 e6784773 René Nussbaumer
2439 e6784773 René Nussbaumer
class TestRunningTimeout(unittest.TestCase):
2440 e6784773 René Nussbaumer
  def setUp(self):
2441 e6784773 René Nussbaumer
    self.time_fn = TimeMock([0.0, 0.3, 4.6, 6.5])
2442 e6784773 René Nussbaumer
2443 e6784773 René Nussbaumer
  def testRemainingFloat(self):
2444 e6784773 René Nussbaumer
    timeout = utils.RunningTimeout(5.0, True, _time_fn=self.time_fn)
2445 e6784773 René Nussbaumer
    self.assertAlmostEqual(timeout.Remaining(), 4.7)
2446 e6784773 René Nussbaumer
    self.assertAlmostEqual(timeout.Remaining(), 0.4)
2447 e6784773 René Nussbaumer
    self.assertAlmostEqual(timeout.Remaining(), -1.5)
2448 e6784773 René Nussbaumer
2449 e6784773 René Nussbaumer
  def testRemaining(self):
2450 e6784773 René Nussbaumer
    self.time_fn = TimeMock([0, 2, 4, 5, 6])
2451 e6784773 René Nussbaumer
    timeout = utils.RunningTimeout(5, True, _time_fn=self.time_fn)
2452 e6784773 René Nussbaumer
    self.assertEqual(timeout.Remaining(), 3)
2453 e6784773 René Nussbaumer
    self.assertEqual(timeout.Remaining(), 1)
2454 e6784773 René Nussbaumer
    self.assertEqual(timeout.Remaining(), 0)
2455 e6784773 René Nussbaumer
    self.assertEqual(timeout.Remaining(), -1)
2456 e6784773 René Nussbaumer
2457 e6784773 René Nussbaumer
  def testRemainingNonNegative(self):
2458 e6784773 René Nussbaumer
    timeout = utils.RunningTimeout(5.0, False, _time_fn=self.time_fn)
2459 e6784773 René Nussbaumer
    self.assertAlmostEqual(timeout.Remaining(), 4.7)
2460 e6784773 René Nussbaumer
    self.assertAlmostEqual(timeout.Remaining(), 0.4)
2461 e6784773 René Nussbaumer
    self.assertEqual(timeout.Remaining(), 0.0)
2462 e6784773 René Nussbaumer
2463 e6784773 René Nussbaumer
  def testNegativeTimeout(self):
2464 e6784773 René Nussbaumer
    self.assertRaises(ValueError, utils.RunningTimeout, -1.0, True)
2465 e6784773 René Nussbaumer
2466 e6784773 René Nussbaumer
2467 a8083063 Iustin Pop
if __name__ == '__main__':
2468 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()