Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.hypervisor.hv_xen_unittest.py @ 2edc1c79

History | View | Annotate | Download (19 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 57270b2d Michael Hanselmann
  def testReadingNonExistentConfigFile(self):
370 57270b2d Michael Hanselmann
    hv = self._GetHv()
371 57270b2d Michael Hanselmann
372 57270b2d Michael Hanselmann
    try:
373 57270b2d Michael Hanselmann
      hv._ReadConfigFile("inst15780.example.com")
374 57270b2d Michael Hanselmann
    except errors.HypervisorError, err:
375 57270b2d Michael Hanselmann
      self.assertTrue(str(err).startswith("Failed to load Xen config file:"))
376 57270b2d Michael Hanselmann
    else:
377 57270b2d Michael Hanselmann
      self.fail("Exception was not raised")
378 57270b2d Michael Hanselmann
379 7610d884 Michael Hanselmann
  def testRemovingAutoConfigFile(self):
380 7610d884 Michael Hanselmann
    name = "inst8206.example.com"
381 7610d884 Michael Hanselmann
    cfgfile = utils.PathJoin(self.tmpdir, name)
382 7610d884 Michael Hanselmann
    autodir = utils.PathJoin(self.tmpdir, "auto")
383 7610d884 Michael Hanselmann
    autocfgfile = utils.PathJoin(autodir, name)
384 7610d884 Michael Hanselmann
385 7610d884 Michael Hanselmann
    os.mkdir(autodir)
386 7610d884 Michael Hanselmann
387 7610d884 Michael Hanselmann
    utils.WriteFile(autocfgfile, data="")
388 7610d884 Michael Hanselmann
389 7610d884 Michael Hanselmann
    hv = self._GetHv()
390 7610d884 Michael Hanselmann
391 7610d884 Michael Hanselmann
    self.assertTrue(os.path.isfile(autocfgfile))
392 7610d884 Michael Hanselmann
    hv._WriteConfigFile(name, "content")
393 7610d884 Michael Hanselmann
    self.assertFalse(os.path.exists(autocfgfile))
394 7610d884 Michael Hanselmann
    self.assertEqual(utils.ReadFile(cfgfile), "content")
395 7610d884 Michael Hanselmann
396 2edc1c79 Michael Hanselmann
  def _XenList(self, cmd):
397 2edc1c79 Michael Hanselmann
    self.assertEqual(cmd, [self.CMD, "list"])
398 2edc1c79 Michael Hanselmann
399 2edc1c79 Michael Hanselmann
    # TODO: Use actual data from "xl" command
400 2edc1c79 Michael Hanselmann
    output = testutils.ReadTestData("xen-xm-list-4.0.1-four-instances.txt")
401 2edc1c79 Michael Hanselmann
402 2edc1c79 Michael Hanselmann
    return self._SuccessCommand(output, cmd)
403 2edc1c79 Michael Hanselmann
404 2edc1c79 Michael Hanselmann
  def testGetInstanceInfo(self):
405 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
406 2edc1c79 Michael Hanselmann
407 2edc1c79 Michael Hanselmann
    (name, instid, memory, vcpus, state, runtime) = \
408 2edc1c79 Michael Hanselmann
      hv.GetInstanceInfo("server01.example.com")
409 2edc1c79 Michael Hanselmann
410 2edc1c79 Michael Hanselmann
    self.assertEqual(name, "server01.example.com")
411 2edc1c79 Michael Hanselmann
    self.assertEqual(instid, 1)
412 2edc1c79 Michael Hanselmann
    self.assertEqual(memory, 1024)
413 2edc1c79 Michael Hanselmann
    self.assertEqual(vcpus, 1)
414 2edc1c79 Michael Hanselmann
    self.assertEqual(state, "-b----")
415 2edc1c79 Michael Hanselmann
    self.assertAlmostEqual(runtime, 167643.2)
416 2edc1c79 Michael Hanselmann
417 2edc1c79 Michael Hanselmann
  def testGetInstanceInfoDom0(self):
418 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
419 2edc1c79 Michael Hanselmann
420 2edc1c79 Michael Hanselmann
    # TODO: Not sure if this is actually used anywhere (can't find it), but the
421 2edc1c79 Michael Hanselmann
    # code supports querying for Dom0
422 2edc1c79 Michael Hanselmann
    (name, instid, memory, vcpus, state, runtime) = \
423 2edc1c79 Michael Hanselmann
      hv.GetInstanceInfo(hv_xen._DOM0_NAME)
424 2edc1c79 Michael Hanselmann
425 2edc1c79 Michael Hanselmann
    self.assertEqual(name, "Domain-0")
426 2edc1c79 Michael Hanselmann
    self.assertEqual(instid, 0)
427 2edc1c79 Michael Hanselmann
    self.assertEqual(memory, 1023)
428 2edc1c79 Michael Hanselmann
    self.assertEqual(vcpus, 1)
429 2edc1c79 Michael Hanselmann
    self.assertEqual(state, "r-----")
430 2edc1c79 Michael Hanselmann
    self.assertAlmostEqual(runtime, 154706.1)
431 2edc1c79 Michael Hanselmann
432 2edc1c79 Michael Hanselmann
  def testGetInstanceInfoUnknown(self):
433 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
434 2edc1c79 Michael Hanselmann
435 2edc1c79 Michael Hanselmann
    result = hv.GetInstanceInfo("unknown.example.com")
436 2edc1c79 Michael Hanselmann
    self.assertTrue(result is None)
437 2edc1c79 Michael Hanselmann
438 2edc1c79 Michael Hanselmann
  def testGetAllInstancesInfo(self):
439 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
440 2edc1c79 Michael Hanselmann
441 2edc1c79 Michael Hanselmann
    result = hv.GetAllInstancesInfo()
442 2edc1c79 Michael Hanselmann
443 2edc1c79 Michael Hanselmann
    self.assertEqual(map(compat.fst, result), [
444 2edc1c79 Michael Hanselmann
      "server01.example.com",
445 2edc1c79 Michael Hanselmann
      "web3106215069.example.com",
446 2edc1c79 Michael Hanselmann
      "testinstance.example.com",
447 2edc1c79 Michael Hanselmann
      ])
448 2edc1c79 Michael Hanselmann
449 2edc1c79 Michael Hanselmann
  def testListInstances(self):
450 2edc1c79 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._XenList)
451 2edc1c79 Michael Hanselmann
452 2edc1c79 Michael Hanselmann
    self.assertEqual(hv.ListInstances(), [
453 2edc1c79 Michael Hanselmann
      "server01.example.com",
454 2edc1c79 Michael Hanselmann
      "web3106215069.example.com",
455 2edc1c79 Michael Hanselmann
      "testinstance.example.com",
456 2edc1c79 Michael Hanselmann
      ])
