tests: Use the new DO_TEST_CAPS_*() macros
[libvirt/ericb.git] / tests / virsystemdtest.c
blob82c02decd13a45d927258bebe09cd5a659d9ced2
1 /*
2 * Copyright (C) 2013, 2014 Red Hat, Inc.
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.
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.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <http://www.gnu.org/licenses/>.
19 #include <config.h>
21 #include "testutils.h"
23 #if defined(WITH_DBUS) && defined(__linux__)
25 # include <dbus/dbus.h>
27 # define LIBVIRT_VIRSYSTEMDPRIV_H_ALLOW
28 # include "virsystemdpriv.h"
30 # include "virsystemd.h"
31 # include "virdbus.h"
32 # include "virlog.h"
33 # include "virmock.h"
34 # define VIR_FROM_THIS VIR_FROM_NONE
36 VIR_LOG_INIT("tests.systemdtest");
38 VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block,
39 DBusMessage *,
40 DBusConnection *, connection,
41 DBusMessage *, message,
42 int, timeout_milliseconds,
43 DBusError *, error)
45 DBusMessage *reply = NULL;
46 const char *service = dbus_message_get_destination(message);
47 const char *member = dbus_message_get_member(message);
49 VIR_MOCK_REAL_INIT(dbus_connection_send_with_reply_and_block);
51 if (STREQ(service, "org.freedesktop.machine1")) {
52 if (getenv("FAIL_BAD_SERVICE")) {
53 dbus_set_error_const(error,
54 "org.freedesktop.systemd.badthing",
55 "Something went wrong creating the machine");
56 } else {
57 reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
59 if (STREQ(member, "GetMachineByPID")) {
60 const char *object_path = "/org/freedesktop/machine1/machine/qemu_2ddemo";
61 DBusMessageIter iter;
63 dbus_message_iter_init_append(reply, &iter);
64 if (!dbus_message_iter_append_basic(&iter,
65 DBUS_TYPE_OBJECT_PATH,
66 &object_path))
67 goto error;
68 } else if (STREQ(member, "Get")) {
69 const char *name = "qemu-demo";
70 DBusMessageIter iter;
71 DBusMessageIter sub;
73 dbus_message_iter_init_append(reply, &iter);
74 dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
75 "s", &sub);
77 if (!dbus_message_iter_append_basic(&sub,
78 DBUS_TYPE_STRING,
79 &name))
80 goto error;
81 dbus_message_iter_close_container(&iter, &sub);
84 } else if (STREQ(service, "org.freedesktop.login1")) {
85 char *supported = getenv("RESULT_SUPPORT");
86 DBusMessageIter iter;
87 reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
88 dbus_message_iter_init_append(reply, &iter);
90 if (!dbus_message_iter_append_basic(&iter,
91 DBUS_TYPE_STRING,
92 &supported))
93 goto error;
94 } else if (STREQ(service, "org.freedesktop.DBus") &&
95 STREQ(member, "ListActivatableNames")) {
96 const char *svc1 = "org.foo.bar.wizz";
97 const char *svc2 = "org.freedesktop.machine1";
98 const char *svc3 = "org.freedesktop.login1";
99 DBusMessageIter iter;
100 DBusMessageIter sub;
101 reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
102 dbus_message_iter_init_append(reply, &iter);
103 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
104 "s", &sub);
106 if (!dbus_message_iter_append_basic(&sub,
107 DBUS_TYPE_STRING,
108 &svc1))
109 goto error;
110 if (!getenv("FAIL_NO_SERVICE") &&
111 !dbus_message_iter_append_basic(&sub,
112 DBUS_TYPE_STRING,
113 &svc2))
114 goto error;
115 if (!getenv("FAIL_NO_SERVICE") &&
116 !dbus_message_iter_append_basic(&sub,
117 DBUS_TYPE_STRING,
118 &svc3))
119 goto error;
120 dbus_message_iter_close_container(&iter, &sub);
121 } else if (STREQ(service, "org.freedesktop.DBus") &&
122 STREQ(member, "ListNames")) {
123 const char *svc1 = "org.foo.bar.wizz";
124 const char *svc2 = "org.freedesktop.systemd1";
125 const char *svc3 = "org.freedesktop.login1";
126 DBusMessageIter iter;
127 DBusMessageIter sub;
128 reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
129 dbus_message_iter_init_append(reply, &iter);
130 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
131 "s", &sub);
133 if (!dbus_message_iter_append_basic(&sub,
134 DBUS_TYPE_STRING,
135 &svc1))
136 goto error;
137 if ((!getenv("FAIL_NO_SERVICE") && !getenv("FAIL_NOT_REGISTERED")) &&
138 !dbus_message_iter_append_basic(&sub,
139 DBUS_TYPE_STRING,
140 &svc2))
141 goto error;
142 if ((!getenv("FAIL_NO_SERVICE") && !getenv("FAIL_NOT_REGISTERED")) &&
143 !dbus_message_iter_append_basic(&sub,
144 DBUS_TYPE_STRING,
145 &svc3))
146 goto error;
147 dbus_message_iter_close_container(&iter, &sub);
148 } else {
149 reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN);
152 return reply;
154 error:
155 virDBusMessageUnref(reply);
156 return NULL;
160 static int testCreateContainer(const void *opaque ATTRIBUTE_UNUSED)
162 unsigned char uuid[VIR_UUID_BUFLEN] = {
163 1, 1, 1, 1,
164 2, 2, 2, 2,
165 3, 3, 3, 3,
166 4, 4, 4, 4
168 if (virSystemdCreateMachine("demo",
169 "lxc",
170 uuid,
171 "/proc/123/root",
172 123,
173 true,
174 0, NULL,
175 "highpriority.slice") < 0) {
176 fprintf(stderr, "%s", "Failed to create LXC machine\n");
177 return -1;
180 return 0;
183 static int testTerminateContainer(const void *opaque ATTRIBUTE_UNUSED)
185 if (virSystemdTerminateMachine("lxc-demo") < 0) {
186 fprintf(stderr, "%s", "Failed to terminate LXC machine\n");
187 return -1;
190 return 0;
193 static int testCreateMachine(const void *opaque ATTRIBUTE_UNUSED)
195 unsigned char uuid[VIR_UUID_BUFLEN] = {
196 1, 1, 1, 1,
197 2, 2, 2, 2,
198 3, 3, 3, 3,
199 4, 4, 4, 4
201 if (virSystemdCreateMachine("demo",
202 "qemu",
203 uuid,
204 NULL,
205 123,
206 false,
207 0, NULL,
208 NULL) < 0) {
209 fprintf(stderr, "%s", "Failed to create KVM machine\n");
210 return -1;
213 return 0;
216 static int testTerminateMachine(const void *opaque ATTRIBUTE_UNUSED)
218 if (virSystemdTerminateMachine("test-qemu-demo") < 0) {
219 fprintf(stderr, "%s", "Failed to terminate KVM machine\n");
220 return -1;
223 return 0;
226 static int testCreateNoSystemd(const void *opaque ATTRIBUTE_UNUSED)
228 unsigned char uuid[VIR_UUID_BUFLEN] = {
229 1, 1, 1, 1,
230 2, 2, 2, 2,
231 3, 3, 3, 3,
232 4, 4, 4, 4
234 int rv;
236 setenv("FAIL_NO_SERVICE", "1", 1);
238 if ((rv = virSystemdCreateMachine("demo",
239 "qemu",
240 uuid,
241 NULL,
242 123,
243 false,
244 0, NULL,
245 NULL)) == 0) {
246 unsetenv("FAIL_NO_SERVICE");
247 fprintf(stderr, "%s", "Unexpected create machine success\n");
248 return -1;
250 unsetenv("FAIL_NO_SERVICE");
252 if (rv != -2) {
253 fprintf(stderr, "%s", "Unexpected create machine error\n");
254 return -1;
257 return 0;
260 static int testCreateSystemdNotRunning(const void *opaque ATTRIBUTE_UNUSED)
262 unsigned char uuid[VIR_UUID_BUFLEN] = {
263 1, 1, 1, 1,
264 2, 2, 2, 2,
265 3, 3, 3, 3,
266 4, 4, 4, 4
268 int rv;
270 setenv("FAIL_NOT_REGISTERED", "1", 1);
272 if ((rv = virSystemdCreateMachine("demo",
273 "qemu",
274 uuid,
275 NULL,
276 123,
277 false,
278 0, NULL,
279 NULL)) == 0) {
280 unsetenv("FAIL_NOT_REGISTERED");
281 fprintf(stderr, "%s", "Unexpected create machine success\n");
282 return -1;
284 unsetenv("FAIL_NOT_REGISTERED");
286 if (rv != -2) {
287 fprintf(stderr, "%s", "Unexpected create machine error\n");
288 return -1;
291 return 0;
294 static int testCreateBadSystemd(const void *opaque ATTRIBUTE_UNUSED)
296 unsigned char uuid[VIR_UUID_BUFLEN] = {
297 1, 1, 1, 1,
298 2, 2, 2, 2,
299 3, 3, 3, 3,
300 4, 4, 4, 4
302 int rv;
304 setenv("FAIL_BAD_SERVICE", "1", 1);
306 if ((rv = virSystemdCreateMachine("demo",
307 "qemu",
308 uuid,
309 NULL,
310 123,
311 false,
312 0, NULL,
313 NULL)) == 0) {
314 unsetenv("FAIL_BAD_SERVICE");
315 fprintf(stderr, "%s", "Unexpected create machine success\n");
316 return -1;
318 unsetenv("FAIL_BAD_SERVICE");
320 if (rv != -1) {
321 fprintf(stderr, "%s", "Unexpected create machine error\n");
322 return -1;
325 return 0;
329 static int testCreateNetwork(const void *opaque ATTRIBUTE_UNUSED)
331 unsigned char uuid[VIR_UUID_BUFLEN] = {
332 1, 1, 1, 1,
333 2, 2, 2, 2,
334 3, 3, 3, 3,
335 4, 4, 4, 4
337 int nicindexes[] = {
338 2, 1729, 87539319,
340 size_t nnicindexes = ARRAY_CARDINALITY(nicindexes);
341 if (virSystemdCreateMachine("demo",
342 "lxc",
343 uuid,
344 "/proc/123/root",
345 123,
346 true,
347 nnicindexes, nicindexes,
348 "highpriority.slice") < 0) {
349 fprintf(stderr, "%s", "Failed to create LXC machine\n");
350 return -1;
353 return 0;
357 static int
358 testGetMachineName(const void *opaque ATTRIBUTE_UNUSED)
360 char *tmp = virSystemdGetMachineNameByPID(1234);
361 int ret = -1;
363 if (!tmp) {
364 fprintf(stderr, "%s", "Failed to create LXC machine\n");
365 return ret;
368 if (STREQ(tmp, "qemu-demo"))
369 ret = 0;
371 VIR_FREE(tmp);
372 return ret;
376 struct testNameData {
377 const char *name;
378 const char *expected;
379 int id;
380 bool legacy;
383 static int
384 testScopeName(const void *opaque)
386 const struct testNameData *data = opaque;
387 int ret = -1;
388 char *actual = NULL;
390 if (!(actual = virSystemdMakeScopeName(data->name, "lxc", data->legacy)))
391 goto cleanup;
393 if (STRNEQ(actual, data->expected)) {
394 fprintf(stderr, "Expected '%s' but got '%s'\n",
395 data->expected, actual);
396 goto cleanup;
399 ret = 0;
401 cleanup:
402 VIR_FREE(actual);
403 return ret;
406 static int
407 testMachineName(const void *opaque)
409 const struct testNameData *data = opaque;
410 int ret = -1;
411 char *actual = NULL;
413 if (!(actual = virDomainGenerateMachineName("qemu", data->id,
414 data->name, true)))
415 goto cleanup;
417 if (STRNEQ(actual, data->expected)) {
418 fprintf(stderr, "Expected '%s' but got '%s'\n",
419 data->expected, actual);
420 goto cleanup;
423 ret = 0;
425 cleanup:
426 VIR_FREE(actual);
427 return ret;
430 typedef int (*virSystemdCanHelper)(bool * result);
431 struct testPMSupportData {
432 virSystemdCanHelper tested;
435 static int testPMSupportHelper(const void *opaque)
437 int rv;
438 bool result;
439 size_t i;
440 const char *results[4] = {"yes", "no", "na", "challenge"};
441 int expected[4] = {1, 0, 0, 1};
442 const struct testPMSupportData *data = opaque;
444 for (i = 0; i < 4; i++) {
445 setenv("RESULT_SUPPORT", results[i], 1);
446 if ((rv = data->tested(&result)) < 0) {
447 fprintf(stderr, "%s", "Unexpected canSuspend error\n");
448 return -1;
451 if (result != expected[i]) {
452 fprintf(stderr, "Unexpected result for answer '%s'\n", results[i]);
453 goto error;
455 unsetenv("RESULT_SUPPORT");
458 return 0;
459 error:
460 unsetenv("RESULT_SUPPORT");
461 return -1;
464 static int testPMSupportHelperNoSystemd(const void *opaque)
466 int rv;
467 bool result;
468 const struct testPMSupportData *data = opaque;
470 setenv("FAIL_NO_SERVICE", "1", 1);
472 if ((rv = data->tested(&result)) == 0) {
473 unsetenv("FAIL_NO_SERVICE");
474 fprintf(stderr, "%s", "Unexpected canSuspend success\n");
475 return -1;
477 unsetenv("FAIL_NO_SERVICE");
479 if (rv != -2) {
480 fprintf(stderr, "%s", "Unexpected canSuspend error\n");
481 return -1;
484 return 0;
487 static int testPMSupportSystemdNotRunning(const void *opaque)
489 int rv;
490 bool result;
491 const struct testPMSupportData *data = opaque;
493 setenv("FAIL_NOT_REGISTERED", "1", 1);
495 if ((rv = data->tested(&result)) == 0) {
496 unsetenv("FAIL_NOT_REGISTERED");
497 fprintf(stderr, "%s", "Unexpected canSuspend success\n");
498 return -1;
500 unsetenv("FAIL_NOT_REGISTERED");
502 if (rv != -2) {
503 fprintf(stderr, "%s", "Unexpected canSuspend error\n");
504 return -1;
507 return 0;
510 static int
511 mymain(void)
513 int ret = 0;
515 unsigned char uuid[VIR_UUID_BUFLEN];
517 /* The one we use in tests quite often */
518 if (virUUIDParse("c7a5fdbd-edaf-9455-926a-d65c16db1809", uuid) < 0)
519 return EXIT_FAILURE;
521 # define DO_TEST(_name, func) \
522 do { \
523 if (virTestRun(_name, func, NULL) < 0) \
524 ret = -1; \
525 if (virTestRun(_name "again ", func, NULL) < 0) \
526 ret = -1; \
527 virSystemdHasMachinedResetCachedValue(); \
528 } while (0)
530 DO_TEST("Test create container ", testCreateContainer);
531 DO_TEST("Test terminate container ", testTerminateContainer);
532 DO_TEST("Test create machine ", testCreateMachine);
533 DO_TEST("Test terminate machine ", testTerminateMachine);
534 DO_TEST("Test create no systemd ", testCreateNoSystemd);
535 DO_TEST("Test create systemd not running ", testCreateSystemdNotRunning);
536 DO_TEST("Test create bad systemd ", testCreateBadSystemd);
537 DO_TEST("Test create with network ", testCreateNetwork);
538 DO_TEST("Test getting machine name ", testGetMachineName);
540 # define TEST_SCOPE(_name, unitname, _legacy) \
541 do { \
542 struct testNameData data = { \
543 .name = _name, .expected = unitname, .legacy = _legacy, \
544 }; \
545 if (virTestRun("Test scopename", testScopeName, &data) < 0) \
546 ret = -1; \
547 } while (0)
549 # define TEST_SCOPE_OLD(name, unitname) \
550 TEST_SCOPE(name, unitname, true)
551 # define TEST_SCOPE_NEW(name, unitname) \
552 TEST_SCOPE(name, unitname, false)
554 TEST_SCOPE_OLD("demo", "machine-lxc\\x2ddemo.scope");
555 TEST_SCOPE_OLD("demo-name", "machine-lxc\\x2ddemo\\x2dname.scope");
556 TEST_SCOPE_OLD("demo!name", "machine-lxc\\x2ddemo\\x21name.scope");
557 TEST_SCOPE_OLD(".demo", "machine-lxc\\x2d\\x2edemo.scope");
558 TEST_SCOPE_OLD("bull💩", "machine-lxc\\x2dbull\\xf0\\x9f\\x92\\xa9.scope");
560 TEST_SCOPE_NEW("qemu-3-demo", "machine-qemu\\x2d3\\x2ddemo.scope");
562 # define TEST_MACHINE(_name, _id, machinename) \
563 do { \
564 struct testNameData data = { \
565 .name = _name, .expected = machinename, .id = _id, \
566 }; \
567 if (virTestRun("Test scopename", testMachineName, &data) < 0) \
568 ret = -1; \
569 } while (0)
571 TEST_MACHINE("demo", 1, "qemu-1-demo");
572 TEST_MACHINE("demo-name", 2, "qemu-2-demo-name");
573 TEST_MACHINE("demo!name", 3, "qemu-3-demoname");
574 TEST_MACHINE(".demo", 4, "qemu-4-.demo");
575 TEST_MACHINE("bull\U0001f4a9", 5, "qemu-5-bull");
576 TEST_MACHINE("demo..name", 6, "qemu-6-demo.name");
577 TEST_MACHINE("12345678901234567890123456789012345678901234567890123456789", 7,
578 "qemu-7-123456789012345678901234567890123456789012345678901234567");
579 TEST_MACHINE("123456789012345678901234567890123456789012345678901234567890", 8,
580 "qemu-8-123456789012345678901234567890123456789012345678901234567");
582 # define TESTS_PM_SUPPORT_HELPER(name, function) \
583 do { \
584 struct testPMSupportData data = { \
585 function \
586 }; \
587 if (virTestRun("Test " name " ", testPMSupportHelper, &data) < 0) \
588 ret = -1; \
589 if (virTestRun("Test " name " no systemd ", \
590 testPMSupportHelperNoSystemd, &data) < 0) \
591 ret = -1; \
592 if (virTestRun("Test systemd " name " not running ", \
593 testPMSupportSystemdNotRunning, &data) < 0) \
594 ret = -1; \
595 } while (0)
597 TESTS_PM_SUPPORT_HELPER("canSuspend", &virSystemdCanSuspend);
598 TESTS_PM_SUPPORT_HELPER("canHibernate", &virSystemdCanHibernate);
599 TESTS_PM_SUPPORT_HELPER("canHybridSleep", &virSystemdCanHybridSleep);
601 return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
604 VIR_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virdbusmock.so")
606 #else /* ! (WITH_DBUS && __linux__) */
608 main(void)
610 return EXIT_AM_SKIP;
612 #endif /* ! WITH_DBUS */