Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils.io_unittest.py @ 415feb2e

History | View | Annotate | Download (34 kB)

1 3865ca48 Michael Hanselmann
#!/usr/bin/python
2 3865ca48 Michael Hanselmann
#
3 3865ca48 Michael Hanselmann
4 3865ca48 Michael Hanselmann
# Copyright (C) 2006, 2007, 2010, 2011 Google Inc.
5 3865ca48 Michael Hanselmann
#
6 3865ca48 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 3865ca48 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 3865ca48 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 3865ca48 Michael Hanselmann
# (at your option) any later version.
10 3865ca48 Michael Hanselmann
#
11 3865ca48 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 3865ca48 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 3865ca48 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 3865ca48 Michael Hanselmann
# General Public License for more details.
15 3865ca48 Michael Hanselmann
#
16 3865ca48 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 3865ca48 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 3865ca48 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 3865ca48 Michael Hanselmann
# 02110-1301, USA.
20 3865ca48 Michael Hanselmann
21 3865ca48 Michael Hanselmann
22 3865ca48 Michael Hanselmann
"""Script for testing ganeti.utils.io"""
23 3865ca48 Michael Hanselmann
24 3865ca48 Michael Hanselmann
import os
25 3865ca48 Michael Hanselmann
import tempfile
26 3865ca48 Michael Hanselmann
import unittest
27 3865ca48 Michael Hanselmann
import shutil
28 3865ca48 Michael Hanselmann
import glob
29 3865ca48 Michael Hanselmann
import time
30 3ae8dd03 Michael Hanselmann
import signal
31 b81b3c96 René Nussbaumer
import stat
32 b81b3c96 René Nussbaumer
import errno
33 3865ca48 Michael Hanselmann
34 3865ca48 Michael Hanselmann
from ganeti import constants
35 3865ca48 Michael Hanselmann
from ganeti import utils
36 3865ca48 Michael Hanselmann
from ganeti import compat
37 3865ca48 Michael Hanselmann
from ganeti import errors
38 3865ca48 Michael Hanselmann
39 3865ca48 Michael Hanselmann
import testutils
40 3865ca48 Michael Hanselmann
41 3865ca48 Michael Hanselmann
42 3865ca48 Michael Hanselmann
class TestReadFile(testutils.GanetiTestCase):
43 3865ca48 Michael Hanselmann
  def testReadAll(self):
44 3865ca48 Michael Hanselmann
    data = utils.ReadFile(self._TestDataFilename("cert1.pem"))
45 3865ca48 Michael Hanselmann
    self.assertEqual(len(data), 814)
46 3865ca48 Michael Hanselmann
47 3865ca48 Michael Hanselmann
    h = compat.md5_hash()
48 3865ca48 Michael Hanselmann
    h.update(data)
49 3865ca48 Michael Hanselmann
    self.assertEqual(h.hexdigest(), "a491efb3efe56a0535f924d5f8680fd4")
50 3865ca48 Michael Hanselmann
51 3865ca48 Michael Hanselmann
  def testReadSize(self):
52 3865ca48 Michael Hanselmann
    data = utils.ReadFile(self._TestDataFilename("cert1.pem"),
53 3865ca48 Michael Hanselmann
                          size=100)
54 3865ca48 Michael Hanselmann
    self.assertEqual(len(data), 100)
55 3865ca48 Michael Hanselmann
56 3865ca48 Michael Hanselmann
    h = compat.md5_hash()
57 3865ca48 Michael Hanselmann
    h.update(data)
58 3865ca48 Michael Hanselmann
    self.assertEqual(h.hexdigest(), "893772354e4e690b9efd073eed433ce7")
59 3865ca48 Michael Hanselmann
60 0e5084ee Michael Hanselmann
  def testCallback(self):
61 0e5084ee Michael Hanselmann
    def _Cb(fh):
62 0e5084ee Michael Hanselmann
      self.assertEqual(fh.tell(), 0)
63 0e5084ee Michael Hanselmann
    data = utils.ReadFile(self._TestDataFilename("cert1.pem"), preread=_Cb)
64 0e5084ee Michael Hanselmann
    self.assertEqual(len(data), 814)
65 0e5084ee Michael Hanselmann
66 3865ca48 Michael Hanselmann
  def testError(self):
67 3865ca48 Michael Hanselmann
    self.assertRaises(EnvironmentError, utils.ReadFile,
68 3865ca48 Michael Hanselmann
                      "/dev/null/does-not-exist")
69 3865ca48 Michael Hanselmann
70 3865ca48 Michael Hanselmann
71 3865ca48 Michael Hanselmann
class TestReadOneLineFile(testutils.GanetiTestCase):
72 3865ca48 Michael Hanselmann
  def setUp(self):
73 3865ca48 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
74 3865ca48 Michael Hanselmann
75 3865ca48 Michael Hanselmann
  def testDefault(self):
76 3865ca48 Michael Hanselmann
    data = utils.ReadOneLineFile(self._TestDataFilename("cert1.pem"))
77 3865ca48 Michael Hanselmann
    self.assertEqual(len(data), 27)
78 3865ca48 Michael Hanselmann
    self.assertEqual(data, "-----BEGIN CERTIFICATE-----")
79 3865ca48 Michael Hanselmann
80 3865ca48 Michael Hanselmann
  def testNotStrict(self):
81 3865ca48 Michael Hanselmann
    data = utils.ReadOneLineFile(self._TestDataFilename("cert1.pem"),
82 3865ca48 Michael Hanselmann
                                 strict=False)
83 3865ca48 Michael Hanselmann
    self.assertEqual(len(data), 27)
84 3865ca48 Michael Hanselmann
    self.assertEqual(data, "-----BEGIN CERTIFICATE-----")
85 3865ca48 Michael Hanselmann
86 3865ca48 Michael Hanselmann
  def testStrictFailure(self):
87 3865ca48 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.ReadOneLineFile,
88 3865ca48 Michael Hanselmann
                      self._TestDataFilename("cert1.pem"), strict=True)
89 3865ca48 Michael Hanselmann
90 3865ca48 Michael Hanselmann
  def testLongLine(self):
91 3865ca48 Michael Hanselmann
    dummydata = (1024 * "Hello World! ")
92 3865ca48 Michael Hanselmann
    myfile = self._CreateTempFile()
93 3865ca48 Michael Hanselmann
    utils.WriteFile(myfile, data=dummydata)
94 3865ca48 Michael Hanselmann
    datastrict = utils.ReadOneLineFile(myfile, strict=True)
95 3865ca48 Michael Hanselmann
    datalax = utils.ReadOneLineFile(myfile, strict=False)
96 3865ca48 Michael Hanselmann
    self.assertEqual(dummydata, datastrict)
97 3865ca48 Michael Hanselmann
    self.assertEqual(dummydata, datalax)
98 3865ca48 Michael Hanselmann
99 3865ca48 Michael Hanselmann
  def testNewline(self):
100 3865ca48 Michael Hanselmann
    myfile = self._CreateTempFile()
101 3865ca48 Michael Hanselmann
    myline = "myline"
102 3865ca48 Michael Hanselmann
    for nl in ["", "\n", "\r\n"]:
103 3865ca48 Michael Hanselmann
      dummydata = "%s%s" % (myline, nl)
104 3865ca48 Michael Hanselmann
      utils.WriteFile(myfile, data=dummydata)
105 3865ca48 Michael Hanselmann
      datalax = utils.ReadOneLineFile(myfile, strict=False)
106 3865ca48 Michael Hanselmann
      self.assertEqual(myline, datalax)
107 3865ca48 Michael Hanselmann
      datastrict = utils.ReadOneLineFile(myfile, strict=True)
108 3865ca48 Michael Hanselmann
      self.assertEqual(myline, datastrict)
109 3865ca48 Michael Hanselmann
110 3865ca48 Michael Hanselmann
  def testWhitespaceAndMultipleLines(self):
111 3865ca48 Michael Hanselmann
    myfile = self._CreateTempFile()
112 3865ca48 Michael Hanselmann
    for nl in ["", "\n", "\r\n"]:
113 3865ca48 Michael Hanselmann
      for ws in [" ", "\t", "\t\t  \t", "\t "]:
114 3865ca48 Michael Hanselmann
        dummydata = (1024 * ("Foo bar baz %s%s" % (ws, nl)))
115 3865ca48 Michael Hanselmann
        utils.WriteFile(myfile, data=dummydata)
116 3865ca48 Michael Hanselmann
        datalax = utils.ReadOneLineFile(myfile, strict=False)
117 3865ca48 Michael Hanselmann
        if nl:
118 3865ca48 Michael Hanselmann
          self.assert_(set("\r\n") & set(dummydata))
119 3865ca48 Michael Hanselmann
          self.assertRaises(errors.GenericError, utils.ReadOneLineFile,
120 3865ca48 Michael Hanselmann
                            myfile, strict=True)
121 3865ca48 Michael Hanselmann
          explen = len("Foo bar baz ") + len(ws)
122 3865ca48 Michael Hanselmann
          self.assertEqual(len(datalax), explen)
123 3865ca48 Michael Hanselmann
          self.assertEqual(datalax, dummydata[:explen])
124 3865ca48 Michael Hanselmann
          self.assertFalse(set("\r\n") & set(datalax))
125 3865ca48 Michael Hanselmann
        else:
126 3865ca48 Michael Hanselmann
          datastrict = utils.ReadOneLineFile(myfile, strict=True)
127 3865ca48 Michael Hanselmann
          self.assertEqual(dummydata, datastrict)
128 3865ca48 Michael Hanselmann
          self.assertEqual(dummydata, datalax)
129 3865ca48 Michael Hanselmann
130 3865ca48 Michael Hanselmann
  def testEmptylines(self):
131 3865ca48 Michael Hanselmann
    myfile = self._CreateTempFile()
132 3865ca48 Michael Hanselmann
    myline = "myline"
133 3865ca48 Michael Hanselmann
    for nl in ["\n", "\r\n"]:
134 3865ca48 Michael Hanselmann
      for ol in ["", "otherline"]:
