3 # Copyright (C) 2007, 2008 Google Inc.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 """Remote API QA tests.
27 from ganeti import utils
28 from ganeti import constants
29 from ganeti import errors
30 from ganeti import serializer
36 from qa_utils import AssertEqual, AssertNotEqual, AssertIn, StartSSH
39 # Create opener which doesn't try to look for proxies.
40 NoProxyOpener = urllib2.build_opener(urllib2.ProxyHandler({}))
43 INSTANCE_FIELDS = ("name", "os", "pnode", "snodes",
45 "disk_template", "disk.sizes",
46 "nic.ips", "nic.macs", "nic.bridges",
47 "beparams", "hvparams",
48 "oper_state", "oper_ram", "status", "tags")
50 NODE_FIELDS = ("name", "dtotal", "dfree",
51 "mtotal", "mnode", "mfree",
52 "pinst_cnt", "sinst_cnt", "tags")
54 LIST_FIELDS = ("id", "uri")
58 """Return whether remote API tests should be run.
61 return constants.RAPI_ENABLE and qa_config.TestEnabled('rapi')
64 def PrintRemoteAPIWarning():
65 """Print warning if remote API is not enabled.
68 if constants.RAPI_ENABLE or not qa_config.TestEnabled('rapi'):
70 msg = ("Remote API is not enabled in this Ganeti build. Please run"
71 " `configure [...] --enable-rapi'.")
73 print qa_utils.FormatWarning(msg)
77 master = qa_config.GetMasterNode()
78 host = master["primary"]
79 port = qa_config.get("rapi-port", default=constants.RAPI_PORT)
81 for uri, verify in uris:
82 assert uri.startswith("/")
84 url = "https://%s:%s%s" % (host, port, uri)
86 print "Testing %s ..." % url
88 response = NoProxyOpener.open(url)
90 AssertEqual(response.info()["Content-type"], "application/json")
92 data = serializer.LoadJson(response.read())
94 if verify is not None:
98 AssertEqual(data, verify)
102 """Testing remote API version.
106 ("/version", constants.RAPI_VERSION),
110 def TestEmptyCluster():
111 """Testing remote API on an empty cluster.
114 master_name = qa_config.GetMasterNode()["primary"]
116 def _VerifyInfo(data):
117 AssertIn("name", data)
118 AssertIn("master", data)
119 AssertEqual(data["master"], master_name)
121 def _VerifyNodes(data):
124 "uri": "/2/nodes/%s" % master_name,
126 AssertIn(master_entry, data)
128 def _VerifyNodesBulk(data):
130 for entry in NODE_FIELDS:
131 AssertIn(entry, node)
135 ("/2/info", _VerifyInfo),
137 ("/2/nodes", _VerifyNodes),
138 ("/2/nodes?bulk=1", _VerifyNodesBulk),
139 ("/2/instances", []),
140 ("/2/instances?bulk=1", []),
145 def TestInstance(instance):
146 """Testing getting instance(s) info via remote API.
149 def _VerifyInstance(data):
150 for entry in INSTANCE_FIELDS:
151 AssertIn(entry, data)
153 def _VerifyInstancesList(data):
154 for instance in data:
155 for entry in LIST_FIELDS:
156 AssertIn(entry, instance)
158 def _VerifyInstancesBulk(data):
159 for instance_data in data:
160 _VerifyInstance(instance_data)
163 ("/2/instances/%s" % instance["name"], _VerifyInstance),
164 ("/2/instances", _VerifyInstancesList),
165 ("/2/instances?bulk=1", _VerifyInstancesBulk),
170 """Testing getting node(s) info via remote API.
173 def _VerifyNode(data):
174 for entry in NODE_FIELDS:
175 AssertIn(entry, data)
177 def _VerifyNodesList(data):
179 for entry in LIST_FIELDS:
180 AssertIn(entry, node)
182 def _VerifyNodesBulk(data):
183 for node_data in data:
184 _VerifyNode(node_data)
187 ("/2/nodes/%s" % node["primary"], _VerifyNode),
188 ("/2/nodes", _VerifyNodesList),
189 ("/2/nodes?bulk=1", _VerifyNodesBulk),
193 def TestTags(kind, name, tags):
194 """Tests .../tags resources.
197 if kind == constants.TAG_CLUSTER:
199 elif kind == constants.TAG_NODE:
200 uri = "/2/nodes/%s/tags" % name
201 elif kind == constants.TAG_INSTANCE:
202 uri = "/2/instances/%s/tags" % name
204 raise errors.ProgrammerError("Unknown tag kind")
206 def _VerifyTags(data):
207 # Create copies to modify
213 AssertEqual(should, returned)