Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.storage.filestorage_unittest.py @ 560ef132

History | View | Annotate | Download (10.3 kB)

1 820bade9 Helga Velroyen
#!/usr/bin/python
2 820bade9 Helga Velroyen
#
3 820bade9 Helga Velroyen
4 820bade9 Helga Velroyen
# Copyright (C) 2013 Google Inc.
5 820bade9 Helga Velroyen
#
6 820bade9 Helga Velroyen
# This program is free software; you can redistribute it and/or modify
7 820bade9 Helga Velroyen
# it under the terms of the GNU General Public License as published by
8 820bade9 Helga Velroyen
# the Free Software Foundation; either version 2 of the License, or
9 820bade9 Helga Velroyen
# (at your option) any later version.
10 820bade9 Helga Velroyen
#
11 820bade9 Helga Velroyen
# This program is distributed in the hope that it will be useful, but
12 820bade9 Helga Velroyen
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 820bade9 Helga Velroyen
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 820bade9 Helga Velroyen
# General Public License for more details.
15 820bade9 Helga Velroyen
#
16 820bade9 Helga Velroyen
# You should have received a copy of the GNU General Public License
17 820bade9 Helga Velroyen
# along with this program; if not, write to the Free Software
18 820bade9 Helga Velroyen
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 820bade9 Helga Velroyen
# 02110-1301, USA.
20 820bade9 Helga Velroyen
21 820bade9 Helga Velroyen
22 2fd2c0fa Santi Raffa
"""Script for unittesting the ganeti.storage.filestorage module"""
23 820bade9 Helga Velroyen
24 9c1c3c19 Helga Velroyen
import os
25 9c1c3c19 Helga Velroyen
import shutil
26 9c1c3c19 Helga Velroyen
import tempfile
27 820bade9 Helga Velroyen
import unittest
28 820bade9 Helga Velroyen
29 820bade9 Helga Velroyen
from ganeti import errors
30 820bade9 Helga Velroyen
from ganeti.storage import filestorage
31 267520ba Santi Raffa
from ganeti.utils import io
32 f3ebe73e Helga Velroyen
from ganeti import utils
33 267520ba Santi Raffa
from ganeti import constants
34 820bade9 Helga Velroyen
35 820bade9 Helga Velroyen
import testutils
36 820bade9 Helga Velroyen
37 820bade9 Helga Velroyen
38 820bade9 Helga Velroyen
class TestFileStorageSpaceInfo(unittest.TestCase):
39 820bade9 Helga Velroyen
40 820bade9 Helga Velroyen
  def testSpaceInfoPathInvalid(self):
41 e798d484 Helga Velroyen
    """Tests that an error is raised when the given path is not existing.
42 820bade9 Helga Velroyen

43 820bade9 Helga Velroyen
    """
44 e798d484 Helga Velroyen
    self.assertRaises(errors.CommandError, filestorage.GetFileStorageSpaceInfo,
45 820bade9 Helga Velroyen
                      "/path/does/not/exist/")
46 820bade9 Helga Velroyen
47 820bade9 Helga Velroyen
  def testSpaceInfoPathValid(self):
48 e798d484 Helga Velroyen
    """Smoke test run on a directory that exists for sure.
49 820bade9 Helga Velroyen

50 820bade9 Helga Velroyen
    """
51 9c1c3c19 Helga Velroyen
    filestorage.GetFileStorageSpaceInfo("/")
52 9c1c3c19 Helga Velroyen
53 9c1c3c19 Helga Velroyen
54 9c1c3c19 Helga Velroyen
class TestCheckFileStoragePath(unittest.TestCase):
55 9c1c3c19 Helga Velroyen
  def _WriteAllowedFile(self, allowed_paths_filename, allowed_paths):
56 9c1c3c19 Helga Velroyen
    allowed_paths_file = open(allowed_paths_filename, 'w')
57 9c1c3c19 Helga Velroyen
    allowed_paths_file.write('\n'.join(allowed_paths))
58 9c1c3c19 Helga Velroyen
    allowed_paths_file.close()
