Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils_unittest.py @ 339be5a8

History | View | Annotate | Download (52.8 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 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 a8083063 Iustin Pop
import unittest
25 a8083063 Iustin Pop
import os
26 a8083063 Iustin Pop
import time
27 a8083063 Iustin Pop
import tempfile
28 a8083063 Iustin Pop
import os.path
29 320b4e2d Alexander Schreiber
import os
30 6bb65e3a Guido Trotter
import stat
31 740c5aab Guido Trotter
import signal
32 2c30e9d7 Alexander Schreiber
import socket
33 eedbda4b Michael Hanselmann
import shutil
34 59072e7e Michael Hanselmann
import re
35 09352fa4 Iustin Pop
import select
36 d392fa34 Iustin Pop
import string
37 27e46076 Michael Hanselmann
import OpenSSL
38 27e46076 Michael Hanselmann
import warnings
39 27e46076 Michael Hanselmann
import distutils.version
40 1d466a4f Michael Hanselmann
import glob
41 a8083063 Iustin Pop
42 a8083063 Iustin Pop
import ganeti
43 c9c4f19e Michael Hanselmann
import testutils
44 16abfbc2 Alexander Schreiber
from ganeti import constants
45 59072e7e Michael Hanselmann
from ganeti import utils
46 a5728081 Guido Trotter
from ganeti import errors
47 e5392d79 Iustin Pop
from ganeti.utils import IsProcessAlive, RunCmd, \
48 31e22135 Iustin Pop
     RemoveFile, MatchNameComponent, FormatUnit, \
49 a8083063 Iustin Pop
     ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \
50 899d2a81 Michael Hanselmann
     ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles, \
51 f65f63ef Iustin Pop
     SetEtcHostsEntry, RemoveEtcHostsEntry, FirstFree, OwnIpAddress, \
52 5b69bc7c Iustin Pop
     TailFile, ForceDictType, SafeEncode, IsNormAbsPath, FormatTime, \
53 26288e68 Iustin Pop
     UnescapeAndSplit, RunParts, PathJoin, HostInfo
54 f65f63ef Iustin Pop
55 b2a1f511 Iustin Pop
from ganeti.errors import LockError, UnitParseError, GenericError, \
56 26288e68 Iustin Pop
     ProgrammerError, OpPrereqError
57 a8083063 Iustin Pop
58 d9f311d7 Iustin Pop
59 a8083063 Iustin Pop
class TestIsProcessAlive(unittest.TestCase):
60 a8083063 Iustin Pop
  """Testing case for IsProcessAlive"""
61 740c5aab Guido Trotter
62 a8083063 Iustin Pop
  def testExists(self):
63 a8083063 Iustin Pop
    mypid = os.getpid()
64 a8083063 Iustin Pop
    self.assert_(IsProcessAlive(mypid),
65 a8083063 Iustin Pop
                 "can't find myself running")
66 a8083063 Iustin Pop
67 a8083063 Iustin Pop
  def testNotExisting(self):
68 09352fa4 Iustin Pop
    pid_non_existing = os.fork()
69 09352fa4 Iustin Pop
    if pid_non_existing == 0:
70 09352fa4 Iustin Pop
      os._exit(0)
71 09352fa4 Iustin Pop
    elif pid_non_existing < 0:
72 09352fa4 Iustin Pop
      raise SystemError("can't fork")
73 09352fa4 Iustin Pop
    os.waitpid(pid_non_existing, 0)
74 09352fa4 Iustin Pop
    self.assert_(not IsProcessAlive(pid_non_existing),
75 09352fa4 Iustin Pop
                 "nonexisting process detected")
76 a8083063 Iustin Pop
77 d9f311d7 Iustin Pop
78 af99afa6 Guido Trotter
class TestPidFileFunctions(unittest.TestCase):
79 d9f311d7 Iustin Pop
  """Tests for WritePidFile, RemovePidFile and ReadPidFile"""
80 af99afa6 Guido Trotter
81 af99afa6 Guido Trotter
  def setUp(self):
82 af99afa6 Guido Trotter
    self.dir = tempfile.mkdtemp()
83 af99afa6 Guido Trotter
    self.f_dpn = lambda name: os.path.join(self.dir, "%s.pid" % name)
84 53beffbb Iustin Pop
    utils.DaemonPidFileName = self.f_dpn
85 af99afa6 Guido Trotter
86 af99afa6 Guido Trotter
  def testPidFileFunctions(self):
87 d9f311d7 Iustin Pop
    pid_file = self.f_dpn('test')
88 af99afa6 Guido Trotter
    utils.WritePidFile('test')
89 d9f311d7 Iustin Pop
    self.failUnless(os.path.exists(pid_file),
90 d9f311d7 Iustin Pop
                    "PID file should have been created")
91 d9f311d7 Iustin Pop
    read_pid = utils.ReadPidFile(pid_file)
92 d9f311d7 Iustin Pop
    self.failUnlessEqual(read_pid, os.getpid())
93 d9f311d7 Iustin Pop
    self.failUnless(utils.IsProcessAlive(read_pid))
94 d9f311d7 Iustin Pop
    self.failUnlessRaises(GenericError, utils.WritePidFile, 'test')
95 d9f311d7 Iustin Pop
    utils.RemovePidFile('test')
96 d9f311d7 Iustin Pop
    self.failIf(os.path.exists(pid_file),
97 d9f311d7 Iustin Pop
                "PID file should not exist anymore")
98 d9f311d7 Iustin Pop
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
99 d9f311d7 Iustin Pop
                         "ReadPidFile should return 0 for missing pid file")
100 d9f311d7 Iustin Pop
    fh = open(pid_file, "w")
101 d9f311d7 Iustin Pop
    fh.write("blah\n")
102 d9f311d7 Iustin Pop
    fh.close()
103 d9f311d7 Iustin Pop
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
104 d9f311d7 Iustin Pop
                         "ReadPidFile should return 0 for invalid pid file")
105 af99afa6 Guido Trotter
    utils.RemovePidFile('test')
106 d9f311d7 Iustin Pop
    self.failIf(os.path.exists(pid_file),
107 d9f311d7 Iustin Pop
                "PID file should not exist anymore")
108 af99afa6 Guido Trotter
109 b2a1f511 Iustin Pop
  def testKill(self):
110 b2a1f511 Iustin Pop
    pid_file = self.f_dpn('child')
111 b2a1f511 Iustin Pop
    r_fd, w_fd = os.pipe()
112 b2a1f511 Iustin Pop
    new_pid = os.fork()
113 b2a1f511 Iustin Pop
    if new_pid == 0: #child
114 b2a1f511 Iustin Pop
      utils.WritePidFile('child')
115 b2a1f511 Iustin Pop
      os.write(w_fd, 'a')
116 b2a1f511 Iustin Pop
      signal.pause()
117 b2a1f511 Iustin Pop
      os._exit(0)
118 b2a1f511 Iustin Pop
      return
119 b2a1f511 Iustin Pop
    # else we are in the parent
120 b2a1f511 Iustin Pop
    # wait until the child has written the pid file
121 b2a1f511 Iustin Pop
    os.read(r_fd, 1)
122 b2a1f511 Iustin Pop
    read_pid = utils.ReadPidFile(pid_file)
123 b2a1f511 Iustin Pop
    self.failUnlessEqual(read_pid, new_pid)
124 b2a1f511 Iustin Pop
    self.failUnless(utils.IsProcessAlive(new_pid))
125 ff5251bc Iustin Pop
    utils.KillProcess(new_pid, waitpid=True)
126 b2a1f511 Iustin Pop
    self.failIf(utils.IsProcessAlive(new_pid))
127 b2a1f511 Iustin Pop
    utils.RemovePidFile('child')
128 b2a1f511 Iustin Pop
    self.failUnlessRaises(ProgrammerError, utils.KillProcess, 0)
129 b2a1f511 Iustin Pop
130 af99afa6 Guido Trotter
  def tearDown(self):
131 d9f311d7 Iustin Pop
    for name in os.listdir(self.dir):
132 d9f311d7 Iustin Pop
      os.unlink(os.path.join(self.dir, name))
133 af99afa6 Guido Trotter
    os.rmdir(self.dir)
134 af99afa6 Guido Trotter
135 a8083063 Iustin Pop
136 36117c2b Iustin Pop
class TestRunCmd(testutils.GanetiTestCase):
137 a8083063 Iustin Pop
  """Testing case for the RunCmd function"""
138 a8083063 Iustin Pop
139 a8083063 Iustin Pop
  def setUp(self):
140 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
141 a8083063 Iustin Pop
    self.magic = time.ctime() + " ganeti test"
142 51596eb2 Iustin Pop
    self.fname = self._CreateTempFile()
143 a8083063 Iustin Pop
144 a8083063 Iustin Pop
  def testOk(self):
145 31ee599c Michael Hanselmann
    """Test successful exit code"""
146 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c 'exit 0'")
147 a8083063 Iustin Pop
    self.assertEqual(result.exit_code, 0)
148 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
149 a8083063 Iustin Pop
150 a8083063 Iustin Pop
  def testFail(self):
151 a8083063 Iustin Pop
    """Test fail exit code"""
152 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c 'exit 1'")
153 a8083063 Iustin Pop
    self.assertEqual(result.exit_code, 1)
154 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
155 a8083063 Iustin Pop
156 a8083063 Iustin Pop
  def testStdout(self):
157 a8083063 Iustin Pop
    """Test standard output"""
158 a8083063 Iustin Pop
    cmd = 'echo -n "%s"' % self.magic
159 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd)
160 a8083063 Iustin Pop
    self.assertEqual(result.stdout, self.magic)
161 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd, output=self.fname)
162 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
163 36117c2b Iustin Pop
    self.assertFileContent(self.fname, self.magic)
164 a8083063 Iustin Pop
165 a8083063 Iustin Pop
  def testStderr(self):
166 a8083063 Iustin Pop
    """Test standard error"""
167 a8083063 Iustin Pop
    cmd = 'echo -n "%s"' % self.magic
168 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s' 1>&2" % cmd)
169 a8083063 Iustin Pop
    self.assertEqual(result.stderr, self.magic)
170 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s' 1>&2" % cmd, output=self.fname)
171 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
172 36117c2b Iustin Pop
    self.assertFileContent(self.fname, self.magic)
173 a8083063 Iustin Pop
174 a8083063 Iustin Pop
  def testCombined(self):
175 a8083063 Iustin Pop
    """Test combined output"""
176 a8083063 Iustin Pop
    cmd = 'echo -n "A%s"; echo -n "B%s" 1>&2' % (self.magic, self.magic)
177 36117c2b Iustin Pop
    expected = "A" + self.magic + "B" + self.magic
178 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd)
179 36117c2b Iustin Pop
    self.assertEqual(result.output, expected)
180 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd, output=self.fname)
181 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
182 36117c2b Iustin Pop
    self.assertFileContent(self.fname, expected)
183 a8083063 Iustin Pop
184 a8083063 Iustin Pop
  def testSignal(self):
185 01fd6005 Manuel Franceschini
    """Test signal"""
186 01fd6005 Manuel Franceschini
    result = RunCmd(["python", "-c", "import os; os.kill(os.getpid(), 15)"])
187 a8083063 Iustin Pop
    self.assertEqual(result.signal, 15)
188 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
189 a8083063 Iustin Pop
190 7fcf849f Iustin Pop
  def testListRun(self):
191 7fcf849f Iustin Pop
    """Test list runs"""
192 7fcf849f Iustin Pop
    result = RunCmd(["true"])
193 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
194 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 0)
195 7fcf849f Iustin Pop
    result = RunCmd(["/bin/sh", "-c", "exit 1"])
196 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
197 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 1)
198 7fcf849f Iustin Pop
    result = RunCmd(["echo", "-n", self.magic])
199 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
200 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 0)
201 7fcf849f Iustin Pop
    self.assertEqual(result.stdout, self.magic)
202 7fcf849f Iustin Pop
203 36117c2b Iustin Pop
  def testFileEmptyOutput(self):
204 36117c2b Iustin Pop
    """Test file output"""
205 36117c2b Iustin Pop
    result = RunCmd(["true"], output=self.fname)
206 36117c2b Iustin Pop
    self.assertEqual(result.signal, None)
207 36117c2b Iustin Pop
    self.assertEqual(result.exit_code, 0)
208 36117c2b Iustin Pop
    self.assertFileContent(self.fname, "")
