Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.rpc_unittest.py @ 91c17910

History | View | Annotate | Download (32.1 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 00267bfe Michael Hanselmann
    self.assertEqual(result, zip(node_list, addr_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 bd6d1202 René Nussbaumer
    self.assertEqual(result, zip(node_list, addr_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 00267bfe Michael Hanselmann
    self.assertEqual(result, zip(node_list, addr_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 00267bfe Michael Hanselmann
    self.assertEqual(result, zip(node_list, addr_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 00267bfe Michael Hanselmann
    self.assertEqual(result, zip(node_list, addr_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 fce5efd1 Michael Hanselmann
    self.assertEqual(res(nodes, NotImplemented), zip(nodes, addresses))
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 00267bfe Michael Hanselmann
  def _GetSingleOnlineNode(name):
403 00267bfe Michael Hanselmann
    assert name == "node90.example.com"
404 00267bfe Michael Hanselmann
    return objects.Node(name=name, offline=False, primary_ip="192.0.2.90")
405 00267bfe Michael Hanselmann
406 00267bfe Michael Hanselmann
  @staticmethod
407 00267bfe Michael Hanselmann
  def _GetSingleOfflineNode(name):
408 00267bfe Michael Hanselmann
    assert name == "node100.example.com"
409 00267bfe Michael Hanselmann
    return objects.Node(name=name, offline=True, primary_ip="192.0.2.100")
410 00267bfe Michael Hanselmann
411 00267bfe Michael Hanselmann
  def testSingleOnline(self):
412 00267bfe Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(self._GetSingleOnlineNode,
413 00267bfe Michael Hanselmann
                                             NotImplemented,
414 fce5efd1 Michael Hanselmann
                                             ["node90.example.com"], None),
415 00267bfe Michael Hanselmann
                     [("node90.example.com", "192.0.2.90")])
416 00267bfe Michael Hanselmann
417 00267bfe Michael Hanselmann
  def testSingleOffline(self):
418 00267bfe Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(self._GetSingleOfflineNode,
419 00267bfe Michael Hanselmann
                                             NotImplemented,
420 fce5efd1 Michael Hanselmann
                                             ["node100.example.com"], None),
421 00267bfe Michael Hanselmann
                     [("node100.example.com", rpc._OFFLINE)])
422 00267bfe Michael Hanselmann
423 890ea4ce Michael Hanselmann
  def testSingleOfflineWithAcceptOffline(self):
424 890ea4ce Michael Hanselmann
    fn = self._GetSingleOfflineNode
425 890ea4ce Michael Hanselmann
    assert fn("node100.example.com").offline
426 890ea4ce Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(fn, NotImplemented,
427 890ea4ce Michael Hanselmann
                                             ["node100.example.com"],
428 890ea4ce Michael Hanselmann
                                             rpc_defs.ACCEPT_OFFLINE_NODE),
429 890ea4ce Michael Hanselmann
                     [("node100.example.com", "192.0.2.100")])
430 890ea4ce Michael Hanselmann
    for i in [False, True, "", "Hello", 0, 1]:
431 890ea4ce Michael Hanselmann
      self.assertRaises(AssertionError, rpc._NodeConfigResolver,
432 890ea4ce Michael Hanselmann
                        fn, NotImplemented, ["node100.example.com"], i)
433 890ea4ce Michael Hanselmann
434 00267bfe Michael Hanselmann
  def testUnknownSingleNode(self):
435 00267bfe Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(lambda _: None, NotImplemented,
436 fce5efd1 Michael Hanselmann
                                             ["node110.example.com"], None),
437 00267bfe Michael Hanselmann
                     [("node110.example.com", "node110.example.com")])
438 00267bfe Michael Hanselmann
439 00267bfe Michael Hanselmann
  def testMultiEmpty(self):
440 00267bfe Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(NotImplemented,
441 00267bfe Michael Hanselmann
                                             lambda: {},
442 fce5efd1 Michael Hanselmann
                                             [], None),
443 00267bfe Michael Hanselmann
                     [])
444 00267bfe Michael Hanselmann
445 00267bfe Michael Hanselmann
  def testMultiSomeOffline(self):
446 00267bfe Michael Hanselmann
    nodes = dict(("node%s.example.com" % i,
447 00267bfe Michael Hanselmann
                  objects.Node(name="node%s.example.com" % i,
448 00267bfe Michael Hanselmann
                               offline=((i % 3) == 0),
449 00267bfe Michael Hanselmann
                               primary_ip="192.0.2.%s" % i))
450 00267bfe Michael Hanselmann
                  for i in range(1, 255))
451 00267bfe Michael Hanselmann
452 00267bfe Michael Hanselmann
    # Resolve no names
453 00267bfe Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(NotImplemented,
454 00267bfe Michael Hanselmann
                                             lambda: nodes,
455 fce5efd1 Michael Hanselmann
                                             [], None),
456 00267bfe Michael Hanselmann
                     [])
457 00267bfe Michael Hanselmann
458 00267bfe Michael Hanselmann
    # Offline, online and unknown hosts
459 00267bfe Michael Hanselmann
    self.assertEqual(rpc._NodeConfigResolver(NotImplemented,
460 00267bfe Michael Hanselmann
                                             lambda: nodes,
461 00267bfe Michael Hanselmann
                                             ["node3.example.com",
462 00267bfe Michael Hanselmann
                                              "node92.example.com",
463 00267bfe Michael Hanselmann
                                              "node54.example.com",
464 fce5efd1 Michael Hanselmann
                                              "unknown.example.com",],
465 fce5efd1 Michael Hanselmann
                                             None), [
466 00267bfe Michael Hanselmann
      ("node3.example.com", rpc._OFFLINE),
467 00267bfe Michael Hanselmann
      ("node92.example.com", "192.0.2.92"),
468 00267bfe Michael Hanselmann
      ("node54.example.com", rpc._OFFLINE),
469 00267bfe Michael Hanselmann
      ("unknown.example.com", "unknown.example.com"),
470 00267bfe Michael Hanselmann
      ])
471 b43dcc5a Manuel Franceschini
472 33231500 Michael Hanselmann
473 120e7e77 Michael Hanselmann
class TestCompress(unittest.TestCase):
474 120e7e77 Michael Hanselmann
  def test(self):
475 120e7e77 Michael Hanselmann
    for data in ["", "Hello", "Hello World!\nnew\nlines"]:
476 120e7e77 Michael Hanselmann
      self.assertEqual(rpc._Compress(data),
477 120e7e77 Michael Hanselmann
                       (constants.RPC_ENCODING_NONE, data))
478 120e7e77 Michael Hanselmann
479 120e7e77 Michael Hanselmann
    for data in [512 * " ", 5242 * "Hello World!\n"]:
480 120e7e77 Michael Hanselmann
      compressed = rpc._Compress(data)
481 120e7e77 Michael Hanselmann
      self.assertEqual(len(compressed), 2)
482 120e7e77 Michael Hanselmann
      self.assertEqual(backend._Decompress(compressed), data)
483 120e7e77 Michael Hanselmann
484 120e7e77 Michael Hanselmann
  def testDecompression(self):
485 120e7e77 Michael Hanselmann
    self.assertRaises(AssertionError, backend._Decompress, "")
486 120e7e77 Michael Hanselmann
    self.assertRaises(AssertionError, backend._Decompress, [""])
487 120e7e77 Michael Hanselmann
    self.assertRaises(AssertionError, backend._Decompress,
488 120e7e77 Michael Hanselmann
                      ("unknown compression", "data"))
489 120e7e77 Michael Hanselmann
    self.assertRaises(Exception, backend._Decompress,
490 120e7e77 Michael Hanselmann
                      (constants.RPC_ENCODING_ZLIB_BASE64, "invalid zlib data"))
491 120e7e77 Michael Hanselmann
492 120e7e77 Michael Hanselmann
493 065be3f0 Michael Hanselmann
class TestRpcClientBase(unittest.TestCase):
494 065be3f0 Michael Hanselmann
  def testNoHosts(self):
495 2ff587d4 Agata Murawska
    cdef = ("test_call", NotImplemented, None, constants.RPC_TMO_SLOW, [],
496 065be3f0 Michael Hanselmann
            None, None, NotImplemented)
497 065be3f0 Michael Hanselmann
    http_proc = _FakeRequestProcessor(NotImplemented)
498 065be3f0 Michael Hanselmann
    client = rpc._RpcClientBase(rpc._StaticResolver([]), NotImplemented,
499 065be3f0 Michael Hanselmann
                                _req_process_fn=http_proc)
500 065be3f0 Michael Hanselmann
    self.assertEqual(client._Call(cdef, [], []), {})
501 065be3f0 Michael Hanselmann
502 065be3f0 Michael Hanselmann
    # Test wrong number of arguments
503 065be3f0 Michael Hanselmann
    self.assertRaises(errors.ProgrammerError, client._Call,
504 065be3f0 Michael Hanselmann
                      cdef, [], [0, 1, 2])
505 065be3f0 Michael Hanselmann
506 065be3f0 Michael Hanselmann
  def testTimeout(self):
507 065be3f0 Michael Hanselmann
    def _CalcTimeout((arg1, arg2)):
508 065be3f0 Michael Hanselmann
      return arg1 + arg2
509 065be3f0 Michael Hanselmann
510 065be3f0 Michael Hanselmann
    def _VerifyRequest(exp_timeout, req):
511 065be3f0 Michael Hanselmann
      self.assertEqual(req.read_timeout, exp_timeout)
512 065be3f0 Michael Hanselmann
513 065be3f0 Michael Hanselmann
      req.success = True
514 065be3f0 Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
515 065be3f0 Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, hex(req.read_timeout)))
516 065be3f0 Michael Hanselmann
517 065be3f0 Michael Hanselmann
    resolver = rpc._StaticResolver([
518 065be3f0 Michael Hanselmann
      "192.0.2.1",
519 065be3f0 Michael Hanselmann
      "192.0.2.2",
520 065be3f0 Michael Hanselmann
      ])
521 065be3f0 Michael Hanselmann
522 065be3f0 Michael Hanselmann
    nodes = [
523 065be3f0 Michael Hanselmann
      "node1.example.com",
524 065be3f0 Michael Hanselmann
      "node2.example.com",
525 065be3f0 Michael Hanselmann
      ]
526 065be3f0 Michael Hanselmann
527 065be3f0 Michael Hanselmann
    tests = [(100, None, 100), (30, None, 30)]
528 065be3f0 Michael Hanselmann
    tests.extend((_CalcTimeout, i, i + 300)
529 065be3f0 Michael Hanselmann
                 for i in [0, 5, 16485, 30516])
530 065be3f0 Michael Hanselmann
531 065be3f0 Michael Hanselmann
    for timeout, arg1, exp_timeout in tests:
532 065be3f0 Michael Hanselmann
      cdef = ("test_call", NotImplemented, None, timeout, [
533 065be3f0 Michael Hanselmann
        ("arg1", None, NotImplemented),
534 065be3f0 Michael Hanselmann
        ("arg2", None, NotImplemented),
535 065be3f0 Michael Hanselmann
        ], None, None, NotImplemented)
536 065be3f0 Michael Hanselmann
537 065be3f0 Michael Hanselmann
      http_proc = _FakeRequestProcessor(compat.partial(_VerifyRequest,
538 065be3f0 Michael Hanselmann
                                                       exp_timeout))
539 065be3f0 Michael Hanselmann
      client = rpc._RpcClientBase(resolver, NotImplemented,
540 065be3f0 Michael Hanselmann
                                  _req_process_fn=http_proc)
541 065be3f0 Michael Hanselmann
      result = client._Call(cdef, nodes, [arg1, 300])
542 065be3f0 Michael Hanselmann
      self.assertEqual(len(result), len(nodes))
543 065be3f0 Michael Hanselmann
      self.assertTrue(compat.all(not res.fail_msg and
544 065be3f0 Michael Hanselmann
                                 res.payload == hex(exp_timeout)
545 065be3f0 Michael Hanselmann
                                 for res in result.values()))
546 065be3f0 Michael Hanselmann
547 065be3f0 Michael Hanselmann
  def testArgumentEncoder(self):
548 065be3f0 Michael Hanselmann
    (AT1, AT2) = range(1, 3)
549 065be3f0 Michael Hanselmann
550 065be3f0 Michael Hanselmann
    resolver = rpc._StaticResolver([
551 065be3f0 Michael Hanselmann
      "192.0.2.5",
552 065be3f0 Michael Hanselmann
      "192.0.2.6",
553 065be3f0 Michael Hanselmann
      ])
554 065be3f0 Michael Hanselmann
555 065be3f0 Michael Hanselmann
    nodes = [
556 065be3f0 Michael Hanselmann
      "node5.example.com",
557 065be3f0 Michael Hanselmann
      "node6.example.com",
558 065be3f0 Michael Hanselmann
      ]
559 065be3f0 Michael Hanselmann
560 065be3f0 Michael Hanselmann
    encoders = {
561 065be3f0 Michael Hanselmann
      AT1: hex,
562 065be3f0 Michael Hanselmann
      AT2: hash,
563 065be3f0 Michael Hanselmann
      }
564 065be3f0 Michael Hanselmann
565 2ff587d4 Agata Murawska
    cdef = ("test_call", NotImplemented, None, constants.RPC_TMO_NORMAL, [
566 065be3f0 Michael Hanselmann
      ("arg0", None, NotImplemented),
567 065be3f0 Michael Hanselmann
      ("arg1", AT1, NotImplemented),
568 065be3f0 Michael Hanselmann
      ("arg1", AT2, NotImplemented),
569 065be3f0 Michael Hanselmann
      ], None, None, NotImplemented)
570 065be3f0 Michael Hanselmann
571 065be3f0 Michael Hanselmann
    def _VerifyRequest(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, req.post_data))
575 065be3f0 Michael Hanselmann
576 065be3f0 Michael Hanselmann
    http_proc = _FakeRequestProcessor(_VerifyRequest)
577 065be3f0 Michael Hanselmann
578 065be3f0 Michael Hanselmann
    for num in [0, 3796, 9032119]:
579 065be3f0 Michael Hanselmann
      client = rpc._RpcClientBase(resolver, encoders.get,
580 065be3f0 Michael Hanselmann
                                  _req_process_fn=http_proc)
581 065be3f0 Michael Hanselmann
      result = client._Call(cdef, nodes, ["foo", num, "Hello%s" % num])
582 065be3f0 Michael Hanselmann
      self.assertEqual(len(result), len(nodes))
583 065be3f0 Michael Hanselmann
      for res in result.values():
584 065be3f0 Michael Hanselmann
        self.assertFalse(res.fail_msg)
585 065be3f0 Michael Hanselmann
        self.assertEqual(serializer.LoadJson(res.payload),
586 065be3f0 Michael Hanselmann
                         ["foo", hex(num), hash("Hello%s" % num)])
587 065be3f0 Michael Hanselmann
588 065be3f0 Michael Hanselmann
  def testPostProc(self):
589 065be3f0 Michael Hanselmann
    def _VerifyRequest(nums, req):
590 065be3f0 Michael Hanselmann
      req.success = True
591 065be3f0 Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
592 065be3f0 Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, nums))
593 065be3f0 Michael Hanselmann
594 065be3f0 Michael Hanselmann
    resolver = rpc._StaticResolver([
595 065be3f0 Michael Hanselmann
      "192.0.2.90",
596 065be3f0 Michael Hanselmann
      "192.0.2.95",
597 065be3f0 Michael Hanselmann
      ])
