• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2018 Igalia S.L.
4  *
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.1 of the License, or (at your option) any later version.
9  *
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.
14  *
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/>.
17  */
18 
19 #include "mock-resolver.h"
20 
21 struct _MockResolver
22 {
23   GResolver parent_instance;
24   guint ipv4_delay_ms;
25   guint ipv6_delay_ms;
26   GList *ipv4_results;
27   GList *ipv6_results;
28   GError *ipv4_error;
29   GError *ipv6_error;
30 };
31 
G_DEFINE_TYPE(MockResolver,mock_resolver,G_TYPE_RESOLVER)32 G_DEFINE_TYPE (MockResolver, mock_resolver, G_TYPE_RESOLVER)
33 
34 MockResolver *
35 mock_resolver_new (void)
36 {
37   return g_object_new (MOCK_TYPE_RESOLVER, NULL);
38 }
39 
40 void
mock_resolver_set_ipv4_delay_ms(MockResolver * self,guint delay_ms)41 mock_resolver_set_ipv4_delay_ms (MockResolver *self, guint delay_ms)
42 {
43   self->ipv4_delay_ms = delay_ms;
44 }
45 
46 static gpointer
copy_object(gconstpointer obj,gpointer user_data)47 copy_object (gconstpointer obj, gpointer user_data)
48 {
49   return g_object_ref (G_OBJECT (obj));
50 }
51 
52 void
mock_resolver_set_ipv4_results(MockResolver * self,GList * results)53 mock_resolver_set_ipv4_results (MockResolver *self, GList *results)
54 {
55   if (self->ipv4_results)
56     g_list_free_full (self->ipv4_results, g_object_unref);
57   self->ipv4_results = g_list_copy_deep (results, copy_object, NULL);
58 }
59 
60 void
mock_resolver_set_ipv4_error(MockResolver * self,GError * error)61 mock_resolver_set_ipv4_error (MockResolver *self, GError *error)
62 {
63   g_clear_error (&self->ipv4_error);
64   if (error)
65     self->ipv4_error = g_error_copy (error);
66 }
67 
68 void
mock_resolver_set_ipv6_delay_ms(MockResolver * self,guint delay_ms)69 mock_resolver_set_ipv6_delay_ms (MockResolver *self, guint delay_ms)
70 {
71   self->ipv6_delay_ms = delay_ms;
72 }
73 
74 void
mock_resolver_set_ipv6_results(MockResolver * self,GList * results)75 mock_resolver_set_ipv6_results (MockResolver *self, GList *results)
76 {
77   if (self->ipv6_results)
78     g_list_free_full (self->ipv6_results, g_object_unref);
79   self->ipv6_results = g_list_copy_deep (results, copy_object, NULL);
80 }
81 
82 void
mock_resolver_set_ipv6_error(MockResolver * self,GError * error)83 mock_resolver_set_ipv6_error (MockResolver *self, GError *error)
84 {
85   g_clear_error (&self->ipv6_error);
86   if (error)
87     self->ipv6_error = g_error_copy (error);
88 }
89 
90 static void
do_lookup_by_name(GTask * task,gpointer source_object,gpointer task_data,GCancellable * cancellable)91 do_lookup_by_name (GTask         *task,
92                    gpointer       source_object,
93                    gpointer       task_data,
94                    GCancellable  *cancellable)
95 {
96   MockResolver *self = source_object;
97   GResolverNameLookupFlags flags = GPOINTER_TO_UINT(task_data);
98 
99   if (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY)
100     {
101       g_usleep (self->ipv4_delay_ms * 1000);
102       if (self->ipv4_error)
103         g_task_return_error (task, g_error_copy (self->ipv4_error));
104       else
105         g_task_return_pointer (task, g_list_copy_deep (self->ipv4_results, copy_object, NULL), NULL);
106     }
107   else if (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY)
108     {
109       g_usleep (self->ipv6_delay_ms * 1000);
110       if (self->ipv6_error)
111         g_task_return_error (task, g_error_copy (self->ipv6_error));
112       else
113         g_task_return_pointer (task, g_list_copy_deep (self->ipv6_results, copy_object, NULL), NULL);
114     }
115   else if (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT)
116     {
117       /* This is only the minimal implementation needed for some tests */
118       g_assert (self->ipv4_error == NULL && self->ipv6_error == NULL && self->ipv6_results == NULL);
119       g_task_return_pointer (task, g_list_copy_deep (self->ipv4_results, copy_object, NULL), NULL);
120     }
121   else
122     g_assert_not_reached ();
123 }
124 
125 static void
lookup_by_name_with_flags_async(GResolver * resolver,const gchar * hostname,GResolverNameLookupFlags flags,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)126 lookup_by_name_with_flags_async (GResolver                *resolver,
127                                  const gchar              *hostname,
128                                  GResolverNameLookupFlags  flags,
129                                  GCancellable             *cancellable,
130                                  GAsyncReadyCallback       callback,
131                                  gpointer                  user_data)
132 {
133   GTask *task = g_task_new (resolver, cancellable, callback, user_data);
134   g_task_set_task_data (task, GUINT_TO_POINTER(flags), NULL);
135   g_task_run_in_thread (task, do_lookup_by_name);
136   g_object_unref (task);
137 }
138 
139 static GList *
lookup_by_name(GResolver * resolver,const gchar * hostname,GCancellable * cancellable,GError ** error)140 lookup_by_name (GResolver    *resolver,
141                 const gchar  *hostname,
142                 GCancellable *cancellable,
143                 GError       **error)
144 {
145   GList *result = NULL;
146   GTask *task = g_task_new (resolver, cancellable, NULL, NULL);
147   g_task_set_task_data (task, GUINT_TO_POINTER (G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT), NULL);
148   g_task_run_in_thread_sync (task, do_lookup_by_name);
149   result = g_task_propagate_pointer (task, error);
150   g_object_unref (task);
151   return result;
152 }
153 
154 
155 static GList *
lookup_by_name_with_flags_finish(GResolver * resolver,GAsyncResult * result,GError ** error)156 lookup_by_name_with_flags_finish (GResolver     *resolver,
157                                   GAsyncResult  *result,
158                                   GError       **error)
159 {
160   return g_task_propagate_pointer (G_TASK (result), error);
161 }
162 
163 static void
mock_resolver_finalize(GObject * object)164 mock_resolver_finalize (GObject *object)
165 {
166   MockResolver *self = (MockResolver*)object;
167 
168   g_clear_error (&self->ipv4_error);
169   g_clear_error (&self->ipv6_error);
170   if (self->ipv6_results)
171     g_list_free_full (self->ipv6_results, g_object_unref);
172   if (self->ipv4_results)
173     g_list_free_full (self->ipv4_results, g_object_unref);
174 
175   G_OBJECT_CLASS (mock_resolver_parent_class)->finalize (object);
176 }
177 
178 static void
mock_resolver_class_init(MockResolverClass * klass)179 mock_resolver_class_init (MockResolverClass *klass)
180 {
181   GResolverClass *resolver_class = G_RESOLVER_CLASS (klass);
182   GObjectClass *object_class = G_OBJECT_CLASS (klass);
183   resolver_class->lookup_by_name_with_flags_async  = lookup_by_name_with_flags_async;
184   resolver_class->lookup_by_name_with_flags_finish = lookup_by_name_with_flags_finish;
185   resolver_class->lookup_by_name = lookup_by_name;
186   object_class->finalize = mock_resolver_finalize;
187 }
188 
189 static void
mock_resolver_init(MockResolver * self)190 mock_resolver_init (MockResolver *self)
191 {
192 }
193