Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.hypervisor.hv_xen_unittest.py @ 398fd4f6

History | View | Annotate | Download (30.8 kB)

1 55cc0a44 Michael Hanselmann
#!/usr/bin/python
2 55cc0a44 Michael Hanselmann
#
3 55cc0a44 Michael Hanselmann
4 b255379d Michael Hanselmann
# Copyright (C) 2011, 2013 Google Inc.
5 55cc0a44 Michael Hanselmann
#
6 55cc0a44 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 55cc0a44 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 55cc0a44 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 55cc0a44 Michael Hanselmann
# (at your option) any later version.
10 55cc0a44 Michael Hanselmann
#
11 55cc0a44 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 55cc0a44 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 55cc0a44 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 55cc0a44 Michael Hanselmann
# General Public License for more details.
15 55cc0a44 Michael Hanselmann
#
16 55cc0a44 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 55cc0a44 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 55cc0a44 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 55cc0a44 Michael Hanselmann
# 02110-1301, USA.
20 55cc0a44 Michael Hanselmann
21 55cc0a44 Michael Hanselmann
22 b44af065 Helga Velroyen
"""Script for testing ganeti.hypervisor.hv_xen"""
23 55cc0a44 Michael Hanselmann
24 d0bb3f24 Michael Hanselmann
import string # pylint: disable=W0402
25 55cc0a44 Michael Hanselmann
import unittest
26 64a66bd2 Michael Hanselmann
import tempfile
27 64a66bd2 Michael Hanselmann
import shutil
28 74a50c46 Michael Hanselmann
import random
29 7610d884 Michael Hanselmann
import os
30 58e356a9 Helga Velroyen
import mock
31 55cc0a44 Michael Hanselmann
32 55cc0a44 Michael Hanselmann
from ganeti import constants
33 55cc0a44 Michael Hanselmann
from ganeti import objects
34 48bba9de Balazs Lecz
from ganeti import pathutils
35 55cc0a44 Michael Hanselmann
from ganeti import hypervisor
36 b255379d Michael Hanselmann
from ganeti import utils
37 b255379d Michael Hanselmann
from ganeti import errors
38 b255379d Michael Hanselmann
from ganeti import compat
39 55cc0a44 Michael Hanselmann
40 55cc0a44 Michael Hanselmann
from ganeti.hypervisor import hv_xen
41 55cc0a44 Michael Hanselmann
42 55cc0a44 Michael Hanselmann
import testutils
43 55cc0a44 Michael Hanselmann
44 55cc0a44 Michael Hanselmann
45 74a50c46 Michael Hanselmann
# Map from hypervisor class to hypervisor name
46 74a50c46 Michael Hanselmann
HVCLASS_TO_HVNAME = utils.InvertDict(hypervisor._HYPERVISOR_MAP)
47 74a50c46 Michael Hanselmann
48 74a50c46 Michael Hanselmann
49 55cc0a44 Michael Hanselmann
class TestConsole(unittest.TestCase):
50 55cc0a44 Michael Hanselmann
  def test(self):
51 55cc0a44 Michael Hanselmann
    for cls in [hv_xen.XenPvmHypervisor, hv_xen.XenHvmHypervisor]:
52 55cc0a44 Michael Hanselmann
      instance = objects.Instance(name="xen.example.com",
53 55cc0a44 Michael Hanselmann
                                  primary_node="node24828")
54 55cc0a44 Michael Hanselmann
      cons = cls.GetInstanceConsole(instance, {}, {})
55 55cc0a44 Michael Hanselmann
      self.assertTrue(cons.Validate())
56 55cc0a44 Michael Hanselmann
      self.assertEqual(cons.kind, constants.CONS_SSH)
57 55cc0a44 Michael Hanselmann
      self.assertEqual(cons.host, instance.primary_node)
58 55cc0a44 Michael Hanselmann
      self.assertEqual(cons.command[-1], instance.name)
59 55cc0a44 Michael Hanselmann
60 55cc0a44 Michael Hanselmann
61 347fa0f1 Michael Hanselmann
class TestCreateConfigCpus(unittest.TestCase):
62 347fa0f1 Michael Hanselmann
  def testEmpty(self):
63 347fa0f1 Michael Hanselmann
    for cpu_mask in [None, ""]:
64 347fa0f1 Michael Hanselmann
      self.assertEqual(hv_xen._CreateConfigCpus(cpu_mask),
65 347fa0f1 Michael Hanselmann
                       "cpus = [  ]")
66 347fa0f1 Michael Hanselmann
67 347fa0f1 Michael Hanselmann
  def testAll(self):
68 347fa0f1 Michael Hanselmann
    self.assertEqual(hv_xen._CreateConfigCpus(constants.CPU_PINNING_ALL),
69 347fa0f1 Michael Hanselmann
                     None)
70 347fa0f1 Michael Hanselmann
71 347fa0f1 Michael Hanselmann
  def testOne(self):
72 347fa0f1 Michael Hanselmann
    self.assertEqual(hv_xen._CreateConfigCpus("9"), "cpu = \"9\"")
73 347fa0f1 Michael Hanselmann
74 347fa0f1 Michael Hanselmann
  def testMultiple(self):
75 347fa0f1 Michael Hanselmann
    self.assertEqual(hv_xen._CreateConfigCpus("0-2,4,5-5:3:all"),
76 347fa0f1 Michael Hanselmann
                     ("cpus = [ \"0,1,2,4,5\", \"3\", \"%s\" ]" %
77 347fa0f1 Michael Hanselmann
                      constants.CPU_PINNING_ALL_XEN))
78 347fa0f1 Michael Hanselmann
79 347fa0f1 Michael Hanselmann
80 3eb073a6 Helga Velroyen
class TestGetCommand(testutils.GanetiTestCase):
81 3eb073a6 Helga Velroyen
  def testCommandExplicit(self):
82 3eb073a6 Helga Velroyen
    """Test the case when the command is given as class parameter explicitly.
83 3eb073a6 Helga Velroyen

84 3eb073a6 Helga Velroyen
    """
85 3eb073a6 Helga Velroyen
    expected_cmd = "xl"
86 3eb073a6 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cmd=constants.XEN_CMD_XL)
87 398fd4f6 Helga Velroyen
    self.assertEqual(hv._GetCommand(None), expected_cmd)
88 3eb073a6 Helga Velroyen
89 3eb073a6 Helga Velroyen
  def testCommandInvalid(self):
90 3eb073a6 Helga Velroyen
    """Test the case an invalid command is given as class parameter explicitly.
91 3eb073a6 Helga Velroyen

92 3eb073a6 Helga Velroyen
    """
93 3eb073a6 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cmd="invalidcommand")
94 3eb073a6 Helga Velroyen
    self.assertRaises(errors.ProgrammerError, hv._GetCommand, None)
95 3eb073a6 Helga Velroyen
96 51a95d00 Helga Velroyen
  def testCommandHvparams(self):
97 51a95d00 Helga Velroyen
    expected_cmd = "xl"
98 51a95d00 Helga Velroyen
    test_hvparams = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
99 51a95d00 Helga Velroyen
    hv = hv_xen.XenHypervisor()
100 398fd4f6 Helga Velroyen
    self.assertEqual(hv._GetCommand(test_hvparams), expected_cmd)
101 51a95d00 Helga Velroyen
102 51a95d00 Helga Velroyen
  def testCommandHvparamsInvalid(self):
103 51a95d00 Helga Velroyen
    test_hvparams = {}
104 51a95d00 Helga Velroyen
    hv = hv_xen.XenHypervisor()
105 398fd4f6 Helga Velroyen
    self.assertRaises(errors.HypervisorError, hv._GetCommand, test_hvparams)
106 51a95d00 Helga Velroyen
107 51a95d00 Helga Velroyen
  def testCommandHvparamsCmdInvalid(self):
108 51a95d00 Helga Velroyen
    test_hvparams = {constants.HV_XEN_CMD: "invalidcommand"}
109 51a95d00 Helga Velroyen
    hv = hv_xen.XenHypervisor()
110 51a95d00 Helga Velroyen
    self.assertRaises(errors.ProgrammerError, hv._GetCommand, test_hvparams)
111 51a95d00 Helga Velroyen
112 3eb073a6 Helga Velroyen
113 2609da63 Helga Velroyen
class TestParseInstanceList(testutils.GanetiTestCase):
114 b255379d Michael Hanselmann
  def test(self):
115 b255379d Michael Hanselmann
    data = testutils.ReadTestData("xen-xm-list-4.0.1-dom0-only.txt")
116 b255379d Michael Hanselmann
117 b255379d Michael Hanselmann
    # Exclude node
118 2609da63 Helga Velroyen
    self.assertEqual(hv_xen._ParseInstanceList(data.splitlines(), False), [])
119 b255379d Michael Hanselmann
120 b255379d Michael Hanselmann
    # Include node
121 2609da63 Helga Velroyen
    result = hv_xen._ParseInstanceList(data.splitlines(), True)
122 b255379d Michael Hanselmann
    self.assertEqual(len(result), 1)
123 b255379d Michael Hanselmann
    self.assertEqual(len(result[0]), 6)
124 b255379d Michael Hanselmann
125 b255379d Michael Hanselmann
    # Name
