Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.client_unittest.py @ 2a7c3583

History | View | Annotate | Download (27.2 kB)

1 95ab4de9 David Knowles
#!/usr/bin/python
2 95ab4de9 David Knowles
#
3 95ab4de9 David Knowles
4 95ab4de9 David Knowles
# Copyright (C) 2010 Google Inc.
5 95ab4de9 David Knowles
#
6 95ab4de9 David Knowles
# This program is free software; you can redistribute it and/or modify
7 95ab4de9 David Knowles
# it under the terms of the GNU General Public License as published by
8 95ab4de9 David Knowles
# the Free Software Foundation; either version 2 of the License, or
9 95ab4de9 David Knowles
# (at your option) any later version.
10 95ab4de9 David Knowles
#
11 95ab4de9 David Knowles
# This program is distributed in the hope that it will be useful, but
12 95ab4de9 David Knowles
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 95ab4de9 David Knowles
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 95ab4de9 David Knowles
# General Public License for more details.
15 95ab4de9 David Knowles
#
16 95ab4de9 David Knowles
# You should have received a copy of the GNU General Public License
17 95ab4de9 David Knowles
# along with this program; if not, write to the Free Software
18 95ab4de9 David Knowles
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 95ab4de9 David Knowles
# 02110-1301, USA.
20 95ab4de9 David Knowles
21 95ab4de9 David Knowles
22 95ab4de9 David Knowles
"""Script for unittesting the RAPI client module"""
23 95ab4de9 David Knowles
24 95ab4de9 David Knowles
25 95ab4de9 David Knowles
import re
26 95ab4de9 David Knowles
import unittest
27 95ab4de9 David Knowles
import warnings
28 2a7c3583 Michael Hanselmann
import pycurl
29 95ab4de9 David Knowles
30 2a7c3583 Michael Hanselmann
from ganeti import constants
31 95ab4de9 David Knowles
from ganeti import http
32 d9b67f70 Michael Hanselmann
from ganeti import serializer
33 95ab4de9 David Knowles
34 95ab4de9 David Knowles
from ganeti.rapi import connector
35 95ab4de9 David Knowles
from ganeti.rapi import rlib2
36 9279e986 Michael Hanselmann
from ganeti.rapi import client
37 95ab4de9 David Knowles
38 95ab4de9 David Knowles
import testutils
39 95ab4de9 David Knowles
40 95ab4de9 David Knowles
41 95ab4de9 David Knowles
_URI_RE = re.compile(r"https://(?P<host>.*):(?P<port>\d+)(?P<path>/.*)")
42 95ab4de9 David Knowles
43 95ab4de9 David Knowles
44 95ab4de9 David Knowles
def _GetPathFromUri(uri):
45 95ab4de9 David Knowles
  """Gets the path and query from a URI.
46 95ab4de9 David Knowles

47 95ab4de9 David Knowles
  """
48 95ab4de9 David Knowles
  match = _URI_RE.match(uri)
49 95ab4de9 David Knowles
  if match:
50 95ab4de9 David Knowles
    return match.groupdict()["path"]
51 95ab4de9 David Knowles
  else:
52 95ab4de9 David Knowles
    return None
53 95ab4de9 David Knowles
54 95ab4de9 David Knowles
55 2a7c3583 Michael Hanselmann
class FakeCurl:
56 2a7c3583 Michael Hanselmann
  def __init__(self, rapi):
57 2a7c3583 Michael Hanselmann
    self._rapi = rapi
58 2a7c3583 Michael Hanselmann
    self._opts = {}
59 2a7c3583 Michael Hanselmann
    self._info = {}
60 9279e986 Michael Hanselmann
61 2a7c3583 Michael Hanselmann
  def setopt(self, opt, value):
62 2a7c3583 Michael Hanselmann
    self._opts[opt] = value
63 95ab4de9 David Knowles
64 2a7c3583 Michael Hanselmann
  def getopt(self, opt):
65 2a7c3583 Michael Hanselmann
    return self._opts.get(opt)
66 95ab4de9 David Knowles
67 2a7c3583 Michael Hanselmann
  def unsetopt(self, opt):
68 2a7c3583 Michael Hanselmann
    self._opts.pop(opt, None)
69 95ab4de9 David Knowles
70 2a7c3583 Michael Hanselmann
  def getinfo(self, info):
71 2a7c3583 Michael Hanselmann
    return self._info[info]
72 95ab4de9 David Knowles
73 2a7c3583 Michael Hanselmann
  def perform(self):
74 2a7c3583 Michael Hanselmann
    method = self._opts[pycurl.CUSTOMREQUEST]
75 2a7c3583 Michael Hanselmann
    url = self._opts[pycurl.URL]
76 2a7c3583 Michael Hanselmann
    request_body = self._opts[pycurl.POSTFIELDS]
77 2a7c3583 Michael Hanselmann
    writefn = self._opts[pycurl.WRITEFUNCTION]
78 95ab4de9 David Knowles
79 2a7c3583 Michael Hanselmann
    path = _GetPathFromUri(url)
80 2a7c3583 Michael Hanselmann
    (code, resp_body) = self._rapi.FetchResponse(path, method, request_body)
81 95ab4de9 David Knowles
82 2a7c3583 Michael Hanselmann
    self._info[pycurl.RESPONSE_CODE] = code
83 2a7c3583 Michael Hanselmann
    if resp_body is not None:
84 2a7c3583 Michael Hanselmann
      writefn(resp_body)
85 95ab4de9 David Knowles
86 95ab4de9 David Knowles
87 95ab4de9 David Knowles
class RapiMock(object):
88 95ab4de9 David Knowles
  def __init__(self):
89 95ab4de9 David Knowles
    self._mapper = connector.Mapper()
90 95ab4de9 David Knowles
    self._responses = []
91 95ab4de9 David Knowles
    self._last_handler = None
92 2a7c3583 Michael Hanselmann
    self._last_req_data = None
93 95ab4de9 David Knowles
94 de4f53e6 Michael Hanselmann
  def AddResponse(self, response, code=200):
95 de4f53e6 Michael Hanselmann
    self._responses.insert(0, (code, response))
96 95ab4de9 David Knowles
97 95ab4de9 David Knowles
  def GetLastHandler(self):
98 95ab4de9 David Knowles
    return self._last_handler
99 95ab4de9 David Knowles
100 2a7c3583 Michael Hanselmann
  def GetLastRequestData(self):
101 2a7c3583 Michael Hanselmann
    return self._last_req_data
102 2a7c3583 Michael Hanselmann
103 2a7c3583 Michael Hanselmann
  def FetchResponse(self, path, method, request_body):
104 2a7c3583 Michael Hanselmann
    self._last_req_data = request_body
105 2a7c3583 Michael Hanselmann
106 95ab4de9 David Knowles
    try:
