From c19a9cd60099556f7824435a2028f24d6261d22f Mon Sep 17 00:00:00 2001 From: HemangChothani Date: Thu, 14 May 2020 19:05:18 +0530 Subject: [PATCH 1/3] fix(storage): add projection parameter to blob.reload method --- google/cloud/storage/_helpers.py | 11 +++++++---- tests/unit/test__helpers.py | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/google/cloud/storage/_helpers.py b/google/cloud/storage/_helpers.py index b649384f7..af9fb5bd6 100644 --- a/google/cloud/storage/_helpers.py +++ b/google/cloud/storage/_helpers.py @@ -121,11 +121,16 @@ def _query_params(self): params["userProject"] = self.user_project return params - def reload(self, client=None, timeout=_DEFAULT_TIMEOUT): + def reload(self, projection="noAcl", client=None, timeout=_DEFAULT_TIMEOUT): """Reload properties from Cloud Storage. If :attr:`user_project` is set, bills the API request to that project. + :type projection: str + :param projection: (Optional) If used, must be 'full' or 'noAcl'. + Defaults to ``'noAcl'``. Specifies the set of + properties to return. + :type client: :class:`~google.cloud.storage.client.Client` or ``NoneType`` :param client: the client to use. If not passed, falls back to the @@ -139,9 +144,7 @@ def reload(self, client=None, timeout=_DEFAULT_TIMEOUT): """ client = self._require_client(client) query_params = self._query_params - # Pass only '?projection=noAcl' here because 'acl' and related - # are handled via custom endpoints. - query_params["projection"] = "noAcl" + query_params["projection"] = projection api_response = client._connection.api_request( method="GET", path=self.path, diff --git a/tests/unit/test__helpers.py b/tests/unit/test__helpers.py index 10b71b7bc..bb0933ab2 100644 --- a/tests/unit/test__helpers.py +++ b/tests/unit/test__helpers.py @@ -151,6 +151,30 @@ def test_reload_w_user_project(self): ) self.assertEqual(derived._changes, set()) + def test_reload_w_projection(self): + connection = _Connection({"foo": "Foo"}) + client = _Client(connection) + derived = self._derivedClass("/path")() + # Make sure changes is not a set instance before calling reload + # (which will clear / replace it with an empty set), checked below. + derived._changes = object() + derived.reload(projection="full", client=client, timeout=42) + self.assertEqual(derived._properties, {"foo": "Foo"}) + kw = connection._requested + self.assertEqual(len(kw), 1) + self.assertEqual( + kw[0], + { + "method": "GET", + "path": "/path", + "query_params": {"projection": "full"}, + "headers": {}, + "_target_object": derived, + "timeout": 42, + }, + ) + self.assertEqual(derived._changes, set()) + def test__set_properties(self): mixin = self._make_one() self.assertEqual(mixin._properties, {}) From b3166ba9f456a73aee519191ae379f086899f452 Mon Sep 17 00:00:00 2001 From: HemangChothani Date: Fri, 15 May 2020 14:05:42 +0530 Subject: [PATCH 2/3] fix(storage): add system test --- tests/system/test_system.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/system/test_system.py b/tests/system/test_system.py index 82f0cb98b..06bbb5b0f 100644 --- a/tests/system/test_system.py +++ b/tests/system/test_system.py @@ -737,6 +737,18 @@ def test_resumable_upload_with_generation_match(self): with open(file_data["path"], "rb") as file_obj: blob.upload_from_file(file_obj, if_metageneration_match=3) + def test_upload_blob_owner(self): + blob = self.bucket.blob("MyBuffer") + file_contents = b"Hello World" + blob.upload_from_string(file_contents) + self.case_blobs_to_delete.append(blob) + + same_blob = self.bucket.blob("MyBuffer") + same_blob.reload(projection="full") # Initialize properties. + user_email = Config.CLIENT._credentials.service_account_email + owner = same_blob.owner + self.assertIn(user_email, owner["entity"]) + class TestUnicode(unittest.TestCase): @vpcsc_config.skip_if_inside_vpcsc From 5f940e2db4917ff2317d480ef9d91b88704deb7b Mon Sep 17 00:00:00 2001 From: HemangChothani Date: Fri, 15 May 2020 19:17:21 +0530 Subject: [PATCH 3/3] fix(storage): nit --- google/cloud/storage/_helpers.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/google/cloud/storage/_helpers.py b/google/cloud/storage/_helpers.py index f482cef71..f8d3bddfd 100644 --- a/google/cloud/storage/_helpers.py +++ b/google/cloud/storage/_helpers.py @@ -135,8 +135,8 @@ def _query_params(self): def reload( self, - projection="noAcl", client=None, + projection="noAcl", timeout=_DEFAULT_TIMEOUT, if_generation_match=None, if_generation_not_match=None, @@ -147,16 +147,16 @@ def reload( If :attr:`user_project` is set, bills the API request to that project. - :type projection: str - :param projection: (Optional) If used, must be 'full' or 'noAcl'. - Defaults to ``'noAcl'``. Specifies the set of - properties to return. - :type client: :class:`~google.cloud.storage.client.Client` or ``NoneType`` :param client: the client to use. If not passed, falls back to the ``client`` stored on the current object. + :type projection: str + :param projection: (Optional) If used, must be 'full' or 'noAcl'. + Defaults to ``'noAcl'``. Specifies the set of + properties to return. + :type timeout: float or tuple :param timeout: (Optional) The amount of time, in seconds, to wait for the server response.