root / test / py / ganeti.hypervisor.hv_kvm_unittest.py @ 398fd4f6
History | View | Annotate | Download (11.8 kB)
1 | 748e4b5a | Michael Hanselmann | #!/usr/bin/python
|
---|---|---|---|
2 | 748e4b5a | Michael Hanselmann | #
|
3 | 748e4b5a | Michael Hanselmann | |
4 | 55cc0a44 | Michael Hanselmann | # Copyright (C) 2010, 2011 Google Inc.
|
5 | 748e4b5a | Michael Hanselmann | #
|
6 | 748e4b5a | Michael Hanselmann | # This program is free software; you can redistribute it and/or modify
|
7 | 748e4b5a | Michael Hanselmann | # it under the terms of the GNU General Public License as published by
|
8 | 748e4b5a | Michael Hanselmann | # the Free Software Foundation; either version 2 of the License, or
|
9 | 748e4b5a | Michael Hanselmann | # (at your option) any later version.
|
10 | 748e4b5a | Michael Hanselmann | #
|
11 | 748e4b5a | Michael Hanselmann | # This program is distributed in the hope that it will be useful, but
|
12 | 748e4b5a | Michael Hanselmann | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 748e4b5a | Michael Hanselmann | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 748e4b5a | Michael Hanselmann | # General Public License for more details.
|
15 | 748e4b5a | Michael Hanselmann | #
|
16 | 748e4b5a | Michael Hanselmann | # You should have received a copy of the GNU General Public License
|
17 | 748e4b5a | Michael Hanselmann | # along with this program; if not, write to the Free Software
|
18 | 748e4b5a | Michael Hanselmann | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | 748e4b5a | Michael Hanselmann | # 02110-1301, USA.
|
20 | 748e4b5a | Michael Hanselmann | |
21 | 748e4b5a | Michael Hanselmann | |
22 | 748e4b5a | Michael Hanselmann | """Script for testing the hypervisor.hv_kvm module"""
|
23 | 748e4b5a | Michael Hanselmann | |
24 | 91c10532 | Andrea Spadaccini | import threading |
25 | 91c10532 | Andrea Spadaccini | import tempfile |
26 | 748e4b5a | Michael Hanselmann | import unittest |
27 | 91c10532 | Andrea Spadaccini | import socket |
28 | 91c10532 | Andrea Spadaccini | import os |
29 | ea2bcb82 | Michael Hanselmann | import struct |
30 | 748e4b5a | Michael Hanselmann | |
31 | 91c10532 | Andrea Spadaccini | from ganeti import serializer |
32 | 748e4b5a | Michael Hanselmann | from ganeti import constants |
33 | 748e4b5a | Michael Hanselmann | from ganeti import compat |
34 | 748e4b5a | Michael Hanselmann | from ganeti import objects |
35 | 748e4b5a | Michael Hanselmann | from ganeti import errors |
36 | 585c8187 | Guido Trotter | from ganeti import utils |
37 | a56625a2 | Michael Hanselmann | from ganeti import pathutils |
38 | 748e4b5a | Michael Hanselmann | |
39 | 748e4b5a | Michael Hanselmann | from ganeti.hypervisor import hv_kvm |
40 | 748e4b5a | Michael Hanselmann | |
41 | 748e4b5a | Michael Hanselmann | import testutils |
42 | 748e4b5a | Michael Hanselmann | |
43 | 748e4b5a | Michael Hanselmann | |
44 | 91c10532 | Andrea Spadaccini | class QmpStub(threading.Thread): |
45 | 91c10532 | Andrea Spadaccini | """Stub for a QMP endpoint for a KVM instance
|
46 | 91c10532 | Andrea Spadaccini |
|
47 | 91c10532 | Andrea Spadaccini | """
|
48 | 51129a7f | Michael Hanselmann | _QMP_BANNER_DATA = { |
49 | 51129a7f | Michael Hanselmann | "QMP": {
|
50 | 51129a7f | Michael Hanselmann | "version": {
|
51 | 51129a7f | Michael Hanselmann | "package": "", |
52 | 51129a7f | Michael Hanselmann | "qemu": {
|
53 | 51129a7f | Michael Hanselmann | "micro": 50, |
54 | 51129a7f | Michael Hanselmann | "minor": 13, |
55 | 51129a7f | Michael Hanselmann | "major": 0, |
56 | 51129a7f | Michael Hanselmann | }, |
57 | 51129a7f | Michael Hanselmann | "capabilities": [],
|
58 | 51129a7f | Michael Hanselmann | }, |
59 | 51129a7f | Michael Hanselmann | } |
60 | 51129a7f | Michael Hanselmann | } |
61 | 51129a7f | Michael Hanselmann | _EMPTY_RESPONSE = { |
62 | 51129a7f | Michael Hanselmann | "return": [],
|
63 | 51129a7f | Michael Hanselmann | } |
64 | 91c10532 | Andrea Spadaccini | |
65 | 91c10532 | Andrea Spadaccini | def __init__(self, socket_filename, server_responses): |
66 | 91c10532 | Andrea Spadaccini | """Creates a QMP stub
|
67 | 91c10532 | Andrea Spadaccini |
|
68 | 91c10532 | Andrea Spadaccini | @type socket_filename: string
|
69 | 91c10532 | Andrea Spadaccini | @param socket_filename: filename of the UNIX socket that will be created
|
70 | 91c10532 | Andrea Spadaccini | this class and used for the communication
|
71 | 91c10532 | Andrea Spadaccini | @type server_responses: list
|
72 | 91c10532 | Andrea Spadaccini | @param server_responses: list of responses that the server sends in response
|
73 | 91c10532 | Andrea Spadaccini | to whatever it receives
|
74 | 91c10532 | Andrea Spadaccini | """
|
75 | 91c10532 | Andrea Spadaccini | threading.Thread.__init__(self)
|
76 | 91c10532 | Andrea Spadaccini | self.socket_filename = socket_filename
|
77 | 91c10532 | Andrea Spadaccini | self.script = server_responses
|
78 | 91c10532 | Andrea Spadaccini | |
79 | 91c10532 | Andrea Spadaccini | self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
80 | 91c10532 | Andrea Spadaccini | self.socket.bind(self.socket_filename) |
81 | 91c10532 | Andrea Spadaccini | self.socket.listen(1) |
82 | 91c10532 | Andrea Spadaccini | |
83 | 91c10532 | Andrea Spadaccini | def run(self): |
84 | 91c10532 | Andrea Spadaccini | # Hypothesis: the messages we receive contain only a complete QMP message
|
85 | 91c10532 | Andrea Spadaccini | # encoded in JSON.
|
86 | 91c10532 | Andrea Spadaccini | conn, addr = self.socket.accept()
|
87 | 91c10532 | Andrea Spadaccini | |
88 | 91c10532 | Andrea Spadaccini | # Send the banner as the first thing
|
89 | 91c10532 | Andrea Spadaccini | conn.send(self.encode_string(self._QMP_BANNER_DATA)) |
90 | 91c10532 | Andrea Spadaccini | |
91 | 91c10532 | Andrea Spadaccini | # Expect qmp_capabilities and return an empty response
|
92 | 91c10532 | Andrea Spadaccini | conn.recv(4096)
|
93 | 91c10532 | Andrea Spadaccini | conn.send(self.encode_string(self._EMPTY_RESPONSE)) |
94 | 91c10532 | Andrea Spadaccini | |
95 | 91c10532 | Andrea Spadaccini | while True: |
96 | 91c10532 | Andrea Spadaccini | # We ignore the expected message, as the purpose of this object is not
|
97 | 91c10532 | Andrea Spadaccini | # to verify the correctness of the communication but to act as a
|
98 | 91c10532 | Andrea Spadaccini | # partner for the SUT (System Under Test, that is QmpConnection)
|
99 | 91c10532 | Andrea Spadaccini | msg = conn.recv(4096)
|
100 | 91c10532 | Andrea Spadaccini | if not msg: |
101 | 91c10532 | Andrea Spadaccini | break
|
102 | 91c10532 | Andrea Spadaccini | |
103 | 91c10532 | Andrea Spadaccini | if not self.script: |
104 | 91c10532 | Andrea Spadaccini | break
|
105 | 91c10532 | Andrea Spadaccini | response = self.script.pop(0) |
106 | 91c10532 | Andrea Spadaccini | if isinstance(response, str): |
107 | 91c10532 | Andrea Spadaccini | conn.send(response) |
108 | 91c10532 | Andrea Spadaccini | elif isinstance(response, list): |
109 | 91c10532 | Andrea Spadaccini | for chunk in response: |
110 | 91c10532 | Andrea Spadaccini | conn.send(chunk) |
111 | 91c10532 | Andrea Spadaccini | else:
|
112 | 91c10532 | Andrea Spadaccini | raise errors.ProgrammerError("Unknown response type for %s" % response) |
113 | 91c10532 | Andrea Spadaccini | |
114 | 91c10532 | Andrea Spadaccini | conn.close() |
115 | 91c10532 | Andrea Spadaccini | |
116 | 91c10532 | Andrea Spadaccini | def encode_string(self, message): |
117 | a182a3ed | Michael Hanselmann | return (serializer.DumpJson(message) +
|
118 | 91c10532 | Andrea Spadaccini | hv_kvm.QmpConnection._MESSAGE_END_TOKEN) |
119 | 91c10532 | Andrea Spadaccini | |
120 | 91c10532 | Andrea Spadaccini | |
121 | 91c10532 | Andrea Spadaccini | class TestQmpMessage(testutils.GanetiTestCase): |
122 | 91c10532 | Andrea Spadaccini | def testSerialization(self): |
123 | 51129a7f | Michael Hanselmann | test_data = { |
124 | 51129a7f | Michael Hanselmann | "execute": "command", |
125 | 51129a7f | Michael Hanselmann | "arguments": ["a", "b", "c"], |
126 | 51129a7f | Michael Hanselmann | } |
127 | 91c10532 | Andrea Spadaccini | message = hv_kvm.QmpMessage(test_data) |
128 | 91c10532 | Andrea Spadaccini | |
129 | 91c10532 | Andrea Spadaccini | for k, v in test_data.items(): |
130 | 51129a7f | Michael Hanselmann | self.assertEqual(message[k], v)
|
131 | 91c10532 | Andrea Spadaccini | |
132 | 51129a7f | Michael Hanselmann | serialized = str(message)
|
133 | 51129a7f | Michael Hanselmann | self.assertEqual(len(serialized.splitlines()), 1, |
134 | 51129a7f | Michael Hanselmann | msg="Got multi-line message")
|
135 | 51129a7f | Michael Hanselmann | |
136 | 51129a7f | Michael Hanselmann | rebuilt_message = hv_kvm.QmpMessage.BuildFromJsonString(serialized) |
137 | 51129a7f | Michael Hanselmann | self.assertEqual(rebuilt_message, message)
|
138 | 91c10532 | Andrea Spadaccini | |
139 | 91c10532 | Andrea Spadaccini | |
140 | 91c10532 | Andrea Spadaccini | class TestQmp(testutils.GanetiTestCase): |
141 | 91c10532 | Andrea Spadaccini | def testQmp(self): |
142 | 91c10532 | Andrea Spadaccini | requests = [ |
143 | 91c10532 | Andrea Spadaccini | {"execute": "query-kvm", "arguments": []}, |
144 | 91c10532 | Andrea Spadaccini | {"execute": "eject", "arguments": {"device": "ide1-cd0"}}, |
145 | 91c10532 | Andrea Spadaccini | {"execute": "query-status", "arguments": []}, |
146 | 91c10532 | Andrea Spadaccini | {"execute": "query-name", "arguments": []}, |
147 | 91c10532 | Andrea Spadaccini | ] |
148 | 91c10532 | Andrea Spadaccini | |
149 | 91c10532 | Andrea Spadaccini | server_responses = [ |
150 | 91c10532 | Andrea Spadaccini | # One message, one send()
|
151 | 91c10532 | Andrea Spadaccini | '{"return": {"enabled": true, "present": true}}\r\n',
|
152 | 91c10532 | Andrea Spadaccini | |
153 | 91c10532 | Andrea Spadaccini | # Message sent using multiple send()
|
154 | 91c10532 | Andrea Spadaccini | ['{"retur', 'n": {}}\r\n'], |
155 | 91c10532 | Andrea Spadaccini | |
156 | 91c10532 | Andrea Spadaccini | # Multiple messages sent using one send()
|
157 | 91c10532 | Andrea Spadaccini | '{"return": [{"name": "quit"}, {"name": "eject"}]}\r\n'
|
158 | 91c10532 | Andrea Spadaccini | '{"return": {"running": true, "singlestep": false}}\r\n',
|
159 | 91c10532 | Andrea Spadaccini | ] |
160 | 91c10532 | Andrea Spadaccini | |
161 | 91c10532 | Andrea Spadaccini | expected_responses = [ |
162 | 91c10532 | Andrea Spadaccini | {"return": {"enabled": True, "present": True}}, |
163 | 91c10532 | Andrea Spadaccini | {"return": {}},
|
164 | 91c10532 | Andrea Spadaccini | {"return": [{"name": "quit"}, {"name": "eject"}]}, |
165 | 91c10532 | Andrea Spadaccini | {"return": {"running": True, "singlestep": False}}, |
166 | 91c10532 | Andrea Spadaccini | ] |
167 | 91c10532 | Andrea Spadaccini | |
168 | 91c10532 | Andrea Spadaccini | # Set up the stub
|
169 | 91c10532 | Andrea Spadaccini | socket_file = tempfile.NamedTemporaryFile() |
170 | 91c10532 | Andrea Spadaccini | os.remove(socket_file.name) |
171 | 91c10532 | Andrea Spadaccini | qmp_stub = QmpStub(socket_file.name, server_responses) |
172 | 91c10532 | Andrea Spadaccini | qmp_stub.start() |
173 | 91c10532 | Andrea Spadaccini | |
174 | 91c10532 | Andrea Spadaccini | # Set up the QMP connection
|
175 | 91c10532 | Andrea Spadaccini | qmp_connection = hv_kvm.QmpConnection(socket_file.name) |
176 | 91c10532 | Andrea Spadaccini | qmp_connection.connect() |
177 | 91c10532 | Andrea Spadaccini | |
178 | 91c10532 | Andrea Spadaccini | # Format the script
|
179 | 91c10532 | Andrea Spadaccini | for request, expected_response in zip(requests, expected_responses): |
180 | 91c10532 | Andrea Spadaccini | response = qmp_connection.Execute(request) |
181 | 51129a7f | Michael Hanselmann | msg = hv_kvm.QmpMessage(expected_response) |
182 | 51129a7f | Michael Hanselmann | self.assertEqual(len(str(msg).splitlines()), 1, |
183 | 51129a7f | Michael Hanselmann | msg="Got multi-line message")
|
184 | 51129a7f | Michael Hanselmann | self.assertEqual(response, msg)
|
185 | 91c10532 | Andrea Spadaccini | |
186 | 91c10532 | Andrea Spadaccini | |
187 | 55cc0a44 | Michael Hanselmann | class TestConsole(unittest.TestCase): |
188 | 55cc0a44 | Michael Hanselmann | def _Test(self, instance, hvparams): |
189 | 55cc0a44 | Michael Hanselmann | cons = hv_kvm.KVMHypervisor.GetInstanceConsole(instance, hvparams, {}) |
190 | 55cc0a44 | Michael Hanselmann | self.assertTrue(cons.Validate())
|
191 | 55cc0a44 | Michael Hanselmann | return cons
|
192 | 55cc0a44 | Michael Hanselmann | |
193 | 55cc0a44 | Michael Hanselmann | def testSerial(self): |
194 | 55cc0a44 | Michael Hanselmann | instance = objects.Instance(name="kvm.example.com",
|
195 | 55cc0a44 | Michael Hanselmann | primary_node="node6017")
|
196 | 55cc0a44 | Michael Hanselmann | hvparams = { |
197 | 55cc0a44 | Michael Hanselmann | constants.HV_SERIAL_CONSOLE: True,
|
198 | 55cc0a44 | Michael Hanselmann | constants.HV_VNC_BIND_ADDRESS: None,
|
199 | 4d2cdb5a | Andrea Spadaccini | constants.HV_KVM_SPICE_BIND: None,
|
200 | 55cc0a44 | Michael Hanselmann | } |
201 | 55cc0a44 | Michael Hanselmann | cons = self._Test(instance, hvparams)
|
202 | 55cc0a44 | Michael Hanselmann | self.assertEqual(cons.kind, constants.CONS_SSH)
|
203 | 55cc0a44 | Michael Hanselmann | self.assertEqual(cons.host, instance.primary_node)
|
204 | a56625a2 | Michael Hanselmann | self.assertEqual(cons.command[0], pathutils.KVM_CONSOLE_WRAPPER) |
205 | 2f4c951e | Stephen Shirley | self.assertEqual(cons.command[1], constants.SOCAT_PATH) |
206 | 55cc0a44 | Michael Hanselmann | |
207 | 55cc0a44 | Michael Hanselmann | def testVnc(self): |
208 | 55cc0a44 | Michael Hanselmann | instance = objects.Instance(name="kvm.example.com",
|
209 | 55cc0a44 | Michael Hanselmann | primary_node="node7235",
|
210 | 55cc0a44 | Michael Hanselmann | network_port=constants.VNC_BASE_PORT + 10)
|
211 | 55cc0a44 | Michael Hanselmann | hvparams = { |
212 | 55cc0a44 | Michael Hanselmann | constants.HV_SERIAL_CONSOLE: False,
|
213 | 55cc0a44 | Michael Hanselmann | constants.HV_VNC_BIND_ADDRESS: "192.0.2.1",
|
214 | 4d2cdb5a | Andrea Spadaccini | constants.HV_KVM_SPICE_BIND: None,
|
215 | 55cc0a44 | Michael Hanselmann | } |
216 | 55cc0a44 | Michael Hanselmann | cons = self._Test(instance, hvparams)
|
217 | 55cc0a44 | Michael Hanselmann | self.assertEqual(cons.kind, constants.CONS_VNC)
|
218 | 55cc0a44 | Michael Hanselmann | self.assertEqual(cons.host, "192.0.2.1") |
219 | 55cc0a44 | Michael Hanselmann | self.assertEqual(cons.port, constants.VNC_BASE_PORT + 10) |
220 | 55cc0a44 | Michael Hanselmann | self.assertEqual(cons.display, 10) |
221 | 55cc0a44 | Michael Hanselmann | |
222 | 4d2cdb5a | Andrea Spadaccini | def testSpice(self): |
223 | 4d2cdb5a | Andrea Spadaccini | instance = objects.Instance(name="kvm.example.com",
|
224 | 4d2cdb5a | Andrea Spadaccini | primary_node="node7235",
|
225 | 4d2cdb5a | Andrea Spadaccini | network_port=11000)
|
226 | 4d2cdb5a | Andrea Spadaccini | hvparams = { |
227 | 4d2cdb5a | Andrea Spadaccini | constants.HV_SERIAL_CONSOLE: False,
|
228 | 4d2cdb5a | Andrea Spadaccini | constants.HV_VNC_BIND_ADDRESS: None,
|
229 | 4d2cdb5a | Andrea Spadaccini | constants.HV_KVM_SPICE_BIND: "192.0.2.1",
|
230 | 4d2cdb5a | Andrea Spadaccini | } |
231 | 4d2cdb5a | Andrea Spadaccini | cons = self._Test(instance, hvparams)
|
232 | 4d2cdb5a | Andrea Spadaccini | self.assertEqual(cons.kind, constants.CONS_SPICE)
|
233 | 4d2cdb5a | Andrea Spadaccini | self.assertEqual(cons.host, "192.0.2.1") |
234 | 4d2cdb5a | Andrea Spadaccini | self.assertEqual(cons.port, 11000) |
235 | 4d2cdb5a | Andrea Spadaccini | |
236 | 55cc0a44 | Michael Hanselmann | def testNoConsole(self): |
237 | 55cc0a44 | Michael Hanselmann | instance = objects.Instance(name="kvm.example.com",
|
238 | 55cc0a44 | Michael Hanselmann | primary_node="node24325",
|
239 | 55cc0a44 | Michael Hanselmann | network_port=0)
|
240 | 55cc0a44 | Michael Hanselmann | hvparams = { |
241 | 55cc0a44 | Michael Hanselmann | constants.HV_SERIAL_CONSOLE: False,
|
242 | 55cc0a44 | Michael Hanselmann | constants.HV_VNC_BIND_ADDRESS: None,
|
243 | 4d2cdb5a | Andrea Spadaccini | constants.HV_KVM_SPICE_BIND: None,
|
244 | 55cc0a44 | Michael Hanselmann | } |
245 | 55cc0a44 | Michael Hanselmann | cons = self._Test(instance, hvparams)
|
246 | 55cc0a44 | Michael Hanselmann | self.assertEqual(cons.kind, constants.CONS_MESSAGE)
|
247 | 55cc0a44 | Michael Hanselmann | |
248 | 55cc0a44 | Michael Hanselmann | |
249 | 585c8187 | Guido Trotter | class TestVersionChecking(testutils.GanetiTestCase): |
250 | 585c8187 | Guido Trotter | def testParseVersion(self): |
251 | 585c8187 | Guido Trotter | parse = hv_kvm.KVMHypervisor._ParseKVMVersion |
252 | 00ef625c | Michael Hanselmann | help_112 = testutils.ReadTestData("kvm_1.1.2_help.txt")
|
253 | 00ef625c | Michael Hanselmann | help_10 = testutils.ReadTestData("kvm_1.0_help.txt")
|
254 | 00ef625c | Michael Hanselmann | help_01590 = testutils.ReadTestData("kvm_0.15.90_help.txt")
|
255 | 00ef625c | Michael Hanselmann | help_0125 = testutils.ReadTestData("kvm_0.12.5_help.txt")
|
256 | 00ef625c | Michael Hanselmann | help_091 = testutils.ReadTestData("kvm_0.9.1_help.txt")
|
257 | eb7a6965 | Guido Trotter | self.assertEqual(parse(help_112), ("1.1.2", 1, 1, 2)) |
258 | 585c8187 | Guido Trotter | self.assertEqual(parse(help_10), ("1.0", 1, 0, 0)) |
259 | 585c8187 | Guido Trotter | self.assertEqual(parse(help_01590), ("0.15.90", 0, 15, 90)) |
260 | 585c8187 | Guido Trotter | self.assertEqual(parse(help_0125), ("0.12.5", 0, 12, 5)) |
261 | 585c8187 | Guido Trotter | self.assertEqual(parse(help_091), ("0.9.1", 0, 9, 1)) |
262 | 585c8187 | Guido Trotter | |
263 | 585c8187 | Guido Trotter | |
264 | 141d1489 | Michael Hanselmann | class TestSpiceParameterList(unittest.TestCase): |
265 | 141d1489 | Michael Hanselmann | def test(self): |
266 | daa49d6f | Michael Hanselmann | defaults = constants.HVC_DEFAULTS[constants.HT_KVM] |
267 | daa49d6f | Michael Hanselmann | |
268 | 141d1489 | Michael Hanselmann | params = \ |
269 | 141d1489 | Michael Hanselmann | compat.UniqueFrozenset(getattr(constants, name)
|
270 | 141d1489 | Michael Hanselmann | for name in dir(constants) |
271 | 141d1489 | Michael Hanselmann | if name.startswith("HV_KVM_SPICE_")) |
272 | 141d1489 | Michael Hanselmann | |
273 | daa49d6f | Michael Hanselmann | # Parameters whose default value evaluates to True and don't need to be set
|
274 | daa49d6f | Michael Hanselmann | defaults_true = frozenset(filter(defaults.__getitem__, params)) |
275 | daa49d6f | Michael Hanselmann | |
276 | daa49d6f | Michael Hanselmann | self.assertEqual(defaults_true, frozenset([ |
277 | daa49d6f | Michael Hanselmann | constants.HV_KVM_SPICE_AUDIO_COMPR, |
278 | daa49d6f | Michael Hanselmann | constants.HV_KVM_SPICE_USE_VDAGENT, |
279 | daa49d6f | Michael Hanselmann | constants.HV_KVM_SPICE_TLS_CIPHERS, |
280 | daa49d6f | Michael Hanselmann | ])) |
281 | daa49d6f | Michael Hanselmann | |
282 | daa49d6f | Michael Hanselmann | # HV_KVM_SPICE_BIND decides whether the other parameters must be set if
|
283 | daa49d6f | Michael Hanselmann | # their default evaluates to False
|
284 | daa49d6f | Michael Hanselmann | assert constants.HV_KVM_SPICE_BIND in params |
285 | daa49d6f | Michael Hanselmann | assert constants.HV_KVM_SPICE_BIND not in defaults_true |
286 | daa49d6f | Michael Hanselmann | |
287 | 141d1489 | Michael Hanselmann | # Exclude some parameters
|
288 | daa49d6f | Michael Hanselmann | params -= defaults_true | frozenset([
|
289 | 141d1489 | Michael Hanselmann | constants.HV_KVM_SPICE_BIND, |
290 | 141d1489 | Michael Hanselmann | ]) |
291 | 141d1489 | Michael Hanselmann | |
292 | 141d1489 | Michael Hanselmann | self.assertEqual(hv_kvm._SPICE_ADDITIONAL_PARAMS, params)
|
293 | 141d1489 | Michael Hanselmann | |
294 | 141d1489 | Michael Hanselmann | |
295 | 0ad7f5d8 | Guido Trotter | class TestHelpRegexps(testutils.GanetiTestCase): |
296 | 0ad7f5d8 | Guido Trotter | def testBootRe(self): |
297 | 0ad7f5d8 | Guido Trotter | """Check _BOOT_RE
|
298 | 0ad7f5d8 | Guido Trotter |
|
299 | 0ad7f5d8 | Guido Trotter | It has too match -drive.*boot=on|off except if there is another dash-option
|
300 | 0ad7f5d8 | Guido Trotter | at the beginning of the line.
|
301 | 0ad7f5d8 | Guido Trotter |
|
302 | 0ad7f5d8 | Guido Trotter | """
|
303 | 0ad7f5d8 | Guido Trotter | boot_re = hv_kvm.KVMHypervisor._BOOT_RE |
304 | 00ef625c | Michael Hanselmann | help_112 = testutils.ReadTestData("kvm_1.1.2_help.txt")
|
305 | 00ef625c | Michael Hanselmann | help_10 = testutils.ReadTestData("kvm_1.0_help.txt")
|
306 | 00ef625c | Michael Hanselmann | help_01590 = testutils.ReadTestData("kvm_0.15.90_help.txt")
|
307 | 00ef625c | Michael Hanselmann | help_0125 = testutils.ReadTestData("kvm_0.12.5_help.txt")
|
308 | 00ef625c | Michael Hanselmann | help_091 = testutils.ReadTestData("kvm_0.9.1_help.txt")
|
309 | 00ef625c | Michael Hanselmann | help_091_fake = testutils.ReadTestData("kvm_0.9.1_help_boot_test.txt")
|
310 | 0ad7f5d8 | Guido Trotter | |
311 | 0ad7f5d8 | Guido Trotter | self.assertTrue(boot_re.search(help_091))
|
312 | 0ad7f5d8 | Guido Trotter | self.assertTrue(boot_re.search(help_0125))
|
313 | eb7a6965 | Guido Trotter | self.assertFalse(boot_re.search(help_091_fake))
|
314 | eb7a6965 | Guido Trotter | self.assertFalse(boot_re.search(help_112))
|
315 | 0ad7f5d8 | Guido Trotter | self.assertFalse(boot_re.search(help_10))
|
316 | 0ad7f5d8 | Guido Trotter | self.assertFalse(boot_re.search(help_01590))
|
317 | 0ad7f5d8 | Guido Trotter | |
318 | 0ad7f5d8 | Guido Trotter | |
319 | ea2bcb82 | Michael Hanselmann | class TestGetTunFeatures(unittest.TestCase): |
320 | ea2bcb82 | Michael Hanselmann | def testWrongIoctl(self): |
321 | ea2bcb82 | Michael Hanselmann | tmpfile = tempfile.NamedTemporaryFile() |
322 | ea2bcb82 | Michael Hanselmann | # A file does not have the right ioctls, so this must always fail
|
323 | ea2bcb82 | Michael Hanselmann | result = hv_kvm._GetTunFeatures(tmpfile.fileno()) |
324 | ea2bcb82 | Michael Hanselmann | self.assertTrue(result is None) |
325 | ea2bcb82 | Michael Hanselmann | |
326 | ea2bcb82 | Michael Hanselmann | def _FakeIoctl(self, features, fd, request, buf): |
327 | ea2bcb82 | Michael Hanselmann | self.assertEqual(request, hv_kvm.TUNGETFEATURES)
|
328 | ea2bcb82 | Michael Hanselmann | |
329 | ea2bcb82 | Michael Hanselmann | (reqno, ) = struct.unpack("I", buf)
|
330 | ea2bcb82 | Michael Hanselmann | self.assertEqual(reqno, 0) |
331 | ea2bcb82 | Michael Hanselmann | |
332 | ea2bcb82 | Michael Hanselmann | return struct.pack("I", features) |
333 | ea2bcb82 | Michael Hanselmann | |
334 | ea2bcb82 | Michael Hanselmann | def test(self): |
335 | ea2bcb82 | Michael Hanselmann | tmpfile = tempfile.NamedTemporaryFile() |
336 | ea2bcb82 | Michael Hanselmann | fd = tmpfile.fileno() |
337 | ea2bcb82 | Michael Hanselmann | |
338 | ea2bcb82 | Michael Hanselmann | for features in [0, hv_kvm.IFF_VNET_HDR]: |
339 | ea2bcb82 | Michael Hanselmann | fn = compat.partial(self._FakeIoctl, features)
|
340 | ea2bcb82 | Michael Hanselmann | result = hv_kvm._GetTunFeatures(fd, _ioctl=fn) |
341 | ea2bcb82 | Michael Hanselmann | self.assertEqual(result, features)
|
342 | ea2bcb82 | Michael Hanselmann | |
343 | ea2bcb82 | Michael Hanselmann | |
344 | ea2bcb82 | Michael Hanselmann | class TestProbeTapVnetHdr(unittest.TestCase): |
345 | ea2bcb82 | Michael Hanselmann | def _FakeTunFeatures(self, expected_fd, flags, fd): |
346 | ea2bcb82 | Michael Hanselmann | self.assertEqual(fd, expected_fd)
|
347 | ea2bcb82 | Michael Hanselmann | return flags
|
348 | ea2bcb82 | Michael Hanselmann | |
349 | ea2bcb82 | Michael Hanselmann | def test(self): |
350 | ea2bcb82 | Michael Hanselmann | tmpfile = tempfile.NamedTemporaryFile() |
351 | ea2bcb82 | Michael Hanselmann | fd = tmpfile.fileno() |
352 | ea2bcb82 | Michael Hanselmann | |
353 | ea2bcb82 | Michael Hanselmann | for flags in [0, hv_kvm.IFF_VNET_HDR]: |
354 | ea2bcb82 | Michael Hanselmann | fn = compat.partial(self._FakeTunFeatures, fd, flags)
|
355 | ea2bcb82 | Michael Hanselmann | |
356 | ea2bcb82 | Michael Hanselmann | result = hv_kvm._ProbeTapVnetHdr(fd, _features_fn=fn) |
357 | ea2bcb82 | Michael Hanselmann | if flags == 0: |
358 | ea2bcb82 | Michael Hanselmann | self.assertFalse(result)
|
359 | ea2bcb82 | Michael Hanselmann | else:
|
360 | ea2bcb82 | Michael Hanselmann | self.assertTrue(result)
|
361 | ea2bcb82 | Michael Hanselmann | |
362 | ea2bcb82 | Michael Hanselmann | def testUnsupported(self): |
363 | ea2bcb82 | Michael Hanselmann | tmpfile = tempfile.NamedTemporaryFile() |
364 | ea2bcb82 | Michael Hanselmann | fd = tmpfile.fileno() |
365 | ea2bcb82 | Michael Hanselmann | |
366 | ea2bcb82 | Michael Hanselmann | self.assertFalse(hv_kvm._ProbeTapVnetHdr(fd, _features_fn=lambda _: None)) |
367 | ea2bcb82 | Michael Hanselmann | |
368 | ea2bcb82 | Michael Hanselmann | |
369 | 748e4b5a | Michael Hanselmann | if __name__ == "__main__": |
370 | 748e4b5a | Michael Hanselmann | testutils.GanetiTestProgram() |