135 3865ca48 Michael Hanselmann
        dummydata = "%s%s%s%s%s%s" % (nl, nl, myline, nl, ol, nl)
136 3865ca48 Michael Hanselmann
        utils.WriteFile(myfile, data=dummydata)
137 3865ca48 Michael Hanselmann
        self.assert_(set("\r\n") & set(dummydata))
138 3865ca48 Michael Hanselmann
        datalax = utils.ReadOneLineFile(myfile, strict=False)
139 3865ca48 Michael Hanselmann
        self.assertEqual(myline, datalax)
140 3865ca48 Michael Hanselmann
        if ol:
141 3865ca48 Michael Hanselmann
          self.assertRaises(errors.GenericError, utils.ReadOneLineFile,
142 3865ca48 Michael Hanselmann
                            myfile, strict=True)
143 3865ca48 Michael Hanselmann
        else:
144 3865ca48 Michael Hanselmann
          datastrict = utils.ReadOneLineFile(myfile, strict=True)
145 3865ca48 Michael Hanselmann
          self.assertEqual(myline, datastrict)
146 3865ca48 Michael Hanselmann
147 3865ca48 Michael Hanselmann
  def testEmptyfile(self):
148 3865ca48 Michael Hanselmann
    myfile = self._CreateTempFile()
149 3865ca48 Michael Hanselmann
    self.assertRaises(errors.GenericError, utils.ReadOneLineFile, myfile)
150 3865ca48 Michael Hanselmann
151 3865ca48 Michael Hanselmann
152 3865ca48 Michael Hanselmann
class TestTimestampForFilename(unittest.TestCase):
153 3865ca48 Michael Hanselmann
  def test(self):
154 3865ca48 Michael Hanselmann
    self.assert_("." not in utils.TimestampForFilename())
155 3865ca48 Michael Hanselmann
    self.assert_(":" not in utils.TimestampForFilename())
156 3865ca48 Michael Hanselmann
157 3865ca48 Michael Hanselmann
158 3865ca48 Michael Hanselmann
class TestCreateBackup(testutils.GanetiTestCase):
159 3865ca48 Michael Hanselmann
  def setUp(self):
160 3865ca48 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
161 3865ca48 Michael Hanselmann
162 3865ca48 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
163 3865ca48 Michael Hanselmann
164 3865ca48 Michael Hanselmann
  def tearDown(self):
165 3865ca48 Michael Hanselmann
    testutils.GanetiTestCase.tearDown(self)
166 3865ca48 Michael Hanselmann
167 3865ca48 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
168 3865ca48 Michael Hanselmann
169 3865ca48 Michael Hanselmann
  def testEmpty(self):
170 3865ca48 Michael Hanselmann
    filename = utils.PathJoin(self.tmpdir, "config.data")
171 3865ca48 Michael Hanselmann
    utils.WriteFile(filename, data="")
172 3865ca48 Michael Hanselmann
    bname = utils.CreateBackup(filename)
173 3865ca48 Michael Hanselmann
    self.assertFileContent(bname, "")
174 3865ca48 Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 2)
175 3865ca48 Michael Hanselmann
    utils.CreateBackup(filename)
176 3865ca48 Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 3)
177 3865ca48 Michael Hanselmann
    utils.CreateBackup(filename)
178 3865ca48 Michael Hanselmann
    self.assertEqual(len(glob.glob("%s*" % filename)), 4)
179 3865ca48 Michael Hanselmann
180 3865ca48 Michael Hanselmann
    fifoname = utils.PathJoin(self.tmpdir, "fifo")
181 3865ca48 Michael Hanselmann
    os.mkfifo(fifoname)
182 3865ca48 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, utils.CreateBackup, fifoname)
183 3865ca48 Michael Hanselmann
184 3865ca48 Michael Hanselmann
  def testContent(self):
185 3865ca48 Michael Hanselmann
    bkpcount = 0
186 3865ca48 Michael Hanselmann
    for data in ["", "X", "Hello World!\n" * 100, "Binary data\0\x01\x02\n"]:
187 3865ca48 Michael Hanselmann
      for rep in [1, 2, 10, 127]:
188 3865ca48 Michael Hanselmann
        testdata = data * rep
189 3865ca48 Michael Hanselmann
190 3865ca48 Michael Hanselmann
        filename = utils.PathJoin(self.tmpdir, "test.data_")
191 3865ca48 Michael Hanselmann
        utils.WriteFile(filename, data=testdata)
192 3865ca48 Michael Hanselmann
        self.assertFileContent(filename, testdata)
193 3865ca48 Michael Hanselmann
194 3865ca48 Michael Hanselmann
        for _ in range(3):
195 3865ca48 Michael Hanselmann
          bname = utils.CreateBackup(filename)
196 3865ca48 Michael Hanselmann
          bkpcount += 1
197 3865ca48 Michael Hanselmann
          self.assertFileContent(bname, testdata)
198 3865ca48 Michael Hanselmann
          self.assertEqual(len(glob.glob("%s*" % filename)), 1 + bkpcount)
199 3865ca48 Michael Hanselmann
200 3865ca48 Michael Hanselmann
201 3865ca48 Michael Hanselmann
class TestListVisibleFiles(unittest.TestCase):
202 3865ca48 Michael Hanselmann
  """Test case for ListVisibleFiles"""
203 3865ca48 Michael Hanselmann
204 3865ca48 Michael Hanselmann
  def setUp(self):
205 3865ca48 Michael Hanselmann
    self.path = tempfile.mkdtemp()
206 3865ca48 Michael Hanselmann
207 3865ca48 Michael Hanselmann
  def tearDown(self):
208 3865ca48 Michael Hanselmann
    shutil.rmtree(self.path)
209 3865ca48 Michael Hanselmann
210 3865ca48 Michael Hanselmann
  def _CreateFiles(self, files):
211 3865ca48 Michael Hanselmann
    for name in files:
212 3865ca48 Michael Hanselmann
      utils.WriteFile(os.path.join(self.path, name), data="test")
213 3865ca48 Michael Hanselmann
214 3865ca48 Michael Hanselmann
  def _test(self, files, expected):
215 3865ca48 Michael Hanselmann
    self._CreateFiles(files)
216 3865ca48 Michael Hanselmann
    found = utils.ListVisibleFiles(self.path)
217 3865ca48 Michael Hanselmann
    self.assertEqual(set(found), set(expected))
218 3865ca48 Michael Hanselmann
219 3865ca48 Michael Hanselmann
  def testAllVisible(self):
220 3865ca48 Michael Hanselmann
    files = ["a", "b", "c"]
221 3865ca48 Michael Hanselmann
    expected = files
222 3865ca48 Michael Hanselmann
    self._test(files, expected)
223 3865ca48 Michael Hanselmann
224 3865ca48 Michael Hanselmann
  def testNoneVisible(self):
225 3865ca48 Michael Hanselmann
    files = [".a", ".b", ".c"]
226 3865ca48 Michael Hanselmann
    expected = []
227 3865ca48 Michael Hanselmann
    self._test(files, expected)
228 3865ca48 Michael Hanselmann
229 3865ca48 Michael Hanselmann
  def testSomeVisible(self):
230 3865ca48 Michael Hanselmann
    files = ["a", "b", ".c"]
231 3865ca48 Michael Hanselmann
    expected = ["a", "b"]
232 3865ca48 Michael Hanselmann
    self._test(files, expected)
233 3865ca48 Michael Hanselmann
234 3865ca48 Michael Hanselmann
  def testNonAbsolutePath(self):
235 3865ca48 Michael Hanselmann
    self.failUnlessRaises(errors.ProgrammerError, utils.ListVisibleFiles,
236 3865ca48 Michael Hanselmann
                          "abc")
237 3865ca48 Michael Hanselmann
238 3865ca48 Michael Hanselmann
  def testNonNormalizedPath(self):
239 3865ca48 Michael Hanselmann
    self.failUnlessRaises(errors.ProgrammerError, utils.ListVisibleFiles,
240 3865ca48 Michael Hanselmann
                          "/bin/../tmp")
241 3865ca48 Michael Hanselmann
242 2dbc6857 Michael Hanselmann
  def testMountpoint(self):
243 2dbc6857 Michael Hanselmann
    lvfmp_fn = compat.partial(utils.ListVisibleFiles,
244 2dbc6857 Michael Hanselmann
                              _is_mountpoint=lambda _: True)
245 2dbc6857 Michael Hanselmann
    self.assertEqual(lvfmp_fn(self.path), [])
246 2dbc6857 Michael Hanselmann
247 2dbc6857 Michael Hanselmann
    # Create "lost+found" as a regular file
248 2dbc6857 Michael Hanselmann
    self._CreateFiles(["foo", "bar", ".baz", "lost+found"])
249 2dbc6857 Michael Hanselmann
    self.assertEqual(set(lvfmp_fn(self.path)),
250 2dbc6857 Michael Hanselmann
                     set(["foo", "bar", "lost+found"]))
251 2dbc6857 Michael Hanselmann
252 2dbc6857 Michael Hanselmann
    # Replace "lost+found" with a directory
253 2dbc6857 Michael Hanselmann
    laf_path = utils.PathJoin(self.path, "lost+found")
254 2dbc6857 Michael Hanselmann
    utils.RemoveFile(laf_path)
255 2dbc6857 Michael Hanselmann
    os.mkdir(laf_path)
256 2dbc6857 Michael Hanselmann
    self.assertEqual(set(lvfmp_fn(self.path)), set(["foo", "bar"]))
257 2dbc6857 Michael Hanselmann
258 2dbc6857 Michael Hanselmann
  def testLostAndFoundNoMountpoint(self):
259 2dbc6857 Michael Hanselmann
    files = ["foo", "bar", ".Hello World", "lost+found"]
260 2dbc6857 Michael Hanselmann
    expected = ["foo", "bar", "lost+found"]
261 2dbc6857 Michael Hanselmann
    self._test(files, expected)
