Statistics
| Branch: | Tag: | Revision:

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

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