126 b255379d Michael Hanselmann
    self.assertEqual(result[0][0], hv_xen._DOM0_NAME)
127 b255379d Michael Hanselmann
128 b255379d Michael Hanselmann
    # ID
129 b255379d Michael Hanselmann
    self.assertEqual(result[0][1], 0)
130 b255379d Michael Hanselmann
131 b255379d Michael Hanselmann
    # Memory
132 b255379d Michael Hanselmann
    self.assertEqual(result[0][2], 1023)
133 b255379d Michael Hanselmann
134 b255379d Michael Hanselmann
    # VCPUs
135 b255379d Michael Hanselmann
    self.assertEqual(result[0][3], 1)
136 b255379d Michael Hanselmann
137 b255379d Michael Hanselmann
    # State
138 b255379d Michael Hanselmann
    self.assertEqual(result[0][4], "r-----")
139 b255379d Michael Hanselmann
140 b255379d Michael Hanselmann
    # Time
141 b255379d Michael Hanselmann
    self.assertAlmostEqual(result[0][5], 121152.6)
142 b255379d Michael Hanselmann
143 b255379d Michael Hanselmann
  def testWrongLineFormat(self):
144 b255379d Michael Hanselmann
    tests = [
145 b255379d Michael Hanselmann
      ["three fields only"],
146 b255379d Michael Hanselmann
      ["name InvalidID 128 1 r----- 12345"],
147 b255379d Michael Hanselmann
      ]
148 b255379d Michael Hanselmann
149 b255379d Michael Hanselmann
    for lines in tests:
150 b255379d Michael Hanselmann
      try:
151 2609da63 Helga Velroyen
        hv_xen._ParseInstanceList(["Header would be here"] + lines, False)
152 b255379d Michael Hanselmann
      except errors.HypervisorError, err:
153 2609da63 Helga Velroyen
        self.assertTrue("Can't parse instance list" in str(err))
154 b255379d Michael Hanselmann
      else:
155 b255379d Michael Hanselmann
        self.fail("Exception was not raised")
156 b255379d Michael Hanselmann
157 b255379d Michael Hanselmann
158 36bebc53 Helga Velroyen
class TestGetInstanceList(testutils.GanetiTestCase):
159 b255379d Michael Hanselmann
  def _Fail(self):
160 b255379d Michael Hanselmann
    return utils.RunResult(constants.EXIT_FAILURE, None,
161 b255379d Michael Hanselmann
                           "stdout", "stderr", None,
162 b255379d Michael Hanselmann
                           NotImplemented, NotImplemented)
163 b255379d Michael Hanselmann
164 b255379d Michael Hanselmann
  def testTimeout(self):
165 b255379d Michael Hanselmann
    fn = testutils.CallCounter(self._Fail)
166 b255379d Michael Hanselmann
    try:
167 36bebc53 Helga Velroyen
      hv_xen._GetInstanceList(fn, False, _timeout=0.1)
168 b255379d Michael Hanselmann
    except errors.HypervisorError, err:
169 b255379d Michael Hanselmann
      self.assertTrue("timeout exceeded" in str(err))
170 b255379d Michael Hanselmann
    else:
171 b255379d Michael Hanselmann
      self.fail("Exception was not raised")
172 b255379d Michael Hanselmann
173 b255379d Michael Hanselmann
    self.assertTrue(fn.Count() < 10,
174 b255379d Michael Hanselmann
                    msg="'xm list' was called too many times")
175 b255379d Michael Hanselmann
176 b255379d Michael Hanselmann
  def _Success(self, stdout):
177 b255379d Michael Hanselmann
    return utils.RunResult(constants.EXIT_SUCCESS, None, stdout, "", None,
178 b255379d Michael Hanselmann
                           NotImplemented, NotImplemented)
179 b255379d Michael Hanselmann
180 b255379d Michael Hanselmann
  def testSuccess(self):
181 b255379d Michael Hanselmann
    data = testutils.ReadTestData("xen-xm-list-4.0.1-four-instances.txt")
182 b255379d Michael Hanselmann
183 b255379d Michael Hanselmann
    fn = testutils.CallCounter(compat.partial(self._Success, data))
184 b255379d Michael Hanselmann
185 36bebc53 Helga Velroyen
    result = hv_xen._GetInstanceList(fn, True, _timeout=0.1)
186 b255379d Michael Hanselmann
187 b255379d Michael Hanselmann
    self.assertEqual(len(result), 4)
188 b255379d Michael Hanselmann
189 b255379d Michael Hanselmann
    self.assertEqual(map(compat.fst, result), [
190 b255379d Michael Hanselmann
      "Domain-0",
191 b255379d Michael Hanselmann
      "server01.example.com",
192 b255379d Michael Hanselmann
      "web3106215069.example.com",
193 b255379d Michael Hanselmann
      "testinstance.example.com",
194 b255379d Michael Hanselmann
      ])
195 b255379d Michael Hanselmann
196 b255379d Michael Hanselmann
    self.assertEqual(fn.Count(), 1)
197 b255379d Michael Hanselmann
198 b255379d Michael Hanselmann
199 06c9a520 Michael Hanselmann
class TestParseNodeInfo(testutils.GanetiTestCase):
200 06c9a520 Michael Hanselmann
  def testEmpty(self):
201 06c9a520 Michael Hanselmann
    self.assertEqual(hv_xen._ParseNodeInfo(""), {})
202 06c9a520 Michael Hanselmann
203 06c9a520 Michael Hanselmann
  def testUnknownInput(self):
204 06c9a520 Michael Hanselmann
    data = "\n".join([
205 06c9a520 Michael Hanselmann
      "foo bar",
206 06c9a520 Michael Hanselmann
      "something else goes",
207 06c9a520 Michael Hanselmann
      "here",
208 06c9a520 Michael Hanselmann
      ])
209 06c9a520 Michael Hanselmann
    self.assertEqual(hv_xen._ParseNodeInfo(data), {})
210 06c9a520 Michael Hanselmann
211 06c9a520 Michael Hanselmann
  def testBasicInfo(self):
212 06c9a520 Michael Hanselmann
    data = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
213 06c9a520 Michael Hanselmann
    result = hv_xen._ParseNodeInfo(data)
214 06c9a520 Michael Hanselmann
    self.assertEqual(result, {
215 06c9a520 Michael Hanselmann
      "cpu_nodes": 1,
216 06c9a520 Michael Hanselmann
      "cpu_sockets": 2,
217 06c9a520 Michael Hanselmann
      "cpu_total": 4,
218 06c9a520 Michael Hanselmann
      "hv_version": (4, 0),
219 06c9a520 Michael Hanselmann
      "memory_free": 8004,
220 06c9a520 Michael Hanselmann
      "memory_total": 16378,
221 06c9a520 Michael Hanselmann
      })
222 06c9a520 Michael Hanselmann
223 06c9a520 Michael Hanselmann
224 06c9a520 Michael Hanselmann
class TestMergeInstanceInfo(testutils.GanetiTestCase):
225 06c9a520 Michael Hanselmann
  def testEmpty(self):
226 fac489a5 Helga Velroyen
    self.assertEqual(hv_xen._MergeInstanceInfo({}, []), {})
227 06c9a520 Michael Hanselmann
228 06c9a520 Michael Hanselmann
  def _FakeXmList(self, include_node):
229 06c9a520 Michael Hanselmann
    return [
230 06c9a520 Michael Hanselmann
      (hv_xen._DOM0_NAME, NotImplemented, 4096, 7, NotImplemented,
231 06c9a520 Michael Hanselmann
       NotImplemented),
232 06c9a520 Michael Hanselmann
      ("inst1.example.com", NotImplemented, 2048, 4, NotImplemented,
233 06c9a520 Michael Hanselmann
       NotImplemented),
234 06c9a520 Michael Hanselmann
      ]
235 06c9a520 Michael Hanselmann
236 06c9a520 Michael Hanselmann
  def testMissingNodeInfo(self):
237 fac489a5 Helga Velroyen
    instance_list = self._FakeXmList(True)
238 fac489a5 Helga Velroyen
    result = hv_xen._MergeInstanceInfo({}, instance_list)
239 06c9a520 Michael Hanselmann
    self.assertEqual(result, {
240 06c9a520 Michael Hanselmann
      "memory_dom0": 4096,
241 06c9a520 Michael Hanselmann
      "dom0_cpus": 7,
242 06c9a520 Michael Hanselmann
      })
243 06c9a520 Michael Hanselmann
244 06c9a520 Michael Hanselmann
  def testWithNodeInfo(self):
245 06c9a520 Michael Hanselmann
    info = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
246 fac489a5 Helga Velroyen
    instance_list = self._FakeXmList(True)
247 fac489a5 Helga Velroyen
    result = hv_xen._GetNodeInfo(info, instance_list)
