Line data Source code
1 : /*
2 : Copyright (C) 2015 Red Hat, Inc.
3 :
4 : This library is free software; you can redistribute it and/or
5 : modify it under the terms of the GNU Lesser General Public
6 : License as published by the Free Software Foundation; either
7 : version 2.1 of the License, or (at your option) any later version.
8 :
9 : This library is distributed in the hope that it will be useful,
10 : but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : Lesser General Public License for more details.
13 :
14 : You should have received a copy of the GNU Lesser General Public
15 : License along with this library; if not, see <http://www.gnu.org/licenses/>.
16 : */
17 : #include <config.h>
18 :
19 : #define G_LOG_DOMAIN "Spice"
20 :
21 : #include <glib.h>
22 : #include <stdlib.h>
23 :
24 : #include "common/log.h"
25 :
26 : #define OTHER_LOG_DOMAIN "Other"
27 : #define LOG_OTHER_HELPER(suffix, level) \
28 : G_GNUC_PRINTF(1, 2) \
29 : static void G_PASTE(other_, suffix)(const gchar *format, ...) \
30 : { \
31 : va_list args; \
32 : \
33 : va_start (args, format); \
34 : g_logv(OTHER_LOG_DOMAIN, G_LOG_LEVEL_ ## level, format, args); \
35 : va_end (args); \
36 : }
37 :
38 : /* Set of helpers to log in a different log domain than "Spice" */
39 4 : LOG_OTHER_HELPER(debug, DEBUG)
40 4 : LOG_OTHER_HELPER(info, INFO)
41 4 : LOG_OTHER_HELPER(message, MESSAGE)
42 2 : LOG_OTHER_HELPER(warning, WARNING)
43 2 : LOG_OTHER_HELPER(critical, CRITICAL)
44 :
45 : /* Checks that spice_warning() aborts after setting G_DEBUG=fatal-warnings */
46 1 : static void test_spice_fatal_warning(void)
47 : {
48 1 : g_setenv("G_DEBUG", "fatal-warnings", TRUE);
49 1 : if (g_test_subprocess()) {
50 0 : spice_warning("spice_warning");
51 0 : return;
52 : }
53 1 : g_test_trap_subprocess(NULL, 0, 0);
54 1 : g_test_trap_assert_failed();
55 1 : g_test_trap_assert_stderr("*spice_warning*");
56 1 : g_unsetenv("G_DEBUG");
57 : }
58 :
59 : /* Checks that spice_critical() aborts by default */
60 1 : static void test_spice_fatal_critical(void)
61 : {
62 1 : if (g_test_subprocess()) {
63 0 : spice_critical("spice_critical");
64 : return;
65 : }
66 1 : g_test_trap_subprocess(NULL, 0, 0);
67 1 : g_test_trap_assert_failed();
68 1 : g_test_trap_assert_stderr("*spice_critical*");
69 : }
70 :
71 : /* Checks that g_critical() does not abort by default */
72 2 : static void test_spice_non_fatal_g_critical(void)
73 : {
74 2 : if (g_test_subprocess()) {
75 1 : g_critical("g_critical");
76 1 : return;
77 : }
78 1 : g_test_trap_subprocess(NULL, 0, 0);
79 1 : g_test_trap_assert_passed();
80 1 : g_test_trap_assert_stderr("*g_critical*");
81 : }
82 :
83 : /* Checks that g_critical() aborts after setting G_DEBUG=fatal-criticals */
84 1 : static void test_spice_fatal_g_critical(void)
85 : {
86 1 : g_setenv("G_DEBUG", "fatal-criticals", TRUE);
87 1 : if (g_test_subprocess()) {
88 0 : g_critical("g_critical");
89 0 : return;
90 : }
91 1 : g_test_trap_subprocess(NULL, 0, 0);
92 1 : g_test_trap_assert_failed();
93 1 : g_test_trap_assert_stderr("*g_critical*");
94 1 : g_unsetenv("G_DEBUG");
95 : }
96 :
97 : /* Checks that spice_return_if_fail() aborts by default */
98 1 : static void test_spice_fatal_return_if_fail(void)
99 : {
100 1 : if (g_test_subprocess()) {
101 0 : spice_return_if_fail(FALSE);
102 : return;
103 : }
104 1 : g_test_trap_subprocess(NULL, 0, 0);
105 1 : g_test_trap_assert_failed();
106 1 : g_test_trap_assert_stderr("*test_spice_fatal_return_if_fail*");
107 : }
108 :
109 : /* Checks that g_return_if_fail() does not abort by default */
110 2 : static void test_spice_non_fatal_g_return_if_fail(void)
111 : {
112 2 : if (g_test_subprocess()) {
113 1 : g_return_if_fail(FALSE);
114 : return;
115 : }
116 1 : g_test_trap_subprocess(NULL, 0, 0);
117 1 : g_test_trap_assert_passed();
118 : }
119 :
120 : /* Checks that spice_*, g_* and other_* (different log domain as g_*) all
121 : * go through g_log() with the correct domain/log level. This then checks
122 : * that only logs with level 'message' or higher are shown by default.
123 : */
124 2 : static void test_log_levels(void)
125 : {
126 2 : if (g_test_subprocess()) {
127 1 : g_test_expect_message(G_LOG_DOMAIN,
128 : G_LOG_LEVEL_WARNING,
129 : "*spice_warning");
130 1 : spice_warning("spice_warning");
131 1 : g_test_expect_message(G_LOG_DOMAIN,
132 : G_LOG_LEVEL_INFO,
133 : "*spice_info");
134 1 : spice_info("spice_info");
135 1 : g_test_expect_message(G_LOG_DOMAIN,
136 : G_LOG_LEVEL_DEBUG,
137 : "*spice_debug");
138 1 : spice_debug("spice_debug");
139 :
140 1 : g_test_expect_message(G_LOG_DOMAIN,
141 : G_LOG_LEVEL_CRITICAL,
142 : "*g_critical");
143 1 : g_critical("g_critical");
144 1 : g_test_expect_message(G_LOG_DOMAIN,
145 : G_LOG_LEVEL_WARNING,
146 : "*g_warning");
147 1 : g_warning("g_warning");
148 1 : g_test_expect_message(G_LOG_DOMAIN,
149 : G_LOG_LEVEL_MESSAGE,
150 : "*g_message");
151 1 : g_message("g_message");
152 1 : g_test_expect_message(G_LOG_DOMAIN,
153 : G_LOG_LEVEL_INFO,
154 : "*g_info");
155 1 : g_info("g_info");
156 1 : g_test_expect_message(G_LOG_DOMAIN,
157 : G_LOG_LEVEL_DEBUG,
158 : "*g_debug");
159 1 : g_debug("g_debug");
160 :
161 1 : g_test_expect_message(OTHER_LOG_DOMAIN,
162 : G_LOG_LEVEL_CRITICAL,
163 : "*other_critical");
164 1 : other_critical("other_critical");
165 1 : g_test_expect_message(OTHER_LOG_DOMAIN,
166 : G_LOG_LEVEL_WARNING,
167 : "*other_warning");
168 1 : other_warning("other_warning");
169 1 : g_test_expect_message(OTHER_LOG_DOMAIN,
170 : G_LOG_LEVEL_MESSAGE,
171 : "*other_message");
172 1 : other_message("other_message");
173 1 : g_test_expect_message(OTHER_LOG_DOMAIN,
174 : G_LOG_LEVEL_INFO,
175 : "*other_info");
176 1 : other_info("other_info");
177 1 : g_test_expect_message(OTHER_LOG_DOMAIN,
178 : G_LOG_LEVEL_DEBUG,
179 : "*other_debug");
180 1 : other_debug("other_debug");
181 :
182 1 : g_test_assert_expected_messages();
183 :
184 :
185 : /* g_test_expected_message only checks whether the appropriate messages got up to g_log()
186 : * The following calls will be caught by the parent process to check what was (not) printed
187 : * to stdout/stderr
188 : */
189 1 : spice_warning("spice_warning");
190 1 : spice_info("spice_info");
191 1 : spice_debug("spice_debug");
192 :
193 1 : g_critical("g_critical");
194 1 : g_warning("g_warning");
195 1 : g_message("g_message");
196 1 : g_info("g_info");
197 1 : g_debug("g_debug");
198 :
199 1 : other_critical("other_critical");
200 1 : other_warning("other_warning");
201 1 : other_message("other_message");
202 1 : other_info("other_info");
203 1 : other_debug("other_debug");
204 :
205 1 : return;
206 : }
207 1 : g_test_trap_subprocess(NULL, 0, 0);
208 1 : g_test_trap_assert_passed();
209 1 : g_test_trap_assert_stderr("*spice_warning\n*g_critical\n*g_warning\n*g_message\n*other_critical\n*other_warning\n*other_message\n");
210 1 : g_test_trap_assert_stdout_unmatched("*spice_info*");
211 1 : g_test_trap_assert_stdout_unmatched("*spice_debug*");
212 1 : g_test_trap_assert_stdout_unmatched("*g_info*");
213 1 : g_test_trap_assert_stdout_unmatched("*g_debug*");
214 1 : g_test_trap_assert_stdout_unmatched("*other_info*");
215 1 : g_test_trap_assert_stdout_unmatched("*other_debug*");
216 : }
217 :
218 : /* Checks that setting G_MESSAGES_DEBUG to 'Spice' impacts spice_debug() and
219 : * g_debug() but not other_debug() */
220 2 : static void test_spice_g_messages_debug(void)
221 : {
222 2 : if (g_test_subprocess()) {
223 1 : g_setenv("G_MESSAGES_DEBUG", "Spice", TRUE);
224 :
225 1 : spice_debug("spice_debug");
226 1 : spice_info("spice_info");
227 1 : g_debug("g_debug");
228 1 : g_info("g_info");
229 1 : g_message("g_message");
230 1 : other_debug("other_debug");
231 1 : other_info("other_info");
232 1 : other_message("other_message");
233 :
234 1 : return;
235 : }
236 :
237 1 : g_test_trap_subprocess(NULL, 0, 0);
238 1 : g_test_trap_assert_passed();
239 1 : g_test_trap_assert_stdout("*spice_debug\n*spice_info\n*g_debug\n*g_info\n");
240 1 : g_test_trap_assert_stderr("*g_message\n*other_message\n");
241 1 : g_test_trap_assert_stdout_unmatched("*other_debug*");
242 1 : g_test_trap_assert_stdout_unmatched("*other_info*");
243 : }
244 :
245 : /* Checks that setting G_MESSAGES_DEBUG to 'all' impacts spice_debug(),
246 : * g_debug() and other_debug() */
247 2 : static void test_spice_g_messages_debug_all(void)
248 : {
249 2 : if (g_test_subprocess()) {
250 1 : g_setenv("G_MESSAGES_DEBUG", "all", TRUE);
251 :
252 1 : spice_debug("spice_debug");
253 1 : spice_info("spice_info");
254 1 : g_debug("g_debug");
255 1 : g_info("g_info");
256 1 : g_message("g_message");
257 1 : other_debug("other_debug");
258 1 : other_info("other_info");
259 1 : other_message("other_message");
260 :
261 1 : return;
262 : }
263 :
264 1 : g_test_trap_subprocess(NULL, 0, 0);
265 1 : g_test_trap_assert_passed();
266 1 : g_test_trap_assert_stdout("*spice_debug\n*spice_info\n*g_debug\n*g_info\n*other_debug\n*other_info\n");
267 1 : g_test_trap_assert_stderr("*g_message\n*other_message\n");
268 : }
269 :
270 : /* Checks that spice_assert() aborts if condition fails */
271 1 : static void test_spice_assert(void)
272 : {
273 1 : if (g_test_subprocess()) {
274 0 : spice_assert(1 == 2);
275 : return;
276 : }
277 1 : g_test_trap_subprocess(NULL, 0, 0);
278 1 : g_test_trap_assert_failed();
279 1 : g_test_trap_assert_stderr("*assertion `1 == 2' failed*");
280 : }
281 :
282 : /* Checks that spice_extra_assert() aborts if condition fails */
283 1 : static void test_spice_extra_assert(void)
284 : {
285 1 : if (g_test_subprocess()) {
286 0 : spice_extra_assert(1 == 2);
287 : return;
288 : }
289 1 : g_test_trap_subprocess(NULL, 0, 0);
290 1 : g_test_trap_assert_failed();
291 1 : g_test_trap_assert_stderr("*assertion `1 == 2' failed*");
292 : }
293 :
294 0 : static void handle_sigabrt(int sig G_GNUC_UNUSED)
295 : {
296 0 : _Exit(1);
297 : }
298 :
299 6 : int main(int argc, char **argv)
300 : {
301 : GLogLevelFlags fatal_mask;
302 :
303 : /* prevents core generations as this could cause some issues/timeout
304 : * depending on system configuration */
305 6 : signal(SIGABRT, handle_sigabrt);
306 :
307 6 : fatal_mask = (GLogLevelFlags)g_log_set_always_fatal((GLogLevelFlags) G_LOG_FATAL_MASK);
308 :
309 6 : g_test_init(&argc, &argv, NULL);
310 :
311 : /* Reset fatal mask set by g_test_init() as we don't want
312 : * warnings/criticals to be fatal by default since this is what some of the
313 : * test cases are going to test */
314 6 : g_log_set_always_fatal(fatal_mask & G_LOG_LEVEL_MASK);
315 :
316 6 : g_test_add_func("/spice-common/spice-g-messages-debug", test_spice_g_messages_debug);
317 6 : g_test_add_func("/spice-common/spice-g-messages-debug-all", test_spice_g_messages_debug_all);
318 6 : g_test_add_func("/spice-common/spice-log-levels", test_log_levels);
319 6 : g_test_add_func("/spice-common/spice-fatal-critical", test_spice_fatal_critical);
320 6 : g_test_add_func("/spice-common/spice-non-fatal-gcritical", test_spice_non_fatal_g_critical);
321 6 : g_test_add_func("/spice-common/spice-fatal-gcritical", test_spice_fatal_g_critical);
322 6 : g_test_add_func("/spice-common/spice-fatal-return-if-fail", test_spice_fatal_return_if_fail);
323 6 : g_test_add_func("/spice-common/spice-non-fatal-greturn-if-fail", test_spice_non_fatal_g_return_if_fail);
324 6 : g_test_add_func("/spice-common/spice-fatal-warning", test_spice_fatal_warning);
325 6 : g_test_add_func("/spice-common/spice-assert", test_spice_assert);
326 : if (spice_extra_checks) {
327 6 : g_test_add_func("/spice-common/spice-extra-assert", test_spice_extra_assert);
328 : }
329 :
330 6 : return g_test_run();
331 : }
|