| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 4e91c54 commit ddce7e5
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -688,6 +688,13 @@ def _prepare_request(self): | |||
| 688 | 688 | _CONTENT_TYPE_HEADER: self._content_type, | |
| 689 | 689 | _helpers.CONTENT_RANGE_HEADER: content_range, | |
| 690 | 690 | } | |
| 691 | + if (start_byte + len(payload) == self._total_bytes) and ( | ||
| 692 | + self._checksum_object is not None | ||
| 693 | + ): | ||
| 694 | + local_checksum = _helpers.prepare_checksum_digest( | ||
| 695 | + self._checksum_object.digest() | ||
| 696 | + ) | ||
| 697 | + headers["x-goog-hash"] = f"{self._checksum_type}={local_checksum}" | ||
| 691 | 698 | return _PUT, self.resumable_url, payload, headers | |
| 692 | 699 | ||
| 693 | 700 | def _update_checksum(self, start_byte, payload): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27,7 +27,6 @@ | |||
| 27 | 27 | import google.cloud.storage._media.requests as resumable_requests | |
| 28 | 28 | from google.cloud.storage._media import _helpers | |
| 29 | 29 | from .. import utils | |
| 30 | - from google.cloud.storage._media import _upload | ||
| 31 | 30 | from google.cloud.storage.exceptions import InvalidResponse | |
| 32 | 31 | from google.cloud.storage.exceptions import DataCorruption | |
| 33 | 32 | ||
@@ -372,29 +371,6 @@ def test_resumable_upload_with_headers( | |||
| 372 | 371 | _resumable_upload_helper(authorized_transport, img_stream, cleanup, headers=headers) | |
| 373 | 372 | ||
| 374 | 373 | ||
| 375 | - @pytest.mark.parametrize("checksum", ["md5", "crc32c"]) | ||
| 376 | - def test_resumable_upload_with_bad_checksum( | ||
| 377 | - authorized_transport, img_stream, bucket, cleanup, checksum | ||
| 378 | - ): | ||
| 379 | - fake_checksum_object = _helpers._get_checksum_object(checksum) | ||
| 380 | - fake_checksum_object.update(b"bad data") | ||
| 381 | - fake_prepared_checksum_digest = _helpers.prepare_checksum_digest( | ||
| 382 | - fake_checksum_object.digest() | ||
| 383 | - ) | ||
| 384 | - with mock.patch.object( | ||
| 385 | - _helpers, "prepare_checksum_digest", return_value=fake_prepared_checksum_digest | ||
| 386 | - ): | ||
| 387 | - with pytest.raises(DataCorruption) as exc_info: | ||
| 388 | - _resumable_upload_helper( | ||
| 389 | - authorized_transport, img_stream, cleanup, checksum=checksum | ||
| 390 | - ) | ||
| 391 | - expected_checksums = {"md5": "1bsd83IYNug8hd+V1ING3Q==", "crc32c": "YQGPxA=="} | ||
| 392 | - expected_message = _upload._UPLOAD_CHECKSUM_MISMATCH_MESSAGE.format( | ||
| 393 | - checksum.upper(), fake_prepared_checksum_digest, expected_checksums[checksum] | ||
| 394 | - ) | ||
| 395 | - assert exc_info.value.args[0] == expected_message | ||
| 396 | - | ||
| 397 | - | ||
| 398 | 374 | def test_resumable_upload_bad_chunk_size(authorized_transport, img_stream): | |
| 399 | 375 | blob_name = os.path.basename(img_stream.name) | |
| 400 | 376 | # Create the actual upload object. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3049,15 +3049,22 @@ def test__initiate_resumable_upload_with_client_custom_headers(self): | |||
| 3049 | 3049 | self._initiate_resumable_helper(client=client) | |
| 3050 | 3050 | ||
| 3051 | 3051 | def _make_resumable_transport( | |
| 3052 | - self, headers1, headers2, headers3, total_bytes, data_corruption=False | ||
| 3052 | + self, | ||
| 3053 | + headers1, | ||
| 3054 | + headers2, | ||
| 3055 | + headers3, | ||
| 3056 | + total_bytes, | ||
| 3057 | + data_corruption=False, | ||
| 3058 | + md5_checksum_value=None, | ||
| 3059 | + crc32c_checksum_value=None, | ||
| 3053 | 3060 | ): | |
| 3054 | 3061 | fake_transport = mock.Mock(spec=["request"]) | |
| 3055 | 3062 | ||
| 3056 | 3063 | fake_response1 = self._mock_requests_response(http.client.OK, headers1) | |
| 3057 | 3064 | fake_response2 = self._mock_requests_response( | |
| 3058 | 3065 | http.client.PERMANENT_REDIRECT, headers2 | |
| 3059 | 3066 | ) | |
| 3060 | - json_body = f'{{"size": "{total_bytes:d}"}}' | ||
| 3067 | + json_body = json.dumps({"size": str(total_bytes), "md5Hash": md5_checksum_value, "crc32c": crc32c_checksum_value}) | ||
| 3061 | 3068 | if data_corruption: | |
| 3062 | 3069 | fake_response3 = DataCorruption(None) | |
| 3063 | 3070 | else: | |
@@ -3151,6 +3158,9 @@ def _do_resumable_upload_call2( | |||
| 3151 | 3158 | if_metageneration_match=None, | |
| 3152 | 3159 | if_metageneration_not_match=None, | |
| 3153 | 3160 | timeout=None, | |
| 3161 | + checksum=None, | ||
| 3162 | + crc32c_checksum_value=None, | ||
| 3163 | + md5_checksum_value=None, | ||
| 3154 | 3164 | ): | |
| 3155 | 3165 | # Third mock transport.request() does sends last chunk. | |
| 3156 | 3166 | content_range = f"bytes {blob.chunk_size:d}-{total_bytes - 1:d}/{total_bytes:d}" | |
@@ -3161,6 +3171,11 @@ def _do_resumable_upload_call2( | |||
| 3161 | 3171 | "content-type": content_type, | |
| 3162 | 3172 | "content-range": content_range, | |
| 3163 | 3173 | } | |
| 3174 | + if checksum == "crc32c": | ||
| 3175 | + expected_headers["x-goog-hash"] = f"crc32c={crc32c_checksum_value}" | ||
| 3176 | + elif checksum == "md5": | ||
| 3177 | + expected_headers["x-goog-hash"] = f"md5={md5_checksum_value}" | ||
| 3178 | + | ||
| 3164 | 3179 | payload = data[blob.chunk_size :] | |
| 3165 | 3180 | return mock.call( | |
| 3166 | 3181 | "PUT", | |
@@ -3181,12 +3196,17 @@ def _do_resumable_helper( | |||
| 3181 | 3196 | timeout=None, | |
| 3182 | 3197 | data_corruption=False, | |
| 3183 | 3198 | retry=None, | |
| 3199 | + checksum=None, # None is also a valid value, when user decides to disable checksum validation. | ||
| 3184 | 3200 | ): | |
| 3185 | 3201 | CHUNK_SIZE = 256 * 1024 | |
| 3186 | 3202 | USER_AGENT = "testing 1.2.3" | |
| 3187 | 3203 | content_type = "text/html" | |
| 3188 | 3204 | # Data to be uploaded. | |
| 3189 | 3205 | data = b"<html>" + (b"A" * CHUNK_SIZE) + b"</html>" | |
| 3206 | + | ||
| 3207 | + # Data calcuated offline and entered here. (Unit test best practice). | ||
| 3208 | + crc32c_checksum_value = "mQ30hg==" | ||
| 3209 | + md5_checksum_value = "wajHeg1f2Q2u9afI6fjPOw==" | ||
| 3190 | 3210 | total_bytes = len(data) | |
| 3191 | 3211 | if use_size: | |
| 3192 | 3212 | size = total_bytes | |
@@ -3213,6 +3233,8 @@ def _do_resumable_helper( | |||
| 3213 | 3233 | headers3, | |
| 3214 | 3234 | total_bytes, | |
| 3215 | 3235 | data_corruption=data_corruption, | |
| 3236 | + md5_checksum_value=md5_checksum_value, | ||
| 3237 | + crc32c_checksum_value=crc32c_checksum_value, | ||
| 3216 | 3238 | ) | |
| 3217 | 3239 | ||
| 3218 | 3240 | # Create some mock arguments and call the method under test. | |
@@ -3247,7 +3269,7 @@ def _do_resumable_helper( | |||
| 3247 | 3269 | if_generation_not_match, | |
| 3248 | 3270 | if_metageneration_match, | |
| 3249 | 3271 | if_metageneration_not_match, | |
| 3250 | - checksum=None, | ||
| 3272 | + checksum=checksum, | ||
| 3251 | 3273 | retry=retry, | |
| 3252 | 3274 | **timeout_kwarg, | |
| 3253 | 3275 | ) | |
@@ -3296,6 +3318,9 @@ def _do_resumable_helper( | |||
| 3296 | 3318 | if_metageneration_match=if_metageneration_match, | |
| 3297 | 3319 | if_metageneration_not_match=if_metageneration_not_match, | |
| 3298 | 3320 | timeout=expected_timeout, | |
| 3321 | + checksum=checksum, | ||
| 3322 | + crc32c_checksum_value=crc32c_checksum_value, | ||
| 3323 | + md5_checksum_value=md5_checksum_value, | ||
| 3299 | 3324 | ) | |
| 3300 | 3325 | self.assertEqual(transport.request.mock_calls, [call0, call1, call2]) | |
| 3301 | 3326 | ||
@@ -3308,6 +3333,12 @@ def test__do_resumable_upload_no_size(self): | |||
| 3308 | 3333 | def test__do_resumable_upload_with_size(self): | |
| 3309 | 3334 | self._do_resumable_helper(use_size=True) | |
| 3310 | 3335 | ||
| 3336 | + def test__do_resumable_upload_with_size_with_crc32c_checksum(self): | ||
| 3337 | + self._do_resumable_helper(use_size=True, checksum="crc32c") | ||
| 3338 | + | ||
| 3339 | + def test__do_resumable_upload_with_size_with_md5_checksum(self): | ||
| 3340 | + self._do_resumable_helper(use_size=True, checksum="md5") | ||
| 3341 | + | ||
| 3311 | 3342 | def test__do_resumable_upload_with_retry(self): | |
| 3312 | 3343 | self._do_resumable_helper(retry=DEFAULT_RETRY) | |
| 3313 | 3344 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments