Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rpc_unittest.py @ 415feb2e

History | View | Annotate | Download (29.5 kB)

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