Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.backend_unittest.py @ a7d524e7

History | View | Annotate | Download (23.1 kB)

1 f942a838 Michael Hanselmann
#!/usr/bin/python
2 f942a838 Michael Hanselmann
#
3 f942a838 Michael Hanselmann
4 45bc4635 Iustin Pop
# Copyright (C) 2010, 2013 Google Inc.
5 f942a838 Michael Hanselmann
#
6 f942a838 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 f942a838 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 f942a838 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 f942a838 Michael Hanselmann
# (at your option) any later version.
10 f942a838 Michael Hanselmann
#
11 f942a838 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 f942a838 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 f942a838 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 f942a838 Michael Hanselmann
# General Public License for more details.
15 f942a838 Michael Hanselmann
#
16 f942a838 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 f942a838 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 f942a838 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 f942a838 Michael Hanselmann
# 02110-1301, USA.
20 f942a838 Michael Hanselmann
21 f942a838 Michael Hanselmann
22 f942a838 Michael Hanselmann
"""Script for testing ganeti.backend"""
23 f942a838 Michael Hanselmann
24 f942a838 Michael Hanselmann
import os
25 f942a838 Michael Hanselmann
import shutil
26 f942a838 Michael Hanselmann
import tempfile
27 f942a838 Michael Hanselmann
import unittest
28 fac83f8a Helga Velroyen
import mock
29 f942a838 Michael Hanselmann
30 f942a838 Michael Hanselmann
from ganeti import utils
31 31ff0247 Michael Hanselmann
from ganeti import constants
32 f942a838 Michael Hanselmann
from ganeti import backend
33 a744b676 Manuel Franceschini
from ganeti import netutils
34 fac83f8a Helga Velroyen
from ganeti import hypervisor
35 f942a838 Michael Hanselmann
36 f942a838 Michael Hanselmann
import testutils
37 f942a838 Michael Hanselmann
38 f942a838 Michael Hanselmann
39 f942a838 Michael Hanselmann
class TestX509Certificates(unittest.TestCase):
40 f942a838 Michael Hanselmann
  def setUp(self):
41 f942a838 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
42 f942a838 Michael Hanselmann
43 f942a838 Michael Hanselmann
  def tearDown(self):
44 f942a838 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
45 f942a838 Michael Hanselmann
46 f942a838 Michael Hanselmann
  def test(self):
47 f942a838 Michael Hanselmann
    (name, cert_pem) = backend.CreateX509Certificate(300, cryptodir=self.tmpdir)
48 f942a838 Michael Hanselmann
49 f942a838 Michael Hanselmann
    self.assertEqual(utils.ReadFile(os.path.join(self.tmpdir, name,
50 f942a838 Michael Hanselmann
                                                 backend._X509_CERT_FILE)),
51 f942a838 Michael Hanselmann
                     cert_pem)
52 f942a838 Michael Hanselmann
    self.assert_(0 < os.path.getsize(os.path.join(self.tmpdir, name,
53 f942a838 Michael Hanselmann
                                                  backend._X509_KEY_FILE)))
54 f942a838 Michael Hanselmann
55 f942a838 Michael Hanselmann
    (name2, cert_pem2) = \
56 f942a838 Michael Hanselmann
      backend.CreateX509Certificate(300, cryptodir=self.tmpdir)
57 f942a838 Michael Hanselmann
58 f942a838 Michael Hanselmann
    backend.RemoveX509Certificate(name, cryptodir=self.tmpdir)
59 f942a838 Michael Hanselmann
    backend.RemoveX509Certificate(name2, cryptodir=self.tmpdir)
60 f942a838 Michael Hanselmann
61 f942a838 Michael Hanselmann
    self.assertEqual(utils.ListVisibleFiles(self.tmpdir), [])
62 f942a838 Michael Hanselmann
63 f942a838 Michael Hanselmann
  def testNonEmpty(self):
64 f942a838 Michael Hanselmann
    (name, _) = backend.CreateX509Certificate(300, cryptodir=self.tmpdir)
65 f942a838 Michael Hanselmann
66 f942a838 Michael Hanselmann
    utils.WriteFile(utils.PathJoin(self.tmpdir, name, "hello-world"),
67 f942a838 Michael Hanselmann
                    data="Hello World")
68 f942a838 Michael Hanselmann
69 f942a838 Michael Hanselmann
    self.assertRaises(backend.RPCFail, backend.RemoveX509Certificate,
70 f942a838 Michael Hanselmann
                      name, cryptodir=self.tmpdir)
71 f942a838 Michael Hanselmann
72 f942a838 Michael Hanselmann
    self.assertEqual(utils.ListVisibleFiles(self.tmpdir), [name])
73 f942a838 Michael Hanselmann
74 f942a838 Michael Hanselmann
75 a3a5f850 Iustin Pop
class TestNodeVerify(testutils.GanetiTestCase):
76 75bf3149 Helga Velroyen
77 75bf3149 Helga Velroyen
  def setUp(self):
78 75bf3149 Helga Velroyen
    testutils.GanetiTestCase.setUp(self)
79 75bf3149 Helga Velroyen
    self._mock_hv = None
80 75bf3149 Helga Velroyen
81 75bf3149 Helga Velroyen
  def _GetHypervisor(self, hv_name):
82 75bf3149 Helga Velroyen
    self._mock_hv = hypervisor.GetHypervisor(hv_name)
83 75bf3149 Helga Velroyen
    self._mock_hv.ValidateParameters = mock.Mock()
84 75bf3149 Helga Velroyen
    self._mock_hv.Verify = mock.Mock()
85 75bf3149 Helga Velroyen
    return self._mock_hv
86 75bf3149 Helga Velroyen
87 a3a5f850 Iustin Pop
  def testMasterIPLocalhost(self):
88 a3a5f850 Iustin Pop
    # this a real functional test, but requires localhost to be reachable
89 b705c7a6 Manuel Franceschini
    local_data = (netutils.Hostname.GetSysName(),
90 b705c7a6 Manuel Franceschini
                  constants.IP4_ADDRESS_LOCALHOST)
91 75bf3149 Helga Velroyen
    result = backend.VerifyNode({constants.NV_MASTERIP: local_data}, None, {})
92 a3a5f850 Iustin Pop
    self.failUnless(constants.NV_MASTERIP in result,
93 a3a5f850 Iustin Pop
                    "Master IP data not returned")
94 a3a5f850 Iustin Pop
    self.failUnless(result[constants.NV_MASTERIP], "Cannot reach localhost")
95 a3a5f850 Iustin Pop
96 a3a5f850 Iustin Pop
  def testMasterIPUnreachable(self):
97 a3a5f850 Iustin Pop
    # Network 192.0.2.0/24 is reserved for test/documentation as per
98 926feaf1 Manuel Franceschini
    # RFC 5737
99 a3a5f850 Iustin Pop
    bad_data =  ("master.example.com", "192.0.2.1")
100 a3a5f850 Iustin Pop
    # we just test that whatever TcpPing returns, VerifyNode returns too
