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_registry_client.py 30KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779
  1. # Copyright 2013 Red Hat, Inc.
  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. """
  16. Tests for Glance Registry's client.
  17. This tests are temporary and will be removed once
  18. the registry's driver tests will be added.
  19. """
  20. import copy
  21. import datetime
  22. import os
  23. import uuid
  24. from mock import patch
  25. from six.moves import reload_module
  26. from glance.common import config
  27. from glance.common import exception
  28. from glance.common import timeutils
  29. from glance import context
  30. from glance.db.sqlalchemy import api as db_api
  31. from glance.i18n import _
  32. from glance.registry.api import v2 as rserver
  33. import glance.registry.client.v2.api as rapi
  34. from glance.registry.client.v2.api import client as rclient
  35. from glance.tests.unit import base
  36. from glance.tests import utils as test_utils
  37. _gen_uuid = lambda: str(uuid.uuid4())
  38. UUID1 = str(uuid.uuid4())
  39. UUID2 = str(uuid.uuid4())
  40. # NOTE(bcwaldon): needed to init config_dir cli opt
  41. config.parse_args(args=[])
  42. class TestRegistryV2Client(base.IsolatedUnitTest,
  43. test_utils.RegistryAPIMixIn):
  44. """Test proper actions made against a registry service.
  45. Test for both valid and invalid requests.
  46. """
  47. # Registry server to user
  48. # in the stub.
  49. registry = rserver
  50. def setUp(self):
  51. """Establish a clean test environment"""
  52. super(TestRegistryV2Client, self).setUp()
  53. db_api.get_engine()
  54. self.context = context.RequestContext(is_admin=True)
  55. uuid1_time = timeutils.utcnow()
  56. uuid2_time = uuid1_time + datetime.timedelta(seconds=5)
  57. self.FIXTURES = [
  58. self.get_extra_fixture(
  59. id=UUID1, name='fake image #1', visibility='shared',
  60. disk_format='ami', container_format='ami', size=13,
  61. virtual_size=26, properties={'type': 'kernel'},
  62. location="swift://user:passwd@acct/container/obj.tar.0",
  63. created_at=uuid1_time),
  64. self.get_extra_fixture(id=UUID2, name='fake image #2',
  65. properties={}, size=19, virtual_size=38,
  66. location="file:///tmp/glance-tests/2",
  67. created_at=uuid2_time)]
  68. self.destroy_fixtures()
  69. self.create_fixtures()
  70. self.client = rclient.RegistryClient("0.0.0.0")
  71. def tearDown(self):
  72. """Clear the test environment"""
  73. super(TestRegistryV2Client, self).tearDown()
  74. self.destroy_fixtures()
  75. def test_image_get_index(self):
  76. """Test correct set of public image returned"""
  77. images = self.client.image_get_all()
  78. self.assertEqual(2, len(images))
  79. def test_create_image_with_null_min_disk_min_ram(self):
  80. UUID3 = _gen_uuid()
  81. extra_fixture = self.get_fixture(id=UUID3, name='asdf', min_disk=None,
  82. min_ram=None)
  83. db_api.image_create(self.context, extra_fixture)
  84. image = self.client.image_get(image_id=UUID3)
  85. self.assertEqual(0, image["min_ram"])
  86. self.assertEqual(0, image["min_disk"])
  87. def test_get_index_sort_name_asc(self):
  88. """Tests that the registry API returns list of public images.
  89. Must be sorted alphabetically by name in ascending order.
  90. """
  91. UUID3 = _gen_uuid()
  92. extra_fixture = self.get_fixture(id=UUID3, name='asdf')
  93. db_api.image_create(self.context, extra_fixture)
  94. UUID4 = _gen_uuid()
  95. extra_fixture = self.get_fixture(id=UUID4, name='xyz')
  96. db_api.image_create(self.context, extra_fixture)
  97. images = self.client.image_get_all(sort_key=['name'],
  98. sort_dir=['asc'])
  99. self.assertEqualImages(images, (UUID3, UUID1, UUID2, UUID4),
  100. unjsonify=False)
  101. def test_get_index_sort_status_desc(self):
  102. """Tests that the registry API returns list of public images.
  103. Must be sorted alphabetically by status in descending order.
  104. """
  105. uuid4_time = timeutils.utcnow() + datetime.timedelta(seconds=10)
  106. UUID3 = _gen_uuid()
  107. extra_fixture = self.get_fixture(id=UUID3, name='asdf',
  108. status='queued')
  109. db_api.image_create(self.context, extra_fixture)
  110. UUID4 = _gen_uuid()
  111. extra_fixture = self.get_fixture(id=UUID4, name='xyz',
  112. created_at=uuid4_time)
  113. db_api.image_create(self.context, extra_fixture)
  114. images = self.client.image_get_all(sort_key=['status'],
  115. sort_dir=['desc'])
  116. self.assertEqualImages(images, (UUID3, UUID4, UUID2, UUID1),
  117. unjsonify=False)
  118. def test_get_index_sort_disk_format_asc(self):
  119. """Tests that the registry API returns list of public images.
  120. Must besorted alphabetically by disk_format in ascending order.
  121. """
  122. UUID3 = _gen_uuid()
  123. extra_fixture = self.get_fixture(id=UUID3, name='asdf',
  124. disk_format='ami',
  125. container_format='ami')
  126. db_api.image_create(self.context, extra_fixture)
  127. UUID4 = _gen_uuid()
  128. extra_fixture = self.get_fixture(id=UUID4, name='xyz',
  129. disk_format='vdi')
  130. db_api.image_create(self.context, extra_fixture)
  131. images = self.client.image_get_all(sort_key=['disk_format'],
  132. sort_dir=['asc'])
  133. self.assertEqualImages(images, (UUID1, UUID3, UUID4, UUID2),
  134. unjsonify=False)
  135. def test_get_index_sort_container_format_desc(self):
  136. """Tests that the registry API returns list of public images.
  137. Must be sorted alphabetically by container_format in descending order.
  138. """
  139. UUID3 = _gen_uuid()
  140. extra_fixture = self.get_fixture(id=UUID3, name='asdf',
  141. disk_format='ami',
  142. container_format='ami')
  143. db_api.image_create(self.context, extra_fixture)
  144. UUID4 = _gen_uuid()
  145. extra_fixture = self.get_fixture(id=UUID4, name='xyz',
  146. disk_format='iso',
  147. container_format='bare')
  148. db_api.image_create(self.context, extra_fixture)
  149. images = self.client.image_get_all(sort_key=['container_format'],
  150. sort_dir=['desc'])
  151. self.assertEqualImages(images, (UUID2, UUID4, UUID3, UUID1),
  152. unjsonify=False)
  153. def test_get_index_sort_size_asc(self):
  154. """Tests that the registry API returns list of public images.
  155. Must be sorted by size in ascending order.
  156. """
  157. UUID3 = _gen_uuid()
  158. extra_fixture = self.get_fixture(id=UUID3, name='asdf',
  159. disk_format='ami',
  160. container_format='ami',
  161. size=100, virtual_size=200)
  162. db_api.image_create(self.context, extra_fixture)
  163. UUID4 = _gen_uuid()
  164. extra_fixture = self.get_fixture(id=UUID4, name='asdf',
  165. disk_format='iso',
  166. container_format='bare',
  167. size=2, virtual_size=4)
  168. db_api.image_create(self.context, extra_fixture)
  169. images = self.client.image_get_all(sort_key=['size'], sort_dir=['asc'])
  170. self.assertEqualImages(images, (UUID4, UUID1, UUID2, UUID3),
  171. unjsonify=False)
  172. def test_get_index_sort_created_at_asc(self):
  173. """Tests that the registry API returns list of public images.
  174. Must be sorted by created_at in ascending order.
  175. """
  176. uuid4_time = timeutils.utcnow() + datetime.timedelta(seconds=10)
  177. uuid3_time = uuid4_time + datetime.timedelta(seconds=5)
  178. UUID3 = _gen_uuid()
  179. extra_fixture = self.get_fixture(id=UUID3, created_at=uuid3_time)
  180. db_api.image_create(self.context, extra_fixture)
  181. UUID4 = _gen_uuid()
  182. extra_fixture = self.get_fixture(id=UUID4, created_at=uuid4_time)
  183. db_api.image_create(self.context, extra_fixture)
  184. images = self.client.image_get_all(sort_key=['created_at'],
  185. sort_dir=['asc'])
  186. self.assertEqualImages(images, (UUID1, UUID2, UUID4, UUID3),
  187. unjsonify=False)
  188. def test_get_index_sort_updated_at_desc(self):
  189. """Tests that the registry API returns list of public images.
  190. Must be sorted by updated_at in descending order.
  191. """
  192. uuid4_time = timeutils.utcnow() + datetime.timedelta(seconds=10)
  193. uuid3_time = uuid4_time + datetime.timedelta(seconds=5)
  194. UUID3 = _gen_uuid()
  195. extra_fixture = self.get_fixture(id=UUID3, created_at=None,
  196. updated_at=uuid3_time)
  197. db_api.image_create(self.context, extra_fixture)
  198. UUID4 = _gen_uuid()
  199. extra_fixture = self.get_fixture(id=UUID4, created_at=None,
  200. updated_at=uuid4_time)
  201. db_api.image_create(self.context, extra_fixture)
  202. images = self.client.image_get_all(sort_key=['updated_at'],
  203. sort_dir=['desc'])
  204. self.assertEqualImages(images, (UUID3, UUID4, UUID2, UUID1),
  205. unjsonify=False)
  206. def test_get_image_details_sort_multiple_keys(self):
  207. """
  208. Tests that a detailed call returns list of
  209. public images sorted by name-size and
  210. size-name in ascending order.
  211. """
  212. UUID3 = _gen_uuid()
  213. extra_fixture = self.get_fixture(id=UUID3, name='asdf',
  214. size=19)
  215. db_api.image_create(self.context, extra_fixture)
  216. UUID4 = _gen_uuid()
  217. extra_fixture = self.get_fixture(id=UUID4, name=u'xyz',
  218. size=20)
  219. db_api.image_create(self.context, extra_fixture)
  220. UUID5 = _gen_uuid()
  221. extra_fixture = self.get_fixture(id=UUID5, name=u'asdf',
  222. size=20)
  223. db_api.image_create(self.context, extra_fixture)
  224. images = self.client.image_get_all(sort_key=['name', 'size'],
  225. sort_dir=['asc'])
  226. self.assertEqualImages(images, (UUID3, UUID5, UUID1, UUID2, UUID4),
  227. unjsonify=False)
  228. images = self.client.image_get_all(sort_key=['size', 'name'],
  229. sort_dir=['asc'])
  230. self.assertEqualImages(images, (UUID1, UUID3, UUID2, UUID5, UUID4),
  231. unjsonify=False)
  232. def test_get_image_details_sort_multiple_dirs(self):
  233. """
  234. Tests that a detailed call returns list of
  235. public images sorted by name-size and
  236. size-name in ascending and descending orders.
  237. """
  238. UUID3 = _gen_uuid()
  239. extra_fixture = self.get_fixture(id=UUID3, name='asdf',
  240. size=19)
  241. db_api.image_create(self.context, extra_fixture)
  242. UUID4 = _gen_uuid()
  243. extra_fixture = self.get_fixture(id=UUID4, name='xyz',
  244. size=20)
  245. db_api.image_create(self.context, extra_fixture)
  246. UUID5 = _gen_uuid()
  247. extra_fixture = self.get_fixture(id=UUID5, name='asdf',
  248. size=20)
  249. db_api.image_create(self.context, extra_fixture)
  250. images = self.client.image_get_all(sort_key=['name', 'size'],
  251. sort_dir=['asc', 'desc'])
  252. self.assertEqualImages(images, (UUID5, UUID3, UUID1, UUID2, UUID4),
  253. unjsonify=False)
  254. images = self.client.image_get_all(sort_key=['name', 'size'],
  255. sort_dir=['desc', 'asc'])
  256. self.assertEqualImages(images, (UUID4, UUID2, UUID1, UUID3, UUID5),
  257. unjsonify=False)
  258. images = self.client.image_get_all(sort_key=['size', 'name'],
  259. sort_dir=['asc', 'desc'])
  260. self.assertEqualImages(images, (UUID1, UUID2, UUID3, UUID4, UUID5),
  261. unjsonify=False)
  262. images = self.client.image_get_all(sort_key=['size', 'name'],
  263. sort_dir=['desc', 'asc'])
  264. self.assertEqualImages(images, (UUID5, UUID4, UUID3, UUID2, UUID1),
  265. unjsonify=False)
  266. def test_image_get_index_marker(self):
  267. """Test correct set of images returned with marker param."""
  268. uuid4_time = timeutils.utcnow() + datetime.timedelta(seconds=10)
  269. uuid3_time = uuid4_time + datetime.timedelta(seconds=5)
  270. UUID3 = _gen_uuid()
  271. extra_fixture = self.get_fixture(id=UUID3, name='new name! #123',
  272. status='saving',
  273. created_at=uuid3_time)
  274. db_api.image_create(self.context, extra_fixture)
  275. UUID4 = _gen_uuid()
  276. extra_fixture = self.get_fixture(id=UUID4, name='new name! #125',
  277. status='saving',
  278. created_at=uuid4_time)
  279. db_api.image_create(self.context, extra_fixture)
  280. images = self.client.image_get_all(marker=UUID3)
  281. self.assertEqualImages(images, (UUID4, UUID2, UUID1), unjsonify=False)
  282. def test_image_get_index_limit(self):
  283. """Test correct number of images returned with limit param."""
  284. extra_fixture = self.get_fixture(id=_gen_uuid(),
  285. name='new name! #123',
  286. status='saving')
  287. db_api.image_create(self.context, extra_fixture)
  288. extra_fixture = self.get_fixture(id=_gen_uuid(),
  289. name='new name! #125',
  290. status='saving')
  291. db_api.image_create(self.context, extra_fixture)
  292. images = self.client.image_get_all(limit=2)
  293. self.assertEqual(2, len(images))
  294. def test_image_get_index_marker_limit(self):
  295. """Test correct set of images returned with marker/limit params."""
  296. uuid4_time = timeutils.utcnow() + datetime.timedelta(seconds=10)
  297. uuid3_time = uuid4_time + datetime.timedelta(seconds=5)
  298. UUID3 = _gen_uuid()
  299. extra_fixture = self.get_fixture(id=UUID3, name='new name! #123',
  300. status='saving',
  301. created_at=uuid3_time)
  302. db_api.image_create(self.context, extra_fixture)
  303. UUID4 = _gen_uuid()
  304. extra_fixture = self.get_fixture(id=UUID4, name='new name! #125',
  305. status='saving',
  306. created_at=uuid4_time)
  307. db_api.image_create(self.context, extra_fixture)
  308. images = self.client.image_get_all(marker=UUID4, limit=1)
  309. self.assertEqualImages(images, (UUID2,), unjsonify=False)
  310. def test_image_get_index_limit_None(self):
  311. """Test correct set of images returned with limit param == None."""
  312. extra_fixture = self.get_fixture(id=_gen_uuid(),
  313. name='new name! #123',
  314. status='saving')
  315. db_api.image_create(self.context, extra_fixture)
  316. extra_fixture = self.get_fixture(id=_gen_uuid(),
  317. name='new name! #125',
  318. status='saving')
  319. db_api.image_create(self.context, extra_fixture)
  320. images = self.client.image_get_all(limit=None)
  321. self.assertEqual(4, len(images))
  322. def test_image_get_index_by_name(self):
  323. """Test correct set of public, name-filtered image returned.
  324. This is just a sanity check, we test the details call more in-depth.
  325. """
  326. extra_fixture = self.get_fixture(id=_gen_uuid(),
  327. name='new name! #123')
  328. db_api.image_create(self.context, extra_fixture)
  329. images = self.client.image_get_all(filters={'name': 'new name! #123'})
  330. self.assertEqual(1, len(images))
  331. for image in images:
  332. self.assertEqual('new name! #123', image['name'])
  333. def test_image_get_is_public_v2(self):
  334. """Tests that a detailed call can be filtered by a property"""
  335. extra_fixture = self.get_fixture(id=_gen_uuid(), status='saving',
  336. properties={'is_public': 'avalue'})
  337. context = copy.copy(self.context)
  338. db_api.image_create(context, extra_fixture)
  339. filters = {'is_public': 'avalue'}
  340. images = self.client.image_get_all(filters=filters)
  341. self.assertEqual(1, len(images))
  342. for image in images:
  343. self.assertEqual('avalue', image['properties'][0]['value'])
  344. def test_image_get(self):
  345. """Tests that the detailed info about an image returned"""
  346. fixture = self.get_fixture(id=UUID1, name='fake image #1',
  347. visibility='shared',
  348. size=13, virtual_size=26,
  349. disk_format='ami', container_format='ami')
  350. data = self.client.image_get(image_id=UUID1)
  351. for k, v in fixture.items():
  352. el = data[k]
  353. self.assertEqual(v, data[k],
  354. "Failed v != data[k] where v = %(v)s and "
  355. "k = %(k)s and data[k] = %(el)s" %
  356. dict(v=v, k=k, el=el))
  357. def test_image_get_non_existing(self):
  358. """Tests that NotFound is raised when getting a non-existing image"""
  359. self.assertRaises(exception.NotFound,
  360. self.client.image_get,
  361. image_id=_gen_uuid())
  362. def test_image_create_basic(self):
  363. """Tests that we can add image metadata and returns the new id"""
  364. fixture = self.get_fixture()
  365. new_image = self.client.image_create(values=fixture)
  366. # Test all other attributes set
  367. data = self.client.image_get(image_id=new_image['id'])
  368. for k, v in fixture.items():
  369. self.assertEqual(v, data[k])
  370. # Test status was updated properly
  371. self.assertIn('status', data)
  372. self.assertEqual('active', data['status'])
  373. def test_image_create_with_properties(self):
  374. """Tests that we can add image metadata with properties"""
  375. fixture = self.get_fixture(location="file:///tmp/glance-tests/2",
  376. properties={'distro': 'Ubuntu 10.04 LTS'})
  377. new_image = self.client.image_create(values=fixture)
  378. self.assertIn('properties', new_image)
  379. self.assertEqual(new_image['properties'][0]['value'],
  380. fixture['properties']['distro'])
  381. del fixture['location']
  382. del fixture['properties']
  383. for k, v in fixture.items():
  384. self.assertEqual(v, new_image[k])
  385. # Test status was updated properly
  386. self.assertIn('status', new_image.keys())
  387. self.assertEqual('active', new_image['status'])
  388. def test_image_create_already_exists(self):
  389. """Tests proper exception is raised if image with ID already exists"""
  390. fixture = self.get_fixture(id=UUID2,
  391. location="file:///tmp/glance-tests/2")
  392. self.assertRaises(exception.Duplicate,
  393. self.client.image_create,
  394. values=fixture)
  395. def test_image_create_with_bad_status(self):
  396. """Tests proper exception is raised if a bad status is set"""
  397. fixture = self.get_fixture(status='bad status',
  398. location="file:///tmp/glance-tests/2")
  399. self.assertRaises(exception.Invalid,
  400. self.client.image_create,
  401. values=fixture)
  402. def test_image_update(self):
  403. """Tests that the registry API updates the image"""
  404. fixture = {'name': 'fake public image #2',
  405. 'disk_format': 'vmdk',
  406. 'status': 'saving'}
  407. self.assertTrue(self.client.image_update(image_id=UUID2,
  408. values=fixture))
  409. # Test all other attributes set
  410. data = self.client.image_get(image_id=UUID2)
  411. for k, v in fixture.items():
  412. self.assertEqual(v, data[k])
  413. def test_image_update_conflict(self):
  414. """Tests that the registry API updates the image"""
  415. next_state = 'saving'
  416. fixture = {'name': 'fake public image #2',
  417. 'disk_format': 'vmdk',
  418. 'status': next_state}
  419. image = self.client.image_get(image_id=UUID2)
  420. current = image['status']
  421. self.assertEqual('active', current)
  422. # image is in 'active' state so this should cause a failure.
  423. from_state = 'saving'
  424. self.assertRaises(exception.Conflict, self.client.image_update,
  425. image_id=UUID2, values=fixture,
  426. from_state=from_state)
  427. try:
  428. self.client.image_update(image_id=UUID2, values=fixture,
  429. from_state=from_state)
  430. except exception.Conflict as exc:
  431. msg = (_('cannot transition from %(current)s to '
  432. '%(next)s in update (wanted '
  433. 'from_state=%(from)s)') %
  434. {'current': current, 'next': next_state,
  435. 'from': from_state})
  436. self.assertEqual(str(exc), msg)
  437. def test_image_update_with_invalid_min_disk(self):
  438. """Tests that the registry API updates the image"""
  439. next_state = 'saving'
  440. fixture = {'name': 'fake image',
  441. 'disk_format': 'vmdk',
  442. 'min_disk': 2 ** 31 + 1,
  443. 'status': next_state}
  444. image = self.client.image_get(image_id=UUID2)
  445. current = image['status']
  446. self.assertEqual('active', current)
  447. # image is in 'active' state so this should cause a failure.
  448. from_state = 'saving'
  449. self.assertRaises(exception.Invalid, self.client.image_update,
  450. image_id=UUID2, values=fixture,
  451. from_state=from_state)
  452. def test_image_update_with_invalid_min_ram(self):
  453. """Tests that the registry API updates the image"""
  454. next_state = 'saving'
  455. fixture = {'name': 'fake image',
  456. 'disk_format': 'vmdk',
  457. 'min_ram': 2 ** 31 + 1,
  458. 'status': next_state}
  459. image = self.client.image_get(image_id=UUID2)
  460. current = image['status']
  461. self.assertEqual('active', current)
  462. # image is in 'active' state so this should cause a failure.
  463. from_state = 'saving'
  464. self.assertRaises(exception.Invalid, self.client.image_update,
  465. image_id=UUID2, values=fixture,
  466. from_state=from_state)
  467. def _test_image_update_not_existing(self):
  468. """Tests non existing image update doesn't work"""
  469. fixture = self.get_fixture(status='bad status')
  470. self.assertRaises(exception.NotFound,
  471. self.client.image_update,
  472. image_id=_gen_uuid(),
  473. values=fixture)
  474. def test_image_destroy(self):
  475. """Tests that image metadata is deleted properly"""
  476. # Grab the original number of images
  477. orig_num_images = len(self.client.image_get_all())
  478. # Delete image #2
  479. image = self.FIXTURES[1]
  480. deleted_image = self.client.image_destroy(image_id=image['id'])
  481. self.assertTrue(deleted_image)
  482. self.assertEqual(image['id'], deleted_image['id'])
  483. self.assertTrue(deleted_image['deleted'])
  484. self.assertTrue(deleted_image['deleted_at'])
  485. # Verify one less image
  486. filters = {'deleted': False}
  487. new_num_images = len(self.client.image_get_all(filters=filters))
  488. self.assertEqual(new_num_images, orig_num_images - 1)
  489. def test_image_destroy_not_existing(self):
  490. """Tests cannot delete non-existing image"""
  491. self.assertRaises(exception.NotFound,
  492. self.client.image_destroy,
  493. image_id=_gen_uuid())
  494. def test_image_get_members(self):
  495. """Tests getting image members"""
  496. memb_list = self.client.image_member_find(image_id=UUID2)
  497. num_members = len(memb_list)
  498. self.assertEqual(0, num_members)
  499. def test_image_get_members_not_existing(self):
  500. """Tests getting non-existent image members"""
  501. self.assertRaises(exception.NotFound,
  502. self.client.image_get_members,
  503. image_id=_gen_uuid())
  504. def test_image_member_find(self):
  505. """Tests getting member images"""
  506. memb_list = self.client.image_member_find(member='pattieblack')
  507. num_members = len(memb_list)
  508. self.assertEqual(0, num_members)
  509. def test_image_member_find_include_deleted(self):
  510. """Tests getting image members including the deleted member"""
  511. values = dict(image_id=UUID2, member='pattieblack')
  512. # create a member
  513. member = self.client.image_member_create(values=values)
  514. memb_list = self.client.image_member_find(member='pattieblack')
  515. memb_list2 = self.client.image_member_find(member='pattieblack',
  516. include_deleted=True)
  517. self.assertEqual(1, len(memb_list))
  518. self.assertEqual(1, len(memb_list2))
  519. # delete the member
  520. self.client.image_member_delete(memb_id=member['id'])
  521. memb_list = self.client.image_member_find(member='pattieblack')
  522. memb_list2 = self.client.image_member_find(member='pattieblack',
  523. include_deleted=True)
  524. self.assertEqual(0, len(memb_list))
  525. self.assertEqual(1, len(memb_list2))
  526. # create it again
  527. member = self.client.image_member_create(values=values)
  528. memb_list = self.client.image_member_find(member='pattieblack')
  529. memb_list2 = self.client.image_member_find(member='pattieblack',
  530. include_deleted=True)
  531. self.assertEqual(1, len(memb_list))
  532. self.assertEqual(2, len(memb_list2))
  533. def test_add_update_members(self):
  534. """Tests updating image members"""
  535. values = dict(image_id=UUID2, member='pattieblack')
  536. member = self.client.image_member_create(values=values)
  537. self.assertTrue(member)
  538. values['member'] = 'pattieblack2'
  539. self.assertTrue(self.client.image_member_update(memb_id=member['id'],
  540. values=values))
  541. def test_add_delete_member(self):
  542. """Tests deleting image members"""
  543. values = dict(image_id=UUID2, member='pattieblack')
  544. member = self.client.image_member_create(values=values)
  545. self.client.image_member_delete(memb_id=member['id'])
  546. memb_list = self.client.image_member_find(member='pattieblack')
  547. self.assertEqual(0, len(memb_list))
  548. class TestRegistryV2ClientApi(base.IsolatedUnitTest):
  549. """Test proper actions made against a registry service.
  550. Test for both valid and invalid requests.
  551. """
  552. def setUp(self):
  553. """Establish a clean test environment"""
  554. super(TestRegistryV2ClientApi, self).setUp()
  555. reload_module(rapi)
  556. def test_configure_registry_client_not_using_use_user_token(self):
  557. self.config(use_user_token=False)
  558. with patch.object(rapi,
  559. 'configure_registry_admin_creds') as mock_rapi:
  560. rapi.configure_registry_client()
  561. mock_rapi.assert_called_once_with()
  562. def _get_fake_config_creds(self, auth_url='auth_url', strategy='keystone'):
  563. return {
  564. 'user': 'user',
  565. 'password': 'password',
  566. 'username': 'user',
  567. 'tenant': 'tenant',
  568. 'auth_url': auth_url,
  569. 'strategy': strategy,
  570. 'region': 'region'
  571. }
  572. def test_configure_registry_admin_creds(self):
  573. expected = self._get_fake_config_creds(auth_url=None,
  574. strategy='configured_strategy')
  575. self.config(admin_user=expected['user'])
  576. self.config(admin_password=expected['password'])
  577. self.config(admin_tenant_name=expected['tenant'])
  578. self.config(auth_strategy=expected['strategy'])
  579. self.config(auth_region=expected['region'])
  580. self.mock_object(os, 'getenv', lambda x: None)
  581. self.assertIsNone(rapi._CLIENT_CREDS)
  582. rapi.configure_registry_admin_creds()
  583. self.assertEqual(expected, rapi._CLIENT_CREDS)
  584. def test_configure_registry_admin_creds_with_auth_url(self):
  585. expected = self._get_fake_config_creds()
  586. self.config(admin_user=expected['user'])
  587. self.config(admin_password=expected['password'])
  588. self.config(admin_tenant_name=expected['tenant'])
  589. self.config(auth_url=expected['auth_url'])
  590. self.config(auth_strategy='test_strategy')
  591. self.config(auth_region=expected['region'])
  592. self.assertIsNone(rapi._CLIENT_CREDS)
  593. rapi.configure_registry_admin_creds()
  594. self.assertEqual(expected, rapi._CLIENT_CREDS)