Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.hypervisor.hv_xen_unittest.py @ d01e51a5

History | View | Annotate | Download (24 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 55cc0a44 Michael Hanselmann
"""Script for testing ganeti.hypervisor.hv_lxc"""
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 55cc0a44 Michael Hanselmann
31 55cc0a44 Michael Hanselmann
from ganeti import constants
32 55cc0a44 Michael Hanselmann
from ganeti import objects
33 55cc0a44 Michael Hanselmann
from ganeti import hypervisor
34 b255379d Michael Hanselmann
from ganeti import utils
35 b255379d Michael Hanselmann
from ganeti import errors
36 b255379d Michael Hanselmann
from ganeti import compat
37 55cc0a44 Michael Hanselmann
38 55cc0a44 Michael Hanselmann
from ganeti.hypervisor import hv_xen
39 55cc0a44 Michael Hanselmann
40 55cc0a44 Michael Hanselmann
import testutils
41 55cc0a44 Michael Hanselmann
42 55cc0a44 Michael Hanselmann
43 74a50c46 Michael Hanselmann
# Map from hypervisor class to hypervisor name
44 74a50c46 Michael Hanselmann
HVCLASS_TO_HVNAME = utils.InvertDict(hypervisor._HYPERVISOR_MAP)
45 74a50c46 Michael Hanselmann
46 74a50c46 Michael Hanselmann
47 55cc0a44 Michael Hanselmann
class TestConsole(unittest.TestCase):
48 55cc0a44 Michael Hanselmann
  def test(self):
49 55cc0a44 Michael Hanselmann
    for cls in [hv_xen.XenPvmHypervisor, hv_xen.XenHvmHypervisor]:
50 55cc0a44 Michael Hanselmann
      instance = objects.Instance(name="xen.example.com",
51 55cc0a44 Michael Hanselmann
                                  primary_node="node24828")
52 55cc0a44 Michael Hanselmann
      cons = cls.GetInstanceConsole(instance, {}, {})
53 55cc0a44 Michael Hanselmann
      self.assertTrue(cons.Validate())
54 55cc0a44 Michael Hanselmann
      self.assertEqual(cons.kind, constants.CONS_SSH)
55 55cc0a44 Michael Hanselmann
      self.assertEqual(cons.host, instance.primary_node)
56 55cc0a44 Michael Hanselmann
      self.assertEqual(cons.command[-1], instance.name)
57 55cc0a44 Michael Hanselmann
58 55cc0a44 Michael Hanselmann
59 347fa0f1 Michael Hanselmann
class TestCreateConfigCpus(unittest.TestCase):
60 347fa0f1 Michael Hanselmann
  def testEmpty(self):
61 347fa0f1 Michael Hanselmann
    for cpu_mask in [None, ""]:
62 347fa0f1 Michael Hanselmann
      self.assertEqual(hv_xen._CreateConfigCpus(cpu_mask),
63 347fa0f1 Michael Hanselmann
                       "cpus = [  ]")
64 347fa0f1 Michael Hanselmann
65 347fa0f1 Michael Hanselmann
  def testAll(self):
66 347fa0f1 Michael Hanselmann
    self.assertEqual(hv_xen._CreateConfigCpus(constants.CPU_PINNING_ALL),
67 347fa0f1 Michael Hanselmann
                     None)
68 347fa0f1 Michael Hanselmann
69 347fa0f1 Michael Hanselmann
  def testOne(self):
70 347fa0f1 Michael Hanselmann
    self.assertEqual(hv_xen._CreateConfigCpus("9"), "cpu = \"9\"")
71 347fa0f1 Michael Hanselmann
72 347fa0f1 Michael Hanselmann
  def testMultiple(self):
73 347fa0f1 Michael Hanselmann
    self.assertEqual(hv_xen._CreateConfigCpus("0-2,4,5-5:3:all"),
74 347fa0f1 Michael Hanselmann
                     ("cpus = [ \"0,1,2,4,5\", \"3\", \"%s\" ]" %
75 347fa0f1 Michael Hanselmann
                      constants.CPU_PINNING_ALL_XEN))
76 347fa0f1 Michael Hanselmann
77 347fa0f1 Michael Hanselmann
78 b255379d Michael Hanselmann
class TestParseXmList(testutils.GanetiTestCase):
79 b255379d Michael Hanselmann
  def test(self):
80 b255379d Michael Hanselmann
    data = testutils.ReadTestData("xen-xm-list-4.0.1-dom0-only.txt")
81 b255379d Michael Hanselmann
82 b255379d Michael Hanselmann
    # Exclude node
83 b255379d Michael Hanselmann
    self.assertEqual(hv_xen._ParseXmList(data.splitlines(), False), [])
84 b255379d Michael Hanselmann
85 b255379d Michael Hanselmann
    # Include node
86 b255379d Michael Hanselmann
    result = hv_xen._ParseXmList(data.splitlines(), True)
87 b255379d Michael Hanselmann
    self.assertEqual(len(result), 1)
88 b255379d Michael Hanselmann
    self.assertEqual(len(result[0]), 6)
89 b255379d Michael Hanselmann
90 b255379d Michael Hanselmann
    # Name
91 b255379d Michael Hanselmann
    self.assertEqual(result[0][0], hv_xen._DOM0_NAME)
92 b255379d Michael Hanselmann
93 b255379d Michael Hanselmann
    # ID
94 b255379d Michael Hanselmann
    self.assertEqual(result[0][1], 0)
95 b255379d Michael Hanselmann
96 b255379d Michael Hanselmann
    # Memory
97 b255379d Michael Hanselmann
    self.assertEqual(result[0][2], 1023)
98 b255379d Michael Hanselmann
99 b255379d Michael Hanselmann
    # VCPUs
100 b255379d Michael Hanselmann
    self.assertEqual(result[0][3], 1)
101 b255379d Michael Hanselmann
102 b255379d Michael Hanselmann
    # State
103 b255379d Michael Hanselmann
    self.assertEqual(result[0][4], "r-----")
104 b255379d Michael Hanselmann
105 b255379d Michael Hanselmann
    # Time
106 b255379d Michael Hanselmann
    self.assertAlmostEqual(result[0][5], 121152.6)
107 b255379d Michael Hanselmann
108 b255379d Michael Hanselmann
  def testWrongLineFormat(self):
109 b255379d Michael Hanselmann
    tests = [
110 b255379d Michael Hanselmann
      ["three fields only"],
111 b255379d Michael Hanselmann
      ["name InvalidID 128 1 r----- 12345"],
112 b255379d Michael Hanselmann
      ]
113 b255379d Michael Hanselmann
114 b255379d Michael Hanselmann
    for lines in tests:
115 b255379d Michael Hanselmann
      try:
116 b255379d Michael Hanselmann
        hv_xen._ParseXmList(["Header would be here"] + lines, False)
117 b255379d Michael Hanselmann
      except errors.HypervisorError, err:
118 b255379d Michael Hanselmann
        self.assertTrue("Can't parse output of xm list" in str(err))
119 b255379d Michael Hanselmann
      else:
120 b255379d Michael Hanselmann
        self.fail("Exception was not raised")
121 b255379d Michael Hanselmann
122 b255379d Michael Hanselmann
123 b255379d Michael Hanselmann
class TestGetXmList(testutils.GanetiTestCase):
124 b255379d Michael Hanselmann
  def _Fail(self):
125 b255379d Michael Hanselmann
    return utils.RunResult(constants.EXIT_FAILURE, None,
126 b255379d Michael Hanselmann
                           "stdout", "stderr", None,
127 b255379d Michael Hanselmann
                           NotImplemented, NotImplemented)
128 b255379d Michael Hanselmann
129 b255379d Michael Hanselmann
  def testTimeout(self):
130 b255379d Michael Hanselmann
    fn = testutils.CallCounter(self._Fail)
131 b255379d Michael Hanselmann
    try:
132 b255379d Michael Hanselmann
      hv_xen._GetXmList(fn, False, _timeout=0.1)
133 b255379d Michael Hanselmann
    except errors.HypervisorError, err:
134 b255379d Michael Hanselmann
      self.assertTrue("timeout exceeded" in str(err))
135 b255379d Michael Hanselmann
    else:
136 b255379d Michael Hanselmann
      self.fail("Exception was not raised")
137 b255379d Michael Hanselmann
138 b255379d Michael Hanselmann
    self.assertTrue(fn.Count() < 10,
139 b255379d Michael Hanselmann
                    msg="'xm list' was called too many times")
140 b255379d Michael Hanselmann
141 b255379d Michael Hanselmann
  def _Success(self, stdout):
142 b255379d Michael Hanselmann
    return utils.RunResult(constants.EXIT_SUCCESS, None, stdout, "", None,
143 b255379d Michael Hanselmann
                           NotImplemented, NotImplemented)
144 b255379d Michael Hanselmann
145 b255379d Michael Hanselmann
  def testSuccess(self):
146 b255379d Michael Hanselmann
    data = testutils.ReadTestData("xen-xm-list-4.0.1-four-instances.txt")
147 b255379d Michael Hanselmann
148 b255379d Michael Hanselmann
    fn = testutils.CallCounter(compat.partial(self._Success, data))
149 b255379d Michael Hanselmann
150 b255379d Michael Hanselmann
    result = hv_xen._GetXmList(fn, True, _timeout=0.1)
151 b255379d Michael Hanselmann
152 b255379d Michael Hanselmann
    self.assertEqual(len(result), 4)
153 b255379d Michael Hanselmann
154 b255379d Michael Hanselmann
    self.assertEqual(map(compat.fst, result), [
155 b255379d Michael Hanselmann
      "Domain-0",
156 b255379d Michael Hanselmann
      "server01.example.com",
157 b255379d Michael Hanselmann
      "web3106215069.example.com",
158 b255379d Michael Hanselmann
      "testinstance.example.com",
159 b255379d Michael Hanselmann
      ])
160 b255379d Michael Hanselmann
161 b255379d Michael Hanselmann
    self.assertEqual(fn.Count(), 1)
162 b255379d Michael Hanselmann
163 b255379d Michael Hanselmann
164 06c9a520 Michael Hanselmann
class TestParseNodeInfo(testutils.GanetiTestCase):
165 06c9a520 Michael Hanselmann
  def testEmpty(self):
166 06c9a520 Michael Hanselmann
    self.assertEqual(hv_xen._ParseNodeInfo(""), {})
167 06c9a520 Michael Hanselmann
168 06c9a520 Michael Hanselmann
  def testUnknownInput(self):
169 06c9a520 Michael Hanselmann
    data = "\n".join([
170 06c9a520 Michael Hanselmann
      "foo bar",
171 06c9a520 Michael Hanselmann
      "something else goes",
172 06c9a520 Michael Hanselmann
      "here",
173 06c9a520 Michael Hanselmann
      ])
174 06c9a520 Michael Hanselmann
    self.assertEqual(hv_xen._ParseNodeInfo(data), {})
175 06c9a520 Michael Hanselmann
176 06c9a520 Michael Hanselmann
  def testBasicInfo(self):
177 06c9a520 Michael Hanselmann
    data = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
178 06c9a520 Michael Hanselmann
    result = hv_xen._ParseNodeInfo(data)
179 06c9a520 Michael Hanselmann
    self.assertEqual(result, {
180 06c9a520 Michael Hanselmann
      "cpu_nodes": 1,
181 06c9a520 Michael Hanselmann
      "cpu_sockets": 2,
182 06c9a520 Michael Hanselmann
      "cpu_total": 4,
183 06c9a520 Michael Hanselmann
      "hv_version": (4, 0),
184 06c9a520 Michael Hanselmann
      "memory_free": 8004,
185 06c9a520 Michael Hanselmann
      "memory_total": 16378,
186 06c9a520 Michael Hanselmann
      })
187 06c9a520 Michael Hanselmann
188 06c9a520 Michael Hanselmann
189 06c9a520 Michael Hanselmann
class TestMergeInstanceInfo(testutils.GanetiTestCase):
190 06c9a520 Michael Hanselmann
  def testEmpty(self):
191 06c9a520 Michael Hanselmann
    self.assertEqual(hv_xen._MergeInstanceInfo({}, lambda _: []), {})
192 06c9a520 Michael Hanselmann
193 06c9a520 Michael Hanselmann
  def _FakeXmList(self, include_node):
194 06c9a520 Michael Hanselmann
    self.assertTrue(include_node)
195 06c9a520 Michael Hanselmann
    return [
196 06c9a520 Michael Hanselmann
      (hv_xen._DOM0_NAME, NotImplemented, 4096, 7, NotImplemented,
197 06c9a520 Michael Hanselmann
       NotImplemented),
198 06c9a520 Michael Hanselmann
      ("inst1.example.com", NotImplemented, 2048, 4, NotImplemented,
199 06c9a520 Michael Hanselmann
       NotImplemented),
200 06c9a520 Michael Hanselmann
      ]
201 06c9a520 Michael Hanselmann
202 06c9a520 Michael Hanselmann
  def testMissingNodeInfo(self):
203 06c9a520 Michael Hanselmann
    result = hv_xen._MergeInstanceInfo({}, self._FakeXmList)
204 06c9a520 Michael Hanselmann
    self.assertEqual(result, {
205 06c9a520 Michael Hanselmann
      "memory_dom0": 4096,
206 06c9a520 Michael Hanselmann
      "dom0_cpus": 7,
207 06c9a520 Michael Hanselmann
      })
208 06c9a520 Michael Hanselmann
209 06c9a520 Michael Hanselmann
  def testWithNodeInfo(self):
210 06c9a520 Michael Hanselmann
    info = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
211 06c9a520 Michael Hanselmann
    result = hv_xen._GetNodeInfo(info, self._FakeXmList)
212 06c9a520 Michael Hanselmann
    self.assertEqual(result, {
213 06c9a520 Michael Hanselmann
      "cpu_nodes": 1,
214 06c9a520 Michael Hanselmann
      "cpu_sockets": 2,
215 06c9a520 Michael Hanselmann
      "cpu_total": 4,
216 06c9a520 Michael Hanselmann
      "dom0_cpus": 7,
217 06c9a520 Michael Hanselmann
      "hv_version": (4, 0),
218 06c9a520 Michael Hanselmann
      "memory_dom0": 4096,
219 06c9a520 Michael Hanselmann
      "memory_free": 8004,
220 06c9a520 Michael Hanselmann
      "memory_hv": 2230,
221 06c9a520 Michael Hanselmann
      "memory_total": 16378,
222 06c9a520 Michael Hanselmann
      })
223 06c9a520 Michael Hanselmann
224 06c9a520 Michael Hanselmann
225 d0bb3f24 Michael Hanselmann
class TestGetConfigFileDiskData(unittest.TestCase):
226 d0bb3f24 Michael Hanselmann
  def testLetterCount(self):
227 d0bb3f24 Michael Hanselmann
    self.assertEqual(len(hv_xen._DISK_LETTERS), 26)
228 d0bb3f24 Michael Hanselmann
229 d0bb3f24 Michael Hanselmann
  def testNoDisks(self):
230 d0bb3f24 Michael Hanselmann
    self.assertEqual(hv_xen._GetConfigFileDiskData([], "hd"), [])
231 d0bb3f24 Michael Hanselmann
232 d0bb3f24 Michael Hanselmann
  def testManyDisks(self):
233 d0bb3f24 Michael Hanselmann
    for offset in [0, 1, 10]:
234 d0bb3f24 Michael Hanselmann
      disks = [(objects.Disk(dev_type=constants.LD_LV), "/tmp/disk/%s" % idx)
235 d0bb3f24 Michael Hanselmann
               for idx in range(len(hv_xen._DISK_LETTERS) + offset)]
236 d0bb3f24 Michael Hanselmann
237 d0bb3f24 Michael Hanselmann
      if offset == 0:
238 d0bb3f24 Michael Hanselmann
        result = hv_xen._GetConfigFileDiskData(disks, "hd")
239 d0bb3f24 Michael Hanselmann
        self.assertEqual(result, [
240 d0bb3f24 Michael Hanselmann
          "'phy:/tmp/disk/%s,hd%s,r'" % (idx, string.ascii_lowercase[idx])
241 d0bb3f24 Michael Hanselmann
          for idx in range(len(hv_xen._DISK_LETTERS) + offset)
242 d0bb3f24 Michael Hanselmann
          ])
243 d0bb3f24 Michael Hanselmann
      else:
244 d0bb3f24 Michael Hanselmann
        try:
245 d0bb3f24 Michael Hanselmann
          hv_xen._GetConfigFileDiskData(disks, "hd")
246 d0bb3f24 Michael Hanselmann
        except errors.HypervisorError, err:
247 d0bb3f24 Michael Hanselmann
          self.assertEqual(str(err), "Too many disks")
248 d0bb3f24 Michael Hanselmann
        else:
249 d0bb3f24 Michael Hanselmann
          self.fail("Exception was not raised")
250 d0bb3f24 Michael Hanselmann
251 d0bb3f24 Michael Hanselmann
  def testTwoLvDisksWithMode(self):
252 d0bb3f24 Michael Hanselmann
    disks = [
253 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_LV, mode=constants.DISK_RDWR),
254 d0bb3f24 Michael Hanselmann
       "/tmp/diskFirst"),
