@@ -819,7 +819,7 @@ AWS_TEST_CASE(
819819 connection_manager_max_pending_acquisitions_with_vended_connections ,
820820 s_test_connection_manager_max_pending_acquisitions_with_vended_connections );
821821
822- static int s_aws_http_connection_manager_create_connection_sync_mock (
822+ static int s_aws_http_connection_manager_create_connection_validate (
823823 const struct aws_http_client_connection_options * options ) {
824824 struct cm_tester * tester = & s_tester ;
825825
@@ -830,8 +830,6 @@ static int s_aws_http_connection_manager_create_connection_sync_mock(
830830 ASSERT_TRUE (aws_byte_cursor_eq_c_str (& interface_name , options -> socket_options -> network_interface_name ));
831831 }
832832
833- size_t next_connection_id = aws_atomic_fetch_add (& tester -> next_connection_id , 1 );
834-
835833 ASSERT_SUCCESS (aws_mutex_lock (& tester -> lock ));
836834 tester -> release_connection_fn = options -> on_shutdown ;
837835 ASSERT_SUCCESS (aws_mutex_unlock (& tester -> lock ));
@@ -847,7 +845,15 @@ static int s_aws_http_connection_manager_create_connection_sync_mock(
847845 ASSERT_UINT_EQUALS (options -> proxy_options -> connection_type , tester -> verify_proxy_options -> connection_type );
848846 }
849847
848+ return AWS_OP_SUCCESS ;
849+ }
850+ static int s_aws_http_connection_manager_create_connection_sync_mock (
851+ const struct aws_http_client_connection_options * options ) {
852+ s_aws_http_connection_manager_create_connection_validate (options );
853+ struct cm_tester * tester = & s_tester ;
854+
850855 struct mock_connection * connection = NULL ;
856+ size_t next_connection_id = aws_atomic_fetch_add (& tester -> next_connection_id , 1 );
851857
852858 if (next_connection_id < aws_array_list_length (& tester -> mock_connections )) {
853859 aws_array_list_get_at (& tester -> mock_connections , & connection , next_connection_id );
@@ -868,6 +874,63 @@ static int s_aws_http_connection_manager_create_connection_sync_mock(
868874 return aws_raise_error (AWS_ERROR_HTTP_UNKNOWN );
869875}
870876
877+ struct connect_task_args {
878+ void * user_data ;
879+ struct mock_connection * connection ;
880+ aws_http_on_client_connection_setup_fn * on_setup ;
881+ };
882+
883+ static void s_aws_http_connection_manager_connect_task (
884+ struct aws_task * task ,
885+ void * user_data ,
886+ enum aws_task_status status ) {
887+ (void )status ;
888+ struct cm_tester * tester = & s_tester ;
889+
890+ struct connect_task_args * task_args = user_data ;
891+ struct mock_connection * connection = task_args -> connection ;
892+ if (connection ) {
893+ if (connection -> result == AWS_NCRT_SUCCESS ) {
894+ task_args -> on_setup ((struct aws_http_connection * )connection , AWS_ERROR_SUCCESS , task_args -> user_data );
895+ } else if (connection -> result == AWS_NCRT_ERROR_VIA_CALLBACK ) {
896+ task_args -> on_setup (NULL , AWS_ERROR_HTTP_UNKNOWN , task_args -> user_data );
897+ } else {
898+ AWS_FATAL_ASSERT (0 && "Unexpected connection->result" );
899+ }
900+ }
901+
902+ aws_mem_release (tester -> allocator , task );
903+ aws_mem_release (tester -> allocator , task_args );
904+ }
905+
906+ static int s_aws_http_connection_manager_connect_async_mock (const struct aws_http_client_connection_options * options ) {
907+ s_aws_http_connection_manager_create_connection_validate (options );
908+ struct cm_tester * tester = & s_tester ;
909+
910+ struct mock_connection * connection = NULL ;
911+ size_t next_connection_id = aws_atomic_fetch_add (& tester -> next_connection_id , 1 );
912+ if (next_connection_id < aws_array_list_length (& tester -> mock_connections )) {
913+ aws_array_list_get_at (& tester -> mock_connections , & connection , next_connection_id );
914+ }
915+
916+ if (connection -> result == AWS_NCRT_ERROR_FROM_CREATE ) {
917+ return aws_raise_error (AWS_ERROR_HTTP_UNKNOWN );
918+ }
919+
920+ struct aws_task * task = aws_mem_calloc (options -> allocator , 1 , sizeof (struct aws_task ));
921+ struct connect_task_args * task_args = aws_mem_calloc (options -> allocator , 1 , sizeof (struct connect_task_args ));
922+ task_args -> connection = connection ;
923+ task_args -> user_data = options -> user_data ;
924+ task_args -> on_setup = options -> on_setup ;
925+ aws_task_init (task , s_aws_http_connection_manager_connect_task , task_args , "create_connection_task" );
926+
927+ struct aws_event_loop * event_loop = aws_event_loop_group_get_next_loop (tester -> event_loop_group );
928+ uint64_t now ;
929+ ASSERT_SUCCESS (aws_event_loop_current_clock_time (event_loop , & now ));
930+ aws_event_loop_schedule_task_future (event_loop , task , now + 1000000000 );
931+ return AWS_OP_SUCCESS ;
932+ }
933+
871934static void s_aws_http_connection_manager_release_connection_sync_mock (struct aws_http_connection * connection ) {
872935 (void )connection ;
873936
@@ -920,6 +983,17 @@ static struct aws_http_connection_manager_system_vtable s_synchronous_mocks = {
920983 .aws_http_connection_get_version = s_aws_http_connection_manager_connection_get_version_sync_mock ,
921984};
922985
986+ static struct aws_http_connection_manager_system_vtable s_async_connect_mock = {
987+ .aws_http_client_connect = s_aws_http_connection_manager_connect_async_mock ,
988+ .aws_http_connection_release = s_aws_http_connection_manager_release_connection_sync_mock ,
989+ .aws_http_connection_close = s_aws_http_connection_manager_close_connection_sync_mock ,
990+ .aws_http_connection_new_requests_allowed = s_aws_http_connection_manager_is_connection_available_sync_mock ,
991+ .aws_high_res_clock_get_ticks = aws_high_res_clock_get_ticks ,
992+ .aws_http_connection_get_channel = s_aws_http_connection_manager_connection_get_channel_sync_mock ,
993+ .aws_channel_thread_is_callers_thread = s_aws_http_connection_manager_is_callers_thread_sync_mock ,
994+ .aws_http_connection_get_version = s_aws_http_connection_manager_connection_get_version_sync_mock ,
995+ };
996+
923997static int s_test_connection_manager_with_network_interface_list (struct aws_allocator * allocator , void * ctx ) {
924998 (void )ctx ;
925999 struct aws_byte_cursor * interface_names_array = aws_mem_calloc (allocator , 3 , sizeof (struct aws_byte_cursor ));
@@ -1055,6 +1129,68 @@ static int s_test_connection_manager_connect_callback_failure(struct aws_allocat
10551129}
10561130AWS_TEST_CASE (connection_manager_connect_callback_failure , s_test_connection_manager_connect_callback_failure );
10571131
1132+ static int s_test_connection_manager_connect_callback_async_failure (struct aws_allocator * allocator , void * ctx ) {
1133+ (void )ctx ;
1134+ int error_connections = 5 ;
1135+ int success_connections = 5 ;
1136+ struct cm_tester_options options = {
1137+ .allocator = allocator ,
1138+ .max_connections = error_connections ,
1139+ .mock_table = & s_async_connect_mock ,
1140+ };
1141+
1142+ ASSERT_SUCCESS (s_cm_tester_init (& options ));
1143+
1144+ s_add_mock_connections (error_connections , AWS_NCRT_ERROR_VIA_CALLBACK , false);
1145+ s_add_mock_connections (success_connections , AWS_NCRT_SUCCESS , true);
1146+
1147+ s_acquire_connections (error_connections + success_connections );
1148+
1149+ ASSERT_SUCCESS (s_wait_on_connection_reply_count (error_connections + success_connections ));
1150+
1151+ ASSERT_UINT_EQUALS (s_tester .connection_errors , error_connections );
1152+ ASSERT_SUCCESS (s_release_connections (success_connections , false));
1153+
1154+ ASSERT_SUCCESS (s_cm_tester_clean_up ());
1155+
1156+ return AWS_OP_SUCCESS ;
1157+ }
1158+ AWS_TEST_CASE (
1159+ test_connection_manager_connect_callback_async_failure ,
1160+ s_test_connection_manager_connect_callback_async_failure );
1161+
1162+ static int s_test_connection_manager_connect_callback_async_with_immediate_failure (
1163+ struct aws_allocator * allocator ,
1164+ void * ctx ) {
1165+ (void )ctx ;
1166+ int error_connections = 5 ;
1167+ int success_connections = 5 ;
1168+ struct cm_tester_options options = {
1169+ .allocator = allocator ,
1170+ .max_connections = error_connections + success_connections ,
1171+ .mock_table = & s_async_connect_mock ,
1172+ };
1173+
1174+ ASSERT_SUCCESS (s_cm_tester_init (& options ));
1175+
1176+ s_add_mock_connections (success_connections , AWS_NCRT_SUCCESS , true);
1177+ s_add_mock_connections (error_connections , AWS_NCRT_ERROR_VIA_CALLBACK , false);
1178+
1179+ s_acquire_connections (error_connections + success_connections );
1180+
1181+ ASSERT_SUCCESS (s_wait_on_connection_reply_count (error_connections + success_connections ));
1182+
1183+ ASSERT_UINT_EQUALS (s_tester .connection_errors , error_connections );
1184+ ASSERT_SUCCESS (s_release_connections (success_connections , false));
1185+
1186+ ASSERT_SUCCESS (s_cm_tester_clean_up ());
1187+
1188+ return AWS_OP_SUCCESS ;
1189+ }
1190+ AWS_TEST_CASE (
1191+ test_connection_manager_connect_callback_async_with_immediate_failure ,
1192+ s_test_connection_manager_connect_callback_async_with_immediate_failure );
1193+
10581194static int s_test_connection_manager_connect_immediate_failure (struct aws_allocator * allocator , void * ctx ) {
10591195 (void )ctx ;
10601196
0 commit comments