blob: 827b5c9c1f4ad70e952a1658d79a58e117a249e1 [file] [log] [blame]
Matthew Treinisha33037e2013-12-05 23:16:39 +00001# Copyright 2013 IBM Corp.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
15import httplib2
vponomaryov67b58fe2014-02-06 19:05:41 +020016import json
Matthew Treinisha33037e2013-12-05 23:16:39 +000017
18from tempest.common import rest_client
Matthew Treinish684d8992014-01-30 16:27:40 +000019from tempest import config
Matthew Treinisha33037e2013-12-05 23:16:39 +000020from tempest import exceptions
21from tempest.openstack.common.fixture import mockpatch
vponomaryov67b58fe2014-02-06 19:05:41 +020022from tempest.services.compute.xml import common as xml
Matthew Treinisha33037e2013-12-05 23:16:39 +000023from tempest.tests import base
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000024from tempest.tests import fake_auth_provider
Matthew Treinisha33037e2013-12-05 23:16:39 +000025from tempest.tests import fake_config
26from tempest.tests import fake_http
27
28
29class BaseRestClientTestClass(base.TestCase):
30
vponomaryov67b58fe2014-02-06 19:05:41 +020031 url = 'fake_endpoint'
32
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000033 def _get_region(self):
34 return 'fake region'
Matthew Treinisha33037e2013-12-05 23:16:39 +000035
36 def setUp(self):
37 super(BaseRestClientTestClass, self).setUp()
Matthew Treinish684d8992014-01-30 16:27:40 +000038 self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakeConfig)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000039 self.rest_client = rest_client.RestClient(
40 fake_auth_provider.FakeAuthProvider())
Matthew Treinisha33037e2013-12-05 23:16:39 +000041 self.stubs.Set(httplib2.Http, 'request', self.fake_http.request)
Andrea Frittoli8bbdb162014-01-06 11:06:13 +000042 self.useFixture(mockpatch.PatchObject(self.rest_client, '_get_region',
43 side_effect=self._get_region()))
Matthew Treinisha33037e2013-12-05 23:16:39 +000044 self.useFixture(mockpatch.PatchObject(self.rest_client,
45 '_log_response'))
46
47
48class TestRestClientHTTPMethods(BaseRestClientTestClass):
49 def setUp(self):
50 self.fake_http = fake_http.fake_httplib2()
51 super(TestRestClientHTTPMethods, self).setUp()
52 self.useFixture(mockpatch.PatchObject(self.rest_client,
53 '_error_checker'))
54
55 def test_post(self):
vponomaryov67b58fe2014-02-06 19:05:41 +020056 __, return_dict = self.rest_client.post(self.url, {}, {})
Matthew Treinisha33037e2013-12-05 23:16:39 +000057 self.assertEqual('POST', return_dict['method'])
58
59 def test_get(self):
vponomaryov67b58fe2014-02-06 19:05:41 +020060 __, return_dict = self.rest_client.get(self.url)
Matthew Treinisha33037e2013-12-05 23:16:39 +000061 self.assertEqual('GET', return_dict['method'])
62
63 def test_delete(self):
vponomaryov67b58fe2014-02-06 19:05:41 +020064 __, return_dict = self.rest_client.delete(self.url)
Matthew Treinisha33037e2013-12-05 23:16:39 +000065 self.assertEqual('DELETE', return_dict['method'])
66
67 def test_patch(self):
vponomaryov67b58fe2014-02-06 19:05:41 +020068 __, return_dict = self.rest_client.patch(self.url, {}, {})
Matthew Treinisha33037e2013-12-05 23:16:39 +000069 self.assertEqual('PATCH', return_dict['method'])
70
71 def test_put(self):
vponomaryov67b58fe2014-02-06 19:05:41 +020072 __, return_dict = self.rest_client.put(self.url, {}, {})
Matthew Treinisha33037e2013-12-05 23:16:39 +000073 self.assertEqual('PUT', return_dict['method'])
74
75 def test_head(self):
76 self.useFixture(mockpatch.PatchObject(self.rest_client,
77 'response_checker'))
vponomaryov67b58fe2014-02-06 19:05:41 +020078 __, return_dict = self.rest_client.head(self.url)
Matthew Treinisha33037e2013-12-05 23:16:39 +000079 self.assertEqual('HEAD', return_dict['method'])
80
81 def test_copy(self):
vponomaryov67b58fe2014-02-06 19:05:41 +020082 __, return_dict = self.rest_client.copy(self.url)
Matthew Treinisha33037e2013-12-05 23:16:39 +000083 self.assertEqual('COPY', return_dict['method'])
84
85
86class TestRestClientNotFoundHandling(BaseRestClientTestClass):
87 def setUp(self):
88 self.fake_http = fake_http.fake_httplib2(404)
89 super(TestRestClientNotFoundHandling, self).setUp()
90
91 def test_post(self):
92 self.assertRaises(exceptions.NotFound, self.rest_client.post,
vponomaryov67b58fe2014-02-06 19:05:41 +020093 self.url, {}, {})
94
95
96class TestRestClientHeadersJSON(TestRestClientHTTPMethods):
97 TYPE = "json"
98
99 def _verify_headers(self, resp):
100 self.assertEqual(self.rest_client._get_type(), self.TYPE)
101 resp = dict((k.lower(), v) for k, v in resp.iteritems())
102 self.assertEqual(self.header_value, resp['accept'])
103 self.assertEqual(self.header_value, resp['content-type'])
104
105 def setUp(self):
106 super(TestRestClientHeadersJSON, self).setUp()
107 self.rest_client.TYPE = self.TYPE
108 self.header_value = 'application/%s' % self.rest_client._get_type()
109
110 def test_post(self):
111 resp, __ = self.rest_client.post(self.url, {})
112 self._verify_headers(resp)
113
114 def test_get(self):
115 resp, __ = self.rest_client.get(self.url)
116 self._verify_headers(resp)
117
118 def test_delete(self):
119 resp, __ = self.rest_client.delete(self.url)
120 self._verify_headers(resp)
121
122 def test_patch(self):
123 resp, __ = self.rest_client.patch(self.url, {})
124 self._verify_headers(resp)
125
126 def test_put(self):
127 resp, __ = self.rest_client.put(self.url, {})
128 self._verify_headers(resp)
129
130 def test_head(self):
131 self.useFixture(mockpatch.PatchObject(self.rest_client,
132 'response_checker'))
133 resp, __ = self.rest_client.head(self.url)
134 self._verify_headers(resp)
135
136 def test_copy(self):
137 resp, __ = self.rest_client.copy(self.url)
138 self._verify_headers(resp)
139
140
141class TestRestClientHeadersXML(TestRestClientHeadersJSON):
142 TYPE = "xml"
143
144 # These two tests are needed in one exemplar
145 def test_send_json_accept_xml(self):
146 resp, __ = self.rest_client.get(self.url,
147 self.rest_client.get_headers("xml",
148 "json"))
149 resp = dict((k.lower(), v) for k, v in resp.iteritems())
150 self.assertEqual("application/json", resp["content-type"])
151 self.assertEqual("application/xml", resp["accept"])
152
153 def test_send_xml_accept_json(self):
154 resp, __ = self.rest_client.get(self.url,
155 self.rest_client.get_headers("json",
156 "xml"))
157 resp = dict((k.lower(), v) for k, v in resp.iteritems())
158 self.assertEqual("application/json", resp["accept"])
159 self.assertEqual("application/xml", resp["content-type"])
160
161
162class TestRestClientParseRespXML(BaseRestClientTestClass):
163 TYPE = "xml"
164
165 keys = ["fake_key1", "fake_key2"]
166 values = ["fake_value1", "fake_value2"]
Dirk Muellerb9a57152014-02-21 15:48:32 +0100167 item_expected = dict((key, value) for (key, value) in zip(keys, values))
vponomaryov67b58fe2014-02-06 19:05:41 +0200168 list_expected = {"body_list": [
169 {keys[0]: values[0]},
170 {keys[1]: values[1]},
171 ]}
172 dict_expected = {"body_dict": {
173 keys[0]: values[0],
174 keys[1]: values[1],
175 }}
176
177 def setUp(self):
178 self.fake_http = fake_http.fake_httplib2()
179 super(TestRestClientParseRespXML, self).setUp()
180 self.rest_client.TYPE = self.TYPE
181
182 def test_parse_resp_body_item(self):
183 body_item = xml.Element("item", **self.item_expected)
184 body = self.rest_client._parse_resp(str(xml.Document(body_item)))
185 self.assertEqual(self.item_expected, body)
186
187 def test_parse_resp_body_list(self):
188 self.rest_client.list_tags = ["fake_list", ]
189 body_list = xml.Element(self.rest_client.list_tags[0])
190 for i in range(2):
191 body_list.append(xml.Element("fake_item",
192 **self.list_expected["body_list"][i]))
193 body = self.rest_client._parse_resp(str(xml.Document(body_list)))
194 self.assertEqual(self.list_expected["body_list"], body)
195
196 def test_parse_resp_body_dict(self):
197 self.rest_client.dict_tags = ["fake_dict", ]
198 body_dict = xml.Element(self.rest_client.dict_tags[0])
199
200 for i in range(2):
201 body_dict.append(xml.Element("fake_item", xml.Text(self.values[i]),
202 key=self.keys[i]))
203
204 body = self.rest_client._parse_resp(str(xml.Document(body_dict)))
205 self.assertEqual(self.dict_expected["body_dict"], body)
206
207
208class TestRestClientParseRespJSON(TestRestClientParseRespXML):
209 TYPE = "json"
210
211 def test_parse_resp_body_item(self):
212 body = self.rest_client._parse_resp(json.dumps(self.item_expected))
213 self.assertEqual(self.item_expected, body)
214
215 def test_parse_resp_body_list(self):
216 body = self.rest_client._parse_resp(json.dumps(self.list_expected))
217 self.assertEqual(self.list_expected["body_list"], body)
218
219 def test_parse_resp_body_dict(self):
220 body = self.rest_client._parse_resp(json.dumps(self.dict_expected))
221 self.assertEqual(self.dict_expected["body_dict"], body)
222
223 def test_parse_resp_two_top_keys(self):
224 dict_two_keys = self.dict_expected.copy()
225 dict_two_keys.update({"second_key": ""})
226 body = self.rest_client._parse_resp(json.dumps(dict_two_keys))
227 self.assertEqual(dict_two_keys, body)
228
229 def test_parse_resp_one_top_key_without_list_or_dict(self):
230 data = {"one_top_key": "not_list_or_dict_value"}
231 body = self.rest_client._parse_resp(json.dumps(data))
232 self.assertEqual(data, body)
vponomaryov6cb6d192014-03-07 09:39:05 +0200233
234
235class TestRestClientErrorCheckerJSON(base.TestCase):
236 c_type = "application/json"
237
238 def set_data(self, r_code, enc=None, r_body=None):
239 if enc is None:
240 enc = self.c_type
241 resp_dict = {'status': r_code, 'content-type': enc}
242 resp = httplib2.Response(resp_dict)
243 data = {
244 "method": "fake_method",
245 "url": "fake_url",
246 "headers": "fake_headers",
247 "body": "fake_body",
248 "resp": resp,
249 "resp_body": '{"resp_body": "fake_resp_body"}',
250 }
251 if r_body is not None:
252 data.update({"resp_body": r_body})
253 return data
254
255 def setUp(self):
256 super(TestRestClientErrorCheckerJSON, self).setUp()
257 self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakeConfig)
258 self.rest_client = rest_client.RestClient(
259 fake_auth_provider.FakeAuthProvider())
260
261 def test_response_less_than_400(self):
262 self.rest_client._error_checker(**self.set_data("399"))
263
264 def test_response_400(self):
265 self.assertRaises(exceptions.BadRequest,
266 self.rest_client._error_checker,
267 **self.set_data("400"))
268
269 def test_response_401(self):
270 self.assertRaises(exceptions.Unauthorized,
271 self.rest_client._error_checker,
272 **self.set_data("401"))
273
274 def test_response_403(self):
275 self.assertRaises(exceptions.Unauthorized,
276 self.rest_client._error_checker,
277 **self.set_data("403"))
278
279 def test_response_404(self):
280 self.assertRaises(exceptions.NotFound,
281 self.rest_client._error_checker,
282 **self.set_data("404"))
283
284 def test_response_409(self):
285 self.assertRaises(exceptions.Conflict,
286 self.rest_client._error_checker,
287 **self.set_data("409"))
288
289 def test_response_413(self):
290 self.assertRaises(exceptions.OverLimit,
291 self.rest_client._error_checker,
292 **self.set_data("413"))
293
294 def test_response_422(self):
295 self.assertRaises(exceptions.UnprocessableEntity,
296 self.rest_client._error_checker,
297 **self.set_data("422"))
298
299 def test_response_500_with_text(self):
300 # _parse_resp is expected to return 'str'
301 self.assertRaises(exceptions.ServerFault,
302 self.rest_client._error_checker,
303 **self.set_data("500"))
304
305 def test_response_501_with_text(self):
306 self.assertRaises(exceptions.ServerFault,
307 self.rest_client._error_checker,
308 **self.set_data("501"))
309
310 def test_response_500_with_dict(self):
311 r_body = '{"resp_body": {"err": "fake_resp_body"}}'
312 self.assertRaises(exceptions.ServerFault,
313 self.rest_client._error_checker,
314 **self.set_data("500", r_body=r_body))
315
316 def test_response_501_with_dict(self):
317 r_body = '{"resp_body": {"err": "fake_resp_body"}}'
318 self.assertRaises(exceptions.ServerFault,
319 self.rest_client._error_checker,
320 **self.set_data("501", r_body=r_body))
321
322 def test_response_bigger_than_400(self):
323 # Any response code, that bigger than 400, and not in
324 # (401, 403, 404, 409, 413, 422, 500, 501)
325 self.assertRaises(exceptions.UnexpectedResponseCode,
326 self.rest_client._error_checker,
327 **self.set_data("402"))
328
329
330class TestRestClientErrorCheckerXML(TestRestClientErrorCheckerJSON):
331 c_type = "application/xml"
332
333
334class TestRestClientErrorCheckerTEXT(TestRestClientErrorCheckerJSON):
335 c_type = "text/plain"
336
337 def test_fake_content_type(self):
338 # This test is required only in one exemplar
339 # Any response code, that bigger than 400, and not in
340 # (401, 403, 404, 409, 413, 422, 500, 501)
341 self.assertRaises(exceptions.InvalidContentType,
342 self.rest_client._error_checker,
343 **self.set_data("405", enc="fake_enc"))