Skip to content
This repository was archived by the owner on Mar 6, 2026. It is now read-only.

Commit 7d889ad

Browse files
committed
Dropping usage of "size" to measure (resumable) bytes uploaded.
1 parent a6d815d commit 7d889ad

4 files changed

Lines changed: 40 additions & 23 deletions

File tree

google/resumable_media/_upload.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ def _make_invalid(self):
548548
"""
549549
self._invalid = True
550550

551-
def _process_response(self, response):
551+
def _process_response(self, response, bytes_sent):
552552
"""Process the response from an HTTP request.
553553
554554
This is everything that must be done after a request that doesn't
@@ -557,6 +557,8 @@ def _process_response(self, response):
557557
558558
Args:
559559
response (object): The HTTP response object.
560+
bytes_sent (int): The number of bytes sent in the request that
561+
``response`` was returned for.
560562
561563
Raises:
562564
~google.resumable_media.common.InvalidResponse: If the status
@@ -571,9 +573,15 @@ def _process_response(self, response):
571573
response, (http_client.OK, resumable_media.PERMANENT_REDIRECT),
572574
self._get_status_code, callback=self._make_invalid)
573575
if status_code == http_client.OK:
574-
body = self._get_body(response)
575-
json_response = json.loads(body.decode(u'utf-8'))
576-
self._bytes_uploaded = int(json_response[u'size'])
576+
# NOTE: We use the "local" information of ``bytes_sent`` to update
577+
# ``bytes_uploaded``, but do not verify this against other
578+
# state. However, there may be some other information:
579+
#
580+
# * a ``size`` key in JSON response body
581+
# * the ``total_bytes`` attribute (if set)
582+
# * ``stream.tell()`` (relying on fact that ``initiate()``
583+
# requires stream to be at the beginning)
584+
self._bytes_uploaded = self._bytes_uploaded + bytes_sent
577585
# Tombstone the current upload so it cannot be used again.
578586
self._finished = True
579587
else:

google/resumable_media/requests/upload.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ def transmit_next_chunk(self, transport):
393393
result = _helpers.http_request(
394394
transport, method, url, data=payload, headers=headers,
395395
retry_strategy=self._retry_strategy)
396-
self._process_response(result)
396+
self._process_response(result, len(payload))
397397
return result
398398

399399
def recover(self, transport):

nox.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,14 @@ def unit_tests(session, python_version):
4242
line_coverage = '--cov-fail-under=99'
4343
session.run(
4444
'py.test',
45-
'--cov=google.resumable_media', '--cov=tests.unit', '--cov-append',
46-
'--cov-config=.coveragerc', '--cov-report=', line_coverage,
45+
'--cov=google.resumable_media',
46+
'--cov=tests.unit',
47+
'--cov-append',
48+
'--cov-config=.coveragerc',
49+
'--cov-report=',
50+
line_coverage,
4751
os.path.join('tests', 'unit'),
52+
*session.posargs
4853
)
4954

5055

@@ -102,7 +107,8 @@ def lint(session):
102107
session.run(
103108
'flake8',
104109
os.path.join('google', 'resumable_media'),
105-
'tests')
110+
'tests',
111+
)
106112

107113

108114
@nox.session
@@ -140,7 +146,11 @@ def system_tests(session, python_version):
140146
session.install('-e', '.')
141147

142148
# Run py.test against the system tests.
143-
session.run('py.test', os.path.join('tests', 'system'))
149+
session.run(
150+
'py.test',
151+
os.path.join('tests', 'system'),
152+
*session.posargs
153+
)
144154

145155

146156
@nox.session

tests/unit/test__upload.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ def test__process_response_bad_status(self):
557557
assert not upload.invalid
558558
response = _make_response(status_code=http_client.NOT_FOUND)
559559
with pytest.raises(common.InvalidResponse) as exc_info:
560-
upload._process_response(response)
560+
upload._process_response(response, None)
561561

562562
error = exc_info.value
563563
assert error.response is response
@@ -572,16 +572,20 @@ def test__process_response_success(self):
572572
upload = _upload.ResumableUpload(RESUMABLE_URL, ONE_MB)
573573
_fix_up_virtual(upload)
574574

575-
total_bytes = 158
576-
response_body = u'{{"size": "{:d}"}}'.format(total_bytes)
577-
response_body = response_body.encode(u'utf-8')
578-
# Check status before.
575+
# Check / set status before.
579576
assert upload._bytes_uploaded == 0
577+
upload._bytes_uploaded = 20
580578
assert not upload._finished
579+
580+
# Set the response body.
581+
bytes_sent = 158
582+
total_bytes = upload._bytes_uploaded + bytes_sent
583+
response_body = u'{{"size": "{:d}"}}'.format(total_bytes)
584+
response_body = response_body.encode(u'utf-8')
581585
response = mock.Mock(
582586
content=response_body, status_code=http_client.OK,
583587
spec=[u'content', u'status_code'])
584-
ret_val = upload._process_response(response)
588+
ret_val = upload._process_response(response, bytes_sent)
585589
assert ret_val is None
586590
# Check status after.
587591
assert upload._bytes_uploaded == total_bytes
@@ -596,7 +600,7 @@ def test__process_response_partial_no_range(self):
596600
# Make sure the upload is valid before the failure.
597601
assert not upload.invalid
598602
with pytest.raises(common.InvalidResponse) as exc_info:
599-
upload._process_response(response)
603+
upload._process_response(response, None)
600604
# Make sure the upload is invalid after the failure.
601605
assert upload.invalid
602606

@@ -616,7 +620,7 @@ def test__process_response_partial_bad_range(self):
616620
response = _make_response(
617621
status_code=resumable_media.PERMANENT_REDIRECT, headers=headers)
618622
with pytest.raises(common.InvalidResponse) as exc_info:
619-
upload._process_response(response)
623+
upload._process_response(response, 81)
620624

621625
# Check the error response.
622626
error = exc_info.value
@@ -635,7 +639,7 @@ def test__process_response_partial(self):
635639
headers = {u'range': u'bytes=0-171'}
636640
response = _make_response(
637641
status_code=resumable_media.PERMANENT_REDIRECT, headers=headers)
638-
ret_val = upload._process_response(response)
642+
ret_val = upload._process_response(response, 172)
639643
assert ret_val is None
640644
# Check status after.
641645
assert upload._bytes_uploaded == 172
@@ -932,14 +936,9 @@ def _get_headers(response):
932936
return response.headers
933937

934938

935-
def _get_body(response):
936-
return response.content
937-
938-
939939
def _fix_up_virtual(upload):
940940
upload._get_status_code = _get_status_code
941941
upload._get_headers = _get_headers
942-
upload._get_body = _get_body
943942

944943

945944
def _check_retry_strategy(upload):

0 commit comments

Comments
 (0)