255 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_LV, mode=constants.DISK_RDONLY),
256 d0bb3f24 Michael Hanselmann
       "/tmp/diskLast"),
257 d0bb3f24 Michael Hanselmann
      ]
258 d0bb3f24 Michael Hanselmann
259 d0bb3f24 Michael Hanselmann
    result = hv_xen._GetConfigFileDiskData(disks, "hd")
260 d0bb3f24 Michael Hanselmann
    self.assertEqual(result, [
261 d0bb3f24 Michael Hanselmann
      "'phy:/tmp/diskFirst,hda,w'",
262 d0bb3f24 Michael Hanselmann
      "'phy:/tmp/diskLast,hdb,r'",
263 d0bb3f24 Michael Hanselmann
      ])
264 d0bb3f24 Michael Hanselmann
265 d0bb3f24 Michael Hanselmann
  def testFileDisks(self):
266 d0bb3f24 Michael Hanselmann
    disks = [
267 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_FILE, mode=constants.DISK_RDWR,
268 d0bb3f24 Michael Hanselmann
                    physical_id=[constants.FD_LOOP]),
269 d0bb3f24 Michael Hanselmann
       "/tmp/diskFirst"),
270 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_FILE, mode=constants.DISK_RDONLY,
271 d0bb3f24 Michael Hanselmann
                    physical_id=[constants.FD_BLKTAP]),
