Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils_unittest.py @ e587b46a

History | View | Annotate | Download (59.9 kB)

1 a8083063 Iustin Pop
#!/usr/bin/python
2 a8083063 Iustin Pop
#
3 a8083063 Iustin Pop
4 a8083063 Iustin Pop
# Copyright (C) 2006, 2007 Google Inc.
5 a8083063 Iustin Pop
#
6 a8083063 Iustin Pop
# This program is free software; you can redistribute it and/or modify
7 a8083063 Iustin Pop
# it under the terms of the GNU General Public License as published by
8 a8083063 Iustin Pop
# the Free Software Foundation; either version 2 of the License, or
9 a8083063 Iustin Pop
# (at your option) any later version.
10 a8083063 Iustin Pop
#
11 a8083063 Iustin Pop
# This program is distributed in the hope that it will be useful, but
12 a8083063 Iustin Pop
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 a8083063 Iustin Pop
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 a8083063 Iustin Pop
# General Public License for more details.
15 a8083063 Iustin Pop
#
16 a8083063 Iustin Pop
# You should have received a copy of the GNU General Public License
17 a8083063 Iustin Pop
# along with this program; if not, write to the Free Software
18 a8083063 Iustin Pop
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 a8083063 Iustin Pop
# 02110-1301, USA.
20 a8083063 Iustin Pop
21 a8083063 Iustin Pop
22 a8083063 Iustin Pop
"""Script for unittesting the utils module"""
23 a8083063 Iustin Pop
24 a8083063 Iustin Pop
import unittest
25 a8083063 Iustin Pop
import os
26 a8083063 Iustin Pop
import time
27 a8083063 Iustin Pop
import tempfile
28 a8083063 Iustin Pop
import os.path
29 320b4e2d Alexander Schreiber
import os
30 6bb65e3a Guido Trotter
import stat
31 740c5aab Guido Trotter
import signal
32 2c30e9d7 Alexander Schreiber
import socket
33 eedbda4b Michael Hanselmann
import shutil
34 59072e7e Michael Hanselmann
import re
35 09352fa4 Iustin Pop
import select
36 d392fa34 Iustin Pop
import string
37 27e46076 Michael Hanselmann
import OpenSSL
38 27e46076 Michael Hanselmann
import warnings
39 27e46076 Michael Hanselmann
import distutils.version
40 1d466a4f Michael Hanselmann
import glob
41 b774bb10 Michael Hanselmann
import md5
42 a8083063 Iustin Pop
43 a8083063 Iustin Pop
import ganeti
44 c9c4f19e Michael Hanselmann
import testutils
45 16abfbc2 Alexander Schreiber
from ganeti import constants
46 59072e7e Michael Hanselmann
from ganeti import utils
47 a5728081 Guido Trotter
from ganeti import errors
48 f93f2016 Michael Hanselmann
from ganeti import serializer
49 e5392d79 Iustin Pop
from ganeti.utils import IsProcessAlive, RunCmd, \
50 31e22135 Iustin Pop
     RemoveFile, MatchNameComponent, FormatUnit, \
51 a8083063 Iustin Pop
     ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \
52 899d2a81 Michael Hanselmann
     ShellQuote, ShellQuoteArgs, TcpPing, ListVisibleFiles, \
53 f65f63ef Iustin Pop
     SetEtcHostsEntry, RemoveEtcHostsEntry, FirstFree, OwnIpAddress, \
54 5b69bc7c Iustin Pop
     TailFile, ForceDictType, SafeEncode, IsNormAbsPath, FormatTime, \
55 e587b46a Guido Trotter
     UnescapeAndSplit, RunParts, PathJoin, HostInfo, ReadOneLineFile
56 f65f63ef Iustin Pop
57 b2a1f511 Iustin Pop
from ganeti.errors import LockError, UnitParseError, GenericError, \
58 26288e68 Iustin Pop
     ProgrammerError, OpPrereqError
59 a8083063 Iustin Pop
60 d9f311d7 Iustin Pop
61 a8083063 Iustin Pop
class TestIsProcessAlive(unittest.TestCase):
62 a8083063 Iustin Pop
  """Testing case for IsProcessAlive"""
63 740c5aab Guido Trotter
64 a8083063 Iustin Pop
  def testExists(self):
65 a8083063 Iustin Pop
    mypid = os.getpid()
66 a8083063 Iustin Pop
    self.assert_(IsProcessAlive(mypid),
67 a8083063 Iustin Pop
                 "can't find myself running")
68 a8083063 Iustin Pop
69 a8083063 Iustin Pop
  def testNotExisting(self):
70 09352fa4 Iustin Pop
    pid_non_existing = os.fork()
71 09352fa4 Iustin Pop
    if pid_non_existing == 0:
72 09352fa4 Iustin Pop
      os._exit(0)
73 09352fa4 Iustin Pop
    elif pid_non_existing < 0:
74 09352fa4 Iustin Pop
      raise SystemError("can't fork")
75 09352fa4 Iustin Pop
    os.waitpid(pid_non_existing, 0)
76 09352fa4 Iustin Pop
    self.assert_(not IsProcessAlive(pid_non_existing),
77 09352fa4 Iustin Pop
                 "nonexisting process detected")
78 a8083063 Iustin Pop
79 d9f311d7 Iustin Pop
80 af99afa6 Guido Trotter
class TestPidFileFunctions(unittest.TestCase):
81 d9f311d7 Iustin Pop
  """Tests for WritePidFile, RemovePidFile and ReadPidFile"""
82 af99afa6 Guido Trotter
83 af99afa6 Guido Trotter
  def setUp(self):
84 af99afa6 Guido Trotter
    self.dir = tempfile.mkdtemp()
85 af99afa6 Guido Trotter
    self.f_dpn = lambda name: os.path.join(self.dir, "%s.pid" % name)
86 53beffbb Iustin Pop
    utils.DaemonPidFileName = self.f_dpn
87 af99afa6 Guido Trotter
88 af99afa6 Guido Trotter
  def testPidFileFunctions(self):
89 d9f311d7 Iustin Pop
    pid_file = self.f_dpn('test')
90 af99afa6 Guido Trotter
    utils.WritePidFile('test')
91 d9f311d7 Iustin Pop
    self.failUnless(os.path.exists(pid_file),
92 d9f311d7 Iustin Pop
                    "PID file should have been created")
93 d9f311d7 Iustin Pop
    read_pid = utils.ReadPidFile(pid_file)
94 d9f311d7 Iustin Pop
    self.failUnlessEqual(read_pid, os.getpid())
95 d9f311d7 Iustin Pop
    self.failUnless(utils.IsProcessAlive(read_pid))
96 d9f311d7 Iustin Pop
    self.failUnlessRaises(GenericError, utils.WritePidFile, 'test')
97 d9f311d7 Iustin Pop
    utils.RemovePidFile('test')
98 d9f311d7 Iustin Pop
    self.failIf(os.path.exists(pid_file),
99 d9f311d7 Iustin Pop
                "PID file should not exist anymore")
100 d9f311d7 Iustin Pop
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
101 d9f311d7 Iustin Pop
                         "ReadPidFile should return 0 for missing pid file")
102 d9f311d7 Iustin Pop
    fh = open(pid_file, "w")
103 d9f311d7 Iustin Pop
    fh.write("blah\n")
104 d9f311d7 Iustin Pop
    fh.close()
105 d9f311d7 Iustin Pop
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
106 d9f311d7 Iustin Pop
                         "ReadPidFile should return 0 for invalid pid file")
107 af99afa6 Guido Trotter
    utils.RemovePidFile('test')
108 d9f311d7 Iustin Pop
    self.failIf(os.path.exists(pid_file),
109 d9f311d7 Iustin Pop
                "PID file should not exist anymore")
110 af99afa6 Guido Trotter
111 b2a1f511 Iustin Pop
  def testKill(self):
112 b2a1f511 Iustin Pop
    pid_file = self.f_dpn('child')
113 b2a1f511 Iustin Pop
    r_fd, w_fd = os.pipe()
114 b2a1f511 Iustin Pop
    new_pid = os.fork()
115 b2a1f511 Iustin Pop
    if new_pid == 0: #child
116 b2a1f511 Iustin Pop
      utils.WritePidFile('child')
117 b2a1f511 Iustin Pop
      os.write(w_fd, 'a')
118 b2a1f511 Iustin Pop
      signal.pause()
119 b2a1f511 Iustin Pop
      os._exit(0)
120 b2a1f511 Iustin Pop
      return
121 b2a1f511 Iustin Pop
    # else we are in the parent
122 b2a1f511 Iustin Pop
    # wait until the child has written the pid file
123 b2a1f511 Iustin Pop
    os.read(r_fd, 1)
124 b2a1f511 Iustin Pop
    read_pid = utils.ReadPidFile(pid_file)
125 b2a1f511 Iustin Pop
    self.failUnlessEqual(read_pid, new_pid)
126 b2a1f511 Iustin Pop
    self.failUnless(utils.IsProcessAlive(new_pid))
127 ff5251bc Iustin Pop
    utils.KillProcess(new_pid, waitpid=True)
128 b2a1f511 Iustin Pop
    self.failIf(utils.IsProcessAlive(new_pid))
129 b2a1f511 Iustin Pop
    utils.RemovePidFile('child')
130 b2a1f511 Iustin Pop
    self.failUnlessRaises(ProgrammerError, utils.KillProcess, 0)
131 b2a1f511 Iustin Pop
132 af99afa6 Guido Trotter
  def tearDown(self):
133 d9f311d7 Iustin Pop
    for name in os.listdir(self.dir):
134 d9f311d7 Iustin Pop
      os.unlink(os.path.join(self.dir, name))
135 af99afa6 Guido Trotter
    os.rmdir(self.dir)
136 af99afa6 Guido Trotter
137 a8083063 Iustin Pop
138 36117c2b Iustin Pop
class TestRunCmd(testutils.GanetiTestCase):
139 a8083063 Iustin Pop
  """Testing case for the RunCmd function"""
140 a8083063 Iustin Pop
141 a8083063 Iustin Pop
  def setUp(self):
142 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
143 a8083063 Iustin Pop
    self.magic = time.ctime() + " ganeti test"
144 51596eb2 Iustin Pop
    self.fname = self._CreateTempFile()
145 a8083063 Iustin Pop
146 a8083063 Iustin Pop
  def testOk(self):
147 31ee599c Michael Hanselmann
    """Test successful exit code"""
148 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c 'exit 0'")
149 a8083063 Iustin Pop
    self.assertEqual(result.exit_code, 0)
150 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
151 a8083063 Iustin Pop
152 a8083063 Iustin Pop
  def testFail(self):
153 a8083063 Iustin Pop
    """Test fail exit code"""
154 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c 'exit 1'")
155 a8083063 Iustin Pop
    self.assertEqual(result.exit_code, 1)
156 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
157 a8083063 Iustin Pop
158 a8083063 Iustin Pop
  def testStdout(self):
159 a8083063 Iustin Pop
    """Test standard output"""
160 a8083063 Iustin Pop
    cmd = 'echo -n "%s"' % self.magic
161 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd)
162 a8083063 Iustin Pop
    self.assertEqual(result.stdout, self.magic)
163 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd, output=self.fname)
164 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
165 36117c2b Iustin Pop
    self.assertFileContent(self.fname, self.magic)
166 a8083063 Iustin Pop
167 a8083063 Iustin Pop
  def testStderr(self):
168 a8083063 Iustin Pop
    """Test standard error"""
169 a8083063 Iustin Pop
    cmd = 'echo -n "%s"' % self.magic
170 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s' 1>&2" % cmd)
171 a8083063 Iustin Pop
    self.assertEqual(result.stderr, self.magic)
172 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s' 1>&2" % cmd, output=self.fname)
173 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
174 36117c2b Iustin Pop
    self.assertFileContent(self.fname, self.magic)
175 a8083063 Iustin Pop
176 a8083063 Iustin Pop
  def testCombined(self):
177 a8083063 Iustin Pop
    """Test combined output"""
178 a8083063 Iustin Pop
    cmd = 'echo -n "A%s"; echo -n "B%s" 1>&2' % (self.magic, self.magic)
179 36117c2b Iustin Pop
    expected = "A" + self.magic + "B" + self.magic
180 a8083063 Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd)
181 36117c2b Iustin Pop
    self.assertEqual(result.output, expected)
182 36117c2b Iustin Pop
    result = RunCmd("/bin/sh -c '%s'" % cmd, output=self.fname)
183 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
184 36117c2b Iustin Pop
    self.assertFileContent(self.fname, expected)
185 a8083063 Iustin Pop
186 a8083063 Iustin Pop
  def testSignal(self):
187 01fd6005 Manuel Franceschini
    """Test signal"""
188 01fd6005 Manuel Franceschini
    result = RunCmd(["python", "-c", "import os; os.kill(os.getpid(), 15)"])
189 a8083063 Iustin Pop
    self.assertEqual(result.signal, 15)
190 36117c2b Iustin Pop
    self.assertEqual(result.output, "")
191 a8083063 Iustin Pop
192 7fcf849f Iustin Pop
  def testListRun(self):
193 7fcf849f Iustin Pop
    """Test list runs"""
194 7fcf849f Iustin Pop
    result = RunCmd(["true"])
195 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
196 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 0)
197 7fcf849f Iustin Pop
    result = RunCmd(["/bin/sh", "-c", "exit 1"])
198 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
199 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 1)
200 7fcf849f Iustin Pop
    result = RunCmd(["echo", "-n", self.magic])
201 7fcf849f Iustin Pop
    self.assertEqual(result.signal, None)
202 7fcf849f Iustin Pop
    self.assertEqual(result.exit_code, 0)
203 7fcf849f Iustin Pop
    self.assertEqual(result.stdout, self.magic)
204 7fcf849f Iustin Pop
205 36117c2b Iustin Pop
  def testFileEmptyOutput(self):
206 36117c2b Iustin Pop
    """Test file output"""
207 36117c2b Iustin Pop
    result = RunCmd(["true"], output=self.fname)
208 36117c2b Iustin Pop
    self.assertEqual(result.signal, None)
209 36117c2b Iustin Pop
    self.assertEqual(result.exit_code, 0)
210 36117c2b Iustin Pop
    self.assertFileContent(self.fname, "")
211 36117c2b Iustin Pop
212 f6441c7c Iustin Pop
  def testLang(self):
213 f6441c7c Iustin Pop
    """Test locale environment"""
214 23f41a3e Michael Hanselmann
    old_env = os.environ.copy()
215 23f41a3e Michael Hanselmann
    try:
216 23f41a3e Michael Hanselmann
      os.environ["LANG"] = "en_US.UTF-8"
217 23f41a3e Michael Hanselmann
      os.environ["LC_ALL"] = "en_US.UTF-8"
218 23f41a3e Michael Hanselmann
      result = RunCmd(["locale"])
219 23f41a3e Michael Hanselmann
      for line in result.output.splitlines():
220 23f41a3e Michael Hanselmann
        key, value = line.split("=", 1)
221 23f41a3e Michael Hanselmann
        # Ignore these variables, they're overridden by LC_ALL
222 23f41a3e Michael Hanselmann
        if key == "LANG" or key == "LANGUAGE":
223 23f41a3e Michael Hanselmann
          continue