107 95ab4de9 David Knowles
      HandlerClass, items, args = self._mapper.getController(path)
108 95ab4de9 David Knowles
      self._last_handler = HandlerClass(items, args, None)
109 95ab4de9 David Knowles
      if not hasattr(self._last_handler, method.upper()):
110 de4f53e6 Michael Hanselmann
        raise http.HttpNotImplemented(message="Method not implemented")
111 de4f53e6 Michael Hanselmann
112 95ab4de9 David Knowles
    except http.HttpException, ex:
113 95ab4de9 David Knowles
      code = ex.code
114 95ab4de9 David Knowles
      response = ex.message
115 de4f53e6 Michael Hanselmann
    else:
116 de4f53e6 Michael Hanselmann
      if not self._responses:
117 de4f53e6 Michael Hanselmann
        raise Exception("No responses")
118 95ab4de9 David Knowles
119 de4f53e6 Michael Hanselmann
      (code, response) = self._responses.pop()
120 95ab4de9 David Knowles
121 95ab4de9 David Knowles
    return code, response
122 95ab4de9 David Knowles
123 95ab4de9 David Knowles
124 2a7c3583 Michael Hanselmann
class TestConstants(unittest.TestCase):
125 2a7c3583 Michael Hanselmann
  def test(self):
126 2a7c3583 Michael Hanselmann
    self.assertEqual(client.GANETI_RAPI_PORT, constants.DEFAULT_RAPI_PORT)
127 2a7c3583 Michael Hanselmann
    self.assertEqual(client.GANETI_RAPI_VERSION, constants.RAPI_VERSION)
128 2a7c3583 Michael Hanselmann
    self.assertEqual(client.HTTP_APP_JSON, http.HTTP_APP_JSON)
129 2a7c3583 Michael Hanselmann
    self.assertEqual(client._REQ_DATA_VERSION_FIELD, rlib2._REQ_DATA_VERSION)
130 2a7c3583 Michael Hanselmann
    self.assertEqual(client._INST_CREATE_REQV1, rlib2._INST_CREATE_REQV1)
131 2a7c3583 Michael Hanselmann
132 2a7c3583 Michael Hanselmann
133 95ab4de9 David Knowles
class RapiMockTest(unittest.TestCase):
134 95ab4de9 David Knowles
  def test(self):
135 95ab4de9 David Knowles
    rapi = RapiMock()
136 95ab4de9 David Knowles
    path = "/version"
137 2a7c3583 Michael Hanselmann
    self.assertEqual((404, None), rapi.FetchResponse("/foo", "GET", None))
138 09127904 Michael Hanselmann
    self.assertEqual((501, "Method not implemented"),
139 2a7c3583 Michael Hanselmann
                     rapi.FetchResponse("/version", "POST", None))
140 95ab4de9 David Knowles
    rapi.AddResponse("2")
141 2a7c3583 Michael Hanselmann
    code, response = rapi.FetchResponse("/version", "GET", None)
142 95ab4de9 David Knowles
    self.assertEqual(200, code)
143 95ab4de9 David Knowles
    self.assertEqual("2", response)
144 95ab4de9 David Knowles
    self.failUnless(isinstance(rapi.GetLastHandler(), rlib2.R_version))
145 95ab4de9 David Knowles
146 95ab4de9 David Knowles
147 2a7c3583 Michael Hanselmann
def _FakeNoSslPycurlVersion():
148 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
149 2a7c3583 Michael Hanselmann
  return (3, "7.16.0", 462848, "mysystem", 1581, None, 0)
150 2a7c3583 Michael Hanselmann
151 2a7c3583 Michael Hanselmann
152 2a7c3583 Michael Hanselmann
def _FakeFancySslPycurlVersion():
153 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
154 2a7c3583 Michael Hanselmann
  return (3, "7.16.0", 462848, "mysystem", 1581, "FancySSL/1.2.3", 0)
155 2a7c3583 Michael Hanselmann
156 2a7c3583 Michael Hanselmann
157 2a7c3583 Michael Hanselmann
def _FakeOpenSslPycurlVersion():
158 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
159 2a7c3583 Michael Hanselmann
  return (2, "7.15.5", 462597, "othersystem", 668, "OpenSSL/0.9.8c", 0)
160 2a7c3583 Michael Hanselmann
161 2a7c3583 Michael Hanselmann
162 2a7c3583 Michael Hanselmann
def _FakeGnuTlsPycurlVersion():
163 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
164 2a7c3583 Michael Hanselmann
  return (3, "7.18.0", 463360, "somesystem", 1581, "GnuTLS/2.0.4", 0)
165 2a7c3583 Michael Hanselmann
166 2a7c3583 Michael Hanselmann
167 2a7c3583 Michael Hanselmann
class TestExtendedConfig(unittest.TestCase):
168 2a7c3583 Michael Hanselmann
  def testAuth(self):
169 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
170 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com",
171 2a7c3583 Michael Hanselmann
                                 username="user", password="pw",
172 2a7c3583 Michael Hanselmann
                                 curl=curl)
173 2a7c3583 Michael Hanselmann
174 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.HTTPAUTH), pycurl.HTTPAUTH_BASIC)
175 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.USERPWD), "user:pw")
176 2a7c3583 Michael Hanselmann
177 2a7c3583 Michael Hanselmann
  def testInvalidAuth(self):
178 2a7c3583 Michael Hanselmann
    # No username
179 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GanetiRapiClient,
180 2a7c3583 Michael Hanselmann
                      "master-a.example.com", password="pw")
181 2a7c3583 Michael Hanselmann
    # No password
182 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GanetiRapiClient,
183 2a7c3583 Michael Hanselmann
                      "master-b.example.com", username="user")
184 2a7c3583 Michael Hanselmann
185 2a7c3583 Michael Hanselmann
  def testCertVerifyInvalidCombinations(self):
186 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GenericCurlConfig,
187 2a7c3583 Michael Hanselmann
                      use_curl_cabundle=True, cafile="cert1.pem")
188 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GenericCurlConfig,
189 2a7c3583 Michael Hanselmann
                      use_curl_cabundle=True, capath="certs/")
190 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GenericCurlConfig,
191 2a7c3583 Michael Hanselmann
                      use_curl_cabundle=True,
192 2a7c3583 Michael Hanselmann
                      cafile="cert1.pem", capath="certs/")
193 2a7c3583 Michael Hanselmann
194 2a7c3583 Michael Hanselmann
  def testProxySignalVerifyHostname(self):
195 2a7c3583 Michael Hanselmann
    for use_gnutls in [False, True]:
196 2a7c3583 Michael Hanselmann
      if use_gnutls:
197 2a7c3583 Michael Hanselmann
        pcverfn = _FakeGnuTlsPycurlVersion
198 2a7c3583 Michael Hanselmann
      else:
199 2a7c3583 Michael Hanselmann
        pcverfn = _FakeOpenSslPycurlVersion
