xref: /qemu/tests/unit/test-qga.c (revision a85d09269bb1a7071d3ce0f2957e3ca9dba7c047)
1681c28a3SPeter Maydell #include "qemu/osdep.h"
262c39b30SMarc-André Lureau #include <locale.h>
362c39b30SMarc-André Lureau #include <glib/gstdio.h>
462c39b30SMarc-André Lureau #include <sys/socket.h>
562c39b30SMarc-André Lureau #include <sys/un.h>
662c39b30SMarc-André Lureau 
7907b5105SMarc-André Lureau #include "../qtest/libqtest.h"
8452fcdbcSMarkus Armbruster #include "qapi/qmp/qdict.h"
947e6b297SMarkus Armbruster #include "qapi/qmp/qlist.h"
1062c39b30SMarc-André Lureau 
1162c39b30SMarc-André Lureau typedef struct {
1262c39b30SMarc-André Lureau     char *test_dir;
1362c39b30SMarc-André Lureau     GMainLoop *loop;
1462c39b30SMarc-André Lureau     int fd;
1562c39b30SMarc-André Lureau     GPid pid;
1662c39b30SMarc-André Lureau } TestFixture;
1762c39b30SMarc-André Lureau 
1862c39b30SMarc-André Lureau static int connect_qga(char *path)
1962c39b30SMarc-André Lureau {
2062c39b30SMarc-André Lureau     int s, ret, len, i = 0;
2162c39b30SMarc-André Lureau     struct sockaddr_un remote;
2262c39b30SMarc-André Lureau 
2362c39b30SMarc-André Lureau     s = socket(AF_UNIX, SOCK_STREAM, 0);
2462c39b30SMarc-André Lureau     g_assert(s != -1);
2562c39b30SMarc-André Lureau 
2662c39b30SMarc-André Lureau     remote.sun_family = AF_UNIX;
2762c39b30SMarc-André Lureau     do {
2862c39b30SMarc-André Lureau         strcpy(remote.sun_path, path);
2962c39b30SMarc-André Lureau         len = strlen(remote.sun_path) + sizeof(remote.sun_family);
3062c39b30SMarc-André Lureau         ret = connect(s, (struct sockaddr *)&remote, len);
3162c39b30SMarc-André Lureau         if (ret == -1) {
3262c39b30SMarc-André Lureau             g_usleep(G_USEC_PER_SEC);
3362c39b30SMarc-André Lureau         }
3462c39b30SMarc-André Lureau         if (i++ == 10) {
3562c39b30SMarc-André Lureau             return -1;
3662c39b30SMarc-André Lureau         }
3762c39b30SMarc-André Lureau     } while (ret == -1);
3862c39b30SMarc-André Lureau 
3962c39b30SMarc-André Lureau     return s;
4062c39b30SMarc-André Lureau }
4162c39b30SMarc-André Lureau 
4262c39b30SMarc-André Lureau static void qga_watch(GPid pid, gint status, gpointer user_data)
4362c39b30SMarc-André Lureau {
4462c39b30SMarc-André Lureau     TestFixture *fixture = user_data;
4562c39b30SMarc-André Lureau 
4662c39b30SMarc-André Lureau     g_assert_cmpint(status, ==, 0);
4762c39b30SMarc-André Lureau     g_main_loop_quit(fixture->loop);
4862c39b30SMarc-André Lureau }
4962c39b30SMarc-André Lureau 
5062c39b30SMarc-André Lureau static void
51c28afa76STomáš Golembiovský fixture_setup(TestFixture *fixture, gconstpointer data, gchar **envp)
5262c39b30SMarc-André Lureau {
5362c39b30SMarc-André Lureau     const gchar *extra_arg = data;
5462c39b30SMarc-André Lureau     GError *error = NULL;
5562c39b30SMarc-André Lureau     gchar *cwd, *path, *cmd, **argv = NULL;
5662c39b30SMarc-André Lureau 
5762c39b30SMarc-André Lureau     fixture->loop = g_main_loop_new(NULL, FALSE);
5862c39b30SMarc-André Lureau 
5962c39b30SMarc-André Lureau     fixture->test_dir = g_strdup("/tmp/qgatest.XXXXXX");
6062c39b30SMarc-André Lureau     g_assert_nonnull(mkdtemp(fixture->test_dir));
6162c39b30SMarc-André Lureau 
6262c39b30SMarc-André Lureau     path = g_build_filename(fixture->test_dir, "sock", NULL);
6362c39b30SMarc-André Lureau     cwd = g_get_current_dir();
64f15bff25SPaolo Bonzini     cmd = g_strdup_printf("%s%cqga%cqemu-ga -m unix-listen -t %s -p %s %s %s",
65f15bff25SPaolo Bonzini                           cwd, G_DIR_SEPARATOR, G_DIR_SEPARATOR,
6662c39b30SMarc-André Lureau                           fixture->test_dir, path,
6762c39b30SMarc-André Lureau                           getenv("QTEST_LOG") ? "-v" : "",
6862c39b30SMarc-André Lureau                           extra_arg ?: "");
6962c39b30SMarc-André Lureau     g_shell_parse_argv(cmd, NULL, &argv, &error);
7062c39b30SMarc-André Lureau     g_assert_no_error(error);
7162c39b30SMarc-André Lureau 
72c28afa76STomáš Golembiovský     g_spawn_async(fixture->test_dir, argv, envp,
7362c39b30SMarc-André Lureau                   G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD,
7462c39b30SMarc-André Lureau                   NULL, NULL, &fixture->pid, &error);
7562c39b30SMarc-André Lureau     g_assert_no_error(error);
7662c39b30SMarc-André Lureau 
7762c39b30SMarc-André Lureau     g_child_watch_add(fixture->pid, qga_watch, fixture);
7862c39b30SMarc-André Lureau 
7962c39b30SMarc-André Lureau     fixture->fd = connect_qga(path);
8062c39b30SMarc-André Lureau     g_assert_cmpint(fixture->fd, !=, -1);
8162c39b30SMarc-André Lureau 
8262c39b30SMarc-André Lureau     g_strfreev(argv);
8362c39b30SMarc-André Lureau     g_free(cmd);
8462c39b30SMarc-André Lureau     g_free(cwd);
8562c39b30SMarc-André Lureau     g_free(path);
8662c39b30SMarc-André Lureau }
8762c39b30SMarc-André Lureau 
8862c39b30SMarc-André Lureau static void
8962c39b30SMarc-André Lureau fixture_tear_down(TestFixture *fixture, gconstpointer data)
9062c39b30SMarc-André Lureau {
9162c39b30SMarc-André Lureau     gchar *tmp;
9262c39b30SMarc-André Lureau 
9362c39b30SMarc-André Lureau     kill(fixture->pid, SIGTERM);
9462c39b30SMarc-André Lureau 
9562c39b30SMarc-André Lureau     g_main_loop_run(fixture->loop);
9662c39b30SMarc-André Lureau     g_main_loop_unref(fixture->loop);
9762c39b30SMarc-André Lureau 
9862c39b30SMarc-André Lureau     g_spawn_close_pid(fixture->pid);
9962c39b30SMarc-André Lureau 
10062c39b30SMarc-André Lureau     tmp = g_build_filename(fixture->test_dir, "foo", NULL);
10162c39b30SMarc-André Lureau     g_unlink(tmp);
10262c39b30SMarc-André Lureau     g_free(tmp);
10362c39b30SMarc-André Lureau 
10462c39b30SMarc-André Lureau     tmp = g_build_filename(fixture->test_dir, "qga.state", NULL);
10562c39b30SMarc-André Lureau     g_unlink(tmp);
10662c39b30SMarc-André Lureau     g_free(tmp);
10762c39b30SMarc-André Lureau 
10862c39b30SMarc-André Lureau     tmp = g_build_filename(fixture->test_dir, "sock", NULL);
10962c39b30SMarc-André Lureau     g_unlink(tmp);
11062c39b30SMarc-André Lureau     g_free(tmp);
11162c39b30SMarc-André Lureau 
11262c39b30SMarc-André Lureau     g_rmdir(fixture->test_dir);
11362c39b30SMarc-André Lureau     g_free(fixture->test_dir);
11443d1da7cSAlex Chen     close(fixture->fd);
11562c39b30SMarc-André Lureau }
11662c39b30SMarc-André Lureau 
11762c39b30SMarc-André Lureau static void qmp_assertion_message_error(const char     *domain,
11862c39b30SMarc-André Lureau                                         const char     *file,
11962c39b30SMarc-André Lureau                                         int             line,
12062c39b30SMarc-André Lureau                                         const char     *func,
12162c39b30SMarc-André Lureau                                         const char     *expr,
12262c39b30SMarc-André Lureau                                         QDict          *dict)
12362c39b30SMarc-André Lureau {
12462c39b30SMarc-André Lureau     const char *class, *desc;
12562c39b30SMarc-André Lureau     char *s;
12662c39b30SMarc-André Lureau     QDict *error;
12762c39b30SMarc-André Lureau 
12862c39b30SMarc-André Lureau     error = qdict_get_qdict(dict, "error");
12962c39b30SMarc-André Lureau     class = qdict_get_try_str(error, "class");
13062c39b30SMarc-André Lureau     desc = qdict_get_try_str(error, "desc");
13162c39b30SMarc-André Lureau 
13262c39b30SMarc-André Lureau     s = g_strdup_printf("assertion failed %s: %s %s", expr, class, desc);
13362c39b30SMarc-André Lureau     g_assertion_message(domain, file, line, func, s);
13462c39b30SMarc-André Lureau     g_free(s);
13562c39b30SMarc-André Lureau }
13662c39b30SMarc-André Lureau 
13762c39b30SMarc-André Lureau #define qmp_assert_no_error(err) do {                                   \
13862c39b30SMarc-André Lureau     if (qdict_haskey(err, "error")) {                                   \
13962c39b30SMarc-André Lureau         qmp_assertion_message_error(G_LOG_DOMAIN, __FILE__, __LINE__,   \
14062c39b30SMarc-André Lureau                                     G_STRFUNC, #err, err);              \
14162c39b30SMarc-André Lureau     }                                                                   \
14262c39b30SMarc-André Lureau } while (0)
14362c39b30SMarc-André Lureau 
14462c39b30SMarc-André Lureau static void test_qga_sync_delimited(gconstpointer fix)
14562c39b30SMarc-André Lureau {
14662c39b30SMarc-André Lureau     const TestFixture *fixture = fix;
1470f555602SPaolo Bonzini     guint32 v, r = g_test_rand_int();
14862c39b30SMarc-André Lureau     unsigned char c;
14962c39b30SMarc-André Lureau     QDict *ret;
15062c39b30SMarc-André Lureau 
151e2f64a68SMarkus Armbruster     qmp_fd_send_raw(fixture->fd, "\xff");
152015715f5SMarkus Armbruster     qmp_fd_send(fixture->fd,
153e2f64a68SMarkus Armbruster                 "{'execute': 'guest-sync-delimited',"
154015715f5SMarkus Armbruster                 " 'arguments': {'id': %u } }",
155015715f5SMarkus Armbruster                 r);
15662c39b30SMarc-André Lureau 
1575229564bSEric Blake     /*
1585229564bSEric Blake      * Read and ignore garbage until resynchronized.
1595229564bSEric Blake      *
1605229564bSEric Blake      * Note that the full reset sequence would involve checking the
1615229564bSEric Blake      * response of guest-sync-delimited and repeating the loop if
1625229564bSEric Blake      * 'id' field of the response does not match the 'id' field of
1635229564bSEric Blake      * the request. Testing this fully would require inserting
1645229564bSEric Blake      * garbage in the response stream and is left as a future test
1655229564bSEric Blake      * to implement.
1665229564bSEric Blake      *
1675229564bSEric Blake      * TODO: The server shouldn't emit so much garbage (among other
1685229564bSEric Blake      * things, it loudly complains about the client's \xff being
1695229564bSEric Blake      * invalid JSON, even though it is a documented part of the
1705229564bSEric Blake      * handshake.
1715229564bSEric Blake      */
1725229564bSEric Blake     do {
17362c39b30SMarc-André Lureau         v = read(fixture->fd, &c, 1);
17462c39b30SMarc-André Lureau         g_assert_cmpint(v, ==, 1);
1755229564bSEric Blake     } while (c != 0xff);
17662c39b30SMarc-André Lureau 
17762c39b30SMarc-André Lureau     ret = qmp_fd_receive(fixture->fd);
17862c39b30SMarc-André Lureau     g_assert_nonnull(ret);
17962c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
18062c39b30SMarc-André Lureau 
18162c39b30SMarc-André Lureau     v = qdict_get_int(ret, "return");
18262c39b30SMarc-André Lureau     g_assert_cmpint(r, ==, v);
18362c39b30SMarc-André Lureau 
184cb3e7f08SMarc-André Lureau     qobject_unref(ret);
18562c39b30SMarc-André Lureau }
18662c39b30SMarc-André Lureau 
18762c39b30SMarc-André Lureau static void test_qga_sync(gconstpointer fix)
18862c39b30SMarc-André Lureau {
18962c39b30SMarc-André Lureau     const TestFixture *fixture = fix;
1900f555602SPaolo Bonzini     guint32 v, r = g_test_rand_int();
19162c39b30SMarc-André Lureau     QDict *ret;
19262c39b30SMarc-André Lureau 
1935229564bSEric Blake     /*
1945229564bSEric Blake      * TODO guest-sync is inherently limited: we cannot distinguish
1955229564bSEric Blake      * failure caused by reacting to garbage on the wire prior to this
1965229564bSEric Blake      * command, from failure of this actual command. Clients are
1975229564bSEric Blake      * supposed to be able to send a raw '\xff' byte to at least
1985229564bSEric Blake      * re-synchronize the server's parser prior to this command, but
1995229564bSEric Blake      * we are not in a position to test that here because (at least
2005229564bSEric Blake      * for now) it causes the server to issue an error message about
2015229564bSEric Blake      * invalid JSON. Testing of '\xff' handling is done in
2025229564bSEric Blake      * guest-sync-delimited instead.
2035229564bSEric Blake      */
204015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
205015715f5SMarkus Armbruster                  "{'execute': 'guest-sync', 'arguments': {'id': %u } }",
206015715f5SMarkus Armbruster                  r);
20762c39b30SMarc-André Lureau 
20862c39b30SMarc-André Lureau     g_assert_nonnull(ret);
20962c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
21062c39b30SMarc-André Lureau 
21162c39b30SMarc-André Lureau     v = qdict_get_int(ret, "return");
21262c39b30SMarc-André Lureau     g_assert_cmpint(r, ==, v);
21362c39b30SMarc-André Lureau 
214cb3e7f08SMarc-André Lureau     qobject_unref(ret);
21562c39b30SMarc-André Lureau }
21662c39b30SMarc-André Lureau 
21762c39b30SMarc-André Lureau static void test_qga_ping(gconstpointer fix)
21862c39b30SMarc-André Lureau {
21962c39b30SMarc-André Lureau     const TestFixture *fixture = fix;
22062c39b30SMarc-André Lureau     QDict *ret;
22162c39b30SMarc-André Lureau 
22262c39b30SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-ping'}");
22362c39b30SMarc-André Lureau     g_assert_nonnull(ret);
22462c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
22562c39b30SMarc-André Lureau 
226cb3e7f08SMarc-André Lureau     qobject_unref(ret);
22762c39b30SMarc-André Lureau }
22862c39b30SMarc-André Lureau 
2294eaca8deSMarc-André Lureau static void test_qga_id(gconstpointer fix)
230b5f84310SMarkus Armbruster {
231b5f84310SMarkus Armbruster     const TestFixture *fixture = fix;
2324eaca8deSMarc-André Lureau     QDict *ret;
233b5f84310SMarkus Armbruster 
234b5f84310SMarkus Armbruster     ret = qmp_fd(fixture->fd, "{'execute': 'guest-ping', 'id': 1}");
235b5f84310SMarkus Armbruster     g_assert_nonnull(ret);
2364eaca8deSMarc-André Lureau     qmp_assert_no_error(ret);
2374eaca8deSMarc-André Lureau     g_assert_cmpint(qdict_get_int(ret, "id"), ==, 1);
238b5f84310SMarkus Armbruster 
239b5f84310SMarkus Armbruster     qobject_unref(ret);
240b5f84310SMarkus Armbruster }
241b5f84310SMarkus Armbruster 
242d4d7ed73SMarkus Armbruster static void test_qga_invalid_oob(gconstpointer fix)
243d4d7ed73SMarkus Armbruster {
244d4d7ed73SMarkus Armbruster     const TestFixture *fixture = fix;
245ebb4d82dSMarc-André Lureau     QDict *ret;
246d4d7ed73SMarkus Armbruster 
24700ecec15SMarkus Armbruster     ret = qmp_fd(fixture->fd, "{'exec-oob': 'guest-ping'}");
248d4d7ed73SMarkus Armbruster     g_assert_nonnull(ret);
249d4d7ed73SMarkus Armbruster 
2503bc1b8eeSMarkus Armbruster     qmp_expect_error_and_unref(ret, "GenericError");
251d4d7ed73SMarkus Armbruster }
252d4d7ed73SMarkus Armbruster 
2534bdadd86SMarc-André Lureau static void test_qga_invalid_args(gconstpointer fix)
2544bdadd86SMarc-André Lureau {
2554bdadd86SMarc-André Lureau     const TestFixture *fixture = fix;
2564bdadd86SMarc-André Lureau     QDict *ret, *error;
2574bdadd86SMarc-André Lureau     const gchar *class, *desc;
2584bdadd86SMarc-André Lureau 
2594bdadd86SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-ping', "
2604bdadd86SMarc-André Lureau                  "'arguments': {'foo': 42 }}");
2614bdadd86SMarc-André Lureau     g_assert_nonnull(ret);
2624bdadd86SMarc-André Lureau 
2634bdadd86SMarc-André Lureau     error = qdict_get_qdict(ret, "error");
2644bdadd86SMarc-André Lureau     class = qdict_get_try_str(error, "class");
2654bdadd86SMarc-André Lureau     desc = qdict_get_try_str(error, "desc");
2664bdadd86SMarc-André Lureau 
2674bdadd86SMarc-André Lureau     g_assert_cmpstr(class, ==, "GenericError");
268910f738bSMarkus Armbruster     g_assert_cmpstr(desc, ==, "Parameter 'foo' is unexpected");
2694bdadd86SMarc-André Lureau 
270cb3e7f08SMarc-André Lureau     qobject_unref(ret);
2714bdadd86SMarc-André Lureau }
2724bdadd86SMarc-André Lureau 
27362c39b30SMarc-André Lureau static void test_qga_invalid_cmd(gconstpointer fix)
27462c39b30SMarc-André Lureau {
27562c39b30SMarc-André Lureau     const TestFixture *fixture = fix;
27662c39b30SMarc-André Lureau     QDict *ret, *error;
27762c39b30SMarc-André Lureau     const gchar *class, *desc;
27862c39b30SMarc-André Lureau 
27962c39b30SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-invalid-cmd'}");
28062c39b30SMarc-André Lureau     g_assert_nonnull(ret);
28162c39b30SMarc-André Lureau 
28262c39b30SMarc-André Lureau     error = qdict_get_qdict(ret, "error");
28362c39b30SMarc-André Lureau     class = qdict_get_try_str(error, "class");
28462c39b30SMarc-André Lureau     desc = qdict_get_try_str(error, "desc");
28562c39b30SMarc-André Lureau 
28662c39b30SMarc-André Lureau     g_assert_cmpstr(class, ==, "CommandNotFound");
28762c39b30SMarc-André Lureau     g_assert_cmpint(strlen(desc), >, 0);
28862c39b30SMarc-André Lureau 
289cb3e7f08SMarc-André Lureau     qobject_unref(ret);
29062c39b30SMarc-André Lureau }
29162c39b30SMarc-André Lureau 
29262c39b30SMarc-André Lureau static void test_qga_info(gconstpointer fix)
29362c39b30SMarc-André Lureau {
29462c39b30SMarc-André Lureau     const TestFixture *fixture = fix;
29562c39b30SMarc-André Lureau     QDict *ret, *val;
29662c39b30SMarc-André Lureau     const gchar *version;
29762c39b30SMarc-André Lureau 
29862c39b30SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-info'}");
29962c39b30SMarc-André Lureau     g_assert_nonnull(ret);
30062c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
30162c39b30SMarc-André Lureau 
30262c39b30SMarc-André Lureau     val = qdict_get_qdict(ret, "return");
30362c39b30SMarc-André Lureau     version = qdict_get_try_str(val, "version");
30462c39b30SMarc-André Lureau     g_assert_cmpstr(version, ==, QEMU_VERSION);
30562c39b30SMarc-André Lureau 
306cb3e7f08SMarc-André Lureau     qobject_unref(ret);
30762c39b30SMarc-André Lureau }
30862c39b30SMarc-André Lureau 
30962c39b30SMarc-André Lureau static void test_qga_get_vcpus(gconstpointer fix)
31062c39b30SMarc-André Lureau {
31162c39b30SMarc-André Lureau     const TestFixture *fixture = fix;
31262c39b30SMarc-André Lureau     QDict *ret;
31362c39b30SMarc-André Lureau     QList *list;
31462c39b30SMarc-André Lureau     const QListEntry *entry;
31562c39b30SMarc-André Lureau 
31662c39b30SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-vcpus'}");
31762c39b30SMarc-André Lureau     g_assert_nonnull(ret);
31862c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
31962c39b30SMarc-André Lureau 
32062c39b30SMarc-André Lureau     /* check there is at least a cpu */
32162c39b30SMarc-André Lureau     list = qdict_get_qlist(ret, "return");
32262c39b30SMarc-André Lureau     entry = qlist_first(list);
3237dc847ebSMax Reitz     g_assert(qdict_haskey(qobject_to(QDict, entry->value), "online"));
3247dc847ebSMax Reitz     g_assert(qdict_haskey(qobject_to(QDict, entry->value), "logical-id"));
32562c39b30SMarc-André Lureau 
326cb3e7f08SMarc-André Lureau     qobject_unref(ret);
32762c39b30SMarc-André Lureau }
32862c39b30SMarc-André Lureau 
32962c39b30SMarc-André Lureau static void test_qga_get_fsinfo(gconstpointer fix)
33062c39b30SMarc-André Lureau {
33162c39b30SMarc-André Lureau     const TestFixture *fixture = fix;
33262c39b30SMarc-André Lureau     QDict *ret;
33362c39b30SMarc-André Lureau     QList *list;
33462c39b30SMarc-André Lureau     const QListEntry *entry;
33562c39b30SMarc-André Lureau 
33662c39b30SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-fsinfo'}");
33762c39b30SMarc-André Lureau     g_assert_nonnull(ret);
33862c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
33962c39b30SMarc-André Lureau 
340b3e9e584SMichael Roth     /* sanity-check the response if there are any filesystems */
34162c39b30SMarc-André Lureau     list = qdict_get_qlist(ret, "return");
34262c39b30SMarc-André Lureau     entry = qlist_first(list);
343b3e9e584SMichael Roth     if (entry) {
3447dc847ebSMax Reitz         g_assert(qdict_haskey(qobject_to(QDict, entry->value), "name"));
3457dc847ebSMax Reitz         g_assert(qdict_haskey(qobject_to(QDict, entry->value), "mountpoint"));
3467dc847ebSMax Reitz         g_assert(qdict_haskey(qobject_to(QDict, entry->value), "type"));
3477dc847ebSMax Reitz         g_assert(qdict_haskey(qobject_to(QDict, entry->value), "disk"));
348b3e9e584SMichael Roth     }
34962c39b30SMarc-André Lureau 
350cb3e7f08SMarc-André Lureau     qobject_unref(ret);
35162c39b30SMarc-André Lureau }
35262c39b30SMarc-André Lureau 
35362c39b30SMarc-André Lureau static void test_qga_get_memory_block_info(gconstpointer fix)
35462c39b30SMarc-André Lureau {
35562c39b30SMarc-André Lureau     const TestFixture *fixture = fix;
35662c39b30SMarc-André Lureau     QDict *ret, *val;
35762c39b30SMarc-André Lureau     int64_t size;
35862c39b30SMarc-André Lureau 
35962c39b30SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-memory-block-info'}");
36062c39b30SMarc-André Lureau     g_assert_nonnull(ret);
36162c39b30SMarc-André Lureau 
36262c39b30SMarc-André Lureau     /* some systems might not expose memory block info in sysfs */
36362c39b30SMarc-André Lureau     if (!qdict_haskey(ret, "error")) {
36462c39b30SMarc-André Lureau         /* check there is at least some memory */
36562c39b30SMarc-André Lureau         val = qdict_get_qdict(ret, "return");
36662c39b30SMarc-André Lureau         size = qdict_get_int(val, "size");
36762c39b30SMarc-André Lureau         g_assert_cmpint(size, >, 0);
36862c39b30SMarc-André Lureau     }
36962c39b30SMarc-André Lureau 
370cb3e7f08SMarc-André Lureau     qobject_unref(ret);
37162c39b30SMarc-André Lureau }
37262c39b30SMarc-André Lureau 
37362c39b30SMarc-André Lureau static void test_qga_get_memory_blocks(gconstpointer fix)
37462c39b30SMarc-André Lureau {
37562c39b30SMarc-André Lureau     const TestFixture *fixture = fix;
37662c39b30SMarc-André Lureau     QDict *ret;
37762c39b30SMarc-André Lureau     QList *list;
37862c39b30SMarc-André Lureau     const QListEntry *entry;
37962c39b30SMarc-André Lureau 
38062c39b30SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-memory-blocks'}");
38162c39b30SMarc-André Lureau     g_assert_nonnull(ret);
38262c39b30SMarc-André Lureau 
38362c39b30SMarc-André Lureau     /* some systems might not expose memory block info in sysfs */
38462c39b30SMarc-André Lureau     if (!qdict_haskey(ret, "error")) {
38562c39b30SMarc-André Lureau         list = qdict_get_qlist(ret, "return");
38662c39b30SMarc-André Lureau         entry = qlist_first(list);
38762c39b30SMarc-André Lureau         /* newer versions of qga may return empty list without error */
38862c39b30SMarc-André Lureau         if (entry) {
3897dc847ebSMax Reitz             g_assert(qdict_haskey(qobject_to(QDict, entry->value),
3907dc847ebSMax Reitz                                   "phys-index"));
3917dc847ebSMax Reitz             g_assert(qdict_haskey(qobject_to(QDict, entry->value), "online"));
39262c39b30SMarc-André Lureau         }
39362c39b30SMarc-André Lureau     }
39462c39b30SMarc-André Lureau 
395cb3e7f08SMarc-André Lureau     qobject_unref(ret);
39662c39b30SMarc-André Lureau }
39762c39b30SMarc-André Lureau 
39862c39b30SMarc-André Lureau static void test_qga_network_get_interfaces(gconstpointer fix)
39962c39b30SMarc-André Lureau {
40062c39b30SMarc-André Lureau     const TestFixture *fixture = fix;
40162c39b30SMarc-André Lureau     QDict *ret;
40262c39b30SMarc-André Lureau     QList *list;
40362c39b30SMarc-André Lureau     const QListEntry *entry;
40462c39b30SMarc-André Lureau 
40562c39b30SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-network-get-interfaces'}");
40662c39b30SMarc-André Lureau     g_assert_nonnull(ret);
40762c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
40862c39b30SMarc-André Lureau 
40962c39b30SMarc-André Lureau     /* check there is at least an interface */
41062c39b30SMarc-André Lureau     list = qdict_get_qlist(ret, "return");
41162c39b30SMarc-André Lureau     entry = qlist_first(list);
4127dc847ebSMax Reitz     g_assert(qdict_haskey(qobject_to(QDict, entry->value), "name"));
41362c39b30SMarc-André Lureau 
414cb3e7f08SMarc-André Lureau     qobject_unref(ret);
41562c39b30SMarc-André Lureau }
41662c39b30SMarc-André Lureau 
41762c39b30SMarc-André Lureau static void test_qga_file_ops(gconstpointer fix)
41862c39b30SMarc-André Lureau {
41962c39b30SMarc-André Lureau     const TestFixture *fixture = fix;
4204eaab85cSMarc-André Lureau     const unsigned char helloworld[] = "Hello World!\n";
42162c39b30SMarc-André Lureau     const char *b64;
422015715f5SMarkus Armbruster     gchar *path, *enc;
4234eaab85cSMarc-André Lureau     unsigned char *dec;
42462c39b30SMarc-André Lureau     QDict *ret, *val;
42562c39b30SMarc-André Lureau     int64_t id, eof;
42662c39b30SMarc-André Lureau     gsize count;
42762c39b30SMarc-André Lureau     FILE *f;
42862c39b30SMarc-André Lureau     char tmp[100];
42962c39b30SMarc-André Lureau 
43062c39b30SMarc-André Lureau     /* open */
43162c39b30SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-file-open',"
43262c39b30SMarc-André Lureau                  " 'arguments': { 'path': 'foo', 'mode': 'w+' } }");
43362c39b30SMarc-André Lureau     g_assert_nonnull(ret);
43462c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
43562c39b30SMarc-André Lureau     id = qdict_get_int(ret, "return");
436cb3e7f08SMarc-André Lureau     qobject_unref(ret);
43762c39b30SMarc-André Lureau 
43862c39b30SMarc-André Lureau     enc = g_base64_encode(helloworld, sizeof(helloworld));
43962c39b30SMarc-André Lureau     /* write */
440015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
441015715f5SMarkus Armbruster                  "{'execute': 'guest-file-write',"
442015715f5SMarkus Armbruster                  " 'arguments': { 'handle': %" PRId64 ", 'buf-b64': %s } }",
443015715f5SMarkus Armbruster                  id, enc);
44462c39b30SMarc-André Lureau     g_assert_nonnull(ret);
44562c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
44662c39b30SMarc-André Lureau 
44762c39b30SMarc-André Lureau     val = qdict_get_qdict(ret, "return");
44862c39b30SMarc-André Lureau     count = qdict_get_int(val, "count");
44962c39b30SMarc-André Lureau     eof = qdict_get_bool(val, "eof");
45062c39b30SMarc-André Lureau     g_assert_cmpint(count, ==, sizeof(helloworld));
45162c39b30SMarc-André Lureau     g_assert_cmpint(eof, ==, 0);
452cb3e7f08SMarc-André Lureau     qobject_unref(ret);
45362c39b30SMarc-André Lureau 
45462c39b30SMarc-André Lureau     /* flush */
455015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
456015715f5SMarkus Armbruster                  "{'execute': 'guest-file-flush',"
45762c39b30SMarc-André Lureau                  " 'arguments': {'handle': %" PRId64 "} }",
45862c39b30SMarc-André Lureau                  id);
459cb3e7f08SMarc-André Lureau     qobject_unref(ret);
46062c39b30SMarc-André Lureau 
46162c39b30SMarc-André Lureau     /* close */
462015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
463015715f5SMarkus Armbruster                  "{'execute': 'guest-file-close',"
46462c39b30SMarc-André Lureau                  " 'arguments': {'handle': %" PRId64 "} }",
46562c39b30SMarc-André Lureau                  id);
466cb3e7f08SMarc-André Lureau     qobject_unref(ret);
46762c39b30SMarc-André Lureau 
46862c39b30SMarc-André Lureau     /* check content */
46962c39b30SMarc-André Lureau     path = g_build_filename(fixture->test_dir, "foo", NULL);
47062c39b30SMarc-André Lureau     f = fopen(path, "r");
4711e271338SMarc-André Lureau     g_free(path);
47262c39b30SMarc-André Lureau     g_assert_nonnull(f);
47362c39b30SMarc-André Lureau     count = fread(tmp, 1, sizeof(tmp), f);
47462c39b30SMarc-André Lureau     g_assert_cmpint(count, ==, sizeof(helloworld));
47562c39b30SMarc-André Lureau     tmp[count] = 0;
47662c39b30SMarc-André Lureau     g_assert_cmpstr(tmp, ==, (char *)helloworld);
47762c39b30SMarc-André Lureau     fclose(f);
47862c39b30SMarc-André Lureau 
47962c39b30SMarc-André Lureau     /* open */
48062c39b30SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-file-open',"
48162c39b30SMarc-André Lureau                  " 'arguments': { 'path': 'foo', 'mode': 'r' } }");
48262c39b30SMarc-André Lureau     g_assert_nonnull(ret);
48362c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
48462c39b30SMarc-André Lureau     id = qdict_get_int(ret, "return");
485cb3e7f08SMarc-André Lureau     qobject_unref(ret);
48662c39b30SMarc-André Lureau 
48762c39b30SMarc-André Lureau     /* read */
488015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
489015715f5SMarkus Armbruster                  "{'execute': 'guest-file-read',"
49062c39b30SMarc-André Lureau                  " 'arguments': { 'handle': %" PRId64 "} }",
49162c39b30SMarc-André Lureau                  id);
49262c39b30SMarc-André Lureau     val = qdict_get_qdict(ret, "return");
49362c39b30SMarc-André Lureau     count = qdict_get_int(val, "count");
49462c39b30SMarc-André Lureau     eof = qdict_get_bool(val, "eof");
49562c39b30SMarc-André Lureau     b64 = qdict_get_str(val, "buf-b64");
49662c39b30SMarc-André Lureau     g_assert_cmpint(count, ==, sizeof(helloworld));
49762c39b30SMarc-André Lureau     g_assert(eof);
49862c39b30SMarc-André Lureau     g_assert_cmpstr(b64, ==, enc);
49962c39b30SMarc-André Lureau 
500cb3e7f08SMarc-André Lureau     qobject_unref(ret);
50162c39b30SMarc-André Lureau     g_free(enc);
50262c39b30SMarc-André Lureau 
50362c39b30SMarc-André Lureau     /* read eof */
504015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
505015715f5SMarkus Armbruster                  "{'execute': 'guest-file-read',"
50662c39b30SMarc-André Lureau                  " 'arguments': { 'handle': %" PRId64 "} }",
50762c39b30SMarc-André Lureau                  id);
50862c39b30SMarc-André Lureau     val = qdict_get_qdict(ret, "return");
50962c39b30SMarc-André Lureau     count = qdict_get_int(val, "count");
51062c39b30SMarc-André Lureau     eof = qdict_get_bool(val, "eof");
51162c39b30SMarc-André Lureau     b64 = qdict_get_str(val, "buf-b64");
51262c39b30SMarc-André Lureau     g_assert_cmpint(count, ==, 0);
51362c39b30SMarc-André Lureau     g_assert(eof);
51462c39b30SMarc-André Lureau     g_assert_cmpstr(b64, ==, "");
515cb3e7f08SMarc-André Lureau     qobject_unref(ret);
51662c39b30SMarc-André Lureau 
51762c39b30SMarc-André Lureau     /* seek */
518015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
519015715f5SMarkus Armbruster                  "{'execute': 'guest-file-seek',"
52062c39b30SMarc-André Lureau                  " 'arguments': { 'handle': %" PRId64 ", "
521015715f5SMarkus Armbruster                  " 'offset': %d, 'whence': %s } }",
5220b4b4938SEric Blake                  id, 6, "set");
52362c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
52462c39b30SMarc-André Lureau     val = qdict_get_qdict(ret, "return");
52562c39b30SMarc-André Lureau     count = qdict_get_int(val, "position");
52662c39b30SMarc-André Lureau     eof = qdict_get_bool(val, "eof");
52762c39b30SMarc-André Lureau     g_assert_cmpint(count, ==, 6);
52862c39b30SMarc-André Lureau     g_assert(!eof);
529cb3e7f08SMarc-André Lureau     qobject_unref(ret);
53062c39b30SMarc-André Lureau 
53162c39b30SMarc-André Lureau     /* partial read */
532015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
533015715f5SMarkus Armbruster                  "{'execute': 'guest-file-read',"
53462c39b30SMarc-André Lureau                  " 'arguments': { 'handle': %" PRId64 "} }",
53562c39b30SMarc-André Lureau                  id);
53662c39b30SMarc-André Lureau     val = qdict_get_qdict(ret, "return");
53762c39b30SMarc-André Lureau     count = qdict_get_int(val, "count");
53862c39b30SMarc-André Lureau     eof = qdict_get_bool(val, "eof");
53962c39b30SMarc-André Lureau     b64 = qdict_get_str(val, "buf-b64");
54062c39b30SMarc-André Lureau     g_assert_cmpint(count, ==, sizeof(helloworld) - 6);
54162c39b30SMarc-André Lureau     g_assert(eof);
54262c39b30SMarc-André Lureau     dec = g_base64_decode(b64, &count);
54362c39b30SMarc-André Lureau     g_assert_cmpint(count, ==, sizeof(helloworld) - 6);
54462c39b30SMarc-André Lureau     g_assert_cmpmem(dec, count, helloworld + 6, sizeof(helloworld) - 6);
54562c39b30SMarc-André Lureau     g_free(dec);
54662c39b30SMarc-André Lureau 
547cb3e7f08SMarc-André Lureau     qobject_unref(ret);
54862c39b30SMarc-André Lureau 
54962c39b30SMarc-André Lureau     /* close */
550015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
551015715f5SMarkus Armbruster                  "{'execute': 'guest-file-close',"
55262c39b30SMarc-André Lureau                  " 'arguments': {'handle': %" PRId64 "} }",
55362c39b30SMarc-André Lureau                  id);
554cb3e7f08SMarc-André Lureau     qobject_unref(ret);
55562c39b30SMarc-André Lureau }
55662c39b30SMarc-André Lureau 
5574eaab85cSMarc-André Lureau static void test_qga_file_write_read(gconstpointer fix)
5584eaab85cSMarc-André Lureau {
5594eaab85cSMarc-André Lureau     const TestFixture *fixture = fix;
5604eaab85cSMarc-André Lureau     const unsigned char helloworld[] = "Hello World!\n";
5614eaab85cSMarc-André Lureau     const char *b64;
562015715f5SMarkus Armbruster     gchar *enc;
5634eaab85cSMarc-André Lureau     QDict *ret, *val;
5644eaab85cSMarc-André Lureau     int64_t id, eof;
5654eaab85cSMarc-André Lureau     gsize count;
5664eaab85cSMarc-André Lureau 
5674eaab85cSMarc-André Lureau     /* open */
5684eaab85cSMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-file-open',"
5694eaab85cSMarc-André Lureau                  " 'arguments': { 'path': 'foo', 'mode': 'w+' } }");
5704eaab85cSMarc-André Lureau     g_assert_nonnull(ret);
5714eaab85cSMarc-André Lureau     qmp_assert_no_error(ret);
5724eaab85cSMarc-André Lureau     id = qdict_get_int(ret, "return");
573cb3e7f08SMarc-André Lureau     qobject_unref(ret);
5744eaab85cSMarc-André Lureau 
5754eaab85cSMarc-André Lureau     enc = g_base64_encode(helloworld, sizeof(helloworld));
5764eaab85cSMarc-André Lureau     /* write */
577015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
578015715f5SMarkus Armbruster                  "{'execute': 'guest-file-write',"
5794eaab85cSMarc-André Lureau                  " 'arguments': { 'handle': %" PRId64 ","
580015715f5SMarkus Armbruster                  " 'buf-b64': %s } }", id, enc);
5814eaab85cSMarc-André Lureau     g_assert_nonnull(ret);
5824eaab85cSMarc-André Lureau     qmp_assert_no_error(ret);
5834eaab85cSMarc-André Lureau 
5844eaab85cSMarc-André Lureau     val = qdict_get_qdict(ret, "return");
5854eaab85cSMarc-André Lureau     count = qdict_get_int(val, "count");
5864eaab85cSMarc-André Lureau     eof = qdict_get_bool(val, "eof");
5874eaab85cSMarc-André Lureau     g_assert_cmpint(count, ==, sizeof(helloworld));
5884eaab85cSMarc-André Lureau     g_assert_cmpint(eof, ==, 0);
589cb3e7f08SMarc-André Lureau     qobject_unref(ret);
5904eaab85cSMarc-André Lureau 
5914eaab85cSMarc-André Lureau     /* read (check implicit flush) */
592015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
593015715f5SMarkus Armbruster                  "{'execute': 'guest-file-read',"
5944eaab85cSMarc-André Lureau                  " 'arguments': { 'handle': %" PRId64 "} }",
5954eaab85cSMarc-André Lureau                  id);
5964eaab85cSMarc-André Lureau     val = qdict_get_qdict(ret, "return");
5974eaab85cSMarc-André Lureau     count = qdict_get_int(val, "count");
5984eaab85cSMarc-André Lureau     eof = qdict_get_bool(val, "eof");
5994eaab85cSMarc-André Lureau     b64 = qdict_get_str(val, "buf-b64");
6004eaab85cSMarc-André Lureau     g_assert_cmpint(count, ==, 0);
6014eaab85cSMarc-André Lureau     g_assert(eof);
6024eaab85cSMarc-André Lureau     g_assert_cmpstr(b64, ==, "");
603cb3e7f08SMarc-André Lureau     qobject_unref(ret);
6044eaab85cSMarc-André Lureau 
6054eaab85cSMarc-André Lureau     /* seek to 0 */
606015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
607015715f5SMarkus Armbruster                  "{'execute': 'guest-file-seek',"
6084eaab85cSMarc-André Lureau                  " 'arguments': { 'handle': %" PRId64 ", "
609015715f5SMarkus Armbruster                  " 'offset': %d, 'whence': %s } }",
6100b4b4938SEric Blake                  id, 0, "set");
6114eaab85cSMarc-André Lureau     qmp_assert_no_error(ret);
6124eaab85cSMarc-André Lureau     val = qdict_get_qdict(ret, "return");
6134eaab85cSMarc-André Lureau     count = qdict_get_int(val, "position");
6144eaab85cSMarc-André Lureau     eof = qdict_get_bool(val, "eof");
6154eaab85cSMarc-André Lureau     g_assert_cmpint(count, ==, 0);
6164eaab85cSMarc-André Lureau     g_assert(!eof);
617cb3e7f08SMarc-André Lureau     qobject_unref(ret);
6184eaab85cSMarc-André Lureau 
6194eaab85cSMarc-André Lureau     /* read */
620015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
621015715f5SMarkus Armbruster                  "{'execute': 'guest-file-read',"
6224eaab85cSMarc-André Lureau                  " 'arguments': { 'handle': %" PRId64 "} }",
6234eaab85cSMarc-André Lureau                  id);
6244eaab85cSMarc-André Lureau     val = qdict_get_qdict(ret, "return");
6254eaab85cSMarc-André Lureau     count = qdict_get_int(val, "count");
6264eaab85cSMarc-André Lureau     eof = qdict_get_bool(val, "eof");
6274eaab85cSMarc-André Lureau     b64 = qdict_get_str(val, "buf-b64");
6284eaab85cSMarc-André Lureau     g_assert_cmpint(count, ==, sizeof(helloworld));
6294eaab85cSMarc-André Lureau     g_assert(eof);
6304eaab85cSMarc-André Lureau     g_assert_cmpstr(b64, ==, enc);
631cb3e7f08SMarc-André Lureau     qobject_unref(ret);
6324eaab85cSMarc-André Lureau     g_free(enc);
6334eaab85cSMarc-André Lureau 
6344eaab85cSMarc-André Lureau     /* close */
635015715f5SMarkus Armbruster     ret = qmp_fd(fixture->fd,
636015715f5SMarkus Armbruster                  "{'execute': 'guest-file-close',"
6374eaab85cSMarc-André Lureau                  " 'arguments': {'handle': %" PRId64 "} }",
6384eaab85cSMarc-André Lureau                  id);
639cb3e7f08SMarc-André Lureau     qobject_unref(ret);
6404eaab85cSMarc-André Lureau }
6414eaab85cSMarc-André Lureau 
64262c39b30SMarc-André Lureau static void test_qga_get_time(gconstpointer fix)
64362c39b30SMarc-André Lureau {
64462c39b30SMarc-André Lureau     const TestFixture *fixture = fix;
64562c39b30SMarc-André Lureau     QDict *ret;
64662c39b30SMarc-André Lureau     int64_t time;
64762c39b30SMarc-André Lureau 
64862c39b30SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-time'}");
64962c39b30SMarc-André Lureau     g_assert_nonnull(ret);
65062c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
65162c39b30SMarc-André Lureau 
65262c39b30SMarc-André Lureau     time = qdict_get_int(ret, "return");
65362c39b30SMarc-André Lureau     g_assert_cmpint(time, >, 0);
65462c39b30SMarc-André Lureau 
655cb3e7f08SMarc-André Lureau     qobject_unref(ret);
65662c39b30SMarc-André Lureau }
65762c39b30SMarc-André Lureau 
65862c39b30SMarc-André Lureau static void test_qga_blacklist(gconstpointer data)
65962c39b30SMarc-André Lureau {
66062c39b30SMarc-André Lureau     TestFixture fix;
66162c39b30SMarc-André Lureau     QDict *ret, *error;
66262c39b30SMarc-André Lureau     const gchar *class, *desc;
66362c39b30SMarc-André Lureau 
664c28afa76STomáš Golembiovský     fixture_setup(&fix, "-b guest-ping,guest-get-time", NULL);
66562c39b30SMarc-André Lureau 
66662c39b30SMarc-André Lureau     /* check blacklist */
66762c39b30SMarc-André Lureau     ret = qmp_fd(fix.fd, "{'execute': 'guest-ping'}");
66862c39b30SMarc-André Lureau     g_assert_nonnull(ret);
66962c39b30SMarc-André Lureau     error = qdict_get_qdict(ret, "error");
67062c39b30SMarc-André Lureau     class = qdict_get_try_str(error, "class");
67162c39b30SMarc-André Lureau     desc = qdict_get_try_str(error, "desc");
6722546be1cSMichal Privoznik     g_assert_cmpstr(class, ==, "CommandNotFound");
67362c39b30SMarc-André Lureau     g_assert_nonnull(g_strstr_len(desc, -1, "has been disabled"));
674cb3e7f08SMarc-André Lureau     qobject_unref(ret);
67562c39b30SMarc-André Lureau 
67662c39b30SMarc-André Lureau     ret = qmp_fd(fix.fd, "{'execute': 'guest-get-time'}");
67762c39b30SMarc-André Lureau     g_assert_nonnull(ret);
67862c39b30SMarc-André Lureau     error = qdict_get_qdict(ret, "error");
67962c39b30SMarc-André Lureau     class = qdict_get_try_str(error, "class");
68062c39b30SMarc-André Lureau     desc = qdict_get_try_str(error, "desc");
6812546be1cSMichal Privoznik     g_assert_cmpstr(class, ==, "CommandNotFound");
68262c39b30SMarc-André Lureau     g_assert_nonnull(g_strstr_len(desc, -1, "has been disabled"));
683cb3e7f08SMarc-André Lureau     qobject_unref(ret);
68462c39b30SMarc-André Lureau 
68562c39b30SMarc-André Lureau     /* check something work */
68662c39b30SMarc-André Lureau     ret = qmp_fd(fix.fd, "{'execute': 'guest-get-fsinfo'}");
68762c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
688cb3e7f08SMarc-André Lureau     qobject_unref(ret);
68962c39b30SMarc-André Lureau 
69062c39b30SMarc-André Lureau     fixture_tear_down(&fix, NULL);
69162c39b30SMarc-André Lureau }
69262c39b30SMarc-André Lureau 
69362c39b30SMarc-André Lureau static void test_qga_config(gconstpointer data)
69462c39b30SMarc-André Lureau {
69562c39b30SMarc-André Lureau     GError *error = NULL;
6961741b945SMarc-André Lureau     char *cwd, *cmd, *out, *err, *str, **strv, **argv = NULL;
69762c39b30SMarc-André Lureau     char *env[2];
6981741b945SMarc-André Lureau     int status;
69962c39b30SMarc-André Lureau     gsize n;
70062c39b30SMarc-André Lureau     GKeyFile *kf;
70162c39b30SMarc-André Lureau 
70262c39b30SMarc-André Lureau     cwd = g_get_current_dir();
703f15bff25SPaolo Bonzini     cmd = g_strdup_printf("%s%cqga%cqemu-ga -D",
704f15bff25SPaolo Bonzini                           cwd, G_DIR_SEPARATOR, G_DIR_SEPARATOR);
7051e271338SMarc-André Lureau     g_free(cwd);
70662c39b30SMarc-André Lureau     g_shell_parse_argv(cmd, NULL, &argv, &error);
7071e271338SMarc-André Lureau     g_free(cmd);
70862c39b30SMarc-André Lureau     g_assert_no_error(error);
70962c39b30SMarc-André Lureau 
7101741b945SMarc-André Lureau     env[0] = g_strdup_printf("QGA_CONF=tests%cdata%ctest-qga-config",
7111741b945SMarc-André Lureau                              G_DIR_SEPARATOR, G_DIR_SEPARATOR);
71262c39b30SMarc-André Lureau     env[1] = NULL;
71362c39b30SMarc-André Lureau     g_spawn_sync(NULL, argv, env, 0,
71462c39b30SMarc-André Lureau                  NULL, NULL, &out, &err, &status, &error);
7151e271338SMarc-André Lureau     g_strfreev(argv);
7161e271338SMarc-André Lureau 
71762c39b30SMarc-André Lureau     g_assert_no_error(error);
71862c39b30SMarc-André Lureau     g_assert_cmpstr(err, ==, "");
71962c39b30SMarc-André Lureau     g_assert_cmpint(status, ==, 0);
72062c39b30SMarc-André Lureau 
72162c39b30SMarc-André Lureau     kf = g_key_file_new();
72262c39b30SMarc-André Lureau     g_key_file_load_from_data(kf, out, -1, G_KEY_FILE_NONE, &error);
72362c39b30SMarc-André Lureau     g_assert_no_error(error);
72462c39b30SMarc-André Lureau 
72562c39b30SMarc-André Lureau     str = g_key_file_get_start_group(kf);
72662c39b30SMarc-André Lureau     g_assert_cmpstr(str, ==, "general");
72762c39b30SMarc-André Lureau     g_free(str);
72862c39b30SMarc-André Lureau 
72962c39b30SMarc-André Lureau     g_assert_false(g_key_file_get_boolean(kf, "general", "daemon", &error));
73062c39b30SMarc-André Lureau     g_assert_no_error(error);
73162c39b30SMarc-André Lureau 
73262c39b30SMarc-André Lureau     str = g_key_file_get_string(kf, "general", "method", &error);
73362c39b30SMarc-André Lureau     g_assert_no_error(error);
73462c39b30SMarc-André Lureau     g_assert_cmpstr(str, ==, "virtio-serial");
73562c39b30SMarc-André Lureau     g_free(str);
73662c39b30SMarc-André Lureau 
73762c39b30SMarc-André Lureau     str = g_key_file_get_string(kf, "general", "path", &error);
73862c39b30SMarc-André Lureau     g_assert_no_error(error);
73962c39b30SMarc-André Lureau     g_assert_cmpstr(str, ==, "/path/to/org.qemu.guest_agent.0");
74062c39b30SMarc-André Lureau     g_free(str);
74162c39b30SMarc-André Lureau 
74262c39b30SMarc-André Lureau     str = g_key_file_get_string(kf, "general", "pidfile", &error);
74362c39b30SMarc-André Lureau     g_assert_no_error(error);
74462c39b30SMarc-André Lureau     g_assert_cmpstr(str, ==, "/var/foo/qemu-ga.pid");
74562c39b30SMarc-André Lureau     g_free(str);
74662c39b30SMarc-André Lureau 
74762c39b30SMarc-André Lureau     str = g_key_file_get_string(kf, "general", "statedir", &error);
74862c39b30SMarc-André Lureau     g_assert_no_error(error);
74962c39b30SMarc-André Lureau     g_assert_cmpstr(str, ==, "/var/state");
75062c39b30SMarc-André Lureau     g_free(str);
75162c39b30SMarc-André Lureau 
75262c39b30SMarc-André Lureau     g_assert_true(g_key_file_get_boolean(kf, "general", "verbose", &error));
75362c39b30SMarc-André Lureau     g_assert_no_error(error);
75462c39b30SMarc-André Lureau 
75562c39b30SMarc-André Lureau     strv = g_key_file_get_string_list(kf, "general", "blacklist", &n, &error);
75662c39b30SMarc-André Lureau     g_assert_cmpint(n, ==, 2);
75762c39b30SMarc-André Lureau     g_assert_true(g_strv_contains((const char * const *)strv,
75862c39b30SMarc-André Lureau                                   "guest-ping"));
75962c39b30SMarc-André Lureau     g_assert_true(g_strv_contains((const char * const *)strv,
76062c39b30SMarc-André Lureau                                   "guest-get-time"));
76162c39b30SMarc-André Lureau     g_assert_no_error(error);
76262c39b30SMarc-André Lureau     g_strfreev(strv);
76362c39b30SMarc-André Lureau 
76462c39b30SMarc-André Lureau     g_free(out);
76562c39b30SMarc-André Lureau     g_free(err);
76662c39b30SMarc-André Lureau     g_free(env[0]);
76762c39b30SMarc-André Lureau     g_key_file_free(kf);
76862c39b30SMarc-André Lureau }
76962c39b30SMarc-André Lureau 
77062c39b30SMarc-André Lureau static void test_qga_fsfreeze_status(gconstpointer fix)
77162c39b30SMarc-André Lureau {
77262c39b30SMarc-André Lureau     const TestFixture *fixture = fix;
77362c39b30SMarc-André Lureau     QDict *ret;
77462c39b30SMarc-André Lureau     const gchar *status;
77562c39b30SMarc-André Lureau 
77662c39b30SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-status'}");
77762c39b30SMarc-André Lureau     g_assert_nonnull(ret);
77862c39b30SMarc-André Lureau     qmp_assert_no_error(ret);
77962c39b30SMarc-André Lureau 
78062c39b30SMarc-André Lureau     status = qdict_get_try_str(ret, "return");
78162c39b30SMarc-André Lureau     g_assert_cmpstr(status, ==, "thawed");
78262c39b30SMarc-André Lureau 
783cb3e7f08SMarc-André Lureau     qobject_unref(ret);
78462c39b30SMarc-André Lureau }
78562c39b30SMarc-André Lureau 
7863dab9fa1SMarc-André Lureau static void test_qga_guest_exec(gconstpointer fix)
7873dab9fa1SMarc-André Lureau {
7883dab9fa1SMarc-André Lureau     const TestFixture *fixture = fix;
7893dab9fa1SMarc-André Lureau     QDict *ret, *val;
7903dab9fa1SMarc-André Lureau     const gchar *out;
7913dab9fa1SMarc-André Lureau     guchar *decoded;
7923dab9fa1SMarc-André Lureau     int64_t pid, now, exitcode;
7933dab9fa1SMarc-André Lureau     gsize len;
7943dab9fa1SMarc-André Lureau     bool exited;
7953dab9fa1SMarc-André Lureau 
7963dab9fa1SMarc-André Lureau     /* exec 'echo foo bar' */
7973dab9fa1SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
7983dab9fa1SMarc-André Lureau                  " 'path': '/bin/echo', 'arg': [ '-n', '\" test_str \"' ],"
7993dab9fa1SMarc-André Lureau                  " 'capture-output': true } }");
8003dab9fa1SMarc-André Lureau     g_assert_nonnull(ret);
8013dab9fa1SMarc-André Lureau     qmp_assert_no_error(ret);
8023dab9fa1SMarc-André Lureau     val = qdict_get_qdict(ret, "return");
8033dab9fa1SMarc-André Lureau     pid = qdict_get_int(val, "pid");
8043dab9fa1SMarc-André Lureau     g_assert_cmpint(pid, >, 0);
805cb3e7f08SMarc-André Lureau     qobject_unref(ret);
8063dab9fa1SMarc-André Lureau 
8073dab9fa1SMarc-André Lureau     /* wait for completion */
8083dab9fa1SMarc-André Lureau     now = g_get_monotonic_time();
8091792d7d0SEric Blake     do {
810015715f5SMarkus Armbruster         ret = qmp_fd(fixture->fd,
811015715f5SMarkus Armbruster                      "{'execute': 'guest-exec-status',"
812015715f5SMarkus Armbruster                      " 'arguments': { 'pid': %" PRId64 " } }", pid);
8133dab9fa1SMarc-André Lureau         g_assert_nonnull(ret);
8143dab9fa1SMarc-André Lureau         val = qdict_get_qdict(ret, "return");
8153dab9fa1SMarc-André Lureau         exited = qdict_get_bool(val, "exited");
8163dab9fa1SMarc-André Lureau         if (!exited) {
817cb3e7f08SMarc-André Lureau             qobject_unref(ret);
8183dab9fa1SMarc-André Lureau         }
8193dab9fa1SMarc-André Lureau     } while (!exited &&
8203dab9fa1SMarc-André Lureau              g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND);
8213dab9fa1SMarc-André Lureau     g_assert(exited);
8223dab9fa1SMarc-André Lureau 
8233dab9fa1SMarc-André Lureau     /* check stdout */
8243dab9fa1SMarc-André Lureau     exitcode = qdict_get_int(val, "exitcode");
8253dab9fa1SMarc-André Lureau     g_assert_cmpint(exitcode, ==, 0);
8263dab9fa1SMarc-André Lureau     out = qdict_get_str(val, "out-data");
8273dab9fa1SMarc-André Lureau     decoded = g_base64_decode(out, &len);
8283dab9fa1SMarc-André Lureau     g_assert_cmpint(len, ==, 12);
8293dab9fa1SMarc-André Lureau     g_assert_cmpstr((char *)decoded, ==, "\" test_str \"");
8303dab9fa1SMarc-André Lureau     g_free(decoded);
831cb3e7f08SMarc-André Lureau     qobject_unref(ret);
8323dab9fa1SMarc-André Lureau }
8333dab9fa1SMarc-André Lureau 
8343dab9fa1SMarc-André Lureau static void test_qga_guest_exec_invalid(gconstpointer fix)
8353dab9fa1SMarc-André Lureau {
8363dab9fa1SMarc-André Lureau     const TestFixture *fixture = fix;
8373dab9fa1SMarc-André Lureau     QDict *ret, *error;
8383dab9fa1SMarc-André Lureau     const gchar *class, *desc;
8393dab9fa1SMarc-André Lureau 
8403dab9fa1SMarc-André Lureau     /* invalid command */
8413dab9fa1SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
8423dab9fa1SMarc-André Lureau                  " 'path': '/bin/invalid-cmd42' } }");
8433dab9fa1SMarc-André Lureau     g_assert_nonnull(ret);
8443dab9fa1SMarc-André Lureau     error = qdict_get_qdict(ret, "error");
8453dab9fa1SMarc-André Lureau     g_assert_nonnull(error);
8463dab9fa1SMarc-André Lureau     class = qdict_get_str(error, "class");
8473dab9fa1SMarc-André Lureau     desc = qdict_get_str(error, "desc");
8483dab9fa1SMarc-André Lureau     g_assert_cmpstr(class, ==, "GenericError");
8493dab9fa1SMarc-André Lureau     g_assert_cmpint(strlen(desc), >, 0);
850cb3e7f08SMarc-André Lureau     qobject_unref(ret);
8513dab9fa1SMarc-André Lureau 
8523dab9fa1SMarc-André Lureau     /* invalid pid */
8533dab9fa1SMarc-André Lureau     ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec-status',"
8543dab9fa1SMarc-André Lureau                  " 'arguments': { 'pid': 0 } }");
8553dab9fa1SMarc-André Lureau     g_assert_nonnull(ret);
8563dab9fa1SMarc-André Lureau     error = qdict_get_qdict(ret, "error");
8573dab9fa1SMarc-André Lureau     g_assert_nonnull(error);
8583dab9fa1SMarc-André Lureau     class = qdict_get_str(error, "class");
8593dab9fa1SMarc-André Lureau     desc = qdict_get_str(error, "desc");
8603dab9fa1SMarc-André Lureau     g_assert_cmpstr(class, ==, "GenericError");
8613dab9fa1SMarc-André Lureau     g_assert_cmpint(strlen(desc), >, 0);
862cb3e7f08SMarc-André Lureau     qobject_unref(ret);
8633dab9fa1SMarc-André Lureau }
8643dab9fa1SMarc-André Lureau 
865509b97fdSTomáš Golembiovský static void test_qga_guest_get_host_name(gconstpointer fix)
866509b97fdSTomáš Golembiovský {
867509b97fdSTomáš Golembiovský     const TestFixture *fixture = fix;
868509b97fdSTomáš Golembiovský     QDict *ret, *val;
869509b97fdSTomáš Golembiovský 
870509b97fdSTomáš Golembiovský     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-host-name'}");
871509b97fdSTomáš Golembiovský     g_assert_nonnull(ret);
872509b97fdSTomáš Golembiovský     qmp_assert_no_error(ret);
873509b97fdSTomáš Golembiovský 
874509b97fdSTomáš Golembiovský     val = qdict_get_qdict(ret, "return");
875509b97fdSTomáš Golembiovský     g_assert(qdict_haskey(val, "host-name"));
876509b97fdSTomáš Golembiovský 
877509b97fdSTomáš Golembiovský     qobject_unref(ret);
878509b97fdSTomáš Golembiovský }
879509b97fdSTomáš Golembiovský 
880509b97fdSTomáš Golembiovský static void test_qga_guest_get_timezone(gconstpointer fix)
881509b97fdSTomáš Golembiovský {
882509b97fdSTomáš Golembiovský     const TestFixture *fixture = fix;
883509b97fdSTomáš Golembiovský     QDict *ret, *val;
884509b97fdSTomáš Golembiovský 
885509b97fdSTomáš Golembiovský     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-timezone'}");
886509b97fdSTomáš Golembiovský     g_assert_nonnull(ret);
887509b97fdSTomáš Golembiovský     qmp_assert_no_error(ret);
888509b97fdSTomáš Golembiovský 
889509b97fdSTomáš Golembiovský     /* Make sure there's at least offset */
890509b97fdSTomáš Golembiovský     val = qdict_get_qdict(ret, "return");
891509b97fdSTomáš Golembiovský     g_assert(qdict_haskey(val, "offset"));
892509b97fdSTomáš Golembiovský 
893509b97fdSTomáš Golembiovský     qobject_unref(ret);
894509b97fdSTomáš Golembiovský }
895509b97fdSTomáš Golembiovský 
896509b97fdSTomáš Golembiovský static void test_qga_guest_get_users(gconstpointer fix)
897509b97fdSTomáš Golembiovský {
898509b97fdSTomáš Golembiovský     const TestFixture *fixture = fix;
899509b97fdSTomáš Golembiovský     QDict *ret;
900509b97fdSTomáš Golembiovský     QList *val;
901509b97fdSTomáš Golembiovský 
902509b97fdSTomáš Golembiovský     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-users'}");
903509b97fdSTomáš Golembiovský     g_assert_nonnull(ret);
904509b97fdSTomáš Golembiovský     qmp_assert_no_error(ret);
905509b97fdSTomáš Golembiovský 
906509b97fdSTomáš Golembiovský     /* There is not much to test here */
907509b97fdSTomáš Golembiovský     val = qdict_get_qlist(ret, "return");
908509b97fdSTomáš Golembiovský     g_assert_nonnull(val);
909509b97fdSTomáš Golembiovský 
910509b97fdSTomáš Golembiovský     qobject_unref(ret);
911509b97fdSTomáš Golembiovský }
912509b97fdSTomáš Golembiovský 
913339ca68bSTomáš Golembiovský static void test_qga_guest_get_osinfo(gconstpointer data)
914339ca68bSTomáš Golembiovský {
915339ca68bSTomáš Golembiovský     TestFixture fixture;
916339ca68bSTomáš Golembiovský     const gchar *str;
917*a85d0926SMarc-André Lureau     QDict *ret = NULL;
918*a85d0926SMarc-André Lureau     char *env[2];
919*a85d0926SMarc-André Lureau     QDict *val;
920339ca68bSTomáš Golembiovský 
921339ca68bSTomáš Golembiovský     env[0] = g_strdup_printf(
922*a85d0926SMarc-André Lureau         "QGA_OS_RELEASE=%s%c..%cdata%ctest-qga-os-release",
923*a85d0926SMarc-André Lureau         g_test_get_dir(G_TEST_DIST), G_DIR_SEPARATOR, G_DIR_SEPARATOR, G_DIR_SEPARATOR);
924339ca68bSTomáš Golembiovský     env[1] = NULL;
925339ca68bSTomáš Golembiovský     fixture_setup(&fixture, NULL, env);
926339ca68bSTomáš Golembiovský 
927339ca68bSTomáš Golembiovský     ret = qmp_fd(fixture.fd, "{'execute': 'guest-get-osinfo'}");
928339ca68bSTomáš Golembiovský     g_assert_nonnull(ret);
929339ca68bSTomáš Golembiovský     qmp_assert_no_error(ret);
930339ca68bSTomáš Golembiovský 
931339ca68bSTomáš Golembiovský     val = qdict_get_qdict(ret, "return");
932339ca68bSTomáš Golembiovský 
933339ca68bSTomáš Golembiovský     str = qdict_get_try_str(val, "id");
934339ca68bSTomáš Golembiovský     g_assert_nonnull(str);
935339ca68bSTomáš Golembiovský     g_assert_cmpstr(str, ==, "qemu-ga-test");
936339ca68bSTomáš Golembiovský 
937339ca68bSTomáš Golembiovský     str = qdict_get_try_str(val, "name");
938339ca68bSTomáš Golembiovský     g_assert_nonnull(str);
939339ca68bSTomáš Golembiovský     g_assert_cmpstr(str, ==, "QEMU-GA");
940339ca68bSTomáš Golembiovský 
941339ca68bSTomáš Golembiovský     str = qdict_get_try_str(val, "pretty-name");
942339ca68bSTomáš Golembiovský     g_assert_nonnull(str);
943339ca68bSTomáš Golembiovský     g_assert_cmpstr(str, ==, "QEMU Guest Agent test");
944339ca68bSTomáš Golembiovský 
945339ca68bSTomáš Golembiovský     str = qdict_get_try_str(val, "version");
946339ca68bSTomáš Golembiovský     g_assert_nonnull(str);
947339ca68bSTomáš Golembiovský     g_assert_cmpstr(str, ==, "Test 1");
948339ca68bSTomáš Golembiovský 
949339ca68bSTomáš Golembiovský     str = qdict_get_try_str(val, "version-id");
950339ca68bSTomáš Golembiovský     g_assert_nonnull(str);
951339ca68bSTomáš Golembiovský     g_assert_cmpstr(str, ==, "1");
952339ca68bSTomáš Golembiovský 
953339ca68bSTomáš Golembiovský     str = qdict_get_try_str(val, "variant");
954339ca68bSTomáš Golembiovský     g_assert_nonnull(str);
955339ca68bSTomáš Golembiovský     g_assert_cmpstr(str, ==, "Unit test \"'$`\\ and \\\\ etc.");
956339ca68bSTomáš Golembiovský 
957339ca68bSTomáš Golembiovský     str = qdict_get_try_str(val, "variant-id");
958339ca68bSTomáš Golembiovský     g_assert_nonnull(str);
959339ca68bSTomáš Golembiovský     g_assert_cmpstr(str, ==, "unit-test");
960339ca68bSTomáš Golembiovský 
961cb3e7f08SMarc-André Lureau     qobject_unref(ret);
962339ca68bSTomáš Golembiovský     g_free(env[0]);
963339ca68bSTomáš Golembiovský     fixture_tear_down(&fixture, NULL);
964339ca68bSTomáš Golembiovský }
965339ca68bSTomáš Golembiovský 
96662c39b30SMarc-André Lureau int main(int argc, char **argv)
96762c39b30SMarc-André Lureau {
96862c39b30SMarc-André Lureau     TestFixture fix;
96962c39b30SMarc-André Lureau     int ret;
97062c39b30SMarc-André Lureau 
971a7bd942cSMarc-André Lureau #ifdef QEMU_SANITIZE_THREAD
972a7bd942cSMarc-André Lureau     {
973a7bd942cSMarc-André Lureau         g_test_skip("tsan enabled, https://github.com/google/sanitizers/issues/1116");
974a7bd942cSMarc-André Lureau         return 0;
975a7bd942cSMarc-André Lureau     }
976a7bd942cSMarc-André Lureau #endif
977a7bd942cSMarc-André Lureau 
97862c39b30SMarc-André Lureau     setlocale (LC_ALL, "");
97962c39b30SMarc-André Lureau     g_test_init(&argc, &argv, NULL);
980c28afa76STomáš Golembiovský     fixture_setup(&fix, NULL, NULL);
98162c39b30SMarc-André Lureau 
98262c39b30SMarc-André Lureau     g_test_add_data_func("/qga/sync-delimited", &fix, test_qga_sync_delimited);
98362c39b30SMarc-André Lureau     g_test_add_data_func("/qga/sync", &fix, test_qga_sync);
98462c39b30SMarc-André Lureau     g_test_add_data_func("/qga/ping", &fix, test_qga_ping);
98562c39b30SMarc-André Lureau     g_test_add_data_func("/qga/info", &fix, test_qga_info);
98662c39b30SMarc-André Lureau     g_test_add_data_func("/qga/network-get-interfaces", &fix,
98762c39b30SMarc-André Lureau                          test_qga_network_get_interfaces);
988ec72c0e2SBruce Rogers     if (!access("/sys/devices/system/cpu/cpu0", F_OK)) {
98962c39b30SMarc-André Lureau         g_test_add_data_func("/qga/get-vcpus", &fix, test_qga_get_vcpus);
990ec72c0e2SBruce Rogers     }
99162c39b30SMarc-André Lureau     g_test_add_data_func("/qga/get-fsinfo", &fix, test_qga_get_fsinfo);
99262c39b30SMarc-André Lureau     g_test_add_data_func("/qga/get-memory-block-info", &fix,
99362c39b30SMarc-André Lureau                          test_qga_get_memory_block_info);
99462c39b30SMarc-André Lureau     g_test_add_data_func("/qga/get-memory-blocks", &fix,
99562c39b30SMarc-André Lureau                          test_qga_get_memory_blocks);
99662c39b30SMarc-André Lureau     g_test_add_data_func("/qga/file-ops", &fix, test_qga_file_ops);
9974eaab85cSMarc-André Lureau     g_test_add_data_func("/qga/file-write-read", &fix, test_qga_file_write_read);
99862c39b30SMarc-André Lureau     g_test_add_data_func("/qga/get-time", &fix, test_qga_get_time);
9994eaca8deSMarc-André Lureau     g_test_add_data_func("/qga/id", &fix, test_qga_id);
1000d4d7ed73SMarkus Armbruster     g_test_add_data_func("/qga/invalid-oob", &fix, test_qga_invalid_oob);
100162c39b30SMarc-André Lureau     g_test_add_data_func("/qga/invalid-cmd", &fix, test_qga_invalid_cmd);
10024bdadd86SMarc-André Lureau     g_test_add_data_func("/qga/invalid-args", &fix, test_qga_invalid_args);
100362c39b30SMarc-André Lureau     g_test_add_data_func("/qga/fsfreeze-status", &fix,
100462c39b30SMarc-André Lureau                          test_qga_fsfreeze_status);
100562c39b30SMarc-André Lureau 
100662c39b30SMarc-André Lureau     g_test_add_data_func("/qga/blacklist", NULL, test_qga_blacklist);
100762c39b30SMarc-André Lureau     g_test_add_data_func("/qga/config", NULL, test_qga_config);
10083dab9fa1SMarc-André Lureau     g_test_add_data_func("/qga/guest-exec", &fix, test_qga_guest_exec);
10093dab9fa1SMarc-André Lureau     g_test_add_data_func("/qga/guest-exec-invalid", &fix,
10103dab9fa1SMarc-André Lureau                          test_qga_guest_exec_invalid);
1011339ca68bSTomáš Golembiovský     g_test_add_data_func("/qga/guest-get-osinfo", &fix,
1012339ca68bSTomáš Golembiovský                          test_qga_guest_get_osinfo);
1013509b97fdSTomáš Golembiovský     g_test_add_data_func("/qga/guest-get-host-name", &fix,
1014509b97fdSTomáš Golembiovský                          test_qga_guest_get_host_name);
1015509b97fdSTomáš Golembiovský     g_test_add_data_func("/qga/guest-get-timezone", &fix,
1016509b97fdSTomáš Golembiovský                          test_qga_guest_get_timezone);
1017509b97fdSTomáš Golembiovský     g_test_add_data_func("/qga/guest-get-users", &fix,
1018509b97fdSTomáš Golembiovský                          test_qga_guest_get_users);
101962c39b30SMarc-André Lureau 
102062c39b30SMarc-André Lureau     ret = g_test_run();
102162c39b30SMarc-André Lureau 
102262c39b30SMarc-André Lureau     fixture_tear_down(&fix, NULL);
102362c39b30SMarc-André Lureau 
102462c39b30SMarc-André Lureau     return ret;
102562c39b30SMarc-André Lureau }
1026