root / qa / qa_rapi.py @ c2c2a903
History | View | Annotate | Download (5 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 | a47f574c | Oleksiy Mishchenko | "admin_state", "admin_ram", |
45 | a47f574c | Oleksiy Mishchenko | "disk_template", "ip", "mac", "bridge", |
46 | a47f574c | Oleksiy Mishchenko | "sda_size", "sdb_size", "vcpus", |
47 | a47f574c | Oleksiy Mishchenko | "oper_state", "status", "tags") |
48 | a47f574c | Oleksiy Mishchenko | |
49 | a47f574c | Oleksiy Mishchenko | NODE_FIELDS = ("name", "dtotal", "dfree", |
50 | a47f574c | Oleksiy Mishchenko | "mtotal", "mnode", "mfree", |
51 | a47f574c | Oleksiy Mishchenko | "pinst_cnt", "sinst_cnt", "tags") |
52 | a47f574c | Oleksiy Mishchenko | |
53 | a47f574c | Oleksiy Mishchenko | LIST_FIELDS = ("name", "uri") |
54 | a47f574c | Oleksiy Mishchenko | |
55 | a47f574c | Oleksiy Mishchenko | |
56 | a47f574c | Oleksiy Mishchenko | def Enabled(): |
57 | a47f574c | Oleksiy Mishchenko | """Return whether remote API tests should be run.
|
58 | a47f574c | Oleksiy Mishchenko |
|
59 | a47f574c | Oleksiy Mishchenko | """
|
60 | a47f574c | Oleksiy Mishchenko | return constants.RAPI_ENABLE and qa_config.TestEnabled('rapi') |
61 | a47f574c | Oleksiy Mishchenko | |
62 | a47f574c | Oleksiy Mishchenko | |
63 | a47f574c | Oleksiy Mishchenko | def PrintRemoteAPIWarning(): |
64 | a47f574c | Oleksiy Mishchenko | """Print warning if remote API is not enabled.
|
65 | a47f574c | Oleksiy Mishchenko |
|
66 | a47f574c | Oleksiy Mishchenko | """
|
67 | a47f574c | Oleksiy Mishchenko | if constants.RAPI_ENABLE or not qa_config.TestEnabled('rapi'): |
68 | a47f574c | Oleksiy Mishchenko | return
|
69 | a47f574c | Oleksiy Mishchenko | msg = ("Remote API is not enabled in this Ganeti build. Please run"
|
70 | a47f574c | Oleksiy Mishchenko | " `configure [...] --enable-rapi'.")
|
71 | a47f574c | Oleksiy Mishchenko | print
|
72 | a47f574c | Oleksiy Mishchenko | print qa_utils.FormatWarning(msg)
|
73 | a47f574c | Oleksiy Mishchenko | |
74 | a47f574c | Oleksiy Mishchenko | |
75 | a47f574c | Oleksiy Mishchenko | def _DoTests(uris): |
76 | a47f574c | Oleksiy Mishchenko | master = qa_config.GetMasterNode() |
77 | a47f574c | Oleksiy Mishchenko | host = master["primary"]
|
78 | a47f574c | Oleksiy Mishchenko | port = qa_config.get("rapi-port", default=constants.RAPI_PORT)
|
79 | a47f574c | Oleksiy Mishchenko | |
80 | a47f574c | Oleksiy Mishchenko | for uri, verify in uris: |
81 | a47f574c | Oleksiy Mishchenko | assert uri.startswith("/") |
82 | a47f574c | Oleksiy Mishchenko | |
83 | a47f574c | Oleksiy Mishchenko | url = "http://%s:%s%s" % (host, port, uri)
|
84 | a47f574c | Oleksiy Mishchenko | |
85 | a47f574c | Oleksiy Mishchenko | print "Testing %s ..." % url |
86 | a47f574c | Oleksiy Mishchenko | |
87 | a47f574c | Oleksiy Mishchenko | response = NoProxyOpener.open(url) |
88 | a47f574c | Oleksiy Mishchenko | |
89 | a47f574c | Oleksiy Mishchenko | AssertEqual(response.info()["Content-type"], "application/json") |
90 | a47f574c | Oleksiy Mishchenko | |
91 | a47f574c | Oleksiy Mishchenko | data = serializer.LoadJson(response.read()) |
92 | a47f574c | Oleksiy Mishchenko | |
93 | a47f574c | Oleksiy Mishchenko | if verify is not None: |
94 | a47f574c | Oleksiy Mishchenko | if callable(verify): |
95 | a47f574c | Oleksiy Mishchenko | verify(data) |
96 | a47f574c | Oleksiy Mishchenko | else:
|
97 | a47f574c | Oleksiy Mishchenko | AssertEqual(data, verify) |
98 | a47f574c | Oleksiy Mishchenko | |
99 | a47f574c | Oleksiy Mishchenko | |
100 | a47f574c | Oleksiy Mishchenko | def TestVersion(): |
101 | a47f574c | Oleksiy Mishchenko | """Testing remote API version.
|
102 | a47f574c | Oleksiy Mishchenko |
|
103 | a47f574c | Oleksiy Mishchenko | """
|
104 | a47f574c | Oleksiy Mishchenko | _DoTests([ |
105 | a47f574c | Oleksiy Mishchenko | ("/version", constants.RAPI_VERSION),
|
106 | a47f574c | Oleksiy Mishchenko | ]) |
107 | a47f574c | Oleksiy Mishchenko | |
108 | a47f574c | Oleksiy Mishchenko | |
109 | a47f574c | Oleksiy Mishchenko | def TestEmptyCluster(): |
110 | a47f574c | Oleksiy Mishchenko | """Testing remote API on an empty cluster.
|
111 | a47f574c | Oleksiy Mishchenko |
|
112 | a47f574c | Oleksiy Mishchenko | """
|
113 | a47f574c | Oleksiy Mishchenko | master_name = qa_config.GetMasterNode()["primary"]
|
114 | a47f574c | Oleksiy Mishchenko | |
115 | a47f574c | Oleksiy Mishchenko | def _VerifyInfo(data): |
116 | a47f574c | Oleksiy Mishchenko | AssertIn("name", data)
|
117 | a47f574c | Oleksiy Mishchenko | AssertIn("master", data)
|
118 | a47f574c | Oleksiy Mishchenko | AssertEqual(data["master"], master_name)
|
119 | a47f574c | Oleksiy Mishchenko | |
120 | a47f574c | Oleksiy Mishchenko | def _VerifyNodes(data): |
121 | a47f574c | Oleksiy Mishchenko | master_entry = { |
122 | a47f574c | Oleksiy Mishchenko | "name": master_name,
|
123 | a47f574c | Oleksiy Mishchenko | "uri": "/nodes/%s" % master_name, |
124 | a47f574c | Oleksiy Mishchenko | } |
125 | a47f574c | Oleksiy Mishchenko | AssertIn(master_entry, data) |
126 | a47f574c | Oleksiy Mishchenko | |
127 | a47f574c | Oleksiy Mishchenko | def _VerifyNodesBulk(data): |
128 | a47f574c | Oleksiy Mishchenko | for node in data: |
129 | a47f574c | Oleksiy Mishchenko | for entry in NODE_FIELDS: |
130 | a47f574c | Oleksiy Mishchenko | AssertIn(entry, node) |
131 | a47f574c | Oleksiy Mishchenko | |
132 | a47f574c | Oleksiy Mishchenko | _DoTests([ |
133 | a47f574c | Oleksiy Mishchenko | ("/", None), |
134 | a47f574c | Oleksiy Mishchenko | ("/info", _VerifyInfo),
|
135 | a47f574c | Oleksiy Mishchenko | ("/tags", None), |
136 | a47f574c | Oleksiy Mishchenko | ("/nodes", _VerifyNodes),
|
137 | a47f574c | Oleksiy Mishchenko | ("/nodes?bulk=1", _VerifyNodesBulk),
|
138 | a47f574c | Oleksiy Mishchenko | ("/instances", []),
|
139 | a47f574c | Oleksiy Mishchenko | ("/instances?bulk=1", []),
|
140 | a47f574c | Oleksiy Mishchenko | ("/os", None), |
141 | a47f574c | Oleksiy Mishchenko | ]) |
142 | a47f574c | Oleksiy Mishchenko | |
143 | a47f574c | Oleksiy Mishchenko | |
144 | a47f574c | Oleksiy Mishchenko | def TestInstance(instance): |
145 | a47f574c | Oleksiy Mishchenko | """Testing getting instance(s) info via remote API.
|
146 | a47f574c | Oleksiy Mishchenko |
|
147 | a47f574c | Oleksiy Mishchenko | """
|
148 | a47f574c | Oleksiy Mishchenko | def _VerifyInstance(data): |
149 | a47f574c | Oleksiy Mishchenko | for entry in INSTANCE_FIELDS: |
150 | a47f574c | Oleksiy Mishchenko | AssertIn(entry, data) |
151 | c85d3b64 | Michael Hanselmann | |
152 | a47f574c | Oleksiy Mishchenko | def _VerifyInstancesList(data): |
153 | a47f574c | Oleksiy Mishchenko | for instance in data: |
154 | c85d3b64 | Michael Hanselmann | for entry in LIST_FIELDS: |
155 | a47f574c | Oleksiy Mishchenko | AssertIn(entry, instance) |
156 | c85d3b64 | Michael Hanselmann | |
157 | a47f574c | Oleksiy Mishchenko | def _VerifyInstancesBulk(data): |
158 | a47f574c | Oleksiy Mishchenko | for instance_data in data: |
159 | a47f574c | Oleksiy Mishchenko | _VerifyInstance(instance_data) |
160 | a47f574c | Oleksiy Mishchenko | |
161 | a47f574c | Oleksiy Mishchenko | _DoTests([ |
162 | a47f574c | Oleksiy Mishchenko | ("/instances/%s" % instance["name"], _VerifyInstance), |
163 | a47f574c | Oleksiy Mishchenko | ("/instances", _VerifyInstancesList),
|
164 | a47f574c | Oleksiy Mishchenko | ("/instances?bulk=1", _VerifyInstancesBulk),
|
165 | a47f574c | Oleksiy Mishchenko | ]) |
166 | a47f574c | Oleksiy Mishchenko | |
167 | a47f574c | Oleksiy Mishchenko | |
168 | a47f574c | Oleksiy Mishchenko | def TestNode(node): |
169 | a47f574c | Oleksiy Mishchenko | """Testing getting node(s) info via remote API.
|
170 | a47f574c | Oleksiy Mishchenko |
|
171 | a47f574c | Oleksiy Mishchenko | """
|
172 | a47f574c | Oleksiy Mishchenko | def _VerifyNode(data): |
173 | a47f574c | Oleksiy Mishchenko | for entry in NODE_FIELDS: |
174 | a47f574c | Oleksiy Mishchenko | AssertIn(entry, data) |
175 | c85d3b64 | Michael Hanselmann | |
176 | a47f574c | Oleksiy Mishchenko | def _VerifyNodesList(data): |
177 | a47f574c | Oleksiy Mishchenko | for node in data: |
178 | c85d3b64 | Michael Hanselmann | for entry in LIST_FIELDS: |
179 | a47f574c | Oleksiy Mishchenko | AssertIn(entry, node) |
180 | c85d3b64 | Michael Hanselmann | |
181 | a47f574c | Oleksiy Mishchenko | def _VerifyNodesBulk(data): |
182 | a47f574c | Oleksiy Mishchenko | for node_data in data: |
183 | a47f574c | Oleksiy Mishchenko | _VerifyNode(node_data) |
184 | a47f574c | Oleksiy Mishchenko | |
185 | a47f574c | Oleksiy Mishchenko | _DoTests([ |
186 | a47f574c | Oleksiy Mishchenko | ("/nodes/%s" % node["primary"], _VerifyNode), |
187 | a47f574c | Oleksiy Mishchenko | ("/nodes", _VerifyNodesList),
|
188 | a47f574c | Oleksiy Mishchenko | ("/nodes?bulk=1", _VerifyNodesBulk),
|
189 | a47f574c | Oleksiy Mishchenko | ]) |
190 | a47f574c | Oleksiy Mishchenko | |
191 | a47f574c | Oleksiy Mishchenko | |
192 | a47f574c | Oleksiy Mishchenko | def TestTags(kind, name, tags): |
193 | a47f574c | Oleksiy Mishchenko | """Tests .../tags resources.
|
194 | a47f574c | Oleksiy Mishchenko |
|
195 | a47f574c | Oleksiy Mishchenko | """
|
196 | a47f574c | Oleksiy Mishchenko | if kind == constants.TAG_CLUSTER:
|
197 | a47f574c | Oleksiy Mishchenko | uri = "/tags"
|
198 | a47f574c | Oleksiy Mishchenko | elif kind == constants.TAG_NODE:
|
199 | a47f574c | Oleksiy Mishchenko | uri = "/nodes/%s/tags" % name
|
200 | a47f574c | Oleksiy Mishchenko | elif kind == constants.TAG_INSTANCE:
|
201 | a47f574c | Oleksiy Mishchenko | uri = "/instances/%s/tags" % name
|
202 | a47f574c | Oleksiy Mishchenko | else:
|
203 | a47f574c | Oleksiy Mishchenko | raise errors.ProgrammerError("Unknown tag kind") |
204 | a47f574c | Oleksiy Mishchenko | |
205 | a47f574c | Oleksiy Mishchenko | def _VerifyTags(data): |
206 | a47f574c | Oleksiy Mishchenko | # Create copies to modify
|
207 | a47f574c | Oleksiy Mishchenko | should = tags[:] |
208 | a47f574c | Oleksiy Mishchenko | should.sort() |
209 | a47f574c | Oleksiy Mishchenko | |
210 | a47f574c | Oleksiy Mishchenko | returned = data[:] |
211 | a47f574c | Oleksiy Mishchenko | returned.sort() |
212 | a47f574c | Oleksiy Mishchenko | AssertEqual(should, returned) |
213 | a47f574c | Oleksiy Mishchenko | |
214 | a47f574c | Oleksiy Mishchenko | _DoTests([ |
215 | a47f574c | Oleksiy Mishchenko | (uri, _VerifyTags), |
216 | a47f574c | Oleksiy Mishchenko | ]) |