248 06c9a520 Michael Hanselmann
    self.assertEqual(result, {
249 06c9a520 Michael Hanselmann
      "cpu_nodes": 1,
250 06c9a520 Michael Hanselmann
      "cpu_sockets": 2,
251 06c9a520 Michael Hanselmann
      "cpu_total": 4,
252 06c9a520 Michael Hanselmann
      "dom0_cpus": 7,
253 06c9a520 Michael Hanselmann
      "hv_version": (4, 0),
254 06c9a520 Michael Hanselmann
      "memory_dom0": 4096,
255 06c9a520 Michael Hanselmann
      "memory_free": 8004,
256 06c9a520 Michael Hanselmann
      "memory_hv": 2230,
257 06c9a520 Michael Hanselmann
      "memory_total": 16378,
258 06c9a520 Michael Hanselmann
      })
259 06c9a520 Michael Hanselmann
260 06c9a520 Michael Hanselmann
261 d0bb3f24 Michael Hanselmann
class TestGetConfigFileDiskData(unittest.TestCase):
262 d0bb3f24 Michael Hanselmann
  def testLetterCount(self):
263 d0bb3f24 Michael Hanselmann
    self.assertEqual(len(hv_xen._DISK_LETTERS), 26)
264 d0bb3f24 Michael Hanselmann
265 d0bb3f24 Michael Hanselmann
  def testNoDisks(self):
266 d0bb3f24 Michael Hanselmann
    self.assertEqual(hv_xen._GetConfigFileDiskData([], "hd"), [])
267 d0bb3f24 Michael Hanselmann
268 d0bb3f24 Michael Hanselmann
  def testManyDisks(self):
269 d0bb3f24 Michael Hanselmann
    for offset in [0, 1, 10]:
270 d0bb3f24 Michael Hanselmann
      disks = [(objects.Disk(dev_type=constants.LD_LV), "/tmp/disk/%s" % idx)
271 d0bb3f24 Michael Hanselmann
               for idx in range(len(hv_xen._DISK_LETTERS) + offset)]
272 d0bb3f24 Michael Hanselmann
273 d0bb3f24 Michael Hanselmann
      if offset == 0:
274 d0bb3f24 Michael Hanselmann
        result = hv_xen._GetConfigFileDiskData(disks, "hd")
275 d0bb3f24 Michael Hanselmann
        self.assertEqual(result, [
276 d0bb3f24 Michael Hanselmann
          "'phy:/tmp/disk/%s,hd%s,r'" % (idx, string.ascii_lowercase[idx])
277 d0bb3f24 Michael Hanselmann
          for idx in range(len(hv_xen._DISK_LETTERS) + offset)
278 d0bb3f24 Michael Hanselmann
          ])
279 d0bb3f24 Michael Hanselmann
      else:
280 d0bb3f24 Michael Hanselmann
        try:
281 d0bb3f24 Michael Hanselmann
          hv_xen._GetConfigFileDiskData(disks, "hd")
282 d0bb3f24 Michael Hanselmann
        except errors.HypervisorError, err:
283 d0bb3f24 Michael Hanselmann
          self.assertEqual(str(err), "Too many disks")
284 d0bb3f24 Michael Hanselmann
        else:
285 d0bb3f24 Michael Hanselmann
          self.fail("Exception was not raised")
286 d0bb3f24 Michael Hanselmann
287 d0bb3f24 Michael Hanselmann
  def testTwoLvDisksWithMode(self):
288 d0bb3f24 Michael Hanselmann
    disks = [
289 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_LV, mode=constants.DISK_RDWR),
290 d0bb3f24 Michael Hanselmann
       "/tmp/diskFirst"),
291 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_LV, mode=constants.DISK_RDONLY),
292 d0bb3f24 Michael Hanselmann
       "/tmp/diskLast"),
293 d0bb3f24 Michael Hanselmann
      ]
294 d0bb3f24 Michael Hanselmann
295 d0bb3f24 Michael Hanselmann
    result = hv_xen._GetConfigFileDiskData(disks, "hd")
296 d0bb3f24 Michael Hanselmann
    self.assertEqual(result, [
297 d0bb3f24 Michael Hanselmann
      "'phy:/tmp/diskFirst,hda,w'",
298 d0bb3f24 Michael Hanselmann
      "'phy:/tmp/diskLast,hdb,r'",
299 d0bb3f24 Michael Hanselmann
      ])
300 d0bb3f24 Michael Hanselmann
301 d0bb3f24 Michael Hanselmann
  def testFileDisks(self):
302 d0bb3f24 Michael Hanselmann
    disks = [
303 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_FILE, mode=constants.DISK_RDWR,
304 d0bb3f24 Michael Hanselmann
                    physical_id=[constants.FD_LOOP]),
305 d0bb3f24 Michael Hanselmann
       "/tmp/diskFirst"),
306 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_FILE, mode=constants.DISK_RDONLY,
307 d0bb3f24 Michael Hanselmann
                    physical_id=[constants.FD_BLKTAP]),
308 d0bb3f24 Michael Hanselmann
       "/tmp/diskTwo"),
309 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_FILE, mode=constants.DISK_RDWR,
310 d0bb3f24 Michael Hanselmann
                    physical_id=[constants.FD_LOOP]),
311 d0bb3f24 Michael Hanselmann
       "/tmp/diskThree"),
312 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_FILE, mode=constants.DISK_RDWR,
313 d0bb3f24 Michael Hanselmann
                    physical_id=[constants.FD_BLKTAP]),
314 d0bb3f24 Michael Hanselmann
       "/tmp/diskLast"),
315 d0bb3f24 Michael Hanselmann
      ]
316 d0bb3f24 Michael Hanselmann
317 d0bb3f24 Michael Hanselmann
    result = hv_xen._GetConfigFileDiskData(disks, "sd")
318 d0bb3f24 Michael Hanselmann
    self.assertEqual(result, [
319 d0bb3f24 Michael Hanselmann
      "'file:/tmp/diskFirst,sda,w'",
320 d0bb3f24 Michael Hanselmann
      "'tap:aio:/tmp/diskTwo,sdb,r'",
321 d0bb3f24 Michael Hanselmann
      "'file:/tmp/diskThree,sdc,w'",
322 d0bb3f24 Michael Hanselmann
      "'tap:aio:/tmp/diskLast,sdd,w'",
323 d0bb3f24 Michael Hanselmann
      ])
324 d0bb3f24 Michael Hanselmann
325 d0bb3f24 Michael Hanselmann
  def testInvalidFileDisk(self):
326 d0bb3f24 Michael Hanselmann
    disks = [
327 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_FILE, mode=constants.DISK_RDWR,
328 d0bb3f24 Michael Hanselmann
                    physical_id=["#unknown#"]),
329 d0bb3f24 Michael Hanselmann
       "/tmp/diskinvalid"),
330 d0bb3f24 Michael Hanselmann
      ]
331 d0bb3f24 Michael Hanselmann
332 d0bb3f24 Michael Hanselmann
    self.assertRaises(KeyError, hv_xen._GetConfigFileDiskData, disks, "sd")
333 d0bb3f24 Michael Hanselmann
334 d0bb3f24 Michael Hanselmann
335 58e356a9 Helga Velroyen
class TestXenHypervisorRunXen(unittest.TestCase):
336 58e356a9 Helga Velroyen
337 58e356a9 Helga Velroyen
  XEN_SUB_CMD = "help"
338 58e356a9 Helga Velroyen
339 58e356a9 Helga Velroyen
  def testCommandUnknown(self):
340 1dee2041 Michael Hanselmann
    cmd = "#unknown command#"
341 1dee2041 Michael Hanselmann
    self.assertFalse(cmd in constants.KNOWN_XEN_COMMANDS)
342 1dee2041 Michael Hanselmann
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
343 1dee2041 Michael Hanselmann
                              _run_cmd_fn=NotImplemented,
344 1dee2041 Michael Hanselmann
                              _cmd=cmd)
345 398fd4f6 Helga Velroyen
    self.assertRaises(errors.ProgrammerError, hv._RunXen, [], None)
346 1dee2041 Michael Hanselmann
347 398fd4f6 Helga Velroyen
  def testCommandNoHvparams(self):
348 58e356a9 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
349 398fd4f6 Helga Velroyen
                              _run_cmd_fn=NotImplemented)
350 398fd4f6 Helga Velroyen
    hvparams = None
351 398fd4f6 Helga Velroyen
    self.assertRaises(errors.HypervisorError, hv._RunXen, [self.XEN_SUB_CMD],
352 398fd4f6 Helga Velroyen
                      hvparams)
353 58e356a9 Helga Velroyen
354 58e356a9 Helga Velroyen
  def testCommandFromHvparams(self):
355 58e356a9 Helga Velroyen
    expected_xen_cmd = "xl"
356 58e356a9 Helga Velroyen
    hvparams = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
357 58e356a9 Helga Velroyen
    mock_run_cmd = mock.Mock()
358 58e356a9 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
359 58e356a9 Helga Velroyen
                              _run_cmd_fn=mock_run_cmd)
360 58e356a9 Helga Velroyen
    hv._RunXen([self.XEN_SUB_CMD], hvparams=hvparams)
361 58e356a9 Helga Velroyen
    mock_run_cmd.assert_called_with([expected_xen_cmd, self.XEN_SUB_CMD])
362 58e356a9 Helga Velroyen
363 58e356a9 Helga Velroyen
364 58e356a9 Helga Velroyen
class TestXenHypervisorGetInstanceList(unittest.TestCase):
365 58e356a9 Helga Velroyen
366 58e356a9 Helga Velroyen
  RESULT_OK = utils.RunResult(0, None, "", "", "", None, None)
