Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils_unittest.py @ 9f5a3645

History | View | Annotate | Download (88.5 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a744b676 Manuel Franceschini
# Copyright (C) 2006, 2007, 2010 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
"""Script for unittesting the utils module"""
23 a8083063 Iustin Pop
24 a744b676 Manuel Franceschini
import distutils.version
25 a744b676 Manuel Franceschini
import errno
26 a744b676 Manuel Franceschini
import fcntl
27 a744b676 Manuel Franceschini
import glob
28 a8083063 Iustin Pop
import os
29 a8083063 Iustin Pop
import os.path
30 a744b676 Manuel Franceschini
import re
31 a744b676 Manuel Franceschini
import shutil
32 740c5aab Guido Trotter
import signal
33 2c30e9d7 Alexander Schreiber
import socket
34 a744b676 Manuel Franceschini
import stat
35 d392fa34 Iustin Pop
import string
36 a744b676 Manuel Franceschini
import tempfile
37 a744b676 Manuel Franceschini
import time
38 a744b676 Manuel Franceschini
import unittest
39 27e46076 Michael Hanselmann
import warnings
40 a744b676 Manuel Franceschini
import OpenSSL
41 858905fb Michael Hanselmann
from cStringIO import StringIO
42 a8083063 Iustin Pop
43 c9c4f19e Michael Hanselmann
import testutils
44 16abfbc2 Alexander Schreiber
from ganeti import constants
45 716a32cb Guido Trotter
from ganeti import compat
46 59072e7e Michael Hanselmann
from ganeti import utils
47 a5728081 Guido Trotter
from ganeti import errors
48 a744b676 Manuel Franceschini
from ganeti.utils import RunCmd, RemoveFile, MatchNameComponent, FormatUnit, \
49 a744b676 Manuel Franceschini
     ParseUnit, ShellQuote, ShellQuoteArgs, ListVisibleFiles, FirstFree, \
50 a744b676 Manuel Franceschini
     TailFile, SafeEncode, FormatTime, UnescapeAndSplit, RunParts, PathJoin, \
51 a744b676 Manuel Franceschini
     ReadOneLineFile, SetEtcHostsEntry, RemoveEtcHostsEntry
52 a8083063 Iustin Pop
53 d9f311d7 Iustin Pop
54 a8083063 Iustin Pop
class TestIsProcessAlive(unittest.TestCase):
55 a8083063 Iustin Pop
  """Testing case for IsProcessAlive"""
56 740c5aab Guido Trotter
57 a8083063 Iustin Pop
  def testExists(self):
58 a8083063 Iustin Pop
    mypid = os.getpid()
59 a744b676 Manuel Franceschini
    self.assert_(utils.IsProcessAlive(mypid), "can't find myself running")
60 a8083063 Iustin Pop
61 a8083063 Iustin Pop
  def testNotExisting(self):
62 09352fa4 Iustin Pop
    pid_non_existing = os.fork()
63 09352fa4 Iustin Pop
    if pid_non_existing == 0:
64 09352fa4 Iustin Pop
      os._exit(0)
65 09352fa4 Iustin Pop
    elif pid_non_existing < 0:
66 09352fa4 Iustin Pop
      raise SystemError("can't fork")
67 09352fa4 Iustin Pop
    os.waitpid(pid_non_existing, 0)
68 a744b676 Manuel Franceschini
    self.assertFalse(utils.IsProcessAlive(pid_non_existing),
69 158206e0 Manuel Franceschini
                     "nonexisting process detected")
70 a8083063 Iustin Pop
71 d9f311d7 Iustin Pop
72 a01b500b Michael Hanselmann
class TestGetProcStatusPath(unittest.TestCase):
73 a01b500b Michael Hanselmann
  def test(self):
74 a01b500b Michael Hanselmann
    self.assert_("/1234/" in utils._GetProcStatusPath(1234))
75 a01b500b Michael Hanselmann
    self.assertNotEqual(utils._GetProcStatusPath(1),
76 a01b500b Michael Hanselmann
                        utils._GetProcStatusPath(2))
77 a01b500b Michael Hanselmann
78 a01b500b Michael Hanselmann
79 a01b500b Michael Hanselmann
class TestIsProcessHandlingSignal(unittest.TestCase):
80 a01b500b Michael Hanselmann
  def setUp(self):
81 a01b500b Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
82 a01b500b Michael Hanselmann
83 a01b500b Michael Hanselmann
  def tearDown(self):
84 a01b500b Michael Hanselmann
    shutil.rmtree(self.tmpdir)
85 a01b500b Michael Hanselmann
86 a01b500b Michael Hanselmann
  def testParseSigsetT(self):
87 a01b500b Michael Hanselmann
    self.assertEqual(len(utils._ParseSigsetT("0")), 0)
88 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("1"), set([1]))
89 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("1000a"), set([2, 4, 17]))
90 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("810002"), set([2, 17, 24, ]))
91 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("0000000180000202"),
92 a01b500b Michael Hanselmann
                     set([2, 10, 32, 33]))
93 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("0000000180000002"),
94 a01b500b Michael Hanselmann
                     set([2, 32, 33]))
95 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("0000000188000002"),
96 a01b500b Michael Hanselmann
                     set([2, 28, 32, 33]))
97 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("000000004b813efb"),
98 a01b500b Michael Hanselmann
                     set([1, 2, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 17,
99 a01b500b Michael Hanselmann
                          24, 25, 26, 28, 31]))
100 a01b500b Michael Hanselmann
    self.assertEqual(utils._ParseSigsetT("ffffff"), set(range(1, 25)))
101 a01b500b Michael Hanselmann
102 a01b500b Michael Hanselmann
  def testGetProcStatusField(self):
103 a01b500b Michael Hanselmann
    for field in ["SigCgt", "Name", "FDSize"]:
104 a01b500b Michael Hanselmann
      for value in ["", "0", "cat", "  1234 KB"]:
105 a01b500b Michael Hanselmann
        pstatus = "\n".join([
106 a01b500b Michael Hanselmann
          "VmPeak: 999 kB",
107 a01b500b Michael Hanselmann
          "%s: %s" % (field, value),
108 a01b500b Michael Hanselmann
          "TracerPid: 0",
109 a01b500b Michael Hanselmann
          ])
110 a01b500b Michael Hanselmann
        result = utils._GetProcStatusField(pstatus, field)
111 a01b500b Michael Hanselmann
        self.assertEqual(result, value.strip())
112 a01b500b Michael Hanselmann
113 a01b500b Michael Hanselmann
  def test(self):
114 a744b676 Manuel Franceschini
    sp = PathJoin(self.tmpdir, "status")
115 a01b500b Michael Hanselmann
116 a01b500b Michael Hanselmann
    utils.WriteFile(sp, data="\n".join([
117 a01b500b Michael Hanselmann
      "Name:   bash",
118 a01b500b Michael Hanselmann
      "State:  S (sleeping)",
119 a01b500b Michael Hanselmann
      "SleepAVG:       98%",
120 a01b500b Michael Hanselmann
      "Pid:    22250",
121 a01b500b Michael Hanselmann
      "PPid:   10858",
122 a01b500b Michael Hanselmann
      "TracerPid:      0",
123 a01b500b Michael Hanselmann
      "SigBlk: 0000000000010000",
124 a01b500b Michael Hanselmann
      "SigIgn: 0000000000384004",
125 a01b500b Michael Hanselmann
      "SigCgt: 000000004b813efb",
126 a01b500b Michael Hanselmann
      "CapEff: 0000000000000000",
127 a01b500b Michael Hanselmann
      ]))
128 a01b500b Michael Hanselmann
129 a01b500b Michael Hanselmann
    self.assert_(utils.IsProcessHandlingSignal(1234, 10, status_path=sp))
130 a01b500b Michael Hanselmann
131 a01b500b Michael Hanselmann
  def testNoSigCgt(self):
132 a744b676 Manuel Franceschini
    sp = PathJoin(self.tmpdir, "status")
133 a01b500b Michael Hanselmann
134 a01b500b Michael Hanselmann
    utils.WriteFile(sp, data="\n".join([
135 a01b500b Michael Hanselmann
      "Name:   bash",
136 a01b500b Michael Hanselmann
      ]))
137 a01b500b Michael Hanselmann
138 a01b500b Michael Hanselmann
    self.assertRaises(RuntimeError, utils.IsProcessHandlingSignal,
139 a01b500b Michael Hanselmann
                      1234, 10, status_path=sp)
140 a01b500b Michael Hanselmann
141 a01b500b Michael Hanselmann
  def testNoSuchFile(self):
142 a744b676 Manuel Franceschini
    sp = PathJoin(self.tmpdir, "notexist")
143 a01b500b Michael Hanselmann
144 a01b500b Michael Hanselmann
    self.assertFalse(utils.IsProcessHandlingSignal(1234, 10, status_path=sp))
145 a01b500b Michael Hanselmann
146 a01b500b Michael Hanselmann
  @staticmethod
147 a01b500b Michael Hanselmann
  def _TestRealProcess():
148 a01b500b Michael Hanselmann
    signal.signal(signal.SIGUSR1, signal.SIG_DFL)
149 a01b500b Michael Hanselmann
    if utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
150 a01b500b Michael Hanselmann
      raise Exception("SIGUSR1 is handled when it should not be")
151 a01b500b Michael Hanselmann
152 a01b500b Michael Hanselmann
    signal.signal(signal.SIGUSR1, lambda signum, frame: None)
153 a01b500b Michael Hanselmann
    if not utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
154 a01b500b Michael Hanselmann
      raise Exception("SIGUSR1 is not handled when it should be")
155 a01b500b Michael Hanselmann
156 a01b500b Michael Hanselmann
    signal.signal(signal.SIGUSR1, signal.SIG_IGN)
157 a01b500b Michael Hanselmann
    if utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
158 a01b500b Michael Hanselmann
      raise Exception("SIGUSR1 is not handled when it should be")
159 a01b500b Michael Hanselmann
160 a01b500b Michael Hanselmann
    signal.signal(signal.SIGUSR1, signal.SIG_DFL)
161 a01b500b Michael Hanselmann
    if utils.IsProcessHandlingSignal(os.getpid(), signal.SIGUSR1):
162 a01b500b Michael Hanselmann
      raise Exception("SIGUSR1 is handled when it should not be")
163 a01b500b Michael Hanselmann
164 a01b500b Michael Hanselmann
    return True
165 a01b500b Michael Hanselmann
166 a01b500b Michael Hanselmann
  def testRealProcess(self):
167 a01b500b Michael Hanselmann
    self.assert_(utils.RunInSeparateProcess(self._TestRealProcess))
168 a01b500b Michael Hanselmann
169 a01b500b Michael Hanselmann
170 af99afa6 Guido Trotter
class TestPidFileFunctions(unittest.TestCase):
171 d9f311d7 Iustin Pop
  """Tests for WritePidFile, RemovePidFile and ReadPidFile"""
172 af99afa6 Guido Trotter
173 af99afa6 Guido Trotter
  def setUp(self):
174 af99afa6 Guido Trotter
    self.dir = tempfile.mkdtemp()
175 af99afa6 Guido Trotter
    self.f_dpn = lambda name: os.path.join(self.dir, "%s.pid" % name)
176 53beffbb Iustin Pop
    utils.DaemonPidFileName = self.f_dpn
177 af99afa6 Guido Trotter
178 af99afa6 Guido Trotter
  def testPidFileFunctions(self):
179 d9f311d7 Iustin Pop
    pid_file = self.f_dpn('test')
180 5c4d37f9 Iustin Pop
    fd = utils.WritePidFile(self.f_dpn('test'))
181 d9f311d7 Iustin Pop
    self.failUnless(os.path.exists(pid_file),
182 d9f311d7 Iustin Pop
                    "PID file should have been created")
183 d9f311d7 Iustin Pop
    read_pid = utils.ReadPidFile(pid_file)
184 d9f311d7 Iustin Pop
    self.failUnlessEqual(read_pid, os.getpid())
185 d9f311d7 Iustin Pop
    self.failUnless(utils.IsProcessAlive(read_pid))
186 5c4d37f9 Iustin Pop
    self.failUnlessRaises(errors.LockError, utils.WritePidFile,
187 5c4d37f9 Iustin Pop
                          self.f_dpn('test'))
188 5c4d37f9 Iustin Pop
    os.close(fd)
189 d9f311d7 Iustin Pop
    utils.RemovePidFile('test')
190 d9f311d7 Iustin Pop
    self.failIf(os.path.exists(pid_file),
191 d9f311d7 Iustin Pop
                "PID file should not exist anymore")
192 d9f311d7 Iustin Pop
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
193 d9f311d7 Iustin Pop
                         "ReadPidFile should return 0 for missing pid file")
194 d9f311d7 Iustin Pop
    fh = open(pid_file, "w")
195 d9f311d7 Iustin Pop
    fh.write("blah\n")
196 d9f311d7 Iustin Pop
    fh.close()
197 d9f311d7 Iustin Pop
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
198 d9f311d7 Iustin Pop
                         "ReadPidFile should return 0 for invalid pid file")
199 5c4d37f9 Iustin Pop
    # but now, even with the file existing, we should be able to lock it
200 5c4d37f9 Iustin Pop
    fd = utils.WritePidFile(self.f_dpn('test'))
201 5c4d37f9 Iustin Pop
    os.close(fd)
202 af99afa6 Guido Trotter
    utils.RemovePidFile('test')
203 d9f311d7 Iustin Pop
    self.failIf(os.path.exists(pid_file),
204 d9f311d7 Iustin Pop
                "PID file should not exist anymore")
205 af99afa6 Guido Trotter
206 b2a1f511 Iustin Pop
  def testKill(self):