262 2dbc6857 Michael Hanselmann
263 3865ca48 Michael Hanselmann
264 fd6eaa09 Bernardo Dal Seno
class TestWriteFile(testutils.GanetiTestCase):
265 3865ca48 Michael Hanselmann
  def setUp(self):
266 fd6eaa09 Bernardo Dal Seno
    testutils.GanetiTestCase.setUp(self)
267 a9d68e40 Michael Hanselmann
    self.tmpdir = None
268 3865ca48 Michael Hanselmann
    self.tfile = tempfile.NamedTemporaryFile()
269 3865ca48 Michael Hanselmann
    self.did_pre = False
270 3865ca48 Michael Hanselmann
    self.did_post = False
271 3865ca48 Michael Hanselmann
    self.did_write = False
272 3865ca48 Michael Hanselmann
273 a9d68e40 Michael Hanselmann
  def tearDown(self):
274 fd6eaa09 Bernardo Dal Seno
    testutils.GanetiTestCase.tearDown(self)
275 a9d68e40 Michael Hanselmann
    if self.tmpdir:
276 a9d68e40 Michael Hanselmann
      shutil.rmtree(self.tmpdir)
277 a9d68e40 Michael Hanselmann
278 3865ca48 Michael Hanselmann
  def markPre(self, fd):
279 3865ca48 Michael Hanselmann
    self.did_pre = True
280 3865ca48 Michael Hanselmann
281 3865ca48 Michael Hanselmann
  def markPost(self, fd):
282 3865ca48 Michael Hanselmann
    self.did_post = True
283 3865ca48 Michael Hanselmann
284 3865ca48 Michael Hanselmann
  def markWrite(self, fd):
285 3865ca48 Michael Hanselmann
    self.did_write = True
286 3865ca48 Michael Hanselmann
287 3865ca48 Michael Hanselmann
  def testWrite(self):
288 3865ca48 Michael Hanselmann
    data = "abc"
289 3865ca48 Michael Hanselmann
    utils.WriteFile(self.tfile.name, data=data)
290 3865ca48 Michael Hanselmann
    self.assertEqual(utils.ReadFile(self.tfile.name), data)
291 3865ca48 Michael Hanselmann
292 1d39e245 Iustin Pop
  def testWriteSimpleUnicode(self):
293 1d39e245 Iustin Pop
    data = u"abc"
294 1d39e245 Iustin Pop
    utils.WriteFile(self.tfile.name, data=data)
295 1d39e245 Iustin Pop
    self.assertEqual(utils.ReadFile(self.tfile.name), data)
296 1d39e245 Iustin Pop
297 3865ca48 Michael Hanselmann
  def testErrors(self):
298 3865ca48 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, utils.WriteFile,
299 3865ca48 Michael Hanselmann
                      self.tfile.name, data="test", fn=lambda fd: None)
300 3865ca48 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, utils.WriteFile, self.tfile.name)
301 3865ca48 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, utils.WriteFile,
302 3865ca48 Michael Hanselmann
                      self.tfile.name, data="test", atime=0)
303 fd6eaa09 Bernardo Dal Seno
    self.assertRaises(errors.ProgrammerError, utils.WriteFile, self.tfile.name,
304 fd6eaa09 Bernardo Dal Seno
                      mode=0400, keep_perms=utils.KP_ALWAYS)
305 fd6eaa09 Bernardo Dal Seno
    self.assertRaises(errors.ProgrammerError, utils.WriteFile, self.tfile.name,
306 fd6eaa09 Bernardo Dal Seno
                      uid=0, keep_perms=utils.KP_ALWAYS)
307 fd6eaa09 Bernardo Dal Seno
    self.assertRaises(errors.ProgrammerError, utils.WriteFile, self.tfile.name,
308 fd6eaa09 Bernardo Dal Seno
                      gid=0, keep_perms=utils.KP_ALWAYS)
309 fd6eaa09 Bernardo Dal Seno
    self.assertRaises(errors.ProgrammerError, utils.WriteFile, self.tfile.name,
310 fd6eaa09 Bernardo Dal Seno
                      mode=0400, uid=0, keep_perms=utils.KP_ALWAYS)
311 3865ca48 Michael Hanselmann
312 a9d68e40 Michael Hanselmann
  def testPreWrite(self):
313 a9d68e40 Michael Hanselmann
    utils.WriteFile(self.tfile.name, data="", prewrite=self.markPre)
314 3865ca48 Michael Hanselmann
    self.assertTrue(self.did_pre)
315 a9d68e40 Michael Hanselmann
    self.assertFalse(self.did_post)
316 a9d68e40 Michael Hanselmann
    self.assertFalse(self.did_write)
317 a9d68e40 Michael Hanselmann
318 a9d68e40 Michael Hanselmann
  def testPostWrite(self):
319 a9d68e40 Michael Hanselmann
    utils.WriteFile(self.tfile.name, data="", postwrite=self.markPost)
320 a9d68e40 Michael Hanselmann
    self.assertFalse(self.did_pre)
321 3865ca48 Michael Hanselmann
    self.assertTrue(self.did_post)
322 a9d68e40 Michael Hanselmann
    self.assertFalse(self.did_write)
323 a9d68e40 Michael Hanselmann
324 a9d68e40 Michael Hanselmann
  def testWriteFunction(self):
325 a9d68e40 Michael Hanselmann
    utils.WriteFile(self.tfile.name, fn=self.markWrite)
326 a9d68e40 Michael Hanselmann
    self.assertFalse(self.did_pre)
327 a9d68e40 Michael Hanselmann
    self.assertFalse(self.did_post)
328 3865ca48 Michael Hanselmann
    self.assertTrue(self.did_write)
329 3865ca48 Michael Hanselmann
330 3865ca48 Michael Hanselmann
  def testDryRun(self):
331 3865ca48 Michael Hanselmann
    orig = "abc"
332 3865ca48 Michael Hanselmann
    self.tfile.write(orig)
333 3865ca48 Michael Hanselmann
    self.tfile.flush()
334 3865ca48 Michael Hanselmann
    utils.WriteFile(self.tfile.name, data="hello", dry_run=True)
335 3865ca48 Michael Hanselmann
    self.assertEqual(utils.ReadFile(self.tfile.name), orig)
336 3865ca48 Michael Hanselmann
337 3865ca48 Michael Hanselmann
  def testTimes(self):
338 3865ca48 Michael Hanselmann
    f = self.tfile.name
339 3865ca48 Michael Hanselmann
    for at, mt in [(0, 0), (1000, 1000), (2000, 3000),
340 3865ca48 Michael Hanselmann
                   (int(time.time()), 5000)]:
341 3865ca48 Michael Hanselmann
      utils.WriteFile(f, data="hello", atime=at, mtime=mt)
342 3865ca48 Michael Hanselmann
      st = os.stat(f)
343 3865ca48 Michael Hanselmann
      self.assertEqual(st.st_atime, at)
344 3865ca48 Michael Hanselmann
      self.assertEqual(st.st_mtime, mt)
345 3865ca48 Michael Hanselmann
346 3865ca48 Michael Hanselmann
  def testNoClose(self):
347 3865ca48 Michael Hanselmann
    data = "hello"
348 3865ca48 Michael Hanselmann
    self.assertEqual(utils.WriteFile(self.tfile.name, data="abc"), None)
349 3865ca48 Michael Hanselmann
    fd = utils.WriteFile(self.tfile.name, data=data, close=False)
350 3865ca48 Michael Hanselmann
    try:
351 3865ca48 Michael Hanselmann
      os.lseek(fd, 0, 0)
352 3865ca48 Michael Hanselmann
      self.assertEqual(os.read(fd, 4096), data)
353 3865ca48 Michael Hanselmann
    finally:
354 3865ca48 Michael Hanselmann
      os.close(fd)
355 3865ca48 Michael Hanselmann
356 a9d68e40 Michael Hanselmann
  def testNoLeftovers(self):
357 a9d68e40 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
358 a9d68e40 Michael Hanselmann
    self.assertEqual(utils.WriteFile(utils.PathJoin(self.tmpdir, "test"),
359 a9d68e40 Michael Hanselmann
                                     data="abc"),
360 a9d68e40 Michael Hanselmann
                     None)
361 a9d68e40 Michael Hanselmann
    self.assertEqual(os.listdir(self.tmpdir), ["test"])
362 a9d68e40 Michael Hanselmann
363 a9d68e40 Michael Hanselmann
  def testFailRename(self):
364 a9d68e40 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
365 a9d68e40 Michael Hanselmann
    target = utils.PathJoin(self.tmpdir, "target")
366 a9d68e40 Michael Hanselmann
    os.mkdir(target)
367 a9d68e40 Michael Hanselmann
    self.assertRaises(OSError, utils.WriteFile, target, data="abc")
368 a9d68e40 Michael Hanselmann
    self.assertTrue(os.path.isdir(target))
369 a9d68e40 Michael Hanselmann
    self.assertEqual(os.listdir(self.tmpdir), ["target"])
370 a9d68e40 Michael Hanselmann
    self.assertFalse(os.listdir(target))
371 a9d68e40 Michael Hanselmann
372 a9d68e40 Michael Hanselmann
  def testFailRenameDryRun(self):
373 a9d68e40 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
374 a9d68e40 Michael Hanselmann
    target = utils.PathJoin(self.tmpdir, "target")
375 a9d68e40 Michael Hanselmann
    os.mkdir(target)
376 a9d68e40 Michael Hanselmann
    self.assertEqual(utils.WriteFile(target, data="abc", dry_run=True), None)
377 a9d68e40 Michael Hanselmann
    self.assertTrue(os.path.isdir(target))
378 a9d68e40 Michael Hanselmann
    self.assertEqual(os.listdir(self.tmpdir), ["target"])
379 a9d68e40 Michael Hanselmann
    self.assertFalse(os.listdir(target))
380 a9d68e40 Michael Hanselmann
381 a9d68e40 Michael Hanselmann
  def testBackup(self):
382 a9d68e40 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
383 a9d68e40 Michael Hanselmann
    testfile = utils.PathJoin(self.tmpdir, "test")
