Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rpc_unittest.py @ 6760e4ed

History | View | Annotate | Download (7.5 kB)

1 33231500 Michael Hanselmann
#!/usr/bin/python
2 33231500 Michael Hanselmann
#
3 33231500 Michael Hanselmann
4 33231500 Michael Hanselmann
# Copyright (C) 2010 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 33231500 Michael Hanselmann
28 33231500 Michael Hanselmann
from ganeti import constants
29 33231500 Michael Hanselmann
from ganeti import compat
30 33231500 Michael Hanselmann
from ganeti import rpc
31 33231500 Michael Hanselmann
from ganeti import http
32 33231500 Michael Hanselmann
from ganeti import errors
33 33231500 Michael Hanselmann
from ganeti import serializer
34 33231500 Michael Hanselmann
35 33231500 Michael Hanselmann
import testutils
36 33231500 Michael Hanselmann
37 33231500 Michael Hanselmann
38 33231500 Michael Hanselmann
class TestTimeouts(unittest.TestCase):
39 33231500 Michael Hanselmann
  def test(self):
40 33231500 Michael Hanselmann
    names = [name[len("call_"):] for name in dir(rpc.RpcRunner)
41 33231500 Michael Hanselmann
             if name.startswith("call_")]
42 33231500 Michael Hanselmann
    self.assertEqual(len(names), len(rpc._TIMEOUTS))
43 33231500 Michael Hanselmann
    self.assertFalse([name for name in names
44 33231500 Michael Hanselmann
                      if not (rpc._TIMEOUTS[name] is None or
45 33231500 Michael Hanselmann
                              rpc._TIMEOUTS[name] > 0)])
46 33231500 Michael Hanselmann
47 33231500 Michael Hanselmann
48 33231500 Michael Hanselmann
class FakeHttpPool:
49 33231500 Michael Hanselmann
  def __init__(self, response_fn):
50 33231500 Michael Hanselmann
    self._response_fn = response_fn
51 33231500 Michael Hanselmann
    self.reqcount = 0
52 33231500 Michael Hanselmann
53 33231500 Michael Hanselmann
  def ProcessRequests(self, reqs):
54 33231500 Michael Hanselmann
    for req in reqs:
55 33231500 Michael Hanselmann
      self.reqcount += 1
56 33231500 Michael Hanselmann
      self._response_fn(req)
57 33231500 Michael Hanselmann
58 33231500 Michael Hanselmann
59 33231500 Michael Hanselmann
class TestClient(unittest.TestCase):
60 33231500 Michael Hanselmann
  def _GetVersionResponse(self, req):
61 33231500 Michael Hanselmann
    self.assertEqual(req.host, "localhost")
62 33231500 Michael Hanselmann
    self.assertEqual(req.port, 24094)
63 33231500 Michael Hanselmann
    self.assertEqual(req.path, "/version")
64 33231500 Michael Hanselmann
    req.success = True
65 33231500 Michael Hanselmann
    req.resp_status_code = http.HTTP_OK
66 33231500 Michael Hanselmann
    req.resp_body = serializer.DumpJson((True, 123))
67 33231500 Michael Hanselmann
68 33231500 Michael Hanselmann
  def testVersionSuccess(self):
69 33231500 Michael Hanselmann
    client = rpc.Client("version", None, 24094)
70 33231500 Michael Hanselmann
    client.ConnectNode("localhost")
71 33231500 Michael Hanselmann
    pool = FakeHttpPool(self._GetVersionResponse)
72 33231500 Michael Hanselmann
    result = client.GetResults(http_pool=pool)
73 33231500 Michael Hanselmann
    self.assertEqual(result.keys(), ["localhost"])
74 33231500 Michael Hanselmann
    lhresp = result["localhost"]
75 33231500 Michael Hanselmann
    self.assertFalse(lhresp.offline)
76 33231500 Michael Hanselmann
    self.assertEqual(lhresp.node, "localhost")