101 a744b676 Manuel Franceschini
    netutils.TcpPing = lambda a, b, source=None: False
102 75bf3149 Helga Velroyen
    result = backend.VerifyNode({constants.NV_MASTERIP: bad_data}, None, {})
103 a3a5f850 Iustin Pop
    self.failUnless(constants.NV_MASTERIP in result,
104 a3a5f850 Iustin Pop
                    "Master IP data not returned")
105 a3a5f850 Iustin Pop
    self.failIf(result[constants.NV_MASTERIP],
106 a744b676 Manuel Franceschini
                "Result from netutils.TcpPing corrupted")
107 a3a5f850 Iustin Pop
108 75bf3149 Helga Velroyen
  def testVerifyHvparams(self):
109 75bf3149 Helga Velroyen
    test_hvparams = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
110 75bf3149 Helga Velroyen
    test_what = {constants.NV_HVPARAMS: \
111 75bf3149 Helga Velroyen
        [("mynode", constants.HT_XEN_PVM, test_hvparams)]}
112 75bf3149 Helga Velroyen
    result = {}
113 75bf3149 Helga Velroyen
    backend._VerifyHvparams(test_what, True, result,
114 75bf3149 Helga Velroyen
                            get_hv_fn=self._GetHypervisor)
115 75bf3149 Helga Velroyen
    self._mock_hv.ValidateParameters.assert_called_with(test_hvparams)
116 75bf3149 Helga Velroyen
117 75bf3149 Helga Velroyen
  def testVerifyHypervisors(self):
118 75bf3149 Helga Velroyen
    hvname = constants.HT_XEN_PVM
119 75bf3149 Helga Velroyen
    hvparams = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
120 75bf3149 Helga Velroyen
    all_hvparams = {hvname: hvparams}
121 75bf3149 Helga Velroyen
    test_what = {constants.NV_HYPERVISOR: [hvname]}
122 75bf3149 Helga Velroyen
    result = {}
123 75bf3149 Helga Velroyen
    backend._VerifyHypervisors(
124 75bf3149 Helga Velroyen
        test_what, True, result, all_hvparams=all_hvparams,
125 75bf3149 Helga Velroyen
        get_hv_fn=self._GetHypervisor)
126 75bf3149 Helga Velroyen
    self._mock_hv.Verify.assert_called_with(hvparams=hvparams)
127 75bf3149 Helga Velroyen
128 a3a5f850 Iustin Pop
129 405bffe2 Michael Hanselmann
def _DefRestrictedCmdOwner():
130 1a2eb2dc Michael Hanselmann
  return (os.getuid(), os.getgid())
131 1a2eb2dc Michael Hanselmann
132 1a2eb2dc Michael Hanselmann
133 405bffe2 Michael Hanselmann
class TestVerifyRestrictedCmdName(unittest.TestCase):
134 1a2eb2dc Michael Hanselmann
  def testAcceptableName(self):
135 1a2eb2dc Michael Hanselmann
    for i in ["foo", "bar", "z1", "000first", "hello-world"]:
136 1a2eb2dc Michael Hanselmann
      for fn in [lambda s: s, lambda s: s.upper(), lambda s: s.title()]:
137 405bffe2 Michael Hanselmann
        (status, msg) = backend._VerifyRestrictedCmdName(fn(i))
138 1a2eb2dc Michael Hanselmann
        self.assertTrue(status)
139 1a2eb2dc Michael Hanselmann
        self.assertTrue(msg is None)
140 1a2eb2dc Michael Hanselmann
141 1a2eb2dc Michael Hanselmann
  def testEmptyAndSpace(self):
142 1a2eb2dc Michael Hanselmann
    for i in ["", " ", "\t", "\n"]:
143 405bffe2 Michael Hanselmann
      (status, msg) = backend._VerifyRestrictedCmdName(i)
144 1a2eb2dc Michael Hanselmann
      self.assertFalse(status)
145 1a2eb2dc Michael Hanselmann
      self.assertEqual(msg, "Missing command name")
146 1a2eb2dc Michael Hanselmann
147 1a2eb2dc Michael Hanselmann
  def testNameWithSlashes(self):
148 1a2eb2dc Michael Hanselmann
    for i in ["/", "./foo", "../moo", "some/name"]:
149 405bffe2 Michael Hanselmann
      (status, msg) = backend._VerifyRestrictedCmdName(i)
150 1a2eb2dc Michael Hanselmann
      self.assertFalse(status)
151 1a2eb2dc Michael Hanselmann
      self.assertEqual(msg, "Invalid command name")
152 1a2eb2dc Michael Hanselmann
153 1a2eb2dc Michael Hanselmann
  def testForbiddenCharacters(self):
154 1a2eb2dc Michael Hanselmann
    for i in ["#", ".", "..", "bash -c ls", "'"]:
155 405bffe2 Michael Hanselmann
      (status, msg) = backend._VerifyRestrictedCmdName(i)
156 1a2eb2dc Michael Hanselmann
      self.assertFalse(status)
157 1a2eb2dc Michael Hanselmann
      self.assertEqual(msg, "Command name contains forbidden characters")
158 1a2eb2dc Michael Hanselmann
159 1a2eb2dc Michael Hanselmann
160 405bffe2 Michael Hanselmann
class TestVerifyRestrictedCmdDirectory(unittest.TestCase):
161 1a2eb2dc Michael Hanselmann
  def setUp(self):
162 1a2eb2dc Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
163 1a2eb2dc Michael Hanselmann
164 1a2eb2dc Michael Hanselmann
  def tearDown(self):
165 1a2eb2dc Michael Hanselmann
    shutil.rmtree(self.tmpdir)
166 1a2eb2dc Michael Hanselmann
167 1a2eb2dc Michael Hanselmann
  def testCanNotStat(self):
168 1a2eb2dc Michael Hanselmann
    tmpname = utils.PathJoin(self.tmpdir, "foobar")
169 1a2eb2dc Michael Hanselmann
    self.assertFalse(os.path.exists(tmpname))
170 1a2eb2dc Michael Hanselmann
    (status, msg) = \
171 405bffe2 Michael Hanselmann
      backend._VerifyRestrictedCmdDirectory(tmpname, _owner=NotImplemented)
172 1a2eb2dc Michael Hanselmann
    self.assertFalse(status)
173 1a2eb2dc Michael Hanselmann
    self.assertTrue(msg.startswith("Can't stat(2) '"))
174 1a2eb2dc Michael Hanselmann
175 1a2eb2dc Michael Hanselmann
  def testTooPermissive(self):
176 1a2eb2dc Michael Hanselmann
    tmpname = utils.PathJoin(self.tmpdir, "foobar")
177 1a2eb2dc Michael Hanselmann
    os.mkdir(tmpname)
178 1a2eb2dc Michael Hanselmann
179 1a2eb2dc Michael Hanselmann
    for mode in [0777, 0706, 0760, 0722]:
180 1a2eb2dc Michael Hanselmann
      os.chmod(tmpname, mode)
181 1a2eb2dc Michael Hanselmann
      self.assertTrue(os.path.isdir(tmpname))
182 1a2eb2dc Michael Hanselmann
      (status, msg) = \
183 405bffe2 Michael Hanselmann
        backend._VerifyRestrictedCmdDirectory(tmpname, _owner=NotImplemented)
184 1a2eb2dc Michael Hanselmann
      self.assertFalse(status)
185 1a2eb2dc Michael Hanselmann
      self.assertTrue(msg.startswith("Permissions on '"))
186 1a2eb2dc Michael Hanselmann
187 1a2eb2dc Michael Hanselmann
  def testNoDirectory(self):
188 1a2eb2dc Michael Hanselmann
    tmpname = utils.PathJoin(self.tmpdir, "foobar")
189 1a2eb2dc Michael Hanselmann
    utils.WriteFile(tmpname, data="empty\n")
190 1a2eb2dc Michael Hanselmann
    self.assertTrue(os.path.isfile(tmpname))
191 1a2eb2dc Michael Hanselmann
    (status, msg) = \
192 405bffe2 Michael Hanselmann
      backend._VerifyRestrictedCmdDirectory(tmpname,
193 405bffe2 Michael Hanselmann
                                            _owner=_DefRestrictedCmdOwner())
194 1a2eb2dc Michael Hanselmann
    self.assertFalse(status)
195 1a2eb2dc Michael Hanselmann
    self.assertTrue(msg.endswith("is not a directory"))
196 1a2eb2dc Michael Hanselmann
197 1a2eb2dc Michael Hanselmann
  def testNormal(self):
198 1a2eb2dc Michael Hanselmann
    tmpname = utils.PathJoin(self.tmpdir, "foobar")
199 1a2eb2dc Michael Hanselmann
    os.mkdir(tmpname)
200 1a2eb2dc Michael Hanselmann
    self.assertTrue(os.path.isdir(tmpname))
201 1a2eb2dc Michael Hanselmann
    (status, msg) = \
202 405bffe2 Michael Hanselmann
      backend._VerifyRestrictedCmdDirectory(tmpname,
203 405bffe2 Michael Hanselmann
                                            _owner=_DefRestrictedCmdOwner())
204 1a2eb2dc Michael Hanselmann
    self.assertTrue(status)
205 1a2eb2dc Michael Hanselmann
    self.assertTrue(msg is None)
206 1a2eb2dc Michael Hanselmann
207 1a2eb2dc Michael Hanselmann
208 405bffe2 Michael Hanselmann
class TestVerifyRestrictedCmd(unittest.TestCase):
209 1a2eb2dc Michael Hanselmann
  def setUp(self):
210 1a2eb2dc Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
211 1a2eb2dc Michael Hanselmann
212 1a2eb2dc Michael Hanselmann
  def tearDown(self):
213 1a2eb2dc Michael Hanselmann
    shutil.rmtree(self.tmpdir)
214 1a2eb2dc Michael Hanselmann
215 1a2eb2dc Michael Hanselmann
  def testCanNotStat(self):
216 1a2eb2dc Michael Hanselmann
    tmpname = utils.PathJoin(self.tmpdir, "helloworld")
217 1a2eb2dc Michael Hanselmann
    self.assertFalse(os.path.exists(tmpname))
218 1a2eb2dc Michael Hanselmann
    (status, msg) = \
219 405bffe2 Michael Hanselmann
      backend._VerifyRestrictedCmd(self.tmpdir, "helloworld",
220 1a2eb2dc Michael Hanselmann
                                   _owner=NotImplemented)
221 1a2eb2dc Michael Hanselmann
    self.assertFalse(status)
222 1a2eb2dc Michael Hanselmann
    self.assertTrue(msg.startswith("Can't stat(2) '"))
223 1a2eb2dc Michael Hanselmann
224 1a2eb2dc Michael Hanselmann
  def testNotExecutable(self):
225 1a2eb2dc Michael Hanselmann
    tmpname = utils.PathJoin(self.tmpdir, "cmdname")
226 1a2eb2dc Michael Hanselmann
    utils.WriteFile(tmpname, data="empty\n")
227 1a2eb2dc Michael Hanselmann
    (status, msg) = \
228 405bffe2 Michael Hanselmann
      backend._VerifyRestrictedCmd(self.tmpdir, "cmdname",
229 405bffe2 Michael Hanselmann
                                   _owner=_DefRestrictedCmdOwner())
230 1a2eb2dc Michael Hanselmann
    self.assertFalse(status)
231 1a2eb2dc Michael Hanselmann
    self.assertTrue(msg.startswith("access(2) thinks '"))
232 1a2eb2dc Michael Hanselmann
233 1a2eb2dc Michael Hanselmann
  def testExecutable(self):
234 1a2eb2dc Michael Hanselmann
    tmpname = utils.PathJoin(self.tmpdir, "cmdname")
235 1a2eb2dc Michael Hanselmann
    utils.WriteFile(tmpname, data="empty\n", mode=0700)
236 1a2eb2dc Michael Hanselmann
    (status, executable) = \
237 405bffe2 Michael Hanselmann
      backend._VerifyRestrictedCmd(self.tmpdir, "cmdname",
238 405bffe2 Michael Hanselmann
                                   _owner=_DefRestrictedCmdOwner())
239 1a2eb2dc Michael Hanselmann
    self.assertTrue(status)
240 1a2eb2dc Michael Hanselmann
    self.assertEqual(executable, tmpname)
241 1a2eb2dc Michael Hanselmann
242 1a2eb2dc Michael Hanselmann
243 405bffe2 Michael Hanselmann
class TestPrepareRestrictedCmd(unittest.TestCase):
244 1a2eb2dc Michael Hanselmann
  _TEST_PATH = "/tmp/some/test/path"
245 1a2eb2dc Michael Hanselmann
246 1a2eb2dc Michael Hanselmann
  def testDirFails(self):
247 1a2eb2dc Michael Hanselmann
    def fn(path):
248 1a2eb2dc Michael Hanselmann
      self.assertEqual(path, self._TEST_PATH)
249 1a2eb2dc Michael Hanselmann
      return (False, "test error 31420")
250 1a2eb2dc Michael Hanselmann
251 1a2eb2dc Michael Hanselmann
    (status, msg) = \
252 405bffe2 Michael Hanselmann
      backend._PrepareRestrictedCmd(self._TEST_PATH, "cmd21152",
253 1a2eb2dc Michael Hanselmann
                                    _verify_dir=fn,
254 1a2eb2dc Michael Hanselmann
                                    _verify_name=NotImplemented,
255 1a2eb2dc Michael Hanselmann
                                    _verify_cmd=NotImplemented)
256 1a2eb2dc Michael Hanselmann
    self.assertFalse(status)
257 1a2eb2dc Michael Hanselmann
    self.assertEqual(msg, "test error 31420")