224 23f41a3e Michael Hanselmann
        self.failIf(value and value != "C" and value != '"C"',
225 23f41a3e Michael Hanselmann
            "Variable %s is set to the invalid value '%s'" % (key, value))
226 23f41a3e Michael Hanselmann
    finally:
227 23f41a3e Michael Hanselmann
      os.environ = old_env
228 f6441c7c Iustin Pop
229 8797df43 Iustin Pop
  def testDefaultCwd(self):
230 8797df43 Iustin Pop
    """Test default working directory"""
231 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"]).stdout.strip(), "/")
232 8797df43 Iustin Pop
233 8797df43 Iustin Pop
  def testCwd(self):
234 8797df43 Iustin Pop
    """Test default working directory"""
235 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd="/").stdout.strip(), "/")
236 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd="/tmp").stdout.strip(), "/tmp")
237 8797df43 Iustin Pop
    cwd = os.getcwd()
238 8797df43 Iustin Pop
    self.failUnlessEqual(RunCmd(["pwd"], cwd=cwd).stdout.strip(), cwd)
239 8797df43 Iustin Pop
240 bf4daac9 Guido Trotter
  def testResetEnv(self):
241 bf4daac9 Guido Trotter
    """Test environment reset functionality"""
242 bf4daac9 Guido Trotter
    self.failUnlessEqual(RunCmd(["env"], reset_env=True).stdout.strip(), "")
243 0babc371 Michael Hanselmann
    self.failUnlessEqual(RunCmd(["env"], reset_env=True,
244 0babc371 Michael Hanselmann
                                env={"FOO": "bar",}).stdout.strip(), "FOO=bar")
245 bf4daac9 Guido Trotter
246 a8083063 Iustin Pop
247 6bb65e3a Guido Trotter
class TestRunParts(unittest.TestCase):
248 6bb65e3a Guido Trotter
  """Testing case for the RunParts function"""
249 6bb65e3a Guido Trotter
250 6bb65e3a Guido Trotter
  def setUp(self):
251 6bb65e3a Guido Trotter
    self.rundir = tempfile.mkdtemp(prefix="ganeti-test", suffix=".tmp")
252 6bb65e3a Guido Trotter
253 6bb65e3a Guido Trotter
  def tearDown(self):
254 6bb65e3a Guido Trotter
    shutil.rmtree(self.rundir)
255 6bb65e3a Guido Trotter
256 6bb65e3a Guido Trotter
  def testEmpty(self):
257 6bb65e3a Guido Trotter
    """Test on an empty dir"""
258 6bb65e3a Guido Trotter
    self.failUnlessEqual(RunParts(self.rundir, reset_env=True), [])
259 6bb65e3a Guido Trotter
260 6bb65e3a Guido Trotter
  def testSkipWrongName(self):
261 6bb65e3a Guido Trotter
    """Test that wrong files are skipped"""
262 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test.dot")
263 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="")
264 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
265 6bb65e3a Guido Trotter
    relname = os.path.basename(fname)
266 6bb65e3a Guido Trotter
    self.failUnlessEqual(RunParts(self.rundir, reset_env=True),
267 6bb65e3a Guido Trotter
                         [(relname, constants.RUNPARTS_SKIP, None)])
268 6bb65e3a Guido Trotter
269 6bb65e3a Guido Trotter
  def testSkipNonExec(self):
270 6bb65e3a Guido Trotter
    """Test that non executable files are skipped"""
271 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
272 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="")
273 6bb65e3a Guido Trotter
    relname = os.path.basename(fname)
274 6bb65e3a Guido Trotter
    self.failUnlessEqual(RunParts(self.rundir, reset_env=True),
275 6bb65e3a Guido Trotter
                         [(relname, constants.RUNPARTS_SKIP, None)])
276 6bb65e3a Guido Trotter
277 6bb65e3a Guido Trotter
  def testError(self):
278 6bb65e3a Guido Trotter
    """Test error on a broken executable"""
279 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
280 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="")
281 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
282 6bb65e3a Guido Trotter
    (relname, status, error) = RunParts(self.rundir, reset_env=True)[0]
283 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(fname))
284 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_ERR)
285 6bb65e3a Guido Trotter
    self.failUnless(error)
286 6bb65e3a Guido Trotter
287 6bb65e3a Guido Trotter
  def testSorted(self):
288 6bb65e3a Guido Trotter
    """Test executions are sorted"""
289 6bb65e3a Guido Trotter
    files = []
290 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "64test"))
291 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "00test"))
292 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "42test"))
293 6bb65e3a Guido Trotter
294 6bb65e3a Guido Trotter
    for fname in files:
295 6bb65e3a Guido Trotter
      utils.WriteFile(fname, data="")
296 6bb65e3a Guido Trotter
297 6bb65e3a Guido Trotter
    results = RunParts(self.rundir, reset_env=True)
298 6bb65e3a Guido Trotter
299 6bb65e3a Guido Trotter
    for fname in sorted(files):
300 6bb65e3a Guido Trotter
      self.failUnlessEqual(os.path.basename(fname), results.pop(0)[0])
301 6bb65e3a Guido Trotter
302 6bb65e3a Guido Trotter
  def testOk(self):
303 6bb65e3a Guido Trotter
    """Test correct execution"""
304 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
305 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="#!/bin/sh\n\necho -n ciao")
306 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
307 6bb65e3a Guido Trotter
    (relname, status, runresult) = RunParts(self.rundir, reset_env=True)[0]
308 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(fname))
309 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
310 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.stdout, "ciao")
311 6bb65e3a Guido Trotter
312 6bb65e3a Guido Trotter
  def testRunFail(self):
313 6bb65e3a Guido Trotter
    """Test correct execution, with run failure"""
314 6bb65e3a Guido Trotter
    fname = os.path.join(self.rundir, "00test")
315 6bb65e3a Guido Trotter
    utils.WriteFile(fname, data="#!/bin/sh\n\nexit 1")
316 6bb65e3a Guido Trotter
    os.chmod(fname, stat.S_IREAD | stat.S_IEXEC)
317 6bb65e3a Guido Trotter
    (relname, status, runresult) = RunParts(self.rundir, reset_env=True)[0]
318 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(fname))
319 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
320 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.exit_code, 1)
321 6bb65e3a Guido Trotter
    self.failUnless(runresult.failed)
322 6bb65e3a Guido Trotter
323 6bb65e3a Guido Trotter
  def testRunMix(self):
324 6bb65e3a Guido Trotter
    files = []
325 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "00test"))
326 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "42test"))
327 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "64test"))
328 6bb65e3a Guido Trotter
    files.append(os.path.join(self.rundir, "99test"))
329 6bb65e3a Guido Trotter
330 6bb65e3a Guido Trotter
    files.sort()
331 6bb65e3a Guido Trotter
332 6bb65e3a Guido Trotter
    # 1st has errors in execution
333 6bb65e3a Guido Trotter
    utils.WriteFile(files[0], data="#!/bin/sh\n\nexit 1")
334 6bb65e3a Guido Trotter
    os.chmod(files[0], stat.S_IREAD | stat.S_IEXEC)
335 6bb65e3a Guido Trotter
336 6bb65e3a Guido Trotter
    # 2nd is skipped
337 6bb65e3a Guido Trotter
    utils.WriteFile(files[1], data="")
338 6bb65e3a Guido Trotter
339 6bb65e3a Guido Trotter
    # 3rd cannot execute properly
340 6bb65e3a Guido Trotter
    utils.WriteFile(files[2], data="")
341 6bb65e3a Guido Trotter
    os.chmod(files[2], stat.S_IREAD | stat.S_IEXEC)
342 6bb65e3a Guido Trotter
343 6bb65e3a Guido Trotter
    # 4th execs
344 6bb65e3a Guido Trotter
    utils.WriteFile(files[3], data="#!/bin/sh\n\necho -n ciao")
345 6bb65e3a Guido Trotter
    os.chmod(files[3], stat.S_IREAD | stat.S_IEXEC)
346 6bb65e3a Guido Trotter
347 6bb65e3a Guido Trotter
    results = RunParts(self.rundir, reset_env=True)
348 6bb65e3a Guido Trotter
349 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[0]
350 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[0]))
351 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
352 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.exit_code, 1)
353 6bb65e3a Guido Trotter
    self.failUnless(runresult.failed)
354 6bb65e3a Guido Trotter
355 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[1]
356 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[1]))
357 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_SKIP)
358 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult, None)
359 6bb65e3a Guido Trotter
360 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[2]
361 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[2]))
362 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_ERR)
363 6bb65e3a Guido Trotter
    self.failUnless(runresult)
364 6bb65e3a Guido Trotter
365 6bb65e3a Guido Trotter
    (relname, status, runresult) = results[3]
366 6bb65e3a Guido Trotter
    self.failUnlessEqual(relname, os.path.basename(files[3]))
367 6bb65e3a Guido Trotter
    self.failUnlessEqual(status, constants.RUNPARTS_RUN)
368 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.output, "ciao")
369 6bb65e3a Guido Trotter
    self.failUnlessEqual(runresult.exit_code, 0)
370 6bb65e3a Guido Trotter
    self.failUnless(not runresult.failed)
371 6bb65e3a Guido Trotter
372 6bb65e3a Guido Trotter
373 a8083063 Iustin Pop
class TestRemoveFile(unittest.TestCase):
374 a8083063 Iustin Pop
  """Test case for the RemoveFile function"""
375 a8083063 Iustin Pop
376 a8083063 Iustin Pop
  def setUp(self):
377 a8083063 Iustin Pop
    """Create a temp dir and file for each case"""
378 a8083063 Iustin Pop
    self.tmpdir = tempfile.mkdtemp('', 'ganeti-unittest-')
379 a8083063 Iustin Pop
    fd, self.tmpfile = tempfile.mkstemp('', '', self.tmpdir)
380 a8083063 Iustin Pop
    os.close(fd)
381 a8083063 Iustin Pop
382 a8083063 Iustin Pop
  def tearDown(self):
383 a8083063 Iustin Pop
    if os.path.exists(self.tmpfile):
384 a8083063 Iustin Pop
      os.unlink(self.tmpfile)
385 a8083063 Iustin Pop
    os.rmdir(self.tmpdir)
386 a8083063 Iustin Pop
387 a8083063 Iustin Pop
388 a8083063 Iustin Pop
  def testIgnoreDirs(self):
389 a8083063 Iustin Pop
    """Test that RemoveFile() ignores directories"""
390 a8083063 Iustin Pop
    self.assertEqual(None, RemoveFile(self.tmpdir))
391 a8083063 Iustin Pop
392 a8083063 Iustin Pop
393 a8083063 Iustin Pop
  def testIgnoreNotExisting(self):
394 a8083063 Iustin Pop
    """Test that RemoveFile() ignores non-existing files"""
395 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
396 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
397 a8083063 Iustin Pop
398 a8083063 Iustin Pop
399 a8083063 Iustin Pop
  def testRemoveFile(self):
400 a8083063 Iustin Pop
    """Test that RemoveFile does remove a file"""
401 a8083063 Iustin Pop
    RemoveFile(self.tmpfile)
402 a8083063 Iustin Pop
    if os.path.exists(self.tmpfile):
403 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % self.tmpfile)
404 a8083063 Iustin Pop
405 a8083063 Iustin Pop
406 a8083063 Iustin Pop
  def testRemoveSymlink(self):
407 a8083063 Iustin Pop
    """Test that RemoveFile does remove symlinks"""
408 a8083063 Iustin Pop
    symlink = self.tmpdir + "/symlink"
409 a8083063 Iustin Pop
    os.symlink("no-such-file", symlink)
410 a8083063 Iustin Pop
    RemoveFile(symlink)
411 a8083063 Iustin Pop
    if os.path.exists(symlink):
412 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % symlink)
413 a8083063 Iustin Pop
    os.symlink(self.tmpfile, symlink)
414 a8083063 Iustin Pop
    RemoveFile(symlink)
415 a8083063 Iustin Pop
    if os.path.exists(symlink):
416 a8083063 Iustin Pop
      self.fail("File '%s' not removed" % symlink)
417 a8083063 Iustin Pop
418 a8083063 Iustin Pop
419 6e797216 Michael Hanselmann
class TestRename(unittest.TestCase):
420 6e797216 Michael Hanselmann
  """Test case for RenameFile"""
421 6e797216 Michael Hanselmann
422 6e797216 Michael Hanselmann
  def setUp(self):
423 6e797216 Michael Hanselmann
    """Create a temporary directory"""
424 6e797216 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
425 6e797216 Michael Hanselmann
    self.tmpfile = os.path.join(self.tmpdir, "test1")
426 6e797216 Michael Hanselmann
427 6e797216 Michael Hanselmann
    # Touch the file
428 6e797216 Michael Hanselmann
    open(self.tmpfile, "w").close()
429 6e797216 Michael Hanselmann
430 6e797216 Michael Hanselmann
  def tearDown(self):
431 6e797216 Michael Hanselmann
    """Remove temporary directory"""
432 6e797216 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
433 6e797216 Michael Hanselmann
434 6e797216 Michael Hanselmann
  def testSimpleRename1(self):
435 6e797216 Michael Hanselmann
    """Simple rename 1"""
436 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"))
437 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "xyz")))
438 6e797216 Michael Hanselmann
439 6e797216 Michael Hanselmann
  def testSimpleRename2(self):
440 6e797216 Michael Hanselmann
    """Simple rename 2"""
441 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"),
442 6e797216 Michael Hanselmann
                     mkdir=True)
443 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "xyz")))
444 6e797216 Michael Hanselmann
445 6e797216 Michael Hanselmann
  def testRenameMkdir(self):
446 6e797216 Michael Hanselmann
    """Rename with mkdir"""
447 6e797216 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "test/xyz"),
448 6e797216 Michael Hanselmann
                     mkdir=True)
449 a426508d Michael Hanselmann
    self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test")))
450 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "test/xyz")))
451 a426508d Michael Hanselmann
452 a426508d Michael Hanselmann
    utils.RenameFile(os.path.join(self.tmpdir, "test/xyz"),
453 a426508d Michael Hanselmann
                     os.path.join(self.tmpdir, "test/foo/bar/baz"),
454 a426508d Michael Hanselmann
                     mkdir=True)
455 a426508d Michael Hanselmann
    self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test")))
456 a426508d Michael Hanselmann
    self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test/foo/bar")))
457 a426508d Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "test/foo/bar/baz")))
458 6e797216 Michael Hanselmann
459 6e797216 Michael Hanselmann
460 a8083063 Iustin Pop
class TestMatchNameComponent(unittest.TestCase):
461 a8083063 Iustin Pop
  """Test case for the MatchNameComponent function"""
462 a8083063 Iustin Pop
463 a8083063 Iustin Pop
  def testEmptyList(self):
464 a8083063 Iustin Pop
    """Test that there is no match against an empty list"""
465 a8083063 Iustin Pop
466 a8083063 Iustin Pop
    self.failUnlessEqual(MatchNameComponent("", []), None)
467 a8083063 Iustin Pop
    self.failUnlessEqual(MatchNameComponent("test", []), None)
468 a8083063 Iustin Pop
469 a8083063 Iustin Pop
  def testSingleMatch(self):
470 a8083063 Iustin Pop
    """Test that a single match is performed correctly"""
