]> Git Repo - qemu.git/blob - tests/test-qga.c
Use error_fatal to simplify obvious fatal errors
[qemu.git] / tests / test-qga.c
1 #include <locale.h>
2 #include <glib.h>
3 #include <glib/gstdio.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <errno.h>
7 #include <string.h>
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <sys/un.h>
11 #include <unistd.h>
12 #include <inttypes.h>
13
14 #include "libqtest.h"
15 #include "config-host.h"
16 #include "qga/guest-agent-core.h"
17
18 typedef struct {
19     char *test_dir;
20     GMainLoop *loop;
21     int fd;
22     GPid pid;
23 } TestFixture;
24
25 static int connect_qga(char *path)
26 {
27     int s, ret, len, i = 0;
28     struct sockaddr_un remote;
29
30     s = socket(AF_UNIX, SOCK_STREAM, 0);
31     g_assert(s != -1);
32
33     remote.sun_family = AF_UNIX;
34     do {
35         strcpy(remote.sun_path, path);
36         len = strlen(remote.sun_path) + sizeof(remote.sun_family);
37         ret = connect(s, (struct sockaddr *)&remote, len);
38         if (ret == -1) {
39             g_usleep(G_USEC_PER_SEC);
40         }
41         if (i++ == 10) {
42             return -1;
43         }
44     } while (ret == -1);
45
46     return s;
47 }
48
49 static void qga_watch(GPid pid, gint status, gpointer user_data)
50 {
51     TestFixture *fixture = user_data;
52
53     g_assert_cmpint(status, ==, 0);
54     g_main_loop_quit(fixture->loop);
55 }
56
57 static void
58 fixture_setup(TestFixture *fixture, gconstpointer data)
59 {
60     const gchar *extra_arg = data;
61     GError *error = NULL;
62     gchar *cwd, *path, *cmd, **argv = NULL;
63
64     fixture->loop = g_main_loop_new(NULL, FALSE);
65
66     fixture->test_dir = g_strdup("/tmp/qgatest.XXXXXX");
67     g_assert_nonnull(mkdtemp(fixture->test_dir));
68
69     path = g_build_filename(fixture->test_dir, "sock", NULL);
70     cwd = g_get_current_dir();
71     cmd = g_strdup_printf("%s%cqemu-ga -m unix-listen -t %s -p %s %s %s",
72                           cwd, G_DIR_SEPARATOR,
73                           fixture->test_dir, path,
74                           getenv("QTEST_LOG") ? "-v" : "",
75                           extra_arg ?: "");
76     g_shell_parse_argv(cmd, NULL, &argv, &error);
77     g_assert_no_error(error);
78
79     g_spawn_async(fixture->test_dir, argv, NULL,
80                   G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD,
81                   NULL, NULL, &fixture->pid, &error);
82     g_assert_no_error(error);
83
84     g_child_watch_add(fixture->pid, qga_watch, fixture);
85
86     fixture->fd = connect_qga(path);
87     g_assert_cmpint(fixture->fd, !=, -1);
88
89     g_strfreev(argv);
90     g_free(cmd);
91     g_free(cwd);
92     g_free(path);
93 }
94
95 static void
96 fixture_tear_down(TestFixture *fixture, gconstpointer data)
97 {
98     gchar *tmp;
99
100     kill(fixture->pid, SIGTERM);
101
102     g_main_loop_run(fixture->loop);
103     g_main_loop_unref(fixture->loop);
104
105     g_spawn_close_pid(fixture->pid);
106
107     tmp = g_build_filename(fixture->test_dir, "foo", NULL);
108     g_unlink(tmp);
109     g_free(tmp);
110
111     tmp = g_build_filename(fixture->test_dir, "qga.state", NULL);
112     g_unlink(tmp);
113     g_free(tmp);
114
115     tmp = g_build_filename(fixture->test_dir, "sock", NULL);
116     g_unlink(tmp);
117     g_free(tmp);
118
119     g_rmdir(fixture->test_dir);
120     g_free(fixture->test_dir);
121 }
122
123 static void qmp_assertion_message_error(const char     *domain,
124                                         const char     *file,
125                                         int             line,
126                                         const char     *func,
127                                         const char     *expr,
128                                         QDict          *dict)
129 {
130     const char *class, *desc;
131     char *s;
132     QDict *error;
133
134     error = qdict_get_qdict(dict, "error");
135     class = qdict_get_try_str(error, "class");
136     desc = qdict_get_try_str(error, "desc");
137
138     s = g_strdup_printf("assertion failed %s: %s %s", expr, class, desc);
139     g_assertion_message(domain, file, line, func, s);
140     g_free(s);
141 }
142
143 #define qmp_assert_no_error(err) do {                                   \
144     if (qdict_haskey(err, "error")) {                                   \
145         qmp_assertion_message_error(G_LOG_DOMAIN, __FILE__, __LINE__,   \
146                                     G_STRFUNC, #err, err);              \
147     }                                                                   \
148 } while (0)
149
150 static void test_qga_sync_delimited(gconstpointer fix)
151 {
152     const TestFixture *fixture = fix;
153     guint32 v, r = g_random_int();
154     unsigned char c;
155     QDict *ret;
156     gchar *cmd;
157
158     cmd = g_strdup_printf("%c{'execute': 'guest-sync-delimited',"
159                           " 'arguments': {'id': %u } }", 0xff, r);
160     qmp_fd_send(fixture->fd, cmd);
161     g_free(cmd);
162
163     v = read(fixture->fd, &c, 1);
164     g_assert_cmpint(v, ==, 1);
165     g_assert_cmpint(c, ==, 0xff);
166
167     ret = qmp_fd_receive(fixture->fd);
168     g_assert_nonnull(ret);
169     qmp_assert_no_error(ret);
170
171     v = qdict_get_int(ret, "return");
172     g_assert_cmpint(r, ==, v);
173
174     QDECREF(ret);
175 }
176
177 static void test_qga_sync(gconstpointer fix)
178 {
179     const TestFixture *fixture = fix;
180     guint32 v, r = g_random_int();
181     QDict *ret;
182     gchar *cmd;
183
184     cmd = g_strdup_printf("%c{'execute': 'guest-sync',"
185                           " 'arguments': {'id': %u } }", 0xff, r);
186     ret = qmp_fd(fixture->fd, cmd);
187     g_free(cmd);
188
189     g_assert_nonnull(ret);
190     qmp_assert_no_error(ret);
191
192     v = qdict_get_int(ret, "return");
193     g_assert_cmpint(r, ==, v);
194
195     QDECREF(ret);
196 }
197
198 static void test_qga_ping(gconstpointer fix)
199 {
200     const TestFixture *fixture = fix;
201     QDict *ret;
202
203     ret = qmp_fd(fixture->fd, "{'execute': 'guest-ping'}");
204     g_assert_nonnull(ret);
205     qmp_assert_no_error(ret);
206
207     QDECREF(ret);
208 }
209
210 static void test_qga_invalid_cmd(gconstpointer fix)
211 {
212     const TestFixture *fixture = fix;
213     QDict *ret, *error;
214     const gchar *class, *desc;
215
216     ret = qmp_fd(fixture->fd, "{'execute': 'guest-invalid-cmd'}");
217     g_assert_nonnull(ret);
218
219     error = qdict_get_qdict(ret, "error");
220     class = qdict_get_try_str(error, "class");
221     desc = qdict_get_try_str(error, "desc");
222
223     g_assert_cmpstr(class, ==, "CommandNotFound");
224     g_assert_cmpint(strlen(desc), >, 0);
225
226     QDECREF(ret);
227 }
228
229 static void test_qga_info(gconstpointer fix)
230 {
231     const TestFixture *fixture = fix;
232     QDict *ret, *val;
233     const gchar *version;
234
235     ret = qmp_fd(fixture->fd, "{'execute': 'guest-info'}");
236     g_assert_nonnull(ret);
237     qmp_assert_no_error(ret);
238
239     val = qdict_get_qdict(ret, "return");
240     version = qdict_get_try_str(val, "version");
241     g_assert_cmpstr(version, ==, QEMU_VERSION);
242
243     QDECREF(ret);
244 }
245
246 static void test_qga_get_vcpus(gconstpointer fix)
247 {
248     const TestFixture *fixture = fix;
249     QDict *ret;
250     QList *list;
251     const QListEntry *entry;
252
253     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-vcpus'}");
254     g_assert_nonnull(ret);
255     qmp_assert_no_error(ret);
256
257     /* check there is at least a cpu */
258     list = qdict_get_qlist(ret, "return");
259     entry = qlist_first(list);
260     g_assert(qdict_haskey(qobject_to_qdict(entry->value), "online"));
261     g_assert(qdict_haskey(qobject_to_qdict(entry->value), "logical-id"));
262
263     QDECREF(ret);
264 }
265
266 static void test_qga_get_fsinfo(gconstpointer fix)
267 {
268     const TestFixture *fixture = fix;
269     QDict *ret;
270     QList *list;
271     const QListEntry *entry;
272
273     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-fsinfo'}");
274     g_assert_nonnull(ret);
275     qmp_assert_no_error(ret);
276
277     /* sanity-check the response if there are any filesystems */
278     list = qdict_get_qlist(ret, "return");
279     entry = qlist_first(list);
280     if (entry) {
281         g_assert(qdict_haskey(qobject_to_qdict(entry->value), "name"));
282         g_assert(qdict_haskey(qobject_to_qdict(entry->value), "mountpoint"));
283         g_assert(qdict_haskey(qobject_to_qdict(entry->value), "type"));
284         g_assert(qdict_haskey(qobject_to_qdict(entry->value), "disk"));
285     }
286
287     QDECREF(ret);
288 }
289
290 static void test_qga_get_memory_block_info(gconstpointer fix)
291 {
292     const TestFixture *fixture = fix;
293     QDict *ret, *val;
294     int64_t size;
295
296     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-memory-block-info'}");
297     g_assert_nonnull(ret);
298
299     /* some systems might not expose memory block info in sysfs */
300     if (!qdict_haskey(ret, "error")) {
301         /* check there is at least some memory */
302         val = qdict_get_qdict(ret, "return");
303         size = qdict_get_int(val, "size");
304         g_assert_cmpint(size, >, 0);
305     }
306
307     QDECREF(ret);
308 }
309
310 static void test_qga_get_memory_blocks(gconstpointer fix)
311 {
312     const TestFixture *fixture = fix;
313     QDict *ret;
314     QList *list;
315     const QListEntry *entry;
316
317     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-memory-blocks'}");
318     g_assert_nonnull(ret);
319
320     /* some systems might not expose memory block info in sysfs */
321     if (!qdict_haskey(ret, "error")) {
322         list = qdict_get_qlist(ret, "return");
323         entry = qlist_first(list);
324         /* newer versions of qga may return empty list without error */
325         if (entry) {
326             g_assert(qdict_haskey(qobject_to_qdict(entry->value), "phys-index"));
327             g_assert(qdict_haskey(qobject_to_qdict(entry->value), "online"));
328         }
329     }
330
331     QDECREF(ret);
332 }
333
334 static void test_qga_network_get_interfaces(gconstpointer fix)
335 {
336     const TestFixture *fixture = fix;
337     QDict *ret;
338     QList *list;
339     const QListEntry *entry;
340
341     ret = qmp_fd(fixture->fd, "{'execute': 'guest-network-get-interfaces'}");
342     g_assert_nonnull(ret);
343     qmp_assert_no_error(ret);
344
345     /* check there is at least an interface */
346     list = qdict_get_qlist(ret, "return");
347     entry = qlist_first(list);
348     g_assert(qdict_haskey(qobject_to_qdict(entry->value), "name"));
349
350     QDECREF(ret);
351 }
352
353 static void test_qga_file_ops(gconstpointer fix)
354 {
355     const TestFixture *fixture = fix;
356     const unsigned char helloworld[] = "Hello World!\n";
357     const char *b64;
358     gchar *cmd, *path, *enc;
359     unsigned char *dec;
360     QDict *ret, *val;
361     int64_t id, eof;
362     gsize count;
363     FILE *f;
364     char tmp[100];
365
366     /* open */
367     ret = qmp_fd(fixture->fd, "{'execute': 'guest-file-open',"
368                  " 'arguments': { 'path': 'foo', 'mode': 'w+' } }");
369     g_assert_nonnull(ret);
370     qmp_assert_no_error(ret);
371     id = qdict_get_int(ret, "return");
372     QDECREF(ret);
373
374     enc = g_base64_encode(helloworld, sizeof(helloworld));
375     /* write */
376     cmd = g_strdup_printf("{'execute': 'guest-file-write',"
377                           " 'arguments': { 'handle': %" PRId64 ","
378                           " 'buf-b64': '%s' } }", id, enc);
379     ret = qmp_fd(fixture->fd, cmd);
380     g_assert_nonnull(ret);
381     qmp_assert_no_error(ret);
382
383     val = qdict_get_qdict(ret, "return");
384     count = qdict_get_int(val, "count");
385     eof = qdict_get_bool(val, "eof");
386     g_assert_cmpint(count, ==, sizeof(helloworld));
387     g_assert_cmpint(eof, ==, 0);
388     QDECREF(ret);
389     g_free(cmd);
390
391     /* flush */
392     cmd = g_strdup_printf("{'execute': 'guest-file-flush',"
393                           " 'arguments': {'handle': %" PRId64 "} }",
394                           id);
395     ret = qmp_fd(fixture->fd, cmd);
396     QDECREF(ret);
397     g_free(cmd);
398
399     /* close */
400     cmd = g_strdup_printf("{'execute': 'guest-file-close',"
401                           " 'arguments': {'handle': %" PRId64 "} }",
402                           id);
403     ret = qmp_fd(fixture->fd, cmd);
404     QDECREF(ret);
405     g_free(cmd);
406
407     /* check content */
408     path = g_build_filename(fixture->test_dir, "foo", NULL);
409     f = fopen(path, "r");
410     g_assert_nonnull(f);
411     count = fread(tmp, 1, sizeof(tmp), f);
412     g_assert_cmpint(count, ==, sizeof(helloworld));
413     tmp[count] = 0;
414     g_assert_cmpstr(tmp, ==, (char *)helloworld);
415     fclose(f);
416
417     /* open */
418     ret = qmp_fd(fixture->fd, "{'execute': 'guest-file-open',"
419                  " 'arguments': { 'path': 'foo', 'mode': 'r' } }");
420     g_assert_nonnull(ret);
421     qmp_assert_no_error(ret);
422     id = qdict_get_int(ret, "return");
423     QDECREF(ret);
424
425     /* read */
426     cmd = g_strdup_printf("{'execute': 'guest-file-read',"
427                           " 'arguments': { 'handle': %" PRId64 "} }",
428                           id);
429     ret = qmp_fd(fixture->fd, cmd);
430     val = qdict_get_qdict(ret, "return");
431     count = qdict_get_int(val, "count");
432     eof = qdict_get_bool(val, "eof");
433     b64 = qdict_get_str(val, "buf-b64");
434     g_assert_cmpint(count, ==, sizeof(helloworld));
435     g_assert(eof);
436     g_assert_cmpstr(b64, ==, enc);
437
438     QDECREF(ret);
439     g_free(cmd);
440     g_free(enc);
441
442     /* read eof */
443     cmd = g_strdup_printf("{'execute': 'guest-file-read',"
444                           " 'arguments': { 'handle': %" PRId64 "} }",
445                           id);
446     ret = qmp_fd(fixture->fd, cmd);
447     val = qdict_get_qdict(ret, "return");
448     count = qdict_get_int(val, "count");
449     eof = qdict_get_bool(val, "eof");
450     b64 = qdict_get_str(val, "buf-b64");
451     g_assert_cmpint(count, ==, 0);
452     g_assert(eof);
453     g_assert_cmpstr(b64, ==, "");
454     QDECREF(ret);
455     g_free(cmd);
456
457     /* seek */
458     cmd = g_strdup_printf("{'execute': 'guest-file-seek',"
459                           " 'arguments': { 'handle': %" PRId64 ", "
460                           " 'offset': %d, 'whence': %d } }",
461                           id, 6, QGA_SEEK_SET);
462     ret = qmp_fd(fixture->fd, cmd);
463     qmp_assert_no_error(ret);
464     val = qdict_get_qdict(ret, "return");
465     count = qdict_get_int(val, "position");
466     eof = qdict_get_bool(val, "eof");
467     g_assert_cmpint(count, ==, 6);
468     g_assert(!eof);
469     QDECREF(ret);
470     g_free(cmd);
471
472     /* partial read */
473     cmd = g_strdup_printf("{'execute': 'guest-file-read',"
474                           " 'arguments': { 'handle': %" PRId64 "} }",
475                           id);
476     ret = qmp_fd(fixture->fd, cmd);
477     val = qdict_get_qdict(ret, "return");
478     count = qdict_get_int(val, "count");
479     eof = qdict_get_bool(val, "eof");
480     b64 = qdict_get_str(val, "buf-b64");
481     g_assert_cmpint(count, ==, sizeof(helloworld) - 6);
482     g_assert(eof);
483     dec = g_base64_decode(b64, &count);
484     g_assert_cmpint(count, ==, sizeof(helloworld) - 6);
485     g_assert_cmpmem(dec, count, helloworld + 6, sizeof(helloworld) - 6);
486     g_free(dec);
487
488     QDECREF(ret);
489     g_free(cmd);
490
491     /* close */
492     cmd = g_strdup_printf("{'execute': 'guest-file-close',"
493                           " 'arguments': {'handle': %" PRId64 "} }",
494                           id);
495     ret = qmp_fd(fixture->fd, cmd);
496     QDECREF(ret);
497     g_free(cmd);
498 }
499
500 static void test_qga_file_write_read(gconstpointer fix)
501 {
502     const TestFixture *fixture = fix;
503     const unsigned char helloworld[] = "Hello World!\n";
504     const char *b64;
505     gchar *cmd, *enc;
506     QDict *ret, *val;
507     int64_t id, eof;
508     gsize count;
509
510     /* open */
511     ret = qmp_fd(fixture->fd, "{'execute': 'guest-file-open',"
512                  " 'arguments': { 'path': 'foo', 'mode': 'w+' } }");
513     g_assert_nonnull(ret);
514     qmp_assert_no_error(ret);
515     id = qdict_get_int(ret, "return");
516     QDECREF(ret);
517
518     enc = g_base64_encode(helloworld, sizeof(helloworld));
519     /* write */
520     cmd = g_strdup_printf("{'execute': 'guest-file-write',"
521                           " 'arguments': { 'handle': %" PRId64 ","
522                           " 'buf-b64': '%s' } }", id, enc);
523     ret = qmp_fd(fixture->fd, cmd);
524     g_assert_nonnull(ret);
525     qmp_assert_no_error(ret);
526
527     val = qdict_get_qdict(ret, "return");
528     count = qdict_get_int(val, "count");
529     eof = qdict_get_bool(val, "eof");
530     g_assert_cmpint(count, ==, sizeof(helloworld));
531     g_assert_cmpint(eof, ==, 0);
532     QDECREF(ret);
533     g_free(cmd);
534
535     /* read (check implicit flush) */
536     cmd = g_strdup_printf("{'execute': 'guest-file-read',"
537                           " 'arguments': { 'handle': %" PRId64 "} }",
538                           id);
539     ret = qmp_fd(fixture->fd, cmd);
540     val = qdict_get_qdict(ret, "return");
541     count = qdict_get_int(val, "count");
542     eof = qdict_get_bool(val, "eof");
543     b64 = qdict_get_str(val, "buf-b64");
544     g_assert_cmpint(count, ==, 0);
545     g_assert(eof);
546     g_assert_cmpstr(b64, ==, "");
547     QDECREF(ret);
548     g_free(cmd);
549
550     /* seek to 0 */
551     cmd = g_strdup_printf("{'execute': 'guest-file-seek',"
552                           " 'arguments': { 'handle': %" PRId64 ", "
553                           " 'offset': %d, 'whence': %d } }",
554                           id, 0, QGA_SEEK_SET);
555     ret = qmp_fd(fixture->fd, cmd);
556     qmp_assert_no_error(ret);
557     val = qdict_get_qdict(ret, "return");
558     count = qdict_get_int(val, "position");
559     eof = qdict_get_bool(val, "eof");
560     g_assert_cmpint(count, ==, 0);
561     g_assert(!eof);
562     QDECREF(ret);
563     g_free(cmd);
564
565     /* read */
566     cmd = g_strdup_printf("{'execute': 'guest-file-read',"
567                           " 'arguments': { 'handle': %" PRId64 "} }",
568                           id);
569     ret = qmp_fd(fixture->fd, cmd);
570     val = qdict_get_qdict(ret, "return");
571     count = qdict_get_int(val, "count");
572     eof = qdict_get_bool(val, "eof");
573     b64 = qdict_get_str(val, "buf-b64");
574     g_assert_cmpint(count, ==, sizeof(helloworld));
575     g_assert(eof);
576     g_assert_cmpstr(b64, ==, enc);
577     QDECREF(ret);
578     g_free(cmd);
579     g_free(enc);
580
581     /* close */
582     cmd = g_strdup_printf("{'execute': 'guest-file-close',"
583                           " 'arguments': {'handle': %" PRId64 "} }",
584                           id);
585     ret = qmp_fd(fixture->fd, cmd);
586     QDECREF(ret);
587     g_free(cmd);
588 }
589
590 static void test_qga_get_time(gconstpointer fix)
591 {
592     const TestFixture *fixture = fix;
593     QDict *ret;
594     int64_t time;
595
596     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-time'}");
597     g_assert_nonnull(ret);
598     qmp_assert_no_error(ret);
599
600     time = qdict_get_int(ret, "return");
601     g_assert_cmpint(time, >, 0);
602
603     QDECREF(ret);
604 }
605
606 static void test_qga_set_time(gconstpointer fix)
607 {
608     const TestFixture *fixture = fix;
609     QDict *ret;
610     int64_t current, time;
611     gchar *cmd;
612
613     /* get current time */
614     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-time'}");
615     g_assert_nonnull(ret);
616     qmp_assert_no_error(ret);
617     current = qdict_get_int(ret, "return");
618     g_assert_cmpint(current, >, 0);
619     QDECREF(ret);
620
621     /* set some old time */
622     ret = qmp_fd(fixture->fd, "{'execute': 'guest-set-time',"
623                  " 'arguments': { 'time': 1000 } }");
624     g_assert_nonnull(ret);
625     qmp_assert_no_error(ret);
626     QDECREF(ret);
627
628     /* check old time */
629     ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-time'}");
630     g_assert_nonnull(ret);
631     qmp_assert_no_error(ret);
632     time = qdict_get_int(ret, "return");
633     g_assert_cmpint(time / 1000, <, G_USEC_PER_SEC * 10);
634     QDECREF(ret);
635
636     /* set back current time */
637     cmd = g_strdup_printf("{'execute': 'guest-set-time',"
638                           " 'arguments': { 'time': %" PRId64 " } }",
639                           current + time * 1000);
640     ret = qmp_fd(fixture->fd, cmd);
641     g_free(cmd);
642     g_assert_nonnull(ret);
643     qmp_assert_no_error(ret);
644     QDECREF(ret);
645 }
646
647 static void test_qga_fstrim(gconstpointer fix)
648 {
649     const TestFixture *fixture = fix;
650     QDict *ret;
651     QList *list;
652     const QListEntry *entry;
653
654     ret = qmp_fd(fixture->fd, "{'execute': 'guest-fstrim',"
655                  " arguments: { minimum: 4194304 } }");
656     g_assert_nonnull(ret);
657     qmp_assert_no_error(ret);
658     list = qdict_get_qlist(ret, "return");
659     entry = qlist_first(list);
660     g_assert(qdict_haskey(qobject_to_qdict(entry->value), "paths"));
661
662     QDECREF(ret);
663 }
664
665 static void test_qga_blacklist(gconstpointer data)
666 {
667     TestFixture fix;
668     QDict *ret, *error;
669     const gchar *class, *desc;
670
671     fixture_setup(&fix, "-b guest-ping,guest-get-time");
672
673     /* check blacklist */
674     ret = qmp_fd(fix.fd, "{'execute': 'guest-ping'}");
675     g_assert_nonnull(ret);
676     error = qdict_get_qdict(ret, "error");
677     class = qdict_get_try_str(error, "class");
678     desc = qdict_get_try_str(error, "desc");
679     g_assert_cmpstr(class, ==, "GenericError");
680     g_assert_nonnull(g_strstr_len(desc, -1, "has been disabled"));
681     QDECREF(ret);
682
683     ret = qmp_fd(fix.fd, "{'execute': 'guest-get-time'}");
684     g_assert_nonnull(ret);
685     error = qdict_get_qdict(ret, "error");
686     class = qdict_get_try_str(error, "class");
687     desc = qdict_get_try_str(error, "desc");
688     g_assert_cmpstr(class, ==, "GenericError");
689     g_assert_nonnull(g_strstr_len(desc, -1, "has been disabled"));
690     QDECREF(ret);
691
692     /* check something work */
693     ret = qmp_fd(fix.fd, "{'execute': 'guest-get-fsinfo'}");
694     qmp_assert_no_error(ret);
695     QDECREF(ret);
696
697     fixture_tear_down(&fix, NULL);
698 }
699
700 static void test_qga_config(gconstpointer data)
701 {
702     GError *error = NULL;
703     char *cwd, *cmd, *out, *err, *str, **strv, *conf, **argv = NULL;
704     char *env[2];
705     int status, tmp;
706     gsize n;
707     GKeyFile *kf;
708     const char *qga_config =
709         "[general]\n"
710         "daemon=false\n"
711         "method=virtio-serial\n"
712         "path=/path/to/org.qemu.guest_agent.0\n"
713         "pidfile=/var/foo/qemu-ga.pid\n"
714         "statedir=/var/state\n"
715         "verbose=true\n"
716         "blacklist=guest-ping;guest-get-time\n";
717
718     tmp = g_file_open_tmp(NULL, &conf, &error);
719     g_assert_no_error(error);
720     g_assert_cmpint(tmp, >=, 0);
721     g_assert_cmpstr(conf, !=, "");
722
723     g_file_set_contents(conf, qga_config, -1, &error);
724     g_assert_no_error(error);
725
726     cwd = g_get_current_dir();
727     cmd = g_strdup_printf("%s%cqemu-ga -D",
728                           cwd, G_DIR_SEPARATOR);
729     g_shell_parse_argv(cmd, NULL, &argv, &error);
730     g_assert_no_error(error);
731
732     env[0] = g_strdup_printf("QGA_CONF=%s", conf);
733     env[1] = NULL;
734     g_spawn_sync(NULL, argv, env, 0,
735                  NULL, NULL, &out, &err, &status, &error);
736     g_assert_no_error(error);
737     g_assert_cmpstr(err, ==, "");
738     g_assert_cmpint(status, ==, 0);
739
740     kf = g_key_file_new();
741     g_key_file_load_from_data(kf, out, -1, G_KEY_FILE_NONE, &error);
742     g_assert_no_error(error);
743
744     str = g_key_file_get_start_group(kf);
745     g_assert_cmpstr(str, ==, "general");
746     g_free(str);
747
748     g_assert_false(g_key_file_get_boolean(kf, "general", "daemon", &error));
749     g_assert_no_error(error);
750
751     str = g_key_file_get_string(kf, "general", "method", &error);
752     g_assert_no_error(error);
753     g_assert_cmpstr(str, ==, "virtio-serial");
754     g_free(str);
755
756     str = g_key_file_get_string(kf, "general", "path", &error);
757     g_assert_no_error(error);
758     g_assert_cmpstr(str, ==, "/path/to/org.qemu.guest_agent.0");
759     g_free(str);
760
761     str = g_key_file_get_string(kf, "general", "pidfile", &error);
762     g_assert_no_error(error);
763     g_assert_cmpstr(str, ==, "/var/foo/qemu-ga.pid");
764     g_free(str);
765
766     str = g_key_file_get_string(kf, "general", "statedir", &error);
767     g_assert_no_error(error);
768     g_assert_cmpstr(str, ==, "/var/state");
769     g_free(str);
770
771     g_assert_true(g_key_file_get_boolean(kf, "general", "verbose", &error));
772     g_assert_no_error(error);
773
774     strv = g_key_file_get_string_list(kf, "general", "blacklist", &n, &error);
775     g_assert_cmpint(n, ==, 2);
776 #if GLIB_CHECK_VERSION(2, 44, 0)
777     g_assert_true(g_strv_contains((const char * const *)strv,
778                                   "guest-ping"));
779     g_assert_true(g_strv_contains((const char * const *)strv,
780                                   "guest-get-time"));
781 #endif
782     g_assert_no_error(error);
783     g_strfreev(strv);
784
785     g_free(out);
786     g_free(err);
787     g_free(conf);
788     g_free(env[0]);
789     g_key_file_free(kf);
790
791     close(tmp);
792 }
793
794 static void test_qga_fsfreeze_status(gconstpointer fix)
795 {
796     const TestFixture *fixture = fix;
797     QDict *ret;
798     const gchar *status;
799
800     ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-status'}");
801     g_assert_nonnull(ret);
802     qmp_assert_no_error(ret);
803
804     status = qdict_get_try_str(ret, "return");
805     g_assert_cmpstr(status, ==, "thawed");
806
807     QDECREF(ret);
808 }
809
810 static void test_qga_fsfreeze_and_thaw(gconstpointer fix)
811 {
812     const TestFixture *fixture = fix;
813     QDict *ret;
814     const gchar *status;
815
816     ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-freeze'}");
817     g_assert_nonnull(ret);
818     qmp_assert_no_error(ret);
819     QDECREF(ret);
820
821     ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-status'}");
822     g_assert_nonnull(ret);
823     qmp_assert_no_error(ret);
824     status = qdict_get_try_str(ret, "return");
825     g_assert_cmpstr(status, ==, "frozen");
826     QDECREF(ret);
827
828     ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-thaw'}");
829     g_assert_nonnull(ret);
830     qmp_assert_no_error(ret);
831     QDECREF(ret);
832 }
833
834 int main(int argc, char **argv)
835 {
836     TestFixture fix;
837     int ret;
838
839     setlocale (LC_ALL, "");
840     g_test_init(&argc, &argv, NULL);
841     fixture_setup(&fix, NULL);
842
843     g_test_add_data_func("/qga/sync-delimited", &fix, test_qga_sync_delimited);
844     g_test_add_data_func("/qga/sync", &fix, test_qga_sync);
845     g_test_add_data_func("/qga/ping", &fix, test_qga_ping);
846     g_test_add_data_func("/qga/info", &fix, test_qga_info);
847     g_test_add_data_func("/qga/network-get-interfaces", &fix,
848                          test_qga_network_get_interfaces);
849     g_test_add_data_func("/qga/get-vcpus", &fix, test_qga_get_vcpus);
850     g_test_add_data_func("/qga/get-fsinfo", &fix, test_qga_get_fsinfo);
851     g_test_add_data_func("/qga/get-memory-block-info", &fix,
852                          test_qga_get_memory_block_info);
853     g_test_add_data_func("/qga/get-memory-blocks", &fix,
854                          test_qga_get_memory_blocks);
855     g_test_add_data_func("/qga/file-ops", &fix, test_qga_file_ops);
856     g_test_add_data_func("/qga/file-write-read", &fix, test_qga_file_write_read);
857     g_test_add_data_func("/qga/get-time", &fix, test_qga_get_time);
858     g_test_add_data_func("/qga/invalid-cmd", &fix, test_qga_invalid_cmd);
859     g_test_add_data_func("/qga/fsfreeze-status", &fix,
860                          test_qga_fsfreeze_status);
861
862     g_test_add_data_func("/qga/blacklist", NULL, test_qga_blacklist);
863     g_test_add_data_func("/qga/config", NULL, test_qga_config);
864
865     if (g_getenv("QGA_TEST_SIDE_EFFECTING")) {
866         g_test_add_data_func("/qga/fsfreeze-and-thaw", &fix,
867                              test_qga_fsfreeze_and_thaw);
868         g_test_add_data_func("/qga/set-time", &fix, test_qga_set_time);
869         g_test_add_data_func("/qga/fstrim", &fix, test_qga_fstrim);
870     }
871
872     ret = g_test_run();
873
874     fixture_tear_down(&fix, NULL);
875
876     return ret;
877 }
This page took 0.072943 seconds and 4 git commands to generate.