Statistics
| Branch: | Tag: | Revision:

root / test / ganeti.rapi.client_unittest.py @ e543a42f

History | View | Annotate | Download (34 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 48436b97 Michael Hanselmann
  def CountPending(self):
98 48436b97 Michael Hanselmann
    return len(self._responses)
99 48436b97 Michael Hanselmann
100 95ab4de9 David Knowles
  def GetLastHandler(self):
101 95ab4de9 David Knowles
    return self._last_handler
102 95ab4de9 David Knowles
103 2a7c3583 Michael Hanselmann
  def GetLastRequestData(self):
104 2a7c3583 Michael Hanselmann
    return self._last_req_data
105 2a7c3583 Michael Hanselmann
106 2a7c3583 Michael Hanselmann
  def FetchResponse(self, path, method, request_body):
107 2a7c3583 Michael Hanselmann
    self._last_req_data = request_body
108 2a7c3583 Michael Hanselmann
109 95ab4de9 David Knowles
    try:
110 95ab4de9 David Knowles
      HandlerClass, items, args = self._mapper.getController(path)
111 95ab4de9 David Knowles
      self._last_handler = HandlerClass(items, args, None)
112 95ab4de9 David Knowles
      if not hasattr(self._last_handler, method.upper()):
113 de4f53e6 Michael Hanselmann
        raise http.HttpNotImplemented(message="Method not implemented")
114 de4f53e6 Michael Hanselmann
115 95ab4de9 David Knowles
    except http.HttpException, ex:
116 95ab4de9 David Knowles
      code = ex.code
117 95ab4de9 David Knowles
      response = ex.message
118 de4f53e6 Michael Hanselmann
    else:
119 de4f53e6 Michael Hanselmann
      if not self._responses:
120 de4f53e6 Michael Hanselmann
        raise Exception("No responses")
121 95ab4de9 David Knowles
122 de4f53e6 Michael Hanselmann
      (code, response) = self._responses.pop()
123 95ab4de9 David Knowles
124 95ab4de9 David Knowles
    return code, response
125 95ab4de9 David Knowles
126 95ab4de9 David Knowles
127 2a7c3583 Michael Hanselmann
class TestConstants(unittest.TestCase):
128 2a7c3583 Michael Hanselmann
  def test(self):
129 2a7c3583 Michael Hanselmann
    self.assertEqual(client.GANETI_RAPI_PORT, constants.DEFAULT_RAPI_PORT)
130 2a7c3583 Michael Hanselmann
    self.assertEqual(client.GANETI_RAPI_VERSION, constants.RAPI_VERSION)
131 2a7c3583 Michael Hanselmann
    self.assertEqual(client.HTTP_APP_JSON, http.HTTP_APP_JSON)
132 2a7c3583 Michael Hanselmann
    self.assertEqual(client._REQ_DATA_VERSION_FIELD, rlib2._REQ_DATA_VERSION)
133 2a7c3583 Michael Hanselmann
    self.assertEqual(client._INST_CREATE_REQV1, rlib2._INST_CREATE_REQV1)
134 48436b97 Michael Hanselmann
    self.assertEqual(client._INST_NIC_PARAMS, constants.INIC_PARAMS)
135 2a7c3583 Michael Hanselmann
136 2a7c3583 Michael Hanselmann
137 95ab4de9 David Knowles
class RapiMockTest(unittest.TestCase):
138 95ab4de9 David Knowles
  def test(self):
139 95ab4de9 David Knowles
    rapi = RapiMock()
140 95ab4de9 David Knowles
    path = "/version"
141 2a7c3583 Michael Hanselmann
    self.assertEqual((404, None), rapi.FetchResponse("/foo", "GET", None))
142 09127904 Michael Hanselmann
    self.assertEqual((501, "Method not implemented"),
143 2a7c3583 Michael Hanselmann
                     rapi.FetchResponse("/version", "POST", None))
144 95ab4de9 David Knowles
    rapi.AddResponse("2")
145 2a7c3583 Michael Hanselmann
    code, response = rapi.FetchResponse("/version", "GET", None)
146 95ab4de9 David Knowles
    self.assertEqual(200, code)
147 95ab4de9 David Knowles
    self.assertEqual("2", response)
148 95ab4de9 David Knowles
    self.failUnless(isinstance(rapi.GetLastHandler(), rlib2.R_version))
149 95ab4de9 David Knowles
150 95ab4de9 David Knowles
151 2a7c3583 Michael Hanselmann
def _FakeNoSslPycurlVersion():
152 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
153 2a7c3583 Michael Hanselmann
  return (3, "7.16.0", 462848, "mysystem", 1581, None, 0)
154 2a7c3583 Michael Hanselmann
155 2a7c3583 Michael Hanselmann
156 2a7c3583 Michael Hanselmann
def _FakeFancySslPycurlVersion():
157 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
158 2a7c3583 Michael Hanselmann
  return (3, "7.16.0", 462848, "mysystem", 1581, "FancySSL/1.2.3", 0)
159 2a7c3583 Michael Hanselmann
160 2a7c3583 Michael Hanselmann
161 2a7c3583 Michael Hanselmann
def _FakeOpenSslPycurlVersion():
162 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
163 2a7c3583 Michael Hanselmann
  return (2, "7.15.5", 462597, "othersystem", 668, "OpenSSL/0.9.8c", 0)
164 2a7c3583 Michael Hanselmann
165 2a7c3583 Michael Hanselmann
166 2a7c3583 Michael Hanselmann
def _FakeGnuTlsPycurlVersion():
167 2a7c3583 Michael Hanselmann
  # Note: incomplete version tuple
168 2a7c3583 Michael Hanselmann
  return (3, "7.18.0", 463360, "somesystem", 1581, "GnuTLS/2.0.4", 0)
169 2a7c3583 Michael Hanselmann
170 2a7c3583 Michael Hanselmann
171 2a7c3583 Michael Hanselmann
class TestExtendedConfig(unittest.TestCase):
172 2a7c3583 Michael Hanselmann
  def testAuth(self):
173 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com",
174 2a7c3583 Michael Hanselmann
                                 username="user", password="pw",
175 a5eba783 Michael Hanselmann
                                 curl_factory=lambda: FakeCurl(RapiMock()))
176 2a7c3583 Michael Hanselmann
177 a5eba783 Michael Hanselmann
    curl = cl._CreateCurl()
178 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.HTTPAUTH), pycurl.HTTPAUTH_BASIC)
179 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.USERPWD), "user:pw")
180 2a7c3583 Michael Hanselmann
181 2a7c3583 Michael Hanselmann
  def testInvalidAuth(self):
182 2a7c3583 Michael Hanselmann
    # No username
183 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GanetiRapiClient,
184 2a7c3583 Michael Hanselmann
                      "master-a.example.com", password="pw")
185 2a7c3583 Michael Hanselmann
    # No password
186 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GanetiRapiClient,
187 2a7c3583 Michael Hanselmann
                      "master-b.example.com", username="user")
188 2a7c3583 Michael Hanselmann
189 2a7c3583 Michael Hanselmann
  def testCertVerifyInvalidCombinations(self):
190 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GenericCurlConfig,
191 2a7c3583 Michael Hanselmann
                      use_curl_cabundle=True, cafile="cert1.pem")
192 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GenericCurlConfig,
193 2a7c3583 Michael Hanselmann
                      use_curl_cabundle=True, capath="certs/")
194 2a7c3583 Michael Hanselmann
    self.assertRaises(client.Error, client.GenericCurlConfig,
195 2a7c3583 Michael Hanselmann
                      use_curl_cabundle=True,
196 2a7c3583 Michael Hanselmann
                      cafile="cert1.pem", capath="certs/")
