Skip to content

Commit 2cb0892

Browse files
authored
tests: add retry conf s7 resumable upload test cases (#720)
* tests: add retry conf s7 resumable upload test cases * adjust fixture and chunk size from design discussion
1 parent c7bf615 commit 2cb0892

File tree

3 files changed

+86
-13
lines changed

3 files changed

+86
-13
lines changed

tests/conformance/conftest.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import os
16+
import random
1617
import uuid
1718

1819
import pytest
@@ -33,16 +34,21 @@
3334
)
3435
_CONF_TEST_PUBSUB_TOPIC_NAME = "my-topic-name"
3536

37+
3638
"""Create content payload in different sizes."""
3739

3840

3941
def _create_block(desired_kib):
40-
line = "abc123XYZ" * 14 + "!" + "\n"
41-
return 1024 * int(desired_kib / len(line)) * line
42+
line = "abcdefXYZ123456789ADDINGrandom#" # len(line) = 31
43+
multiplier = int(desired_kib / (len(line) + 1))
44+
lines = "".join(
45+
line + str(random.randint(0, 9)) for _ in range(multiplier)
46+
) # add random single digit integers
47+
return 1024 * lines
4248

4349

4450
_STRING_CONTENT = "hello world"
45-
_SIZE_16MB = 16384 # 16*1024 KiB
51+
_SIZE_9MB = 9216 # 9*1024 KiB
4652

4753

4854
########################################################################################################################################
@@ -115,7 +121,7 @@ def hmac_key(client):
115121
@pytest.fixture
116122
def file_data(client, bucket):
117123
blob = client.bucket(bucket.name).blob(uuid.uuid4().hex)
118-
payload = _create_block(_SIZE_16MB)
124+
payload = _create_block(_SIZE_9MB)
119125
blob.upload_from_string(payload)
120126
yield blob, payload
121127
try:

tests/conformance/retry_strategy_test_data.json

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,20 @@
243243
{
244244
"id": 7,
245245
"description": "resumable_uploads_handle_complex_retries",
246-
"cases": [],
247-
"methods": [],
246+
"cases": [
247+
{
248+
"instructions": ["return-reset-connection", "return-503"]
249+
},
250+
{
251+
"instructions": ["return-503-after-256K"]
252+
},
253+
{
254+
"instructions": ["return-503-after-8192K"]
255+
}
256+
],
257+
"methods": [
258+
{"name": "storage.objects.insert", "group": "storage.resumable.upload", "resources": ["BUCKET"]}
259+
],
248260
"preconditionProvided": true,
249261
"expectSuccess": true
250262
},

tests/conformance/test_conformance.py

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454

5555
_STRING_CONTENT = "hello world"
5656
_BYTE_CONTENT = b"12345678"
57+
_RESUMABLE_UPLOAD_CHUNK_SIZE = 2 * 1024 * 1024
5758

5859

5960
########################################################################################################################################
@@ -461,7 +462,7 @@ def blob_upload_from_string(client, _preconditions, **resources):
461462
bucket = resources.get("bucket")
462463
_, data = resources.get("file_data")
463464
blob = client.bucket(bucket.name).blob(uuid.uuid4().hex)
464-
blob.chunk_size = 4 * 1024 * 1024
465+
blob.chunk_size = _RESUMABLE_UPLOAD_CHUNK_SIZE
465466
if _preconditions:
466467
blob.upload_from_string(data, if_generation_match=0)
467468
else:
@@ -471,26 +472,67 @@ def blob_upload_from_string(client, _preconditions, **resources):
471472

472473
def blob_upload_from_file(client, _preconditions, **resources):
473474
bucket = resources.get("bucket")
474-
blob = client.bucket(bucket.name).blob(uuid.uuid4().hex)
475+
file, data = resources.get("file_data")
476+
file_blob = client.bucket(bucket.name).blob(file.name)
477+
upload_blob = client.bucket(bucket.name).blob(uuid.uuid4().hex)
478+
upload_blob.chunk_size = _RESUMABLE_UPLOAD_CHUNK_SIZE
479+
475480
with tempfile.NamedTemporaryFile() as temp_f:
481+
# Create a named temporary file with payload.
482+
with open(temp_f.name, "wb") as file_obj:
483+
client.download_blob_to_file(file_blob, file_obj)
484+
# Upload the temporary file and assert data integrity.
476485
if _preconditions:
477-
blob.upload_from_file(temp_f, if_generation_match=0)
486+
upload_blob.upload_from_file(temp_f, if_generation_match=0)
478487
else:
479-
blob.upload_from_file(temp_f)
488+
upload_blob.upload_from_file(temp_f)
489+
490+
upload_blob.reload()
491+
assert upload_blob.size == len(data)
480492