471 a8083063 Iustin Pop
    mlist = ["test1.example.com", "test2.example.com", "test3.example.com"]
472 a8083063 Iustin Pop
    for key in "test2", "test2.example", "test2.example.com":
473 a8083063 Iustin Pop
      self.failUnlessEqual(MatchNameComponent(key, mlist), mlist[1])
474 a8083063 Iustin Pop
475 a8083063 Iustin Pop
  def testMultipleMatches(self):
476 a8083063 Iustin Pop
    """Test that a multiple match is returned as None"""
477 a8083063 Iustin Pop
    mlist = ["test1.example.com", "test1.example.org", "test1.example.net"]
478 a8083063 Iustin Pop
    for key in "test1", "test1.example":
479 a8083063 Iustin Pop
      self.failUnlessEqual(MatchNameComponent(key, mlist), None)
480 a8083063 Iustin Pop
481 3a541d90 Iustin Pop
  def testFullMatch(self):
482 3a541d90 Iustin Pop
    """Test that a full match is returned correctly"""
483 3a541d90 Iustin Pop
    key1 = "test1"
484 3a541d90 Iustin Pop
    key2 = "test1.example"
485 3a541d90 Iustin Pop
    mlist = [key2, key2 + ".com"]
486 3a541d90 Iustin Pop
    self.failUnlessEqual(MatchNameComponent(key1, mlist), None)
487 3a541d90 Iustin Pop
    self.failUnlessEqual(MatchNameComponent(key2, mlist), key2)
488 3a541d90 Iustin Pop
489 256eb94b Guido Trotter
  def testCaseInsensitivePartialMatch(self):
490 256eb94b Guido Trotter
    """Test for the case_insensitive keyword"""
491 256eb94b Guido Trotter
    mlist = ["test1.example.com", "test2.example.net"]
492 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("test2", mlist, case_sensitive=False),
493 256eb94b Guido Trotter
                     "test2.example.net")
494 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Test2", mlist, case_sensitive=False),
495 256eb94b Guido Trotter
                     "test2.example.net")
496 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("teSt2", mlist, case_sensitive=False),
497 256eb94b Guido Trotter
                     "test2.example.net")
498 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("TeSt2", mlist, case_sensitive=False),
499 256eb94b Guido Trotter
                     "test2.example.net")
500 256eb94b Guido Trotter
501 256eb94b Guido Trotter
502 256eb94b Guido Trotter
  def testCaseInsensitiveFullMatch(self):
503 256eb94b Guido Trotter
    mlist = ["ts1.ex", "ts1.ex.org", "ts2.ex", "Ts2.ex"]
504 256eb94b Guido Trotter
    # Between the two ts1 a full string match non-case insensitive should work
505 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Ts1", mlist, case_sensitive=False),
506 256eb94b Guido Trotter
                     None)
507 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Ts1.ex", mlist, case_sensitive=False),
508 256eb94b Guido Trotter
                     "ts1.ex")
509 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("ts1.ex", mlist, case_sensitive=False),
510 256eb94b Guido Trotter
                     "ts1.ex")
511 256eb94b Guido Trotter
    # Between the two ts2 only case differs, so only case-match works
512 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("ts2.ex", mlist, case_sensitive=False),
513 256eb94b Guido Trotter
                     "ts2.ex")
514 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("Ts2.ex", mlist, case_sensitive=False),
515 256eb94b Guido Trotter
                     "Ts2.ex")
516 256eb94b Guido Trotter
    self.assertEqual(MatchNameComponent("TS2.ex", mlist, case_sensitive=False),
517 256eb94b Guido Trotter
                     None)
518 256eb94b Guido Trotter
519 a8083063 Iustin Pop
520 b774bb10 Michael Hanselmann
class TestReadFile(testutils.GanetiTestCase):
521 b774bb10 Michael Hanselmann
522 b774bb10 Michael Hanselmann
  def testReadAll(self):
523 b774bb10 Michael Hanselmann
    data = utils.ReadFile(self._TestDataFilename("cert1.pem"))
524 b774bb10 Michael Hanselmann
    self.assertEqual(len(data), 814)
525 b774bb10 Michael Hanselmann
526 b774bb10 Michael Hanselmann
    h = md5.new()
527 b774bb10 Michael Hanselmann
    h.update(data)
528 b774bb10 Michael Hanselmann
    self.assertEqual(h.hexdigest(), "a491efb3efe56a0535f924d5f8680fd4")
529 b774bb10 Michael Hanselmann
530 b774bb10 Michael Hanselmann
  def testReadSize(self):
531 b774bb10 Michael Hanselmann
    data = utils.ReadFile(self._TestDataFilename("cert1.pem"),
532 b774bb10 Michael Hanselmann
                          size=100)
533 b774bb10 Michael Hanselmann
    self.assertEqual(len(data), 100)
534 b774bb10 Michael Hanselmann
535 b774bb10 Michael Hanselmann
    h = md5.new()
536 b774bb10 Michael Hanselmann
    h.update(data)
537 b774bb10 Michael Hanselmann
    self.assertEqual(h.hexdigest(), "893772354e4e690b9efd073eed433ce7")
538 b774bb10 Michael Hanselmann
539 b774bb10 Michael Hanselmann
  def testError(self):
540 b774bb10 Michael Hanselmann
    self.assertRaises(EnvironmentError, utils.ReadFile,
541 582ed043 Guido Trotter
                      "/dev/null/does-not-exist")
542 b774bb10 Michael Hanselmann
543 b774bb10 Michael Hanselmann
544 e587b46a Guido Trotter
class TestReadOneLineFile(testutils.GanetiTestCase):
545 e587b46a Guido Trotter
546 e587b46a Guido Trotter
  def setUp(self):
547 e587b46a Guido Trotter
    testutils.GanetiTestCase.setUp(self)
548 e587b46a Guido Trotter
549 e587b46a Guido Trotter
  def testDefault(self):
550 e587b46a Guido Trotter
    data = ReadOneLineFile(self._TestDataFilename("cert1.pem"))
551 e587b46a Guido Trotter
    self.assertEqual(len(data), 27)
552 e587b46a Guido Trotter
    self.assertEqual(data, "-----BEGIN CERTIFICATE-----")
553 e587b46a Guido Trotter
554 e587b46a Guido Trotter
  def testNotStrict(self):
555 e587b46a Guido Trotter
    data = ReadOneLineFile(self._TestDataFilename("cert1.pem"), strict=False)
556 e587b46a Guido Trotter
    self.assertEqual(len(data), 27)
557 e587b46a Guido Trotter
    self.assertEqual(data, "-----BEGIN CERTIFICATE-----")
558 e587b46a Guido Trotter
559 e587b46a Guido Trotter
  def testStrictFailure(self):
560 e587b46a Guido Trotter
    self.assertRaises(errors.GenericError, ReadOneLineFile,
561 e587b46a Guido Trotter
                      self._TestDataFilename("cert1.pem"), strict=True)
562 e587b46a Guido Trotter
563 e587b46a Guido Trotter
  def testLongLine(self):
564 e587b46a Guido Trotter
    dummydata = (1024 * "Hello World! ")
565 e587b46a Guido Trotter
    myfile = self._CreateTempFile()
566 e587b46a Guido Trotter
    utils.WriteFile(myfile, data=dummydata)
567 e587b46a Guido Trotter
    datastrict = ReadOneLineFile(myfile, strict=True)
568 e587b46a Guido Trotter
    datalax = ReadOneLineFile(myfile, strict=False)
569 e587b46a Guido Trotter
    self.assertEqual(dummydata, datastrict)
570 e587b46a Guido Trotter
    self.assertEqual(dummydata, datalax)
571 e587b46a Guido Trotter
572 e587b46a Guido Trotter
  def testNewline(self):
573 e587b46a Guido Trotter
    myfile = self._CreateTempFile()
574 e587b46a Guido Trotter
    myline = "myline"
575 e587b46a Guido Trotter
    for nl in ["", "\n", "\r\n"]:
576 e587b46a Guido Trotter
      dummydata = "%s%s" % (myline, nl)
577 e587b46a Guido Trotter
      utils.WriteFile(myfile, data=dummydata)
578 e587b46a Guido Trotter
      datalax = ReadOneLineFile(myfile, strict=False)
579 e587b46a Guido Trotter
      self.assertEqual(myline, datalax)
580 e587b46a Guido Trotter
      datastrict = ReadOneLineFile(myfile, strict=True)
581 e587b46a Guido Trotter
      self.assertEqual(myline, datastrict)
582 e587b46a Guido Trotter
583 e587b46a Guido Trotter
  def testWhitespaceAndMultipleLines(self):
584 e587b46a Guido Trotter
    myfile = self._CreateTempFile()
585 e587b46a Guido Trotter
    for nl in ["", "\n", "\r\n"]:
586 e587b46a Guido Trotter
      for ws in [" ", "\t", "\t\t  \t", "\t "]:
587 e587b46a Guido Trotter
        dummydata = (1024 * ("Foo bar baz %s%s" % (ws, nl)))
588 e587b46a Guido Trotter
        utils.WriteFile(myfile, data=dummydata)
589 e587b46a Guido Trotter
        datalax = ReadOneLineFile(myfile, strict=False)
590 e587b46a Guido Trotter
        if nl:
591 e587b46a Guido Trotter
          self.assert_(set("\r\n") & set(dummydata))
592 e587b46a Guido Trotter
          self.assertRaises(errors.GenericError, ReadOneLineFile,
593 e587b46a Guido Trotter
                            myfile, strict=True)
594 e587b46a Guido Trotter
          explen = len("Foo bar baz ") + len(ws)
595 e587b46a Guido Trotter
          self.assertEqual(len(datalax), explen)
596 e587b46a Guido Trotter
          self.assertEqual(datalax, dummydata[:explen])
597 e587b46a Guido Trotter
          self.assertFalse(set("\r\n") & set(datalax))
598 e587b46a Guido Trotter
        else:
599 e587b46a Guido Trotter
          datastrict = ReadOneLineFile(myfile, strict=True)
600 e587b46a Guido Trotter
          self.assertEqual(dummydata, datastrict)
601 e587b46a Guido Trotter
          self.assertEqual(dummydata, datalax)
602 e587b46a Guido Trotter
603 e587b46a Guido Trotter
  def testEmptylines(self):
604 e587b46a Guido Trotter
    myfile = self._CreateTempFile()
605 e587b46a Guido Trotter
    myline = "myline"
606 e587b46a Guido Trotter
    for nl in ["\n", "\r\n"]:
607 e587b46a Guido Trotter
      for ol in ["", "otherline"]:
608 e587b46a Guido Trotter
        dummydata = "%s%s%s%s%s%s" % (nl, nl, myline, nl, ol, nl)
609 e587b46a Guido Trotter
        utils.WriteFile(myfile, data=dummydata)
610 e587b46a Guido Trotter
        self.assert_(set("\r\n") & set(dummydata))
611 e587b46a Guido Trotter
        datalax = ReadOneLineFile(myfile, strict=False)
612 e587b46a Guido Trotter
        self.assertEqual(myline, datalax)
613 e587b46a Guido Trotter
        if ol:
614 e587b46a Guido Trotter
          self.assertRaises(errors.GenericError, ReadOneLineFile,
615 e587b46a Guido Trotter
                            myfile, strict=True)
616 e587b46a Guido Trotter
        else:
617 e587b46a Guido Trotter
          datastrict = ReadOneLineFile(myfile, strict=True)
618 e587b46a Guido Trotter
          self.assertEqual(myline, datastrict)
619 e587b46a Guido Trotter
620 e587b46a Guido Trotter
621 1d466a4f Michael Hanselmann
class TestTimestampForFilename(unittest.TestCase):
622 1d466a4f Michael Hanselmann
  def test(self):
623 1d466a4f Michael Hanselmann
    self.assert_("." not in utils.TimestampForFilename())
624 1d466a4f Michael Hanselmann
    self.assert_(":" not in utils.TimestampForFilename())
625 1d466a4f Michael Hanselmann
626 1d466a4f Michael Hanselmann
627 1d466a4f Michael Hanselmann
class TestCreateBackup(testutils.GanetiTestCase):
628 1d466a4f Michael Hanselmann
  def setUp(self):
629 1d466a4f Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
630 1d466a4f Michael Hanselmann
631 1d466a4f Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
632 1d466a4f Michael Hanselmann
633 1d466a4f Michael Hanselmann
  def tearDown(self):
634 1d466a4f Michael Hanselmann
    testutils.GanetiTestCase.tearDown(self)
635 1d466a4f Michael Hanselmann
636 1d466a4f Michael Hanselmann
    shutil.rmtree(self.tmpdir)
637 1d466a4f Michael Hanselmann
638 1d466a4f Michael Hanselmann
  def testEmpty(self):
639 1d466a4f Michael Hanselmann
    filename = utils.PathJoin(self.tmpdir, "config.data")
640 1d466a4f Michael Hanselmann
    utils.WriteFile(filename, data="")
641 1d466a4f Michael Hanselmann
    bname = utils.CreateBackup(filename)
642 1d466a4f Michael Hanselmann
    self.assertFileContent(bname, "")
643 1d466a4f Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 2)
644 1d466a4f Michael Hanselmann
    utils.CreateBackup(filename)
645 1d466a4f Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 3)
646 1d466a4f Michael Hanselmann
    utils.CreateBackup(filename)
647 1d466a4f Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 4)
648 1d466a4f Michael Hanselmann
649 1d466a4f Michael Hanselmann
    fifoname = utils.PathJoin(self.tmpdir, "fifo")
650 1d466a4f Michael Hanselmann
    os.mkfifo(fifoname)
651 1d466a4f Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, utils.CreateBackup, fifoname)
652 1d466a4f Michael Hanselmann
653 1d466a4f Michael Hanselmann
  def testContent(self):
654 1d466a4f Michael Hanselmann
    bkpcount = 0
655 1d466a4f Michael Hanselmann
    for data in ["", "X", "Hello World!\n" * 100, "Binary data\0\x01\x02\n"]:
656 1d466a4f Michael Hanselmann
      for rep in [1, 2, 10, 127]:
657 1d466a4f Michael Hanselmann
        testdata = data * rep
658 1d466a4f Michael Hanselmann
659 1d466a4f Michael Hanselmann
        filename = utils.PathJoin(self.tmpdir, "test.data_")
660 1d466a4f Michael Hanselmann
        utils.WriteFile(filename, data=testdata)
661 1d466a4f Michael Hanselmann
        self.assertFileContent(filename, testdata)
662 1d466a4f Michael Hanselmann
663 1d466a4f Michael Hanselmann
        for _ in range(3):
664 1d466a4f Michael Hanselmann
          bname = utils.CreateBackup(filename)
665 1d466a4f Michael Hanselmann
          bkpcount += 1
666 1d466a4f Michael Hanselmann
          self.assertFileContent(bname, testdata)
667 1d466a4f Michael Hanselmann
          self.assertEqual(len(glob.glob("%s*" % filename)), 1 + bkpcount)
668 1d466a4f Michael Hanselmann
669 1d466a4f Michael Hanselmann
670 a8083063 Iustin Pop
class TestFormatUnit(unittest.TestCase):
671 a8083063 Iustin Pop
  """Test case for the FormatUnit function"""
672 a8083063 Iustin Pop
673 a8083063 Iustin Pop
  def testMiB(self):