258 1a2eb2dc Michael Hanselmann
259 1a2eb2dc Michael Hanselmann
  def testNameFails(self):
260 1a2eb2dc Michael Hanselmann
    def fn(cmd):
261 1a2eb2dc Michael Hanselmann
      self.assertEqual(cmd, "cmd4617")
262 1a2eb2dc Michael Hanselmann
      return (False, "test error 591")
263 1a2eb2dc Michael Hanselmann
264 1a2eb2dc Michael Hanselmann
    (status, msg) = \
265 405bffe2 Michael Hanselmann
      backend._PrepareRestrictedCmd(self._TEST_PATH, "cmd4617",
266 1a2eb2dc Michael Hanselmann
                                    _verify_dir=lambda _: (True, None),
267 1a2eb2dc Michael Hanselmann
                                    _verify_name=fn,
268 1a2eb2dc Michael Hanselmann
                                    _verify_cmd=NotImplemented)
269 1a2eb2dc Michael Hanselmann
    self.assertFalse(status)
270 1a2eb2dc Michael Hanselmann
    self.assertEqual(msg, "test error 591")
271 1a2eb2dc Michael Hanselmann
272 1a2eb2dc Michael Hanselmann
  def testCommandFails(self):
273 1a2eb2dc Michael Hanselmann
    def fn(path, cmd):
274 1a2eb2dc Michael Hanselmann
      self.assertEqual(path, self._TEST_PATH)
275 1a2eb2dc Michael Hanselmann
      self.assertEqual(cmd, "cmd17577")
276 1a2eb2dc Michael Hanselmann
      return (False, "test error 25524")
277 1a2eb2dc Michael Hanselmann
278 1a2eb2dc Michael Hanselmann
    (status, msg) = \
279 405bffe2 Michael Hanselmann
      backend._PrepareRestrictedCmd(self._TEST_PATH, "cmd17577",
280 1a2eb2dc Michael Hanselmann
                                    _verify_dir=lambda _: (True, None),
281 1a2eb2dc Michael Hanselmann
                                    _verify_name=lambda _: (True, None),
282 1a2eb2dc Michael Hanselmann
                                    _verify_cmd=fn)
283 1a2eb2dc Michael Hanselmann
    self.assertFalse(status)
284 1a2eb2dc Michael Hanselmann
    self.assertEqual(msg, "test error 25524")
285 1a2eb2dc Michael Hanselmann
286 1a2eb2dc Michael Hanselmann
  def testSuccess(self):
287 1a2eb2dc Michael Hanselmann
    def fn(path, cmd):
288 1a2eb2dc Michael Hanselmann
      return (True, utils.PathJoin(path, cmd))
289 1a2eb2dc Michael Hanselmann
290 1a2eb2dc Michael Hanselmann
    (status, executable) = \
291 405bffe2 Michael Hanselmann
      backend._PrepareRestrictedCmd(self._TEST_PATH, "cmd22633",
292 1a2eb2dc Michael Hanselmann
                                    _verify_dir=lambda _: (True, None),
293 1a2eb2dc Michael Hanselmann
                                    _verify_name=lambda _: (True, None),
294 1a2eb2dc Michael Hanselmann
                                    _verify_cmd=fn)
295 1a2eb2dc Michael Hanselmann
    self.assertTrue(status)
296 1a2eb2dc Michael Hanselmann
    self.assertEqual(executable, utils.PathJoin(self._TEST_PATH, "cmd22633"))
297 1a2eb2dc Michael Hanselmann
298 1a2eb2dc Michael Hanselmann
299 405bffe2 Michael Hanselmann
def _SleepForRestrictedCmd(duration):
300 1a2eb2dc Michael Hanselmann
  assert duration > 5
301 1a2eb2dc Michael Hanselmann
302 1a2eb2dc Michael Hanselmann
303 405bffe2 Michael Hanselmann
def _GenericRestrictedCmdError(cmd):
304 1a2eb2dc Michael Hanselmann
  return "Executing command '%s' failed" % cmd
305 1a2eb2dc Michael Hanselmann
306 1a2eb2dc Michael Hanselmann
307 42bd26e8 Michael Hanselmann
class TestRunRestrictedCmd(unittest.TestCase):
308 1a2eb2dc Michael Hanselmann
  def setUp(self):
309 1a2eb2dc Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
310 1a2eb2dc Michael Hanselmann
311 1a2eb2dc Michael Hanselmann
  def tearDown(self):
312 1a2eb2dc Michael Hanselmann
    shutil.rmtree(self.tmpdir)
313 1a2eb2dc Michael Hanselmann
314 1a2eb2dc Michael Hanselmann
  def testNonExistantLockDirectory(self):
315 1a2eb2dc Michael Hanselmann
    lockfile = utils.PathJoin(self.tmpdir, "does", "not", "exist")
316 405bffe2 Michael Hanselmann
    sleep_fn = testutils.CallCounter(_SleepForRestrictedCmd)
317 1a2eb2dc Michael Hanselmann
    self.assertFalse(os.path.exists(lockfile))
318 1a2eb2dc Michael Hanselmann
    self.assertRaises(backend.RPCFail,
319 42bd26e8 Michael Hanselmann
                      backend.RunRestrictedCmd, "test",
320 1a2eb2dc Michael Hanselmann
                      _lock_timeout=NotImplemented,
321 1a2eb2dc Michael Hanselmann
                      _lock_file=lockfile,
322 1a2eb2dc Michael Hanselmann
                      _path=NotImplemented,
323 1a2eb2dc Michael Hanselmann
                      _sleep_fn=sleep_fn,
324 1a2eb2dc Michael Hanselmann
                      _prepare_fn=NotImplemented,
325 1a2eb2dc Michael Hanselmann
                      _runcmd_fn=NotImplemented,
326 1a2eb2dc Michael Hanselmann
                      _enabled=True)
327 1a2eb2dc Michael Hanselmann
    self.assertEqual(sleep_fn.Count(), 1)
328 1a2eb2dc Michael Hanselmann
329 1a2eb2dc Michael Hanselmann
  @staticmethod
330 1a2eb2dc Michael Hanselmann
  def _TryLock(lockfile):
331 405bffe2 Michael Hanselmann
    sleep_fn = testutils.CallCounter(_SleepForRestrictedCmd)
332 1a2eb2dc Michael Hanselmann
333 1a2eb2dc Michael Hanselmann
    result = False
334 1a2eb2dc Michael Hanselmann
    try:
335 42bd26e8 Michael Hanselmann
      backend.RunRestrictedCmd("test22717",
336 1a2eb2dc Michael Hanselmann
                               _lock_timeout=0.1,
337 1a2eb2dc Michael Hanselmann
                               _lock_file=lockfile,
338 1a2eb2dc Michael Hanselmann
                               _path=NotImplemented,
339 1a2eb2dc Michael Hanselmann
                               _sleep_fn=sleep_fn,
340 1a2eb2dc Michael Hanselmann
                               _prepare_fn=NotImplemented,
341 1a2eb2dc Michael Hanselmann
                               _runcmd_fn=NotImplemented,
342 1a2eb2dc Michael Hanselmann
                               _enabled=True)
