Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils_unittest.py @ a5728081

History | View | Annotate | Download (31.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 a8083063 Iustin Pop
import md5
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 a8083063 Iustin Pop
37 a8083063 Iustin Pop
import ganeti
38 c9c4f19e Michael Hanselmann
import testutils
39 16abfbc2 Alexander Schreiber
from ganeti import constants
40 59072e7e Michael Hanselmann
from ganeti import utils
41 a5728081 Guido Trotter
from ganeti import errors
42 e5392d79 Iustin Pop
from ganeti.utils import IsProcessAlive, RunCmd, \
43 a8083063 Iustin Pop
     RemoveFile, CheckDict, MatchNameComponent, FormatUnit, \
44 a8083063 Iustin Pop
     ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \
45 899d2a81 Michael Hanselmann
     ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles, \
46 f65f63ef Iustin Pop
     SetEtcHostsEntry, RemoveEtcHostsEntry, FirstFree, OwnIpAddress, \
47 a5728081 Guido Trotter
     TailFile, ForceDictType
48 f65f63ef Iustin Pop
49 b2a1f511 Iustin Pop
from ganeti.errors import LockError, UnitParseError, GenericError, \
50 b2a1f511 Iustin Pop
     ProgrammerError
51 a8083063 Iustin Pop
52 d9f311d7 Iustin Pop
53 a8083063 Iustin Pop
class TestIsProcessAlive(unittest.TestCase):
54 a8083063 Iustin Pop
  """Testing case for IsProcessAlive"""
55 740c5aab Guido Trotter
56 a8083063 Iustin Pop
  def testExists(self):
57 a8083063 Iustin Pop
    mypid = os.getpid()
58 a8083063 Iustin Pop
    self.assert_(IsProcessAlive(mypid),
59 a8083063 Iustin Pop
                 "can't find myself running")
60 a8083063 Iustin Pop
61 a8083063 Iustin Pop
  def testNotExisting(self):
62 09352fa4 Iustin Pop
    pid_non_existing = os.fork()
63 09352fa4 Iustin Pop
    if pid_non_existing == 0:
64 09352fa4 Iustin Pop
      os._exit(0)
65 09352fa4 Iustin Pop
    elif pid_non_existing < 0:
66 09352fa4 Iustin Pop
      raise SystemError("can't fork")
67 09352fa4 Iustin Pop
    os.waitpid(pid_non_existing, 0)
68 09352fa4 Iustin Pop
    self.assert_(not IsProcessAlive(pid_non_existing),
69 09352fa4 Iustin Pop
                 "nonexisting process detected")
70 a8083063 Iustin Pop
71 d9f311d7 Iustin Pop
72 af99afa6 Guido Trotter
class TestPidFileFunctions(unittest.TestCase):
73 d9f311d7 Iustin Pop
  """Tests for WritePidFile, RemovePidFile and ReadPidFile"""
74 af99afa6 Guido Trotter
75 af99afa6 Guido Trotter
  def setUp(self):
76 af99afa6 Guido Trotter
    self.dir = tempfile.mkdtemp()
77 af99afa6 Guido Trotter
    self.f_dpn = lambda name: os.path.join(self.dir, "%s.pid" % name)
78 53beffbb Iustin Pop
    utils.DaemonPidFileName = self.f_dpn
79 af99afa6 Guido Trotter
80 af99afa6 Guido Trotter
  def testPidFileFunctions(self):
81 d9f311d7 Iustin Pop
    pid_file = self.f_dpn('test')
82 af99afa6 Guido Trotter
    utils.WritePidFile('test')
83 d9f311d7 Iustin Pop
    self.failUnless(os.path.exists(pid_file),
84 d9f311d7 Iustin Pop
                    "PID file should have been created")
85 d9f311d7 Iustin Pop
    read_pid = utils.ReadPidFile(pid_file)
86 d9f311d7 Iustin Pop
    self.failUnlessEqual(read_pid, os.getpid())
87 d9f311d7 Iustin Pop
    self.failUnless(utils.IsProcessAlive(read_pid))
88 d9f311d7 Iustin Pop
    self.failUnlessRaises(GenericError, utils.WritePidFile, 'test')
89 d9f311d7 Iustin Pop
    utils.RemovePidFile('test')
90 d9f311d7 Iustin Pop
    self.failIf(os.path.exists(pid_file),
91 d9f311d7 Iustin Pop
                "PID file should not exist anymore")
92 d9f311d7 Iustin Pop
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
93 d9f311d7 Iustin Pop
                         "ReadPidFile should return 0 for missing pid file")
94 d9f311d7 Iustin Pop
    fh = open(pid_file, "w")
95 d9f311d7 Iustin Pop
    fh.write("blah\n")
96 d9f311d7 Iustin Pop
    fh.close()
97 d9f311d7 Iustin Pop
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
98 d9f311d7 Iustin Pop
                         "ReadPidFile should return 0 for invalid pid file")
99 af99afa6 Guido Trotter
    utils.RemovePidFile('test')
100 d9f311d7 Iustin Pop
    self.failIf(os.path.exists(pid_file),
101 d9f311d7 Iustin Pop
                "PID file should not exist anymore")
102 af99afa6 Guido Trotter
103 b2a1f511 Iustin Pop
  def testKill(self):
104 b2a1f511 Iustin Pop
    pid_file = self.f_dpn('child')
105 b2a1f511 Iustin Pop
    r_fd, w_fd = os.pipe()
106 b2a1f511 Iustin Pop
    new_pid = os.fork()
107 b2a1f511 Iustin Pop
    if new_pid == 0: #child
108 b2a1f511 Iustin Pop
      utils.WritePidFile('child')
109 b2a1f511 Iustin Pop
      os.write(w_fd, 'a')
110 b2a1f511 Iustin Pop
      signal.pause()
111 b2a1f511 Iustin Pop
      os._exit(0)
112 b2a1f511 Iustin Pop
      return
113 b2a1f511 Iustin Pop
    # else we are in the parent
114 b2a1f511 Iustin Pop
    # wait until the child has written the pid file
115 b2a1f511 Iustin Pop
    os.read(r_fd, 1)
116 b2a1f511 Iustin Pop
    read_pid = utils.ReadPidFile(pid_file)
117 b2a1f511 Iustin Pop
    self.failUnlessEqual(read_pid, new_pid)
118 b2a1f511 Iustin Pop
    self.failUnless(utils.IsProcessAlive(new_pid))
119 ff5251bc Iustin Pop
    utils.KillProcess(new_pid, waitpid=True)
120 b2a1f511 Iustin Pop
    self.failIf(utils.IsProcessAlive(new_pid))
121 b2a1f511 Iustin Pop
    utils.RemovePidFile('child')
122 b2a1f511 Iustin Pop
    self.failUnlessRaises(ProgrammerError, utils.KillProcess, 0)
123 b2a1f511 Iustin Pop
124 af99afa6 Guido Trotter
  def tearDown(self):
125 d9f311d7 Iustin Pop
    for name in os.listdir(self.dir):
126 d9f311d7 Iustin Pop
      os.unlink(os.path.join(self.dir, name))
127 af99afa6 Guido Trotter
    os.rmdir(self.dir)