59 9c1c3c19 Helga Velroyen
60 9c1c3c19 Helga Velroyen
  def setUp(self):
61 9c1c3c19 Helga Velroyen
    self.tmpdir = tempfile.mkdtemp()
62 9c1c3c19 Helga Velroyen
    self.allowed_paths = [os.path.join(self.tmpdir, "allowed")]
63 9c1c3c19 Helga Velroyen
    for path in self.allowed_paths:
64 9c1c3c19 Helga Velroyen
      os.mkdir(path)
65 9c1c3c19 Helga Velroyen
    self.allowed_paths_filename = os.path.join(self.tmpdir, "allowed-path-file")
66 9c1c3c19 Helga Velroyen
    self._WriteAllowedFile(self.allowed_paths_filename, self.allowed_paths)
67 9c1c3c19 Helga Velroyen
68 9c1c3c19 Helga Velroyen
  def tearDown(self):
69 9c1c3c19 Helga Velroyen
    shutil.rmtree(self.tmpdir)
70 9c1c3c19 Helga Velroyen
71 9c1c3c19 Helga Velroyen
  def testCheckFileStoragePathExistance(self):
72 9c1c3c19 Helga Velroyen
    filestorage._CheckFileStoragePathExistance(self.tmpdir)
73 9c1c3c19 Helga Velroyen
74 9c1c3c19 Helga Velroyen
  def testCheckFileStoragePathExistanceFail(self):
75 9c1c3c19 Helga Velroyen
    path = os.path.join(self.tmpdir, "does/not/exist")
76 9c1c3c19 Helga Velroyen
    self.assertRaises(errors.FileStoragePathError,
77 9c1c3c19 Helga Velroyen
        filestorage._CheckFileStoragePathExistance, path)
78 9c1c3c19 Helga Velroyen
79 9c1c3c19 Helga Velroyen
  def testCheckFileStoragePathNotWritable(self):
80 9c1c3c19 Helga Velroyen
    path = os.path.join(self.tmpdir, "isnotwritable/")
81 9c1c3c19 Helga Velroyen
    os.mkdir(path)
82 9c1c3c19 Helga Velroyen
    os.chmod(path, 0)
83 9c1c3c19 Helga Velroyen
    self.assertRaises(errors.FileStoragePathError,
84 9c1c3c19 Helga Velroyen
        filestorage._CheckFileStoragePathExistance, path)
85 9c1c3c19 Helga Velroyen
    os.chmod(path, 777)
86 9c1c3c19 Helga Velroyen
87 9c1c3c19 Helga Velroyen
  def testCheckFileStoragePath(self):
88 9c1c3c19 Helga Velroyen
    path = os.path.join(self.allowed_paths[0], "allowedsubdir")
89 9c1c3c19 Helga Velroyen
    os.mkdir(path)
90 9c1c3c19 Helga Velroyen
    result = filestorage.CheckFileStoragePath(
91 9c1c3c19 Helga Velroyen
        path, _allowed_paths_file=self.allowed_paths_filename)
92 9c1c3c19 Helga Velroyen
    self.assertEqual(None, result)
93 9c1c3c19 Helga Velroyen
94 9c1c3c19 Helga Velroyen
  def testCheckFileStoragePathNotAllowed(self):
95 9c1c3c19 Helga Velroyen
    path = os.path.join(self.tmpdir, "notallowed")
96 9c1c3c19 Helga Velroyen
    result = filestorage.CheckFileStoragePath(
97 9c1c3c19 Helga Velroyen
        path, _allowed_paths_file=self.allowed_paths_filename)
98 9c1c3c19 Helga Velroyen
    self.assertTrue("not acceptable" in result)
99 820bade9 Helga Velroyen
100 820bade9 Helga Velroyen
101 f3ebe73e Helga Velroyen
class TestLoadAllowedFileStoragePaths(testutils.GanetiTestCase):
102 f3ebe73e Helga Velroyen
  def testDevNull(self):
103 f3ebe73e Helga Velroyen
    self.assertEqual(filestorage._LoadAllowedFileStoragePaths("/dev/null"), [])