367 58e356a9 Helga Velroyen
  XEN_LIST = "list"
368 58e356a9 Helga Velroyen
369 398fd4f6 Helga Velroyen
  def testNoHvparams(self):
370 58e356a9 Helga Velroyen
    expected_xen_cmd = "xm"
371 58e356a9 Helga Velroyen
    mock_run_cmd = mock.Mock( return_value=self.RESULT_OK )
372 58e356a9 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
373 58e356a9 Helga Velroyen
                              _run_cmd_fn=mock_run_cmd)
374 398fd4f6 Helga Velroyen
    self.assertRaises(errors.HypervisorError, hv._GetInstanceList, True, None)
375 58e356a9 Helga Velroyen
376 58e356a9 Helga Velroyen
  def testFromHvparams(self):
377 58e356a9 Helga Velroyen
    expected_xen_cmd = "xl"
378 58e356a9 Helga Velroyen
    hvparams = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
379 58e356a9 Helga Velroyen
    mock_run_cmd = mock.Mock( return_value=self.RESULT_OK )
380 58e356a9 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
381 58e356a9 Helga Velroyen
                              _run_cmd_fn=mock_run_cmd)
382 398fd4f6 Helga Velroyen
    hv._GetInstanceList(True, hvparams)
383 58e356a9 Helga Velroyen
    mock_run_cmd.assert_called_with([expected_xen_cmd, self.XEN_LIST])
384 58e356a9 Helga Velroyen
385 58e356a9 Helga Velroyen
386 58e356a9 Helga Velroyen
class TestXenHypervisorListInstances(unittest.TestCase):
387 58e356a9 Helga Velroyen
388 58e356a9 Helga Velroyen
  RESULT_OK = utils.RunResult(0, None, "", "", "", None, None)
389 58e356a9 Helga Velroyen
  XEN_LIST = "list"
390 58e356a9 Helga Velroyen
391 398fd4f6 Helga Velroyen
  def testNoHvparams(self):
392 58e356a9 Helga Velroyen
    expected_xen_cmd = "xm"
393 58e356a9 Helga Velroyen
    mock_run_cmd = mock.Mock( return_value=self.RESULT_OK )
394 58e356a9 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
395 58e356a9 Helga Velroyen
                              _run_cmd_fn=mock_run_cmd)
396 398fd4f6 Helga Velroyen
    self.assertRaises(errors.HypervisorError, hv.ListInstances)
397 58e356a9 Helga Velroyen
398 58e356a9 Helga Velroyen
  def testHvparamsXl(self):
399 58e356a9 Helga Velroyen
    expected_xen_cmd = "xl"
400 58e356a9 Helga Velroyen
    hvparams = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
401 58e356a9 Helga Velroyen
    mock_run_cmd = mock.Mock( return_value=self.RESULT_OK )
402 58e356a9 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
403 58e356a9 Helga Velroyen
                              _run_cmd_fn=mock_run_cmd)
404 58e356a9 Helga Velroyen
    hv.ListInstances(hvparams=hvparams)
405 58e356a9 Helga Velroyen
    mock_run_cmd.assert_called_with([expected_xen_cmd, self.XEN_LIST])
406 58e356a9 Helga Velroyen
407 1dee2041 Michael Hanselmann
408 75bf3149 Helga Velroyen
class TestXenHypervisorCheckToolstack(unittest.TestCase):
409 75bf3149 Helga Velroyen
410 75bf3149 Helga Velroyen
  def setUp(self):
411 75bf3149 Helga Velroyen
    self.tmpdir = tempfile.mkdtemp()
412 75bf3149 Helga Velroyen
    self.cfg_name = "xen_config"
413 75bf3149 Helga Velroyen
    self.cfg_path = utils.PathJoin(self.tmpdir, self.cfg_name)
414 75bf3149 Helga Velroyen
    self.hv = hv_xen.XenHypervisor()
415 75bf3149 Helga Velroyen
416 75bf3149 Helga Velroyen
  def tearDown(self):
417 75bf3149 Helga Velroyen
    shutil.rmtree(self.tmpdir)
418 75bf3149 Helga Velroyen
419 75bf3149 Helga Velroyen
  def testBinaryNotFound(self):
420 75bf3149 Helga Velroyen
    RESULT_FAILED = utils.RunResult(1, None, "", "", "", None, None)
421 75bf3149 Helga Velroyen
    mock_run_cmd = mock.Mock(return_value=RESULT_FAILED)
422 75bf3149 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
423 75bf3149 Helga Velroyen
                              _run_cmd_fn=mock_run_cmd)
424 75bf3149 Helga Velroyen
    result = hv._CheckToolstackBinary("xl")
425 75bf3149 Helga Velroyen
    self.assertFalse(result)
426 75bf3149 Helga Velroyen
427 75bf3149 Helga Velroyen
  def testCheckToolstackXlConfigured(self):
428 75bf3149 Helga Velroyen
    RESULT_OK = utils.RunResult(0, None, "", "", "", None, None)
429 75bf3149 Helga Velroyen
    mock_run_cmd = mock.Mock(return_value=RESULT_OK)
430 75bf3149 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
431 75bf3149 Helga Velroyen
                              _run_cmd_fn=mock_run_cmd)
432 75bf3149 Helga Velroyen
    result = hv._CheckToolstackXlConfigured()
433 75bf3149 Helga Velroyen
    self.assertTrue(result)
434 75bf3149 Helga Velroyen
435 75bf3149 Helga Velroyen
  def testCheckToolstackXlNotConfigured(self):
436 75bf3149 Helga Velroyen
    RESULT_FAILED = utils.RunResult(
437 75bf3149 Helga Velroyen
        1, None, "",
438 75bf3149 Helga Velroyen
        "ERROR:  A different toolstack (xm) have been selected!",
439 75bf3149 Helga Velroyen
        "", None, None)
440 75bf3149 Helga Velroyen
    mock_run_cmd = mock.Mock(return_value=RESULT_FAILED)
441 75bf3149 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
442 75bf3149 Helga Velroyen
                              _run_cmd_fn=mock_run_cmd)
443 75bf3149 Helga Velroyen
    result = hv._CheckToolstackXlConfigured()
444 75bf3149 Helga Velroyen
    self.assertFalse(result)
445 75bf3149 Helga Velroyen
446 75bf3149 Helga Velroyen
  def testCheckToolstackXlFails(self):
447 75bf3149 Helga Velroyen
    RESULT_FAILED = utils.RunResult(
448 75bf3149 Helga Velroyen
        1, None, "",
449 75bf3149 Helga Velroyen
        "ERROR: The pink bunny hid the binary.",
450 75bf3149 Helga Velroyen
        "", None, None)
451 75bf3149 Helga Velroyen
    mock_run_cmd = mock.Mock(return_value=RESULT_FAILED)
452 75bf3149 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
453 75bf3149 Helga Velroyen
                              _run_cmd_fn=mock_run_cmd)
454 75bf3149 Helga Velroyen
    self.assertRaises(errors.HypervisorError, hv._CheckToolstackXlConfigured)
455 75bf3149 Helga Velroyen
456 75bf3149 Helga Velroyen
457 64a66bd2 Michael Hanselmann
class TestXenHypervisorWriteConfigFile(unittest.TestCase):
458 64a66bd2 Michael Hanselmann
  def setUp(self):
459 64a66bd2 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
460 64a66bd2 Michael Hanselmann
461 64a66bd2 Michael Hanselmann
  def tearDown(self):
462 64a66bd2 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
463 64a66bd2 Michael Hanselmann
464 64a66bd2 Michael Hanselmann
  def testWriteError(self):
465 64a66bd2 Michael Hanselmann
    cfgdir = utils.PathJoin(self.tmpdir, "foobar")
466 64a66bd2 Michael Hanselmann
467 64a66bd2 Michael Hanselmann
    hv = hv_xen.XenHypervisor(_cfgdir=cfgdir,
468 64a66bd2 Michael Hanselmann
                              _run_cmd_fn=NotImplemented,
469 64a66bd2 Michael Hanselmann
                              _cmd=NotImplemented)
470 64a66bd2 Michael Hanselmann
471 64a66bd2 Michael Hanselmann
    self.assertFalse(os.path.exists(cfgdir))
472 64a66bd2 Michael Hanselmann
473 64a66bd2 Michael Hanselmann
    try:
474 64a66bd2 Michael Hanselmann
      hv._WriteConfigFile("name", "data")
475 64a66bd2 Michael Hanselmann
    except errors.HypervisorError, err:
476 64a66bd2 Michael Hanselmann
      self.assertTrue(str(err).startswith("Cannot write Xen instance"))
477 64a66bd2 Michael Hanselmann
    else:
478 64a66bd2 Michael Hanselmann
      self.fail("Exception was not raised")
479 64a66bd2 Michael Hanselmann
480 64a66bd2 Michael Hanselmann
481 75bf3149 Helga Velroyen
class TestXenHypervisorVerify(unittest.TestCase):
482 75bf3149 Helga Velroyen
483 75bf3149 Helga Velroyen
  def setUp(self):
484 75bf3149 Helga Velroyen
    output = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