209 36117c2b Iustin Pop
210 f6441c7c Iustin Pop
  def testLang(self):
211 f6441c7c Iustin Pop
    """Test locale environment"""
212 23f41a3e Michael Hanselmann
    old_env = os.environ.copy()
213 23f41a3e Michael Hanselmann
    try:
214 23f41a3e Michael Hanselmann
      os.environ["LANG"] = "en_US.UTF-8"
215 23f41a3e Michael Hanselmann
      os.environ["LC_ALL"] = "en_US.UTF-8"
216 23f41a3e Michael Hanselmann
      result = RunCmd(["locale"])
217 23f41a3e Michael Hanselmann
      for line in result.output.splitlines():
218 23f41a3e Michael Hanselmann
        key, value = line.split("=", 1)
219 23f41a3e Michael Hanselmann
        # Ignore these variables, they're overridden by LC_ALL
220 23f41a3e Michael Hanselmann
        if key == "LANG" or key == "LANGUAGE":
221 23f41a3e Michael Hanselmann
          continue
222 23f41a3e Michael Hanselmann
        self.failIf(value and value != "C" and value != '"C"',
223 23f41a3e Michael Hanselmann
            "Variable %s is set to the invalid value '%s'" % (key, value))
224 23f41a3e Michael Hanselmann
    finally:
225 23f41a3e Michael Hanselmann
      os.environ = old_env
226 f6441c7c Iustin Pop
227 8797df43 Iustin Pop
  def testDefaultCwd(self):
228 8797df43 Iustin Pop
    """Test default working directory"""
229 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"]).stdout.strip(), "/")
230 8797df43 Iustin Pop
231 8797df43 Iustin Pop
  def testCwd(self):
232 8797df43 Iustin Pop
    """Test default working directory"""
233 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd="/").stdout.strip(), "/")
234 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd="/tmp").stdout.strip(), "/tmp")
235 8797df43 Iustin Pop
    cwd = os.getcwd()
236 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd=cwd).stdout.strip(), cwd)
237 8797df43 Iustin Pop
238 bf4daac9 Guido Trotter
  def testResetEnv(self):
239 bf4daac9 Guido Trotter
    """Test environment reset functionality"""
240 bf4daac9 Guido Trotter
    self.failUnlessEqual(RunCmd(["env"], reset_env=True).stdout.strip(), "")
241 0babc371 Michael Hanselmann
    self.failUnlessEqual(RunCmd(["env"], reset_env=True,
242 0babc371 Michael Hanselmann
                                env={"FOO": "bar",}).stdout.strip(), "FOO=bar")
243 bf4daac9 Guido Trotter
244 a8083063 Iustin Pop
245 6bb65e3a Guido Trotter
class TestRunParts(unittest.TestCase):
246 6bb65e3a Guido Trotter
  """Testing case for the RunParts function"""
247 6bb65e3a Guido Trotter
248 6bb65e3a Guido Trotter
  def setUp(self):
249 6bb65e3a Guido Trotter
    self.rundir = tempfile.mkdtemp(prefix="ganeti-test", suffix=".tmp")
250 6bb65e3a Guido Trotter
251 6bb65e3a Guido Trotter
  def tearDown(self):
252 6bb65e3a Guido Trotter
    shutil.rmtree(self.rundir)
253 6bb65e3a Guido Trotter
254 6bb65e3a Guido Trotter
  def testEmpty(self):
255 6bb65e3a Guido Trotter
    """Test on an empty dir"""
256 6bb65e3a Guido Trotter
    self.failUnlessEqual(RunParts(self.rundir, reset_env=True), [])
257 6bb65e3a Guido Trotter
258 6bb65e3a Guido Trotter
  def testSkipWrongName(self):
259 6bb65e3a Guido Trotter
    """Test that wrong files are skipped"""
260 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test.dot")
261 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="")
262 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
263 6bb65e3a Guido Trotter
    relname = os.path.basename(fname)
264 6bb65e3a Guido Trotter
    self.failUnlessEqual(RunParts(self.rundir, reset_env=True),
265 6bb65e3a Guido Trotter
                         [(relname, constants.RUNPARTS_SKIP, None)])
266 6bb65e3a Guido Trotter
267 6bb65e3a Guido Trotter
  def testSkipNonExec(self):
268 6bb65e3a Guido Trotter
    """Test that non executable files are skipped"""
269 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
270 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="")
271 6bb65e3a Guido Trotter
    relname = os.path.basename(fname)
272 6bb65e3a Guido Trotter
    self.failUnlessEqual(RunParts(self.rundir, reset_env=True),
273 6bb65e3a Guido Trotter
                         [(relname, constants.RUNPARTS_SKIP, None)])
274 6bb65e3a Guido Trotter
275 6bb65e3a Guido Trotter
  def testError(self):
276 6bb65e3a Guido Trotter
    """Test error on a broken executable"""
277 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
278 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="")
279 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
280 6bb65e3a Guido Trotter
    (relname, status, error) = RunParts(self.rundir, reset_env=True)[0]
281 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(fname))
282 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_ERR)
283 6bb65e3a Guido Trotter
    self.failUnless(error)
284 6bb65e3a Guido Trotter
285 6bb65e3a Guido Trotter
  def testSorted(self):
286 6bb65e3a Guido Trotter
    """Test executions are sorted"""
287 6bb65e3a Guido Trotter
    files = []
288 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "64test"))
289 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "00test"))
290 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "42test"))
291 6bb65e3a Guido Trotter
292 6bb65e3a Guido Trotter
    for fname in files:
293 6bb65e3a Guido Trotter
      utils.WriteFile(fname, data="")
294 6bb65e3a Guido Trotter
295 6bb65e3a Guido Trotter
    results = RunParts(self.rundir, reset_env=True)
296 6bb65e3a Guido Trotter
297 6bb65e3a Guido Trotter
    for fname in sorted(files):
298 6bb65e3a Guido Trotter
      self.failUnlessEqual(os.path.basename(fname), results.pop(0)[0])
299 6bb65e3a Guido Trotter
300 6bb65e3a Guido Trotter
  def testOk(self):
301 6bb65e3a Guido Trotter
    """Test correct execution"""
302 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
303 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="#!/bin/sh\n\necho -n ciao")
304 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
305 6bb65e3a Guido Trotter
    (relname, status, runresult) = RunParts(self.rundir, reset_env=True)[0]
306 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(fname))
307 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
308 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.stdout, "ciao")
309 6bb65e3a Guido Trotter
310 6bb65e3a Guido Trotter
  def testRunFail(self):
311 6bb65e3a Guido Trotter
    """Test correct execution, with run failure"""
312 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
313 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="#!/bin/sh\n\nexit 1")
314 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
315 6bb65e3a Guido Trotter
    (relname, status, runresult) = RunParts(self.rundir, reset_env=True)[0]
316 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(fname))
317 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
318 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.exit_code, 1)
319 6bb65e3a Guido Trotter
    self.failUnless(runresult.failed)
320 6bb65e3a Guido Trotter
321 6bb65e3a Guido Trotter
  def testRunMix(self):
322 6bb65e3a Guido Trotter
    files = []
323 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "00test"))
324 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "42test"))
325 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "64test"))
326 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "99test"))
327 6bb65e3a Guido Trotter
328 6bb65e3a Guido Trotter
    files.sort()
329 6bb65e3a Guido Trotter
330 6bb65e3a Guido Trotter
    # 1st has errors in execution
331 6bb65e3a Guido Trotter
    utils.WriteFile(files[0], data="#!/bin/sh\n\nexit 1")
332 6bb65e3a Guido Trotter
    os.chmod(files[0], stat.S_IREAD | stat.S_IEXEC)
333 6bb65e3a Guido Trotter
334 6bb65e3a Guido Trotter
    # 2nd is skipped
335 6bb65e3a Guido Trotter
    utils.WriteFile(files[1], data="")
336 6bb65e3a Guido Trotter
337 6bb65e3a Guido Trotter
    # 3rd cannot execute properly
338 6bb65e3a Guido Trotter
    utils.WriteFile(files[2], data="")
339 6bb65e3a Guido Trotter
    os.chmod(files[2], stat.S_IREAD | stat.S_IEXEC)
340 6bb65e3a Guido Trotter
341 6bb65e3a Guido Trotter
    # 4th execs
342 6bb65e3a Guido Trotter
    utils.WriteFile(files[3], data="#!/bin/sh\n\necho -n ciao")
343 6bb65e3a Guido Trotter
    os.chmod(files[3], stat.S_IREAD | stat.S_IEXEC)
344 6bb65e3a Guido Trotter
345 6bb65e3a Guido Trotter
    results = RunParts(self.rundir, reset_env=True)
346 6bb65e3a Guido Trotter
347 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[0]
348 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[0]))
349 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
350 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.exit_code, 1)
351 6bb65e3a Guido Trotter
    self.failUnless(runresult.failed)
352 6bb65e3a Guido Trotter
353 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[1]
354 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[1]))
355 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_SKIP)
356 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult, None)
357 6bb65e3a Guido Trotter
358 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[2]
359 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[2]))
360 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_ERR)
361 6bb65e3a Guido Trotter
    self.failUnless(runresult)
362 6bb65e3a Guido Trotter
363 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[3]
364 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[3]))
365 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
366 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.output, "ciao")
367 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.exit_code, 0)
368 6bb65e3a Guido Trotter
    self.failUnless(not runresult.failed)
369 6bb65e3a Guido Trotter
370 6bb65e3a Guido Trotter
371 a8083063 Iustin Pop
class TestRemoveFile(unittest.TestCase):
372 a8083063 Iustin Pop
  """Test case for the RemoveFile function"""
373 a8083063 Iustin Pop
374 a8083063 Iustin Pop
  def setUp(self):
375 a8083063 Iustin Pop
    """Create a temp dir and file for each case"""
376 a8083063 Iustin Pop
    self.tmpdir = tempfile.mkdtemp('', 'ganeti-unittest-')
377 a8083063 Iustin Pop
    fd, self.tmpfile = tempfile.mkstemp('', '', self.tmpdir)
378 a8083063 Iustin Pop
    os.close(fd)
379 a8083063 Iustin Pop
380 a8083063 Iustin Pop
  def tearDown(self):
381 a8083063 Iustin Pop
    if os.path.exists(self.tmpfile):
382 a8083063 Iustin Pop
      os.unlink(self.tmpfile)
383 a8083063 Iustin Pop
    os.rmdir(self.tmpdir)
384 a8083063 Iustin Pop
385 a8083063 Iustin Pop
386 a8083063 Iustin Pop
  def testIgnoreDirs(self):
387 a8083063 Iustin Pop
    """Test that RemoveFile() ignores directories"""
388 a8083063 Iustin Pop
    self.assertEqual(None, RemoveFile(self.tmpdir))
389 a8083063 Iustin Pop
390 a8083063 Iustin Pop
391 a8083063 Iustin Pop
  def testIgnoreNotExisting(self):
392 a8083063 Iustin Pop
    """Test that RemoveFile() ignores non-existing files"""
393 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
394 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
395 a8083063 Iustin Pop
396 a8083063 Iustin Pop
397 a8083063 Iustin Pop
  def testRemoveFile(self):
398 a8083063 Iustin Pop
    """Test that RemoveFile does remove a file"""
399 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
400 a8083063 Iustin Pop
    if os.path.exists(self.tmpfile):
401 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % self.tmpfile)
402 a8083063 Iustin Pop
403 a8083063 Iustin Pop
404 a8083063 Iustin Pop
  def testRemoveSymlink(self):
405 a8083063 Iustin Pop
    """Test that RemoveFile does remove symlinks"""
406 a8083063 Iustin Pop
    symlink = self.tmpdir + "/symlink"
407 a8083063 Iustin Pop
    os.symlink("no-such-file", symlink)
408 a8083063 Iustin Pop
    RemoveFile(symlink)
409 a8083063 Iustin Pop
    if os.path.exists(symlink):
410 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % symlink)
411 a8083063 Iustin Pop
    os.symlink(self.tmpfile, symlink)
412 a8083063 Iustin Pop
    RemoveFile(symlink)
413 a8083063 Iustin Pop
    if os.path.exists(symlink):
414 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % symlink)
415 a8083063 Iustin Pop
416 a8083063 Iustin Pop
417 6e797216 Michael Hanselmann
class TestRename(unittest.TestCase):
418 6e797216 Michael Hanselmann
  """Test case for RenameFile"""