207 b2a1f511 Iustin Pop
    pid_file = self.f_dpn('child')
208 b2a1f511 Iustin Pop
    r_fd, w_fd = os.pipe()
209 b2a1f511 Iustin Pop
    new_pid = os.fork()
210 b2a1f511 Iustin Pop
    if new_pid == 0: #child
211 5c4d37f9 Iustin Pop
      utils.WritePidFile(self.f_dpn('child'))
212 b2a1f511 Iustin Pop
      os.write(w_fd, 'a')
213 b2a1f511 Iustin Pop
      signal.pause()
214 b2a1f511 Iustin Pop
      os._exit(0)
215 b2a1f511 Iustin Pop
      return
216 b2a1f511 Iustin Pop
    # else we are in the parent
217 b2a1f511 Iustin Pop
    # wait until the child has written the pid file
218 b2a1f511 Iustin Pop
    os.read(r_fd, 1)
219 b2a1f511 Iustin Pop
    read_pid = utils.ReadPidFile(pid_file)
220 b2a1f511 Iustin Pop
    self.failUnlessEqual(read_pid, new_pid)
221 b2a1f511 Iustin Pop
    self.failUnless(utils.IsProcessAlive(new_pid))
222 ff5251bc Iustin Pop
    utils.KillProcess(new_pid, waitpid=True)
223 b2a1f511 Iustin Pop
    self.failIf(utils.IsProcessAlive(new_pid))
224 b2a1f511 Iustin Pop
    utils.RemovePidFile('child')
225 a744b676 Manuel Franceschini
    self.failUnlessRaises(errors.ProgrammerError, utils.KillProcess, 0)
226 b2a1f511 Iustin Pop
227 af99afa6 Guido Trotter
  def tearDown(self):
228 d9f311d7 Iustin Pop
    for name in os.listdir(self.dir):
229 d9f311d7 Iustin Pop
      os.unlink(os.path.join(self.dir, name))
230 af99afa6 Guido Trotter
    os.rmdir(self.dir)
231 af99afa6 Guido Trotter
232 a8083063 Iustin Pop
233 36117c2b Iustin Pop
class TestRunCmd(testutils.GanetiTestCase):
234 a8083063 Iustin Pop
  """Testing case for the RunCmd function"""
235 a8083063 Iustin Pop
236 a8083063 Iustin Pop
  def setUp(self):
237 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
238 a8083063 Iustin Pop
    self.magic = time.ctime() + " ganeti test"
239 51596eb2 Iustin Pop
    self.fname = self._CreateTempFile()
240 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 9f5a3645 Michael Hanselmann
class TestFindDuplicates(unittest.TestCase):
1341 9f5a3645 Michael Hanselmann
  """Test case for FindDuplicates"""
1342 9f5a3645 Michael Hanselmann
1343 9f5a3645 Michael Hanselmann
  def _Test(self, seq, expected):
1344 9f5a3645 Michael Hanselmann
    result = utils.FindDuplicates(seq)
1345 9f5a3645 Michael Hanselmann
    self.assertEqual(result, utils.UniqueSequence(result))
1346 9f5a3645 Michael Hanselmann
    self.assertEqual(set(result), set(expected))
1347 9f5a3645 Michael Hanselmann
1348 9f5a3645 Michael Hanselmann
  def test(self):
1349 9f5a3645 Michael Hanselmann
    self._Test([], [])
1350 9f5a3645 Michael Hanselmann
    self._Test([1, 2, 3], [])
1351 9f5a3645 Michael Hanselmann
    self._Test([9, 8, 8, 0, 5, 1, 7, 0, 6, 7], [8, 0, 7])
1352 9f5a3645 Michael Hanselmann
    for exp in [[1, 2, 3], [3, 2, 1]]:
1353 9f5a3645 Michael Hanselmann
      self._Test([1, 1, 2, 2, 3, 3], exp)
1354 9f5a3645 Michael Hanselmann
1355 9f5a3645 Michael Hanselmann
    self._Test(["A", "a", "B"], [])
1356 9f5a3645 Michael Hanselmann
    self._Test(["a", "A", "a", "B"], ["a"])
1357 9f5a3645 Michael Hanselmann
    self._Test("Hello World out there!", ["e", " ", "o", "r", "t", "l"])
1358 9f5a3645 Michael Hanselmann
1359 9f5a3645 Michael Hanselmann
    self._Test(self._Gen(False), [])
1360 9f5a3645 Michael Hanselmann
    self._Test(self._Gen(True), range(1, 10))
1361 9f5a3645 Michael Hanselmann
1362 9f5a3645 Michael Hanselmann
  @staticmethod
1363 9f5a3645 Michael Hanselmann
  def _Gen(dup):
1364 9f5a3645 Michael Hanselmann
    for i in range(10):
1365 9f5a3645 Michael Hanselmann
      yield i
1366 9f5a3645 Michael Hanselmann
      if dup:
1367 9f5a3645 Michael Hanselmann
        for _ in range(i):
1368 9f5a3645 Michael Hanselmann
          yield i
1369 9f5a3645 Michael Hanselmann
1370 9f5a3645 Michael Hanselmann
1371 7b4126b7 Iustin Pop
class TestFirstFree(unittest.TestCase):
1372 7b4126b7 Iustin Pop
  """Test case for the FirstFree function"""
1373 7b4126b7 Iustin Pop
1374 7b4126b7 Iustin Pop
  def test(self):
1375 7b4126b7 Iustin Pop
    """Test FirstFree"""
1376 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([0, 1, 3]), 2)
1377 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([]), None)
1378 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([3, 4, 6]), 0)
1379 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([3, 4, 6], base=3), 5)
1380 7b4126b7 Iustin Pop
    self.failUnlessRaises(AssertionError, FirstFree, [0, 3, 4, 6], base=3)
1381 f7414041 Michael Hanselmann
1382 a87b4824 Michael Hanselmann
1383 f65f63ef Iustin Pop
class TestTailFile(testutils.GanetiTestCase):
1384 f65f63ef Iustin Pop
  """Test case for the TailFile function"""
1385 f65f63ef Iustin Pop
1386 f65f63ef Iustin Pop
  def testEmpty(self):
1387 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1388 f65f63ef Iustin Pop
    self.failUnlessEqual(TailFile(fname), [])
1389 f65f63ef Iustin Pop
    self.failUnlessEqual(TailFile(fname, lines=25), [])
1390 f65f63ef Iustin Pop
1391 f65f63ef Iustin Pop
  def testAllLines(self):
1392 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1393 f65f63ef Iustin Pop
    for i in range(30):
1394 f65f63ef Iustin Pop
      fname = self._CreateTempFile()
1395 f65f63ef Iustin Pop
      fd = open(fname, "w")
1396 f65f63ef Iustin Pop
      fd.write("\n".join(data[:i]))
1397 f65f63ef Iustin Pop
      if i > 0:
1398 f65f63ef Iustin Pop
        fd.write("\n")
1399 f65f63ef Iustin Pop
      fd.close()
1400 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[:i])
1401 f65f63ef Iustin Pop
1402 f65f63ef Iustin Pop
  def testPartialLines(self):
1403 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1404 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1405 f65f63ef Iustin Pop
    fd = open(fname, "w")
1406 f65f63ef Iustin Pop
    fd.write("\n".join(data))
1407 f65f63ef Iustin Pop
    fd.write("\n")
1408 f65f63ef Iustin Pop
    fd.close()
1409 f65f63ef Iustin Pop
    for i in range(1, 30):
1410 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[-i:])
1411 f65f63ef Iustin Pop
1412 f65f63ef Iustin Pop
  def testBigFile(self):
1413 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1414 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1415 f65f63ef Iustin Pop
    fd = open(fname, "w")
1416 f65f63ef Iustin Pop
    fd.write("X" * 1048576)
1417 f65f63ef Iustin Pop
    fd.write("\n")
1418 f65f63ef Iustin Pop
    fd.write("\n".join(data))
1419 f65f63ef Iustin Pop
    fd.write("\n")
1420 f65f63ef Iustin Pop
    fd.close()
1421 f65f63ef Iustin Pop
    for i in range(1, 30):
1422 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[-i:])
1423 f65f63ef Iustin Pop
1424 f65f63ef Iustin Pop
1425 b4478d34 Michael Hanselmann
class _BaseFileLockTest:
1426 a87b4824 Michael Hanselmann
  """Test case for the FileLock class"""
1427 a87b4824 Michael Hanselmann
1428 a87b4824 Michael Hanselmann
  def testSharedNonblocking(self):
1429 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1430 a87b4824 Michael Hanselmann
    self.lock.Close()
1431 a87b4824 Michael Hanselmann
1432 a87b4824 Michael Hanselmann
  def testExclusiveNonblocking(self):
1433 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1434 a87b4824 Michael Hanselmann
    self.lock.Close()
1435 a87b4824 Michael Hanselmann
1436 a87b4824 Michael Hanselmann
  def testUnlockNonblocking(self):
1437 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1438 a87b4824 Michael Hanselmann
    self.lock.Close()
1439 a87b4824 Michael Hanselmann
1440 a87b4824 Michael Hanselmann
  def testSharedBlocking(self):
1441 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=True)
1442 a87b4824 Michael Hanselmann
    self.lock.Close()
1443 a87b4824 Michael Hanselmann
1444 a87b4824 Michael Hanselmann
  def testExclusiveBlocking(self):
1445 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=True)
1446 a87b4824 Michael Hanselmann
    self.lock.Close()
1447 a87b4824 Michael Hanselmann
1448 a87b4824 Michael Hanselmann
  def testUnlockBlocking(self):
1449 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=True)
1450 a87b4824 Michael Hanselmann
    self.lock.Close()
1451 a87b4824 Michael Hanselmann
1452 a87b4824 Michael Hanselmann
  def testSharedExclusiveUnlock(self):
1453 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1454 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1455 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1456 a87b4824 Michael Hanselmann
    self.lock.Close()
1457 a87b4824 Michael Hanselmann
1458 a87b4824 Michael Hanselmann
  def testExclusiveSharedUnlock(self):
1459 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1460 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1461 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1462 a87b4824 Michael Hanselmann
    self.lock.Close()
1463 a87b4824 Michael Hanselmann
1464 b4478d34 Michael Hanselmann
  def testSimpleTimeout(self):
1465 b4478d34 Michael Hanselmann
    # These will succeed on the first attempt, hence a short timeout
1466 b4478d34 Michael Hanselmann
    self.lock.Shared(blocking=True, timeout=10.0)
1467 b4478d34 Michael Hanselmann
    self.lock.Exclusive(blocking=False, timeout=10.0)
1468 b4478d34 Michael Hanselmann
    self.lock.Unlock(blocking=True, timeout=10.0)
1469 b4478d34 Michael Hanselmann
    self.lock.Close()
1470 b4478d34 Michael Hanselmann
1471 b4478d34 Michael Hanselmann
  @staticmethod
1472 b4478d34 Michael Hanselmann
  def _TryLockInner(filename, shared, blocking):
1473 b4478d34 Michael Hanselmann
    lock = utils.FileLock.Open(filename)
1474 b4478d34 Michael Hanselmann
1475 b4478d34 Michael Hanselmann
    if shared:
1476 b4478d34 Michael Hanselmann
      fn = lock.Shared
1477 b4478d34 Michael Hanselmann
    else:
1478 b4478d34 Michael Hanselmann
      fn = lock.Exclusive
1479 b4478d34 Michael Hanselmann
1480 b4478d34 Michael Hanselmann
    try:
1481 b4478d34 Michael Hanselmann
      # The timeout doesn't really matter as the parent process waits for us to
1482 b4478d34 Michael Hanselmann
      # finish anyway.
1483 b4478d34 Michael Hanselmann
      fn(blocking=blocking, timeout=0.01)
1484 b4478d34 Michael Hanselmann
    except errors.LockError, err:
1485 b4478d34 Michael Hanselmann
      return False
1486 b4478d34 Michael Hanselmann
1487 b4478d34 Michael Hanselmann
    return True
1488 b4478d34 Michael Hanselmann
1489 b4478d34 Michael Hanselmann
  def _TryLock(self, *args):
1490 b4478d34 Michael Hanselmann
    return utils.RunInSeparateProcess(self._TryLockInner, self.tmpfile.name,
1491 b4478d34 Michael Hanselmann
                                      *args)
1492 b4478d34 Michael Hanselmann
1493 b4478d34 Michael Hanselmann
  def testTimeout(self):
1494 b4478d34 Michael Hanselmann
    for blocking in [True, False]:
1495 b4478d34 Michael Hanselmann
      self.lock.Exclusive(blocking=True)
1496 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(False, blocking))
1497 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(True, blocking))
1498 b4478d34 Michael Hanselmann
1499 b4478d34 Michael Hanselmann
      self.lock.Shared(blocking=True)
1500 b4478d34 Michael Hanselmann
      self.assert_(self._TryLock(True, blocking))
1501 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(False, blocking))
1502 b4478d34 Michael Hanselmann
1503 a87b4824 Michael Hanselmann
  def testCloseShared(self):
1504 a87b4824 Michael Hanselmann
    self.lock.Close()
1505 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Shared, blocking=False)
1506 a87b4824 Michael Hanselmann
1507 a87b4824 Michael Hanselmann
  def testCloseExclusive(self):
1508 a87b4824 Michael Hanselmann
    self.lock.Close()
1509 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Exclusive, blocking=False)
1510 a87b4824 Michael Hanselmann
1511 a87b4824 Michael Hanselmann
  def testCloseUnlock(self):
1512 a87b4824 Michael Hanselmann
    self.lock.Close()