128 af99afa6 Guido Trotter
129 a8083063 Iustin Pop
130 36117c2b Iustin Pop
class TestRunCmd(testutils.GanetiTestCase):
131 a8083063 Iustin Pop
  """Testing case for the RunCmd function"""
132 a8083063 Iustin Pop
133 a8083063 Iustin Pop
  def setUp(self):
134 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
135 a8083063 Iustin Pop
    self.magic = time.ctime() + " ganeti test"
136 51596eb2 Iustin Pop
    self.fname = self._CreateTempFile()
137 a8083063 Iustin Pop
138 a8083063 Iustin Pop
  def testOk(self):
139 31ee599c Michael Hanselmann
    """Test successful exit code"""
140 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c 'exit 0'")
141 a8083063 Iustin Pop
    self.assertEqual(result.exit_code, 0)
142 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
143 a8083063 Iustin Pop
144 a8083063 Iustin Pop
  def testFail(self):
145 a8083063 Iustin Pop
    """Test fail exit code"""
146 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c 'exit 1'")
147 a8083063 Iustin Pop
    self.assertEqual(result.exit_code, 1)
148 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
149 a8083063 Iustin Pop
150 a8083063 Iustin Pop
  def testStdout(self):
151 a8083063 Iustin Pop
    """Test standard output"""
152 a8083063 Iustin Pop
    cmd = 'echo -n "%s"' % self.magic
153 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd)
154 a8083063 Iustin Pop
    self.assertEqual(result.stdout, self.magic)
155 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd, output=self.fname)
156 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
157 36117c2b Iustin Pop
    self.assertFileContent(self.fname, self.magic)
158 a8083063 Iustin Pop
159 a8083063 Iustin Pop
  def testStderr(self):
160 a8083063 Iustin Pop
    """Test standard error"""
161 a8083063 Iustin Pop
    cmd = 'echo -n "%s"' % self.magic
162 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s' 1>&2" % cmd)
163 a8083063 Iustin Pop
    self.assertEqual(result.stderr, self.magic)
164 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s' 1>&2" % cmd, output=self.fname)
165 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
166 36117c2b Iustin Pop
    self.assertFileContent(self.fname, self.magic)
167 a8083063 Iustin Pop
168 a8083063 Iustin Pop
  def testCombined(self):
169 a8083063 Iustin Pop
    """Test combined output"""
170 a8083063 Iustin Pop
    cmd = 'echo -n "A%s"; echo -n "B%s" 1>&2' % (self.magic, self.magic)
171 36117c2b Iustin Pop
    expected = "A" + self.magic + "B" + self.magic
172 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd)
173 36117c2b Iustin Pop
    self.assertEqual(result.output, expected)
174 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd, output=self.fname)
175 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
176 36117c2b Iustin Pop
    self.assertFileContent(self.fname, expected)
177 a8083063 Iustin Pop
178 a8083063 Iustin Pop
  def testSignal(self):
179 01fd6005 Manuel Franceschini
    """Test signal"""
180 01fd6005 Manuel Franceschini
    result = RunCmd(["python", "-c", "import os; os.kill(os.getpid(), 15)"])
181 a8083063 Iustin Pop
    self.assertEqual(result.signal, 15)
182 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
183 a8083063 Iustin Pop
184 7fcf849f Iustin Pop
  def testListRun(self):
185 7fcf849f Iustin Pop
    """Test list runs"""
186 7fcf849f Iustin Pop
    result = RunCmd(["true"])
187 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
188 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 0)
189 7fcf849f Iustin Pop
    result = RunCmd(["/bin/sh", "-c", "exit 1"])
190 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
191 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 1)
192 7fcf849f Iustin Pop
    result = RunCmd(["echo", "-n", self.magic])
193 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
194 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 0)
195 7fcf849f Iustin Pop
    self.assertEqual(result.stdout, self.magic)
196 7fcf849f Iustin Pop
197 36117c2b Iustin Pop
  def testFileEmptyOutput(self):
198 36117c2b Iustin Pop
    """Test file output"""
199 36117c2b Iustin Pop
    result = RunCmd(["true"], output=self.fname)
200 36117c2b Iustin Pop
    self.assertEqual(result.signal, None)
201 36117c2b Iustin Pop
    self.assertEqual(result.exit_code, 0)
202 36117c2b Iustin Pop
    self.assertFileContent(self.fname, "")
203 36117c2b Iustin Pop
204 f6441c7c Iustin Pop
  def testLang(self):
205 f6441c7c Iustin Pop
    """Test locale environment"""
206 23f41a3e Michael Hanselmann
    old_env = os.environ.copy()
207 23f41a3e Michael Hanselmann
    try:
208 23f41a3e Michael Hanselmann
      os.environ["LANG"] = "en_US.UTF-8"
209 23f41a3e Michael Hanselmann
      os.environ["LC_ALL"] = "en_US.UTF-8"
210 23f41a3e Michael Hanselmann
      result = RunCmd(["locale"])
211 23f41a3e Michael Hanselmann
      for line in result.output.splitlines():
212 23f41a3e Michael Hanselmann
        key, value = line.split("=", 1)
213 23f41a3e Michael Hanselmann
        # Ignore these variables, they're overridden by LC_ALL
214 23f41a3e Michael Hanselmann
        if key == "LANG" or key == "LANGUAGE":
215 23f41a3e Michael Hanselmann
          continue
216 23f41a3e Michael Hanselmann
        self.failIf(value and value != "C" and value != '"C"',
217 23f41a3e Michael Hanselmann
            "Variable %s is set to the invalid value '%s'" % (key, value))
218 23f41a3e Michael Hanselmann
    finally:
219 23f41a3e Michael Hanselmann
      os.environ = old_env
220 f6441c7c Iustin Pop
221 8797df43 Iustin Pop
  def testDefaultCwd(self):
222 8797df43 Iustin Pop
    """Test default working directory"""
223 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"]).stdout.strip(), "/")
224 8797df43 Iustin Pop
225 8797df43 Iustin Pop
  def testCwd(self):
226 8797df43 Iustin Pop
    """Test default working directory"""
227 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd="/").stdout.strip(), "/")
228 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd="/tmp").stdout.strip(), "/tmp")
229 8797df43 Iustin Pop
    cwd = os.getcwd()
230 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd=cwd).stdout.strip(), cwd)
231 8797df43 Iustin Pop
232 a8083063 Iustin Pop
233 a8083063 Iustin Pop
class TestRemoveFile(unittest.TestCase):
234 a8083063 Iustin Pop
  """Test case for the RemoveFile function"""
235 a8083063 Iustin Pop
236 a8083063 Iustin Pop
  def setUp(self):
237 a8083063 Iustin Pop
    """Create a temp dir and file for each case"""
238 a8083063 Iustin Pop
    self.tmpdir = tempfile.mkdtemp('', 'ganeti-unittest-')
239 a8083063 Iustin Pop
    fd, self.tmpfile = tempfile.mkstemp('', '', self.tmpdir)
240 a8083063 Iustin Pop
    os.close(fd)
241 a8083063 Iustin Pop
242 a8083063 Iustin Pop
  def tearDown(self):
243 a8083063 Iustin Pop
    if os.path.exists(self.tmpfile):
