Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.rpc_unittest.py @ cd3b4ff4

History | View | Annotate | Download (34.4 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 120e7e77 Michael Hanselmann
      self.assertEqual(rpc._Compress(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 120e7e77 Michael Hanselmann
      compressed = rpc._Compress(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 065be3f0 Michael Hanselmann
      AT1: hex,
570 065be3f0 Michael Hanselmann
      AT2: hash,
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 7e6b6f1f Michael Hanselmann
  def GetClusterInfo(self):
724 7e6b6f1f Michael Hanselmann
    return self._cluster
725 7e6b6f1f Michael Hanselmann
726 19fe9138 René Nussbaumer
  def GetInstanceDiskParams(self, _):
727 19fe9138 René Nussbaumer
    return constants.DISK_DT_DEFAULTS
728 19fe9138 René Nussbaumer
729 601dfcbb Michael Hanselmann
730 065be3f0 Michael Hanselmann
class TestRpcRunner(unittest.TestCase):
731 065be3f0 Michael Hanselmann
  def testUploadFile(self):
732 601dfcbb Michael Hanselmann
    data = 1779 * "Hello World\n"
733 601dfcbb Michael Hanselmann
734 601dfcbb Michael Hanselmann
    tmpfile = tempfile.NamedTemporaryFile()
735 601dfcbb Michael Hanselmann
    tmpfile.write(data)
736 601dfcbb Michael Hanselmann
    tmpfile.flush()
737 601dfcbb Michael Hanselmann
    st = os.stat(tmpfile.name)
738 601dfcbb Michael Hanselmann
739 601dfcbb Michael Hanselmann
    def _VerifyRequest(req):
740 601dfcbb Michael Hanselmann
      (uldata, ) = serializer.LoadJson(req.post_data)
741 601dfcbb Michael Hanselmann
      self.assertEqual(len(uldata), 7)
742 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[0], tmpfile.name)
743 601dfcbb Michael Hanselmann
      self.assertEqual(list(uldata[1]), list(rpc._Compress(data)))
744 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[2], st.st_mode)
745 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[3], "user%s" % os.getuid())
746 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[4], "group%s" % os.getgid())
747 7e6b6f1f Michael Hanselmann
      self.assertTrue(uldata[5] is not None)
748 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[6], st.st_mtime)
749 601dfcbb Michael Hanselmann
750 601dfcbb Michael Hanselmann
      req.success = True
751 601dfcbb Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
752 601dfcbb Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, None))
753 601dfcbb Michael Hanselmann
754 601dfcbb Michael Hanselmann
    http_proc = _FakeRequestProcessor(_VerifyRequest)
755 c2dc025a Michael Hanselmann
756 c2dc025a Michael Hanselmann
    std_runner = rpc.RpcRunner(_FakeConfigForRpcRunner(), None,
757 c2dc025a Michael Hanselmann
                               _req_process_fn=http_proc,
758 c2dc025a Michael Hanselmann
                               _getents=mocks.FakeGetentResolver)
759 c2dc025a Michael Hanselmann
760 c2dc025a Michael Hanselmann
    cfg_runner = rpc.ConfigRunner(None, ["192.0.2.13"],
761 c2dc025a Michael Hanselmann
                                  _req_process_fn=http_proc,
762 c2dc025a Michael Hanselmann
                                  _getents=mocks.FakeGetentResolver)
763 601dfcbb Michael Hanselmann
764 601dfcbb Michael Hanselmann
    nodes = [
765 601dfcbb Michael Hanselmann
      "node1.example.com",
766 601dfcbb Michael Hanselmann
      ]
767 601dfcbb Michael Hanselmann
768 c2dc025a Michael Hanselmann
    for runner in [std_runner, cfg_runner]:
769 c2dc025a Michael Hanselmann
      result = runner.call_upload_file(nodes, tmpfile.name)
770 c2dc025a Michael Hanselmann
      self.assertEqual(len(result), len(nodes))
771 c2dc025a Michael Hanselmann
      for (idx, (node, res)) in enumerate(result.items()):
772 c2dc025a Michael Hanselmann
        self.assertFalse(res.fail_msg)
773 065be3f0 Michael Hanselmann
774 7e6b6f1f Michael Hanselmann
  def testEncodeInstance(self):