77 33231500 Michael Hanselmann
    self.assertFalse(lhresp.fail_msg)
78 33231500 Michael Hanselmann
    self.assertEqual(lhresp.payload, 123)
79 33231500 Michael Hanselmann
    self.assertEqual(lhresp.call, "version")
80 33231500 Michael Hanselmann
    lhresp.Raise("should not raise")
81 33231500 Michael Hanselmann
    self.assertEqual(pool.reqcount, 1)
82 33231500 Michael Hanselmann
83 33231500 Michael Hanselmann
  def _GetMultiVersionResponse(self, req):
84 33231500 Michael Hanselmann
    self.assert_(req.host.startswith("node"))
85 33231500 Michael Hanselmann
    self.assertEqual(req.port, 23245)
86 33231500 Michael Hanselmann
    self.assertEqual(req.path, "/version")
87 33231500 Michael Hanselmann
    req.success = True
88 33231500 Michael Hanselmann
    req.resp_status_code = http.HTTP_OK
89 33231500 Michael Hanselmann
    req.resp_body = serializer.DumpJson((True, 987))
90 33231500 Michael Hanselmann
91 33231500 Michael Hanselmann
  def testMultiVersionSuccess(self):
92 33231500 Michael Hanselmann
    nodes = ["node%s" % i for i in range(50)]
93 33231500 Michael Hanselmann
    client = rpc.Client("version", None, 23245)
94 33231500 Michael Hanselmann
    client.ConnectList(nodes)
95 33231500 Michael Hanselmann
96 33231500 Michael Hanselmann
    pool = FakeHttpPool(self._GetMultiVersionResponse)
97 33231500 Michael Hanselmann
    result = client.GetResults(http_pool=pool)
98 33231500 Michael Hanselmann
    self.assertEqual(sorted(result.keys()), sorted(nodes))
99 33231500 Michael Hanselmann
100 33231500 Michael Hanselmann
    for name in nodes:
101 33231500 Michael Hanselmann
      lhresp = result[name]
102 33231500 Michael Hanselmann
      self.assertFalse(lhresp.offline)
103 33231500 Michael Hanselmann
      self.assertEqual(lhresp.node, name)
104 33231500 Michael Hanselmann
      self.assertFalse(lhresp.fail_msg)
105 33231500 Michael Hanselmann
      self.assertEqual(lhresp.payload, 987)
106 33231500 Michael Hanselmann
      self.assertEqual(lhresp.call, "version")
107 33231500 Michael Hanselmann
      lhresp.Raise("should not raise")
108 33231500 Michael Hanselmann
109 33231500 Michael Hanselmann
    self.assertEqual(pool.reqcount, len(nodes))
110 33231500 Michael Hanselmann
111 33231500 Michael Hanselmann
  def _GetVersionResponseFail(self, req):
112 33231500 Michael Hanselmann
    self.assertEqual(req.path, "/version")
113 33231500 Michael Hanselmann
    req.success = True
114 33231500 Michael Hanselmann
    req.resp_status_code = http.HTTP_OK
115 33231500 Michael Hanselmann
    req.resp_body = serializer.DumpJson((False, "Unknown error"))
116 33231500 Michael Hanselmann
117 33231500 Michael Hanselmann
  def testVersionFailure(self):
118 33231500 Michael Hanselmann
    client = rpc.Client("version", None, 5903)
119 33231500 Michael Hanselmann
    client.ConnectNode("aef9ur4i.example.com")
120 33231500 Michael Hanselmann
    pool = FakeHttpPool(self._GetVersionResponseFail)
121 33231500 Michael Hanselmann
    result = client.GetResults(http_pool=pool)
122 33231500 Michael Hanselmann
    self.assertEqual(result.keys(), ["aef9ur4i.example.com"])
123 33231500 Michael Hanselmann
    lhresp = result["aef9ur4i.example.com"]
124 33231500 Michael Hanselmann
    self.assertFalse(lhresp.offline)
125 33231500 Michael Hanselmann
    self.assertEqual(lhresp.node, "aef9ur4i.example.com")