457 2edc1c79 Michael Hanselmann
458 b666f213 Michael Hanselmann
  def testVerify(self):
459 b666f213 Michael Hanselmann
    output = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
460 b666f213 Michael Hanselmann
    hv = self._GetHv(run_cmd=compat.partial(self._SuccessCommand,
461 b666f213 Michael Hanselmann
                                            output))
462 b666f213 Michael Hanselmann
    self.assertTrue(hv.Verify() is None)
463 b666f213 Michael Hanselmann
464 b666f213 Michael Hanselmann
  def testVerifyFailing(self):
465 b666f213 Michael Hanselmann
    hv = self._GetHv(run_cmd=self._FailingCommand)
466 b666f213 Michael Hanselmann
    self.assertTrue("failed:" in hv.Verify())
467 b666f213 Michael Hanselmann
468 396672cd Michael Hanselmann
  def _StartInstanceCommand(self, inst, paused, failcreate, cmd):
469 396672cd Michael Hanselmann
    if cmd == [self.CMD, "info"]:
470 396672cd Michael Hanselmann
      output = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
471 396672cd Michael Hanselmann
    elif cmd == [self.CMD, "list"]:
472 396672cd Michael Hanselmann
      output = testutils.ReadTestData("xen-xm-list-4.0.1-dom0-only.txt")
