Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.rpc_unittest.py @ 14933c17

History | View | Annotate | Download (33.6 kB)

1 33231500 Michael Hanselmann
#!/usr/bin/python
2 33231500 Michael Hanselmann
#
3 33231500 Michael Hanselmann
4 91c17910 Iustin Pop
# Copyright (C) 2010, 2011, 2012, 2013 Google Inc.
5 33231500 Michael Hanselmann
#
6 33231500 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 33231500 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 33231500 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 33231500 Michael Hanselmann
# (at your option) any later version.
10 33231500 Michael Hanselmann
#
11 33231500 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 33231500 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 33231500 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 33231500 Michael Hanselmann
# General Public License for more details.
15 33231500 Michael Hanselmann
#
16 33231500 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 33231500 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 33231500 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 33231500 Michael Hanselmann
# 02110-1301, USA.
20 33231500 Michael Hanselmann
21 33231500 Michael Hanselmann
22 33231500 Michael Hanselmann
"""Script for testing ganeti.rpc"""
23 33231500 Michael Hanselmann
24 33231500 Michael Hanselmann
import os
25 33231500 Michael Hanselmann
import sys
26 33231500 Michael Hanselmann
import unittest
27 065be3f0 Michael Hanselmann
import random
28 601dfcbb Michael Hanselmann
import tempfile
29 33231500 Michael Hanselmann
30 33231500 Michael Hanselmann
from ganeti import constants
31 33231500 Michael Hanselmann
from ganeti import compat
32 33231500 Michael Hanselmann
from ganeti import rpc
33 890ea4ce Michael Hanselmann
from ganeti import rpc_defs
34 33231500 Michael Hanselmann
from ganeti import http
35 33231500 Michael Hanselmann
from ganeti import errors
36 33231500 Michael Hanselmann
from ganeti import serializer
37 00267bfe Michael Hanselmann
from ganeti import objects
38 120e7e77 Michael Hanselmann
from ganeti import backend
39 33231500 Michael Hanselmann
40 33231500 Michael Hanselmann
import testutils
41 601dfcbb Michael Hanselmann
import mocks
42 33231500 Michael Hanselmann
43 33231500 Michael Hanselmann
44 abbf2cd9 Michael Hanselmann
class _FakeRequestProcessor:
45 33231500 Michael Hanselmann
  def __init__(self, response_fn):
46 33231500 Michael Hanselmann
    self._response_fn = response_fn
47 33231500 Michael Hanselmann
    self.reqcount = 0
48 33231500 Michael Hanselmann
49 abbf2cd9 Michael Hanselmann
  def __call__(self, reqs, lock_monitor_cb=None):
50 abbf2cd9 Michael Hanselmann
    assert lock_monitor_cb is None or callable(lock_monitor_cb)
51 33231500 Michael Hanselmann
    for req in reqs:
52 33231500 Michael Hanselmann
      self.reqcount += 1
53 33231500 Michael Hanselmann
      self._response_fn(req)
54 33231500 Michael Hanselmann
55 33231500 Michael Hanselmann
56 eb202c13 Manuel Franceschini
def GetFakeSimpleStoreClass(fn):
57 eb202c13 Manuel Franceschini
  class FakeSimpleStore:
58 eb202c13 Manuel Franceschini
    GetNodePrimaryIPList = fn
59 b43dcc5a Manuel Franceschini
    GetPrimaryIPFamily = lambda _: None
60 eb202c13 Manuel Franceschini
61 eb202c13 Manuel Franceschini
  return FakeSimpleStore
62 eb202c13 Manuel Franceschini
63 eb202c13 Manuel Franceschini
64 bd6d1202 René Nussbaumer
def _RaiseNotImplemented():
65 bd6d1202 René Nussbaumer
  """Simple wrapper to raise NotImplementedError.
66 bd6d1202 René Nussbaumer

67 bd6d1202 René Nussbaumer
  """
68 bd6d1202 René Nussbaumer
  raise NotImplementedError
69 bd6d1202 René Nussbaumer
70 bd6d1202 René Nussbaumer
71 00267bfe Michael Hanselmann
class TestRpcProcessor(unittest.TestCase):
72 eb202c13 Manuel Franceschini
  def _FakeAddressLookup(self, map):
73 eb202c13 Manuel Franceschini
    return lambda node_list: [map.get(node) for node in node_list]
74 eb202c13 Manuel Franceschini
75 33231500 Michael Hanselmann
  def _GetVersionResponse(self, req):
76 00267bfe Michael Hanselmann
    self.assertEqual(req.host, "127.0.0.1")
77 33231500 Michael Hanselmann
    self.assertEqual(req.port, 24094)
78 33231500 Michael Hanselmann
    self.assertEqual(req.path, "/version")
79 2ff587d4 Agata Murawska
    self.assertEqual(req.read_timeout, constants.RPC_TMO_URGENT)
80 33231500 Michael Hanselmann
    req.success = True
81 33231500 Michael Hanselmann
    req.resp_status_code = http.HTTP_OK
82 33231500 Michael Hanselmann
    req.resp_body = serializer.DumpJson((True, 123))
83 33231500 Michael Hanselmann
84 33231500 Michael Hanselmann
  def testVersionSuccess(self):
85 00267bfe Michael Hanselmann
    resolver = rpc._StaticResolver(["127.0.0.1"])
86 abbf2cd9 Michael Hanselmann
    http_proc = _FakeRequestProcessor(self._GetVersionResponse)
87 00267bfe Michael Hanselmann
    proc = rpc._RpcProcessor(resolver, 24094)
88 f863d7aa Michael Hanselmann
    result = proc(["localhost"], "version", {"localhost": ""}, 60,
89 fce5efd1 Michael Hanselmann
                  NotImplemented, _req_process_fn=http_proc)
90 33231500 Michael Hanselmann
    self.assertEqual(result.keys(), ["localhost"])
91 33231500 Michael Hanselmann
    lhresp = result["localhost"]
92 33231500 Michael Hanselmann
    self.assertFalse(lhresp.offline)
93 33231500 Michael Hanselmann
    self.assertEqual(lhresp.node, "localhost")
94 33231500 Michael Hanselmann
    self.assertFalse(lhresp.fail_msg)
95 33231500 Michael Hanselmann
    self.assertEqual(lhresp.payload, 123)
96 33231500 Michael Hanselmann
    self.assertEqual(lhresp.call, "version")
97 33231500 Michael Hanselmann
    lhresp.Raise("should not raise")
98 abbf2cd9 Michael Hanselmann
    self.assertEqual(http_proc.reqcount, 1)
99 33231500 Michael Hanselmann
100 00267bfe Michael Hanselmann
  def _ReadTimeoutResponse(self, req):
101 00267bfe Michael Hanselmann
    self.assertEqual(req.host, "192.0.2.13")
102 00267bfe Michael Hanselmann
    self.assertEqual(req.port, 19176)
103 00267bfe Michael Hanselmann
    self.assertEqual(req.path, "/version")
104 00267bfe Michael Hanselmann
    self.assertEqual(req.read_timeout, 12356)
105 00267bfe Michael Hanselmann
    req.success = True
106 00267bfe Michael Hanselmann
    req.resp_status_code = http.HTTP_OK
107 00267bfe Michael Hanselmann
    req.resp_body = serializer.DumpJson((True, -1))
108 00267bfe Michael Hanselmann
109 00267bfe Michael Hanselmann
  def testReadTimeout(self):
110 00267bfe Michael Hanselmann
    resolver = rpc._StaticResolver(["192.0.2.13"])
111 abbf2cd9 Michael Hanselmann
    http_proc = _FakeRequestProcessor(self._ReadTimeoutResponse)
112 00267bfe Michael Hanselmann
    proc = rpc._RpcProcessor(resolver, 19176)
113 d9de612c Iustin Pop
    host = "node31856"
114 d9de612c Iustin Pop
    body = {host: ""}
115 fce5efd1 Michael Hanselmann
    result = proc([host], "version", body, 12356, NotImplemented,
116 fce5efd1 Michael Hanselmann
                  _req_process_fn=http_proc)
117 d9de612c Iustin Pop
    self.assertEqual(result.keys(), [host])
118 d9de612c Iustin Pop
    lhresp = result[host]
119 00267bfe Michael Hanselmann
    self.assertFalse(lhresp.offline)
120 d9de612c Iustin Pop
    self.assertEqual(lhresp.node, host)
121 00267bfe Michael Hanselmann
    self.assertFalse(lhresp.fail_msg)
122 00267bfe Michael Hanselmann
    self.assertEqual(lhresp.payload, -1)
123 00267bfe Michael Hanselmann
    self.assertEqual(lhresp.call, "version")
124 00267bfe Michael Hanselmann
    lhresp.Raise("should not raise")
125 abbf2cd9 Michael Hanselmann
    self.assertEqual(http_proc.reqcount, 1)
126 00267bfe Michael Hanselmann
127 00267bfe Michael Hanselmann
  def testOfflineNode(self):
128 00267bfe Michael Hanselmann
    resolver = rpc._StaticResolver([rpc._OFFLINE])
129 abbf2cd9 Michael Hanselmann
    http_proc = _FakeRequestProcessor(NotImplemented)
130 00267bfe Michael Hanselmann
    proc = rpc._RpcProcessor(resolver, 30668)
131 d9de612c Iustin Pop
    host = "n17296"
132 d9de612c Iustin Pop
    body = {host: ""}
133 fce5efd1 Michael Hanselmann
    result = proc([host], "version", body, 60, NotImplemented,
134 fce5efd1 Michael Hanselmann
                  _req_process_fn=http_proc)
135 d9de612c Iustin Pop
    self.assertEqual(result.keys(), [host])
