LCOV - code coverage report
Current view: top level - glib/gio/tests - gsocketclient-slow.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 81 81 100.0 %
Date: 2024-04-23 05:16:05 Functions: 7 7 100.0 %
Branches: 6 6 100.0 %

           Branch data     Line data    Source code
       1                 :            : /* GIO - GLib Input, Output and Streaming Library
       2                 :            :  *
       3                 :            :  * Copyright (C) 2018 Igalia S.L.
       4                 :            :  *
       5                 :            :  * SPDX-License-Identifier: LGPL-2.1-or-later
       6                 :            :  *
       7                 :            :  * This library is free software; you can redistribute it and/or
       8                 :            :  * modify it under the terms of the GNU Lesser General Public
       9                 :            :  * License as published by the Free Software Foundation; either
      10                 :            :  * version 2.1 of the License, or (at your option) any later version.
      11                 :            :  *
      12                 :            :  * This library is distributed in the hope that it will be useful,
      13                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15                 :            :  * Lesser General Public License for more details.
      16                 :            :  *
      17                 :            :  * You should have received a copy of the GNU Lesser General
      18                 :            :  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      19                 :            :  */
      20                 :            : 
      21                 :            : #include <gio/gio.h>
      22                 :            : 
      23                 :            : static void
      24                 :          1 : on_connected (GObject      *source_object,
      25                 :            :               GAsyncResult *result,
      26                 :            :               gpointer      user_data)
      27                 :            : {
      28                 :            :   GSocketConnection *conn;
      29                 :          1 :   GError *error = NULL;
      30                 :            : 
      31                 :          1 :   conn = g_socket_client_connect_to_uri_finish (G_SOCKET_CLIENT (source_object), result, &error);
      32                 :          1 :   g_assert_no_error (error);
      33                 :            : 
      34                 :          1 :   g_object_unref (conn);
      35                 :          1 :   g_main_loop_quit (user_data);
      36                 :          1 : }
      37                 :            : 
      38                 :            : static void
      39                 :          1 : test_happy_eyeballs (void)
      40                 :            : {
      41                 :            :   GSocketClient *client;
      42                 :            :   GSocketService *service;
      43                 :          1 :   GError *error = NULL;
      44                 :            :   guint16 port;
      45                 :            :   GMainLoop *loop;
      46                 :            : 
      47                 :          1 :   loop = g_main_loop_new (NULL, FALSE);
      48                 :            : 
      49                 :          1 :   service = g_socket_service_new ();
      50                 :          1 :   port = g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL, &error);
      51                 :          1 :   g_assert_no_error (error);
      52                 :          1 :   g_socket_service_start (service);
      53                 :            : 
      54                 :            :   /* All of the magic here actually happens in slow-connect-preload.c
      55                 :            :    * which as you would guess is preloaded. So this is just making a
      56                 :            :    * normal connection that happens to take 600ms each time. This will
      57                 :            :    * trigger the logic to make multiple parallel connections.
      58                 :            :    */
      59                 :          1 :   client = g_socket_client_new ();
      60                 :          1 :   g_socket_client_connect_to_host_async (client, "localhost", port, NULL, on_connected, loop);
      61                 :          1 :   g_main_loop_run (loop);
      62                 :            : 
      63                 :          1 :   g_main_loop_unref (loop);
      64                 :          1 :   g_object_unref (service);
      65                 :          1 :   g_object_unref (client);
      66                 :          1 : }
      67                 :            : 
      68                 :            : static void
      69                 :          2 : on_connected_cancelled (GObject      *source_object,
      70                 :            :                         GAsyncResult *result,
      71                 :            :                         gpointer      user_data)
      72                 :            : {
      73                 :            :   GSocketConnection *conn;
      74                 :          2 :   GError *error = NULL;
      75                 :            : 
      76                 :          2 :   conn = g_socket_client_connect_to_uri_finish (G_SOCKET_CLIENT (source_object), result, &error);
      77                 :          2 :   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
      78                 :          2 :   g_assert_null (conn);
      79                 :            : 
      80                 :          2 :   g_error_free (error);
      81                 :          2 :   g_main_loop_quit (user_data);
      82                 :          2 : }
      83                 :            : 
      84                 :            : typedef struct
      85                 :            : {
      86                 :            :   GCancellable *cancellable;
      87                 :            :   gboolean completed;
      88                 :            : } EventCallbackData;
      89                 :            : 
      90                 :            : static void
      91                 :          5 : on_event (GSocketClient      *client,
      92                 :            :           GSocketClientEvent  event,
      93                 :            :           GSocketConnectable *connectable,
      94                 :            :           GIOStream          *connection,
      95                 :            :           EventCallbackData  *data)
      96                 :            : {
      97   [ +  +  +  + ]:          5 :   if (data->cancellable && event == G_SOCKET_CLIENT_CONNECTED)
      98                 :            :     {
      99                 :          1 :       g_cancellable_cancel (data->cancellable);
     100                 :            :     }
     101         [ +  + ]:          4 :   else if (event == G_SOCKET_CLIENT_COMPLETE)
     102                 :            :     {
     103                 :          2 :       data->completed = TRUE;
     104                 :          2 :       g_assert_null (connection);
     105                 :            :     }
     106                 :          5 : }
     107                 :            : 
     108                 :            : static void
     109                 :          1 : test_happy_eyeballs_cancel_delayed (void)
     110                 :            : {
     111                 :            :   GSocketClient *client;
     112                 :            :   GSocketService *service;
     113                 :          1 :   GError *error = NULL;
     114                 :            :   guint16 port;
     115                 :            :   GMainLoop *loop;
     116                 :          1 :   EventCallbackData data = { NULL, FALSE };
     117                 :            : 
     118                 :            :   /* This just tests that cancellation works as expected, still emits the completed signal,
     119                 :            :    * and never returns a connection */
     120                 :            : 
     121                 :          1 :   loop = g_main_loop_new (NULL, FALSE);
     122                 :            : 
     123                 :          1 :   service = g_socket_service_new ();
     124                 :          1 :   port = g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL, &error);
     125                 :          1 :   g_assert_no_error (error);
     126                 :          1 :   g_socket_service_start (service);
     127                 :            : 
     128                 :          1 :   client = g_socket_client_new ();
     129                 :          1 :   data.cancellable = g_cancellable_new ();
     130                 :          1 :   g_socket_client_connect_to_host_async (client, "localhost", port, data.cancellable, on_connected_cancelled, loop);
     131                 :          1 :   g_signal_connect (client, "event", G_CALLBACK (on_event), &data);
     132                 :          1 :   g_main_loop_run (loop);
     133                 :            : 
     134                 :          1 :   g_assert_true (data.completed);
     135                 :          1 :   g_main_loop_unref (loop);
     136                 :          1 :   g_object_unref (service);
     137                 :          1 :   g_object_unref (client);
     138                 :          1 :   g_object_unref (data.cancellable);
     139                 :          1 : }
     140                 :            : 
     141                 :            : static void
     142                 :          1 : test_happy_eyeballs_cancel_instant (void)
     143                 :            : {
     144                 :            :   GSocketClient *client;
     145                 :            :   GSocketService *service;
     146                 :          1 :   GError *error = NULL;
     147                 :            :   guint16 port;
     148                 :            :   GMainLoop *loop;
     149                 :            :   GCancellable *cancel;
     150                 :          1 :   EventCallbackData data = { NULL, FALSE };
     151                 :            : 
     152                 :            :   /* This tests the same things as above, test_happy_eyeballs_cancel_delayed(), but
     153                 :            :    * with different timing since it sends an already cancelled cancellable */
     154                 :            : 
     155                 :          1 :   loop = g_main_loop_new (NULL, FALSE);
     156                 :            : 
     157                 :          1 :   service = g_socket_service_new ();
     158                 :          1 :   port = g_socket_listener_add_any_inet_port (G_SOCKET_LISTENER (service), NULL, &error);
     159                 :          1 :   g_assert_no_error (error);
     160                 :          1 :   g_socket_service_start (service);
     161                 :            : 
     162                 :          1 :   client = g_socket_client_new ();
     163                 :          1 :   cancel = g_cancellable_new ();
     164                 :          1 :   g_cancellable_cancel (cancel);
     165                 :          1 :   g_socket_client_connect_to_host_async (client, "localhost", port, cancel, on_connected_cancelled, loop);
     166                 :          1 :   g_signal_connect (client, "event", G_CALLBACK (on_event), &data);
     167                 :          1 :   g_main_loop_run (loop);
     168                 :            : 
     169                 :          1 :   g_assert_true (data.completed);
     170                 :          1 :   g_main_loop_unref (loop);
     171                 :          1 :   g_object_unref (service);
     172                 :          1 :   g_object_unref (client);
     173                 :          1 :   g_object_unref (cancel);
     174                 :          1 : }
     175                 :            : 
     176                 :            : int
     177                 :          1 : main (int argc, char *argv[])
     178                 :            : {
     179                 :          1 :   g_test_init (&argc, &argv, NULL);
     180                 :            : 
     181                 :          1 :   g_test_add_func ("/socket-client/happy-eyeballs/slow", test_happy_eyeballs);
     182                 :          1 :   g_test_add_func ("/socket-client/happy-eyeballs/cancellation/instant", test_happy_eyeballs_cancel_instant);
     183                 :          1 :   g_test_add_func ("/socket-client/happy-eyeballs/cancellation/delayed", test_happy_eyeballs_cancel_delayed);
     184                 :            : 
     185                 :            : 
     186                 :          1 :   return g_test_run ();
     187                 :            : }

Generated by: LCOV version 1.14