598 065be3f0 Michael Hanselmann
599 065be3f0 Michael Hanselmann
    nodes = [
600 065be3f0 Michael Hanselmann
      "node90.example.com",
601 065be3f0 Michael Hanselmann
      "node95.example.com",
602 065be3f0 Michael Hanselmann
      ]
603 065be3f0 Michael Hanselmann
604 065be3f0 Michael Hanselmann
    def _PostProc(res):
605 065be3f0 Michael Hanselmann
      self.assertFalse(res.fail_msg)
606 065be3f0 Michael Hanselmann
      res.payload = sum(res.payload)
607 065be3f0 Michael Hanselmann
      return res
608 065be3f0 Michael Hanselmann
609 2ff587d4 Agata Murawska
    cdef = ("test_call", NotImplemented, None, constants.RPC_TMO_NORMAL, [],
610 065be3f0 Michael Hanselmann
            None, _PostProc, NotImplemented)
611 065be3f0 Michael Hanselmann
612 065be3f0 Michael Hanselmann
    # Seeded random generator
613 065be3f0 Michael Hanselmann
    rnd = random.Random(20299)
614 065be3f0 Michael Hanselmann
615 065be3f0 Michael Hanselmann
    for i in [0, 4, 74, 1391]:
616 065be3f0 Michael Hanselmann
      nums = [rnd.randint(0, 1000) for _ in range(i)]