272 d0bb3f24 Michael Hanselmann
       "/tmp/diskTwo"),
273 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_FILE, mode=constants.DISK_RDWR,
274 d0bb3f24 Michael Hanselmann
                    physical_id=[constants.FD_LOOP]),
275 d0bb3f24 Michael Hanselmann
       "/tmp/diskThree"),
276 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_FILE, mode=constants.DISK_RDWR,
277 d0bb3f24 Michael Hanselmann
                    physical_id=[constants.FD_BLKTAP]),
278 d0bb3f24 Michael Hanselmann
       "/tmp/diskLast"),
279 d0bb3f24 Michael Hanselmann
      ]
280 d0bb3f24 Michael Hanselmann
281 d0bb3f24 Michael Hanselmann
    result = hv_xen._GetConfigFileDiskData(disks, "sd")
282 d0bb3f24 Michael Hanselmann
    self.assertEqual(result, [
283 d0bb3f24 Michael Hanselmann
      "'file:/tmp/diskFirst,sda,w'",
284 d0bb3f24 Michael Hanselmann
      "'tap:aio:/tmp/diskTwo,sdb,r'",
285 d0bb3f24 Michael Hanselmann
      "'file:/tmp/diskThree,sdc,w'",
286 d0bb3f24 Michael Hanselmann
      "'tap:aio:/tmp/diskLast,sdd,w'",
287 d0bb3f24 Michael Hanselmann
      ])
288 d0bb3f24 Michael Hanselmann
289 d0bb3f24 Michael Hanselmann
  def testInvalidFileDisk(self):
290 d0bb3f24 Michael Hanselmann
    disks = [
291 d0bb3f24 Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_FILE, mode=constants.DISK_RDWR,
292 d0bb3f24 Michael Hanselmann
                    physical_id=["#unknown#"]),
293 d0bb3f24 Michael Hanselmann
       "/tmp/diskinvalid"),
294 d0bb3f24 Michael Hanselmann
      ]
295 d0bb3f24 Michael Hanselmann
296 d0bb3f24 Michael Hanselmann
    self.assertRaises(KeyError, hv_xen._GetConfigFileDiskData, disks, "sd")
297 d0bb3f24 Michael Hanselmann
298 d0bb3f24 Michael Hanselmann
299 1dee2041 Michael Hanselmann
class TestXenHypervisorUnknownCommand(unittest.TestCase):
300 1dee2041 Michael Hanselmann
  def test(self):
301 1dee2041 Michael Hanselmann
    cmd = "#unknown command#"
302 1dee2041 Michael Hanselmann
    self.assertFalse(cmd in constants.KNOWN_XEN_COMMANDS)
303 1dee2041 Michael Hanselmann
    hv = hv_xen.XenHypervisor(_cfgdir=NotImplemented,
304 1dee2041 Michael Hanselmann
                              _run_cmd_fn=NotImplemented,
305 1dee2041 Michael Hanselmann
                              _cmd=cmd)