343 1a2eb2dc Michael Hanselmann
    except backend.RPCFail, err:
344 405bffe2 Michael Hanselmann
      assert str(err) == _GenericRestrictedCmdError("test22717"), \
345 1a2eb2dc Michael Hanselmann
             "Did not fail with generic error message"
346 1a2eb2dc Michael Hanselmann
      result = True
347 1a2eb2dc Michael Hanselmann
348 1a2eb2dc Michael Hanselmann
    assert sleep_fn.Count() == 1
349 1a2eb2dc Michael Hanselmann
350 1a2eb2dc Michael Hanselmann
    return result
351 1a2eb2dc Michael Hanselmann
352 1a2eb2dc Michael Hanselmann
  def testLockHeldByOtherProcess(self):
353 1a2eb2dc Michael Hanselmann
    lockfile = utils.PathJoin(self.tmpdir, "lock")
354 1a2eb2dc Michael Hanselmann
355 1a2eb2dc Michael Hanselmann
    lock = utils.FileLock.Open(lockfile)
356 1a2eb2dc Michael Hanselmann
    lock.Exclusive(blocking=True, timeout=1.0)
357 1a2eb2dc Michael Hanselmann
    try:
358 1a2eb2dc Michael Hanselmann
      self.assertTrue(utils.RunInSeparateProcess(self._TryLock, lockfile))
359 1a2eb2dc Michael Hanselmann
    finally:
360 1a2eb2dc Michael Hanselmann
      lock.Close()
361 1a2eb2dc Michael Hanselmann
362 1a2eb2dc Michael Hanselmann
  @staticmethod
363 1a2eb2dc Michael Hanselmann
  def _PrepareRaisingException(path, cmd):
364 1a2eb2dc Michael Hanselmann
    assert cmd == "test23122"
365 1a2eb2dc Michael Hanselmann
    raise Exception("test")
366 1a2eb2dc Michael Hanselmann
367 1a2eb2dc Michael Hanselmann
  def testPrepareRaisesException(self):
368 1a2eb2dc Michael Hanselmann
    lockfile = utils.PathJoin(self.tmpdir, "lock")
369 1a2eb2dc Michael Hanselmann
370 405bffe2 Michael Hanselmann
    sleep_fn = testutils.CallCounter(_SleepForRestrictedCmd)
371 1a2eb2dc Michael Hanselmann
    prepare_fn = testutils.CallCounter(self._PrepareRaisingException)
372 1a2eb2dc Michael Hanselmann
373 1a2eb2dc Michael Hanselmann
    try:
374 42bd26e8 Michael Hanselmann
      backend.RunRestrictedCmd("test23122",
375 1a2eb2dc Michael Hanselmann
                               _lock_timeout=1.0, _lock_file=lockfile,
376 1a2eb2dc Michael Hanselmann
                               _path=NotImplemented, _runcmd_fn=NotImplemented,
377 1a2eb2dc Michael Hanselmann
                               _sleep_fn=sleep_fn, _prepare_fn=prepare_fn,
378 1a2eb2dc Michael Hanselmann
                               _enabled=True)
379 1a2eb2dc Michael Hanselmann
    except backend.RPCFail, err:
380 405bffe2 Michael Hanselmann
      self.assertEqual(str(err), _GenericRestrictedCmdError("test23122"))
381 1a2eb2dc Michael Hanselmann
    else:
382 1a2eb2dc Michael Hanselmann
      self.fail("Didn't fail")
383 1a2eb2dc Michael Hanselmann
384 1a2eb2dc Michael Hanselmann
    self.assertEqual(sleep_fn.Count(), 1)
385 1a2eb2dc Michael Hanselmann
    self.assertEqual(prepare_fn.Count(), 1)
386 1a2eb2dc Michael Hanselmann
387 1a2eb2dc Michael Hanselmann
  @staticmethod
388 1a2eb2dc Michael Hanselmann
  def _PrepareFails(path, cmd):
389 1a2eb2dc Michael Hanselmann
    assert cmd == "test29327"
390 1a2eb2dc Michael Hanselmann
    return ("some error message", None)
391 1a2eb2dc Michael Hanselmann
392 1a2eb2dc Michael Hanselmann
  def testPrepareFails(self):
393 1a2eb2dc Michael Hanselmann
    lockfile = utils.PathJoin(self.tmpdir, "lock")
394 1a2eb2dc Michael Hanselmann
395 405bffe2 Michael Hanselmann
    sleep_fn = testutils.CallCounter(_SleepForRestrictedCmd)
396 1a2eb2dc Michael Hanselmann
    prepare_fn = testutils.CallCounter(self._PrepareFails)
397 1a2eb2dc Michael Hanselmann
398 1a2eb2dc Michael Hanselmann
    try:
399 42bd26e8 Michael Hanselmann
      backend.RunRestrictedCmd("test29327",
400 1a2eb2dc Michael Hanselmann
                               _lock_timeout=1.0, _lock_file=lockfile,
401 1a2eb2dc Michael Hanselmann
                               _path=NotImplemented, _runcmd_fn=NotImplemented,
402 1a2eb2dc Michael Hanselmann
                               _sleep_fn=sleep_fn, _prepare_fn=prepare_fn,
403 1a2eb2dc Michael Hanselmann
                               _enabled=True)
404 1a2eb2dc Michael Hanselmann
    except backend.RPCFail, err:
405 405bffe2 Michael Hanselmann
      self.assertEqual(str(err), _GenericRestrictedCmdError("test29327"))
406 1a2eb2dc Michael Hanselmann
    else:
407 1a2eb2dc Michael Hanselmann
      self.fail("Didn't fail")
408 1a2eb2dc Michael Hanselmann
409 1a2eb2dc Michael Hanselmann
    self.assertEqual(sleep_fn.Count(), 1)
410 1a2eb2dc Michael Hanselmann
    self.assertEqual(prepare_fn.Count(), 1)
411 1a2eb2dc Michael Hanselmann
412 1a2eb2dc Michael Hanselmann
  @staticmethod
413 1a2eb2dc Michael Hanselmann
  def _SuccessfulPrepare(path, cmd):
414 1a2eb2dc Michael Hanselmann
    return (True, utils.PathJoin(path, cmd))
415 1a2eb2dc Michael Hanselmann
416 1a2eb2dc Michael Hanselmann
  def testRunCmdFails(self):
417 1a2eb2dc Michael Hanselmann
    lockfile = utils.PathJoin(self.tmpdir, "lock")
418 1a2eb2dc Michael Hanselmann
419 1a2eb2dc Michael Hanselmann
    def fn(args, env=NotImplemented, reset_env=NotImplemented,
420 1a2eb2dc Michael Hanselmann
           postfork_fn=NotImplemented):