617 065be3f0 Michael Hanselmann
      http_proc = _FakeRequestProcessor(compat.partial(_VerifyRequest, nums))
618 065be3f0 Michael Hanselmann
      client = rpc._RpcClientBase(resolver, NotImplemented,
619 065be3f0 Michael Hanselmann
                                  _req_process_fn=http_proc)
620 065be3f0 Michael Hanselmann
      result = client._Call(cdef, nodes, [])
621 065be3f0 Michael Hanselmann
      self.assertEqual(len(result), len(nodes))
622 065be3f0 Michael Hanselmann
      for res in result.values():
623 065be3f0 Michael Hanselmann
        self.assertFalse(res.fail_msg)
624 065be3f0 Michael Hanselmann
        self.assertEqual(res.payload, sum(nums))
625 065be3f0 Michael Hanselmann
626 065be3f0 Michael Hanselmann
  def testPreProc(self):
627 065be3f0 Michael Hanselmann
    def _VerifyRequest(req):
628 065be3f0 Michael Hanselmann
      req.success = True
629 065be3f0 Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
630 065be3f0 Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, req.post_data))
631 065be3f0 Michael Hanselmann
632 065be3f0 Michael Hanselmann
    resolver = rpc._StaticResolver([
633 065be3f0 Michael Hanselmann
      "192.0.2.30",
634 065be3f0 Michael Hanselmann
      "192.0.2.35",
635 065be3f0 Michael Hanselmann
      ])