384 a9d68e40 Michael Hanselmann
385 a9d68e40 Michael Hanselmann
    self.assertEqual(utils.WriteFile(testfile, data="foo", backup=True), None)
386 a9d68e40 Michael Hanselmann
    self.assertEqual(utils.ReadFile(testfile), "foo")
387 a9d68e40 Michael Hanselmann
    self.assertEqual(os.listdir(self.tmpdir), ["test"])
388 a9d68e40 Michael Hanselmann
389 a9d68e40 Michael Hanselmann
    # Write again
390 a9d68e40 Michael Hanselmann
    assert os.path.isfile(testfile)
391 a9d68e40 Michael Hanselmann
    self.assertEqual(utils.WriteFile(testfile, data="bar", backup=True), None)
392 a9d68e40 Michael Hanselmann
    self.assertEqual(utils.ReadFile(testfile), "bar")
393 a9d68e40 Michael Hanselmann
    self.assertEqual(len(glob.glob("%s.backup*" % testfile)), 1)
394 a9d68e40 Michael Hanselmann
    self.assertTrue("test" in os.listdir(self.tmpdir))
395 a9d68e40 Michael Hanselmann
    self.assertEqual(len(os.listdir(self.tmpdir)), 2)
396 a9d68e40 Michael Hanselmann
397 a9d68e40 Michael Hanselmann
    # Write again as dry-run
398 a9d68e40 Michael Hanselmann
    assert os.path.isfile(testfile)
399 a9d68e40 Michael Hanselmann
    self.assertEqual(utils.WriteFile(testfile, data="000", backup=True,
400 a9d68e40 Michael Hanselmann
                                     dry_run=True),
401 a9d68e40 Michael Hanselmann
                     None)
402 a9d68e40 Michael Hanselmann
    self.assertEqual(utils.ReadFile(testfile), "bar")
403 a9d68e40 Michael Hanselmann
    self.assertEqual(len(glob.glob("%s.backup*" % testfile)), 1)
404 a9d68e40 Michael Hanselmann
    self.assertTrue("test" in os.listdir(self.tmpdir))
405 a9d68e40 Michael Hanselmann
    self.assertEqual(len(os.listdir(self.tmpdir)), 2)
406 a9d68e40 Michael Hanselmann
407 fd6eaa09 Bernardo Dal Seno
  def testFileMode(self):
408 fd6eaa09 Bernardo Dal Seno
    self.tmpdir = tempfile.mkdtemp()
409 fd6eaa09 Bernardo Dal Seno
    target = utils.PathJoin(self.tmpdir, "target")
410 fd6eaa09 Bernardo Dal Seno
    self.assertRaises(OSError, utils.WriteFile, target, data="data",
411 fd6eaa09 Bernardo Dal Seno
                      keep_perms=utils.KP_ALWAYS)
412 fd6eaa09 Bernardo Dal Seno
    # All masks have only user bits set, to avoid interactions with umask
413 fd6eaa09 Bernardo Dal Seno
    utils.WriteFile(target, data="data", mode=0200)
414 fd6eaa09 Bernardo Dal Seno
    self.assertFileMode(target, 0200)
415 fd6eaa09 Bernardo Dal Seno
    utils.WriteFile(target, data="data", mode=0400,
416 fd6eaa09 Bernardo Dal Seno
                    keep_perms=utils.KP_IF_EXISTS)
417 fd6eaa09 Bernardo Dal Seno
    self.assertFileMode(target, 0200)
418 fd6eaa09 Bernardo Dal Seno
    utils.WriteFile(target, data="data", keep_perms=utils.KP_ALWAYS)
419 fd6eaa09 Bernardo Dal Seno
    self.assertFileMode(target, 0200)
420 fd6eaa09 Bernardo Dal Seno
    utils.WriteFile(target, data="data", mode=0700)
421 fd6eaa09 Bernardo Dal Seno
    self.assertFileMode(target, 0700)
422 fd6eaa09 Bernardo Dal Seno
423 fd6eaa09 Bernardo Dal Seno
  def testNewFileMode(self):
424 fd6eaa09 Bernardo Dal Seno
    self.tmpdir = tempfile.mkdtemp()
425 fd6eaa09 Bernardo Dal Seno
    target = utils.PathJoin(self.tmpdir, "target")
426 fd6eaa09 Bernardo Dal Seno
    utils.WriteFile(target, data="data", mode=0400,
427 fd6eaa09 Bernardo Dal Seno
                    keep_perms=utils.KP_IF_EXISTS)
428 fd6eaa09 Bernardo Dal Seno
    self.assertFileMode(target, 0400)
429 3865ca48 Michael Hanselmann
430 3865ca48 Michael Hanselmann
class TestFileID(testutils.GanetiTestCase):
431 3865ca48 Michael Hanselmann
  def testEquality(self):
432 3865ca48 Michael Hanselmann
    name = self._CreateTempFile()
433 3865ca48 Michael Hanselmann
    oldi = utils.GetFileID(path=name)
434 3865ca48 Michael Hanselmann
    self.failUnless(utils.VerifyFileID(oldi, oldi))
435 3865ca48 Michael Hanselmann
436 3865ca48 Michael Hanselmann
  def testUpdate(self):
437 3865ca48 Michael Hanselmann
    name = self._CreateTempFile()
438 3865ca48 Michael Hanselmann
    oldi = utils.GetFileID(path=name)
439 3865ca48 Michael Hanselmann
    fd = os.open(name, os.O_RDWR)
440 3865ca48 Michael Hanselmann
    try:
441 3865ca48 Michael Hanselmann
      newi = utils.GetFileID(fd=fd)
442 3865ca48 Michael Hanselmann
      self.failUnless(utils.VerifyFileID(oldi, newi))
443 3865ca48 Michael Hanselmann
      self.failUnless(utils.VerifyFileID(newi, oldi))
444 3865ca48 Michael Hanselmann
    finally:
445 3865ca48 Michael Hanselmann
      os.close(fd)
446 3865ca48 Michael Hanselmann
447 3865ca48 Michael Hanselmann
  def testWriteFile(self):
448 3865ca48 Michael Hanselmann
    name = self._CreateTempFile()
449 3865ca48 Michael Hanselmann
    oldi = utils.GetFileID(path=name)
450 3865ca48 Michael Hanselmann
    mtime = oldi[2]
451 3865ca48 Michael Hanselmann
    os.utime(name, (mtime + 10, mtime + 10))
452 3865ca48 Michael Hanselmann
    self.assertRaises(errors.LockError, utils.SafeWriteFile, name,
453 3865ca48 Michael Hanselmann
                      oldi, data="")
454 3865ca48 Michael Hanselmann
    os.utime(name, (mtime - 10, mtime - 10))
455 3865ca48 Michael Hanselmann
    utils.SafeWriteFile(name, oldi, data="")
456 3865ca48 Michael Hanselmann
    oldi = utils.GetFileID(path=name)
457 3865ca48 Michael Hanselmann
    mtime = oldi[2]
458 3865ca48 Michael Hanselmann
    os.utime(name, (mtime + 10, mtime + 10))
459 3865ca48 Michael Hanselmann
    # this doesn't raise, since we passed None
460 3865ca48 Michael Hanselmann
    utils.SafeWriteFile(name, None, data="")
461 3865ca48 Michael Hanselmann
462 3865ca48 Michael Hanselmann
  def testError(self):
463 3865ca48 Michael Hanselmann
    t = tempfile.NamedTemporaryFile()
464 3865ca48 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, utils.GetFileID,
465 3865ca48 Michael Hanselmann
                      path=t.name, fd=t.fileno())
466 3865ca48 Michael Hanselmann
467 3865ca48 Michael Hanselmann
468 3865ca48 Michael Hanselmann
class TestRemoveFile(unittest.TestCase):
469 3865ca48 Michael Hanselmann
  """Test case for the RemoveFile function"""
470 3865ca48 Michael Hanselmann
471 3865ca48 Michael Hanselmann
  def setUp(self):
472 3865ca48 Michael Hanselmann
    """Create a temp dir and file for each case"""
473 3865ca48 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp('', 'ganeti-unittest-')
474 3865ca48 Michael Hanselmann
    fd, self.tmpfile = tempfile.mkstemp('', '', self.tmpdir)
475 3865ca48 Michael Hanselmann
    os.close(fd)
476 3865ca48 Michael Hanselmann
477 3865ca48 Michael Hanselmann
  def tearDown(self):
478 3865ca48 Michael Hanselmann
    if os.path.exists(self.tmpfile):
479 3865ca48 Michael Hanselmann
      os.unlink(self.tmpfile)
480 3865ca48 Michael Hanselmann
    os.rmdir(self.tmpdir)
481 3865ca48 Michael Hanselmann
482 3865ca48 Michael Hanselmann
  def testIgnoreDirs(self):
483 3865ca48 Michael Hanselmann
    """Test that RemoveFile() ignores directories"""
484 3865ca48 Michael Hanselmann
    self.assertEqual(None, utils.RemoveFile(self.tmpdir))
485 3865ca48 Michael Hanselmann
486 3865ca48 Michael Hanselmann
  def testIgnoreNotExisting(self):
487 3865ca48 Michael Hanselmann
    """Test that RemoveFile() ignores non-existing files"""
488 3865ca48 Michael Hanselmann
    utils.RemoveFile(self.tmpfile)
489 3865ca48 Michael Hanselmann
    utils.RemoveFile(self.tmpfile)
490 3865ca48 Michael Hanselmann
491 3865ca48 Michael Hanselmann
  def testRemoveFile(self):
492 3865ca48 Michael Hanselmann
    """Test that RemoveFile does remove a file"""
493 3865ca48 Michael Hanselmann
    utils.RemoveFile(self.tmpfile)
494 3865ca48 Michael Hanselmann
    if os.path.exists(self.tmpfile):
495 3865ca48 Michael Hanselmann
      self.fail("File '%s' not removed" % self.tmpfile)
