Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils_unittest.py @ f40ae421

History | View | Annotate | Download (87.7 kB)

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