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, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
23 #define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_34
28 * We have an echo server, two proxy servers, two GProxy
29 * implementations, and two GProxyResolver implementations.
31 * The echo server runs at @server.server_addr (on
32 * @server.server_port).
34 * The two proxy servers, A and B, run on @proxy_a.port and
35 * @proxy_b.port, with @proxy_a.uri and @proxy_b.uri pointing to them.
36 * The "negotiation" with the two proxies is just sending the single
37 * letter "a" or "b" and receiving it back in uppercase; the proxy
38 * then connects to @server_addr.
40 * Proxy A supports "alpha://" URIs, and does not support hostname
41 * resolution, and Proxy B supports "beta://" URIs, and does support
42 * hostname resolution (but it just ignores the hostname and always
43 * connects to @server_addr anyway).
45 * The default GProxyResolver (GTestProxyResolver) looks at its URI
46 * and returns [ "direct://" ] for "simple://" URIs, and [
47 * proxy_a.uri, proxy_b.uri ] for other URIs. The other GProxyResolver
48 * (GTestAltProxyResolver) always returns [ proxy_a.uri ].
53 gchar *supported_protocol;
57 GCancellable *cancellable;
61 GSocket *client_sock, *server_sock;
67 static ProxyData proxy_a, proxy_b;
71 GThread *server_thread;
72 GCancellable *cancellable;
73 GSocketAddress *server_addr;
77 static ServerData server;
79 static gchar **last_proxies;
81 static GSocketClient *client;
84 /**************************************/
85 /* Test GProxyResolver implementation */
86 /**************************************/
89 GObject parent_instance;
93 GObjectClass parent_class;
94 } GTestProxyResolverClass;
96 static void g_test_proxy_resolver_iface_init (GProxyResolverInterface *iface);
98 static GType _g_test_proxy_resolver_get_type (void);
99 #define g_test_proxy_resolver_get_type _g_test_proxy_resolver_get_type
100 G_DEFINE_TYPE_WITH_CODE (GTestProxyResolver, g_test_proxy_resolver, G_TYPE_OBJECT,
101 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,
102 g_test_proxy_resolver_iface_init)
103 g_io_extension_point_implement (G_PROXY_RESOLVER_EXTENSION_POINT_NAME,
109 g_test_proxy_resolver_init (GTestProxyResolver *resolver)
114 g_test_proxy_resolver_is_supported (GProxyResolver *resolver)
120 g_test_proxy_resolver_lookup (GProxyResolver *resolver,
122 GCancellable *cancellable,
127 g_assert (last_proxies == NULL);
129 if (g_cancellable_set_error_if_cancelled (cancellable, error))
132 proxies = g_new (gchar *, 3);
134 if (!strncmp (uri, "simple://", 4))
136 proxies[0] = g_strdup ("direct://");
141 /* Proxy A can only deal with "alpha://" URIs, not
142 * "beta://", but we always return both URIs
143 * anyway so we can test error handling when the first
146 proxies[0] = g_strdup (proxy_a.uri);
147 proxies[1] = g_strdup (proxy_b.uri);
151 last_proxies = g_strdupv (proxies);
157 g_test_proxy_resolver_lookup_async (GProxyResolver *resolver,
159 GCancellable *cancellable,
160 GAsyncReadyCallback callback,
163 GError *error = NULL;
167 proxies = g_proxy_resolver_lookup (resolver, uri, cancellable, &error);
169 task = g_task_new (resolver, NULL, callback, user_data);
171 g_task_return_error (task, error);
173 g_task_return_pointer (task, proxies, (GDestroyNotify) g_strfreev);
175 g_object_unref (task);
179 g_test_proxy_resolver_lookup_finish (GProxyResolver *resolver,
180 GAsyncResult *result,
183 return g_task_propagate_pointer (G_TASK (result), error);
187 g_test_proxy_resolver_class_init (GTestProxyResolverClass *resolver_class)
192 g_test_proxy_resolver_iface_init (GProxyResolverInterface *iface)
194 iface->is_supported = g_test_proxy_resolver_is_supported;
195 iface->lookup = g_test_proxy_resolver_lookup;
196 iface->lookup_async = g_test_proxy_resolver_lookup_async;
197 iface->lookup_finish = g_test_proxy_resolver_lookup_finish;
200 /****************************/
201 /* Alternate GProxyResolver */
202 /****************************/
204 typedef GTestProxyResolver GTestAltProxyResolver;
205 typedef GTestProxyResolverClass GTestAltProxyResolverClass;
207 static void g_test_alt_proxy_resolver_iface_init (GProxyResolverInterface *iface);
209 static GType _g_test_alt_proxy_resolver_get_type (void);
210 #define g_test_alt_proxy_resolver_get_type _g_test_alt_proxy_resolver_get_type
211 G_DEFINE_TYPE_WITH_CODE (GTestAltProxyResolver, g_test_alt_proxy_resolver, g_test_proxy_resolver_get_type (),
212 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,
213 g_test_alt_proxy_resolver_iface_init);
217 g_test_alt_proxy_resolver_init (GTestProxyResolver *resolver)
222 g_test_alt_proxy_resolver_lookup (GProxyResolver *resolver,
224 GCancellable *cancellable,
229 proxies = g_new (gchar *, 2);
231 proxies[0] = g_strdup (proxy_a.uri);
234 last_proxies = g_strdupv (proxies);
240 g_test_alt_proxy_resolver_class_init (GTestProxyResolverClass *resolver_class)
245 g_test_alt_proxy_resolver_iface_init (GProxyResolverInterface *iface)
247 iface->lookup = g_test_alt_proxy_resolver_lookup;
251 /****************************************/
252 /* Test proxy implementation base class */
253 /****************************************/
258 ProxyData *proxy_data;
262 GObjectClass parent_class;
265 static GType _g_proxy_base_get_type (void);
266 #define g_proxy_base_get_type _g_proxy_base_get_type
267 G_DEFINE_ABSTRACT_TYPE (GProxyBase, g_proxy_base, G_TYPE_OBJECT)
270 g_proxy_base_init (GProxyBase *proxy)
275 g_proxy_base_connect (GProxy *proxy,
276 GIOStream *io_stream,
277 GProxyAddress *proxy_address,
278 GCancellable *cancellable,
281 ProxyData *data = ((GProxyBase *) proxy)->proxy_data;
282 const gchar *protocol;
283 GOutputStream *ostream;
284 GInputStream *istream;
287 g_assert_no_error (data->last_error);
289 protocol = g_proxy_address_get_destination_protocol (proxy_address);
290 if (strcmp (protocol, data->supported_protocol) != 0)
292 g_set_error_literal (&data->last_error,
293 G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
294 "Unsupported protocol");
298 ostream = g_io_stream_get_output_stream (io_stream);
299 if (g_output_stream_write (ostream, data->proxy_command, 1, cancellable,
300 &data->last_error) != 1)
303 istream = g_io_stream_get_input_stream (io_stream);
304 if (g_input_stream_read (istream, &response, 1, cancellable,
305 &data->last_error) != 1)
308 if (response != g_ascii_toupper (*data->proxy_command))
310 g_set_error_literal (&data->last_error,
311 G_IO_ERROR, G_IO_ERROR_FAILED,
316 return g_object_ref (io_stream);
319 g_propagate_error (error, g_error_copy (data->last_error));
324 g_proxy_base_connect_async (GProxy *proxy,
325 GIOStream *io_stream,
326 GProxyAddress *proxy_address,
327 GCancellable *cancellable,
328 GAsyncReadyCallback callback,
331 GError *error = NULL;
333 GIOStream *proxy_io_stream;
335 task = g_task_new (proxy, NULL, callback, user_data);
337 proxy_io_stream = g_proxy_connect (proxy, io_stream, proxy_address,
338 cancellable, &error);
340 g_task_return_pointer (task, proxy_io_stream, g_object_unref);
342 g_task_return_error (task, error);
343 g_object_unref (task);
347 g_proxy_base_connect_finish (GProxy *proxy,
348 GAsyncResult *result,
351 return g_task_propagate_pointer (G_TASK (result), error);
355 g_proxy_base_class_init (GProxyBaseClass *class)
360 /********************************************/
361 /* Test proxy implementation #1 ("Proxy A") */
362 /********************************************/
364 typedef GProxyBase GProxyA;
365 typedef GProxyBaseClass GProxyAClass;
367 static void g_proxy_a_iface_init (GProxyInterface *proxy_iface);
369 static GType _g_proxy_a_get_type (void);
370 #define g_proxy_a_get_type _g_proxy_a_get_type
371 G_DEFINE_TYPE_WITH_CODE (GProxyA, g_proxy_a, g_proxy_base_get_type (),
372 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
373 g_proxy_a_iface_init)
374 g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
380 g_proxy_a_init (GProxyA *proxy)
382 ((GProxyBase *) proxy)->proxy_data = &proxy_a;
386 g_proxy_a_supports_hostname (GProxy *proxy)
392 g_proxy_a_class_init (GProxyAClass *class)
397 g_proxy_a_iface_init (GProxyInterface *proxy_iface)
399 proxy_iface->connect = g_proxy_base_connect;
400 proxy_iface->connect_async = g_proxy_base_connect_async;
401 proxy_iface->connect_finish = g_proxy_base_connect_finish;
402 proxy_iface->supports_hostname = g_proxy_a_supports_hostname;
405 /********************************************/
406 /* Test proxy implementation #2 ("Proxy B") */
407 /********************************************/
409 typedef GProxyBase GProxyB;
410 typedef GProxyBaseClass GProxyBClass;
412 static void g_proxy_b_iface_init (GProxyInterface *proxy_iface);
414 static GType _g_proxy_b_get_type (void);
415 #define g_proxy_b_get_type _g_proxy_b_get_type
416 G_DEFINE_TYPE_WITH_CODE (GProxyB, g_proxy_b, g_proxy_base_get_type (),
417 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
418 g_proxy_b_iface_init)
419 g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
425 g_proxy_b_init (GProxyB *proxy)
427 ((GProxyBase *) proxy)->proxy_data = &proxy_b;
431 g_proxy_b_supports_hostname (GProxy *proxy)
437 g_proxy_b_class_init (GProxyBClass *class)
442 g_proxy_b_iface_init (GProxyInterface *proxy_iface)
444 proxy_iface->connect = g_proxy_base_connect;
445 proxy_iface->connect_async = g_proxy_base_connect_async;
446 proxy_iface->connect_finish = g_proxy_base_connect_finish;
447 proxy_iface->supports_hostname = g_proxy_b_supports_hostname;
451 /***********************************/
452 /* The proxy server implementation */
453 /***********************************/
456 proxy_bytes (GSocket *socket,
457 GIOCondition condition,
460 ProxyData *proxy = user_data;
461 gssize nread, nwrote, total;
464 GError *error = NULL;
466 nread = g_socket_receive_with_blocking (socket, buffer, sizeof (buffer),
470 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
474 g_assert_no_error (error);
478 g_main_loop_quit (proxy->loop);
482 if (socket == proxy->client_sock)
483 out_socket = proxy->server_sock;
485 out_socket = proxy->client_sock;
487 for (total = 0; total < nread; total += nwrote)
489 nwrote = g_socket_send_with_blocking (out_socket,
490 buffer + total, nread - total,
492 g_assert_no_error (error);
499 proxy_thread (gpointer user_data)
501 ProxyData *proxy = user_data;
502 GError *error = NULL;
503 gssize nread, nwrote;
504 gchar command[2] = { 0, 0 };
505 GMainContext *context;
506 GSource *read_source, *write_source;
508 context = g_main_context_new ();
509 proxy->loop = g_main_loop_new (context, FALSE);
513 proxy->client_sock = g_socket_accept (proxy->server, proxy->cancellable, &error);
514 if (!proxy->client_sock)
516 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
517 g_error_free (error);
521 g_assert_no_error (error);
523 nread = g_socket_receive (proxy->client_sock, command, 1, NULL, &error);
524 g_assert_no_error (error);
528 g_clear_object (&proxy->client_sock);
532 g_assert_cmpint (nread, ==, 1);
533 g_assert_cmpstr (command, ==, proxy->proxy_command);
535 *command = g_ascii_toupper (*command);
536 nwrote = g_socket_send (proxy->client_sock, command, 1, NULL, &error);
537 g_assert_no_error (error);
538 g_assert_cmpint (nwrote, ==, 1);
540 proxy->server_sock = g_socket_new (G_SOCKET_FAMILY_IPV4,
541 G_SOCKET_TYPE_STREAM,
542 G_SOCKET_PROTOCOL_DEFAULT,
544 g_assert_no_error (error);
545 g_socket_connect (proxy->server_sock, server.server_addr, NULL, &error);
546 g_assert_no_error (error);
548 read_source = g_socket_create_source (proxy->client_sock, G_IO_IN, NULL);
549 g_source_set_callback (read_source, (GSourceFunc)proxy_bytes, proxy, NULL);
550 g_source_attach (read_source, context);
552 write_source = g_socket_create_source (proxy->server_sock, G_IO_IN, NULL);
553 g_source_set_callback (write_source, (GSourceFunc)proxy_bytes, proxy, NULL);
554 g_source_attach (write_source, context);
556 g_main_loop_run (proxy->loop);
558 g_socket_close (proxy->client_sock, &error);
559 g_assert_no_error (error);
560 g_clear_object (&proxy->client_sock);
562 g_socket_close (proxy->server_sock, &error);
563 g_assert_no_error (error);
564 g_clear_object (&proxy->server_sock);
566 g_source_destroy (read_source);
567 g_source_unref (read_source);
568 g_source_destroy (write_source);
569 g_source_unref (write_source);
572 g_main_loop_unref (proxy->loop);
573 g_main_context_unref (context);
575 g_object_unref (proxy->server);
576 g_object_unref (proxy->cancellable);
578 g_free (proxy->proxy_command);
579 g_free (proxy->supported_protocol);
586 create_proxy (ProxyData *proxy,
587 gchar proxy_protocol,
588 const gchar *destination_protocol,
589 GCancellable *cancellable)
591 GError *error = NULL;
592 GSocketAddress *addr;
595 proxy->proxy_command = g_strdup_printf ("%c", proxy_protocol);
596 proxy->supported_protocol = g_strdup (destination_protocol);
597 proxy->cancellable = g_object_ref (cancellable);
599 proxy->server = g_socket_new (G_SOCKET_FAMILY_IPV4,
600 G_SOCKET_TYPE_STREAM,
601 G_SOCKET_PROTOCOL_DEFAULT,
603 g_assert_no_error (error);
605 iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
606 addr = g_inet_socket_address_new (iaddr, 0);
607 g_object_unref (iaddr);
609 g_socket_bind (proxy->server, addr, TRUE, &error);
610 g_assert_no_error (error);
611 g_object_unref (addr);
613 addr = g_socket_get_local_address (proxy->server, &error);
614 proxy->port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
615 proxy->uri = g_strdup_printf ("proxy-%c://127.0.0.1:%u",
616 g_ascii_tolower (proxy_protocol),
618 g_object_unref (addr);
620 g_socket_listen (proxy->server, &error);
621 g_assert_no_error (error);
623 proxy->thread = g_thread_new ("proxy", proxy_thread, proxy);
628 /**************************/
629 /* The actual echo server */
630 /**************************/
633 echo_server_thread (gpointer user_data)
635 ServerData *data = user_data;
637 GError *error = NULL;
638 gssize nread, nwrote;
643 sock = g_socket_accept (data->server, data->cancellable, &error);
646 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
647 g_error_free (error);
651 g_assert_no_error (error);
655 nread = g_socket_receive (sock, buf, sizeof (buf), NULL, &error);
656 g_assert_no_error (error);
657 g_assert_cmpint (nread, >=, 0);
662 nwrote = g_socket_send (sock, buf, nread, NULL, &error);
663 g_assert_no_error (error);
664 g_assert_cmpint (nwrote, ==, nread);
667 g_socket_close (sock, &error);
668 g_assert_no_error (error);
669 g_object_unref (sock);
672 g_object_unref (data->server);
673 g_object_unref (data->server_addr);
674 g_object_unref (data->cancellable);
680 create_server (ServerData *data, GCancellable *cancellable)
682 GError *error = NULL;
683 GSocketAddress *addr;
686 data->cancellable = g_object_ref (cancellable);
688 data->server = g_socket_new (G_SOCKET_FAMILY_IPV4,
689 G_SOCKET_TYPE_STREAM,
690 G_SOCKET_PROTOCOL_DEFAULT,
692 g_assert_no_error (error);
694 g_socket_set_blocking (data->server, TRUE);
695 iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
696 addr = g_inet_socket_address_new (iaddr, 0);
697 g_object_unref (iaddr);
699 g_socket_bind (data->server, addr, TRUE, &error);
700 g_assert_no_error (error);
701 g_object_unref (addr);
703 data->server_addr = g_socket_get_local_address (data->server, &error);
704 g_assert_no_error (error);
706 data->server_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (data->server_addr));
708 g_socket_listen (data->server, &error);
709 g_assert_no_error (error);
711 data->server_thread = g_thread_new ("server", echo_server_thread, data);
715 /******************************************************************/
716 /* Now a GResolver implementation, so the can't-resolve test will */
717 /* pass even if you have an evil DNS-faking ISP. */
718 /******************************************************************/
720 typedef GResolver GFakeResolver;
721 typedef GResolverClass GFakeResolverClass;
723 static GType g_fake_resolver_get_type (void);
724 G_DEFINE_TYPE (GFakeResolver, g_fake_resolver, G_TYPE_RESOLVER)
727 g_fake_resolver_init (GFakeResolver *gtr)
732 g_fake_resolver_lookup_by_name (GResolver *resolver,
733 const gchar *hostname,
734 GCancellable *cancellable,
737 if (!strcmp (hostname, "example.com"))
738 return g_list_prepend (NULL, g_inet_address_new_from_string ("127.0.0.1"));
741 /* Anything else is expected to fail. */
744 G_RESOLVER_ERROR_NOT_FOUND,
751 g_fake_resolver_lookup_by_name_async (GResolver *resolver,
752 const gchar *hostname,
753 GCancellable *cancellable,
754 GAsyncReadyCallback callback,
759 task = g_task_new (resolver, cancellable, callback, user_data);
761 if (!strcmp (hostname, "example.com"))
765 result = g_list_prepend (NULL, g_inet_address_new_from_string ("127.0.0.1"));
766 g_task_return_pointer (task, result, (GDestroyNotify) g_resolver_free_addresses);
770 g_task_return_new_error (task,
771 G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND,
774 g_object_unref (task);
778 g_fake_resolver_lookup_by_name_finish (GResolver *resolver,
779 GAsyncResult *result,
782 return g_task_propagate_pointer (G_TASK (result), error);
786 g_fake_resolver_class_init (GFakeResolverClass *fake_class)
788 GResolverClass *resolver_class = G_RESOLVER_CLASS (fake_class);
790 resolver_class->lookup_by_name = g_fake_resolver_lookup_by_name;
791 resolver_class->lookup_by_name_async = g_fake_resolver_lookup_by_name_async;
792 resolver_class->lookup_by_name_finish = g_fake_resolver_lookup_by_name_finish;
797 /****************************************/
798 /* We made it! Now for the actual test! */
799 /****************************************/
802 setup_test (gpointer fixture,
803 gconstpointer user_data)
808 teardown_test (gpointer fixture,
809 gconstpointer user_data)
813 g_strfreev (last_proxies);
816 g_clear_error (&proxy_a.last_error);
817 g_clear_error (&proxy_b.last_error);
821 static const gchar *testbuf = "0123456789abcdef";
824 do_echo_test (GSocketConnection *conn)
826 GIOStream *iostream = G_IO_STREAM (conn);
827 GInputStream *istream = g_io_stream_get_input_stream (iostream);
828 GOutputStream *ostream = g_io_stream_get_output_stream (iostream);
832 GError *error = NULL;
834 g_output_stream_write_all (ostream, testbuf, strlen (testbuf),
835 &nwrote, NULL, &error);
836 g_assert_no_error (error);
837 g_assert_cmpint (nwrote, ==, strlen (testbuf));
839 for (total = 0; total < nwrote; total += nread)
841 nread = g_input_stream_read (istream,
842 buf + total, sizeof (buf) - total,
844 g_assert_no_error (error);
845 g_assert_cmpint (nread, >, 0);
849 g_assert_cmpstr (buf, ==, testbuf);
853 async_got_conn (GObject *source,
854 GAsyncResult *result,
857 GSocketConnection **conn = user_data;
858 GError *error = NULL;
860 *conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (source),
862 g_assert_no_error (error);
866 async_got_error (GObject *source,
867 GAsyncResult *result,
870 GError **error = user_data;
872 g_assert (error != NULL && *error == NULL);
873 g_socket_client_connect_finish (G_SOCKET_CLIENT (source),
875 g_assert (*error != NULL);
880 assert_direct (GSocketConnection *conn)
882 GSocketAddress *addr;
883 GError *error = NULL;
885 g_assert_cmpint (g_strv_length (last_proxies), ==, 1);
886 g_assert_cmpstr (last_proxies[0], ==, "direct://");
887 g_assert_no_error (proxy_a.last_error);
888 g_assert_no_error (proxy_b.last_error);
890 addr = g_socket_connection_get_remote_address (conn, &error);
891 g_assert_no_error (error);
892 g_assert (!G_IS_PROXY_ADDRESS (addr));
893 g_object_unref (addr);
895 addr = g_socket_connection_get_local_address (conn, &error);
896 g_assert_no_error (error);
897 g_object_unref (addr);
899 g_assert (g_socket_connection_is_connected (conn));
903 test_direct_sync (gpointer fixture,
904 gconstpointer user_data)
906 GSocketConnection *conn;
908 GError *error = NULL;
910 /* The simple:// URI should not require any proxy. */
912 uri = g_strdup_printf ("simple://127.0.0.1:%u", server.server_port);
913 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
915 g_assert_no_error (error);
917 assert_direct (conn);
919 g_object_unref (conn);
923 test_direct_async (gpointer fixture,
924 gconstpointer user_data)
926 GSocketConnection *conn;
929 /* The simple:// URI should not require any proxy. */
930 uri = g_strdup_printf ("simple://127.0.0.1:%u", server.server_port);
932 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
933 async_got_conn, &conn);
936 g_main_context_iteration (NULL, TRUE);
938 assert_direct (conn);
940 g_object_unref (conn);
944 assert_single (GSocketConnection *conn)
946 GSocketAddress *addr;
947 const gchar *proxy_uri;
949 GError *error = NULL;
951 g_assert_cmpint (g_strv_length (last_proxies), ==, 2);
952 g_assert_cmpstr (last_proxies[0], ==, proxy_a.uri);
953 g_assert_cmpstr (last_proxies[1], ==, proxy_b.uri);
954 g_assert_no_error (proxy_a.last_error);
955 g_assert_no_error (proxy_b.last_error);
957 addr = g_socket_connection_get_remote_address (conn, &error);
958 g_assert_no_error (error);
959 g_assert (G_IS_PROXY_ADDRESS (addr));
960 proxy_uri = g_proxy_address_get_uri (G_PROXY_ADDRESS (addr));
961 g_assert_cmpstr (proxy_uri, ==, proxy_a.uri);
962 proxy_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
963 g_assert_cmpint (proxy_port, ==, proxy_a.port);
965 g_object_unref (addr);
969 test_single_sync (gpointer fixture,
970 gconstpointer user_data)
972 GSocketConnection *conn;
973 GError *error = NULL;
976 /* The alpha:// URI should be proxied via Proxy A */
977 uri = g_strdup_printf ("alpha://127.0.0.1:%u", server.server_port);
978 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
980 g_assert_no_error (error);
982 assert_single (conn);
985 g_object_unref (conn);
989 test_single_async (gpointer fixture,
990 gconstpointer user_data)
992 GSocketConnection *conn;
995 /* The alpha:// URI should be proxied via Proxy A */
996 uri = g_strdup_printf ("alpha://127.0.0.1:%u", server.server_port);
998 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
999 async_got_conn, &conn);
1001 while (conn == NULL)
1002 g_main_context_iteration (NULL, TRUE);
1004 assert_single (conn);
1005 do_echo_test (conn);
1006 g_object_unref (conn);
1010 assert_multiple (GSocketConnection *conn)
1012 GSocketAddress *addr;
1013 const gchar *proxy_uri;
1015 GError *error = NULL;
1017 g_assert_cmpint (g_strv_length (last_proxies), ==, 2);
1018 g_assert_cmpstr (last_proxies[0], ==, proxy_a.uri);
1019 g_assert_cmpstr (last_proxies[1], ==, proxy_b.uri);
1020 g_assert_error (proxy_a.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1021 g_assert_no_error (proxy_b.last_error);
1023 addr = g_socket_connection_get_remote_address (conn, &error);
1024 g_assert_no_error (error);
1025 g_assert (G_IS_PROXY_ADDRESS (addr));
1026 proxy_uri = g_proxy_address_get_uri (G_PROXY_ADDRESS (addr));
1027 g_assert_cmpstr (proxy_uri, ==, proxy_b.uri);
1028 proxy_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
1029 g_assert_cmpint (proxy_port, ==, proxy_b.port);
1031 g_object_unref (addr);
1035 test_multiple_sync (gpointer fixture,
1036 gconstpointer user_data)
1038 GSocketConnection *conn;
1039 GError *error = NULL;
1042 /* The beta:// URI should be proxied via Proxy B, after failing
1045 uri = g_strdup_printf ("beta://127.0.0.1:%u", server.server_port);
1046 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1048 g_assert_no_error (error);
1050 assert_multiple (conn);
1051 do_echo_test (conn);
1052 g_object_unref (conn);
1056 test_multiple_async (gpointer fixture,
1057 gconstpointer user_data)
1059 GSocketConnection *conn;
1062 /* The beta:// URI should be proxied via Proxy B, after failing
1065 uri = g_strdup_printf ("beta://127.0.0.1:%u", server.server_port);
1067 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1068 async_got_conn, &conn);
1070 while (conn == NULL)
1071 g_main_context_iteration (NULL, TRUE);
1073 assert_multiple (conn);
1074 do_echo_test (conn);
1075 g_object_unref (conn);
1079 test_dns (gpointer fixture,
1080 gconstpointer user_data)
1082 GSocketConnection *conn;
1083 GError *error = NULL;
1086 /* The simple:// and alpha:// URIs should fail with a DNS error,
1087 * but the beta:// URI should succeed, because we pass it to
1088 * Proxy B without trying to resolve it first
1092 uri = g_strdup_printf ("simple://no-such-host.xx:%u", server.server_port);
1093 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1094 g_assert_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND);
1095 g_clear_error (&error);
1097 g_assert_no_error (proxy_a.last_error);
1098 g_assert_no_error (proxy_b.last_error);
1099 teardown_test (NULL, NULL);
1101 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1102 async_got_error, &error);
1103 while (error == NULL)
1104 g_main_context_iteration (NULL, TRUE);
1105 g_assert_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND);
1106 g_clear_error (&error);
1109 g_assert_no_error (proxy_a.last_error);
1110 g_assert_no_error (proxy_b.last_error);
1111 teardown_test (NULL, NULL);
1114 uri = g_strdup_printf ("alpha://no-such-host.xx:%u", server.server_port);
1115 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1116 /* Since Proxy A fails, @client will try Proxy B too, which won't
1117 * load an alpha:// URI.
1119 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1120 g_clear_error (&error);
1122 g_assert_no_error (proxy_a.last_error);
1123 g_assert_error (proxy_b.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1124 teardown_test (NULL, NULL);
1126 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1127 async_got_error, &error);
1128 while (error == NULL)
1129 g_main_context_iteration (NULL, TRUE);
1130 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1131 g_clear_error (&error);
1134 g_assert_no_error (proxy_a.last_error);
1135 g_assert_error (proxy_b.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1136 teardown_test (NULL, NULL);
1139 uri = g_strdup_printf ("beta://no-such-host.xx:%u", server.server_port);
1140 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1141 g_assert_no_error (error);
1143 g_assert_no_error (proxy_a.last_error);
1144 g_assert_no_error (proxy_b.last_error);
1146 do_echo_test (conn);
1147 g_clear_object (&conn);
1148 teardown_test (NULL, NULL);
1150 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1151 async_got_conn, &conn);
1152 while (conn == NULL)
1153 g_main_context_iteration (NULL, TRUE);
1156 g_assert_no_error (proxy_a.last_error);
1157 g_assert_no_error (proxy_b.last_error);
1159 do_echo_test (conn);
1160 g_clear_object (&conn);
1161 teardown_test (NULL, NULL);
1165 assert_override (GSocketConnection *conn)
1167 g_assert_cmpint (g_strv_length (last_proxies), ==, 1);
1168 g_assert_cmpstr (last_proxies[0], ==, proxy_a.uri);
1171 g_assert_no_error (proxy_a.last_error);
1173 g_assert_error (proxy_a.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1177 test_override (gpointer fixture,
1178 gconstpointer user_data)
1180 GProxyResolver *alt_resolver;
1181 GSocketConnection *conn;
1182 GError *error = NULL;
1185 g_assert (g_socket_client_get_proxy_resolver (client) == g_proxy_resolver_get_default ());
1186 alt_resolver = g_object_new (g_test_alt_proxy_resolver_get_type (), NULL);
1187 g_socket_client_set_proxy_resolver (client, alt_resolver);
1188 g_assert (g_socket_client_get_proxy_resolver (client) == alt_resolver);
1190 /* Alt proxy resolver always returns Proxy A, so alpha:// should
1191 * succeed, and simple:// and beta:// should fail.
1195 uri = g_strdup_printf ("simple://127.0.0.1:%u", server.server_port);
1196 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1197 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1198 g_clear_error (&error);
1199 assert_override (conn);
1200 teardown_test (NULL, NULL);
1202 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1203 async_got_error, &error);
1204 while (error == NULL)
1205 g_main_context_iteration (NULL, TRUE);
1206 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1207 g_clear_error (&error);
1208 assert_override (conn);
1210 teardown_test (NULL, NULL);
1213 uri = g_strdup_printf ("alpha://127.0.0.1:%u", server.server_port);
1214 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1215 g_assert_no_error (error);
1216 assert_override (conn);
1217 do_echo_test (conn);
1218 g_clear_object (&conn);
1219 teardown_test (NULL, NULL);
1222 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1223 async_got_conn, &conn);
1224 while (conn == NULL)
1225 g_main_context_iteration (NULL, TRUE);
1226 assert_override (conn);
1227 do_echo_test (conn);
1228 g_clear_object (&conn);
1230 teardown_test (NULL, NULL);
1233 uri = g_strdup_printf ("beta://127.0.0.1:%u", server.server_port);
1234 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1235 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1236 g_clear_error (&error);
1237 assert_override (conn);
1238 teardown_test (NULL, NULL);
1240 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1241 async_got_error, &error);
1242 while (error == NULL)
1243 g_main_context_iteration (NULL, TRUE);
1244 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1245 g_clear_error (&error);
1246 assert_override (conn);
1248 teardown_test (NULL, NULL);
1250 g_assert (g_socket_client_get_proxy_resolver (client) == alt_resolver);
1251 g_socket_client_set_proxy_resolver (client, NULL);
1252 g_assert (g_socket_client_get_proxy_resolver (client) == g_proxy_resolver_get_default ());
1253 g_object_unref (alt_resolver);
1257 assert_destination_port (GSocketAddressEnumerator *etor,
1260 GSocketAddress *addr;
1261 GProxyAddress *paddr;
1262 GError *error = NULL;
1264 while ((addr = g_socket_address_enumerator_next (etor, NULL, &error)))
1266 g_assert_no_error (error);
1268 g_assert (G_IS_PROXY_ADDRESS (addr));
1269 paddr = G_PROXY_ADDRESS (addr);
1270 g_assert_cmpint (g_proxy_address_get_destination_port (paddr), ==, port);
1271 g_object_unref (addr);
1273 g_assert_no_error (error);
1277 test_proxy_enumerator_ports (void)
1279 GSocketAddressEnumerator *etor;
1281 etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
1282 "uri", "http://example.com/",
1284 assert_destination_port (etor, 0);
1285 g_object_unref (etor);
1287 /* Have to call this to clear last_proxies so the next call to
1288 * g_test_proxy_resolver_lookup() won't assert.
1290 teardown_test (NULL, NULL);
1292 etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
1293 "uri", "http://example.com:8080/",
1295 assert_destination_port (etor, 8080);
1296 g_object_unref (etor);
1298 teardown_test (NULL, NULL);
1300 etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
1301 "uri", "http://example.com/",
1304 assert_destination_port (etor, 80);
1305 g_object_unref (etor);
1307 teardown_test (NULL, NULL);
1309 etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
1310 "uri", "http://example.com:8080/",
1313 assert_destination_port (etor, 8080);
1314 g_object_unref (etor);
1316 teardown_test (NULL, NULL);
1323 GResolver *fake_resolver;
1324 GCancellable *cancellable;
1327 g_test_init (&argc, &argv, NULL);
1329 /* Register stuff. The dummy g_proxy_get_default_for_protocol() call
1330 * is to force _g_io_modules_ensure_extension_points_registered() to
1331 * get called, so we can then register a proxy resolver extension
1334 g_proxy_get_default_for_protocol ("foo");
1335 g_test_proxy_resolver_get_type ();
1336 g_proxy_a_get_type ();
1337 g_proxy_b_get_type ();
1338 g_setenv ("GIO_USE_PROXY_RESOLVER", "test", TRUE);
1340 fake_resolver = g_object_new (g_fake_resolver_get_type (), NULL);
1341 g_resolver_set_default (fake_resolver);
1343 cancellable = g_cancellable_new ();
1344 create_server (&server, cancellable);
1345 create_proxy (&proxy_a, 'a', "alpha", cancellable);
1346 create_proxy (&proxy_b, 'b', "beta", cancellable);
1348 client = g_socket_client_new ();
1349 g_assert_cmpint (g_socket_client_get_enable_proxy (client), ==, TRUE);
1351 g_test_add_vtable ("/proxy/direct_sync", 0, NULL, setup_test, test_direct_sync, teardown_test);
1352 g_test_add_vtable ("/proxy/direct_async", 0, NULL, setup_test, test_direct_async, teardown_test);
1353 g_test_add_vtable ("/proxy/single_sync", 0, NULL, setup_test, test_single_sync, teardown_test);
1354 g_test_add_vtable ("/proxy/single_async", 0, NULL, setup_test, test_single_async, teardown_test);
1355 g_test_add_vtable ("/proxy/multiple_sync", 0, NULL, setup_test, test_multiple_sync, teardown_test);
1356 g_test_add_vtable ("/proxy/multiple_async", 0, NULL, setup_test, test_multiple_async, teardown_test);
1357 g_test_add_vtable ("/proxy/dns", 0, NULL, setup_test, test_dns, teardown_test);
1358 g_test_add_vtable ("/proxy/override", 0, NULL, setup_test, test_override, teardown_test);
1359 g_test_add_func ("/proxy/enumerator-ports", test_proxy_enumerator_ports);
1361 result = g_test_run();
1363 g_object_unref (client);
1365 g_cancellable_cancel (cancellable);
1366 g_thread_join (proxy_a.thread);
1367 g_thread_join (proxy_b.thread);
1368 g_thread_join (server.server_thread);
1370 g_object_unref (cancellable);