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",
44 "admin_state", "admin_ram",
45 "disk_template", "ip", "mac", "bridge",
46 "sda_size", "sdb_size", "vcpus",
47 "oper_state", "status", "tags")
49 NODE_FIELDS = ("name", "dtotal", "dfree",
50 "mtotal", "mnode", "mfree",
51 "pinst_cnt", "sinst_cnt", "tags")
53 LIST_FIELDS = ("name", "uri")
57 """Return whether remote API tests should be run.
60 return constants.RAPI_ENABLE and qa_config.TestEnabled('rapi')
63 def PrintRemoteAPIWarning():
64 """Print warning if remote API is not enabled.
67 if constants.RAPI_ENABLE or not qa_config.TestEnabled('rapi'):
69 msg = ("Remote API is not enabled in this Ganeti build. Please run"
70 " `configure [...] --enable-rapi'.")
72 print qa_utils.FormatWarning(msg)
76 master = qa_config.GetMasterNode()
77 host = master["primary"]
78 port = qa_config.get("rapi-port", default=constants.RAPI_PORT)
80 for uri, verify in uris:
81 assert uri.startswith("/")
83 url = "http://%s:%s%s" % (host, port, uri)
85 print "Testing %s ..." % url
87 response = NoProxyOpener.open(url)
89 AssertEqual(response.info()["Content-type"], "application/json")
91 data = serializer.LoadJson(response.read())
93 if verify is not None:
97 AssertEqual(data, verify)
101 """Testing remote API version.
105 ("/version", constants.RAPI_VERSION),
109 def TestEmptyCluster():
110 """Testing remote API on an empty cluster.
113 master_name = qa_config.GetMasterNode()["primary"]
115 def _VerifyInfo(data):
116 AssertIn("name", data)
117 AssertIn("master", data)
118 AssertEqual(data["master"], master_name)
120 def _VerifyNodes(data):
123 "uri": "/nodes/%s" % master_name,
125 AssertIn(master_entry, data)
127 def _VerifyNodesBulk(data):
129 for entry in NODE_FIELDS:
130 AssertIn(entry, node)
134 ("/info", _VerifyInfo),
136 ("/nodes", _VerifyNodes),
137 ("/nodes?bulk=1", _VerifyNodesBulk),
139 ("/instances?bulk=1", []),
144 def TestInstance(instance):
145 """Testing getting instance(s) info via remote API.
148 def _VerifyInstance(data):
149 for entry in INSTANCE_FIELDS:
150 AssertIn(entry, data)
152 def _VerifyInstancesList(data):
153 for instance in data:
154 for entry in LIST_FIELDS:
155 AssertIn(entry, instance)
157 def _VerifyInstancesBulk(data):
158 for instance_data in data:
159 _VerifyInstance(instance_data)
162 ("/instances/%s" % instance["name"], _VerifyInstance),
163 ("/instances", _VerifyInstancesList),
164 ("/instances?bulk=1", _VerifyInstancesBulk),
169 """Testing getting node(s) info via remote API.
172 def _VerifyNode(data):
173 for entry in NODE_FIELDS:
174 AssertIn(entry, data)
176 def _VerifyNodesList(data):
178 for entry in LIST_FIELDS:
179 AssertIn(entry, node)
181 def _VerifyNodesBulk(data):
182 for node_data in data:
183 _VerifyNode(node_data)
186 ("/nodes/%s" % node["primary"], _VerifyNode),
187 ("/nodes", _VerifyNodesList),
188 ("/nodes?bulk=1", _VerifyNodesBulk),
192 def TestTags(kind, name, tags):
193 """Tests .../tags resources.
196 if kind == constants.TAG_CLUSTER:
198 elif kind == constants.TAG_NODE:
199 uri = "/nodes/%s/tags" % name
200 elif kind == constants.TAG_INSTANCE:
201 uri = "/instances/%s/tags" % name
203 raise errors.ProgrammerError("Unknown tag kind")
205 def _VerifyTags(data):
206 # Create copies to modify
212 AssertEqual(should, returned)