674 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1, 'h'), '1M')
675 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(100, 'h'), '100M')
676 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1023, 'h'), '1023M')
677 9fbfbb7b Iustin Pop
678 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1, 'm'), '1')
679 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(100, 'm'), '100')
680 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1023, 'm'), '1023')
681 9fbfbb7b Iustin Pop
682 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'm'), '1024')
683 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'm'), '1536')
684 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'm'), '17133')
685 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'm'), '1048575')
686 a8083063 Iustin Pop
687 a8083063 Iustin Pop
  def testGiB(self):
688 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'h'), '1.0G')
689 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'h'), '1.5G')
690 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'h'), '16.7G')
691 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'h'), '1024.0G')
692 9fbfbb7b Iustin Pop
693 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024, 'g'), '1.0')
694 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1536, 'g'), '1.5')
695 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(17133, 'g'), '16.7')
696 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024 - 1, 'g'), '1024.0')
697 9fbfbb7b Iustin Pop
698 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 'g'), '1024.0')
699 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 'g'), '5120.0')
700 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 'g'), '29829.0')
701 a8083063 Iustin Pop
702 a8083063 Iustin Pop
  def testTiB(self):
703 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 'h'), '1.0T')
704 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 'h'), '5.0T')
705 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 'h'), '29.1T')
706 a8083063 Iustin Pop
707 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(1024 * 1024, 't'), '1.0')
708 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(5120 * 1024, 't'), '5.0')
709 9fbfbb7b Iustin Pop
    self.assertEqual(FormatUnit(29829 * 1024, 't'), '29.1')
710 a8083063 Iustin Pop
711 a8083063 Iustin Pop
class TestParseUnit(unittest.TestCase):
712 a8083063 Iustin Pop
  """Test case for the ParseUnit function"""
713 a8083063 Iustin Pop
714 a8083063 Iustin Pop
  SCALES = (('', 1),
715 a8083063 Iustin Pop
            ('M', 1), ('G', 1024), ('T', 1024 * 1024),
716 a8083063 Iustin Pop
            ('MB', 1), ('GB', 1024), ('TB', 1024 * 1024),
717 a8083063 Iustin Pop
            ('MiB', 1), ('GiB', 1024), ('TiB', 1024 * 1024))
718 a8083063 Iustin Pop
719 a8083063 Iustin Pop
  def testRounding(self):
720 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0'), 0)
721 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1'), 4)
722 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2'), 4)
723 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('3'), 4)
724 a8083063 Iustin Pop
725 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('124'), 124)
726 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('125'), 128)
727 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('126'), 128)
728 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('127'), 128)
729 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('128'), 128)
730 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('129'), 132)
731 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('130'), 132)
732 a8083063 Iustin Pop
733 a8083063 Iustin Pop
  def testFloating(self):
734 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0'), 0)
735 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('0.5'), 4)
736 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.75'), 4)
737 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.99'), 4)
738 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2.00'), 4)
739 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('2.01'), 4)
740 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('3.99'), 4)
741 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('4.00'), 4)
742 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('4.01'), 8)
743 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.5G'), 1536)
744 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('1.8G'), 1844)
745 a8083063 Iustin Pop
    self.assertEqual(ParseUnit('8.28T'), 8682212)
746 a8083063 Iustin Pop
747 a8083063 Iustin Pop
  def testSuffixes(self):
748 a8083063 Iustin Pop
    for sep in ('', ' ', '   ', "\t", "\t "):
749 a8083063 Iustin Pop
      for suffix, scale in TestParseUnit.SCALES:
750 a8083063 Iustin Pop
        for func in (lambda x: x, str.lower, str.upper):
751 667479d5 Michael Hanselmann
          self.assertEqual(ParseUnit('1024' + sep + func(suffix)),
752 667479d5 Michael Hanselmann
                           1024 * scale)
753 a8083063 Iustin Pop
754 a8083063 Iustin Pop
  def testInvalidInput(self):
755 a8083063 Iustin Pop
    for sep in ('-', '_', ',', 'a'):
756 a8083063 Iustin Pop
      for suffix, _ in TestParseUnit.SCALES:
757 a8083063 Iustin Pop
        self.assertRaises(UnitParseError, ParseUnit, '1' + sep + suffix)
758 a8083063 Iustin Pop
759 a8083063 Iustin Pop
    for suffix, _ in TestParseUnit.SCALES:
760 a8083063 Iustin Pop
      self.assertRaises(UnitParseError, ParseUnit, '1,3' + suffix)
761 a8083063 Iustin Pop
762 a8083063 Iustin Pop
763 c9c4f19e Michael Hanselmann
class TestSshKeys(testutils.GanetiTestCase):
764 a8083063 Iustin Pop
  """Test case for the AddAuthorizedKey function"""
765 a8083063 Iustin Pop
766 a8083063 Iustin Pop
  KEY_A = 'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a'
767 a8083063 Iustin Pop
  KEY_B = ('command="/usr/bin/fooserver -t --verbose",from="1.2.3.4" '
768 a8083063 Iustin Pop
           'ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b')
769 a8083063 Iustin Pop
770 ebe8ef17 Michael Hanselmann
  def setUp(self):
771 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
772 51596eb2 Iustin Pop
    self.tmpname = self._CreateTempFile()
773 51596eb2 Iustin Pop
    handle = open(self.tmpname, 'w')
774 a8083063 Iustin Pop
    try:
775 51596eb2 Iustin Pop
      handle.write("%s\n" % TestSshKeys.KEY_A)
776 51596eb2 Iustin Pop
      handle.write("%s\n" % TestSshKeys.KEY_B)
777 51596eb2 Iustin Pop
    finally:
778 51596eb2 Iustin Pop
      handle.close()
779 a8083063 Iustin Pop
780 a8083063 Iustin Pop
  def testAddingNewKey(self):
781 ebe8ef17 Michael Hanselmann
    AddAuthorizedKey(self.tmpname, 'ssh-dss AAAAB3NzaC1kc3MAAACB root@test')
782 a8083063 Iustin Pop
783 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
784 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
785 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
786 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
787 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1kc3MAAACB root@test\n")
788 a8083063 Iustin Pop
789 f89f17a8 Michael Hanselmann
  def testAddingAlmostButNotCompletelyTheSameKey(self):
790 ebe8ef17 Michael Hanselmann
    AddAuthorizedKey(self.tmpname,
791 ebe8ef17 Michael Hanselmann
        'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test')
792 ebe8ef17 Michael Hanselmann
793 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
794 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
795 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
796 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
797 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test\n")
798 a8083063 Iustin Pop
799 a8083063 Iustin Pop
  def testAddingExistingKeyWithSomeMoreSpaces(self):
800 ebe8ef17 Michael Hanselmann
    AddAuthorizedKey(self.tmpname,
801 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
802 a8083063 Iustin Pop
803 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
804 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
805 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
806 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
807 a8083063 Iustin Pop
808 a8083063 Iustin Pop
  def testRemovingExistingKeyWithSomeMoreSpaces(self):
809 ebe8ef17 Michael Hanselmann
    RemoveAuthorizedKey(self.tmpname,
810 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
811 a8083063 Iustin Pop
812 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
813 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
814 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
815 a8083063 Iustin Pop
816 a8083063 Iustin Pop
  def testRemovingNonExistingKey(self):
817 ebe8ef17 Michael Hanselmann
    RemoveAuthorizedKey(self.tmpname,
818 ebe8ef17 Michael Hanselmann
        'ssh-dss  AAAAB3Nsdfj230xxjxJjsjwjsjdjU   root@test')
819 a8083063 Iustin Pop
820 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
821 ebe8ef17 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
822 ebe8ef17 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="1.2.3.4"'
823 ebe8ef17 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
824 a8083063 Iustin Pop
825 a8083063 Iustin Pop
826 c9c4f19e Michael Hanselmann
class TestEtcHosts(testutils.GanetiTestCase):
827 899d2a81 Michael Hanselmann
  """Test functions modifying /etc/hosts"""
828 899d2a81 Michael Hanselmann
829 ebe8ef17 Michael Hanselmann
  def setUp(self):
830 51596eb2 Iustin Pop
    testutils.GanetiTestCase.setUp(self)
831 51596eb2 Iustin Pop
    self.tmpname = self._CreateTempFile()
832 51596eb2 Iustin Pop
    handle = open(self.tmpname, 'w')
833 899d2a81 Michael Hanselmann
    try:
834 51596eb2 Iustin Pop
      handle.write('# This is a test file for /etc/hosts\n')
835 51596eb2 Iustin Pop
      handle.write('127.0.0.1\tlocalhost\n')
836 51596eb2 Iustin Pop
      handle.write('192.168.1.1 router gw\n')
837 51596eb2 Iustin Pop
    finally:
838 51596eb2 Iustin Pop
      handle.close()
839 899d2a81 Michael Hanselmann
840 9440aeab Michael Hanselmann
  def testSettingNewIp(self):
841 ebe8ef17 Michael Hanselmann
    SetEtcHostsEntry(self.tmpname, '1.2.3.4', 'myhost.domain.tld', ['myhost'])
842 899d2a81 Michael Hanselmann
843 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
844 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
845 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
846 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router gw\n"
847 ebe8ef17 Michael Hanselmann
      "1.2.3.4\tmyhost.domain.tld myhost\n")
848 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
849 899d2a81 Michael Hanselmann
850 9440aeab Michael Hanselmann
  def testSettingExistingIp(self):
851 ebe8ef17 Michael Hanselmann
    SetEtcHostsEntry(self.tmpname, '192.168.1.1', 'myhost.domain.tld',
852 ebe8ef17 Michael Hanselmann
                     ['myhost'])
853 899d2a81 Michael Hanselmann
854 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
855 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
856 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
857 ebe8ef17 Michael Hanselmann
      "192.168.1.1\tmyhost.domain.tld myhost\n")
858 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
859 899d2a81 Michael Hanselmann
860 7fbb1f65 Michael Hanselmann
  def testSettingDuplicateName(self):
861 7fbb1f65 Michael Hanselmann
    SetEtcHostsEntry(self.tmpname, '1.2.3.4', 'myhost', ['myhost'])
862 7fbb1f65 Michael Hanselmann
863 7fbb1f65 Michael Hanselmann
    self.assertFileContent(self.tmpname,
864 7fbb1f65 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
865 7fbb1f65 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
866 7fbb1f65 Michael Hanselmann
      "192.168.1.1 router gw\n"
867 7fbb1f65 Michael Hanselmann
      "1.2.3.4\tmyhost\n")
868 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
869 7fbb1f65 Michael Hanselmann
870 899d2a81 Michael Hanselmann
  def testRemovingExistingHost(self):
871 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'router')
872 899d2a81 Michael Hanselmann
873 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
874 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
875 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
876 ebe8ef17 Michael Hanselmann
      "192.168.1.1 gw\n")
877 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
878 899d2a81 Michael Hanselmann
879 899d2a81 Michael Hanselmann
  def testRemovingSingleExistingHost(self):
880 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'localhost')
881 899d2a81 Michael Hanselmann
882 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
883 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
884 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router gw\n")
885 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
886 899d2a81 Michael Hanselmann
887 899d2a81 Michael Hanselmann
  def testRemovingNonExistingHost(self):
888 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'myhost')
889 899d2a81 Michael Hanselmann
890 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
891 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
892 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
893 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router gw\n")
894 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
895 899d2a81 Michael Hanselmann
896 9440aeab Michael Hanselmann
  def testRemovingAlias(self):
897 ebe8ef17 Michael Hanselmann
    RemoveEtcHostsEntry(self.tmpname, 'gw')
898 9440aeab Michael Hanselmann
899 ebe8ef17 Michael Hanselmann
    self.assertFileContent(self.tmpname,
900 ebe8ef17 Michael Hanselmann
      "# This is a test file for /etc/hosts\n"
901 ebe8ef17 Michael Hanselmann
      "127.0.0.1\tlocalhost\n"
902 ebe8ef17 Michael Hanselmann
      "192.168.1.1 router\n")
903 9b977740 Guido Trotter
    self.assertFileMode(self.tmpname, 0644)
904 9440aeab Michael Hanselmann
905 899d2a81 Michael Hanselmann
906 a8083063 Iustin Pop
class TestShellQuoting(unittest.TestCase):
907 a8083063 Iustin Pop
  """Test case for shell quoting functions"""
908 a8083063 Iustin Pop
909 a8083063 Iustin Pop
  def testShellQuote(self):
910 a8083063 Iustin Pop
    self.assertEqual(ShellQuote('abc'), "abc")
911 a8083063 Iustin Pop
    self.assertEqual(ShellQuote('ab"c'), "'ab\"c'")
912 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a'bc"), "'a'\\''bc'")
913 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a b c"), "'a b c'")
914 a8083063 Iustin Pop
    self.assertEqual(ShellQuote("a b\\ c"), "'a b\\ c'")
915 a8083063 Iustin Pop
916 a8083063 Iustin Pop
  def testShellQuoteArgs(self):
917 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b', 'c']), "a b c")
918 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b"', 'c']), "a 'b\"' c")
919 a8083063 Iustin Pop
    self.assertEqual(ShellQuoteArgs(['a', 'b\'', 'c']), "a 'b'\\\''' c")
920 a8083063 Iustin Pop
921 a8083063 Iustin Pop
922 2c30e9d7 Alexander Schreiber
class TestTcpPing(unittest.TestCase):
923 2c30e9d7 Alexander Schreiber
  """Testcase for TCP version of ping - against listen(2)ing port"""
924 2c30e9d7 Alexander Schreiber
925 2c30e9d7 Alexander Schreiber
  def setUp(self):
926 2c30e9d7 Alexander Schreiber
    self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
927 16abfbc2 Alexander Schreiber
    self.listener.bind((constants.LOCALHOST_IP_ADDRESS, 0))
928 2c30e9d7 Alexander Schreiber
    self.listenerport = self.listener.getsockname()[1]
929 2c30e9d7 Alexander Schreiber
    self.listener.listen(1)
930 2c30e9d7 Alexander Schreiber
931 2c30e9d7 Alexander Schreiber
  def tearDown(self):
932 2c30e9d7 Alexander Schreiber
    self.listener.shutdown(socket.SHUT_RDWR)
933 2c30e9d7 Alexander Schreiber
    del self.listener
934 2c30e9d7 Alexander Schreiber
    del self.listenerport
935 2c30e9d7 Alexander Schreiber
936 2c30e9d7 Alexander Schreiber
  def testTcpPingToLocalHostAccept(self):
937 16abfbc2 Alexander Schreiber
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
938 2c30e9d7 Alexander Schreiber
                         self.listenerport,
939 2c30e9d7 Alexander Schreiber
                         timeout=10,
940 b15d625f Iustin Pop
                         live_port_needed=True,
941 b15d625f Iustin Pop
                         source=constants.LOCALHOST_IP_ADDRESS,
942 b15d625f Iustin Pop
                         ),
943 2c30e9d7 Alexander Schreiber
                 "failed to connect to test listener")
944 2c30e9d7 Alexander Schreiber
945 b15d625f Iustin Pop
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
946 b15d625f Iustin Pop
                         self.listenerport,
947 b15d625f Iustin Pop
                         timeout=10,
948 b15d625f Iustin Pop
                         live_port_needed=True,
949 b15d625f Iustin Pop
                         ),
