From c025336a7a78dce57a8485292d5502b41bbfe8eb Mon Sep 17 00:00:00 2001 From: Luciano Pacheco Date: Tue, 21 Mar 2017 18:23:56 +1100 Subject: [PATCH 1/2] Fixes #3150 - Ignores resource key when it isn't present --- storage/google/cloud/storage/blob.py | 6 +++++- storage/unit_tests/test_blob.py | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/storage/google/cloud/storage/blob.py b/storage/google/cloud/storage/blob.py index 3ed778bde062..a55a74763f27 100644 --- a/storage/google/cloud/storage/blob.py +++ b/storage/google/cloud/storage/blob.py @@ -868,9 +868,13 @@ def rewrite(self, source, token=None, client=None): method='POST', path=source.path + '/rewriteTo' + self.path, query_params=query_params, data=self._properties, headers=headers, _target_object=self) - self._set_properties(api_response['resource']) rewritten = int(api_response['totalBytesRewritten']) size = int(api_response['objectSize']) + try: + self._set_properties(api_response['resource']) + except KeyError: + # API might not return resource key + pass if api_response['done']: return None, rewritten, size diff --git a/storage/unit_tests/test_blob.py b/storage/unit_tests/test_blob.py index d0de26ef3bbc..45bfc901ee32 100644 --- a/storage/unit_tests/test_blob.py +++ b/storage/unit_tests/test_blob.py @@ -1288,6 +1288,33 @@ def test_compose_w_additional_property_changes(self): self.assertEqual(kw[0]['path'], '/b/name/o/%s/compose' % DESTINATION) self.assertEqual(kw[0]['data'], SENT) + def test_rewrite_response_without_resource(self): + from six.moves.http_client import OK + + SOURCE_BLOB = 'source' + DEST_BLOB = 'dest' + DEST_BUCKET = 'other-bucket' + TOKEN = 'TOKEN' + RESPONSE = { + 'totalBytesRewritten': 33, + 'objectSize': 42, + 'done': False, + 'rewriteToken': TOKEN, + } + response = ({'status': OK}, RESPONSE) + connection = _Connection(response) + client = _Client(connection) + source_bucket = _Bucket(client=client) + source_blob = self._make_one(SOURCE_BLOB, bucket=source_bucket) + dest_bucket = _Bucket(client=client, name=DEST_BUCKET) + dest_blob = self._make_one(DEST_BLOB, bucket=dest_bucket) + + token, rewritten, size = dest_blob.rewrite(source_blob) + + self.assertEqual(token, TOKEN) + self.assertEqual(rewritten, 33) + self.assertEqual(size, 42) + def test_rewrite_other_bucket_other_name_no_encryption_partial(self): from six.moves.http_client import OK From 63f35a21a44f396c8ce1d548f847525b0cc913e5 Mon Sep 17 00:00:00 2001 From: Luke Sneeringer Date: Tue, 21 Mar 2017 08:07:34 -0700 Subject: [PATCH 2/2] Move setting the resource property into the done if block. --- storage/google/cloud/storage/blob.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/storage/google/cloud/storage/blob.py b/storage/google/cloud/storage/blob.py index a55a74763f27..c99555277e95 100644 --- a/storage/google/cloud/storage/blob.py +++ b/storage/google/cloud/storage/blob.py @@ -870,13 +870,12 @@ def rewrite(self, source, token=None, client=None): _target_object=self) rewritten = int(api_response['totalBytesRewritten']) size = int(api_response['objectSize']) - try: - self._set_properties(api_response['resource']) - except KeyError: - # API might not return resource key - pass + # The resource key is set if and only if the API response is + # completely done. Additionally, there is no rewrite token to return + # in this case. if api_response['done']: + self._set_properties(api_response['resource']) return None, rewritten, size return api_response['rewriteToken'], rewritten, size