136 d9de612c Iustin Pop
    lhresp = result[host]
137 00267bfe Michael Hanselmann
    self.assertTrue(lhresp.offline)
138 d9de612c Iustin Pop
    self.assertEqual(lhresp.node, host)
139 00267bfe Michael Hanselmann
    self.assertTrue(lhresp.fail_msg)
140 00267bfe Michael Hanselmann
    self.assertFalse(lhresp.payload)
141 00267bfe Michael Hanselmann
    self.assertEqual(lhresp.call, "version")
142 00267bfe Michael Hanselmann
143 00267bfe Michael Hanselmann
    # With a message
144 00267bfe Michael Hanselmann
    self.assertRaises(errors.OpExecError, lhresp.Raise, "should raise")
145 00267bfe Michael Hanselmann
146 00267bfe Michael Hanselmann
    # No message
147 00267bfe Michael Hanselmann
    self.assertRaises(errors.OpExecError, lhresp.Raise, None)
148 00267bfe Michael Hanselmann
149 abbf2cd9 Michael Hanselmann
    self.assertEqual(http_proc.reqcount, 0)
150 00267bfe Michael Hanselmann
151 33231500 Michael Hanselmann
  def _GetMultiVersionResponse(self, req):
152 33231500 Michael Hanselmann
    self.assert_(req.host.startswith("node"))
153 33231500 Michael Hanselmann
    self.assertEqual(req.port, 23245)
154 33231500 Michael Hanselmann
    self.assertEqual(req.path, "/version")
155 33231500 Michael Hanselmann
    req.success = True
156 33231500 Michael Hanselmann
    req.resp_status_code = http.HTTP_OK
157 33231500 Michael Hanselmann
    req.resp_body = serializer.DumpJson((True, 987))
158 33231500 Michael Hanselmann
159 33231500 Michael Hanselmann
  def testMultiVersionSuccess(self):
160 33231500 Michael Hanselmann
    nodes = ["node%s" % i for i in range(50)]
161 d9de612c Iustin Pop
    body = dict((n, "") for n in nodes)
162 00267bfe Michael Hanselmann
    resolver = rpc._StaticResolver(nodes)
163 abbf2cd9 Michael Hanselmann
    http_proc = _FakeRequestProcessor(self._GetMultiVersionResponse)
164 00267bfe Michael Hanselmann
    proc = rpc._RpcProcessor(resolver, 23245)
165 fce5efd1 Michael Hanselmann
    result = proc(nodes, "version", body, 60, NotImplemented,
166 fce5efd1 Michael Hanselmann
                  _req_process_fn=http_proc)
167 33231500 Michael Hanselmann
    self.assertEqual(sorted(result.keys()), sorted(nodes))
168 33231500 Michael Hanselmann
169 33231500 Michael Hanselmann
    for name in nodes:
170 33231500 Michael Hanselmann
      lhresp = result[name]
171 33231500 Michael Hanselmann
      self.assertFalse(lhresp.offline)
172 33231500 Michael Hanselmann
      self.assertEqual(lhresp.node, name)
173 33231500 Michael Hanselmann
      self.assertFalse(lhresp.fail_msg)
174 33231500 Michael Hanselmann
      self.assertEqual(lhresp.payload, 987)
175 33231500 Michael Hanselmann
      self.assertEqual(lhresp.call, "version")
176 33231500 Michael Hanselmann
      lhresp.Raise("should not raise")
177 33231500 Michael Hanselmann
178 abbf2cd9 Michael Hanselmann
    self.assertEqual(http_proc.reqcount, len(nodes))
179 33231500 Michael Hanselmann
180 00267bfe Michael Hanselmann
  def _GetVersionResponseFail(self, errinfo, req):
181 33231500 Michael Hanselmann
    self.assertEqual(req.path, "/version")
182 33231500 Michael Hanselmann
    req.success = True
183 33231500 Michael Hanselmann
    req.resp_status_code = http.HTTP_OK
184 00267bfe Michael Hanselmann
    req.resp_body = serializer.DumpJson((False, errinfo))
185 33231500 Michael Hanselmann
186 33231500 Michael Hanselmann
  def testVersionFailure(self):
187 00267bfe Michael Hanselmann
    resolver = rpc._StaticResolver(["aef9ur4i.example.com"])
188 00267bfe Michael Hanselmann
    proc = rpc._RpcProcessor(resolver, 5903)
189 00267bfe Michael Hanselmann
    for errinfo in [None, "Unknown error"]:
190 abbf2cd9 Michael Hanselmann
      http_proc = \
191 abbf2cd9 Michael Hanselmann
        _FakeRequestProcessor(compat.partial(self._GetVersionResponseFail,
192 abbf2cd9 Michael Hanselmann
                                             errinfo))
193 d9de612c Iustin Pop
      host = "aef9ur4i.example.com"
194 d9de612c Iustin Pop
      body = {host: ""}
195 fce5efd1 Michael Hanselmann
      result = proc(body.keys(), "version", body, 60, NotImplemented,
196 f863d7aa Michael Hanselmann
                    _req_process_fn=http_proc)
197 d9de612c Iustin Pop
      self.assertEqual(result.keys(), [host])
198 d9de612c Iustin Pop
      lhresp = result[host]
199 00267bfe Michael Hanselmann
      self.assertFalse(lhresp.offline)
200 d9de612c Iustin Pop
      self.assertEqual(lhresp.node, host)
201 00267bfe Michael Hanselmann
      self.assert_(lhresp.fail_msg)
202 00267bfe Michael Hanselmann
      self.assertFalse(lhresp.payload)
203 00267bfe Michael Hanselmann
      self.assertEqual(lhresp.call, "version")
204 00267bfe Michael Hanselmann
      self.assertRaises(errors.OpExecError, lhresp.Raise, "failed")
205 abbf2cd9 Michael Hanselmann
      self.assertEqual(http_proc.reqcount, 1)
206 33231500 Michael Hanselmann
207 33231500 Michael Hanselmann
  def _GetHttpErrorResponse(self, httperrnodes, failnodes, req):
208 33231500 Michael Hanselmann
    self.assertEqual(req.path, "/vg_list")
209 33231500 Michael Hanselmann
    self.assertEqual(req.port, 15165)
210 33231500 Michael Hanselmann
211 33231500 Michael Hanselmann
    if req.host in httperrnodes:
212 33231500 Michael Hanselmann
      req.success = False
213 33231500 Michael Hanselmann
      req.error = "Node set up for HTTP errors"
214 33231500 Michael Hanselmann
215 33231500 Michael Hanselmann
    elif req.host in failnodes:
216 33231500 Michael Hanselmann
      req.success = True
217 33231500 Michael Hanselmann
      req.resp_status_code = 404
218 33231500 Michael Hanselmann
      req.resp_body = serializer.DumpJson({
219 33231500 Michael Hanselmann
        "code": 404,
220 33231500 Michael Hanselmann
        "message": "Method not found",
221 33231500 Michael Hanselmann
        "explain": "Explanation goes here",
222 33231500 Michael Hanselmann
        })
223 33231500 Michael Hanselmann
    else:
224 33231500 Michael Hanselmann
      req.success = True
225 33231500 Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
226 33231500 Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, hash(req.host)))
227 33231500 Michael Hanselmann
228 33231500 Michael Hanselmann
  def testHttpError(self):
229 33231500 Michael Hanselmann
    nodes = ["uaf6pbbv%s" % i for i in range(50)]
230 d9de612c Iustin Pop
    body = dict((n, "") for n in nodes)
231 00267bfe Michael Hanselmann
    resolver = rpc._StaticResolver(nodes)
232 33231500 Michael Hanselmann
233 33231500 Michael Hanselmann
    httperrnodes = set(nodes[1::7])
234 33231500 Michael Hanselmann
    self.assertEqual(len(httperrnodes), 7)
235 33231500 Michael Hanselmann
236 33231500 Michael Hanselmann
    failnodes = set(nodes[2::3]) - httperrnodes
237 33231500 Michael Hanselmann
    self.assertEqual(len(failnodes), 14)
238 33231500 Michael Hanselmann
239 33231500 Michael Hanselmann
    self.assertEqual(len(set(nodes) - failnodes - httperrnodes), 29)
240 33231500 Michael Hanselmann
241 00267bfe Michael Hanselmann
    proc = rpc._RpcProcessor(resolver, 15165)
242 abbf2cd9 Michael Hanselmann
    http_proc = \
243 abbf2cd9 Michael Hanselmann
      _FakeRequestProcessor(compat.partial(self._GetHttpErrorResponse,
244 abbf2cd9 Michael Hanselmann
                                           httperrnodes, failnodes))
245 2ff587d4 Agata Murawska
    result = proc(nodes, "vg_list", body,
246 2ff587d4 Agata Murawska
                  constants.RPC_TMO_URGENT, NotImplemented,
247 f863d7aa Michael Hanselmann
                  _req_process_fn=http_proc)
248 33231500 Michael Hanselmann
    self.assertEqual(sorted(result.keys()), sorted(nodes))
249 33231500 Michael Hanselmann
250 33231500 Michael Hanselmann
    for name in nodes:
251 33231500 Michael Hanselmann
      lhresp = result[name]
252 33231500 Michael Hanselmann
      self.assertFalse(lhresp.offline)
253 33231500 Michael Hanselmann
      self.assertEqual(lhresp.node, name)
254 33231500 Michael Hanselmann
      self.assertEqual(lhresp.call, "vg_list")
255 33231500 Michael Hanselmann
256 33231500 Michael Hanselmann
      if name in httperrnodes:
257 33231500 Michael Hanselmann
        self.assert_(lhresp.fail_msg)
