1 | /* GLib testing framework examples and tests |
2 | * |
3 | * Copyright (C) 2008-2010 Red Hat, Inc. |
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 | * Author: David Zeuthen <davidz@redhat.com> |
19 | */ |
20 | |
21 | #include <locale.h> |
22 | #include <gio/gio.h> |
23 | |
24 | /* ---------------------------------------------------------------------------------------------------- */ |
25 | |
26 | static void |
27 | on_notify_locked (GObject *object, |
28 | GParamSpec *pspec, |
29 | gpointer user_data) |
30 | { |
31 | gint *count = user_data; |
32 | *count += 1; |
33 | } |
34 | |
35 | static void |
36 | message_lock (void) |
37 | { |
38 | GDBusMessage *m; |
39 | gint count; |
40 | |
41 | count = 0; |
42 | m = g_dbus_message_new (); |
43 | g_signal_connect (m, |
44 | "notify::locked" , |
45 | G_CALLBACK (on_notify_locked), |
46 | &count); |
47 | g_assert (!g_dbus_message_get_locked (m)); |
48 | g_dbus_message_lock (message: m); |
49 | g_assert (g_dbus_message_get_locked (m)); |
50 | g_assert_cmpint (count, ==, 1); |
51 | g_dbus_message_lock (message: m); |
52 | g_assert (g_dbus_message_get_locked (m)); |
53 | g_assert_cmpint (count, ==, 1); |
54 | |
55 | g_test_expect_message (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_WARNING, |
56 | pattern: "*Attempted to modify a locked message*" ); |
57 | g_dbus_message_set_serial (message: m, serial: 42); |
58 | g_test_assert_expected_messages (); |
59 | |
60 | g_test_expect_message (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_WARNING, |
61 | pattern: "*Attempted to modify a locked message*" ); |
62 | g_dbus_message_set_byte_order (message: m, byte_order: G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN); |
63 | g_test_assert_expected_messages (); |
64 | |
65 | g_test_expect_message (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_WARNING, |
66 | pattern: "*Attempted to modify a locked message*" ); |
67 | g_dbus_message_set_message_type (message: m, type: G_DBUS_MESSAGE_TYPE_METHOD_CALL); |
68 | g_test_assert_expected_messages (); |
69 | |
70 | g_test_expect_message (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_WARNING, |
71 | pattern: "*Attempted to modify a locked message*" ); |
72 | g_dbus_message_set_flags (message: m, flags: G_DBUS_MESSAGE_FLAGS_NONE); |
73 | g_test_assert_expected_messages (); |
74 | |
75 | g_test_expect_message (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_WARNING, |
76 | pattern: "*Attempted to modify a locked message*" ); |
77 | g_dbus_message_set_body (message: m, NULL); |
78 | g_test_assert_expected_messages (); |
79 | |
80 | g_test_expect_message (G_LOG_DOMAIN, log_level: G_LOG_LEVEL_WARNING, |
81 | pattern: "*Attempted to modify a locked message*" ); |
82 | g_dbus_message_set_header (message: m, header_field: 0, NULL); |
83 | g_test_assert_expected_messages (); |
84 | |
85 | g_object_unref (object: m); |
86 | } |
87 | |
88 | /* ---------------------------------------------------------------------------------------------------- */ |
89 | |
90 | static void |
91 | message_copy (void) |
92 | { |
93 | GDBusMessage *m; |
94 | GDBusMessage *copy; |
95 | GError *error; |
96 | guchar *; |
97 | guchar *; |
98 | guint n; |
99 | |
100 | m = g_dbus_message_new_method_call (name: "org.example.Name" , |
101 | path: "/org/example/Object" , |
102 | interface_: "org.example.Interface" , |
103 | method: "Method" ); |
104 | g_dbus_message_set_serial (message: m, serial: 42); |
105 | g_dbus_message_set_byte_order (message: m, byte_order: G_DBUS_MESSAGE_BYTE_ORDER_BIG_ENDIAN); |
106 | |
107 | error = NULL; |
108 | copy = g_dbus_message_copy (message: m, error: &error); |
109 | g_assert_no_error (error); |
110 | g_assert (G_IS_DBUS_MESSAGE (copy)); |
111 | g_assert (m != copy); |
112 | g_assert_cmpint (G_OBJECT (m)->ref_count, ==, 1); |
113 | g_assert_cmpint (G_OBJECT (copy)->ref_count, ==, 1); |
114 | |
115 | g_assert_cmpint (g_dbus_message_get_serial (copy), ==, g_dbus_message_get_serial (m)); |
116 | g_assert_cmpint (g_dbus_message_get_byte_order (copy), ==, g_dbus_message_get_byte_order (m)); |
117 | g_assert_cmpint (g_dbus_message_get_flags (copy), ==, g_dbus_message_get_flags (m)); |
118 | g_assert_cmpint (g_dbus_message_get_message_type (copy), ==, g_dbus_message_get_message_type (m)); |
119 | m_headers = g_dbus_message_get_header_fields (message: m); |
120 | copy_headers = g_dbus_message_get_header_fields (message: copy); |
121 | g_assert (m_headers != NULL); |
122 | g_assert (copy_headers != NULL); |
123 | for (n = 0; m_headers[n] != 0; n++) |
124 | { |
125 | GVariant *m_val; |
126 | GVariant *copy_val; |
127 | m_val = g_dbus_message_get_header (message: m, header_field: m_headers[n]); |
128 | copy_val = g_dbus_message_get_header (message: m, header_field: m_headers[n]); |
129 | g_assert (m_val != NULL); |
130 | g_assert (copy_val != NULL); |
131 | g_assert_cmpvariant (m_val, copy_val); |
132 | } |
133 | g_assert_cmpint (n, >, 0); /* make sure we actually compared headers etc. */ |
134 | g_assert_cmpint (copy_headers[n], ==, 0); |
135 | g_free (mem: m_headers); |
136 | g_free (mem: copy_headers); |
137 | |
138 | g_object_unref (object: copy); |
139 | g_object_unref (object: m); |
140 | } |
141 | |
142 | /* ---------------------------------------------------------------------------------------------------- */ |
143 | |
144 | /* Test g_dbus_message_bytes_needed() returns correct results for a variety of |
145 | * arbitrary binary inputs.*/ |
146 | static void |
147 | message_bytes_needed (void) |
148 | { |
149 | const struct |
150 | { |
151 | const guint8 blob[16]; |
152 | gssize expected_bytes_needed; |
153 | } |
154 | vectors[] = |
155 | { |
156 | /* Little endian with header rounding */ |
157 | { { 'l', 0, 0, 1, /* endianness, message type, flags, protocol version */ |
158 | 50, 0, 0, 0, /* body length */ |
159 | 1, 0, 0, 0, /* message serial */ |
160 | 7, 0, 0, 0 /* header length */}, 74 }, |
161 | /* Little endian without header rounding */ |
162 | { { 'l', 0, 0, 1, /* endianness, message type, flags, protocol version */ |
163 | 50, 0, 0, 0, /* body length */ |
164 | 1, 0, 0, 0, /* message serial */ |
165 | 8, 0, 0, 0 /* header length */}, 74 }, |
166 | /* Big endian with header rounding */ |
167 | { { 'B', 0, 0, 1, /* endianness, message type, flags, protocol version */ |
168 | 0, 0, 0, 50, /* body length */ |
169 | 0, 0, 0, 1, /* message serial */ |
170 | 0, 0, 0, 7 /* header length */}, 74 }, |
171 | /* Big endian without header rounding */ |
172 | { { 'B', 0, 0, 1, /* endianness, message type, flags, protocol version */ |
173 | 0, 0, 0, 50, /* body length */ |
174 | 0, 0, 0, 1, /* message serial */ |
175 | 0, 0, 0, 8 /* header length */}, 74 }, |
176 | /* Invalid endianness */ |
177 | { { '!', 0, 0, 1, /* endianness, message type, flags, protocol version */ |
178 | 0, 0, 0, 50, /* body length */ |
179 | 0, 0, 0, 1, /* message serial */ |
180 | 0, 0, 0, 8 /* header length */}, -1 }, |
181 | /* Oversized */ |
182 | { { 'l', 0, 0, 1, /* endianness, message type, flags, protocol version */ |
183 | 0, 0, 0, 0x08, /* body length (128MiB) */ |
184 | 1, 0, 0, 0, /* message serial */ |
185 | 7, 0, 0, 0 /* header length */}, -1 }, |
186 | }; |
187 | gsize i; |
188 | |
189 | for (i = 0; i < G_N_ELEMENTS (vectors); i++) |
190 | { |
191 | gssize bytes_needed; |
192 | GError *local_error = NULL; |
193 | |
194 | g_test_message (format: "Vector: %" G_GSIZE_FORMAT, i); |
195 | |
196 | bytes_needed = g_dbus_message_bytes_needed (blob: (guchar *) vectors[i].blob, |
197 | G_N_ELEMENTS (vectors[i].blob), |
198 | error: &local_error); |
199 | |
200 | if (vectors[i].expected_bytes_needed < 0) |
201 | g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT); |
202 | else |
203 | g_assert_no_error (local_error); |
204 | g_assert_cmpint (bytes_needed, ==, vectors[i].expected_bytes_needed); |
205 | |
206 | g_clear_error (err: &local_error); |
207 | } |
208 | } |
209 | |
210 | /* ---------------------------------------------------------------------------------------------------- */ |
211 | |
212 | int |
213 | main (int argc, |
214 | char *argv[]) |
215 | { |
216 | setlocale (LC_ALL, locale: "C" ); |
217 | |
218 | g_test_init (argc: &argc, argv: &argv, NULL); |
219 | |
220 | g_test_add_func (testpath: "/gdbus/message/lock" , test_func: message_lock); |
221 | g_test_add_func (testpath: "/gdbus/message/copy" , test_func: message_copy); |
222 | g_test_add_func (testpath: "/gdbus/message/bytes-needed" , test_func: message_bytes_needed); |
223 | |
224 | return g_test_run (); |
225 | } |
226 | |