473 396672cd Michael Hanselmann
    elif cmd[:2] == [self.CMD, "create"]:
474 396672cd Michael Hanselmann
      args = cmd[2:]
475 396672cd Michael Hanselmann
      cfgfile = utils.PathJoin(self.tmpdir, inst.name)
476 396672cd Michael Hanselmann
477 396672cd Michael Hanselmann
      if paused:
478 396672cd Michael Hanselmann
        self.assertEqual(args, ["-p", cfgfile])
479 396672cd Michael Hanselmann
      else:
480 396672cd Michael Hanselmann
        self.assertEqual(args, [cfgfile])
481 396672cd Michael Hanselmann
482 396672cd Michael Hanselmann
      if failcreate:
483 396672cd Michael Hanselmann
        return self._FailingCommand(cmd)
484 396672cd Michael Hanselmann
485 396672cd Michael Hanselmann
      output = ""
486 396672cd Michael Hanselmann
    else:
487 396672cd Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
488 396672cd Michael Hanselmann
489 396672cd Michael Hanselmann
    return self._SuccessCommand(output, cmd)
490 396672cd Michael Hanselmann
    #return self._FailingCommand(cmd)
491 396672cd Michael Hanselmann
492 396672cd Michael Hanselmann
  def _MakeInstance(self):
493 396672cd Michael Hanselmann
    # Copy default parameters
494 396672cd Michael Hanselmann
    bep = objects.FillDict(constants.BEC_DEFAULTS, {})
495 396672cd Michael Hanselmann
    hvp = objects.FillDict(constants.HVC_DEFAULTS[self.HVNAME], {})
496 396672cd Michael Hanselmann
497 396672cd Michael Hanselmann
    # Override default VNC password file path
498 396672cd Michael Hanselmann
    if constants.HV_VNC_PASSWORD_FILE in hvp:
499 396672cd Michael Hanselmann
      hvp[constants.HV_VNC_PASSWORD_FILE] = self.vncpw_path
500 396672cd Michael Hanselmann
501 396672cd Michael Hanselmann
    disks = [
502 396672cd Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_LV, mode=constants.DISK_RDWR),
503 396672cd Michael Hanselmann
       utils.PathJoin(self.tmpdir, "disk0")),
504 396672cd Michael Hanselmann
      (objects.Disk(dev_type=constants.LD_LV, mode=constants.DISK_RDONLY),
505 396672cd Michael Hanselmann
       utils.PathJoin(self.tmpdir, "disk1")),
506 396672cd Michael Hanselmann
      ]
507 396672cd Michael Hanselmann
508 396672cd Michael Hanselmann
    inst = objects.Instance(name="server01.example.com",
509 396672cd Michael Hanselmann
                            hvparams=hvp, beparams=bep,
510 396672cd Michael Hanselmann
                            osparams={}, nics=[], os="deb1",
511 396672cd Michael Hanselmann
                            disks=map(compat.fst, disks))
512 396672cd Michael Hanselmann
    inst.UpgradeConfig()
513 396672cd Michael Hanselmann
514 396672cd Michael Hanselmann
    return (inst, disks)
515 396672cd Michael Hanselmann
516 396672cd Michael Hanselmann
  def testStartInstance(self):
517 396672cd Michael Hanselmann
    (inst, disks) = self._MakeInstance()
518 396672cd Michael Hanselmann
519 396672cd Michael Hanselmann
    for failcreate in [False, True]:
520 396672cd Michael Hanselmann
      for paused in [False, True]:
521 396672cd Michael Hanselmann
        run_cmd = compat.partial(self._StartInstanceCommand,
522 396672cd Michael Hanselmann
                                 inst, paused, failcreate)
523 396672cd Michael Hanselmann
524 396672cd Michael Hanselmann
        hv = self._GetHv(run_cmd=run_cmd)
