Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: from_string method of blob and bucket class #290

Merged
merged 7 commits into from Nov 11, 2020
6 changes: 4 additions & 2 deletions google/cloud/storage/blob.py
Expand Up @@ -1607,12 +1607,13 @@ def _do_multipart_upload(
msg = _READ_LESS_THAN_SIZE.format(size, len(data))
raise ValueError(msg)

client = self._require_client(client)
transport = self._get_transport(client)
info = self._get_upload_arguments(content_type)
headers, object_metadata, content_type = info

base_url = _MULTIPART_URL_TEMPLATE.format(
hostname=self.client._connection.API_BASE_URL, bucket_path=self.bucket.path
hostname=client._connection.API_BASE_URL, bucket_path=self.bucket.path
)
name_value_pairs = []

Expand Down Expand Up @@ -1769,6 +1770,7 @@ def _initiate_resumable_upload(
that was created
* The ``transport`` used to initiate the upload.
"""
client = self._require_client(client)
if chunk_size is None:
chunk_size = self.chunk_size
if chunk_size is None:
Expand All @@ -1781,7 +1783,7 @@ def _initiate_resumable_upload(
headers.update(extra_headers)

base_url = _RESUMABLE_URL_TEMPLATE.format(
hostname=self.client._connection.API_BASE_URL, bucket_path=self.bucket.path
hostname=client._connection.API_BASE_URL, bucket_path=self.bucket.path
)
name_value_pairs = []

Expand Down
2 changes: 1 addition & 1 deletion google/cloud/storage/client.py
Expand Up @@ -581,7 +581,7 @@ def download_blob_to_file(self, blob_or_uri, file_obj, start=None, end=None):
try:
blob_or_uri.download_to_file(file_obj, client=self, start=start, end=end)
except AttributeError:
blob = Blob.from_string(blob_or_uri)
blob = Blob.from_string(blob_or_uri, self)
blob.download_to_file(file_obj, client=self, start=start, end=end)

def list_blobs(
Expand Down
52 changes: 37 additions & 15 deletions tests/unit/test_blob.py
Expand Up @@ -1818,6 +1818,7 @@ def _mock_transport(self, status_code, headers, content=b""):
def _do_multipart_success(
self,
mock_get_boundary,
client=None,
size=None,
num_retries=None,
user_project=None,
Expand All @@ -1835,12 +1836,13 @@ def _do_multipart_success(
blob = self._make_one(u"blob-name", bucket=bucket, kms_key_name=kms_key_name)
self.assertIsNone(blob.chunk_size)

# Create mocks to be checked for doing transport.
transport = self._mock_transport(http_client.OK, {})

# Create some mock arguments.
client = mock.Mock(_http=transport, _connection=_Connection, spec=["_http"])
client._connection.API_BASE_URL = "https://storage.googleapis.com"
if not client:
# Create mocks to be checked for doing transport.
transport = self._mock_transport(http_client.OK, {})

client = mock.Mock(_http=transport, _connection=_Connection, spec=["_http"])
client._connection.API_BASE_URL = "https://storage.googleapis.com"
data = b"data here hear hier"
stream = io.BytesIO(data)
content_type = u"application/xml"
Expand All @@ -1867,7 +1869,7 @@ def _do_multipart_success(
)

# Check the mocks and the returned value.
self.assertIs(response, transport.request.return_value)
self.assertIs(response, client._http.request.return_value)
if size is None:
data_read = data
self.assertEqual(stream.tell(), len(data))
Expand Down Expand Up @@ -1916,7 +1918,7 @@ def _do_multipart_success(
+ b"\r\n--==0==--"
)
headers = {"content-type": b'multipart/related; boundary="==0=="'}
transport.request.assert_called_once_with(
client._http.request.assert_called_once_with(
"POST", upload_url, data=payload, headers=headers, timeout=expected_timeout
)

Expand Down Expand Up @@ -1974,6 +1976,13 @@ def test__do_multipart_upload_with_generation_not_match(self, mock_get_boundary)
mock_get_boundary, if_generation_not_match=4, if_metageneration_not_match=4
)

@mock.patch(u"google.resumable_media._upload.get_boundary", return_value=b"==0==")
def test__do_multipart_upload_with_client(self, mock_get_boundary):
transport = self._mock_transport(http_client.OK, {})
client = mock.Mock(_http=transport, _connection=_Connection, spec=["_http"])
client._connection.API_BASE_URL = "https://storage.googleapis.com"
self._do_multipart_success(mock_get_boundary, client=client)

def test__do_multipart_upload_bad_size(self):
blob = self._make_one(u"blob-name", bucket=None)

Expand All @@ -1993,6 +2002,7 @@ def test__do_multipart_upload_bad_size(self):

def _initiate_resumable_helper(
self,
client=None,
size=None,
extra_headers=None,
chunk_size=None,
Expand Down Expand Up @@ -2025,14 +2035,17 @@ def _initiate_resumable_helper(
object_metadata = blob._get_writable_metadata()
blob._get_writable_metadata = mock.Mock(return_value=object_metadata, spec=[])

# Create mocks to be checked for doing transport.
resumable_url = "http://test.invalid?upload_id=hey-you"
response_headers = {"location": resumable_url}
transport = self._mock_transport(http_client.OK, response_headers)

# Create some mock arguments and call the method under test.
client = mock.Mock(_http=transport, _connection=_Connection, spec=[u"_http"])
client._connection.API_BASE_URL = "https://storage.googleapis.com"
if not client:
# Create mocks to be checked for doing transport.
response_headers = {"location": resumable_url}
transport = self._mock_transport(http_client.OK, response_headers)

# Create some mock arguments and call the method under test.
client = mock.Mock(
_http=transport, _connection=_Connection, spec=[u"_http"]
)
client._connection.API_BASE_URL = "https://storage.googleapis.com"
data = b"hello hallo halo hi-low"
stream = io.BytesIO(data)
content_type = u"text/plain"
Expand Down Expand Up @@ -2121,7 +2134,7 @@ def _initiate_resumable_helper(
else:
self.assertIsNone(retry_strategy.max_cumulative_retry)
self.assertEqual(retry_strategy.max_retries, num_retries)
self.assertIs(transport, transport)
self.assertIs(client._http, transport)
# Make sure we never read from the stream.
self.assertEqual(stream.tell(), 0)

Expand Down Expand Up @@ -2203,6 +2216,15 @@ def test__initiate_resumable_upload_with_generation_not_match(self):
def test__initiate_resumable_upload_with_predefined_acl(self):
self._initiate_resumable_helper(predefined_acl="private")

def test__initiate_resumable_upload_with_client(self):
resumable_url = "http://test.invalid?upload_id=hey-you"
response_headers = {"location": resumable_url}
transport = self._mock_transport(http_client.OK, response_headers)

client = mock.Mock(_http=transport, _connection=_Connection, spec=[u"_http"])
client._connection.API_BASE_URL = "https://storage.googleapis.com"
self._initiate_resumable_helper(client=client)

def _make_resumable_transport(
self, headers1, headers2, headers3, total_bytes, data_corruption=False
):
Expand Down