496 3865ca48 Michael Hanselmann
497 3865ca48 Michael Hanselmann
  def testRemoveSymlink(self):
498 3865ca48 Michael Hanselmann
    """Test that RemoveFile does remove symlinks"""
499 3865ca48 Michael Hanselmann
    symlink = self.tmpdir + "/symlink"
500 3865ca48 Michael Hanselmann
    os.symlink("no-such-file", symlink)
501 3865ca48 Michael Hanselmann
    utils.RemoveFile(symlink)
502 3865ca48 Michael Hanselmann
    if os.path.exists(symlink):
503 3865ca48 Michael Hanselmann
      self.fail("File '%s' not removed" % symlink)
504 3865ca48 Michael Hanselmann
    os.symlink(self.tmpfile, symlink)
505 3865ca48 Michael Hanselmann
    utils.RemoveFile(symlink)
506 3865ca48 Michael Hanselmann
    if os.path.exists(symlink):
507 3865ca48 Michael Hanselmann
      self.fail("File '%s' not removed" % symlink)
508 3865ca48 Michael Hanselmann
509 3865ca48 Michael Hanselmann
510 3865ca48 Michael Hanselmann
class TestRemoveDir(unittest.TestCase):
511 3865ca48 Michael Hanselmann
  def setUp(self):
512 3865ca48 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
513 3865ca48 Michael Hanselmann
514 3865ca48 Michael Hanselmann
  def tearDown(self):
515 3865ca48 Michael Hanselmann
    try:
516 3865ca48 Michael Hanselmann
      shutil.rmtree(self.tmpdir)
517 3865ca48 Michael Hanselmann
    except EnvironmentError:
518 3865ca48 Michael Hanselmann
      pass
519 3865ca48 Michael Hanselmann
520 3865ca48 Michael Hanselmann
  def testEmptyDir(self):
521 3865ca48 Michael Hanselmann
    utils.RemoveDir(self.tmpdir)
522 3865ca48 Michael Hanselmann
    self.assertFalse(os.path.isdir(self.tmpdir))
523 3865ca48 Michael Hanselmann
524 3865ca48 Michael Hanselmann
  def testNonEmptyDir(self):
525 3865ca48 Michael Hanselmann
    self.tmpfile = os.path.join(self.tmpdir, "test1")
526 3865ca48 Michael Hanselmann
    open(self.tmpfile, "w").close()
527 3865ca48 Michael Hanselmann
    self.assertRaises(EnvironmentError, utils.RemoveDir, self.tmpdir)
528 3865ca48 Michael Hanselmann
529 3865ca48 Michael Hanselmann
530 3865ca48 Michael Hanselmann
class TestRename(unittest.TestCase):
531 3865ca48 Michael Hanselmann
  """Test case for RenameFile"""
532 3865ca48 Michael Hanselmann
533 3865ca48 Michael Hanselmann
  def setUp(self):
534 3865ca48 Michael Hanselmann
    """Create a temporary directory"""
535 3865ca48 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
536 3865ca48 Michael Hanselmann
    self.tmpfile = os.path.join(self.tmpdir, "test1")
537 3865ca48 Michael Hanselmann
538 3865ca48 Michael Hanselmann
    # Touch the file
539 3865ca48 Michael Hanselmann
    open(self.tmpfile, "w").close()
540 3865ca48 Michael Hanselmann
541 3865ca48 Michael Hanselmann
  def tearDown(self):
542 3865ca48 Michael Hanselmann
    """Remove temporary directory"""
543 3865ca48 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
544 3865ca48 Michael Hanselmann
545 3865ca48 Michael Hanselmann
  def testSimpleRename1(self):
546 3865ca48 Michael Hanselmann
    """Simple rename 1"""
547 3865ca48 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"))
548 3865ca48 Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "xyz")))
549 3865ca48 Michael Hanselmann
550 3865ca48 Michael Hanselmann
  def testSimpleRename2(self):
551 3865ca48 Michael Hanselmann
    """Simple rename 2"""
552 3865ca48 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"),
553 3865ca48 Michael Hanselmann
                     mkdir=True)
554 3865ca48 Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "xyz")))
555 3865ca48 Michael Hanselmann
556 3865ca48 Michael Hanselmann
  def testRenameMkdir(self):
557 3865ca48 Michael Hanselmann
    """Rename with mkdir"""
558 3865ca48 Michael Hanselmann
    utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "test/xyz"),
559 3865ca48 Michael Hanselmann
                     mkdir=True)
560 3865ca48 Michael Hanselmann
    self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test")))
561 3865ca48 Michael Hanselmann
    self.assert_(os.path.isfile(os.path.join(self.tmpdir, "test/xyz")))
562 3865ca48 Michael Hanselmann
563 9c2b3a70 René Nussbaumer
    self.assertRaises(EnvironmentError, utils.RenameFile,
564 9c2b3a70 René Nussbaumer
                      os.path.join(self.tmpdir, "test/xyz"),
565 9c2b3a70 René Nussbaumer
                      os.path.join(self.tmpdir, "test/foo/bar/baz"),
566 9c2b3a70 René Nussbaumer
                      mkdir=True)
567 9c2b3a70 René Nussbaumer
568 9c2b3a70 René Nussbaumer
    self.assertTrue(os.path.exists(os.path.join(self.tmpdir, "test/xyz")))
569 9c2b3a70 René Nussbaumer
    self.assertFalse(os.path.exists(os.path.join(self.tmpdir, "test/foo/bar")))
570 b355affb René Nussbaumer
    self.assertFalse(os.path.exists(os.path.join(self.tmpdir,
571 b355affb René Nussbaumer
                                                 "test/foo/bar/baz")))
572 3865ca48 Michael Hanselmann
573 3865ca48 Michael Hanselmann
574 3865ca48 Michael Hanselmann
class TestMakedirs(unittest.TestCase):
575 3865ca48 Michael Hanselmann
  def setUp(self):
576 3865ca48 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
577 3865ca48 Michael Hanselmann
578 3865ca48 Michael Hanselmann
  def tearDown(self):
579 3865ca48 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
580 3865ca48 Michael Hanselmann
581 3865ca48 Michael Hanselmann
  def testNonExisting(self):
582 3865ca48 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "foo")
583 3865ca48 Michael Hanselmann
    utils.Makedirs(path)
584 3865ca48 Michael Hanselmann
    self.assert_(os.path.isdir(path))
585 3865ca48 Michael Hanselmann
586 3865ca48 Michael Hanselmann
  def testExisting(self):
587 3865ca48 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "foo")
588 3865ca48 Michael Hanselmann
    os.mkdir(path)
589 3865ca48 Michael Hanselmann
    utils.Makedirs(path)
590 3865ca48 Michael Hanselmann
    self.assert_(os.path.isdir(path))
591 3865ca48 Michael Hanselmann
592 3865ca48 Michael Hanselmann
  def testRecursiveNonExisting(self):
593 3865ca48 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "foo/bar/baz")
594 3865ca48 Michael Hanselmann
    utils.Makedirs(path)
595 3865ca48 Michael Hanselmann
    self.assert_(os.path.isdir(path))
596 3865ca48 Michael Hanselmann
597 3865ca48 Michael Hanselmann
  def testRecursiveExisting(self):
598 3865ca48 Michael Hanselmann
    path = utils.PathJoin(self.tmpdir, "B/moo/xyz")
599 3865ca48 Michael Hanselmann
    self.assertFalse(os.path.exists(path))
600 3865ca48 Michael Hanselmann
    os.mkdir(utils.PathJoin(self.tmpdir, "B"))
601 3865ca48 Michael Hanselmann
    utils.Makedirs(path)
602 3865ca48 Michael Hanselmann
    self.assert_(os.path.isdir(path))
603 3865ca48 Michael Hanselmann
604 3865ca48 Michael Hanselmann
605 3865ca48 Michael Hanselmann
class TestEnsureDirs(unittest.TestCase):
606 3865ca48 Michael Hanselmann
  """Tests for EnsureDirs"""
607 3865ca48 Michael Hanselmann
608 3865ca48 Michael Hanselmann
  def setUp(self):
609 3865ca48 Michael Hanselmann
    self.dir = tempfile.mkdtemp()
610 3865ca48 Michael Hanselmann
    self.old_umask = os.umask(0777)
611 3865ca48 Michael Hanselmann
612 3865ca48 Michael Hanselmann
  def testEnsureDirs(self):
613 3865ca48 Michael Hanselmann
    utils.EnsureDirs([
614 3865ca48 Michael Hanselmann
        (utils.PathJoin(self.dir, "foo"), 0777),
615 3865ca48 Michael Hanselmann
        (utils.PathJoin(self.dir, "bar"), 0000),
616 3865ca48 Michael Hanselmann
        ])
617 3865ca48 Michael Hanselmann
    self.assertEquals(os.stat(utils.PathJoin(self.dir, "foo"))[0] & 0777, 0777)
618 3865ca48 Michael Hanselmann
    self.assertEquals(os.stat(utils.PathJoin(self.dir, "bar"))[0] & 0777, 0000)
619 3865ca48 Michael Hanselmann
620 3865ca48 Michael Hanselmann
  def tearDown(self):
621 3865ca48 Michael Hanselmann
    os.rmdir(utils.PathJoin(self.dir, "foo"))
622 3865ca48 Michael Hanselmann
    os.rmdir(utils.PathJoin(self.dir, "bar"))
623 3865ca48 Michael Hanselmann
    os.rmdir(self.dir)
624 3865ca48 Michael Hanselmann
    os.umask(self.old_umask)
625 3865ca48 Michael Hanselmann
626 3865ca48 Michael Hanselmann
627 3865ca48 Michael Hanselmann
class TestIsNormAbsPath(unittest.TestCase):
628 3865ca48 Michael Hanselmann
  """Testing case for IsNormAbsPath"""
629 3865ca48 Michael Hanselmann
630 3865ca48 Michael Hanselmann
  def _pathTestHelper(self, path, result):
631 3865ca48 Michael Hanselmann
    if result:
632 3865ca48 Michael Hanselmann
      self.assert_(utils.IsNormAbsPath(path),
633 3865ca48 Michael Hanselmann
          "Path %s should result absolute and normalized" % path)
634 3865ca48 Michael Hanselmann
    else:
635 3865ca48 Michael Hanselmann
      self.assertFalse(utils.IsNormAbsPath(path),
636 3865ca48 Michael Hanselmann
          "Path %s should not result absolute and normalized" % path)
637 3865ca48 Michael Hanselmann
638 3865ca48 Michael Hanselmann
  def testBase(self):
639 3865ca48 Michael Hanselmann
    self._pathTestHelper("/etc", True)
640 3865ca48 Michael Hanselmann
    self._pathTestHelper("/srv", True)
641 3865ca48 Michael Hanselmann
    self._pathTestHelper("etc", False)
642 3865ca48 Michael Hanselmann
    self._pathTestHelper("/etc/../root", False)
643 3865ca48 Michael Hanselmann
    self._pathTestHelper("/etc/", False)
644 3865ca48 Michael Hanselmann
645 3865ca48 Michael Hanselmann
646 fb17bebd René Nussbaumer
class TestIsBelowDir(unittest.TestCase):
647 fb17bebd René Nussbaumer
  """Testing case for IsBelowDir"""
648 fb17bebd René Nussbaumer
649 fb17bebd René Nussbaumer
  def testSamePrefix(self):
650 fb17bebd René Nussbaumer
    self.assertTrue(utils.IsBelowDir("/a/b", "/a/b/c"))
651 fb17bebd René Nussbaumer
    self.assertTrue(utils.IsBelowDir("/a/b/", "/a/b/e"))
652 fb17bebd René Nussbaumer
653 fb17bebd René Nussbaumer
  def testSamePrefixButDifferentDir(self):
654 fb17bebd René Nussbaumer
    self.assertFalse(utils.IsBelowDir("/a/b", "/a/bc/d"))
655 fb17bebd René Nussbaumer
    self.assertFalse(utils.IsBelowDir("/a/b/", "/a/bc/e"))
656 fb17bebd René Nussbaumer
657 fb17bebd René Nussbaumer
  def testSamePrefixButDirTraversal(self):
658 fb17bebd René Nussbaumer
    self.assertFalse(utils.IsBelowDir("/a/b", "/a/b/../c"))
659 fb17bebd René Nussbaumer
    self.assertFalse(utils.IsBelowDir("/a/b/", "/a/b/../d"))
660 fb17bebd René Nussbaumer
661 fb17bebd René Nussbaumer
  def testSamePrefixAndTraversal(self):
662 fb17bebd René Nussbaumer
    self.assertTrue(utils.IsBelowDir("/a/b", "/a/b/c/../d"))
663 fb17bebd René Nussbaumer
    self.assertTrue(utils.IsBelowDir("/a/b", "/a/b/c/./e"))
664 fb17bebd René Nussbaumer
    self.assertTrue(utils.IsBelowDir("/a/b", "/a/b/../b/./e"))
665 fb17bebd René Nussbaumer
666 fb17bebd René Nussbaumer
  def testBothAbsPath(self):
667 fb17bebd René Nussbaumer
    self.assertRaises(ValueError, utils.IsBelowDir, "/a/b/c", "d")
668 fb17bebd René Nussbaumer
    self.assertRaises(ValueError, utils.IsBelowDir, "a/b/c", "/d")
669 fb17bebd René Nussbaumer
    self.assertRaises(ValueError, utils.IsBelowDir, "a/b/c", "d")
670 fb17bebd René Nussbaumer
671 fb17bebd René Nussbaumer
672 3865ca48 Michael Hanselmann
class TestPathJoin(unittest.TestCase):
673 3865ca48 Michael Hanselmann
  """Testing case for PathJoin"""
674 3865ca48 Michael Hanselmann
675 3865ca48 Michael Hanselmann
  def testBasicItems(self):
676 3865ca48 Michael Hanselmann
    mlist = ["/a", "b", "c"]
677 3865ca48 Michael Hanselmann
    self.failUnlessEqual(utils.PathJoin(*mlist), "/".join(mlist))
678 3865ca48 Michael Hanselmann
679 3865ca48 Michael Hanselmann
  def testNonAbsPrefix(self):
680 3865ca48 Michael Hanselmann
    self.failUnlessRaises(ValueError, utils.PathJoin, "a", "b")
681 3865ca48 Michael Hanselmann
682 3865ca48 Michael Hanselmann
  def testBackTrack(self):
683 3865ca48 Michael Hanselmann
    self.failUnlessRaises(ValueError, utils.PathJoin, "/a", "b/../c")
684 3865ca48 Michael Hanselmann
685 3865ca48 Michael Hanselmann
  def testMultiAbs(self):
686 3865ca48 Michael Hanselmann
    self.failUnlessRaises(ValueError, utils.PathJoin, "/a", "/b")
687 3865ca48 Michael Hanselmann
688 3865ca48 Michael Hanselmann
689 3865ca48 Michael Hanselmann
class TestTailFile(testutils.GanetiTestCase):
690 3865ca48 Michael Hanselmann
  """Test case for the TailFile function"""
691 3865ca48 Michael Hanselmann
692 3865ca48 Michael Hanselmann
  def testEmpty(self):
693 3865ca48 Michael Hanselmann
    fname = self._CreateTempFile()
694 3865ca48 Michael Hanselmann
    self.failUnlessEqual(utils.TailFile(fname), [])
695 3865ca48 Michael Hanselmann
    self.failUnlessEqual(utils.TailFile(fname, lines=25), [])
696 3865ca48 Michael Hanselmann
697 3865ca48 Michael Hanselmann
  def testAllLines(self):
698 3865ca48 Michael Hanselmann
    data = ["test %d" % i for i in range(30)]
699 3865ca48 Michael Hanselmann
    for i in range(30):
700 3865ca48 Michael Hanselmann
      fname = self._CreateTempFile()
701 3865ca48 Michael Hanselmann
      fd = open(fname, "w")
702 3865ca48 Michael Hanselmann
      fd.write("\n".join(data[:i]))
703 3865ca48 Michael Hanselmann
      if i > 0:
704 3865ca48 Michael Hanselmann
        fd.write("\n")
705 3865ca48 Michael Hanselmann
      fd.close()
706 3865ca48 Michael Hanselmann
      self.failUnlessEqual(utils.TailFile(fname, lines=i), data[:i])
707 3865ca48 Michael Hanselmann
708 3865ca48 Michael Hanselmann
  def testPartialLines(self):
709 3865ca48 Michael Hanselmann
    data = ["test %d" % i for i in range(30)]
710 3865ca48 Michael Hanselmann
    fname = self._CreateTempFile()
711 3865ca48 Michael Hanselmann
    fd = open(fname, "w")
712 3865ca48 Michael Hanselmann
    fd.write("\n".join(data))
713 3865ca48 Michael Hanselmann
    fd.write("\n")
714 3865ca48 Michael Hanselmann
    fd.close()
715 3865ca48 Michael Hanselmann
    for i in range(1, 30):
716 3865ca48 Michael Hanselmann
      self.failUnlessEqual(utils.TailFile(fname, lines=i), data[-i:])
717 3865ca48 Michael Hanselmann
718 3865ca48 Michael Hanselmann
  def testBigFile(self):
719 3865ca48 Michael Hanselmann
    data = ["test %d" % i for i in range(30)]
720 3865ca48 Michael Hanselmann
    fname = self._CreateTempFile()
721 3865ca48 Michael Hanselmann
    fd = open(fname, "w")
722 3865ca48 Michael Hanselmann
    fd.write("X" * 1048576)
723 3865ca48 Michael Hanselmann
    fd.write("\n")
724 3865ca48 Michael Hanselmann
    fd.write("\n".join(data))
725 3865ca48 Michael Hanselmann
    fd.write("\n")
726 3865ca48 Michael Hanselmann
    fd.close()
727 3865ca48 Michael Hanselmann
    for i in range(1, 30):
728 3865ca48 Michael Hanselmann
      self.failUnlessEqual(utils.TailFile(fname, lines=i), data[-i:])
729 3865ca48 Michael Hanselmann
730 3865ca48 Michael Hanselmann
731 3865ca48 Michael Hanselmann
class TestPidFileFunctions(unittest.TestCase):
732 79b60c1c Michael Hanselmann
  """Tests for WritePidFile and ReadPidFile"""
733 3865ca48 Michael Hanselmann
734 3865ca48 Michael Hanselmann
  def setUp(self):
735 3865ca48 Michael Hanselmann
    self.dir = tempfile.mkdtemp()
736 3865ca48 Michael Hanselmann
    self.f_dpn = lambda name: os.path.join(self.dir, "%s.pid" % name)
737 3865ca48 Michael Hanselmann
738 3865ca48 Michael Hanselmann
  def testPidFileFunctions(self):
739 3865ca48 Michael Hanselmann
    pid_file = self.f_dpn('test')
740 3865ca48 Michael Hanselmann
    fd = utils.WritePidFile(self.f_dpn('test'))
741 3865ca48 Michael Hanselmann
    self.failUnless(os.path.exists(pid_file),
742 3865ca48 Michael Hanselmann
                    "PID file should have been created")
743 3865ca48 Michael Hanselmann
    read_pid = utils.ReadPidFile(pid_file)
744 3865ca48 Michael Hanselmann
    self.failUnlessEqual(read_pid, os.getpid())
745 3865ca48 Michael Hanselmann
    self.failUnless(utils.IsProcessAlive(read_pid))
746 b6522276 Michael Hanselmann
    self.failUnlessRaises(errors.PidFileLockError, utils.WritePidFile,
747 3865ca48 Michael Hanselmann
                          self.f_dpn('test'))
748 3865ca48 Michael Hanselmann
    os.close(fd)
749 79b60c1c Michael Hanselmann
    utils.RemoveFile(self.f_dpn("test"))
750 3865ca48 Michael Hanselmann
    self.failIf(os.path.exists(pid_file),
751 3865ca48 Michael Hanselmann
                "PID file should not exist anymore")
