Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils_unittest.py @ 09352fa4

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