421 1a2eb2dc Michael Hanselmann
      self.assertEqual(args, [utils.PathJoin(self.tmpdir, "test3079")])
422 1a2eb2dc Michael Hanselmann
      self.assertEqual(env, {})
423 1a2eb2dc Michael Hanselmann
      self.assertTrue(reset_env)
424 1a2eb2dc Michael Hanselmann
      self.assertTrue(callable(postfork_fn))
425 1a2eb2dc Michael Hanselmann
426 1a2eb2dc Michael Hanselmann
      trylock = utils.FileLock.Open(lockfile)
427 1a2eb2dc Michael Hanselmann
      try:
428 1a2eb2dc Michael Hanselmann
        # See if lockfile is still held
429 1a2eb2dc Michael Hanselmann
        self.assertRaises(EnvironmentError, trylock.Exclusive, blocking=False)
430 1a2eb2dc Michael Hanselmann
431 1a2eb2dc Michael Hanselmann
        # Call back to release lock
432 1a2eb2dc Michael Hanselmann
        postfork_fn(NotImplemented)
433 1a2eb2dc Michael Hanselmann
434 1a2eb2dc Michael Hanselmann
        # See if lockfile can be acquired
435 1a2eb2dc Michael Hanselmann
        trylock.Exclusive(blocking=False)
436 1a2eb2dc Michael Hanselmann
      finally:
437 1a2eb2dc Michael Hanselmann
        trylock.Close()
438 1a2eb2dc Michael Hanselmann
439 1a2eb2dc Michael Hanselmann
      # Simulate a failed command
440 1a2eb2dc Michael Hanselmann
      return utils.RunResult(constants.EXIT_FAILURE, None,
441 1a2eb2dc Michael Hanselmann
                             "stdout", "stderr406328567",
442 1a2eb2dc Michael Hanselmann
                             utils.ShellQuoteArgs(args),
443 1a2eb2dc Michael Hanselmann
                             NotImplemented, NotImplemented)
444 1a2eb2dc Michael Hanselmann
445 405bffe2 Michael Hanselmann
    sleep_fn = testutils.CallCounter(_SleepForRestrictedCmd)
446 1a2eb2dc Michael Hanselmann
    prepare_fn = testutils.CallCounter(self._SuccessfulPrepare)
447 1a2eb2dc Michael Hanselmann
    runcmd_fn = testutils.CallCounter(fn)
448 1a2eb2dc Michael Hanselmann
449 1a2eb2dc Michael Hanselmann
    try:
450 42bd26e8 Michael Hanselmann
      backend.RunRestrictedCmd("test3079",
451 1a2eb2dc Michael Hanselmann
                               _lock_timeout=1.0, _lock_file=lockfile,
452 1a2eb2dc Michael Hanselmann
                               _path=self.tmpdir, _runcmd_fn=runcmd_fn,
453 1a2eb2dc Michael Hanselmann
                               _sleep_fn=sleep_fn, _prepare_fn=prepare_fn,
454 1a2eb2dc Michael Hanselmann
                               _enabled=True)
455 1a2eb2dc Michael Hanselmann
    except backend.RPCFail, err:
456 45bc4635 Iustin Pop
      self.assertTrue(str(err).startswith("Restricted command 'test3079'"
457 45bc4635 Iustin Pop
                                          " failed:"))
458 1a2eb2dc Michael Hanselmann
      self.assertTrue("stderr406328567" in str(err),
459 1a2eb2dc Michael Hanselmann
                      msg="Error did not include output")
460 1a2eb2dc Michael Hanselmann
    else:
461 1a2eb2dc Michael Hanselmann
      self.fail("Didn't fail")
462 1a2eb2dc Michael Hanselmann
463 1a2eb2dc Michael Hanselmann
    self.assertEqual(sleep_fn.Count(), 0)
464 1a2eb2dc Michael Hanselmann
    self.assertEqual(prepare_fn.Count(), 1)
465 1a2eb2dc Michael Hanselmann
    self.assertEqual(runcmd_fn.Count(), 1)
466 1a2eb2dc Michael Hanselmann
467 1a2eb2dc Michael Hanselmann
  def testRunCmdSucceeds(self):
468 1a2eb2dc Michael Hanselmann
    lockfile = utils.PathJoin(self.tmpdir, "lock")
469 1a2eb2dc Michael Hanselmann
470 1a2eb2dc Michael Hanselmann
    def fn(args, env=NotImplemented, reset_env=NotImplemented,
471 1a2eb2dc Michael Hanselmann
           postfork_fn=NotImplemented):
472 1a2eb2dc Michael Hanselmann
      self.assertEqual(args, [utils.PathJoin(self.tmpdir, "test5667")])
473 1a2eb2dc Michael Hanselmann
      self.assertEqual(env, {})
474 1a2eb2dc Michael Hanselmann
      self.assertTrue(reset_env)
475 1a2eb2dc Michael Hanselmann
476 1a2eb2dc Michael Hanselmann
      # Call back to release lock
477 1a2eb2dc Michael Hanselmann
      postfork_fn(NotImplemented)
478 1a2eb2dc Michael Hanselmann
479 1a2eb2dc Michael Hanselmann
      # Simulate a successful command
480 1a2eb2dc Michael Hanselmann
      return utils.RunResult(constants.EXIT_SUCCESS, None, "stdout14463", "",
481 1a2eb2dc Michael Hanselmann
                             utils.ShellQuoteArgs(args),
482 1a2eb2dc Michael Hanselmann
                             NotImplemented, NotImplemented)
483 1a2eb2dc Michael Hanselmann
484 405bffe2 Michael Hanselmann
    sleep_fn = testutils.CallCounter(_SleepForRestrictedCmd)
485 1a2eb2dc Michael Hanselmann
    prepare_fn = testutils.CallCounter(self._SuccessfulPrepare)
486 1a2eb2dc Michael Hanselmann
    runcmd_fn = testutils.CallCounter(fn)
487 1a2eb2dc Michael Hanselmann
488 42bd26e8 Michael Hanselmann
    result = backend.RunRestrictedCmd("test5667",
489 1a2eb2dc Michael Hanselmann
                                      _lock_timeout=1.0, _lock_file=lockfile,
490 1a2eb2dc Michael Hanselmann
                                      _path=self.tmpdir, _runcmd_fn=runcmd_fn,
491 1a2eb2dc Michael Hanselmann
                                      _sleep_fn=sleep_fn,
492 1a2eb2dc Michael Hanselmann
                                      _prepare_fn=prepare_fn,
493 1a2eb2dc Michael Hanselmann
                                      _enabled=True)
494 1a2eb2dc Michael Hanselmann
    self.assertEqual(result, "stdout14463")
495 1a2eb2dc Michael Hanselmann
496 1a2eb2dc Michael Hanselmann
    self.assertEqual(sleep_fn.Count(), 0)
497 1a2eb2dc Michael Hanselmann
    self.assertEqual(prepare_fn.Count(), 1)
