Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.utils.io_unittest.py @ fe4f6dca

History | View | Annotate | Download (34.2 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 fbdac0d9 Michael Hanselmann
  def testExactlyTheSame(self):
650 fbdac0d9 Michael Hanselmann
    self.assertFalse(utils.IsBelowDir("/a/b", "/a/b"))
651 fbdac0d9 Michael Hanselmann
    self.assertFalse(utils.IsBelowDir("/a/b", "/a/b/"))
652 fbdac0d9 Michael Hanselmann
    self.assertFalse(utils.IsBelowDir("/a/b/", "/a/b"))
653 fbdac0d9 Michael Hanselmann
    self.assertFalse(utils.IsBelowDir("/a/b/", "/a/b/"))
654 fbdac0d9 Michael Hanselmann
655 fb17bebd René Nussbaumer
  def testSamePrefix(self):
656 fb17bebd René Nussbaumer
    self.assertTrue(utils.IsBelowDir("/a/b", "/a/b/c"))
657 fb17bebd René Nussbaumer
    self.assertTrue(utils.IsBelowDir("/a/b/", "/a/b/e"))
658 fb17bebd René Nussbaumer
659 fb17bebd René Nussbaumer
  def testSamePrefixButDifferentDir(self):
660 fb17bebd René Nussbaumer
    self.assertFalse(utils.IsBelowDir("/a/b", "/a/bc/d"))
661 fb17bebd René Nussbaumer
    self.assertFalse(utils.IsBelowDir("/a/b/", "/a/bc/e"))
662 fb17bebd René Nussbaumer
663 fb17bebd René Nussbaumer
  def testSamePrefixButDirTraversal(self):
664 fb17bebd René Nussbaumer
    self.assertFalse(utils.IsBelowDir("/a/b", "/a/b/../c"))
665 fb17bebd René Nussbaumer
    self.assertFalse(utils.IsBelowDir("/a/b/", "/a/b/../d"))
666 fb17bebd René Nussbaumer
667 fb17bebd René Nussbaumer
  def testSamePrefixAndTraversal(self):
668 fb17bebd René Nussbaumer
    self.assertTrue(utils.IsBelowDir("/a/b", "/a/b/c/../d"))
669 fb17bebd René Nussbaumer
    self.assertTrue(utils.IsBelowDir("/a/b", "/a/b/c/./e"))
670 fb17bebd René Nussbaumer
    self.assertTrue(utils.IsBelowDir("/a/b", "/a/b/../b/./e"))
671 fb17bebd René Nussbaumer
672 fb17bebd René Nussbaumer
  def testBothAbsPath(self):
673 fb17bebd René Nussbaumer
    self.assertRaises(ValueError, utils.IsBelowDir, "/a/b/c", "d")
674 fb17bebd René Nussbaumer
    self.assertRaises(ValueError, utils.IsBelowDir, "a/b/c", "/d")
675 fb17bebd René Nussbaumer
    self.assertRaises(ValueError, utils.IsBelowDir, "a/b/c", "d")
676 fb17bebd René Nussbaumer
677 fb17bebd René Nussbaumer
678 3865ca48 Michael Hanselmann
class TestPathJoin(unittest.TestCase):
679 3865ca48 Michael Hanselmann
  """Testing case for PathJoin"""
680 3865ca48 Michael Hanselmann
681 3865ca48 Michael Hanselmann
  def testBasicItems(self):
682 3865ca48 Michael Hanselmann
    mlist = ["/a", "b", "c"]
683 3865ca48 Michael Hanselmann
    self.failUnlessEqual(utils.PathJoin(*mlist), "/".join(mlist))
684 3865ca48 Michael Hanselmann
685 3865ca48 Michael Hanselmann
  def testNonAbsPrefix(self):
686 3865ca48 Michael Hanselmann
    self.failUnlessRaises(ValueError, utils.PathJoin, "a", "b")
687 3865ca48 Michael Hanselmann
688 3865ca48 Michael Hanselmann
  def testBackTrack(self):
689 3865ca48 Michael Hanselmann
    self.failUnlessRaises(ValueError, utils.PathJoin, "/a", "b/../c")
690 3865ca48 Michael Hanselmann
691 3865ca48 Michael Hanselmann
  def testMultiAbs(self):
692 3865ca48 Michael Hanselmann
    self.failUnlessRaises(ValueError, utils.PathJoin, "/a", "/b")
693 3865ca48 Michael Hanselmann
694 3865ca48 Michael Hanselmann
695 3865ca48 Michael Hanselmann
class TestTailFile(testutils.GanetiTestCase):
696 3865ca48 Michael Hanselmann
  """Test case for the TailFile function"""
697 3865ca48 Michael Hanselmann
698 3865ca48 Michael Hanselmann
  def testEmpty(self):
699 3865ca48 Michael Hanselmann
    fname = self._CreateTempFile()
700 3865ca48 Michael Hanselmann
    self.failUnlessEqual(utils.TailFile(fname), [])
701 3865ca48 Michael Hanselmann
    self.failUnlessEqual(utils.TailFile(fname, lines=25), [])
702 3865ca48 Michael Hanselmann
703 3865ca48 Michael Hanselmann
  def testAllLines(self):
704 3865ca48 Michael Hanselmann
    data = ["test %d" % i for i in range(30)]
705 3865ca48 Michael Hanselmann
    for i in range(30):
706 3865ca48 Michael Hanselmann
      fname = self._CreateTempFile()
707 3865ca48 Michael Hanselmann
      fd = open(fname, "w")
708 3865ca48 Michael Hanselmann
      fd.write("\n".join(data[:i]))
709 3865ca48 Michael Hanselmann
      if i > 0:
710 3865ca48 Michael Hanselmann
        fd.write("\n")
711 3865ca48 Michael Hanselmann
      fd.close()
712 3865ca48 Michael Hanselmann
      self.failUnlessEqual(utils.TailFile(fname, lines=i), data[:i])
713 3865ca48 Michael Hanselmann
714 3865ca48 Michael Hanselmann
  def testPartialLines(self):
715 3865ca48 Michael Hanselmann
    data = ["test %d" % i for i in range(30)]
716 3865ca48 Michael Hanselmann
    fname = self._CreateTempFile()
717 3865ca48 Michael Hanselmann
    fd = open(fname, "w")
718 3865ca48 Michael Hanselmann
    fd.write("\n".join(data))
719 3865ca48 Michael Hanselmann
    fd.write("\n")
720 3865ca48 Michael Hanselmann
    fd.close()
721 3865ca48 Michael Hanselmann
    for i in range(1, 30):
722 3865ca48 Michael Hanselmann
      self.failUnlessEqual(utils.TailFile(fname, lines=i), data[-i:])
723 3865ca48 Michael Hanselmann
724 3865ca48 Michael Hanselmann
  def testBigFile(self):
725 3865ca48 Michael Hanselmann
    data = ["test %d" % i for i in range(30)]
726 3865ca48 Michael Hanselmann
    fname = self._CreateTempFile()
727 3865ca48 Michael Hanselmann
    fd = open(fname, "w")
728 3865ca48 Michael Hanselmann
    fd.write("X" * 1048576)
729 3865ca48 Michael Hanselmann
    fd.write("\n")
730 3865ca48 Michael Hanselmann
    fd.write("\n".join(data))
731 3865ca48 Michael Hanselmann
    fd.write("\n")
732 3865ca48 Michael Hanselmann
    fd.close()
733 3865ca48 Michael Hanselmann
    for i in range(1, 30):
734 3865ca48 Michael Hanselmann
      self.failUnlessEqual(utils.TailFile(fname, lines=i), data[-i:])
735 3865ca48 Michael Hanselmann
736 3865ca48 Michael Hanselmann
737 3865ca48 Michael Hanselmann
class TestPidFileFunctions(unittest.TestCase):
738 79b60c1c Michael Hanselmann
  """Tests for WritePidFile and ReadPidFile"""
739 3865ca48 Michael Hanselmann
740 3865ca48 Michael Hanselmann
  def setUp(self):
741 3865ca48 Michael Hanselmann
    self.dir = tempfile.mkdtemp()
742 3865ca48 Michael Hanselmann
    self.f_dpn = lambda name: os.path.join(self.dir, "%s.pid" % name)
743 3865ca48 Michael Hanselmann
744 3865ca48 Michael Hanselmann
  def testPidFileFunctions(self):
745 3865ca48 Michael Hanselmann
    pid_file = self.f_dpn('test')
746 3865ca48 Michael Hanselmann
    fd = utils.WritePidFile(self.f_dpn('test'))
747 3865ca48 Michael Hanselmann
    self.failUnless(os.path.exists(pid_file),
748 3865ca48 Michael Hanselmann
                    "PID file should have been created")
749 3865ca48 Michael Hanselmann
    read_pid = utils.ReadPidFile(pid_file)
750 3865ca48 Michael Hanselmann
    self.failUnlessEqual(read_pid, os.getpid())
751 3865ca48 Michael Hanselmann
    self.failUnless(utils.IsProcessAlive(read_pid))
752 b6522276 Michael Hanselmann
    self.failUnlessRaises(errors.PidFileLockError, utils.WritePidFile,
753 3865ca48 Michael Hanselmann
                          self.f_dpn('test'))
754 3865ca48 Michael Hanselmann
    os.close(fd)
755 79b60c1c Michael Hanselmann
    utils.RemoveFile(self.f_dpn("test"))
756 3865ca48 Michael Hanselmann
    self.failIf(os.path.exists(pid_file),
757 3865ca48 Michael Hanselmann
                "PID file should not exist anymore")
758 3865ca48 Michael Hanselmann
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
759 3865ca48 Michael Hanselmann
                         "ReadPidFile should return 0 for missing pid file")
