1 /**
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0.
4 */
5
6 #include "s3_tester.h"
7 #include "aws/s3/private/s3_auto_ranged_get.h"
8 #include "aws/s3/private/s3_client_impl.h"
9 #include "aws/s3/private/s3_meta_request_impl.h"
10 #include "aws/s3/private/s3_util.h"
11 #include <aws/auth/credentials.h>
12 #include <aws/common/system_info.h>
13 #include <aws/http/request_response.h>
14 #include <aws/io/channel_bootstrap.h>
15 #include <aws/io/event_loop.h>
16 #include <aws/io/host_resolver.h>
17 #include <aws/io/stream.h>
18 #include <aws/io/tls_channel_handler.h>
19 #include <aws/testing/aws_test_harness.h>
20 #include <inttypes.h>
21 #include <stdlib.h>
22 #include <time.h>
23
24 #if _MSC_VER
25 # pragma warning(disable : 4232) /* function pointer to dll symbol */
26 #endif
27
28 const struct aws_byte_cursor g_test_body_content_type = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("text/plain");
29 const struct aws_byte_cursor g_test_s3_region = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("us-west-2");
30 const struct aws_byte_cursor g_test_bucket_name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("aws-crt-canary-bucket");
31 const struct aws_byte_cursor g_test_public_bucket_name =
32 AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("aws-crt-test-stuff-us-west-2");
33 const struct aws_byte_cursor g_s3_path_get_object_test_1MB =
34 AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("/get_object_test_1MB.txt");
35 const struct aws_byte_cursor g_s3_sse_header = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("x-amz-server-side-encryption");
36
37 /* TODO populate these at the beginning of running tests with names that are unique to the test run. */
38 const struct aws_byte_cursor g_pre_existing_object_1MB =
39 AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("/pre-existing_object_1MB.txt");
40 const struct aws_byte_cursor g_pre_existing_object_kms_10MB =
41 AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("/pre-existing_object_kms_10MB.txt");
42 const struct aws_byte_cursor g_pre_existing_object_aes256_10MB =
43 AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("/pre-existing_object_aes256_10MB.txt");
44 const struct aws_byte_cursor g_pre_existing_empty_object =
45 AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("/pre-existing_object_empty.txt");
46
47 #ifdef BYO_CRYPTO
48 /* Under BYO_CRYPTO, this function currently needs to be defined by the user. Defining a null implementation here so
49 * that tests build, but it is not currently meant to be used by any tests. */
aws_tls_handler_protocol(struct aws_channel_handler * handler)50 struct aws_byte_buf aws_tls_handler_protocol(struct aws_channel_handler *handler) {
51 (void)handler;
52 AWS_FATAL_ASSERT(false);
53 struct aws_byte_buf byte_buf;
54 AWS_ZERO_STRUCT(byte_buf);
55 return byte_buf;
56 }
57 #endif
58
s_s3_test_meta_request_header_callback(struct aws_s3_meta_request * meta_request,const struct aws_http_headers * headers,int response_status,void * user_data)59 static int s_s3_test_meta_request_header_callback(
60 struct aws_s3_meta_request *meta_request,
61 const struct aws_http_headers *headers,
62 int response_status,
63 void *user_data) {
64 (void)meta_request;
65
66 struct aws_s3_meta_request_test_results *meta_request_test_results =
67 (struct aws_s3_meta_request_test_results *)user_data;
68
69 aws_http_headers_release(meta_request_test_results->response_headers);
70
71 meta_request_test_results->response_headers = (struct aws_http_headers *)headers;
72 aws_http_headers_acquire(meta_request_test_results->response_headers);
73
74 meta_request_test_results->headers_response_status = response_status;
75
76 if (meta_request_test_results->headers_callback != NULL) {
77 return meta_request_test_results->headers_callback(meta_request, headers, response_status, user_data);
78 }
79
80 return AWS_OP_SUCCESS;
81 }
82
s_s3_test_meta_request_body_callback(struct aws_s3_meta_request * meta_request,const struct aws_byte_cursor * body,uint64_t range_start,void * user_data)83 static int s_s3_test_meta_request_body_callback(
84 struct aws_s3_meta_request *meta_request,
85 const struct aws_byte_cursor *body,
86 uint64_t range_start,
87 void *user_data) {
88 (void)meta_request;
89 (void)body;
90 AWS_PRECONDITION(meta_request);
91 AWS_PRECONDITION(body);
92
93 struct aws_s3_meta_request_test_results *meta_request_test_results = user_data;
94 meta_request_test_results->received_body_size += body->len;
95
96 AWS_LOGF_DEBUG(
97 AWS_LS_S3_GENERAL,
98 "Received range %" PRIu64 "-%" PRIu64 ". Expected range start: %" PRIu64,
99 range_start,
100 range_start + body->len - 1,
101 meta_request_test_results->expected_range_start);
102
103 uint64_t object_range_start = 0;
104
105 /* If this is an auto-ranged-get meta request, then grab the object range start so that the expected_range_start can
106 * be properly offset.*/
107 if (meta_request->type == AWS_S3_META_REQUEST_TYPE_GET_OBJECT) {
108
109 aws_s3_meta_request_lock_synced_data(meta_request);
110
111 struct aws_s3_auto_ranged_get *auto_ranged_get = meta_request->impl;
112 AWS_PRECONDITION(auto_ranged_get);
113
114 bool object_range_known = auto_ranged_get->synced_data.object_range_known != 0;
115 object_range_start = auto_ranged_get->synced_data.object_range_start;
116
117 aws_s3_meta_request_unlock_synced_data(meta_request);
118
119 ASSERT_TRUE(object_range_known);
120 }
121
122 ASSERT_TRUE((object_range_start + meta_request_test_results->expected_range_start) == range_start);
123 meta_request_test_results->expected_range_start += body->len;
124
125 if (meta_request_test_results->body_callback != NULL) {
126 return meta_request_test_results->body_callback(meta_request, body, range_start, user_data);
127 }
128
129 return AWS_OP_SUCCESS;
130 }
131
s_s3_test_meta_request_finish(struct aws_s3_meta_request * meta_request,const struct aws_s3_meta_request_result * result,void * user_data)132 static void s_s3_test_meta_request_finish(
133 struct aws_s3_meta_request *meta_request,
134 const struct aws_s3_meta_request_result *result,
135 void *user_data) {
136 (void)meta_request;
137
138 struct aws_s3_meta_request_test_results *meta_request_test_results = user_data;
139 struct aws_s3_tester *tester = meta_request_test_results->tester;
140
141 meta_request_test_results->error_response_headers = result->error_response_headers;
142
143 if (result->error_response_headers != NULL) {
144 aws_http_headers_acquire(result->error_response_headers);
145 }
146
147 if (result->error_response_body != NULL) {
148 aws_byte_buf_init_copy(
149 &meta_request_test_results->error_response_body, tester->allocator, result->error_response_body);
150 }
151
152 meta_request_test_results->finished_response_status = result->response_status;
153 meta_request_test_results->finished_error_code = result->error_code;
154
155 aws_s3_tester_notify_meta_request_finished(tester, result);
156 }
157
s_s3_test_meta_request_shutdown(void * user_data)158 static void s_s3_test_meta_request_shutdown(void *user_data) {
159 struct aws_s3_meta_request_test_results *meta_request_test_results = user_data;
160 struct aws_s3_tester *tester = meta_request_test_results->tester;
161
162 aws_s3_tester_notify_meta_request_shutdown(tester);
163 }
164
165 /* Wait for the cleanup notification. This, and the s_s3_test_client_shutdown function are meant to be used for
166 * sequential clean up only, and should not overlap with the "finish" callback. (Both currently use the same
167 * mutex/signal.) */
168 static void s_s3_tester_wait_for_client_shutdown(struct aws_s3_tester *tester);
169
170 /* Notify the tester that a particular clean up step has finished. */
171 static void s_s3_test_client_shutdown(void *user_data);
172
173 static bool s_s3_tester_have_meta_requests_finished(void *user_data);
174
175 static bool s_s3_tester_has_client_shutdown(void *user_data);
176
aws_s3_tester_build_endpoint_string(struct aws_allocator * allocator,const struct aws_byte_cursor * bucket_name,const struct aws_byte_cursor * region)177 struct aws_string *aws_s3_tester_build_endpoint_string(
178 struct aws_allocator *allocator,
179 const struct aws_byte_cursor *bucket_name,
180 const struct aws_byte_cursor *region) {
181
182 struct aws_byte_cursor endpoint_url_part0 = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(".s3.");
183 struct aws_byte_cursor endpoint_url_part1 = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(".amazonaws.com");
184
185 struct aws_byte_buf endpoint_buffer;
186 aws_byte_buf_init(&endpoint_buffer, allocator, 128);
187
188 aws_byte_buf_append_dynamic(&endpoint_buffer, bucket_name);
189 aws_byte_buf_append_dynamic(&endpoint_buffer, &endpoint_url_part0);
190 aws_byte_buf_append_dynamic(&endpoint_buffer, region);
191 aws_byte_buf_append_dynamic(&endpoint_buffer, &endpoint_url_part1);
192
193 struct aws_string *endpoint_string = aws_string_new_from_buf(allocator, &endpoint_buffer);
194
195 aws_byte_buf_clean_up(&endpoint_buffer);
196
197 return endpoint_string;
198 }
199
aws_s3_tester_init(struct aws_allocator * allocator,struct aws_s3_tester * tester)200 int aws_s3_tester_init(struct aws_allocator *allocator, struct aws_s3_tester *tester) {
201
202 AWS_PRECONDITION(allocator);
203 AWS_PRECONDITION(tester);
204
205 (void)allocator;
206
207 AWS_ZERO_STRUCT(*tester);
208
209 tester->allocator = allocator;
210
211 aws_s3_library_init(allocator);
212
213 if (aws_mutex_init(&tester->synced_data.lock)) {
214 return AWS_OP_ERR;
215 }
216
217 if (aws_condition_variable_init(&tester->signal)) {
218 goto condition_variable_failed;
219 }
220
221 ASSERT_SUCCESS(aws_array_list_init_dynamic(
222 &tester->client_vtable_patches, tester->allocator, 4, sizeof(struct aws_s3_client_vtable_patch)));
223
224 ASSERT_SUCCESS(aws_array_list_init_dynamic(
225 &tester->meta_request_vtable_patches, tester->allocator, 4, sizeof(struct aws_s3_meta_request_vtable_patch)));
226
227 /* Setup an event loop group and host resolver. */
228 tester->el_group = aws_event_loop_group_new_default(allocator, 0, NULL);
229 ASSERT_TRUE(tester->el_group != NULL);
230
231 struct aws_host_resolver_default_options resolver_options = {
232 .max_entries = 10,
233 .el_group = tester->el_group,
234 };
235 tester->host_resolver = aws_host_resolver_new_default(allocator, &resolver_options);
236 ASSERT_TRUE(tester->host_resolver != NULL);
237
238 /* Setup the client boot strap. */
239 {
240 struct aws_client_bootstrap_options bootstrap_options;
241 AWS_ZERO_STRUCT(bootstrap_options);
242 bootstrap_options.event_loop_group = tester->el_group;
243 bootstrap_options.host_resolver = tester->host_resolver;
244 bootstrap_options.user_data = tester;
245
246 tester->client_bootstrap = aws_client_bootstrap_new(allocator, &bootstrap_options);
247 }
248
249 #ifndef BYO_CRYPTO
250 /* Setup the credentials provider */
251 {
252 struct aws_credentials_provider_chain_default_options credentials_config;
253 AWS_ZERO_STRUCT(credentials_config);
254 credentials_config.bootstrap = tester->client_bootstrap;
255 tester->credentials_provider = aws_credentials_provider_new_chain_default(allocator, &credentials_config);
256 }
257 #endif
258
259 aws_s3_init_default_signing_config(&tester->default_signing_config, g_test_s3_region, tester->credentials_provider);
260
261 return AWS_OP_SUCCESS;
262
263 condition_variable_failed:
264
265 aws_mutex_clean_up(&tester->synced_data.lock);
266
267 return AWS_OP_ERR;
268 }
269
aws_s3_tester_bind_client(struct aws_s3_tester * tester,struct aws_s3_client_config * config,uint32_t flags)270 int aws_s3_tester_bind_client(struct aws_s3_tester *tester, struct aws_s3_client_config *config, uint32_t flags) {
271 AWS_PRECONDITION(tester);
272 AWS_PRECONDITION(config);
273
274 ASSERT_TRUE(!tester->bound_to_client);
275 tester->bound_to_client = true;
276
277 ASSERT_TRUE(config->client_bootstrap == NULL);
278 config->client_bootstrap = tester->client_bootstrap;
279
280 if (flags & AWS_S3_TESTER_BIND_CLIENT_REGION) {
281 ASSERT_TRUE(config->region.len == 0);
282 config->region = g_test_s3_region;
283 }
284
285 if (flags & AWS_S3_TESTER_BIND_CLIENT_SIGNING) {
286 ASSERT_TRUE(config->signing_config == NULL);
287 config->signing_config = &tester->default_signing_config;
288 }
289
290 ASSERT_TRUE(config->shutdown_callback == NULL);
291 config->shutdown_callback = s_s3_test_client_shutdown;
292
293 ASSERT_TRUE(config->shutdown_callback_user_data == NULL);
294 config->shutdown_callback_user_data = tester;
295
296 return AWS_OP_SUCCESS;
297 }
298
aws_s3_tester_bind_meta_request(struct aws_s3_tester * tester,struct aws_s3_meta_request_options * options,struct aws_s3_meta_request_test_results * meta_request_test_results)299 int aws_s3_tester_bind_meta_request(
300 struct aws_s3_tester *tester,
301 struct aws_s3_meta_request_options *options,
302 struct aws_s3_meta_request_test_results *meta_request_test_results) {
303
304 meta_request_test_results->tester = tester;
305
306 aws_s3_tester_lock_synced_data(tester);
307 ++tester->synced_data.desired_meta_request_finish_count;
308 ++tester->synced_data.desired_meta_request_shutdown_count;
309 aws_s3_tester_unlock_synced_data(tester);
310
311 ASSERT_TRUE(options->headers_callback == NULL);
312 options->headers_callback = s_s3_test_meta_request_header_callback;
313
314 ASSERT_TRUE(options->body_callback == NULL);
315 options->body_callback = s_s3_test_meta_request_body_callback;
316
317 ASSERT_TRUE(options->finish_callback == NULL);
318 options->finish_callback = s_s3_test_meta_request_finish;
319
320 ASSERT_TRUE(options->shutdown_callback == NULL);
321 options->shutdown_callback = s_s3_test_meta_request_shutdown;
322
323 ASSERT_TRUE(options->user_data == NULL);
324 options->user_data = meta_request_test_results;
325
326 return AWS_OP_SUCCESS;
327 }
328
aws_s3_meta_request_test_results_clean_up(struct aws_s3_meta_request_test_results * test_meta_request)329 void aws_s3_meta_request_test_results_clean_up(struct aws_s3_meta_request_test_results *test_meta_request) {
330 if (test_meta_request == NULL) {
331 return;
332 }
333
334 aws_http_headers_release(test_meta_request->error_response_headers);
335 aws_byte_buf_clean_up(&test_meta_request->error_response_body);
336 aws_http_headers_release(test_meta_request->response_headers);
337
338 AWS_ZERO_STRUCT(*test_meta_request);
339 }
340
aws_s3_tester_notify_meta_request_finished(struct aws_s3_tester * tester,const struct aws_s3_meta_request_result * result)341 void aws_s3_tester_notify_meta_request_finished(
342 struct aws_s3_tester *tester,
343 const struct aws_s3_meta_request_result *result) {
344 AWS_PRECONDITION(tester);
345
346 bool notify = false;
347
348 aws_s3_tester_lock_synced_data(tester);
349 ++tester->synced_data.meta_request_finish_count;
350
351 int error_code = AWS_ERROR_SUCCESS;
352
353 if (result != NULL) {
354 error_code = result->error_code;
355 }
356
357 if (tester->synced_data.desired_meta_request_finish_count == 0 ||
358 tester->synced_data.meta_request_finish_count == tester->synced_data.desired_meta_request_finish_count ||
359 (error_code != AWS_ERROR_SUCCESS)) {
360
361 tester->synced_data.meta_requests_finished = true;
362 tester->synced_data.finish_error_code = error_code;
363
364 notify = true;
365 }
366
367 aws_s3_tester_unlock_synced_data(tester);
368
369 if (notify) {
370 aws_condition_variable_notify_all(&tester->signal);
371 }
372 }
373
s_s3_tester_have_meta_requests_finished(void * user_data)374 static bool s_s3_tester_have_meta_requests_finished(void *user_data) {
375 AWS_PRECONDITION(user_data);
376 struct aws_s3_tester *tester = (struct aws_s3_tester *)user_data;
377
378 return tester->synced_data.meta_requests_finished > 0;
379 }
380
aws_s3_tester_wait_for_meta_request_finish(struct aws_s3_tester * tester)381 void aws_s3_tester_wait_for_meta_request_finish(struct aws_s3_tester *tester) {
382 AWS_PRECONDITION(tester);
383
384 aws_s3_tester_lock_synced_data(tester);
385 aws_condition_variable_wait_pred(
386 &tester->signal, &tester->synced_data.lock, s_s3_tester_have_meta_requests_finished, tester);
387
388 tester->synced_data.meta_requests_finished = false;
389 aws_s3_tester_unlock_synced_data(tester);
390 }
391
aws_s3_tester_notify_meta_request_shutdown(struct aws_s3_tester * tester)392 void aws_s3_tester_notify_meta_request_shutdown(struct aws_s3_tester *tester) {
393 bool notify = false;
394
395 aws_s3_tester_lock_synced_data(tester);
396 ++tester->synced_data.meta_request_shutdown_count;
397
398 if (tester->synced_data.desired_meta_request_shutdown_count == 0 ||
399 tester->synced_data.meta_request_shutdown_count == tester->synced_data.desired_meta_request_shutdown_count) {
400
401 tester->synced_data.meta_requests_shutdown = true;
402 notify = true;
403 }
404
405 aws_s3_tester_unlock_synced_data(tester);
406
407 if (notify) {
408 aws_condition_variable_notify_all(&tester->signal);
409 }
410 }
411
s_s3_tester_have_meta_requests_shutdown(void * user_data)412 static bool s_s3_tester_have_meta_requests_shutdown(void *user_data) {
413 AWS_PRECONDITION(user_data);
414 struct aws_s3_tester *tester = (struct aws_s3_tester *)user_data;
415
416 return tester->synced_data.meta_requests_shutdown > 0;
417 }
418
aws_s3_tester_wait_for_meta_request_shutdown(struct aws_s3_tester * tester)419 void aws_s3_tester_wait_for_meta_request_shutdown(struct aws_s3_tester *tester) {
420 AWS_PRECONDITION(tester);
421
422 aws_s3_tester_lock_synced_data(tester);
423 aws_condition_variable_wait_pred(
424 &tester->signal, &tester->synced_data.lock, s_s3_tester_have_meta_requests_shutdown, tester);
425
426 tester->synced_data.meta_requests_shutdown = false;
427 aws_s3_tester_unlock_synced_data(tester);
428 }
429
s_s3_tester_counters_equal_desired(void * user_data)430 static bool s_s3_tester_counters_equal_desired(void *user_data) {
431 AWS_PRECONDITION(user_data);
432 struct aws_s3_tester *tester = (struct aws_s3_tester *)user_data;
433
434 return tester->synced_data.counter1 == tester->synced_data.desired_counter1 &&
435 tester->synced_data.counter2 == tester->synced_data.desired_counter2;
436 }
437
aws_s3_tester_wait_for_signal(struct aws_s3_tester * tester)438 void aws_s3_tester_wait_for_signal(struct aws_s3_tester *tester) {
439 aws_s3_tester_lock_synced_data(tester);
440 aws_condition_variable_wait(&tester->signal, &tester->synced_data.lock);
441 aws_s3_tester_unlock_synced_data(tester);
442 }
443
aws_s3_tester_notify_signal(struct aws_s3_tester * tester)444 void aws_s3_tester_notify_signal(struct aws_s3_tester *tester) {
445 aws_condition_variable_notify_all(&tester->signal);
446 }
447
aws_s3_tester_wait_for_counters(struct aws_s3_tester * tester)448 void aws_s3_tester_wait_for_counters(struct aws_s3_tester *tester) {
449 aws_s3_tester_lock_synced_data(tester);
450 aws_condition_variable_wait_pred(
451 &tester->signal, &tester->synced_data.lock, s_s3_tester_counters_equal_desired, tester);
452 aws_s3_tester_unlock_synced_data(tester);
453 }
454
aws_s3_tester_inc_counter1(struct aws_s3_tester * tester)455 size_t aws_s3_tester_inc_counter1(struct aws_s3_tester *tester) {
456 aws_s3_tester_lock_synced_data(tester);
457 size_t result = ++tester->synced_data.counter1;
458 aws_s3_tester_unlock_synced_data(tester);
459
460 aws_condition_variable_notify_all(&tester->signal);
461
462 return result;
463 }
464
aws_s3_tester_inc_counter2(struct aws_s3_tester * tester)465 size_t aws_s3_tester_inc_counter2(struct aws_s3_tester *tester) {
466 aws_s3_tester_lock_synced_data(tester);
467 size_t result = ++tester->synced_data.counter2;
468 aws_s3_tester_unlock_synced_data(tester);
469
470 aws_condition_variable_notify_all(&tester->signal);
471
472 return result;
473 }
474
aws_s3_tester_reset_counter1(struct aws_s3_tester * tester)475 void aws_s3_tester_reset_counter1(struct aws_s3_tester *tester) {
476 aws_s3_tester_lock_synced_data(tester);
477 tester->synced_data.counter1 = 0;
478 aws_s3_tester_unlock_synced_data(tester);
479 }
480
aws_s3_tester_reset_counter2(struct aws_s3_tester * tester)481 void aws_s3_tester_reset_counter2(struct aws_s3_tester *tester) {
482 aws_s3_tester_lock_synced_data(tester);
483 tester->synced_data.counter2 = 0;
484 aws_s3_tester_unlock_synced_data(tester);
485 }
486
aws_s3_tester_set_counter1_desired(struct aws_s3_tester * tester,size_t value)487 void aws_s3_tester_set_counter1_desired(struct aws_s3_tester *tester, size_t value) {
488 aws_s3_tester_lock_synced_data(tester);
489 tester->synced_data.desired_counter1 = value;
490 aws_s3_tester_unlock_synced_data(tester);
491 }
492
aws_s3_tester_set_counter2_desired(struct aws_s3_tester * tester,size_t value)493 void aws_s3_tester_set_counter2_desired(struct aws_s3_tester *tester, size_t value) {
494 aws_s3_tester_lock_synced_data(tester);
495 tester->synced_data.desired_counter2 = value;
496 aws_s3_tester_unlock_synced_data(tester);
497 }
498
aws_s3_tester_clean_up(struct aws_s3_tester * tester)499 void aws_s3_tester_clean_up(struct aws_s3_tester *tester) {
500 AWS_PRECONDITION(tester);
501
502 if (tester->bound_to_client) {
503 s_s3_tester_wait_for_client_shutdown(tester);
504 tester->bound_to_client = false;
505 }
506
507 aws_array_list_clean_up(&tester->client_vtable_patches);
508 aws_array_list_clean_up(&tester->meta_request_vtable_patches);
509
510 aws_client_bootstrap_release(tester->client_bootstrap);
511 tester->client_bootstrap = NULL;
512
513 aws_credentials_provider_release(tester->credentials_provider);
514 tester->credentials_provider = NULL;
515
516 aws_host_resolver_release(tester->host_resolver);
517 tester->host_resolver = NULL;
518
519 aws_event_loop_group_release(tester->el_group);
520 tester->el_group = NULL;
521
522 aws_s3_library_clean_up();
523
524 aws_condition_variable_clean_up(&tester->signal);
525 aws_mutex_clean_up(&tester->synced_data.lock);
526 }
527
aws_s3_tester_lock_synced_data(struct aws_s3_tester * tester)528 void aws_s3_tester_lock_synced_data(struct aws_s3_tester *tester) {
529 AWS_PRECONDITION(tester);
530 aws_mutex_lock(&tester->synced_data.lock);
531 }
532
aws_s3_tester_unlock_synced_data(struct aws_s3_tester * tester)533 void aws_s3_tester_unlock_synced_data(struct aws_s3_tester *tester) {
534 AWS_PRECONDITION(tester);
535
536 aws_mutex_unlock(&tester->synced_data.lock);
537 }
538
s_s3_client_meta_request_factory_empty(struct aws_s3_client * client,const struct aws_s3_meta_request_options * options)539 struct aws_s3_meta_request *s_s3_client_meta_request_factory_empty(
540 struct aws_s3_client *client,
541 const struct aws_s3_meta_request_options *options) {
542 AWS_PRECONDITION(client);
543 AWS_PRECONDITION(options);
544
545 (void)client;
546 (void)options;
547
548 return NULL;
549 }
550
s_s3_client_create_connection_for_request_empty(struct aws_s3_client * client,struct aws_s3_request * request)551 void s_s3_client_create_connection_for_request_empty(struct aws_s3_client *client, struct aws_s3_request *request) {
552 AWS_PRECONDITION(client);
553 AWS_PRECONDITION(request);
554
555 (void)client;
556 (void)request;
557 }
558
s_s3_client_acquire_http_connection_empty(struct aws_http_connection_manager * conn_manager,aws_http_connection_manager_on_connection_setup_fn * on_connection_acquired_callback,void * user_data)559 static void s_s3_client_acquire_http_connection_empty(
560 struct aws_http_connection_manager *conn_manager,
561 aws_http_connection_manager_on_connection_setup_fn *on_connection_acquired_callback,
562 void *user_data) {
563 (void)conn_manager;
564 (void)on_connection_acquired_callback;
565 (void)user_data;
566 }
567
s_s3_client_get_host_address_count_empty(struct aws_host_resolver * host_resolver,const struct aws_string * host_name,uint32_t flags)568 size_t s_s3_client_get_host_address_count_empty(
569 struct aws_host_resolver *host_resolver,
570 const struct aws_string *host_name,
571 uint32_t flags) {
572 (void)host_resolver;
573 (void)host_name;
574 (void)flags;
575 return 0;
576 }
577
s_s3_client_schedule_process_work_synced_empty(struct aws_s3_client * client)578 static void s_s3_client_schedule_process_work_synced_empty(struct aws_s3_client *client) {
579 (void)client;
580 }
581
s_s3_client_process_work_empty(struct aws_s3_client * client)582 static void s_s3_client_process_work_empty(struct aws_s3_client *client) {
583 AWS_PRECONDITION(client);
584 (void)client;
585 }
586
s_s3_client_endpoint_ref_count_zero_empty(struct aws_s3_endpoint * endpoint)587 static bool s_s3_client_endpoint_ref_count_zero_empty(struct aws_s3_endpoint *endpoint) {
588 AWS_PRECONDITION(endpoint);
589 (void)endpoint;
590 return true;
591 }
592
s_s3_client_endpoint_shutdown_callback_empty(void * user_data)593 static void s_s3_client_endpoint_shutdown_callback_empty(void *user_data) {
594 AWS_PRECONDITION(user_data);
595 (void)user_data;
596 }
597
s_s3_client_finish_destroy_empty(struct aws_s3_client * client)598 static void s_s3_client_finish_destroy_empty(struct aws_s3_client *client) {
599 AWS_PRECONDITION(client);
600 (void)client;
601 }
602
603 struct aws_s3_client_vtable g_aws_s3_client_mock_vtable = {
604 .meta_request_factory = s_s3_client_meta_request_factory_empty,
605 .create_connection_for_request = s_s3_client_create_connection_for_request_empty,
606 .acquire_http_connection = s_s3_client_acquire_http_connection_empty,
607 .get_host_address_count = s_s3_client_get_host_address_count_empty,
608 .schedule_process_work_synced = s_s3_client_schedule_process_work_synced_empty,
609 .process_work = s_s3_client_process_work_empty,
610 .endpoint_ref_count_zero = s_s3_client_endpoint_ref_count_zero_empty,
611 .endpoint_shutdown_callback = s_s3_client_endpoint_shutdown_callback_empty,
612 .finish_destroy = s_s3_client_finish_destroy_empty,
613 };
614
s_s3_mock_client_start_destroy(void * user_data)615 static void s_s3_mock_client_start_destroy(void *user_data) {
616 struct aws_s3_client *client = user_data;
617 AWS_ASSERT(client);
618
619 aws_mem_release(client->allocator, client);
620 }
621
aws_s3_tester_mock_client_new(struct aws_s3_tester * tester)622 struct aws_s3_client *aws_s3_tester_mock_client_new(struct aws_s3_tester *tester) {
623 struct aws_allocator *allocator = tester->allocator;
624 struct aws_s3_client *mock_client = aws_mem_calloc(allocator, 1, sizeof(struct aws_s3_client));
625
626 mock_client->allocator = allocator;
627 mock_client->vtable = &g_aws_s3_client_mock_vtable;
628
629 aws_ref_count_init(
630 &mock_client->ref_count, mock_client, (aws_simple_completion_callback *)s_s3_mock_client_start_destroy);
631
632 aws_mutex_init(&mock_client->synced_data.lock);
633
634 aws_atomic_init_int(&mock_client->stats.num_requests_in_flight, 0);
635
636 for (uint32_t i = 0; i < (uint32_t)AWS_S3_META_REQUEST_TYPE_MAX; ++i) {
637 aws_atomic_init_int(&mock_client->stats.num_requests_network_io[i], 0);
638 }
639
640 aws_atomic_init_int(&mock_client->stats.num_requests_stream_queued_waiting, 0);
641 aws_atomic_init_int(&mock_client->stats.num_requests_streaming, 0);
642
643 return mock_client;
644 }
645
aws_s3_tester_dummy_http_request_new(struct aws_s3_tester * tester)646 struct aws_http_message *aws_s3_tester_dummy_http_request_new(struct aws_s3_tester *tester) {
647 AWS_PRECONDITION(tester);
648
649 struct aws_http_message *message = aws_http_message_new_request(tester->allocator);
650
651 struct aws_http_header host_header = {
652 .name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Host"),
653 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("dummy_host"),
654 };
655
656 aws_http_message_add_header(message, host_header);
657
658 return message;
659 }
660
s_s3_meta_request_update_empty(struct aws_s3_meta_request * meta_request,uint32_t flags,struct aws_s3_request ** out_request)661 static bool s_s3_meta_request_update_empty(
662 struct aws_s3_meta_request *meta_request,
663 uint32_t flags,
664 struct aws_s3_request **out_request) {
665 (void)meta_request;
666 (void)flags;
667 (void)out_request;
668 return false;
669 }
670
s_s3_meta_request_send_request_finish_empty(struct aws_s3_connection * connection,struct aws_http_stream * stream,int error_code)671 void s_s3_meta_request_send_request_finish_empty(
672 struct aws_s3_connection *connection,
673 struct aws_http_stream *stream,
674 int error_code) {
675 (void)connection;
676 (void)stream;
677 (void)error_code;
678 }
679
s_s3_meta_request_finished_request_empty(struct aws_s3_meta_request * meta_request,struct aws_s3_request * request,int error_code)680 static void s_s3_meta_request_finished_request_empty(
681 struct aws_s3_meta_request *meta_request,
682 struct aws_s3_request *request,
683 int error_code) {
684 (void)meta_request;
685 (void)request;
686 (void)error_code;
687 }
688
s_s3_meta_request_schedule_prepare_request_empty(struct aws_s3_meta_request * meta_request,struct aws_s3_request * request,aws_s3_meta_request_prepare_request_callback_fn * callback,void * user_data)689 static void s_s3_meta_request_schedule_prepare_request_empty(
690 struct aws_s3_meta_request *meta_request,
691 struct aws_s3_request *request,
692 aws_s3_meta_request_prepare_request_callback_fn *callback,
693 void *user_data) {
694 (void)meta_request;
695 (void)request;
696 (void)callback;
697 (void)user_data;
698 }
699
s_s3_meta_request_prepare_request_empty(struct aws_s3_meta_request * meta_request,struct aws_s3_request * request)700 static int s_s3_meta_request_prepare_request_empty(
701 struct aws_s3_meta_request *meta_request,
702 struct aws_s3_request *request) {
703 (void)meta_request;
704 (void)request;
705 return AWS_OP_ERR;
706 }
707
s_s3_meta_request_init_signing_date_time_empty(struct aws_s3_meta_request * meta_request,struct aws_date_time * date_time)708 static void s_s3_meta_request_init_signing_date_time_empty(
709 struct aws_s3_meta_request *meta_request,
710 struct aws_date_time *date_time) {
711 (void)meta_request;
712 (void)date_time;
713 }
714
s_s3_meta_request_sign_request_empty(struct aws_s3_meta_request * meta_request,struct aws_s3_request * request,aws_signing_complete_fn * on_signing_complete,void * user_data)715 static void s_s3_meta_request_sign_request_empty(
716 struct aws_s3_meta_request *meta_request,
717 struct aws_s3_request *request,
718 aws_signing_complete_fn *on_signing_complete,
719 void *user_data) {
720 (void)meta_request;
721 (void)request;
722 (void)on_signing_complete;
723 (void)user_data;
724 }
725
s_s3_mock_meta_request_destroy(struct aws_s3_meta_request * meta_request)726 static void s_s3_mock_meta_request_destroy(struct aws_s3_meta_request *meta_request) {
727 AWS_PRECONDITION(meta_request);
728
729 aws_mem_release(meta_request->allocator, meta_request->impl);
730 }
731
732 static struct aws_s3_meta_request_vtable s_s3_mock_meta_request_vtable = {
733 .update = s_s3_meta_request_update_empty,
734 .send_request_finish = s_s3_meta_request_send_request_finish_empty,
735 .schedule_prepare_request = s_s3_meta_request_schedule_prepare_request_empty,
736 .prepare_request = s_s3_meta_request_prepare_request_empty,
737 .finished_request = s_s3_meta_request_finished_request_empty,
738 .init_signing_date_time = s_s3_meta_request_init_signing_date_time_empty,
739 .sign_request = s_s3_meta_request_sign_request_empty,
740 .destroy = s_s3_mock_meta_request_destroy,
741 };
742
743 struct aws_s3_empty_meta_request {
744 struct aws_s3_meta_request base;
745 };
746
s_s3_mock_endpoint_zero_ref(void * user_data)747 static void s_s3_mock_endpoint_zero_ref(void *user_data) {
748 struct aws_s3_endpoint *endpoint = user_data;
749
750 aws_string_destroy(endpoint->host_name);
751 aws_mem_release(endpoint->allocator, endpoint);
752 }
753
aws_s3_tester_mock_endpoint_new(struct aws_s3_tester * tester)754 struct aws_s3_endpoint *aws_s3_tester_mock_endpoint_new(struct aws_s3_tester *tester) {
755 struct aws_s3_endpoint *endpoint = aws_mem_calloc(tester->allocator, 1, sizeof(struct aws_s3_endpoint));
756 endpoint->allocator = tester->allocator;
757 aws_ref_count_init(&endpoint->ref_count, endpoint, s_s3_mock_endpoint_zero_ref);
758
759 struct aws_byte_cursor empty_cursor = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("");
760 endpoint->host_name = aws_string_new_from_cursor(tester->allocator, &empty_cursor);
761
762 return endpoint;
763 }
764
aws_s3_tester_mock_meta_request_new(struct aws_s3_tester * tester)765 struct aws_s3_meta_request *aws_s3_tester_mock_meta_request_new(struct aws_s3_tester *tester) {
766 AWS_PRECONDITION(tester);
767
768 struct aws_s3_empty_meta_request *empty_meta_request =
769 aws_mem_calloc(tester->allocator, 1, sizeof(struct aws_s3_empty_meta_request));
770
771 struct aws_http_message *dummy_http_message = aws_s3_tester_dummy_http_request_new(tester);
772
773 struct aws_s3_meta_request_options options = {
774 .message = dummy_http_message,
775 };
776
777 aws_s3_meta_request_init_base(
778 tester->allocator,
779 NULL,
780 0,
781 false,
782 &options,
783 empty_meta_request,
784 &s_s3_mock_meta_request_vtable,
785 &empty_meta_request->base);
786
787 aws_http_message_release(dummy_http_message);
788
789 return &empty_meta_request->base;
790 }
791
aws_s3_create_test_buffer(struct aws_allocator * allocator,size_t buffer_size,struct aws_byte_buf * out_buf)792 void aws_s3_create_test_buffer(struct aws_allocator *allocator, size_t buffer_size, struct aws_byte_buf *out_buf) {
793 AWS_PRECONDITION(allocator);
794 AWS_PRECONDITION(out_buf);
795
796 struct aws_byte_cursor test_string = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("This is an S3 test.");
797
798 aws_byte_buf_init(out_buf, allocator, buffer_size);
799
800 for (size_t buffer_pos = 0; buffer_pos < buffer_size; buffer_pos += test_string.len) {
801 size_t buffer_size_remaining = buffer_size - buffer_pos;
802 size_t string_copy_size = test_string.len;
803
804 if (buffer_size_remaining < string_copy_size) {
805 string_copy_size = buffer_size_remaining;
806 }
807
808 struct aws_byte_cursor from_byte_cursor = {.len = string_copy_size, .ptr = test_string.ptr};
809
810 aws_byte_buf_append(out_buf, &from_byte_cursor);
811 }
812 }
813
s_s3_test_client_shutdown(void * user_data)814 static void s_s3_test_client_shutdown(void *user_data) {
815 AWS_PRECONDITION(user_data);
816
817 struct aws_s3_tester *tester = (struct aws_s3_tester *)user_data;
818
819 aws_s3_tester_lock_synced_data(tester);
820 tester->synced_data.client_shutdown = true;
821 aws_s3_tester_unlock_synced_data(tester);
822
823 aws_condition_variable_notify_all(&tester->signal);
824 }
825
s_s3_tester_has_client_shutdown(void * user_data)826 static bool s_s3_tester_has_client_shutdown(void *user_data) {
827 AWS_PRECONDITION(user_data);
828 struct aws_s3_tester *tester = (struct aws_s3_tester *)user_data;
829
830 return tester->synced_data.client_shutdown > 0;
831 }
832
s_s3_tester_wait_for_client_shutdown(struct aws_s3_tester * tester)833 static void s_s3_tester_wait_for_client_shutdown(struct aws_s3_tester *tester) {
834 AWS_PRECONDITION(tester);
835
836 aws_s3_tester_lock_synced_data(tester);
837 aws_condition_variable_wait_pred(
838 &tester->signal, &tester->synced_data.lock, s_s3_tester_has_client_shutdown, tester);
839
840 tester->synced_data.client_shutdown = false;
841 aws_s3_tester_unlock_synced_data(tester);
842 }
843
aws_s3_test_get_object_request_new(struct aws_allocator * allocator,struct aws_byte_cursor host,struct aws_byte_cursor key)844 struct aws_http_message *aws_s3_test_get_object_request_new(
845 struct aws_allocator *allocator,
846 struct aws_byte_cursor host,
847 struct aws_byte_cursor key) {
848
849 struct aws_http_message *message = aws_http_message_new_request(allocator);
850
851 if (message == NULL) {
852 return NULL;
853 }
854
855 struct aws_http_header host_header = {.name = g_host_header_name, .value = host};
856
857 if (aws_http_message_add_header(message, host_header)) {
858 goto error_clean_up_message;
859 }
860
861 if (aws_http_message_set_request_method(message, aws_http_method_get)) {
862 goto error_clean_up_message;
863 }
864
865 if (aws_http_message_set_request_path(message, key)) {
866 goto error_clean_up_message;
867 }
868
869 return message;
870
871 error_clean_up_message:
872
873 if (message != NULL) {
874 aws_http_message_release(message);
875 message = NULL;
876 }
877
878 return NULL;
879 }
880
aws_s3_tester_patch_client_vtable(struct aws_s3_tester * tester,struct aws_s3_client * client,size_t * out_index)881 struct aws_s3_client_vtable *aws_s3_tester_patch_client_vtable(
882 struct aws_s3_tester *tester,
883 struct aws_s3_client *client,
884 size_t *out_index) {
885
886 struct aws_s3_client_vtable_patch patch;
887 AWS_ZERO_STRUCT(patch);
888
889 /* Push a new vtable patch into the array. */
890 aws_array_list_push_back(&tester->client_vtable_patches, (void *)&patch);
891
892 /* Get a pointer to the new vtable patch. */
893 size_t index = aws_array_list_length(&tester->client_vtable_patches) - 1;
894 struct aws_s3_client_vtable_patch *patch_array_ptr = aws_s3_tester_get_client_vtable_patch(tester, index);
895
896 /* Cache a pointer to the original vtable. */
897 patch_array_ptr->original_vtable = client->vtable;
898
899 /* Copy the original vtable contents into the patched vtable. */
900 memcpy(&patch_array_ptr->patched_vtable, patch_array_ptr->original_vtable, sizeof(struct aws_s3_client_vtable));
901
902 /* Point the client at the new vtable. */
903 client->vtable = &patch_array_ptr->patched_vtable;
904
905 if (out_index) {
906 *out_index = index;
907 }
908
909 return &patch_array_ptr->patched_vtable;
910 }
911
aws_s3_tester_get_client_vtable_patch(struct aws_s3_tester * tester,size_t index)912 struct aws_s3_client_vtable_patch *aws_s3_tester_get_client_vtable_patch(struct aws_s3_tester *tester, size_t index) {
913 struct aws_s3_client_vtable_patch *patch = NULL;
914 aws_array_list_get_at_ptr(&tester->client_vtable_patches, (void **)&patch, index);
915 return patch;
916 }
917
aws_s3_tester_patch_meta_request_vtable(struct aws_s3_tester * tester,struct aws_s3_meta_request * meta_request,size_t * out_index)918 struct aws_s3_meta_request_vtable *aws_s3_tester_patch_meta_request_vtable(
919 struct aws_s3_tester *tester,
920 struct aws_s3_meta_request *meta_request,
921 size_t *out_index) {
922
923 struct aws_s3_meta_request_vtable_patch patch;
924 AWS_ZERO_STRUCT(patch);
925
926 /* Push a new vtable patch into the array. */
927 aws_array_list_push_back(&tester->meta_request_vtable_patches, (void *)&patch);
928
929 /* Get a pointer to the new vtable patch. */
930 size_t index = aws_array_list_length(&tester->meta_request_vtable_patches) - 1;
931 struct aws_s3_meta_request_vtable_patch *patch_array_ptr =
932 aws_s3_tester_get_meta_request_vtable_patch(tester, index);
933
934 /* Cache a pointer to the original vtable. */
935 patch_array_ptr->original_vtable = meta_request->vtable;
936
937 /* Copy the original vtable contents into the patched vtable. */
938 memcpy(
939 &patch_array_ptr->patched_vtable, patch_array_ptr->original_vtable, sizeof(struct aws_s3_meta_request_vtable));
940
941 /* Point the meta request at the new vtable. */
942 meta_request->vtable = &patch_array_ptr->patched_vtable;
943
944 if (out_index) {
945 *out_index = index;
946 }
947
948 return &patch_array_ptr->patched_vtable;
949 }
950
aws_s3_tester_get_meta_request_vtable_patch(struct aws_s3_tester * tester,size_t index)951 struct aws_s3_meta_request_vtable_patch *aws_s3_tester_get_meta_request_vtable_patch(
952 struct aws_s3_tester *tester,
953 size_t index) {
954 struct aws_s3_meta_request_vtable_patch *patch = NULL;
955 aws_array_list_get_at_ptr(&tester->meta_request_vtable_patches, (void **)&patch, index);
956 return patch;
957 }
958
aws_s3_test_put_object_request_new(struct aws_allocator * allocator,struct aws_byte_cursor host,struct aws_byte_cursor key,struct aws_byte_cursor content_type,struct aws_input_stream * body_stream,uint32_t flags)959 struct aws_http_message *aws_s3_test_put_object_request_new(
960 struct aws_allocator *allocator,
961 struct aws_byte_cursor host,
962 struct aws_byte_cursor key,
963 struct aws_byte_cursor content_type,
964 struct aws_input_stream *body_stream,
965 uint32_t flags) {
966
967 AWS_PRECONDITION(allocator);
968 AWS_PRECONDITION(body_stream);
969
970 int64_t body_stream_length = 0;
971
972 if (aws_input_stream_get_length(body_stream, &body_stream_length)) {
973 return NULL;
974 }
975
976 struct aws_http_message *message = aws_http_message_new_request(allocator);
977
978 if (message == NULL) {
979 return NULL;
980 }
981
982 struct aws_http_header host_header = {.name = g_host_header_name, .value = host};
983
984 struct aws_http_header content_type_header = {.name = g_content_type_header_name, .value = content_type};
985
986 char content_length_buffer[64] = "";
987 snprintf(content_length_buffer, sizeof(content_length_buffer), "%" PRId64 "", body_stream_length);
988
989 struct aws_http_header content_length_header = {
990 .name = g_content_length_header_name,
991 .value = aws_byte_cursor_from_c_str(content_length_buffer),
992 };
993
994 struct aws_http_header sse_kms_header = {.name = g_s3_sse_header, .value = aws_byte_cursor_from_c_str("aws:kms")};
995 struct aws_http_header sse_aes256_header = {.name = g_s3_sse_header, .value = aws_byte_cursor_from_c_str("AES256")};
996 struct aws_http_header acl_public_read_header = {
997 .name = g_acl_header_name,
998 .value = aws_byte_cursor_from_c_str("bucket-owner-read"),
999 };
1000
1001 if (aws_http_message_add_header(message, host_header)) {
1002 goto error_clean_up_message;
1003 }
1004
1005 if (aws_http_message_add_header(message, content_type_header)) {
1006 goto error_clean_up_message;
1007 }
1008
1009 if (aws_http_message_add_header(message, content_length_header)) {
1010 goto error_clean_up_message;
1011 }
1012
1013 if (flags & AWS_S3_TESTER_SEND_META_REQUEST_SSE_KMS) {
1014 if (aws_http_message_add_header(message, sse_kms_header)) {
1015 goto error_clean_up_message;
1016 }
1017 }
1018
1019 if (flags & AWS_S3_TESTER_SEND_META_REQUEST_SSE_AES256) {
1020 if (aws_http_message_add_header(message, sse_aes256_header)) {
1021 goto error_clean_up_message;
1022 }
1023 }
1024
1025 if (flags & AWS_S3_TESTER_SEND_META_REQUEST_PUT_ACL) {
1026 if (aws_http_message_add_header(message, acl_public_read_header)) {
1027 goto error_clean_up_message;
1028 }
1029 }
1030
1031 if (aws_http_message_set_request_method(message, aws_http_method_put)) {
1032 goto error_clean_up_message;
1033 }
1034
1035 if (aws_http_message_set_request_path(message, key)) {
1036 goto error_clean_up_message;
1037 }
1038
1039 aws_http_message_set_body_stream(message, body_stream);
1040
1041 return message;
1042
1043 error_clean_up_message:
1044
1045 if (message != NULL) {
1046 aws_http_message_release(message);
1047 message = NULL;
1048 }
1049
1050 return NULL;
1051 }
1052
aws_s3_tester_client_new(struct aws_s3_tester * tester,struct aws_s3_tester_client_options * options,struct aws_s3_client ** out_client)1053 int aws_s3_tester_client_new(
1054 struct aws_s3_tester *tester,
1055 struct aws_s3_tester_client_options *options,
1056 struct aws_s3_client **out_client) {
1057 ASSERT_TRUE(tester != NULL);
1058 ASSERT_TRUE(options != NULL);
1059 ASSERT_TRUE(out_client != NULL);
1060
1061 struct aws_s3_client_config client_config = {
1062 .part_size = options->part_size,
1063 .max_part_size = options->max_part_size,
1064 };
1065
1066 struct aws_tls_connection_options tls_connection_options;
1067 AWS_ZERO_STRUCT(tls_connection_options);
1068
1069 #ifndef BYO_CRYPTO
1070 struct aws_tls_ctx_options tls_context_options;
1071 aws_tls_ctx_options_init_default_client(&tls_context_options, tester->allocator);
1072
1073 struct aws_tls_ctx *context = aws_tls_client_ctx_new(tester->allocator, &tls_context_options);
1074 aws_tls_connection_options_init_from_ctx(&tls_connection_options, context);
1075 #endif
1076
1077 struct aws_string *endpoint =
1078 aws_s3_tester_build_endpoint_string(tester->allocator, &g_test_bucket_name, &g_test_s3_region);
1079 struct aws_byte_cursor endpoint_cursor = aws_byte_cursor_from_string(endpoint);
1080
1081 tls_connection_options.server_name = aws_string_new_from_cursor(tester->allocator, &endpoint_cursor);
1082
1083 switch (options->tls_usage) {
1084 case AWS_S3_TLS_ENABLED:
1085 client_config.tls_mode = AWS_MR_TLS_ENABLED;
1086 client_config.tls_connection_options = &tls_connection_options;
1087 break;
1088 case AWS_S3_TLS_DISABLED:
1089 client_config.tls_mode = AWS_MR_TLS_DISABLED;
1090 break;
1091 default:
1092 break;
1093 }
1094
1095 ASSERT_SUCCESS(aws_s3_tester_bind_client(
1096 tester, &client_config, AWS_S3_TESTER_BIND_CLIENT_REGION | AWS_S3_TESTER_BIND_CLIENT_SIGNING));
1097
1098 *out_client = aws_s3_client_new(tester->allocator, &client_config);
1099
1100 aws_string_destroy(endpoint);
1101
1102 #ifndef BYO_CRYPTO
1103 aws_tls_ctx_release(context);
1104 aws_tls_connection_options_clean_up(&tls_connection_options);
1105 aws_tls_ctx_options_clean_up(&tls_context_options);
1106 #endif
1107
1108 return AWS_OP_SUCCESS;
1109 }
1110
aws_s3_tester_send_meta_request_with_options(struct aws_s3_tester * tester,struct aws_s3_tester_meta_request_options * options,struct aws_s3_meta_request_test_results * out_results)1111 int aws_s3_tester_send_meta_request_with_options(
1112 struct aws_s3_tester *tester,
1113 struct aws_s3_tester_meta_request_options *options,
1114 struct aws_s3_meta_request_test_results *out_results) {
1115 ASSERT_TRUE(options != NULL);
1116
1117 struct aws_allocator *allocator = options->allocator;
1118
1119 struct aws_s3_tester local_tester;
1120 AWS_ZERO_STRUCT(local_tester);
1121 bool clean_up_local_tester = false;
1122
1123 if (tester == NULL) {
1124 ASSERT_TRUE(options->allocator);
1125 ASSERT_SUCCESS(aws_s3_tester_init(options->allocator, &local_tester));
1126 tester = &local_tester;
1127 clean_up_local_tester = true;
1128 } else if (allocator == NULL) {
1129 allocator = tester->allocator;
1130 }
1131
1132 struct aws_s3_client *client = options->client;
1133
1134 if (client == NULL) {
1135
1136 if (options->client_options != NULL) {
1137 ASSERT_SUCCESS(aws_s3_tester_client_new(tester, options->client_options, &client));
1138 } else {
1139 struct aws_s3_tester_client_options client_options;
1140 AWS_ZERO_STRUCT(client_options);
1141 ASSERT_SUCCESS(aws_s3_tester_client_new(tester, &client_options, &client));
1142 }
1143
1144 } else {
1145 aws_s3_client_acquire(client);
1146 }
1147
1148 struct aws_s3_meta_request_options meta_request_options = {
1149 .type = options->meta_request_type,
1150 .message = options->message,
1151 };
1152
1153 struct aws_byte_buf input_stream_buffer;
1154 AWS_ZERO_STRUCT(input_stream_buffer);
1155
1156 struct aws_input_stream *input_stream = NULL;
1157
1158 if (meta_request_options.message == NULL) {
1159 const struct aws_byte_cursor *bucket_name = options->bucket_name;
1160
1161 if (bucket_name == NULL) {
1162 bucket_name = &g_test_bucket_name;
1163 }
1164
1165 struct aws_string *host_name = aws_s3_tester_build_endpoint_string(allocator, bucket_name, &g_test_s3_region);
1166
1167 if (meta_request_options.type == AWS_S3_META_REQUEST_TYPE_GET_OBJECT ||
1168 (meta_request_options.type == AWS_S3_META_REQUEST_TYPE_DEFAULT &&
1169 options->default_type_options.mode == AWS_S3_TESTER_DEFAULT_TYPE_MODE_GET)) {
1170
1171 struct aws_http_message *message = aws_s3_test_get_object_request_new(
1172 allocator, aws_byte_cursor_from_string(host_name), options->get_options.object_path);
1173
1174 if (options->get_options.object_range.ptr != NULL) {
1175 struct aws_http_header range_header = {
1176 .name = g_range_header_name,
1177 .value = options->get_options.object_range,
1178 };
1179
1180 aws_http_message_add_header(message, range_header);
1181 }
1182
1183 meta_request_options.message = message;
1184
1185 } else if (
1186 meta_request_options.type == AWS_S3_META_REQUEST_TYPE_PUT_OBJECT ||
1187 (meta_request_options.type == AWS_S3_META_REQUEST_TYPE_DEFAULT &&
1188 options->default_type_options.mode == AWS_S3_TESTER_DEFAULT_TYPE_MODE_PUT)) {
1189
1190 uint32_t object_size_mb = options->put_options.object_size_mb;
1191 size_t object_size_bytes = (size_t)object_size_mb * 1024ULL * 1024ULL;
1192
1193 if (options->put_options.ensure_multipart) {
1194 if (object_size_bytes == 0) {
1195 object_size_bytes = client->part_size * 2;
1196 object_size_mb = (uint32_t)(object_size_bytes / 1024 / 1024);
1197 }
1198
1199 ASSERT_TRUE(object_size_bytes > client->part_size);
1200 }
1201
1202 if (options->put_options.invalid_input_stream) {
1203 input_stream = aws_s3_bad_input_stream_new(allocator, object_size_bytes);
1204 } else {
1205 input_stream = aws_s3_test_input_stream_new(allocator, object_size_bytes);
1206 }
1207
1208 struct aws_byte_buf object_path_buffer;
1209 aws_byte_buf_init(&object_path_buffer, allocator, 128);
1210
1211 if (options->put_options.object_path_override.ptr != NULL) {
1212 aws_byte_buf_append_dynamic(&object_path_buffer, &options->put_options.object_path_override);
1213 } else {
1214 char object_path_sprintf_buffer[128] = "";
1215
1216 switch (options->sse_type) {
1217 case AWS_S3_TESTER_SSE_NONE:
1218 snprintf(
1219 object_path_sprintf_buffer,
1220 sizeof(object_path_sprintf_buffer),
1221 "/put_object_test_%uMB.txt",
1222 object_size_mb);
1223 break;
1224 case AWS_S3_TESTER_SSE_KMS:
1225 snprintf(
1226 object_path_sprintf_buffer,
1227 sizeof(object_path_sprintf_buffer),
1228 "/put_object_test_kms_%uMB.txt",
1229 object_size_mb);
1230 break;
1231 case AWS_S3_TESTER_SSE_AES256:
1232 snprintf(
1233 object_path_sprintf_buffer,
1234 sizeof(object_path_sprintf_buffer),
1235 "/put_object_test_aes256_%uMB.txt",
1236 object_size_mb);
1237 break;
1238
1239 default:
1240 break;
1241 }
1242
1243 struct aws_byte_cursor sprintf_buffer_cursor = aws_byte_cursor_from_c_str(object_path_sprintf_buffer);
1244 aws_byte_buf_append_dynamic(&object_path_buffer, &sprintf_buffer_cursor);
1245 }
1246
1247 struct aws_byte_cursor test_object_path = aws_byte_cursor_from_buf(&object_path_buffer);
1248
1249 /* Put together a simple S3 Put Object request. */
1250 struct aws_http_message *message = aws_s3_test_put_object_request_new(
1251 allocator,
1252 aws_byte_cursor_from_string(host_name),
1253 test_object_path,
1254 g_test_body_content_type,
1255 input_stream,
1256 options->sse_type);
1257
1258 aws_byte_buf_clean_up(&object_path_buffer);
1259
1260 if (options->put_options.content_length) {
1261 /* make a invalid request */
1262 char content_length_buffer[64] = "";
1263 snprintf(
1264 content_length_buffer, sizeof(content_length_buffer), "%zu", options->put_options.content_length);
1265
1266 struct aws_http_headers *headers = aws_http_message_get_headers(message);
1267 aws_http_headers_set(
1268 headers, g_content_length_header_name, aws_byte_cursor_from_c_str(content_length_buffer));
1269 }
1270
1271 if (options->put_options.invalid_request) {
1272 /* make a invalid request */
1273 aws_http_message_set_request_path(message, aws_byte_cursor_from_c_str("invalid_path"));
1274 }
1275
1276 meta_request_options.message = message;
1277 }
1278
1279 ASSERT_TRUE(meta_request_options.message != NULL);
1280
1281 aws_string_destroy(host_name);
1282 } else {
1283 aws_http_message_acquire(meta_request_options.message);
1284 }
1285
1286 struct aws_s3_meta_request_test_results meta_request_test_results;
1287 AWS_ZERO_STRUCT(meta_request_test_results);
1288
1289 if (out_results == NULL) {
1290 out_results = &meta_request_test_results;
1291 }
1292
1293 out_results->headers_callback = options->headers_callback;
1294 out_results->body_callback = options->body_callback;
1295
1296 ASSERT_SUCCESS(aws_s3_tester_bind_meta_request(tester, &meta_request_options, out_results));
1297
1298 struct aws_s3_meta_request *meta_request = aws_s3_client_make_meta_request(client, &meta_request_options);
1299
1300 if (meta_request == NULL) {
1301 out_results->finished_error_code = aws_last_error();
1302 }
1303
1304 aws_http_message_release(meta_request_options.message);
1305 meta_request_options.message = NULL;
1306
1307 if (meta_request != NULL) {
1308 /* Wait for the request to finish. */
1309 aws_s3_tester_wait_for_meta_request_finish(tester);
1310 ASSERT_TRUE(aws_s3_meta_request_is_finished(meta_request));
1311 }
1312
1313 aws_s3_tester_lock_synced_data(tester);
1314
1315 switch (options->validate_type) {
1316 case AWS_S3_TESTER_VALIDATE_TYPE_EXPECT_SUCCESS:
1317 ASSERT_TRUE(out_results->finished_error_code == AWS_ERROR_SUCCESS);
1318
1319 if (meta_request_options.type == AWS_S3_META_REQUEST_TYPE_GET_OBJECT) {
1320 ASSERT_SUCCESS(aws_s3_tester_validate_get_object_results(out_results, options->sse_type));
1321 } else if (meta_request_options.type == AWS_S3_META_REQUEST_TYPE_PUT_OBJECT) {
1322 ASSERT_SUCCESS(aws_s3_tester_validate_put_object_results(out_results, options->sse_type));
1323 }
1324 break;
1325 case AWS_S3_TESTER_VALIDATE_TYPE_EXPECT_FAILURE:
1326 ASSERT_FALSE(out_results->finished_error_code == AWS_ERROR_SUCCESS);
1327 break;
1328
1329 default:
1330 ASSERT_TRUE(false);
1331 break;
1332 }
1333
1334 aws_s3_tester_unlock_synced_data(tester);
1335
1336 if (meta_request != NULL) {
1337 out_results->part_size = meta_request->part_size;
1338 aws_s3_meta_request_release(meta_request);
1339 meta_request = NULL;
1340
1341 if (!options->dont_wait_for_shutdown) {
1342 aws_s3_tester_wait_for_meta_request_shutdown(tester);
1343 }
1344 }
1345
1346 aws_s3_meta_request_test_results_clean_up(&meta_request_test_results);
1347
1348 aws_s3_client_release(client);
1349
1350 aws_input_stream_destroy(input_stream);
1351 input_stream = NULL;
1352
1353 aws_byte_buf_clean_up(&input_stream_buffer);
1354
1355 if (clean_up_local_tester) {
1356 aws_s3_tester_clean_up(&local_tester);
1357 }
1358
1359 return AWS_OP_SUCCESS;
1360 }
1361
aws_s3_tester_send_meta_request(struct aws_s3_tester * tester,struct aws_s3_client * client,struct aws_s3_meta_request_options * options,struct aws_s3_meta_request_test_results * test_results,uint32_t flags)1362 int aws_s3_tester_send_meta_request(
1363 struct aws_s3_tester *tester,
1364 struct aws_s3_client *client,
1365 struct aws_s3_meta_request_options *options,
1366 struct aws_s3_meta_request_test_results *test_results,
1367 uint32_t flags) {
1368
1369 ASSERT_SUCCESS(aws_s3_tester_bind_meta_request(tester, options, test_results));
1370
1371 struct aws_s3_meta_request *meta_request = aws_s3_client_make_meta_request(client, options);
1372
1373 ASSERT_TRUE(meta_request != NULL);
1374
1375 if (flags & AWS_S3_TESTER_SEND_META_REQUEST_CANCEL) {
1376 /* take a random sleep from 0-1 ms. */
1377 srand((uint32_t)time(NULL));
1378 aws_thread_current_sleep(rand() % 1000000);
1379 aws_s3_meta_request_cancel(meta_request);
1380 }
1381
1382 /* Wait for the request to finish. */
1383 aws_s3_tester_wait_for_meta_request_finish(tester);
1384
1385 ASSERT_TRUE(aws_s3_meta_request_is_finished(meta_request));
1386
1387 aws_s3_tester_lock_synced_data(tester);
1388
1389 if (flags & AWS_S3_TESTER_SEND_META_REQUEST_EXPECT_SUCCESS) {
1390 ASSERT_TRUE(tester->synced_data.finish_error_code == AWS_ERROR_SUCCESS);
1391 } else if (flags & AWS_S3_TESTER_SEND_META_REQUEST_CANCEL) {
1392 ASSERT_TRUE(tester->synced_data.finish_error_code == AWS_ERROR_S3_CANCELED);
1393 } else {
1394 ASSERT_FALSE(tester->synced_data.finish_error_code == AWS_ERROR_SUCCESS);
1395 }
1396
1397 aws_s3_tester_unlock_synced_data(tester);
1398
1399 test_results->part_size = meta_request->part_size;
1400
1401 aws_s3_meta_request_release(meta_request);
1402
1403 if ((flags & AWS_S3_TESTER_SEND_META_REQUEST_DONT_WAIT_FOR_SHUTDOWN) == 0) {
1404 aws_s3_tester_wait_for_meta_request_shutdown(tester);
1405 }
1406
1407 return AWS_OP_SUCCESS;
1408 }
1409
aws_s3_tester_send_get_object_meta_request(struct aws_s3_tester * tester,struct aws_s3_client * client,struct aws_byte_cursor s3_path,uint32_t flags,struct aws_s3_meta_request_test_results * out_results)1410 int aws_s3_tester_send_get_object_meta_request(
1411 struct aws_s3_tester *tester,
1412 struct aws_s3_client *client,
1413 struct aws_byte_cursor s3_path,
1414 uint32_t flags,
1415 struct aws_s3_meta_request_test_results *out_results) {
1416
1417 struct aws_string *host_name =
1418 aws_s3_tester_build_endpoint_string(tester->allocator, &g_test_bucket_name, &g_test_s3_region);
1419
1420 /* Put together a simple S3 Get Object request. */
1421 struct aws_http_message *message =
1422 aws_s3_test_get_object_request_new(tester->allocator, aws_byte_cursor_from_string(host_name), s3_path);
1423
1424 struct aws_s3_meta_request_options options;
1425 AWS_ZERO_STRUCT(options);
1426 options.type = AWS_S3_META_REQUEST_TYPE_GET_OBJECT;
1427 options.message = message;
1428
1429 /* Trigger accelerating of our Get Object request. */
1430 struct aws_s3_meta_request_test_results meta_request_test_results;
1431 AWS_ZERO_STRUCT(meta_request_test_results);
1432
1433 if (out_results == NULL) {
1434 out_results = &meta_request_test_results;
1435 }
1436
1437 ASSERT_SUCCESS(aws_s3_tester_send_meta_request(tester, client, &options, out_results, flags));
1438
1439 if (flags & AWS_S3_TESTER_SEND_META_REQUEST_EXPECT_SUCCESS) {
1440 ASSERT_SUCCESS(aws_s3_tester_validate_get_object_results(out_results, flags));
1441 }
1442
1443 aws_s3_meta_request_test_results_clean_up(&meta_request_test_results);
1444
1445 aws_http_message_release(message);
1446 aws_string_destroy(host_name);
1447
1448 return AWS_OP_SUCCESS;
1449 }
1450
aws_s3_tester_validate_get_object_results(struct aws_s3_meta_request_test_results * meta_request_test_results,uint32_t flags)1451 int aws_s3_tester_validate_get_object_results(
1452 struct aws_s3_meta_request_test_results *meta_request_test_results,
1453 uint32_t flags) {
1454 AWS_PRECONDITION(meta_request_test_results);
1455 AWS_PRECONDITION(meta_request_test_results->tester);
1456
1457 ASSERT_TRUE(meta_request_test_results->response_headers != NULL);
1458
1459 if (aws_http_headers_has(
1460 meta_request_test_results->response_headers, aws_byte_cursor_from_c_str("Content-Range"))) {
1461 ASSERT_TRUE(meta_request_test_results->finished_response_status == 206);
1462 } else {
1463 ASSERT_TRUE(meta_request_test_results->finished_response_status == 200);
1464 }
1465
1466 ASSERT_TRUE(
1467 meta_request_test_results->finished_response_status == meta_request_test_results->headers_response_status);
1468 ASSERT_TRUE(meta_request_test_results->finished_error_code == AWS_ERROR_SUCCESS);
1469
1470 ASSERT_TRUE(meta_request_test_results->error_response_headers == NULL);
1471 ASSERT_TRUE(meta_request_test_results->error_response_body.len == 0);
1472
1473 struct aws_s3_tester *tester = meta_request_test_results->tester;
1474
1475 struct aws_byte_cursor content_length_cursor;
1476 AWS_ZERO_STRUCT(content_length_cursor);
1477 ASSERT_SUCCESS(aws_http_headers_get(
1478 meta_request_test_results->response_headers,
1479 aws_byte_cursor_from_c_str("Content-Length"),
1480 &content_length_cursor));
1481
1482 struct aws_byte_cursor sse_byte_cursor;
1483
1484 if (flags & AWS_S3_TESTER_SEND_META_REQUEST_SSE_KMS) {
1485 ASSERT_SUCCESS(
1486 aws_http_headers_get(meta_request_test_results->response_headers, g_s3_sse_header, &sse_byte_cursor));
1487 ASSERT_TRUE(aws_byte_cursor_eq_c_str(&sse_byte_cursor, "aws:kms"));
1488 }
1489
1490 if (flags & AWS_S3_TESTER_SEND_META_REQUEST_SSE_AES256) {
1491 ASSERT_SUCCESS(
1492 aws_http_headers_get(meta_request_test_results->response_headers, g_s3_sse_header, &sse_byte_cursor));
1493 ASSERT_TRUE(aws_byte_cursor_eq_c_str(&sse_byte_cursor, "AES256"));
1494 }
1495
1496 struct aws_string *content_length_str = aws_string_new_from_cursor(tester->allocator, &content_length_cursor);
1497
1498 char *content_length_str_end = NULL;
1499 uint64_t content_length = strtoull((const char *)content_length_str->bytes, &content_length_str_end, 10);
1500
1501 aws_string_destroy(content_length_str);
1502
1503 AWS_LOGF_DEBUG(
1504 AWS_LS_S3_GENERAL,
1505 "Content length in header is %" PRIu64 " and received body size is %" PRIu64,
1506 content_length,
1507 meta_request_test_results->received_body_size);
1508
1509 ASSERT_TRUE(content_length == meta_request_test_results->received_body_size);
1510
1511 return AWS_OP_SUCCESS;
1512 }
1513
aws_s3_tester_send_put_object_meta_request(struct aws_s3_tester * tester,struct aws_s3_client * client,uint32_t file_size_mb,uint32_t flags,struct aws_s3_meta_request_test_results * out_results)1514 int aws_s3_tester_send_put_object_meta_request(
1515 struct aws_s3_tester *tester,
1516 struct aws_s3_client *client,
1517 uint32_t file_size_mb,
1518 uint32_t flags,
1519 struct aws_s3_meta_request_test_results *out_results) {
1520 ASSERT_TRUE(tester != NULL);
1521 ASSERT_TRUE(client != NULL);
1522
1523 struct aws_allocator *allocator = tester->allocator;
1524
1525 struct aws_byte_buf test_buffer;
1526 aws_s3_create_test_buffer(allocator, (size_t)file_size_mb * 1024ULL * 1024ULL, &test_buffer);
1527
1528 struct aws_byte_cursor test_body_cursor = aws_byte_cursor_from_buf(&test_buffer);
1529 struct aws_input_stream *input_stream = aws_input_stream_new_from_cursor(allocator, &test_body_cursor);
1530
1531 struct aws_string *host_name =
1532 aws_s3_tester_build_endpoint_string(allocator, &g_test_bucket_name, &g_test_s3_region);
1533
1534 char object_path_buffer[128] = "";
1535
1536 if (flags & AWS_S3_TESTER_SEND_META_REQUEST_SSE_KMS) {
1537 snprintf(object_path_buffer, sizeof(object_path_buffer), "/get_object_test_kms_%uMB.txt", file_size_mb);
1538 } else if (flags & AWS_S3_TESTER_SEND_META_REQUEST_SSE_KMS) {
1539 snprintf(object_path_buffer, sizeof(object_path_buffer), "/get_object_test_aes256_%uMB.txt", file_size_mb);
1540 } else if (flags & AWS_S3_TESTER_SEND_META_REQUEST_PUT_ACL) {
1541 snprintf(
1542 object_path_buffer, sizeof(object_path_buffer), "/get_object_test_acl_public_read_%uMB.txt", file_size_mb);
1543 } else {
1544 snprintf(object_path_buffer, sizeof(object_path_buffer), "/get_object_test_%uMB.txt", file_size_mb);
1545 }
1546 struct aws_byte_cursor test_object_path = aws_byte_cursor_from_c_str(object_path_buffer);
1547
1548 /* Put together a simple S3 Put Object request. */
1549 struct aws_http_message *message = aws_s3_test_put_object_request_new(
1550 allocator,
1551 aws_byte_cursor_from_string(host_name),
1552 test_object_path,
1553 g_test_body_content_type,
1554 input_stream,
1555 flags);
1556
1557 if (flags & AWS_S3_TESTER_SEND_META_REQUEST_WITH_CORRECT_CONTENT_MD5) {
1558 ASSERT_SUCCESS(aws_s3_message_util_add_content_md5_header(allocator, &test_buffer, message));
1559 } else if (flags & AWS_S3_TESTER_SEND_META_REQUEST_WITH_INCORRECT_CONTENT_MD5) {
1560 struct aws_http_header content_md5_header = {
1561 .name = g_content_md5_header_name,
1562 .value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("dummy_content_md5"),
1563 };
1564 ASSERT_SUCCESS(aws_http_message_add_header(message, content_md5_header));
1565 }
1566
1567 struct aws_s3_meta_request_options options;
1568 AWS_ZERO_STRUCT(options);
1569 options.type = AWS_S3_META_REQUEST_TYPE_PUT_OBJECT;
1570 options.message = message;
1571
1572 struct aws_s3_meta_request_test_results meta_request_test_results;
1573 AWS_ZERO_STRUCT(meta_request_test_results);
1574
1575 if (out_results == NULL) {
1576 out_results = &meta_request_test_results;
1577 }
1578
1579 ASSERT_SUCCESS(aws_s3_tester_send_meta_request(tester, client, &options, out_results, flags));
1580
1581 if (flags & AWS_S3_TESTER_SEND_META_REQUEST_EXPECT_SUCCESS) {
1582 ASSERT_SUCCESS(aws_s3_tester_validate_put_object_results(out_results, flags));
1583 }
1584
1585 aws_s3_meta_request_test_results_clean_up(&meta_request_test_results);
1586
1587 aws_http_message_release(message);
1588 message = NULL;
1589
1590 aws_string_destroy(host_name);
1591 host_name = NULL;
1592
1593 aws_input_stream_destroy(input_stream);
1594 input_stream = NULL;
1595
1596 aws_byte_buf_clean_up(&test_buffer);
1597
1598 return AWS_OP_SUCCESS;
1599 }
1600
aws_s3_tester_validate_put_object_results(struct aws_s3_meta_request_test_results * meta_request_test_results,uint32_t flags)1601 int aws_s3_tester_validate_put_object_results(
1602 struct aws_s3_meta_request_test_results *meta_request_test_results,
1603 uint32_t flags) {
1604 ASSERT_TRUE(meta_request_test_results->finished_response_status == 200);
1605 ASSERT_TRUE(
1606 meta_request_test_results->finished_response_status == meta_request_test_results->headers_response_status);
1607 ASSERT_TRUE(meta_request_test_results->finished_error_code == AWS_ERROR_SUCCESS);
1608
1609 ASSERT_TRUE(meta_request_test_results->error_response_headers == NULL);
1610 ASSERT_TRUE(meta_request_test_results->error_response_body.len == 0);
1611
1612 struct aws_byte_cursor etag_byte_cursor;
1613 AWS_ZERO_STRUCT(etag_byte_cursor);
1614 ASSERT_SUCCESS(
1615 aws_http_headers_get(meta_request_test_results->response_headers, g_etag_header_name, &etag_byte_cursor));
1616 struct aws_byte_cursor sse_byte_cursor;
1617 if (flags & AWS_S3_TESTER_SEND_META_REQUEST_SSE_KMS) {
1618 ASSERT_SUCCESS(
1619 aws_http_headers_get(meta_request_test_results->response_headers, g_s3_sse_header, &sse_byte_cursor));
1620 ASSERT_TRUE(aws_byte_cursor_eq_c_str(&sse_byte_cursor, "aws:kms"));
1621 }
1622 if (flags & AWS_S3_TESTER_SEND_META_REQUEST_SSE_AES256) {
1623 ASSERT_SUCCESS(
1624 aws_http_headers_get(meta_request_test_results->response_headers, g_s3_sse_header, &sse_byte_cursor));
1625 ASSERT_TRUE(aws_byte_cursor_eq_c_str(&sse_byte_cursor, "AES256"));
1626 }
1627 ASSERT_TRUE(etag_byte_cursor.len > 0);
1628
1629 struct aws_byte_cursor quote_entity = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL(""");
1630
1631 if (etag_byte_cursor.len >= quote_entity.len) {
1632 for (size_t i = 0; i < (etag_byte_cursor.len - quote_entity.len + 1); ++i) {
1633 ASSERT_TRUE(
1634 strncmp((const char *)&etag_byte_cursor.ptr[i], (const char *)quote_entity.ptr, quote_entity.len) != 0);
1635 }
1636 }
1637
1638 return AWS_OP_SUCCESS;
1639 }
1640