197 2a7c3583 Michael Hanselmann
198 2a7c3583 Michael Hanselmann
  def testProxySignalVerifyHostname(self):
199 2a7c3583 Michael Hanselmann
    for use_gnutls in [False, True]:
200 2a7c3583 Michael Hanselmann
      if use_gnutls:
201 2a7c3583 Michael Hanselmann
        pcverfn = _FakeGnuTlsPycurlVersion
202 2a7c3583 Michael Hanselmann
      else:
203 2a7c3583 Michael Hanselmann
        pcverfn = _FakeOpenSslPycurlVersion
204 2a7c3583 Michael Hanselmann
205 2a7c3583 Michael Hanselmann
      for proxy in ["", "http://127.0.0.1:1234"]:
206 2a7c3583 Michael Hanselmann
        for use_signal in [False, True]:
207 2a7c3583 Michael Hanselmann
          for verify_hostname in [False, True]:
208 2a7c3583 Michael Hanselmann
            cfgfn = client.GenericCurlConfig(proxy=proxy, use_signal=use_signal,
209 2a7c3583 Michael Hanselmann
                                             verify_hostname=verify_hostname,
210 2a7c3583 Michael Hanselmann
                                             _pycurl_version_fn=pcverfn)
211 2a7c3583 Michael Hanselmann
212 a5eba783 Michael Hanselmann
            curl_factory = lambda: FakeCurl(RapiMock())
213 2a7c3583 Michael Hanselmann
            cl = client.GanetiRapiClient("master.example.com",
214 a5eba783 Michael Hanselmann
                                         curl_config_fn=cfgfn,
215 a5eba783 Michael Hanselmann
                                         curl_factory=curl_factory)
216 2a7c3583 Michael Hanselmann
217 a5eba783 Michael Hanselmann
            curl = cl._CreateCurl()
218 2a7c3583 Michael Hanselmann
            self.assertEqual(curl.getopt(pycurl.PROXY), proxy)
219 2a7c3583 Michael Hanselmann
            self.assertEqual(curl.getopt(pycurl.NOSIGNAL), not use_signal)
220 2a7c3583 Michael Hanselmann
221 2a7c3583 Michael Hanselmann
            if verify_hostname:
222 2a7c3583 Michael Hanselmann
              self.assertEqual(curl.getopt(pycurl.SSL_VERIFYHOST), 2)
223 2a7c3583 Michael Hanselmann
            else:
224 2a7c3583 Michael Hanselmann
              self.assertEqual(curl.getopt(pycurl.SSL_VERIFYHOST), 0)
225 2a7c3583 Michael Hanselmann
226 2a7c3583 Michael Hanselmann
  def testNoCertVerify(self):
227 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig()
228 2a7c3583 Michael Hanselmann
229 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
230 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
231 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
232 2a7c3583 Michael Hanselmann
233 a5eba783 Michael Hanselmann
    curl = cl._CreateCurl()
234 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.SSL_VERIFYPEER))
235 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAINFO))
236 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAPATH))
237 2a7c3583 Michael Hanselmann
238 2a7c3583 Michael Hanselmann
  def testCertVerifyCurlBundle(self):
239 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(use_curl_cabundle=True)
240 2a7c3583 Michael Hanselmann
241 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
242 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
243 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
244 2a7c3583 Michael Hanselmann
245 a5eba783 Michael Hanselmann
    curl = cl._CreateCurl()
246 2a7c3583 Michael Hanselmann
    self.assert_(curl.getopt(pycurl.SSL_VERIFYPEER))
247 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAINFO))
248 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAPATH))
249 2a7c3583 Michael Hanselmann
250 2a7c3583 Michael Hanselmann
  def testCertVerifyCafile(self):
251 2a7c3583 Michael Hanselmann
    mycert = "/tmp/some/UNUSED/cert/file.pem"
252 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(cafile=mycert)
253 2a7c3583 Michael Hanselmann
254 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
255 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
256 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
257 2a7c3583 Michael Hanselmann
258 a5eba783 Michael Hanselmann
    curl = cl._CreateCurl()
259 2a7c3583 Michael Hanselmann
    self.assert_(curl.getopt(pycurl.SSL_VERIFYPEER))
260 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.CAINFO), mycert)
261 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAPATH))
262 2a7c3583 Michael Hanselmann
263 2a7c3583 Michael Hanselmann
  def testCertVerifyCapath(self):
264 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
265 2a7c3583 Michael Hanselmann
    pcverfn = _FakeOpenSslPycurlVersion
266 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
267 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
268 2a7c3583 Michael Hanselmann
269 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
270 2a7c3583 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
271 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
272 2a7c3583 Michael Hanselmann
273 a5eba783 Michael Hanselmann
    curl = cl._CreateCurl()
274 2a7c3583 Michael Hanselmann
    self.assert_(curl.getopt(pycurl.SSL_VERIFYPEER))
275 2a7c3583 Michael Hanselmann
    self.assertEqual(curl.getopt(pycurl.CAPATH), certdir)
276 2a7c3583 Michael Hanselmann
    self.assertFalse(curl.getopt(pycurl.CAINFO))
277 2a7c3583 Michael Hanselmann
278 2a7c3583 Michael Hanselmann
  def testCertVerifyCapathGnuTls(self):
279 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
280 2a7c3583 Michael Hanselmann
    pcverfn = _FakeGnuTlsPycurlVersion
281 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
282 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
283 2a7c3583 Michael Hanselmann
284 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
285 a5eba783 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
286 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
287 a5eba783 Michael Hanselmann
288 a5eba783 Michael Hanselmann
    self.assertRaises(client.Error, cl._CreateCurl)
289 2a7c3583 Michael Hanselmann
290 2a7c3583 Michael Hanselmann
  def testCertVerifyNoSsl(self):
291 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
292 2a7c3583 Michael Hanselmann
    pcverfn = _FakeNoSslPycurlVersion
293 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
294 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
295 2a7c3583 Michael Hanselmann
296 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
297 a5eba783 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
298 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
299 a5eba783 Michael Hanselmann
300 a5eba783 Michael Hanselmann
    self.assertRaises(client.Error, cl._CreateCurl)
301 2a7c3583 Michael Hanselmann
302 2a7c3583 Michael Hanselmann
  def testCertVerifyFancySsl(self):
303 2a7c3583 Michael Hanselmann
    certdir = "/tmp/some/UNUSED/cert/directory"
304 2a7c3583 Michael Hanselmann
    pcverfn = _FakeFancySslPycurlVersion
305 2a7c3583 Michael Hanselmann
    cfgfn = client.GenericCurlConfig(capath=certdir,
306 2a7c3583 Michael Hanselmann
                                     _pycurl_version_fn=pcverfn)
307 2a7c3583 Michael Hanselmann
308 a5eba783 Michael Hanselmann
    curl_factory = lambda: FakeCurl(RapiMock())
309 a5eba783 Michael Hanselmann
    cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
310 a5eba783 Michael Hanselmann
                                 curl_factory=curl_factory)
311 a5eba783 Michael Hanselmann
312 a5eba783 Michael Hanselmann
    self.assertRaises(NotImplementedError, cl._CreateCurl)
313 2a7c3583 Michael Hanselmann
314 2a7c3583 Michael Hanselmann
  def testCertVerifyCapath(self):
315 2a7c3583 Michael Hanselmann
    for connect_timeout in [None, 1, 5, 10, 30, 60, 300]:
316 2a7c3583 Michael Hanselmann
      for timeout in [None, 1, 30, 60, 3600, 24 * 3600]:
317 2a7c3583 Michael Hanselmann
        cfgfn = client.GenericCurlConfig(connect_timeout=connect_timeout,
318 2a7c3583 Michael Hanselmann
                                         timeout=timeout)