525 396672cd Michael Hanselmann
526 396672cd Michael Hanselmann
        # Ensure instance is not listed
527 396672cd Michael Hanselmann
        self.assertTrue(inst.name not in hv.ListInstances())
528 396672cd Michael Hanselmann
529 396672cd Michael Hanselmann
        # Remove configuration
530 396672cd Michael Hanselmann
        cfgfile = utils.PathJoin(self.tmpdir, inst.name)
531 396672cd Michael Hanselmann
        utils.RemoveFile(cfgfile)
532 396672cd Michael Hanselmann
533 396672cd Michael Hanselmann
        if failcreate:
534 396672cd Michael Hanselmann
          self.assertRaises(errors.HypervisorError, hv.StartInstance,
535 396672cd Michael Hanselmann
                            inst, disks, paused)
536 396672cd Michael Hanselmann
        else:
537 396672cd Michael Hanselmann
          hv.StartInstance(inst, disks, paused)
538 396672cd Michael Hanselmann
539 396672cd Michael Hanselmann
        # Check if configuration was updated
540 396672cd Michael Hanselmann
        lines = utils.ReadFile(cfgfile).splitlines()
541 396672cd Michael Hanselmann
542 396672cd Michael Hanselmann
        if constants.HV_VNC_PASSWORD_FILE in inst.hvparams:
543 396672cd Michael Hanselmann
          self.assertTrue(("vncpasswd = '%s'" % self.vncpw) in lines)
544 396672cd Michael Hanselmann
        else:
545 396672cd Michael Hanselmann
          extra = inst.hvparams[constants.HV_KERNEL_ARGS]
546 396672cd Michael Hanselmann
          self.assertTrue(("extra = '%s'" % extra) in lines)
547 396672cd Michael Hanselmann
548 664b392d Michael Hanselmann
  def _StopInstanceCommand(self, instance_name, force, fail, cmd):
549 664b392d Michael Hanselmann
    if ((force and cmd[:2] == [self.CMD, "destroy"]) or
550 664b392d Michael Hanselmann
        (not force and cmd[:2] == [self.CMD, "shutdown"])):
551 664b392d Michael Hanselmann
      self.assertEqual(cmd[2:], [instance_name])
552 664b392d Michael Hanselmann
      output = ""
553 664b392d Michael Hanselmann
    else:
554 664b392d Michael Hanselmann
      self.fail("Unhandled command: %s" % (cmd, ))
555 664b392d Michael Hanselmann
556 664b392d Michael Hanselmann
    if fail:
557 664b392d Michael Hanselmann
      # Simulate a failing command
558 664b392d Michael Hanselmann
      return self._FailingCommand(cmd)
559 664b392d Michael Hanselmann
    else:
560 664b392d Michael Hanselmann
      return self._SuccessCommand(output, cmd)
561 664b392d Michael Hanselmann
562 664b392d Michael Hanselmann
  def testStopInstance(self):
563 664b392d Michael Hanselmann
    name = "inst4284.example.com"
564 664b392d Michael Hanselmann
    cfgfile = utils.PathJoin(self.tmpdir, name)
565 664b392d Michael Hanselmann
    cfgdata = "config file content\n"
566 664b392d Michael Hanselmann
567 664b392d Michael Hanselmann
    for force in [False, True]:
568 664b392d Michael Hanselmann
      for fail in [False, True]:
569 664b392d Michael Hanselmann
        utils.WriteFile(cfgfile, data=cfgdata)
570 664b392d Michael Hanselmann
571 664b392d Michael Hanselmann
        run_cmd = compat.partial(self._StopInstanceCommand, name, force, fail)
572 664b392d Michael Hanselmann
573 664b392d Michael Hanselmann
        hv = self._GetHv(run_cmd=run_cmd)
574 664b392d Michael Hanselmann
575 664b392d Michael Hanselmann
        self.assertTrue(os.path.isfile(cfgfile))