104 f3ebe73e Helga Velroyen
105 f3ebe73e Helga Velroyen
  def testNonExistantFile(self):
106 f3ebe73e Helga Velroyen
    filename = "/tmp/this/file/does/not/exist"
107 f3ebe73e Helga Velroyen
    assert not os.path.exists(filename)
108 f3ebe73e Helga Velroyen
    self.assertEqual(filestorage._LoadAllowedFileStoragePaths(filename), [])
109 f3ebe73e Helga Velroyen
110 f3ebe73e Helga Velroyen
  def test(self):
111 f3ebe73e Helga Velroyen
    tmpfile = self._CreateTempFile()
112 f3ebe73e Helga Velroyen
113 f3ebe73e Helga Velroyen
    utils.WriteFile(tmpfile, data="""
114 f3ebe73e Helga Velroyen
      # This is a test file
115 f3ebe73e Helga Velroyen
      /tmp
116 f3ebe73e Helga Velroyen
      /srv/storage
117 f3ebe73e Helga Velroyen
      relative/path
118 f3ebe73e Helga Velroyen
      """)
119 f3ebe73e Helga Velroyen
120 f3ebe73e Helga Velroyen
    self.assertEqual(filestorage._LoadAllowedFileStoragePaths(tmpfile), [
121 f3ebe73e Helga Velroyen
      "/tmp",
122 f3ebe73e Helga Velroyen
      "/srv/storage",
123 f3ebe73e Helga Velroyen
      "relative/path",
124 f3ebe73e Helga Velroyen
      ])
125 f3ebe73e Helga Velroyen
126 f3ebe73e Helga Velroyen
127 f3ebe73e Helga Velroyen
class TestComputeWrongFileStoragePathsInternal(unittest.TestCase):
128 f3ebe73e Helga Velroyen
  def testPaths(self):
129 f3ebe73e Helga Velroyen
    paths = filestorage._GetForbiddenFileStoragePaths()
130 f3ebe73e Helga Velroyen
131 f3ebe73e Helga Velroyen
    for path in ["/bin", "/usr/local/sbin", "/lib64", "/etc", "/sys"]:
132 f3ebe73e Helga Velroyen
      self.assertTrue(path in paths)
133 f3ebe73e Helga Velroyen
134 f3ebe73e Helga Velroyen
    self.assertEqual(set(map(os.path.normpath, paths)), paths)
135 f3ebe73e Helga Velroyen
136 f3ebe73e Helga Velroyen
  def test(self):
137 f3ebe73e Helga Velroyen
    vfsp = filestorage._ComputeWrongFileStoragePaths
138 f3ebe73e Helga Velroyen
    self.assertEqual(vfsp([]), [])
139 f3ebe73e Helga Velroyen
    self.assertEqual(vfsp(["/tmp"]), [])
140 f3ebe73e Helga Velroyen
    self.assertEqual(vfsp(["/bin/ls"]), ["/bin/ls"])
141 f3ebe73e Helga Velroyen
    self.assertEqual(vfsp(["/bin"]), ["/bin"])
142 f3ebe73e Helga Velroyen
    self.assertEqual(vfsp(["/usr/sbin/vim", "/srv/file-storage"]),
143 f3ebe73e Helga Velroyen
                     ["/usr/sbin/vim"])
144 f3ebe73e Helga Velroyen
145 f3ebe73e Helga Velroyen
146 f3ebe73e Helga Velroyen
class TestComputeWrongFileStoragePaths(testutils.GanetiTestCase):
147 f3ebe73e Helga Velroyen
  def test(self):
148 f3ebe73e Helga Velroyen
    tmpfile = self._CreateTempFile()
149 f3ebe73e Helga Velroyen
150 f3ebe73e Helga Velroyen
    utils.WriteFile(tmpfile, data="""
151 f3ebe73e Helga Velroyen
      /tmp
152 f3ebe73e Helga Velroyen
      x/y///z/relative
153 f3ebe73e Helga Velroyen
      # This is a test file
154 f3ebe73e Helga Velroyen
      /srv/storage
155 f3ebe73e Helga Velroyen
      /bin
156 f3ebe73e Helga Velroyen
      /usr/local/lib32/
157 f3ebe73e Helga Velroyen
      relative/path
158 f3ebe73e Helga Velroyen
      """)
