Skip to content

Commit d5b12ab

Browse files
committed
see if it's reproducing the issue
1 parent 4a072cc commit d5b12ab

File tree

9 files changed

+61
-30
lines changed

9 files changed

+61
-30
lines changed

include/aws/s3/private/s3_client_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ struct aws_s3_client_vtable {
175175
struct aws_http_connection *client_connection,
176176
const struct aws_http_make_request_options *options);
177177

178-
void (*after_prepare_upload_part_finish)(struct aws_s3_request *request);
178+
void (*after_prepare_upload_part_finish)(struct aws_s3_request *request, struct aws_http_message *message);
179179
};
180180

181181
struct aws_s3_upload_part_timeout_stats {

include/aws/s3/s3_client.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ struct aws_s3_meta_request_options {
884884
* Optional.
885885
* Callback for reviewing an upload before it completes.
886886
* WARNING: experimental/unstable
887-
* See `aws_s3_upload_review_fn`
887+
* See `aws_s3_meta_request_upload_review_fn`
888888
*/
889889
aws_s3_meta_request_upload_review_fn *upload_review_callback;
890890

source/s3_auto_ranged_put.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,15 +1184,15 @@ static void s_s3_prepare_upload_part_finish(struct aws_s3_prepare_upload_part_jo
11841184
aws_future_http_message_set_error(part_prep->on_complete, aws_last_error());
11851185
goto on_done;
11861186
}
1187+
if (client->vtable->after_prepare_upload_part_finish) {
1188+
/* TEST ONLY, allow test to stub here. */
1189+
client->vtable->after_prepare_upload_part_finish(request, message);
1190+
}
11871191

11881192
/* Success! */
11891193
aws_future_http_message_set_result_by_move(part_prep->on_complete, &message);
11901194

11911195
on_done:
1192-
if (client->vtable->after_prepare_upload_part_finish) {
1193-
/* TEST ONLY, allow test to stub here. */
1194-
client->vtable->after_prepare_upload_part_finish(request);
1195-
}
11961196
AWS_FATAL_ASSERT(aws_future_http_message_is_done(part_prep->on_complete));
11971197
aws_future_bool_release(part_prep->asyncstep_read_part);
11981198
aws_future_http_message_release(part_prep->on_complete);

source/s3_checksum_stream.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ static void s_aws_input_checksum_stream_destroy(struct aws_checksum_stream *impl
113113
}
114114

115115
/* Compute the checksum of whatever was read, if we didn't reach the end of the underlying stream. */
116-
// s_finalize_checksum(impl);
116+
s_finalize_checksum(impl);
117117

118118
aws_checksum_destroy(impl->checksum);
119119
aws_input_stream_release(impl->old_stream);

source/s3_chunk_stream.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ static void s_aws_input_chunk_stream_destroy(struct aws_chunk_stream *impl) {
167167
}
168168
aws_byte_buf_clean_up(&impl->pre_chunk_buffer);
169169
aws_byte_buf_clean_up(&impl->post_chunk_buffer);
170+
/* Either we calculated the checksum, or we the checksum is empty. Otherwise, something was wrong. */
171+
AWS_ASSERT(impl->checksum_context->checksum_calculated || impl->checksum_context->base64_checksum.len == 0);
170172
aws_s3_upload_request_checksum_context_release(impl->checksum_context);
171173
aws_mem_release(impl->allocator, impl);
172174
}

tests/mock_s3_server/mock_s3_server.py

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
# Flags to keep between requests
2424
SHOULD_THROTTLE = True
25-
SHOULD_SKIP_WAIT = True
2625
RETRY_REQUEST_COUNT = 0
2726

2827

@@ -55,16 +54,37 @@ class ResponseConfig:
5554
disconnect_after_headers = False
5655
generate_body_size: Optional[int] = None
5756
json_path: str = None
58-
throttle: bool = False
57+
forced_throttle: bool = False
5958
force_retry: bool = False
59+
should_skip_wait = False
6060
request_headers: Optional[List[Tuple[bytes, bytes]]] = None
6161

62+
def __init__(self, path, request=None):
63+
self.path = path
64+
self.request_headers = request.headers
65+
self.json_path = None
66+
self.generate_body_size = None
67+
self.disconnect_after_headers = False
68+
self.forced_throttle = False
69+
self.force_retry = False
70+
self.should_skip_wait = False
71+
72+
if get_request_header_value(request, "before_finish") is not None:
73+
self.should_skip_wait = True
74+
if get_request_header_value(request, "force_throttle") is not None:
75+
self.forced_throttle = True
76+
6277
def _resolve_file_path(self, wrapper, request_type):
6378
global SHOULD_THROTTLE
6479
if self.json_path is None:
80+
if self.forced_throttle:
81+
# force the throttle to happend, instead of just 50%.
82+
response_file = os.path.join(
83+
base_dir, request_type.name, f"throttle.json")
84+
self.json_path = response_file
85+
return
6586
response_file = os.path.join(
6687
base_dir, request_type.name, f"{self.path[1:]}.json")
67-
print(response_file)
6888
if os.path.exists(response_file) == False:
6989
wrapper.info(
7090
response_file, "not exist, using the default response")
@@ -77,7 +97,6 @@ def _resolve_file_path(self, wrapper, request_type):
7797
response_file = os.path.join(
7898
base_dir, request_type.name, f"default.json")
7999
else:
80-
print("throttle")
81100
wrapper.info("Throttling")
82101
# Flip the flag
83102
SHOULD_THROTTLE = not SHOULD_THROTTLE
@@ -483,27 +502,21 @@ async def handle_mock_s3_request(wrapper, request):
483502
# TODO: support more type.
484503
wrapper.info("unsupported request:", request)
485504
request_type = S3Opts.CreateMultipartUpload
486-
global SHOULD_SKIP_WAIT
487-
if "before_finish" not in parsed_path.path or request_type is not S3Opts.UploadPart:
488-
# restore the state
489-
SHOULD_SKIP_WAIT = True
490-
if "before_finish" in parsed_path.path and SHOULD_SKIP_WAIT and request_type is S3Opts.UploadPart:
491-
print("not wait for the request to complete")
492-
SHOULD_SKIP_WAIT = False
493-
else:
505+
506+
if response_config is None:
507+
response_config = ResponseConfig(parsed_path.path, request)
508+
509+
if not response_config.should_skip_wait:
494510
while True:
495511
event = await wrapper.next_event()
496512
if type(event) is h11.EndOfMessage:
497513
break
498514
assert type(event) is h11.Data
499-
500-
if response_config is None:
501-
response_config = ResponseConfig(parsed_path.path)
502-
response_config.request_headers = request.headers
515+
else:
516+
print("Skipping waiting for request body")
503517

504518
response = response_config.resolve_response(
505519
wrapper, request_type, head_request=method == "HEAD")
506-
507520
await send_response(wrapper, response)
508521

509522

tests/s3_mock_server_tests.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -435,13 +435,31 @@ TEST_CASE(multipart_upload_with_network_interface_names_mock_server) {
435435
}
436436

437437
/* Total hack to flip the bytes. */
438-
static void s_after_prepare_upload_part_finish(struct aws_s3_request *request) {
438+
static void s_after_prepare_upload_part_finish(struct aws_s3_request *request, struct aws_http_message *message) {
439+
(void)message;
439440
if (request->num_times_prepared > 1) {
440441
/* mock that the body buffer was messed up in memory */
441442
request->request_body.buffer[1]++;
442443
}
443444
}
444445

446+
static void s_after_prepare_upload_part_finish_retry_before_finish_sending(
447+
struct aws_s3_request *request,
448+
struct aws_http_message *message) {
449+
if (request->num_times_prepared == 0 && message != NULL) {
450+
struct aws_http_header before_finish_header = {
451+
.name = aws_byte_cursor_from_c_str("before_finish"),
452+
.value = aws_byte_cursor_from_c_str("true"),
453+
};
454+
aws_http_message_add_header(message, before_finish_header);
455+
struct aws_http_header throttle_header = {
456+
.name = aws_byte_cursor_from_c_str("force_throttle"),
457+
.value = aws_byte_cursor_from_c_str("true"),
458+
};
459+
aws_http_message_add_header(message, throttle_header);
460+
}
461+
}
462+
445463
/**
446464
* This test is built for
447465
* 1. The retry happens before the upload has finished.
@@ -458,9 +476,10 @@ TEST_CASE(multipart_upload_checksum_with_retry_before_finish_mock_server) {
458476
struct aws_s3_client *client = NULL;
459477
ASSERT_SUCCESS(aws_s3_tester_client_new(&tester, &client_options, &client));
460478
struct aws_s3_client_vtable *patched_client_vtable = aws_s3_tester_patch_client_vtable(&tester, client, NULL);
461-
patched_client_vtable->after_prepare_upload_part_finish = s_after_prepare_upload_part_finish;
479+
patched_client_vtable->after_prepare_upload_part_finish =
480+
s_after_prepare_upload_part_finish_retry_before_finish_sending;
462481

463-
struct aws_byte_cursor object_path = aws_byte_cursor_from_c_str("/throttle_before_finish");
482+
struct aws_byte_cursor object_path = aws_byte_cursor_from_c_str("/throttle");
464483
{
465484
/* 1. Trailer checksum */
466485
struct aws_s3_tester_meta_request_options put_options = {
@@ -473,7 +492,6 @@ TEST_CASE(multipart_upload_checksum_with_retry_before_finish_mock_server) {
473492
{
474493
.object_size_mb = 10,
475494
.object_path_override = object_path,
476-
.sleep_before_read_secs = 1,
477495
},
478496
.mock_server = true,
479497
};

tests/s3_tester.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1681,7 +1681,6 @@ int aws_s3_tester_send_meta_request_with_options(
16811681
.autogen_length = upload_size_bytes,
16821682
.eof_requires_extra_read = options->put_options.eof_requires_extra_read,
16831683
.max_bytes_per_read = options->put_options.max_bytes_per_read,
1684-
.sleep_before_read_secs = options->put_options.sleep_before_read_secs,
16851684
},
16861685
};
16871686
if (options->put_options.invalid_input_stream) {

tests/s3_tester.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ struct aws_s3_tester_meta_request_options {
229229
struct aws_byte_cursor content_encoding;
230230
enum aws_s3_tester_full_object_checksum full_object_checksum;
231231
struct aws_byte_cursor if_none_match_header;
232-
size_t sleep_before_read_secs;
233232
} put_options;
234233

235234
enum aws_s3_tester_sse_type sse_type;

0 commit comments

Comments
 (0)