Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils_unittest.py @ 45bc5e4a

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