775 7e6b6f1f Michael Hanselmann
    cluster = objects.Cluster(hvparams={
776 7e6b6f1f Michael Hanselmann
      constants.HT_KVM: {
777 7e6b6f1f Michael Hanselmann
        constants.HV_BLOCKDEV_PREFIX: "foo",
778 7e6b6f1f Michael Hanselmann
        },
779 7e6b6f1f Michael Hanselmann
      },
780 7e6b6f1f Michael Hanselmann
      beparams={
781 7e6b6f1f Michael Hanselmann
        constants.PP_DEFAULT: {
782 7e6b6f1f Michael Hanselmann
          constants.BE_MAXMEM: 8192,
783 7e6b6f1f Michael Hanselmann
          },
784 7e6b6f1f Michael Hanselmann
        },
785 7e6b6f1f Michael Hanselmann
      os_hvp={},
786 7e6b6f1f Michael Hanselmann
      osparams={
787 7e6b6f1f Michael Hanselmann
        "linux": {
788 7e6b6f1f Michael Hanselmann
          "role": "unknown",
789 7e6b6f1f Michael Hanselmann
          },
790 7e6b6f1f Michael Hanselmann
        })
791 7e6b6f1f Michael Hanselmann
    cluster.UpgradeConfig()
792 7e6b6f1f Michael Hanselmann
793 7e6b6f1f Michael Hanselmann
    inst = objects.Instance(name="inst1.example.com",
794 7e6b6f1f Michael Hanselmann
      hypervisor=constants.HT_FAKE,
795 7e6b6f1f Michael Hanselmann
      os="linux",
796 7e6b6f1f Michael Hanselmann
      hvparams={
797 7e6b6f1f Michael Hanselmann
        constants.HT_KVM: {
798 7e6b6f1f Michael Hanselmann
          constants.HV_BLOCKDEV_PREFIX: "bar",
799 7e6b6f1f Michael Hanselmann
          constants.HV_ROOT_PATH: "/tmp",
800 7e6b6f1f Michael Hanselmann
          },
801 7e6b6f1f Michael Hanselmann
        },
802 7e6b6f1f Michael Hanselmann
      beparams={
803 7e6b6f1f Michael Hanselmann
        constants.BE_MINMEM: 128,
804 7e6b6f1f Michael Hanselmann
        constants.BE_MAXMEM: 256,
805 7e6b6f1f Michael Hanselmann
        },
806 7e6b6f1f Michael Hanselmann
      nics=[
807 7e6b6f1f Michael Hanselmann
        objects.NIC(nicparams={
808 7e6b6f1f Michael Hanselmann
          constants.NIC_MODE: "mymode",
809 7e6b6f1f Michael Hanselmann
          }),
810 7e6b6f1f Michael Hanselmann
        ],
811 0e2b7c58 Michael Hanselmann
      disk_template=constants.DT_PLAIN,
812 0e2b7c58 Michael Hanselmann
      disks=[
813 cd3b4ff4 Helga Velroyen
        objects.Disk(dev_type=constants.DT_PLAIN, size=4096,
814 0e2b7c58 Michael Hanselmann
                     logical_id=("vg", "disk6120")),
815 cd3b4ff4 Helga Velroyen
        objects.Disk(dev_type=constants.DT_PLAIN, size=1024,
816 0e2b7c58 Michael Hanselmann
                     logical_id=("vg", "disk8508")),
817 0e2b7c58 Michael Hanselmann
        ])
818 7e6b6f1f Michael Hanselmann
    inst.UpgradeConfig()
819 7e6b6f1f Michael Hanselmann
820 7e6b6f1f Michael Hanselmann
    cfg = _FakeConfigForRpcRunner(cluster=cluster)
821 7e6b6f1f Michael Hanselmann
    runner = rpc.RpcRunner(cfg, None,
822 7e6b6f1f Michael Hanselmann
                           _req_process_fn=NotImplemented,
823 7e6b6f1f Michael Hanselmann
                           _getents=mocks.FakeGetentResolver)
824 7e6b6f1f Michael Hanselmann
825 7e6b6f1f Michael Hanselmann
    def _CheckBasics(result):
826 7e6b6f1f Michael Hanselmann
      self.assertEqual(result["name"], "inst1.example.com")
827 7e6b6f1f Michael Hanselmann
      self.assertEqual(result["os"], "linux")
828 7e6b6f1f Michael Hanselmann
      self.assertEqual(result["beparams"][constants.BE_MINMEM], 128)
829 7e6b6f1f Michael Hanselmann
      self.assertEqual(len(result["hvparams"]), 1)
830 7e6b6f1f Michael Hanselmann
      self.assertEqual(len(result["nics"]), 1)
