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
21struct _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
32G_DEFINE_TYPE (MockResolver, mock_resolver, G_TYPE_RESOLVER)
33
34MockResolver *
35mock_resolver_new (void)
36{
37 return g_object_new (MOCK_TYPE_RESOLVER, NULL);
38}
39
40void
41mock_resolver_set_ipv4_delay_ms (MockResolver *self, guint delay_ms)
42{
43 self->ipv4_delay_ms = delay_ms;
44}
45
46static gpointer
47copy_object (gconstpointer obj, gpointer user_data)
48{
49 return g_object_ref (G_OBJECT (obj));
50}
51
52void
53mock_resolver_set_ipv4_results (MockResolver *self, GList *results)
54{
55 if (self->ipv4_results)
56 g_list_free_full (list: self->ipv4_results, free_func: g_object_unref);
57 self->ipv4_results = g_list_copy_deep (list: results, func: copy_object, NULL);
58}
59
60void
61mock_resolver_set_ipv4_error (MockResolver *self, GError *error)
62{
63 g_clear_error (err: &self->ipv4_error);
64 if (error)
65 self->ipv4_error = g_error_copy (error);
66}
67
68void
69mock_resolver_set_ipv6_delay_ms (MockResolver *self, guint delay_ms)
70{
71 self->ipv6_delay_ms = delay_ms;
72}
73
74void
75mock_resolver_set_ipv6_results (MockResolver *self, GList *results)
76{
77 if (self->ipv6_results)
78 g_list_free_full (list: self->ipv6_results, free_func: g_object_unref);
79 self->ipv6_results = g_list_copy_deep (list: results, func: copy_object, NULL);
80}
81
82void
83mock_resolver_set_ipv6_error (MockResolver *self, GError *error)
84{
85 g_clear_error (err: &self->ipv6_error);
86 if (error)
87 self->ipv6_error = g_error_copy (error);
88}
89
90static void
91do_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 (microseconds: self->ipv4_delay_ms * 1000);
102 if (self->ipv4_error)
103 g_task_return_error (task, error: g_error_copy (error: self->ipv4_error));
104 else
105 g_task_return_pointer (task, result: g_list_copy_deep (list: self->ipv4_results, func: copy_object, NULL), NULL);
106 }
107 else if (flags == G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY)
108 {
109 g_usleep (microseconds: self->ipv6_delay_ms * 1000);
110 if (self->ipv6_error)
111 g_task_return_error (task, error: g_error_copy (error: self->ipv6_error));
112 else
113 g_task_return_pointer (task, result: g_list_copy_deep (list: self->ipv6_results, func: 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, result: g_list_copy_deep (list: self->ipv4_results, func: copy_object, NULL), NULL);
120 }
121 else
122 g_assert_not_reached ();
123}
124
125static void
126lookup_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 (source_object: resolver, cancellable, callback, callback_data: user_data);
134 g_task_set_task_data (task, GUINT_TO_POINTER(flags), NULL);
135 g_task_run_in_thread (task, task_func: do_lookup_by_name);
136 g_object_unref (object: task);
137}
138
139static GList *
140lookup_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 (source_object: 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, task_func: do_lookup_by_name);
149 result = g_task_propagate_pointer (task, error);
150 g_object_unref (object: task);
151 return result;
152}
153
154
155static GList *
156lookup_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
163static void
164mock_resolver_finalize (GObject *object)
165{
166 MockResolver *self = (MockResolver*)object;
167
168 g_clear_error (err: &self->ipv4_error);
169 g_clear_error (err: &self->ipv6_error);
170 if (self->ipv6_results)
171 g_list_free_full (list: self->ipv6_results, free_func: g_object_unref);
172 if (self->ipv4_results)
173 g_list_free_full (list: self->ipv4_results, free_func: g_object_unref);
174
175 G_OBJECT_CLASS (mock_resolver_parent_class)->finalize (object);
176}
177
178static void
179mock_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
189static void
190mock_resolver_init (MockResolver *self)
191{
192}
193

source code of gtk/subprojects/glib/gio/tests/mock-resolver.c