419 6e797216 Michael Hanselmann
420 6e797216 Michael Hanselmann
  def setUp(self):
421 6e797216 Michael Hanselmann
    """Create a temporary directory"""
422 6e797216 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
423 6e797216 Michael Hanselmann
    self.tmpfile = os.path.join(self.tmpdir, "test1")
424 6e797216 Michael Hanselmann
425 6e797216 Michael Hanselmann
    # Touch the file
426 6e797216 Michael Hanselmann
    open(self.tmpfile, "w").close()
427 6e797216 Michael Hanselmann
428 6e797216 Michael Hanselmann
  def tearDown(self):
429 6e797216 Michael Hanselmann
    """Remove temporary directory"""
430 6e797216 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
431 6e797216 Michael Hanselmann
432 6e797216 Michael Hanselmann
  def testSimpleRename1(self):
433 6e797216 Michael Hanselmann
    """Simple rename 1"""
434 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"))
435 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "xyz")))
436 6e797216 Michael Hanselmann
437 6e797216 Michael Hanselmann
  def testSimpleRename2(self):
438 6e797216 Michael Hanselmann
    """Simple rename 2"""
439 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"),
440 6e797216 Michael Hanselmann
                     mkdir=True)
441 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "xyz")))
442 6e797216 Michael Hanselmann
443 6e797216 Michael Hanselmann
  def testRenameMkdir(self):
444 6e797216 Michael Hanselmann
    """Rename with mkdir"""
445 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "test/xyz"),
446 6e797216 Michael Hanselmann
                     mkdir=True)
447 a426508d Michael Hanselmann
    self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test")))
448 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "test/xyz")))
449 a426508d Michael Hanselmann
450 a426508d Michael Hanselmann
    utils.RenameFile(os.path.join(self.tmpdir, "test/xyz"),
451 a426508d Michael Hanselmann
                     os.path.join(self.tmpdir, "test/foo/bar/baz"),
452 a426508d Michael Hanselmann
                     mkdir=True)
453 a426508d Michael Hanselmann
    self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test")))
454 a426508d Michael Hanselmann
    self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test/foo/bar")))
455 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "test/foo/bar/baz")))
456 6e797216 Michael Hanselmann
457 6e797216 Michael Hanselmann
458 a8083063 Iustin Pop
class TestMatchNameComponent(unittest.TestCase):
459 a8083063 Iustin Pop
  """Test case for the MatchNameComponent function"""
460 a8083063 Iustin Pop
461 a8083063 Iustin Pop
  def testEmptyList(self):
462 a8083063 Iustin Pop
    """Test that there is no match against an empty list"""
463 a8083063 Iustin Pop
464 a8083063 Iustin Pop
    self.failUnlessEqual(MatchNameComponent("", []), None)
465 a8083063 Iustin Pop
    self.failUnlessEqual(MatchNameComponent("test", []), None)
466 a8083063 Iustin Pop
467 a8083063 Iustin Pop
  def testSingleMatch(self):
468 a8083063 Iustin Pop
    """Test that a single match is performed correctly"""
469 a8083063 Iustin Pop
    mlist = ["test1.example.com", "test2.example.com", "test3.example.com"]
470 a8083063 Iustin Pop
    for key in "test2", "test2.example", "test2.example.com":
471 a8083063 Iustin Pop
      self.failUnlessEqual(MatchNameComponent(key, mlist), mlist[1])
472 a8083063 Iustin Pop
473 a8083063 Iustin Pop
  def testMultipleMatches(self):
474 a8083063 Iustin Pop
    """Test that a multiple match is returned as None"""
475 a8083063 Iustin Pop
    mlist = ["test1.example.com", "test1.example.org", "test1.example.net"]
476 a8083063 Iustin Pop
    for key in "test1", "test1.example":
477 a8083063 Iustin Pop
      self.failUnlessEqual(MatchNameComponent(key, mlist), None)
478 a8083063 Iustin Pop
479 3a541d90 Iustin Pop
  def testFullMatch(self):
480 3a541d90 Iustin Pop
    """Test that a full match is returned correctly"""
481 3a541d90 Iustin Pop
    key1 = "test1"
482 3a541d90 Iustin Pop
    key2 = "test1.example"
483 3a541d90 Iustin Pop
    mlist = [key2, key2 + ".com"]
484 3a541d90 Iustin Pop
    self.failUnlessEqual(MatchNameComponent(key1, mlist), None)
485 3a541d90 Iustin Pop
    self.failUnlessEqual(MatchNameComponent(key2, mlist), key2)
486 3a541d90 Iustin Pop
487 256eb94b Guido Trotter
  def testCaseInsensitivePartialMatch(self):
488 256eb94b Guido Trotter
    """Test for the case_insensitive keyword"""
489 256eb94b Guido Trotter
    mlist = ["test1.example.com", "test2.example.net"]
490 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("test2", mlist, case_sensitive=False),
491 256eb94b Guido Trotter
                     "test2.example.net")
492 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Test2", mlist, case_sensitive=False),
493 256eb94b Guido Trotter
                     "test2.example.net")
494 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("teSt2", mlist, case_sensitive=False),
495 256eb94b Guido Trotter
                     "test2.example.net")
496 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("TeSt2", mlist, case_sensitive=False),
497 256eb94b Guido Trotter
                     "test2.example.net")
498 256eb94b Guido Trotter
499 256eb94b Guido Trotter
500 256eb94b Guido Trotter
  def testCaseInsensitiveFullMatch(self):
501 256eb94b Guido Trotter
    mlist = ["ts1.ex", "ts1.ex.org", "ts2.ex", "Ts2.ex"]
502 256eb94b Guido Trotter
    # Between the two ts1 a full string match non-case insensitive should work
503 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Ts1", mlist, case_sensitive=False),
504 256eb94b Guido Trotter
                     None)
505 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Ts1.ex", mlist, case_sensitive=False),
506 256eb94b Guido Trotter
                     "ts1.ex")
507 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("ts1.ex", mlist, case_sensitive=False),
508 256eb94b Guido Trotter
                     "ts1.ex")
509 256eb94b Guido Trotter
    # Between the two ts2 only case differs, so only case-match works
510 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("ts2.ex", mlist, case_sensitive=False),
511 256eb94b Guido Trotter
                     "ts2.ex")
512 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Ts2.ex", mlist, case_sensitive=False),
513 256eb94b Guido Trotter
                     "Ts2.ex")
514 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("TS2.ex", mlist, case_sensitive=False),
515 256eb94b Guido Trotter
                     None)
516 256eb94b Guido Trotter
517 a8083063 Iustin Pop
518 1d466a4f Michael Hanselmann
class TestTimestampForFilename(unittest.TestCase):
519 1d466a4f Michael Hanselmann
  def test(self):
520 1d466a4f Michael Hanselmann
    self.assert_("." not in utils.TimestampForFilename())
521 1d466a4f Michael Hanselmann
    self.assert_(":" not in utils.TimestampForFilename())
522 1d466a4f Michael Hanselmann
523 1d466a4f Michael Hanselmann
524 1d466a4f Michael Hanselmann
class TestCreateBackup(testutils.GanetiTestCase):
525 1d466a4f Michael Hanselmann
  def setUp(self):
526 1d466a4f Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
527 1d466a4f Michael Hanselmann
528 1d466a4f Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
529 1d466a4f Michael Hanselmann
530 1d466a4f Michael Hanselmann
  def tearDown(self):
531 1d466a4f Michael Hanselmann
    testutils.GanetiTestCase.tearDown(self)
532 1d466a4f Michael Hanselmann
533 1d466a4f Michael Hanselmann
    shutil.rmtree(self.tmpdir)
534 1d466a4f Michael Hanselmann
535 1d466a4f Michael Hanselmann
  def testEmpty(self):
536 1d466a4f Michael Hanselmann
    filename = utils.PathJoin(self.tmpdir, "config.data")
537 1d466a4f Michael Hanselmann
    utils.WriteFile(filename, data="")
538 1d466a4f Michael Hanselmann
    bname = utils.CreateBackup(filename)
539 1d466a4f Michael Hanselmann
    self.assertFileContent(bname, "")
540 1d466a4f Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 2)
541 1d466a4f Michael Hanselmann
    utils.CreateBackup(filename)
542 1d466a4f Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 3)
543 1d466a4f Michael Hanselmann
    utils.CreateBackup(filename)
544 1d466a4f Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 4)
545 1d466a4f Michael Hanselmann
546 1d466a4f Michael Hanselmann
    fifoname = utils.PathJoin(self.tmpdir, "fifo")
547 1d466a4f Michael Hanselmann
    os.mkfifo(fifoname)
548 1d466a4f Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, utils.CreateBackup, fifoname)
549 1d466a4f Michael Hanselmann
550 1d466a4f Michael Hanselmann
  def testContent(self):
551 1d466a4f Michael Hanselmann
    bkpcount = 0
552 1d466a4f Michael Hanselmann
    for data in ["", "X", "Hello World!\n" * 100, "Binary data\0\x01\x02\n"]:
553 1d466a4f Michael Hanselmann
      for rep in [1, 2, 10, 127]:
554 1d466a4f Michael Hanselmann
        testdata = data * rep
555 1d466a4f Michael Hanselmann
556 1d466a4f Michael Hanselmann
        filename = utils.PathJoin(self.tmpdir, "test.data_")
557 1d466a4f Michael Hanselmann
        utils.WriteFile(filename, data=testdata)
558 1d466a4f Michael Hanselmann
        self.assertFileContent(filename, testdata)
559 1d466a4f Michael Hanselmann
560 1d466a4f Michael Hanselmann
        for _ in range(3):
561 1d466a4f Michael Hanselmann
          bname = utils.CreateBackup(filename)
562 1d466a4f Michael Hanselmann
          bkpcount += 1
563 1d466a4f Michael Hanselmann
          self.assertFileContent(bname, testdata)
564 1d466a4f Michael Hanselmann
          self.assertEqual(len(glob.glob("%s*" % filename)), 1 + bkpcount)
565 1d466a4f Michael Hanselmann
566 1d466a4f Michael Hanselmann
567 a8083063 Iustin Pop
class TestFormatUnit(unittest.TestCase):
568 a8083063 Iustin Pop
  """Test case for the FormatUnit function"""
569 a8083063 Iustin Pop
570 a8083063 Iustin Pop
  def testMiB(self):
571 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1, 'h'), '1M')
572 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(100, 'h'), '100M')
573 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1023, 'h'), '1023M')
574 9fbfbb7b Iustin Pop
575 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1, 'm'), '1')
576 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(100, 'm'), '100')
577 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1023, 'm'), '1023')
578 9fbfbb7b Iustin Pop
579 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'm'), '1024')
580 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'm'), '1536')
581 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'm'), '17133')
582 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'm'), '1048575')
583 a8083063 Iustin Pop
584 a8083063 Iustin Pop
  def testGiB(self):
585 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'h'), '1.0G')
586 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'h'), '1.5G')
587 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'h'), '16.7G')
588 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'h'), '1024.0G')
589 9fbfbb7b Iustin Pop
590 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'g'), '1.0')
591 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'g'), '1.5')
592 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'g'), '16.7')
593 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'g'), '1024.0')
594 9fbfbb7b Iustin Pop
595 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 'g'), '1024.0')
596 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 'g'), '5120.0')
597 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 'g'), '29829.0')
598 a8083063 Iustin Pop
599 a8083063 Iustin Pop
  def testTiB(self):
600 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 'h'), '1.0T')
601 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 'h'), '5.0T')
602 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 'h'), '29.1T')
603 a8083063 Iustin Pop
604 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 't'), '1.0')
605 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 't'), '5.0')
606 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 't'), '29.1')
607 a8083063 Iustin Pop
608 a8083063 Iustin Pop
class TestParseUnit(unittest.TestCase):
609 a8083063 Iustin Pop
  """Test case for the ParseUnit function"""
610 a8083063 Iustin Pop
611 a8083063 Iustin Pop
  SCALES = (('', 1),
612 a8083063 Iustin Pop
            ('M', 1), ('G', 1024), ('T', 1024 * 1024),
613 a8083063 Iustin Pop
            ('MB', 1), ('GB', 1024), ('TB', 1024 * 1024),
614 a8083063 Iustin Pop
            ('MiB', 1), ('GiB', 1024), ('TiB', 1024 * 1024))