306 1dee2041 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, hv._RunXen, [])
307 1dee2041 Michael Hanselmann
308 1dee2041 Michael Hanselmann
309 64a66bd2 Michael Hanselmann
class TestXenHypervisorWriteConfigFile(unittest.TestCase):
310 64a66bd2 Michael Hanselmann
  def setUp(self):
311 64a66bd2 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
312 64a66bd2 Michael Hanselmann
313 64a66bd2 Michael Hanselmann
  def tearDown(self):
314 64a66bd2 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
315 64a66bd2 Michael Hanselmann
316 64a66bd2 Michael Hanselmann
  def testWriteError(self):
317 64a66bd2 Michael Hanselmann
    cfgdir = utils.PathJoin(self.tmpdir, "foobar")
318 64a66bd2 Michael Hanselmann
319 64a66bd2 Michael Hanselmann
    hv = hv_xen.XenHypervisor(_cfgdir=cfgdir,
320 64a66bd2 Michael Hanselmann
                              _run_cmd_fn=NotImplemented,
321 64a66bd2 Michael Hanselmann
                              _cmd=NotImplemented)
322 64a66bd2 Michael Hanselmann
323 64a66bd2 Michael Hanselmann
    self.assertFalse(os.path.exists(cfgdir))
324 64a66bd2 Michael Hanselmann
325 64a66bd2 Michael Hanselmann
    try:
326 64a66bd2 Michael Hanselmann
      hv._WriteConfigFile("name", "data")
327 64a66bd2 Michael Hanselmann
    except errors.HypervisorError, err:
328 64a66bd2 Michael Hanselmann
      self.assertTrue(str(err).startswith("Cannot write Xen instance"))
329 64a66bd2 Michael Hanselmann
    else:
330 64a66bd2 Michael Hanselmann
      self.fail("Exception was not raised")
331 64a66bd2 Michael Hanselmann
332 64a66bd2 Michael Hanselmann
333 74a50c46 Michael Hanselmann
class _TestXenHypervisor(object):
334 74a50c46 Michael Hanselmann
  TARGET = NotImplemented
335 74a50c46 Michael Hanselmann
  CMD = NotImplemented
336 74a50c46 Michael Hanselmann
  HVNAME = NotImplemented
337 74a50c46 Michael Hanselmann
338 74a50c46 Michael Hanselmann
  def setUp(self):
339 74a50c46 Michael Hanselmann
    super(_TestXenHypervisor, self).setUp()
340 74a50c46 Michael Hanselmann
341 74a50c46 Michael Hanselmann
    self.tmpdir = tempfile.mkdtemp()
342 74a50c46 Michael Hanselmann
343 74a50c46 Michael Hanselmann
    self.vncpw = "".join(random.sample(string.ascii_letters, 10))
344 74a50c46 Michael Hanselmann
345 74a50c46 Michael Hanselmann
    self.vncpw_path = utils.PathJoin(self.tmpdir, "vncpw")
346 74a50c46 Michael Hanselmann
    utils.WriteFile(self.vncpw_path, data=self.vncpw)
347 74a50c46 Michael Hanselmann
348 74a50c46 Michael Hanselmann
  def tearDown(self):
349 74a50c46 Michael Hanselmann
    super(_TestXenHypervisor, self).tearDown()
350 74a50c46 Michael Hanselmann
351 74a50c46 Michael Hanselmann
    shutil.rmtree(self.tmpdir)
352 74a50c46 Michael Hanselmann
353 74a50c46 Michael Hanselmann
  def _GetHv(self, run_cmd=NotImplemented):
354 74a50c46 Michael Hanselmann
    return self.TARGET(_cfgdir=self.tmpdir, _run_cmd_fn=run_cmd, _cmd=self.CMD)
355 74a50c46 Michael Hanselmann
356 74a50c46 Michael Hanselmann
  def _SuccessCommand(self, stdout, cmd):
357 74a50c46 Michael Hanselmann
    self.assertEqual(cmd[0], self.CMD)
358 74a50c46 Michael Hanselmann
359 74a50c46 Michael Hanselmann
    return utils.RunResult(constants.EXIT_SUCCESS, None, stdout, "", None,
360 74a50c46 Michael Hanselmann
                           NotImplemented, NotImplemented)
361 74a50c46 Michael Hanselmann
362 74a50c46 Michael Hanselmann
  def _FailingCommand(self, cmd):
363 74a50c46 Michael Hanselmann
    self.assertEqual(cmd[0], self.CMD)
364 74a50c46 Michael Hanselmann
365 74a50c46 Michael Hanselmann
    return utils.RunResult(constants.EXIT_FAILURE, None,
366 74a50c46 Michael Hanselmann
                           "", "This command failed", None,
367 74a50c46 Michael Hanselmann
                           NotImplemented, NotImplemented)
368 74a50c46 Michael Hanselmann
369 d8784f7d Michael Hanselmann
  def _FakeTcpPing(self, expected, result, target, port, **kwargs):
370 d8784f7d Michael Hanselmann
    self.assertEqual((target, port), expected)
371 d8784f7d Michael Hanselmann
    return result
372 d8784f7d Michael Hanselmann
373 57270b2d Michael Hanselmann
  def testReadingNonExistentConfigFile(self):
374 57270b2d Michael Hanselmann
    hv = self._GetHv()
375 57270b2d Michael Hanselmann
376 57270b2d Michael Hanselmann
    try:
377 57270b2d Michael Hanselmann
      hv._ReadConfigFile("inst15780.example.com")
378 57270b2d Michael Hanselmann
    except errors.HypervisorError, err:
379 57270b2d Michael Hanselmann
      self.assertTrue(str(err).startswith("Failed to load Xen config file:"))
380 57270b2d Michael Hanselmann
    else:
381 57270b2d Michael Hanselmann
      self.fail("Exception was not raised")
382 57270b2d Michael Hanselmann
383 7610d884 Michael Hanselmann
  def testRemovingAutoConfigFile(self):
384 7610d884 Michael Hanselmann
    name = "inst8206.example.com"
385 7610d884 Michael Hanselmann
    cfgfile = utils.PathJoin(self.tmpdir, name)
386 7610d884 Michael Hanselmann
    autodir = utils.PathJoin(self.tmpdir, "auto")
387 7610d884 Michael Hanselmann
    autocfgfile = utils.PathJoin(autodir, name)
388 7610d884 Michael Hanselmann
389 7610d884 Michael Hanselmann
    os.mkdir(autodir)
390 7610d884 Michael Hanselmann
391 7610d884 Michael Hanselmann
    utils.WriteFile(autocfgfile, data="")
392 7610d884 Michael Hanselmann
393 7610d884 Michael Hanselmann
    hv = self._GetHv()
394 7610d884 Michael Hanselmann
395 7610d884 Michael Hanselmann
    self.assertTrue(os.path.isfile(autocfgfile))
396 7610d884 Michael Hanselmann
    hv._WriteConfigFile(name, "content")
397 7610d884 Michael Hanselmann
    self.assertFalse(os.path.exists(autocfgfile))
398 7610d884 Michael Hanselmann
    self.assertEqual(utils.ReadFile(cfgfile), "content")
399 7610d884 Michael Hanselmann
400 2edc1c79 Michael Hanselmann
  def _XenList(self, cmd):