760 3865ca48 Michael Hanselmann
    fh = open(pid_file, "w")
761 3865ca48 Michael Hanselmann
    fh.write("blah\n")
762 3865ca48 Michael Hanselmann
    fh.close()
763 3865ca48 Michael Hanselmann
    self.failUnlessEqual(utils.ReadPidFile(pid_file), 0,
764 3865ca48 Michael Hanselmann
                         "ReadPidFile should return 0 for invalid pid file")
765 3865ca48 Michael Hanselmann
    # but now, even with the file existing, we should be able to lock it
766 3865ca48 Michael Hanselmann
    fd = utils.WritePidFile(self.f_dpn('test'))
767 3865ca48 Michael Hanselmann
    os.close(fd)
768 79b60c1c Michael Hanselmann
    utils.RemoveFile(self.f_dpn("test"))
769 3865ca48 Michael Hanselmann
    self.failIf(os.path.exists(pid_file),
770 3865ca48 Michael Hanselmann
                "PID file should not exist anymore")
771 3865ca48 Michael Hanselmann
772 3865ca48 Michael Hanselmann
  def testKill(self):
773 3865ca48 Michael Hanselmann
    pid_file = self.f_dpn('child')
774 3865ca48 Michael Hanselmann
    r_fd, w_fd = os.pipe()