258 33231500 Michael Hanselmann
        self.assertRaises(errors.OpExecError, lhresp.Raise, "failed")
259 33231500 Michael Hanselmann
      elif name in failnodes:
260 33231500 Michael Hanselmann
        self.assert_(lhresp.fail_msg)
261 33231500 Michael Hanselmann
        self.assertRaises(errors.OpPrereqError, lhresp.Raise, "failed",
262 33231500 Michael Hanselmann
                          prereq=True, ecode=errors.ECODE_INVAL)
263 33231500 Michael Hanselmann
      else:
264 33231500 Michael Hanselmann
        self.assertFalse(lhresp.fail_msg)
265 33231500 Michael Hanselmann
        self.assertEqual(lhresp.payload, hash(name))
266 33231500 Michael Hanselmann
        lhresp.Raise("should not raise")
267 33231500 Michael Hanselmann
268 abbf2cd9 Michael Hanselmann
    self.assertEqual(http_proc.reqcount, len(nodes))
269 33231500 Michael Hanselmann
270 33231500 Michael Hanselmann
  def _GetInvalidResponseA(self, req):
271 33231500 Michael Hanselmann
    self.assertEqual(req.path, "/version")
272 33231500 Michael Hanselmann
    req.success = True
273 33231500 Michael Hanselmann
    req.resp_status_code = http.HTTP_OK
274 33231500 Michael Hanselmann
    req.resp_body = serializer.DumpJson(("This", "is", "an", "invalid",
275 33231500 Michael Hanselmann
                                         "response", "!", 1, 2, 3))
276 33231500 Michael Hanselmann
277 33231500 Michael Hanselmann
  def _GetInvalidResponseB(self, req):
278 33231500 Michael Hanselmann
    self.assertEqual(req.path, "/version")
279 33231500 Michael Hanselmann
    req.success = True
280 33231500 Michael Hanselmann
    req.resp_status_code = http.HTTP_OK
281 33231500 Michael Hanselmann
    req.resp_body = serializer.DumpJson("invalid response")
282 33231500 Michael Hanselmann
283 33231500 Michael Hanselmann
  def testInvalidResponse(self):
284 00267bfe Michael Hanselmann
    resolver = rpc._StaticResolver(["oqo7lanhly.example.com"])
285 00267bfe Michael Hanselmann
    proc = rpc._RpcProcessor(resolver, 19978)
286 00267bfe Michael Hanselmann
287 33231500 Michael Hanselmann
    for fn in [self._GetInvalidResponseA, self._GetInvalidResponseB]:
288 abbf2cd9 Michael Hanselmann
      http_proc = _FakeRequestProcessor(fn)
289 d9de612c Iustin Pop
      host = "oqo7lanhly.example.com"
290 d9de612c Iustin Pop
      body = {host: ""}
291 fce5efd1 Michael Hanselmann
      result = proc([host], "version", body, 60, NotImplemented,
292 f863d7aa Michael Hanselmann
                    _req_process_fn=http_proc)
293 d9de612c Iustin Pop
      self.assertEqual(result.keys(), [host])
294 d9de612c Iustin Pop
      lhresp = result[host]
295 33231500 Michael Hanselmann
      self.assertFalse(lhresp.offline)
296 d9de612c Iustin Pop
      self.assertEqual(lhresp.node, host)
297 33231500 Michael Hanselmann
      self.assert_(lhresp.fail_msg)
298 33231500 Michael Hanselmann
      self.assertFalse(lhresp.payload)
299 33231500 Michael Hanselmann
      self.assertEqual(lhresp.call, "version")
300 33231500 Michael Hanselmann
      self.assertRaises(errors.OpExecError, lhresp.Raise, "failed")
301 abbf2cd9 Michael Hanselmann
      self.assertEqual(http_proc.reqcount, 1)
302 33231500 Michael Hanselmann
303 00267bfe Michael Hanselmann
  def _GetBodyTestResponse(self, test_data, req):
304 00267bfe Michael Hanselmann
    self.assertEqual(req.host, "192.0.2.84")
305 00267bfe Michael Hanselmann
    self.assertEqual(req.port, 18700)
306 00267bfe Michael Hanselmann
    self.assertEqual(req.path, "/upload_file")
307 00267bfe Michael Hanselmann
    self.assertEqual(serializer.LoadJson(req.post_data), test_data)
308 00267bfe Michael Hanselmann
    req.success = True
309 00267bfe Michael Hanselmann
    req.resp_status_code = http.HTTP_OK
310 00267bfe Michael Hanselmann
    req.resp_body = serializer.DumpJson((True, None))
311 00267bfe Michael Hanselmann
312 00267bfe Michael Hanselmann
  def testResponseBody(self):
313 00267bfe Michael Hanselmann
    test_data = {
314 00267bfe Michael Hanselmann
      "Hello": "World",
315 00267bfe Michael Hanselmann
      "xyz": range(10),
316 00267bfe Michael Hanselmann
      }
317 00267bfe Michael Hanselmann
    resolver = rpc._StaticResolver(["192.0.2.84"])
318 abbf2cd9 Michael Hanselmann
    http_proc = _FakeRequestProcessor(compat.partial(self._GetBodyTestResponse,
319 abbf2cd9 Michael Hanselmann
                                                     test_data))
320 00267bfe Michael Hanselmann
    proc = rpc._RpcProcessor(resolver, 18700)
321 d9de612c Iustin Pop
    host = "node19759"
322 d9de612c Iustin Pop
    body = {host: serializer.DumpJson(test_data)}
323 fce5efd1 Michael Hanselmann
    result = proc([host], "upload_file", body, 30, NotImplemented,
324 fce5efd1 Michael Hanselmann
                  _req_process_fn=http_proc)
325 d9de612c Iustin Pop
    self.assertEqual(result.keys(), [host])
326 d9de612c Iustin Pop
    lhresp = result[host]
327 00267bfe Michael Hanselmann
    self.assertFalse(lhresp.offline)
328 d9de612c Iustin Pop
    self.assertEqual(lhresp.node, host)
329 00267bfe Michael Hanselmann
    self.assertFalse(lhresp.fail_msg)
330 00267bfe Michael Hanselmann
    self.assertEqual(lhresp.payload, None)
331 00267bfe Michael Hanselmann
    self.assertEqual(lhresp.call, "upload_file")
332 00267bfe Michael Hanselmann
    lhresp.Raise("should not raise")
333 abbf2cd9 Michael Hanselmann
    self.assertEqual(http_proc.reqcount, 1)
334 00267bfe Michael Hanselmann
335 00267bfe Michael Hanselmann
336 00267bfe Michael Hanselmann
class TestSsconfResolver(unittest.TestCase):
337 00267bfe Michael Hanselmann
  def testSsconfLookup(self):
338 eb202c13 Manuel Franceschini
    addr_list = ["192.0.2.%d" % n for n in range(0, 255, 13)]
339 eb202c13 Manuel Franceschini
    node_list = ["node%d.example.com" % n for n in range(0, 255, 13)]
340 00267bfe Michael Hanselmann
    node_addr_list = [" ".join(t) for t in zip(node_list, addr_list)]
341 b43dcc5a Manuel Franceschini
    ssc = GetFakeSimpleStoreClass(lambda _: node_addr_list)
342 bd6d1202 René Nussbaumer
    result = rpc._SsconfResolver(True, node_list, NotImplemented,
343 fce5efd1 Michael Hanselmann
                                 ssc=ssc, nslookup_fn=NotImplemented)
344 1c3231aa Thomas Thrainer
    self.assertEqual(result, zip(node_list, addr_list, node_list))
345 eb202c13 Manuel Franceschini
346 00267bfe Michael Hanselmann
  def testNsLookup(self):
347 eb202c13 Manuel Franceschini
    addr_list = ["192.0.2.%d" % n for n in range(0, 255, 13)]
348 eb202c13 Manuel Franceschini
    node_list = ["node%d.example.com" % n for n in range(0, 255, 13)]
349 b43dcc5a Manuel Franceschini
    ssc = GetFakeSimpleStoreClass(lambda _: [])
350 eb202c13 Manuel Franceschini
    node_addr_map = dict(zip(node_list, addr_list))
351 b43dcc5a Manuel Franceschini
    nslookup_fn = lambda name, family=None: node_addr_map.get(name)
352 bd6d1202 René Nussbaumer
    result = rpc._SsconfResolver(True, node_list, NotImplemented,
353 bd6d1202 René Nussbaumer
                                 ssc=ssc, nslookup_fn=nslookup_fn)
354 1c3231aa Thomas Thrainer
    self.assertEqual(result, zip(node_list, addr_list, node_list))
355 bd6d1202 René Nussbaumer
356 bd6d1202 René Nussbaumer
  def testDisabledSsconfIp(self):
357 bd6d1202 René Nussbaumer
    addr_list = ["192.0.2.%d" % n for n in range(0, 255, 13)]
358 bd6d1202 René Nussbaumer
    node_list = ["node%d.example.com" % n for n in range(0, 255, 13)]
359 bd6d1202 René Nussbaumer
    ssc = GetFakeSimpleStoreClass(_RaiseNotImplemented)
360 bd6d1202 René Nussbaumer
    node_addr_map = dict(zip(node_list, addr_list))
361 bd6d1202 René Nussbaumer
    nslookup_fn = lambda name, family=None: node_addr_map.get(name)
362 bd6d1202 René Nussbaumer
    result = rpc._SsconfResolver(False, node_list, NotImplemented,
363 fce5efd1 Michael Hanselmann
                                 ssc=ssc, nslookup_fn=nslookup_fn)
364 1c3231aa Thomas Thrainer
    self.assertEqual(result, zip(node_list, addr_list, node_list))