950 b15d625f Iustin Pop
                 "failed to connect to test listener (no source)")
951 b15d625f Iustin Pop
952 2c30e9d7 Alexander Schreiber
953 2c30e9d7 Alexander Schreiber
class TestTcpPingDeaf(unittest.TestCase):
954 2c30e9d7 Alexander Schreiber
  """Testcase for TCP version of ping - against non listen(2)ing port"""
955 2c30e9d7 Alexander Schreiber
956 2c30e9d7 Alexander Schreiber
  def setUp(self):
957 2c30e9d7 Alexander Schreiber
    self.deaflistener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
958 16abfbc2 Alexander Schreiber
    self.deaflistener.bind((constants.LOCALHOST_IP_ADDRESS, 0))
959 2c30e9d7 Alexander Schreiber
    self.deaflistenerport = self.deaflistener.getsockname()[1]
960 2c30e9d7 Alexander Schreiber
961 2c30e9d7 Alexander Schreiber
  def tearDown(self):
962 2c30e9d7 Alexander Schreiber
    del self.deaflistener
963 2c30e9d7 Alexander Schreiber
    del self.deaflistenerport
964 2c30e9d7 Alexander Schreiber
965 2c30e9d7 Alexander Schreiber
  def testTcpPingToLocalHostAcceptDeaf(self):
966 16abfbc2 Alexander Schreiber
    self.failIf(TcpPing(constants.LOCALHOST_IP_ADDRESS,
967 2c30e9d7 Alexander Schreiber
                        self.deaflistenerport,
968 16abfbc2 Alexander Schreiber
                        timeout=constants.TCP_PING_TIMEOUT,
969 b15d625f Iustin Pop
                        live_port_needed=True,
970 b15d625f Iustin Pop
                        source=constants.LOCALHOST_IP_ADDRESS,
971 b15d625f Iustin Pop
                        ), # need successful connect(2)
972 2c30e9d7 Alexander Schreiber
                "successfully connected to deaf listener")
973 2c30e9d7 Alexander Schreiber
974 b15d625f Iustin Pop
    self.failIf(TcpPing(constants.LOCALHOST_IP_ADDRESS,
975 b15d625f Iustin Pop
                        self.deaflistenerport,
976 b15d625f Iustin Pop
                        timeout=constants.TCP_PING_TIMEOUT,
977 b15d625f Iustin Pop
                        live_port_needed=True,
978 b15d625f Iustin Pop
                        ), # need successful connect(2)
979 b15d625f Iustin Pop
                "successfully connected to deaf listener (no source addr)")
980 b15d625f Iustin Pop
981 2c30e9d7 Alexander Schreiber
  def testTcpPingToLocalHostNoAccept(self):
982 16abfbc2 Alexander Schreiber
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
983 2c30e9d7 Alexander Schreiber
                         self.deaflistenerport,
984 16abfbc2 Alexander Schreiber
                         timeout=constants.TCP_PING_TIMEOUT,
985 b15d625f Iustin Pop
                         live_port_needed=False,
986 b15d625f Iustin Pop
                         source=constants.LOCALHOST_IP_ADDRESS,
987 b15d625f Iustin Pop
                         ), # ECONNREFUSED is OK
988 2c30e9d7 Alexander Schreiber
                 "failed to ping alive host on deaf port")
989 2c30e9d7 Alexander Schreiber
990 b15d625f Iustin Pop
    self.assert_(TcpPing(constants.LOCALHOST_IP_ADDRESS,
991 b15d625f Iustin Pop
                         self.deaflistenerport,
992 b15d625f Iustin Pop
                         timeout=constants.TCP_PING_TIMEOUT,
993 b15d625f Iustin Pop
                         live_port_needed=False,
994 b15d625f Iustin Pop
                         ), # ECONNREFUSED is OK
995 b15d625f Iustin Pop
                 "failed to ping alive host on deaf port (no source addr)")
996 b15d625f Iustin Pop
997 2c30e9d7 Alexander Schreiber
998 caad16e2 Iustin Pop
class TestOwnIpAddress(unittest.TestCase):
999 caad16e2 Iustin Pop
  """Testcase for OwnIpAddress"""
1000 caad16e2 Iustin Pop
1001 caad16e2 Iustin Pop
  def testOwnLoopback(self):
1002 caad16e2 Iustin Pop
    """check having the loopback ip"""
1003 caad16e2 Iustin Pop
    self.failUnless(OwnIpAddress(constants.LOCALHOST_IP_ADDRESS),
1004 caad16e2 Iustin Pop
                    "Should own the loopback address")
1005 caad16e2 Iustin Pop
1006 caad16e2 Iustin Pop
  def testNowOwnAddress(self):
1007 caad16e2 Iustin Pop
    """check that I don't own an address"""
1008 caad16e2 Iustin Pop
1009 caad16e2 Iustin Pop
    # network 192.0.2.0/24 is reserved for test/documentation as per
1010 caad16e2 Iustin Pop
    # rfc 3330, so we *should* not have an address of this range... if
1011 caad16e2 Iustin Pop
    # this fails, we should extend the test to multiple addresses
1012 caad16e2 Iustin Pop
    DST_IP = "192.0.2.1"
1013 caad16e2 Iustin Pop
    self.failIf(OwnIpAddress(DST_IP), "Should not own IP address %s" % DST_IP)
1014 caad16e2 Iustin Pop
1015 caad16e2 Iustin Pop
1016 f93f2016 Michael Hanselmann
def _GetSocketCredentials(path):
1017 f93f2016 Michael Hanselmann
  """Connect to a Unix socket and return remote credentials.
1018 f93f2016 Michael Hanselmann

1019 f93f2016 Michael Hanselmann
  """
1020 f93f2016 Michael Hanselmann
  sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
1021 f93f2016 Michael Hanselmann
  try:
1022 f93f2016 Michael Hanselmann
    sock.settimeout(10)
1023 f93f2016 Michael Hanselmann
    sock.connect(path)
1024 f93f2016 Michael Hanselmann
    return utils.GetSocketCredentials(sock)
1025 f93f2016 Michael Hanselmann
  finally:
1026 f93f2016 Michael Hanselmann
    sock.close()
1027 f93f2016 Michael Hanselmann
1028 f93f2016 Michael Hanselmann
1029 f93f2016 Michael Hanselmann
class TestGetSocketCredentials(unittest.TestCase):
1030 f93f2016 Michael Hanselmann
  def setUp(self):
1031 f93f2016 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
1032 f93f2016 Michael Hanselmann
    self.sockpath = utils.PathJoin(self.tmpdir, "sock")
1033 f93f2016 Michael Hanselmann
1034 f93f2016 Michael Hanselmann
    self.listener = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
1035 f93f2016 Michael Hanselmann
    self.listener.settimeout(10)
1036 f93f2016 Michael Hanselmann
    self.listener.bind(self.sockpath)
1037 f93f2016 Michael Hanselmann
    self.listener.listen(1)
1038 f93f2016 Michael Hanselmann
1039 f93f2016 Michael Hanselmann
  def tearDown(self):
1040 f93f2016 Michael Hanselmann
    self.listener.shutdown(socket.SHUT_RDWR)
1041 f93f2016 Michael Hanselmann
    self.listener.close()
1042 f93f2016 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
1043 f93f2016 Michael Hanselmann
1044 f93f2016 Michael Hanselmann
  def test(self):
1045 f93f2016 Michael Hanselmann
    (c2pr, c2pw) = os.pipe()
1046 f93f2016 Michael Hanselmann
1047 f93f2016 Michael Hanselmann
    # Start child process
1048 f93f2016 Michael Hanselmann
    child = os.fork()
1049 f93f2016 Michael Hanselmann
    if child == 0:
1050 f93f2016 Michael Hanselmann
      try:
1051 f93f2016 Michael Hanselmann
        data = serializer.DumpJson(_GetSocketCredentials(self.sockpath))
1052 f93f2016 Michael Hanselmann
1053 f93f2016 Michael Hanselmann
        os.write(c2pw, data)
1054 f93f2016 Michael Hanselmann
        os.close(c2pw)
1055 f93f2016 Michael Hanselmann
1056 f93f2016 Michael Hanselmann
        os._exit(0)
1057 f93f2016 Michael Hanselmann
      finally:
1058 f93f2016 Michael Hanselmann
        os._exit(1)
1059 f93f2016 Michael Hanselmann
1060 f93f2016 Michael Hanselmann
    os.close(c2pw)
1061 f93f2016 Michael Hanselmann
1062 f93f2016 Michael Hanselmann
    # Wait for one connection
1063 f93f2016 Michael Hanselmann
    (conn, _) = self.listener.accept()
1064 f93f2016 Michael Hanselmann
    conn.recv(1)
1065 f93f2016 Michael Hanselmann
    conn.close()
1066 f93f2016 Michael Hanselmann
1067 f93f2016 Michael Hanselmann
    # Wait for result
1068 f93f2016 Michael Hanselmann
    result = os.read(c2pr, 4096)
1069 f93f2016 Michael Hanselmann
    os.close(c2pr)
1070 f93f2016 Michael Hanselmann
1071 f93f2016 Michael Hanselmann
    # Check child's exit code
1072 f93f2016 Michael Hanselmann
    (_, status) = os.waitpid(child, 0)
1073 f93f2016 Michael Hanselmann
    self.assertFalse(os.WIFSIGNALED(status))
1074 f93f2016 Michael Hanselmann
    self.assertEqual(os.WEXITSTATUS(status), 0)
1075 f93f2016 Michael Hanselmann
1076 f93f2016 Michael Hanselmann
    # Check result
1077 f93f2016 Michael Hanselmann
    (pid, uid, gid) = serializer.LoadJson(result)
1078 f93f2016 Michael Hanselmann
    self.assertEqual(pid, os.getpid())
1079 f93f2016 Michael Hanselmann
    self.assertEqual(uid, os.getuid())
1080 f93f2016 Michael Hanselmann
    self.assertEqual(gid, os.getgid())
1081 f93f2016 Michael Hanselmann
1082 f93f2016 Michael Hanselmann
1083 eedbda4b Michael Hanselmann
class TestListVisibleFiles(unittest.TestCase):
1084 eedbda4b Michael Hanselmann
  """Test case for ListVisibleFiles"""
1085 eedbda4b Michael Hanselmann
1086 eedbda4b Michael Hanselmann
  def setUp(self):
1087 eedbda4b Michael Hanselmann
    self.path = tempfile.mkdtemp()
1088 eedbda4b Michael Hanselmann
1089 eedbda4b Michael Hanselmann
  def tearDown(self):
1090 eedbda4b Michael Hanselmann
    shutil.rmtree(self.path)
1091 eedbda4b Michael Hanselmann
1092 eedbda4b Michael Hanselmann
  def _test(self, files, expected):
1093 eedbda4b Michael Hanselmann
    # Sort a copy
1094 eedbda4b Michael Hanselmann
    expected = expected[:]
1095 eedbda4b Michael Hanselmann
    expected.sort()
1096 eedbda4b Michael Hanselmann
1097 eedbda4b Michael Hanselmann
    for name in files:
1098 eedbda4b Michael Hanselmann
      f = open(os.path.join(self.path, name), 'w')
1099 eedbda4b Michael Hanselmann
      try:
1100 eedbda4b Michael Hanselmann
        f.write("Test\n")
1101 eedbda4b Michael Hanselmann
      finally:
1102 eedbda4b Michael Hanselmann
        f.close()
1103 eedbda4b Michael Hanselmann
1104 eedbda4b Michael Hanselmann
    found = ListVisibleFiles(self.path)
1105 eedbda4b Michael Hanselmann
    found.sort()
1106 eedbda4b Michael Hanselmann
1107 eedbda4b Michael Hanselmann
    self.assertEqual(found, expected)
1108 eedbda4b Michael Hanselmann
1109 eedbda4b Michael Hanselmann
  def testAllVisible(self):
1110 eedbda4b Michael Hanselmann
    files = ["a", "b", "c"]
1111 eedbda4b Michael Hanselmann
    expected = files
1112 eedbda4b Michael Hanselmann
    self._test(files, expected)
1113 eedbda4b Michael Hanselmann
1114 eedbda4b Michael Hanselmann
  def testNoneVisible(self):
1115 eedbda4b Michael Hanselmann
    files = [".a", ".b", ".c"]
1116 eedbda4b Michael Hanselmann
    expected = []
1117 eedbda4b Michael Hanselmann
    self._test(files, expected)
1118 eedbda4b Michael Hanselmann
1119 eedbda4b Michael Hanselmann
  def testSomeVisible(self):
1120 eedbda4b Michael Hanselmann
    files = ["a", "b", ".c"]
1121 eedbda4b Michael Hanselmann
    expected = ["a", "b"]
1122 eedbda4b Michael Hanselmann
    self._test(files, expected)
1123 eedbda4b Michael Hanselmann
1124 04a69a18 Iustin Pop
  def testNonAbsolutePath(self):
1125 04a69a18 Iustin Pop
    self.failUnlessRaises(errors.ProgrammerError, ListVisibleFiles, "abc")
1126 04a69a18 Iustin Pop
1127 04a69a18 Iustin Pop
  def testNonNormalizedPath(self):
1128 04a69a18 Iustin Pop
    self.failUnlessRaises(errors.ProgrammerError, ListVisibleFiles,
1129 04a69a18 Iustin Pop
                          "/bin/../tmp")
1130 04a69a18 Iustin Pop
1131 eedbda4b Michael Hanselmann
1132 24818e8f Michael Hanselmann
class TestNewUUID(unittest.TestCase):
1133 24818e8f Michael Hanselmann
  """Test case for NewUUID"""
1134 59072e7e Michael Hanselmann
1135 59072e7e Michael Hanselmann
  _re_uuid = re.compile('^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-'
1136 59072e7e Michael Hanselmann
                        '[a-f0-9]{4}-[a-f0-9]{12}$')
1137 59072e7e Michael Hanselmann
1138 59072e7e Michael Hanselmann
  def runTest(self):
1139 24818e8f Michael Hanselmann
    self.failUnless(self._re_uuid.match(utils.NewUUID()))
1140 59072e7e Michael Hanselmann
1141 59072e7e Michael Hanselmann
1142 f7414041 Michael Hanselmann
class TestUniqueSequence(unittest.TestCase):
1143 f7414041 Michael Hanselmann
  """Test case for UniqueSequence"""
1144 f7414041 Michael Hanselmann
1145 f7414041 Michael Hanselmann
  def _test(self, input, expected):
1146 f7414041 Michael Hanselmann
    self.assertEqual(utils.UniqueSequence(input), expected)
1147 f7414041 Michael Hanselmann
1148 f7414041 Michael Hanselmann
  def runTest(self):
1149 f7414041 Michael Hanselmann
    # Ordered input
1150 f7414041 Michael Hanselmann
    self._test([1, 2, 3], [1, 2, 3])
1151 f7414041 Michael Hanselmann
    self._test([1, 1, 2, 2, 3, 3], [1, 2, 3])
1152 f7414041 Michael Hanselmann
    self._test([1, 2, 2, 3], [1, 2, 3])
1153 f7414041 Michael Hanselmann
    self._test([1, 2, 3, 3], [1, 2, 3])
1154 f7414041 Michael Hanselmann
1155 f7414041 Michael Hanselmann
    # Unordered input