576 664b392d Michael Hanselmann
577 664b392d Michael Hanselmann
        if fail:
578 664b392d Michael Hanselmann
          try:
579 664b392d Michael Hanselmann
            hv._StopInstance(name, force)
580 664b392d Michael Hanselmann
          except errors.HypervisorError, err:
581 664b392d Michael Hanselmann
            self.assertTrue(str(err).startswith("Failed to stop instance"))
582 664b392d Michael Hanselmann
          else:
583 664b392d Michael Hanselmann
            self.fail("Exception was not raised")
584 664b392d Michael Hanselmann
          self.assertEqual(utils.ReadFile(cfgfile), cfgdata,
585 664b392d Michael Hanselmann
                           msg=("Configuration was removed when stopping"
586 664b392d Michael Hanselmann
                                " instance failed"))
587 664b392d Michael Hanselmann
        else:
588 664b392d Michael Hanselmann
          hv._StopInstance(name, force)
589 664b392d Michael Hanselmann
          self.assertFalse(os.path.exists(cfgfile))
590 664b392d Michael Hanselmann
591 74a50c46 Michael Hanselmann
592 74a50c46 Michael Hanselmann
def _MakeTestClass(cls, cmd):
593 74a50c46 Michael Hanselmann
  """Makes a class for testing.
594 74a50c46 Michael Hanselmann

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

597 74a50c46 Michael Hanselmann
    class Test{cls.__name__}{cmd}(_TestXenHypervisor, unittest.TestCase):
598 74a50c46 Michael Hanselmann
      TARGET = {cls}
599 74a50c46 Michael Hanselmann
      CMD = {cmd}
600 74a50c46 Michael Hanselmann
      HVNAME = {Hypervisor name retrieved using class}
601 74a50c46 Michael Hanselmann

602 74a50c46 Michael Hanselmann
  @type cls: class
603 74a50c46 Michael Hanselmann
  @param cls: Hypervisor class to be tested
604 74a50c46 Michael Hanselmann
  @type cmd: string
605 74a50c46 Michael Hanselmann
  @param cmd: Hypervisor command
606 74a50c46 Michael Hanselmann
  @rtype: tuple
607 74a50c46 Michael Hanselmann
  @return: Class name and class object (not instance)
608 74a50c46 Michael Hanselmann

609 74a50c46 Michael Hanselmann
  """
610 74a50c46 Michael Hanselmann
  name = "Test%sCmd%s" % (cls.__name__, cmd.title())
611 74a50c46 Michael Hanselmann
  bases = (_TestXenHypervisor, unittest.TestCase)
612 74a50c46 Michael Hanselmann
  hvname = HVCLASS_TO_HVNAME[cls]
613 74a50c46 Michael Hanselmann
614 74a50c46 Michael Hanselmann
  return (name, type(name, bases, dict(TARGET=cls, CMD=cmd, HVNAME=hvname)))
615 74a50c46 Michael Hanselmann
616 74a50c46 Michael Hanselmann
617 74a50c46 Michael Hanselmann
# Create test classes programmatically instead of manually to reduce the risk
618 74a50c46 Michael Hanselmann
# of forgetting some combinations
619 74a50c46 Michael Hanselmann
for cls in [hv_xen.XenPvmHypervisor, hv_xen.XenHvmHypervisor]:
620 74a50c46 Michael Hanselmann
  for cmd in constants.KNOWN_XEN_COMMANDS:
621 74a50c46 Michael Hanselmann
    (name, testcls) = _MakeTestClass(cls, cmd)
622 74a50c46 Michael Hanselmann
623 74a50c46 Michael Hanselmann
    assert name not in locals()
624 74a50c46 Michael Hanselmann
625 74a50c46 Michael Hanselmann
    locals()[name] = testcls
626 74a50c46 Michael Hanselmann
627 74a50c46 Michael Hanselmann
628 55cc0a44 Michael Hanselmann
if __name__ == "__main__":
629 55cc0a44 Michael Hanselmann
  testutils.GanetiTestProgram()