159 f3ebe73e Helga Velroyen
160 f3ebe73e Helga Velroyen
    self.assertEqual(
161 f3ebe73e Helga Velroyen
        filestorage.ComputeWrongFileStoragePaths(_filename=tmpfile),
162 f3ebe73e Helga Velroyen
        ["/bin",
163 f3ebe73e Helga Velroyen
         "/usr/local/lib32",
164 f3ebe73e Helga Velroyen
         "relative/path",
165 f3ebe73e Helga Velroyen
         "x/y/z/relative",
166 f3ebe73e Helga Velroyen
        ])
167 f3ebe73e Helga Velroyen
168 f3ebe73e Helga Velroyen
169 f3ebe73e Helga Velroyen
class TestCheckFileStoragePathInternal(unittest.TestCase):
170 f3ebe73e Helga Velroyen
  def testNonAbsolute(self):
171 f3ebe73e Helga Velroyen
    for i in ["", "tmp", "foo/bar/baz"]:
172 f3ebe73e Helga Velroyen
      self.assertRaises(errors.FileStoragePathError,
173 f3ebe73e Helga Velroyen
                        filestorage._CheckFileStoragePath, i, ["/tmp"])
174 f3ebe73e Helga Velroyen
175 f3ebe73e Helga Velroyen
    self.assertRaises(errors.FileStoragePathError,
176 f3ebe73e Helga Velroyen
                      filestorage._CheckFileStoragePath, "/tmp", ["tmp", "xyz"])
177 f3ebe73e Helga Velroyen
178 f3ebe73e Helga Velroyen
  def testNoAllowed(self):
179 f3ebe73e Helga Velroyen
    self.assertRaises(errors.FileStoragePathError,
180 f3ebe73e Helga Velroyen
                      filestorage._CheckFileStoragePath, "/tmp", [])
181 f3ebe73e Helga Velroyen
182 f3ebe73e Helga Velroyen
  def testNoAdditionalPathComponent(self):
183 f3ebe73e Helga Velroyen
    self.assertRaises(errors.FileStoragePathError,
184 f3ebe73e Helga Velroyen
                      filestorage._CheckFileStoragePath, "/tmp/foo",
185 f3ebe73e Helga Velroyen
                      ["/tmp/foo"])
186 f3ebe73e Helga Velroyen
187 f3ebe73e Helga Velroyen
  def testAllowed(self):
188 f3ebe73e Helga Velroyen
    filestorage._CheckFileStoragePath("/tmp/foo/a", ["/tmp/foo"])
189 f3ebe73e Helga Velroyen
    filestorage._CheckFileStoragePath("/tmp/foo/a/x", ["/tmp/foo"])
190 f3ebe73e Helga Velroyen
191 f3ebe73e Helga Velroyen
192 f3ebe73e Helga Velroyen
class TestCheckFileStoragePathExistance(testutils.GanetiTestCase):
193 f3ebe73e Helga Velroyen
  def testNonExistantFile(self):
194 f3ebe73e Helga Velroyen
    filename = "/tmp/this/file/does/not/exist"
195 f3ebe73e Helga Velroyen
    assert not os.path.exists(filename)
196 f3ebe73e Helga Velroyen
    self.assertRaises(errors.FileStoragePathError,
197 f3ebe73e Helga Velroyen
                      filestorage.CheckFileStoragePathAcceptance, "/bin/",
198 f3ebe73e Helga Velroyen
                      _filename=filename)
199 f3ebe73e Helga Velroyen
    self.assertRaises(errors.FileStoragePathError,
200 f3ebe73e Helga Velroyen
                      filestorage.CheckFileStoragePathAcceptance,
201 f3ebe73e Helga Velroyen
                      "/srv/file-storage", _filename=filename)
202 f3ebe73e Helga Velroyen
203 f3ebe73e Helga Velroyen
  def testAllowedPath(self):
204 f3ebe73e Helga Velroyen
    tmpfile = self._CreateTempFile()