200 2a7c3583 Michael Hanselmann
201 2a7c3583 Michael Hanselmann
      for proxy in ["", "http://127.0.0.1:1234"]:
202 2a7c3583 Michael Hanselmann
        for use_signal in [False, True]:
203 2a7c3583 Michael Hanselmann
          for verify_hostname in [False, True]:
204 2a7c3583 Michael Hanselmann
            cfgfn = client.GenericCurlConfig(proxy=proxy, use_signal=use_signal,
205 2a7c3583 Michael Hanselmann
                                             verify_hostname=verify_hostname,
206 2a7c3583 Michael Hanselmann
                                             _pycurl_version_fn=pcverfn)
207 2a7c3583 Michael Hanselmann
208 2a7c3583 Michael Hanselmann
            curl = FakeCurl(RapiMock())
209 2a7c3583 Michael Hanselmann
            cl = client.GanetiRapiClient("master.example.com",
210 2a7c3583 Michael Hanselmann
                                         curl_config_fn=cfgfn, curl=curl)
211 2a7c3583 Michael Hanselmann
212 2a7c3583 Michael Hanselmann
            self.assertEqual(curl.getopt(pycurl.PROXY), proxy)
213 2a7c3583 Michael Hanselmann
            self.assertEqual(curl.getopt(pycurl.NOSIGNAL), not use_signal)
214 2a7c3583 Michael Hanselmann
215 2a7c3583 Michael Hanselmann
            if verify_hostname:
216 2a7c3583 Michael Hanselmann
              self.assertEqual(curl.getopt(pycurl.SSL_VERIFYHOST), 2)
217 2a7c3583 Michael Hanselmann
            else:
218 2a7c3583 Michael Hanselmann
              self.assertEqual(curl.getopt(pycurl.SSL_VERIFYHOST), 0)
219 2a7c3583 Michael Hanselmann
220 2a7c3583 Michael Hanselmann
  def testNoCertVerify(self):
221 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig()
222 2a7c3583 Michael Hanselmann
223 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
224 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
225 2a7c3583 Michael Hanselmann
                                 curl=curl)
226 2a7c3583 Michael Hanselmann
227 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.SSL_VERIFYPEER))
228 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAINFO))
229 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAPATH))
230 2a7c3583 Michael Hanselmann
231 2a7c3583 Michael Hanselmann
  def testCertVerifyCurlBundle(self):
232 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(use_curl_cabundle=True)
233 2a7c3583 Michael Hanselmann
234 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
235 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
236 2a7c3583 Michael Hanselmann
                                 curl=curl)
237 2a7c3583 Michael Hanselmann
238 2a7c3583 Michael Hanselmann
    self.assert_(curl.getopt(pycurl.SSL_VERIFYPEER))
239 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAINFO))
240 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAPATH))
241 2a7c3583 Michael Hanselmann
242 2a7c3583 Michael Hanselmann
  def testCertVerifyCafile(self):
243 2a7c3583 Michael Hanselmann
    mycert = "/tmp/some/UNUSED/cert/file.pem"
244 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(cafile=mycert)
245 2a7c3583 Michael Hanselmann
246 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
247 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
248 2a7c3583 Michael Hanselmann
                                 curl=curl)
249 2a7c3583 Michael Hanselmann
250 2a7c3583 Michael Hanselmann
    self.assert_(curl.getopt(pycurl.SSL_VERIFYPEER))
251 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.CAINFO), mycert)
252 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAPATH))
253 2a7c3583 Michael Hanselmann
254 2a7c3583 Michael Hanselmann
  def testCertVerifyCapath(self):
255 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
256 2a7c3583 Michael Hanselmann
    pcverfn = _FakeOpenSslPycurlVersion
257 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
258 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
259 2a7c3583 Michael Hanselmann
260 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
261 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
262 2a7c3583 Michael Hanselmann
                                 curl=curl)
263 2a7c3583 Michael Hanselmann
264 2a7c3583 Michael Hanselmann
    self.assert_(curl.getopt(pycurl.SSL_VERIFYPEER))
265 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.CAPATH), certdir)
266 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAINFO))
267 2a7c3583 Michael Hanselmann
268 2a7c3583 Michael Hanselmann
  def testCertVerifyCapathGnuTls(self):
269 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
270 2a7c3583 Michael Hanselmann
    pcverfn = _FakeGnuTlsPycurlVersion
271 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
272 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
273 2a7c3583 Michael Hanselmann
274 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
275 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GanetiRapiClient,
276 2a7c3583 Michael Hanselmann
                      "master.example.com", curl_config_fn=cfgfn, curl=curl)
277 2a7c3583 Michael Hanselmann
278 2a7c3583 Michael Hanselmann
  def testCertVerifyNoSsl(self):
279 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
280 2a7c3583 Michael Hanselmann
    pcverfn = _FakeNoSslPycurlVersion
281 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
282 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
283 2a7c3583 Michael Hanselmann
284 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
285 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GanetiRapiClient,
286 2a7c3583 Michael Hanselmann
                      "master.example.com", curl_config_fn=cfgfn, curl=curl)
287 2a7c3583 Michael Hanselmann
288 2a7c3583 Michael Hanselmann
  def testCertVerifyFancySsl(self):
289 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
290 2a7c3583 Michael Hanselmann
    pcverfn = _FakeFancySslPycurlVersion
291 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
292 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
293 2a7c3583 Michael Hanselmann
294 2a7c3583 Michael Hanselmann
    curl = FakeCurl(RapiMock())
295 2a7c3583 Michael Hanselmann
    self.assertRaises(NotImplementedError, client.GanetiRapiClient,
296 2a7c3583 Michael Hanselmann
                      "master.example.com", curl_config_fn=cfgfn, curl=curl)
297 2a7c3583 Michael Hanselmann
298 2a7c3583 Michael Hanselmann
  def testCertVerifyCapath(self):
299 2a7c3583 Michael Hanselmann
    for connect_timeout in [None, 1, 5, 10, 30, 60, 300]:
300 2a7c3583 Michael Hanselmann
      for timeout in [None, 1, 30, 60, 3600, 24 * 3600]:
301 2a7c3583 Michael Hanselmann
        cfgfn = client.GenericCurlConfig(connect_timeout=connect_timeout,
302 2a7c3583 Michael Hanselmann
                                         timeout=timeout)
303 2a7c3583 Michael Hanselmann
304 2a7c3583 Michael Hanselmann
        curl = FakeCurl(RapiMock())
305 2a7c3583 Michael Hanselmann
        cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
306 2a7c3583 Michael Hanselmann
                                     curl=curl)
307 2a7c3583 Michael Hanselmann
308 2a7c3583 Michael Hanselmann
        self.assertEqual(curl.getopt(pycurl.CONNECTTIMEOUT), connect_timeout)