636 065be3f0 Michael Hanselmann
637 065be3f0 Michael Hanselmann
    nodes = [
638 065be3f0 Michael Hanselmann
      "node30.example.com",
639 065be3f0 Michael Hanselmann
      "node35.example.com",
640 065be3f0 Michael Hanselmann
      ]
641 065be3f0 Michael Hanselmann
642 065be3f0 Michael Hanselmann
    def _PreProc(node, data):
643 065be3f0 Michael Hanselmann
      self.assertEqual(len(data), 1)
644 065be3f0 Michael Hanselmann
      return data[0] + node
645 065be3f0 Michael Hanselmann
646 2ff587d4 Agata Murawska
    cdef = ("test_call", NotImplemented, None, constants.RPC_TMO_NORMAL, [
647 065be3f0 Michael Hanselmann
      ("arg0", None, NotImplemented),
648 065be3f0 Michael Hanselmann
      ], _PreProc, None, NotImplemented)
649 065be3f0 Michael Hanselmann
650 065be3f0 Michael Hanselmann
    http_proc = _FakeRequestProcessor(_VerifyRequest)
651 065be3f0 Michael Hanselmann
    client = rpc._RpcClientBase(resolver, NotImplemented,
652 065be3f0 Michael Hanselmann
                                _req_process_fn=http_proc)
653 065be3f0 Michael Hanselmann
654 065be3f0 Michael Hanselmann
    for prefix in ["foo", "bar", "baz"]:
655 065be3f0 Michael Hanselmann
      result = client._Call(cdef, nodes, [prefix])
656 065be3f0 Michael Hanselmann
      self.assertEqual(len(result), len(nodes))
657 065be3f0 Michael Hanselmann
      for (idx, (node, res)) in enumerate(result.items()):
658 065be3f0 Michael Hanselmann
        self.assertFalse(res.fail_msg)
659 065be3f0 Michael Hanselmann
        self.assertEqual(serializer.LoadJson(res.payload), prefix + node)
660 065be3f0 Michael Hanselmann
661 065be3f0 Michael Hanselmann
  def testResolverOptions(self):
662 065be3f0 Michael Hanselmann
    def _VerifyRequest(req):
663 065be3f0 Michael Hanselmann
      req.success = True
