Skip to content

Commit 3eadf8a

Browse files
committed
try to fix the flaky test
1 parent cbcc4e5 commit 3eadf8a

File tree

7 files changed

+74
-22
lines changed

7 files changed

+74
-22
lines changed

include/aws/s3/private/s3_client_impl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ struct aws_s3_client_vtable {
178178
struct aws_http_connection *client_connection,
179179
const struct aws_http_make_request_options *options);
180180

181-
void (*after_prepare_upload_part_finish)(struct aws_s3_request *request, struct aws_http_message *message);
181+
/********************* TEST ONLY STUB **************************/
182+
void (*after_prepare_upload_part_finish_stub)(struct aws_s3_request *request, struct aws_http_message *message);
182183
};
183184

184185
struct aws_s3_upload_part_timeout_stats {

include/aws/s3/private/s3_meta_request_impl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ struct aws_s3_meta_request_vtable {
122122

123123
/* Pause the given request */
124124
int (*pause)(struct aws_s3_meta_request *meta_request, struct aws_s3_meta_request_resume_token **resume_token);
125+
126+
/********************* TEST ONLY STUB **************************/
127+
/* A stub to the update implementation from meta request with the lock held. Only for tests. */
128+
bool (*synced_update_stub)(struct aws_s3_meta_request *meta_request);
125129
};
126130

127131
/**

source/s3_auto_ranged_get.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,11 @@ static bool s_s3_auto_ranged_get_update(
202202
/* BEGIN CRITICAL SECTION */
203203
{
204204
aws_s3_meta_request_lock_synced_data(meta_request);
205+
if (meta_request->vtable->synced_update_stub && meta_request->vtable->synced_update_stub(meta_request)) {
206+
/* TEST ONLY, allow test to stub here. */
207+
aws_s3_meta_request_unlock_synced_data(meta_request);
208+
return true;
209+
}
205210

206211
/* If nothing has set the "finish result" then this meta request is still in progress, and we can potentially
207212
* send additional requests. */

source/s3_auto_ranged_put.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,11 @@ static bool s_s3_auto_ranged_put_update(
486486
/* BEGIN CRITICAL SECTION */
487487
{
488488
aws_s3_meta_request_lock_synced_data(meta_request);
489+
if (meta_request->vtable->synced_update_stub && meta_request->vtable->synced_update_stub(meta_request)) {
490+
/* TEST ONLY, allow test to stub here. */
491+
aws_s3_meta_request_unlock_synced_data(meta_request);
492+
return true;
493+
}
489494

490495
if (!aws_s3_meta_request_has_finish_result_synced(meta_request)) {
491496
/* If resuming and list part has not been sent, do it now. */
@@ -1248,9 +1253,9 @@ static void s_s3_prepare_upload_part_finish(struct aws_s3_prepare_upload_part_jo
12481253
aws_future_http_message_set_error(part_prep->on_complete, aws_last_error());
12491254
goto on_done;
12501255
}
1251-
if (client->vtable->after_prepare_upload_part_finish) {
1256+
if (client->vtable->after_prepare_upload_part_finish_stub) {
12521257
/* TEST ONLY, allow test to stub here. */
1253-
client->vtable->after_prepare_upload_part_finish(request, message);
1258+
client->vtable->after_prepare_upload_part_finish_stub(request, message);
12541259
}
12551260

12561261
/* Success! */
@@ -1779,6 +1784,8 @@ static void s_s3_auto_ranged_put_request_finished(
17791784
aws_s3_meta_request_unlock_synced_data(meta_request);
17801785
}
17811786

1787+
/* NOTES: the implementation has been copy/pasted to `s_pause_meta_request_synced` for testing purpose, if changed made
1788+
* here, please update the other function correspondingly. */
17821789
static int s_s3_auto_ranged_put_pause(
17831790
struct aws_s3_meta_request *meta_request,
17841791
struct aws_s3_meta_request_resume_token **out_resume_token) {

source/s3_default_meta_request.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,11 @@ static bool s_s3_meta_request_default_update(
160160
/* BEGIN CRITICAL SECTION */
161161
{
162162
aws_s3_meta_request_lock_synced_data(meta_request);
163-
163+
if (meta_request->vtable->synced_update_stub && meta_request->vtable->synced_update_stub(meta_request)) {
164+
/* TEST ONLY, allow test to stub here. */
165+
aws_s3_meta_request_unlock_synced_data(meta_request);
166+
return true;
167+
}
164168
if (!aws_s3_meta_request_has_finish_result_synced(meta_request)) {
165169

166170
/* If the request hasn't been sent, then create and send it now. */

tests/s3_cancel_tests.c

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,48 @@ struct s3_cancel_test_user_data {
4040
bool abort_successful;
4141
};
4242

43-
static bool s_s3_meta_request_update_cancel_test(
43+
/* TODO: this is an unfortunately copy/paste from `s_s3_auto_ranged_put_pause`, we need to hold the lock to invoke the
44+
* pause for the test to avoid the checks changed after checking it and used afterward. In between move the
45+
* synced_section from s_s3_auto_ranged_put_pause to a function that can be used here and copy/paste it here. I picked
46+
* copy/paste it to avoid exposing a weird test only function to our API. */
47+
static void s_pause_meta_request_synced(
4448
struct aws_s3_meta_request *meta_request,
45-
uint32_t flags,
46-
struct aws_s3_request **out_request) {
49+
struct aws_s3_meta_request_resume_token **out_resume_token) {
50+
51+
struct aws_s3_auto_ranged_put *auto_ranged_put = meta_request->impl;
52+
/* upload can be in one of several states:
53+
* - not started, i.e. we didn't even call crete mpu yet - return success,
54+
* token is NULL and cancel the upload
55+
* - in the middle of upload - return success, create token and cancel
56+
* upload
57+
* - complete MPU started - return success, generate token and try to cancel
58+
* complete MPU
59+
*/
60+
if (auto_ranged_put->synced_data.create_multipart_upload_completed) {
61+
62+
*out_resume_token = aws_s3_meta_request_resume_token_new(meta_request->allocator);
63+
64+
(*out_resume_token)->type = AWS_S3_META_REQUEST_TYPE_PUT_OBJECT;
65+
(*out_resume_token)->multipart_upload_id =
66+
aws_string_clone_or_reuse(meta_request->allocator, auto_ranged_put->upload_id);
67+
(*out_resume_token)->part_size = meta_request->part_size;
68+
(*out_resume_token)->total_num_parts = auto_ranged_put->total_num_parts_from_content_length;
69+
(*out_resume_token)->num_parts_completed = auto_ranged_put->synced_data.num_parts_completed;
70+
}
71+
72+
/**
73+
* Cancels the meta request using the PAUSED flag to avoid deletion of uploaded parts.
74+
* This allows the client to resume the upload later, setting the persistable state in the meta request options.
75+
*/
76+
aws_s3_meta_request_set_fail_synced(meta_request, NULL, AWS_ERROR_S3_PAUSED);
77+
78+
aws_s3_meta_request_cancel_cancellable_requests_synced(meta_request, AWS_ERROR_S3_PAUSED);
79+
aws_s3_meta_request_cancel_pending_buffer_futures_synced(meta_request, AWS_ERROR_S3_PAUSED);
80+
}
81+
82+
static bool s_s3_meta_request_cancel_test_synced_update_stub(struct aws_s3_meta_request *meta_request) {
4783
AWS_PRECONDITION(meta_request);
48-
AWS_PRECONDITION(out_request);
84+
ASSERT_SYNCED_DATA_LOCK_HELD(meta_request);
4985

5086
struct aws_s3_meta_request_test_results *results = meta_request->user_data;
5187
struct aws_s3_tester *tester = results->tester;
@@ -57,8 +93,6 @@ static bool s_s3_meta_request_update_cancel_test(
5793
bool call_cancel_or_pause = false;
5894
bool block_update = false;
5995

60-
aws_s3_meta_request_lock_synced_data(meta_request);
61-
6296
switch (cancel_test_user_data->type) {
6397
case S3_UPDATE_CANCEL_TYPE_NO_CANCEL:
6498
break;
@@ -131,23 +165,20 @@ static bool s_s3_meta_request_update_cancel_test(
131165
break;
132166
}
133167

134-
aws_s3_meta_request_unlock_synced_data(meta_request);
135168
if (call_cancel_or_pause) {
136169
if (cancel_test_user_data->pause) {
137-
aws_s3_meta_request_pause(meta_request, &cancel_test_user_data->resume_token);
170+
s_pause_meta_request_synced(meta_request, &cancel_test_user_data->resume_token);
138171
} else {
139-
aws_s3_meta_request_cancel(meta_request);
172+
aws_s3_meta_request_set_fail_synced(meta_request, NULL, AWS_ERROR_S3_CANCELED);
173+
aws_s3_meta_request_cancel_cancellable_requests_synced(meta_request, AWS_ERROR_S3_CANCELED);
174+
aws_s3_meta_request_cancel_pending_buffer_futures_synced(meta_request, AWS_ERROR_S3_CANCELED);
140175
}
141176
}
142177

143178
if (block_update) {
144179
return true;
145180
}
146-
147-
struct aws_s3_meta_request_vtable *original_meta_request_vtable =
148-
aws_s3_tester_get_meta_request_vtable_patch(tester, 0)->original_vtable;
149-
150-
return original_meta_request_vtable->update(meta_request, flags, out_request);
181+
return false;
151182
}
152183

153184
static void s_s3_meta_request_finished_request_cancel_test(
@@ -188,7 +219,7 @@ static struct aws_s3_meta_request *s_meta_request_factory_patch_update_cancel_te
188219

189220
struct aws_s3_meta_request_vtable *patched_meta_request_vtable =
190221
aws_s3_tester_patch_meta_request_vtable(tester, meta_request, NULL);
191-
patched_meta_request_vtable->update = s_s3_meta_request_update_cancel_test;
222+
patched_meta_request_vtable->synced_update_stub = s_s3_meta_request_cancel_test_synced_update_stub;
192223
patched_meta_request_vtable->finished_request = s_s3_meta_request_finished_request_cancel_test;
193224

194225
return meta_request;

tests/s3_mock_server_tests.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ TEST_CASE(multipart_upload_checksum_with_retry_before_finish_mock_server) {
487487
struct aws_s3_client *client = NULL;
488488
ASSERT_SUCCESS(aws_s3_tester_client_new(&tester, &client_options, &client));
489489
struct aws_s3_client_vtable *patched_client_vtable = aws_s3_tester_patch_client_vtable(&tester, client, NULL);
490-
patched_client_vtable->after_prepare_upload_part_finish =
490+
patched_client_vtable->after_prepare_upload_part_finish_stub =
491491
s_after_prepare_upload_part_finish_retry_before_finish_sending;
492492

493493
struct aws_byte_cursor object_path = aws_byte_cursor_from_c_str("/default");
@@ -547,7 +547,7 @@ TEST_CASE(multipart_upload_checksum_with_retry_mock_server) {
547547
struct aws_s3_client *client = NULL;
548548
ASSERT_SUCCESS(aws_s3_tester_client_new(&tester, &client_options, &client));
549549
struct aws_s3_client_vtable *patched_client_vtable = aws_s3_tester_patch_client_vtable(&tester, client, NULL);
550-
patched_client_vtable->after_prepare_upload_part_finish = s_after_prepare_upload_part_finish;
550+
patched_client_vtable->after_prepare_upload_part_finish_stub = s_after_prepare_upload_part_finish;
551551

552552
struct aws_byte_cursor object_path = aws_byte_cursor_from_c_str("/default");
553553
{
@@ -629,7 +629,7 @@ TEST_CASE(multipart_upload_checksum_fio_with_retry_mock_server) {
629629
struct aws_s3_client *client = NULL;
630630
ASSERT_SUCCESS(aws_s3_tester_client_new(&tester, &client_options, &client));
631631
struct aws_s3_client_vtable *patched_client_vtable = aws_s3_tester_patch_client_vtable(&tester, client, NULL);
632-
patched_client_vtable->after_prepare_upload_part_finish =
632+
patched_client_vtable->after_prepare_upload_part_finish_stub =
633633
s_after_prepare_upload_part_finish_retry_before_finish_sending;
634634
struct aws_s3_file_io_options fio_opts = {
635635
.should_stream = true,

0 commit comments

Comments
 (0)