752 3865ca48 Michael Hanselmann
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
753 3865ca48 Michael Hanselmann
                         "ReadPidFile should return 0 for missing pid file")
754 3865ca48 Michael Hanselmann
    fh = open(pid_file, "w")
755 3865ca48 Michael Hanselmann
    fh.write("blah\n")
756 3865ca48 Michael Hanselmann
    fh.close()
757 3865ca48 Michael Hanselmann
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
758 3865ca48 Michael Hanselmann
                         "ReadPidFile should return 0 for invalid pid file")
759 3865ca48 Michael Hanselmann
    # but now, even with the file existing, we should be able to lock it
760 3865ca48 Michael Hanselmann
    fd = utils.WritePidFile(self.f_dpn('test'))
761 3865ca48 Michael Hanselmann
    os.close(fd)
762 79b60c1c Michael Hanselmann
    utils.RemoveFile(self.f_dpn("test"))
763 3865ca48 Michael Hanselmann
    self.failIf(os.path.exists(pid_file),
764 3865ca48 Michael Hanselmann
                "PID file should not exist anymore")
765 3865ca48 Michael Hanselmann
766 3865ca48 Michael Hanselmann
  def testKill(self):
767 3865ca48 Michael Hanselmann
    pid_file = self.f_dpn('child')
768 3865ca48 Michael Hanselmann
    r_fd, w_fd = os.pipe()
769 3865ca48 Michael Hanselmann
    new_pid = os.fork()
770 3865ca48 Michael Hanselmann
    if new_pid == 0: #child
771 3865ca48 Michael Hanselmann
      utils.WritePidFile(self.f_dpn('child'))
772 3865ca48 Michael Hanselmann
      os.write(w_fd, 'a')
773 3865ca48 Michael Hanselmann
      signal.pause()
774 3865ca48 Michael Hanselmann
      os._exit(0)
775 3865ca48 Michael Hanselmann
      return
776 3865ca48 Michael Hanselmann
    # else we are in the parent
777 3865ca48 Michael Hanselmann
    # wait until the child has written the pid file
778 3865ca48 Michael Hanselmann
    os.read(r_fd, 1)
779 3865ca48 Michael Hanselmann
    read_pid = utils.ReadPidFile(pid_file)
780 3865ca48 Michael Hanselmann
    self.failUnlessEqual(read_pid, new_pid)
781 3865ca48 Michael Hanselmann
    self.failUnless(utils.IsProcessAlive(new_pid))
782 b6522276 Michael Hanselmann
783 b6522276 Michael Hanselmann
    # Try writing to locked file
784 b6522276 Michael Hanselmann
    try:
785 b6522276 Michael Hanselmann
      utils.WritePidFile(pid_file)
786 b6522276 Michael Hanselmann
    except errors.PidFileLockError, err:
787 b6522276 Michael Hanselmann
      errmsg = str(err)
788 b6522276 Michael Hanselmann
      self.assertTrue(errmsg.endswith(" %s" % new_pid),
789 b6522276 Michael Hanselmann
                      msg=("Error message ('%s') didn't contain correct"
790 b6522276 Michael Hanselmann
                           " PID (%s)" % (errmsg, new_pid)))
791 b6522276 Michael Hanselmann
    else:
792 b6522276 Michael Hanselmann
      self.fail("Writing to locked file didn't fail")
793 b6522276 Michael Hanselmann
794 3865ca48 Michael Hanselmann
    utils.KillProcess(new_pid, waitpid=True)
795 3865ca48 Michael Hanselmann
    self.failIf(utils.IsProcessAlive(new_pid))
796 79b60c1c Michael Hanselmann
    utils.RemoveFile(self.f_dpn('child'))
797 3865ca48 Michael Hanselmann
    self.failUnlessRaises(errors.ProgrammerError, utils.KillProcess, 0)
798 3865ca48 Michael Hanselmann
799 b6522276 Michael Hanselmann
  def testExceptionType(self):
800 b6522276 Michael Hanselmann
    # Make sure the PID lock error is a subclass of LockError in case some code
801 b6522276 Michael Hanselmann
    # depends on it
802 b6522276 Michael Hanselmann
    self.assertTrue(issubclass(errors.PidFileLockError, errors.LockError))
803 b6522276 Michael Hanselmann
804 3865ca48 Michael Hanselmann
  def tearDown(self):
805 3865ca48 Michael Hanselmann
    shutil.rmtree(self.dir)
806 3865ca48 Michael Hanselmann
807 3865ca48 Michael Hanselmann
808 3865ca48 Michael Hanselmann
class TestSshKeys(testutils.GanetiTestCase):
809 3865ca48 Michael Hanselmann
  """Test case for the AddAuthorizedKey function"""
810 3865ca48 Michael Hanselmann
811 3865ca48 Michael Hanselmann
  KEY_A = 'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a'
812 3865ca48 Michael Hanselmann
  KEY_B = ('command="/usr/bin/fooserver -t --verbose",from="198.51.100.4" '
813 3865ca48 Michael Hanselmann
           'ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b')
814 3865ca48 Michael Hanselmann
815 3865ca48 Michael Hanselmann
  def setUp(self):
816 3865ca48 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
817 3865ca48 Michael Hanselmann
    self.tmpname = self._CreateTempFile()
818 3865ca48 Michael Hanselmann
    handle = open(self.tmpname, 'w')
819 3865ca48 Michael Hanselmann
    try:
820 3865ca48 Michael Hanselmann
      handle.write("%s\n" % TestSshKeys.KEY_A)
821 3865ca48 Michael Hanselmann
      handle.write("%s\n" % TestSshKeys.KEY_B)
822 3865ca48 Michael Hanselmann
    finally:
823 3865ca48 Michael Hanselmann
      handle.close()
824 3865ca48 Michael Hanselmann
825 3865ca48 Michael Hanselmann
  def testAddingNewKey(self):
826 3865ca48 Michael Hanselmann
    utils.AddAuthorizedKey(self.tmpname,
827 3865ca48 Michael Hanselmann
                           'ssh-dss AAAAB3NzaC1kc3MAAACB root@test')