205 f3ebe73e Helga Velroyen
206 f3ebe73e Helga Velroyen
    utils.WriteFile(tmpfile, data="""
207 f3ebe73e Helga Velroyen
      /srv/storage
208 f3ebe73e Helga Velroyen
      """)
209 f3ebe73e Helga Velroyen
210 f3ebe73e Helga Velroyen
    filestorage.CheckFileStoragePathAcceptance(
211 f3ebe73e Helga Velroyen
        "/srv/storage/inst1", _filename=tmpfile)
212 f3ebe73e Helga Velroyen
213 f3ebe73e Helga Velroyen
    # No additional path component
214 f3ebe73e Helga Velroyen
    self.assertRaises(errors.FileStoragePathError,
215 f3ebe73e Helga Velroyen
                      filestorage.CheckFileStoragePathAcceptance,
216 f3ebe73e Helga Velroyen
                      "/srv/storage", _filename=tmpfile)
217 f3ebe73e Helga Velroyen
218 f3ebe73e Helga Velroyen
    # Forbidden path
219 f3ebe73e Helga Velroyen
    self.assertRaises(errors.FileStoragePathError,
220 f3ebe73e Helga Velroyen
                      filestorage.CheckFileStoragePathAcceptance,
221 f3ebe73e Helga Velroyen
                      "/usr/lib64/xyz", _filename=tmpfile)
222 f3ebe73e Helga Velroyen
223 f3ebe73e Helga Velroyen
224 267520ba Santi Raffa
class TestFileDeviceHelper(testutils.GanetiTestCase):
225 267520ba Santi Raffa
226 267520ba Santi Raffa
  @staticmethod
227 267520ba Santi Raffa
  def _Make(path, create_with_size=None, create_folders=False):
228 267520ba Santi Raffa
    skip_checks = lambda path: None
229 267520ba Santi Raffa
    if create_with_size:
230 58793040 Santi Raffa
      return filestorage.FileDeviceHelper.CreateFile(
231 267520ba Santi Raffa
        path, create_with_size, create_folders=create_folders,
232 267520ba Santi Raffa
        _file_path_acceptance_fn=skip_checks
233 267520ba Santi Raffa
      )
234 267520ba Santi Raffa
    else:
235 267520ba Santi Raffa
      return filestorage.FileDeviceHelper(path,
236 267520ba Santi Raffa
                                          _file_path_acceptance_fn=skip_checks)
237 267520ba Santi Raffa
238 267520ba Santi Raffa
  class TempEnvironment(object):
239 267520ba Santi Raffa
240 267520ba Santi Raffa
    def __init__(self, create_file=False, delete_file=True):
241 267520ba Santi Raffa
      self.create_file = create_file
242 267520ba Santi Raffa
      self.delete_file = delete_file
243 267520ba Santi Raffa
244 267520ba Santi Raffa
    def __enter__(self):
245 267520ba Santi Raffa
      self.directory = tempfile.mkdtemp()
246 267520ba Santi Raffa
      self.subdirectory = io.PathJoin(self.directory, "pinky")
247 267520ba Santi Raffa
      os.mkdir(self.subdirectory)
248 267520ba Santi Raffa
      self.path = io.PathJoin(self.subdirectory, "bunny")
249 267520ba Santi Raffa
      self.volume = TestFileDeviceHelper._Make(self.path)
250 267520ba Santi Raffa
      if self.create_file:
251 267520ba Santi Raffa
        open(self.path, mode="w").close()
252 267520ba Santi Raffa
      return self
253 267520ba Santi Raffa
254 267520ba Santi Raffa
    def __exit__(self, *args):
255 267520ba Santi Raffa
      if self.delete_file:
256 267520ba Santi Raffa
        os.unlink(self.path)
257 267520ba Santi Raffa
      os.rmdir(self.subdirectory)
258 267520ba Santi Raffa
      os.rmdir(self.directory)
259 267520ba Santi Raffa
      return False #don't swallow exceptions
260 267520ba Santi Raffa
261 267520ba Santi Raffa
  def testOperationsOnNonExistingFiles(self):