365 eb202c13 Manuel Franceschini
366 00267bfe Michael Hanselmann
  def testBothLookups(self):
367 eb202c13 Manuel Franceschini
    addr_list = ["192.0.2.%d" % n for n in range(0, 255, 13)]
368 eb202c13 Manuel Franceschini
    node_list = ["node%d.example.com" % n for n in range(0, 255, 13)]
369 eb202c13 Manuel Franceschini
    n = len(addr_list) / 2
370 00267bfe Michael Hanselmann
    node_addr_list = [" ".join(t) for t in zip(node_list[n:], addr_list[n:])]
371 b43dcc5a Manuel Franceschini
    ssc = GetFakeSimpleStoreClass(lambda _: node_addr_list)
372 eb202c13 Manuel Franceschini
    node_addr_map = dict(zip(node_list[:n], addr_list[:n]))
373 b43dcc5a Manuel Franceschini
    nslookup_fn = lambda name, family=None: node_addr_map.get(name)
374 bd6d1202 René Nussbaumer
    result = rpc._SsconfResolver(True, node_list, NotImplemented,
375 fce5efd1 Michael Hanselmann
                                 ssc=ssc, nslookup_fn=nslookup_fn)
376 1c3231aa Thomas Thrainer
    self.assertEqual(result, zip(node_list, addr_list, node_list))
377 eb202c13 Manuel Franceschini
378 b43dcc5a Manuel Franceschini
  def testAddressLookupIPv6(self):
379 00267bfe Michael Hanselmann
    addr_list = ["2001:db8::%d" % n for n in range(0, 255, 11)]
380 00267bfe Michael Hanselmann
    node_list = ["node%d.example.com" % n for n in range(0, 255, 11)]
381 00267bfe Michael Hanselmann
    node_addr_list = [" ".join(t) for t in zip(node_list, addr_list)]
382 b43dcc5a Manuel Franceschini
    ssc = GetFakeSimpleStoreClass(lambda _: node_addr_list)
383 bd6d1202 René Nussbaumer
    result = rpc._SsconfResolver(True, node_list, NotImplemented,
384 fce5efd1 Michael Hanselmann
                                 ssc=ssc, nslookup_fn=NotImplemented)
385 1c3231aa Thomas Thrainer
    self.assertEqual(result, zip(node_list, addr_list, node_list))
386 00267bfe Michael Hanselmann
387 00267bfe Michael Hanselmann
388 00267bfe Michael Hanselmann
class TestStaticResolver(unittest.TestCase):
389 00267bfe Michael Hanselmann
  def test(self):
390 00267bfe Michael Hanselmann
    addresses = ["192.0.2.%d" % n for n in range(0, 123, 7)]
391 00267bfe Michael Hanselmann
    nodes = ["node%s.example.com" % n for n in range(0, 123, 7)]
392 00267bfe Michael Hanselmann
    res = rpc._StaticResolver(addresses)
393 1c3231aa Thomas Thrainer
    self.assertEqual(res(nodes, NotImplemented), zip(nodes, addresses, nodes))
394 00267bfe Michael Hanselmann
395 00267bfe Michael Hanselmann
  def testWrongLength(self):
396 00267bfe Michael Hanselmann
    res = rpc._StaticResolver([])
397 fce5efd1 Michael Hanselmann
    self.assertRaises(AssertionError, res, ["abc"], NotImplemented)
398 00267bfe Michael Hanselmann
399 00267bfe Michael Hanselmann
400 00267bfe Michael Hanselmann
class TestNodeConfigResolver(unittest.TestCase):
401 00267bfe Michael Hanselmann
  @staticmethod
402 1c3231aa Thomas Thrainer
  def _GetSingleOnlineNode(uuid):
403 1c3231aa Thomas Thrainer
    assert uuid == "node90-uuid"
404 1c3231aa Thomas Thrainer
    return objects.Node(name="node90.example.com",
405 1c3231aa Thomas Thrainer
                        uuid=uuid,
406 1c3231aa Thomas Thrainer
                        offline=False,
407 1c3231aa Thomas Thrainer
                        primary_ip="192.0.2.90")
408 00267bfe Michael Hanselmann
409 00267bfe Michael Hanselmann
  @staticmethod
410 1c3231aa Thomas Thrainer
  def _GetSingleOfflineNode(uuid):
411 1c3231aa Thomas Thrainer
    assert uuid == "node100-uuid"
412 1c3231aa Thomas Thrainer
    return objects.Node(name="node100.example.com",
413 1c3231aa Thomas Thrainer
                        uuid=uuid,
414 1c3231aa Thomas Thrainer
                        offline=True,
415 1c3231aa Thomas Thrainer
                        primary_ip="192.0.2.100")
416 00267bfe Michael Hanselmann
417 00267bfe Michael Hanselmann
  def testSingleOnline(self):
418 00267bfe Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(self._GetSingleOnlineNode,
419 00267bfe Michael Hanselmann
                                             NotImplemented,
420 1c3231aa Thomas Thrainer
                                             ["node90-uuid"], None),
421 1c3231aa Thomas Thrainer
                     [("node90.example.com", "192.0.2.90", "node90-uuid")])
422 00267bfe Michael Hanselmann
423 00267bfe Michael Hanselmann
  def testSingleOffline(self):
424 00267bfe Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(self._GetSingleOfflineNode,
425 00267bfe Michael Hanselmann
                                             NotImplemented,
426 1c3231aa Thomas Thrainer
                                             ["node100-uuid"], None),
427 1c3231aa Thomas Thrainer
                     [("node100.example.com", rpc._OFFLINE, "node100-uuid")])
428 00267bfe Michael Hanselmann
429 890ea4ce Michael Hanselmann
  def testSingleOfflineWithAcceptOffline(self):
430 890ea4ce Michael Hanselmann
    fn = self._GetSingleOfflineNode
431 1c3231aa Thomas Thrainer
    assert fn("node100-uuid").offline
432 890ea4ce Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(fn, NotImplemented,
433 1c3231aa Thomas Thrainer
                                             ["node100-uuid"],
434 890ea4ce Michael Hanselmann
                                             rpc_defs.ACCEPT_OFFLINE_NODE),
435 1c3231aa Thomas Thrainer
                     [("node100.example.com", "192.0.2.100", "node100-uuid")])
436 890ea4ce Michael Hanselmann
    for i in [False, True, "", "Hello", 0, 1]:
437 890ea4ce Michael Hanselmann
      self.assertRaises(AssertionError, rpc._NodeConfigResolver,
438 890ea4ce Michael Hanselmann
                        fn, NotImplemented, ["node100.example.com"], i)
439 890ea4ce Michael Hanselmann
440 00267bfe Michael Hanselmann
  def testUnknownSingleNode(self):
441 00267bfe Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(lambda _: None, NotImplemented,
442 fce5efd1 Michael Hanselmann
                                             ["node110.example.com"], None),
443 1c3231aa Thomas Thrainer
                     [("node110.example.com", "node110.example.com",
444 1c3231aa Thomas Thrainer
                       "node110.example.com")])
445 00267bfe Michael Hanselmann
446 00267bfe Michael Hanselmann
  def testMultiEmpty(self):
447 00267bfe Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(NotImplemented,
448 00267bfe Michael Hanselmann
                                             lambda: {},
449 fce5efd1 Michael Hanselmann
                                             [], None),
450 00267bfe Michael Hanselmann
                     [])
451 00267bfe Michael Hanselmann
452 00267bfe Michael Hanselmann
  def testMultiSomeOffline(self):
453 1c3231aa Thomas Thrainer
    nodes = dict(("node%s-uuid" % i,
454 00267bfe Michael Hanselmann
                  objects.Node(name="node%s.example.com" % i,
455 00267bfe Michael Hanselmann
                               offline=((i % 3) == 0),
456 1c3231aa Thomas Thrainer
                               primary_ip="192.0.2.%s" % i,
457 1c3231aa Thomas Thrainer
                               uuid="node%s-uuid" % i))
458 00267bfe Michael Hanselmann
                  for i in range(1, 255))
459 00267bfe Michael Hanselmann
460 00267bfe Michael Hanselmann
    # Resolve no names
461 00267bfe Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(NotImplemented,
462 00267bfe Michael Hanselmann
                                             lambda: nodes,
463 fce5efd1 Michael Hanselmann
                                             [], None),
464 00267bfe Michael Hanselmann
                     [])
465 00267bfe Michael Hanselmann
466 00267bfe Michael Hanselmann
    # Offline, online and unknown hosts
467 00267bfe Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(NotImplemented,
468 00267bfe Michael Hanselmann
                                             lambda: nodes,
469 1c3231aa Thomas Thrainer
                                             ["node3-uuid",
470 1c3231aa Thomas Thrainer
                                              "node92-uuid",
471 1c3231aa Thomas Thrainer
                                              "node54-uuid",
472 fce5efd1 Michael Hanselmann
                                              "unknown.example.com",],
473 fce5efd1 Michael Hanselmann
                                             None), [
474 1c3231aa Thomas Thrainer
      ("node3.example.com", rpc._OFFLINE, "node3-uuid"),
475 1c3231aa Thomas Thrainer
      ("node92.example.com", "192.0.2.92", "node92-uuid"),
476 1c3231aa Thomas Thrainer
      ("node54.example.com", rpc._OFFLINE, "node54-uuid"),
477 1c3231aa Thomas Thrainer
      ("unknown.example.com", "unknown.example.com", "unknown.example.com"),
478 00267bfe Michael Hanselmann
      ])
