@@ -364,6 +364,152 @@ static int s_test_s3_get_num_parts_and_get_part_range(struct aws_allocator *allo
364
364
return 0 ;
365
365
}
366
366
367
+ struct s3_request_part_config_example {
368
+ const char * name ;
369
+ uint64_t content_length ;
370
+ size_t client_part_size ;
371
+ uint64_t client_max_part_size ;
372
+ size_t expected_part_size ;
373
+ uint32_t expected_num_parts ;
374
+ };
375
+
376
+ AWS_TEST_CASE (test_s3_mpu_get_part_size_and_num_parts , s_test_s3_mpu_get_part_size_and_num_parts )
377
+ static int s_test_s3_mpu_get_part_size_and_num_parts (struct aws_allocator * allocator , void * ctx ) {
378
+ (void )allocator ;
379
+ (void )ctx ;
380
+ uint64_t default_max_part_size = 5368709120ULL ;
381
+
382
+ const struct s3_request_part_config_example valid_request_part_config [] = {
383
+ {
384
+ .name = "simple case" ,
385
+ .content_length = MB_TO_BYTES ((uint64_t )10000 ),
386
+ .client_part_size = MB_TO_BYTES (5 ),
387
+ .client_max_part_size = default_max_part_size ,
388
+ .expected_part_size = 5242880 ,
389
+ .expected_num_parts = 2000 ,
390
+ },
391
+ {
392
+ .name = "large content length with small part size" ,
393
+ .content_length = MB_TO_BYTES ((uint64_t )990000 ),
394
+ .client_part_size = MB_TO_BYTES (5 ),
395
+ .client_max_part_size = default_max_part_size ,
396
+ .expected_part_size = 103809024 ,
397
+ .expected_num_parts = 10000 ,
398
+ },
399
+ {
400
+
401
+ .name = "large content length with large part size" ,
402
+ .content_length = MB_TO_BYTES ((uint64_t )1000000 ),
403
+ .client_part_size = MB_TO_BYTES (500 ),
404
+ .client_max_part_size = default_max_part_size ,
405
+ .expected_part_size = MB_TO_BYTES (500 ),
406
+ .expected_num_parts = 2000 ,
407
+ },
408
+ {
409
+ .name = "large odd content length" ,
410
+ .content_length = 1044013645824 ,
411
+ .client_part_size = 5242880 ,
412
+ .client_max_part_size = default_max_part_size ,
413
+ .expected_part_size = 104401365 ,
414
+ .expected_num_parts = 10000 ,
415
+ },
416
+ {
417
+ .name = "10k parts" ,
418
+ .content_length = MB_TO_BYTES ((uint64_t )50000 ),
419
+ .client_part_size = MB_TO_BYTES (5 ),
420
+ .client_max_part_size = default_max_part_size ,
421
+ .expected_part_size = MB_TO_BYTES (5 ),
422
+ .expected_num_parts = 10000 ,
423
+ },
424
+ {
425
+ .name = "10k - 1 parts" ,
426
+ .content_length = 49995 ,
427
+ .client_part_size = 5 ,
428
+ .client_max_part_size = default_max_part_size ,
429
+ .expected_part_size = 5 ,
430
+ .expected_num_parts = 9999 ,
431
+ },
432
+ {
433
+ .name = "10k with small last part" ,
434
+ .content_length = 49998 ,
435
+ .client_part_size = 5 ,
436
+ .client_max_part_size = default_max_part_size ,
437
+ .expected_part_size = 5 ,
438
+ .expected_num_parts = 10000 ,
439
+ },
440
+ {
441
+ .name = "10k + 1 parts" ,
442
+ .content_length = 50001 ,
443
+ .client_part_size = 5 ,
444
+ .client_max_part_size = default_max_part_size ,
445
+ .expected_part_size = 6 ,
446
+ .expected_num_parts = 8334 ,
447
+
448
+ },
449
+ {
450
+ .name = "bump content length" ,
451
+ .content_length = 100000 ,
452
+ .client_part_size = 5 ,
453
+ .client_max_part_size = default_max_part_size ,
454
+ .expected_part_size = 10 ,
455
+ .expected_num_parts = 10000 ,
456
+ },
457
+ {
458
+ .name = "bump content length with non-zero mod" ,
459
+ .content_length = 999999 ,
460
+ .client_part_size = 5 ,
461
+ .client_max_part_size = default_max_part_size ,
462
+ .expected_part_size = 100 ,
463
+ .expected_num_parts = 10000 ,
464
+ },
465
+ {
466
+ .name = "5 tb content length" ,
467
+ .content_length = MB_TO_BYTES ((uint64_t )5 * 1024 * 1024 ),
468
+ .client_part_size = MB_TO_BYTES ((uint64_t )5 ),
469
+ .client_max_part_size = default_max_part_size ,
470
+ .expected_part_size = 549755814 ,
471
+ .expected_num_parts = 10000 ,
472
+ },
473
+ };
474
+ for (size_t i = 0 ; i < AWS_ARRAY_SIZE (valid_request_part_config ); ++ i ) {
475
+ AWS_LOGF_INFO (AWS_LS_S3_GENERAL , "valid example [%zu]: %s\n" , i , valid_request_part_config [i ].name );
476
+
477
+ uint64_t content_length = valid_request_part_config [i ].content_length ;
478
+ size_t part_size ;
479
+ uint32_t num_parts ;
480
+
481
+ ASSERT_SUCCESS (aws_s3_calculate_optimal_mpu_part_size_and_num_parts (
482
+ content_length ,
483
+ valid_request_part_config [i ].client_part_size ,
484
+ valid_request_part_config [i ].client_max_part_size ,
485
+ & part_size ,
486
+ & num_parts ));
487
+ ASSERT_INT_EQUALS (valid_request_part_config [i ].expected_part_size , part_size );
488
+ ASSERT_INT_EQUALS (valid_request_part_config [i ].expected_num_parts , num_parts );
489
+ }
490
+
491
+ /* Invalid cases */
492
+ const struct s3_request_part_config_example invalid_request_part_config [] = {{
493
+ .name = "max part < required part size" ,
494
+ .content_length = 900000 ,
495
+ .client_part_size = 5 ,
496
+ .client_max_part_size = 10 ,
497
+ }};
498
+
499
+ for (size_t i = 0 ; i < AWS_ARRAY_SIZE (invalid_request_part_config ); ++ i ) {
500
+ printf ("invalid example [%zu]: %s\n" , i , invalid_request_part_config [i ].name );
501
+ size_t part_size ;
502
+ uint32_t num_parts ;
503
+ ASSERT_FAILS (aws_s3_calculate_optimal_mpu_part_size_and_num_parts (
504
+ invalid_request_part_config [i ].content_length ,
505
+ invalid_request_part_config [i ].client_part_size ,
506
+ invalid_request_part_config [i ].client_max_part_size ,
507
+ & part_size ,
508
+ & num_parts ));
509
+ }
510
+ return AWS_OP_SUCCESS ;
511
+ }
512
+
367
513
AWS_TEST_CASE (test_s3_aws_xml_get_top_level_tag_with_root_name , s_test_s3_aws_xml_get_top_level_tag_with_root_name )
368
514
static int s_test_s3_aws_xml_get_top_level_tag_with_root_name (struct aws_allocator * allocator , void * ctx ) {
369
515
(void )allocator ;
0 commit comments