summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-08-16 08:08:34 +0000
committerGerrit Code Review <review@openstack.org>2018-08-16 08:08:34 +0000
commit62c2c914ef2ac55f03877a42c2bc81b695320648 (patch)
treeee032d6bec2c2caee4e8707a34a68f9dffb7b018
parentb506e3cf793b2fccd4f17f78159d76890786fc59 (diff)
parent432b9f6c24f8c4a121767b60a0f81eb2185d1ed5 (diff)
Merge "Add multihash checks to functional tests"
-rw-r--r--glance/tests/functional/ft_utils.py28
-rw-r--r--glance/tests/functional/v2/test_images.py277
2 files changed, 143 insertions, 162 deletions
diff --git a/glance/tests/functional/ft_utils.py b/glance/tests/functional/ft_utils.py
index ea0791d..edbfe5b 100644
--- a/glance/tests/functional/ft_utils.py
+++ b/glance/tests/functional/ft_utils.py
@@ -13,6 +13,7 @@
13# License for the specific language governing permissions and limitations 13# License for the specific language governing permissions and limitations
14# under the License. 14# under the License.
15 15
16import six
16import time 17import time
17 18
18from oslo_serialization import jsonutils 19from oslo_serialization import jsonutils
@@ -20,6 +21,33 @@ import requests
20from six.moves import http_client as http 21from six.moves import http_client as http
21 22
22 23
24def verify_image_hashes_and_status(
25 test_obj, image_id, checksum=None, os_hash_value=None, status=None,
26 os_hash_algo='sha512'):
27 """Makes image-detail request and checks response.
28
29 :param test_obj: The test object; expected to have _url() and
30 _headers() defined on it
31 :param image_id: Image id to use in the request
32 :param checksum: Expected checksum (default: None)
33 :param os_hash_value: Expected multihash value (default: None)
34 :param status: Expected status (default: None)
35 :param os_hash_algo: Expected value of os_hash_algo; only checked when
36 os_hash_value is not None (default: 'sha512')
37 """
38 path = test_obj._url('/v2/images/%s' % image_id)
39 response = requests.get(path, headers=test_obj._headers())
40 test_obj.assertEqual(http.OK, response.status_code)
41 image = jsonutils.loads(response.text)
42 test_obj.assertEqual(checksum, image['checksum'])
43 if os_hash_value:
44 # make sure we're using the hashing_algorithm we expect
45 test_obj.assertEqual(six.text_type(os_hash_algo),
46 image['os_hash_algo'])
47 test_obj.assertEqual(os_hash_value, image['os_hash_value'])
48 test_obj.assertEqual(status, image['status'])
49
50
23def wait_for_status(request_path, request_headers, status='active', 51def wait_for_status(request_path, request_headers, status='active',
24 max_sec=10, delay_sec=0.2, start_delay_sec=None): 52 max_sec=10, delay_sec=0.2, start_delay_sec=None):
25 """ 53 """
diff --git a/glance/tests/functional/v2/test_images.py b/glance/tests/functional/v2/test_images.py
index 11ce561..eb58436 100644
--- a/glance/tests/functional/v2/test_images.py
+++ b/glance/tests/functional/v2/test_images.py
@@ -189,20 +189,6 @@ class TestImages(functional.FunctionalTest):
189 self.assertEqual(1, len(images)) 189 self.assertEqual(1, len(images))
190 self.assertEqual(image_id, images[0]['id']) 190 self.assertEqual(image_id, images[0]['id'])
191 191
192 def _verify_image_hashes_and_status(
193 checksum=None, os_hash_value=None, status=None):
194 path = self._url('/v2/images/%s' % image_id)
195 response = requests.get(path, headers=self._headers())
196 self.assertEqual(http.OK, response.status_code)
197 image = jsonutils.loads(response.text)
198 self.assertEqual(checksum, image['checksum'])
199 if os_hash_value:
200 # make sure we're using the hashing_algorithm we expect
201 self.assertEqual(six.text_type('sha512'),
202 image['os_hash_algo'])
203 self.assertEqual(os_hash_value, image['os_hash_value'])
204 self.assertEqual(status, image['status'])
205
206 # Upload some image data to staging area 192 # Upload some image data to staging area
207 path = self._url('/v2/images/%s/stage' % image_id) 193 path = self._url('/v2/images/%s/stage' % image_id)
208 headers = self._headers({'Content-Type': 'application/octet-stream'}) 194 headers = self._headers({'Content-Type': 'application/octet-stream'})
@@ -211,7 +197,8 @@ class TestImages(functional.FunctionalTest):
211 self.assertEqual(http.NO_CONTENT, response.status_code) 197 self.assertEqual(http.NO_CONTENT, response.status_code)
212 198
213 # Verify image is in uploading state, hashes are None 199 # Verify image is in uploading state, hashes are None
214 _verify_image_hashes_and_status(status='uploading') 200 func_utils.verify_image_hashes_and_status(self, image_id,
201 status='uploading')
215 202
216 # Import image to store 203 # Import image to store
217 path = self._url('/v2/images/%s/import' % image_id) 204 path = self._url('/v2/images/%s/import' % image_id)
@@ -236,9 +223,11 @@ class TestImages(functional.FunctionalTest):
236 delay_sec=0.2) 223 delay_sec=0.2)
237 expect_c = six.text_type(hashlib.md5(image_data).hexdigest()) 224 expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
238 expect_h = six.text_type(hashlib.sha512(image_data).hexdigest()) 225 expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
239 _verify_image_hashes_and_status(checksum=expect_c, 226 func_utils.verify_image_hashes_and_status(self,
240 os_hash_value=expect_h, 227 image_id,
241 status='active') 228 checksum=expect_c,
229 os_hash_value=expect_h,
230 status='active')
242 231
243 # Ensure the size is updated to reflect the data uploaded 232 # Ensure the size is updated to reflect the data uploaded
244 path = self._url('/v2/images/%s' % image_id) 233 path = self._url('/v2/images/%s' % image_id)
@@ -341,22 +330,10 @@ class TestImages(functional.FunctionalTest):
341 self.assertEqual(1, len(images)) 330 self.assertEqual(1, len(images))
342 self.assertEqual(image_id, images[0]['id']) 331 self.assertEqual(image_id, images[0]['id'])
343 332
344 def _verify_image_hashes_and_status(
345 checksum=None, os_hash_value=None, status=None):
346 path = self._url('/v2/images/%s' % image_id)
347 response = requests.get(path, headers=self._headers())
348 self.assertEqual(http.OK, response.status_code)
349 image = jsonutils.loads(response.text)
350 self.assertEqual(checksum, image['checksum'])
351 if os_hash_value:
352 # make sure we're using the hashing_algorithm we expect
353 self.assertEqual(six.text_type('sha512'),
354 image['os_hash_algo'])
355 self.assertEqual(os_hash_value, image['os_hash_value'])
356 self.assertEqual(status, image['status'])
357
358 # Verify image is in queued state and hashes are None 333 # Verify image is in queued state and hashes are None
359 _verify_image_hashes_and_status(status='queued') 334 func_utils.verify_image_hashes_and_status(self,
335 image_id,
336 status='queued')
360 337
361 # Import image to store 338 # Import image to store
362 path = self._url('/v2/images/%s/import' % image_id) 339 path = self._url('/v2/images/%s/import' % image_id)
@@ -386,9 +363,11 @@ class TestImages(functional.FunctionalTest):
386 with requests.get(image_data_uri) as r: 363 with requests.get(image_data_uri) as r:
387 expect_c = six.text_type(hashlib.md5(r.content).hexdigest()) 364 expect_c = six.text_type(hashlib.md5(r.content).hexdigest())
388 expect_h = six.text_type(hashlib.sha512(r.content).hexdigest()) 365 expect_h = six.text_type(hashlib.sha512(r.content).hexdigest())
389 _verify_image_hashes_and_status(checksum=expect_c, 366 func_utils.verify_image_hashes_and_status(self,
390 os_hash_value=expect_h, 367 image_id,
391 status='active') 368 checksum=expect_c,
369 os_hash_value=expect_h,
370 status='active')
392 371
393 # Deleting image should work 372 # Deleting image should work
394 path = self._url('/v2/images/%s' % image_id) 373 path = self._url('/v2/images/%s' % image_id)
@@ -748,18 +727,6 @@ class TestImages(functional.FunctionalTest):
748 response = requests.get(path, headers=headers) 727 response = requests.get(path, headers=headers)
749 self.assertEqual(http.NO_CONTENT, response.status_code) 728 self.assertEqual(http.NO_CONTENT, response.status_code)
750 729
751 def _verify_image_hashes_and_status(checksum, os_hash_value, status):
752 # hashes should be populated and status should be active
753 path = self._url('/v2/images/%s' % image_id)
754 response = requests.get(path, headers=self._headers())
755 self.assertEqual(http.OK, response.status_code)
756 image = jsonutils.loads(response.text)
757 self.assertEqual(checksum, image['checksum'])
758 # make sure we're using the default algo
759 self.assertEqual(six.text_type('sha512'), image['os_hash_algo'])
760 self.assertEqual(os_hash_value, image['os_hash_value'])
761 self.assertEqual(status, image['status'])
762
763 # Upload some image data 730 # Upload some image data
764 path = self._url('/v2/images/%s/file' % image_id) 731 path = self._url('/v2/images/%s/file' % image_id)
765 headers = self._headers({'Content-Type': 'application/octet-stream'}) 732 headers = self._headers({'Content-Type': 'application/octet-stream'})
@@ -769,7 +736,8 @@ class TestImages(functional.FunctionalTest):
769 736
770 expect_c = six.text_type(hashlib.md5(image_data).hexdigest()) 737 expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
771 expect_h = six.text_type(hashlib.sha512(image_data).hexdigest()) 738 expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
772 _verify_image_hashes_and_status(expect_c, expect_h, 'active') 739 func_utils.verify_image_hashes_and_status(self, image_id, expect_c,
740 expect_h, 'active')
773 741
774 # `disk_format` and `container_format` cannot 742 # `disk_format` and `container_format` cannot
775 # be replaced when the image is active. 743 # be replaced when the image is active.
@@ -797,7 +765,8 @@ class TestImages(functional.FunctionalTest):
797 headers = self._headers({'Content-Type': 'application/octet-stream'}) 765 headers = self._headers({'Content-Type': 'application/octet-stream'})
798 response = requests.put(path, headers=headers, data='XXX') 766 response = requests.put(path, headers=headers, data='XXX')
799 self.assertEqual(http.CONFLICT, response.status_code) 767 self.assertEqual(http.CONFLICT, response.status_code)
800 _verify_image_hashes_and_status(expect_c, expect_h, 'active') 768 func_utils.verify_image_hashes_and_status(self, image_id, expect_c,
769 expect_h, 'active')
801 770
802 # Ensure the size is updated to reflect the data uploaded 771 # Ensure the size is updated to reflect the data uploaded
803 path = self._url('/v2/images/%s' % image_id) 772 path = self._url('/v2/images/%s' % image_id)
@@ -1100,33 +1069,32 @@ class TestImages(functional.FunctionalTest):
1100 response = requests.get(path, headers=self._headers()) 1069 response = requests.get(path, headers=self._headers())
1101 self.assertEqual(http.BAD_REQUEST, response.status_code) 1070 self.assertEqual(http.BAD_REQUEST, response.status_code)
1102 1071
1103 def _verify_image_checksum_and_status(checksum, status):
1104 # Checksum should be populated and status should be active
1105 path = self._url('/v2/images/%s' % image_id)
1106 response = requests.get(path, headers=self._headers())
1107 self.assertEqual(http.OK, response.status_code)
1108 image = jsonutils.loads(response.text)
1109 self.assertEqual(checksum, image['checksum'])
1110 self.assertEqual(status, image['status'])
1111
1112 # Upload some image data to image-1 1072 # Upload some image data to image-1
1113 path = self._url('/v2/images/%s/file' % image_id) 1073 path = self._url('/v2/images/%s/file' % image_id)
1114 headers = self._headers({'Content-Type': 'application/octet-stream'}) 1074 headers = self._headers({'Content-Type': 'application/octet-stream'})
1115 response = requests.put(path, headers=headers, data='ZZZZZ') 1075 image_data = b'ZZZZZ'
1076 response = requests.put(path, headers=headers, data=image_data)
1116 self.assertEqual(http.NO_CONTENT, response.status_code) 1077 self.assertEqual(http.NO_CONTENT, response.status_code)
1117 1078 expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
1118 expected_checksum = '8f113e38d28a79a5a451b16048cc2b72' 1079 expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
1119 _verify_image_checksum_and_status(expected_checksum, 'active') 1080 func_utils.verify_image_hashes_and_status(self,
1120 1081 image_id,
1082 expect_c,
1083 expect_h,
1084 status='active')
1121 # Upload some image data to image-2 1085 # Upload some image data to image-2
1122 path = self._url('/v2/images/%s/file' % image2_id) 1086 path = self._url('/v2/images/%s/file' % image2_id)
1123 headers = self._headers({'Content-Type': 'application/octet-stream'}) 1087 headers = self._headers({'Content-Type': 'application/octet-stream'})
1124 response = requests.put(path, headers=headers, data='ZZZZZ') 1088 image_data = b'WWWWW'
1089 response = requests.put(path, headers=headers, data=image_data)
1125 self.assertEqual(http.NO_CONTENT, response.status_code) 1090 self.assertEqual(http.NO_CONTENT, response.status_code)
1126 1091 expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
1127 expected_checksum = '8f113e38d28a79a5a451b16048cc2b72' 1092 expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
1128 _verify_image_checksum_and_status(expected_checksum, 'active') 1093 func_utils.verify_image_hashes_and_status(self,
1129 1094 image2_id,
1095 expect_c,
1096 expect_h,
1097 status='active')
1130 # Hide image-1 1098 # Hide image-1
1131 path = self._url('/v2/images/%s' % image_id) 1099 path = self._url('/v2/images/%s' % image_id)
1132 media_type = 'application/openstack-images-v2.1-json-patch' 1100 media_type = 'application/openstack-images-v2.1-json-patch'
@@ -4601,23 +4569,16 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
4601 self.assertEqual(1, len(images)) 4569 self.assertEqual(1, len(images))
4602 self.assertEqual(image_id, images[0]['id']) 4570 self.assertEqual(image_id, images[0]['id'])
4603 4571
4604 def _verify_image_checksum_and_status(checksum=None, status=None):
4605 # Checksum should be populated and status should be active
4606 path = self._url('/v2/images/%s' % image_id)
4607 response = requests.get(path, headers=self._headers())
4608 self.assertEqual(http.OK, response.status_code)
4609 image = jsonutils.loads(response.text)
4610 self.assertEqual(checksum, image['checksum'])
4611 self.assertEqual(status, image['status'])
4612
4613 # Upload some image data to staging area 4572 # Upload some image data to staging area
4573 image_data = b'QQQQQ'
4614 path = self._url('/v2/images/%s/stage' % image_id) 4574 path = self._url('/v2/images/%s/stage' % image_id)
4615 headers = self._headers({'Content-Type': 'application/octet-stream'}) 4575 headers = self._headers({'Content-Type': 'application/octet-stream'})
4616 response = requests.put(path, headers=headers, data='ZZZZZ') 4576 response = requests.put(path, headers=headers, data=image_data)
4617 self.assertEqual(http.NO_CONTENT, response.status_code) 4577 self.assertEqual(http.NO_CONTENT, response.status_code)
4618 4578
4619 # Verify image is in uploading state and checksum is None 4579 # Verify image is in uploading state and checksum is None
4620 _verify_image_checksum_and_status(status='uploading') 4580 func_utils.verify_image_hashes_and_status(self, image_id,
4581 status='uploading')
4621 4582
4622 # Import image to store 4583 # Import image to store
4623 path = self._url('/v2/images/%s/import' % image_id) 4584 path = self._url('/v2/images/%s/import' % image_id)
@@ -4640,15 +4601,20 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
4640 status='active', 4601 status='active',
4641 max_sec=2, 4602 max_sec=2,
4642 delay_sec=0.2) 4603 delay_sec=0.2)
4643 _verify_image_checksum_and_status( 4604 expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
4644 checksum='8f113e38d28a79a5a451b16048cc2b72', 4605 expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
4645 status='active') 4606 func_utils.verify_image_hashes_and_status(self,
4607 image_id,
4608 checksum=expect_c,
4609 os_hash_value=expect_h,
4610 status='active')
4646 4611
4647 # Ensure the size is updated to reflect the data uploaded 4612 # Ensure the size is updated to reflect the data uploaded
4648 path = self._url('/v2/images/%s' % image_id) 4613 path = self._url('/v2/images/%s' % image_id)
4649 response = requests.get(path, headers=self._headers()) 4614 response = requests.get(path, headers=self._headers())
4650 self.assertEqual(http.OK, response.status_code) 4615 self.assertEqual(http.OK, response.status_code)
4651 self.assertEqual(5, jsonutils.loads(response.text)['size']) 4616 self.assertEqual(len(image_data),
4617 jsonutils.loads(response.text)['size'])
4652 4618
4653 # Ensure image is created in default backend 4619 # Ensure image is created in default backend
4654 self.assertIn('file1', jsonutils.loads(response.text)['stores']) 4620 self.assertIn('file1', jsonutils.loads(response.text)['stores'])
@@ -4763,23 +4729,16 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
4763 self.assertEqual(1, len(images)) 4729 self.assertEqual(1, len(images))
4764 self.assertEqual(image_id, images[0]['id']) 4730 self.assertEqual(image_id, images[0]['id'])
4765 4731
4766 def _verify_image_checksum_and_status(checksum=None, status=None):
4767 # Checksum should be populated and status should be active
4768 path = self._url('/v2/images/%s' % image_id)
4769 response = requests.get(path, headers=self._headers())
4770 self.assertEqual(http.OK, response.status_code)
4771 image = jsonutils.loads(response.text)
4772 self.assertEqual(checksum, image['checksum'])
4773 self.assertEqual(status, image['status'])
4774
4775 # Upload some image data to staging area 4732 # Upload some image data to staging area
4733 image_data = b'GLANCE IS DEAD SEXY'
4776 path = self._url('/v2/images/%s/stage' % image_id) 4734 path = self._url('/v2/images/%s/stage' % image_id)
4777 headers = self._headers({'Content-Type': 'application/octet-stream'}) 4735 headers = self._headers({'Content-Type': 'application/octet-stream'})
4778 response = requests.put(path, headers=headers, data='ZZZZZ') 4736 response = requests.put(path, headers=headers, data=image_data)
4779 self.assertEqual(http.NO_CONTENT, response.status_code) 4737 self.assertEqual(http.NO_CONTENT, response.status_code)
4780 4738
4781 # Verify image is in uploading state and checksum is None 4739 # Verify image is in uploading state and checksum is None
4782 _verify_image_checksum_and_status(status='uploading') 4740 func_utils.verify_image_hashes_and_status(self, image_id,
4741 status='uploading')
4783 4742
4784 # Import image to file2 store (other than default backend) 4743 # Import image to file2 store (other than default backend)
4785 path = self._url('/v2/images/%s/import' % image_id) 4744 path = self._url('/v2/images/%s/import' % image_id)
@@ -4803,15 +4762,20 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
4803 status='active', 4762 status='active',
4804 max_sec=2, 4763 max_sec=2,
4805 delay_sec=0.2) 4764 delay_sec=0.2)
4806 _verify_image_checksum_and_status( 4765 expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
4807 checksum='8f113e38d28a79a5a451b16048cc2b72', 4766 expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
4808 status='active') 4767 func_utils.verify_image_hashes_and_status(self,
4768 image_id,
4769 checksum=expect_c,
4770 os_hash_value=expect_h,
4771 status='active')
4809 4772
4810 # Ensure the size is updated to reflect the data uploaded 4773 # Ensure the size is updated to reflect the data uploaded
4811 path = self._url('/v2/images/%s' % image_id) 4774 path = self._url('/v2/images/%s' % image_id)
4812 response = requests.get(path, headers=self._headers()) 4775 response = requests.get(path, headers=self._headers())
4813 self.assertEqual(http.OK, response.status_code) 4776 self.assertEqual(http.OK, response.status_code)
4814 self.assertEqual(5, jsonutils.loads(response.text)['size']) 4777 self.assertEqual(len(image_data),
4778 jsonutils.loads(response.text)['size'])
4815 4779
4816 # Ensure image is created in different backend 4780 # Ensure image is created in different backend
4817 self.assertIn('file2', jsonutils.loads(response.text)['stores']) 4781 self.assertIn('file2', jsonutils.loads(response.text)['stores'])
@@ -4927,17 +4891,9 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
4927 self.assertEqual(1, len(images)) 4891 self.assertEqual(1, len(images))
4928 self.assertEqual(image_id, images[0]['id']) 4892 self.assertEqual(image_id, images[0]['id'])
4929 4893
4930 def _verify_image_checksum_and_status(checksum=None, status=None):
4931 # Checksum should be populated and status should be active
4932 path = self._url('/v2/images/%s' % image_id)
4933 response = requests.get(path, headers=self._headers())
4934 self.assertEqual(http.OK, response.status_code)
4935 image = jsonutils.loads(response.text)
4936 self.assertEqual(checksum, image['checksum'])
4937 self.assertEqual(status, image['status'])
4938
4939 # Verify image is in queued state and checksum is None 4894 # Verify image is in queued state and checksum is None
4940 _verify_image_checksum_and_status(status='queued') 4895 func_utils.verify_image_hashes_and_status(self, image_id,
4896 status='queued')
4941 4897
4942 # Import image to store 4898 # Import image to store
4943 path = self._url('/v2/images/%s/import' % image_id) 4899 path = self._url('/v2/images/%s/import' % image_id)
@@ -4945,10 +4901,11 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
4945 'content-type': 'application/json', 4901 'content-type': 'application/json',
4946 'X-Roles': 'admin', 4902 'X-Roles': 'admin',
4947 }) 4903 })
4904 image_data_uri = ('https://www.openstack.org/assets/openstack-logo/'
4905 '2016R/OpenStack-Logo-Horizontal.eps.zip')
4948 data = jsonutils.dumps({'method': { 4906 data = jsonutils.dumps({'method': {
4949 'name': 'web-download', 4907 'name': 'web-download',
4950 'uri': 'https://www.openstack.org/assets/openstack-logo/' 4908 'uri': image_data_uri
4951 '2016R/OpenStack-Logo-Horizontal.eps.zip'
4952 }}) 4909 }})
4953 response = requests.post(path, headers=headers, data=data) 4910 response = requests.post(path, headers=headers, data=data)
4954 self.assertEqual(http.ACCEPTED, response.status_code) 4911 self.assertEqual(http.ACCEPTED, response.status_code)
@@ -4963,10 +4920,14 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
4963 max_sec=20, 4920 max_sec=20,
4964 delay_sec=0.2, 4921 delay_sec=0.2,
4965 start_delay_sec=1) 4922 start_delay_sec=1)
4966 _verify_image_checksum_and_status( 4923 with requests.get(image_data_uri) as r:
4967 checksum='bcd65f8922f61a9e6a20572ad7aa2bdd', 4924 expect_c = six.text_type(hashlib.md5(r.content).hexdigest())
4968 status='active') 4925 expect_h = six.text_type(hashlib.sha512(r.content).hexdigest())
4969 4926 func_utils.verify_image_hashes_and_status(self,
4927 image_id,
4928 checksum=expect_c,
4929 os_hash_value=expect_h,
4930 status='active')
4970 # Ensure image is created in default backend 4931 # Ensure image is created in default backend
4971 path = self._url('/v2/images/%s' % image_id) 4932 path = self._url('/v2/images/%s' % image_id)
4972 response = requests.get(path, headers=self._headers()) 4933 response = requests.get(path, headers=self._headers())
@@ -5084,18 +5045,9 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
5084 self.assertEqual(1, len(images)) 5045 self.assertEqual(1, len(images))
5085 self.assertEqual(image_id, images[0]['id']) 5046 self.assertEqual(image_id, images[0]['id'])
5086 5047
5087 def _verify_image_checksum_and_status(checksum=None, status=None):
5088 # Checksum should be populated and status should be active
5089 path = self._url('/v2/images/%s' % image_id)
5090 response = requests.get(path, headers=self._headers())
5091 self.assertEqual(http.OK, response.status_code)
5092 image = jsonutils.loads(response.text)
5093 self.assertEqual(checksum, image['checksum'])
5094 self.assertEqual(status, image['status'])
5095
5096 # Verify image is in queued state and checksum is None 5048 # Verify image is in queued state and checksum is None
5097 _verify_image_checksum_and_status(status='queued') 5049 func_utils.verify_image_hashes_and_status(self, image_id,
5098 5050 status='queued')
5099 # Import image to store 5051 # Import image to store
5100 path = self._url('/v2/images/%s/import' % image_id) 5052 path = self._url('/v2/images/%s/import' % image_id)
5101 headers = self._headers({ 5053 headers = self._headers({
@@ -5103,10 +5055,11 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
5103 'X-Roles': 'admin', 5055 'X-Roles': 'admin',
5104 'X-Image-Meta-Store': 'file2' 5056 'X-Image-Meta-Store': 'file2'
5105 }) 5057 })
5058 image_data_uri = ('https://www.openstack.org/assets/openstack-logo/'
5059 '2016R/OpenStack-Logo-Horizontal.eps.zip')
5106 data = jsonutils.dumps({'method': { 5060 data = jsonutils.dumps({'method': {
5107 'name': 'web-download', 5061 'name': 'web-download',
5108 'uri': 'https://www.openstack.org/assets/openstack-logo/' 5062 'uri': image_data_uri
5109 '2016R/OpenStack-Logo-Horizontal.eps.zip'
5110 }}) 5063 }})
5111 response = requests.post(path, headers=headers, data=data) 5064 response = requests.post(path, headers=headers, data=data)
5112 self.assertEqual(http.ACCEPTED, response.status_code) 5065 self.assertEqual(http.ACCEPTED, response.status_code)
@@ -5121,10 +5074,14 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
5121 max_sec=20, 5074 max_sec=20,
5122 delay_sec=0.2, 5075 delay_sec=0.2,
5123 start_delay_sec=1) 5076 start_delay_sec=1)
5124 _verify_image_checksum_and_status( 5077 with requests.get(image_data_uri) as r:
5125 checksum='bcd65f8922f61a9e6a20572ad7aa2bdd', 5078 expect_c = six.text_type(hashlib.md5(r.content).hexdigest())
5126 status='active') 5079 expect_h = six.text_type(hashlib.sha512(r.content).hexdigest())
5127 5080 func_utils.verify_image_hashes_and_status(self,
5081 image_id,
5082 checksum=expect_c,
5083 os_hash_value=expect_h,
5084 status='active')
5128 # Ensure image is created in different backend 5085 # Ensure image is created in different backend
5129 path = self._url('/v2/images/%s' % image_id) 5086 path = self._url('/v2/images/%s' % image_id)
5130 response = requests.get(path, headers=self._headers()) 5087 response = requests.get(path, headers=self._headers())
@@ -5243,23 +5200,20 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
5243 response = requests.get(path, headers=headers) 5200 response = requests.get(path, headers=headers)
5244 self.assertEqual(http.NO_CONTENT, response.status_code) 5201 self.assertEqual(http.NO_CONTENT, response.status_code)
5245 5202
5246 def _verify_image_checksum_and_status(checksum, status):
5247 # Checksum should be populated and status should be active
5248 path = self._url('/v2/images/%s' % image_id)
5249 response = requests.get(path, headers=self._headers())
5250 self.assertEqual(http.OK, response.status_code)
5251 image = jsonutils.loads(response.text)
5252 self.assertEqual(checksum, image['checksum'])
5253 self.assertEqual(status, image['status'])
5254
5255 # Upload some image data 5203 # Upload some image data
5204 image_data = b'OpenStack Rules, Other Clouds Drool'
5256 path = self._url('/v2/images/%s/file' % image_id) 5205 path = self._url('/v2/images/%s/file' % image_id)
5257 headers = self._headers({'Content-Type': 'application/octet-stream'}) 5206 headers = self._headers({'Content-Type': 'application/octet-stream'})
5258 response = requests.put(path, headers=headers, data='ZZZZZ') 5207 response = requests.put(path, headers=headers, data=image_data)
5259 self.assertEqual(http.NO_CONTENT, response.status_code) 5208 self.assertEqual(http.NO_CONTENT, response.status_code)
5260 5209
5261 expected_checksum = '8f113e38d28a79a5a451b16048cc2b72' 5210 expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
5262 _verify_image_checksum_and_status(expected_checksum, 'active') 5211 expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
5212 func_utils.verify_image_hashes_and_status(self,
5213 image_id,
5214 checksum=expect_c,
5215 os_hash_value=expect_h,
5216 status='active')
5263 5217
5264 # Ensure image is created in default backend 5218 # Ensure image is created in default backend
5265 path = self._url('/v2/images/%s' % image_id) 5219 path = self._url('/v2/images/%s' % image_id)
@@ -5271,14 +5225,15 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
5271 path = self._url('/v2/images/%s/file' % image_id) 5225 path = self._url('/v2/images/%s/file' % image_id)
5272 response = requests.get(path, headers=self._headers()) 5226 response = requests.get(path, headers=self._headers())
5273 self.assertEqual(http.OK, response.status_code) 5227 self.assertEqual(http.OK, response.status_code)
5274 self.assertEqual(expected_checksum, response.headers['Content-MD5']) 5228 self.assertEqual(expect_c, response.headers['Content-MD5'])
5275 self.assertEqual('ZZZZZ', response.text) 5229 self.assertEqual(image_data.decode('utf-8'), response.text)
5276 5230
5277 # Ensure the size is updated to reflect the data uploaded 5231 # Ensure the size is updated to reflect the data uploaded
5278 path = self._url('/v2/images/%s' % image_id) 5232 path = self._url('/v2/images/%s' % image_id)
5279 response = requests.get(path, headers=self._headers()) 5233 response = requests.get(path, headers=self._headers())
5280 self.assertEqual(http.OK, response.status_code) 5234 self.assertEqual(http.OK, response.status_code)
5281 self.assertEqual(5, jsonutils.loads(response.text)['size']) 5235 self.assertEqual(len(image_data),
5236 jsonutils.loads(response.text)['size'])
5282 5237
5283 # Unprotect image for deletion 5238 # Unprotect image for deletion
5284 path = self._url('/v2/images/%s' % image_id) 5239 path = self._url('/v2/images/%s' % image_id)
@@ -5413,26 +5368,23 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
5413 response = requests.get(path, headers=headers) 5368 response = requests.get(path, headers=headers)
5414 self.assertEqual(http.NO_CONTENT, response.status_code) 5369 self.assertEqual(http.NO_CONTENT, response.status_code)
5415 5370
5416 def _verify_image_checksum_and_status(checksum, status):
5417 # Checksum should be populated and status should be active
5418 path = self._url('/v2/images/%s' % image_id)
5419 response = requests.get(path, headers=self._headers())
5420 self.assertEqual(http.OK, response.status_code)
5421 image = jsonutils.loads(response.text)
5422 self.assertEqual(checksum, image['checksum'])
5423 self.assertEqual(status, image['status'])
5424
5425 # Upload some image data 5371 # Upload some image data
5372 image_data = b'just a passing glance'
5426 path = self._url('/v2/images/%s/file' % image_id) 5373 path = self._url('/v2/images/%s/file' % image_id)
5427 headers = self._headers({ 5374 headers = self._headers({
5428 'Content-Type': 'application/octet-stream', 5375 'Content-Type': 'application/octet-stream',
5429 'X-Image-Meta-Store': 'file2' 5376 'X-Image-Meta-Store': 'file2'
5430 }) 5377 })
5431 response = requests.put(path, headers=headers, data='ZZZZZ') 5378 response = requests.put(path, headers=headers, data=image_data)
5432 self.assertEqual(http.NO_CONTENT, response.status_code) 5379 self.assertEqual(http.NO_CONTENT, response.status_code)
5433 5380
5434 expected_checksum = '8f113e38d28a79a5a451b16048cc2b72' 5381 expect_c = six.text_type(hashlib.md5(image_data).hexdigest())
5435 _verify_image_checksum_and_status(expected_checksum, 'active') 5382 expect_h = six.text_type(hashlib.sha512(image_data).hexdigest())
5383 func_utils.verify_image_hashes_and_status(self,
5384 image_id,
5385 checksum=expect_c,
5386 os_hash_value=expect_h,
5387 status='active')
5436 5388
5437 # Ensure image is created in different backend 5389 # Ensure image is created in different backend
5438 path = self._url('/v2/images/%s' % image_id) 5390 path = self._url('/v2/images/%s' % image_id)
@@ -5444,14 +5396,15 @@ class TestImagesMultipleBackend(functional.MultipleBackendFunctionalTest):
5444 path = self._url('/v2/images/%s/file' % image_id) 5396 path = self._url('/v2/images/%s/file' % image_id)
5445 response = requests.get(path, headers=self._headers()) 5397 response = requests.get(path, headers=self._headers())
5446 self.assertEqual(http.OK, response.status_code) 5398 self.assertEqual(http.OK, response.status_code)
5447 self.assertEqual(expected_checksum, response.headers['Content-MD5']) 5399 self.assertEqual(expect_c, response.headers['Content-MD5'])
5448 self.assertEqual('ZZZZZ', response.text) 5400 self.assertEqual(image_data.decode('utf-8'), response.text)
5449 5401
5450 # Ensure the size is updated to reflect the data uploaded 5402 # Ensure the size is updated to reflect the data uploaded
5451 path = self._url('/v2/images/%s' % image_id) 5403 path = self._url('/v2/images/%s' % image_id)
5452 response = requests.get(path, headers=self._headers()) 5404 response = requests.get(path, headers=self._headers())
5453 self.assertEqual(http.OK, response.status_code) 5405 self.assertEqual(http.OK, response.status_code)
5454 self.assertEqual(5, jsonutils.loads(response.text)['size']) 5406 self.assertEqual(len(image_data),
5407 jsonutils.loads(response.text)['size'])
5455 5408
5456 # Unprotect image for deletion 5409 # Unprotect image for deletion
5457 path = self._url('/v2/images/%s' % image_id) 5410 path = self._url('/v2/images/%s' % image_id)