262 267520ba Santi Raffa
    path = "/e/no/ent"
263 267520ba Santi Raffa
    volume = TestFileDeviceHelper._Make(path)
264 267520ba Santi Raffa
265 267520ba Santi Raffa
    # These should fail horribly.
266 267520ba Santi Raffa
    volume.Exists(assert_exists=False)
267 267520ba Santi Raffa
    self.assertRaises(errors.BlockDeviceError, lambda: \
268 267520ba Santi Raffa
      volume.Exists(assert_exists=True))
269 267520ba Santi Raffa
    self.assertRaises(errors.BlockDeviceError, lambda: \
270 267520ba Santi Raffa
      volume.Size())
271 267520ba Santi Raffa
    self.assertRaises(errors.BlockDeviceError, lambda: \
272 267520ba Santi Raffa
      volume.Grow(0.020, True, False, None))
273 267520ba Santi Raffa
274 267520ba Santi Raffa
    # Removing however fails silently.
275 267520ba Santi Raffa
    volume.Remove()
276 267520ba Santi Raffa
277 267520ba Santi Raffa
    # Make sure we don't create all directories for you unless we ask for it
278 267520ba Santi Raffa
    self.assertRaises(errors.BlockDeviceError, lambda: \
279 267520ba Santi Raffa
      TestFileDeviceHelper._Make(path, create_with_size=1))
280 267520ba Santi Raffa
281 267520ba Santi Raffa
  def testFileCreation(self):
282 267520ba Santi Raffa
    with TestFileDeviceHelper.TempEnvironment() as env:
283 267520ba Santi Raffa
      TestFileDeviceHelper._Make(env.path, create_with_size=1)
284 267520ba Santi Raffa
285 267520ba Santi Raffa
      self.assertTrue(env.volume.Exists())
286 267520ba Santi Raffa
      env.volume.Exists(assert_exists=True)
287 267520ba Santi Raffa
      self.assertRaises(errors.BlockDeviceError, lambda: \
288 267520ba Santi Raffa
        env.volume.Exists(assert_exists=False))
289 267520ba Santi Raffa
290 267520ba Santi Raffa
    self.assertRaises(errors.BlockDeviceError, lambda: \
291 267520ba Santi Raffa
      TestFileDeviceHelper._Make("/enoent", create_with_size=0.042))
292 267520ba Santi Raffa
293 267520ba Santi Raffa
  def testFailSizeDirectory(self):
294 267520ba Santi Raffa
  # This should still fail.
295 267520ba Santi Raffa
   with TestFileDeviceHelper.TempEnvironment(delete_file=False) as env:
296 267520ba Santi Raffa
    self.assertRaises(errors.BlockDeviceError, lambda: \
297 267520ba Santi Raffa
      TestFileDeviceHelper._Make(env.subdirectory).Size())
298 267520ba Santi Raffa
299 267520ba Santi Raffa
  def testGrowFile(self):
300 267520ba Santi Raffa
    with TestFileDeviceHelper.TempEnvironment(create_file=True) as env:
301 267520ba Santi Raffa
      self.assertRaises(errors.BlockDeviceError, lambda: \
302 267520ba Santi Raffa
        env.volume.Grow(-1, False, True, None))
303 267520ba Santi Raffa
304 267520ba Santi Raffa
      env.volume.Grow(2, False, True, None)
305 267520ba Santi Raffa
      self.assertEqual(2.0, env.volume.Size() / 1024.0**2)
306 267520ba Santi Raffa
307 267520ba Santi Raffa
  def testRemoveFile(self):
308 267520ba Santi Raffa
    with TestFileDeviceHelper.TempEnvironment(create_file=True,
309 267520ba Santi Raffa
                                              delete_file=False) as env:
310 267520ba Santi Raffa
      env.volume.Remove()
311 267520ba Santi Raffa
      env.volume.Exists(assert_exists=False)
312 267520ba Santi Raffa
313 820bade9 Helga Velroyen
if __name__ == "__main__":
314 820bade9 Helga Velroyen
  testutils.GanetiTestProgram()