126 33231500 Michael Hanselmann
    self.assert_(lhresp.fail_msg)
127 33231500 Michael Hanselmann
    self.assertFalse(lhresp.payload)
128 33231500 Michael Hanselmann
    self.assertEqual(lhresp.call, "version")
129 33231500 Michael Hanselmann
    self.assertRaises(errors.OpExecError, lhresp.Raise, "failed")
130 33231500 Michael Hanselmann
    self.assertEqual(pool.reqcount, 1)
131 33231500 Michael Hanselmann
132 33231500 Michael Hanselmann
  def _GetHttpErrorResponse(self, httperrnodes, failnodes, req):
133 33231500 Michael Hanselmann
    self.assertEqual(req.path, "/vg_list")
134 33231500 Michael Hanselmann
    self.assertEqual(req.port, 15165)
135 33231500 Michael Hanselmann
136 33231500 Michael Hanselmann
    if req.host in httperrnodes:
137 33231500 Michael Hanselmann
      req.success = False
138 33231500 Michael Hanselmann
      req.error = "Node set up for HTTP errors"
139 33231500 Michael Hanselmann
140 33231500 Michael Hanselmann
    elif req.host in failnodes:
141 33231500 Michael Hanselmann
      req.success = True
142 33231500 Michael Hanselmann
      req.resp_status_code = 404
143 33231500 Michael Hanselmann
      req.resp_body = serializer.DumpJson({
144 33231500 Michael Hanselmann
        "code": 404,
145 33231500 Michael Hanselmann
        "message": "Method not found",
146 33231500 Michael Hanselmann
        "explain": "Explanation goes here",
147 33231500 Michael Hanselmann
        })
148 33231500 Michael Hanselmann
    else:
149 33231500 Michael Hanselmann
      req.success = True
150 33231500 Michael Hanselmann
      req.resp_status_code = http.HTTP_OK
151 33231500 Michael Hanselmann
      req.resp_body = serializer.DumpJson((True, hash(req.host)))
152 33231500 Michael Hanselmann
153 33231500 Michael Hanselmann
  def testHttpError(self):
154 33231500 Michael Hanselmann
    nodes = ["uaf6pbbv%s" % i for i in range(50)]
155 33231500 Michael Hanselmann
156 33231500 Michael Hanselmann
    httperrnodes = set(nodes[1::7])
157 33231500 Michael Hanselmann
    self.assertEqual(len(httperrnodes), 7)
158 33231500 Michael Hanselmann
159 33231500 Michael Hanselmann
    failnodes = set(nodes[2::3]) - httperrnodes
160 33231500 Michael Hanselmann
    self.assertEqual(len(failnodes), 14)
161 33231500 Michael Hanselmann
162 33231500 Michael Hanselmann
    self.assertEqual(len(set(nodes) - failnodes - httperrnodes), 29)
163 33231500 Michael Hanselmann
164 33231500 Michael Hanselmann
    client = rpc.Client("vg_list", None, 15165)
165 33231500 Michael Hanselmann
    client.ConnectList(nodes)
166 33231500 Michael Hanselmann
167 33231500 Michael Hanselmann
    pool = FakeHttpPool(compat.partial(self._GetHttpErrorResponse,
168 33231500 Michael Hanselmann
                                       httperrnodes, failnodes))
169 33231500 Michael Hanselmann
    result = client.GetResults(http_pool=pool)
170 33231500 Michael Hanselmann
    self.assertEqual(sorted(result.keys()), sorted(nodes))
171 33231500 Michael Hanselmann
172 33231500 Michael Hanselmann
    for name in nodes:
173 33231500 Michael Hanselmann
      lhresp = result[name]
174 33231500 Michael Hanselmann
      self.assertFalse(lhresp.offline)
175 33231500 Michael Hanselmann
      self.assertEqual(lhresp.node, name)
176 33231500 Michael Hanselmann
      self.assertEqual(lhresp.call, "vg_list")