319 2a7c3583 Michael Hanselmann
320 a5eba783 Michael Hanselmann
        curl_factory = lambda: FakeCurl(RapiMock())
321 2a7c3583 Michael Hanselmann
        cl = client.GanetiRapiClient("master.example.com", curl_config_fn=cfgfn,
322 a5eba783 Michael Hanselmann
                                     curl_factory=curl_factory)
323 2a7c3583 Michael Hanselmann
324 a5eba783 Michael Hanselmann
        curl = cl._CreateCurl()
325 2a7c3583 Michael Hanselmann
        self.assertEqual(curl.getopt(pycurl.CONNECTTIMEOUT), connect_timeout)
326 2a7c3583 Michael Hanselmann
        self.assertEqual(curl.getopt(pycurl.TIMEOUT), timeout)
327 2a7c3583 Michael Hanselmann
328 2a7c3583 Michael Hanselmann
329 d9b67f70 Michael Hanselmann
class GanetiRapiClientTests(testutils.GanetiTestCase):
330 95ab4de9 David Knowles
  def setUp(self):
331 d9b67f70 Michael Hanselmann
    testutils.GanetiTestCase.setUp(self)
332 d9b67f70 Michael Hanselmann
333 95ab4de9 David Knowles
    self.rapi = RapiMock()
334 2a7c3583 Michael Hanselmann
    self.curl = FakeCurl(self.rapi)
335 2a7c3583 Michael Hanselmann
    self.client = client.GanetiRapiClient("master.example.com",
336 a5eba783 Michael Hanselmann
                                          curl_factory=lambda: self.curl)
337 95ab4de9 David Knowles
338 95ab4de9 David Knowles
  def assertHandler(self, handler_cls):
339 95ab4de9 David Knowles
    self.failUnless(isinstance(self.rapi.GetLastHandler(), handler_cls))
340 95ab4de9 David Knowles
341 95ab4de9 David Knowles
  def assertQuery(self, key, value):
342 95ab4de9 David Knowles
    self.assertEqual(value, self.rapi.GetLastHandler().queryargs.get(key, None))
343 95ab4de9 David Knowles
344 95ab4de9 David Knowles
  def assertItems(self, items):
345 95ab4de9 David Knowles
    self.assertEqual(items, self.rapi.GetLastHandler().items)
346 95ab4de9 David Knowles
347 95ab4de9 David Knowles
  def assertBulk(self):
348 95ab4de9 David Knowles
    self.assertTrue(self.rapi.GetLastHandler().useBulk())
349 95ab4de9 David Knowles
350 95ab4de9 David Knowles
  def assertDryRun(self):
351 95ab4de9 David Knowles
    self.assertTrue(self.rapi.GetLastHandler().dryRun())
352 95ab4de9 David Knowles
353 10f5ab6c Michael Hanselmann
  def testEncodeQuery(self):
354 10f5ab6c Michael Hanselmann
    query = [
355 10f5ab6c Michael Hanselmann
      ("a", None),
356 10f5ab6c Michael Hanselmann
      ("b", 1),
357 10f5ab6c Michael Hanselmann
      ("c", 2),
358 10f5ab6c Michael Hanselmann
      ("d", "Foo"),
359 10f5ab6c Michael Hanselmann
      ("e", True),
360 10f5ab6c Michael Hanselmann
      ]
361 10f5ab6c Michael Hanselmann
362 10f5ab6c Michael Hanselmann
    expected = [
363 10f5ab6c Michael Hanselmann
      ("a", ""),
364 10f5ab6c Michael Hanselmann
      ("b", 1),
365 10f5ab6c Michael Hanselmann
      ("c", 2),
366 10f5ab6c Michael Hanselmann
      ("d", "Foo"),
367 10f5ab6c Michael Hanselmann
      ("e", 1),
368 10f5ab6c Michael Hanselmann
      ]
369 10f5ab6c Michael Hanselmann
370 10f5ab6c Michael Hanselmann
    self.assertEqualValues(self.client._EncodeQuery(query),
371 10f5ab6c Michael Hanselmann
                           expected)
372 10f5ab6c Michael Hanselmann
373 10f5ab6c Michael Hanselmann
    # invalid types
374 10f5ab6c Michael Hanselmann
    for i in [[1, 2, 3], {"moo": "boo"}, (1, 2, 3)]:
375 10f5ab6c Michael Hanselmann
      self.assertRaises(ValueError, self.client._EncodeQuery, [("x", i)])
376 10f5ab6c Michael Hanselmann
377 a5eba783 Michael Hanselmann
  def testCurlSettings(self):
378 a5eba783 Michael Hanselmann
    self.rapi.AddResponse("2")
379 a5eba783 Michael Hanselmann
    self.assertEqual(2, self.client.GetVersion())
380 a5eba783 Michael Hanselmann
    self.assertHandler(rlib2.R_version)
381 a5eba783 Michael Hanselmann
382 a5eba783 Michael Hanselmann
    # Signals should be disabled by default
383 a5eba783 Michael Hanselmann
    self.assert_(self.curl.getopt(pycurl.NOSIGNAL))
384 a5eba783 Michael Hanselmann
385 a5eba783 Michael Hanselmann
    # No auth and no proxy
386 a5eba783 Michael Hanselmann
    self.assertFalse(self.curl.getopt(pycurl.USERPWD))
387 a5eba783 Michael Hanselmann
    self.assert_(self.curl.getopt(pycurl.PROXY) is None)
388 a5eba783 Michael Hanselmann
389 a5eba783 Michael Hanselmann
    # Content-type is required for requests
390 a5eba783 Michael Hanselmann
    headers = self.curl.getopt(pycurl.HTTPHEADER)
391 a5eba783 Michael Hanselmann
    self.assert_("Content-type: application/json" in headers)
392 a5eba783 Michael Hanselmann
393 8a019a03 Michael Hanselmann
  def testHttpError(self):
394 8a019a03 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
395 8a019a03 Michael Hanselmann
    try:
396 8a019a03 Michael Hanselmann
      self.client.GetJobStatus(15140)
397 8a019a03 Michael Hanselmann
    except client.GanetiApiError, err:
398 8a019a03 Michael Hanselmann
      self.assertEqual(err.code, 404)
399 8a019a03 Michael Hanselmann
    else:
400 8a019a03 Michael Hanselmann
      self.fail("Didn't raise exception")
401 8a019a03 Michael Hanselmann
402 95ab4de9 David Knowles
  def testGetVersion(self):
403 95ab4de9 David Knowles
    self.rapi.AddResponse("2")
404 95ab4de9 David Knowles
    self.assertEqual(2, self.client.GetVersion())
405 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_version)
406 95ab4de9 David Knowles
407 7eac4a4d Michael Hanselmann
  def testGetFeatures(self):
408 7eac4a4d Michael Hanselmann
    for features in [[], ["foo", "bar", "baz"]]:
409 7eac4a4d Michael Hanselmann
      self.rapi.AddResponse(serializer.DumpJson(features))
410 7eac4a4d Michael Hanselmann
      self.assertEqual(features, self.client.GetFeatures())
411 7eac4a4d Michael Hanselmann
      self.assertHandler(rlib2.R_2_features)
412 7eac4a4d Michael Hanselmann
413 48436b97 Michael Hanselmann
  def testGetFeaturesNotFound(self):
414 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
415 48436b97 Michael Hanselmann
    self.assertEqual([], self.client.GetFeatures())
416 48436b97 Michael Hanselmann
417 95ab4de9 David Knowles
  def testGetOperatingSystems(self):
418 95ab4de9 David Knowles
    self.rapi.AddResponse("[\"beos\"]")
419 95ab4de9 David Knowles
    self.assertEqual(["beos"], self.client.GetOperatingSystems())
