Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils_unittest.py @ 75561e6b

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