309 2a7c3583 Michael Hanselmann
        self.assertEqual(curl.getopt(pycurl.TIMEOUT), timeout)
310 2a7c3583 Michael Hanselmann
311 2a7c3583 Michael Hanselmann
312 d9b67f70 Michael Hanselmann
class GanetiRapiClientTests(testutils.GanetiTestCase):
313 95ab4de9 David Knowles
  def setUp(self):
314 d9b67f70 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
315 d9b67f70 Michael Hanselmann
316 95ab4de9 David Knowles
    self.rapi = RapiMock()
317 2a7c3583 Michael Hanselmann
    self.curl = FakeCurl(self.rapi)
318 2a7c3583 Michael Hanselmann
    self.client = client.GanetiRapiClient("master.example.com",
319 2a7c3583 Michael Hanselmann
                                          curl=self.curl)
320 2a7c3583 Michael Hanselmann
321 2a7c3583 Michael Hanselmann
    # Signals should be disabled by default
322 2a7c3583 Michael Hanselmann
    self.assert_(self.curl.getopt(pycurl.NOSIGNAL))
323 2a7c3583 Michael Hanselmann
324 2a7c3583 Michael Hanselmann
    # No auth and no proxy
325 2a7c3583 Michael Hanselmann
    self.assertFalse(self.curl.getopt(pycurl.USERPWD))
326 2a7c3583 Michael Hanselmann
    self.assert_(self.curl.getopt(pycurl.PROXY) is None)
327 2a7c3583 Michael Hanselmann
328 2a7c3583 Michael Hanselmann
    # Content-type is required for requests
329 2a7c3583 Michael Hanselmann
    headers = self.curl.getopt(pycurl.HTTPHEADER)
330 2a7c3583 Michael Hanselmann
    self.assert_("Content-type: application/json" in headers)
331 95ab4de9 David Knowles
332 95ab4de9 David Knowles
  def assertHandler(self, handler_cls):
333 95ab4de9 David Knowles
    self.failUnless(isinstance(self.rapi.GetLastHandler(), handler_cls))
334 95ab4de9 David Knowles
335 95ab4de9 David Knowles
  def assertQuery(self, key, value):
336 95ab4de9 David Knowles
    self.assertEqual(value, self.rapi.GetLastHandler().queryargs.get(key, None))
337 95ab4de9 David Knowles
338 95ab4de9 David Knowles
  def assertItems(self, items):
339 95ab4de9 David Knowles
    self.assertEqual(items, self.rapi.GetLastHandler().items)
340 95ab4de9 David Knowles
341 95ab4de9 David Knowles
  def assertBulk(self):
342 95ab4de9 David Knowles
    self.assertTrue(self.rapi.GetLastHandler().useBulk())
343 95ab4de9 David Knowles
344 95ab4de9 David Knowles
  def assertDryRun(self):
345 95ab4de9 David Knowles
    self.assertTrue(self.rapi.GetLastHandler().dryRun())
346 95ab4de9 David Knowles
347 10f5ab6c Michael Hanselmann
  def testEncodeQuery(self):
348 10f5ab6c Michael Hanselmann
    query = [
349 10f5ab6c Michael Hanselmann
      ("a", None),
350 10f5ab6c Michael Hanselmann
      ("b", 1),
351 10f5ab6c Michael Hanselmann
      ("c", 2),
352 10f5ab6c Michael Hanselmann
      ("d", "Foo"),
353 10f5ab6c Michael Hanselmann
      ("e", True),
354 10f5ab6c Michael Hanselmann
      ]
355 10f5ab6c Michael Hanselmann
356 10f5ab6c Michael Hanselmann
    expected = [
357 10f5ab6c Michael Hanselmann
      ("a", ""),
358 10f5ab6c Michael Hanselmann
      ("b", 1),
359 10f5ab6c Michael Hanselmann
      ("c", 2),
360 10f5ab6c Michael Hanselmann
      ("d", "Foo"),
361 10f5ab6c Michael Hanselmann
      ("e", 1),
362 10f5ab6c Michael Hanselmann
      ]
363 10f5ab6c Michael Hanselmann
364 10f5ab6c Michael Hanselmann
    self.assertEqualValues(self.client._EncodeQuery(query),
365 10f5ab6c Michael Hanselmann
                           expected)
366 10f5ab6c Michael Hanselmann
367 10f5ab6c Michael Hanselmann
    # invalid types
368 10f5ab6c Michael Hanselmann
    for i in [[1, 2, 3], {"moo": "boo"}, (1, 2, 3)]:
369 10f5ab6c Michael Hanselmann
      self.assertRaises(ValueError, self.client._EncodeQuery, [("x", i)])
370 10f5ab6c Michael Hanselmann
371 8a019a03 Michael Hanselmann
  def testHttpError(self):
372 8a019a03 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
373 8a019a03 Michael Hanselmann
    try:
374 8a019a03 Michael Hanselmann
      self.client.GetJobStatus(15140)
375 8a019a03 Michael Hanselmann
    except client.GanetiApiError, err:
376 8a019a03 Michael Hanselmann
      self.assertEqual(err.code, 404)
377 8a019a03 Michael Hanselmann
    else:
378 8a019a03 Michael Hanselmann
      self.fail("Didn't raise exception")
379 8a019a03 Michael Hanselmann
380 95ab4de9 David Knowles
  def testGetVersion(self):
381 95ab4de9 David Knowles
    self.client._version = None
382 95ab4de9 David Knowles
    self.rapi.AddResponse("2")
383 95ab4de9 David Knowles
    self.assertEqual(2, self.client.GetVersion())
384 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_version)
385 95ab4de9 David Knowles
386 7eac4a4d Michael Hanselmann
  def testGetFeatures(self):
387 7eac4a4d Michael Hanselmann
    for features in [[], ["foo", "bar", "baz"]]:
388 7eac4a4d Michael Hanselmann
      self.rapi.AddResponse(serializer.DumpJson(features))
389 7eac4a4d Michael Hanselmann
      self.assertEqual(features, self.client.GetFeatures())
390 7eac4a4d Michael Hanselmann
      self.assertHandler(rlib2.R_2_features)
391 7eac4a4d Michael Hanselmann
392 95ab4de9 David Knowles
  def testGetOperatingSystems(self):
393 95ab4de9 David Knowles
    self.rapi.AddResponse("[\"beos\"]")
394 95ab4de9 David Knowles
    self.assertEqual(["beos"], self.client.GetOperatingSystems())
395 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_os)
396 95ab4de9 David Knowles
397 95ab4de9 David Knowles
  def testGetClusterTags(self):
398 95ab4de9 David Knowles
    self.rapi.AddResponse("[\"tag\"]")
399 95ab4de9 David Knowles
    self.assertEqual(["tag"], self.client.GetClusterTags())
400 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_tags)
401 95ab4de9 David Knowles
402 95ab4de9 David Knowles
  def testAddClusterTags(self):