664 065be3f0 Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
665 065be3f0 Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, req.post_data))
666 065be3f0 Michael Hanselmann
667 065be3f0 Michael Hanselmann
    nodes = [
668 065be3f0 Michael Hanselmann
      "node30.example.com",
669 065be3f0 Michael Hanselmann
      "node35.example.com",
670 065be3f0 Michael Hanselmann
      ]
671 065be3f0 Michael Hanselmann
672 065be3f0 Michael Hanselmann
    def _Resolver(expected, hosts, options):
673 065be3f0 Michael Hanselmann
      self.assertEqual(hosts, nodes)
674 065be3f0 Michael Hanselmann
      self.assertEqual(options, expected)
675 065be3f0 Michael Hanselmann
      return zip(hosts, nodes)
676 065be3f0 Michael Hanselmann
677 065be3f0 Michael Hanselmann
    def _DynamicResolverOptions((arg0, )):
678 065be3f0 Michael Hanselmann
      return sum(arg0)
679 065be3f0 Michael Hanselmann
680 065be3f0 Michael Hanselmann
    tests = [
681 065be3f0 Michael Hanselmann
      (None, None, None),
682 065be3f0 Michael Hanselmann
      (rpc_defs.ACCEPT_OFFLINE_NODE, None, rpc_defs.ACCEPT_OFFLINE_NODE),
683 065be3f0 Michael Hanselmann
      (False, None, False),
684 065be3f0 Michael Hanselmann
      (True, None, True),
685 065be3f0 Michael Hanselmann
      (0, None, 0),
686 065be3f0 Michael Hanselmann
      (_DynamicResolverOptions, [1, 2, 3], 6),
687 065be3f0 Michael Hanselmann
      (_DynamicResolverOptions, range(4, 19), 165),
688 065be3f0 Michael Hanselmann
      ]
689 065be3f0 Michael Hanselmann
690 065be3f0 Michael Hanselmann
    for (resolver_opts, arg0, expected) in tests:
691 2ff587d4 Agata Murawska
      cdef = ("test_call", NotImplemented, resolver_opts,
692 2ff587d4 Agata Murawska
              constants.RPC_TMO_NORMAL, [
693 065be3f0 Michael Hanselmann
        ("arg0", None, NotImplemented),
694 065be3f0 Michael Hanselmann
        ], None, None, NotImplemented)
695 065be3f0 Michael Hanselmann
696 065be3f0 Michael Hanselmann
      http_proc = _FakeRequestProcessor(_VerifyRequest)
697 065be3f0 Michael Hanselmann
698 065be3f0 Michael Hanselmann
      client = rpc._RpcClientBase(compat.partial(_Resolver, expected),
699 065be3f0 Michael Hanselmann
                                  NotImplemented, _req_process_fn=http_proc)
700 065be3f0 Michael Hanselmann
      result = client._Call(cdef, nodes, [arg0])
701 065be3f0 Michael Hanselmann
      self.assertEqual(len(result), len(nodes))
702 065be3f0 Michael Hanselmann
      for (idx, (node, res)) in enumerate(result.items()):
703 065be3f0 Michael Hanselmann
        self.assertFalse(res.fail_msg)
704 065be3f0 Michael Hanselmann
705 065be3f0 Michael Hanselmann
706 601dfcbb Michael Hanselmann
class _FakeConfigForRpcRunner:
707 601dfcbb Michael Hanselmann
  GetAllNodesInfo = NotImplemented
708 601dfcbb Michael Hanselmann
709 7e6b6f1f Michael Hanselmann
  def __init__(self, cluster=NotImplemented):
710 7e6b6f1f Michael Hanselmann
    self._cluster = cluster
711 7e6b6f1f Michael Hanselmann
712 601dfcbb Michael Hanselmann
  def GetNodeInfo(self, name):
713 601dfcbb Michael Hanselmann
    return objects.Node(name=name)
714 601dfcbb Michael Hanselmann
715 7e6b6f1f Michael Hanselmann
  def GetClusterInfo(self):
716 7e6b6f1f Michael Hanselmann
    return self._cluster
717 7e6b6f1f Michael Hanselmann
718 19fe9138 René Nussbaumer
  def GetInstanceDiskParams(self, _):
719 19fe9138 René Nussbaumer
    return constants.DISK_DT_DEFAULTS
720 19fe9138 René Nussbaumer
721 601dfcbb Michael Hanselmann
722 065be3f0 Michael Hanselmann
class TestRpcRunner(unittest.TestCase):
723 065be3f0 Michael Hanselmann
  def testUploadFile(self):
724 601dfcbb Michael Hanselmann
    data = 1779 * "Hello World\n"
725 601dfcbb Michael Hanselmann
726 601dfcbb Michael Hanselmann
    tmpfile = tempfile.NamedTemporaryFile()
727 601dfcbb Michael Hanselmann
    tmpfile.write(data)
728 601dfcbb Michael Hanselmann
    tmpfile.flush()
729 601dfcbb Michael Hanselmann
    st = os.stat(tmpfile.name)
730 601dfcbb Michael Hanselmann
731 601dfcbb Michael Hanselmann
    def _VerifyRequest(req):
732 601dfcbb Michael Hanselmann
      (uldata, ) = serializer.LoadJson(req.post_data)
733 601dfcbb Michael Hanselmann
      self.assertEqual(len(uldata), 7)
