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