177 33231500 Michael Hanselmann
178 33231500 Michael Hanselmann
      if name in httperrnodes:
179 33231500 Michael Hanselmann
        self.assert_(lhresp.fail_msg)
180 33231500 Michael Hanselmann
        self.assertRaises(errors.OpExecError, lhresp.Raise, "failed")
181 33231500 Michael Hanselmann
      elif name in failnodes:
182 33231500 Michael Hanselmann
        self.assert_(lhresp.fail_msg)
183 33231500 Michael Hanselmann
        self.assertRaises(errors.OpPrereqError, lhresp.Raise, "failed",
184 33231500 Michael Hanselmann
                          prereq=True, ecode=errors.ECODE_INVAL)
185 33231500 Michael Hanselmann
      else:
186 33231500 Michael Hanselmann
        self.assertFalse(lhresp.fail_msg)
187 33231500 Michael Hanselmann
        self.assertEqual(lhresp.payload, hash(name))
188 33231500 Michael Hanselmann
        lhresp.Raise("should not raise")
189 33231500 Michael Hanselmann
190 33231500 Michael Hanselmann
    self.assertEqual(pool.reqcount, len(nodes))
191 33231500 Michael Hanselmann
192 33231500 Michael Hanselmann
  def _GetInvalidResponseA(self, req):
193 33231500 Michael Hanselmann
    self.assertEqual(req.path, "/version")
194 33231500 Michael Hanselmann
    req.success = True
195 33231500 Michael Hanselmann
    req.resp_status_code = http.HTTP_OK
196 33231500 Michael Hanselmann
    req.resp_body = serializer.DumpJson(("This", "is", "an", "invalid",
197 33231500 Michael Hanselmann
                                         "response", "!", 1, 2, 3))
198 33231500 Michael Hanselmann
199 33231500 Michael Hanselmann
  def _GetInvalidResponseB(self, req):
200 33231500 Michael Hanselmann
    self.assertEqual(req.path, "/version")
201 33231500 Michael Hanselmann
    req.success = True
202 33231500 Michael Hanselmann
    req.resp_status_code = http.HTTP_OK
203 33231500 Michael Hanselmann
    req.resp_body = serializer.DumpJson("invalid response")
204 33231500 Michael Hanselmann
205 33231500 Michael Hanselmann
  def testInvalidResponse(self):
206 33231500 Michael Hanselmann
    client = rpc.Client("version", None, 19978)
207 33231500 Michael Hanselmann
    for fn in [self._GetInvalidResponseA, self._GetInvalidResponseB]:
208 33231500 Michael Hanselmann
      client.ConnectNode("oqo7lanhly.example.com")
209 33231500 Michael Hanselmann
      pool = FakeHttpPool(fn)
210 33231500 Michael Hanselmann
      result = client.GetResults(http_pool=pool)
211 33231500 Michael Hanselmann
      self.assertEqual(result.keys(), ["oqo7lanhly.example.com"])
212 33231500 Michael Hanselmann
      lhresp = result["oqo7lanhly.example.com"]
213 33231500 Michael Hanselmann
      self.assertFalse(lhresp.offline)
214 33231500 Michael Hanselmann
      self.assertEqual(lhresp.node, "oqo7lanhly.example.com")
215 33231500 Michael Hanselmann
      self.assert_(lhresp.fail_msg)
216 33231500 Michael Hanselmann
      self.assertFalse(lhresp.payload)
217 33231500 Michael Hanselmann
      self.assertEqual(lhresp.call, "version")
218 33231500 Michael Hanselmann
      self.assertRaises(errors.OpExecError, lhresp.Raise, "failed")
219 33231500 Michael Hanselmann
      self.assertEqual(pool.reqcount, 1)
220 33231500 Michael Hanselmann
221 33231500 Michael Hanselmann
222 33231500 Michael Hanselmann
if __name__ == "__main__":
223 33231500 Michael Hanselmann
  testutils.GanetiTestProgram()