615 a8083063 Iustin Pop
616 a8083063 Iustin Pop
  def testRounding(self):
617 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0'), 0)
618 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1'), 4)
619 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2'), 4)
620 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('3'), 4)
621 a8083063 Iustin Pop
622 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('124'), 124)
623 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('125'), 128)
624 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('126'), 128)
625 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('127'), 128)
626 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('128'), 128)
627 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('129'), 132)
628 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('130'), 132)
629 a8083063 Iustin Pop
630 a8083063 Iustin Pop
  def testFloating(self):
631 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0'), 0)
632 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0.5'), 4)
633 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.75'), 4)
634 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.99'), 4)
635 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2.00'), 4)
636 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2.01'), 4)
637 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('3.99'), 4)
638 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('4.00'), 4)
639 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('4.01'), 8)
640 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.5G'), 1536)
641 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.8G'), 1844)
642 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('8.28T'), 8682212)
643 a8083063 Iustin Pop
644 a8083063 Iustin Pop
  def testSuffixes(self):
645 a8083063 Iustin Pop
    for sep in ('', ' ', '   ', "\t", "\t "):
646 a8083063 Iustin Pop
      for suffix, scale in TestParseUnit.SCALES:
647 a8083063 Iustin Pop
        for func in (lambda x: x, str.lower, str.upper):
648 667479d5 Michael Hanselmann
          self.assertEqual(ParseUnit('1024' + sep + func(suffix)),
649 667479d5 Michael Hanselmann
                           1024 * scale)
650 a8083063 Iustin Pop
651 a8083063 Iustin Pop
  def testInvalidInput(self):
652 a8083063 Iustin Pop
    for sep in ('-', '_', ',', 'a'):
653 a8083063 Iustin Pop
      for suffix, _ in TestParseUnit.SCALES:
654 a8083063 Iustin Pop
        self.assertRaises(UnitParseError, ParseUnit, '1' + sep + suffix)
655 a8083063 Iustin Pop
656 a8083063 Iustin Pop
    for suffix, _ in TestParseUnit.SCALES:
657 a8083063 Iustin Pop
      self.assertRaises(UnitParseError, ParseUnit, '1,3' + suffix)
658 a8083063 Iustin Pop
659 a8083063 Iustin Pop
660 c9c4f19e Michael Hanselmann
class TestSshKeys(testutils.GanetiTestCase):
661 a8083063 Iustin Pop
  """Test case for the AddAuthorizedKey function"""
662 a8083063 Iustin Pop
663 a8083063 Iustin Pop
  KEY_A = 'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a'
664 a8083063 Iustin Pop
  KEY_B = ('command="/usr/bin/fooserver -t --verbose",from="1.2.3.4" '
665 a8083063 Iustin Pop
           'ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b')
666 a8083063 Iustin Pop
667 ebe8ef17 Michael Hanselmann
  def setUp(self):
668 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
669 51596eb2 Iustin Pop
    self.tmpname = self._CreateTempFile()
670 51596eb2 Iustin Pop
    handle = open(self.tmpname, 'w')
671 a8083063 Iustin Pop
    try:
672 51596eb2 Iustin Pop
      handle.write("%s\n" % TestSshKeys.KEY_A)
673 51596eb2 Iustin Pop
      handle.write("%s\n" % TestSshKeys.KEY_B)
674 51596eb2 Iustin Pop
    finally:
675 51596eb2 Iustin Pop
      handle.close()
676 a8083063 Iustin Pop
677 a8083063 Iustin Pop
  def testAddingNewKey(self):
678 ebe8ef17 Michael Hanselmann
    AddAuthorizedKey(self.tmpname, 'ssh-dss AAAAB3NzaC1kc3MAAACB root@test')
679 a8083063 Iustin Pop
680 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
681 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
682 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
683 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
684 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1kc3MAAACB root@test\n")
685 a8083063 Iustin Pop
686 f89f17a8 Michael Hanselmann
  def testAddingAlmostButNotCompletelyTheSameKey(self):
687 ebe8ef17 Michael Hanselmann
    AddAuthorizedKey(self.tmpname,
688 ebe8ef17 Michael Hanselmann
        'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test')
689 ebe8ef17 Michael Hanselmann
690 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
691 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
692 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
693 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
694 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test\n")
695 a8083063 Iustin Pop
696 a8083063 Iustin Pop
  def testAddingExistingKeyWithSomeMoreSpaces(self):
697 ebe8ef17 Michael Hanselmann
    AddAuthorizedKey(self.tmpname,
698 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
699 a8083063 Iustin Pop
700 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
701 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
702 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
703 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
704 a8083063 Iustin Pop
705 a8083063 Iustin Pop
  def testRemovingExistingKeyWithSomeMoreSpaces(self):
706 ebe8ef17 Michael Hanselmann
    RemoveAuthorizedKey(self.tmpname,
707 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
708 a8083063 Iustin Pop
709 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
710 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
711 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
712 a8083063 Iustin Pop
713 a8083063 Iustin Pop
  def testRemovingNonExistingKey(self):
714 ebe8ef17 Michael Hanselmann
    RemoveAuthorizedKey(self.tmpname,
715 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3Nsdfj230xxjxJjsjwjsjdjU   root@test')
716 a8083063 Iustin Pop
717 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
718 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
719 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
720 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
721 a8083063 Iustin Pop
722 a8083063 Iustin Pop
723 c9c4f19e Michael Hanselmann
class TestEtcHosts(testutils.GanetiTestCase):
724 899d2a81 Michael Hanselmann
  """Test functions modifying /etc/hosts"""
725 899d2a81 Michael Hanselmann
726 ebe8ef17 Michael Hanselmann
  def setUp(self):
727 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
728 51596eb2 Iustin Pop
    self.tmpname = self._CreateTempFile()
729 51596eb2 Iustin Pop
    handle = open(self.tmpname, 'w')
730 899d2a81 Michael Hanselmann
    try:
731 51596eb2 Iustin Pop
      handle.write('# This is a test file for /etc/hosts\n')
732 51596eb2 Iustin Pop
      handle.write('127.0.0.1\tlocalhost\n')
733 51596eb2 Iustin Pop
      handle.write('192.168.1.1 router gw\n')
734 51596eb2 Iustin Pop
    finally:
735 51596eb2 Iustin Pop
      handle.close()
736 899d2a81 Michael Hanselmann
737 9440aeab Michael Hanselmann
  def testSettingNewIp(self):
738 ebe8ef17 Michael Hanselmann
    SetEtcHostsEntry(self.tmpname, '1.2.3.4', 'myhost.domain.tld', ['myhost'])
739 899d2a81 Michael Hanselmann
740 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
741 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
742 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
743 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router gw\n"
744 ebe8ef17 Michael Hanselmann
      "1.2.3.4\tmyhost.domain.tld myhost\n")
745 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
746 899d2a81 Michael Hanselmann
747 9440aeab Michael Hanselmann
  def testSettingExistingIp(self):
748 ebe8ef17 Michael Hanselmann
    SetEtcHostsEntry(self.tmpname, '192.168.1.1', 'myhost.domain.tld',
749 ebe8ef17 Michael Hanselmann
                     ['myhost'])
750 899d2a81 Michael Hanselmann
751 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
752 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
753 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
754 ebe8ef17 Michael Hanselmann
      "192.168.1.1\tmyhost.domain.tld myhost\n")
755 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
756 899d2a81 Michael Hanselmann
757 7fbb1f65 Michael Hanselmann
  def testSettingDuplicateName(self):
758 7fbb1f65 Michael Hanselmann
    SetEtcHostsEntry(self.tmpname, '1.2.3.4', 'myhost', ['myhost'])
759 7fbb1f65 Michael Hanselmann
760 7fbb1f65 Michael Hanselmann
    self.assertFileContent(self.tmpname,
761 7fbb1f65 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
762 7fbb1f65 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
763 7fbb1f65 Michael Hanselmann
      "192.168.1.1 router gw\n"
764 7fbb1f65 Michael Hanselmann
      "1.2.3.4\tmyhost\n")
765 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
766 7fbb1f65 Michael Hanselmann
767 899d2a81 Michael Hanselmann
  def testRemovingExistingHost(self):
768 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'router')
769 899d2a81 Michael Hanselmann
770 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
771 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
772 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
773 ebe8ef17 Michael Hanselmann
      "192.168.1.1 gw\n")
774 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
775 899d2a81 Michael Hanselmann
776 899d2a81 Michael Hanselmann
  def testRemovingSingleExistingHost(self):
777 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'localhost')
778 899d2a81 Michael Hanselmann
779 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
780 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
781 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router gw\n")
782 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
783 899d2a81 Michael Hanselmann
784 899d2a81 Michael Hanselmann
  def testRemovingNonExistingHost(self):
785 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'myhost')
786 899d2a81 Michael Hanselmann
787 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
788 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
789 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
790 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router gw\n")
791 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
792 899d2a81 Michael Hanselmann
793 9440aeab Michael Hanselmann
  def testRemovingAlias(self):
794 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'gw')
795 9440aeab Michael Hanselmann
796 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
797 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
798 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
799 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router\n")
800 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
801 9440aeab Michael Hanselmann
802 899d2a81 Michael Hanselmann
803 a8083063 Iustin Pop
class TestShellQuoting(unittest.TestCase):
804 a8083063 Iustin Pop
  """Test case for shell quoting functions"""
805 a8083063 Iustin Pop
806 a8083063 Iustin Pop
  def testShellQuote(self):
807 a8083063 Iustin Pop
    self.assertEqual(ShellQuote('abc'), "abc")
808 a8083063 Iustin Pop
    self.assertEqual(ShellQuote('ab"c'), "'ab\"c'")
809 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a'bc"), "'a'\\''bc'")
810 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a b c"), "'a b c'")
811 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a b\\ c"), "'a b\\ c'")
812 a8083063 Iustin Pop
813 a8083063 Iustin Pop
  def testShellQuoteArgs(self):
814 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b', 'c']), "a b c")
815 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b"', 'c']), "a 'b\"' c")
816 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b\'', 'c']), "a 'b'\\\''' c")
817 a8083063 Iustin Pop
818 a8083063 Iustin Pop
819 2c30e9d7 Alexander Schreiber
class TestTcpPing(unittest.TestCase):
820 2c30e9d7 Alexander Schreiber
  """Testcase for TCP version of ping - against listen(2)ing port"""
821 2c30e9d7 Alexander Schreiber
822 2c30e9d7 Alexander Schreiber
  def setUp(self):
823 2c30e9d7 Alexander Schreiber
    self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
824 16abfbc2 Alexander Schreiber
    self.listener.bind((constants.LOCALHOST_IP_ADDRESS, 0))
825 2c30e9d7 Alexander Schreiber
    self.listenerport = self.listener.getsockname()[1]
826 2c30e9d7 Alexander Schreiber
    self.listener.listen(1)
827 2c30e9d7 Alexander Schreiber
828 2c30e9d7 Alexander Schreiber
  def tearDown(self):
829 2c30e9d7 Alexander Schreiber
    self.listener.shutdown(socket.SHUT_RDWR)
830 2c30e9d7 Alexander Schreiber
    del self.listener
831 2c30e9d7 Alexander Schreiber
    del self.listenerport
832 2c30e9d7 Alexander Schreiber
833 2c30e9d7 Alexander Schreiber
  def testTcpPingToLocalHostAccept(self):
834 16abfbc2 Alexander Schreiber
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
835 2c30e9d7 Alexander Schreiber
                         self.listenerport,
836 2c30e9d7 Alexander Schreiber
                         timeout=10,
837 b15d625f Iustin Pop
                         live_port_needed=True,
838 b15d625f Iustin Pop
                         source=constants.LOCALHOST_IP_ADDRESS,
839 b15d625f Iustin Pop
                         ),
840 2c30e9d7 Alexander Schreiber
                 "failed to connect to test listener")
841 2c30e9d7 Alexander Schreiber
842 b15d625f Iustin Pop
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
843 b15d625f Iustin Pop
                         self.listenerport,
844 b15d625f Iustin Pop
                         timeout=10,
845 b15d625f Iustin Pop
                         live_port_needed=True,
846 b15d625f Iustin Pop
                         ),
847 b15d625f Iustin Pop
                 "failed to connect to test listener (no source)")