401 2edc1c79 Michael Hanselmann
    self.assertEqual(cmd, [self.CMD, "list"])
402 2edc1c79 Michael Hanselmann
403 2edc1c79 Michael Hanselmann
    # TODO: Use actual data from "xl" command
404 2edc1c79 Michael Hanselmann
    output = testutils.ReadTestData("xen-xm-list-4.0.1-four-instances.txt")
405 2edc1c79 Michael Hanselmann
406 2edc1c79 Michael Hanselmann
    return self._SuccessCommand(output, cmd)
407 2edc1c79 Michael Hanselmann
408 2edc1c79 Michael Hanselmann
  def testGetInstanceInfo(self):
409 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
410 2edc1c79 Michael Hanselmann
411 2edc1c79 Michael Hanselmann
    (name, instid, memory, vcpus, state, runtime) = \
412 2edc1c79 Michael Hanselmann
      hv.GetInstanceInfo("server01.example.com")
413 2edc1c79 Michael Hanselmann
414 2edc1c79 Michael Hanselmann
    self.assertEqual(name, "server01.example.com")
415 2edc1c79 Michael Hanselmann
    self.assertEqual(instid, 1)
416 2edc1c79 Michael Hanselmann
    self.assertEqual(memory, 1024)
417 2edc1c79 Michael Hanselmann
    self.assertEqual(vcpus, 1)
418 2edc1c79 Michael Hanselmann
    self.assertEqual(state, "-b----")
419 2edc1c79 Michael Hanselmann
    self.assertAlmostEqual(runtime, 167643.2)
420 2edc1c79 Michael Hanselmann
421 2edc1c79 Michael Hanselmann
  def testGetInstanceInfoDom0(self):
422 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
423 2edc1c79 Michael Hanselmann
424 2edc1c79 Michael Hanselmann
    # TODO: Not sure if this is actually used anywhere (can't find it), but the
425 2edc1c79 Michael Hanselmann
    # code supports querying for Dom0
426 2edc1c79 Michael Hanselmann
    (name, instid, memory, vcpus, state, runtime) = \
427 2edc1c79 Michael Hanselmann
      hv.GetInstanceInfo(hv_xen._DOM0_NAME)
428 2edc1c79 Michael Hanselmann
429 2edc1c79 Michael Hanselmann
    self.assertEqual(name, "Domain-0")
430 2edc1c79 Michael Hanselmann
    self.assertEqual(instid, 0)
431 2edc1c79 Michael Hanselmann
    self.assertEqual(memory, 1023)
432 2edc1c79 Michael Hanselmann
    self.assertEqual(vcpus, 1)
433 2edc1c79 Michael Hanselmann
    self.assertEqual(state, "r-----")
434 2edc1c79 Michael Hanselmann
    self.assertAlmostEqual(runtime, 154706.1)
435 2edc1c79 Michael Hanselmann
436 2edc1c79 Michael Hanselmann
  def testGetInstanceInfoUnknown(self):
437 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
438 2edc1c79 Michael Hanselmann
439 2edc1c79 Michael Hanselmann
    result = hv.GetInstanceInfo("unknown.example.com")
440 2edc1c79 Michael Hanselmann
    self.assertTrue(result is None)
441 2edc1c79 Michael Hanselmann
442 2edc1c79 Michael Hanselmann
  def testGetAllInstancesInfo(self):
443 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
444 2edc1c79 Michael Hanselmann
445 2edc1c79 Michael Hanselmann
    result = hv.GetAllInstancesInfo()
446 2edc1c79 Michael Hanselmann
447 2edc1c79 Michael Hanselmann
    self.assertEqual(map(compat.fst, result), [
448 2edc1c79 Michael Hanselmann
      "server01.example.com",
449 2edc1c79 Michael Hanselmann
      "web3106215069.example.com",
450 2edc1c79 Michael Hanselmann
      "testinstance.example.com",
451 2edc1c79 Michael Hanselmann
      ])
452 2edc1c79 Michael Hanselmann
453 2edc1c79 Michael Hanselmann
  def testListInstances(self):
454 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
455 2edc1c79 Michael Hanselmann
456 2edc1c79 Michael Hanselmann
    self.assertEqual(hv.ListInstances(), [
457 2edc1c79 Michael Hanselmann
      "server01.example.com",
458 2edc1c79 Michael Hanselmann
      "web3106215069.example.com",
459 2edc1c79 Michael Hanselmann
      "testinstance.example.com",
460 2edc1c79 Michael Hanselmann
      ])
461 2edc1c79 Michael Hanselmann
462 b666f213 Michael Hanselmann
  def testVerify(self):
463 b666f213 Michael Hanselmann
    output = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
464 b666f213 Michael Hanselmann
    hv = self._GetHv(run_cmd=compat.partial(self._SuccessCommand,
465 b666f213 Michael Hanselmann
                                            output))
466 b666f213 Michael Hanselmann
    self.assertTrue(hv.Verify() is None)
467 b666f213 Michael Hanselmann
468 b666f213 Michael Hanselmann
  def testVerifyFailing(self):
469 b666f213 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._FailingCommand)
470 b666f213 Michael Hanselmann
    self.assertTrue("failed:" in hv.Verify())
471 b666f213 Michael Hanselmann
472 396672cd Michael Hanselmann
  def _StartInstanceCommand(self, inst, paused, failcreate, cmd):
473 396672cd Michael Hanselmann
    if cmd == [self.CMD, "info"]:
474 396672cd Michael Hanselmann
      output = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
475 396672cd Michael Hanselmann
    elif cmd == [self.CMD, "list"]:
476 396672cd Michael Hanselmann
      output = testutils.ReadTestData("xen-xm-list-4.0.1-dom0-only.txt")
477 396672cd Michael Hanselmann
    elif cmd[:2] == [self.CMD, "create"]:
478 396672cd Michael Hanselmann
      args = cmd[2:]
479 396672cd Michael Hanselmann
      cfgfile = utils.PathJoin(self.tmpdir, inst.name)
480 396672cd Michael Hanselmann
481 396672cd Michael Hanselmann
      if paused:
482 396672cd Michael Hanselmann
        self.assertEqual(args, ["-p", cfgfile])
483 396672cd Michael Hanselmann
      else:
484 396672cd Michael Hanselmann
        self.assertEqual(args, [cfgfile])
485 396672cd Michael Hanselmann
486 396672cd Michael Hanselmann
      if failcreate:
487 396672cd Michael Hanselmann
        return self._FailingCommand(cmd)
488 396672cd Michael Hanselmann
489 396672cd Michael Hanselmann
      output = ""
490 396672cd Michael Hanselmann
    else:
491 396672cd Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
492 396672cd Michael Hanselmann
493 396672cd Michael Hanselmann
    return self._SuccessCommand(output, cmd)
494 396672cd Michael Hanselmann
    #return self._FailingCommand(cmd)
495 396672cd Michael Hanselmann
496 396672cd Michael Hanselmann
  def _MakeInstance(self):
497 396672cd Michael Hanselmann
    # Copy default parameters
498 396672cd Michael Hanselmann
    bep = objects.FillDict(constants.BEC_DEFAULTS, {})
499 396672cd Michael Hanselmann
    hvp = objects.FillDict(constants.HVC_DEFAULTS[self.HVNAME], {})