1513 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Unlock, blocking=False)
1514 a87b4824 Michael Hanselmann
1515 a87b4824 Michael Hanselmann
1516 b4478d34 Michael Hanselmann
class TestFileLockWithFilename(testutils.GanetiTestCase, _BaseFileLockTest):
1517 b4478d34 Michael Hanselmann
  TESTDATA = "Hello World\n" * 10
1518 b4478d34 Michael Hanselmann
1519 b4478d34 Michael Hanselmann
  def setUp(self):
1520 b4478d34 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
1521 b4478d34 Michael Hanselmann
1522 b4478d34 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1523 b4478d34 Michael Hanselmann
    utils.WriteFile(self.tmpfile.name, data=self.TESTDATA)
1524 b4478d34 Michael Hanselmann
    self.lock = utils.FileLock.Open(self.tmpfile.name)
1525 b4478d34 Michael Hanselmann
1526 b4478d34 Michael Hanselmann
    # Ensure "Open" didn't truncate file
1527 b4478d34 Michael Hanselmann
    self.assertFileContent(self.tmpfile.name, self.TESTDATA)
1528 b4478d34 Michael Hanselmann
1529 b4478d34 Michael Hanselmann
  def tearDown(self):
1530 b4478d34 Michael Hanselmann
    self.assertFileContent(self.tmpfile.name, self.TESTDATA)
1531 b4478d34 Michael Hanselmann
1532 b4478d34 Michael Hanselmann
    testutils.GanetiTestCase.tearDown(self)
1533 b4478d34 Michael Hanselmann
1534 b4478d34 Michael Hanselmann
1535 b4478d34 Michael Hanselmann
class TestFileLockWithFileObject(unittest.TestCase, _BaseFileLockTest):
1536 b4478d34 Michael Hanselmann
  def setUp(self):
1537 b4478d34 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1538 b4478d34 Michael Hanselmann
    self.lock = utils.FileLock(open(self.tmpfile.name, "w"), self.tmpfile.name)
1539 b4478d34 Michael Hanselmann
1540 b4478d34 Michael Hanselmann
1541 739be818 Michael Hanselmann
class TestTimeFunctions(unittest.TestCase):
1542 739be818 Michael Hanselmann
  """Test case for time functions"""
1543 739be818 Michael Hanselmann
1544 739be818 Michael Hanselmann
  def runTest(self):
1545 739be818 Michael Hanselmann
    self.assertEqual(utils.SplitTime(1), (1, 0))
1546 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(1.5), (1, 500000))
1547 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(1218448917.4809151), (1218448917, 480915))
1548 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.48012), (123, 480120))
1549 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9996), (123, 999600))
1550 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9995), (123, 999500))
1551 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9994), (123, 999400))
1552 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.999999999), (123, 999999))
1553 45bc5e4a Michael Hanselmann
1554 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.SplitTime, -1)
1555 739be818 Michael Hanselmann
1556 739be818 Michael Hanselmann
    self.assertEqual(utils.MergeTime((1, 0)), 1.0)
1557 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.MergeTime((1, 500000)), 1.5)
1558 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.MergeTime((1218448917, 500000)), 1218448917.5)
1559 739be818 Michael Hanselmann
1560 4d4a651d Michael Hanselmann
    self.assertEqual(round(utils.MergeTime((1218448917, 481000)), 3),
1561 4d4a651d Michael Hanselmann
                     1218448917.481)
1562 45bc5e4a Michael Hanselmann
    self.assertEqual(round(utils.MergeTime((1, 801000)), 3), 1.801)
1563 739be818 Michael Hanselmann
1564 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, -1))
1565 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, 1000000))
1566 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, 9999999))
1567 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (-1, 0))
1568 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (-9999, 0))
1569 739be818 Michael Hanselmann
1570 739be818 Michael Hanselmann
1571 a2d2e1a7 Iustin Pop
class FieldSetTestCase(unittest.TestCase):
1572 a2d2e1a7 Iustin Pop
  """Test case for FieldSets"""
1573 a2d2e1a7 Iustin Pop
1574 a2d2e1a7 Iustin Pop
  def testSimpleMatch(self):
1575 a2d2e1a7 Iustin Pop
    f = utils.FieldSet("a", "b", "c", "def")
1576 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("a"))
1577 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("d"), "Substring matched")
1578 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("defghi"), "Prefix string matched")
1579 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["b", "c"]))
1580 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["a", "b", "c", "def"]))
1581 a2d2e1a7 Iustin Pop
    self.failUnless(f.NonMatching(["a", "d"]))
1582 a2d2e1a7 Iustin Pop
1583 a2d2e1a7 Iustin Pop
  def testRegexMatch(self):
1584 a2d2e1a7 Iustin Pop
    f = utils.FieldSet("a", "b([0-9]+)", "c")
1585 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("b1"))
1586 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("b99"))
1587 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("b/1"))
1588 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["b12", "c"]))
1589 a2d2e1a7 Iustin Pop
    self.failUnless(f.NonMatching(["a", "1"]))
1590 a2d2e1a7 Iustin Pop
1591 a5728081 Guido Trotter
class TestForceDictType(unittest.TestCase):
1592 a5728081 Guido Trotter
  """Test case for ForceDictType"""
1593 f40ae421 Iustin Pop
  KEY_TYPES = {
1594 f40ae421 Iustin Pop
    "a": constants.VTYPE_INT,
1595 f40ae421 Iustin Pop
    "b": constants.VTYPE_BOOL,
1596 f40ae421 Iustin Pop
    "c": constants.VTYPE_STRING,
1597 f40ae421 Iustin Pop
    "d": constants.VTYPE_SIZE,
1598 f40ae421 Iustin Pop
    "e": constants.VTYPE_MAYBE_STRING,
1599 f40ae421 Iustin Pop
    }
1600 a5728081 Guido Trotter
1601 a5728081 Guido Trotter
  def _fdt(self, dict, allowed_values=None):
1602 a5728081 Guido Trotter
    if allowed_values is None:
1603 f40ae421 Iustin Pop
      utils.ForceDictType(dict, self.KEY_TYPES)
1604 a5728081 Guido Trotter
    else:
1605 f40ae421 Iustin Pop
      utils.ForceDictType(dict, self.KEY_TYPES, allowed_values=allowed_values)
1606 a5728081 Guido Trotter
1607 a5728081 Guido Trotter
    return dict
1608 a5728081 Guido Trotter
1609 a5728081 Guido Trotter
  def testSimpleDict(self):
1610 a5728081 Guido Trotter
    self.assertEqual(self._fdt({}), {})
1611 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': 1}), {'a': 1})
1612 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': '1'}), {'a': 1})
1613 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': 1, 'b': 1}), {'a':1, 'b': True})
1614 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 1, 'c': 'foo'}), {'b': True, 'c': 'foo'})
1615 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 1, 'c': False}), {'b': True, 'c': ''})
1616 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'false'}), {'b': False})
1617 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'False'}), {'b': False})
1618 f40ae421 Iustin Pop
    self.assertEqual(self._fdt({'b': False}), {'b': False})
1619 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'true'}), {'b': True})
1620 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'True'}), {'b': True})
1621 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'d': '4'}), {'d': 4})
1622 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'d': '4M'}), {'d': 4})
1623 59525e1f Michael Hanselmann
    self.assertEqual(self._fdt({"e": None, }), {"e": None, })
1624 59525e1f Michael Hanselmann
    self.assertEqual(self._fdt({"e": "Hello World", }), {"e": "Hello World", })
1625 59525e1f Michael Hanselmann
    self.assertEqual(self._fdt({"e": False, }), {"e": '', })
1626 f40ae421 Iustin Pop
    self.assertEqual(self._fdt({"b": "hello", }, ["hello"]), {"b": "hello"})
1627 a5728081 Guido Trotter
1628 a5728081 Guido Trotter
  def testErrors(self):
1629 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'a': 'astring'})
1630 f40ae421 Iustin Pop
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {"b": "hello"})
1631 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'c': True})
1632 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': 'astring'})
1633 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': '4 L'})
1634 59525e1f Michael Hanselmann
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {"e": object(), })
1635 59525e1f Michael Hanselmann
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {"e": [], })
1636 f40ae421 Iustin Pop
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {"x": None, })
1637 f40ae421 Iustin Pop
    self.assertRaises(errors.TypeEnforcementError, self._fdt, [])
1638 f40ae421 Iustin Pop
    self.assertRaises(errors.ProgrammerError, utils.ForceDictType,
1639 f40ae421 Iustin Pop
                      {"b": "hello"}, {"b": "no-such-type"})
1640 a5728081 Guido Trotter
1641 a2d2e1a7 Iustin Pop
1642 05489142 Guido Trotter
class TestIsNormAbsPath(unittest.TestCase):
1643 c1dd99d4 Michael Hanselmann
  """Testing case for IsNormAbsPath"""
1644 da961187 Guido Trotter
1645 da961187 Guido Trotter
  def _pathTestHelper(self, path, result):
1646 da961187 Guido Trotter
    if result:
1647 a744b676 Manuel Franceschini
      self.assert_(utils.IsNormAbsPath(path),
1648 17c61836 Guido Trotter
          "Path %s should result absolute and normalized" % path)
1649 da961187 Guido Trotter
    else:
1650 a744b676 Manuel Franceschini
      self.assertFalse(utils.IsNormAbsPath(path),
1651 17c61836 Guido Trotter
          "Path %s should not result absolute and normalized" % path)
1652 da961187 Guido Trotter
1653 da961187 Guido Trotter
  def testBase(self):
1654 da961187 Guido Trotter
    self._pathTestHelper('/etc', True)
1655 da961187 Guido Trotter
    self._pathTestHelper('/srv', True)
1656 da961187 Guido Trotter
    self._pathTestHelper('etc', False)
1657 da961187 Guido Trotter
    self._pathTestHelper('/etc/../root', False)
1658 da961187 Guido Trotter
    self._pathTestHelper('/etc/', False)
1659 da961187 Guido Trotter
1660 af0413bb Guido Trotter
1661 d392fa34 Iustin Pop
class TestSafeEncode(unittest.TestCase):
1662 d392fa34 Iustin Pop
  """Test case for SafeEncode"""
1663 d392fa34 Iustin Pop
1664 d392fa34 Iustin Pop
  def testAscii(self):
1665 d392fa34 Iustin Pop
    for txt in [string.digits, string.letters, string.punctuation]:
1666 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1667 d392fa34 Iustin Pop
1668 d392fa34 Iustin Pop
  def testDoubleEncode(self):
1669 d392fa34 Iustin Pop
    for i in range(255):
1670 d392fa34 Iustin Pop
      txt = SafeEncode(chr(i))
1671 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1672 d392fa34 Iustin Pop
1673 d392fa34 Iustin Pop
  def testUnicode(self):
1674 d392fa34 Iustin Pop
    # 1024 is high enough to catch non-direct ASCII mappings
1675 d392fa34 Iustin Pop
    for i in range(1024):
1676 d392fa34 Iustin Pop
      txt = SafeEncode(unichr(i))
1677 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1678 d392fa34 Iustin Pop
1679 d392fa34 Iustin Pop
1680 3b813dd2 Iustin Pop
class TestFormatTime(unittest.TestCase):
1681 3b813dd2 Iustin Pop
  """Testing case for FormatTime"""
1682 3b813dd2 Iustin Pop
1683 3b813dd2 Iustin Pop
  def testNone(self):
1684 3b813dd2 Iustin Pop
    self.failUnlessEqual(FormatTime(None), "N/A")
1685 3b813dd2 Iustin Pop
1686 3b813dd2 Iustin Pop
  def testInvalid(self):
1687 3b813dd2 Iustin Pop
    self.failUnlessEqual(FormatTime(()), "N/A")
1688 3b813dd2 Iustin Pop
1689 3b813dd2 Iustin Pop
  def testNow(self):
1690 3b813dd2 Iustin Pop
    # tests that we accept time.time input
1691 3b813dd2 Iustin Pop
    FormatTime(time.time())
1692 3b813dd2 Iustin Pop
    # tests that we accept int input
1693 3b813dd2 Iustin Pop
    FormatTime(int(time.time()))
1694 3b813dd2 Iustin Pop
1695 3b813dd2 Iustin Pop
1696 eb58f7bd Michael Hanselmann
class RunInSeparateProcess(unittest.TestCase):
1697 eb58f7bd Michael Hanselmann
  def test(self):
1698 eb58f7bd Michael Hanselmann
    for exp in [True, False]:
1699 eb58f7bd Michael Hanselmann
      def _child():
1700 eb58f7bd Michael Hanselmann
        return exp
1701 eb58f7bd Michael Hanselmann
1702 eb58f7bd Michael Hanselmann
      self.assertEqual(exp, utils.RunInSeparateProcess(_child))
1703 eb58f7bd Michael Hanselmann
1704 bdefe5dd Michael Hanselmann
  def testArgs(self):
1705 bdefe5dd Michael Hanselmann
    for arg in [0, 1, 999, "Hello World", (1, 2, 3)]:
1706 bdefe5dd Michael Hanselmann
      def _child(carg1, carg2):
1707 bdefe5dd Michael Hanselmann
        return carg1 == "Foo" and carg2 == arg
1708 bdefe5dd Michael Hanselmann
1709 bdefe5dd Michael Hanselmann
      self.assert_(utils.RunInSeparateProcess(_child, "Foo", arg))
1710 bdefe5dd Michael Hanselmann
1711 eb58f7bd Michael Hanselmann
  def testPid(self):
1712 eb58f7bd Michael Hanselmann
    parent_pid = os.getpid()
1713 eb58f7bd Michael Hanselmann
1714 eb58f7bd Michael Hanselmann
    def _check():
