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_bin_glance_cache_manage.py 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. # Copyright 2011 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. """Functional test case that utilizes the bin/glance-cache-manage CLI tool"""
  16. import datetime
  17. import hashlib
  18. import os
  19. import sys
  20. import httplib2
  21. from oslo_serialization import jsonutils
  22. from oslo_utils import units
  23. from six.moves import http_client
  24. # NOTE(jokke): simplified transition to py3, behaves like py2 xrange
  25. from six.moves import range
  26. from glance.tests import functional
  27. from glance.tests.utils import execute
  28. from glance.tests.utils import minimal_headers
  29. FIVE_KB = 5 * units.Ki
  30. class TestBinGlanceCacheManage(functional.FunctionalTest):
  31. """Functional tests for the bin/glance CLI tool"""
  32. def setUp(self):
  33. self.image_cache_driver = "sqlite"
  34. super(TestBinGlanceCacheManage, self).setUp()
  35. self.api_server.deployment_flavor = "cachemanagement"
  36. # NOTE(sirp): This is needed in case we are running the tests under an
  37. # environment in which OS_AUTH_STRATEGY=keystone. The test server we
  38. # spin up won't have keystone support, so we need to switch to the
  39. # NoAuth strategy.
  40. os.environ['OS_AUTH_STRATEGY'] = 'noauth'
  41. os.environ['OS_AUTH_URL'] = ''
  42. def add_image(self, name):
  43. """
  44. Adds an image with supplied name and returns the newly-created
  45. image identifier.
  46. """
  47. image_data = b"*" * FIVE_KB
  48. headers = minimal_headers(name)
  49. path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port)
  50. http = httplib2.Http()
  51. response, content = http.request(path, 'POST', headers=headers,
  52. body=image_data)
  53. self.assertEqual(http_client.CREATED, response.status)
  54. data = jsonutils.loads(content)
  55. self.assertEqual(hashlib.md5(image_data).hexdigest(),
  56. data['image']['checksum'])
  57. self.assertEqual(FIVE_KB, data['image']['size'])
  58. self.assertEqual(name, data['image']['name'])
  59. self.assertTrue(data['image']['is_public'])
  60. return data['image']['id']
  61. def is_image_cached(self, image_id):
  62. """
  63. Return True if supplied image ID is cached, False otherwise
  64. """
  65. exe_cmd = '%s -m glance.cmd.cache_manage' % sys.executable
  66. cmd = "%s --port=%d list-cached" % (exe_cmd, self.api_port)
  67. exitcode, out, err = execute(cmd)
  68. self.assertEqual(0, exitcode)
  69. out = out.decode('utf-8')
  70. return image_id in out
  71. def iso_date(self, image_id):
  72. """
  73. Return True if supplied image ID is cached, False otherwise
  74. """
  75. exe_cmd = '%s -m glance.cmd.cache_manage' % sys.executable
  76. cmd = "%s --port=%d list-cached" % (exe_cmd, self.api_port)
  77. exitcode, out, err = execute(cmd)
  78. out = out.decode('utf-8')
  79. return datetime.datetime.utcnow().strftime("%Y-%m-%d") in out
  80. def test_no_cache_enabled(self):
  81. """
  82. Test that cache index command works
  83. """
  84. self.cleanup()
  85. self.api_server.deployment_flavor = ''
  86. self.start_servers() # Not passing in cache_manage in pipeline...
  87. api_port = self.api_port
  88. # Verify decent error message returned
  89. exe_cmd = '%s -m glance.cmd.cache_manage' % sys.executable
  90. cmd = "%s --port=%d list-cached" % (exe_cmd, api_port)
  91. exitcode, out, err = execute(cmd, raise_error=False)
  92. self.assertEqual(1, exitcode)
  93. self.assertIn(b'Cache management middleware not enabled on host',
  94. out.strip())
  95. self.stop_servers()
  96. def test_cache_index(self):
  97. """
  98. Test that cache index command works
  99. """
  100. self.cleanup()
  101. self.start_servers(**self.__dict__.copy())
  102. api_port = self.api_port
  103. # Verify no cached images
  104. exe_cmd = '%s -m glance.cmd.cache_manage' % sys.executable
  105. cmd = "%s --port=%d list-cached" % (exe_cmd, api_port)
  106. exitcode, out, err = execute(cmd)
  107. self.assertEqual(0, exitcode)
  108. self.assertIn(b'No cached images', out.strip())
  109. ids = {}
  110. # Add a few images and cache the second one of them
  111. # by GETing the image...
  112. for x in range(4):
  113. ids[x] = self.add_image("Image%s" % x)
  114. path = "http://%s:%d/v1/images/%s" % ("127.0.0.1", api_port,
  115. ids[1])
  116. http = httplib2.Http()
  117. response, content = http.request(path, 'GET')
  118. self.assertEqual(http_client.OK, response.status)
  119. self.assertTrue(self.is_image_cached(ids[1]),
  120. "%s is not cached." % ids[1])
  121. self.assertTrue(self.iso_date(ids[1]))
  122. self.stop_servers()
  123. def test_queue(self):
  124. """
  125. Test that we can queue and fetch images using the
  126. CLI utility
  127. """
  128. self.cleanup()
  129. self.start_servers(**self.__dict__.copy())
  130. api_port = self.api_port
  131. # Verify no cached images
  132. exe_cmd = '%s -m glance.cmd.cache_manage' % sys.executable
  133. cmd = "%s --port=%d list-cached" % (exe_cmd, api_port)
  134. exitcode, out, err = execute(cmd)
  135. self.assertEqual(0, exitcode)
  136. self.assertIn(b'No cached images', out.strip())
  137. # Verify no queued images
  138. cmd = "%s --port=%d list-queued" % (exe_cmd, api_port)
  139. exitcode, out, err = execute(cmd)
  140. self.assertEqual(0, exitcode)
  141. self.assertIn(b'No queued images', out.strip())
  142. ids = {}
  143. # Add a few images and cache the second one of them
  144. # by GETing the image...
  145. for x in range(4):
  146. ids[x] = self.add_image("Image%s" % x)
  147. # Queue second image and then cache it
  148. cmd = "%s --port=%d --force queue-image %s" % (
  149. exe_cmd, api_port, ids[1])
  150. exitcode, out, err = execute(cmd)
  151. self.assertEqual(0, exitcode)
  152. # Verify queued second image
  153. cmd = "%s --port=%d list-queued" % (exe_cmd, api_port)
  154. exitcode, out, err = execute(cmd)
  155. self.assertEqual(0, exitcode)
  156. out = out.decode('utf-8')
  157. self.assertIn(ids[1], out, 'Image %s was not queued!' % ids[1])
  158. # Cache images in the queue by running the prefetcher
  159. cache_config_filepath = os.path.join(self.test_dir, 'etc',
  160. 'glance-cache.conf')
  161. cache_file_options = {
  162. 'image_cache_dir': self.api_server.image_cache_dir,
  163. 'image_cache_driver': self.image_cache_driver,
  164. 'registry_port': self.registry_server.bind_port,
  165. 'lock_path': self.test_dir,
  166. 'log_file': os.path.join(self.test_dir, 'cache.log'),
  167. 'metadata_encryption_key': "012345678901234567890123456789ab",
  168. 'filesystem_store_datadir': self.test_dir
  169. }
  170. with open(cache_config_filepath, 'w') as cache_file:
  171. cache_file.write("""[DEFAULT]
  172. debug = True
  173. lock_path = %(lock_path)s
  174. image_cache_dir = %(image_cache_dir)s
  175. image_cache_driver = %(image_cache_driver)s
  176. registry_host = 127.0.0.1
  177. registry_port = %(registry_port)s
  178. metadata_encryption_key = %(metadata_encryption_key)s
  179. log_file = %(log_file)s
  180. [glance_store]
  181. filesystem_store_datadir=%(filesystem_store_datadir)s
  182. """ % cache_file_options)
  183. cmd = ("%s -m glance.cmd.cache_prefetcher --config-file %s" %
  184. (sys.executable, cache_config_filepath))
  185. exitcode, out, err = execute(cmd)
  186. self.assertEqual(0, exitcode)
  187. self.assertEqual(b'', out.strip(), out)
  188. # Verify no queued images
  189. cmd = "%s --port=%d list-queued" % (exe_cmd, api_port)
  190. exitcode, out, err = execute(cmd)
  191. self.assertEqual(0, exitcode)
  192. self.assertIn(b'No queued images', out.strip())
  193. # Verify second image now cached
  194. cmd = "%s --port=%d list-cached" % (exe_cmd, api_port)
  195. exitcode, out, err = execute(cmd)
  196. self.assertEqual(0, exitcode)
  197. out = out.decode('utf-8')
  198. self.assertIn(ids[1], out, 'Image %s was not cached!' % ids[1])
  199. # Queue third image and then delete it from queue
  200. cmd = "%s --port=%d --force queue-image %s" % (
  201. exe_cmd, api_port, ids[2])
  202. exitcode, out, err = execute(cmd)
  203. self.assertEqual(0, exitcode)
  204. # Verify queued third image
  205. cmd = "%s --port=%d list-queued" % (exe_cmd, api_port)
  206. exitcode, out, err = execute(cmd)
  207. self.assertEqual(0, exitcode)
  208. out = out.decode('utf-8')
  209. self.assertIn(ids[2], out, 'Image %s was not queued!' % ids[2])
  210. # Delete the image from the queue
  211. cmd = ("%s --port=%d --force "
  212. "delete-queued-image %s") % (exe_cmd, api_port, ids[2])
  213. exitcode, out, err = execute(cmd)
  214. self.assertEqual(0, exitcode)
  215. # Verify no queued images
  216. cmd = "%s --port=%d list-queued" % (exe_cmd, api_port)
  217. exitcode, out, err = execute(cmd)
  218. self.assertEqual(0, exitcode)
  219. self.assertIn(b'No queued images', out.strip())
  220. # Queue all images
  221. for x in range(4):
  222. cmd = ("%s --port=%d --force "
  223. "queue-image %s") % (exe_cmd, api_port, ids[x])
  224. exitcode, out, err = execute(cmd)
  225. self.assertEqual(0, exitcode)
  226. # Verify queued third image
  227. cmd = "%s --port=%d list-queued" % (exe_cmd, api_port)
  228. exitcode, out, err = execute(cmd)
  229. self.assertEqual(0, exitcode)
  230. self.assertIn(b'Found 3 queued images', out)
  231. # Delete the image from the queue
  232. cmd = ("%s --port=%d --force "
  233. "delete-all-queued-images") % (exe_cmd, api_port)
  234. exitcode, out, err = execute(cmd)
  235. self.assertEqual(0, exitcode)
  236. # Verify nothing in queue anymore
  237. cmd = "%s --port=%d list-queued" % (exe_cmd, api_port)
  238. exitcode, out, err = execute(cmd)
  239. self.assertEqual(0, exitcode)
  240. self.assertIn(b'No queued images', out.strip())
  241. # verify two image id when queue-image
  242. cmd = ("%s --port=%d --force "
  243. "queue-image %s %s") % (exe_cmd, api_port, ids[0], ids[1])
  244. exitcode, out, err = execute(cmd, raise_error=False)
  245. self.assertEqual(1, exitcode)
  246. self.assertIn(b'Please specify one and only ID of '
  247. b'the image you wish to ', out.strip())
  248. # verify two image id when delete-queued-image
  249. cmd = ("%s --port=%d --force delete-queued-image "
  250. "%s %s") % (exe_cmd, api_port, ids[0], ids[1])
  251. exitcode, out, err = execute(cmd, raise_error=False)
  252. self.assertEqual(1, exitcode)
  253. self.assertIn(b'Please specify one and only ID of '
  254. b'the image you wish to ', out.strip())
  255. # verify two image id when delete-cached-image
  256. cmd = ("%s --port=%d --force delete-cached-image "
  257. "%s %s") % (exe_cmd, api_port, ids[0], ids[1])
  258. exitcode, out, err = execute(cmd, raise_error=False)
  259. self.assertEqual(1, exitcode)
  260. self.assertIn(b'Please specify one and only ID of '
  261. b'the image you wish to ', out.strip())
  262. self.stop_servers()