1 /* GLib testing framework examples and tests
3 * Copyright 2012 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_34
26 * We have an echo server, two proxy servers, two GProxy
27 * implementations, and two GProxyResolver implementations.
29 * The echo server runs at @server.server_addr (on
30 * @server.server_port).
32 * The two proxy servers, A and B, run on @proxy_a.port and
33 * @proxy_b.port, with @proxy_a.uri and @proxy_b.uri pointing to them.
34 * The "negotiation" with the two proxies is just sending the single
35 * letter "a" or "b" and receiving it back in uppercase; the proxy
36 * then connects to @server_addr.
38 * Proxy A supports "alpha://" URIs, and does not support hostname
39 * resolution, and Proxy B supports "beta://" URIs, and does support
40 * hostname resolution (but it just ignores the hostname and always
41 * connects to @server_addr anyway).
43 * The default GProxyResolver (GTestProxyResolver) looks at its URI
44 * and returns [ "direct://" ] for "simple://" URIs, and [
45 * proxy_a.uri, proxy_b.uri ] for other URIs. The other GProxyResolver
46 * (GTestAltProxyResolver) always returns [ proxy_a.uri ].
51 gchar
*supported_protocol
;
55 GCancellable
*cancellable
;
59 GSocket
*client_sock
, *server_sock
;
65 static ProxyData proxy_a
, proxy_b
;
69 GThread
*server_thread
;
70 GCancellable
*cancellable
;
71 GSocketAddress
*server_addr
;
75 static ServerData server
;
77 static gchar
**last_proxies
;
79 static GSocketClient
*client
;
82 /**************************************/
83 /* Test GProxyResolver implementation */
84 /**************************************/
87 GObject parent_instance
;
91 GObjectClass parent_class
;
92 } GTestProxyResolverClass
;
94 static void g_test_proxy_resolver_iface_init (GProxyResolverInterface
*iface
);
96 static GType
_g_test_proxy_resolver_get_type (void);
97 #define g_test_proxy_resolver_get_type _g_test_proxy_resolver_get_type
98 G_DEFINE_TYPE_WITH_CODE (GTestProxyResolver
, g_test_proxy_resolver
, G_TYPE_OBJECT
,
99 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER
,
100 g_test_proxy_resolver_iface_init
)
101 g_io_extension_point_implement (G_PROXY_RESOLVER_EXTENSION_POINT_NAME
,
107 g_test_proxy_resolver_init (GTestProxyResolver
*resolver
)
112 g_test_proxy_resolver_is_supported (GProxyResolver
*resolver
)
118 g_test_proxy_resolver_lookup (GProxyResolver
*resolver
,
120 GCancellable
*cancellable
,
125 g_assert (last_proxies
== NULL
);
127 if (g_cancellable_set_error_if_cancelled (cancellable
, error
))
130 proxies
= g_new (gchar
*, 3);
132 if (!strncmp (uri
, "simple://", 4))
134 proxies
[0] = g_strdup ("direct://");
139 /* Proxy A can only deal with "alpha://" URIs, not
140 * "beta://", but we always return both URIs
141 * anyway so we can test error handling when the first
144 proxies
[0] = g_strdup (proxy_a
.uri
);
145 proxies
[1] = g_strdup (proxy_b
.uri
);
149 last_proxies
= g_strdupv (proxies
);
155 g_test_proxy_resolver_lookup_async (GProxyResolver
*resolver
,
157 GCancellable
*cancellable
,
158 GAsyncReadyCallback callback
,
161 GError
*error
= NULL
;
165 proxies
= g_proxy_resolver_lookup (resolver
, uri
, cancellable
, &error
);
167 task
= g_task_new (resolver
, NULL
, callback
, user_data
);
169 g_task_return_error (task
, error
);
171 g_task_return_pointer (task
, proxies
, (GDestroyNotify
) g_strfreev
);
173 g_object_unref (task
);
177 g_test_proxy_resolver_lookup_finish (GProxyResolver
*resolver
,
178 GAsyncResult
*result
,
181 return g_task_propagate_pointer (G_TASK (result
), error
);
185 g_test_proxy_resolver_class_init (GTestProxyResolverClass
*resolver_class
)
190 g_test_proxy_resolver_iface_init (GProxyResolverInterface
*iface
)
192 iface
->is_supported
= g_test_proxy_resolver_is_supported
;
193 iface
->lookup
= g_test_proxy_resolver_lookup
;
194 iface
->lookup_async
= g_test_proxy_resolver_lookup_async
;
195 iface
->lookup_finish
= g_test_proxy_resolver_lookup_finish
;
198 /****************************/
199 /* Alternate GProxyResolver */
200 /****************************/
202 typedef GTestProxyResolver GTestAltProxyResolver
;
203 typedef GTestProxyResolverClass GTestAltProxyResolverClass
;
205 static void g_test_alt_proxy_resolver_iface_init (GProxyResolverInterface
*iface
);
207 static GType
_g_test_alt_proxy_resolver_get_type (void);
208 #define g_test_alt_proxy_resolver_get_type _g_test_alt_proxy_resolver_get_type
209 G_DEFINE_TYPE_WITH_CODE (GTestAltProxyResolver
, g_test_alt_proxy_resolver
, g_test_proxy_resolver_get_type (),
210 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER
,
211 g_test_alt_proxy_resolver_iface_init
);
215 g_test_alt_proxy_resolver_init (GTestProxyResolver
*resolver
)
220 g_test_alt_proxy_resolver_lookup (GProxyResolver
*resolver
,
222 GCancellable
*cancellable
,
227 proxies
= g_new (gchar
*, 2);
229 proxies
[0] = g_strdup (proxy_a
.uri
);
232 last_proxies
= g_strdupv (proxies
);
238 g_test_alt_proxy_resolver_class_init (GTestProxyResolverClass
*resolver_class
)
243 g_test_alt_proxy_resolver_iface_init (GProxyResolverInterface
*iface
)
245 iface
->lookup
= g_test_alt_proxy_resolver_lookup
;
249 /****************************************/
250 /* Test proxy implementation base class */
251 /****************************************/
256 ProxyData
*proxy_data
;
260 GObjectClass parent_class
;
263 static GType
_g_proxy_base_get_type (void);
264 #define g_proxy_base_get_type _g_proxy_base_get_type
265 G_DEFINE_ABSTRACT_TYPE (GProxyBase
, g_proxy_base
, G_TYPE_OBJECT
)
268 g_proxy_base_init (GProxyBase
*proxy
)
273 g_proxy_base_connect (GProxy
*proxy
,
274 GIOStream
*io_stream
,
275 GProxyAddress
*proxy_address
,
276 GCancellable
*cancellable
,
279 ProxyData
*data
= ((GProxyBase
*) proxy
)->proxy_data
;
280 const gchar
*protocol
;
281 GOutputStream
*ostream
;
282 GInputStream
*istream
;
285 g_assert_no_error (data
->last_error
);
287 protocol
= g_proxy_address_get_destination_protocol (proxy_address
);
288 if (strcmp (protocol
, data
->supported_protocol
) != 0)
290 g_set_error_literal (&data
->last_error
,
291 G_IO_ERROR
, G_IO_ERROR_NOT_SUPPORTED
,
292 "Unsupported protocol");
296 ostream
= g_io_stream_get_output_stream (io_stream
);
297 if (g_output_stream_write (ostream
, data
->proxy_command
, 1, cancellable
,
298 &data
->last_error
) != 1)
301 istream
= g_io_stream_get_input_stream (io_stream
);
302 if (g_input_stream_read (istream
, &response
, 1, cancellable
,
303 &data
->last_error
) != 1)
306 if (response
!= g_ascii_toupper (*data
->proxy_command
))
308 g_set_error_literal (&data
->last_error
,
309 G_IO_ERROR
, G_IO_ERROR_FAILED
,
314 return g_object_ref (io_stream
);
317 g_propagate_error (error
, g_error_copy (data
->last_error
));
322 g_proxy_base_connect_async (GProxy
*proxy
,
323 GIOStream
*io_stream
,
324 GProxyAddress
*proxy_address
,
325 GCancellable
*cancellable
,
326 GAsyncReadyCallback callback
,
329 GError
*error
= NULL
;
331 GIOStream
*proxy_io_stream
;
333 task
= g_task_new (proxy
, NULL
, callback
, user_data
);
335 proxy_io_stream
= g_proxy_connect (proxy
, io_stream
, proxy_address
,
336 cancellable
, &error
);
338 g_task_return_pointer (task
, proxy_io_stream
, g_object_unref
);
340 g_task_return_error (task
, error
);
341 g_object_unref (task
);
345 g_proxy_base_connect_finish (GProxy
*proxy
,
346 GAsyncResult
*result
,
349 return g_task_propagate_pointer (G_TASK (result
), error
);
353 g_proxy_base_class_init (GProxyBaseClass
*class)
358 /********************************************/
359 /* Test proxy implementation #1 ("Proxy A") */
360 /********************************************/
362 typedef GProxyBase GProxyA
;
363 typedef GProxyBaseClass GProxyAClass
;
365 static void g_proxy_a_iface_init (GProxyInterface
*proxy_iface
);
367 static GType
_g_proxy_a_get_type (void);
368 #define g_proxy_a_get_type _g_proxy_a_get_type
369 G_DEFINE_TYPE_WITH_CODE (GProxyA
, g_proxy_a
, g_proxy_base_get_type (),
370 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY
,
371 g_proxy_a_iface_init
)
372 g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME
,
378 g_proxy_a_init (GProxyA
*proxy
)
380 ((GProxyBase
*) proxy
)->proxy_data
= &proxy_a
;
384 g_proxy_a_supports_hostname (GProxy
*proxy
)
390 g_proxy_a_class_init (GProxyAClass
*class)
395 g_proxy_a_iface_init (GProxyInterface
*proxy_iface
)
397 proxy_iface
->connect
= g_proxy_base_connect
;
398 proxy_iface
->connect_async
= g_proxy_base_connect_async
;
399 proxy_iface
->connect_finish
= g_proxy_base_connect_finish
;
400 proxy_iface
->supports_hostname
= g_proxy_a_supports_hostname
;
403 /********************************************/
404 /* Test proxy implementation #2 ("Proxy B") */
405 /********************************************/
407 typedef GProxyBase GProxyB
;
408 typedef GProxyBaseClass GProxyBClass
;
410 static void g_proxy_b_iface_init (GProxyInterface
*proxy_iface
);
412 static GType
_g_proxy_b_get_type (void);
413 #define g_proxy_b_get_type _g_proxy_b_get_type
414 G_DEFINE_TYPE_WITH_CODE (GProxyB
, g_proxy_b
, g_proxy_base_get_type (),
415 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY
,
416 g_proxy_b_iface_init
)
417 g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME
,
423 g_proxy_b_init (GProxyB
*proxy
)
425 ((GProxyBase
*) proxy
)->proxy_data
= &proxy_b
;
429 g_proxy_b_supports_hostname (GProxy
*proxy
)
435 g_proxy_b_class_init (GProxyBClass
*class)
440 g_proxy_b_iface_init (GProxyInterface
*proxy_iface
)
442 proxy_iface
->connect
= g_proxy_base_connect
;
443 proxy_iface
->connect_async
= g_proxy_base_connect_async
;
444 proxy_iface
->connect_finish
= g_proxy_base_connect_finish
;
445 proxy_iface
->supports_hostname
= g_proxy_b_supports_hostname
;
449 /***********************************/
450 /* The proxy server implementation */
451 /***********************************/
454 proxy_bytes (GSocket
*socket
,
455 GIOCondition condition
,
458 ProxyData
*proxy
= user_data
;
459 gssize nread
, nwrote
, total
;
462 GError
*error
= NULL
;
464 nread
= g_socket_receive_with_blocking (socket
, buffer
, sizeof (buffer
),
468 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_CLOSED
);
472 g_assert_no_error (error
);
476 g_main_loop_quit (proxy
->loop
);
480 if (socket
== proxy
->client_sock
)
481 out_socket
= proxy
->server_sock
;
483 out_socket
= proxy
->client_sock
;
485 for (total
= 0; total
< nread
; total
+= nwrote
)
487 nwrote
= g_socket_send_with_blocking (out_socket
,
488 buffer
+ total
, nread
- total
,
490 g_assert_no_error (error
);
497 proxy_thread (gpointer user_data
)
499 ProxyData
*proxy
= user_data
;
500 GError
*error
= NULL
;
501 gssize nread
, nwrote
;
502 gchar command
[2] = { 0, 0 };
503 GMainContext
*context
;
504 GSource
*read_source
, *write_source
;
506 context
= g_main_context_new ();
507 proxy
->loop
= g_main_loop_new (context
, FALSE
);
511 proxy
->client_sock
= g_socket_accept (proxy
->server
, proxy
->cancellable
, &error
);
512 if (!proxy
->client_sock
)
514 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_CANCELLED
);
515 g_error_free (error
);
519 g_assert_no_error (error
);
521 nread
= g_socket_receive (proxy
->client_sock
, command
, 1, NULL
, &error
);
522 g_assert_no_error (error
);
526 g_clear_object (&proxy
->client_sock
);
530 g_assert_cmpint (nread
, ==, 1);
531 g_assert_cmpstr (command
, ==, proxy
->proxy_command
);
533 *command
= g_ascii_toupper (*command
);
534 nwrote
= g_socket_send (proxy
->client_sock
, command
, 1, NULL
, &error
);
535 g_assert_no_error (error
);
536 g_assert_cmpint (nwrote
, ==, 1);
538 proxy
->server_sock
= g_socket_new (G_SOCKET_FAMILY_IPV4
,
539 G_SOCKET_TYPE_STREAM
,
540 G_SOCKET_PROTOCOL_DEFAULT
,
542 g_assert_no_error (error
);
543 g_socket_connect (proxy
->server_sock
, server
.server_addr
, NULL
, &error
);
544 g_assert_no_error (error
);
546 read_source
= g_socket_create_source (proxy
->client_sock
, G_IO_IN
, NULL
);
547 g_source_set_callback (read_source
, (GSourceFunc
)proxy_bytes
, proxy
, NULL
);
548 g_source_attach (read_source
, context
);
550 write_source
= g_socket_create_source (proxy
->server_sock
, G_IO_IN
, NULL
);
551 g_source_set_callback (write_source
, (GSourceFunc
)proxy_bytes
, proxy
, NULL
);
552 g_source_attach (write_source
, context
);
554 g_main_loop_run (proxy
->loop
);
556 g_socket_close (proxy
->client_sock
, &error
);
557 g_assert_no_error (error
);
558 g_clear_object (&proxy
->client_sock
);
560 g_socket_close (proxy
->server_sock
, &error
);
561 g_assert_no_error (error
);
562 g_clear_object (&proxy
->server_sock
);
564 g_source_destroy (read_source
);
565 g_source_unref (read_source
);
566 g_source_destroy (write_source
);
567 g_source_unref (write_source
);
570 g_main_loop_unref (proxy
->loop
);
571 g_main_context_unref (context
);
573 g_object_unref (proxy
->server
);
574 g_object_unref (proxy
->cancellable
);
576 g_free (proxy
->proxy_command
);
577 g_free (proxy
->supported_protocol
);
584 create_proxy (ProxyData
*proxy
,
585 gchar proxy_protocol
,
586 const gchar
*destination_protocol
,
587 GCancellable
*cancellable
)
589 GError
*error
= NULL
;
590 GSocketAddress
*addr
;
593 proxy
->proxy_command
= g_strdup_printf ("%c", proxy_protocol
);
594 proxy
->supported_protocol
= g_strdup (destination_protocol
);
595 proxy
->cancellable
= g_object_ref (cancellable
);
597 proxy
->server
= g_socket_new (G_SOCKET_FAMILY_IPV4
,
598 G_SOCKET_TYPE_STREAM
,
599 G_SOCKET_PROTOCOL_DEFAULT
,
601 g_assert_no_error (error
);
603 iaddr
= g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4
);
604 addr
= g_inet_socket_address_new (iaddr
, 0);
605 g_object_unref (iaddr
);
607 g_socket_bind (proxy
->server
, addr
, TRUE
, &error
);
608 g_assert_no_error (error
);
609 g_object_unref (addr
);
611 addr
= g_socket_get_local_address (proxy
->server
, &error
);
612 proxy
->port
= g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr
));
613 proxy
->uri
= g_strdup_printf ("proxy-%c://127.0.0.1:%u",
614 g_ascii_tolower (proxy_protocol
),
616 g_object_unref (addr
);
618 g_socket_listen (proxy
->server
, &error
);
619 g_assert_no_error (error
);
621 proxy
->thread
= g_thread_new ("proxy", proxy_thread
, proxy
);
626 /**************************/
627 /* The actual echo server */
628 /**************************/
631 echo_server_thread (gpointer user_data
)
633 ServerData
*data
= user_data
;
635 GError
*error
= NULL
;
636 gssize nread
, nwrote
;
641 sock
= g_socket_accept (data
->server
, data
->cancellable
, &error
);
644 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_CANCELLED
);
645 g_error_free (error
);
649 g_assert_no_error (error
);
653 nread
= g_socket_receive (sock
, buf
, sizeof (buf
), NULL
, &error
);
654 g_assert_no_error (error
);
655 g_assert_cmpint (nread
, >=, 0);
660 nwrote
= g_socket_send (sock
, buf
, nread
, NULL
, &error
);
661 g_assert_no_error (error
);
662 g_assert_cmpint (nwrote
, ==, nread
);
665 g_socket_close (sock
, &error
);
666 g_assert_no_error (error
);
667 g_object_unref (sock
);
670 g_object_unref (data
->server
);
671 g_object_unref (data
->server_addr
);
672 g_object_unref (data
->cancellable
);
678 create_server (ServerData
*data
, GCancellable
*cancellable
)
680 GError
*error
= NULL
;
681 GSocketAddress
*addr
;
684 data
->cancellable
= g_object_ref (cancellable
);
686 data
->server
= g_socket_new (G_SOCKET_FAMILY_IPV4
,
687 G_SOCKET_TYPE_STREAM
,
688 G_SOCKET_PROTOCOL_DEFAULT
,
690 g_assert_no_error (error
);
692 g_socket_set_blocking (data
->server
, TRUE
);
693 iaddr
= g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4
);
694 addr
= g_inet_socket_address_new (iaddr
, 0);
695 g_object_unref (iaddr
);
697 g_socket_bind (data
->server
, addr
, TRUE
, &error
);
698 g_assert_no_error (error
);
699 g_object_unref (addr
);
701 data
->server_addr
= g_socket_get_local_address (data
->server
, &error
);
702 g_assert_no_error (error
);
704 data
->server_port
= g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (data
->server_addr
));
706 g_socket_listen (data
->server
, &error
);
707 g_assert_no_error (error
);
709 data
->server_thread
= g_thread_new ("server", echo_server_thread
, data
);
713 /******************************************************************/
714 /* Now a GResolver implementation, so the can't-resolve test will */
715 /* pass even if you have an evil DNS-faking ISP. */
716 /******************************************************************/
718 typedef GResolver GFakeResolver
;
719 typedef GResolverClass GFakeResolverClass
;
721 static GType
g_fake_resolver_get_type (void);
722 G_DEFINE_TYPE (GFakeResolver
, g_fake_resolver
, G_TYPE_RESOLVER
)
725 g_fake_resolver_init (GFakeResolver
*gtr
)
730 g_fake_resolver_lookup_by_name (GResolver
*resolver
,
731 const gchar
*hostname
,
732 GCancellable
*cancellable
,
735 if (!strcmp (hostname
, "example.com"))
736 return g_list_prepend (NULL
, g_inet_address_new_from_string ("127.0.0.1"));
739 /* Anything else is expected to fail. */
742 G_RESOLVER_ERROR_NOT_FOUND
,
749 g_fake_resolver_lookup_by_name_async (GResolver
*resolver
,
750 const gchar
*hostname
,
751 GCancellable
*cancellable
,
752 GAsyncReadyCallback callback
,
757 task
= g_task_new (resolver
, cancellable
, callback
, user_data
);
759 if (!strcmp (hostname
, "example.com"))
763 result
= g_list_prepend (NULL
, g_inet_address_new_from_string ("127.0.0.1"));
764 g_task_return_pointer (task
, result
, (GDestroyNotify
) g_resolver_free_addresses
);
768 g_task_return_new_error (task
,
769 G_RESOLVER_ERROR
, G_RESOLVER_ERROR_NOT_FOUND
,
772 g_object_unref (task
);
776 g_fake_resolver_lookup_by_name_finish (GResolver
*resolver
,
777 GAsyncResult
*result
,
780 return g_task_propagate_pointer (G_TASK (result
), error
);
784 g_fake_resolver_class_init (GFakeResolverClass
*fake_class
)
786 GResolverClass
*resolver_class
= G_RESOLVER_CLASS (fake_class
);
788 resolver_class
->lookup_by_name
= g_fake_resolver_lookup_by_name
;
789 resolver_class
->lookup_by_name_async
= g_fake_resolver_lookup_by_name_async
;
790 resolver_class
->lookup_by_name_finish
= g_fake_resolver_lookup_by_name_finish
;
795 /****************************************/
796 /* We made it! Now for the actual test! */
797 /****************************************/
800 setup_test (gpointer fixture
,
801 gconstpointer user_data
)
806 teardown_test (gpointer fixture
,
807 gconstpointer user_data
)
811 g_strfreev (last_proxies
);
814 g_clear_error (&proxy_a
.last_error
);
815 g_clear_error (&proxy_b
.last_error
);
819 static const gchar
*testbuf
= "0123456789abcdef";
822 do_echo_test (GSocketConnection
*conn
)
824 GIOStream
*iostream
= G_IO_STREAM (conn
);
825 GInputStream
*istream
= g_io_stream_get_input_stream (iostream
);
826 GOutputStream
*ostream
= g_io_stream_get_output_stream (iostream
);
830 GError
*error
= NULL
;
832 g_output_stream_write_all (ostream
, testbuf
, strlen (testbuf
),
833 &nwrote
, NULL
, &error
);
834 g_assert_no_error (error
);
835 g_assert_cmpint (nwrote
, ==, strlen (testbuf
));
837 for (total
= 0; total
< nwrote
; total
+= nread
)
839 nread
= g_input_stream_read (istream
,
840 buf
+ total
, sizeof (buf
) - total
,
842 g_assert_no_error (error
);
843 g_assert_cmpint (nread
, >, 0);
847 g_assert_cmpstr (buf
, ==, testbuf
);
851 async_got_conn (GObject
*source
,
852 GAsyncResult
*result
,
855 GSocketConnection
**conn
= user_data
;
856 GError
*error
= NULL
;
858 *conn
= g_socket_client_connect_finish (G_SOCKET_CLIENT (source
),
860 g_assert_no_error (error
);
864 async_got_error (GObject
*source
,
865 GAsyncResult
*result
,
868 GError
**error
= user_data
;
870 g_assert (error
!= NULL
&& *error
== NULL
);
871 g_socket_client_connect_finish (G_SOCKET_CLIENT (source
),
873 g_assert (*error
!= NULL
);
878 assert_direct (GSocketConnection
*conn
)
880 GSocketAddress
*addr
;
881 GError
*error
= NULL
;
883 g_assert_cmpint (g_strv_length (last_proxies
), ==, 1);
884 g_assert_cmpstr (last_proxies
[0], ==, "direct://");
885 g_assert_no_error (proxy_a
.last_error
);
886 g_assert_no_error (proxy_b
.last_error
);
888 addr
= g_socket_connection_get_remote_address (conn
, &error
);
889 g_assert_no_error (error
);
890 g_assert (addr
!= NULL
&& !G_IS_PROXY_ADDRESS (addr
));
891 g_object_unref (addr
);
893 addr
= g_socket_connection_get_local_address (conn
, &error
);
894 g_assert_no_error (error
);
895 g_object_unref (addr
);
897 g_assert (g_socket_connection_is_connected (conn
));
901 test_direct_sync (gpointer fixture
,
902 gconstpointer user_data
)
904 GSocketConnection
*conn
;
906 GError
*error
= NULL
;
908 /* The simple:// URI should not require any proxy. */
910 uri
= g_strdup_printf ("simple://127.0.0.1:%u", server
.server_port
);
911 conn
= g_socket_client_connect_to_uri (client
, uri
, 0, NULL
, &error
);
913 g_assert_no_error (error
);
915 assert_direct (conn
);
917 g_object_unref (conn
);
921 test_direct_async (gpointer fixture
,
922 gconstpointer user_data
)
924 GSocketConnection
*conn
;
927 /* The simple:// URI should not require any proxy. */
928 uri
= g_strdup_printf ("simple://127.0.0.1:%u", server
.server_port
);
930 g_socket_client_connect_to_uri_async (client
, uri
, 0, NULL
,
931 async_got_conn
, &conn
);
934 g_main_context_iteration (NULL
, TRUE
);
936 assert_direct (conn
);
938 g_object_unref (conn
);
942 assert_single (GSocketConnection
*conn
)
944 GSocketAddress
*addr
;
945 const gchar
*proxy_uri
;
947 GError
*error
= NULL
;
949 g_assert_cmpint (g_strv_length (last_proxies
), ==, 2);
950 g_assert_cmpstr (last_proxies
[0], ==, proxy_a
.uri
);
951 g_assert_cmpstr (last_proxies
[1], ==, proxy_b
.uri
);
952 g_assert_no_error (proxy_a
.last_error
);
953 g_assert_no_error (proxy_b
.last_error
);
955 addr
= g_socket_connection_get_remote_address (conn
, &error
);
956 g_assert_no_error (error
);
957 g_assert (G_IS_PROXY_ADDRESS (addr
));
958 proxy_uri
= g_proxy_address_get_uri (G_PROXY_ADDRESS (addr
));
959 g_assert_cmpstr (proxy_uri
, ==, proxy_a
.uri
);
960 proxy_port
= g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr
));
961 g_assert_cmpint (proxy_port
, ==, proxy_a
.port
);
963 g_object_unref (addr
);
967 test_single_sync (gpointer fixture
,
968 gconstpointer user_data
)
970 GSocketConnection
*conn
;
971 GError
*error
= NULL
;
974 /* The alpha:// URI should be proxied via Proxy A */
975 uri
= g_strdup_printf ("alpha://127.0.0.1:%u", server
.server_port
);
976 conn
= g_socket_client_connect_to_uri (client
, uri
, 0, NULL
, &error
);
978 g_assert_no_error (error
);
980 assert_single (conn
);
983 g_object_unref (conn
);
987 test_single_async (gpointer fixture
,
988 gconstpointer user_data
)
990 GSocketConnection
*conn
;
993 /* The alpha:// URI should be proxied via Proxy A */
994 uri
= g_strdup_printf ("alpha://127.0.0.1:%u", server
.server_port
);
996 g_socket_client_connect_to_uri_async (client
, uri
, 0, NULL
,
997 async_got_conn
, &conn
);
1000 g_main_context_iteration (NULL
, TRUE
);
1002 assert_single (conn
);
1003 do_echo_test (conn
);
1004 g_object_unref (conn
);
1008 assert_multiple (GSocketConnection
*conn
)
1010 GSocketAddress
*addr
;
1011 const gchar
*proxy_uri
;
1013 GError
*error
= NULL
;
1015 g_assert_cmpint (g_strv_length (last_proxies
), ==, 2);
1016 g_assert_cmpstr (last_proxies
[0], ==, proxy_a
.uri
);
1017 g_assert_cmpstr (last_proxies
[1], ==, proxy_b
.uri
);
1018 g_assert_error (proxy_a
.last_error
, G_IO_ERROR
, G_IO_ERROR_NOT_SUPPORTED
);
1019 g_assert_no_error (proxy_b
.last_error
);
1021 addr
= g_socket_connection_get_remote_address (conn
, &error
);
1022 g_assert_no_error (error
);
1023 g_assert (G_IS_PROXY_ADDRESS (addr
));
1024 proxy_uri
= g_proxy_address_get_uri (G_PROXY_ADDRESS (addr
));
1025 g_assert_cmpstr (proxy_uri
, ==, proxy_b
.uri
);
1026 proxy_port
= g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr
));
1027 g_assert_cmpint (proxy_port
, ==, proxy_b
.port
);
1029 g_object_unref (addr
);
1033 test_multiple_sync (gpointer fixture
,
1034 gconstpointer user_data
)
1036 GSocketConnection
*conn
;
1037 GError
*error
= NULL
;
1040 /* The beta:// URI should be proxied via Proxy B, after failing
1043 uri
= g_strdup_printf ("beta://127.0.0.1:%u", server
.server_port
);
1044 conn
= g_socket_client_connect_to_uri (client
, uri
, 0, NULL
, &error
);
1046 g_assert_no_error (error
);
1048 assert_multiple (conn
);
1049 do_echo_test (conn
);
1050 g_object_unref (conn
);
1054 test_multiple_async (gpointer fixture
,
1055 gconstpointer user_data
)
1057 GSocketConnection
*conn
;
1060 /* The beta:// URI should be proxied via Proxy B, after failing
1063 uri
= g_strdup_printf ("beta://127.0.0.1:%u", server
.server_port
);
1065 g_socket_client_connect_to_uri_async (client
, uri
, 0, NULL
,
1066 async_got_conn
, &conn
);
1068 while (conn
== NULL
)
1069 g_main_context_iteration (NULL
, TRUE
);
1071 assert_multiple (conn
);
1072 do_echo_test (conn
);
1073 g_object_unref (conn
);
1077 test_dns (gpointer fixture
,
1078 gconstpointer user_data
)
1080 GSocketConnection
*conn
;
1081 GError
*error
= NULL
;
1084 /* The simple:// and alpha:// URIs should fail with a DNS error,
1085 * but the beta:// URI should succeed, because we pass it to
1086 * Proxy B without trying to resolve it first
1090 uri
= g_strdup_printf ("simple://no-such-host.xx:%u", server
.server_port
);
1091 conn
= g_socket_client_connect_to_uri (client
, uri
, 0, NULL
, &error
);
1092 g_assert_error (error
, G_RESOLVER_ERROR
, G_RESOLVER_ERROR_NOT_FOUND
);
1093 g_clear_error (&error
);
1095 g_assert_no_error (proxy_a
.last_error
);
1096 g_assert_no_error (proxy_b
.last_error
);
1097 teardown_test (NULL
, NULL
);
1099 g_socket_client_connect_to_uri_async (client
, uri
, 0, NULL
,
1100 async_got_error
, &error
);
1101 while (error
== NULL
)
1102 g_main_context_iteration (NULL
, TRUE
);
1103 g_assert_error (error
, G_RESOLVER_ERROR
, G_RESOLVER_ERROR_NOT_FOUND
);
1104 g_clear_error (&error
);
1107 g_assert_no_error (proxy_a
.last_error
);
1108 g_assert_no_error (proxy_b
.last_error
);
1109 teardown_test (NULL
, NULL
);
1112 uri
= g_strdup_printf ("alpha://no-such-host.xx:%u", server
.server_port
);
1113 conn
= g_socket_client_connect_to_uri (client
, uri
, 0, NULL
, &error
);
1114 /* Since Proxy A fails, @client will try Proxy B too, which won't
1115 * load an alpha:// URI.
1117 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_NOT_SUPPORTED
);
1118 g_clear_error (&error
);
1120 g_assert_no_error (proxy_a
.last_error
);
1121 g_assert_error (proxy_b
.last_error
, G_IO_ERROR
, G_IO_ERROR_NOT_SUPPORTED
);
1122 teardown_test (NULL
, NULL
);
1124 g_socket_client_connect_to_uri_async (client
, uri
, 0, NULL
,
1125 async_got_error
, &error
);
1126 while (error
== NULL
)
1127 g_main_context_iteration (NULL
, TRUE
);
1128 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_NOT_SUPPORTED
);
1129 g_clear_error (&error
);
1132 g_assert_no_error (proxy_a
.last_error
);
1133 g_assert_error (proxy_b
.last_error
, G_IO_ERROR
, G_IO_ERROR_NOT_SUPPORTED
);
1134 teardown_test (NULL
, NULL
);
1137 uri
= g_strdup_printf ("beta://no-such-host.xx:%u", server
.server_port
);
1138 conn
= g_socket_client_connect_to_uri (client
, uri
, 0, NULL
, &error
);
1139 g_assert_no_error (error
);
1141 g_assert_no_error (proxy_a
.last_error
);
1142 g_assert_no_error (proxy_b
.last_error
);
1144 do_echo_test (conn
);
1145 g_clear_object (&conn
);
1146 teardown_test (NULL
, NULL
);
1148 g_socket_client_connect_to_uri_async (client
, uri
, 0, NULL
,
1149 async_got_conn
, &conn
);
1150 while (conn
== NULL
)
1151 g_main_context_iteration (NULL
, TRUE
);
1154 g_assert_no_error (proxy_a
.last_error
);
1155 g_assert_no_error (proxy_b
.last_error
);
1157 do_echo_test (conn
);
1158 g_clear_object (&conn
);
1159 teardown_test (NULL
, NULL
);
1163 assert_override (GSocketConnection
*conn
)
1165 g_assert_cmpint (g_strv_length (last_proxies
), ==, 1);
1166 g_assert_cmpstr (last_proxies
[0], ==, proxy_a
.uri
);
1169 g_assert_no_error (proxy_a
.last_error
);
1171 g_assert_error (proxy_a
.last_error
, G_IO_ERROR
, G_IO_ERROR_NOT_SUPPORTED
);
1175 test_override (gpointer fixture
,
1176 gconstpointer user_data
)
1178 GProxyResolver
*alt_resolver
;
1179 GSocketConnection
*conn
;
1180 GError
*error
= NULL
;
1183 g_assert (g_socket_client_get_proxy_resolver (client
) == g_proxy_resolver_get_default ());
1184 alt_resolver
= g_object_new (g_test_alt_proxy_resolver_get_type (), NULL
);
1185 g_socket_client_set_proxy_resolver (client
, alt_resolver
);
1186 g_assert (g_socket_client_get_proxy_resolver (client
) == alt_resolver
);
1188 /* Alt proxy resolver always returns Proxy A, so alpha:// should
1189 * succeed, and simple:// and beta:// should fail.
1193 uri
= g_strdup_printf ("simple://127.0.0.1:%u", server
.server_port
);
1194 conn
= g_socket_client_connect_to_uri (client
, uri
, 0, NULL
, &error
);
1195 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_NOT_SUPPORTED
);
1196 g_clear_error (&error
);
1197 assert_override (conn
);
1198 teardown_test (NULL
, NULL
);
1200 g_socket_client_connect_to_uri_async (client
, uri
, 0, NULL
,
1201 async_got_error
, &error
);
1202 while (error
== NULL
)
1203 g_main_context_iteration (NULL
, TRUE
);
1204 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_NOT_SUPPORTED
);
1205 g_clear_error (&error
);
1206 assert_override (conn
);
1208 teardown_test (NULL
, NULL
);
1211 uri
= g_strdup_printf ("alpha://127.0.0.1:%u", server
.server_port
);
1212 conn
= g_socket_client_connect_to_uri (client
, uri
, 0, NULL
, &error
);
1213 g_assert_no_error (error
);
1214 assert_override (conn
);
1215 do_echo_test (conn
);
1216 g_clear_object (&conn
);
1217 teardown_test (NULL
, NULL
);
1220 g_socket_client_connect_to_uri_async (client
, uri
, 0, NULL
,
1221 async_got_conn
, &conn
);
1222 while (conn
== NULL
)
1223 g_main_context_iteration (NULL
, TRUE
);
1224 assert_override (conn
);
1225 do_echo_test (conn
);
1226 g_clear_object (&conn
);
1228 teardown_test (NULL
, NULL
);
1231 uri
= g_strdup_printf ("beta://127.0.0.1:%u", server
.server_port
);
1232 conn
= g_socket_client_connect_to_uri (client
, uri
, 0, NULL
, &error
);
1233 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_NOT_SUPPORTED
);
1234 g_clear_error (&error
);
1235 assert_override (conn
);
1236 teardown_test (NULL
, NULL
);
1238 g_socket_client_connect_to_uri_async (client
, uri
, 0, NULL
,
1239 async_got_error
, &error
);
1240 while (error
== NULL
)
1241 g_main_context_iteration (NULL
, TRUE
);
1242 g_assert_error (error
, G_IO_ERROR
, G_IO_ERROR_NOT_SUPPORTED
);
1243 g_clear_error (&error
);
1244 assert_override (conn
);
1246 teardown_test (NULL
, NULL
);
1248 g_assert (g_socket_client_get_proxy_resolver (client
) == alt_resolver
);
1249 g_socket_client_set_proxy_resolver (client
, NULL
);
1250 g_assert (g_socket_client_get_proxy_resolver (client
) == g_proxy_resolver_get_default ());
1251 g_object_unref (alt_resolver
);
1255 assert_destination_port (GSocketAddressEnumerator
*etor
,
1258 GSocketAddress
*addr
;
1259 GProxyAddress
*paddr
;
1260 GError
*error
= NULL
;
1262 while ((addr
= g_socket_address_enumerator_next (etor
, NULL
, &error
)))
1264 g_assert_no_error (error
);
1266 g_assert (G_IS_PROXY_ADDRESS (addr
));
1267 paddr
= G_PROXY_ADDRESS (addr
);
1268 g_assert_cmpint (g_proxy_address_get_destination_port (paddr
), ==, port
);
1269 g_object_unref (addr
);
1271 g_assert_no_error (error
);
1275 test_proxy_enumerator_ports (void)
1277 GSocketAddressEnumerator
*etor
;
1279 etor
= g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR
,
1280 "uri", "http://example.com/",
1282 assert_destination_port (etor
, 0);
1283 g_object_unref (etor
);
1285 /* Have to call this to clear last_proxies so the next call to
1286 * g_test_proxy_resolver_lookup() won't assert.
1288 teardown_test (NULL
, NULL
);
1290 etor
= g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR
,
1291 "uri", "http://example.com:8080/",
1293 assert_destination_port (etor
, 8080);
1294 g_object_unref (etor
);
1296 teardown_test (NULL
, NULL
);
1298 etor
= g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR
,
1299 "uri", "http://example.com/",
1302 assert_destination_port (etor
, 80);
1303 g_object_unref (etor
);
1305 teardown_test (NULL
, NULL
);
1307 etor
= g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR
,
1308 "uri", "http://example.com:8080/",
1311 assert_destination_port (etor
, 8080);
1312 g_object_unref (etor
);
1314 teardown_test (NULL
, NULL
);
1321 GResolver
*fake_resolver
;
1322 GCancellable
*cancellable
;
1325 g_test_init (&argc
, &argv
, NULL
);
1327 /* Register stuff. The dummy g_proxy_get_default_for_protocol() call
1328 * is to force _g_io_modules_ensure_extension_points_registered() to
1329 * get called, so we can then register a proxy resolver extension
1332 g_proxy_get_default_for_protocol ("foo");
1333 g_test_proxy_resolver_get_type ();
1334 g_proxy_a_get_type ();
1335 g_proxy_b_get_type ();
1336 g_setenv ("GIO_USE_PROXY_RESOLVER", "test", TRUE
);
1338 fake_resolver
= g_object_new (g_fake_resolver_get_type (), NULL
);
1339 g_resolver_set_default (fake_resolver
);
1341 cancellable
= g_cancellable_new ();
1342 create_server (&server
, cancellable
);
1343 create_proxy (&proxy_a
, 'a', "alpha", cancellable
);
1344 create_proxy (&proxy_b
, 'b', "beta", cancellable
);
1346 client
= g_socket_client_new ();
1347 g_assert_cmpint (g_socket_client_get_enable_proxy (client
), ==, TRUE
);
1349 g_test_add_vtable ("/proxy/direct_sync", 0, NULL
, setup_test
, test_direct_sync
, teardown_test
);
1350 g_test_add_vtable ("/proxy/direct_async", 0, NULL
, setup_test
, test_direct_async
, teardown_test
);
1351 g_test_add_vtable ("/proxy/single_sync", 0, NULL
, setup_test
, test_single_sync
, teardown_test
);
1352 g_test_add_vtable ("/proxy/single_async", 0, NULL
, setup_test
, test_single_async
, teardown_test
);
1353 g_test_add_vtable ("/proxy/multiple_sync", 0, NULL
, setup_test
, test_multiple_sync
, teardown_test
);
1354 g_test_add_vtable ("/proxy/multiple_async", 0, NULL
, setup_test
, test_multiple_async
, teardown_test
);
1355 g_test_add_vtable ("/proxy/dns", 0, NULL
, setup_test
, test_dns
, teardown_test
);
1356 g_test_add_vtable ("/proxy/override", 0, NULL
, setup_test
, test_override
, teardown_test
);
1357 g_test_add_func ("/proxy/enumerator-ports", test_proxy_enumerator_ports
);
1359 result
= g_test_run();
1361 g_object_unref (client
);
1363 g_cancellable_cancel (cancellable
);
1364 g_thread_join (proxy_a
.thread
);
1365 g_thread_join (proxy_b
.thread
);
1366 g_thread_join (server
.server_thread
);
1368 g_object_unref (cancellable
);