500 396672cd Michael Hanselmann
501 396672cd Michael Hanselmann
    # Override default VNC password file path
502 396672cd Michael Hanselmann
    if constants.HV_VNC_PASSWORD_FILE in hvp:
503 396672cd Michael Hanselmann
      hvp[constants.HV_VNC_PASSWORD_FILE] = self.vncpw_path
504 396672cd Michael Hanselmann
505 396672cd Michael Hanselmann
    disks = [
506 396672cd Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_LV, mode=constants.DISK_RDWR),
507 396672cd Michael Hanselmann
       utils.PathJoin(self.tmpdir, "disk0")),
508 396672cd Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_LV, mode=constants.DISK_RDONLY),
509 396672cd Michael Hanselmann
       utils.PathJoin(self.tmpdir, "disk1")),
510 396672cd Michael Hanselmann
      ]
511 396672cd Michael Hanselmann
512 396672cd Michael Hanselmann
    inst = objects.Instance(name="server01.example.com",
513 396672cd Michael Hanselmann
                            hvparams=hvp, beparams=bep,
514 396672cd Michael Hanselmann
                            osparams={}, nics=[], os="deb1",
515 396672cd Michael Hanselmann
                            disks=map(compat.fst, disks))
516 396672cd Michael Hanselmann
    inst.UpgradeConfig()
517 396672cd Michael Hanselmann
518 396672cd Michael Hanselmann
    return (inst, disks)
519 396672cd Michael Hanselmann
520 396672cd Michael Hanselmann
  def testStartInstance(self):
521 396672cd Michael Hanselmann
    (inst, disks) = self._MakeInstance()
522 396672cd Michael Hanselmann
523 396672cd Michael Hanselmann
    for failcreate in [False, True]:
524 396672cd Michael Hanselmann
      for paused in [False, True]:
525 396672cd Michael Hanselmann
        run_cmd = compat.partial(self._StartInstanceCommand,
526 396672cd Michael Hanselmann
                                 inst, paused, failcreate)
527 396672cd Michael Hanselmann
528 396672cd Michael Hanselmann
        hv = self._GetHv(run_cmd=run_cmd)
529 396672cd Michael Hanselmann
530 396672cd Michael Hanselmann
        # Ensure instance is not listed
531 396672cd Michael Hanselmann
        self.assertTrue(inst.name not in hv.ListInstances())
532 396672cd Michael Hanselmann
533 396672cd Michael Hanselmann
        # Remove configuration
534 396672cd Michael Hanselmann
        cfgfile = utils.PathJoin(self.tmpdir, inst.name)
535 396672cd Michael Hanselmann
        utils.RemoveFile(cfgfile)
536 396672cd Michael Hanselmann
537 396672cd Michael Hanselmann
        if failcreate:
538 396672cd Michael Hanselmann
          self.assertRaises(errors.HypervisorError, hv.StartInstance,
539 396672cd Michael Hanselmann
                            inst, disks, paused)
540 396672cd Michael Hanselmann
        else:
541 396672cd Michael Hanselmann
          hv.StartInstance(inst, disks, paused)
542 396672cd Michael Hanselmann
543 396672cd Michael Hanselmann
        # Check if configuration was updated
544 396672cd Michael Hanselmann
        lines = utils.ReadFile(cfgfile).splitlines()
545 396672cd Michael Hanselmann
546 396672cd Michael Hanselmann
        if constants.HV_VNC_PASSWORD_FILE in inst.hvparams:
547 396672cd Michael Hanselmann
          self.assertTrue(("vncpasswd = '%s'" % self.vncpw) in lines)
548 396672cd Michael Hanselmann
        else:
549 396672cd Michael Hanselmann
          extra = inst.hvparams[constants.HV_KERNEL_ARGS]
550 396672cd Michael Hanselmann
          self.assertTrue(("extra = '%s'" % extra) in lines)
551 396672cd Michael Hanselmann
552 664b392d Michael Hanselmann
  def _StopInstanceCommand(self, instance_name, force, fail, cmd):
553 664b392d Michael Hanselmann
    if ((force and cmd[:2] == [self.CMD, "destroy"]) or
554 664b392d Michael Hanselmann
        (not force and cmd[:2] == [self.CMD, "shutdown"])):
555 664b392d Michael Hanselmann
      self.assertEqual(cmd[2:], [instance_name])
556 664b392d Michael Hanselmann
      output = ""
557 664b392d Michael Hanselmann
    else:
558 664b392d Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
559 664b392d Michael Hanselmann
560 664b392d Michael Hanselmann
    if fail:
561 664b392d Michael Hanselmann
      # Simulate a failing command
562 664b392d Michael Hanselmann
      return self._FailingCommand(cmd)
563 664b392d Michael Hanselmann
    else:
564 664b392d Michael Hanselmann
      return self._SuccessCommand(output, cmd)
565 664b392d Michael Hanselmann
566 664b392d Michael Hanselmann
  def testStopInstance(self):
567 664b392d Michael Hanselmann
    name = "inst4284.example.com"
568 664b392d Michael Hanselmann
    cfgfile = utils.PathJoin(self.tmpdir, name)
569 664b392d Michael Hanselmann
    cfgdata = "config file content\n"
570 664b392d Michael Hanselmann
571 664b392d Michael Hanselmann
    for force in [False, True]:
572 664b392d Michael Hanselmann
      for fail in [False, True]:
573 664b392d Michael Hanselmann
        utils.WriteFile(cfgfile, data=cfgdata)
574 664b392d Michael Hanselmann
575 664b392d Michael Hanselmann
        run_cmd = compat.partial(self._StopInstanceCommand, name, force, fail)
576 664b392d Michael Hanselmann
577 664b392d Michael Hanselmann
        hv = self._GetHv(run_cmd=run_cmd)
578 664b392d Michael Hanselmann
579 664b392d Michael Hanselmann
        self.assertTrue(os.path.isfile(cfgfile))
580 664b392d Michael Hanselmann
581 664b392d Michael Hanselmann
        if fail:
582 664b392d Michael Hanselmann
          try:
583 664b392d Michael Hanselmann
            hv._StopInstance(name, force)
584 664b392d Michael Hanselmann
          except errors.HypervisorError, err:
585 664b392d Michael Hanselmann
            self.assertTrue(str(err).startswith("Failed to stop instance"))
586 664b392d Michael Hanselmann
          else:
587 664b392d Michael Hanselmann
            self.fail("Exception was not raised")
588 664b392d Michael Hanselmann
          self.assertEqual(utils.ReadFile(cfgfile), cfgdata,
589 664b392d Michael Hanselmann
                           msg=("Configuration was removed when stopping"
590 664b392d Michael Hanselmann
                                " instance failed"))
591 664b392d Michael Hanselmann
        else:
592 664b392d Michael Hanselmann
          hv._StopInstance(name, force)
593 664b392d Michael Hanselmann
          self.assertFalse(os.path.exists(cfgfile))
594 664b392d Michael Hanselmann
595 d8784f7d Michael Hanselmann
  def _MigrateNonRunningInstCmd(self, cmd):
596 d8784f7d Michael Hanselmann
    if cmd == [self.CMD, "list"]:
597 d8784f7d Michael Hanselmann
      output = testutils.ReadTestData("xen-xm-list-4.0.1-dom0-only.txt")