848 b15d625f Iustin Pop
849 2c30e9d7 Alexander Schreiber
850 2c30e9d7 Alexander Schreiber
class TestTcpPingDeaf(unittest.TestCase):
851 2c30e9d7 Alexander Schreiber
  """Testcase for TCP version of ping - against non listen(2)ing port"""
852 2c30e9d7 Alexander Schreiber
853 2c30e9d7 Alexander Schreiber
  def setUp(self):
854 2c30e9d7 Alexander Schreiber
    self.deaflistener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
855 16abfbc2 Alexander Schreiber
    self.deaflistener.bind((constants.LOCALHOST_IP_ADDRESS, 0))
856 2c30e9d7 Alexander Schreiber
    self.deaflistenerport = self.deaflistener.getsockname()[1]
857 2c30e9d7 Alexander Schreiber
858 2c30e9d7 Alexander Schreiber
  def tearDown(self):
859 2c30e9d7 Alexander Schreiber
    del self.deaflistener
860 2c30e9d7 Alexander Schreiber
    del self.deaflistenerport
861 2c30e9d7 Alexander Schreiber
862 2c30e9d7 Alexander Schreiber
  def testTcpPingToLocalHostAcceptDeaf(self):
863 16abfbc2 Alexander Schreiber
    self.failIf(TcpPing(constants.LOCALHOST_IP_ADDRESS,
864 2c30e9d7 Alexander Schreiber
                        self.deaflistenerport,
865 16abfbc2 Alexander Schreiber
                        timeout=constants.TCP_PING_TIMEOUT,
866 b15d625f Iustin Pop
                        live_port_needed=True,
867 b15d625f Iustin Pop
                        source=constants.LOCALHOST_IP_ADDRESS,
868 b15d625f Iustin Pop
                        ), # need successful connect(2)
869 2c30e9d7 Alexander Schreiber
                "successfully connected to deaf listener")
870 2c30e9d7 Alexander Schreiber
871 b15d625f Iustin Pop
    self.failIf(TcpPing(constants.LOCALHOST_IP_ADDRESS,
872 b15d625f Iustin Pop
                        self.deaflistenerport,
873 b15d625f Iustin Pop
                        timeout=constants.TCP_PING_TIMEOUT,
874 b15d625f Iustin Pop
                        live_port_needed=True,
875 b15d625f Iustin Pop
                        ), # need successful connect(2)
876 b15d625f Iustin Pop
                "successfully connected to deaf listener (no source addr)")
877 b15d625f Iustin Pop
878 2c30e9d7 Alexander Schreiber
  def testTcpPingToLocalHostNoAccept(self):
879 16abfbc2 Alexander Schreiber
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
880 2c30e9d7 Alexander Schreiber
                         self.deaflistenerport,
881 16abfbc2 Alexander Schreiber
                         timeout=constants.TCP_PING_TIMEOUT,
882 b15d625f Iustin Pop
                         live_port_needed=False,
883 b15d625f Iustin Pop
                         source=constants.LOCALHOST_IP_ADDRESS,
884 b15d625f Iustin Pop
                         ), # ECONNREFUSED is OK
885 2c30e9d7 Alexander Schreiber
                 "failed to ping alive host on deaf port")
886 2c30e9d7 Alexander Schreiber
887 b15d625f Iustin Pop
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
888 b15d625f Iustin Pop
                         self.deaflistenerport,
889 b15d625f Iustin Pop
                         timeout=constants.TCP_PING_TIMEOUT,
890 b15d625f Iustin Pop
                         live_port_needed=False,
891 b15d625f Iustin Pop
                         ), # ECONNREFUSED is OK
892 b15d625f Iustin Pop
                 "failed to ping alive host on deaf port (no source addr)")
893 b15d625f Iustin Pop
894 2c30e9d7 Alexander Schreiber
895 caad16e2 Iustin Pop
class TestOwnIpAddress(unittest.TestCase):
896 caad16e2 Iustin Pop
  """Testcase for OwnIpAddress"""
897 caad16e2 Iustin Pop
898 caad16e2 Iustin Pop
  def testOwnLoopback(self):
899 caad16e2 Iustin Pop
    """check having the loopback ip"""
900 caad16e2 Iustin Pop
    self.failUnless(OwnIpAddress(constants.LOCALHOST_IP_ADDRESS),
901 caad16e2 Iustin Pop
                    "Should own the loopback address")
902 caad16e2 Iustin Pop
903 caad16e2 Iustin Pop
  def testNowOwnAddress(self):
904 caad16e2 Iustin Pop
    """check that I don't own an address"""
905 caad16e2 Iustin Pop
906 caad16e2 Iustin Pop
    # network 192.0.2.0/24 is reserved for test/documentation as per
907 caad16e2 Iustin Pop
    # rfc 3330, so we *should* not have an address of this range... if
908 caad16e2 Iustin Pop
    # this fails, we should extend the test to multiple addresses
909 caad16e2 Iustin Pop
    DST_IP = "192.0.2.1"
910 caad16e2 Iustin Pop
    self.failIf(OwnIpAddress(DST_IP), "Should not own IP address %s" % DST_IP)
911 caad16e2 Iustin Pop
912 caad16e2 Iustin Pop
913 eedbda4b Michael Hanselmann
class TestListVisibleFiles(unittest.TestCase):
914 eedbda4b Michael Hanselmann
  """Test case for ListVisibleFiles"""
915 eedbda4b Michael Hanselmann
916 eedbda4b Michael Hanselmann
  def setUp(self):
917 eedbda4b Michael Hanselmann
    self.path = tempfile.mkdtemp()
918 eedbda4b Michael Hanselmann
919 eedbda4b Michael Hanselmann
  def tearDown(self):
920 eedbda4b Michael Hanselmann
    shutil.rmtree(self.path)
921 eedbda4b Michael Hanselmann
922 eedbda4b Michael Hanselmann
  def _test(self, files, expected):
923 eedbda4b Michael Hanselmann
    # Sort a copy
924 eedbda4b Michael Hanselmann
    expected = expected[:]
925 eedbda4b Michael Hanselmann
    expected.sort()
926 eedbda4b Michael Hanselmann
927 eedbda4b Michael Hanselmann
    for name in files:
928 eedbda4b Michael Hanselmann
      f = open(os.path.join(self.path, name), 'w')
929 eedbda4b Michael Hanselmann
      try:
930 eedbda4b Michael Hanselmann
        f.write("Test\n")
931 eedbda4b Michael Hanselmann
      finally:
932 eedbda4b Michael Hanselmann
        f.close()
933 eedbda4b Michael Hanselmann
934 eedbda4b Michael Hanselmann
    found = ListVisibleFiles(self.path)
935 eedbda4b Michael Hanselmann
    found.sort()
936 eedbda4b Michael Hanselmann
937 eedbda4b Michael Hanselmann
    self.assertEqual(found, expected)
938 eedbda4b Michael Hanselmann
939 eedbda4b Michael Hanselmann
  def testAllVisible(self):
940 eedbda4b Michael Hanselmann
    files = ["a", "b", "c"]
941 eedbda4b Michael Hanselmann
    expected = files
942 eedbda4b Michael Hanselmann
    self._test(files, expected)
943 eedbda4b Michael Hanselmann
944 eedbda4b Michael Hanselmann
  def testNoneVisible(self):
945 eedbda4b Michael Hanselmann
    files = [".a", ".b", ".c"]
946 eedbda4b Michael Hanselmann
    expected = []
947 eedbda4b Michael Hanselmann
    self._test(files, expected)
948 eedbda4b Michael Hanselmann
949 eedbda4b Michael Hanselmann
  def testSomeVisible(self):
950 eedbda4b Michael Hanselmann
    files = ["a", "b", ".c"]
951 eedbda4b Michael Hanselmann
    expected = ["a", "b"]
952 eedbda4b Michael Hanselmann
    self._test(files, expected)
953 eedbda4b Michael Hanselmann
954 04a69a18 Iustin Pop
  def testNonAbsolutePath(self):
955 04a69a18 Iustin Pop
    self.failUnlessRaises(errors.ProgrammerError, ListVisibleFiles, "abc")
956 04a69a18 Iustin Pop
957 04a69a18 Iustin Pop
  def testNonNormalizedPath(self):
958 04a69a18 Iustin Pop
    self.failUnlessRaises(errors.ProgrammerError, ListVisibleFiles,
959 04a69a18 Iustin Pop
                          "/bin/../tmp")
960 04a69a18 Iustin Pop
961 eedbda4b Michael Hanselmann
962 24818e8f Michael Hanselmann
class TestNewUUID(unittest.TestCase):
963 24818e8f Michael Hanselmann
  """Test case for NewUUID"""
964 59072e7e Michael Hanselmann
965 59072e7e Michael Hanselmann
  _re_uuid = re.compile('^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-'
966 59072e7e Michael Hanselmann
                        '[a-f0-9]{4}-[a-f0-9]{12}$')
967 59072e7e Michael Hanselmann
968 59072e7e Michael Hanselmann
  def runTest(self):
969 24818e8f Michael Hanselmann
    self.failUnless(self._re_uuid.match(utils.NewUUID()))
970 59072e7e Michael Hanselmann
971 59072e7e Michael Hanselmann
972 f7414041 Michael Hanselmann
class TestUniqueSequence(unittest.TestCase):
973 f7414041 Michael Hanselmann
  """Test case for UniqueSequence"""
974 f7414041 Michael Hanselmann
975 f7414041 Michael Hanselmann
  def _test(self, input, expected):
976 f7414041 Michael Hanselmann
    self.assertEqual(utils.UniqueSequence(input), expected)
977 f7414041 Michael Hanselmann
978 f7414041 Michael Hanselmann
  def runTest(self):
979 f7414041 Michael Hanselmann
    # Ordered input
980 f7414041 Michael Hanselmann
    self._test([1, 2, 3], [1, 2, 3])
981 f7414041 Michael Hanselmann
    self._test([1, 1, 2, 2, 3, 3], [1, 2, 3])
982 f7414041 Michael Hanselmann
    self._test([1, 2, 2, 3], [1, 2, 3])
983 f7414041 Michael Hanselmann
    self._test([1, 2, 3, 3], [1, 2, 3])
984 f7414041 Michael Hanselmann
985 f7414041 Michael Hanselmann
    # Unordered input
986 f7414041 Michael Hanselmann
    self._test([1, 2, 3, 1, 2, 3], [1, 2, 3])
987 f7414041 Michael Hanselmann
    self._test([1, 1, 2, 3, 3, 1, 2], [1, 2, 3])
988 f7414041 Michael Hanselmann
989 f7414041 Michael Hanselmann
    # Strings
990 f7414041 Michael Hanselmann
    self._test(["a", "a"], ["a"])
991 f7414041 Michael Hanselmann
    self._test(["a", "b"], ["a", "b"])
992 f7414041 Michael Hanselmann
    self._test(["a", "b", "a"], ["a", "b"])
993 f7414041 Michael Hanselmann
994 a87b4824 Michael Hanselmann
995 7b4126b7 Iustin Pop
class TestFirstFree(unittest.TestCase):
996 7b4126b7 Iustin Pop
  """Test case for the FirstFree function"""
997 7b4126b7 Iustin Pop
998 7b4126b7 Iustin Pop
  def test(self):
999 7b4126b7 Iustin Pop
    """Test FirstFree"""
1000 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([0, 1, 3]), 2)
1001 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([]), None)
1002 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([3, 4, 6]), 0)
1003 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([3, 4, 6], base=3), 5)
1004 7b4126b7 Iustin Pop
    self.failUnlessRaises(AssertionError, FirstFree, [0, 3, 4, 6], base=3)
1005 f7414041 Michael Hanselmann
1006 a87b4824 Michael Hanselmann
1007 f65f63ef Iustin Pop
class TestTailFile(testutils.GanetiTestCase):
1008 f65f63ef Iustin Pop
  """Test case for the TailFile function"""
1009 f65f63ef Iustin Pop
1010 f65f63ef Iustin Pop
  def testEmpty(self):
1011 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1012 f65f63ef Iustin Pop
    self.failUnlessEqual(TailFile(fname), [])
1013 f65f63ef Iustin Pop
    self.failUnlessEqual(TailFile(fname, lines=25), [])
1014 f65f63ef Iustin Pop
1015 f65f63ef Iustin Pop
  def testAllLines(self):
1016 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1017 f65f63ef Iustin Pop
    for i in range(30):