479 b43dcc5a Manuel Franceschini
480 33231500 Michael Hanselmann
481 120e7e77 Michael Hanselmann
class TestCompress(unittest.TestCase):
482 120e7e77 Michael Hanselmann
  def test(self):
483 120e7e77 Michael Hanselmann
    for data in ["", "Hello", "Hello World!\nnew\nlines"]:
484 3d835d1b Thomas Thrainer
      self.assertEqual(rpc._Compress(NotImplemented, data),
485 120e7e77 Michael Hanselmann
                       (constants.RPC_ENCODING_NONE, data))
486 120e7e77 Michael Hanselmann
487 120e7e77 Michael Hanselmann
    for data in [512 * " ", 5242 * "Hello World!\n"]:
488 3d835d1b Thomas Thrainer
      compressed = rpc._Compress(NotImplemented, data)
489 120e7e77 Michael Hanselmann
      self.assertEqual(len(compressed), 2)
490 120e7e77 Michael Hanselmann
      self.assertEqual(backend._Decompress(compressed), data)
491 120e7e77 Michael Hanselmann
492 120e7e77 Michael Hanselmann
  def testDecompression(self):
493 120e7e77 Michael Hanselmann
    self.assertRaises(AssertionError, backend._Decompress, "")
494 120e7e77 Michael Hanselmann
    self.assertRaises(AssertionError, backend._Decompress, [""])
495 120e7e77 Michael Hanselmann
    self.assertRaises(AssertionError, backend._Decompress,
496 120e7e77 Michael Hanselmann
                      ("unknown compression", "data"))
497 120e7e77 Michael Hanselmann
    self.assertRaises(Exception, backend._Decompress,
498 120e7e77 Michael Hanselmann
                      (constants.RPC_ENCODING_ZLIB_BASE64, "invalid zlib data"))
499 120e7e77 Michael Hanselmann
500 120e7e77 Michael Hanselmann
501 065be3f0 Michael Hanselmann
class TestRpcClientBase(unittest.TestCase):
502 065be3f0 Michael Hanselmann
  def testNoHosts(self):
503 2ff587d4 Agata Murawska
    cdef = ("test_call", NotImplemented, None, constants.RPC_TMO_SLOW, [],
504 065be3f0 Michael Hanselmann
            None, None, NotImplemented)
505 065be3f0 Michael Hanselmann
    http_proc = _FakeRequestProcessor(NotImplemented)
506 065be3f0 Michael Hanselmann
    client = rpc._RpcClientBase(rpc._StaticResolver([]), NotImplemented,
507 065be3f0 Michael Hanselmann
                                _req_process_fn=http_proc)
508 065be3f0 Michael Hanselmann
    self.assertEqual(client._Call(cdef, [], []), {})
509 065be3f0 Michael Hanselmann
510 065be3f0 Michael Hanselmann
    # Test wrong number of arguments
511 065be3f0 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, client._Call,
512 065be3f0 Michael Hanselmann
                      cdef, [], [0, 1, 2])
513 065be3f0 Michael Hanselmann
514 065be3f0 Michael Hanselmann
  def testTimeout(self):
515 065be3f0 Michael Hanselmann
    def _CalcTimeout((arg1, arg2)):
516 065be3f0 Michael Hanselmann
      return arg1 + arg2
517 065be3f0 Michael Hanselmann
518 065be3f0 Michael Hanselmann
    def _VerifyRequest(exp_timeout, req):
519 065be3f0 Michael Hanselmann
      self.assertEqual(req.read_timeout, exp_timeout)
520 065be3f0 Michael Hanselmann
521 065be3f0 Michael Hanselmann
      req.success = True
522 065be3f0 Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
523 065be3f0 Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, hex(req.read_timeout)))
524 065be3f0 Michael Hanselmann
525 065be3f0 Michael Hanselmann
    resolver = rpc._StaticResolver([
526 065be3f0 Michael Hanselmann
      "192.0.2.1",
527 065be3f0 Michael Hanselmann
      "192.0.2.2",
528 065be3f0 Michael Hanselmann
      ])
529 065be3f0 Michael Hanselmann
530 065be3f0 Michael Hanselmann
    nodes = [
531 065be3f0 Michael Hanselmann
      "node1.example.com",
532 065be3f0 Michael Hanselmann
      "node2.example.com",
533 065be3f0 Michael Hanselmann
      ]
534 065be3f0 Michael Hanselmann
535 065be3f0 Michael Hanselmann
    tests = [(100, None, 100), (30, None, 30)]
536 065be3f0 Michael Hanselmann
    tests.extend((_CalcTimeout, i, i + 300)
537 065be3f0 Michael Hanselmann
                 for i in [0, 5, 16485, 30516])
538 065be3f0 Michael Hanselmann
539 065be3f0 Michael Hanselmann
    for timeout, arg1, exp_timeout in tests:
540 065be3f0 Michael Hanselmann
      cdef = ("test_call", NotImplemented, None, timeout, [
541 065be3f0 Michael Hanselmann
        ("arg1", None, NotImplemented),
542 065be3f0 Michael Hanselmann
        ("arg2", None, NotImplemented),
543 065be3f0 Michael Hanselmann
        ], None, None, NotImplemented)
544 065be3f0 Michael Hanselmann
545 065be3f0 Michael Hanselmann
      http_proc = _FakeRequestProcessor(compat.partial(_VerifyRequest,
546 065be3f0 Michael Hanselmann
                                                       exp_timeout))
547 065be3f0 Michael Hanselmann
      client = rpc._RpcClientBase(resolver, NotImplemented,
548 065be3f0 Michael Hanselmann
                                  _req_process_fn=http_proc)
549 065be3f0 Michael Hanselmann
      result = client._Call(cdef, nodes, [arg1, 300])
550 065be3f0 Michael Hanselmann
      self.assertEqual(len(result), len(nodes))
551 065be3f0 Michael Hanselmann
      self.assertTrue(compat.all(not res.fail_msg and
552 065be3f0 Michael Hanselmann
                                 res.payload == hex(exp_timeout)
553 065be3f0 Michael Hanselmann
                                 for res in result.values()))
554 065be3f0 Michael Hanselmann
555 065be3f0 Michael Hanselmann
  def testArgumentEncoder(self):
556 065be3f0 Michael Hanselmann
    (AT1, AT2) = range(1, 3)
557 065be3f0 Michael Hanselmann
558 065be3f0 Michael Hanselmann
    resolver = rpc._StaticResolver([
559 065be3f0 Michael Hanselmann
      "192.0.2.5",
560 065be3f0 Michael Hanselmann
      "192.0.2.6",
561 065be3f0 Michael Hanselmann
      ])
562 065be3f0 Michael Hanselmann
563 065be3f0 Michael Hanselmann
    nodes = [
564 065be3f0 Michael Hanselmann
      "node5.example.com",
565 065be3f0 Michael Hanselmann
      "node6.example.com",
566 065be3f0 Michael Hanselmann
      ]
567 065be3f0 Michael Hanselmann
568 065be3f0 Michael Hanselmann
    encoders = {
569 3d835d1b Thomas Thrainer
      AT1: lambda _, value: hex(value),
570 3d835d1b Thomas Thrainer
      AT2: lambda _, value: hash(value),
571 065be3f0 Michael Hanselmann
      }
572 065be3f0 Michael Hanselmann
573 2ff587d4 Agata Murawska
    cdef = ("test_call", NotImplemented, None, constants.RPC_TMO_NORMAL, [
574 065be3f0 Michael Hanselmann
      ("arg0", None, NotImplemented),
575 065be3f0 Michael Hanselmann
      ("arg1", AT1, NotImplemented),
576 065be3f0 Michael Hanselmann
      ("arg1", AT2, NotImplemented),
577 065be3f0 Michael Hanselmann
      ], None, None, NotImplemented)
578 065be3f0 Michael Hanselmann
579 065be3f0 Michael Hanselmann
    def _VerifyRequest(req):
580 065be3f0 Michael Hanselmann
      req.success = True
581 065be3f0 Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
582 065be3f0 Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, req.post_data))
583 065be3f0 Michael Hanselmann
584 065be3f0 Michael Hanselmann
    http_proc = _FakeRequestProcessor(_VerifyRequest)
585 065be3f0 Michael Hanselmann
586 065be3f0 Michael Hanselmann
    for num in [0, 3796, 9032119]:
587 065be3f0 Michael Hanselmann
      client = rpc._RpcClientBase(resolver, encoders.get,
588 065be3f0 Michael Hanselmann
                                  _req_process_fn=http_proc)
589 065be3f0 Michael Hanselmann
      result = client._Call(cdef, nodes, ["foo", num, "Hello%s" % num])
590 065be3f0 Michael Hanselmann
      self.assertEqual(len(result), len(nodes))
591 065be3f0 Michael Hanselmann
      for res in result.values():
592 065be3f0 Michael Hanselmann
        self.assertFalse(res.fail_msg)
593 065be3f0 Michael Hanselmann
        self.assertEqual(serializer.LoadJson(res.payload),
594 065be3f0 Michael Hanselmann
                         ["foo", hex(num), hash("Hello%s" % num)])
595 065be3f0 Michael Hanselmann
596 065be3f0 Michael Hanselmann
  def testPostProc(self):
597 065be3f0 Michael Hanselmann
    def _VerifyRequest(nums, req):
598 065be3f0 Michael Hanselmann
      req.success = True
599 065be3f0 Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
600 065be3f0 Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, nums))
601 065be3f0 Michael Hanselmann
602 065be3f0 Michael Hanselmann
    resolver = rpc._StaticResolver([
603 065be3f0 Michael Hanselmann
      "192.0.2.90",
604 065be3f0 Michael Hanselmann
      "192.0.2.95",
605 065be3f0 Michael Hanselmann
      ])