420 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_os)
421 95ab4de9 David Knowles
422 95ab4de9 David Knowles
  def testGetClusterTags(self):
423 95ab4de9 David Knowles
    self.rapi.AddResponse("[\"tag\"]")
424 95ab4de9 David Knowles
    self.assertEqual(["tag"], self.client.GetClusterTags())
425 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_tags)
426 95ab4de9 David Knowles
427 95ab4de9 David Knowles
  def testAddClusterTags(self):
428 cab667cc David Knowles
    self.rapi.AddResponse("1234")
429 cab667cc David Knowles
    self.assertEqual(1234,
430 cab667cc David Knowles
        self.client.AddClusterTags(["awesome"], dry_run=True))
431 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_tags)
432 95ab4de9 David Knowles
    self.assertDryRun()
433 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
434 95ab4de9 David Knowles
435 95ab4de9 David Knowles
  def testDeleteClusterTags(self):
436 cd577680 Michael Hanselmann
    self.rapi.AddResponse("5107")
437 cd577680 Michael Hanselmann
    self.assertEqual(5107, self.client.DeleteClusterTags(["awesome"],
438 cd577680 Michael Hanselmann
                                                         dry_run=True))
439 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_tags)
440 95ab4de9 David Knowles
    self.assertDryRun()
441 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
442 95ab4de9 David Knowles
443 95ab4de9 David Knowles
  def testGetInfo(self):
444 95ab4de9 David Knowles
    self.rapi.AddResponse("{}")
445 95ab4de9 David Knowles
    self.assertEqual({}, self.client.GetInfo())
446 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_info)
447 95ab4de9 David Knowles
448 95ab4de9 David Knowles
  def testGetInstances(self):
449 95ab4de9 David Knowles
    self.rapi.AddResponse("[]")
450 95ab4de9 David Knowles
    self.assertEqual([], self.client.GetInstances(bulk=True))
451 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances)
452 95ab4de9 David Knowles
    self.assertBulk()
453 95ab4de9 David Knowles
454 591e5103 Michael Hanselmann
  def testGetInstance(self):
455 95ab4de9 David Knowles
    self.rapi.AddResponse("[]")
456 591e5103 Michael Hanselmann
    self.assertEqual([], self.client.GetInstance("instance"))
457 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name)
458 95ab4de9 David Knowles
    self.assertItems(["instance"])
459 95ab4de9 David Knowles
460 591e5103 Michael Hanselmann
  def testGetInstanceInfo(self):
461 591e5103 Michael Hanselmann
    self.rapi.AddResponse("21291")
462 591e5103 Michael Hanselmann
    self.assertEqual(21291, self.client.GetInstanceInfo("inst3"))
463 591e5103 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_info)
464 591e5103 Michael Hanselmann
    self.assertItems(["inst3"])
465 591e5103 Michael Hanselmann
    self.assertQuery("static", None)
466 591e5103 Michael Hanselmann
467 591e5103 Michael Hanselmann
    self.rapi.AddResponse("3428")
468 591e5103 Michael Hanselmann
    self.assertEqual(3428, self.client.GetInstanceInfo("inst31", static=False))
469 591e5103 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_info)
470 591e5103 Michael Hanselmann
    self.assertItems(["inst31"])
471 591e5103 Michael Hanselmann
    self.assertQuery("static", ["0"])
472 591e5103 Michael Hanselmann
473 591e5103 Michael Hanselmann
    self.rapi.AddResponse("15665")
474 591e5103 Michael Hanselmann
    self.assertEqual(15665, self.client.GetInstanceInfo("inst32", static=True))
475 591e5103 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_info)
476 591e5103 Michael Hanselmann
    self.assertItems(["inst32"])
477 591e5103 Michael Hanselmann
    self.assertQuery("static", ["1"])
478 591e5103 Michael Hanselmann
479 8a47b447 Michael Hanselmann
  def testCreateInstanceOldVersion(self):
480 48436b97 Michael Hanselmann
    # No NICs
481 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
482 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
483 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [], [])
484 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
485 48436b97 Michael Hanselmann
486 48436b97 Michael Hanselmann
    # More than one NIC
487 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
488 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
489 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [],
490 48436b97 Michael Hanselmann
                      [{}, {}, {}])
491 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
492 48436b97 Michael Hanselmann
493 48436b97 Michael Hanselmann
    # Unsupported NIC fields
494 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
495 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
496 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [],
497 48436b97 Michael Hanselmann
                      [{"x": True, "y": False}])
498 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
499 48436b97 Michael Hanselmann
500 48436b97 Michael Hanselmann
    # Unsupported disk fields
501 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
502 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
503 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain",
504 48436b97 Michael Hanselmann
                      [{}, {"moo": "foo",}], [{}])
505 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
506 48436b97 Michael Hanselmann
507 48436b97 Michael Hanselmann
    # Unsupported fields
508 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
509 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
510 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [], [{}],
511 48436b97 Michael Hanselmann
                      hello_world=123)
512 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
513 48436b97 Michael Hanselmann
514 48436b97 Michael Hanselmann
    self.rapi.AddResponse(None, code=404)
515 48436b97 Michael Hanselmann
    self.assertRaises(client.GanetiApiError, self.client.CreateInstance,
516 48436b97 Michael Hanselmann
                      "create", "inst1.example.com", "plain", [], [{}],
517 48436b97 Michael Hanselmann
                      memory=128)
518 48436b97 Michael Hanselmann
    self.assertEqual(self.rapi.CountPending(), 0)
519 48436b97 Michael Hanselmann
520 48436b97 Michael Hanselmann
    # Normal creation
521 48436b97 Michael Hanselmann
    testnics = [
522 48436b97 Michael Hanselmann
      [{}],
523 48436b97 Michael Hanselmann
      [{ "mac": constants.VALUE_AUTO, }],
524 48436b97 Michael Hanselmann
      [{ "ip": "192.0.2.99", "mode": constants.NIC_MODE_ROUTED, }],
525 48436b97 Michael Hanselmann
      ]
526 48436b97 Michael Hanselmann
527 48436b97 Michael Hanselmann
    testdisks = [
528 48436b97 Michael Hanselmann
      [],
529 48436b97 Michael Hanselmann
      [{ "size": 128, }],
530 48436b97 Michael Hanselmann
      [{ "size": 321, }, { "size": 4096, }],
531 48436b97 Michael Hanselmann
      ]
532 48436b97 Michael Hanselmann
533 48436b97 Michael Hanselmann
    for idx, nics in enumerate(testnics):
534 48436b97 Michael Hanselmann
      for disks in testdisks:
535 48436b97 Michael Hanselmann
        beparams = {
536 48436b97 Michael Hanselmann
          constants.BE_MEMORY: 512,
537 48436b97 Michael Hanselmann
          constants.BE_AUTO_BALANCE: False,
538 48436b97 Michael Hanselmann
          }
539 48436b97 Michael Hanselmann
        hvparams = {
540 48436b97 Michael Hanselmann
          constants.HV_MIGRATION_PORT: 9876,
541 48436b97 Michael Hanselmann
          constants.HV_VNC_TLS: True,
542 48436b97 Michael Hanselmann
          }
543 48436b97 Michael Hanselmann
544 48436b97 Michael Hanselmann
        self.rapi.AddResponse(None, code=404)
545 48436b97 Michael Hanselmann
        self.rapi.AddResponse(serializer.DumpJson(3122617 + idx))
546 48436b97 Michael Hanselmann
        job_id = self.client.CreateInstance("create", "inst1.example.com",
547 48436b97 Michael Hanselmann
                                            "plain", disks, nics,
548 48436b97 Michael Hanselmann
                                            pnode="node99", dry_run=True,
549 48436b97 Michael Hanselmann
                                            hvparams=hvparams,
550 48436b97 Michael Hanselmann
                                            beparams=beparams)