1156 f7414041 Michael Hanselmann
    self._test([1, 2, 3, 1, 2, 3], [1, 2, 3])
1157 f7414041 Michael Hanselmann
    self._test([1, 1, 2, 3, 3, 1, 2], [1, 2, 3])
1158 f7414041 Michael Hanselmann
1159 f7414041 Michael Hanselmann
    # Strings
1160 f7414041 Michael Hanselmann
    self._test(["a", "a"], ["a"])
1161 f7414041 Michael Hanselmann
    self._test(["a", "b"], ["a", "b"])
1162 f7414041 Michael Hanselmann
    self._test(["a", "b", "a"], ["a", "b"])
1163 f7414041 Michael Hanselmann
1164 a87b4824 Michael Hanselmann
1165 7b4126b7 Iustin Pop
class TestFirstFree(unittest.TestCase):
1166 7b4126b7 Iustin Pop
  """Test case for the FirstFree function"""
1167 7b4126b7 Iustin Pop
1168 7b4126b7 Iustin Pop
  def test(self):
1169 7b4126b7 Iustin Pop
    """Test FirstFree"""
1170 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([0, 1, 3]), 2)
1171 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([]), None)
1172 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([3, 4, 6]), 0)
1173 7b4126b7 Iustin Pop
    self.failUnlessEqual(FirstFree([3, 4, 6], base=3), 5)
1174 7b4126b7 Iustin Pop
    self.failUnlessRaises(AssertionError, FirstFree, [0, 3, 4, 6], base=3)
1175 f7414041 Michael Hanselmann
1176 a87b4824 Michael Hanselmann
1177 f65f63ef Iustin Pop
class TestTailFile(testutils.GanetiTestCase):
1178 f65f63ef Iustin Pop
  """Test case for the TailFile function"""
1179 f65f63ef Iustin Pop
1180 f65f63ef Iustin Pop
  def testEmpty(self):
1181 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1182 f65f63ef Iustin Pop
    self.failUnlessEqual(TailFile(fname), [])
1183 f65f63ef Iustin Pop
    self.failUnlessEqual(TailFile(fname, lines=25), [])
1184 f65f63ef Iustin Pop
1185 f65f63ef Iustin Pop
  def testAllLines(self):
1186 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1187 f65f63ef Iustin Pop
    for i in range(30):
1188 f65f63ef Iustin Pop
      fname = self._CreateTempFile()
1189 f65f63ef Iustin Pop
      fd = open(fname, "w")
1190 f65f63ef Iustin Pop
      fd.write("\n".join(data[:i]))
1191 f65f63ef Iustin Pop
      if i > 0:
1192 f65f63ef Iustin Pop
        fd.write("\n")
1193 f65f63ef Iustin Pop
      fd.close()
1194 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[:i])
1195 f65f63ef Iustin Pop
1196 f65f63ef Iustin Pop
  def testPartialLines(self):
1197 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1198 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1199 f65f63ef Iustin Pop
    fd = open(fname, "w")
1200 f65f63ef Iustin Pop
    fd.write("\n".join(data))
1201 f65f63ef Iustin Pop
    fd.write("\n")
1202 f65f63ef Iustin Pop
    fd.close()
1203 f65f63ef Iustin Pop
    for i in range(1, 30):
1204 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[-i:])
1205 f65f63ef Iustin Pop
1206 f65f63ef Iustin Pop
  def testBigFile(self):
1207 f65f63ef Iustin Pop
    data = ["test %d" % i for i in range(30)]
1208 f65f63ef Iustin Pop
    fname = self._CreateTempFile()
1209 f65f63ef Iustin Pop
    fd = open(fname, "w")
1210 f65f63ef Iustin Pop
    fd.write("X" * 1048576)
1211 f65f63ef Iustin Pop
    fd.write("\n")
1212 f65f63ef Iustin Pop
    fd.write("\n".join(data))
1213 f65f63ef Iustin Pop
    fd.write("\n")
1214 f65f63ef Iustin Pop
    fd.close()
1215 f65f63ef Iustin Pop
    for i in range(1, 30):
1216 f65f63ef Iustin Pop
      self.failUnlessEqual(TailFile(fname, lines=i), data[-i:])
1217 f65f63ef Iustin Pop
1218 f65f63ef Iustin Pop
1219 b4478d34 Michael Hanselmann
class _BaseFileLockTest:
1220 a87b4824 Michael Hanselmann
  """Test case for the FileLock class"""
1221 a87b4824 Michael Hanselmann
1222 a87b4824 Michael Hanselmann
  def testSharedNonblocking(self):
1223 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1224 a87b4824 Michael Hanselmann
    self.lock.Close()
1225 a87b4824 Michael Hanselmann
1226 a87b4824 Michael Hanselmann
  def testExclusiveNonblocking(self):
1227 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1228 a87b4824 Michael Hanselmann
    self.lock.Close()
1229 a87b4824 Michael Hanselmann
1230 a87b4824 Michael Hanselmann
  def testUnlockNonblocking(self):
1231 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1232 a87b4824 Michael Hanselmann
    self.lock.Close()
1233 a87b4824 Michael Hanselmann
1234 a87b4824 Michael Hanselmann
  def testSharedBlocking(self):
1235 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=True)
1236 a87b4824 Michael Hanselmann
    self.lock.Close()
1237 a87b4824 Michael Hanselmann
1238 a87b4824 Michael Hanselmann
  def testExclusiveBlocking(self):
1239 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=True)
1240 a87b4824 Michael Hanselmann
    self.lock.Close()
1241 a87b4824 Michael Hanselmann
1242 a87b4824 Michael Hanselmann
  def testUnlockBlocking(self):
1243 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=True)
1244 a87b4824 Michael Hanselmann
    self.lock.Close()
1245 a87b4824 Michael Hanselmann
1246 a87b4824 Michael Hanselmann
  def testSharedExclusiveUnlock(self):
1247 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1248 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1249 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1250 a87b4824 Michael Hanselmann
    self.lock.Close()
1251 a87b4824 Michael Hanselmann
1252 a87b4824 Michael Hanselmann
  def testExclusiveSharedUnlock(self):
1253 a87b4824 Michael Hanselmann
    self.lock.Exclusive(blocking=False)
1254 a87b4824 Michael Hanselmann
    self.lock.Shared(blocking=False)
1255 a87b4824 Michael Hanselmann
    self.lock.Unlock(blocking=False)
1256 a87b4824 Michael Hanselmann
    self.lock.Close()
1257 a87b4824 Michael Hanselmann
1258 b4478d34 Michael Hanselmann
  def testSimpleTimeout(self):
1259 b4478d34 Michael Hanselmann
    # These will succeed on the first attempt, hence a short timeout
1260 b4478d34 Michael Hanselmann
    self.lock.Shared(blocking=True, timeout=10.0)
1261 b4478d34 Michael Hanselmann
    self.lock.Exclusive(blocking=False, timeout=10.0)
1262 b4478d34 Michael Hanselmann
    self.lock.Unlock(blocking=True, timeout=10.0)
1263 b4478d34 Michael Hanselmann
    self.lock.Close()
1264 b4478d34 Michael Hanselmann
1265 b4478d34 Michael Hanselmann
  @staticmethod
1266 b4478d34 Michael Hanselmann
  def _TryLockInner(filename, shared, blocking):
1267 b4478d34 Michael Hanselmann
    lock = utils.FileLock.Open(filename)
1268 b4478d34 Michael Hanselmann
1269 b4478d34 Michael Hanselmann
    if shared:
1270 b4478d34 Michael Hanselmann
      fn = lock.Shared
1271 b4478d34 Michael Hanselmann
    else:
1272 b4478d34 Michael Hanselmann
      fn = lock.Exclusive
1273 b4478d34 Michael Hanselmann
1274 b4478d34 Michael Hanselmann
    try:
1275 b4478d34 Michael Hanselmann
      # The timeout doesn't really matter as the parent process waits for us to
1276 b4478d34 Michael Hanselmann
      # finish anyway.
1277 b4478d34 Michael Hanselmann
      fn(blocking=blocking, timeout=0.01)
1278 b4478d34 Michael Hanselmann
    except errors.LockError, err:
1279 b4478d34 Michael Hanselmann
      return False
1280 b4478d34 Michael Hanselmann
1281 b4478d34 Michael Hanselmann
    return True
1282 b4478d34 Michael Hanselmann
1283 b4478d34 Michael Hanselmann
  def _TryLock(self, *args):
1284 b4478d34 Michael Hanselmann
    return utils.RunInSeparateProcess(self._TryLockInner, self.tmpfile.name,
1285 b4478d34 Michael Hanselmann
                                      *args)
1286 b4478d34 Michael Hanselmann
1287 b4478d34 Michael Hanselmann
  def testTimeout(self):
1288 b4478d34 Michael Hanselmann
    for blocking in [True, False]:
1289 b4478d34 Michael Hanselmann
      self.lock.Exclusive(blocking=True)
1290 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(False, blocking))
1291 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(True, blocking))
1292 b4478d34 Michael Hanselmann
1293 b4478d34 Michael Hanselmann
      self.lock.Shared(blocking=True)
1294 b4478d34 Michael Hanselmann
      self.assert_(self._TryLock(True, blocking))
1295 b4478d34 Michael Hanselmann
      self.failIf(self._TryLock(False, blocking))
1296 b4478d34 Michael Hanselmann
1297 a87b4824 Michael Hanselmann
  def testCloseShared(self):
1298 a87b4824 Michael Hanselmann
    self.lock.Close()
1299 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Shared, blocking=False)
1300 a87b4824 Michael Hanselmann
1301 a87b4824 Michael Hanselmann
  def testCloseExclusive(self):
1302 a87b4824 Michael Hanselmann
    self.lock.Close()
1303 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Exclusive, blocking=False)
1304 a87b4824 Michael Hanselmann
1305 a87b4824 Michael Hanselmann
  def testCloseUnlock(self):
1306 a87b4824 Michael Hanselmann
    self.lock.Close()
1307 a87b4824 Michael Hanselmann
    self.assertRaises(AssertionError, self.lock.Unlock, blocking=False)
1308 a87b4824 Michael Hanselmann
1309 a87b4824 Michael Hanselmann
1310 b4478d34 Michael Hanselmann
class TestFileLockWithFilename(testutils.GanetiTestCase, _BaseFileLockTest):
1311 b4478d34 Michael Hanselmann
  TESTDATA = "Hello World\n" * 10
1312 b4478d34 Michael Hanselmann
1313 b4478d34 Michael Hanselmann
  def setUp(self):
1314 b4478d34 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
1315 b4478d34 Michael Hanselmann
1316 b4478d34 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1317 b4478d34 Michael Hanselmann
    utils.WriteFile(self.tmpfile.name, data=self.TESTDATA)
1318 b4478d34 Michael Hanselmann
    self.lock = utils.FileLock.Open(self.tmpfile.name)
1319 b4478d34 Michael Hanselmann
1320 b4478d34 Michael Hanselmann
    # Ensure "Open" didn't truncate file
1321 b4478d34 Michael Hanselmann
    self.assertFileContent(self.tmpfile.name, self.TESTDATA)
1322 b4478d34 Michael Hanselmann
1323 b4478d34 Michael Hanselmann
  def tearDown(self):
1324 b4478d34 Michael Hanselmann
    self.assertFileContent(self.tmpfile.name, self.TESTDATA)
1325 b4478d34 Michael Hanselmann
1326 b4478d34 Michael Hanselmann
    testutils.GanetiTestCase.tearDown(self)
1327 b4478d34 Michael Hanselmann
1328 b4478d34 Michael Hanselmann
1329 b4478d34 Michael Hanselmann
class TestFileLockWithFileObject(unittest.TestCase, _BaseFileLockTest):
1330 b4478d34 Michael Hanselmann
  def setUp(self):
1331 b4478d34 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1332 b4478d34 Michael Hanselmann
    self.lock = utils.FileLock(open(self.tmpfile.name, "w"), self.tmpfile.name)
1333 b4478d34 Michael Hanselmann
1334 b4478d34 Michael Hanselmann
1335 739be818 Michael Hanselmann
class TestTimeFunctions(unittest.TestCase):
1336 739be818 Michael Hanselmann
  """Test case for time functions"""
1337 739be818 Michael Hanselmann
1338 739be818 Michael Hanselmann
  def runTest(self):
1339 739be818 Michael Hanselmann
    self.assertEqual(utils.SplitTime(1), (1, 0))
1340 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(1.5), (1, 500000))
1341 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(1218448917.4809151), (1218448917, 480915))
1342 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.48012), (123, 480120))
1343 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9996), (123, 999600))
1344 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9995), (123, 999500))
1345 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.9994), (123, 999400))
1346 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.SplitTime(123.999999999), (123, 999999))
1347 45bc5e4a Michael Hanselmann
1348 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.SplitTime, -1)
1349 739be818 Michael Hanselmann
1350 739be818 Michael Hanselmann
    self.assertEqual(utils.MergeTime((1, 0)), 1.0)
1351 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.MergeTime((1, 500000)), 1.5)
1352 45bc5e4a Michael Hanselmann
    self.assertEqual(utils.MergeTime((1218448917, 500000)), 1218448917.5)
1353 739be818 Michael Hanselmann
1354 4d4a651d Michael Hanselmann
    self.assertEqual(round(utils.MergeTime((1218448917, 481000)), 3),
1355 4d4a651d Michael Hanselmann
                     1218448917.481)
1356 45bc5e4a Michael Hanselmann
    self.assertEqual(round(utils.MergeTime((1, 801000)), 3), 1.801)
1357 739be818 Michael Hanselmann
1358 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, -1))
1359 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, 1000000))
1360 45bc5e4a Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (0, 9999999))
1361 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (-1, 0))
1362 739be818 Michael Hanselmann
    self.assertRaises(AssertionError, utils.MergeTime, (-9999, 0))
1363 739be818 Michael Hanselmann
1364 739be818 Michael Hanselmann
1365 a2d2e1a7 Iustin Pop
class FieldSetTestCase(unittest.TestCase):
1366 a2d2e1a7 Iustin Pop
  """Test case for FieldSets"""
1367 a2d2e1a7 Iustin Pop
1368 a2d2e1a7 Iustin Pop
  def testSimpleMatch(self):
1369 a2d2e1a7 Iustin Pop
    f = utils.FieldSet("a", "b", "c", "def")
1370 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("a"))
1371 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("d"), "Substring matched")
1372 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("defghi"), "Prefix string matched")
1373 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["b", "c"]))
1374 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["a", "b", "c", "def"]))
1375 a2d2e1a7 Iustin Pop
    self.failUnless(f.NonMatching(["a", "d"]))
1376 a2d2e1a7 Iustin Pop
1377 a2d2e1a7 Iustin Pop
  def testRegexMatch(self):
1378 a2d2e1a7 Iustin Pop
    f = utils.FieldSet("a", "b([0-9]+)", "c")
1379 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("b1"))
1380 a2d2e1a7 Iustin Pop
    self.failUnless(f.Matches("b99"))
1381 a2d2e1a7 Iustin Pop
    self.failIf(f.Matches("b/1"))
1382 a2d2e1a7 Iustin Pop
    self.failIf(f.NonMatching(["b12", "c"]))