1715 eb58f7bd Michael Hanselmann
      return os.getpid() == parent_pid
1716 eb58f7bd Michael Hanselmann
1717 eb58f7bd Michael Hanselmann
    self.failIf(utils.RunInSeparateProcess(_check))
1718 eb58f7bd Michael Hanselmann
1719 eb58f7bd Michael Hanselmann
  def testSignal(self):
1720 eb58f7bd Michael Hanselmann
    def _kill():
1721 eb58f7bd Michael Hanselmann
      os.kill(os.getpid(), signal.SIGTERM)
1722 eb58f7bd Michael Hanselmann
1723 eb58f7bd Michael Hanselmann
    self.assertRaises(errors.GenericError,
1724 eb58f7bd Michael Hanselmann
                      utils.RunInSeparateProcess, _kill)
1725 eb58f7bd Michael Hanselmann
1726 eb58f7bd Michael Hanselmann
  def testException(self):
1727 eb58f7bd Michael Hanselmann
    def _exc():
1728 eb58f7bd Michael Hanselmann
      raise errors.GenericError("This is a test")
1729 eb58f7bd Michael Hanselmann
1730 eb58f7bd Michael Hanselmann
    self.assertRaises(errors.GenericError,
1731 eb58f7bd Michael Hanselmann
                      utils.RunInSeparateProcess, _exc)
1732 eb58f7bd Michael Hanselmann
1733 eb58f7bd Michael Hanselmann
1734 f40ae421 Iustin Pop
class TestFingerprintFiles(unittest.TestCase):
1735 fabee4b2 Michael Hanselmann
  def setUp(self):
1736 fabee4b2 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1737 f40ae421 Iustin Pop
    self.tmpfile2 = tempfile.NamedTemporaryFile()
1738 f40ae421 Iustin Pop
    utils.WriteFile(self.tmpfile2.name, data="Hello World\n")
1739 f40ae421 Iustin Pop
    self.results = {
1740 f40ae421 Iustin Pop
      self.tmpfile.name: "da39a3ee5e6b4b0d3255bfef95601890afd80709",
1741 f40ae421 Iustin Pop
      self.tmpfile2.name: "648a6a6ffffdaa0badb23b8baf90b6168dd16b3a",
1742 f40ae421 Iustin Pop
      }
1743 fabee4b2 Michael Hanselmann
1744 f40ae421 Iustin Pop
  def testSingleFile(self):
1745 fabee4b2 Michael Hanselmann
    self.assertEqual(utils._FingerprintFile(self.tmpfile.name),
1746 f40ae421 Iustin Pop
                     self.results[self.tmpfile.name])
1747 f40ae421 Iustin Pop
1748 f40ae421 Iustin Pop
    self.assertEqual(utils._FingerprintFile("/no/such/file"), None)
1749 fabee4b2 Michael Hanselmann
1750 f40ae421 Iustin Pop
  def testBigFile(self):
1751 f40ae421 Iustin Pop
    self.tmpfile.write("A" * 8192)
1752 f40ae421 Iustin Pop
    self.tmpfile.flush()
1753 fabee4b2 Michael Hanselmann
    self.assertEqual(utils._FingerprintFile(self.tmpfile.name),
1754 f40ae421 Iustin Pop
                     "35b6795ca20d6dc0aff8c7c110c96cd1070b8c38")
1755 f40ae421 Iustin Pop
1756 f40ae421 Iustin Pop
  def testMultiple(self):
1757 f40ae421 Iustin Pop
    all_files = self.results.keys()
1758 f40ae421 Iustin Pop
    all_files.append("/no/such/file")
1759 f40ae421 Iustin Pop
    self.assertEqual(utils.FingerprintFiles(self.results.keys()), self.results)
1760 fabee4b2 Michael Hanselmann
1761 fabee4b2 Michael Hanselmann
1762 5b69bc7c Iustin Pop
class TestUnescapeAndSplit(unittest.TestCase):
1763 5b69bc7c Iustin Pop
  """Testing case for UnescapeAndSplit"""
1764 5b69bc7c Iustin Pop
1765 5b69bc7c Iustin Pop
  def setUp(self):
1766 5b69bc7c Iustin Pop
    # testing more that one separator for regexp safety
1767 5b69bc7c Iustin Pop
    self._seps = [",", "+", "."]
1768 5b69bc7c Iustin Pop
1769 5b69bc7c Iustin Pop
  def testSimple(self):
1770 5b69bc7c Iustin Pop
    a = ["a", "b", "c", "d"]
1771 5b69bc7c Iustin Pop
    for sep in self._seps:
1772 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), a)
1773 5b69bc7c Iustin Pop
1774 5b69bc7c Iustin Pop
  def testEscape(self):
1775 5b69bc7c Iustin Pop
    for sep in self._seps:
1776 5b69bc7c Iustin Pop
      a = ["a", "b\\" + sep + "c", "d"]
1777 5b69bc7c Iustin Pop
      b = ["a", "b" + sep + "c", "d"]
1778 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1779 5b69bc7c Iustin Pop
1780 5b69bc7c Iustin Pop
  def testDoubleEscape(self):
1781 5b69bc7c Iustin Pop
    for sep in self._seps:
1782 5b69bc7c Iustin Pop
      a = ["a", "b\\\\", "c", "d"]
1783 5b69bc7c Iustin Pop
      b = ["a", "b\\", "c", "d"]
1784 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1785 5b69bc7c Iustin Pop
1786 5b69bc7c Iustin Pop
  def testThreeEscape(self):
1787 5b69bc7c Iustin Pop
    for sep in self._seps:
1788 5b69bc7c Iustin Pop
      a = ["a", "b\\\\\\" + sep + "c", "d"]
1789 5b69bc7c Iustin Pop
      b = ["a", "b\\" + sep + "c", "d"]
1790 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1791 5b69bc7c Iustin Pop
1792 5b69bc7c Iustin Pop
1793 bdd5e420 Michael Hanselmann
class TestGenerateSelfSignedX509Cert(unittest.TestCase):
1794 a55474c7 Michael Hanselmann
  def setUp(self):
1795 a55474c7 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
1796 a55474c7 Michael Hanselmann
1797 a55474c7 Michael Hanselmann
  def tearDown(self):
1798 a55474c7 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
1799 a55474c7 Michael Hanselmann
1800 bdd5e420 Michael Hanselmann
  def _checkRsaPrivateKey(self, key):
1801 a55474c7 Michael Hanselmann
    lines = key.splitlines()
1802 bdd5e420 Michael Hanselmann
    return ("-----BEGIN RSA PRIVATE KEY-----" in lines and
1803 bdd5e420 Michael Hanselmann
            "-----END RSA PRIVATE KEY-----" in lines)
1804 a55474c7 Michael Hanselmann
1805 bdd5e420 Michael Hanselmann
  def _checkCertificate(self, cert):
1806 a55474c7 Michael Hanselmann
    lines = cert.splitlines()
1807 bdd5e420 Michael Hanselmann
    return ("-----BEGIN CERTIFICATE-----" in lines and
1808 bdd5e420 Michael Hanselmann
            "-----END CERTIFICATE-----" in lines)
1809 a55474c7 Michael Hanselmann
1810 bdd5e420 Michael Hanselmann
  def test(self):
1811 bdd5e420 Michael Hanselmann
    for common_name in [None, ".", "Ganeti", "node1.example.com"]:
1812 bdd5e420 Michael Hanselmann
      (key_pem, cert_pem) = utils.GenerateSelfSignedX509Cert(common_name, 300)
1813 bdd5e420 Michael Hanselmann
      self._checkRsaPrivateKey(key_pem)
1814 bdd5e420 Michael Hanselmann
      self._checkCertificate(cert_pem)
1815 bdd5e420 Michael Hanselmann
1816 bdd5e420 Michael Hanselmann
      key = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM,
1817 bdd5e420 Michael Hanselmann
                                           key_pem)
1818 bdd5e420 Michael Hanselmann
      self.assert_(key.bits() >= 1024)
1819 bdd5e420 Michael Hanselmann
      self.assertEqual(key.bits(), constants.RSA_KEY_BITS)
1820 bdd5e420 Michael Hanselmann
      self.assertEqual(key.type(), OpenSSL.crypto.TYPE_RSA)
1821 bdd5e420 Michael Hanselmann
1822 bdd5e420 Michael Hanselmann
      x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
1823 bdd5e420 Michael Hanselmann
                                             cert_pem)
1824 bdd5e420 Michael Hanselmann
      self.failIf(x509.has_expired())
1825 bdd5e420 Michael Hanselmann
      self.assertEqual(x509.get_issuer().CN, common_name)
1826 bdd5e420 Michael Hanselmann
      self.assertEqual(x509.get_subject().CN, common_name)
1827 bdd5e420 Michael Hanselmann
      self.assertEqual(x509.get_pubkey().bits(), constants.RSA_KEY_BITS)
1828 bdd5e420 Michael Hanselmann
1829 bdd5e420 Michael Hanselmann
  def testLegacy(self):
1830 a55474c7 Michael Hanselmann
    cert1_filename = os.path.join(self.tmpdir, "cert1.pem")
1831 a55474c7 Michael Hanselmann
1832 a55474c7 Michael Hanselmann
    utils.GenerateSelfSignedSslCert(cert1_filename, validity=1)
1833 a55474c7 Michael Hanselmann
1834 a55474c7 Michael Hanselmann
    cert1 = utils.ReadFile(cert1_filename)
1835 a55474c7 Michael Hanselmann
1836 bdd5e420 Michael Hanselmann
    self.assert_(self._checkRsaPrivateKey(cert1))
1837 bdd5e420 Michael Hanselmann
    self.assert_(self._checkCertificate(cert1))
1838 a55474c7 Michael Hanselmann
1839 a55474c7 Michael Hanselmann
1840 4bb678e9 Iustin Pop
class TestPathJoin(unittest.TestCase):
1841 4bb678e9 Iustin Pop
  """Testing case for PathJoin"""
1842 4bb678e9 Iustin Pop
1843 4bb678e9 Iustin Pop
  def testBasicItems(self):
1844 4bb678e9 Iustin Pop
    mlist = ["/a", "b", "c"]
1845 4bb678e9 Iustin Pop
    self.failUnlessEqual(PathJoin(*mlist), "/".join(mlist))
1846 4bb678e9 Iustin Pop
1847 4bb678e9 Iustin Pop
  def testNonAbsPrefix(self):
1848 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "a", "b")
1849 4bb678e9 Iustin Pop
1850 4bb678e9 Iustin Pop
  def testBackTrack(self):
1851 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "/a", "b/../c")
1852 4bb678e9 Iustin Pop
1853 4bb678e9 Iustin Pop
  def testMultiAbs(self):
1854 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "/a", "/b")
1855 4bb678e9 Iustin Pop
1856 4bb678e9 Iustin Pop
1857 28f34048 Michael Hanselmann
class TestValidateServiceName(unittest.TestCase):
1858 28f34048 Michael Hanselmann
  def testValid(self):
1859 28f34048 Michael Hanselmann
    testnames = [
1860 28f34048 Michael Hanselmann
      0, 1, 2, 3, 1024, 65000, 65534, 65535,
1861 28f34048 Michael Hanselmann
      "ganeti",
1862 28f34048 Michael Hanselmann
      "gnt-masterd",
1863 28f34048 Michael Hanselmann
      "HELLO_WORLD_SVC",
1864 28f34048 Michael Hanselmann
      "hello.world.1",
1865 28f34048 Michael Hanselmann
      "0", "80", "1111", "65535",
1866 28f34048 Michael Hanselmann
      ]
1867 28f34048 Michael Hanselmann
1868 28f34048 Michael Hanselmann
    for name in testnames:
1869 28f34048 Michael Hanselmann
      self.assertEqual(utils.ValidateServiceName(name), name)
1870 28f34048 Michael Hanselmann
1871 28f34048 Michael Hanselmann
  def testInvalid(self):
1872 28f34048 Michael Hanselmann
    testnames = [
1873 28f34048 Michael Hanselmann
      -15756, -1, 65536, 133428083,
1874 28f34048 Michael Hanselmann
      "", "Hello World!", "!", "'", "\"", "\t", "\n", "`",
1875 28f34048 Michael Hanselmann
      "-8546", "-1", "65536",
1876 28f34048 Michael Hanselmann
      (129 * "A"),
1877 28f34048 Michael Hanselmann
      ]
1878 28f34048 Michael Hanselmann
1879 28f34048 Michael Hanselmann
    for name in testnames:
1880 a744b676 Manuel Franceschini
      self.assertRaises(errors.OpPrereqError, utils.ValidateServiceName, name)
1881 28f34048 Michael Hanselmann
1882 28f34048 Michael Hanselmann
1883 27e46076 Michael Hanselmann
class TestParseAsn1Generalizedtime(unittest.TestCase):
1884 27e46076 Michael Hanselmann
  def test(self):
1885 27e46076 Michael Hanselmann
    # UTC
1886 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("19700101000000Z"), 0)
1887 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100222174152Z"),
1888 27e46076 Michael Hanselmann
                     1266860512)
1889 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20380119031407Z"),
1890 27e46076 Michael Hanselmann
                     (2**31) - 1)
1891 27e46076 Michael Hanselmann
1892 27e46076 Michael Hanselmann
    # With offset
1893 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100222174152+0000"),
1894 27e46076 Michael Hanselmann
                     1266860512)
1895 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100223131652+0000"),
1896 27e46076 Michael Hanselmann
                     1266931012)
1897 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100223051808-0800"),
1898 27e46076 Michael Hanselmann
                     1266931088)
1899 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100224002135+1100"),
1900 27e46076 Michael Hanselmann
                     1266931295)