606 065be3f0 Michael Hanselmann
607 065be3f0 Michael Hanselmann
    nodes = [
608 065be3f0 Michael Hanselmann
      "node90.example.com",
609 065be3f0 Michael Hanselmann
      "node95.example.com",
610 065be3f0 Michael Hanselmann
      ]
611 065be3f0 Michael Hanselmann
612 065be3f0 Michael Hanselmann
    def _PostProc(res):
613 065be3f0 Michael Hanselmann
      self.assertFalse(res.fail_msg)
614 065be3f0 Michael Hanselmann
      res.payload = sum(res.payload)
615 065be3f0 Michael Hanselmann
      return res
616 065be3f0 Michael Hanselmann
617 2ff587d4 Agata Murawska
    cdef = ("test_call", NotImplemented, None, constants.RPC_TMO_NORMAL, [],
618 065be3f0 Michael Hanselmann
            None, _PostProc, NotImplemented)
619 065be3f0 Michael Hanselmann
620 065be3f0 Michael Hanselmann
    # Seeded random generator
621 065be3f0 Michael Hanselmann
    rnd = random.Random(20299)
622 065be3f0 Michael Hanselmann
623 065be3f0 Michael Hanselmann
    for i in [0, 4, 74, 1391]:
624 065be3f0 Michael Hanselmann
      nums = [rnd.randint(0, 1000) for _ in range(i)]
625 065be3f0 Michael Hanselmann
      http_proc = _FakeRequestProcessor(compat.partial(_VerifyRequest, nums))
626 065be3f0 Michael Hanselmann
      client = rpc._RpcClientBase(resolver, NotImplemented,
627 065be3f0 Michael Hanselmann
                                  _req_process_fn=http_proc)
628 065be3f0 Michael Hanselmann
      result = client._Call(cdef, nodes, [])
629 065be3f0 Michael Hanselmann
      self.assertEqual(len(result), len(nodes))
630 065be3f0 Michael Hanselmann
      for res in result.values():
631 065be3f0 Michael Hanselmann
        self.assertFalse(res.fail_msg)
632 065be3f0 Michael Hanselmann
        self.assertEqual(res.payload, sum(nums))
633 065be3f0 Michael Hanselmann
634 065be3f0 Michael Hanselmann
  def testPreProc(self):
635 065be3f0 Michael Hanselmann
    def _VerifyRequest(req):
636 065be3f0 Michael Hanselmann
      req.success = True
637 065be3f0 Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
638 065be3f0 Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, req.post_data))
639 065be3f0 Michael Hanselmann
640 065be3f0 Michael Hanselmann
    resolver = rpc._StaticResolver([
641 065be3f0 Michael Hanselmann
      "192.0.2.30",
642 065be3f0 Michael Hanselmann
      "192.0.2.35",
643 065be3f0 Michael Hanselmann
      ])
644 065be3f0 Michael Hanselmann
645 065be3f0 Michael Hanselmann
    nodes = [
646 065be3f0 Michael Hanselmann
      "node30.example.com",
647 065be3f0 Michael Hanselmann
      "node35.example.com",
648 065be3f0 Michael Hanselmann
      ]
649 065be3f0 Michael Hanselmann
650 065be3f0 Michael Hanselmann
    def _PreProc(node, data):
651 065be3f0 Michael Hanselmann
      self.assertEqual(len(data), 1)
652 065be3f0 Michael Hanselmann
      return data[0] + node
653 065be3f0 Michael Hanselmann
654 2ff587d4 Agata Murawska
    cdef = ("test_call", NotImplemented, None, constants.RPC_TMO_NORMAL, [
655 065be3f0 Michael Hanselmann
      ("arg0", None, NotImplemented),
656 065be3f0 Michael Hanselmann
      ], _PreProc, None, NotImplemented)
657 065be3f0 Michael Hanselmann
658 065be3f0 Michael Hanselmann
    http_proc = _FakeRequestProcessor(_VerifyRequest)
659 065be3f0 Michael Hanselmann
    client = rpc._RpcClientBase(resolver, NotImplemented,
660 065be3f0 Michael Hanselmann
                                _req_process_fn=http_proc)
661 065be3f0 Michael Hanselmann
662 065be3f0 Michael Hanselmann
    for prefix in ["foo", "bar", "baz"]:
663 065be3f0 Michael Hanselmann
      result = client._Call(cdef, nodes, [prefix])
664 065be3f0 Michael Hanselmann
      self.assertEqual(len(result), len(nodes))
665 065be3f0 Michael Hanselmann
      for (idx, (node, res)) in enumerate(result.items()):
666 065be3f0 Michael Hanselmann
        self.assertFalse(res.fail_msg)
667 065be3f0 Michael Hanselmann
        self.assertEqual(serializer.LoadJson(res.payload), prefix + node)
668 065be3f0 Michael Hanselmann
669 065be3f0 Michael Hanselmann
  def testResolverOptions(self):
670 065be3f0 Michael Hanselmann
    def _VerifyRequest(req):
671 065be3f0 Michael Hanselmann
      req.success = True
672 065be3f0 Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
673 065be3f0 Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, req.post_data))
674 065be3f0 Michael Hanselmann
675 065be3f0 Michael Hanselmann
    nodes = [
676 065be3f0 Michael Hanselmann
      "node30.example.com",
677 065be3f0 Michael Hanselmann
      "node35.example.com",
678 065be3f0 Michael Hanselmann
      ]
679 065be3f0 Michael Hanselmann
680 065be3f0 Michael Hanselmann
    def _Resolver(expected, hosts, options):
681 065be3f0 Michael Hanselmann
      self.assertEqual(hosts, nodes)
682 065be3f0 Michael Hanselmann
      self.assertEqual(options, expected)
683 1c3231aa Thomas Thrainer
      return zip(hosts, nodes, hosts)
684 065be3f0 Michael Hanselmann
685 065be3f0 Michael Hanselmann
    def _DynamicResolverOptions((arg0, )):
686 065be3f0 Michael Hanselmann
      return sum(arg0)
687 065be3f0 Michael Hanselmann
688 065be3f0 Michael Hanselmann
    tests = [
689 065be3f0 Michael Hanselmann
      (None, None, None),
690 065be3f0 Michael Hanselmann
      (rpc_defs.ACCEPT_OFFLINE_NODE, None, rpc_defs.ACCEPT_OFFLINE_NODE),
691 065be3f0 Michael Hanselmann
      (False, None, False),
692 065be3f0 Michael Hanselmann
      (True, None, True),
693 065be3f0 Michael Hanselmann
      (0, None, 0),
694 065be3f0 Michael Hanselmann
      (_DynamicResolverOptions, [1, 2, 3], 6),
695 065be3f0 Michael Hanselmann
      (_DynamicResolverOptions, range(4, 19), 165),
696 065be3f0 Michael Hanselmann
      ]
697 065be3f0 Michael Hanselmann
698 065be3f0 Michael Hanselmann
    for (resolver_opts, arg0, expected) in tests:
699 2ff587d4 Agata Murawska
      cdef = ("test_call", NotImplemented, resolver_opts,
700 2ff587d4 Agata Murawska
              constants.RPC_TMO_NORMAL, [
701 065be3f0 Michael Hanselmann
        ("arg0", None, NotImplemented),
702 065be3f0 Michael Hanselmann
        ], None, None, NotImplemented)
703 065be3f0 Michael Hanselmann
704 065be3f0 Michael Hanselmann
      http_proc = _FakeRequestProcessor(_VerifyRequest)
705 065be3f0 Michael Hanselmann
706 065be3f0 Michael Hanselmann
      client = rpc._RpcClientBase(compat.partial(_Resolver, expected),
707 065be3f0 Michael Hanselmann
                                  NotImplemented, _req_process_fn=http_proc)
708 065be3f0 Michael Hanselmann
      result = client._Call(cdef, nodes, [arg0])
709 065be3f0 Michael Hanselmann
      self.assertEqual(len(result), len(nodes))
710 065be3f0 Michael Hanselmann
      for (idx, (node, res)) in enumerate(result.items()):
711 065be3f0 Michael Hanselmann
        self.assertFalse(res.fail_msg)
712 065be3f0 Michael Hanselmann
713 065be3f0 Michael Hanselmann
714 601dfcbb Michael Hanselmann
class _FakeConfigForRpcRunner:
715 601dfcbb Michael Hanselmann
  GetAllNodesInfo = NotImplemented
716 601dfcbb Michael Hanselmann
717 7e6b6f1f Michael Hanselmann
  def __init__(self, cluster=NotImplemented):
718 7e6b6f1f Michael Hanselmann
    self._cluster = cluster
719 7e6b6f1f Michael Hanselmann
720 601dfcbb Michael Hanselmann
  def GetNodeInfo(self, name):
721 601dfcbb Michael Hanselmann
    return objects.Node(name=name)
722 601dfcbb Michael Hanselmann
723 3d835d1b Thomas Thrainer
  def GetMultiNodeInfo(self, names):
724 3d835d1b Thomas Thrainer
    return [(name, self.GetNodeInfo(name)) for name in names]
725 3d835d1b Thomas Thrainer
726 7e6b6f1f Michael Hanselmann
  def GetClusterInfo(self):
727 7e6b6f1f Michael Hanselmann
    return self._cluster
728 7e6b6f1f Michael Hanselmann
729 19fe9138 René Nussbaumer
  def GetInstanceDiskParams(self, _):
730 19fe9138 René Nussbaumer
    return constants.DISK_DT_DEFAULTS
731 19fe9138 René Nussbaumer
732 601dfcbb Michael Hanselmann
733 065be3f0 Michael Hanselmann
class TestRpcRunner(unittest.TestCase):
734 065be3f0 Michael Hanselmann
  def testUploadFile(self):
