OpenStack Image Management (Glance)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_api.py 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. # Copyright 2012 OpenStack Foundation
  2. # All Rights Reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  5. # not use this file except in compliance with the License. You may obtain
  6. # a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. # License for the specific language governing permissions and limitations
  14. # under the License.
  15. """Version-independent api tests"""
  16. import httplib2
  17. from oslo_serialization import jsonutils
  18. from six.moves import http_client
  19. from glance.tests import functional
  20. # TODO(rosmaita): all the EXPERIMENTAL stuff in this file can be ripped out
  21. # when v2.6 becomes CURRENT in Queens
  22. def _generate_v1_versions(url):
  23. v1_versions = {'versions': [
  24. {
  25. 'id': 'v1.1',
  26. 'status': 'DEPRECATED',
  27. 'links': [{'rel': 'self', 'href': url % '1'}],
  28. },
  29. {
  30. 'id': 'v1.0',
  31. 'status': 'DEPRECATED',
  32. 'links': [{'rel': 'self', 'href': url % '1'}],
  33. },
  34. ]}
  35. return v1_versions
  36. def _generate_v2_versions(url):
  37. version_list = []
  38. version_list.extend([
  39. {
  40. 'id': 'v2.6',
  41. 'status': 'CURRENT',
  42. 'links': [{'rel': 'self', 'href': url % '2'}],
  43. },
  44. {
  45. 'id': 'v2.5',
  46. 'status': 'SUPPORTED',
  47. 'links': [{'rel': 'self', 'href': url % '2'}],
  48. },
  49. {
  50. 'id': 'v2.4',
  51. 'status': 'SUPPORTED',
  52. 'links': [{'rel': 'self', 'href': url % '2'}],
  53. },
  54. {
  55. 'id': 'v2.3',
  56. 'status': 'SUPPORTED',
  57. 'links': [{'rel': 'self', 'href': url % '2'}],
  58. },
  59. {
  60. 'id': 'v2.2',
  61. 'status': 'SUPPORTED',
  62. 'links': [{'rel': 'self', 'href': url % '2'}],
  63. },
  64. {
  65. 'id': 'v2.1',
  66. 'status': 'SUPPORTED',
  67. 'links': [{'rel': 'self', 'href': url % '2'}],
  68. },
  69. {
  70. 'id': 'v2.0',
  71. 'status': 'SUPPORTED',
  72. 'links': [{'rel': 'self', 'href': url % '2'}],
  73. }
  74. ])
  75. v2_versions = {'versions': version_list}
  76. return v2_versions
  77. def _generate_all_versions(url):
  78. v1 = _generate_v1_versions(url)
  79. v2 = _generate_v2_versions(url)
  80. all_versions = {'versions': v2['versions'] + v1['versions']}
  81. return all_versions
  82. class TestApiVersions(functional.FunctionalTest):
  83. def test_version_configurations(self):
  84. """Test that versioning is handled properly through all channels"""
  85. # v1 and v2 api enabled
  86. self.start_servers(**self.__dict__.copy())
  87. url = 'http://127.0.0.1:%d/v%%s/' % self.api_port
  88. versions = _generate_all_versions(url)
  89. # Verify version choices returned.
  90. path = 'http://%s:%d' % ('127.0.0.1', self.api_port)
  91. http = httplib2.Http()
  92. response, content_json = http.request(path, 'GET')
  93. self.assertEqual(http_client.MULTIPLE_CHOICES, response.status)
  94. content = jsonutils.loads(content_json.decode())
  95. self.assertEqual(versions, content)
  96. def test_v2_api_configuration(self):
  97. self.api_server.enable_v1_api = False
  98. self.api_server.enable_v2_api = True
  99. self.start_servers(**self.__dict__.copy())
  100. url = 'http://127.0.0.1:%d/v%%s/' % self.api_port
  101. versions = _generate_v2_versions(url)
  102. # Verify version choices returned.
  103. path = 'http://%s:%d' % ('127.0.0.1', self.api_port)
  104. http = httplib2.Http()
  105. response, content_json = http.request(path, 'GET')
  106. self.assertEqual(http_client.MULTIPLE_CHOICES, response.status)
  107. content = jsonutils.loads(content_json.decode())
  108. self.assertEqual(versions, content)
  109. def test_v1_api_configuration(self):
  110. self.api_server.enable_v1_api = True
  111. self.api_server.enable_v2_api = False
  112. self.start_servers(**self.__dict__.copy())
  113. url = 'http://127.0.0.1:%d/v%%s/' % self.api_port
  114. versions = _generate_v1_versions(url)
  115. # Verify version choices returned.
  116. path = 'http://%s:%d' % ('127.0.0.1', self.api_port)
  117. http = httplib2.Http()
  118. response, content_json = http.request(path, 'GET')
  119. self.assertEqual(http_client.MULTIPLE_CHOICES, response.status)
  120. content = jsonutils.loads(content_json.decode())
  121. self.assertEqual(versions, content)
  122. class TestApiPaths(functional.FunctionalTest):
  123. def setUp(self):
  124. super(TestApiPaths, self).setUp()
  125. self.start_servers(**self.__dict__.copy())
  126. url = 'http://127.0.0.1:%d/v%%s/' % self.api_port
  127. self.versions = _generate_all_versions(url)
  128. images = {'images': []}
  129. self.images_json = jsonutils.dumps(images)
  130. def test_get_root_path(self):
  131. """Assert GET / with `no Accept:` header.
  132. Verify version choices returned.
  133. Bug lp:803260 no Accept header causes a 500 in glance-api
  134. """
  135. path = 'http://%s:%d' % ('127.0.0.1', self.api_port)
  136. http = httplib2.Http()
  137. response, content_json = http.request(path, 'GET')
  138. self.assertEqual(http_client.MULTIPLE_CHOICES, response.status)
  139. content = jsonutils.loads(content_json.decode())
  140. self.assertEqual(self.versions, content)
  141. def test_get_images_path(self):
  142. """Assert GET /images with `no Accept:` header.
  143. Verify version choices returned.
  144. """
  145. path = 'http://%s:%d/images' % ('127.0.0.1', self.api_port)
  146. http = httplib2.Http()
  147. response, content_json = http.request(path, 'GET')
  148. self.assertEqual(http_client.MULTIPLE_CHOICES, response.status)
  149. content = jsonutils.loads(content_json.decode())
  150. self.assertEqual(self.versions, content)
  151. def test_get_v1_images_path(self):
  152. """GET /v1/images with `no Accept:` header.
  153. Verify empty images list returned.
  154. """
  155. path = 'http://%s:%d/v1/images' % ('127.0.0.1', self.api_port)
  156. http = httplib2.Http()
  157. response, content = http.request(path, 'GET')
  158. self.assertEqual(http_client.OK, response.status)
  159. def test_get_root_path_with_unknown_header(self):
  160. """Assert GET / with Accept: unknown header
  161. Verify version choices returned. Verify message in API log about
  162. unknown accept header.
  163. """
  164. path = 'http://%s:%d/' % ('127.0.0.1', self.api_port)
  165. http = httplib2.Http()
  166. headers = {'Accept': 'unknown'}
  167. response, content_json = http.request(path, 'GET', headers=headers)
  168. self.assertEqual(http_client.MULTIPLE_CHOICES, response.status)
  169. content = jsonutils.loads(content_json.decode())
  170. self.assertEqual(self.versions, content)
  171. def test_get_root_path_with_openstack_header(self):
  172. """Assert GET / with an Accept: application/vnd.openstack.images-v1
  173. Verify empty image list returned
  174. """
  175. path = 'http://%s:%d/images' % ('127.0.0.1', self.api_port)
  176. http = httplib2.Http()
  177. headers = {'Accept': 'application/vnd.openstack.images-v1'}
  178. response, content = http.request(path, 'GET', headers=headers)
  179. self.assertEqual(http_client.OK, response.status)
  180. self.assertEqual(self.images_json, content.decode())
  181. def test_get_images_path_with_openstack_header(self):
  182. """Assert GET /images with a
  183. `Accept: application/vnd.openstack.compute-v1` header.
  184. Verify version choices returned. Verify message in API log
  185. about unknown accept header.
  186. """
  187. path = 'http://%s:%d/images' % ('127.0.0.1', self.api_port)
  188. http = httplib2.Http()
  189. headers = {'Accept': 'application/vnd.openstack.compute-v1'}
  190. response, content_json = http.request(path, 'GET', headers=headers)
  191. self.assertEqual(http_client.MULTIPLE_CHOICES, response.status)
  192. content = jsonutils.loads(content_json.decode())
  193. self.assertEqual(self.versions, content)
  194. def test_get_v10_images_path(self):
  195. """Assert GET /v1.0/images with no Accept: header
  196. Verify version choices returned
  197. """
  198. path = 'http://%s:%d/v1.a/images' % ('127.0.0.1', self.api_port)
  199. http = httplib2.Http()
  200. response, content = http.request(path, 'GET')
  201. self.assertEqual(http_client.MULTIPLE_CHOICES, response.status)
  202. def test_get_v1a_images_path(self):
  203. """Assert GET /v1.a/images with no Accept: header
  204. Verify version choices returned
  205. """
  206. path = 'http://%s:%d/v1.a/images' % ('127.0.0.1', self.api_port)
  207. http = httplib2.Http()
  208. response, content = http.request(path, 'GET')
  209. self.assertEqual(http_client.MULTIPLE_CHOICES, response.status)
  210. def test_get_va1_images_path(self):
  211. """Assert GET /va.1/images with no Accept: header
  212. Verify version choices returned
  213. """
  214. path = 'http://%s:%d/va.1/images' % ('127.0.0.1', self.api_port)
  215. http = httplib2.Http()
  216. response, content_json = http.request(path, 'GET')
  217. self.assertEqual(http_client.MULTIPLE_CHOICES, response.status)
  218. content = jsonutils.loads(content_json.decode())
  219. self.assertEqual(self.versions, content)
  220. def test_get_versions_path(self):
  221. """Assert GET /versions with no Accept: header
  222. Verify version choices returned
  223. """
  224. path = 'http://%s:%d/versions' % ('127.0.0.1', self.api_port)
  225. http = httplib2.Http()
  226. response, content_json = http.request(path, 'GET')
  227. self.assertEqual(http_client.OK, response.status)
  228. content = jsonutils.loads(content_json.decode())
  229. self.assertEqual(self.versions, content)
  230. def test_get_versions_path_with_openstack_header(self):
  231. """Assert GET /versions with the
  232. `Accept: application/vnd.openstack.images-v1` header.
  233. Verify version choices returned.
  234. """
  235. path = 'http://%s:%d/versions' % ('127.0.0.1', self.api_port)
  236. http = httplib2.Http()
  237. headers = {'Accept': 'application/vnd.openstack.images-v1'}
  238. response, content_json = http.request(path, 'GET', headers=headers)
  239. self.assertEqual(http_client.OK, response.status)
  240. content = jsonutils.loads(content_json.decode())
  241. self.assertEqual(self.versions, content)
  242. def test_get_v1_versions_path(self):
  243. """Assert GET /v1/versions with `no Accept:` header
  244. Verify 404 returned
  245. """
  246. path = 'http://%s:%d/v1/versions' % ('127.0.0.1', self.api_port)
  247. http = httplib2.Http()
  248. response, content = http.request(path, 'GET')
  249. self.assertEqual(http_client.NOT_FOUND, response.status)
  250. def test_get_versions_choices(self):
  251. """Verify version choices returned"""
  252. path = 'http://%s:%d/v10' % ('127.0.0.1', self.api_port)
  253. http = httplib2.Http()
  254. response, content_json = http.request(path, 'GET')
  255. self.assertEqual(http_client.MULTIPLE_CHOICES, response.status)
  256. content = jsonutils.loads(content_json.decode())
  257. self.assertEqual(self.versions, content)
  258. def test_get_images_path_with_openstack_v2_header(self):
  259. """Assert GET /images with a
  260. `Accept: application/vnd.openstack.compute-v2` header.
  261. Verify version choices returned. Verify message in API log
  262. about unknown version in accept header.
  263. """
  264. path = 'http://%s:%d/images' % ('127.0.0.1', self.api_port)
  265. http = httplib2.Http()
  266. headers = {'Accept': 'application/vnd.openstack.images-v10'}
  267. response, content_json = http.request(path, 'GET', headers=headers)
  268. self.assertEqual(http_client.MULTIPLE_CHOICES, response.status)
  269. content = jsonutils.loads(content_json.decode())
  270. self.assertEqual(self.versions, content)
  271. def test_get_v12_images_path(self):
  272. """Assert GET /v1.2/images with `no Accept:` header
  273. Verify version choices returned
  274. """
  275. path = 'http://%s:%d/v1.2/images' % ('127.0.0.1', self.api_port)
  276. http = httplib2.Http()
  277. response, content_json = http.request(path, 'GET')
  278. self.assertEqual(http_client.MULTIPLE_CHOICES, response.status)
  279. content = jsonutils.loads(content_json.decode())
  280. self.assertEqual(self.versions, content)