1901 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("19700101000000-0100"),
1902 27e46076 Michael Hanselmann
                     3600)
1903 27e46076 Michael Hanselmann
1904 27e46076 Michael Hanselmann
    # Leap seconds are not supported by datetime.datetime
1905 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1906 27e46076 Michael Hanselmann
                      "19841231235960+0000")
1907 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1908 27e46076 Michael Hanselmann
                      "19920630235960+0000")
1909 27e46076 Michael Hanselmann
1910 27e46076 Michael Hanselmann
    # Errors
1911 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime, "")
1912 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime, "invalid")
1913 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1914 27e46076 Michael Hanselmann
                      "20100222174152")
1915 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1916 27e46076 Michael Hanselmann
                      "Mon Feb 22 17:47:02 UTC 2010")
1917 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1918 27e46076 Michael Hanselmann
                      "2010-02-22 17:42:02")
1919 27e46076 Michael Hanselmann
1920 27e46076 Michael Hanselmann
1921 27e46076 Michael Hanselmann
class TestGetX509CertValidity(testutils.GanetiTestCase):
1922 27e46076 Michael Hanselmann
  def setUp(self):
1923 27e46076 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
1924 27e46076 Michael Hanselmann
1925 27e46076 Michael Hanselmann
    pyopenssl_version = distutils.version.LooseVersion(OpenSSL.__version__)
1926 27e46076 Michael Hanselmann
1927 27e46076 Michael Hanselmann
    # Test whether we have pyOpenSSL 0.7 or above
1928 27e46076 Michael Hanselmann
    self.pyopenssl0_7 = (pyopenssl_version >= "0.7")
1929 27e46076 Michael Hanselmann
1930 27e46076 Michael Hanselmann
    if not self.pyopenssl0_7:
1931 27e46076 Michael Hanselmann
      warnings.warn("This test requires pyOpenSSL 0.7 or above to"
1932 27e46076 Michael Hanselmann
                    " function correctly")
1933 27e46076 Michael Hanselmann
1934 27e46076 Michael Hanselmann
  def _LoadCert(self, name):
1935 27e46076 Michael Hanselmann
    return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
1936 27e46076 Michael Hanselmann
                                           self._ReadTestData(name))
1937 27e46076 Michael Hanselmann
1938 27e46076 Michael Hanselmann
  def test(self):
1939 27e46076 Michael Hanselmann
    validity = utils.GetX509CertValidity(self._LoadCert("cert1.pem"))
1940 27e46076 Michael Hanselmann
    if self.pyopenssl0_7:
1941 27e46076 Michael Hanselmann
      self.assertEqual(validity, (1266919967, 1267524767))
1942 27e46076 Michael Hanselmann
    else:
1943 27e46076 Michael Hanselmann
      self.assertEqual(validity, (None, None))
1944 27e46076 Michael Hanselmann
1945 26288e68 Iustin Pop
1946 68857643 Michael Hanselmann
class TestSignX509Certificate(unittest.TestCase):
1947 68857643 Michael Hanselmann
  KEY = "My private key!"
1948 68857643 Michael Hanselmann
  KEY_OTHER = "Another key"
1949 68857643 Michael Hanselmann
1950 68857643 Michael Hanselmann
  def test(self):
1951 68857643 Michael Hanselmann
    # Generate certificate valid for 5 minutes
1952 68857643 Michael Hanselmann
    (_, cert_pem) = utils.GenerateSelfSignedX509Cert(None, 300)
1953 68857643 Michael Hanselmann
1954 68857643 Michael Hanselmann
    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
1955 68857643 Michael Hanselmann
                                           cert_pem)
1956 68857643 Michael Hanselmann
1957 68857643 Michael Hanselmann
    # No signature at all
1958 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError,
1959 68857643 Michael Hanselmann
                      utils.LoadSignedX509Certificate, cert_pem, self.KEY)
1960 68857643 Michael Hanselmann
1961 68857643 Michael Hanselmann
    # Invalid input
1962 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
1963 68857643 Michael Hanselmann
                      "", self.KEY)
1964 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
1965 68857643 Michael Hanselmann
                      "X-Ganeti-Signature: \n", self.KEY)
1966 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
1967 68857643 Michael Hanselmann
                      "X-Ganeti-Sign: $1234$abcdef\n", self.KEY)
1968 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
1969 68857643 Michael Hanselmann
                      "X-Ganeti-Signature: $1234567890$abcdef\n", self.KEY)
1970 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
1971 68857643 Michael Hanselmann
                      "X-Ganeti-Signature: $1234$abc\n\n" + cert_pem, self.KEY)
1972 68857643 Michael Hanselmann
1973 68857643 Michael Hanselmann
    # Invalid salt
1974 68857643 Michael Hanselmann
    for salt in list("-_@$,:;/\\ \t\n"):
1975 68857643 Michael Hanselmann
      self.assertRaises(errors.GenericError, utils.SignX509Certificate,
1976 68857643 Michael Hanselmann
                        cert_pem, self.KEY, "foo%sbar" % salt)
1977 68857643 Michael Hanselmann
1978 68857643 Michael Hanselmann
    for salt in ["HelloWorld", "salt", string.letters, string.digits,
1979 68857643 Michael Hanselmann
                 utils.GenerateSecret(numbytes=4),
1980 68857643 Michael Hanselmann
                 utils.GenerateSecret(numbytes=16),
1981 68857643 Michael Hanselmann
                 "{123:456}".encode("hex")]:
1982 68857643 Michael Hanselmann
      signed_pem = utils.SignX509Certificate(cert, self.KEY, salt)
1983 68857643 Michael Hanselmann
1984 68857643 Michael Hanselmann
      self._Check(cert, salt, signed_pem)
1985 68857643 Michael Hanselmann
1986 68857643 Michael Hanselmann
      self._Check(cert, salt, "X-Another-Header: with a value\n" + signed_pem)
1987 68857643 Michael Hanselmann
      self._Check(cert, salt, (10 * "Hello World!\n") + signed_pem)
1988 68857643 Michael Hanselmann
      self._Check(cert, salt, (signed_pem + "\n\na few more\n"
1989 68857643 Michael Hanselmann
                               "lines----\n------ at\nthe end!"))
1990 68857643 Michael Hanselmann
1991 68857643 Michael Hanselmann
  def _Check(self, cert, salt, pem):
1992 68857643 Michael Hanselmann
    (cert2, salt2) = utils.LoadSignedX509Certificate(pem, self.KEY)
1993 68857643 Michael Hanselmann
    self.assertEqual(salt, salt2)
1994 68857643 Michael Hanselmann
    self.assertEqual(cert.digest("sha1"), cert2.digest("sha1"))
1995 68857643 Michael Hanselmann
1996 68857643 Michael Hanselmann
    # Other key
1997 68857643 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.LoadSignedX509Certificate,
1998 68857643 Michael Hanselmann
                      pem, self.KEY_OTHER)
1999 68857643 Michael Hanselmann
2000 68857643 Michael Hanselmann
2001 76e5f8b5 Michael Hanselmann
class TestMakedirs(unittest.TestCase):
2002 76e5f8b5 Michael Hanselmann
  def setUp(self):
2003 76e5f8b5 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
2004 76e5f8b5 Michael Hanselmann
2005 76e5f8b5 Michael Hanselmann
  def tearDown(self):
2006 76e5f8b5 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
2007 76e5f8b5 Michael Hanselmann
2008 76e5f8b5 Michael Hanselmann
  def testNonExisting(self):
2009 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "foo")
2010 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
2011 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
2012 76e5f8b5 Michael Hanselmann
2013 76e5f8b5 Michael Hanselmann
  def testExisting(self):
2014 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "foo")
2015 76e5f8b5 Michael Hanselmann
    os.mkdir(path)
2016 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
2017 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
2018 76e5f8b5 Michael Hanselmann
2019 76e5f8b5 Michael Hanselmann
  def testRecursiveNonExisting(self):
2020 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "foo/bar/baz")
2021 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
2022 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
2023 76e5f8b5 Michael Hanselmann
2024 76e5f8b5 Michael Hanselmann
  def testRecursiveExisting(self):
2025 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "B/moo/xyz")
2026 158206e0 Manuel Franceschini
    self.assertFalse(os.path.exists(path))
2027 a744b676 Manuel Franceschini
    os.mkdir(PathJoin(self.tmpdir, "B"))
2028 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
2029 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
2030 76e5f8b5 Michael Hanselmann
2031 76e5f8b5 Michael Hanselmann
2032 1b429e2a Iustin Pop
class TestRetry(testutils.GanetiTestCase):
2033 45cc4913 Guido Trotter
  def setUp(self):
2034 45cc4913 Guido Trotter
    testutils.GanetiTestCase.setUp(self)
2035 45cc4913 Guido Trotter
    self.retries = 0
2036 45cc4913 Guido Trotter
2037 1b429e2a Iustin Pop
  @staticmethod
2038 1b429e2a Iustin Pop
  def _RaiseRetryAgain():
2039 1b429e2a Iustin Pop
    raise utils.RetryAgain()
2040 1b429e2a Iustin Pop
2041 506be7c5 Guido Trotter
  @staticmethod
2042 506be7c5 Guido Trotter
  def _RaiseRetryAgainWithArg(args):
2043 506be7c5 Guido Trotter
    raise utils.RetryAgain(*args)
2044 506be7c5 Guido Trotter
2045 1b429e2a Iustin Pop
  def _WrongNestedLoop(self):
2046 1b429e2a Iustin Pop
    return utils.Retry(self._RaiseRetryAgain, 0.01, 0.02)
2047 1b429e2a Iustin Pop
2048 45cc4913 Guido Trotter
  def _RetryAndSucceed(self, retries):
2049 45cc4913 Guido Trotter
    if self.retries < retries:
2050 45cc4913 Guido Trotter
      self.retries += 1
2051 45cc4913 Guido Trotter
      raise utils.RetryAgain()
2052 45cc4913 Guido Trotter
    else:
2053 45cc4913 Guido Trotter
      return True
2054 45cc4913 Guido Trotter
2055 1b429e2a Iustin Pop
  def testRaiseTimeout(self):
2056 1b429e2a Iustin Pop
    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
2057 1b429e2a Iustin Pop
                          self._RaiseRetryAgain, 0.01, 0.02)
2058 45cc4913 Guido Trotter
    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
2059 45cc4913 Guido Trotter
                          self._RetryAndSucceed, 0.01, 0, args=[1])
2060 45cc4913 Guido Trotter
    self.failUnlessEqual(self.retries, 1)
2061 1b429e2a Iustin Pop
2062 1b429e2a Iustin Pop
  def testComplete(self):
2063 1b429e2a Iustin Pop
    self.failUnlessEqual(utils.Retry(lambda: True, 0, 1), True)
2064 45cc4913 Guido Trotter
    self.failUnlessEqual(utils.Retry(self._RetryAndSucceed, 0, 1, args=[2]),
2065 45cc4913 Guido Trotter
                         True)
2066 45cc4913 Guido Trotter
    self.failUnlessEqual(self.retries, 2)
2067 1b429e2a Iustin Pop
2068 1b429e2a Iustin Pop
  def testNestedLoop(self):
2069 1b429e2a Iustin Pop
    try:
2070 1b429e2a Iustin Pop
      self.failUnlessRaises(errors.ProgrammerError, utils.Retry,
2071 1b429e2a Iustin Pop
                            self._WrongNestedLoop, 0, 1)
2072 1b429e2a Iustin Pop
    except utils.RetryTimeout:
2073 1b429e2a Iustin Pop
      self.fail("Didn't detect inner loop's exception")
2074 1b429e2a Iustin Pop
2075 506be7c5 Guido Trotter
  def testTimeoutArgument(self):
2076 506be7c5 Guido Trotter
    retry_arg="my_important_debugging_message"
2077 506be7c5 Guido Trotter
    try:
2078 506be7c5 Guido Trotter
      utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02, args=[[retry_arg]])
2079 506be7c5 Guido Trotter
    except utils.RetryTimeout, err:
2080 506be7c5 Guido Trotter
      self.failUnlessEqual(err.args, (retry_arg, ))
2081 506be7c5 Guido Trotter
    else:
2082 506be7c5 Guido Trotter
      self.fail("Expected timeout didn't happen")
2083 506be7c5 Guido Trotter
2084 506be7c5 Guido Trotter
  def testRaiseInnerWithExc(self):
2085 506be7c5 Guido Trotter
    retry_arg="my_important_debugging_message"
2086 506be7c5 Guido Trotter
    try:
2087 506be7c5 Guido Trotter
      try:
2088 506be7c5 Guido Trotter
        utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02,
2089 506be7c5 Guido Trotter
                    args=[[errors.GenericError(retry_arg, retry_arg)]])
2090 506be7c5 Guido Trotter
      except utils.RetryTimeout, err:
2091 506be7c5 Guido Trotter
        err.RaiseInner()
2092 506be7c5 Guido Trotter
      else:
2093 506be7c5 Guido Trotter
        self.fail("Expected timeout didn't happen")
2094 506be7c5 Guido Trotter
    except errors.GenericError, err:
2095 506be7c5 Guido Trotter
      self.failUnlessEqual(err.args, (retry_arg, retry_arg))
2096 506be7c5 Guido Trotter
    else:
2097 506be7c5 Guido Trotter
      self.fail("Expected GenericError didn't happen")
2098 506be7c5 Guido Trotter
2099 506be7c5 Guido Trotter
  def testRaiseInnerWithMsg(self):
2100 506be7c5 Guido Trotter
    retry_arg="my_important_debugging_message"
2101 506be7c5 Guido Trotter
    try:
2102 506be7c5 Guido Trotter
      try:
2103 506be7c5 Guido Trotter
        utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02,
2104 506be7c5 Guido Trotter
                    args=[[retry_arg, retry_arg]])
2105 506be7c5 Guido Trotter
      except utils.RetryTimeout, err:
2106 506be7c5 Guido Trotter
        err.RaiseInner()
2107 506be7c5 Guido Trotter
      else:
2108 506be7c5 Guido Trotter
        self.fail("Expected timeout didn't happen")
2109 506be7c5 Guido Trotter
    except utils.RetryTimeout, err:
2110 506be7c5 Guido Trotter
      self.failUnlessEqual(err.args, (retry_arg, retry_arg))
2111 506be7c5 Guido Trotter
    else:
2112 506be7c5 Guido Trotter
      self.fail("Expected RetryTimeout didn't happen")
2113 506be7c5 Guido Trotter
2114 1b429e2a Iustin Pop
2115 339be5a8 Michael Hanselmann
class TestLineSplitter(unittest.TestCase):
2116 339be5a8 Michael Hanselmann
  def test(self):
2117 339be5a8 Michael Hanselmann
    lines = []
2118 339be5a8 Michael Hanselmann
    ls = utils.LineSplitter(lines.append)
2119 339be5a8 Michael Hanselmann
    ls.write("Hello World\n")
2120 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
2121 339be5a8 Michael Hanselmann
    ls.write("Foo\n Bar\r\n ")
2122 339be5a8 Michael Hanselmann
    ls.write("Baz")
2123 339be5a8 Michael Hanselmann
    ls.write("Moo")
2124 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
2125 339be5a8 Michael Hanselmann
    ls.flush()
2126 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["Hello World", "Foo", " Bar"])
2127 339be5a8 Michael Hanselmann
    ls.close()
2128 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["Hello World", "Foo", " Bar", " BazMoo"])
2129 339be5a8 Michael Hanselmann
2130 339be5a8 Michael Hanselmann
  def _testExtra(self, line, all_lines, p1, p2):
2131 339be5a8 Michael Hanselmann
    self.assertEqual(p1, 999)
2132 339be5a8 Michael Hanselmann
    self.assertEqual(p2, "extra")
2133 339be5a8 Michael Hanselmann
    all_lines.append(line)
2134 339be5a8 Michael Hanselmann
2135 339be5a8 Michael Hanselmann
  def testExtraArgsNoFlush(self):
2136 339be5a8 Michael Hanselmann
    lines = []
2137 339be5a8 Michael Hanselmann
    ls = utils.LineSplitter(self._testExtra, lines, 999, "extra")
2138 339be5a8 Michael Hanselmann
    ls.write("\n\nHello World\n")
2139 339be5a8 Michael Hanselmann
    ls.write("Foo\n Bar\r\n ")
2140 339be5a8 Michael Hanselmann
    ls.write("")
2141 339be5a8 Michael Hanselmann
    ls.write("Baz")
2142 339be5a8 Michael Hanselmann
    ls.write("Moo\n\nx\n")
2143 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
2144 339be5a8 Michael Hanselmann
    ls.close()
2145 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["", "", "Hello World", "Foo", " Bar", " BazMoo",
2146 339be5a8 Michael Hanselmann
                             "", "x"])
2147 339be5a8 Michael Hanselmann
2148 339be5a8 Michael Hanselmann
2149 debed9ae Michael Hanselmann
class TestReadLockedPidFile(unittest.TestCase):
2150 debed9ae Michael Hanselmann
  def setUp(self):
2151 debed9ae Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
2152 debed9ae Michael Hanselmann
2153 debed9ae Michael Hanselmann
  def tearDown(self):
2154 debed9ae Michael Hanselmann
    shutil.rmtree(self.tmpdir)
2155 debed9ae Michael Hanselmann
2156 debed9ae Michael Hanselmann
  def testNonExistent(self):
2157 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "nonexist")
2158 debed9ae Michael Hanselmann
    self.assert_(utils.ReadLockedPidFile(path) is None)
2159 debed9ae Michael Hanselmann
2160 debed9ae Michael Hanselmann
  def testUnlocked(self):
2161 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "pid")
2162 debed9ae Michael Hanselmann
    utils.WriteFile(path, data="123")
2163 debed9ae Michael Hanselmann
    self.assert_(utils.ReadLockedPidFile(path) is None)
2164 debed9ae Michael Hanselmann
2165 debed9ae Michael Hanselmann
  def testLocked(self):
2166 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "pid")
2167 debed9ae Michael Hanselmann
    utils.WriteFile(path, data="123")
2168 debed9ae Michael Hanselmann
2169 debed9ae Michael Hanselmann
    fl = utils.FileLock.Open(path)
2170 debed9ae Michael Hanselmann
    try:
2171 debed9ae Michael Hanselmann
      fl.Exclusive(blocking=True)
2172 debed9ae Michael Hanselmann
2173 debed9ae Michael Hanselmann
      self.assertEqual(utils.ReadLockedPidFile(path), 123)
2174 debed9ae Michael Hanselmann
    finally:
2175 debed9ae Michael Hanselmann
      fl.Close()
2176 debed9ae Michael Hanselmann
2177 debed9ae Michael Hanselmann
    self.assert_(utils.ReadLockedPidFile(path) is None)
2178 debed9ae Michael Hanselmann
2179 debed9ae Michael Hanselmann
  def testError(self):
2180 a744b676 Manuel Franceschini
    path = PathJoin(self.tmpdir, "foobar", "pid")
2181 a744b676 Manuel Franceschini
    utils.WriteFile(PathJoin(self.tmpdir, "foobar"), data="")
2182 debed9ae Michael Hanselmann
    # open(2) should return ENOTDIR
2183 debed9ae Michael Hanselmann
    self.assertRaises(EnvironmentError, utils.ReadLockedPidFile, path)
2184 debed9ae Michael Hanselmann
2185 debed9ae Michael Hanselmann
2186 24d70417 Michael Hanselmann
class TestCertVerification(testutils.GanetiTestCase):
2187 24d70417 Michael Hanselmann
  def setUp(self):
2188 24d70417 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
2189 24d70417 Michael Hanselmann
2190 24d70417 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
2191 24d70417 Michael Hanselmann
2192 24d70417 Michael Hanselmann
  def tearDown(self):
2193 24d70417 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
2194 24d70417 Michael Hanselmann
2195 24d70417 Michael Hanselmann
  def testVerifyCertificate(self):
2196 24d70417 Michael Hanselmann
    cert_pem = utils.ReadFile(self._TestDataFilename("cert1.pem"))
2197 24d70417 Michael Hanselmann
    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
2198 24d70417 Michael Hanselmann
                                           cert_pem)
2199 24d70417 Michael Hanselmann
2200 24d70417 Michael Hanselmann
    # Not checking return value as this certificate is expired
2201 24d70417 Michael Hanselmann
    utils.VerifyX509Certificate(cert, 30, 7)
2202 24d70417 Michael Hanselmann
2203 24d70417 Michael Hanselmann
2204 24d70417 Michael Hanselmann
class TestVerifyCertificateInner(unittest.TestCase):
2205 24d70417 Michael Hanselmann
  def test(self):
2206 24d70417 Michael Hanselmann
    vci = utils._VerifyCertificateInner
2207 24d70417 Michael Hanselmann
2208 24d70417 Michael Hanselmann
    # Valid
2209 24d70417 Michael Hanselmann
    self.assertEqual(vci(False, 1263916313, 1298476313, 1266940313, 30, 7),
2210 24d70417 Michael Hanselmann
                     (None, None))
2211 24d70417 Michael Hanselmann
2212 24d70417 Michael Hanselmann
    # Not yet valid
2213 24d70417 Michael Hanselmann
    (errcode, msg) = vci(False, 1266507600, 1267544400, 1266075600, 30, 7)
2214 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_WARNING)
2215 24d70417 Michael Hanselmann
2216 24d70417 Michael Hanselmann
    # Expiring soon
2217 24d70417 Michael Hanselmann
    (errcode, msg) = vci(False, 1266507600, 1267544400, 1266939600, 30, 7)
2218 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2219 24d70417 Michael Hanselmann
2220 24d70417 Michael Hanselmann
    (errcode, msg) = vci(False, 1266507600, 1267544400, 1266939600, 30, 1)
2221 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_WARNING)
2222 24d70417 Michael Hanselmann
2223 24d70417 Michael Hanselmann
    (errcode, msg) = vci(False, 1266507600, None, 1266939600, 30, 7)
2224 24d70417 Michael Hanselmann
    self.assertEqual(errcode, None)
2225 24d70417 Michael Hanselmann
2226 24d70417 Michael Hanselmann
    # Expired
2227 24d70417 Michael Hanselmann
    (errcode, msg) = vci(True, 1266507600, 1267544400, 1266939600, 30, 7)
2228 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2229 24d70417 Michael Hanselmann
2230 24d70417 Michael Hanselmann
    (errcode, msg) = vci(True, None, 1267544400, 1266939600, 30, 7)
2231 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2232 24d70417 Michael Hanselmann
2233 24d70417 Michael Hanselmann
    (errcode, msg) = vci(True, 1266507600, None, 1266939600, 30, 7)
2234 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2235 24d70417 Michael Hanselmann
2236 24d70417 Michael Hanselmann
    (errcode, msg) = vci(True, None, None, 1266939600, 30, 7)
2237 24d70417 Michael Hanselmann
    self.assertEqual(errcode, utils.CERT_ERROR)
2238 24d70417 Michael Hanselmann
2239 24d70417 Michael Hanselmann
2240 615aaaba Michael Hanselmann
class TestHmacFunctions(unittest.TestCase):
2241 615aaaba Michael Hanselmann
  # Digests can be checked with "openssl sha1 -hmac $key"
2242 615aaaba Michael Hanselmann
  def testSha1Hmac(self):
2243 615aaaba Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("", ""),
2244 615aaaba Michael Hanselmann
                     "fbdb1d1b18aa6c08324b7d64b71fb76370690e1d")
2245 615aaaba Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("3YzMxZWE", "Hello World"),
2246 615aaaba Michael Hanselmann
                     "ef4f3bda82212ecb2f7ce868888a19092481f1fd")
2247 615aaaba Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("TguMTA2K", ""),
2248 615aaaba Michael Hanselmann
                     "f904c2476527c6d3e6609ab683c66fa0652cb1dc")
2249 615aaaba Michael Hanselmann
2250 615aaaba Michael Hanselmann
    longtext = 1500 * "The quick brown fox jumps over the lazy dog\n"
2251 615aaaba Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("3YzMxZWE", longtext),
2252 615aaaba Michael Hanselmann
                     "35901b9a3001a7cdcf8e0e9d7c2e79df2223af54")
2253 615aaaba Michael Hanselmann
2254 3718bf6d Michael Hanselmann
  def testSha1HmacSalt(self):
2255 3718bf6d Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("TguMTA2K", "", salt="abc0"),
2256 3718bf6d Michael Hanselmann
                     "4999bf342470eadb11dfcd24ca5680cf9fd7cdce")
2257 3718bf6d Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("TguMTA2K", "", salt="abc9"),
2258 3718bf6d Michael Hanselmann
                     "17a4adc34d69c0d367d4ffbef96fd41d4df7a6e8")
2259 3718bf6d Michael Hanselmann
    self.assertEqual(utils.Sha1Hmac("3YzMxZWE", "Hello World", salt="xyz0"),
2260 3718bf6d Michael Hanselmann
                     "7f264f8114c9066afc9bb7636e1786d996d3cc0d")
2261 3718bf6d Michael Hanselmann
2262 615aaaba Michael Hanselmann
  def testVerifySha1Hmac(self):
2263 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("", "", ("fbdb1d1b18aa6c08324b"
2264 615aaaba Michael Hanselmann
                                               "7d64b71fb76370690e1d")))
2265 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("TguMTA2K", "",
2266 615aaaba Michael Hanselmann
                                      ("f904c2476527c6d3e660"
2267 615aaaba Michael Hanselmann
                                       "9ab683c66fa0652cb1dc")))
2268 615aaaba Michael Hanselmann
2269 615aaaba Michael Hanselmann
    digest = "ef4f3bda82212ecb2f7ce868888a19092481f1fd"
2270 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World", digest))
2271 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World",
2272 615aaaba Michael Hanselmann
                                      digest.lower()))
2273 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World",
2274 615aaaba Michael Hanselmann
                                      digest.upper()))
2275 615aaaba Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World",
2276 615aaaba Michael Hanselmann
                                      digest.title()))
2277 615aaaba Michael Hanselmann
2278 3718bf6d Michael Hanselmann
  def testVerifySha1HmacSalt(self):
2279 3718bf6d Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("TguMTA2K", "",
2280 3718bf6d Michael Hanselmann
                                      ("17a4adc34d69c0d367d4"
2281 3718bf6d Michael Hanselmann
                                       "ffbef96fd41d4df7a6e8"),
2282 3718bf6d Michael Hanselmann
                                      salt="abc9"))
2283 3718bf6d Michael Hanselmann
    self.assert_(utils.VerifySha1Hmac("3YzMxZWE", "Hello World",
2284 3718bf6d Michael Hanselmann
                                      ("7f264f8114c9066afc9b"
2285 3718bf6d Michael Hanselmann
                                       "b7636e1786d996d3cc0d"),
2286 3718bf6d Michael Hanselmann
                                      salt="xyz0"))
2287 3718bf6d Michael Hanselmann
2288 615aaaba Michael Hanselmann
2289 232144d0 Guido Trotter
class TestIgnoreSignals(unittest.TestCase):
2290 232144d0 Guido Trotter
  """Test the IgnoreSignals decorator"""