735 601dfcbb Michael Hanselmann
    data = 1779 * "Hello World\n"
736 601dfcbb Michael Hanselmann
737 601dfcbb Michael Hanselmann
    tmpfile = tempfile.NamedTemporaryFile()
738 601dfcbb Michael Hanselmann
    tmpfile.write(data)
739 601dfcbb Michael Hanselmann
    tmpfile.flush()
740 601dfcbb Michael Hanselmann
    st = os.stat(tmpfile.name)
741 601dfcbb Michael Hanselmann
742 3d835d1b Thomas Thrainer
    nodes = [
743 3d835d1b Thomas Thrainer
      "node1.example.com",
744 3d835d1b Thomas Thrainer
      ]
745 3d835d1b Thomas Thrainer
746 601dfcbb Michael Hanselmann
    def _VerifyRequest(req):
747 601dfcbb Michael Hanselmann
      (uldata, ) = serializer.LoadJson(req.post_data)
748 601dfcbb Michael Hanselmann
      self.assertEqual(len(uldata), 7)
749 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[0], tmpfile.name)
750 3d835d1b Thomas Thrainer
      self.assertEqual(list(uldata[1]), list(rpc._Compress(nodes[0], data)))
751 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[2], st.st_mode)
752 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[3], "user%s" % os.getuid())
753 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[4], "group%s" % os.getgid())
754 7e6b6f1f Michael Hanselmann
      self.assertTrue(uldata[5] is not None)
755 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[6], st.st_mtime)
756 601dfcbb Michael Hanselmann
757 601dfcbb Michael Hanselmann
      req.success = True
758 601dfcbb Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
759 601dfcbb Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, None))
760 601dfcbb Michael Hanselmann
761 601dfcbb Michael Hanselmann
    http_proc = _FakeRequestProcessor(_VerifyRequest)
762 c2dc025a Michael Hanselmann
763 c2dc025a Michael Hanselmann
    std_runner = rpc.RpcRunner(_FakeConfigForRpcRunner(), None,
764 c2dc025a Michael Hanselmann
                               _req_process_fn=http_proc,
765 c2dc025a Michael Hanselmann
                               _getents=mocks.FakeGetentResolver)
766 c2dc025a Michael Hanselmann
767 c2dc025a Michael Hanselmann
    cfg_runner = rpc.ConfigRunner(None, ["192.0.2.13"],
768 c2dc025a Michael Hanselmann
                                  _req_process_fn=http_proc,
769 c2dc025a Michael Hanselmann
                                  _getents=mocks.FakeGetentResolver)
770 601dfcbb Michael Hanselmann
771 c2dc025a Michael Hanselmann
    for runner in [std_runner, cfg_runner]:
772 c2dc025a Michael Hanselmann
      result = runner.call_upload_file(nodes, tmpfile.name)
773 c2dc025a Michael Hanselmann
      self.assertEqual(len(result), len(nodes))
774 c2dc025a Michael Hanselmann
      for (idx, (node, res)) in enumerate(result.items()):
775 c2dc025a Michael Hanselmann
        self.assertFalse(res.fail_msg)
776 065be3f0 Michael Hanselmann
777 7e6b6f1f Michael Hanselmann
  def testEncodeInstance(self):
778 7e6b6f1f Michael Hanselmann
    cluster = objects.Cluster(hvparams={
779 7e6b6f1f Michael Hanselmann
      constants.HT_KVM: {
780 7e6b6f1f Michael Hanselmann
        constants.HV_BLOCKDEV_PREFIX: "foo",
781 7e6b6f1f Michael Hanselmann
        },
782 7e6b6f1f Michael Hanselmann
      },
783 7e6b6f1f Michael Hanselmann
      beparams={
784 7e6b6f1f Michael Hanselmann
        constants.PP_DEFAULT: {
785 7e6b6f1f Michael Hanselmann
          constants.BE_MAXMEM: 8192,
786 7e6b6f1f Michael Hanselmann
          },
787 7e6b6f1f Michael Hanselmann
        },
788 7e6b6f1f Michael Hanselmann
      os_hvp={},
789 7e6b6f1f Michael Hanselmann
      osparams={
790 7e6b6f1f Michael Hanselmann
        "linux": {
791 7e6b6f1f Michael Hanselmann
          "role": "unknown",
792 7e6b6f1f Michael Hanselmann
          },
793 7e6b6f1f Michael Hanselmann
        })
794 7e6b6f1f Michael Hanselmann
    cluster.UpgradeConfig()
795 7e6b6f1f Michael Hanselmann
796 7e6b6f1f Michael Hanselmann
    inst = objects.Instance(name="inst1.example.com",
797 7e6b6f1f Michael Hanselmann
      hypervisor=constants.HT_FAKE,
798 7e6b6f1f Michael Hanselmann
      os="linux",
799 7e6b6f1f Michael Hanselmann
      hvparams={
800 7e6b6f1f Michael Hanselmann
        constants.HT_KVM: {
801 7e6b6f1f Michael Hanselmann
          constants.HV_BLOCKDEV_PREFIX: "bar",
802 7e6b6f1f Michael Hanselmann
          constants.HV_ROOT_PATH: "/tmp",
803 7e6b6f1f Michael Hanselmann
          },
804 7e6b6f1f Michael Hanselmann
        },
805 7e6b6f1f Michael Hanselmann
      beparams={
806 7e6b6f1f Michael Hanselmann
        constants.BE_MINMEM: 128,
807 7e6b6f1f Michael Hanselmann
        constants.BE_MAXMEM: 256,
808 7e6b6f1f Michael Hanselmann
        },
809 7e6b6f1f Michael Hanselmann
      nics=[
810 7e6b6f1f Michael Hanselmann
        objects.NIC(nicparams={
811 7e6b6f1f Michael Hanselmann
          constants.NIC_MODE: "mymode",
812 7e6b6f1f Michael Hanselmann
          }),
813 7e6b6f1f Michael Hanselmann
        ],
814 0e2b7c58 Michael Hanselmann
      disk_template=constants.DT_PLAIN,
815 0e2b7c58 Michael Hanselmann
      disks=[
816 cd3b4ff4 Helga Velroyen
        objects.Disk(dev_type=constants.DT_PLAIN, size=4096,
817 0e2b7c58 Michael Hanselmann
                     logical_id=("vg", "disk6120")),
818 cd3b4ff4 Helga Velroyen
        objects.Disk(dev_type=constants.DT_PLAIN, size=1024,
819 0e2b7c58 Michael Hanselmann
                     logical_id=("vg", "disk8508")),
820 0e2b7c58 Michael Hanselmann
        ])
821 7e6b6f1f Michael Hanselmann
    inst.UpgradeConfig()
822 7e6b6f1f Michael Hanselmann
823 7e6b6f1f Michael Hanselmann
    cfg = _FakeConfigForRpcRunner(cluster=cluster)
824 7e6b6f1f Michael Hanselmann
    runner = rpc.RpcRunner(cfg, None,
825 7e6b6f1f Michael Hanselmann
                           _req_process_fn=NotImplemented,
826 7e6b6f1f Michael Hanselmann
                           _getents=mocks.FakeGetentResolver)
827 7e6b6f1f Michael Hanselmann
828 7e6b6f1f Michael Hanselmann
    def _CheckBasics(result):
829 7e6b6f1f Michael Hanselmann
      self.assertEqual(result["name"], "inst1.example.com")
830 7e6b6f1f Michael Hanselmann
      self.assertEqual(result["os"], "linux")
831 7e6b6f1f Michael Hanselmann
      self.assertEqual(result["beparams"][constants.BE_MINMEM], 128)
832 7e6b6f1f Michael Hanselmann
      self.assertEqual(len(result["hvparams"]), 1)
833 7e6b6f1f Michael Hanselmann
      self.assertEqual(len(result["nics"]), 1)
834 7e6b6f1f Michael Hanselmann
      self.assertEqual(result["nics"][0]["nicparams"][constants.NIC_MODE],
835 7e6b6f1f Michael Hanselmann
                       "mymode")
836 7e6b6f1f Michael Hanselmann
837 7e6b6f1f Michael Hanselmann
    # Generic object serialization
838 3d835d1b Thomas Thrainer
    result = runner._encoder(NotImplemented, (rpc_defs.ED_OBJECT_DICT, inst))
839 7e6b6f1f Michael Hanselmann
    _CheckBasics(result)
840 7e6b6f1f Michael Hanselmann
841 3d835d1b Thomas Thrainer
    result = runner._encoder(NotImplemented,
842 3d835d1b Thomas Thrainer
                             (rpc_defs.ED_OBJECT_DICT_LIST, 5 * [inst]))
843 7e6b6f1f Michael Hanselmann
    map(_CheckBasics, result)
844 7e6b6f1f Michael Hanselmann
845 7e6b6f1f Michael Hanselmann
    # Just an instance
846 3d835d1b Thomas Thrainer
    result = runner._encoder(NotImplemented, (rpc_defs.ED_INST_DICT, inst))
847 7e6b6f1f Michael Hanselmann
    _CheckBasics(result)
848 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["beparams"][constants.BE_MAXMEM], 256)
849 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["hvparams"][constants.HT_KVM], {
850 7e6b6f1f Michael Hanselmann
      constants.HV_BLOCKDEV_PREFIX: "bar",
851 7e6b6f1f Michael Hanselmann
      constants.HV_ROOT_PATH: "/tmp",
852 7e6b6f1f Michael Hanselmann
      })
853 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["osparams"], {
854 7e6b6f1f Michael Hanselmann
      "role": "unknown",
855 7e6b6f1f Michael Hanselmann
      })