1383 a2d2e1a7 Iustin Pop
    self.failUnless(f.NonMatching(["a", "1"]))
1384 a2d2e1a7 Iustin Pop
1385 a5728081 Guido Trotter
class TestForceDictType(unittest.TestCase):
1386 a5728081 Guido Trotter
  """Test case for ForceDictType"""
1387 a5728081 Guido Trotter
1388 a5728081 Guido Trotter
  def setUp(self):
1389 a5728081 Guido Trotter
    self.key_types = {
1390 a5728081 Guido Trotter
      'a': constants.VTYPE_INT,
1391 a5728081 Guido Trotter
      'b': constants.VTYPE_BOOL,
1392 a5728081 Guido Trotter
      'c': constants.VTYPE_STRING,
1393 a5728081 Guido Trotter
      'd': constants.VTYPE_SIZE,
1394 a5728081 Guido Trotter
      }
1395 a5728081 Guido Trotter
1396 a5728081 Guido Trotter
  def _fdt(self, dict, allowed_values=None):
1397 a5728081 Guido Trotter
    if allowed_values is None:
1398 a5728081 Guido Trotter
      ForceDictType(dict, self.key_types)
1399 a5728081 Guido Trotter
    else:
1400 a5728081 Guido Trotter
      ForceDictType(dict, self.key_types, allowed_values=allowed_values)
1401 a5728081 Guido Trotter
1402 a5728081 Guido Trotter
    return dict
1403 a5728081 Guido Trotter
1404 a5728081 Guido Trotter
  def testSimpleDict(self):
1405 a5728081 Guido Trotter
    self.assertEqual(self._fdt({}), {})
1406 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': 1}), {'a': 1})
1407 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': '1'}), {'a': 1})
1408 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'a': 1, 'b': 1}), {'a':1, 'b': True})
1409 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 1, 'c': 'foo'}), {'b': True, 'c': 'foo'})
1410 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 1, 'c': False}), {'b': True, 'c': ''})
1411 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'false'}), {'b': False})
1412 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'False'}), {'b': False})
1413 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'true'}), {'b': True})
1414 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'b': 'True'}), {'b': True})
1415 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'d': '4'}), {'d': 4})
1416 a5728081 Guido Trotter
    self.assertEqual(self._fdt({'d': '4M'}), {'d': 4})
1417 a5728081 Guido Trotter
1418 a5728081 Guido Trotter
  def testErrors(self):
1419 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'a': 'astring'})
1420 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'c': True})
1421 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': 'astring'})
1422 a5728081 Guido Trotter
    self.assertRaises(errors.TypeEnforcementError, self._fdt, {'d': '4 L'})
1423 a5728081 Guido Trotter
1424 a2d2e1a7 Iustin Pop
1425 05489142 Guido Trotter
class TestIsNormAbsPath(unittest.TestCase):
1426 05489142 Guido Trotter
  """Testing case for IsNormAbsPath"""
1427 da961187 Guido Trotter
1428 da961187 Guido Trotter
  def _pathTestHelper(self, path, result):
1429 da961187 Guido Trotter
    if result:
1430 da961187 Guido Trotter
      self.assert_(IsNormAbsPath(path),
1431 17c61836 Guido Trotter
          "Path %s should result absolute and normalized" % path)
1432 da961187 Guido Trotter
    else:
1433 da961187 Guido Trotter
      self.assert_(not IsNormAbsPath(path),
1434 17c61836 Guido Trotter
          "Path %s should not result absolute and normalized" % path)
1435 da961187 Guido Trotter
1436 da961187 Guido Trotter
  def testBase(self):
1437 da961187 Guido Trotter
    self._pathTestHelper('/etc', True)
1438 da961187 Guido Trotter
    self._pathTestHelper('/srv', True)
1439 da961187 Guido Trotter
    self._pathTestHelper('etc', False)
1440 da961187 Guido Trotter
    self._pathTestHelper('/etc/../root', False)
1441 da961187 Guido Trotter
    self._pathTestHelper('/etc/', False)
1442 da961187 Guido Trotter
1443 af0413bb Guido Trotter
1444 d392fa34 Iustin Pop
class TestSafeEncode(unittest.TestCase):
1445 d392fa34 Iustin Pop
  """Test case for SafeEncode"""
1446 d392fa34 Iustin Pop
1447 d392fa34 Iustin Pop
  def testAscii(self):
1448 d392fa34 Iustin Pop
    for txt in [string.digits, string.letters, string.punctuation]:
1449 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1450 d392fa34 Iustin Pop
1451 d392fa34 Iustin Pop
  def testDoubleEncode(self):
1452 d392fa34 Iustin Pop
    for i in range(255):
1453 d392fa34 Iustin Pop
      txt = SafeEncode(chr(i))
1454 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1455 d392fa34 Iustin Pop
1456 d392fa34 Iustin Pop
  def testUnicode(self):
1457 d392fa34 Iustin Pop
    # 1024 is high enough to catch non-direct ASCII mappings
1458 d392fa34 Iustin Pop
    for i in range(1024):
1459 d392fa34 Iustin Pop
      txt = SafeEncode(unichr(i))
1460 d392fa34 Iustin Pop
      self.failUnlessEqual(txt, SafeEncode(txt))
1461 d392fa34 Iustin Pop
1462 d392fa34 Iustin Pop
1463 3b813dd2 Iustin Pop
class TestFormatTime(unittest.TestCase):
1464 3b813dd2 Iustin Pop
  """Testing case for FormatTime"""
1465 3b813dd2 Iustin Pop
1466 3b813dd2 Iustin Pop
  def testNone(self):
1467 3b813dd2 Iustin Pop
    self.failUnlessEqual(FormatTime(None), "N/A")
1468 3b813dd2 Iustin Pop
1469 3b813dd2 Iustin Pop
  def testInvalid(self):
1470 3b813dd2 Iustin Pop
    self.failUnlessEqual(FormatTime(()), "N/A")
1471 3b813dd2 Iustin Pop
1472 3b813dd2 Iustin Pop
  def testNow(self):
1473 3b813dd2 Iustin Pop
    # tests that we accept time.time input
1474 3b813dd2 Iustin Pop
    FormatTime(time.time())
1475 3b813dd2 Iustin Pop
    # tests that we accept int input
1476 3b813dd2 Iustin Pop
    FormatTime(int(time.time()))
1477 3b813dd2 Iustin Pop
1478 3b813dd2 Iustin Pop
1479 eb58f7bd Michael Hanselmann
class RunInSeparateProcess(unittest.TestCase):
1480 eb58f7bd Michael Hanselmann
  def test(self):
1481 eb58f7bd Michael Hanselmann
    for exp in [True, False]:
1482 eb58f7bd Michael Hanselmann
      def _child():
1483 eb58f7bd Michael Hanselmann
        return exp
1484 eb58f7bd Michael Hanselmann
1485 eb58f7bd Michael Hanselmann
      self.assertEqual(exp, utils.RunInSeparateProcess(_child))
1486 eb58f7bd Michael Hanselmann
1487 bdefe5dd Michael Hanselmann
  def testArgs(self):
1488 bdefe5dd Michael Hanselmann
    for arg in [0, 1, 999, "Hello World", (1, 2, 3)]:
1489 bdefe5dd Michael Hanselmann
      def _child(carg1, carg2):
1490 bdefe5dd Michael Hanselmann
        return carg1 == "Foo" and carg2 == arg
1491 bdefe5dd Michael Hanselmann
1492 bdefe5dd Michael Hanselmann
      self.assert_(utils.RunInSeparateProcess(_child, "Foo", arg))
1493 bdefe5dd Michael Hanselmann
1494 eb58f7bd Michael Hanselmann
  def testPid(self):
1495 eb58f7bd Michael Hanselmann
    parent_pid = os.getpid()
1496 eb58f7bd Michael Hanselmann
1497 eb58f7bd Michael Hanselmann
    def _check():
1498 eb58f7bd Michael Hanselmann
      return os.getpid() == parent_pid
1499 eb58f7bd Michael Hanselmann
1500 eb58f7bd Michael Hanselmann
    self.failIf(utils.RunInSeparateProcess(_check))
1501 eb58f7bd Michael Hanselmann
1502 eb58f7bd Michael Hanselmann
  def testSignal(self):
1503 eb58f7bd Michael Hanselmann
    def _kill():
1504 eb58f7bd Michael Hanselmann
      os.kill(os.getpid(), signal.SIGTERM)
1505 eb58f7bd Michael Hanselmann
1506 eb58f7bd Michael Hanselmann
    self.assertRaises(errors.GenericError,
1507 eb58f7bd Michael Hanselmann
                      utils.RunInSeparateProcess, _kill)
1508 eb58f7bd Michael Hanselmann
1509 eb58f7bd Michael Hanselmann
  def testException(self):
1510 eb58f7bd Michael Hanselmann
    def _exc():
1511 eb58f7bd Michael Hanselmann
      raise errors.GenericError("This is a test")
1512 eb58f7bd Michael Hanselmann
1513 eb58f7bd Michael Hanselmann
    self.assertRaises(errors.GenericError,
1514 eb58f7bd Michael Hanselmann
                      utils.RunInSeparateProcess, _exc)
1515 eb58f7bd Michael Hanselmann
1516 eb58f7bd Michael Hanselmann
1517 fabee4b2 Michael Hanselmann
class TestFingerprintFile(unittest.TestCase):
1518 fabee4b2 Michael Hanselmann
  def setUp(self):
1519 fabee4b2 Michael Hanselmann
    self.tmpfile = tempfile.NamedTemporaryFile()
1520 fabee4b2 Michael Hanselmann
1521 fabee4b2 Michael Hanselmann
  def test(self):
1522 fabee4b2 Michael Hanselmann
    self.assertEqual(utils._FingerprintFile(self.tmpfile.name),
1523 fabee4b2 Michael Hanselmann
                     "da39a3ee5e6b4b0d3255bfef95601890afd80709")
1524 fabee4b2 Michael Hanselmann
1525 fabee4b2 Michael Hanselmann
    utils.WriteFile(self.tmpfile.name, data="Hello World\n")
1526 fabee4b2 Michael Hanselmann
    self.assertEqual(utils._FingerprintFile(self.tmpfile.name),
1527 fabee4b2 Michael Hanselmann
                     "648a6a6ffffdaa0badb23b8baf90b6168dd16b3a")
1528 fabee4b2 Michael Hanselmann
1529 fabee4b2 Michael Hanselmann
1530 5b69bc7c Iustin Pop
class TestUnescapeAndSplit(unittest.TestCase):
1531 5b69bc7c Iustin Pop
  """Testing case for UnescapeAndSplit"""
1532 5b69bc7c Iustin Pop
1533 5b69bc7c Iustin Pop
  def setUp(self):
1534 5b69bc7c Iustin Pop
    # testing more that one separator for regexp safety
1535 5b69bc7c Iustin Pop
    self._seps = [",", "+", "."]
1536 5b69bc7c Iustin Pop
1537 5b69bc7c Iustin Pop
  def testSimple(self):
1538 5b69bc7c Iustin Pop
    a = ["a", "b", "c", "d"]
1539 5b69bc7c Iustin Pop
    for sep in self._seps:
1540 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), a)
1541 5b69bc7c Iustin Pop
1542 5b69bc7c Iustin Pop
  def testEscape(self):
1543 5b69bc7c Iustin Pop
    for sep in self._seps:
1544 5b69bc7c Iustin Pop
      a = ["a", "b\\" + sep + "c", "d"]
1545 5b69bc7c Iustin Pop
      b = ["a", "b" + sep + "c", "d"]
1546 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1547 5b69bc7c Iustin Pop
1548 5b69bc7c Iustin Pop
  def testDoubleEscape(self):
1549 5b69bc7c Iustin Pop
    for sep in self._seps:
1550 5b69bc7c Iustin Pop
      a = ["a", "b\\\\", "c", "d"]
1551 5b69bc7c Iustin Pop
      b = ["a", "b\\", "c", "d"]
1552 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1553 5b69bc7c Iustin Pop
1554 5b69bc7c Iustin Pop
  def testThreeEscape(self):
1555 5b69bc7c Iustin Pop
    for sep in self._seps:
1556 5b69bc7c Iustin Pop
      a = ["a", "b\\\\\\" + sep + "c", "d"]
1557 5b69bc7c Iustin Pop
      b = ["a", "b\\" + sep + "c", "d"]
1558 5b69bc7c Iustin Pop
      self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
1559 5b69bc7c Iustin Pop
1560 5b69bc7c Iustin Pop
1561 4bb678e9 Iustin Pop
class TestPathJoin(unittest.TestCase):
1562 4bb678e9 Iustin Pop
  """Testing case for PathJoin"""
1563 4bb678e9 Iustin Pop
1564 4bb678e9 Iustin Pop
  def testBasicItems(self):
1565 4bb678e9 Iustin Pop
    mlist = ["/a", "b", "c"]
1566 4bb678e9 Iustin Pop
    self.failUnlessEqual(PathJoin(*mlist), "/".join(mlist))
1567 4bb678e9 Iustin Pop
1568 4bb678e9 Iustin Pop
  def testNonAbsPrefix(self):
1569 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "a", "b")
1570 4bb678e9 Iustin Pop
1571 4bb678e9 Iustin Pop
  def testBackTrack(self):
1572 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "/a", "b/../c")
1573 4bb678e9 Iustin Pop
1574 4bb678e9 Iustin Pop
  def testMultiAbs(self):
1575 4bb678e9 Iustin Pop
    self.failUnlessRaises(ValueError, PathJoin, "/a", "/b")
1576 4bb678e9 Iustin Pop
1577 4bb678e9 Iustin Pop
1578 26288e68 Iustin Pop
class TestHostInfo(unittest.TestCase):
1579 26288e68 Iustin Pop
  """Testing case for HostInfo"""
1580 26288e68 Iustin Pop
1581 26288e68 Iustin Pop
  def testUppercase(self):
1582 26288e68 Iustin Pop
    data = "AbC.example.com"
1583 26288e68 Iustin Pop
    self.failUnlessEqual(HostInfo.NormalizeName(data), data.lower())
1584 26288e68 Iustin Pop
1585 26288e68 Iustin Pop
  def testTooLongName(self):
1586 26288e68 Iustin Pop
    data = "a.b." + "c" * 255
1587 26288e68 Iustin Pop
    self.failUnlessRaises(OpPrereqError, HostInfo.NormalizeName, data)
1588 26288e68 Iustin Pop
1589 26288e68 Iustin Pop
  def testTrailingDot(self):
1590 26288e68 Iustin Pop
    data = "a.b.c"
1591 26288e68 Iustin Pop
    self.failUnlessEqual(HostInfo.NormalizeName(data + "."), data)
1592 26288e68 Iustin Pop
1593 26288e68 Iustin Pop
  def testInvalidName(self):
1594 26288e68 Iustin Pop
    data = [
1595 26288e68 Iustin Pop
      "a b",
1596 26288e68 Iustin Pop
      "a/b",
1597 26288e68 Iustin Pop
      ".a.b",
1598 26288e68 Iustin Pop
      "a..b",
1599 26288e68 Iustin Pop
      ]
1600 26288e68 Iustin Pop
    for value in data:
1601 26288e68 Iustin Pop
      self.failUnlessRaises(OpPrereqError, HostInfo.NormalizeName, value)