2291 232144d0 Guido Trotter
2292 232144d0 Guido Trotter
  @staticmethod
2293 232144d0 Guido Trotter
  def _Raise(exception):
2294 232144d0 Guido Trotter
    raise exception
2295 232144d0 Guido Trotter
2296 232144d0 Guido Trotter
  @staticmethod
2297 232144d0 Guido Trotter
  def _Return(rval):
2298 232144d0 Guido Trotter
    return rval
2299 232144d0 Guido Trotter
2300 232144d0 Guido Trotter
  def testIgnoreSignals(self):
2301 232144d0 Guido Trotter
    sock_err_intr = socket.error(errno.EINTR, "Message")
2302 232144d0 Guido Trotter
    sock_err_inval = socket.error(errno.EINVAL, "Message")
2303 232144d0 Guido Trotter
2304 232144d0 Guido Trotter
    env_err_intr = EnvironmentError(errno.EINTR, "Message")
2305 232144d0 Guido Trotter
    env_err_inval = EnvironmentError(errno.EINVAL, "Message")
2306 232144d0 Guido Trotter
2307 232144d0 Guido Trotter
    self.assertRaises(socket.error, self._Raise, sock_err_intr)
2308 232144d0 Guido Trotter
    self.assertRaises(socket.error, self._Raise, sock_err_inval)
2309 232144d0 Guido Trotter
    self.assertRaises(EnvironmentError, self._Raise, env_err_intr)
2310 232144d0 Guido Trotter
    self.assertRaises(EnvironmentError, self._Raise, env_err_inval)
2311 232144d0 Guido Trotter
2312 232144d0 Guido Trotter
    self.assertEquals(utils.IgnoreSignals(self._Raise, sock_err_intr), None)
2313 232144d0 Guido Trotter
    self.assertEquals(utils.IgnoreSignals(self._Raise, env_err_intr), None)
2314 232144d0 Guido Trotter
    self.assertRaises(socket.error, utils.IgnoreSignals, self._Raise,
2315 232144d0 Guido Trotter
                      sock_err_inval)
2316 232144d0 Guido Trotter
    self.assertRaises(EnvironmentError, utils.IgnoreSignals, self._Raise,
2317 232144d0 Guido Trotter
                      env_err_inval)
2318 232144d0 Guido Trotter
2319 232144d0 Guido Trotter
    self.assertEquals(utils.IgnoreSignals(self._Return, True), True)
2320 232144d0 Guido Trotter
    self.assertEquals(utils.IgnoreSignals(self._Return, 33), 33)
2321 232144d0 Guido Trotter
2322 232144d0 Guido Trotter
2323 b73360e3 Balazs Lecz
class TestEnsureDirs(unittest.TestCase):
2324 b73360e3 Balazs Lecz
  """Tests for EnsureDirs"""
2325 b73360e3 Balazs Lecz
2326 b73360e3 Balazs Lecz
  def setUp(self):
2327 b73360e3 Balazs Lecz
    self.dir = tempfile.mkdtemp()
2328 b73360e3 Balazs Lecz
    self.old_umask = os.umask(0777)
2329 b73360e3 Balazs Lecz
2330 b73360e3 Balazs Lecz
  def testEnsureDirs(self):
2331 b73360e3 Balazs Lecz
    utils.EnsureDirs([
2332 a744b676 Manuel Franceschini
        (PathJoin(self.dir, "foo"), 0777),
2333 a744b676 Manuel Franceschini
        (PathJoin(self.dir, "bar"), 0000),
2334 b73360e3 Balazs Lecz
        ])
2335 a744b676 Manuel Franceschini
    self.assertEquals(os.stat(PathJoin(self.dir, "foo"))[0] & 0777, 0777)
2336 a744b676 Manuel Franceschini
    self.assertEquals(os.stat(PathJoin(self.dir, "bar"))[0] & 0777, 0000)
2337 b73360e3 Balazs Lecz
2338 b73360e3 Balazs Lecz
  def tearDown(self):
2339 a744b676 Manuel Franceschini
    os.rmdir(PathJoin(self.dir, "foo"))
2340 a744b676 Manuel Franceschini
    os.rmdir(PathJoin(self.dir, "bar"))
2341 b73360e3 Balazs Lecz
    os.rmdir(self.dir)
2342 b73360e3 Balazs Lecz
    os.umask(self.old_umask)
2343 b73360e3 Balazs Lecz
2344 f8ea4ada Michael Hanselmann
2345 f8ea4ada Michael Hanselmann
class TestFormatSeconds(unittest.TestCase):
2346 f8ea4ada Michael Hanselmann
  def test(self):
2347 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(1), "1s")
2348 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(3600), "1h 0m 0s")
2349 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(3599), "59m 59s")
2350 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(7200), "2h 0m 0s")
2351 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(7201), "2h 0m 1s")
2352 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(7281), "2h 1m 21s")
2353 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(29119), "8h 5m 19s")
2354 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(19431228), "224d 21h 33m 48s")
2355 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(-1), "-1s")
2356 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(-282), "-282s")
2357 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(-29119), "-29119s")
2358 f8ea4ada Michael Hanselmann
2359 f8ea4ada Michael Hanselmann
  def testFloat(self):
2360 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(1.3), "1s")
2361 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(1.9), "2s")
2362 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(3912.12311), "1h 5m 12s")
2363 f8ea4ada Michael Hanselmann
    self.assertEqual(utils.FormatSeconds(3912.8), "1h 5m 13s")
2364 f8ea4ada Michael Hanselmann
2365 f8ea4ada Michael Hanselmann
2366 9dc71d5a Michael Hanselmann
class TestIgnoreProcessNotFound(unittest.TestCase):
2367 560cbec1 Michael Hanselmann
  @staticmethod
2368 560cbec1 Michael Hanselmann
  def _WritePid(fd):
2369 560cbec1 Michael Hanselmann
    os.write(fd, str(os.getpid()))
2370 560cbec1 Michael Hanselmann
    os.close(fd)
2371 560cbec1 Michael Hanselmann
    return True
2372 560cbec1 Michael Hanselmann
2373 560cbec1 Michael Hanselmann
  def test(self):
2374 560cbec1 Michael Hanselmann
    (pid_read_fd, pid_write_fd) = os.pipe()
2375 560cbec1 Michael Hanselmann
2376 560cbec1 Michael Hanselmann
    # Start short-lived process which writes its PID to pipe
2377 560cbec1 Michael Hanselmann
    self.assert_(utils.RunInSeparateProcess(self._WritePid, pid_write_fd))
2378 560cbec1 Michael Hanselmann
    os.close(pid_write_fd)
2379 560cbec1 Michael Hanselmann
2380 560cbec1 Michael Hanselmann
    # Read PID from pipe
2381 560cbec1 Michael Hanselmann
    pid = int(os.read(pid_read_fd, 1024))
2382 560cbec1 Michael Hanselmann
    os.close(pid_read_fd)
2383 560cbec1 Michael Hanselmann
2384 560cbec1 Michael Hanselmann
    # Try to send signal to process which exited recently
2385 560cbec1 Michael Hanselmann
    self.assertFalse(utils.IgnoreProcessNotFound(os.kill, pid, 0))
2386 560cbec1 Michael Hanselmann
2387 560cbec1 Michael Hanselmann
2388 858905fb Michael Hanselmann
class TestShellWriter(unittest.TestCase):
2389 858905fb Michael Hanselmann
  def test(self):
2390 858905fb Michael Hanselmann
    buf = StringIO()
2391 858905fb Michael Hanselmann
    sw = utils.ShellWriter(buf)
2392 858905fb Michael Hanselmann
    sw.Write("#!/bin/bash")
2393 858905fb Michael Hanselmann
    sw.Write("if true; then")
2394 858905fb Michael Hanselmann
    sw.IncIndent()
2395 858905fb Michael Hanselmann
    try:
2396 858905fb Michael Hanselmann
      sw.Write("echo true")
2397 858905fb Michael Hanselmann
2398 858905fb Michael Hanselmann
      sw.Write("for i in 1 2 3")
2399 858905fb Michael Hanselmann
      sw.Write("do")
2400 858905fb Michael Hanselmann
      sw.IncIndent()
2401 858905fb Michael Hanselmann
      try:
2402 858905fb Michael Hanselmann
        self.assertEqual(sw._indent, 2)
2403 858905fb Michael Hanselmann
        sw.Write("date")
2404 858905fb Michael Hanselmann
      finally:
2405 858905fb Michael Hanselmann
        sw.DecIndent()
2406 858905fb Michael Hanselmann
      sw.Write("done")
2407 858905fb Michael Hanselmann
    finally:
2408 858905fb Michael Hanselmann
      sw.DecIndent()
2409 858905fb Michael Hanselmann
    sw.Write("echo %s", utils.ShellQuote("Hello World"))
2410 858905fb Michael Hanselmann
    sw.Write("exit 0")
2411 858905fb Michael Hanselmann
2412 858905fb Michael Hanselmann
    self.assertEqual(sw._indent, 0)
2413 858905fb Michael Hanselmann
2414 858905fb Michael Hanselmann
    output = buf.getvalue()
2415 858905fb Michael Hanselmann
2416 858905fb Michael Hanselmann
    self.assert_(output.endswith("\n"))
2417 858905fb Michael Hanselmann
2418 858905fb Michael Hanselmann
    lines = output.splitlines()
2419 858905fb Michael Hanselmann
    self.assertEqual(len(lines), 9)
2420 858905fb Michael Hanselmann
    self.assertEqual(lines[0], "#!/bin/bash")
2421 858905fb Michael Hanselmann
    self.assert_(re.match(r"^\s+date$", lines[5]))
2422 858905fb Michael Hanselmann
    self.assertEqual(lines[7], "echo 'Hello World'")
2423 858905fb Michael Hanselmann
2424 858905fb Michael Hanselmann
  def testEmpty(self):
2425 858905fb Michael Hanselmann
    buf = StringIO()
2426 858905fb Michael Hanselmann
    sw = utils.ShellWriter(buf)
2427 858905fb Michael Hanselmann
    sw = None
2428 858905fb Michael Hanselmann
    self.assertEqual(buf.getvalue(), "")
2429 858905fb Michael Hanselmann
2430 858905fb Michael Hanselmann
2431 750022e0 Michael Hanselmann
class TestCommaJoin(unittest.TestCase):
2432 750022e0 Michael Hanselmann
  def test(self):
2433 750022e0 Michael Hanselmann
    self.assertEqual(utils.CommaJoin([]), "")
2434 750022e0 Michael Hanselmann
    self.assertEqual(utils.CommaJoin([1, 2, 3]), "1, 2, 3")
2435 750022e0 Michael Hanselmann
    self.assertEqual(utils.CommaJoin(["Hello"]), "Hello")
2436 750022e0 Michael Hanselmann
    self.assertEqual(utils.CommaJoin(["Hello", "World"]), "Hello, World")
2437 750022e0 Michael Hanselmann
    self.assertEqual(utils.CommaJoin(["Hello", "World", 99]),
2438 750022e0 Michael Hanselmann
                     "Hello, World, 99")
2439 750022e0 Michael Hanselmann
2440 750022e0 Michael Hanselmann
2441 691c81b7 Michael Hanselmann
class TestFindMatch(unittest.TestCase):
2442 691c81b7 Michael Hanselmann
  def test(self):
2443 691c81b7 Michael Hanselmann
    data = {
2444 691c81b7 Michael Hanselmann
      "aaaa": "Four A",
2445 691c81b7 Michael Hanselmann
      "bb": {"Two B": True},
2446 691c81b7 Michael Hanselmann
      re.compile(r"^x(foo|bar|bazX)([0-9]+)$"): (1, 2, 3),
2447 691c81b7 Michael Hanselmann
      }
2448 691c81b7 Michael Hanselmann
2449 691c81b7 Michael Hanselmann
    self.assertEqual(utils.FindMatch(data, "aaaa"), ("Four A", []))
2450 691c81b7 Michael Hanselmann
    self.assertEqual(utils.FindMatch(data, "bb"), ({"Two B": True}, []))
2451 691c81b7 Michael Hanselmann
2452 691c81b7 Michael Hanselmann
    for i in ["foo", "bar", "bazX"]:
2453 691c81b7 Michael Hanselmann
      for j in range(1, 100, 7):
2454 691c81b7 Michael Hanselmann
        self.assertEqual(utils.FindMatch(data, "x%s%s" % (i, j)),
2455 691c81b7 Michael Hanselmann
                         ((1, 2, 3), [i, str(j)]))
2456 691c81b7 Michael Hanselmann
2457 691c81b7 Michael Hanselmann
  def testNoMatch(self):
2458 691c81b7 Michael Hanselmann
    self.assert_(utils.FindMatch({}, "") is None)
2459 691c81b7 Michael Hanselmann
    self.assert_(utils.FindMatch({}, "foo") is None)
2460 691c81b7 Michael Hanselmann
    self.assert_(utils.FindMatch({}, 1234) is None)
2461 691c81b7 Michael Hanselmann
2462 691c81b7 Michael Hanselmann
    data = {
2463 691c81b7 Michael Hanselmann
      "X": "Hello World",
2464 691c81b7 Michael Hanselmann
      re.compile("^(something)$"): "Hello World",
2465 691c81b7 Michael Hanselmann
      }
2466 691c81b7 Michael Hanselmann
2467 691c81b7 Michael Hanselmann
    self.assert_(utils.FindMatch(data, "") is None)
2468 691c81b7 Michael Hanselmann
    self.assert_(utils.FindMatch(data, "Hello World") is None)
