Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils_unittest.py @ 4fd029cf

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