1602 26288e68 Iustin Pop
1603 26288e68 Iustin Pop
  def testValidName(self):
1604 26288e68 Iustin Pop
    data = [
1605 26288e68 Iustin Pop
      "a.b",
1606 26288e68 Iustin Pop
      "a-b",
1607 26288e68 Iustin Pop
      "a_b",
1608 26288e68 Iustin Pop
      "a.b.c",
1609 26288e68 Iustin Pop
      ]
1610 26288e68 Iustin Pop
    for value in data:
1611 26288e68 Iustin Pop
      HostInfo.NormalizeName(value)
1612 26288e68 Iustin Pop
1613 26288e68 Iustin Pop
1614 27e46076 Michael Hanselmann
class TestParseAsn1Generalizedtime(unittest.TestCase):
1615 27e46076 Michael Hanselmann
  def test(self):
1616 27e46076 Michael Hanselmann
    # UTC
1617 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("19700101000000Z"), 0)
1618 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100222174152Z"),
1619 27e46076 Michael Hanselmann
                     1266860512)
1620 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20380119031407Z"),
1621 27e46076 Michael Hanselmann
                     (2**31) - 1)
1622 27e46076 Michael Hanselmann
1623 27e46076 Michael Hanselmann
    # With offset
1624 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100222174152+0000"),
1625 27e46076 Michael Hanselmann
                     1266860512)
1626 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100223131652+0000"),
1627 27e46076 Michael Hanselmann
                     1266931012)
1628 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100223051808-0800"),
1629 27e46076 Michael Hanselmann
                     1266931088)
1630 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("20100224002135+1100"),
1631 27e46076 Michael Hanselmann
                     1266931295)
1632 27e46076 Michael Hanselmann
    self.assertEqual(utils._ParseAsn1Generalizedtime("19700101000000-0100"),
1633 27e46076 Michael Hanselmann
                     3600)
1634 27e46076 Michael Hanselmann
1635 27e46076 Michael Hanselmann
    # Leap seconds are not supported by datetime.datetime
1636 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1637 27e46076 Michael Hanselmann
                      "19841231235960+0000")
1638 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1639 27e46076 Michael Hanselmann
                      "19920630235960+0000")
1640 27e46076 Michael Hanselmann
1641 27e46076 Michael Hanselmann
    # Errors
1642 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime, "")
1643 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime, "invalid")
1644 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1645 27e46076 Michael Hanselmann
                      "20100222174152")
1646 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1647 27e46076 Michael Hanselmann
                      "Mon Feb 22 17:47:02 UTC 2010")
1648 27e46076 Michael Hanselmann
    self.assertRaises(ValueError, utils._ParseAsn1Generalizedtime,
1649 27e46076 Michael Hanselmann
                      "2010-02-22 17:42:02")
1650 27e46076 Michael Hanselmann
1651 27e46076 Michael Hanselmann
1652 27e46076 Michael Hanselmann
class TestGetX509CertValidity(testutils.GanetiTestCase):
1653 27e46076 Michael Hanselmann
  def setUp(self):
1654 27e46076 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
1655 27e46076 Michael Hanselmann
1656 27e46076 Michael Hanselmann
    pyopenssl_version = distutils.version.LooseVersion(OpenSSL.__version__)
1657 27e46076 Michael Hanselmann
1658 27e46076 Michael Hanselmann
    # Test whether we have pyOpenSSL 0.7 or above
1659 27e46076 Michael Hanselmann
    self.pyopenssl0_7 = (pyopenssl_version >= "0.7")
1660 27e46076 Michael Hanselmann
1661 27e46076 Michael Hanselmann
    if not self.pyopenssl0_7:
1662 27e46076 Michael Hanselmann
      warnings.warn("This test requires pyOpenSSL 0.7 or above to"
1663 27e46076 Michael Hanselmann
                    " function correctly")
1664 27e46076 Michael Hanselmann
1665 27e46076 Michael Hanselmann
  def _LoadCert(self, name):
1666 27e46076 Michael Hanselmann
    return OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
1667 27e46076 Michael Hanselmann
                                           self._ReadTestData(name))
1668 27e46076 Michael Hanselmann
1669 27e46076 Michael Hanselmann
  def test(self):
1670 27e46076 Michael Hanselmann
    validity = utils.GetX509CertValidity(self._LoadCert("cert1.pem"))
1671 27e46076 Michael Hanselmann
    if self.pyopenssl0_7:
1672 27e46076 Michael Hanselmann
      self.assertEqual(validity, (1266919967, 1267524767))
1673 27e46076 Michael Hanselmann
    else:
1674 27e46076 Michael Hanselmann
      self.assertEqual(validity, (None, None))
1675 27e46076 Michael Hanselmann
1676 26288e68 Iustin Pop
1677 76e5f8b5 Michael Hanselmann
class TestMakedirs(unittest.TestCase):
1678 76e5f8b5 Michael Hanselmann
  def setUp(self):
1679 76e5f8b5 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
1680 76e5f8b5 Michael Hanselmann
1681 76e5f8b5 Michael Hanselmann
  def tearDown(self):
1682 76e5f8b5 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
1683 76e5f8b5 Michael Hanselmann
1684 76e5f8b5 Michael Hanselmann
  def testNonExisting(self):
1685 76e5f8b5 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "foo")
1686 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
1687 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
1688 76e5f8b5 Michael Hanselmann
1689 76e5f8b5 Michael Hanselmann
  def testExisting(self):
1690 76e5f8b5 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "foo")
1691 76e5f8b5 Michael Hanselmann
    os.mkdir(path)
1692 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
1693 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
1694 76e5f8b5 Michael Hanselmann
1695 76e5f8b5 Michael Hanselmann
  def testRecursiveNonExisting(self):
1696 76e5f8b5 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "foo/bar/baz")
1697 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
1698 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
1699 76e5f8b5 Michael Hanselmann
1700 76e5f8b5 Michael Hanselmann
  def testRecursiveExisting(self):
1701 76e5f8b5 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "B/moo/xyz")
1702 76e5f8b5 Michael Hanselmann
    self.assert_(not os.path.exists(path))
1703 76e5f8b5 Michael Hanselmann
    os.mkdir(utils.PathJoin(self.tmpdir, "B"))
1704 76e5f8b5 Michael Hanselmann
    utils.Makedirs(path)
1705 76e5f8b5 Michael Hanselmann
    self.assert_(os.path.isdir(path))
1706 76e5f8b5 Michael Hanselmann
1707 76e5f8b5 Michael Hanselmann
1708 1b429e2a Iustin Pop
class TestRetry(testutils.GanetiTestCase):
1709 45cc4913 Guido Trotter
  def setUp(self):
1710 45cc4913 Guido Trotter
    testutils.GanetiTestCase.setUp(self)
1711 45cc4913 Guido Trotter
    self.retries = 0
1712 45cc4913 Guido Trotter
1713 1b429e2a Iustin Pop
  @staticmethod
1714 1b429e2a Iustin Pop
  def _RaiseRetryAgain():
1715 1b429e2a Iustin Pop
    raise utils.RetryAgain()
1716 1b429e2a Iustin Pop
1717 506be7c5 Guido Trotter
  @staticmethod
1718 506be7c5 Guido Trotter
  def _RaiseRetryAgainWithArg(args):
1719 506be7c5 Guido Trotter
    raise utils.RetryAgain(*args)
1720 506be7c5 Guido Trotter
1721 1b429e2a Iustin Pop
  def _WrongNestedLoop(self):
1722 1b429e2a Iustin Pop
    return utils.Retry(self._RaiseRetryAgain, 0.01, 0.02)
1723 1b429e2a Iustin Pop
1724 45cc4913 Guido Trotter
  def _RetryAndSucceed(self, retries):
1725 45cc4913 Guido Trotter
    if self.retries < retries:
1726 45cc4913 Guido Trotter
      self.retries += 1
1727 45cc4913 Guido Trotter
      raise utils.RetryAgain()
1728 45cc4913 Guido Trotter
    else:
1729 45cc4913 Guido Trotter
      return True
1730 45cc4913 Guido Trotter
1731 1b429e2a Iustin Pop
  def testRaiseTimeout(self):
1732 1b429e2a Iustin Pop
    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
1733 1b429e2a Iustin Pop
                          self._RaiseRetryAgain, 0.01, 0.02)
1734 45cc4913 Guido Trotter
    self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
1735 45cc4913 Guido Trotter
                          self._RetryAndSucceed, 0.01, 0, args=[1])
1736 45cc4913 Guido Trotter
    self.failUnlessEqual(self.retries, 1)
1737 1b429e2a Iustin Pop
1738 1b429e2a Iustin Pop
  def testComplete(self):
1739 1b429e2a Iustin Pop
    self.failUnlessEqual(utils.Retry(lambda: True, 0, 1), True)
1740 45cc4913 Guido Trotter
    self.failUnlessEqual(utils.Retry(self._RetryAndSucceed, 0, 1, args=[2]),
1741 45cc4913 Guido Trotter
                         True)
1742 45cc4913 Guido Trotter
    self.failUnlessEqual(self.retries, 2)
1743 1b429e2a Iustin Pop
1744 1b429e2a Iustin Pop
  def testNestedLoop(self):
1745 1b429e2a Iustin Pop
    try:
1746 1b429e2a Iustin Pop
      self.failUnlessRaises(errors.ProgrammerError, utils.Retry,
1747 1b429e2a Iustin Pop
                            self._WrongNestedLoop, 0, 1)
1748 1b429e2a Iustin Pop
    except utils.RetryTimeout:
1749 1b429e2a Iustin Pop
      self.fail("Didn't detect inner loop's exception")
1750 1b429e2a Iustin Pop
1751 506be7c5 Guido Trotter
  def testTimeoutArgument(self):
1752 506be7c5 Guido Trotter
    retry_arg="my_important_debugging_message"
1753 506be7c5 Guido Trotter
    try:
1754 506be7c5 Guido Trotter
      utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02, args=[[retry_arg]])
1755 506be7c5 Guido Trotter
    except utils.RetryTimeout, err:
1756 506be7c5 Guido Trotter
      self.failUnlessEqual(err.args, (retry_arg, ))
1757 506be7c5 Guido Trotter
    else:
1758 506be7c5 Guido Trotter
      self.fail("Expected timeout didn't happen")
1759 506be7c5 Guido Trotter
1760 506be7c5 Guido Trotter
  def testRaiseInnerWithExc(self):
1761 506be7c5 Guido Trotter
    retry_arg="my_important_debugging_message"
1762 506be7c5 Guido Trotter
    try:
1763 506be7c5 Guido Trotter
      try:
1764 506be7c5 Guido Trotter
        utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02,
1765 506be7c5 Guido Trotter
                    args=[[errors.GenericError(retry_arg, retry_arg)]])
1766 506be7c5 Guido Trotter
      except utils.RetryTimeout, err:
1767 506be7c5 Guido Trotter
        err.RaiseInner()
1768 506be7c5 Guido Trotter
      else:
1769 506be7c5 Guido Trotter
        self.fail("Expected timeout didn't happen")
1770 506be7c5 Guido Trotter
    except errors.GenericError, err:
1771 506be7c5 Guido Trotter
      self.failUnlessEqual(err.args, (retry_arg, retry_arg))
1772 506be7c5 Guido Trotter
    else:
1773 506be7c5 Guido Trotter
      self.fail("Expected GenericError didn't happen")
1774 506be7c5 Guido Trotter
1775 506be7c5 Guido Trotter
  def testRaiseInnerWithMsg(self):
1776 506be7c5 Guido Trotter
    retry_arg="my_important_debugging_message"
1777 506be7c5 Guido Trotter
    try:
1778 506be7c5 Guido Trotter
      try:
1779 506be7c5 Guido Trotter
        utils.Retry(self._RaiseRetryAgainWithArg, 0.01, 0.02,
1780 506be7c5 Guido Trotter
                    args=[[retry_arg, retry_arg]])
1781 506be7c5 Guido Trotter
      except utils.RetryTimeout, err:
1782 506be7c5 Guido Trotter
        err.RaiseInner()
1783 506be7c5 Guido Trotter
      else:
1784 506be7c5 Guido Trotter
        self.fail("Expected timeout didn't happen")
1785 506be7c5 Guido Trotter
    except utils.RetryTimeout, err:
1786 506be7c5 Guido Trotter
      self.failUnlessEqual(err.args, (retry_arg, retry_arg))
1787 506be7c5 Guido Trotter
    else:
1788 506be7c5 Guido Trotter
      self.fail("Expected RetryTimeout didn't happen")
1789 506be7c5 Guido Trotter
1790 1b429e2a Iustin Pop
1791 339be5a8 Michael Hanselmann
class TestLineSplitter(unittest.TestCase):
1792 339be5a8 Michael Hanselmann
  def test(self):
1793 339be5a8 Michael Hanselmann
    lines = []
1794 339be5a8 Michael Hanselmann
    ls = utils.LineSplitter(lines.append)
1795 339be5a8 Michael Hanselmann
    ls.write("Hello World\n")
1796 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
1797 339be5a8 Michael Hanselmann
    ls.write("Foo\n Bar\r\n ")
1798 339be5a8 Michael Hanselmann
    ls.write("Baz")
1799 339be5a8 Michael Hanselmann
    ls.write("Moo")
1800 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
1801 339be5a8 Michael Hanselmann
    ls.flush()
1802 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["Hello World", "Foo", " Bar"])
1803 339be5a8 Michael Hanselmann
    ls.close()
1804 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["Hello World", "Foo", " Bar", " BazMoo"])
1805 339be5a8 Michael Hanselmann
1806 339be5a8 Michael Hanselmann
  def _testExtra(self, line, all_lines, p1, p2):
1807 339be5a8 Michael Hanselmann
    self.assertEqual(p1, 999)
1808 339be5a8 Michael Hanselmann
    self.assertEqual(p2, "extra")
1809 339be5a8 Michael Hanselmann
    all_lines.append(line)
1810 339be5a8 Michael Hanselmann
1811 339be5a8 Michael Hanselmann
  def testExtraArgsNoFlush(self):
1812 339be5a8 Michael Hanselmann
    lines = []
1813 339be5a8 Michael Hanselmann
    ls = utils.LineSplitter(self._testExtra, lines, 999, "extra")
1814 339be5a8 Michael Hanselmann
    ls.write("\n\nHello World\n")
1815 339be5a8 Michael Hanselmann
    ls.write("Foo\n Bar\r\n ")
1816 339be5a8 Michael Hanselmann
    ls.write("")
1817 339be5a8 Michael Hanselmann
    ls.write("Baz")
1818 339be5a8 Michael Hanselmann
    ls.write("Moo\n\nx\n")
1819 339be5a8 Michael Hanselmann
    self.assertEqual(lines, [])
1820 339be5a8 Michael Hanselmann
    ls.close()
1821 339be5a8 Michael Hanselmann
    self.assertEqual(lines, ["", "", "Hello World", "Foo", " Bar", " BazMoo",
1822 339be5a8 Michael Hanselmann
                             "", "x"])
1823 339be5a8 Michael Hanselmann
1824 339be5a8 Michael Hanselmann
1825 a8083063 Iustin Pop
if __name__ == '__main__':
1826 25231ec5 Michael Hanselmann
  testutils.GanetiTestProgram()