856 7e6b6f1f Michael Hanselmann
857 7e6b6f1f Michael Hanselmann
    # Instance with OS parameters
858 3d835d1b Thomas Thrainer
    result = runner._encoder(NotImplemented,
859 3d835d1b Thomas Thrainer
                             (rpc_defs.ED_INST_DICT_OSP_DP, (inst, {
860 3d835d1b Thomas Thrainer
                               "role": "webserver",
861 3d835d1b Thomas Thrainer
                               "other": "field",
862 3d835d1b Thomas Thrainer
                             })))
863 7e6b6f1f Michael Hanselmann
    _CheckBasics(result)
864 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["beparams"][constants.BE_MAXMEM], 256)
865 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["hvparams"][constants.HT_KVM], {
866 7e6b6f1f Michael Hanselmann
      constants.HV_BLOCKDEV_PREFIX: "bar",
867 7e6b6f1f Michael Hanselmann
      constants.HV_ROOT_PATH: "/tmp",
868 7e6b6f1f Michael Hanselmann
      })
869 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["osparams"], {
870 7e6b6f1f Michael Hanselmann
      "role": "webserver",
871 7e6b6f1f Michael Hanselmann
      "other": "field",
872 7e6b6f1f Michael Hanselmann
      })
873 7e6b6f1f Michael Hanselmann
874 7e6b6f1f Michael Hanselmann
    # Instance with hypervisor and backend parameters
875 3d835d1b Thomas Thrainer
    result = runner._encoder(NotImplemented,
876 3d835d1b Thomas Thrainer
                             (rpc_defs.ED_INST_DICT_HVP_BEP_DP, (inst, {
877 7e6b6f1f Michael Hanselmann
      constants.HT_KVM: {
878 7e6b6f1f Michael Hanselmann
        constants.HV_BOOT_ORDER: "xyz",
879 7e6b6f1f Michael Hanselmann
        },
880 7e6b6f1f Michael Hanselmann
      }, {
881 7e6b6f1f Michael Hanselmann
      constants.BE_VCPUS: 100,
882 7e6b6f1f Michael Hanselmann
      constants.BE_MAXMEM: 4096,
883 7e6b6f1f Michael Hanselmann
      })))
884 7e6b6f1f Michael Hanselmann
    _CheckBasics(result)
885 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["beparams"][constants.BE_MAXMEM], 4096)
886 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["beparams"][constants.BE_VCPUS], 100)
887 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["hvparams"][constants.HT_KVM], {
888 7e6b6f1f Michael Hanselmann
      constants.HV_BOOT_ORDER: "xyz",
889 7e6b6f1f Michael Hanselmann
      })
890 0e2b7c58 Michael Hanselmann
    self.assertEqual(result["disks"], [{
891 cd3b4ff4 Helga Velroyen
      "dev_type": constants.DT_PLAIN,
892 3d835d1b Thomas Thrainer
      "dynamic_params": {},
893 0e2b7c58 Michael Hanselmann
      "size": 4096,
894 0e2b7c58 Michael Hanselmann
      "logical_id": ("vg", "disk6120"),
895 0e2b7c58 Michael Hanselmann
      "params": constants.DISK_DT_DEFAULTS[inst.disk_template],
896 0e2b7c58 Michael Hanselmann
      }, {
897 cd3b4ff4 Helga Velroyen
      "dev_type": constants.DT_PLAIN,
898 3d835d1b Thomas Thrainer
      "dynamic_params": {},
899 0e2b7c58 Michael Hanselmann
      "size": 1024,
900 0e2b7c58 Michael Hanselmann
      "logical_id": ("vg", "disk8508"),
901 0e2b7c58 Michael Hanselmann
      "params": constants.DISK_DT_DEFAULTS[inst.disk_template],
902 0e2b7c58 Michael Hanselmann
      }])
903 0e2b7c58 Michael Hanselmann
904 0e2b7c58 Michael Hanselmann
    self.assertTrue(compat.all(disk.params == {} for disk in inst.disks),
905 0e2b7c58 Michael Hanselmann
                    msg="Configuration objects were modified")
906 7e6b6f1f Michael Hanselmann
907 065be3f0 Michael Hanselmann
908 91c17910 Iustin Pop
class TestLegacyNodeInfo(unittest.TestCase):
909 91c17910 Iustin Pop
  KEY_BOOT = "bootid"
910 4d1429e4 Helga Velroyen
  KEY_NAME = "name"
911 4d1429e4 Helga Velroyen
  KEY_STORAGE_FREE = "storage_free"
912 4d1429e4 Helga Velroyen
  KEY_STORAGE_TOTAL = "storage_size"
913 4d1429e4 Helga Velroyen
  KEY_CPU_COUNT = "cpu_count"
914 4d1429e4 Helga Velroyen
  KEY_SPINDLES_FREE = "spindles_free"
915 4d1429e4 Helga Velroyen
  KEY_SPINDLES_TOTAL = "spindles_total"
916 4d1429e4 Helga Velroyen
  KEY_STORAGE_TYPE = "type" # key for storage type
917 91c17910 Iustin Pop
  VAL_BOOT = 0
918 4d1429e4 Helga Velroyen
  VAL_VG_NAME = "xy"
919 4d1429e4 Helga Velroyen
  VAL_VG_FREE = 11
920 4d1429e4 Helga Velroyen
  VAL_VG_TOTAL = 12
921 4d1429e4 Helga Velroyen
  VAL_VG_TYPE = "lvm-vg"
922 4d1429e4 Helga Velroyen
  VAL_CPU_COUNT = 2
923 4d1429e4 Helga Velroyen
  VAL_PV_NAME = "ab"
924 4d1429e4 Helga Velroyen
  VAL_PV_FREE = 31
925 4d1429e4 Helga Velroyen
  VAL_PV_TOTAL = 32
926 4d1429e4 Helga Velroyen
  VAL_PV_TYPE = "lvm-pv"
927 06fb92cf Bernardo Dal Seno
  DICT_VG = {
928 4d1429e4 Helga Velroyen
    KEY_NAME: VAL_VG_NAME,
929 4d1429e4 Helga Velroyen
    KEY_STORAGE_FREE: VAL_VG_FREE,
930 4d1429e4 Helga Velroyen
    KEY_STORAGE_TOTAL: VAL_VG_TOTAL,
931 4d1429e4 Helga Velroyen
    KEY_STORAGE_TYPE: VAL_VG_TYPE,
932 06fb92cf Bernardo Dal Seno
    }
933 4d1429e4 Helga Velroyen
  DICT_HV = {KEY_CPU_COUNT: VAL_CPU_COUNT}
934 06fb92cf Bernardo Dal Seno
  DICT_SP = {
935 4d1429e4 Helga Velroyen
    KEY_STORAGE_TYPE: VAL_PV_TYPE,
936 4d1429e4 Helga Velroyen
    KEY_NAME: VAL_PV_NAME,
937 4d1429e4 Helga Velroyen
    KEY_STORAGE_FREE: VAL_PV_FREE,
938 4d1429e4 Helga Velroyen
    KEY_STORAGE_TOTAL: VAL_PV_TOTAL,
939 06fb92cf Bernardo Dal Seno
    }
940 06fb92cf Bernardo Dal Seno
  STD_LST = [VAL_BOOT, [DICT_VG, DICT_SP], [DICT_HV]]
941 91c17910 Iustin Pop
  STD_DICT = {
942 91c17910 Iustin Pop
    KEY_BOOT: VAL_BOOT,
943 4d1429e4 Helga Velroyen
    KEY_NAME: VAL_VG_NAME,
944 4d1429e4 Helga Velroyen
    KEY_STORAGE_FREE: VAL_VG_FREE,
945 4d1429e4 Helga Velroyen
    KEY_STORAGE_TOTAL: VAL_VG_TOTAL,
946 6c00b2c7 Helga Velroyen
    KEY_SPINDLES_FREE: VAL_PV_FREE,
947 6c00b2c7 Helga Velroyen
    KEY_SPINDLES_TOTAL: VAL_PV_TOTAL,
948 4d1429e4 Helga Velroyen
    KEY_CPU_COUNT: VAL_CPU_COUNT,
949 91c17910 Iustin Pop
    }
950 91c17910 Iustin Pop
951 6c00b2c7 Helga Velroyen
  def testWithSpindles(self):
952 6c00b2c7 Helga Velroyen
    result = rpc.MakeLegacyNodeInfo(self.STD_LST, constants.DT_PLAIN)
953 91c17910 Iustin Pop
    self.assertEqual(result, self.STD_DICT)
954 91c17910 Iustin Pop
955 6c00b2c7 Helga Velroyen
  def testNoSpindles(self):
956 6c00b2c7 Helga Velroyen
    my_lst = [self.VAL_BOOT, [self.DICT_VG], [self.DICT_HV]]
957 6c00b2c7 Helga Velroyen
    result = rpc.MakeLegacyNodeInfo(my_lst, constants.DT_PLAIN)
958 6c00b2c7 Helga Velroyen
    expected_dict = dict((k,v) for k, v in self.STD_DICT.iteritems())
959 6c00b2c7 Helga Velroyen
    expected_dict[self.KEY_SPINDLES_FREE] = 0
960 6c00b2c7 Helga Velroyen
    expected_dict[self.KEY_SPINDLES_TOTAL] = 0
961 6c00b2c7 Helga Velroyen
    self.assertEqual(result, expected_dict)
962 b844311b Helga Velroyen
963 b844311b Helga Velroyen
964 33231500 Michael Hanselmann
if __name__ == "__main__":
965 33231500 Michael Hanselmann
  testutils.GanetiTestProgram()