831 7e6b6f1f Michael Hanselmann
      self.assertEqual(result["nics"][0]["nicparams"][constants.NIC_MODE],
832 7e6b6f1f Michael Hanselmann
                       "mymode")
833 7e6b6f1f Michael Hanselmann
834 7e6b6f1f Michael Hanselmann
    # Generic object serialization
835 7e6b6f1f Michael Hanselmann
    result = runner._encoder((rpc_defs.ED_OBJECT_DICT, inst))
836 7e6b6f1f Michael Hanselmann
    _CheckBasics(result)
837 7e6b6f1f Michael Hanselmann
838 7e6b6f1f Michael Hanselmann
    result = runner._encoder((rpc_defs.ED_OBJECT_DICT_LIST, 5 * [inst]))
839 7e6b6f1f Michael Hanselmann
    map(_CheckBasics, result)
840 7e6b6f1f Michael Hanselmann
841 7e6b6f1f Michael Hanselmann
    # Just an instance
842 7e6b6f1f Michael Hanselmann
    result = runner._encoder((rpc_defs.ED_INST_DICT, inst))
843 7e6b6f1f Michael Hanselmann
    _CheckBasics(result)
844 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["beparams"][constants.BE_MAXMEM], 256)
845 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["hvparams"][constants.HT_KVM], {
846 7e6b6f1f Michael Hanselmann
      constants.HV_BLOCKDEV_PREFIX: "bar",
847 7e6b6f1f Michael Hanselmann
      constants.HV_ROOT_PATH: "/tmp",
848 7e6b6f1f Michael Hanselmann
      })
849 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["osparams"], {
850 7e6b6f1f Michael Hanselmann
      "role": "unknown",
851 7e6b6f1f Michael Hanselmann
      })
852 7e6b6f1f Michael Hanselmann
853 7e6b6f1f Michael Hanselmann
    # Instance with OS parameters
854 19fe9138 René Nussbaumer
    result = runner._encoder((rpc_defs.ED_INST_DICT_OSP_DP, (inst, {
855 7e6b6f1f Michael Hanselmann
      "role": "webserver",
856 7e6b6f1f Michael Hanselmann
      "other": "field",
857 7e6b6f1f Michael Hanselmann
      })))
858 7e6b6f1f Michael Hanselmann
    _CheckBasics(result)
859 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["beparams"][constants.BE_MAXMEM], 256)
860 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["hvparams"][constants.HT_KVM], {
861 7e6b6f1f Michael Hanselmann
      constants.HV_BLOCKDEV_PREFIX: "bar",
862 7e6b6f1f Michael Hanselmann
      constants.HV_ROOT_PATH: "/tmp",
863 7e6b6f1f Michael Hanselmann
      })
864 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["osparams"], {
865 7e6b6f1f Michael Hanselmann
      "role": "webserver",
866 7e6b6f1f Michael Hanselmann
      "other": "field",
867 7e6b6f1f Michael Hanselmann
      })
868 7e6b6f1f Michael Hanselmann
869 7e6b6f1f Michael Hanselmann
    # Instance with hypervisor and backend parameters
870 0e2b7c58 Michael Hanselmann
    result = runner._encoder((rpc_defs.ED_INST_DICT_HVP_BEP_DP, (inst, {
871 7e6b6f1f Michael Hanselmann
      constants.HT_KVM: {
872 7e6b6f1f Michael Hanselmann
        constants.HV_BOOT_ORDER: "xyz",
873 7e6b6f1f Michael Hanselmann
        },
874 7e6b6f1f Michael Hanselmann
      }, {
875 7e6b6f1f Michael Hanselmann
      constants.BE_VCPUS: 100,
876 7e6b6f1f Michael Hanselmann
      constants.BE_MAXMEM: 4096,
877 7e6b6f1f Michael Hanselmann
      })))
878 7e6b6f1f Michael Hanselmann
    _CheckBasics(result)
879 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["beparams"][constants.BE_MAXMEM], 4096)
880 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["beparams"][constants.BE_VCPUS], 100)
881 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["hvparams"][constants.HT_KVM], {
882 7e6b6f1f Michael Hanselmann
      constants.HV_BOOT_ORDER: "xyz",
883 7e6b6f1f Michael Hanselmann
      })