1018 f65f63ef Iustin Pop
      fname = self._CreateTempFile()
1019 f65f63ef Iustin Pop
      fd = open(fname, "w")
1020 f65f63ef Iustin Pop
      fd.write("\n".join(data[:i]))
1021 f65f63ef Iustin Pop
      if i > 0:
1022 f65f63ef Iustin Pop
        fd.write("\n")
1023 f65f63ef Iustin Pop
      fd.close()
1024 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[:i])
1025 f65f63ef Iustin Pop
1026 f65f63ef Iustin Pop
  def testPartialLines(self):
1027 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1028 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1029 f65f63ef Iustin Pop
    fd = open(fname, "w")
1030 f65f63ef Iustin Pop
    fd.write("\n".join(data))
1031 f65f63ef Iustin Pop
    fd.write("\n")
1032 f65f63ef Iustin Pop
    fd.close()
1033 f65f63ef Iustin Pop
    for i in range(1, 30):
1034 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[-i:])
1035 f65f63ef Iustin Pop
1036 f65f63ef Iustin Pop
  def testBigFile(self):
1037 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1038 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1039 f65f63ef Iustin Pop
    fd = open(fname, "w")
1040 f65f63ef Iustin Pop
    fd.write("X" * 1048576)
1041 f65f63ef Iustin Pop
    fd.write("\n")
1042 f65f63ef Iustin Pop
    fd.write("\n".join(data))
1043 f65f63ef Iustin Pop
    fd.write("\n")
1044 f65f63ef Iustin Pop
    fd.close()
1045 f65f63ef Iustin Pop
    for i in range(1, 30):
1046 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[-i:])
1047 f65f63ef Iustin Pop
1048 f65f63ef Iustin Pop
1049 b4478d34 Michael Hanselmann
class _BaseFileLockTest:
1050 a87b4824 Michael Hanselmann
  """Test case for the FileLock class"""
1051 a87b4824 Michael Hanselmann
1052 a87b4824 Michael Hanselmann
  def testSharedNonblocking(self):
1053 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1054 a87b4824 Michael Hanselmann
    self.lock.Close()
1055 a87b4824 Michael Hanselmann
1056 a87b4824 Michael Hanselmann
  def testExclusiveNonblocking(self):
1057 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1058 a87b4824 Michael Hanselmann
    self.lock.Close()
1059 a87b4824 Michael Hanselmann
1060 a87b4824 Michael Hanselmann
  def testUnlockNonblocking(self):
1061 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1062 a87b4824 Michael Hanselmann
    self.lock.Close()
1063 a87b4824 Michael Hanselmann
1064 a87b4824 Michael Hanselmann
  def testSharedBlocking(self):
1065 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=True)
1066 a87b4824 Michael Hanselmann
    self.lock.Close()
1067 a87b4824 Michael Hanselmann
1068 a87b4824 Michael Hanselmann
  def testExclusiveBlocking(self):
1069 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=True)
1070 a87b4824 Michael Hanselmann
    self.lock.Close()
1071 a87b4824 Michael Hanselmann
1072 a87b4824 Michael Hanselmann
  def testUnlockBlocking(self):
1073 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=True)
1074 a87b4824 Michael Hanselmann
    self.lock.Close()
1075 a87b4824 Michael Hanselmann
1076 a87b4824 Michael Hanselmann
  def testSharedExclusiveUnlock(self):
1077 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1078 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1079 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1080 a87b4824 Michael Hanselmann
    self.lock.Close()
1081 a87b4824 Michael Hanselmann
1082 a87b4824 Michael Hanselmann
  def testExclusiveSharedUnlock(self):
1083 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1084 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1085 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1086 a87b4824 Michael Hanselmann
    self.lock.Close()
1087 a87b4824 Michael Hanselmann
1088 b4478d34 Michael Hanselmann
  def testSimpleTimeout(self):
1089 b4478d34 Michael Hanselmann
    # These will succeed on the first attempt, hence a short timeout
1090 b4478d34 Michael Hanselmann
    self.lock.Shared(blocking=True, timeout=10.0)
1091 b4478d34 Michael Hanselmann
    self.lock.Exclusive(blocking=False, timeout=10.0)
1092 b4478d34 Michael Hanselmann
    self.lock.Unlock(blocking=True, timeout=10.0)
1093 b4478d34 Michael Hanselmann
    self.lock.Close()
1094 b4478d34 Michael Hanselmann
1095 b4478d34 Michael Hanselmann
  @staticmethod
1096 b4478d34 Michael Hanselmann
  def _TryLockInner(filename, shared, blocking):
1097 b4478d34 Michael Hanselmann
    lock = utils.FileLock.Open(filename)
1098 b4478d34 Michael Hanselmann
1099 b4478d34 Michael Hanselmann
    if shared:
1100 b4478d34 Michael Hanselmann
      fn = lock.Shared
1101 b4478d34 Michael Hanselmann
    else:
1102 b4478d34 Michael Hanselmann
      fn = lock.Exclusive
1103 b4478d34 Michael Hanselmann
1104 b4478d34 Michael Hanselmann
    try:
1105 b4478d34 Michael Hanselmann
      # The timeout doesn't really matter as the parent process waits for us to
1106 b4478d34 Michael Hanselmann
      # finish anyway.
1107 b4478d34 Michael Hanselmann
      fn(blocking=blocking, timeout=0.01)
1108 b4478d34 Michael Hanselmann
    except errors.LockError, err:
1109 b4478d34 Michael Hanselmann
      return False
1110 b4478d34 Michael Hanselmann
1111 b4478d34 Michael Hanselmann
    return True
1112 b4478d34 Michael Hanselmann
1113 b4478d34 Michael Hanselmann
  def _TryLock(self, *args):
1114 b4478d34 Michael Hanselmann
    return utils.RunInSeparateProcess(self._TryLockInner, self.tmpfile.name,
1115 b4478d34 Michael Hanselmann
                                      *args)
1116 b4478d34 Michael Hanselmann
1117 b4478d34 Michael Hanselmann
  def testTimeout(self):
1118 b4478d34 Michael Hanselmann
    for blocking in [True, False]:
1119 b4478d34 Michael Hanselmann
      self.lock.Exclusive(blocking=True)
1120 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(False, blocking))
1121 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(True, blocking))
1122 b4478d34 Michael Hanselmann
1123 b4478d34 Michael Hanselmann
      self.lock.Shared(blocking=True)
1124 b4478d34 Michael Hanselmann
      self.assert_(self._TryLock(True, blocking))
1125 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(False, blocking))
1126 b4478d34 Michael Hanselmann
1127 a87b4824 Michael Hanselmann
  def testCloseShared(self):
1128 a87b4824 Michael Hanselmann
    self.lock.Close()
1129 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Shared, blocking=False)
1130 a87b4824 Michael Hanselmann
1131 a87b4824 Michael Hanselmann
  def testCloseExclusive(self):
1132 a87b4824 Michael Hanselmann
    self.lock.Close()
1133 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Exclusive, blocking=False)
1134 a87b4824 Michael Hanselmann
1135 a87b4824 Michael Hanselmann
  def testCloseUnlock(self):
1136 a87b4824 Michael Hanselmann
    self.lock.Close()
1137 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Unlock, blocking=False)
1138 a87b4824 Michael Hanselmann
1139 a87b4824 Michael Hanselmann
1140 b4478d34 Michael Hanselmann
class TestFileLockWithFilename(testutils.GanetiTestCase, _BaseFileLockTest):
1141 b4478d34 Michael Hanselmann
  TESTDATA = "Hello World\n" * 10
1142 b4478d34 Michael Hanselmann
1143 b4478d34 Michael Hanselmann
  def setUp(self):
1144 b4478d34 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
1145 b4478d34 Michael Hanselmann
1146 b4478d34 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1147 b4478d34 Michael Hanselmann
    utils.WriteFile(self.tmpfile.name, data=self.TESTDATA)
1148 b4478d34 Michael Hanselmann
    self.lock = utils.FileLock.Open(self.tmpfile.name)
1149 b4478d34 Michael Hanselmann
1150 b4478d34 Michael Hanselmann
    # Ensure "Open" didn't truncate file
1151 b4478d34 Michael Hanselmann
    self.assertFileContent(self.tmpfile.name, self.TESTDATA)
1152 b4478d34 Michael Hanselmann
1153 b4478d34 Michael Hanselmann
  def tearDown(self):
1154 b4478d34 Michael Hanselmann
    self.assertFileContent(self.tmpfile.name, self.TESTDATA)
1155 b4478d34 Michael Hanselmann
1156 b4478d34 Michael Hanselmann
    testutils.GanetiTestCase.tearDown(self)
1157 b4478d34 Michael Hanselmann
1158 b4478d34 Michael Hanselmann
1159 b4478d34 Michael Hanselmann
class TestFileLockWithFileObject(unittest.TestCase, _BaseFileLockTest):
1160 b4478d34 Michael Hanselmann
  def setUp(self):
1161 b4478d34 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1162 b4478d34 Michael Hanselmann
    self.lock = utils.FileLock(open(self.tmpfile.name, "w"), self.tmpfile.name)
1163 b4478d34 Michael Hanselmann
1164 b4478d34 Michael Hanselmann
1165 739be818 Michael Hanselmann
class TestTimeFunctions(unittest.TestCase):
1166 739be818 Michael Hanselmann
  """Test case for time functions"""
1167 739be818 Michael Hanselmann
1168 739be818 Michael Hanselmann
  def runTest(self):
1169 739be818 Michael Hanselmann
    self.assertEqual(utils.SplitTime(1), (1, 0))
1170 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(1.5), (1, 500000))
1171 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(1218448917.4809151), (1218448917, 480915))
1172 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.48012), (123, 480120))
1173 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9996), (123, 999600))
1174 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9995), (123, 999500))
1175 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9994), (123, 999400))
1176 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.999999999), (123, 999999))
1177 45bc5e4a Michael Hanselmann
1178 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.SplitTime, -1)
1179 739be818 Michael Hanselmann
1180 739be818 Michael Hanselmann
    self.assertEqual(utils.MergeTime((1, 0)), 1.0)
1181 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.MergeTime((1, 500000)), 1.5)
1182 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.MergeTime((1218448917, 500000)), 1218448917.5)
1183 739be818 Michael Hanselmann
1184 4d4a651d Michael Hanselmann
    self.assertEqual(round(utils.MergeTime((1218448917, 481000)), 3),
1185 4d4a651d Michael Hanselmann
                     1218448917.481)
1186 45bc5e4a Michael Hanselmann
    self.assertEqual(round(utils.MergeTime((1, 801000)), 3), 1.801)
1187 739be818 Michael Hanselmann
1188 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, -1))
1189 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, 1000000))
1190 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, 9999999))
1191 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (-1, 0))
1192 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (-9999, 0))
1193 739be818 Michael Hanselmann
1194 739be818 Michael Hanselmann
1195 a2d2e1a7 Iustin Pop
class FieldSetTestCase(unittest.TestCase):
1196 a2d2e1a7 Iustin Pop
  """Test case for FieldSets"""
1197 a2d2e1a7 Iustin Pop
1198 a2d2e1a7 Iustin Pop
  def testSimpleMatch(self):
1199 a2d2e1a7 Iustin Pop
    f = utils.FieldSet("a", "b", "c", "def")
1200 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("a"))
1201 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("d"), "Substring matched")
1202 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("defghi"), "Prefix string matched")
1203 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["b", "c"]))
1204 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["a", "b", "c", "def"]))
1205 a2d2e1a7 Iustin Pop
    self.failUnless(f.NonMatching(["a", "d"]))
1206 a2d2e1a7 Iustin Pop
1207 a2d2e1a7 Iustin Pop
  def testRegexMatch(self):
1208 a2d2e1a7 Iustin Pop
    f = utils.FieldSet("a", "b([0-9]+)", "c")
1209 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("b1"))
1210 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("b99"))
1211 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("b/1"))
1212 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["b12", "c"]))
1213 a2d2e1a7 Iustin Pop
    self.failUnless(f.NonMatching(["a", "1"]))
1214 a2d2e1a7 Iustin Pop
1215 a5728081 Guido Trotter
class TestForceDictType(unittest.TestCase):
1216 a5728081 Guido Trotter
  """Test case for ForceDictType"""
1217 a5728081 Guido Trotter
1218 a5728081 Guido Trotter
  def setUp(self):