551 48436b97 Michael Hanselmann
        self.assertEqual(job_id, 3122617 + idx)
552 48436b97 Michael Hanselmann
        self.assertHandler(rlib2.R_2_instances)
553 48436b97 Michael Hanselmann
        self.assertDryRun()
554 48436b97 Michael Hanselmann
        self.assertEqual(self.rapi.CountPending(), 0)
555 48436b97 Michael Hanselmann
556 54dc4fdb Michael Hanselmann
        data = serializer.LoadJson(self.rapi.GetLastRequestData())
557 48436b97 Michael Hanselmann
        self.assertEqual(data["name"], "inst1.example.com")
558 48436b97 Michael Hanselmann
        self.assertEqual(data["disk_template"], "plain")
559 48436b97 Michael Hanselmann
        self.assertEqual(data["pnode"], "node99")
560 48436b97 Michael Hanselmann
        self.assertEqual(data[constants.BE_MEMORY], 512)
561 48436b97 Michael Hanselmann
        self.assertEqual(data[constants.BE_AUTO_BALANCE], False)
562 48436b97 Michael Hanselmann
        self.assertEqual(data[constants.HV_MIGRATION_PORT], 9876)
563 48436b97 Michael Hanselmann
        self.assertEqual(data[constants.HV_VNC_TLS], True)
564 48436b97 Michael Hanselmann
        self.assertEqual(data["disks"], [disk["size"] for disk in disks])
565 8a47b447 Michael Hanselmann
566 95ab4de9 David Knowles
  def testCreateInstance(self):
567 8a47b447 Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson([rlib2._INST_CREATE_REQV1]))
568 8a47b447 Michael Hanselmann
    self.rapi.AddResponse("23030")
569 8a47b447 Michael Hanselmann
    job_id = self.client.CreateInstance("create", "inst1.example.com",
570 8a47b447 Michael Hanselmann
                                        "plain", [], [], dry_run=True)
571 8a47b447 Michael Hanselmann
    self.assertEqual(job_id, 23030)
572 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances)
573 95ab4de9 David Knowles
    self.assertDryRun()
574 95ab4de9 David Knowles
575 2a7c3583 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
576 8a47b447 Michael Hanselmann
577 8a47b447 Michael Hanselmann
    for field in ["dry_run", "beparams", "hvparams", "start"]:
578 8a47b447 Michael Hanselmann
      self.assertFalse(field in data)
579 8a47b447 Michael Hanselmann
580 8a47b447 Michael Hanselmann
    self.assertEqual(data["name"], "inst1.example.com")
581 8a47b447 Michael Hanselmann
    self.assertEqual(data["disk_template"], "plain")
582 8a47b447 Michael Hanselmann
583 8a47b447 Michael Hanselmann
  def testCreateInstance2(self):
584 8a47b447 Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson([rlib2._INST_CREATE_REQV1]))
585 8a47b447 Michael Hanselmann
    self.rapi.AddResponse("24740")
586 8a47b447 Michael Hanselmann
    job_id = self.client.CreateInstance("import", "inst2.example.com",
587 8a47b447 Michael Hanselmann
                                        "drbd8", [{"size": 100,}],
588 8a47b447 Michael Hanselmann
                                        [{}, {"bridge": "br1", }],
589 8a47b447 Michael Hanselmann
                                        dry_run=False, start=True,
590 8a47b447 Michael Hanselmann
                                        pnode="node1", snode="node9",
591 8a47b447 Michael Hanselmann
                                        ip_check=False)
592 8a47b447 Michael Hanselmann
    self.assertEqual(job_id, 24740)
593 8a47b447 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances)
594 8a47b447 Michael Hanselmann
595 2a7c3583 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
596 8a47b447 Michael Hanselmann
    self.assertEqual(data[rlib2._REQ_DATA_VERSION], 1)
597 8a47b447 Michael Hanselmann
    self.assertEqual(data["name"], "inst2.example.com")
598 8a47b447 Michael Hanselmann
    self.assertEqual(data["disk_template"], "drbd8")
599 8a47b447 Michael Hanselmann
    self.assertEqual(data["start"], True)
600 8a47b447 Michael Hanselmann
    self.assertEqual(data["ip_check"], False)
601 8a47b447 Michael Hanselmann
    self.assertEqualValues(data["disks"], [{"size": 100,}])
602 8a47b447 Michael Hanselmann
    self.assertEqualValues(data["nics"], [{}, {"bridge": "br1", }])
603 8a47b447 Michael Hanselmann
604 95ab4de9 David Knowles
  def testDeleteInstance(self):
605 cab667cc David Knowles
    self.rapi.AddResponse("1234")
606 cab667cc David Knowles
    self.assertEqual(1234, self.client.DeleteInstance("instance", dry_run=True))
607 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name)
608 95ab4de9 David Knowles
    self.assertItems(["instance"])
609 95ab4de9 David Knowles
    self.assertDryRun()
610 95ab4de9 David Knowles
611 95ab4de9 David Knowles
  def testGetInstanceTags(self):
612 95ab4de9 David Knowles
    self.rapi.AddResponse("[]")
613 95ab4de9 David Knowles
    self.assertEqual([], self.client.GetInstanceTags("fooinstance"))
614 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_tags)
615 95ab4de9 David Knowles
    self.assertItems(["fooinstance"])
616 95ab4de9 David Knowles
617 95ab4de9 David Knowles
  def testAddInstanceTags(self):
618 cab667cc David Knowles
    self.rapi.AddResponse("1234")
619 cab667cc David Knowles
    self.assertEqual(1234,
620 cab667cc David Knowles
        self.client.AddInstanceTags("fooinstance", ["awesome"], dry_run=True))
621 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_tags)
622 95ab4de9 David Knowles
    self.assertItems(["fooinstance"])
623 95ab4de9 David Knowles
    self.assertDryRun()
624 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
625 95ab4de9 David Knowles
626 95ab4de9 David Knowles
  def testDeleteInstanceTags(self):
627 cd577680 Michael Hanselmann
    self.rapi.AddResponse("25826")
628 cd577680 Michael Hanselmann
    self.assertEqual(25826, self.client.DeleteInstanceTags("foo", ["awesome"],
629 cd577680 Michael Hanselmann
                                                           dry_run=True))
630 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_tags)
631 95ab4de9 David Knowles
    self.assertItems(["foo"])
632 95ab4de9 David Knowles
    self.assertDryRun()
633 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
634 95ab4de9 David Knowles
635 95ab4de9 David Knowles
  def testRebootInstance(self):
636 cd577680 Michael Hanselmann
    self.rapi.AddResponse("6146")
637 cd577680 Michael Hanselmann
    job_id = self.client.RebootInstance("i-bar", reboot_type="hard",
638 cd577680 Michael Hanselmann
                                        ignore_secondaries=True, dry_run=True)
639 cd577680 Michael Hanselmann
    self.assertEqual(6146, job_id)
640 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_reboot)
641 95ab4de9 David Knowles
    self.assertItems(["i-bar"])
642 95ab4de9 David Knowles
    self.assertDryRun()
643 95ab4de9 David Knowles
    self.assertQuery("type", ["hard"])
644 10f5ab6c Michael Hanselmann
    self.assertQuery("ignore_secondaries", ["1"])
645 95ab4de9 David Knowles
646 95ab4de9 David Knowles
  def testShutdownInstance(self):
647 cd577680 Michael Hanselmann
    self.rapi.AddResponse("1487")
648 cd577680 Michael Hanselmann
    self.assertEqual(1487, self.client.ShutdownInstance("foo-instance",
649 cd577680 Michael Hanselmann
                                                        dry_run=True))
650 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_shutdown)
651 95ab4de9 David Knowles
    self.assertItems(["foo-instance"])
652 95ab4de9 David Knowles
    self.assertDryRun()
653 95ab4de9 David Knowles
654 95ab4de9 David Knowles
  def testStartupInstance(self):
655 cd577680 Michael Hanselmann
    self.rapi.AddResponse("27149")
656 cd577680 Michael Hanselmann
    self.assertEqual(27149, self.client.StartupInstance("bar-instance",
657 cd577680 Michael Hanselmann
                                                        dry_run=True))
658 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_startup)
659 95ab4de9 David Knowles
    self.assertItems(["bar-instance"])
660 95ab4de9 David Knowles
    self.assertDryRun()
661 95ab4de9 David Knowles
662 95ab4de9 David Knowles
  def testReinstallInstance(self):
663 cd577680 Michael Hanselmann
    self.rapi.AddResponse("19119")
664 fcee9675 David Knowles
    self.assertEqual(19119, self.client.ReinstallInstance("baz-instance",
665 fcee9675 David Knowles
                                                          os="DOS",
666 cd577680 Michael Hanselmann
                                                          no_startup=True))
667 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_reinstall)
668 95ab4de9 David Knowles
    self.assertItems(["baz-instance"])
669 95ab4de9 David Knowles
    self.assertQuery("os", ["DOS"])
670 95ab4de9 David Knowles
    self.assertQuery("nostartup", ["1"])
671 95ab4de9 David Knowles
672 95ab4de9 David Knowles
  def testReplaceInstanceDisks(self):
673 95ab4de9 David Knowles
    self.rapi.AddResponse("999")
674 95ab4de9 David Knowles
    job_id = self.client.ReplaceInstanceDisks("instance-name",
675 bfc2002f Michael Hanselmann
        disks=[0, 1], dry_run=True, iallocator="hail")
676 95ab4de9 David Knowles
    self.assertEqual(999, job_id)
677 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_instances_name_replace_disks)
678 95ab4de9 David Knowles
    self.assertItems(["instance-name"])
679 bfc2002f Michael Hanselmann
    self.assertQuery("disks", ["0,1"])
680 95ab4de9 David Knowles
    self.assertQuery("mode", ["replace_auto"])
681 95ab4de9 David Knowles
    self.assertQuery("iallocator", ["hail"])
682 95ab4de9 David Knowles
    self.assertDryRun()
683 95ab4de9 David Knowles
684 95ab4de9 David Knowles
    self.rapi.AddResponse("1000")
685 95ab4de9 David Knowles
    job_id = self.client.ReplaceInstanceDisks("instance-bar",
686 bfc2002f Michael Hanselmann
        disks=[1], mode="replace_on_secondary", remote_node="foo-node",
687 95ab4de9 David Knowles
        dry_run=True)
688 95ab4de9 David Knowles
    self.assertEqual(1000, job_id)
689 95ab4de9 David Knowles
    self.assertItems(["instance-bar"])
690 bfc2002f Michael Hanselmann
    self.assertQuery("disks", ["1"])
691 95ab4de9 David Knowles
    self.assertQuery("remote_node", ["foo-node"])
692 95ab4de9 David Knowles
    self.assertDryRun()
693 95ab4de9 David Knowles
694 bfc2002f Michael Hanselmann
    self.rapi.AddResponse("5175")
695 bfc2002f Michael Hanselmann
    self.assertEqual(5175, self.client.ReplaceInstanceDisks("instance-moo"))
696 bfc2002f Michael Hanselmann
    self.assertItems(["instance-moo"])
697 bfc2002f Michael Hanselmann
    self.assertQuery("disks", None)
698 bfc2002f Michael Hanselmann
699 ebeb600f Michael Hanselmann
  def testPrepareExport(self):
700 ebeb600f Michael Hanselmann
    self.rapi.AddResponse("8326")
701 ebeb600f Michael Hanselmann
    self.assertEqual(8326, self.client.PrepareExport("inst1", "local"))
702 ebeb600f Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_prepare_export)
703 ebeb600f Michael Hanselmann
    self.assertItems(["inst1"])
704 ebeb600f Michael Hanselmann
    self.assertQuery("mode", ["local"])
705 ebeb600f Michael Hanselmann
706 ebeb600f Michael Hanselmann
  def testExportInstance(self):
707 ebeb600f Michael Hanselmann
    self.rapi.AddResponse("19695")
708 ebeb600f Michael Hanselmann
    job_id = self.client.ExportInstance("inst2", "local", "nodeX",
709 ebeb600f Michael Hanselmann
                                        shutdown=True)
710 ebeb600f Michael Hanselmann
    self.assertEqual(job_id, 19695)
711 ebeb600f Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_export)
712 ebeb600f Michael Hanselmann
    self.assertItems(["inst2"])
713 ebeb600f Michael Hanselmann
714 2a7c3583 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
715 ebeb600f Michael Hanselmann
    self.assertEqual(data["mode"], "local")
716 ebeb600f Michael Hanselmann
    self.assertEqual(data["destination"], "nodeX")
717 ebeb600f Michael Hanselmann
    self.assertEqual(data["shutdown"], True)
718 ebeb600f Michael Hanselmann
719 e0ac6ce6 Michael Hanselmann
  def testMigrateInstanceDefaults(self):
720 e0ac6ce6 Michael Hanselmann
    self.rapi.AddResponse("24873")
721 e0ac6ce6 Michael Hanselmann
    job_id = self.client.MigrateInstance("inst91")
722 e0ac6ce6 Michael Hanselmann
    self.assertEqual(job_id, 24873)
723 e0ac6ce6 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_migrate)
724 e0ac6ce6 Michael Hanselmann
    self.assertItems(["inst91"])
725 e0ac6ce6 Michael Hanselmann
726 e0ac6ce6 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
727 e0ac6ce6 Michael Hanselmann
    self.assertFalse(data)
728 e0ac6ce6 Michael Hanselmann
729 e0ac6ce6 Michael Hanselmann
  def testMigrateInstance(self):
730 e0ac6ce6 Michael Hanselmann
    for mode in constants.HT_MIGRATION_MODES:
731 e0ac6ce6 Michael Hanselmann
      for cleanup in [False, True]:
732 e0ac6ce6 Michael Hanselmann
        self.rapi.AddResponse("31910")
733 e0ac6ce6 Michael Hanselmann
        job_id = self.client.MigrateInstance("inst289", mode=mode,
734 e0ac6ce6 Michael Hanselmann
                                             cleanup=cleanup)
735 e0ac6ce6 Michael Hanselmann
        self.assertEqual(job_id, 31910)
736 e0ac6ce6 Michael Hanselmann
        self.assertHandler(rlib2.R_2_instances_name_migrate)
737 e0ac6ce6 Michael Hanselmann
        self.assertItems(["inst289"])
738 e0ac6ce6 Michael Hanselmann
739 e0ac6ce6 Michael Hanselmann
        data = serializer.LoadJson(self.rapi.GetLastRequestData())
740 e0ac6ce6 Michael Hanselmann
        self.assertEqual(len(data), 2)
741 e0ac6ce6 Michael Hanselmann
        self.assertEqual(data["mode"], mode)
742 e0ac6ce6 Michael Hanselmann
        self.assertEqual(data["cleanup"], cleanup)
743 e0ac6ce6 Michael Hanselmann
744 d654aae1 Michael Hanselmann
  def testRenameInstanceDefaults(self):
745 d654aae1 Michael Hanselmann
    new_name = "newnametha7euqu"
746 d654aae1 Michael Hanselmann
    self.rapi.AddResponse("8791")
