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

feat: add support for return-X-after-YK of downloaded data #274

Closed
wants to merge 4 commits into from

Conversation

cojenco
Copy link
Contributor

@cojenco cojenco commented Feb 2, 2022

Fixes #273

As part of the GCS client library retry alignment project, this adds support in the Retry Test API to return-X-after-YK of downloaded data.

I've noted a TODO entry to introduce a Retry Test API method "storage.objects.download" to further support complex download test cases for larger files.

  • Tests pass
  • Appropriate changes to README are included in PR

@codecov
Copy link

codecov bot commented Feb 2, 2022

Codecov Report

Merging #274 (32a26cf) into main (9a145b0) will increase coverage by 0.01%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #274      +/-   ##
==========================================
+ Coverage   97.61%   97.63%   +0.01%     
==========================================
  Files          48       48              
  Lines        7582     7643      +61     
==========================================
+ Hits         7401     7462      +61     
  Misses        181      181              
Flag Coverage Δ
unittests 97.63% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
testbench/common.py 98.71% <100.00%> (+0.06%) ⬆️
tests/test_testbench_retry.py 99.47% <100.00%> (+0.05%) ⬆️
testbench/grpc_server.py 100.00% <0.00%> (ø)
tests/test_grpc_server.py 99.84% <0.00%> (+<0.01%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9a145b0...32a26cf. Read the comment docs.

@cojenco cojenco marked this pull request as ready for review February 2, 2022 23:25
@cojenco cojenco requested review from coryan and a team as code owners February 2, 2022 23:25
@cojenco cojenco requested review from tritone and frankyn February 2, 2022 23:25
Copy link
Contributor

@coryan coryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few nits. The TODO entry I care about, the stuff about file names and KiB vs. KB vs. kb is just trivia.

I do wonder if this is going to work as you expect outside of unit tests.

@@ -242,7 +242,7 @@ curl -H "x-retry-test-id: 1d05c20627844214a9ff7cbcf696317d" "http://localhost:91
| Failure Id | Description
| ----------------------- | ---
| return-X | Testbench will fail with HTTP code provided for `X`, e.g. return-503 returns a 503
| return-X-after-YK | Testbench will return X after YKiB of uploaded data
| return-broken-stream-final-chunk-after-YB | Testbench will break connection on final chunk of a resumable upload after Y bytes.
| return-X-after-YK | Testbench will return X after YKiB of uploaded or downloaded data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: return-X-after-YK cannot really work for a download... the error code is returned at the beginning, after the headers but before the payload. Any client will receive a 200 if the download starts successfully.

Copy link
Contributor Author

@cojenco cojenco Feb 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I did not think of the fact that the error code is returned before the payload. So return-X-after-YK is unrealistic to happen for downloads in the live server...

I think it "works" here merely because I forcefully trigger the streamer first before returning the response (L694)

# Inject fault outside of the streamer considering execution flow and werkzeug wrappers
try:
    response = flask.Response(streamer())
    _ = response.data
    return response
except testbench.error.RestException as e:
    raise e

Thus it "works" when I test it against the python retry conformance test, like so

127.0.0.1 - - [02/Feb/2022:16:50:50 -0800] "GET /download/storage/v1/b/aef6bb4577734e59b6f41c5cdfe501fa/o/4678f04722e54979845541c381a5025e?alt=media HTTP/1.1" 504 97 "-" "python-requests/2.27.1"
127.0.0.1 - - [02/Feb/2022:16:50:51 -0800] "GET /download/storage/v1/b/aef6bb4577734e59b6f41c5cdfe501fa/o/4678f04722e54979845541c381a5025e?alt=media HTTP/1.1" 200 1100000 "-" "python-requests/2.27.1"

I will probably close this FR since it does not match live server behavior, unless we decide it is helpful for testing purposes. Will look into #173 as that seems more realistic. Thanks for the feedback!

if bytes_downloaded >= limit:
database.dequeue_next_instruction(test_id, method)
raise testbench.error.RestException(
f"Retry Test: Caused a {error_code}. Fault injected after downloading {bytes_downloaded} bytes",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a large buffer, and probably only when using a real TCP/IP connection, the error code here has no effect on the client-side, just FYI.

@@ -752,6 +783,14 @@ def handle_retry_test_instruction(database, request, method):
grpc_code=StatusCode.INTERNAL, # not really used
context=None,
)
# TODO(cathyo@): introduce Retry Test API method "storage.objects.download" for large file downloads
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use a GitHub issue numbers to track TODO items, in case you win the lottery and or leave us for greener pa$ture$

# Use the XML API to inject a larger object and smaller object.
media = self._create_block(UPLOAD_QUANTUM)
blob_larger = self.client.put(
"/bucket-name/256kb.txt",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: some inconsistency between the filename with kb (Kilobits) and the generated block (256KiB).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support return-X-after-YK for downloads
2 participants