1219 a5728081 Guido Trotter
    self.key_types = {
1220 a5728081 Guido Trotter
      'a': constants.VTYPE_INT,
1221 a5728081 Guido Trotter
      'b': constants.VTYPE_BOOL,
1222 a5728081 Guido Trotter
      'c': constants.VTYPE_STRING,
1223 a5728081 Guido Trotter
      'd': constants.VTYPE_SIZE,
1224 a5728081 Guido Trotter
      }
1225 a5728081 Guido Trotter
1226 a5728081 Guido Trotter
  def _fdt(self, dict, allowed_values=None):
1227 a5728081 Guido Trotter
    if allowed_values is None:
1228 a5728081 Guido Trotter
      ForceDictType(dict, self.key_types)
1229 a5728081 Guido Trotter
    else:
1230 a5728081 Guido Trotter
      ForceDictType(dict, self.key_types, allowed_values=allowed_values)
1231 a5728081 Guido Trotter
1232 a5728081 Guido Trotter
    return dict
1233 a5728081 Guido Trotter
1234 a5728081 Guido Trotter
  def testSimpleDict(self):
1235 a5728081 Guido Trotter
    self.assertEqual(self._fdt({}), {})
1236 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': 1}), {'a': 1})
1237 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': '1'}), {'a': 1})
1238 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': 1, 'b': 1}), {'a':1, 'b': True})
1239 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 1, 'c': 'foo'}), {'b': True, 'c': 'foo'})
1240 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 1, 'c': False}), {'b': True, 'c': ''})
1241 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'false'}), {'b': False})
1242 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'False'}), {'b': False})
1243 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'true'}), {'b': True})
1244 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'True'}), {'b': True})
1245 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'d': '4'}), {'d': 4})
1246 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'d': '4M'}), {'d': 4})
1247 a5728081 Guido Trotter
1248 a5728081 Guido Trotter
  def testErrors(self):
1249 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'a': 'astring'})
1250 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'c': True})
1251 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': 'astring'})
1252 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': '4 L'})
1253 a5728081 Guido Trotter
1254 a2d2e1a7 Iustin Pop
1255 da961187 Guido Trotter
class TestIsAbsNormPath(unittest.TestCase):
1256 da961187 Guido Trotter
  """Testing case for IsProcessAlive"""
1257 da961187 Guido Trotter
1258 da961187 Guido Trotter
  def _pathTestHelper(self, path, result):
1259 da961187 Guido Trotter
    if result:
1260 da961187 Guido Trotter
      self.assert_(IsNormAbsPath(path),
1261 17c61836 Guido Trotter
          "Path %s should result absolute and normalized" % path)
1262 da961187 Guido Trotter
    else:
1263 da961187 Guido Trotter
      self.assert_(not IsNormAbsPath(path),
1264 17c61836 Guido Trotter
          "Path %s should not result absolute and normalized" % path)
1265 da961187 Guido Trotter
1266 da961187 Guido Trotter
  def testBase(self):
1267 da961187 Guido Trotter
    self._pathTestHelper('/etc', True)
1268 da961187 Guido Trotter
    self._pathTestHelper('/srv', True)
1269 da961187 Guido Trotter
    self._pathTestHelper('etc', False)
1270 da961187 Guido Trotter
    self._pathTestHelper('/etc/../root', False)
1271 da961187 Guido Trotter
    self._pathTestHelper('/etc/', False)
1272 da961187 Guido Trotter
1273 af0413bb Guido Trotter
1274 d392fa34 Iustin Pop
class TestSafeEncode(unittest.TestCase):
1275 d392fa34 Iustin Pop
  """Test case for SafeEncode"""
1276 d392fa34 Iustin Pop
1277 d392fa34 Iustin Pop
  def testAscii(self):
1278 d392fa34 Iustin Pop
    for txt in [string.digits, string.letters, string.punctuation]:
1279 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1280 d392fa34 Iustin Pop
1281 d392fa34 Iustin Pop
  def testDoubleEncode(self):
1282 d392fa34 Iustin Pop
    for i in range(255):
1283 d392fa34 Iustin Pop
      txt = SafeEncode(chr(i))
1284 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1285 d392fa34 Iustin Pop
1286 d392fa34 Iustin Pop
  def testUnicode(self):
1287 d392fa34 Iustin Pop
    # 1024 is high enough to catch non-direct ASCII mappings
1288 d392fa34 Iustin Pop
    for i in range(1024):
1289 d392fa34 Iustin Pop
      txt = SafeEncode(unichr(i))
1290 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1291 d392fa34 Iustin Pop
1292 d392fa34 Iustin Pop
1293 3b813dd2 Iustin Pop
class TestFormatTime(unittest.TestCase):
1294 3b813dd2 Iustin Pop
  """Testing case for FormatTime"""
1295 3b813dd2 Iustin Pop
1296 3b813dd2 Iustin Pop
  def testNone(self):
1297 3b813dd2 Iustin Pop
    self.failUnlessEqual(FormatTime(None), "N/A")
1298 3b813dd2 Iustin Pop
1299 3b813dd2 Iustin Pop
  def testInvalid(self):
1300 3b813dd2 Iustin Pop
    self.failUnlessEqual(FormatTime(()), "N/A")
1301 3b813dd2 Iustin Pop
1302 3b813dd2 Iustin Pop
  def testNow(self):
1303 3b813dd2 Iustin Pop
    # tests that we accept time.time input
1304 3b813dd2 Iustin Pop
    FormatTime(time.time())
1305 3b813dd2 Iustin Pop
    # tests that we accept int input
1306 3b813dd2 Iustin Pop
    FormatTime(int(time.time()))
1307 3b813dd2 Iustin Pop
1308 3b813dd2 Iustin Pop
1309 eb58f7bd Michael Hanselmann
class RunInSeparateProcess(unittest.TestCase):
1310 eb58f7bd Michael Hanselmann
  def test(self):
1311 eb58f7bd Michael Hanselmann
    for exp in [True, False]:
1312 eb58f7bd Michael Hanselmann
      def _child():
1313 eb58f7bd Michael Hanselmann
        return exp
1314 eb58f7bd Michael Hanselmann
1315 eb58f7bd Michael Hanselmann
      self.assertEqual(exp, utils.RunInSeparateProcess(_child))
1316 eb58f7bd Michael Hanselmann
1317 bdefe5dd Michael Hanselmann
  def testArgs(self):
1318 bdefe5dd Michael Hanselmann
    for arg in [0, 1, 999, "Hello World", (1, 2, 3)]:
1319 bdefe5dd Michael Hanselmann
      def _child(carg1, carg2):
1320 bdefe5dd Michael Hanselmann
        return carg1 == "Foo" and carg2 == arg
1321 bdefe5dd Michael Hanselmann
1322 bdefe5dd Michael Hanselmann
      self.assert_(utils.RunInSeparateProcess(_child, "Foo", arg))
1323 bdefe5dd Michael Hanselmann
1324 eb58f7bd Michael Hanselmann
  def testPid(self):
1325 eb58f7bd Michael Hanselmann
    parent_pid = os.getpid()
1326 eb58f7bd Michael Hanselmann
1327 eb58f7bd Michael Hanselmann
    def _check():
1328 eb58f7bd Michael Hanselmann
      return os.getpid() == parent_pid
1329 eb58f7bd Michael Hanselmann
1330 eb58f7bd Michael Hanselmann
    self.failIf(utils.RunInSeparateProcess(_check))
1331 eb58f7bd Michael Hanselmann
1332 eb58f7bd Michael Hanselmann
  def testSignal(self):
1333 eb58f7bd Michael Hanselmann
    def _kill():
1334 eb58f7bd Michael Hanselmann
      os.kill(os.getpid(), signal.SIGTERM)
1335 eb58f7bd Michael Hanselmann
1336 eb58f7bd Michael Hanselmann
    self.assertRaises(errors.GenericError,
1337 eb58f7bd Michael Hanselmann
                      utils.RunInSeparateProcess, _kill)
1338 eb58f7bd Michael Hanselmann
1339 eb58f7bd Michael Hanselmann
  def testException(self):
1340 eb58f7bd Michael Hanselmann
    def _exc():
1341 eb58f7bd Michael Hanselmann
      raise errors.GenericError("This is a test")
1342 eb58f7bd Michael Hanselmann
1343 eb58f7bd Michael Hanselmann
    self.assertRaises(errors.GenericError,
1344 eb58f7bd Michael Hanselmann
                      utils.RunInSeparateProcess, _exc)
1345 eb58f7bd Michael Hanselmann
1346 eb58f7bd Michael Hanselmann
1347 fabee4b2 Michael Hanselmann
class TestFingerprintFile(unittest.TestCase):
1348 fabee4b2 Michael Hanselmann
  def setUp(self):
1349 fabee4b2 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1350 fabee4b2 Michael Hanselmann
1351 fabee4b2 Michael Hanselmann
  def test(self):
1352 fabee4b2 Michael Hanselmann
    self.assertEqual(utils._FingerprintFile(self.tmpfile.name),
1353 fabee4b2 Michael Hanselmann
                     "da39a3ee5e6b4b0d3255bfef95601890afd80709")
1354 fabee4b2 Michael Hanselmann
1355 fabee4b2 Michael Hanselmann
    utils.WriteFile(self.tmpfile.name, data="Hello World\n")
1356 fabee4b2 Michael Hanselmann
    self.assertEqual(utils._FingerprintFile(self.tmpfile.name),
1357 fabee4b2 Michael Hanselmann
                     "648a6a6ffffdaa0badb23b8baf90b6168dd16b3a")
1358 fabee4b2 Michael Hanselmann
1359 fabee4b2 Michael Hanselmann
1360 5b69bc7c Iustin Pop
class TestUnescapeAndSplit(unittest.TestCase):
1361 5b69bc7c Iustin Pop
  """Testing case for UnescapeAndSplit"""
1362 5b69bc7c Iustin Pop
1363 5b69bc7c Iustin Pop
  def setUp(self):
1364 5b69bc7c Iustin Pop
    # testing more that one separator for regexp safety
1365 5b69bc7c Iustin Pop
    self._seps = [",", "+", "."]
1366 5b69bc7c Iustin Pop
1367 5b69bc7c Iustin Pop
  def testSimple(self):
1368 5b69bc7c Iustin Pop
    a = ["a", "b", "c", "d"]
1369 5b69bc7c Iustin Pop
    for sep in self._seps:
1370 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), a)
1371 5b69bc7c Iustin Pop
1372 5b69bc7c Iustin Pop
  def testEscape(self):
1373 5b69bc7c Iustin Pop
    for sep in self._seps:
1374 5b69bc7c Iustin Pop
      a = ["a", "b\\" + sep + "c", "d"]
1375 5b69bc7c Iustin Pop
      b = ["a", "b" + sep + "c", "d"]
1376 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1377 5b69bc7c Iustin Pop
1378 5b69bc7c Iustin Pop
  def testDoubleEscape(self):
1379 5b69bc7c Iustin Pop
    for sep in self._seps:
1380 5b69bc7c Iustin Pop
      a = ["a", "b\\\\", "c", "d"]
1381 5b69bc7c Iustin Pop
      b = ["a", "b\\", "c", "d"]
1382 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1383 5b69bc7c Iustin Pop
1384 5b69bc7c Iustin Pop
  def testThreeEscape(self):
1385 5b69bc7c Iustin Pop
    for sep in self._seps:
1386 5b69bc7c Iustin Pop
      a = ["a", "b\\\\\\" + sep + "c", "d"]
1387 5b69bc7c Iustin Pop
      b = ["a", "b\\" + sep + "c", "d"]
1388 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1389 5b69bc7c Iustin Pop
1390 5b69bc7c Iustin Pop
1391 4bb678e9 Iustin Pop
class TestPathJoin(unittest.TestCase):
1392 4bb678e9 Iustin Pop
  """Testing case for PathJoin"""
1393 4bb678e9 Iustin Pop
1394 4bb678e9 Iustin Pop
  def testBasicItems(self):
1395 4bb678e9 Iustin Pop
    mlist = ["/a", "b", "c"]
1396 4bb678e9 Iustin Pop
    self.failUnlessEqual(PathJoin(*mlist), "/".join(mlist))
1397 4bb678e9 Iustin Pop
1398 4bb678e9 Iustin Pop
  def testNonAbsPrefix(self):