747 d654aae1 Michael Hanselmann
    job_id = self.client.RenameInstance("inst18821", new_name)
748 d654aae1 Michael Hanselmann
    self.assertEqual(job_id, 8791)
749 d654aae1 Michael Hanselmann
    self.assertHandler(rlib2.R_2_instances_name_rename)
750 d654aae1 Michael Hanselmann
    self.assertItems(["inst18821"])
751 d654aae1 Michael Hanselmann
752 d654aae1 Michael Hanselmann
    data = serializer.LoadJson(self.rapi.GetLastRequestData())
753 d654aae1 Michael Hanselmann
    self.assertEqualValues(data, {"new_name": new_name, })
754 d654aae1 Michael Hanselmann
755 d654aae1 Michael Hanselmann
  def testRenameInstance(self):
756 d654aae1 Michael Hanselmann
    new_name = "new-name-yiux1iin"
757 d654aae1 Michael Hanselmann
    for ip_check in [False, True]:
758 d654aae1 Michael Hanselmann
      for name_check in [False, True]:
759 d654aae1 Michael Hanselmann
        self.rapi.AddResponse("24776")
760 d654aae1 Michael Hanselmann
        job_id = self.client.RenameInstance("inst20967", new_name,
761 d654aae1 Michael Hanselmann
                                             ip_check=ip_check,
762 d654aae1 Michael Hanselmann
                                             name_check=name_check)
763 d654aae1 Michael Hanselmann
        self.assertEqual(job_id, 24776)
764 d654aae1 Michael Hanselmann
        self.assertHandler(rlib2.R_2_instances_name_rename)
765 d654aae1 Michael Hanselmann
        self.assertItems(["inst20967"])
766 d654aae1 Michael Hanselmann
767 d654aae1 Michael Hanselmann
        data = serializer.LoadJson(self.rapi.GetLastRequestData())
768 d654aae1 Michael Hanselmann
        self.assertEqual(len(data), 3)
769 d654aae1 Michael Hanselmann
        self.assertEqual(data["new_name"], new_name)
770 d654aae1 Michael Hanselmann
        self.assertEqual(data["ip_check"], ip_check)
771 d654aae1 Michael Hanselmann
        self.assertEqual(data["name_check"], name_check)
772 d654aae1 Michael Hanselmann
773 95ab4de9 David Knowles
  def testGetJobs(self):
774 2004e673 Iustin Pop
    self.rapi.AddResponse('[ { "id": "123", "uri": "\\/2\\/jobs\\/123" },'
775 2004e673 Iustin Pop
                          '  { "id": "124", "uri": "\\/2\\/jobs\\/124" } ]')
776 95ab4de9 David Knowles
    self.assertEqual([123, 124], self.client.GetJobs())
777 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_jobs)
778 95ab4de9 David Knowles
779 95ab4de9 David Knowles
  def testGetJobStatus(self):
780 95ab4de9 David Knowles
    self.rapi.AddResponse("{\"foo\": \"bar\"}")
781 95ab4de9 David Knowles
    self.assertEqual({"foo": "bar"}, self.client.GetJobStatus(1234))
782 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_jobs_id)
783 95ab4de9 David Knowles
    self.assertItems(["1234"])
784 95ab4de9 David Knowles
785 d9b67f70 Michael Hanselmann
  def testWaitForJobChange(self):
786 d9b67f70 Michael Hanselmann
    fields = ["id", "summary"]
787 d9b67f70 Michael Hanselmann
    expected = {
788 d9b67f70 Michael Hanselmann
      "job_info": [123, "something"],
789 d9b67f70 Michael Hanselmann
      "log_entries": [],
790 d9b67f70 Michael Hanselmann
      }
791 d9b67f70 Michael Hanselmann
792 d9b67f70 Michael Hanselmann
    self.rapi.AddResponse(serializer.DumpJson(expected))
793 d9b67f70 Michael Hanselmann
    result = self.client.WaitForJobChange(123, fields, [], -1)
794 d9b67f70 Michael Hanselmann
    self.assertEqualValues(expected, result)
795 d9b67f70 Michael Hanselmann
    self.assertHandler(rlib2.R_2_jobs_id_wait)
796 d9b67f70 Michael Hanselmann
    self.assertItems(["123"])
797 d9b67f70 Michael Hanselmann
798 cf9ada49 Michael Hanselmann
  def testCancelJob(self):
799 cd577680 Michael Hanselmann
    self.rapi.AddResponse("[true, \"Job 123 will be canceled\"]")
800 cd577680 Michael Hanselmann
    self.assertEqual([True, "Job 123 will be canceled"],
801 cf9ada49 Michael Hanselmann
                     self.client.CancelJob(999, dry_run=True))
802 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_jobs_id)
803 95ab4de9 David Knowles
    self.assertItems(["999"])
804 95ab4de9 David Knowles
    self.assertDryRun()
805 95ab4de9 David Knowles
806 95ab4de9 David Knowles
  def testGetNodes(self):
807 95ab4de9 David Knowles
    self.rapi.AddResponse("[ { \"id\": \"node1\", \"uri\": \"uri1\" },"
808 95ab4de9 David Knowles
                          " { \"id\": \"node2\", \"uri\": \"uri2\" } ]")
809 95ab4de9 David Knowles
    self.assertEqual(["node1", "node2"], self.client.GetNodes())
810 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes)
811 95ab4de9 David Knowles
812 95ab4de9 David Knowles
    self.rapi.AddResponse("[ { \"id\": \"node1\", \"uri\": \"uri1\" },"
813 95ab4de9 David Knowles
                          " { \"id\": \"node2\", \"uri\": \"uri2\" } ]")
814 95ab4de9 David Knowles
    self.assertEqual([{"id": "node1", "uri": "uri1"},
815 95ab4de9 David Knowles
                      {"id": "node2", "uri": "uri2"}],
816 95ab4de9 David Knowles
                     self.client.GetNodes(bulk=True))
817 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes)
818 95ab4de9 David Knowles
    self.assertBulk()
819 95ab4de9 David Knowles
820 591e5103 Michael Hanselmann
  def testGetNode(self):
821 95ab4de9 David Knowles
    self.rapi.AddResponse("{}")
822 591e5103 Michael Hanselmann
    self.assertEqual({}, self.client.GetNode("node-foo"))
823 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name)
824 95ab4de9 David Knowles
    self.assertItems(["node-foo"])
825 95ab4de9 David Knowles
826 95ab4de9 David Knowles
  def testEvacuateNode(self):
827 95ab4de9 David Knowles
    self.rapi.AddResponse("9876")
828 95ab4de9 David Knowles
    job_id = self.client.EvacuateNode("node-1", remote_node="node-2")
829 95ab4de9 David Knowles
    self.assertEqual(9876, job_id)
830 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_evacuate)
831 95ab4de9 David Knowles
    self.assertItems(["node-1"])
832 95ab4de9 David Knowles
    self.assertQuery("remote_node", ["node-2"])
833 95ab4de9 David Knowles
834 95ab4de9 David Knowles
    self.rapi.AddResponse("8888")
835 95ab4de9 David Knowles
    job_id = self.client.EvacuateNode("node-3", iallocator="hail", dry_run=True)
836 95ab4de9 David Knowles
    self.assertEqual(8888, job_id)
837 95ab4de9 David Knowles
    self.assertItems(["node-3"])
838 95ab4de9 David Knowles
    self.assertQuery("iallocator", ["hail"])
839 95ab4de9 David Knowles
    self.assertDryRun()
840 95ab4de9 David Knowles
841 95ab4de9 David Knowles
    self.assertRaises(client.GanetiApiError,
842 95ab4de9 David Knowles
                      self.client.EvacuateNode,
843 95ab4de9 David Knowles
                      "node-4", iallocator="hail", remote_node="node-5")