598 d8784f7d Michael Hanselmann
    else:
599 d8784f7d Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
600 d8784f7d Michael Hanselmann
601 d8784f7d Michael Hanselmann
    return self._SuccessCommand(output, cmd)
602 d8784f7d Michael Hanselmann
603 d8784f7d Michael Hanselmann
  def testMigrateInstanceNotRunning(self):
604 d8784f7d Michael Hanselmann
    name = "nonexistinginstance.example.com"
605 d8784f7d Michael Hanselmann
    target = constants.IP4_ADDRESS_LOCALHOST
606 d8784f7d Michael Hanselmann
    port = 14618
607 d8784f7d Michael Hanselmann
608 d8784f7d Michael Hanselmann
    hv = self._GetHv(run_cmd=self._MigrateNonRunningInstCmd)
609 d8784f7d Michael Hanselmann
610 d8784f7d Michael Hanselmann
    for live in [False, True]:
611 d8784f7d Michael Hanselmann
      try:
612 d8784f7d Michael Hanselmann
        hv._MigrateInstance(NotImplemented, name, target, port, live,
613 d8784f7d Michael Hanselmann
                            _ping_fn=NotImplemented)
614 d8784f7d Michael Hanselmann
      except errors.HypervisorError, err:
615 d8784f7d Michael Hanselmann
        self.assertEqual(str(err), "Instance not running, cannot migrate")
616 d8784f7d Michael Hanselmann
      else:
617 d8784f7d Michael Hanselmann
        self.fail("Exception was not raised")
618 d8784f7d Michael Hanselmann
619 d8784f7d Michael Hanselmann
  def _MigrateInstTargetUnreachCmd(self, cmd):
620 d8784f7d Michael Hanselmann
    if cmd == [self.CMD, "list"]:
621 d8784f7d Michael Hanselmann
      output = testutils.ReadTestData("xen-xm-list-4.0.1-four-instances.txt")
622 d8784f7d Michael Hanselmann
    else:
623 d8784f7d Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
624 d8784f7d Michael Hanselmann
625 d8784f7d Michael Hanselmann
    return self._SuccessCommand(output, cmd)
626 d8784f7d Michael Hanselmann
627 d8784f7d Michael Hanselmann
  def testMigrateTargetUnreachable(self):
628 d8784f7d Michael Hanselmann
    name = "server01.example.com"
629 d8784f7d Michael Hanselmann
    target = constants.IP4_ADDRESS_LOCALHOST
630 d8784f7d Michael Hanselmann
    port = 28349
631 d8784f7d Michael Hanselmann
632 d8784f7d Michael Hanselmann
    hv = self._GetHv(run_cmd=self._MigrateInstTargetUnreachCmd)
633 d8784f7d Michael Hanselmann
634 d8784f7d Michael Hanselmann
    for live in [False, True]:
635 d8784f7d Michael Hanselmann
      if self.CMD == constants.XEN_CMD_XL:
636 d8784f7d Michael Hanselmann
        # TODO: Detect unreachable targets
637 d8784f7d Michael Hanselmann
        pass
638 d8784f7d Michael Hanselmann
      else:
639 d8784f7d Michael Hanselmann
        try:
640 d8784f7d Michael Hanselmann
          hv._MigrateInstance(NotImplemented, name, target, port, live,
641 d8784f7d Michael Hanselmann
                              _ping_fn=compat.partial(self._FakeTcpPing,
642 d8784f7d Michael Hanselmann
                                                      (target, port), False))
643 d8784f7d Michael Hanselmann
        except errors.HypervisorError, err:
644 d8784f7d Michael Hanselmann
          wanted = "Remote host %s not" % target
645 d8784f7d Michael Hanselmann
          self.assertTrue(str(err).startswith(wanted))
646 d8784f7d Michael Hanselmann
        else:
647 d8784f7d Michael Hanselmann
          self.fail("Exception was not raised")
648 d8784f7d Michael Hanselmann
649 d8784f7d Michael Hanselmann
  def _MigrateInstanceCmd(self, cluster_name, instance_name, target, port,
650 d8784f7d Michael Hanselmann
                          live, fail, cmd):
651 d8784f7d Michael Hanselmann
    if cmd == [self.CMD, "list"]:
652 d8784f7d Michael Hanselmann
      output = testutils.ReadTestData("xen-xm-list-4.0.1-four-instances.txt")
653 d8784f7d Michael Hanselmann
    elif cmd[:2] == [self.CMD, "migrate"]:
654 d8784f7d Michael Hanselmann
      if self.CMD == constants.XEN_CMD_XM:
655 d8784f7d Michael Hanselmann
        args = ["-p", str(port)]
656 d8784f7d Michael Hanselmann
657 d8784f7d Michael Hanselmann
        if live:
658 d8784f7d Michael Hanselmann
          args.append("-l")
659 d8784f7d Michael Hanselmann
660 d8784f7d Michael Hanselmann
      elif self.CMD == constants.XEN_CMD_XL:
661 d8784f7d Michael Hanselmann
        args = [
662 d8784f7d Michael Hanselmann
          "-s", constants.XL_SSH_CMD % cluster_name,
663 d8784f7d Michael Hanselmann
          "-C", utils.PathJoin(self.tmpdir, instance_name),
664 d8784f7d Michael Hanselmann
          ]
665 d8784f7d Michael Hanselmann
666 d8784f7d Michael Hanselmann
      else:
667 d8784f7d Michael Hanselmann
        self.fail("Unknown Xen command '%s'" % self.CMD)
668 d8784f7d Michael Hanselmann
669 d8784f7d Michael Hanselmann
      args.extend([instance_name, target])
670 d8784f7d Michael Hanselmann
      self.assertEqual(cmd[2:], args)
671 d8784f7d Michael Hanselmann
672 d8784f7d Michael Hanselmann
      if fail:
673 d8784f7d Michael Hanselmann
        return self._FailingCommand(cmd)
674 d8784f7d Michael Hanselmann
675 d8784f7d Michael Hanselmann
      output = ""
676 d8784f7d Michael Hanselmann
    else:
677 d8784f7d Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
678 d8784f7d Michael Hanselmann
679 d8784f7d Michael Hanselmann
    return self._SuccessCommand(output, cmd)
680 d8784f7d Michael Hanselmann
681 d8784f7d Michael Hanselmann
  def testMigrateInstance(self):
682 d8784f7d Michael Hanselmann
    clustername = "cluster.example.com"
683 d8784f7d Michael Hanselmann
    instname = "server01.example.com"
684 d8784f7d Michael Hanselmann
    target = constants.IP4_ADDRESS_LOCALHOST
685 d8784f7d Michael Hanselmann
    port = 22364
686 d8784f7d Michael Hanselmann
687 d8784f7d Michael Hanselmann
    for live in [False, True]:
688 d8784f7d Michael Hanselmann
      for fail in [False, True]:
689 d8784f7d Michael Hanselmann
        ping_fn = \
690 d8784f7d Michael Hanselmann
          testutils.CallCounter(compat.partial(self._FakeTcpPing,
691 d8784f7d Michael Hanselmann
                                               (target, port), True))
692 d8784f7d Michael Hanselmann
693 d8784f7d Michael Hanselmann
        run_cmd = \