775 3865ca48 Michael Hanselmann
    new_pid = os.fork()
776 3865ca48 Michael Hanselmann
    if new_pid == 0: #child
777 3865ca48 Michael Hanselmann
      utils.WritePidFile(self.f_dpn('child'))
778 3865ca48 Michael Hanselmann
      os.write(w_fd, 'a')
779 3865ca48 Michael Hanselmann
      signal.pause()
780 3865ca48 Michael Hanselmann
      os._exit(0)
781 3865ca48 Michael Hanselmann
      return
782 3865ca48 Michael Hanselmann
    # else we are in the parent
783 3865ca48 Michael Hanselmann
    # wait until the child has written the pid file
784 3865ca48 Michael Hanselmann
    os.read(r_fd, 1)
785 3865ca48 Michael Hanselmann
    read_pid = utils.ReadPidFile(pid_file)
786 3865ca48 Michael Hanselmann
    self.failUnlessEqual(read_pid, new_pid)
787 3865ca48 Michael Hanselmann
    self.failUnless(utils.IsProcessAlive(new_pid))
788 b6522276 Michael Hanselmann
789 b6522276 Michael Hanselmann
    # Try writing to locked file
790 b6522276 Michael Hanselmann
    try:
791 b6522276 Michael Hanselmann
      utils.WritePidFile(pid_file)
792 b6522276 Michael Hanselmann
    except errors.PidFileLockError, err:
793 b6522276 Michael Hanselmann
      errmsg = str(err)