2469 691c81b7 Michael Hanselmann
2470 691c81b7 Michael Hanselmann
2471 9e100285 Iustin Pop
class TestFileID(testutils.GanetiTestCase):
2472 9e100285 Iustin Pop
  def testEquality(self):
2473 9e100285 Iustin Pop
    name = self._CreateTempFile()
2474 9e100285 Iustin Pop
    oldi = utils.GetFileID(path=name)
2475 9e100285 Iustin Pop
    self.failUnless(utils.VerifyFileID(oldi, oldi))
2476 9e100285 Iustin Pop
2477 9e100285 Iustin Pop
  def testUpdate(self):
2478 9e100285 Iustin Pop
    name = self._CreateTempFile()
2479 9e100285 Iustin Pop
    oldi = utils.GetFileID(path=name)
2480 9e100285 Iustin Pop
    os.utime(name, None)
2481 9e100285 Iustin Pop
    fd = os.open(name, os.O_RDWR)
2482 9e100285 Iustin Pop
    try:
2483 9e100285 Iustin Pop
      newi = utils.GetFileID(fd=fd)
2484 9e100285 Iustin Pop
      self.failUnless(utils.VerifyFileID(oldi, newi))
2485 9e100285 Iustin Pop
      self.failUnless(utils.VerifyFileID(newi, oldi))
2486 9e100285 Iustin Pop
    finally:
2487 9e100285 Iustin Pop
      os.close(fd)
2488 9e100285 Iustin Pop
2489 4138d39f Iustin Pop
  def testWriteFile(self):
2490 4138d39f Iustin Pop
    name = self._CreateTempFile()
2491 4138d39f Iustin Pop
    oldi = utils.GetFileID(path=name)
2492 4138d39f Iustin Pop
    mtime = oldi[2]
2493 4138d39f Iustin Pop
    os.utime(name, (mtime + 10, mtime + 10))
2494 4138d39f Iustin Pop
    self.assertRaises(errors.LockError, utils.SafeWriteFile, name,
2495 4138d39f Iustin Pop
                      oldi, data="")
2496 4138d39f Iustin Pop
    os.utime(name, (mtime - 10, mtime - 10))
2497 4138d39f Iustin Pop
    utils.SafeWriteFile(name, oldi, data="")
2498 4138d39f Iustin Pop
    oldi = utils.GetFileID(path=name)
2499 4138d39f Iustin Pop
    mtime = oldi[2]
2500 4138d39f Iustin Pop
    os.utime(name, (mtime + 10, mtime + 10))
2501 4138d39f Iustin Pop
    # this doesn't raise, since we passed None
2502 4138d39f Iustin Pop
    utils.SafeWriteFile(name, None, data="")
2503 4138d39f Iustin Pop
2504 f40ae421 Iustin Pop
  def testError(self):
2505 f40ae421 Iustin Pop
    t = tempfile.NamedTemporaryFile()
2506 f40ae421 Iustin Pop
    self.assertRaises(errors.ProgrammerError, utils.GetFileID,
2507 f40ae421 Iustin Pop
                      path=t.name, fd=t.fileno())
2508 f40ae421 Iustin Pop
2509 9e100285 Iustin Pop
2510 e6784773 René Nussbaumer
class TimeMock:
2511 e6784773 René Nussbaumer
  def __init__(self, values):
2512 e6784773 René Nussbaumer
    self.values = values
2513 e6784773 René Nussbaumer
2514 e6784773 René Nussbaumer
  def __call__(self):
2515 e6784773 René Nussbaumer
    return self.values.pop(0)
2516 e6784773 René Nussbaumer
2517 e6784773 René Nussbaumer
2518 e6784773 René Nussbaumer
class TestRunningTimeout(unittest.TestCase):
2519 e6784773 René Nussbaumer
  def setUp(self):
2520 e6784773 René Nussbaumer
    self.time_fn = TimeMock([0.0, 0.3, 4.6, 6.5])
2521 e6784773 René Nussbaumer
2522 e6784773 René Nussbaumer
  def testRemainingFloat(self):
2523 e6784773 René Nussbaumer
    timeout = utils.RunningTimeout(5.0, True, _time_fn=self.time_fn)
2524 e6784773 René Nussbaumer
    self.assertAlmostEqual(timeout.Remaining(), 4.7)
2525 e6784773 René Nussbaumer
    self.assertAlmostEqual(timeout.Remaining(), 0.4)
2526 e6784773 René Nussbaumer
    self.assertAlmostEqual(timeout.Remaining(), -1.5)
2527 e6784773 René Nussbaumer
2528 e6784773 René Nussbaumer
  def testRemaining(self):
2529 e6784773 René Nussbaumer
    self.time_fn = TimeMock([0, 2, 4, 5, 6])
2530 e6784773 René Nussbaumer
    timeout = utils.RunningTimeout(5, True, _time_fn=self.time_fn)
2531 e6784773 René Nussbaumer
    self.assertEqual(timeout.Remaining(), 3)
2532 e6784773 René Nussbaumer
    self.assertEqual(timeout.Remaining(), 1)
2533 e6784773 René Nussbaumer
    self.assertEqual(timeout.Remaining(), 0)
2534 e6784773 René Nussbaumer
    self.assertEqual(timeout.Remaining(), -1)
2535 e6784773 René Nussbaumer
2536 e6784773 René Nussbaumer
  def testRemainingNonNegative(self):
2537 e6784773 René Nussbaumer
    timeout = utils.RunningTimeout(5.0, False, _time_fn=self.time_fn)
2538 e6784773 René Nussbaumer
    self.assertAlmostEqual(timeout.Remaining(), 4.7)
2539 e6784773 René Nussbaumer
    self.assertAlmostEqual(timeout.Remaining(), 0.4)
2540 e6784773 René Nussbaumer
    self.assertEqual(timeout.Remaining(), 0.0)
2541 e6784773 René Nussbaumer
2542 e6784773 René Nussbaumer
  def testNegativeTimeout(self):
2543 e6784773 René Nussbaumer
    self.assertRaises(ValueError, utils.RunningTimeout, -1.0, True)
2544 e6784773 René Nussbaumer
2545 e6784773 René Nussbaumer
2546 f40ae421 Iustin Pop
class TestTryConvert(unittest.TestCase):
2547 f40ae421 Iustin Pop
  def test(self):
2548 f40ae421 Iustin Pop
    for src, fn, result in [
2549 f40ae421 Iustin Pop
      ("1", int, 1),
2550 f40ae421 Iustin Pop
      ("a", int, "a"),
2551 f40ae421 Iustin Pop
      ("", bool, False),
2552 f40ae421 Iustin Pop
      ("a", bool, True),
2553 f40ae421 Iustin Pop
      ]:
2554 f40ae421 Iustin Pop
      self.assertEqual(utils.TryConvert(fn, src), result)
2555 f40ae421 Iustin Pop
2556 f40ae421 Iustin Pop
2557 f40ae421 Iustin Pop
class TestIsValidShellParam(unittest.TestCase):
2558 f40ae421 Iustin Pop
  def test(self):
2559 f40ae421 Iustin Pop
    for val, result in [
2560 f40ae421 Iustin Pop
      ("abc", True),
2561 f40ae421 Iustin Pop
      ("ab;cd", False),
2562 f40ae421 Iustin Pop
      ]:
2563 f40ae421 Iustin Pop
      self.assertEqual(utils.IsValidShellParam(val), result)
2564 f40ae421 Iustin Pop
2565 f40ae421 Iustin Pop
2566 f40ae421 Iustin Pop
class TestBuildShellCmd(unittest.TestCase):
2567 f40ae421 Iustin Pop
  def test(self):
2568 f40ae421 Iustin Pop
    self.assertRaises(errors.ProgrammerError, utils.BuildShellCmd,
2569 f40ae421 Iustin Pop
                      "ls %s", "ab;cd")
2570 f40ae421 Iustin Pop
    self.assertEqual(utils.BuildShellCmd("ls %s", "ab"), "ls ab")
2571 f40ae421 Iustin Pop
2572 f40ae421 Iustin Pop
2573 f40ae421 Iustin Pop
class TestWriteFile(unittest.TestCase):
2574 f40ae421 Iustin Pop
  def setUp(self):
2575 f40ae421 Iustin Pop
    self.tfile = tempfile.NamedTemporaryFile()
2576 f40ae421 Iustin Pop
    self.did_pre = False
2577 f40ae421 Iustin Pop
    self.did_post = False
2578 f40ae421 Iustin Pop
    self.did_write = False
2579 f40ae421 Iustin Pop
2580 f40ae421 Iustin Pop
  def markPre(self, fd):
2581 f40ae421 Iustin Pop
    self.did_pre = True
2582 f40ae421 Iustin Pop
2583 f40ae421 Iustin Pop
  def markPost(self, fd):
2584 f40ae421 Iustin Pop
    self.did_post = True
2585 f40ae421 Iustin Pop
2586 f40ae421 Iustin Pop
  def markWrite(self, fd):
2587 f40ae421 Iustin Pop
    self.did_write = True
2588 f40ae421 Iustin Pop
2589 f40ae421 Iustin Pop
  def testWrite(self):
2590 f40ae421 Iustin Pop
    data = "abc"
2591 f40ae421 Iustin Pop
    utils.WriteFile(self.tfile.name, data=data)
2592 f40ae421 Iustin Pop
    self.assertEqual(utils.ReadFile(self.tfile.name), data)
2593 f40ae421 Iustin Pop
2594 f40ae421 Iustin Pop
  def testErrors(self):
2595 f40ae421 Iustin Pop
    self.assertRaises(errors.ProgrammerError, utils.WriteFile,
2596 f40ae421 Iustin Pop
                      self.tfile.name, data="test", fn=lambda fd: None)
2597 f40ae421 Iustin Pop
    self.assertRaises(errors.ProgrammerError, utils.WriteFile, self.tfile.name)
2598 f40ae421 Iustin Pop
    self.assertRaises(errors.ProgrammerError, utils.WriteFile,
2599 f40ae421 Iustin Pop
                      self.tfile.name, data="test", atime=0)
2600 f40ae421 Iustin Pop
2601 f40ae421 Iustin Pop
  def testCalls(self):
2602 f40ae421 Iustin Pop
    utils.WriteFile(self.tfile.name, fn=self.markWrite,
2603 f40ae421 Iustin Pop
                    prewrite=self.markPre, postwrite=self.markPost)
2604 f40ae421 Iustin Pop
    self.assertTrue(self.did_pre)
2605 f40ae421 Iustin Pop
    self.assertTrue(self.did_post)
2606 f40ae421 Iustin Pop
    self.assertTrue(self.did_write)
2607 f40ae421 Iustin Pop
2608 f40ae421 Iustin Pop
  def testDryRun(self):
2609 f40ae421 Iustin Pop
    orig = "abc"
2610 f40ae421 Iustin Pop
    self.tfile.write(orig)
2611 f40ae421 Iustin Pop
    self.tfile.flush()
2612 f40ae421 Iustin Pop
    utils.WriteFile(self.tfile.name, data="hello", dry_run=True)
2613 f40ae421 Iustin Pop
    self.assertEqual(utils.ReadFile(self.tfile.name), orig)
2614 f40ae421 Iustin Pop
2615 f40ae421 Iustin Pop
  def testTimes(self):
2616 f40ae421 Iustin Pop
    f = self.tfile.name
2617 f40ae421 Iustin Pop
    for at, mt in [(0, 0), (1000, 1000), (2000, 3000),
2618 f40ae421 Iustin Pop
                   (int(time.time()), 5000)]:
2619 f40ae421 Iustin Pop
      utils.WriteFile(f, data="hello", atime=at, mtime=mt)
2620 f40ae421 Iustin Pop
      st = os.stat(f)
2621 f40ae421 Iustin Pop
      self.assertEqual(st.st_atime, at)
2622 f40ae421 Iustin Pop
      self.assertEqual(st.st_mtime, mt)
2623 f40ae421 Iustin Pop
2624 f40ae421 Iustin Pop
2625 f40ae421 Iustin Pop
  def testNoClose(self):
2626 f40ae421 Iustin Pop
    data = "hello"
2627 f40ae421 Iustin Pop
    self.assertEqual(utils.WriteFile(self.tfile.name, data="abc"), None)
2628 f40ae421 Iustin Pop
    fd = utils.WriteFile(self.tfile.name, data=data, close=False)
2629 f40ae421 Iustin Pop
    try:
2630 f40ae421 Iustin Pop
      os.lseek(fd, 0, 0)
2631 f40ae421 Iustin Pop
      self.assertEqual(os.read(fd, 4096), data)
2632 f40ae421 Iustin Pop
    finally:
2633 f40ae421 Iustin Pop
      os.close(fd)
2634 f40ae421 Iustin Pop
2635 f40ae421 Iustin Pop
2636 f40ae421 Iustin Pop
class TestNormalizeAndValidateMac(unittest.TestCase):
2637 f40ae421 Iustin Pop
  def testInvalid(self):
2638 f40ae421 Iustin Pop
    self.assertRaises(errors.OpPrereqError,
2639 f40ae421 Iustin Pop
                      utils.NormalizeAndValidateMac, "xxx")
2640 f40ae421 Iustin Pop
2641 f40ae421 Iustin Pop
  def testNormalization(self):
2642 f40ae421 Iustin Pop
    for mac in ["aa:bb:cc:dd:ee:ff", "00:AA:11:bB:22:cc"]:
2643 f40ae421 Iustin Pop
      self.assertEqual(utils.NormalizeAndValidateMac(mac), mac.lower())
2644 f40ae421 Iustin Pop
2645 f40ae421 Iustin Pop
2646 a8083063 Iustin Pop
if __name__ == '__main__':
2647 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()