hv_xen: Refactor getting node information, add tests
[ganeti-github.git] / test / py / ganeti.hypervisor.hv_xen_unittest.py
1 #!/usr/bin/python
2 #
3
4 # Copyright (C) 2011, 2013 Google Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21
22 """Script for testing ganeti.hypervisor.hv_lxc"""
23
24 import unittest
25
26 from ganeti import constants
27 from ganeti import objects
28 from ganeti import hypervisor
29 from ganeti import utils
30 from ganeti import errors
31 from ganeti import compat
32
33 from ganeti.hypervisor import hv_xen
34
35 import testutils
36
37
38 class TestConsole(unittest.TestCase):
39 def test(self):
40 for cls in [hv_xen.XenPvmHypervisor, hv_xen.XenHvmHypervisor]:
41 instance = objects.Instance(name="xen.example.com",
42 primary_node="node24828")
43 cons = cls.GetInstanceConsole(instance, {}, {})
44 self.assertTrue(cons.Validate())
45 self.assertEqual(cons.kind, constants.CONS_SSH)
46 self.assertEqual(cons.host, instance.primary_node)
47 self.assertEqual(cons.command[-1], instance.name)
48
49
50 class TestCreateConfigCpus(unittest.TestCase):
51 def testEmpty(self):
52 for cpu_mask in [None, ""]:
53 self.assertEqual(hv_xen._CreateConfigCpus(cpu_mask),
54 "cpus = [ ]")
55
56 def testAll(self):
57 self.assertEqual(hv_xen._CreateConfigCpus(constants.CPU_PINNING_ALL),
58 None)
59
60 def testOne(self):
61 self.assertEqual(hv_xen._CreateConfigCpus("9"), "cpu = \"9\"")
62
63 def testMultiple(self):
64 self.assertEqual(hv_xen._CreateConfigCpus("0-2,4,5-5:3:all"),
65 ("cpus = [ \"0,1,2,4,5\", \"3\", \"%s\" ]" %
66 constants.CPU_PINNING_ALL_XEN))
67
68
69 class TestParseXmList(testutils.GanetiTestCase):
70 def test(self):
71 data = testutils.ReadTestData("xen-xm-list-4.0.1-dom0-only.txt")
72
73 # Exclude node
74 self.assertEqual(hv_xen._ParseXmList(data.splitlines(), False), [])
75
76 # Include node
77 result = hv_xen._ParseXmList(data.splitlines(), True)
78 self.assertEqual(len(result), 1)
79 self.assertEqual(len(result[0]), 6)
80
81 # Name
82 self.assertEqual(result[0][0], hv_xen._DOM0_NAME)
83
84 # ID
85 self.assertEqual(result[0][1], 0)
86
87 # Memory
88 self.assertEqual(result[0][2], 1023)
89
90 # VCPUs
91 self.assertEqual(result[0][3], 1)
92
93 # State
94 self.assertEqual(result[0][4], "r-----")
95
96 # Time
97 self.assertAlmostEqual(result[0][5], 121152.6)
98
99 def testWrongLineFormat(self):
100 tests = [
101 ["three fields only"],
102 ["name InvalidID 128 1 r----- 12345"],
103 ]
104
105 for lines in tests:
106 try:
107 hv_xen._ParseXmList(["Header would be here"] + lines, False)
108 except errors.HypervisorError, err:
109 self.assertTrue("Can't parse output of xm list" in str(err))
110 else:
111 self.fail("Exception was not raised")
112
113
114 class TestGetXmList(testutils.GanetiTestCase):
115 def _Fail(self):
116 return utils.RunResult(constants.EXIT_FAILURE, None,
117 "stdout", "stderr", None,
118 NotImplemented, NotImplemented)
119
120 def testTimeout(self):
121 fn = testutils.CallCounter(self._Fail)
122 try:
123 hv_xen._GetXmList(fn, False, _timeout=0.1)
124 except errors.HypervisorError, err:
125 self.assertTrue("timeout exceeded" in str(err))
126 else:
127 self.fail("Exception was not raised")
128
129 self.assertTrue(fn.Count() < 10,
130 msg="'xm list' was called too many times")
131
132 def _Success(self, stdout):
133 return utils.RunResult(constants.EXIT_SUCCESS, None, stdout, "", None,
134 NotImplemented, NotImplemented)
135
136 def testSuccess(self):
137 data = testutils.ReadTestData("xen-xm-list-4.0.1-four-instances.txt")
138
139 fn = testutils.CallCounter(compat.partial(self._Success, data))
140
141 result = hv_xen._GetXmList(fn, True, _timeout=0.1)
142
143 self.assertEqual(len(result), 4)
144
145 self.assertEqual(map(compat.fst, result), [
146 "Domain-0",
147 "server01.example.com",
148 "web3106215069.example.com",
149 "testinstance.example.com",
150 ])
151
152 self.assertEqual(fn.Count(), 1)
153
154
155 class TestParseNodeInfo(testutils.GanetiTestCase):
156 def testEmpty(self):
157 self.assertEqual(hv_xen._ParseNodeInfo(""), {})
158
159 def testUnknownInput(self):
160 data = "\n".join([
161 "foo bar",
162 "something else goes",
163 "here",
164 ])
165 self.assertEqual(hv_xen._ParseNodeInfo(data), {})
166
167 def testBasicInfo(self):
168 data = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
169 result = hv_xen._ParseNodeInfo(data)
170 self.assertEqual(result, {
171 "cpu_nodes": 1,
172 "cpu_sockets": 2,
173 "cpu_total": 4,
174 "hv_version": (4, 0),
175 "memory_free": 8004,
176 "memory_total": 16378,
177 })
178
179
180 class TestMergeInstanceInfo(testutils.GanetiTestCase):
181 def testEmpty(self):
182 self.assertEqual(hv_xen._MergeInstanceInfo({}, lambda _: []), {})
183
184 def _FakeXmList(self, include_node):
185 self.assertTrue(include_node)
186 return [
187 (hv_xen._DOM0_NAME, NotImplemented, 4096, 7, NotImplemented,
188 NotImplemented),
189 ("inst1.example.com", NotImplemented, 2048, 4, NotImplemented,
190 NotImplemented),
191 ]
192
193 def testMissingNodeInfo(self):
194 result = hv_xen._MergeInstanceInfo({}, self._FakeXmList)
195 self.assertEqual(result, {
196 "memory_dom0": 4096,
197 "dom0_cpus": 7,
198 })
199
200 def testWithNodeInfo(self):
201 info = testutils.ReadTestData("xen-xm-info-4.0.1.txt")
202 result = hv_xen._GetNodeInfo(info, self._FakeXmList)
203 self.assertEqual(result, {
204 "cpu_nodes": 1,
205 "cpu_sockets": 2,
206 "cpu_total": 4,
207 "dom0_cpus": 7,
208 "hv_version": (4, 0),
209 "memory_dom0": 4096,
210 "memory_free": 8004,
211 "memory_hv": 2230,
212 "memory_total": 16378,
213 })
214
215
216 if __name__ == "__main__":
217 testutils.GanetiTestProgram()