485 75bf3149 Helga Velroyen
    self._result_ok = utils.RunResult(0, None, output, "", "", None, None)
486 75bf3149 Helga Velroyen
487 75bf3149 Helga Velroyen
  def testVerify(self):
488 75bf3149 Helga Velroyen
    hvparams = {constants.HV_XEN_CMD : constants.XEN_CMD_XL}
489 75bf3149 Helga Velroyen
    mock_run_cmd = mock.Mock(return_value=self._result_ok)
490 75bf3149 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
491 75bf3149 Helga Velroyen
                              _run_cmd_fn=mock_run_cmd)
492 75bf3149 Helga Velroyen
    hv._CheckToolstack = mock.Mock(return_value=True)
493 75bf3149 Helga Velroyen
    result = hv.Verify(hvparams)
494 75bf3149 Helga Velroyen
    self.assertTrue(result is None)
495 75bf3149 Helga Velroyen
496 75bf3149 Helga Velroyen
  def testVerifyToolstackNotOk(self):
497 75bf3149 Helga Velroyen
    hvparams = {constants.HV_XEN_CMD : constants.XEN_CMD_XL}
498 75bf3149 Helga Velroyen
    mock_run_cmd = mock.Mock(return_value=self._result_ok)
499 75bf3149 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
500 75bf3149 Helga Velroyen
                              _run_cmd_fn=mock_run_cmd)
501 75bf3149 Helga Velroyen
    hv._CheckToolstack = mock.Mock()
502 75bf3149 Helga Velroyen
    hv._CheckToolstack.side_effect = errors.HypervisorError("foo")
503 75bf3149 Helga Velroyen
    result = hv.Verify(hvparams)
504 75bf3149 Helga Velroyen
    self.assertTrue(result is not None)
505 75bf3149 Helga Velroyen
506 75bf3149 Helga Velroyen
  def testVerifyFailing(self):
507 75bf3149 Helga Velroyen
    result_failed = utils.RunResult(1, None, "", "", "", None, None)
508 75bf3149 Helga Velroyen
    mock_run_cmd = mock.Mock(return_value=result_failed)
509 75bf3149 Helga Velroyen
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
510 75bf3149 Helga Velroyen
                              _run_cmd_fn=mock_run_cmd)
511 75bf3149 Helga Velroyen
    hv._CheckToolstack = mock.Mock(return_value=True)
512 75bf3149 Helga Velroyen
    result = hv.Verify()
513 75bf3149 Helga Velroyen
    self.assertTrue(result is not None)
514 75bf3149 Helga Velroyen
515 75bf3149 Helga Velroyen
516 74a50c46 Michael Hanselmann
class _TestXenHypervisor(object):
517 74a50c46 Michael Hanselmann
  TARGET = NotImplemented
518 74a50c46 Michael Hanselmann
  CMD = NotImplemented
519 74a50c46 Michael Hanselmann
  HVNAME = NotImplemented
520 8351df2f Helga Velroyen
  VALID_HVPARAMS = {constants.HV_XEN_CMD: constants.XEN_CMD_XL}
521 74a50c46 Michael Hanselmann
522 74a50c46 Michael Hanselmann
  def setUp(self):
523 74a50c46 Michael Hanselmann
    super(_TestXenHypervisor, self).setUp()
524 74a50c46 Michael Hanselmann
525 74a50c46 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
526 74a50c46 Michael Hanselmann
527 74a50c46 Michael Hanselmann
    self.vncpw = "".join(random.sample(string.ascii_letters, 10))
528 74a50c46 Michael Hanselmann
529 74a50c46 Michael Hanselmann
    self.vncpw_path = utils.PathJoin(self.tmpdir, "vncpw")
530 74a50c46 Michael Hanselmann
    utils.WriteFile(self.vncpw_path, data=self.vncpw)
531 74a50c46 Michael Hanselmann
532 74a50c46 Michael Hanselmann
  def tearDown(self):
533 74a50c46 Michael Hanselmann
    super(_TestXenHypervisor, self).tearDown()
534 74a50c46 Michael Hanselmann
535 74a50c46 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
536 74a50c46 Michael Hanselmann
537 74a50c46 Michael Hanselmann
  def _GetHv(self, run_cmd=NotImplemented):
538 74a50c46 Michael Hanselmann
    return self.TARGET(_cfgdir=self.tmpdir, _run_cmd_fn=run_cmd, _cmd=self.CMD)
539 74a50c46 Michael Hanselmann
540 74a50c46 Michael Hanselmann
  def _SuccessCommand(self, stdout, cmd):
541 74a50c46 Michael Hanselmann
    self.assertEqual(cmd[0], self.CMD)
542 74a50c46 Michael Hanselmann
543 74a50c46 Michael Hanselmann
    return utils.RunResult(constants.EXIT_SUCCESS, None, stdout, "", None,
544 74a50c46 Michael Hanselmann
                           NotImplemented, NotImplemented)
545 74a50c46 Michael Hanselmann
546 74a50c46 Michael Hanselmann
  def _FailingCommand(self, cmd):
547 74a50c46 Michael Hanselmann
    self.assertEqual(cmd[0], self.CMD)
548 74a50c46 Michael Hanselmann
549 74a50c46 Michael Hanselmann
    return utils.RunResult(constants.EXIT_FAILURE, None,
550 74a50c46 Michael Hanselmann
                           "", "This command failed", None,
551 74a50c46 Michael Hanselmann
                           NotImplemented, NotImplemented)
552 74a50c46 Michael Hanselmann
553 d8784f7d Michael Hanselmann
  def _FakeTcpPing(self, expected, result, target, port, **kwargs):
554 d8784f7d Michael Hanselmann
    self.assertEqual((target, port), expected)
555 d8784f7d Michael Hanselmann
    return result
556 d8784f7d Michael Hanselmann
557 57270b2d Michael Hanselmann
  def testReadingNonExistentConfigFile(self):
558 57270b2d Michael Hanselmann
    hv = self._GetHv()
559 57270b2d Michael Hanselmann
560 57270b2d Michael Hanselmann
    try:
561 57270b2d Michael Hanselmann
      hv._ReadConfigFile("inst15780.example.com")
562 57270b2d Michael Hanselmann
    except errors.HypervisorError, err:
563 57270b2d Michael Hanselmann
      self.assertTrue(str(err).startswith("Failed to load Xen config file:"))
564 57270b2d Michael Hanselmann
    else:
565 57270b2d Michael Hanselmann
      self.fail("Exception was not raised")
566 57270b2d Michael Hanselmann
567 7610d884 Michael Hanselmann
  def testRemovingAutoConfigFile(self):
568 7610d884 Michael Hanselmann
    name = "inst8206.example.com"
569 7610d884 Michael Hanselmann
    cfgfile = utils.PathJoin(self.tmpdir, name)
570 7610d884 Michael Hanselmann
    autodir = utils.PathJoin(self.tmpdir, "auto")
571 7610d884 Michael Hanselmann
    autocfgfile = utils.PathJoin(autodir, name)
572 7610d884 Michael Hanselmann
573 7610d884 Michael Hanselmann
    os.mkdir(autodir)
574 7610d884 Michael Hanselmann
575 7610d884 Michael Hanselmann
    utils.WriteFile(autocfgfile, data="")
576 7610d884 Michael Hanselmann
577 7610d884 Michael Hanselmann
    hv = self._GetHv()
578 7610d884 Michael Hanselmann
579 7610d884 Michael Hanselmann
    self.assertTrue(os.path.isfile(autocfgfile))
580 7610d884 Michael Hanselmann
    hv._WriteConfigFile(name, "content")
581 7610d884 Michael Hanselmann
    self.assertFalse(os.path.exists(autocfgfile))
582 7610d884 Michael Hanselmann
    self.assertEqual(utils.ReadFile(cfgfile), "content")
583 7610d884 Michael Hanselmann
584 2edc1c79 Michael Hanselmann
  def _XenList(self, cmd):
585 2edc1c79 Michael Hanselmann
    self.assertEqual(cmd, [self.CMD, "list"])
586 2edc1c79 Michael Hanselmann
587 2edc1c79 Michael Hanselmann
    # TODO: Use actual data from "xl" command
588 2edc1c79 Michael Hanselmann
    output = testutils.ReadTestData("xen-xm-list-4.0.1-four-instances.txt")
589 2edc1c79 Michael Hanselmann
590 2edc1c79 Michael Hanselmann
    return self._SuccessCommand(output, cmd)
591 2edc1c79 Michael Hanselmann
592 2edc1c79 Michael Hanselmann
  def testGetInstanceInfo(self):
593 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
594 2edc1c79 Michael Hanselmann
595 2edc1c79 Michael Hanselmann
    (name, instid, memory, vcpus, state, runtime) = \
596 2edc1c79 Michael Hanselmann
      hv.GetInstanceInfo("server01.example.com")
597 2edc1c79 Michael Hanselmann
598 2edc1c79 Michael Hanselmann
    self.assertEqual(name, "server01.example.com")
599 2edc1c79 Michael Hanselmann
    self.assertEqual(instid, 1)
600 2edc1c79 Michael Hanselmann
    self.assertEqual(memory, 1024)