244 a8083063 Iustin Pop
      os.unlink(self.tmpfile)
245 a8083063 Iustin Pop
    os.rmdir(self.tmpdir)
246 a8083063 Iustin Pop
247 a8083063 Iustin Pop
248 a8083063 Iustin Pop
  def testIgnoreDirs(self):
249 a8083063 Iustin Pop
    """Test that RemoveFile() ignores directories"""
250 a8083063 Iustin Pop
    self.assertEqual(None, RemoveFile(self.tmpdir))
251 a8083063 Iustin Pop
252 a8083063 Iustin Pop
253 a8083063 Iustin Pop
  def testIgnoreNotExisting(self):
254 a8083063 Iustin Pop
    """Test that RemoveFile() ignores non-existing files"""
255 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
256 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
257 a8083063 Iustin Pop
258 a8083063 Iustin Pop
259 a8083063 Iustin Pop
  def testRemoveFile(self):
260 a8083063 Iustin Pop
    """Test that RemoveFile does remove a file"""
261 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
262 a8083063 Iustin Pop
    if os.path.exists(self.tmpfile):
263 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % self.tmpfile)
264 a8083063 Iustin Pop
265 a8083063 Iustin Pop
266 a8083063 Iustin Pop
  def testRemoveSymlink(self):
267 a8083063 Iustin Pop
    """Test that RemoveFile does remove symlinks"""
268 a8083063 Iustin Pop
    symlink = self.tmpdir + "/symlink"
269 a8083063 Iustin Pop
    os.symlink("no-such-file", symlink)
270 a8083063 Iustin Pop
    RemoveFile(symlink)
271 a8083063 Iustin Pop
    if os.path.exists(symlink):
272 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % symlink)
273 a8083063 Iustin Pop
    os.symlink(self.tmpfile, symlink)
274 a8083063 Iustin Pop
    RemoveFile(symlink)
275 a8083063 Iustin Pop
    if os.path.exists(symlink):
276 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % symlink)
277 a8083063 Iustin Pop
278 a8083063 Iustin Pop
279 6e797216 Michael Hanselmann
class TestRename(unittest.TestCase):
280 6e797216 Michael Hanselmann
  """Test case for RenameFile"""
281 6e797216 Michael Hanselmann
282 6e797216 Michael Hanselmann
  def setUp(self):
283 6e797216 Michael Hanselmann
    """Create a temporary directory"""
284 6e797216 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
285 6e797216 Michael Hanselmann
    self.tmpfile = os.path.join(self.tmpdir, "test1")
286 6e797216 Michael Hanselmann
287 6e797216 Michael Hanselmann
    # Touch the file
288 6e797216 Michael Hanselmann
    open(self.tmpfile, "w").close()
289 6e797216 Michael Hanselmann
290 6e797216 Michael Hanselmann
  def tearDown(self):
291 6e797216 Michael Hanselmann
    """Remove temporary directory"""
292 6e797216 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
293 6e797216 Michael Hanselmann
294 6e797216 Michael Hanselmann
  def testSimpleRename1(self):
295 6e797216 Michael Hanselmann
    """Simple rename 1"""
296 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"))
297 6e797216 Michael Hanselmann
298 6e797216 Michael Hanselmann
  def testSimpleRename2(self):
299 6e797216 Michael Hanselmann
    """Simple rename 2"""
300 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"),
301 6e797216 Michael Hanselmann
                     mkdir=True)
302 6e797216 Michael Hanselmann
303 6e797216 Michael Hanselmann
  def testRenameMkdir(self):
304 6e797216 Michael Hanselmann
    """Rename with mkdir"""
305 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "test/xyz"),
306 6e797216 Michael Hanselmann
                     mkdir=True)
307 6e797216 Michael Hanselmann
308 6e797216 Michael Hanselmann
309 a8083063 Iustin Pop
class TestCheckdict(unittest.TestCase):
310 a8083063 Iustin Pop
  """Test case for the CheckDict function"""
311 a8083063 Iustin Pop
312 a8083063 Iustin Pop
  def testAdd(self):
313 a8083063 Iustin Pop
    """Test that CheckDict adds a missing key with the correct value"""
314 a8083063 Iustin Pop
315 a8083063 Iustin Pop
    tgt = {'a':1}
316 a8083063 Iustin Pop
    tmpl = {'b': 2}
317 a8083063 Iustin Pop
    CheckDict(tgt, tmpl)
318 a8083063 Iustin Pop
    if 'b' not in tgt or tgt['b'] != 2:
319 a8083063 Iustin Pop
      self.fail("Failed to update dict")
320 a8083063 Iustin Pop
321 a8083063 Iustin Pop
322 a8083063 Iustin Pop
  def testNoUpdate(self):
323 a8083063 Iustin Pop
    """Test that CheckDict does not overwrite an existing key"""
324 a8083063 Iustin Pop
    tgt = {'a':1, 'b': 3}
325 a8083063 Iustin Pop
    tmpl = {'b': 2}
326 a8083063 Iustin Pop
    CheckDict(tgt, tmpl)
327 a8083063 Iustin Pop
    self.failUnlessEqual(tgt['b'], 3)
328 a8083063 Iustin Pop
329 a8083063 Iustin Pop
330 a8083063 Iustin Pop
class TestMatchNameComponent(unittest.TestCase):
331 a8083063 Iustin Pop
  """Test case for the MatchNameComponent function"""
332 a8083063 Iustin Pop
333 a8083063 Iustin Pop
  def testEmptyList(self):
334 a8083063 Iustin Pop
    """Test that there is no match against an empty list"""
335 a8083063 Iustin Pop
336 a8083063 Iustin Pop
    self.failUnlessEqual(MatchNameComponent("", []), None)
337 a8083063 Iustin Pop
    self.failUnlessEqual(MatchNameComponent("test", []), None)
338 a8083063 Iustin Pop
339 a8083063 Iustin Pop
  def testSingleMatch(self):
340 a8083063 Iustin Pop
    """Test that a single match is performed correctly"""
341 a8083063 Iustin Pop
    mlist = ["test1.example.com", "test2.example.com", "test3.example.com"]
342 a8083063 Iustin Pop
    for key in "test2", "test2.example", "test2.example.com":
343 a8083063 Iustin Pop
      self.failUnlessEqual(MatchNameComponent(key, mlist), mlist[1])
344 a8083063 Iustin Pop
345 a8083063 Iustin Pop
  def testMultipleMatches(self):
346 a8083063 Iustin Pop
    """Test that a multiple match is returned as None"""
347 a8083063 Iustin Pop
    mlist = ["test1.example.com", "test1.example.org", "test1.example.net"]
348 a8083063 Iustin Pop
    for key in "test1", "test1.example":
349 a8083063 Iustin Pop
      self.failUnlessEqual(MatchNameComponent(key, mlist), None)
350 a8083063 Iustin Pop
351 a8083063 Iustin Pop
352 a8083063 Iustin Pop
class TestFormatUnit(unittest.TestCase):
353 a8083063 Iustin Pop
  """Test case for the FormatUnit function"""
354 a8083063 Iustin Pop
355 a8083063 Iustin Pop
  def testMiB(self):
356 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1, 'h'), '1M')
357 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(100, 'h'), '100M')
358 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1023, 'h'), '1023M')
359 9fbfbb7b Iustin Pop
360 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1, 'm'), '1')
361 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(100, 'm'), '100')
362 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1023, 'm'), '1023')
363 9fbfbb7b Iustin Pop
364 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'm'), '1024')
365 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'm'), '1536')
366 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'm'), '17133')
367 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'm'), '1048575')
368 a8083063 Iustin Pop
369 a8083063 Iustin Pop
  def testGiB(self):
370 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'h'), '1.0G')
371 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'h'), '1.5G')
372 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'h'), '16.7G')
373 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'h'), '1024.0G')
374 9fbfbb7b Iustin Pop
375 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'g'), '1.0')
376 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'g'), '1.5')
377 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'g'), '16.7')
378 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'g'), '1024.0')
379 9fbfbb7b Iustin Pop
380 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 'g'), '1024.0')
381 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 'g'), '5120.0')
382 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 'g'), '29829.0')
383 a8083063 Iustin Pop
384 a8083063 Iustin Pop
  def testTiB(self):
385 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 'h'), '1.0T')
386 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 'h'), '5.0T')
387 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 'h'), '29.1T')
388 a8083063 Iustin Pop
389 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 't'), '1.0')
390 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 't'), '5.0')
391 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 't'), '29.1')
392 a8083063 Iustin Pop
393 a8083063 Iustin Pop
class TestParseUnit(unittest.TestCase):
394 a8083063 Iustin Pop
  """Test case for the ParseUnit function"""
395 a8083063 Iustin Pop
396 a8083063 Iustin Pop
  SCALES = (('', 1),
397 a8083063 Iustin Pop
            ('M', 1), ('G', 1024), ('T', 1024 * 1024),
398 a8083063 Iustin Pop
            ('MB', 1), ('GB', 1024), ('TB', 1024 * 1024),
399 a8083063 Iustin Pop
            ('MiB', 1), ('GiB', 1024), ('TiB', 1024 * 1024))
400 a8083063 Iustin Pop
401 a8083063 Iustin Pop
  def testRounding(self):
402 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0'), 0)
403 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1'), 4)
404 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2'), 4)
405 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('3'), 4)
406 a8083063 Iustin Pop
407 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('124'), 124)
408 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('125'), 128)
409 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('126'), 128)
410 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('127'), 128)
411 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('128'), 128)
412 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('129'), 132)
413 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('130'), 132)
414 a8083063 Iustin Pop
415 a8083063 Iustin Pop
  def testFloating(self):
416 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0'), 0)
417 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0.5'), 4)
418 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.75'), 4)
419 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.99'), 4)
420 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2.00'), 4)
421 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2.01'), 4)
422 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('3.99'), 4)
423 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('4.00'), 4)
424 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('4.01'), 8)
425 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.5G'), 1536)
426 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.8G'), 1844)
427 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('8.28T'), 8682212)
428 a8083063 Iustin Pop
429 a8083063 Iustin Pop
  def testSuffixes(self):
430 a8083063 Iustin Pop
    for sep in ('', ' ', '   ', "\t", "\t "):
431 a8083063 Iustin Pop
      for suffix, scale in TestParseUnit.SCALES:
432 a8083063 Iustin Pop
        for func in (lambda x: x, str.lower, str.upper):
433 667479d5 Michael Hanselmann
          self.assertEqual(ParseUnit('1024' + sep + func(suffix)),
434 667479d5 Michael Hanselmann
                           1024 * scale)
435 a8083063 Iustin Pop
436 a8083063 Iustin Pop
  def testInvalidInput(self):
437 a8083063 Iustin Pop
    for sep in ('-', '_', ',', 'a'):
438 a8083063 Iustin Pop
      for suffix, _ in TestParseUnit.SCALES:
439 a8083063 Iustin Pop
        self.assertRaises(UnitParseError, ParseUnit, '1' + sep + suffix)
440 a8083063 Iustin Pop
441 a8083063 Iustin Pop
    for suffix, _ in TestParseUnit.SCALES:
442 a8083063 Iustin Pop
      self.assertRaises(UnitParseError, ParseUnit, '1,3' + suffix)
443 a8083063 Iustin Pop
444 a8083063 Iustin Pop
445 c9c4f19e Michael Hanselmann
class TestSshKeys(testutils.GanetiTestCase):
446 a8083063 Iustin Pop
  """Test case for the AddAuthorizedKey function"""
447 a8083063 Iustin Pop
448 a8083063 Iustin Pop
  KEY_A = 'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a'
449 a8083063 Iustin Pop
  KEY_B = ('command="/usr/bin/fooserver -t --verbose",from="1.2.3.4" '
450 a8083063 Iustin Pop
           'ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b')
451 a8083063 Iustin Pop
452 ebe8ef17 Michael Hanselmann
  def setUp(self):
453 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
454 51596eb2 Iustin Pop
    self.tmpname = self._CreateTempFile()
455 51596eb2 Iustin Pop
    handle = open(self.tmpname, 'w')
456 a8083063 Iustin Pop
    try:
457 51596eb2 Iustin Pop
      handle.write("%s\n" % TestSshKeys.KEY_A)
458 51596eb2 Iustin Pop
      handle.write("%s\n" % TestSshKeys.KEY_B)
459 51596eb2 Iustin Pop
    finally:
460 51596eb2 Iustin Pop
      handle.close()
461 a8083063 Iustin Pop
462 a8083063 Iustin Pop
  def testAddingNewKey(self):
463 ebe8ef17 Michael Hanselmann
    AddAuthorizedKey(self.tmpname, 'ssh-dss AAAAB3NzaC1kc3MAAACB root@test')
464 a8083063 Iustin Pop
465 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
466 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
467 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
468 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
469 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1kc3MAAACB root@test\n")
470 a8083063 Iustin Pop
471 f89f17a8 Michael Hanselmann
  def testAddingAlmostButNotCompletelyTheSameKey(self):
472 ebe8ef17 Michael Hanselmann
    AddAuthorizedKey(self.tmpname,
473 ebe8ef17 Michael Hanselmann
        'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test')
474 ebe8ef17 Michael Hanselmann
475 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
476 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
477 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
478 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
479 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test\n")
480 a8083063 Iustin Pop
481 a8083063 Iustin Pop
  def testAddingExistingKeyWithSomeMoreSpaces(self):
482 ebe8ef17 Michael Hanselmann
    AddAuthorizedKey(self.tmpname,
483 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
484 a8083063 Iustin Pop
485 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
486 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
487 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
488 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
489 a8083063 Iustin Pop
490 a8083063 Iustin Pop
  def testRemovingExistingKeyWithSomeMoreSpaces(self):
491 ebe8ef17 Michael Hanselmann
    RemoveAuthorizedKey(self.tmpname,
492 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
493 a8083063 Iustin Pop
494 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
495 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
496 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
497 a8083063 Iustin Pop
498 a8083063 Iustin Pop
  def testRemovingNonExistingKey(self):
499 ebe8ef17 Michael Hanselmann
    RemoveAuthorizedKey(self.tmpname,
500 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3Nsdfj230xxjxJjsjwjsjdjU   root@test')
501 a8083063 Iustin Pop
502 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
503 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
504 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
505 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
506 a8083063 Iustin Pop
507 a8083063 Iustin Pop
508 c9c4f19e Michael Hanselmann
class TestEtcHosts(testutils.GanetiTestCase):
509 899d2a81 Michael Hanselmann
  """Test functions modifying /etc/hosts"""
510 899d2a81 Michael Hanselmann
511 ebe8ef17 Michael Hanselmann
  def setUp(self):
512 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
513 51596eb2 Iustin Pop
    self.tmpname = self._CreateTempFile()
514 51596eb2 Iustin Pop
    handle = open(self.tmpname, 'w')
515 899d2a81 Michael Hanselmann
    try:
516 51596eb2 Iustin Pop
      handle.write('# This is a test file for /etc/hosts\n')
517 51596eb2 Iustin Pop
      handle.write('127.0.0.1\tlocalhost\n')
518 51596eb2 Iustin Pop
      handle.write('192.168.1.1 router gw\n')
519 51596eb2 Iustin Pop
    finally:
520 51596eb2 Iustin Pop
      handle.close()
521 899d2a81 Michael Hanselmann
522 9440aeab Michael Hanselmann
  def testSettingNewIp(self):
523 ebe8ef17 Michael Hanselmann
    SetEtcHostsEntry(self.tmpname, '1.2.3.4', 'myhost.domain.tld', ['myhost'])
524 899d2a81 Michael Hanselmann
525 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
526 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
527 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
528 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router gw\n"
529 ebe8ef17 Michael Hanselmann
      "1.2.3.4\tmyhost.domain.tld myhost\n")
530 899d2a81 Michael Hanselmann
531 9440aeab Michael Hanselmann
  def testSettingExistingIp(self):
532 ebe8ef17 Michael Hanselmann
    SetEtcHostsEntry(self.tmpname, '192.168.1.1', 'myhost.domain.tld',
533 ebe8ef17 Michael Hanselmann
                     ['myhost'])
534 899d2a81 Michael Hanselmann
535 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
536 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
537 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
538 ebe8ef17 Michael Hanselmann
      "192.168.1.1\tmyhost.domain.tld myhost\n")
539 899d2a81 Michael Hanselmann
540 7fbb1f65 Michael Hanselmann
  def testSettingDuplicateName(self):
541 7fbb1f65 Michael Hanselmann
    SetEtcHostsEntry(self.tmpname, '1.2.3.4', 'myhost', ['myhost'])
542 7fbb1f65 Michael Hanselmann
543 7fbb1f65 Michael Hanselmann
    self.assertFileContent(self.tmpname,
544 7fbb1f65 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
545 7fbb1f65 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
546 7fbb1f65 Michael Hanselmann
      "192.168.1.1 router gw\n"
547 7fbb1f65 Michael Hanselmann
      "1.2.3.4\tmyhost\n")
548 7fbb1f65 Michael Hanselmann
549 899d2a81 Michael Hanselmann
  def testRemovingExistingHost(self):
550 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'router')
551 899d2a81 Michael Hanselmann
552 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
553 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
554 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
555 ebe8ef17 Michael Hanselmann
      "192.168.1.1 gw\n")
556 899d2a81 Michael Hanselmann
557 899d2a81 Michael Hanselmann
  def testRemovingSingleExistingHost(self):
558 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'localhost')
559 899d2a81 Michael Hanselmann
560 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
561 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
562 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router gw\n")
563 899d2a81 Michael Hanselmann
564 899d2a81 Michael Hanselmann
  def testRemovingNonExistingHost(self):
565 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'myhost')
566 899d2a81 Michael Hanselmann
567 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
568 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
569 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
570 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router gw\n")
571 899d2a81 Michael Hanselmann
572 9440aeab Michael Hanselmann
  def testRemovingAlias(self):
573 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'gw')
574 9440aeab Michael Hanselmann
575 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
576 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
577 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
578 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router\n")
579 9440aeab Michael Hanselmann
580 899d2a81 Michael Hanselmann
581 a8083063 Iustin Pop
class TestShellQuoting(unittest.TestCase):
582 a8083063 Iustin Pop
  """Test case for shell quoting functions"""
583 a8083063 Iustin Pop
584 a8083063 Iustin Pop
  def testShellQuote(self):
585 a8083063 Iustin Pop
    self.assertEqual(ShellQuote('abc'), "abc")
586 a8083063 Iustin Pop
    self.assertEqual(ShellQuote('ab"c'), "'ab\"c'")
587 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a'bc"), "'a'\\''bc'")
588 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a b c"), "'a b c'")
589 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a b\\ c"), "'a b\\ c'")
590 a8083063 Iustin Pop
591 a8083063 Iustin Pop
  def testShellQuoteArgs(self):
592 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b', 'c']), "a b c")
593 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b"', 'c']), "a 'b\"' c")
594 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b\'', 'c']), "a 'b'\\\''' c")
595 a8083063 Iustin Pop
596 a8083063 Iustin Pop
597 2c30e9d7 Alexander Schreiber
class TestTcpPing(unittest.TestCase):
598 2c30e9d7 Alexander Schreiber
  """Testcase for TCP version of ping - against listen(2)ing port"""
599 2c30e9d7 Alexander Schreiber
600 2c30e9d7 Alexander Schreiber
  def setUp(self):
601 2c30e9d7 Alexander Schreiber
    self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
602 16abfbc2 Alexander Schreiber
    self.listener.bind((constants.LOCALHOST_IP_ADDRESS, 0))
603 2c30e9d7 Alexander Schreiber
    self.listenerport = self.listener.getsockname()[1]
604 2c30e9d7 Alexander Schreiber
    self.listener.listen(1)
605 2c30e9d7 Alexander Schreiber
606 2c30e9d7 Alexander Schreiber
  def tearDown(self):
607 2c30e9d7 Alexander Schreiber
    self.listener.shutdown(socket.SHUT_RDWR)
608 2c30e9d7 Alexander Schreiber
    del self.listener
609 2c30e9d7 Alexander Schreiber
    del self.listenerport
610 2c30e9d7 Alexander Schreiber
611 2c30e9d7 Alexander Schreiber
  def testTcpPingToLocalHostAccept(self):
612 16abfbc2 Alexander Schreiber
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
613 2c30e9d7 Alexander Schreiber
                         self.listenerport,
614 2c30e9d7 Alexander Schreiber
                         timeout=10,
615 b15d625f Iustin Pop
                         live_port_needed=True,
616 b15d625f Iustin Pop
                         source=constants.LOCALHOST_IP_ADDRESS,
617 b15d625f Iustin Pop
                         ),
618 2c30e9d7 Alexander Schreiber
                 "failed to connect to test listener")
619 2c30e9d7 Alexander Schreiber
620 b15d625f Iustin Pop
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
621 b15d625f Iustin Pop
                         self.listenerport,
622 b15d625f Iustin Pop
                         timeout=10,
623 b15d625f Iustin Pop
                         live_port_needed=True,
624 b15d625f Iustin Pop
                         ),
625 b15d625f Iustin Pop
                 "failed to connect to test listener (no source)")
626 b15d625f Iustin Pop
627 2c30e9d7 Alexander Schreiber
628 2c30e9d7 Alexander Schreiber
class TestTcpPingDeaf(unittest.TestCase):
629 2c30e9d7 Alexander Schreiber
  """Testcase for TCP version of ping - against non listen(2)ing port"""
630 2c30e9d7 Alexander Schreiber
631 2c30e9d7 Alexander Schreiber
  def setUp(self):
632 2c30e9d7 Alexander Schreiber
    self.deaflistener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
633 16abfbc2 Alexander Schreiber
    self.deaflistener.bind((constants.LOCALHOST_IP_ADDRESS, 0))
634 2c30e9d7 Alexander Schreiber
    self.deaflistenerport = self.deaflistener.getsockname()[1]
635 2c30e9d7 Alexander Schreiber
636 2c30e9d7 Alexander Schreiber
  def tearDown(self):
637 2c30e9d7 Alexander Schreiber
    del self.deaflistener
638 2c30e9d7 Alexander Schreiber
    del self.deaflistenerport
639 2c30e9d7 Alexander Schreiber
640 2c30e9d7 Alexander Schreiber
  def testTcpPingToLocalHostAcceptDeaf(self):
641 16abfbc2 Alexander Schreiber
    self.failIf(TcpPing(constants.LOCALHOST_IP_ADDRESS,
642 2c30e9d7 Alexander Schreiber
                        self.deaflistenerport,
643 16abfbc2 Alexander Schreiber
                        timeout=constants.TCP_PING_TIMEOUT,
644 b15d625f Iustin Pop
                        live_port_needed=True,
645 b15d625f Iustin Pop
                        source=constants.LOCALHOST_IP_ADDRESS,
646 b15d625f Iustin Pop
                        ), # need successful connect(2)
647 2c30e9d7 Alexander Schreiber
                "successfully connected to deaf listener")
648 2c30e9d7 Alexander Schreiber
649 b15d625f Iustin Pop
    self.failIf(TcpPing(constants.LOCALHOST_IP_ADDRESS,
650 b15d625f Iustin Pop
                        self.deaflistenerport,
651 b15d625f Iustin Pop
                        timeout=constants.TCP_PING_TIMEOUT,
652 b15d625f Iustin Pop
                        live_port_needed=True,
653 b15d625f Iustin Pop
                        ), # need successful connect(2)
654 b15d625f Iustin Pop
                "successfully connected to deaf listener (no source addr)")
655 b15d625f Iustin Pop
656 2c30e9d7 Alexander Schreiber
  def testTcpPingToLocalHostNoAccept(self):
657 16abfbc2 Alexander Schreiber
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
658 2c30e9d7 Alexander Schreiber
                         self.deaflistenerport,
659 16abfbc2 Alexander Schreiber
                         timeout=constants.TCP_PING_TIMEOUT,
660 b15d625f Iustin Pop
                         live_port_needed=False,
661 b15d625f Iustin Pop
                         source=constants.LOCALHOST_IP_ADDRESS,
662 b15d625f Iustin Pop
                         ), # ECONNREFUSED is OK
663 2c30e9d7 Alexander Schreiber
                 "failed to ping alive host on deaf port")
664 2c30e9d7 Alexander Schreiber
665 b15d625f Iustin Pop
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
666 b15d625f Iustin Pop
                         self.deaflistenerport,
667 b15d625f Iustin Pop
                         timeout=constants.TCP_PING_TIMEOUT,
668 b15d625f Iustin Pop
                         live_port_needed=False,
669 b15d625f Iustin Pop
                         ), # ECONNREFUSED is OK
670 b15d625f Iustin Pop
                 "failed to ping alive host on deaf port (no source addr)")
671 b15d625f Iustin Pop
672 2c30e9d7 Alexander Schreiber
673 caad16e2 Iustin Pop
class TestOwnIpAddress(unittest.TestCase):
674 caad16e2 Iustin Pop
  """Testcase for OwnIpAddress"""
675 caad16e2 Iustin Pop
676 caad16e2 Iustin Pop
  def testOwnLoopback(self):
677 caad16e2 Iustin Pop
    """check having the loopback ip"""
678 caad16e2 Iustin Pop
    self.failUnless(OwnIpAddress(constants.LOCALHOST_IP_ADDRESS),
679 caad16e2 Iustin Pop
                    "Should own the loopback address")
680 caad16e2 Iustin Pop
681 caad16e2 Iustin Pop
  def testNowOwnAddress(self):
682 caad16e2 Iustin Pop
    """check that I don't own an address"""
683 caad16e2 Iustin Pop
684 caad16e2 Iustin Pop
    # network 192.0.2.0/24 is reserved for test/documentation as per
685 caad16e2 Iustin Pop
    # rfc 3330, so we *should* not have an address of this range... if
686 caad16e2 Iustin Pop
    # this fails, we should extend the test to multiple addresses
687 caad16e2 Iustin Pop
    DST_IP = "192.0.2.1"
688 caad16e2 Iustin Pop
    self.failIf(OwnIpAddress(DST_IP), "Should not own IP address %s" % DST_IP)
689 caad16e2 Iustin Pop
690 caad16e2 Iustin Pop
691 eedbda4b Michael Hanselmann
class TestListVisibleFiles(unittest.TestCase):
692 eedbda4b Michael Hanselmann
  """Test case for ListVisibleFiles"""
693 eedbda4b Michael Hanselmann
694 eedbda4b Michael Hanselmann
  def setUp(self):
695 eedbda4b Michael Hanselmann
    self.path = tempfile.mkdtemp()
696 eedbda4b Michael Hanselmann
697 eedbda4b Michael Hanselmann
  def tearDown(self):
698 eedbda4b Michael Hanselmann
    shutil.rmtree(self.path)
699 eedbda4b Michael Hanselmann
700 eedbda4b Michael Hanselmann
  def _test(self, files, expected):
701 eedbda4b Michael Hanselmann
    # Sort a copy
702 eedbda4b Michael Hanselmann
    expected = expected[:]
703 eedbda4b Michael Hanselmann
    expected.sort()
704 eedbda4b Michael Hanselmann
705 eedbda4b Michael Hanselmann
    for name in files:
706 eedbda4b Michael Hanselmann
      f = open(os.path.join(self.path, name), 'w')
707 eedbda4b Michael Hanselmann
      try:
708 eedbda4b Michael Hanselmann
        f.write("Test\n")
709 eedbda4b Michael Hanselmann
      finally:
710 eedbda4b Michael Hanselmann
        f.close()
711 eedbda4b Michael Hanselmann
712 eedbda4b Michael Hanselmann
    found = ListVisibleFiles(self.path)
713 eedbda4b Michael Hanselmann
    found.sort()
714 eedbda4b Michael Hanselmann
715 eedbda4b Michael Hanselmann
    self.assertEqual(found, expected)
716 eedbda4b Michael Hanselmann
717 eedbda4b Michael Hanselmann
  def testAllVisible(self):
718 eedbda4b Michael Hanselmann
    files = ["a", "b", "c"]
719 eedbda4b Michael Hanselmann
    expected = files
720 eedbda4b Michael Hanselmann
    self._test(files, expected)
721 eedbda4b Michael Hanselmann
722 eedbda4b Michael Hanselmann
  def testNoneVisible(self):
723 eedbda4b Michael Hanselmann
    files = [".a", ".b", ".c"]
724 eedbda4b Michael Hanselmann
    expected = []
725 eedbda4b Michael Hanselmann
    self._test(files, expected)
726 eedbda4b Michael Hanselmann
727 eedbda4b Michael Hanselmann
  def testSomeVisible(self):
728 eedbda4b Michael Hanselmann
    files = ["a", "b", ".c"]
729 eedbda4b Michael Hanselmann
    expected = ["a", "b"]
730 eedbda4b Michael Hanselmann
    self._test(files, expected)
731 eedbda4b Michael Hanselmann
732 eedbda4b Michael Hanselmann
733 24818e8f Michael Hanselmann
class TestNewUUID(unittest.TestCase):
734 24818e8f Michael Hanselmann
  """Test case for NewUUID"""
735 59072e7e Michael Hanselmann
736 59072e7e Michael Hanselmann
  _re_uuid = re.compile('^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-'
737 59072e7e Michael Hanselmann
                        '[a-f0-9]{4}-[a-f0-9]{12}$')
738 59072e7e Michael Hanselmann
739 59072e7e Michael Hanselmann
  def runTest(self):
740 24818e8f Michael Hanselmann
    self.failUnless(self._re_uuid.match(utils.NewUUID()))
741 59072e7e Michael Hanselmann
742 59072e7e Michael Hanselmann
743 f7414041 Michael Hanselmann
class TestUniqueSequence(unittest.TestCase):
744 f7414041 Michael Hanselmann
  """Test case for UniqueSequence"""
745 f7414041 Michael Hanselmann
746 f7414041 Michael Hanselmann
  def _test(self, input, expected):
747 f7414041 Michael Hanselmann
    self.assertEqual(utils.UniqueSequence(input), expected)
748 f7414041 Michael Hanselmann
749 f7414041 Michael Hanselmann
  def runTest(self):
750 f7414041 Michael Hanselmann
    # Ordered input
751 f7414041 Michael Hanselmann
    self._test([1, 2, 3], [1, 2, 3])
752 f7414041 Michael Hanselmann
    self._test([1, 1, 2, 2, 3, 3], [1, 2, 3])
753 f7414041 Michael Hanselmann
    self._test([1, 2, 2, 3], [1, 2, 3])
754 f7414041 Michael Hanselmann
    self._test([1, 2, 3, 3], [1, 2, 3])
755 f7414041 Michael Hanselmann
756 f7414041 Michael Hanselmann
    # Unordered input
757 f7414041 Michael Hanselmann
    self._test([1, 2, 3, 1, 2, 3], [1, 2, 3])
758 f7414041 Michael Hanselmann
    self._test([1, 1, 2, 3, 3, 1, 2], [1, 2, 3])
759 f7414041 Michael Hanselmann
760 f7414041 Michael Hanselmann
    # Strings
761 f7414041 Michael Hanselmann
    self._test(["a", "a"], ["a"])
762 f7414041 Michael Hanselmann
    self._test(["a", "b"], ["a", "b"])
763 f7414041 Michael Hanselmann
    self._test(["a", "b", "a"], ["a", "b"])
764 f7414041 Michael Hanselmann
765 a87b4824 Michael Hanselmann
766 7b4126b7 Iustin Pop
class TestFirstFree(unittest.TestCase):
767 7b4126b7 Iustin Pop
  """Test case for the FirstFree function"""
768 7b4126b7 Iustin Pop
769 7b4126b7 Iustin Pop
  def test(self):
770 7b4126b7 Iustin Pop
    """Test FirstFree"""
771 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([0, 1, 3]), 2)
772 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([]), None)
773 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([3, 4, 6]), 0)
774 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([3, 4, 6], base=3), 5)
775 7b4126b7 Iustin Pop
    self.failUnlessRaises(AssertionError, FirstFree, [0, 3, 4, 6], base=3)
776 f7414041 Michael Hanselmann
777 a87b4824 Michael Hanselmann
778 f65f63ef Iustin Pop
class TestTailFile(testutils.GanetiTestCase):
779 f65f63ef Iustin Pop
  """Test case for the TailFile function"""
780 f65f63ef Iustin Pop
781 f65f63ef Iustin Pop
  def testEmpty(self):
782 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
783 f65f63ef Iustin Pop
    self.failUnlessEqual(TailFile(fname), [])
784 f65f63ef Iustin Pop
    self.failUnlessEqual(TailFile(fname, lines=25), [])
785 f65f63ef Iustin Pop
786 f65f63ef Iustin Pop
  def testAllLines(self):
787 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
788 f65f63ef Iustin Pop
    for i in range(30):
789 f65f63ef Iustin Pop
      fname = self._CreateTempFile()
790 f65f63ef Iustin Pop
      fd = open(fname, "w")
791 f65f63ef Iustin Pop
      fd.write("\n".join(data[:i]))
792 f65f63ef Iustin Pop
      if i > 0:
793 f65f63ef Iustin Pop
        fd.write("\n")
794 f65f63ef Iustin Pop
      fd.close()
795 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[:i])
796 f65f63ef Iustin Pop
797 f65f63ef Iustin Pop
  def testPartialLines(self):
798 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
799 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
800 f65f63ef Iustin Pop
    fd = open(fname, "w")
801 f65f63ef Iustin Pop
    fd.write("\n".join(data))
802 f65f63ef Iustin Pop
    fd.write("\n")
803 f65f63ef Iustin Pop
    fd.close()
804 f65f63ef Iustin Pop
    for i in range(1, 30):
805 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[-i:])
806 f65f63ef Iustin Pop
807 f65f63ef Iustin Pop
  def testBigFile(self):
808 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
809 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
810 f65f63ef Iustin Pop
    fd = open(fname, "w")
811 f65f63ef Iustin Pop
    fd.write("X" * 1048576)
812 f65f63ef Iustin Pop
    fd.write("\n")
813 f65f63ef Iustin Pop
    fd.write("\n".join(data))
814 f65f63ef Iustin Pop
    fd.write("\n")
815 f65f63ef Iustin Pop
    fd.close()
816 f65f63ef Iustin Pop
    for i in range(1, 30):
817 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[-i:])
818 f65f63ef Iustin Pop
819 f65f63ef Iustin Pop
820 a87b4824 Michael Hanselmann
class TestFileLock(unittest.TestCase):
821 a87b4824 Michael Hanselmann
  """Test case for the FileLock class"""
822 a87b4824 Michael Hanselmann
823 a87b4824 Michael Hanselmann
  def setUp(self):
824 a87b4824 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
825 a87b4824 Michael Hanselmann
    self.lock = utils.FileLock(self.tmpfile.name)
826 a87b4824 Michael Hanselmann
827 a87b4824 Michael Hanselmann
  def testSharedNonblocking(self):
828 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
829 a87b4824 Michael Hanselmann
    self.lock.Close()
830 a87b4824 Michael Hanselmann
831 a87b4824 Michael Hanselmann
  def testExclusiveNonblocking(self):
832 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
833 a87b4824 Michael Hanselmann
    self.lock.Close()
834 a87b4824 Michael Hanselmann
835 a87b4824 Michael Hanselmann
  def testUnlockNonblocking(self):
836 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
837 a87b4824 Michael Hanselmann
    self.lock.Close()
838 a87b4824 Michael Hanselmann
839 a87b4824 Michael Hanselmann
  def testSharedBlocking(self):
840 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=True)
841 a87b4824 Michael Hanselmann
    self.lock.Close()
842 a87b4824 Michael Hanselmann
843 a87b4824 Michael Hanselmann
  def testExclusiveBlocking(self):
844 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=True)
845 a87b4824 Michael Hanselmann
    self.lock.Close()
846 a87b4824 Michael Hanselmann
847 a87b4824 Michael Hanselmann
  def testUnlockBlocking(self):
848 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=True)
849 a87b4824 Michael Hanselmann
    self.lock.Close()
850 a87b4824 Michael Hanselmann
851 a87b4824 Michael Hanselmann
  def testSharedExclusiveUnlock(self):
852 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
853 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
854 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
855 a87b4824 Michael Hanselmann
    self.lock.Close()
856 a87b4824 Michael Hanselmann
857 a87b4824 Michael Hanselmann
  def testExclusiveSharedUnlock(self):
858 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
859 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
860 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
861 a87b4824 Michael Hanselmann
    self.lock.Close()
862 a87b4824 Michael Hanselmann
863 a87b4824 Michael Hanselmann
  def testCloseShared(self):
864 a87b4824 Michael Hanselmann
    self.lock.Close()
865 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Shared, blocking=False)
866 a87b4824 Michael Hanselmann
867 a87b4824 Michael Hanselmann
  def testCloseExclusive(self):
868 a87b4824 Michael Hanselmann
    self.lock.Close()
869 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Exclusive, blocking=False)
870 a87b4824 Michael Hanselmann
871 a87b4824 Michael Hanselmann
  def testCloseUnlock(self):
872 a87b4824 Michael Hanselmann
    self.lock.Close()
873 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Unlock, blocking=False)
874 a87b4824 Michael Hanselmann
875 a87b4824 Michael Hanselmann
876 739be818 Michael Hanselmann
class TestTimeFunctions(unittest.TestCase):
877 739be818 Michael Hanselmann
  """Test case for time functions"""
878 739be818 Michael Hanselmann
879 739be818 Michael Hanselmann
  def runTest(self):
880 739be818 Michael Hanselmann
    self.assertEqual(utils.SplitTime(1), (1, 0))
881 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(1.5), (1, 500000))
882 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(1218448917.4809151), (1218448917, 480915))
883 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.48012), (123, 480120))
884 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9996), (123, 999600))
885 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9995), (123, 999500))
886 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9994), (123, 999400))
887 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.999999999), (123, 999999))
888 45bc5e4a Michael Hanselmann
889 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.SplitTime, -1)
890 739be818 Michael Hanselmann
891 739be818 Michael Hanselmann
    self.assertEqual(utils.MergeTime((1, 0)), 1.0)
892 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.MergeTime((1, 500000)), 1.5)
893 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.MergeTime((1218448917, 500000)), 1218448917.5)
894 739be818 Michael Hanselmann
895 45bc5e4a Michael Hanselmann
    self.assertEqual(round(utils.MergeTime((1218448917, 481000)), 3), 1218448917.481)
896 45bc5e4a Michael Hanselmann
    self.assertEqual(round(utils.MergeTime((1, 801000)), 3), 1.801)
897 739be818 Michael Hanselmann
898 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, -1))
899 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, 1000000))
900 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, 9999999))
901 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (-1, 0))
902 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (-9999, 0))
903 739be818 Michael Hanselmann
904 739be818 Michael Hanselmann
905 a2d2e1a7 Iustin Pop
class FieldSetTestCase(unittest.TestCase):
906 a2d2e1a7 Iustin Pop
  """Test case for FieldSets"""
907 a2d2e1a7 Iustin Pop
908 a2d2e1a7 Iustin Pop
  def testSimpleMatch(self):
909 a2d2e1a7 Iustin Pop
    f = utils.FieldSet("a", "b", "c", "def")
910 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("a"))
911 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("d"), "Substring matched")
912 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("defghi"), "Prefix string matched")
913 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["b", "c"]))
914 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["a", "b", "c", "def"]))
915 a2d2e1a7 Iustin Pop
    self.failUnless(f.NonMatching(["a", "d"]))
916 a2d2e1a7 Iustin Pop
917 a2d2e1a7 Iustin Pop
  def testRegexMatch(self):
918 a2d2e1a7 Iustin Pop
    f = utils.FieldSet("a", "b([0-9]+)", "c")
919 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("b1"))
920 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("b99"))
921 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("b/1"))
922 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["b12", "c"]))
923 a2d2e1a7 Iustin Pop
    self.failUnless(f.NonMatching(["a", "1"]))
924 a2d2e1a7 Iustin Pop
925 a5728081 Guido Trotter
class TestForceDictType(unittest.TestCase):
926 a5728081 Guido Trotter
  """Test case for ForceDictType"""
927 a5728081 Guido Trotter
928 a5728081 Guido Trotter
  def setUp(self):
929 a5728081 Guido Trotter
    self.key_types = {
930 a5728081 Guido Trotter
      'a': constants.VTYPE_INT,
931 a5728081 Guido Trotter
      'b': constants.VTYPE_BOOL,
932 a5728081 Guido Trotter
      'c': constants.VTYPE_STRING,
933 a5728081 Guido Trotter
      'd': constants.VTYPE_SIZE,
934 a5728081 Guido Trotter
      }
935 a5728081 Guido Trotter
936 a5728081 Guido Trotter
  def _fdt(self, dict, allowed_values=None):
937 a5728081 Guido Trotter
    if allowed_values is None:
938 a5728081 Guido Trotter
      ForceDictType(dict, self.key_types)
939 a5728081 Guido Trotter
    else:
940 a5728081 Guido Trotter
      ForceDictType(dict, self.key_types, allowed_values=allowed_values)
941 a5728081 Guido Trotter
942 a5728081 Guido Trotter
    return dict
943 a5728081 Guido Trotter
944 a5728081 Guido Trotter
  def testSimpleDict(self):
945 a5728081 Guido Trotter
    self.assertEqual(self._fdt({}), {})
946 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': 1}), {'a': 1})
947 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': '1'}), {'a': 1})
948 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': 1, 'b': 1}), {'a':1, 'b': True})
949 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 1, 'c': 'foo'}), {'b': True, 'c': 'foo'})
950 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 1, 'c': False}), {'b': True, 'c': ''})
951 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'false'}), {'b': False})
952 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'False'}), {'b': False})
953 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'true'}), {'b': True})
954 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'True'}), {'b': True})
955 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'d': '4'}), {'d': 4})
956 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'d': '4M'}), {'d': 4})
957 a5728081 Guido Trotter
958 a5728081 Guido Trotter
  def testErrors(self):
959 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'a': 'astring'})
960 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'c': True})
961 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': 'astring'})
962 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': '4 L'})
963 a5728081 Guido Trotter
964 a2d2e1a7 Iustin Pop
965 a8083063 Iustin Pop
if __name__ == '__main__':
966 a8083063 Iustin Pop
  unittest.main()