403 cab667cc David Knowles
    self.rapi.AddResponse("1234")
404 cab667cc David Knowles
    self.assertEqual(1234,
405 cab667cc David Knowles
        self.client.AddClusterTags(["awesome"], dry_run=True))
406 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_tags)
407 95ab4de9 David Knowles
    self.assertDryRun()
408 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
409 95ab4de9 David Knowles
410 95ab4de9 David Knowles
  def testDeleteClusterTags(self):
411 cd577680 Michael Hanselmann
    self.rapi.AddResponse("5107")
412 cd577680 Michael Hanselmann
    self.assertEqual(5107, self.client.DeleteClusterTags(["awesome"],
413 cd577680 Michael Hanselmann
                                                         dry_run=True))
414 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_tags)
415 95ab4de9 David Knowles
    self.assertDryRun()
416 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
417 95ab4de9 David Knowles
418 95ab4de9 David Knowles
  def testGetInfo(self):
419 95ab4de9 David Knowles
    self.rapi.AddResponse("{}")
420 95ab4de9 David Knowles
    self.assertEqual({}, self.client.GetInfo())
421 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_info)
422 95ab4de9 David Knowles
423 95ab4de9 David Knowles
  def testGetInstances(self):
424 95ab4de9 David Knowles
    self.rapi.AddResponse("[]")
425 95ab4de9 David Knowles
    self.assertEqual([], self.client.GetInstances(bulk=True))
426 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances)
427 95ab4de9 David Knowles
    self.assertBulk()
428 95ab4de9 David Knowles
429 591e5103 Michael Hanselmann
  def testGetInstance(self):
430 95ab4de9 David Knowles
    self.rapi.AddResponse("[]")
431 591e5103 Michael Hanselmann
    self.assertEqual([], self.client.GetInstance("instance"))
432 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name)
433 95ab4de9 David Knowles
    self.assertItems(["instance"])
434 95ab4de9 David Knowles
435 591e5103 Michael Hanselmann
  def testGetInstanceInfo(self):
436 591e5103 Michael Hanselmann
    self.rapi.AddResponse("21291")
437 591e5103 Michael Hanselmann
    self.assertEqual(21291, self.client.GetInstanceInfo("inst3"))
438 591e5103 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_info)
439 591e5103 Michael Hanselmann
    self.assertItems(["inst3"])
440 591e5103 Michael Hanselmann
    self.assertQuery("static", None)
441 591e5103 Michael Hanselmann
442 591e5103 Michael Hanselmann
    self.rapi.AddResponse("3428")
443 591e5103 Michael Hanselmann
    self.assertEqual(3428, self.client.GetInstanceInfo("inst31", static=False))
444 591e5103 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_info)
445 591e5103 Michael Hanselmann
    self.assertItems(["inst31"])
446 591e5103 Michael Hanselmann
    self.assertQuery("static", ["0"])
447 591e5103 Michael Hanselmann
448 591e5103 Michael Hanselmann
    self.rapi.AddResponse("15665")
449 591e5103 Michael Hanselmann
    self.assertEqual(15665, self.client.GetInstanceInfo("inst32", static=True))
450 591e5103 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_info)
451 591e5103 Michael Hanselmann
    self.assertItems(["inst32"])
452 591e5103 Michael Hanselmann
    self.assertQuery("static", ["1"])
453 591e5103 Michael Hanselmann
454 8a47b447 Michael Hanselmann
  def testCreateInstanceOldVersion(self):
455 8a47b447 Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson([]))
456 8a47b447 Michael Hanselmann
    self.assertRaises(NotImplementedError, self.client.CreateInstance,
457 8a47b447 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [], [],
458 8a47b447 Michael Hanselmann
                      dry_run=True)
459 8a47b447 Michael Hanselmann
460 95ab4de9 David Knowles
  def testCreateInstance(self):
461 8a47b447 Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson([rlib2._INST_CREATE_REQV1]))
462 8a47b447 Michael Hanselmann
    self.rapi.AddResponse("23030")
463 8a47b447 Michael Hanselmann
    job_id = self.client.CreateInstance("create", "inst1.example.com",
464 8a47b447 Michael Hanselmann
                                        "plain", [], [], dry_run=True)
465 8a47b447 Michael Hanselmann
    self.assertEqual(job_id, 23030)
466 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances)
467 95ab4de9 David Knowles
    self.assertDryRun()
468 95ab4de9 David Knowles
469 2a7c3583 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
470 8a47b447 Michael Hanselmann
471 8a47b447 Michael Hanselmann
    for field in ["dry_run", "beparams", "hvparams", "start"]:
472 8a47b447 Michael Hanselmann
      self.assertFalse(field in data)
473 8a47b447 Michael Hanselmann
474 8a47b447 Michael Hanselmann
    self.assertEqual(data["name"], "inst1.example.com")
475 8a47b447 Michael Hanselmann
    self.assertEqual(data["disk_template"], "plain")
476 8a47b447 Michael Hanselmann
477 8a47b447 Michael Hanselmann
  def testCreateInstance2(self):
478 8a47b447 Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson([rlib2._INST_CREATE_REQV1]))
479 8a47b447 Michael Hanselmann
    self.rapi.AddResponse("24740")
480 8a47b447 Michael Hanselmann
    job_id = self.client.CreateInstance("import", "inst2.example.com",
481 8a47b447 Michael Hanselmann
                                        "drbd8", [{"size": 100,}],
482 8a47b447 Michael Hanselmann
                                        [{}, {"bridge": "br1", }],
483 8a47b447 Michael Hanselmann
                                        dry_run=False, start=True,
484 8a47b447 Michael Hanselmann
                                        pnode="node1", snode="node9",
485 8a47b447 Michael Hanselmann
                                        ip_check=False)
486 8a47b447 Michael Hanselmann
    self.assertEqual(job_id, 24740)
487 8a47b447 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances)
488 8a47b447 Michael Hanselmann
489 2a7c3583 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
490 8a47b447 Michael Hanselmann
    self.assertEqual(data[rlib2._REQ_DATA_VERSION], 1)
491 8a47b447 Michael Hanselmann
    self.assertEqual(data["name"], "inst2.example.com")
492 8a47b447 Michael Hanselmann
    self.assertEqual(data["disk_template"], "drbd8")
493 8a47b447 Michael Hanselmann
    self.assertEqual(data["start"], True)
494 8a47b447 Michael Hanselmann
    self.assertEqual(data["ip_check"], False)
495 8a47b447 Michael Hanselmann
    self.assertEqualValues(data["disks"], [{"size": 100,}])
496 8a47b447 Michael Hanselmann
    self.assertEqualValues(data["nics"], [{}, {"bridge": "br1", }])
497 8a47b447 Michael Hanselmann
498 95ab4de9 David Knowles
  def testDeleteInstance(self):