828 3865ca48 Michael Hanselmann
829 3865ca48 Michael Hanselmann
    self.assertFileContent(self.tmpname,
830 3865ca48 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
831 3865ca48 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
832 3865ca48 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
833 3865ca48 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1kc3MAAACB root@test\n")
834 3865ca48 Michael Hanselmann
835 3865ca48 Michael Hanselmann
  def testAddingAlmostButNotCompletelyTheSameKey(self):
836 3865ca48 Michael Hanselmann
    utils.AddAuthorizedKey(self.tmpname,
837 3865ca48 Michael Hanselmann
        'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test')
838 3865ca48 Michael Hanselmann
839 3865ca48 Michael Hanselmann
    self.assertFileContent(self.tmpname,
840 3865ca48 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
841 3865ca48 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
842 3865ca48 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
843 3865ca48 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test\n")
844 3865ca48 Michael Hanselmann
845 3865ca48 Michael Hanselmann
  def testAddingExistingKeyWithSomeMoreSpaces(self):
846 3865ca48 Michael Hanselmann
    utils.AddAuthorizedKey(self.tmpname,
847 3865ca48 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
848 3865ca48 Michael Hanselmann
849 3865ca48 Michael Hanselmann
    self.assertFileContent(self.tmpname,
850 3865ca48 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
851 3865ca48 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
852 3865ca48 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
853 3865ca48 Michael Hanselmann
854 3865ca48 Michael Hanselmann
  def testRemovingExistingKeyWithSomeMoreSpaces(self):
855 3865ca48 Michael Hanselmann
    utils.RemoveAuthorizedKey(self.tmpname,
856 3865ca48 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
857 3865ca48 Michael Hanselmann
858 3865ca48 Michael Hanselmann
    self.assertFileContent(self.tmpname,
859 3865ca48 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
860 3865ca48 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
861 3865ca48 Michael Hanselmann
862 3865ca48 Michael Hanselmann
  def testRemovingNonExistingKey(self):
863 3865ca48 Michael Hanselmann
    utils.RemoveAuthorizedKey(self.tmpname,
864 3865ca48 Michael Hanselmann
        'ssh-dss  AAAAB3Nsdfj230xxjxJjsjwjsjdjU   root@test')
865 3865ca48 Michael Hanselmann
866 3865ca48 Michael Hanselmann
    self.assertFileContent(self.tmpname,
867 3865ca48 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
868 3865ca48 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
869 3865ca48 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
870 3865ca48 Michael Hanselmann
871 3865ca48 Michael Hanselmann
872 90e234a6 Michael Hanselmann
class TestNewUUID(unittest.TestCase):
873 90e234a6 Michael Hanselmann
  """Test case for NewUUID"""
874 90e234a6 Michael Hanselmann
875 90e234a6 Michael Hanselmann
  def runTest(self):
876 90e234a6 Michael Hanselmann
    self.failUnless(utils.UUID_RE.match(utils.NewUUID()))
877 90e234a6 Michael Hanselmann
878 90e234a6 Michael Hanselmann
879 b81b3c96 René Nussbaumer
def _MockStatResult(cb, mode, uid, gid):
880 b81b3c96 René Nussbaumer
  def _fn(path):
881 b81b3c96 René Nussbaumer
    if cb:
882 b81b3c96 René Nussbaumer
      cb()
883 b81b3c96 René Nussbaumer
    return {
884 b81b3c96 René Nussbaumer
      stat.ST_MODE: mode,
885 b81b3c96 René Nussbaumer
      stat.ST_UID: uid,
886 b81b3c96 René Nussbaumer
      stat.ST_GID: gid,
887 b81b3c96 René Nussbaumer
      }
888 b81b3c96 René Nussbaumer
  return _fn
889 b81b3c96 René Nussbaumer
890 b81b3c96 René Nussbaumer
891 b81b3c96 René Nussbaumer
def _RaiseNoEntError():
892 b81b3c96 René Nussbaumer
  raise EnvironmentError(errno.ENOENT, "not found")
893 b81b3c96 René Nussbaumer
894 b81b3c96 René Nussbaumer
895 b81b3c96 René Nussbaumer
def _OtherStatRaise():
896 b81b3c96 René Nussbaumer
  raise EnvironmentError()
897 b81b3c96 René Nussbaumer
898 b81b3c96 René Nussbaumer
899 b81b3c96 René Nussbaumer
class TestPermissionEnforcements(unittest.TestCase):
900 b81b3c96 René Nussbaumer
  UID_A = 16024
901 b81b3c96 René Nussbaumer
  UID_B = 25850
902 b81b3c96 René Nussbaumer
  GID_A = 14028
903 b81b3c96 René Nussbaumer
  GID_B = 29801
904 b81b3c96 René Nussbaumer
905 b81b3c96 René Nussbaumer
  def setUp(self):
906 b81b3c96 René Nussbaumer
    self._chown_calls = []
907 b81b3c96 René Nussbaumer
    self._chmod_calls = []
908 b81b3c96 René Nussbaumer
    self._mkdir_calls = []
909 b81b3c96 René Nussbaumer
910 b81b3c96 René Nussbaumer
  def tearDown(self):
911 b81b3c96 René Nussbaumer
    self.assertRaises(IndexError, self._mkdir_calls.pop)
912 b81b3c96 René Nussbaumer
    self.assertRaises(IndexError, self._chmod_calls.pop)
913 b81b3c96 René Nussbaumer
    self.assertRaises(IndexError, self._chown_calls.pop)
914 b81b3c96 René Nussbaumer
915 b81b3c96 René Nussbaumer
  def _FakeMkdir(self, path):
916 b81b3c96 René Nussbaumer
    self._mkdir_calls.append(path)
917 b81b3c96 René Nussbaumer
918 b81b3c96 René Nussbaumer
  def _FakeChown(self, path, uid, gid):
919 b81b3c96 René Nussbaumer
    self._chown_calls.append((path, uid, gid))
920 b81b3c96 René Nussbaumer
921 b81b3c96 René Nussbaumer
  def _ChmodWrapper(self, cb):
922 b81b3c96 René Nussbaumer
    def _fn(path, mode):
923 b81b3c96 René Nussbaumer
      self._chmod_calls.append((path, mode))
924 b81b3c96 René Nussbaumer
      if cb:
925 b81b3c96 René Nussbaumer
        cb()
926 b81b3c96 René Nussbaumer
    return _fn
927 b81b3c96 René Nussbaumer
928 b81b3c96 René Nussbaumer
  def _VerifyPerm(self, path, mode, uid=-1, gid=-1):
929 b81b3c96 René Nussbaumer
    self.assertEqual(path, "/ganeti-qa-non-test")
930 b81b3c96 René Nussbaumer
    self.assertEqual(mode, 0700)
931 b81b3c96 René Nussbaumer
    self.assertEqual(uid, self.UID_A)
932 b81b3c96 René Nussbaumer
    self.assertEqual(gid, self.GID_A)
933 b81b3c96 René Nussbaumer
934 b81b3c96 René Nussbaumer
  def testMakeDirWithPerm(self):
935 b81b3c96 René Nussbaumer
    is_dir_stat = _MockStatResult(None, stat.S_IFDIR, 0, 0)
936 b81b3c96 René Nussbaumer
    utils.MakeDirWithPerm("/ganeti-qa-non-test", 0700, self.UID_A, self.GID_A,
937 b81b3c96 René Nussbaumer
                          _lstat_fn=is_dir_stat, _perm_fn=self._VerifyPerm)
938 b81b3c96 René Nussbaumer
939 b81b3c96 René Nussbaumer
  def testDirErrors(self):
940 b81b3c96 René Nussbaumer
    self.assertRaises(errors.GenericError, utils.MakeDirWithPerm,
941 b81b3c96 René Nussbaumer
                      "/ganeti-qa-non-test", 0700, 0, 0,
942 b81b3c96 René Nussbaumer
                      _lstat_fn=_MockStatResult(None, 0, 0, 0))
943 b81b3c96 René Nussbaumer
    self.assertRaises(IndexError, self._mkdir_calls.pop)
944 b81b3c96 René Nussbaumer
945 b81b3c96 René Nussbaumer
    other_stat_raise = _MockStatResult(_OtherStatRaise, stat.S_IFDIR, 0, 0)
946 b81b3c96 René Nussbaumer
    self.assertRaises(errors.GenericError, utils.MakeDirWithPerm,
947 b81b3c96 René Nussbaumer
                      "/ganeti-qa-non-test", 0700, 0, 0,
948 b81b3c96 René Nussbaumer
                      _lstat_fn=other_stat_raise)
949 b81b3c96 René Nussbaumer
    self.assertRaises(IndexError, self._mkdir_calls.pop)
950 b81b3c96 René Nussbaumer
951 b81b3c96 René Nussbaumer
    non_exist_stat = _MockStatResult(_RaiseNoEntError, stat.S_IFDIR, 0, 0)
952 b81b3c96 René Nussbaumer
    utils.MakeDirWithPerm("/ganeti-qa-non-test", 0700, self.UID_A, self.GID_A,
953 b81b3c96 René Nussbaumer
                          _lstat_fn=non_exist_stat, _mkdir_fn=self._FakeMkdir,
954 b81b3c96 René Nussbaumer
                          _perm_fn=self._VerifyPerm)
955 b81b3c96 René Nussbaumer
    self.assertEqual(self._mkdir_calls.pop(0), "/ganeti-qa-non-test")
956 b81b3c96 René Nussbaumer
957 b81b3c96 René Nussbaumer
  def testEnforcePermissionNoEnt(self):
958 b81b3c96 René Nussbaumer
    self.assertRaises(errors.GenericError, utils.EnforcePermission,
959 b81b3c96 René Nussbaumer
                      "/ganeti-qa-non-test", 0600,
960 b81b3c96 René Nussbaumer
                      _chmod_fn=NotImplemented, _chown_fn=NotImplemented,
961 b81b3c96 René Nussbaumer
                      _stat_fn=_MockStatResult(_RaiseNoEntError, 0, 0, 0))
962 b81b3c96 René Nussbaumer
963 b81b3c96 René Nussbaumer
  def testEnforcePermissionNoEntMustNotExist(self):
964 b81b3c96 René Nussbaumer
    utils.EnforcePermission("/ganeti-qa-non-test", 0600, must_exist=False,
965 b81b3c96 René Nussbaumer
                            _chmod_fn=NotImplemented,
966 b81b3c96 René Nussbaumer
                            _chown_fn=NotImplemented,
967 b81b3c96 René Nussbaumer
                            _stat_fn=_MockStatResult(_RaiseNoEntError,
968 b81b3c96 René Nussbaumer
                                                          0, 0, 0))
969 b81b3c96 René Nussbaumer
970 b81b3c96 René Nussbaumer
  def testEnforcePermissionOtherErrorMustNotExist(self):
971 b81b3c96 René Nussbaumer
    self.assertRaises(errors.GenericError, utils.EnforcePermission,
972 b81b3c96 René Nussbaumer
                      "/ganeti-qa-non-test", 0600, must_exist=False,
973 b81b3c96 René Nussbaumer
                      _chmod_fn=NotImplemented, _chown_fn=NotImplemented,
974 b81b3c96 René Nussbaumer
                      _stat_fn=_MockStatResult(_OtherStatRaise, 0, 0, 0))
975 b81b3c96 René Nussbaumer
976 b81b3c96 René Nussbaumer
  def testEnforcePermissionNoChanges(self):
977 b81b3c96 René Nussbaumer
    utils.EnforcePermission("/ganeti-qa-non-test", 0600,
978 b81b3c96 René Nussbaumer
                            _stat_fn=_MockStatResult(None, 0600, 0, 0),
979 b81b3c96 René Nussbaumer
                            _chmod_fn=self._ChmodWrapper(None),
980 b81b3c96 René Nussbaumer
                            _chown_fn=self._FakeChown)
981 b81b3c96 René Nussbaumer
982 b81b3c96 René Nussbaumer
  def testEnforcePermissionChangeMode(self):
983 b81b3c96 René Nussbaumer
    utils.EnforcePermission("/ganeti-qa-non-test", 0444,
984 b81b3c96 René Nussbaumer
                            _stat_fn=_MockStatResult(None, 0600, 0, 0),
985 b81b3c96 René Nussbaumer
                            _chmod_fn=self._ChmodWrapper(None),
986 b81b3c96 René Nussbaumer
                            _chown_fn=self._FakeChown)
987 b81b3c96 René Nussbaumer
    self.assertEqual(self._chmod_calls.pop(0), ("/ganeti-qa-non-test", 0444))
988 b81b3c96 René Nussbaumer
989 b81b3c96 René Nussbaumer
  def testEnforcePermissionSetUidGid(self):
990 b81b3c96 René Nussbaumer
    utils.EnforcePermission("/ganeti-qa-non-test", 0600,
991 b81b3c96 René Nussbaumer
                            uid=self.UID_B, gid=self.GID_B,
992 b81b3c96 René Nussbaumer
                            _stat_fn=_MockStatResult(None, 0600,
993 b81b3c96 René Nussbaumer
                                                     self.UID_A,
994 b81b3c96 René Nussbaumer
                                                     self.GID_A),
995 b81b3c96 René Nussbaumer
                            _chmod_fn=self._ChmodWrapper(None),
996 b81b3c96 René Nussbaumer
                            _chown_fn=self._FakeChown)
997 b81b3c96 René Nussbaumer
    self.assertEqual(self._chown_calls.pop(0),
998 b81b3c96 René Nussbaumer
                     ("/ganeti-qa-non-test", self.UID_B, self.GID_B))
999 b81b3c96 René Nussbaumer
1000 b81b3c96 René Nussbaumer
1001 3865ca48 Michael Hanselmann
if __name__ == "__main__":
1002 3865ca48 Michael Hanselmann
  testutils.GanetiTestProgram()