Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.hypervisor.hv_xen_unittest.py @ 3fc1dc2f

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

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

763 74a50c46 Michael Hanselmann
    class Test{cls.__name__}{cmd}(_TestXenHypervisor, unittest.TestCase):
764 74a50c46 Michael Hanselmann
      TARGET = {cls}
765 74a50c46 Michael Hanselmann
      CMD = {cmd}
766 74a50c46 Michael Hanselmann
      HVNAME = {Hypervisor name retrieved using class}
767 74a50c46 Michael Hanselmann

768 74a50c46 Michael Hanselmann
  @type cls: class
769 74a50c46 Michael Hanselmann
  @param cls: Hypervisor class to be tested
770 74a50c46 Michael Hanselmann
  @type cmd: string
771 74a50c46 Michael Hanselmann
  @param cmd: Hypervisor command
772 74a50c46 Michael Hanselmann
  @rtype: tuple
773 74a50c46 Michael Hanselmann
  @return: Class name and class object (not instance)
774 74a50c46 Michael Hanselmann

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