Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.backend_unittest.py @ 14933c17

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

839 f79be8ec Helga Velroyen
  These tests ensure, that the constant 'STS_REPORT' is consitent
840 f79be8ec Helga Velroyen
  with the implementation of invoking space reporting functions
841 f79be8ec Helga Velroyen
  in backend.py. Once space reporting is available for all types,
842 f79be8ec Helga Velroyen
  the constant can be removed and these tests as well.
843 f79be8ec Helga Velroyen

844 f79be8ec Helga Velroyen
  """
845 f79be8ec Helga Velroyen
  def testAllReportingTypesHaveAReportingFunction(self):
846 f79be8ec Helga Velroyen
    for storage_type in constants.STS_REPORT:
847 f79be8ec Helga Velroyen
      self.assertTrue(backend._STORAGE_TYPE_INFO_FN[storage_type] is not None)
848 f79be8ec Helga Velroyen
849 f79be8ec Helga Velroyen
  def testAllNotReportingTypesDoneHaveFunction(self):
850 9d0d4f21 Helga Velroyen
    non_reporting_types = set(constants.STORAGE_TYPES)\
851 f79be8ec Helga Velroyen
        - set(constants.STS_REPORT)
852 f79be8ec Helga Velroyen
    for storage_type in non_reporting_types:
853 f79be8ec Helga Velroyen
      self.assertEqual(None, backend._STORAGE_TYPE_INFO_FN[storage_type])
854 f79be8ec Helga Velroyen
855 f79be8ec Helga Velroyen
856 f942a838 Michael Hanselmann
if __name__ == "__main__":
857 f942a838 Michael Hanselmann
  testutils.GanetiTestProgram()