734 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[0], tmpfile.name)
735 601dfcbb Michael Hanselmann
      self.assertEqual(list(uldata[1]), list(rpc._Compress(data)))
736 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[2], st.st_mode)
737 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[3], "user%s" % os.getuid())
738 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[4], "group%s" % os.getgid())
739 7e6b6f1f Michael Hanselmann
      self.assertTrue(uldata[5] is not None)
740 601dfcbb Michael Hanselmann
      self.assertEqual(uldata[6], st.st_mtime)
741 601dfcbb Michael Hanselmann
742 601dfcbb Michael Hanselmann
      req.success = True
743 601dfcbb Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
744 601dfcbb Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, None))
745 601dfcbb Michael Hanselmann
746 601dfcbb Michael Hanselmann
    http_proc = _FakeRequestProcessor(_VerifyRequest)
747 c2dc025a Michael Hanselmann
748 c2dc025a Michael Hanselmann
    std_runner = rpc.RpcRunner(_FakeConfigForRpcRunner(), None,
749 c2dc025a Michael Hanselmann
                               _req_process_fn=http_proc,
750 c2dc025a Michael Hanselmann
                               _getents=mocks.FakeGetentResolver)
751 c2dc025a Michael Hanselmann
752 c2dc025a Michael Hanselmann
    cfg_runner = rpc.ConfigRunner(None, ["192.0.2.13"],
753 c2dc025a Michael Hanselmann
                                  _req_process_fn=http_proc,
754 c2dc025a Michael Hanselmann
                                  _getents=mocks.FakeGetentResolver)
755 601dfcbb Michael Hanselmann
756 601dfcbb Michael Hanselmann
    nodes = [
757 601dfcbb Michael Hanselmann
      "node1.example.com",
758 601dfcbb Michael Hanselmann
      ]
759 601dfcbb Michael Hanselmann
760 c2dc025a Michael Hanselmann
    for runner in [std_runner, cfg_runner]:
761 c2dc025a Michael Hanselmann
      result = runner.call_upload_file(nodes, tmpfile.name)
762 c2dc025a Michael Hanselmann
      self.assertEqual(len(result), len(nodes))
763 c2dc025a Michael Hanselmann
      for (idx, (node, res)) in enumerate(result.items()):
764 c2dc025a Michael Hanselmann
        self.assertFalse(res.fail_msg)
765 065be3f0 Michael Hanselmann
766 7e6b6f1f Michael Hanselmann
  def testEncodeInstance(self):
767 7e6b6f1f Michael Hanselmann
    cluster = objects.Cluster(hvparams={
768 7e6b6f1f Michael Hanselmann
      constants.HT_KVM: {
769 7e6b6f1f Michael Hanselmann
        constants.HV_BLOCKDEV_PREFIX: "foo",
770 7e6b6f1f Michael Hanselmann
        },
771 7e6b6f1f Michael Hanselmann
      },
772 7e6b6f1f Michael Hanselmann
      beparams={
773 7e6b6f1f Michael Hanselmann
        constants.PP_DEFAULT: {
774 7e6b6f1f Michael Hanselmann
          constants.BE_MAXMEM: 8192,
775 7e6b6f1f Michael Hanselmann
          },
776 7e6b6f1f Michael Hanselmann
        },
777 7e6b6f1f Michael Hanselmann
      os_hvp={},
778 7e6b6f1f Michael Hanselmann
      osparams={
779 7e6b6f1f Michael Hanselmann
        "linux": {
780 7e6b6f1f Michael Hanselmann
          "role": "unknown",
781 7e6b6f1f Michael Hanselmann
          },
782 7e6b6f1f Michael Hanselmann
        })
783 7e6b6f1f Michael Hanselmann
    cluster.UpgradeConfig()
784 7e6b6f1f Michael Hanselmann
785 7e6b6f1f Michael Hanselmann
    inst = objects.Instance(name="inst1.example.com",
786 7e6b6f1f Michael Hanselmann
      hypervisor=constants.HT_FAKE,
787 7e6b6f1f Michael Hanselmann
      os="linux",
788 7e6b6f1f Michael Hanselmann
      hvparams={
789 7e6b6f1f Michael Hanselmann
        constants.HT_KVM: {
790 7e6b6f1f Michael Hanselmann
          constants.HV_BLOCKDEV_PREFIX: "bar",
791 7e6b6f1f Michael Hanselmann
          constants.HV_ROOT_PATH: "/tmp",
792 7e6b6f1f Michael Hanselmann
          },
793 7e6b6f1f Michael Hanselmann
        },
794 7e6b6f1f Michael Hanselmann
      beparams={
795 7e6b6f1f Michael Hanselmann
        constants.BE_MINMEM: 128,
796 7e6b6f1f Michael Hanselmann
        constants.BE_MAXMEM: 256,
797 7e6b6f1f Michael Hanselmann
        },
798 7e6b6f1f Michael Hanselmann
      nics=[
799 7e6b6f1f Michael Hanselmann
        objects.NIC(nicparams={
800 7e6b6f1f Michael Hanselmann
          constants.NIC_MODE: "mymode",
801 7e6b6f1f Michael Hanselmann
          }),
802 7e6b6f1f Michael Hanselmann
        ],
803 0e2b7c58 Michael Hanselmann
      disk_template=constants.DT_PLAIN,
804 0e2b7c58 Michael Hanselmann
      disks=[
805 0e2b7c58 Michael Hanselmann
        objects.Disk(dev_type=constants.LD_LV, size=4096,
806 0e2b7c58 Michael Hanselmann
                     logical_id=("vg", "disk6120")),
807 0e2b7c58 Michael Hanselmann
        objects.Disk(dev_type=constants.LD_LV, size=1024,
808 0e2b7c58 Michael Hanselmann
                     logical_id=("vg", "disk8508")),
809 0e2b7c58 Michael Hanselmann
        ])
