Fix RAPI QA, broken by NIC parameters changes
[ganeti-local] / qa / qa_rapi.py
1 #
2
3 # Copyright (C) 2007, 2008 Google Inc.
4 #
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.
9 #
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.
14 #
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
18 # 02110-1301, USA.
19
20
21 """Remote API QA tests.
22
23 """
24
25 import urllib2
26
27 from ganeti import utils
28 from ganeti import constants
29 from ganeti import errors
30 from ganeti import serializer
31
32 import qa_config
33 import qa_utils
34 import qa_error
35
36 from qa_utils import AssertEqual, AssertNotEqual, AssertIn, StartSSH
37
38
39 # Create opener which doesn't try to look for proxies.
40 NoProxyOpener = urllib2.build_opener(urllib2.ProxyHandler({}))
41
42
43 INSTANCE_FIELDS = ("name", "os", "pnode", "snodes",
44                    "admin_state",
45                    "disk_template", "disk.sizes",
46                    "nic.ips", "nic.macs", "nic.modes", "nic.links",
47                    "beparams", "hvparams",
48                    "oper_state", "oper_ram", "status", "tags")
49
50 NODE_FIELDS = ("name", "dtotal", "dfree",
51                "mtotal", "mnode", "mfree",
52                "pinst_cnt", "sinst_cnt", "tags")
53
54 LIST_FIELDS = ("id", "uri")
55
56
57 def Enabled():
58   """Return whether remote API tests should be run.
59
60   """
61   return qa_config.TestEnabled('rapi')
62
63
64 def _DoTests(uris):
65   master = qa_config.GetMasterNode()
66   host = master["primary"]
67   port = qa_config.get("rapi-port", default=constants.DEFAULT_RAPI_PORT)
68
69   for uri, verify in uris:
70     assert uri.startswith("/")
71
72     url = "https://%s:%s%s" % (host, port, uri)
73
74     print "Testing %s ..." % url
75
76     response = NoProxyOpener.open(url)
77
78     AssertEqual(response.info()["Content-type"], "application/json")
79
80     data = serializer.LoadJson(response.read())
81
82     if verify is not None:
83       if callable(verify):
84         verify(data)
85       else:
86         AssertEqual(data, verify)
87
88
89 def TestVersion():
90   """Testing remote API version.
91
92   """
93   _DoTests([
94     ("/version", constants.RAPI_VERSION),
95     ])
96
97
98 def TestEmptyCluster():
99   """Testing remote API on an empty cluster.
100
101   """
102   master_name = qa_config.GetMasterNode()["primary"]
103
104   def _VerifyInfo(data):
105     AssertIn("name", data)
106     AssertIn("master", data)
107     AssertEqual(data["master"], master_name)
108
109   def _VerifyNodes(data):
110     master_entry = {
111       "id": master_name,
112       "uri": "/2/nodes/%s" % master_name,
113       }
114     AssertIn(master_entry, data)
115
116   def _VerifyNodesBulk(data):
117     for node in data:
118       for entry in NODE_FIELDS:
119         AssertIn(entry, node)
120
121   _DoTests([
122     ("/", None),
123     ("/2/info", _VerifyInfo),
124     ("/2/tags", None),
125     ("/2/nodes", _VerifyNodes),
126     ("/2/nodes?bulk=1", _VerifyNodesBulk),
127     ("/2/instances", []),
128     ("/2/instances?bulk=1", []),
129     ("/2/os", None),
130     ])
131
132
133 def TestInstance(instance):
134   """Testing getting instance(s) info via remote API.
135
136   """
137   def _VerifyInstance(data):
138     for entry in INSTANCE_FIELDS:
139       AssertIn(entry, data)
140
141   def _VerifyInstancesList(data):
142     for instance in data:
143       for entry in LIST_FIELDS:
144         AssertIn(entry, instance)
145
146   def _VerifyInstancesBulk(data):
147     for instance_data in data:
148       _VerifyInstance(instance_data)
149
150   _DoTests([
151     ("/2/instances/%s" % instance["name"], _VerifyInstance),
152     ("/2/instances", _VerifyInstancesList),
153     ("/2/instances?bulk=1", _VerifyInstancesBulk),
154     ])
155
156
157 def TestNode(node):
158   """Testing getting node(s) info via remote API.
159
160   """
161   def _VerifyNode(data):
162     for entry in NODE_FIELDS:
163       AssertIn(entry, data)
164
165   def _VerifyNodesList(data):
166     for node in data:
167       for entry in LIST_FIELDS:
168         AssertIn(entry, node)
169
170   def _VerifyNodesBulk(data):
171     for node_data in data:
172       _VerifyNode(node_data)
173
174   _DoTests([
175     ("/2/nodes/%s" % node["primary"], _VerifyNode),
176     ("/2/nodes", _VerifyNodesList),
177     ("/2/nodes?bulk=1", _VerifyNodesBulk),
178     ])
179
180
181 def TestTags(kind, name, tags):
182   """Tests .../tags resources.
183
184   """
185   if kind == constants.TAG_CLUSTER:
186     uri = "/2/tags"
187   elif kind == constants.TAG_NODE:
188     uri = "/2/nodes/%s/tags" % name
189   elif kind == constants.TAG_INSTANCE:
190     uri = "/2/instances/%s/tags" % name
191   else:
192     raise errors.ProgrammerError("Unknown tag kind")
193
194   def _VerifyTags(data):
195     # Create copies to modify
196     should = tags[:]
197     should.sort()
198
199     returned = data[:]
200     returned.sort()
201     AssertEqual(should, returned)
202
203   _DoTests([
204     (uri, _VerifyTags),
205     ])