601 2edc1c79 Michael Hanselmann
    self.assertEqual(vcpus, 1)
602 2edc1c79 Michael Hanselmann
    self.assertEqual(state, "-b----")
603 2edc1c79 Michael Hanselmann
    self.assertAlmostEqual(runtime, 167643.2)
604 2edc1c79 Michael Hanselmann
605 2edc1c79 Michael Hanselmann
  def testGetInstanceInfoDom0(self):
606 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
607 2edc1c79 Michael Hanselmann
608 2edc1c79 Michael Hanselmann
    # TODO: Not sure if this is actually used anywhere (can't find it), but the
609 2edc1c79 Michael Hanselmann
    # code supports querying for Dom0
610 2edc1c79 Michael Hanselmann
    (name, instid, memory, vcpus, state, runtime) = \
611 2edc1c79 Michael Hanselmann
      hv.GetInstanceInfo(hv_xen._DOM0_NAME)
612 2edc1c79 Michael Hanselmann
613 2edc1c79 Michael Hanselmann
    self.assertEqual(name, "Domain-0")
614 2edc1c79 Michael Hanselmann
    self.assertEqual(instid, 0)
615 2edc1c79 Michael Hanselmann
    self.assertEqual(memory, 1023)
616 2edc1c79 Michael Hanselmann
    self.assertEqual(vcpus, 1)
617 2edc1c79 Michael Hanselmann
    self.assertEqual(state, "r-----")
618 2edc1c79 Michael Hanselmann
    self.assertAlmostEqual(runtime, 154706.1)
619 2edc1c79 Michael Hanselmann
620 2edc1c79 Michael Hanselmann
  def testGetInstanceInfoUnknown(self):
621 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
622 2edc1c79 Michael Hanselmann
623 2edc1c79 Michael Hanselmann
    result = hv.GetInstanceInfo("unknown.example.com")
624 2edc1c79 Michael Hanselmann
    self.assertTrue(result is None)
625 2edc1c79 Michael Hanselmann
626 2edc1c79 Michael Hanselmann
  def testGetAllInstancesInfo(self):
627 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
628 2edc1c79 Michael Hanselmann
629 2edc1c79 Michael Hanselmann
    result = hv.GetAllInstancesInfo()
630 2edc1c79 Michael Hanselmann
631 2edc1c79 Michael Hanselmann
    self.assertEqual(map(compat.fst, result), [
632 2edc1c79 Michael Hanselmann
      "server01.example.com",
633 2edc1c79 Michael Hanselmann
      "web3106215069.example.com",
634 2edc1c79 Michael Hanselmann
      "testinstance.example.com",
635 2edc1c79 Michael Hanselmann
      ])
636 2edc1c79 Michael Hanselmann
637 2edc1c79 Michael Hanselmann
  def testListInstances(self):
638 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
639 2edc1c79 Michael Hanselmann
640 2edc1c79 Michael Hanselmann
    self.assertEqual(hv.ListInstances(), [
641 2edc1c79 Michael Hanselmann
      "server01.example.com",
642 2edc1c79 Michael Hanselmann
      "web3106215069.example.com",
643 2edc1c79 Michael Hanselmann
      "testinstance.example.com",
644 2edc1c79 Michael Hanselmann
      ])
645 2edc1c79 Michael Hanselmann
646 396672cd Michael Hanselmann
  def _StartInstanceCommand(self, inst, paused, failcreate, cmd):
647 396672cd Michael Hanselmann
    if cmd == [self.CMD, "info"]:
648 396672cd Michael Hanselmann
      output = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
649 396672cd Michael Hanselmann
    elif cmd == [self.CMD, "list"]:
650 396672cd Michael Hanselmann
      output = testutils.ReadTestData("xen-xm-list-4.0.1-dom0-only.txt")
651 396672cd Michael Hanselmann
    elif cmd[:2] == [self.CMD, "create"]:
652 396672cd Michael Hanselmann
      args = cmd[2:]
653 396672cd Michael Hanselmann
      cfgfile = utils.PathJoin(self.tmpdir, inst.name)
654 396672cd Michael Hanselmann
655 396672cd Michael Hanselmann
      if paused:
656 396672cd Michael Hanselmann
        self.assertEqual(args, ["-p", cfgfile])
657 396672cd Michael Hanselmann
      else:
658 396672cd Michael Hanselmann
        self.assertEqual(args, [cfgfile])
659 396672cd Michael Hanselmann
660 396672cd Michael Hanselmann
      if failcreate:
661 396672cd Michael Hanselmann
        return self._FailingCommand(cmd)
662 396672cd Michael Hanselmann
663 396672cd Michael Hanselmann
      output = ""
664 396672cd Michael Hanselmann
    else:
665 396672cd Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
666 396672cd Michael Hanselmann
667 396672cd Michael Hanselmann
    return self._SuccessCommand(output, cmd)
668 396672cd Michael Hanselmann
669 396672cd Michael Hanselmann
  def _MakeInstance(self):
670 396672cd Michael Hanselmann
    # Copy default parameters
671 396672cd Michael Hanselmann
    bep = objects.FillDict(constants.BEC_DEFAULTS, {})
672 396672cd Michael Hanselmann
    hvp = objects.FillDict(constants.HVC_DEFAULTS[self.HVNAME], {})
673 396672cd Michael Hanselmann
674 396672cd Michael Hanselmann
    # Override default VNC password file path
675 396672cd Michael Hanselmann
    if constants.HV_VNC_PASSWORD_FILE in hvp:
676 396672cd Michael Hanselmann
      hvp[constants.HV_VNC_PASSWORD_FILE] = self.vncpw_path
677 396672cd Michael Hanselmann
678 396672cd Michael Hanselmann
    disks = [
679 396672cd Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_LV, mode=constants.DISK_RDWR),
680 396672cd Michael Hanselmann
       utils.PathJoin(self.tmpdir, "disk0")),
681 396672cd Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_LV, mode=constants.DISK_RDONLY),
682 396672cd Michael Hanselmann
       utils.PathJoin(self.tmpdir, "disk1")),
683 396672cd Michael Hanselmann
      ]
684 396672cd Michael Hanselmann
685 396672cd Michael Hanselmann
    inst = objects.Instance(name="server01.example.com",
686 396672cd Michael Hanselmann
                            hvparams=hvp, beparams=bep,
687 396672cd Michael Hanselmann
                            osparams={}, nics=[], os="deb1",
688 396672cd Michael Hanselmann
                            disks=map(compat.fst, disks))
689 396672cd Michael Hanselmann
    inst.UpgradeConfig()
690 396672cd Michael Hanselmann
691 396672cd Michael Hanselmann
    return (inst, disks)
692 396672cd Michael Hanselmann
693 396672cd Michael Hanselmann
  def testStartInstance(self):
694 396672cd Michael Hanselmann
    (inst, disks) = self._MakeInstance()
695 48bba9de Balazs Lecz
    pathutils.LOG_XEN_DIR = self.tmpdir
696 396672cd Michael Hanselmann
697 396672cd Michael Hanselmann
    for failcreate in [False, True]:
698 396672cd Michael Hanselmann
      for paused in [False, True]:
699 396672cd Michael Hanselmann
        run_cmd = compat.partial(self._StartInstanceCommand,
700 396672cd Michael Hanselmann
                                 inst, paused, failcreate)
701 396672cd Michael Hanselmann
702 396672cd Michael Hanselmann
        hv = self._GetHv(run_cmd=run_cmd)
703 396672cd Michael Hanselmann
704 396672cd Michael Hanselmann
        # Ensure instance is not listed
705 396672cd Michael Hanselmann
        self.assertTrue(inst.name not in hv.ListInstances())
706 396672cd Michael Hanselmann
707 396672cd Michael Hanselmann
        # Remove configuration
708 396672cd Michael Hanselmann
        cfgfile = utils.PathJoin(self.tmpdir, inst.name)
709 396672cd Michael Hanselmann
        utils.RemoveFile(cfgfile)
710 396672cd Michael Hanselmann
711 396672cd Michael Hanselmann
        if failcreate:
712 396672cd Michael Hanselmann
          self.assertRaises(errors.HypervisorError, hv.StartInstance,
713 396672cd Michael Hanselmann
                            inst, disks, paused)
714 48bba9de Balazs Lecz
          # Check whether a stale config file is left behind
715 48bba9de Balazs Lecz
          self.assertFalse(os.path.exists(cfgfile))
716 396672cd Michael Hanselmann
        else:
717 396672cd Michael Hanselmann
          hv.StartInstance(inst, disks, paused)
718 48bba9de Balazs Lecz
          # Check if configuration was updated
719 48bba9de Balazs Lecz
          lines = utils.ReadFile(cfgfile).splitlines()
720 396672cd Michael Hanselmann
721 396672cd Michael Hanselmann
        if constants.HV_VNC_PASSWORD_FILE in inst.hvparams:
722 396672cd Michael Hanselmann
          self.assertTrue(("vncpasswd = '%s'" % self.vncpw) in lines)
723 396672cd Michael Hanselmann
        else:
724 396672cd Michael Hanselmann
          extra = inst.hvparams[constants.HV_KERNEL_ARGS]
725 396672cd Michael Hanselmann
          self.assertTrue(("extra = '%s'" % extra) in lines)