498 1a2eb2dc Michael Hanselmann
    self.assertEqual(runcmd_fn.Count(), 1)
499 1a2eb2dc Michael Hanselmann
500 1a2eb2dc Michael Hanselmann
  def testCommandsDisabled(self):
501 1a2eb2dc Michael Hanselmann
    try:
502 42bd26e8 Michael Hanselmann
      backend.RunRestrictedCmd("test",
503 1a2eb2dc Michael Hanselmann
                               _lock_timeout=NotImplemented,
504 1a2eb2dc Michael Hanselmann
                               _lock_file=NotImplemented,
505 1a2eb2dc Michael Hanselmann
                               _path=NotImplemented,
506 1a2eb2dc Michael Hanselmann
                               _sleep_fn=NotImplemented,
507 1a2eb2dc Michael Hanselmann
                               _prepare_fn=NotImplemented,
508 1a2eb2dc Michael Hanselmann
                               _runcmd_fn=NotImplemented,
509 1a2eb2dc Michael Hanselmann
                               _enabled=False)
510 1a2eb2dc Michael Hanselmann
    except backend.RPCFail, err:
511 45bc4635 Iustin Pop
      self.assertEqual(str(err),
512 45bc4635 Iustin Pop
                       "Restricted commands disabled at configure time")
513 1a2eb2dc Michael Hanselmann
    else:
514 1a2eb2dc Michael Hanselmann
      self.fail("Did not raise exception")
515 1a2eb2dc Michael Hanselmann
516 1a2eb2dc Michael Hanselmann
517 99e222b1 Michael Hanselmann
class TestSetWatcherPause(unittest.TestCase):
518 99e222b1 Michael Hanselmann
  def setUp(self):
519 99e222b1 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
520 99e222b1 Michael Hanselmann
    self.filename = utils.PathJoin(self.tmpdir, "pause")
521 99e222b1 Michael Hanselmann
522 99e222b1 Michael Hanselmann
  def tearDown(self):
523 99e222b1 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
524 99e222b1 Michael Hanselmann
525 99e222b1 Michael Hanselmann
  def testUnsetNonExisting(self):
526 99e222b1 Michael Hanselmann
    self.assertFalse(os.path.exists(self.filename))
527 99e222b1 Michael Hanselmann
    backend.SetWatcherPause(None, _filename=self.filename)
528 99e222b1 Michael Hanselmann
    self.assertFalse(os.path.exists(self.filename))
529 99e222b1 Michael Hanselmann
530 99e222b1 Michael Hanselmann
  def testSetNonNumeric(self):
531 99e222b1 Michael Hanselmann
    for i in ["", [], {}, "Hello World", "0", "1.0"]:
532 99e222b1 Michael Hanselmann
      self.assertFalse(os.path.exists(self.filename))
533 99e222b1 Michael Hanselmann
534 99e222b1 Michael Hanselmann
      try:
535 99e222b1 Michael Hanselmann
        backend.SetWatcherPause(i, _filename=self.filename)
536 99e222b1 Michael Hanselmann
      except backend.RPCFail, err:
537 99e222b1 Michael Hanselmann
        self.assertEqual(str(err), "Duration must be numeric")
538 99e222b1 Michael Hanselmann
      else:
539 99e222b1 Michael Hanselmann
        self.fail("Did not raise exception")
540 99e222b1 Michael Hanselmann
541 99e222b1 Michael Hanselmann
      self.assertFalse(os.path.exists(self.filename))
542 99e222b1 Michael Hanselmann
543 99e222b1 Michael Hanselmann
  def testSet(self):
544 99e222b1 Michael Hanselmann
    self.assertFalse(os.path.exists(self.filename))
545 99e222b1 Michael Hanselmann
546 99e222b1 Michael Hanselmann
    for i in range(10):
547 99e222b1 Michael Hanselmann
      backend.SetWatcherPause(i, _filename=self.filename)
548 99e222b1 Michael Hanselmann
      self.assertEqual(utils.ReadFile(self.filename), "%s\n" % i)
549 99e222b1 Michael Hanselmann
      self.assertEqual(os.stat(self.filename).st_mode & 0777, 0644)
550 99e222b1 Michael Hanselmann
551 99e222b1 Michael Hanselmann
552 3b721842 Michael Hanselmann
class TestGetBlockDevSymlinkPath(unittest.TestCase):
553 3b721842 Michael Hanselmann
  def setUp(self):
554 3b721842 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
555 3b721842 Michael Hanselmann
556 3b721842 Michael Hanselmann
  def tearDown(self):
557 3b721842 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
558 3b721842 Michael Hanselmann
559 3b721842 Michael Hanselmann
  def _Test(self, name, idx):
560 3b721842 Michael Hanselmann
    self.assertEqual(backend._GetBlockDevSymlinkPath(name, idx,
561 3b721842 Michael Hanselmann
                                                     _dir=self.tmpdir),
562 3b721842 Michael Hanselmann
                     ("%s/%s%s%s" % (self.tmpdir, name,
563 3b721842 Michael Hanselmann
                                     constants.DISK_SEPARATOR, idx)))
564 3b721842 Michael Hanselmann
565 3b721842 Michael Hanselmann
  def test(self):
566 3b721842 Michael Hanselmann
    for idx in range(100):
567 3b721842 Michael Hanselmann
      self._Test("inst1.example.com", idx)
568 3b721842 Michael Hanselmann
569 3b721842 Michael Hanselmann
570 fac83f8a Helga Velroyen
class TestGetInstanceList(unittest.TestCase):
571 fac83f8a Helga Velroyen
572 fac83f8a Helga Velroyen
  def setUp(self):
573 fac83f8a Helga Velroyen
    self._test_hv = self._TestHypervisor()
574 fac83f8a Helga Velroyen
    self._test_hv.ListInstances = mock.Mock(
575 fac83f8a Helga Velroyen
      return_value=["instance1", "instance2", "instance3"] )
576 fac83f8a Helga Velroyen
577 fac83f8a Helga Velroyen
  class _TestHypervisor(hypervisor.hv_base.BaseHypervisor):
578 fac83f8a Helga Velroyen
    def __init__(self):
579 fac83f8a Helga Velroyen
      hypervisor.hv_base.BaseHypervisor.__init__(self)
580 fac83f8a Helga Velroyen
581 fac83f8a Helga Velroyen
  def _GetHypervisor(self, name):
582 fac83f8a Helga Velroyen
    return self._test_hv
583 fac83f8a Helga Velroyen
584 fac83f8a Helga Velroyen
  def testHvparams(self):
585 fac83f8a Helga Velroyen
    fake_hvparams = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
586 fac83f8a Helga Velroyen
    hvparams = {constants.HT_FAKE: fake_hvparams}
587 fac83f8a Helga Velroyen
    backend.GetInstanceList([constants.HT_FAKE], all_hvparams=hvparams,
588 fac83f8a Helga Velroyen
                            get_hv_fn=self._GetHypervisor)