810 7e6b6f1f Michael Hanselmann
    inst.UpgradeConfig()
811 7e6b6f1f Michael Hanselmann
812 7e6b6f1f Michael Hanselmann
    cfg = _FakeConfigForRpcRunner(cluster=cluster)
813 7e6b6f1f Michael Hanselmann
    runner = rpc.RpcRunner(cfg, None,
814 7e6b6f1f Michael Hanselmann
                           _req_process_fn=NotImplemented,
815 7e6b6f1f Michael Hanselmann
                           _getents=mocks.FakeGetentResolver)
816 7e6b6f1f Michael Hanselmann
817 7e6b6f1f Michael Hanselmann
    def _CheckBasics(result):
818 7e6b6f1f Michael Hanselmann
      self.assertEqual(result["name"], "inst1.example.com")
819 7e6b6f1f Michael Hanselmann
      self.assertEqual(result["os"], "linux")
820 7e6b6f1f Michael Hanselmann
      self.assertEqual(result["beparams"][constants.BE_MINMEM], 128)
821 7e6b6f1f Michael Hanselmann
      self.assertEqual(len(result["hvparams"]), 1)
822 7e6b6f1f Michael Hanselmann
      self.assertEqual(len(result["nics"]), 1)
823 7e6b6f1f Michael Hanselmann
      self.assertEqual(result["nics"][0]["nicparams"][constants.NIC_MODE],
824 7e6b6f1f Michael Hanselmann
                       "mymode")
825 7e6b6f1f Michael Hanselmann
826 7e6b6f1f Michael Hanselmann
    # Generic object serialization
827 7e6b6f1f Michael Hanselmann
    result = runner._encoder((rpc_defs.ED_OBJECT_DICT, inst))
828 7e6b6f1f Michael Hanselmann
    _CheckBasics(result)
829 7e6b6f1f Michael Hanselmann
830 7e6b6f1f Michael Hanselmann
    result = runner._encoder((rpc_defs.ED_OBJECT_DICT_LIST, 5 * [inst]))
831 7e6b6f1f Michael Hanselmann
    map(_CheckBasics, result)
832 7e6b6f1f Michael Hanselmann
833 7e6b6f1f Michael Hanselmann
    # Just an instance
834 7e6b6f1f Michael Hanselmann
    result = runner._encoder((rpc_defs.ED_INST_DICT, inst))
835 7e6b6f1f Michael Hanselmann
    _CheckBasics(result)
836 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["beparams"][constants.BE_MAXMEM], 256)
837 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["hvparams"][constants.HT_KVM], {
838 7e6b6f1f Michael Hanselmann
      constants.HV_BLOCKDEV_PREFIX: "bar",
839 7e6b6f1f Michael Hanselmann
      constants.HV_ROOT_PATH: "/tmp",
840 7e6b6f1f Michael Hanselmann
      })
841 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["osparams"], {
842 7e6b6f1f Michael Hanselmann
      "role": "unknown",
843 7e6b6f1f Michael Hanselmann
      })
844 7e6b6f1f Michael Hanselmann
845 7e6b6f1f Michael Hanselmann
    # Instance with OS parameters
846 19fe9138 René Nussbaumer
    result = runner._encoder((rpc_defs.ED_INST_DICT_OSP_DP, (inst, {
847 7e6b6f1f Michael Hanselmann
      "role": "webserver",
848 7e6b6f1f Michael Hanselmann
      "other": "field",
849 7e6b6f1f Michael Hanselmann
      })))
850 7e6b6f1f Michael Hanselmann
    _CheckBasics(result)
851 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["beparams"][constants.BE_MAXMEM], 256)
852 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["hvparams"][constants.HT_KVM], {
853 7e6b6f1f Michael Hanselmann
      constants.HV_BLOCKDEV_PREFIX: "bar",
854 7e6b6f1f Michael Hanselmann
      constants.HV_ROOT_PATH: "/tmp",
855 7e6b6f1f Michael Hanselmann
      })
856 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["osparams"], {
857 7e6b6f1f Michael Hanselmann
      "role": "webserver",
858 7e6b6f1f Michael Hanselmann
      "other": "field",
859 7e6b6f1f Michael Hanselmann
      })
860 7e6b6f1f Michael Hanselmann
861 7e6b6f1f Michael Hanselmann
    # Instance with hypervisor and backend parameters