1399 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "a", "b")
1400 4bb678e9 Iustin Pop
1401 4bb678e9 Iustin Pop
  def testBackTrack(self):
1402 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "/a", "b/../c")
1403 4bb678e9 Iustin Pop
1404 4bb678e9 Iustin Pop
  def testMultiAbs(self):
1405 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "/a", "/b")
1406 4bb678e9 Iustin Pop
1407 4bb678e9 Iustin Pop
1408 26288e68 Iustin Pop
class TestHostInfo(unittest.TestCase):
1409 26288e68 Iustin Pop
  """Testing case for HostInfo"""
1410 26288e68 Iustin Pop
1411 26288e68 Iustin Pop
  def testUppercase(self):
1412 26288e68 Iustin Pop
    data = "AbC.example.com"
1413 26288e68 Iustin Pop
    self.failUnlessEqual(HostInfo.NormalizeName(data), data.lower())
1414 26288e68 Iustin Pop
1415 26288e68 Iustin Pop
  def testTooLongName(self):
1416 26288e68 Iustin Pop
    data = "a.b." + "c" * 255
1417 26288e68 Iustin Pop
    self.failUnlessRaises(OpPrereqError, HostInfo.NormalizeName, data)
1418 26288e68 Iustin Pop
1419 26288e68 Iustin Pop
  def testTrailingDot(self):
1420 26288e68 Iustin Pop
    data = "a.b.c"
1421 26288e68 Iustin Pop
    self.failUnlessEqual(HostInfo.NormalizeName(data + "."), data)
1422 26288e68 Iustin Pop
1423 26288e68 Iustin Pop
  def testInvalidName(self):
1424 26288e68 Iustin Pop
    data = [
1425 26288e68 Iustin Pop
      "a b",
1426 26288e68 Iustin Pop
      "a/b",
1427 26288e68 Iustin Pop
      ".a.b",
1428 26288e68 Iustin Pop
      "a..b",
1429 26288e68 Iustin Pop
      ]
1430 26288e68 Iustin Pop
    for value in data:
1431 26288e68 Iustin Pop
      self.failUnlessRaises(OpPrereqError, HostInfo.NormalizeName, value)
1432 26288e68 Iustin Pop
1433 26288e68 Iustin Pop
  def testValidName(self):
1434 26288e68 Iustin Pop
    data = [
1435 26288e68 Iustin Pop
      "a.b",
1436 26288e68 Iustin Pop
      "a-b",
1437 26288e68 Iustin Pop
      "a_b",
1438 26288e68 Iustin Pop
      "a.b.c",
1439 26288e68 Iustin Pop
      ]
1440 26288e68 Iustin Pop
    for value in data:
1441 26288e68 Iustin Pop
      HostInfo.NormalizeName(value)
1442 26288e68 Iustin Pop
1443 26288e68 Iustin Pop
1444 27e46076 Michael Hanselmann
class TestParseAsn1Generalizedtime(unittest.TestCase):
1445 27e46076 Michael Hanselmann
  def test(self):
1446 27e46076 Michael Hanselmann
    # UTC
1447 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("19700101000000Z"), 0)
1448 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100222174152Z"),
1449 27e46076 Michael Hanselmann
                     1266860512)
1450 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20380119031407Z"),
1451 27e46076 Michael Hanselmann
                     (2**31) - 1)
1452 27e46076 Michael Hanselmann
1453 27e46076 Michael Hanselmann
    # With offset
1454 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100222174152+0000"),
1455 27e46076 Michael Hanselmann
                     1266860512)
1456 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100223131652+0000"),
1457 27e46076 Michael Hanselmann
                     1266931012)
1458 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100223051808-0800"),
1459 27e46076 Michael Hanselmann
                     1266931088)
1460 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100224002135+1100"),
1461 27e46076 Michael Hanselmann
                     1266931295)
1462 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("19700101000000-0100"),
1463 27e46076 Michael Hanselmann
                     3600)
1464 27e46076 Michael Hanselmann
1465 27e46076 Michael Hanselmann
    # Leap seconds are not supported by datetime.datetime
1466 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1467 27e46076 Michael Hanselmann
                      "19841231235960+0000")
1468 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1469 27e46076 Michael Hanselmann
                      "19920630235960+0000")
1470 27e46076 Michael Hanselmann
1471 27e46076 Michael Hanselmann
    # Errors
1472 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime, "")
1473 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime, "invalid")
1474 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1475 27e46076 Michael Hanselmann
                      "20100222174152")
1476 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1477 27e46076 Michael Hanselmann
                      "Mon Feb 22 17:47:02 UTC 2010")
1478 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1479 27e46076 Michael Hanselmann
                      "2010-02-22 17:42:02")
1480 27e46076 Michael Hanselmann
1481 27e46076 Michael Hanselmann
1482 27e46076 Michael Hanselmann
class TestGetX509CertValidity(testutils.GanetiTestCase):
1483 27e46076 Michael Hanselmann
  def setUp(self):
1484 27e46076 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
1485 27e46076 Michael Hanselmann
1486 27e46076 Michael Hanselmann
    pyopenssl_version = distutils.version.LooseVersion(OpenSSL.__version__)
1487 27e46076 Michael Hanselmann
1488 27e46076 Michael Hanselmann
    # Test whether we have pyOpenSSL 0.7 or above
1489 27e46076 Michael Hanselmann
    self.pyopenssl0_7 = (pyopenssl_version >= "0.7")
1490 27e46076 Michael Hanselmann
1491 27e46076 Michael Hanselmann
    if not self.pyopenssl0_7:
1492 27e46076 Michael Hanselmann
      warnings.warn("This test requires pyOpenSSL 0.7 or above to"
1493 27e46076 Michael Hanselmann
                    " function correctly")
1494 27e46076 Michael Hanselmann
1495 27e46076 Michael Hanselmann
  def _LoadCert(self, name):
1496 27e46076 Michael Hanselmann
    return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
1497 27e46076 Michael Hanselmann
                                           self._ReadTestData(name))
1498 27e46076 Michael Hanselmann
1499 27e46076 Michael Hanselmann
  def test(self):
1500 27e46076 Michael Hanselmann
    validity = utils.GetX509CertValidity(self._LoadCert("cert1.pem"))
1501 27e46076 Michael Hanselmann
    if self.pyopenssl0_7:
1502 27e46076 Michael Hanselmann
      self.assertEqual(validity, (1266919967, 1267524767))
1503 27e46076 Michael Hanselmann
    else:
1504 27e46076 Michael Hanselmann
      self.assertEqual(validity, (None, None))
1505 27e46076 Michael Hanselmann
1506 26288e68 Iustin Pop
1507 76e5f8b5 Michael Hanselmann
class TestMakedirs(unittest.TestCase):
1508 76e5f8b5 Michael Hanselmann
  def setUp(self):
1509 76e5f8b5 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
1510 76e5f8b5 Michael Hanselmann
1511 76e5f8b5 Michael Hanselmann
  def tearDown(self):
1512 76e5f8b5 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
1513 76e5f8b5 Michael Hanselmann
1514 76e5f8b5 Michael Hanselmann
  def testNonExisting(self):
1515 76e5f8b5 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "foo")
1516 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
1517 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
1518 76e5f8b5 Michael Hanselmann
1519 76e5f8b5 Michael Hanselmann
  def testExisting(self):
1520 76e5f8b5 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "foo")
1521 76e5f8b5 Michael Hanselmann
    os.mkdir(path)
1522 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
1523 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
1524 76e5f8b5 Michael Hanselmann
1525 76e5f8b5 Michael Hanselmann
  def testRecursiveNonExisting(self):
1526 76e5f8b5 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "foo/bar/baz")
1527 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
1528 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
1529 76e5f8b5 Michael Hanselmann
1530 76e5f8b5 Michael Hanselmann
  def testRecursiveExisting(self):
1531 76e5f8b5 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "B/moo/xyz")
1532 76e5f8b5 Michael Hanselmann
    self.assert_(not os.path.exists(path))
1533 76e5f8b5 Michael Hanselmann
    os.mkdir(utils.PathJoin(self.tmpdir, "B"))
1534 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
1535 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
1536 76e5f8b5 Michael Hanselmann
1537 76e5f8b5 Michael Hanselmann
1538 1b429e2a Iustin Pop
class TestRetry(testutils.GanetiTestCase):
1539 1b429e2a Iustin Pop
  @staticmethod
1540 1b429e2a Iustin Pop
  def _RaiseRetryAgain():
1541 1b429e2a Iustin Pop
    raise utils.RetryAgain()
1542 1b429e2a Iustin Pop
1543 1b429e2a Iustin Pop
  def _WrongNestedLoop(self):
1544 1b429e2a Iustin Pop
    return utils.Retry(self._RaiseRetryAgain, 0.01, 0.02)
1545 1b429e2a Iustin Pop
1546 1b429e2a Iustin Pop
  def testRaiseTimeout(self):
1547 1b429e2a Iustin Pop
    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
1548 1b429e2a Iustin Pop
                          self._RaiseRetryAgain, 0.01, 0.02)
1549 1b429e2a Iustin Pop
1550 1b429e2a Iustin Pop
  def testComplete(self):
1551 1b429e2a Iustin Pop
    self.failUnlessEqual(utils.Retry(lambda: True, 0, 1), True)
1552 1b429e2a Iustin Pop
1553 1b429e2a Iustin Pop
  def testNestedLoop(self):
1554 1b429e2a Iustin Pop
    try:
1555 1b429e2a Iustin Pop
      self.failUnlessRaises(errors.ProgrammerError, utils.Retry,
1556 1b429e2a Iustin Pop
                            self._WrongNestedLoop, 0, 1)
1557 1b429e2a Iustin Pop
    except utils.RetryTimeout:
1558 1b429e2a Iustin Pop
      self.fail("Didn't detect inner loop's exception")
1559 1b429e2a Iustin Pop
1560 1b429e2a Iustin Pop
1561 339be5a8 Michael Hanselmann
class TestLineSplitter(unittest.TestCase):
1562 339be5a8 Michael Hanselmann
  def test(self):
1563 339be5a8 Michael Hanselmann
    lines = []
1564 339be5a8 Michael Hanselmann
    ls = utils.LineSplitter(lines.append)
1565 339be5a8 Michael Hanselmann
    ls.write("Hello World\n")
1566 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
1567 339be5a8 Michael Hanselmann
    ls.write("Foo\n Bar\r\n ")
1568 339be5a8 Michael Hanselmann
    ls.write("Baz")
1569 339be5a8 Michael Hanselmann
    ls.write("Moo")
1570 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
1571 339be5a8 Michael Hanselmann
    ls.flush()
1572 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["Hello World", "Foo", " Bar"])
1573 339be5a8 Michael Hanselmann
    ls.close()
1574 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["Hello World", "Foo", " Bar", " BazMoo"])
1575 339be5a8 Michael Hanselmann
1576 339be5a8 Michael Hanselmann
  def _testExtra(self, line, all_lines, p1, p2):
1577 339be5a8 Michael Hanselmann
    self.assertEqual(p1, 999)
1578 339be5a8 Michael Hanselmann
    self.assertEqual(p2, "extra")
1579 339be5a8 Michael Hanselmann
    all_lines.append(line)
1580 339be5a8 Michael Hanselmann
1581 339be5a8 Michael Hanselmann
  def testExtraArgsNoFlush(self):
1582 339be5a8 Michael Hanselmann
    lines = []
1583 339be5a8 Michael Hanselmann
    ls = utils.LineSplitter(self._testExtra, lines, 999, "extra")
1584 339be5a8 Michael Hanselmann
    ls.write("\n\nHello World\n")
1585 339be5a8 Michael Hanselmann
    ls.write("Foo\n Bar\r\n ")
1586 339be5a8 Michael Hanselmann
    ls.write("")
1587 339be5a8 Michael Hanselmann
    ls.write("Baz")
1588 339be5a8 Michael Hanselmann
    ls.write("Moo\n\nx\n")
1589 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
1590 339be5a8 Michael Hanselmann
    ls.close()
1591 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["", "", "Hello World", "Foo", " Bar", " BazMoo",
1592 339be5a8 Michael Hanselmann
                             "", "x"])
1593 339be5a8 Michael Hanselmann
1594 339be5a8 Michael Hanselmann
1595 a8083063 Iustin Pop
if __name__ == '__main__':
1596 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()