726 396672cd Michael Hanselmann
727 664b392d Michael Hanselmann
  def _StopInstanceCommand(self, instance_name, force, fail, cmd):
728 664b392d Michael Hanselmann
    if ((force and cmd[:2] == [self.CMD, "destroy"]) or
729 664b392d Michael Hanselmann
        (not force and cmd[:2] == [self.CMD, "shutdown"])):
730 664b392d Michael Hanselmann
      self.assertEqual(cmd[2:], [instance_name])
731 664b392d Michael Hanselmann
      output = ""
732 664b392d Michael Hanselmann
    else:
733 664b392d Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
734 664b392d Michael Hanselmann
735 664b392d Michael Hanselmann
    if fail:
736 664b392d Michael Hanselmann
      # Simulate a failing command
737 664b392d Michael Hanselmann
      return self._FailingCommand(cmd)
738 664b392d Michael Hanselmann
    else:
739 664b392d Michael Hanselmann
      return self._SuccessCommand(output, cmd)
740 664b392d Michael Hanselmann
741 664b392d Michael Hanselmann
  def testStopInstance(self):
742 664b392d Michael Hanselmann
    name = "inst4284.example.com"
743 664b392d Michael Hanselmann
    cfgfile = utils.PathJoin(self.tmpdir, name)
744 664b392d Michael Hanselmann
    cfgdata = "config file content\n"
745 664b392d Michael Hanselmann
746 664b392d Michael Hanselmann
    for force in [False, True]:
747 664b392d Michael Hanselmann
      for fail in [False, True]:
748 664b392d Michael Hanselmann
        utils.WriteFile(cfgfile, data=cfgdata)
749 664b392d Michael Hanselmann
750 664b392d Michael Hanselmann
        run_cmd = compat.partial(self._StopInstanceCommand, name, force, fail)
751 664b392d Michael Hanselmann
752 664b392d Michael Hanselmann
        hv = self._GetHv(run_cmd=run_cmd)
753 664b392d Michael Hanselmann
754 664b392d Michael Hanselmann
        self.assertTrue(os.path.isfile(cfgfile))
755 664b392d Michael Hanselmann
756 664b392d Michael Hanselmann
        if fail:
757 664b392d Michael Hanselmann
          try:
758 58e356a9 Helga Velroyen
            hv._StopInstance(name, force, None)
759 664b392d Michael Hanselmann
          except errors.HypervisorError, err:
760 664b392d Michael Hanselmann
            self.assertTrue(str(err).startswith("Failed to stop instance"))
761 664b392d Michael Hanselmann
          else:
762 664b392d Michael Hanselmann
            self.fail("Exception was not raised")
763 664b392d Michael Hanselmann
          self.assertEqual(utils.ReadFile(cfgfile), cfgdata,
764 664b392d Michael Hanselmann
                           msg=("Configuration was removed when stopping"
765 664b392d Michael Hanselmann
                                " instance failed"))
766 664b392d Michael Hanselmann
        else:
767 58e356a9 Helga Velroyen
          hv._StopInstance(name, force, None)
768 664b392d Michael Hanselmann
          self.assertFalse(os.path.exists(cfgfile))
769 664b392d Michael Hanselmann
770 d8784f7d Michael Hanselmann
  def _MigrateNonRunningInstCmd(self, cmd):
771 d8784f7d Michael Hanselmann
    if cmd == [self.CMD, "list"]:
772 d8784f7d Michael Hanselmann
      output = testutils.ReadTestData("xen-xm-list-4.0.1-dom0-only.txt")
773 d8784f7d Michael Hanselmann
    else:
774 d8784f7d Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
775 d8784f7d Michael Hanselmann
776 d8784f7d Michael Hanselmann
    return self._SuccessCommand(output, cmd)
777 d8784f7d Michael Hanselmann
778 d8784f7d Michael Hanselmann
  def testMigrateInstanceNotRunning(self):
779 d8784f7d Michael Hanselmann
    name = "nonexistinginstance.example.com"
780 d8784f7d Michael Hanselmann
    target = constants.IP4_ADDRESS_LOCALHOST
781 d8784f7d Michael Hanselmann
    port = 14618
782 d8784f7d Michael Hanselmann
783 d8784f7d Michael Hanselmann
    hv = self._GetHv(run_cmd=self._MigrateNonRunningInstCmd)
784 d8784f7d Michael Hanselmann
785 d8784f7d Michael Hanselmann
    for live in [False, True]:
786 d8784f7d Michael Hanselmann
      try:
787 d8784f7d Michael Hanselmann
        hv._MigrateInstance(NotImplemented, name, target, port, live,
788 8351df2f Helga Velroyen
                            self.VALID_HVPARAMS, _ping_fn=NotImplemented)
789 d8784f7d Michael Hanselmann
      except errors.HypervisorError, err:
790 d8784f7d Michael Hanselmann
        self.assertEqual(str(err), "Instance not running, cannot migrate")
791 d8784f7d Michael Hanselmann
      else:
792 d8784f7d Michael Hanselmann
        self.fail("Exception was not raised")
793 d8784f7d Michael Hanselmann
794 d8784f7d Michael Hanselmann
  def _MigrateInstTargetUnreachCmd(self, cmd):
795 d8784f7d Michael Hanselmann
    if cmd == [self.CMD, "list"]:
796 d8784f7d Michael Hanselmann
      output = testutils.ReadTestData("xen-xm-list-4.0.1-four-instances.txt")
797 d8784f7d Michael Hanselmann
    else:
798 d8784f7d Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
799 d8784f7d Michael Hanselmann
800 d8784f7d Michael Hanselmann
    return self._SuccessCommand(output, cmd)
801 d8784f7d Michael Hanselmann
802 d8784f7d Michael Hanselmann
  def testMigrateTargetUnreachable(self):
803 d8784f7d Michael Hanselmann
    name = "server01.example.com"
804 d8784f7d Michael Hanselmann
    target = constants.IP4_ADDRESS_LOCALHOST
805 d8784f7d Michael Hanselmann
    port = 28349
806 d8784f7d Michael Hanselmann
807 d8784f7d Michael Hanselmann
    hv = self._GetHv(run_cmd=self._MigrateInstTargetUnreachCmd)
808 8351df2f Helga Velroyen
    hvparams = {constants.HV_XEN_CMD: self.CMD}
809 d8784f7d Michael Hanselmann
810 d8784f7d Michael Hanselmann
    for live in [False, True]:
811 d8784f7d Michael Hanselmann
      if self.CMD == constants.XEN_CMD_XL:
812 d8784f7d Michael Hanselmann
        # TODO: Detect unreachable targets
813 d8784f7d Michael Hanselmann
        pass
814 d8784f7d Michael Hanselmann
      else:
815 d8784f7d Michael Hanselmann
        try:
816 d8784f7d Michael Hanselmann
          hv._MigrateInstance(NotImplemented, name, target, port, live,
817 8351df2f Helga Velroyen
                              hvparams,
818 d8784f7d Michael Hanselmann
                              _ping_fn=compat.partial(self._FakeTcpPing,
819 d8784f7d Michael Hanselmann
                                                      (target, port), False))
820 d8784f7d Michael Hanselmann
        except errors.HypervisorError, err:
821 d8784f7d Michael Hanselmann
          wanted = "Remote host %s not" % target
822 d8784f7d Michael Hanselmann
          self.assertTrue(str(err).startswith(wanted))
823 d8784f7d Michael Hanselmann
        else:
824 d8784f7d Michael Hanselmann
          self.fail("Exception was not raised")
825 d8784f7d Michael Hanselmann
826 d8784f7d Michael Hanselmann
  def _MigrateInstanceCmd(self, cluster_name, instance_name, target, port,
827 d8784f7d Michael Hanselmann
                          live, fail, cmd):
828 d8784f7d Michael Hanselmann
    if cmd == [self.CMD, "list"]:
829 d8784f7d Michael Hanselmann
      output = testutils.ReadTestData("xen-xm-list-4.0.1-four-instances.txt")
830 d8784f7d Michael Hanselmann
    elif cmd[:2] == [self.CMD, "migrate"]:
831 d8784f7d Michael Hanselmann
      if self.CMD == constants.XEN_CMD_XM:
832 d8784f7d Michael Hanselmann
        args = ["-p", str(port)]
833 d8784f7d Michael Hanselmann
834 d8784f7d Michael Hanselmann
        if live:
835 d8784f7d Michael Hanselmann
          args.append("-l")
836 d8784f7d Michael Hanselmann
837 d8784f7d Michael Hanselmann
      elif self.CMD == constants.XEN_CMD_XL:
838 d8784f7d Michael Hanselmann
        args = [
839 d8784f7d Michael Hanselmann
          "-s", constants.XL_SSH_CMD % cluster_name,
840 d8784f7d Michael Hanselmann
          "-C", utils.PathJoin(self.tmpdir, instance_name),
841 d8784f7d Michael Hanselmann
          ]
842 d8784f7d Michael Hanselmann
843 d8784f7d Michael Hanselmann
      else:
844 d8784f7d Michael Hanselmann
        self.fail("Unknown Xen command '%s'" % self.CMD)