862 0e2b7c58 Michael Hanselmann
    result = runner._encoder((rpc_defs.ED_INST_DICT_HVP_BEP_DP, (inst, {
863 7e6b6f1f Michael Hanselmann
      constants.HT_KVM: {
864 7e6b6f1f Michael Hanselmann
        constants.HV_BOOT_ORDER: "xyz",
865 7e6b6f1f Michael Hanselmann
        },
866 7e6b6f1f Michael Hanselmann
      }, {
867 7e6b6f1f Michael Hanselmann
      constants.BE_VCPUS: 100,
868 7e6b6f1f Michael Hanselmann
      constants.BE_MAXMEM: 4096,
869 7e6b6f1f Michael Hanselmann
      })))
870 7e6b6f1f Michael Hanselmann
    _CheckBasics(result)
871 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["beparams"][constants.BE_MAXMEM], 4096)
872 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["beparams"][constants.BE_VCPUS], 100)
873 7e6b6f1f Michael Hanselmann
    self.assertEqual(result["hvparams"][constants.HT_KVM], {
874 7e6b6f1f Michael Hanselmann
      constants.HV_BOOT_ORDER: "xyz",
875 7e6b6f1f Michael Hanselmann
      })
876 0e2b7c58 Michael Hanselmann
    self.assertEqual(result["disks"], [{
877 0e2b7c58 Michael Hanselmann
      "dev_type": constants.LD_LV,
878 0e2b7c58 Michael Hanselmann
      "size": 4096,
879 0e2b7c58 Michael Hanselmann
      "logical_id": ("vg", "disk6120"),
880 0e2b7c58 Michael Hanselmann
      "params": constants.DISK_DT_DEFAULTS[inst.disk_template],
881 0e2b7c58 Michael Hanselmann
      }, {
882 0e2b7c58 Michael Hanselmann
      "dev_type": constants.LD_LV,
883 0e2b7c58 Michael Hanselmann
      "size": 1024,
884 0e2b7c58 Michael Hanselmann
      "logical_id": ("vg", "disk8508"),
885 0e2b7c58 Michael Hanselmann
      "params": constants.DISK_DT_DEFAULTS[inst.disk_template],
886 0e2b7c58 Michael Hanselmann
      }])
887 0e2b7c58 Michael Hanselmann
888 0e2b7c58 Michael Hanselmann
    self.assertTrue(compat.all(disk.params == {} for disk in inst.disks),
889 0e2b7c58 Michael Hanselmann
                    msg="Configuration objects were modified")
890 7e6b6f1f Michael Hanselmann
891 065be3f0 Michael Hanselmann
892 91c17910 Iustin Pop
class TestLegacyNodeInfo(unittest.TestCase):
893 91c17910 Iustin Pop
  KEY_BOOT = "bootid"
894 91c17910 Iustin Pop
  KEY_VG = "disk_free"
895 91c17910 Iustin Pop
  KEY_HV = "cpu_count"
896 91c17910 Iustin Pop
  VAL_BOOT = 0
897 91c17910 Iustin Pop
  VAL_VG = 1
898 91c17910 Iustin Pop
  VAL_HV = 2
899 91c17910 Iustin Pop
  DICT_VG = {KEY_VG: VAL_VG}
900 91c17910 Iustin Pop
  DICT_HV = {KEY_HV: VAL_HV}
901 91c17910 Iustin Pop
  STD_LST = [VAL_BOOT, [DICT_VG], [DICT_HV]]
902 91c17910 Iustin Pop
  STD_DICT = {
903 91c17910 Iustin Pop
    KEY_BOOT: VAL_BOOT,
904 91c17910 Iustin Pop
    KEY_VG: VAL_VG,
905 91c17910 Iustin Pop
    KEY_HV: VAL_HV
906 91c17910 Iustin Pop
    }
907 91c17910 Iustin Pop
908 91c17910 Iustin Pop
  def testStandard(self):
909 91c17910 Iustin Pop
    result = rpc.MakeLegacyNodeInfo(self.STD_LST)
910 91c17910 Iustin Pop
    self.assertEqual(result, self.STD_DICT)
911 91c17910 Iustin Pop
912 91c17910 Iustin Pop
  def testReqVg(self):
913 91c17910 Iustin Pop
    my_lst = [self.VAL_BOOT, [], [self.DICT_HV]]
914 91c17910 Iustin Pop
    self.assertRaises(ValueError, rpc.MakeLegacyNodeInfo, my_lst)
915 91c17910 Iustin Pop
916 91c17910 Iustin Pop
  def testNoReqVg(self):
917 91c17910 Iustin Pop
    my_lst = [self.VAL_BOOT, [], [self.DICT_HV]]
918 91c17910 Iustin Pop
    result = rpc.MakeLegacyNodeInfo(my_lst, require_vg_info = False)
919 91c17910 Iustin Pop
    self.assertEqual(result, {self.KEY_BOOT: self.VAL_BOOT,
920 91c17910 Iustin Pop
                              self.KEY_HV: self.VAL_HV})
921 91c17910 Iustin Pop
    result = rpc.MakeLegacyNodeInfo(self.STD_LST, require_vg_info = False)
922 91c17910 Iustin Pop
    self.assertEqual(result, self.STD_DICT)
923 91c17910 Iustin Pop
924 91c17910 Iustin Pop
925 33231500 Michael Hanselmann
if __name__ == "__main__":
926 33231500 Michael Hanselmann
  testutils.GanetiTestProgram()