884 0e2b7c58 Michael Hanselmann
    self.assertEqual(result["disks"], [{
885 cd3b4ff4 Helga Velroyen
      "dev_type": constants.DT_PLAIN,
886 0e2b7c58 Michael Hanselmann
      "size": 4096,
887 0e2b7c58 Michael Hanselmann
      "logical_id": ("vg", "disk6120"),
888 0e2b7c58 Michael Hanselmann
      "params": constants.DISK_DT_DEFAULTS[inst.disk_template],
889 0e2b7c58 Michael Hanselmann
      }, {
890 cd3b4ff4 Helga Velroyen
      "dev_type": constants.DT_PLAIN,
891 0e2b7c58 Michael Hanselmann
      "size": 1024,
892 0e2b7c58 Michael Hanselmann
      "logical_id": ("vg", "disk8508"),
893 0e2b7c58 Michael Hanselmann
      "params": constants.DISK_DT_DEFAULTS[inst.disk_template],
894 0e2b7c58 Michael Hanselmann
      }])
895 0e2b7c58 Michael Hanselmann
896 0e2b7c58 Michael Hanselmann
    self.assertTrue(compat.all(disk.params == {} for disk in inst.disks),
897 0e2b7c58 Michael Hanselmann
                    msg="Configuration objects were modified")
898 7e6b6f1f Michael Hanselmann
899 065be3f0 Michael Hanselmann
900 91c17910 Iustin Pop
class TestLegacyNodeInfo(unittest.TestCase):
901 91c17910 Iustin Pop
  KEY_BOOT = "bootid"
902 06fb92cf Bernardo Dal Seno
  KEY_VG0 = "name"
903 32389d91 Helga Velroyen
  KEY_VG1 = "storage_free"
904 32389d91 Helga Velroyen
  KEY_VG2 = "storage_size"
905 91c17910 Iustin Pop
  KEY_HV = "cpu_count"
906 06fb92cf Bernardo Dal Seno
  KEY_SP1 = "spindles_free"
907 06fb92cf Bernardo Dal Seno
  KEY_SP2 = "spindles_total"
908 32389d91 Helga Velroyen
  KEY_ST = "type" # key for storage type
909 91c17910 Iustin Pop
  VAL_BOOT = 0
910 06fb92cf Bernardo Dal Seno
  VAL_VG0 = "xy"
911 06fb92cf Bernardo Dal Seno
  VAL_VG1 = 11
912 06fb92cf Bernardo Dal Seno
  VAL_VG2 = 12
913 32389d91 Helga Velroyen
  VAL_VG3 = "lvm-vg"
914 91c17910 Iustin Pop
  VAL_HV = 2
915 06fb92cf Bernardo Dal Seno
  VAL_SP0 = "ab"
916 06fb92cf Bernardo Dal Seno
  VAL_SP1 = 31
917 06fb92cf Bernardo Dal Seno
  VAL_SP2 = 32
918 32389d91 Helga Velroyen
  VAL_SP3 = "lvm-pv"
919 06fb92cf Bernardo Dal Seno
  DICT_VG = {
920 06fb92cf Bernardo Dal Seno
    KEY_VG0: VAL_VG0,
921 06fb92cf Bernardo Dal Seno
    KEY_VG1: VAL_VG1,
922 06fb92cf Bernardo Dal Seno
    KEY_VG2: VAL_VG2,
923 32389d91 Helga Velroyen
    KEY_ST: VAL_VG3,
924 06fb92cf Bernardo Dal Seno
    }
925 91c17910 Iustin Pop
  DICT_HV = {KEY_HV: VAL_HV}
926 06fb92cf Bernardo Dal Seno
  DICT_SP = {
927 32389d91 Helga Velroyen
    KEY_ST: VAL_SP3,
928 06fb92cf Bernardo Dal Seno
    KEY_VG0: VAL_SP0,
929 06fb92cf Bernardo Dal Seno
    KEY_VG1: VAL_SP1,
930 06fb92cf Bernardo Dal Seno
    KEY_VG2: VAL_SP2,
931 06fb92cf Bernardo Dal Seno
    }
932 06fb92cf Bernardo Dal Seno
  STD_LST = [VAL_BOOT, [DICT_VG, DICT_SP], [DICT_HV]]
933 91c17910 Iustin Pop
  STD_DICT = {
934 91c17910 Iustin Pop
    KEY_BOOT: VAL_BOOT,
935 06fb92cf Bernardo Dal Seno
    KEY_VG0: VAL_VG0,
936 06fb92cf Bernardo Dal Seno
    KEY_VG1: VAL_VG1,
937 06fb92cf Bernardo Dal Seno
    KEY_VG2: VAL_VG2,
938 06fb92cf Bernardo Dal Seno
    KEY_HV: VAL_HV,
939 91c17910 Iustin Pop
    }