481493

482494
def blob_upload_from_filename(client, _preconditions, **resources):
483495
bucket = resources.get("bucket")
484496
blob = client.bucket(bucket.name).blob(uuid.uuid4().hex)
497+
blob.chunk_size = _RESUMABLE_UPLOAD_CHUNK_SIZE
498+
499+
bucket = resources.get("bucket")
500+
file, data = resources.get("file_data")
501+
file_blob = client.bucket(bucket.name).blob(file.name)
502+
upload_blob = client.bucket(bucket.name).blob(uuid.uuid4().hex)
503+
upload_blob.chunk_size = _RESUMABLE_UPLOAD_CHUNK_SIZE
485504

486505
with tempfile.NamedTemporaryFile() as temp_f:
506+
# Create a named temporary file with payload.
507+
with open(temp_f.name, "wb") as file_obj:
508+
client.download_blob_to_file(file_blob, file_obj)
509+
# Upload the temporary file and assert data integrity.
487510
if _preconditions:
488-
blob.upload_from_filename(temp_f.name, if_generation_match=0)
511+
upload_blob.upload_from_filename(temp_f.name, if_generation_match=0)
489512
else:
490-
blob.upload_from_filename(temp_f.name)
513+
upload_blob.upload_from_filename(temp_f.name)
514+
515+
upload_blob.reload()
516+
assert upload_blob.size == len(data)
491517

492518

493519
def blobwriter_write(client, _preconditions, **resources):
520+
bucket = resources.get("bucket")
521+
_, data = resources.get("file_data")
522+
blob = client.bucket(bucket.name).blob(uuid.uuid4().hex)
523+
if _preconditions:
524+
with blob.open(
525+
"w", chunk_size=_RESUMABLE_UPLOAD_CHUNK_SIZE, if_generation_match=0
526+
) as writer:
527+
writer.write(data)
528+
else:
529+
with blob.open("w", chunk_size=_RESUMABLE_UPLOAD_CHUNK_SIZE) as writer:
530+
writer.write(data)
531+
blob.reload()
532+
assert blob.size == len(data)
533+
534+
535+
def blobwriter_write_multipart(client, _preconditions, **resources):
494536
chunk_size = 256 * 1024
495537
bucket = resources.get("bucket")
496538
blob = client.bucket(bucket.name).blob(uuid.uuid4().hex)
@@ -502,6 +544,15 @@ def blobwriter_write(client, _preconditions, **resources):
502544
writer.write(_BYTE_CONTENT)
503545

504546

547+
def blob_upload_from_string_multipart(client, _preconditions, **resources):
548+
bucket = resources.get("bucket")
549+
blob = client.bucket(bucket.name).blob(uuid.uuid4().hex)
550+
if _preconditions:
551+
blob.upload_from_string(_STRING_CONTENT, if_generation_match=0)
552+
else:
553+
blob.upload_from_string(_STRING_CONTENT)
554+
555+
505556
def blob_create_resumable_upload_session(client, _preconditions, **resources):
506557
bucket = resources.get("bucket")
507558
blob = client.bucket(bucket.name).blob(uuid.uuid4().hex)
@@ -745,11 +796,15 @@ def object_acl_clear(client, _preconditions, **resources):
745796
bucket_rename_blob,
746797
],
747798
"storage.objects.insert": [
799+
blob_upload_from_string_multipart,
800+
blobwriter_write_multipart,
801+
blob_create_resumable_upload_session,
802+
],
803+
"storage.resumable.upload": [
748804
blob_upload_from_string,
749805
blob_upload_from_file,
750806
blob_upload_from_filename,
751807
blobwriter_write,
752-
blob_create_resumable_upload_session,
753808
],
754809
"storage.objects.patch": [
755810
blob_patch,

0 commit comments

Comments
 (0)