499 cab667cc David Knowles
    self.rapi.AddResponse("1234")
500 cab667cc David Knowles
    self.assertEqual(1234, self.client.DeleteInstance("instance", dry_run=True))
501 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name)
502 95ab4de9 David Knowles
    self.assertItems(["instance"])
503 95ab4de9 David Knowles
    self.assertDryRun()
504 95ab4de9 David Knowles
505 95ab4de9 David Knowles
  def testGetInstanceTags(self):
506 95ab4de9 David Knowles
    self.rapi.AddResponse("[]")
507 95ab4de9 David Knowles
    self.assertEqual([], self.client.GetInstanceTags("fooinstance"))
508 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_tags)
509 95ab4de9 David Knowles
    self.assertItems(["fooinstance"])
510 95ab4de9 David Knowles
511 95ab4de9 David Knowles
  def testAddInstanceTags(self):
512 cab667cc David Knowles
    self.rapi.AddResponse("1234")
513 cab667cc David Knowles
    self.assertEqual(1234,
514 cab667cc David Knowles
        self.client.AddInstanceTags("fooinstance", ["awesome"], dry_run=True))
515 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_tags)
516 95ab4de9 David Knowles
    self.assertItems(["fooinstance"])
517 95ab4de9 David Knowles
    self.assertDryRun()
518 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
519 95ab4de9 David Knowles
520 95ab4de9 David Knowles
  def testDeleteInstanceTags(self):
521 cd577680 Michael Hanselmann
    self.rapi.AddResponse("25826")
522 cd577680 Michael Hanselmann
    self.assertEqual(25826, self.client.DeleteInstanceTags("foo", ["awesome"],
523 cd577680 Michael Hanselmann
                                                           dry_run=True))
524 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_tags)
525 95ab4de9 David Knowles
    self.assertItems(["foo"])
526 95ab4de9 David Knowles
    self.assertDryRun()
527 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
528 95ab4de9 David Knowles
529 95ab4de9 David Knowles
  def testRebootInstance(self):
530 cd577680 Michael Hanselmann
    self.rapi.AddResponse("6146")
531 cd577680 Michael Hanselmann
    job_id = self.client.RebootInstance("i-bar", reboot_type="hard",
532 cd577680 Michael Hanselmann
                                        ignore_secondaries=True, dry_run=True)
533 cd577680 Michael Hanselmann
    self.assertEqual(6146, job_id)
534 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_reboot)
535 95ab4de9 David Knowles
    self.assertItems(["i-bar"])
536 95ab4de9 David Knowles
    self.assertDryRun()
537 95ab4de9 David Knowles
    self.assertQuery("type", ["hard"])
538 10f5ab6c Michael Hanselmann
    self.assertQuery("ignore_secondaries", ["1"])
539 95ab4de9 David Knowles
540 95ab4de9 David Knowles
  def testShutdownInstance(self):
541 cd577680 Michael Hanselmann
    self.rapi.AddResponse("1487")
542 cd577680 Michael Hanselmann
    self.assertEqual(1487, self.client.ShutdownInstance("foo-instance",
543 cd577680 Michael Hanselmann
                                                        dry_run=True))
544 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_shutdown)
545 95ab4de9 David Knowles
    self.assertItems(["foo-instance"])
546 95ab4de9 David Knowles
    self.assertDryRun()
547 95ab4de9 David Knowles
548 95ab4de9 David Knowles
  def testStartupInstance(self):
549 cd577680 Michael Hanselmann
    self.rapi.AddResponse("27149")
550 cd577680 Michael Hanselmann
    self.assertEqual(27149, self.client.StartupInstance("bar-instance",
551 cd577680 Michael Hanselmann
                                                        dry_run=True))
552 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_startup)
553 95ab4de9 David Knowles
    self.assertItems(["bar-instance"])
554 95ab4de9 David Knowles
    self.assertDryRun()
555 95ab4de9 David Knowles
556 95ab4de9 David Knowles
  def testReinstallInstance(self):
557 cd577680 Michael Hanselmann
    self.rapi.AddResponse("19119")
558 cd577680 Michael Hanselmann
    self.assertEqual(19119, self.client.ReinstallInstance("baz-instance", "DOS",
559 cd577680 Michael Hanselmann
                                                          no_startup=True))
560 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_reinstall)
561 95ab4de9 David Knowles
    self.assertItems(["baz-instance"])
562 95ab4de9 David Knowles
    self.assertQuery("os", ["DOS"])
563 95ab4de9 David Knowles
    self.assertQuery("nostartup", ["1"])
564 95ab4de9 David Knowles
565 95ab4de9 David Knowles
  def testReplaceInstanceDisks(self):
566 95ab4de9 David Knowles
    self.rapi.AddResponse("999")
567 95ab4de9 David Knowles
    job_id = self.client.ReplaceInstanceDisks("instance-name",
568 bfc2002f Michael Hanselmann
        disks=[0, 1], dry_run=True, iallocator="hail")
569 95ab4de9 David Knowles
    self.assertEqual(999, job_id)
570 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_replace_disks)
571 95ab4de9 David Knowles
    self.assertItems(["instance-name"])
572 bfc2002f Michael Hanselmann
    self.assertQuery("disks", ["0,1"])
573 95ab4de9 David Knowles
    self.assertQuery("mode", ["replace_auto"])
574 95ab4de9 David Knowles
    self.assertQuery("iallocator", ["hail"])
575 95ab4de9 David Knowles
    self.assertDryRun()
576 95ab4de9 David Knowles
577 95ab4de9 David Knowles
    self.rapi.AddResponse("1000")
578 95ab4de9 David Knowles
    job_id = self.client.ReplaceInstanceDisks("instance-bar",
579 bfc2002f Michael Hanselmann
        disks=[1], mode="replace_on_secondary", remote_node="foo-node",
580 95ab4de9 David Knowles
        dry_run=True)
581 95ab4de9 David Knowles
    self.assertEqual(1000, job_id)
582 95ab4de9 David Knowles
    self.assertItems(["instance-bar"])
583 bfc2002f Michael Hanselmann
    self.assertQuery("disks", ["1"])
584 95ab4de9 David Knowles
    self.assertQuery("remote_node", ["foo-node"])
585 95ab4de9 David Knowles
    self.assertDryRun()
586 95ab4de9 David Knowles
587 bfc2002f Michael Hanselmann
    self.rapi.AddResponse("5175")
588 bfc2002f Michael Hanselmann
    self.assertEqual(5175, self.client.ReplaceInstanceDisks("instance-moo"))
589 bfc2002f Michael Hanselmann
    self.assertItems(["instance-moo"])
590 bfc2002f Michael Hanselmann
    self.assertQuery("disks", None)
591 bfc2002f Michael Hanselmann
592 ebeb600f Michael Hanselmann
  def testPrepareExport(self):