694 d8784f7d Michael Hanselmann
          compat.partial(self._MigrateInstanceCmd,
695 d8784f7d Michael Hanselmann
                         clustername, instname, target, port, live,
696 d8784f7d Michael Hanselmann
                         fail)
697 d8784f7d Michael Hanselmann
698 d8784f7d Michael Hanselmann
        hv = self._GetHv(run_cmd=run_cmd)
699 d8784f7d Michael Hanselmann
700 d8784f7d Michael Hanselmann
        if fail:
701 d8784f7d Michael Hanselmann
          try:
702 d8784f7d Michael Hanselmann
            hv._MigrateInstance(clustername, instname, target, port, live,
703 d8784f7d Michael Hanselmann
                                _ping_fn=ping_fn)
704 d8784f7d Michael Hanselmann
          except errors.HypervisorError, err:
705 d8784f7d Michael Hanselmann
            self.assertTrue(str(err).startswith("Failed to migrate instance"))
706 d8784f7d Michael Hanselmann
          else:
707 d8784f7d Michael Hanselmann
            self.fail("Exception was not raised")
708 d8784f7d Michael Hanselmann
        else:
709 d8784f7d Michael Hanselmann
          hv._MigrateInstance(clustername, instname, target, port, live,
710 d8784f7d Michael Hanselmann
                              _ping_fn=ping_fn)
711 d8784f7d Michael Hanselmann
712 d8784f7d Michael Hanselmann
        if self.CMD == constants.XEN_CMD_XM:
713 d8784f7d Michael Hanselmann
          expected_pings = 1
714 d8784f7d Michael Hanselmann
        else:
715 d8784f7d Michael Hanselmann
          expected_pings = 0
716 d8784f7d Michael Hanselmann
717 d8784f7d Michael Hanselmann
        self.assertEqual(ping_fn.Count(), expected_pings)
718 d8784f7d Michael Hanselmann
719 1b9e1f42 Michael Hanselmann
  def _GetNodeInfoCmd(self, fail, cmd):
720 1b9e1f42 Michael Hanselmann
    if cmd == [self.CMD, "info"]:
721 1b9e1f42 Michael Hanselmann
      if fail:
722 1b9e1f42 Michael Hanselmann
        return self._FailingCommand(cmd)
723 1b9e1f42 Michael Hanselmann
      else:
724 1b9e1f42 Michael Hanselmann
        output = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
725 1b9e1f42 Michael Hanselmann
    elif cmd == [self.CMD, "list"]:
726 1b9e1f42 Michael Hanselmann
      if fail:
727 1b9e1f42 Michael Hanselmann
        self.fail("'xm list' shouldn't be called when 'xm info' failed")
728 1b9e1f42 Michael Hanselmann
      else:
729 1b9e1f42 Michael Hanselmann
        output = testutils.ReadTestData("xen-xm-list-4.0.1-four-instances.txt")
730 1b9e1f42 Michael Hanselmann
    else:
731 1b9e1f42 Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
732 1b9e1f42 Michael Hanselmann
733 1b9e1f42 Michael Hanselmann
    return self._SuccessCommand(output, cmd)
734 1b9e1f42 Michael Hanselmann
735 1b9e1f42 Michael Hanselmann
  def testGetNodeInfo(self):
736 1b9e1f42 Michael Hanselmann
    run_cmd = compat.partial(self._GetNodeInfoCmd, False)
737 1b9e1f42 Michael Hanselmann
    hv = self._GetHv(run_cmd=run_cmd)
738 1b9e1f42 Michael Hanselmann
    result = hv.GetNodeInfo()
739 1b9e1f42 Michael Hanselmann
740 1b9e1f42 Michael Hanselmann
    self.assertEqual(result["hv_version"], (4, 0))
741 1b9e1f42 Michael Hanselmann
    self.assertEqual(result["memory_free"], 8004)
742 1b9e1f42 Michael Hanselmann
743 1b9e1f42 Michael Hanselmann
  def testGetNodeInfoFailing(self):
744 1b9e1f42 Michael Hanselmann
    run_cmd = compat.partial(self._GetNodeInfoCmd, True)
745 1b9e1f42 Michael Hanselmann
    hv = self._GetHv(run_cmd=run_cmd)
746 1b9e1f42 Michael Hanselmann
    self.assertTrue(hv.GetNodeInfo() is None)
747 1b9e1f42 Michael Hanselmann
748 74a50c46 Michael Hanselmann
749 74a50c46 Michael Hanselmann
def _MakeTestClass(cls, cmd):
750 74a50c46 Michael Hanselmann
  """Makes a class for testing.
751 74a50c46 Michael Hanselmann

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

754 74a50c46 Michael Hanselmann
    class Test{cls.__name__}{cmd}(_TestXenHypervisor, unittest.TestCase):
755 74a50c46 Michael Hanselmann
      TARGET = {cls}
756 74a50c46 Michael Hanselmann
      CMD = {cmd}
757 74a50c46 Michael Hanselmann
      HVNAME = {Hypervisor name retrieved using class}
758 74a50c46 Michael Hanselmann

759 74a50c46 Michael Hanselmann
  @type cls: class
760 74a50c46 Michael Hanselmann
  @param cls: Hypervisor class to be tested
761 74a50c46 Michael Hanselmann
  @type cmd: string
762 74a50c46 Michael Hanselmann
  @param cmd: Hypervisor command
763 74a50c46 Michael Hanselmann
  @rtype: tuple
764 74a50c46 Michael Hanselmann
  @return: Class name and class object (not instance)
765 74a50c46 Michael Hanselmann

766 74a50c46 Michael Hanselmann
  """
767 74a50c46 Michael Hanselmann
  name = "Test%sCmd%s" % (cls.__name__, cmd.title())
768 74a50c46 Michael Hanselmann
  bases = (_TestXenHypervisor, unittest.TestCase)
769 74a50c46 Michael Hanselmann
  hvname = HVCLASS_TO_HVNAME[cls]
770 74a50c46 Michael Hanselmann
771 74a50c46 Michael Hanselmann
  return (name, type(name, bases, dict(TARGET=cls, CMD=cmd, HVNAME=hvname)))
772 74a50c46 Michael Hanselmann
773 74a50c46 Michael Hanselmann
774 74a50c46 Michael Hanselmann
# Create test classes programmatically instead of manually to reduce the risk
775 74a50c46 Michael Hanselmann
# of forgetting some combinations
776 74a50c46 Michael Hanselmann
for cls in [hv_xen.XenPvmHypervisor, hv_xen.XenHvmHypervisor]:
777 74a50c46 Michael Hanselmann
  for cmd in constants.KNOWN_XEN_COMMANDS:
778 74a50c46 Michael Hanselmann
    (name, testcls) = _MakeTestClass(cls, cmd)
779 74a50c46 Michael Hanselmann
780 74a50c46 Michael Hanselmann
    assert name not in locals()
781 74a50c46 Michael Hanselmann
782 74a50c46 Michael Hanselmann
    locals()[name] = testcls
783 74a50c46 Michael Hanselmann
784 74a50c46 Michael Hanselmann
785 55cc0a44 Michael Hanselmann
if __name__ == "__main__":
786 55cc0a44 Michael Hanselmann
  testutils.GanetiTestProgram()