root / qa / qa_rapi.py @ 74aa2478
History | View | Annotate | Download (5.1 kB)
1 | a47f574c | Oleksiy Mishchenko | #
|
---|---|---|---|
2 | a47f574c | Oleksiy Mishchenko | |
3 | a47f574c | Oleksiy Mishchenko | # Copyright (C) 2007, 2008 Google Inc.
|
4 | a47f574c | Oleksiy Mishchenko | #
|
5 | a47f574c | Oleksiy Mishchenko | # This program is free software; you can redistribute it and/or modify
|
6 | a47f574c | Oleksiy Mishchenko | # it under the terms of the GNU General Public License as published by
|
7 | a47f574c | Oleksiy Mishchenko | # the Free Software Foundation; either version 2 of the License, or
|
8 | a47f574c | Oleksiy Mishchenko | # (at your option) any later version.
|
9 | a47f574c | Oleksiy Mishchenko | #
|
10 | a47f574c | Oleksiy Mishchenko | # This program is distributed in the hope that it will be useful, but
|
11 | a47f574c | Oleksiy Mishchenko | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
12 | a47f574c | Oleksiy Mishchenko | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13 | a47f574c | Oleksiy Mishchenko | # General Public License for more details.
|
14 | a47f574c | Oleksiy Mishchenko | #
|
15 | a47f574c | Oleksiy Mishchenko | # You should have received a copy of the GNU General Public License
|
16 | a47f574c | Oleksiy Mishchenko | # along with this program; if not, write to the Free Software
|
17 | a47f574c | Oleksiy Mishchenko | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
18 | a47f574c | Oleksiy Mishchenko | # 02110-1301, USA.
|
19 | a47f574c | Oleksiy Mishchenko | |
20 | a47f574c | Oleksiy Mishchenko | |
21 | a47f574c | Oleksiy Mishchenko | """Remote API QA tests.
|
22 | a47f574c | Oleksiy Mishchenko |
|
23 | a47f574c | Oleksiy Mishchenko | """
|
24 | a47f574c | Oleksiy Mishchenko | |
25 | a47f574c | Oleksiy Mishchenko | import urllib2 |
26 | a47f574c | Oleksiy Mishchenko | |
27 | a47f574c | Oleksiy Mishchenko | from ganeti import utils |
28 | a47f574c | Oleksiy Mishchenko | from ganeti import constants |
29 | a47f574c | Oleksiy Mishchenko | from ganeti import errors |
30 | a47f574c | Oleksiy Mishchenko | from ganeti import serializer |
31 | a47f574c | Oleksiy Mishchenko | |
32 | a47f574c | Oleksiy Mishchenko | import qa_config |
33 | a47f574c | Oleksiy Mishchenko | import qa_utils |
34 | a47f574c | Oleksiy Mishchenko | import qa_error |
35 | a47f574c | Oleksiy Mishchenko | |
36 | a47f574c | Oleksiy Mishchenko | from qa_utils import AssertEqual, AssertNotEqual, AssertIn, StartSSH |
37 | a47f574c | Oleksiy Mishchenko | |
38 | a47f574c | Oleksiy Mishchenko | |
39 | a47f574c | Oleksiy Mishchenko | # Create opener which doesn't try to look for proxies.
|
40 | a47f574c | Oleksiy Mishchenko | NoProxyOpener = urllib2.build_opener(urllib2.ProxyHandler({})) |
41 | a47f574c | Oleksiy Mishchenko | |
42 | a47f574c | Oleksiy Mishchenko | |
43 | a47f574c | Oleksiy Mishchenko | INSTANCE_FIELDS = ("name", "os", "pnode", "snodes", |
44 | a5b9d725 | Iustin Pop | "admin_state",
|
45 | a5b9d725 | Iustin Pop | "disk_template", "disk.sizes", |
46 | a5b9d725 | Iustin Pop | "nic.ips", "nic.macs", "nic.bridges", |
47 | a5b9d725 | Iustin Pop | "beparams", "hvparams", |
48 | a5b9d725 | Iustin Pop | "oper_state", "oper_ram", "status", "tags") |
49 | a47f574c | Oleksiy Mishchenko | |
50 | a47f574c | Oleksiy Mishchenko | NODE_FIELDS = ("name", "dtotal", "dfree", |
51 | a47f574c | Oleksiy Mishchenko | "mtotal", "mnode", "mfree", |
52 | a47f574c | Oleksiy Mishchenko | "pinst_cnt", "sinst_cnt", "tags") |
53 | a47f574c | Oleksiy Mishchenko | |
54 | 68289c75 | Iustin Pop | LIST_FIELDS = ("id", "uri") |
55 | a47f574c | Oleksiy Mishchenko | |
56 | a47f574c | Oleksiy Mishchenko | |
57 | a47f574c | Oleksiy Mishchenko | def Enabled(): |
58 | a47f574c | Oleksiy Mishchenko | """Return whether remote API tests should be run.
|
59 | a47f574c | Oleksiy Mishchenko |
|
60 | a47f574c | Oleksiy Mishchenko | """
|
61 | a47f574c | Oleksiy Mishchenko | return constants.RAPI_ENABLE and qa_config.TestEnabled('rapi') |
62 | a47f574c | Oleksiy Mishchenko | |
63 | a47f574c | Oleksiy Mishchenko | |
64 | a47f574c | Oleksiy Mishchenko | def PrintRemoteAPIWarning(): |
65 | a47f574c | Oleksiy Mishchenko | """Print warning if remote API is not enabled.
|
66 | a47f574c | Oleksiy Mishchenko |
|
67 | a47f574c | Oleksiy Mishchenko | """
|
68 | a47f574c | Oleksiy Mishchenko | if constants.RAPI_ENABLE or not qa_config.TestEnabled('rapi'): |
69 | a47f574c | Oleksiy Mishchenko | return
|
70 | a47f574c | Oleksiy Mishchenko | msg = ("Remote API is not enabled in this Ganeti build. Please run"
|
71 | a47f574c | Oleksiy Mishchenko | " `configure [...] --enable-rapi'.")
|
72 | a47f574c | Oleksiy Mishchenko | print
|
73 | a47f574c | Oleksiy Mishchenko | print qa_utils.FormatWarning(msg)
|
74 | a47f574c | Oleksiy Mishchenko | |
75 | a47f574c | Oleksiy Mishchenko | |
76 | a47f574c | Oleksiy Mishchenko | def _DoTests(uris): |
77 | a47f574c | Oleksiy Mishchenko | master = qa_config.GetMasterNode() |
78 | a47f574c | Oleksiy Mishchenko | host = master["primary"]
|
79 | a47f574c | Oleksiy Mishchenko | port = qa_config.get("rapi-port", default=constants.RAPI_PORT)
|
80 | a47f574c | Oleksiy Mishchenko | |
81 | a47f574c | Oleksiy Mishchenko | for uri, verify in uris: |
82 | a47f574c | Oleksiy Mishchenko | assert uri.startswith("/") |
83 | a47f574c | Oleksiy Mishchenko | |
84 | 49b1d36e | Iustin Pop | url = "https://%s:%s%s" % (host, port, uri)
|
85 | a47f574c | Oleksiy Mishchenko | |
86 | a47f574c | Oleksiy Mishchenko | print "Testing %s ..." % url |
87 | a47f574c | Oleksiy Mishchenko | |
88 | a47f574c | Oleksiy Mishchenko | response = NoProxyOpener.open(url) |
89 | a47f574c | Oleksiy Mishchenko | |
90 | a47f574c | Oleksiy Mishchenko | AssertEqual(response.info()["Content-type"], "application/json") |
91 | a47f574c | Oleksiy Mishchenko | |
92 | a47f574c | Oleksiy Mishchenko | data = serializer.LoadJson(response.read()) |
93 | a47f574c | Oleksiy Mishchenko | |
94 | a47f574c | Oleksiy Mishchenko | if verify is not None: |
95 | a47f574c | Oleksiy Mishchenko | if callable(verify): |
96 | a47f574c | Oleksiy Mishchenko | verify(data) |
97 | a47f574c | Oleksiy Mishchenko | else:
|
98 | a47f574c | Oleksiy Mishchenko | AssertEqual(data, verify) |
99 | a47f574c | Oleksiy Mishchenko | |
100 | a47f574c | Oleksiy Mishchenko | |
101 | a47f574c | Oleksiy Mishchenko | def TestVersion(): |
102 | a47f574c | Oleksiy Mishchenko | """Testing remote API version.
|
103 | a47f574c | Oleksiy Mishchenko |
|
104 | a47f574c | Oleksiy Mishchenko | """
|
105 | a47f574c | Oleksiy Mishchenko | _DoTests([ |
106 | a47f574c | Oleksiy Mishchenko | ("/version", constants.RAPI_VERSION),
|
107 | a47f574c | Oleksiy Mishchenko | ]) |
108 | a47f574c | Oleksiy Mishchenko | |
109 | a47f574c | Oleksiy Mishchenko | |
110 | a47f574c | Oleksiy Mishchenko | def TestEmptyCluster(): |
111 | a47f574c | Oleksiy Mishchenko | """Testing remote API on an empty cluster.
|
112 | a47f574c | Oleksiy Mishchenko |
|
113 | a47f574c | Oleksiy Mishchenko | """
|
114 | a47f574c | Oleksiy Mishchenko | master_name = qa_config.GetMasterNode()["primary"]
|
115 | a47f574c | Oleksiy Mishchenko | |
116 | a47f574c | Oleksiy Mishchenko | def _VerifyInfo(data): |
117 | a47f574c | Oleksiy Mishchenko | AssertIn("name", data)
|
118 | a47f574c | Oleksiy Mishchenko | AssertIn("master", data)
|
119 | a47f574c | Oleksiy Mishchenko | AssertEqual(data["master"], master_name)
|
120 | a47f574c | Oleksiy Mishchenko | |
121 | a47f574c | Oleksiy Mishchenko | def _VerifyNodes(data): |
122 | a47f574c | Oleksiy Mishchenko | master_entry = { |
123 | a5b9d725 | Iustin Pop | "id": master_name,
|
124 | a5b9d725 | Iustin Pop | "uri": "/2/nodes/%s" % master_name, |
125 | a47f574c | Oleksiy Mishchenko | } |
126 | a47f574c | Oleksiy Mishchenko | AssertIn(master_entry, data) |
127 | a47f574c | Oleksiy Mishchenko | |
128 | a47f574c | Oleksiy Mishchenko | def _VerifyNodesBulk(data): |
129 | a47f574c | Oleksiy Mishchenko | for node in data: |
130 | a47f574c | Oleksiy Mishchenko | for entry in NODE_FIELDS: |
131 | a47f574c | Oleksiy Mishchenko | AssertIn(entry, node) |
132 | a47f574c | Oleksiy Mishchenko | |
133 | a47f574c | Oleksiy Mishchenko | _DoTests([ |
134 | a47f574c | Oleksiy Mishchenko | ("/", None), |
135 | a5b9d725 | Iustin Pop | ("/2/info", _VerifyInfo),
|
136 | a5b9d725 | Iustin Pop | ("/2/tags", None), |
137 | a5b9d725 | Iustin Pop | ("/2/nodes", _VerifyNodes),
|
138 | a5b9d725 | Iustin Pop | ("/2/nodes?bulk=1", _VerifyNodesBulk),
|
139 | a5b9d725 | Iustin Pop | ("/2/instances", []),
|
140 | a5b9d725 | Iustin Pop | ("/2/instances?bulk=1", []),
|
141 | a5b9d725 | Iustin Pop | ("/2/os", None), |
142 | a47f574c | Oleksiy Mishchenko | ]) |
143 | a47f574c | Oleksiy Mishchenko | |
144 | a47f574c | Oleksiy Mishchenko | |
145 | a47f574c | Oleksiy Mishchenko | def TestInstance(instance): |
146 | a47f574c | Oleksiy Mishchenko | """Testing getting instance(s) info via remote API.
|
147 | a47f574c | Oleksiy Mishchenko |
|
148 | a47f574c | Oleksiy Mishchenko | """
|
149 | a47f574c | Oleksiy Mishchenko | def _VerifyInstance(data): |
150 | a47f574c | Oleksiy Mishchenko | for entry in INSTANCE_FIELDS: |
151 | a47f574c | Oleksiy Mishchenko | AssertIn(entry, data) |
152 | c85d3b64 | Michael Hanselmann | |
153 | a47f574c | Oleksiy Mishchenko | def _VerifyInstancesList(data): |
154 | a47f574c | Oleksiy Mishchenko | for instance in data: |
155 | c85d3b64 | Michael Hanselmann | for entry in LIST_FIELDS: |
156 | a47f574c | Oleksiy Mishchenko | AssertIn(entry, instance) |
157 | c85d3b64 | Michael Hanselmann | |
158 | a47f574c | Oleksiy Mishchenko | def _VerifyInstancesBulk(data): |
159 | a47f574c | Oleksiy Mishchenko | for instance_data in data: |
160 | a47f574c | Oleksiy Mishchenko | _VerifyInstance(instance_data) |
161 | a47f574c | Oleksiy Mishchenko | |
162 | a47f574c | Oleksiy Mishchenko | _DoTests([ |
163 | a5b9d725 | Iustin Pop | ("/2/instances/%s" % instance["name"], _VerifyInstance), |
164 | a5b9d725 | Iustin Pop | ("/2/instances", _VerifyInstancesList),
|
165 | a5b9d725 | Iustin Pop | ("/2/instances?bulk=1", _VerifyInstancesBulk),
|
166 | a47f574c | Oleksiy Mishchenko | ]) |
167 | a47f574c | Oleksiy Mishchenko | |
168 | a47f574c | Oleksiy Mishchenko | |
169 | a47f574c | Oleksiy Mishchenko | def TestNode(node): |
170 | a47f574c | Oleksiy Mishchenko | """Testing getting node(s) info via remote API.
|
171 | a47f574c | Oleksiy Mishchenko |
|
172 | a47f574c | Oleksiy Mishchenko | """
|
173 | a47f574c | Oleksiy Mishchenko | def _VerifyNode(data): |
174 | a47f574c | Oleksiy Mishchenko | for entry in NODE_FIELDS: |
175 | a47f574c | Oleksiy Mishchenko | AssertIn(entry, data) |
176 | c85d3b64 | Michael Hanselmann | |
177 | a47f574c | Oleksiy Mishchenko | def _VerifyNodesList(data): |
178 | a47f574c | Oleksiy Mishchenko | for node in data: |
179 | c85d3b64 | Michael Hanselmann | for entry in LIST_FIELDS: |
180 | a47f574c | Oleksiy Mishchenko | AssertIn(entry, node) |
181 | c85d3b64 | Michael Hanselmann | |
182 | a47f574c | Oleksiy Mishchenko | def _VerifyNodesBulk(data): |
183 | a47f574c | Oleksiy Mishchenko | for node_data in data: |
184 | a47f574c | Oleksiy Mishchenko | _VerifyNode(node_data) |
185 | a47f574c | Oleksiy Mishchenko | |
186 | a47f574c | Oleksiy Mishchenko | _DoTests([ |
187 | a5b9d725 | Iustin Pop | ("/2/nodes/%s" % node["primary"], _VerifyNode), |
188 | a5b9d725 | Iustin Pop | ("/2/nodes", _VerifyNodesList),
|
189 | a5b9d725 | Iustin Pop | ("/2/nodes?bulk=1", _VerifyNodesBulk),
|
190 | a47f574c | Oleksiy Mishchenko | ]) |
191 | a47f574c | Oleksiy Mishchenko | |
192 | a47f574c | Oleksiy Mishchenko | |
193 | a47f574c | Oleksiy Mishchenko | def TestTags(kind, name, tags): |
194 | a47f574c | Oleksiy Mishchenko | """Tests .../tags resources.
|
195 | a47f574c | Oleksiy Mishchenko |
|
196 | a47f574c | Oleksiy Mishchenko | """
|
197 | a47f574c | Oleksiy Mishchenko | if kind == constants.TAG_CLUSTER:
|
198 | a5b9d725 | Iustin Pop | uri = "/2/tags"
|
199 | a47f574c | Oleksiy Mishchenko | elif kind == constants.TAG_NODE:
|
200 | a5b9d725 | Iustin Pop | uri = "/2/nodes/%s/tags" % name
|
201 | a47f574c | Oleksiy Mishchenko | elif kind == constants.TAG_INSTANCE:
|
202 | a5b9d725 | Iustin Pop | uri = "/2/instances/%s/tags" % name
|
203 | a47f574c | Oleksiy Mishchenko | else:
|
204 | a47f574c | Oleksiy Mishchenko | raise errors.ProgrammerError("Unknown tag kind") |
205 | a47f574c | Oleksiy Mishchenko | |
206 | a47f574c | Oleksiy Mishchenko | def _VerifyTags(data): |
207 | a47f574c | Oleksiy Mishchenko | # Create copies to modify
|
208 | a47f574c | Oleksiy Mishchenko | should = tags[:] |
209 | a47f574c | Oleksiy Mishchenko | should.sort() |
210 | a47f574c | Oleksiy Mishchenko | |
211 | a47f574c | Oleksiy Mishchenko | returned = data[:] |
212 | a47f574c | Oleksiy Mishchenko | returned.sort() |
213 | a47f574c | Oleksiy Mishchenko | AssertEqual(should, returned) |
214 | a47f574c | Oleksiy Mishchenko | |
215 | a47f574c | Oleksiy Mishchenko | _DoTests([ |
216 | a47f574c | Oleksiy Mishchenko | (uri, _VerifyTags), |
217 | a47f574c | Oleksiy Mishchenko | ]) |