845 d8784f7d Michael Hanselmann
846 d8784f7d Michael Hanselmann
      args.extend([instance_name, target])
847 d8784f7d Michael Hanselmann
      self.assertEqual(cmd[2:], args)
848 d8784f7d Michael Hanselmann
849 d8784f7d Michael Hanselmann
      if fail:
850 d8784f7d Michael Hanselmann
        return self._FailingCommand(cmd)
851 d8784f7d Michael Hanselmann
852 d8784f7d Michael Hanselmann
      output = ""
853 d8784f7d Michael Hanselmann
    else:
854 d8784f7d Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
855 d8784f7d Michael Hanselmann
856 d8784f7d Michael Hanselmann
    return self._SuccessCommand(output, cmd)
857 d8784f7d Michael Hanselmann
858 d8784f7d Michael Hanselmann
  def testMigrateInstance(self):
859 d8784f7d Michael Hanselmann
    clustername = "cluster.example.com"
860 d8784f7d Michael Hanselmann
    instname = "server01.example.com"
861 d8784f7d Michael Hanselmann
    target = constants.IP4_ADDRESS_LOCALHOST
862 d8784f7d Michael Hanselmann
    port = 22364
863 d8784f7d Michael Hanselmann
864 8351df2f Helga Velroyen
    hvparams = {constants.HV_XEN_CMD: self.CMD}
865 8351df2f Helga Velroyen
866 d8784f7d Michael Hanselmann
    for live in [False, True]:
867 d8784f7d Michael Hanselmann
      for fail in [False, True]:
868 d8784f7d Michael Hanselmann
        ping_fn = \
869 d8784f7d Michael Hanselmann
          testutils.CallCounter(compat.partial(self._FakeTcpPing,
870 d8784f7d Michael Hanselmann
                                               (target, port), True))
871 d8784f7d Michael Hanselmann
872 d8784f7d Michael Hanselmann
        run_cmd = \
873 d8784f7d Michael Hanselmann
          compat.partial(self._MigrateInstanceCmd,
874 d8784f7d Michael Hanselmann
                         clustername, instname, target, port, live,
875 d8784f7d Michael Hanselmann
                         fail)
876 d8784f7d Michael Hanselmann
877 d8784f7d Michael Hanselmann
        hv = self._GetHv(run_cmd=run_cmd)
878 d8784f7d Michael Hanselmann
879 d8784f7d Michael Hanselmann
        if fail:
880 d8784f7d Michael Hanselmann
          try:
881 d8784f7d Michael Hanselmann
            hv._MigrateInstance(clustername, instname, target, port, live,
882 8351df2f Helga Velroyen
                                hvparams, _ping_fn=ping_fn)
883 d8784f7d Michael Hanselmann
          except errors.HypervisorError, err:
884 d8784f7d Michael Hanselmann
            self.assertTrue(str(err).startswith("Failed to migrate instance"))
885 d8784f7d Michael Hanselmann
          else:
886 d8784f7d Michael Hanselmann
            self.fail("Exception was not raised")
887 d8784f7d Michael Hanselmann
        else:
888 d8784f7d Michael Hanselmann
          hv._MigrateInstance(clustername, instname, target, port, live,
889 8351df2f Helga Velroyen
                              hvparams, _ping_fn=ping_fn)
890 d8784f7d Michael Hanselmann
891 d8784f7d Michael Hanselmann
        if self.CMD == constants.XEN_CMD_XM:
892 d8784f7d Michael Hanselmann
          expected_pings = 1
893 d8784f7d Michael Hanselmann
        else:
894 d8784f7d Michael Hanselmann
          expected_pings = 0
895 d8784f7d Michael Hanselmann
896 d8784f7d Michael Hanselmann
        self.assertEqual(ping_fn.Count(), expected_pings)
897 d8784f7d Michael Hanselmann
898 1b9e1f42 Michael Hanselmann
  def _GetNodeInfoCmd(self, fail, cmd):
899 1b9e1f42 Michael Hanselmann
    if cmd == [self.CMD, "info"]:
900 1b9e1f42 Michael Hanselmann
      if fail:
901 1b9e1f42 Michael Hanselmann
        return self._FailingCommand(cmd)
902 1b9e1f42 Michael Hanselmann
      else:
903 1b9e1f42 Michael Hanselmann
        output = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
904 1b9e1f42 Michael Hanselmann
    elif cmd == [self.CMD, "list"]:
905 1b9e1f42 Michael Hanselmann
      if fail:
906 1b9e1f42 Michael Hanselmann
        self.fail("'xm list' shouldn't be called when 'xm info' failed")
907 1b9e1f42 Michael Hanselmann
      else:
908 1b9e1f42 Michael Hanselmann
        output = testutils.ReadTestData("xen-xm-list-4.0.1-four-instances.txt")
909 1b9e1f42 Michael Hanselmann
    else:
910 1b9e1f42 Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
911 1b9e1f42 Michael Hanselmann
912 1b9e1f42 Michael Hanselmann
    return self._SuccessCommand(output, cmd)
913 1b9e1f42 Michael Hanselmann
914 1b9e1f42 Michael Hanselmann
  def testGetNodeInfo(self):
915 1b9e1f42 Michael Hanselmann
    run_cmd = compat.partial(self._GetNodeInfoCmd, False)
916 1b9e1f42 Michael Hanselmann
    hv = self._GetHv(run_cmd=run_cmd)
917 1b9e1f42 Michael Hanselmann
    result = hv.GetNodeInfo()
918 1b9e1f42 Michael Hanselmann
919 1b9e1f42 Michael Hanselmann
    self.assertEqual(result["hv_version"], (4, 0))
920 1b9e1f42 Michael Hanselmann
    self.assertEqual(result["memory_free"], 8004)
921 1b9e1f42 Michael Hanselmann
922 1b9e1f42 Michael Hanselmann
  def testGetNodeInfoFailing(self):
923 1b9e1f42 Michael Hanselmann
    run_cmd = compat.partial(self._GetNodeInfoCmd, True)
924 1b9e1f42 Michael Hanselmann
    hv = self._GetHv(run_cmd=run_cmd)
925 1b9e1f42 Michael Hanselmann
    self.assertTrue(hv.GetNodeInfo() is None)
926 1b9e1f42 Michael Hanselmann
927 74a50c46 Michael Hanselmann
928 74a50c46 Michael Hanselmann
def _MakeTestClass(cls, cmd):
929 74a50c46 Michael Hanselmann
  """Makes a class for testing.
930 74a50c46 Michael Hanselmann

931 74a50c46 Michael Hanselmann
  The returned class has structure as shown in the following pseudo code:
932 74a50c46 Michael Hanselmann

933 74a50c46 Michael Hanselmann
    class Test{cls.__name__}{cmd}(_TestXenHypervisor, unittest.TestCase):
934 74a50c46 Michael Hanselmann
      TARGET = {cls}
935 74a50c46 Michael Hanselmann
      CMD = {cmd}
936 74a50c46 Michael Hanselmann
      HVNAME = {Hypervisor name retrieved using class}
937 74a50c46 Michael Hanselmann

938 74a50c46 Michael Hanselmann
  @type cls: class
939 74a50c46 Michael Hanselmann
  @param cls: Hypervisor class to be tested
940 74a50c46 Michael Hanselmann
  @type cmd: string
941 74a50c46 Michael Hanselmann
  @param cmd: Hypervisor command
942 74a50c46 Michael Hanselmann
  @rtype: tuple
943 74a50c46 Michael Hanselmann
  @return: Class name and class object (not instance)
944 74a50c46 Michael Hanselmann

945 74a50c46 Michael Hanselmann
  """
946 74a50c46 Michael Hanselmann
  name = "Test%sCmd%s" % (cls.__name__, cmd.title())
947 74a50c46 Michael Hanselmann
  bases = (_TestXenHypervisor, unittest.TestCase)
948 74a50c46 Michael Hanselmann
  hvname = HVCLASS_TO_HVNAME[cls]
949 74a50c46 Michael Hanselmann
950 74a50c46 Michael Hanselmann
  return (name, type(name, bases, dict(TARGET=cls, CMD=cmd, HVNAME=hvname)))
951 74a50c46 Michael Hanselmann
952 74a50c46 Michael Hanselmann
953 74a50c46 Michael Hanselmann
# Create test classes programmatically instead of manually to reduce the risk
954 74a50c46 Michael Hanselmann
# of forgetting some combinations
955 74a50c46 Michael Hanselmann
for cls in [hv_xen.XenPvmHypervisor, hv_xen.XenHvmHypervisor]:
956 74a50c46 Michael Hanselmann
  for cmd in constants.KNOWN_XEN_COMMANDS:
957 74a50c46 Michael Hanselmann
    (name, testcls) = _MakeTestClass(cls, cmd)
958 74a50c46 Michael Hanselmann
959 74a50c46 Michael Hanselmann
    assert name not in locals()
960 74a50c46 Michael Hanselmann
961 74a50c46 Michael Hanselmann
    locals()[name] = testcls
962 74a50c46 Michael Hanselmann
963 74a50c46 Michael Hanselmann
964 55cc0a44 Michael Hanselmann
if __name__ == "__main__":
965 55cc0a44 Michael Hanselmann
  testutils.GanetiTestProgram()