794 b6522276 Michael Hanselmann
      self.assertTrue(errmsg.endswith(" %s" % new_pid),
795 b6522276 Michael Hanselmann
                      msg=("Error message ('%s') didn't contain correct"
796 b6522276 Michael Hanselmann
                           " PID (%s)" % (errmsg, new_pid)))
797 b6522276 Michael Hanselmann
    else:
798 b6522276 Michael Hanselmann
      self.fail("Writing to locked file didn't fail")
799 b6522276 Michael Hanselmann
800 3865ca48 Michael Hanselmann
    utils.KillProcess(new_pid, waitpid=True)
801 3865ca48 Michael Hanselmann
    self.failIf(utils.IsProcessAlive(new_pid))
802 79b60c1c Michael Hanselmann
    utils.RemoveFile(self.f_dpn('child'))
803 3865ca48 Michael Hanselmann
    self.failUnlessRaises(errors.ProgrammerError, utils.KillProcess, 0)
804 3865ca48 Michael Hanselmann
805 b6522276 Michael Hanselmann
  def testExceptionType(self):
806 b6522276 Michael Hanselmann
    # Make sure the PID lock error is a subclass of LockError in case some code
807 b6522276 Michael Hanselmann
    # depends on it
808 b6522276 Michael Hanselmann
    self.assertTrue(issubclass(errors.PidFileLockError, errors.LockError))
809 b6522276 Michael Hanselmann
810 3865ca48 Michael Hanselmann
  def tearDown(self):
811 3865ca48 Michael Hanselmann
    shutil.rmtree(self.dir)
812 3865ca48 Michael Hanselmann
813 3865ca48 Michael Hanselmann
814 3865ca48 Michael Hanselmann
class TestSshKeys(testutils.GanetiTestCase):
815 3865ca48 Michael Hanselmann
  """Test case for the AddAuthorizedKey function"""
816 3865ca48 Michael Hanselmann
817 3865ca48 Michael Hanselmann
  KEY_A = 'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a'
818 3865ca48 Michael Hanselmann
  KEY_B = ('command="/usr/bin/fooserver -t --verbose",from="198.51.100.4" '
819 3865ca48 Michael Hanselmann
           'ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b')
820 3865ca48 Michael Hanselmann
821 3865ca48 Michael Hanselmann
  def setUp(self):
822 3865ca48 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
823 3865ca48 Michael Hanselmann
    self.tmpname = self._CreateTempFile()
824 3865ca48 Michael Hanselmann
    handle = open(self.tmpname, 'w')
825 3865ca48 Michael Hanselmann
    try:
826 3865ca48 Michael Hanselmann
      handle.write("%s\n" % TestSshKeys.KEY_A)
827 3865ca48 Michael Hanselmann
      handle.write("%s\n" % TestSshKeys.KEY_B)
828 3865ca48 Michael Hanselmann
    finally:
829 3865ca48 Michael Hanselmann
      handle.close()
830 3865ca48 Michael Hanselmann
831 3865ca48 Michael Hanselmann
  def testAddingNewKey(self):
832 3865ca48 Michael Hanselmann
    utils.AddAuthorizedKey(self.tmpname,
833 3865ca48 Michael Hanselmann
                           'ssh-dss AAAAB3NzaC1kc3MAAACB root@test')
