@@ -815,7 +815,7 @@ AWS_TEST_CASE(
815815 connection_manager_max_pending_acquisitions_with_vended_connections ,
816816 s_test_connection_manager_max_pending_acquisitions_with_vended_connections );
817817
818- static int s_aws_http_connection_manager_create_connection_sync_mock (
818+ static int s_aws_http_connection_manager_create_connection_validate (
819819 const struct aws_http_client_connection_options * options ) {
820820 struct cm_tester * tester = & s_tester ;
821821
@@ -826,8 +826,6 @@ static int s_aws_http_connection_manager_create_connection_sync_mock(
826826 ASSERT_TRUE (aws_byte_cursor_eq_c_str (& interface_name , options -> socket_options -> network_interface_name ));
827827 }
828828
829- size_t next_connection_id = aws_atomic_fetch_add (& tester -> next_connection_id , 1 );
830-
831829 ASSERT_SUCCESS (aws_mutex_lock (& tester -> lock ));
832830 tester -> release_connection_fn = options -> on_shutdown ;
833831 ASSERT_SUCCESS (aws_mutex_unlock (& tester -> lock ));
@@ -843,7 +841,15 @@ static int s_aws_http_connection_manager_create_connection_sync_mock(
843841 ASSERT_UINT_EQUALS (options -> proxy_options -> connection_type , tester -> verify_proxy_options -> connection_type );
844842 }
845843
844+ return AWS_OP_SUCCESS ;
845+ }
846+ static int s_aws_http_connection_manager_create_connection_sync_mock (
847+ const struct aws_http_client_connection_options * options ) {
848+ s_aws_http_connection_manager_create_connection_validate (options );
849+ struct cm_tester * tester = & s_tester ;
850+
846851 struct mock_connection * connection = NULL ;
852+ size_t next_connection_id = aws_atomic_fetch_add (& tester -> next_connection_id , 1 );
847853
848854 if (next_connection_id < aws_array_list_length (& tester -> mock_connections )) {
849855 aws_array_list_get_at (& tester -> mock_connections , & connection , next_connection_id );
@@ -864,6 +870,63 @@ static int s_aws_http_connection_manager_create_connection_sync_mock(
864870 return aws_raise_error (AWS_ERROR_HTTP_UNKNOWN );
865871}
866872
873+ struct connect_task_args {
874+ void * user_data ;
875+ struct mock_connection * connection ;
876+ aws_http_on_client_connection_setup_fn * on_setup ;
877+ };
878+
879+ static void s_aws_http_connection_manager_connect_task (
880+ struct aws_task * task ,
881+ void * user_data ,
882+ enum aws_task_status status ) {
883+ (void )status ;
884+ struct cm_tester * tester = & s_tester ;
885+
886+ struct connect_task_args * task_args = user_data ;
887+ struct mock_connection * connection = task_args -> connection ;
888+ if (connection ) {
889+ if (connection -> result == AWS_NCRT_SUCCESS ) {
890+ task_args -> on_setup ((struct aws_http_connection * )connection , AWS_ERROR_SUCCESS , task_args -> user_data );
891+ } else if (connection -> result == AWS_NCRT_ERROR_VIA_CALLBACK ) {
892+ task_args -> on_setup (NULL , AWS_ERROR_HTTP_UNKNOWN , task_args -> user_data );
893+ } else {
894+ AWS_FATAL_ASSERT (0 && "Unexpected connection->result" );
895+ }
896+ }
897+
898+ aws_mem_release (tester -> allocator , task );
899+ aws_mem_release (tester -> allocator , task_args );
900+ }
901+
902+ static int s_aws_http_connection_manager_connect_async_mock (const struct aws_http_client_connection_options * options ) {
903+ s_aws_http_connection_manager_create_connection_validate (options );
904+ struct cm_tester * tester = & s_tester ;
905+
906+ struct mock_connection * connection = NULL ;
907+ size_t next_connection_id = aws_atomic_fetch_add (& tester -> next_connection_id , 1 );
908+ if (next_connection_id < aws_array_list_length (& tester -> mock_connections )) {
909+ aws_array_list_get_at (& tester -> mock_connections , & connection , next_connection_id );
910+ }
911+
912+ if (connection -> result == AWS_NCRT_ERROR_FROM_CREATE ) {
913+ return aws_raise_error (AWS_ERROR_HTTP_UNKNOWN );
914+ }
915+
916+ struct aws_task * task = aws_mem_calloc (options -> allocator , 1 , sizeof (struct aws_task ));
917+ struct connect_task_args * task_args = aws_mem_calloc (options -> allocator , 1 , sizeof (struct connect_task_args ));
918+ task_args -> connection = connection ;
919+ task_args -> user_data = options -> user_data ;
920+ task_args -> on_setup = options -> on_setup ;
921+ aws_task_init (task , s_aws_http_connection_manager_connect_task , task_args , "create_connection_task" );
922+
923+ struct aws_event_loop * event_loop = aws_event_loop_group_get_next_loop (tester -> event_loop_group );
924+ uint64_t now ;
925+ ASSERT_SUCCESS (aws_event_loop_current_clock_time (event_loop , & now ));
926+ aws_event_loop_schedule_task_future (event_loop , task , now + 1000000000 );
927+ return AWS_OP_SUCCESS ;
928+ }
929+
867930static void s_aws_http_connection_manager_release_connection_sync_mock (struct aws_http_connection * connection ) {
868931 (void )connection ;
869932
@@ -916,6 +979,17 @@ static struct aws_http_connection_manager_system_vtable s_synchronous_mocks = {
916979 .aws_http_connection_get_version = s_aws_http_connection_manager_connection_get_version_sync_mock ,
917980};
918981
982+ static struct aws_http_connection_manager_system_vtable s_async_connect_mock = {
983+ .aws_http_client_connect = s_aws_http_connection_manager_connect_async_mock ,
984+ .aws_http_connection_release = s_aws_http_connection_manager_release_connection_sync_mock ,
985+ .aws_http_connection_close = s_aws_http_connection_manager_close_connection_sync_mock ,
986+ .aws_http_connection_new_requests_allowed = s_aws_http_connection_manager_is_connection_available_sync_mock ,
987+ .aws_high_res_clock_get_ticks = aws_high_res_clock_get_ticks ,
988+ .aws_http_connection_get_channel = s_aws_http_connection_manager_connection_get_channel_sync_mock ,
989+ .aws_channel_thread_is_callers_thread = s_aws_http_connection_manager_is_callers_thread_sync_mock ,
990+ .aws_http_connection_get_version = s_aws_http_connection_manager_connection_get_version_sync_mock ,
991+ };
992+
919993static int s_test_connection_manager_with_network_interface_list (struct aws_allocator * allocator , void * ctx ) {
920994 (void )ctx ;
921995 struct aws_byte_cursor * interface_names_array = aws_mem_calloc (allocator , 3 , sizeof (struct aws_byte_cursor ));
@@ -1051,6 +1125,68 @@ static int s_test_connection_manager_connect_callback_failure(struct aws_allocat
10511125}
10521126AWS_TEST_CASE (connection_manager_connect_callback_failure , s_test_connection_manager_connect_callback_failure );
10531127
1128+ static int s_test_connection_manager_connect_callback_async_failure (struct aws_allocator * allocator , void * ctx ) {
1129+ (void )ctx ;
1130+ int error_connections = 5 ;
1131+ int success_connections = 5 ;
1132+ struct cm_tester_options options = {
1133+ .allocator = allocator ,
1134+ .max_connections = error_connections ,
1135+ .mock_table = & s_async_connect_mock ,
1136+ };
1137+
1138+ ASSERT_SUCCESS (s_cm_tester_init (& options ));
1139+
1140+ s_add_mock_connections (error_connections , AWS_NCRT_ERROR_VIA_CALLBACK , false);
1141+ s_add_mock_connections (success_connections , AWS_NCRT_SUCCESS , true);
1142+
1143+ s_acquire_connections (error_connections + success_connections );
1144+
1145+ ASSERT_SUCCESS (s_wait_on_connection_reply_count (error_connections + success_connections ));
1146+
1147+ ASSERT_UINT_EQUALS (s_tester .connection_errors , error_connections );
1148+ ASSERT_SUCCESS (s_release_connections (success_connections , false));
1149+
1150+ ASSERT_SUCCESS (s_cm_tester_clean_up ());
1151+
1152+ return AWS_OP_SUCCESS ;
1153+ }
1154+ AWS_TEST_CASE (
1155+ test_connection_manager_connect_callback_async_failure ,
1156+ s_test_connection_manager_connect_callback_async_failure );
1157+
1158+ static int s_test_connection_manager_connect_callback_async_with_immediate_failure (
1159+ struct aws_allocator * allocator ,
1160+ void * ctx ) {
1161+ (void )ctx ;
1162+ int error_connections = 5 ;
1163+ int success_connections = 5 ;
1164+ struct cm_tester_options options = {
1165+ .allocator = allocator ,
1166+ .max_connections = error_connections + success_connections ,
1167+ .mock_table = & s_async_connect_mock ,
1168+ };
1169+
1170+ ASSERT_SUCCESS (s_cm_tester_init (& options ));
1171+
1172+ s_add_mock_connections (success_connections , AWS_NCRT_SUCCESS , true);
1173+ s_add_mock_connections (error_connections , AWS_NCRT_ERROR_VIA_CALLBACK , false);
1174+
1175+ s_acquire_connections (error_connections + success_connections );
1176+
1177+ ASSERT_SUCCESS (s_wait_on_connection_reply_count (error_connections + success_connections ));
1178+
1179+ ASSERT_UINT_EQUALS (s_tester .connection_errors , error_connections );
1180+ ASSERT_SUCCESS (s_release_connections (success_connections , false));
1181+
1182+ ASSERT_SUCCESS (s_cm_tester_clean_up ());
1183+
1184+ return AWS_OP_SUCCESS ;
1185+ }
1186+ AWS_TEST_CASE (
1187+ test_connection_manager_connect_callback_async_with_immediate_failure ,
1188+ s_test_connection_manager_connect_callback_async_with_immediate_failure );
1189+
10541190static int s_test_connection_manager_connect_immediate_failure (struct aws_allocator * allocator , void * ctx ) {
10551191 (void )ctx ;
10561192
0 commit comments