589 fac83f8a Helga Velroyen
    self._test_hv.ListInstances.assert_called_with(hvparams=fake_hvparams)
590 fac83f8a Helga Velroyen
591 fac83f8a Helga Velroyen
592 439e1d3f Helga Velroyen
class TestGetHvInfo(unittest.TestCase):
593 439e1d3f Helga Velroyen
594 439e1d3f Helga Velroyen
  def setUp(self):
595 439e1d3f Helga Velroyen
    self._test_hv = self._TestHypervisor()
596 439e1d3f Helga Velroyen
    self._test_hv.GetNodeInfo = mock.Mock()
597 439e1d3f Helga Velroyen
598 439e1d3f Helga Velroyen
  class _TestHypervisor(hypervisor.hv_base.BaseHypervisor):
599 439e1d3f Helga Velroyen
    def __init__(self):
600 439e1d3f Helga Velroyen
      hypervisor.hv_base.BaseHypervisor.__init__(self)
601 439e1d3f Helga Velroyen
602 439e1d3f Helga Velroyen
  def _GetHypervisor(self, name):
603 439e1d3f Helga Velroyen
    return self._test_hv
604 439e1d3f Helga Velroyen
605 439e1d3f Helga Velroyen
  def testGetHvInfoAllNone(self):
606 439e1d3f Helga Velroyen
    result = backend._GetHvInfoAll(None)
607 439e1d3f Helga Velroyen
    self.assertTrue(result is None)
608 439e1d3f Helga Velroyen
609 439e1d3f Helga Velroyen
  def testGetHvInfoAll(self):
610 439e1d3f Helga Velroyen
    hvname = constants.HT_XEN_PVM
611 439e1d3f Helga Velroyen
    hvparams = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
612 439e1d3f Helga Velroyen
    hv_specs = [(hvname, hvparams)]
613 439e1d3f Helga Velroyen
614 a7d524e7 Helga Velroyen
    backend._GetHvInfoAll(hv_specs, self._GetHypervisor)
615 439e1d3f Helga Velroyen
    self._test_hv.GetNodeInfo.assert_called_with(hvparams=hvparams)
616 439e1d3f Helga Velroyen
617 439e1d3f Helga Velroyen
618 f39a8d14 Helga Velroyen
class TestApplyStorageInfoFunction(unittest.TestCase):
619 f39a8d14 Helga Velroyen
620 f39a8d14 Helga Velroyen
  _STORAGE_KEY = "some_key"
621 f39a8d14 Helga Velroyen
  _SOME_ARGS = "some_args"
622 f39a8d14 Helga Velroyen
623 f39a8d14 Helga Velroyen
  def setUp(self):
624 f39a8d14 Helga Velroyen
    self.mock_storage_fn = mock.Mock()
625 f39a8d14 Helga Velroyen
626 f39a8d14 Helga Velroyen
  def testApplyValidStorageType(self):
627 f39a8d14 Helga Velroyen
    storage_type = constants.ST_LVM_VG
628 f39a8d14 Helga Velroyen
    backend._STORAGE_TYPE_INFO_FN = {
629 f39a8d14 Helga Velroyen
        storage_type: self.mock_storage_fn
630 f39a8d14 Helga Velroyen
      }
631 f39a8d14 Helga Velroyen
632 f39a8d14 Helga Velroyen
    backend._ApplyStorageInfoFunction(
633 f39a8d14 Helga Velroyen
        storage_type, self._STORAGE_KEY, self._SOME_ARGS)
634 f39a8d14 Helga Velroyen
635 f39a8d14 Helga Velroyen
    self.mock_storage_fn.assert_called_with(self._STORAGE_KEY, self._SOME_ARGS)
636 f39a8d14 Helga Velroyen
637 f39a8d14 Helga Velroyen
  def testApplyInValidStorageType(self):
638 f39a8d14 Helga Velroyen
    storage_type = "invalid_storage_type"
639 f39a8d14 Helga Velroyen
    backend._STORAGE_TYPE_INFO_FN = {}
640 f39a8d14 Helga Velroyen
641 f39a8d14 Helga Velroyen
    self.assertRaises(KeyError, backend._ApplyStorageInfoFunction,
642 f39a8d14 Helga Velroyen
                      storage_type, self._STORAGE_KEY, self._SOME_ARGS)
643 f39a8d14 Helga Velroyen
644 f39a8d14 Helga Velroyen
  def testApplyNotImplementedStorageType(self):
645 f39a8d14 Helga Velroyen
    storage_type = "not_implemented_storage_type"
646 f39a8d14 Helga Velroyen
    backend._STORAGE_TYPE_INFO_FN = {storage_type: None}
647 f39a8d14 Helga Velroyen
648 f39a8d14 Helga Velroyen
    self.assertRaises(NotImplementedError,
649 f39a8d14 Helga Velroyen
                      backend._ApplyStorageInfoFunction,
650 f39a8d14 Helga Velroyen
                      storage_type, self._STORAGE_KEY, self._SOME_ARGS)
651 f39a8d14 Helga Velroyen
652 f39a8d14 Helga Velroyen
653 f39a8d14 Helga Velroyen
class TestGetNodeInfo(unittest.TestCase):
654 f39a8d14 Helga Velroyen
655 f39a8d14 Helga Velroyen
  _SOME_RESULT = None
656 f39a8d14 Helga Velroyen
657 f39a8d14 Helga Velroyen
  def testApplyStorageInfoFunction(self):
658 f39a8d14 Helga Velroyen
    excl_storage_flag = False
659 f39a8d14 Helga Velroyen
    backend._ApplyStorageInfoFunction = mock.Mock(
660 f39a8d14 Helga Velroyen
        return_value=self._SOME_RESULT)
661 f39a8d14 Helga Velroyen
    storage_units = [(st, st + "_key") for st in
662 f39a8d14 Helga Velroyen
                     constants.VALID_STORAGE_TYPES]
663 f39a8d14 Helga Velroyen
664 f39a8d14 Helga Velroyen
    backend.GetNodeInfo(storage_units, None, excl_storage_flag)
665 f39a8d14 Helga Velroyen
666 f39a8d14 Helga Velroyen
    call_args_list = backend._ApplyStorageInfoFunction.call_args_list
667 f39a8d14 Helga Velroyen
    self.assertEqual(len(constants.VALID_STORAGE_TYPES), len(call_args_list))
668 f39a8d14 Helga Velroyen
    for call in call_args_list:
669 f39a8d14 Helga Velroyen
      storage_type, storage_key, excl_storage = call[0]
670 f39a8d14 Helga Velroyen
      self.assertEqual(storage_type + "_key", storage_key)
671 f39a8d14 Helga Velroyen
      self.assertTrue(storage_type in constants.VALID_STORAGE_TYPES)
672 f39a8d14 Helga Velroyen
673 f39a8d14 Helga Velroyen
674 f942a838 Michael Hanselmann
if __name__ == "__main__":
675 f942a838 Michael Hanselmann
  testutils.GanetiTestProgram()