834 3865ca48 Michael Hanselmann
835 3865ca48 Michael Hanselmann
    self.assertFileContent(self.tmpname,
836 3865ca48 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
837 3865ca48 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
838 3865ca48 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
839 3865ca48 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1kc3MAAACB root@test\n")
840 3865ca48 Michael Hanselmann
841 3865ca48 Michael Hanselmann
  def testAddingAlmostButNotCompletelyTheSameKey(self):
842 3865ca48 Michael Hanselmann
    utils.AddAuthorizedKey(self.tmpname,
843 3865ca48 Michael Hanselmann
        'ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test')
844 3865ca48 Michael Hanselmann
845 3865ca48 Michael Hanselmann
    self.assertFileContent(self.tmpname,
846 3865ca48 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
847 3865ca48 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
848 3865ca48 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n"
849 3865ca48 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@test\n")
850 3865ca48 Michael Hanselmann
851 3865ca48 Michael Hanselmann
  def testAddingExistingKeyWithSomeMoreSpaces(self):
852 3865ca48 Michael Hanselmann
    utils.AddAuthorizedKey(self.tmpname,
853 3865ca48 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
854 3865ca48 Michael Hanselmann
855 3865ca48 Michael Hanselmann
    self.assertFileContent(self.tmpname,
856 3865ca48 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
857 3865ca48 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
858 3865ca48 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
859 3865ca48 Michael Hanselmann
860 3865ca48 Michael Hanselmann
  def testRemovingExistingKeyWithSomeMoreSpaces(self):
861 3865ca48 Michael Hanselmann
    utils.RemoveAuthorizedKey(self.tmpname,
862 3865ca48 Michael Hanselmann
        'ssh-dss  AAAAB3NzaC1w5256closdj32mZaQU   root@key-a')
863 3865ca48 Michael Hanselmann
864 3865ca48 Michael Hanselmann
    self.assertFileContent(self.tmpname,
865 3865ca48 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
866 3865ca48 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
867 3865ca48 Michael Hanselmann
868 3865ca48 Michael Hanselmann
  def testRemovingNonExistingKey(self):
869 3865ca48 Michael Hanselmann
    utils.RemoveAuthorizedKey(self.tmpname,
870 3865ca48 Michael Hanselmann
        'ssh-dss  AAAAB3Nsdfj230xxjxJjsjwjsjdjU   root@test')
871 3865ca48 Michael Hanselmann
872 3865ca48 Michael Hanselmann
    self.assertFileContent(self.tmpname,
873 3865ca48 Michael Hanselmann
      "ssh-dss AAAAB3NzaC1w5256closdj32mZaQU root@key-a\n"
874 3865ca48 Michael Hanselmann
      'command="/usr/bin/fooserver -t --verbose",from="198.51.100.4"'
875 3865ca48 Michael Hanselmann
      " ssh-dss AAAAB3NzaC1w520smc01ms0jfJs22 root@key-b\n")
876 3865ca48 Michael Hanselmann
877 3865ca48 Michael Hanselmann
878 90e234a6 Michael Hanselmann
class TestNewUUID(unittest.TestCase):
879 90e234a6 Michael Hanselmann
  """Test case for NewUUID"""
880 90e234a6 Michael Hanselmann
881 90e234a6 Michael Hanselmann
  def runTest(self):
882 90e234a6 Michael Hanselmann
    self.failUnless(utils.UUID_RE.match(utils.NewUUID()))
883 90e234a6 Michael Hanselmann
884 90e234a6 Michael Hanselmann
885 b81b3c96 René Nussbaumer
def _MockStatResult(cb, mode, uid, gid):
886 b81b3c96 René Nussbaumer
  def _fn(path):
887 b81b3c96 René Nussbaumer
    if cb:
888 b81b3c96 René Nussbaumer
      cb()
889 b81b3c96 René Nussbaumer
    return {
890 b81b3c96 René Nussbaumer
      stat.ST_MODE: mode,
891 b81b3c96 René Nussbaumer
      stat.ST_UID: uid,
892 b81b3c96 René Nussbaumer
      stat.ST_GID: gid,
893 b81b3c96 René Nussbaumer
      }
894 b81b3c96 René Nussbaumer
  return _fn
895 b81b3c96 René Nussbaumer
896 b81b3c96 René Nussbaumer
897 b81b3c96 René Nussbaumer
def _RaiseNoEntError():
898 b81b3c96 René Nussbaumer
  raise EnvironmentError(errno.ENOENT, "not found")
899 b81b3c96 René Nussbaumer
900 b81b3c96 René Nussbaumer
901 b81b3c96 René Nussbaumer
def _OtherStatRaise():
902 b81b3c96 René Nussbaumer
  raise EnvironmentError()
903 b81b3c96 René Nussbaumer
904 b81b3c96 René Nussbaumer
905 b81b3c96 René Nussbaumer
class TestPermissionEnforcements(unittest.TestCase):
906 b81b3c96 René Nussbaumer
  UID_A = 16024
907 b81b3c96 René Nussbaumer
  UID_B = 25850
908 b81b3c96 René Nussbaumer
  GID_A = 14028
909 b81b3c96 René Nussbaumer
  GID_B = 29801
910 b81b3c96 René Nussbaumer
911 b81b3c96 René Nussbaumer
  def setUp(self):
912 b81b3c96 René Nussbaumer
    self._chown_calls = []
913 b81b3c96 René Nussbaumer
    self._chmod_calls = []
914 b81b3c96 René Nussbaumer
    self._mkdir_calls = []
915 b81b3c96 René Nussbaumer
916 b81b3c96 René Nussbaumer
  def tearDown(self):
917 b81b3c96 René Nussbaumer
    self.assertRaises(IndexError, self._mkdir_calls.pop)
918 b81b3c96 René Nussbaumer
    self.assertRaises(IndexError, self._chmod_calls.pop)
919 b81b3c96 René Nussbaumer
    self.assertRaises(IndexError, self._chown_calls.pop)
920 b81b3c96 René Nussbaumer
921 b81b3c96 René Nussbaumer
  def _FakeMkdir(self, path):
922 b81b3c96 René Nussbaumer
    self._mkdir_calls.append(path)
923 b81b3c96 René Nussbaumer
924 b81b3c96 René Nussbaumer
  def _FakeChown(self, path, uid, gid):
925 b81b3c96 René Nussbaumer
    self._chown_calls.append((path, uid, gid))
926 b81b3c96 René Nussbaumer
927 b81b3c96 René Nussbaumer
  def _ChmodWrapper(self, cb):
928 b81b3c96 René Nussbaumer
    def _fn(path, mode):
929 b81b3c96 René Nussbaumer
      self._chmod_calls.append((path, mode))
930 b81b3c96 René Nussbaumer
      if cb:
931 b81b3c96 René Nussbaumer
        cb()
932 b81b3c96 René Nussbaumer
    return _fn
933 b81b3c96 René Nussbaumer
934 b81b3c96 René Nussbaumer
  def _VerifyPerm(self, path, mode, uid=-1, gid=-1):
935 b81b3c96 René Nussbaumer
    self.assertEqual(path, "/ganeti-qa-non-test")
936 b81b3c96 René Nussbaumer
    self.assertEqual(mode, 0700)
937 b81b3c96 René Nussbaumer
    self.assertEqual(uid, self.UID_A)
938 b81b3c96 René Nussbaumer
    self.assertEqual(gid, self.GID_A)
939 b81b3c96 René Nussbaumer
940 b81b3c96 René Nussbaumer
  def testMakeDirWithPerm(self):
941 b81b3c96 René Nussbaumer
    is_dir_stat = _MockStatResult(None, stat.S_IFDIR, 0, 0)
942 b81b3c96 René Nussbaumer
    utils.MakeDirWithPerm("/ganeti-qa-non-test", 0700, self.UID_A, self.GID_A,
943 b81b3c96 René Nussbaumer
                          _lstat_fn=is_dir_stat, _perm_fn=self._VerifyPerm)
944 b81b3c96 René Nussbaumer
945 b81b3c96 René Nussbaumer
  def testDirErrors(self):
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=_MockStatResult(None, 0, 0, 0))
949 b81b3c96 René Nussbaumer
    self.assertRaises(IndexError, self._mkdir_calls.pop)
950 b81b3c96 René Nussbaumer
951 b81b3c96 René Nussbaumer
    other_stat_raise = _MockStatResult(_OtherStatRaise, stat.S_IFDIR, 0, 0)
952 b81b3c96 René Nussbaumer
    self.assertRaises(errors.GenericError, utils.MakeDirWithPerm,
953 b81b3c96 René Nussbaumer
                      "/ganeti-qa-non-test", 0700, 0, 0,
954 b81b3c96 René Nussbaumer
                      _lstat_fn=other_stat_raise)
955 b81b3c96 René Nussbaumer
    self.assertRaises(IndexError, self._mkdir_calls.pop)
956 b81b3c96 René Nussbaumer
957 b81b3c96 René Nussbaumer
    non_exist_stat = _MockStatResult(_RaiseNoEntError, stat.S_IFDIR, 0, 0)
958 b81b3c96 René Nussbaumer
    utils.MakeDirWithPerm("/ganeti-qa-non-test", 0700, self.UID_A, self.GID_A,
959 b81b3c96 René Nussbaumer
                          _lstat_fn=non_exist_stat, _mkdir_fn=self._FakeMkdir,
960 b81b3c96 René Nussbaumer
                          _perm_fn=self._VerifyPerm)
961 b81b3c96 René Nussbaumer
    self.assertEqual(self._mkdir_calls.pop(0), "/ganeti-qa-non-test")
962 b81b3c96 René Nussbaumer
963 b81b3c96 René Nussbaumer
  def testEnforcePermissionNoEnt(self):
964 b81b3c96 René Nussbaumer
    self.assertRaises(errors.GenericError, utils.EnforcePermission,
965 b81b3c96 René Nussbaumer
                      "/ganeti-qa-non-test", 0600,
966 b81b3c96 René Nussbaumer
                      _chmod_fn=NotImplemented, _chown_fn=NotImplemented,
967 b81b3c96 René Nussbaumer
                      _stat_fn=_MockStatResult(_RaiseNoEntError, 0, 0, 0))
968 b81b3c96 René Nussbaumer
969 b81b3c96 René Nussbaumer
  def testEnforcePermissionNoEntMustNotExist(self):
970 b81b3c96 René Nussbaumer
    utils.EnforcePermission("/ganeti-qa-non-test", 0600, must_exist=False,
971 b81b3c96 René Nussbaumer
                            _chmod_fn=NotImplemented,
972 b81b3c96 René Nussbaumer
                            _chown_fn=NotImplemented,
973 b81b3c96 René Nussbaumer
                            _stat_fn=_MockStatResult(_RaiseNoEntError,
974 b81b3c96 René Nussbaumer
                                                          0, 0, 0))
975 b81b3c96 René Nussbaumer
976 b81b3c96 René Nussbaumer
  def testEnforcePermissionOtherErrorMustNotExist(self):
977 b81b3c96 René Nussbaumer
    self.assertRaises(errors.GenericError, utils.EnforcePermission,
978 b81b3c96 René Nussbaumer
                      "/ganeti-qa-non-test", 0600, must_exist=False,
979 b81b3c96 René Nussbaumer
                      _chmod_fn=NotImplemented, _chown_fn=NotImplemented,
980 b81b3c96 René Nussbaumer
                      _stat_fn=_MockStatResult(_OtherStatRaise, 0, 0, 0))
981 b81b3c96 René Nussbaumer
982 b81b3c96 René Nussbaumer
  def testEnforcePermissionNoChanges(self):
983 b81b3c96 René Nussbaumer
    utils.EnforcePermission("/ganeti-qa-non-test", 0600,
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
988 b81b3c96 René Nussbaumer
  def testEnforcePermissionChangeMode(self):
989 b81b3c96 René Nussbaumer
    utils.EnforcePermission("/ganeti-qa-non-test", 0444,
990 b81b3c96 René Nussbaumer
                            _stat_fn=_MockStatResult(None, 0600, 0, 0),
991 b81b3c96 René Nussbaumer
                            _chmod_fn=self._ChmodWrapper(None),
992 b81b3c96 René Nussbaumer
                            _chown_fn=self._FakeChown)
993 b81b3c96 René Nussbaumer
    self.assertEqual(self._chmod_calls.pop(0), ("/ganeti-qa-non-test", 0444))
994 b81b3c96 René Nussbaumer
995 b81b3c96 René Nussbaumer
  def testEnforcePermissionSetUidGid(self):
996 b81b3c96 René Nussbaumer
    utils.EnforcePermission("/ganeti-qa-non-test", 0600,
997 b81b3c96 René Nussbaumer
                            uid=self.UID_B, gid=self.GID_B,
998 b81b3c96 René Nussbaumer
                            _stat_fn=_MockStatResult(None, 0600,
999 b81b3c96 René Nussbaumer
                                                     self.UID_A,
1000 b81b3c96 René Nussbaumer
                                                     self.GID_A),
1001 b81b3c96 René Nussbaumer
                            _chmod_fn=self._ChmodWrapper(None),
1002 b81b3c96 René Nussbaumer
                            _chown_fn=self._FakeChown)
1003 b81b3c96 René Nussbaumer
    self.assertEqual(self._chown_calls.pop(0),
1004 b81b3c96 René Nussbaumer
                     ("/ganeti-qa-non-test", self.UID_B, self.GID_B))
1005 b81b3c96 René Nussbaumer
1006 b81b3c96 René Nussbaumer
1007 3865ca48 Michael Hanselmann
if __name__ == "__main__":
1008 3865ca48 Michael Hanselmann
  testutils.GanetiTestProgram()