844 95ab4de9 David Knowles
845 95ab4de9 David Knowles
  def testMigrateNode(self):
846 95ab4de9 David Knowles
    self.rapi.AddResponse("1111")
847 95ab4de9 David Knowles
    self.assertEqual(1111, self.client.MigrateNode("node-a", dry_run=True))
848 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_migrate)
849 95ab4de9 David Knowles
    self.assertItems(["node-a"])
850 1f334d96 Iustin Pop
    self.assert_("mode" not in self.rapi.GetLastHandler().queryargs)
851 1f334d96 Iustin Pop
    self.assertDryRun()
852 1f334d96 Iustin Pop
853 1f334d96 Iustin Pop
    self.rapi.AddResponse("1112")
854 1f334d96 Iustin Pop
    self.assertEqual(1112, self.client.MigrateNode("node-a", dry_run=True,
855 1f334d96 Iustin Pop
                                                   mode="live"))
856 1f334d96 Iustin Pop
    self.assertHandler(rlib2.R_2_nodes_name_migrate)
857 1f334d96 Iustin Pop
    self.assertItems(["node-a"])
858 1f334d96 Iustin Pop
    self.assertQuery("mode", ["live"])
859 95ab4de9 David Knowles
    self.assertDryRun()
860 95ab4de9 David Knowles
861 95ab4de9 David Knowles
  def testGetNodeRole(self):
862 95ab4de9 David Knowles
    self.rapi.AddResponse("\"master\"")
863 95ab4de9 David Knowles
    self.assertEqual("master", self.client.GetNodeRole("node-a"))
864 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_role)
865 95ab4de9 David Knowles
    self.assertItems(["node-a"])
866 95ab4de9 David Knowles
867 95ab4de9 David Knowles
  def testSetNodeRole(self):
868 95ab4de9 David Knowles
    self.rapi.AddResponse("789")
869 95ab4de9 David Knowles
    self.assertEqual(789,
870 95ab4de9 David Knowles
        self.client.SetNodeRole("node-foo", "master-candidate", force=True))
871 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_role)
872 95ab4de9 David Knowles
    self.assertItems(["node-foo"])
873 10f5ab6c Michael Hanselmann
    self.assertQuery("force", ["1"])
874 2a7c3583 Michael Hanselmann
    self.assertEqual("\"master-candidate\"", self.rapi.GetLastRequestData())
875 95ab4de9 David Knowles
876 95ab4de9 David Knowles
  def testGetNodeStorageUnits(self):
877 95ab4de9 David Knowles
    self.rapi.AddResponse("42")
878 95ab4de9 David Knowles
    self.assertEqual(42,
879 95ab4de9 David Knowles
        self.client.GetNodeStorageUnits("node-x", "lvm-pv", "fields"))
880 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_storage)
881 95ab4de9 David Knowles
    self.assertItems(["node-x"])
882 95ab4de9 David Knowles
    self.assertQuery("storage_type", ["lvm-pv"])
883 95ab4de9 David Knowles
    self.assertQuery("output_fields", ["fields"])
884 95ab4de9 David Knowles
885 95ab4de9 David Knowles
  def testModifyNodeStorageUnits(self):
886 95ab4de9 David Knowles
    self.rapi.AddResponse("14")
887 95ab4de9 David Knowles
    self.assertEqual(14,
888 95ab4de9 David Knowles
        self.client.ModifyNodeStorageUnits("node-z", "lvm-pv", "hda"))
889 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_storage_modify)
890 95ab4de9 David Knowles
    self.assertItems(["node-z"])
891 95ab4de9 David Knowles
    self.assertQuery("storage_type", ["lvm-pv"])
892 95ab4de9 David Knowles
    self.assertQuery("name", ["hda"])
893 fde28316 Michael Hanselmann
    self.assertQuery("allocatable", None)
894 fde28316 Michael Hanselmann
895 fde28316 Michael Hanselmann
    for allocatable, query_allocatable in [(True, "1"), (False, "0")]:
896 fde28316 Michael Hanselmann
      self.rapi.AddResponse("7205")
897 fde28316 Michael Hanselmann
      job_id = self.client.ModifyNodeStorageUnits("node-z", "lvm-pv", "hda",
898 fde28316 Michael Hanselmann
                                                  allocatable=allocatable)
899 fde28316 Michael Hanselmann
      self.assertEqual(7205, job_id)
900 fde28316 Michael Hanselmann
      self.assertHandler(rlib2.R_2_nodes_name_storage_modify)
901 fde28316 Michael Hanselmann
      self.assertItems(["node-z"])
902 fde28316 Michael Hanselmann
      self.assertQuery("storage_type", ["lvm-pv"])
903 fde28316 Michael Hanselmann
      self.assertQuery("name", ["hda"])
904 fde28316 Michael Hanselmann
      self.assertQuery("allocatable", [query_allocatable])
905 95ab4de9 David Knowles
906 752df8bb Michael Hanselmann
  def testRepairNodeStorageUnits(self):
907 752df8bb Michael Hanselmann
    self.rapi.AddResponse("99")
908 752df8bb Michael Hanselmann
    self.assertEqual(99, self.client.RepairNodeStorageUnits("node-z", "lvm-pv",
909 752df8bb Michael Hanselmann
                                                            "hda"))
910 752df8bb Michael Hanselmann
    self.assertHandler(rlib2.R_2_nodes_name_storage_repair)
911 752df8bb Michael Hanselmann
    self.assertItems(["node-z"])
912 752df8bb Michael Hanselmann
    self.assertQuery("storage_type", ["lvm-pv"])
913 752df8bb Michael Hanselmann
    self.assertQuery("name", ["hda"])
914 752df8bb Michael Hanselmann
915 95ab4de9 David Knowles
  def testGetNodeTags(self):
916 95ab4de9 David Knowles
    self.rapi.AddResponse("[\"fry\", \"bender\"]")
917 95ab4de9 David Knowles
    self.assertEqual(["fry", "bender"], self.client.GetNodeTags("node-k"))
918 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_tags)
919 95ab4de9 David Knowles
    self.assertItems(["node-k"])
920 95ab4de9 David Knowles
921 95ab4de9 David Knowles
  def testAddNodeTags(self):
922 cab667cc David Knowles
    self.rapi.AddResponse("1234")
923 cab667cc David Knowles
    self.assertEqual(1234,
924 cab667cc David Knowles
        self.client.AddNodeTags("node-v", ["awesome"], dry_run=True))
925 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_tags)
926 95ab4de9 David Knowles
    self.assertItems(["node-v"])
927 95ab4de9 David Knowles
    self.assertDryRun()
928 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
929 95ab4de9 David Knowles
930 95ab4de9 David Knowles
  def testDeleteNodeTags(self):
931 cd577680 Michael Hanselmann
    self.rapi.AddResponse("16861")
932 cd577680 Michael Hanselmann
    self.assertEqual(16861, self.client.DeleteNodeTags("node-w", ["awesome"],
933 cd577680 Michael Hanselmann
                                                       dry_run=True))
934 95ab4de9 David Knowles
    self.assertHandler(rlib2.R_2_nodes_name_tags)
935 95ab4de9 David Knowles
    self.assertItems(["node-w"])
936 95ab4de9 David Knowles
    self.assertDryRun()
937 95ab4de9 David Knowles
    self.assertQuery("tag", ["awesome"])
938 95ab4de9 David Knowles
939 95ab4de9 David Knowles
940 95ab4de9 David Knowles
if __name__ == '__main__':
941 2a7c3583 Michael Hanselmann
  client.UsesRapiClient(testutils.GanetiTestProgram)()