940 91c17910 Iustin Pop
941 91c17910 Iustin Pop
  def testStandard(self):
942 91c17910 Iustin Pop
    result = rpc.MakeLegacyNodeInfo(self.STD_LST)
943 91c17910 Iustin Pop
    self.assertEqual(result, self.STD_DICT)
944 91c17910 Iustin Pop
945 20faaa74 Helga Velroyen
  def testSpindlesRequired(self):
946 91c17910 Iustin Pop
    my_lst = [self.VAL_BOOT, [], [self.DICT_HV]]
947 20faaa74 Helga Velroyen
    self.assertRaises(errors.OpExecError, rpc.MakeLegacyNodeInfo, my_lst,
948 20faaa74 Helga Velroyen
        require_spindles=True)
949 91c17910 Iustin Pop
950 20faaa74 Helga Velroyen
  def testNoSpindlesRequired(self):
951 91c17910 Iustin Pop
    my_lst = [self.VAL_BOOT, [], [self.DICT_HV]]
952 20faaa74 Helga Velroyen
    result = rpc.MakeLegacyNodeInfo(my_lst, require_spindles = False)
953 91c17910 Iustin Pop
    self.assertEqual(result, {self.KEY_BOOT: self.VAL_BOOT,
954 91c17910 Iustin Pop
                              self.KEY_HV: self.VAL_HV})
955 20faaa74 Helga Velroyen
    result = rpc.MakeLegacyNodeInfo(self.STD_LST, require_spindles = False)
956 91c17910 Iustin Pop
    self.assertEqual(result, self.STD_DICT)
957 91c17910 Iustin Pop
958 91c17910 Iustin Pop
959 b844311b Helga Velroyen
class TestAddDefaultStorageInfoToLegacyNodeInfo(unittest.TestCase):
960 b844311b Helga Velroyen
961 b844311b Helga Velroyen
  def setUp(self):
962 b844311b Helga Velroyen
    self.free_storage_file = 23
963 b844311b Helga Velroyen
    self.total_storage_file = 42
964 b844311b Helga Velroyen
    self.free_storage_lvm = 69
965 b844311b Helga Velroyen
    self.total_storage_lvm = 666
966 20faaa74 Helga Velroyen
    self.node_info = [{"name": "myfile",
967 b844311b Helga Velroyen
                       "type": constants.ST_FILE,
968 b844311b Helga Velroyen
                       "storage_free": self.free_storage_file,
969 b844311b Helga Velroyen
                       "storage_size": self.total_storage_file},
970 20faaa74 Helga Velroyen
                      {"name": "myvg",
971 b844311b Helga Velroyen
                       "type": constants.ST_LVM_VG,
972 b844311b Helga Velroyen
                       "storage_free": self.free_storage_lvm,
973 b844311b Helga Velroyen
                       "storage_size": self.total_storage_lvm},
974 20faaa74 Helga Velroyen
                      {"name": "myspindle",
975 b844311b Helga Velroyen
                       "type": constants.ST_LVM_PV,
976 b844311b Helga Velroyen
                       "storage_free": 33,
977 b844311b Helga Velroyen
                       "storage_size": 44}]
978 b844311b Helga Velroyen
979 b844311b Helga Velroyen
  def testAddDefaultStorageInfoToLegacyNodeInfo(self):
980 b844311b Helga Velroyen
    result = {}
981 20faaa74 Helga Velroyen
    rpc._AddDefaultStorageInfoToLegacyNodeInfo(result, self.node_info)
982 b844311b Helga Velroyen
    self.assertEqual(self.free_storage_file, result["storage_free"])
983 b844311b Helga Velroyen
    self.assertEqual(self.total_storage_file, result["storage_size"])
984 b844311b Helga Velroyen
985 b844311b Helga Velroyen
  def testAddDefaultStorageInfoToLegacyNodeInfoNoDefaults(self):
986 b844311b Helga Velroyen
    result = {}
987 20faaa74 Helga Velroyen
    rpc._AddDefaultStorageInfoToLegacyNodeInfo(result, self.node_info[-1:])
988 b844311b Helga Velroyen
    self.assertFalse("storage_free" in result)
989 b844311b Helga Velroyen
    self.assertFalse("storage_size" in result)
990 b844311b Helga Velroyen
991 b844311b Helga Velroyen
992 33231500 Michael Hanselmann
if __name__ == "__main__":
993 33231500 Michael Hanselmann
  testutils.GanetiTestProgram()