593 ebeb600f Michael Hanselmann
    self.rapi.AddResponse("8326")
594 ebeb600f Michael Hanselmann
    self.assertEqual(8326, self.client.PrepareExport("inst1", "local"))
595 ebeb600f Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_prepare_export)
596 ebeb600f Michael Hanselmann
    self.assertItems(["inst1"])
597 ebeb600f Michael Hanselmann
    self.assertQuery("mode", ["local"])
598 ebeb600f Michael Hanselmann
599 ebeb600f Michael Hanselmann
  def testExportInstance(self):
600 ebeb600f Michael Hanselmann
    self.rapi.AddResponse("19695")
601 ebeb600f Michael Hanselmann
    job_id = self.client.ExportInstance("inst2", "local", "nodeX",
602 ebeb600f Michael Hanselmann
                                        shutdown=True)
603 ebeb600f Michael Hanselmann
    self.assertEqual(job_id, 19695)
604 ebeb600f Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_export)
605 ebeb600f Michael Hanselmann
    self.assertItems(["inst2"])
606 ebeb600f Michael Hanselmann
607 2a7c3583 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
608 ebeb600f Michael Hanselmann
    self.assertEqual(data["mode"], "local")
609 ebeb600f Michael Hanselmann
    self.assertEqual(data["destination"], "nodeX")
610 ebeb600f Michael Hanselmann
    self.assertEqual(data["shutdown"], True)
611 ebeb600f Michael Hanselmann
612 95ab4de9 David Knowles
  def testGetJobs(self):
613 2004e673 Iustin Pop
    self.rapi.AddResponse('[ { "id": "123", "uri": "\\/2\\/jobs\\/123" },'
614 2004e673 Iustin Pop
                          '  { "id": "124", "uri": "\\/2\\/jobs\\/124" } ]')
615 95ab4de9 David Knowles
    self.assertEqual([123, 124], self.client.GetJobs())
616 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_jobs)
617 95ab4de9 David Knowles
618 95ab4de9 David Knowles
  def testGetJobStatus(self):
619 95ab4de9 David Knowles
    self.rapi.AddResponse("{\"foo\": \"bar\"}")
620 95ab4de9 David Knowles
    self.assertEqual({"foo": "bar"}, self.client.GetJobStatus(1234))
621 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_jobs_id)
622 95ab4de9 David Knowles
    self.assertItems(["1234"])
623 95ab4de9 David Knowles
624 d9b67f70 Michael Hanselmann
  def testWaitForJobChange(self):
625 d9b67f70 Michael Hanselmann
    fields = ["id", "summary"]
626 d9b67f70 Michael Hanselmann
    expected = {
627 d9b67f70 Michael Hanselmann
      "job_info": [123, "something"],
628 d9b67f70 Michael Hanselmann
      "log_entries": [],
629 d9b67f70 Michael Hanselmann
      }
630 d9b67f70 Michael Hanselmann
631 d9b67f70 Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson(expected))
632 d9b67f70 Michael Hanselmann
    result = self.client.WaitForJobChange(123, fields, [], -1)
633 d9b67f70 Michael Hanselmann
    self.assertEqualValues(expected, result)
634 d9b67f70 Michael Hanselmann
    self.assertHandler(rlib2.R_2_jobs_id_wait)
635 d9b67f70 Michael Hanselmann
    self.assertItems(["123"])
636 d9b67f70 Michael Hanselmann
637 cf9ada49 Michael Hanselmann
  def testCancelJob(self):
638 cd577680 Michael Hanselmann
    self.rapi.AddResponse("[true, \"Job 123 will be canceled\"]")
639 cd577680 Michael Hanselmann
    self.assertEqual([True, "Job 123 will be canceled"],
640 cf9ada49 Michael Hanselmann
                     self.client.CancelJob(999, dry_run=True))
641 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_jobs_id)
642 95ab4de9 David Knowles
    self.assertItems(["999"])
643 95ab4de9 David Knowles
    self.assertDryRun()
644 95ab4de9 David Knowles
645 95ab4de9 David Knowles
  def testGetNodes(self):
646 95ab4de9 David Knowles
    self.rapi.AddResponse("[ { \"id\": \"node1\", \"uri\": \"uri1\" },"
647 95ab4de9 David Knowles
                          " { \"id\": \"node2\", \"uri\": \"uri2\" } ]")
648 95ab4de9 David Knowles
    self.assertEqual(["node1", "node2"], self.client.GetNodes())
649 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes)
650 95ab4de9 David Knowles
651 95ab4de9 David Knowles
    self.rapi.AddResponse("[ { \"id\": \"node1\", \"uri\": \"uri1\" },"
652 95ab4de9 David Knowles
                          " { \"id\": \"node2\", \"uri\": \"uri2\" } ]")
653 95ab4de9 David Knowles
    self.assertEqual([{"id": "node1", "uri": "uri1"},
654 95ab4de9 David Knowles
                      {"id": "node2", "uri": "uri2"}],
655 95ab4de9 David Knowles
                     self.client.GetNodes(bulk=True))
656 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes)
657 95ab4de9 David Knowles
    self.assertBulk()
658 95ab4de9 David Knowles
659 591e5103 Michael Hanselmann
  def testGetNode(self):
660 95ab4de9 David Knowles
    self.rapi.AddResponse("{}")
661 591e5103 Michael Hanselmann
    self.assertEqual({}, self.client.GetNode("node-foo"))
662 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name)
663 95ab4de9 David Knowles
    self.assertItems(["node-foo"])
664 95ab4de9 David Knowles
665 95ab4de9 David Knowles
  def testEvacuateNode(self):
666 95ab4de9 David Knowles
    self.rapi.AddResponse("9876")
667 95ab4de9 David Knowles
    job_id = self.client.EvacuateNode("node-1", remote_node="node-2")
668 95ab4de9 David Knowles
    self.assertEqual(9876, job_id)
669 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_evacuate)
670 95ab4de9 David Knowles
    self.assertItems(["node-1"])
671 95ab4de9 David Knowles
    self.assertQuery("remote_node", ["node-2"])
672 95ab4de9 David Knowles
673 95ab4de9 David Knowles
    self.rapi.AddResponse("8888")
674 95ab4de9 David Knowles
    job_id = self.client.EvacuateNode("node-3", iallocator="hail", dry_run=True)
675 95ab4de9 David Knowles
    self.assertEqual(8888, job_id)
676 95ab4de9 David Knowles
    self.assertItems(["node-3"])
677 95ab4de9 David Knowles
    self.assertQuery("iallocator", ["hail"])
678 95ab4de9 David Knowles
    self.assertDryRun()
679 95ab4de9 David Knowles
680 95ab4de9 David Knowles
    self.assertRaises(client.GanetiApiError,
681 95ab4de9 David Knowles
                      self.client.EvacuateNode,
682 95ab4de9 David Knowles
                      "node-4", iallocator="hail", remote_node="node-5")
683 95ab4de9 David Knowles
684 95ab4de9 David Knowles
  def testMigrateNode(self):
685 95ab4de9 David Knowles
    self.rapi.AddResponse("1111")
686 95ab4de9 David Knowles
    self.assertEqual(1111, self.client.MigrateNode("node-a", dry_run=True))
687 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_migrate)
688 95ab4de9 David Knowles
    self.assertItems(["node-a"])
689 95ab4de9 David Knowles
    self.assertQuery("live", ["1"])
690 95ab4de9 David Knowles
    self.assertDryRun()
691 95ab4de9 David Knowles
692 95ab4de9 David Knowles
  def testGetNodeRole(self):
693 95ab4de9 David Knowles
    self.rapi.AddResponse("\"master\"")
694 95ab4de9 David Knowles
    self.assertEqual("master", self.client.GetNodeRole("node-a"))
695 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_role)
696 95ab4de9 David Knowles
    self.assertItems(["node-a"])
697 95ab4de9 David Knowles
698 95ab4de9 David Knowles
  def testSetNodeRole(self):
699 95ab4de9 David Knowles
    self.rapi.AddResponse("789")
700 95ab4de9 David Knowles
    self.assertEqual(789,
701 95ab4de9 David Knowles
        self.client.SetNodeRole("node-foo", "master-candidate", force=True))
702 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_role)
703 95ab4de9 David Knowles
    self.assertItems(["node-foo"])
704 10f5ab6c Michael Hanselmann
    self.assertQuery("force", ["1"])
705 2a7c3583 Michael Hanselmann
    self.assertEqual("\"master-candidate\"", self.rapi.GetLastRequestData())
706 95ab4de9 David Knowles
707 95ab4de9 David Knowles
  def testGetNodeStorageUnits(self):
708 95ab4de9 David Knowles
    self.rapi.AddResponse("42")
709 95ab4de9 David Knowles
    self.assertEqual(42,
710 95ab4de9 David Knowles
        self.client.GetNodeStorageUnits("node-x", "lvm-pv", "fields"))
711 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_storage)
712 95ab4de9 David Knowles
    self.assertItems(["node-x"])
713 95ab4de9 David Knowles
    self.assertQuery("storage_type", ["lvm-pv"])
714 95ab4de9 David Knowles
    self.assertQuery("output_fields", ["fields"])
715 95ab4de9 David Knowles
716 95ab4de9 David Knowles
  def testModifyNodeStorageUnits(self):
717 95ab4de9 David Knowles
    self.rapi.AddResponse("14")
718 95ab4de9 David Knowles
    self.assertEqual(14,
719 95ab4de9 David Knowles
        self.client.ModifyNodeStorageUnits("node-z", "lvm-pv", "hda"))
720 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_storage_modify)
721 95ab4de9 David Knowles
    self.assertItems(["node-z"])
722 95ab4de9 David Knowles
    self.assertQuery("storage_type", ["lvm-pv"])
723 95ab4de9 David Knowles
    self.assertQuery("name", ["hda"])
724 fde28316 Michael Hanselmann
    self.assertQuery("allocatable", None)
725 fde28316 Michael Hanselmann
726 fde28316 Michael Hanselmann
    for allocatable, query_allocatable in [(True, "1"), (False, "0")]:
727 fde28316 Michael Hanselmann
      self.rapi.AddResponse("7205")
728 fde28316 Michael Hanselmann
      job_id = self.client.ModifyNodeStorageUnits("node-z", "lvm-pv", "hda",
729 fde28316 Michael Hanselmann
                                                  allocatable=allocatable)
730 fde28316 Michael Hanselmann
      self.assertEqual(7205, job_id)
731 fde28316 Michael Hanselmann
      self.assertHandler(rlib2.R_2_nodes_name_storage_modify)
732 fde28316 Michael Hanselmann
      self.assertItems(["node-z"])
733 fde28316 Michael Hanselmann
      self.assertQuery("storage_type", ["lvm-pv"])
734 fde28316 Michael Hanselmann
      self.assertQuery("name", ["hda"])
735 fde28316 Michael Hanselmann
      self.assertQuery("allocatable", [query_allocatable])
736 95ab4de9 David Knowles
737 752df8bb Michael Hanselmann
  def testRepairNodeStorageUnits(self):
738 752df8bb Michael Hanselmann
    self.rapi.AddResponse("99")
739 752df8bb Michael Hanselmann
    self.assertEqual(99, self.client.RepairNodeStorageUnits("node-z", "lvm-pv",
740 752df8bb Michael Hanselmann
                                                            "hda"))
741 752df8bb Michael Hanselmann
    self.assertHandler(rlib2.R_2_nodes_name_storage_repair)
742 752df8bb Michael Hanselmann
    self.assertItems(["node-z"])
743 752df8bb Michael Hanselmann
    self.assertQuery("storage_type", ["lvm-pv"])
744 752df8bb Michael Hanselmann
    self.assertQuery("name", ["hda"])
745 752df8bb Michael Hanselmann
746 95ab4de9 David Knowles
  def testGetNodeTags(self):
747 95ab4de9 David Knowles
    self.rapi.AddResponse("[\"fry\", \"bender\"]")
748 95ab4de9 David Knowles
    self.assertEqual(["fry", "bender"], self.client.GetNodeTags("node-k"))
749 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_tags)
750 95ab4de9 David Knowles
    self.assertItems(["node-k"])
751 95ab4de9 David Knowles
752 95ab4de9 David Knowles
  def testAddNodeTags(self):
753 cab667cc David Knowles
    self.rapi.AddResponse("1234")
754 cab667cc David Knowles
    self.assertEqual(1234,
755 cab667cc David Knowles
        self.client.AddNodeTags("node-v", ["awesome"], dry_run=True))
756 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_tags)
757 95ab4de9 David Knowles
    self.assertItems(["node-v"])
758 95ab4de9 David Knowles
    self.assertDryRun()
759 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
760 95ab4de9 David Knowles
761 95ab4de9 David Knowles
  def testDeleteNodeTags(self):
762 cd577680 Michael Hanselmann
    self.rapi.AddResponse("16861")
763 cd577680 Michael Hanselmann
    self.assertEqual(16861, self.client.DeleteNodeTags("node-w", ["awesome"],
764 cd577680 Michael Hanselmann
                                                       dry_run=True))
765 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_tags)
766 95ab4de9 David Knowles
    self.assertItems(["node-w"])
767 95ab4de9 David Knowles
    self.assertDryRun()
768 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
769 95ab4de9 David Knowles
770 95ab4de9 David Knowles
771 95ab4de9 David Knowles
if __name__ == '__main__':
772 2a7c3583 Michael Hanselmann
  client.UsesRapiClient(testutils.GanetiTestProgram)()