]>
Commit | Line | Data |
---|---|---|
78f86a2b TH |
1 | /* |
2 | * Test HMP commands. | |
3 | * | |
4 | * Copyright (c) 2017 Red Hat Inc. | |
5 | * | |
6 | * Author: | |
7 | * Thomas Huth <thuth@redhat.com> | |
8 | * | |
9 | * This work is licensed under the terms of the GNU GPL, version 2 | |
10 | * or later. See the COPYING file in the top-level directory. | |
11 | * | |
12 | * This test calls some HMP commands for all machines that the current | |
13 | * QEMU binary provides, to check whether they terminate successfully | |
14 | * (i.e. do not crash QEMU). | |
15 | */ | |
16 | ||
17 | #include "qemu/osdep.h" | |
907b5105 | 18 | #include "libqtest.h" |
78f86a2b TH |
19 | |
20 | static int verbose; | |
21 | ||
22 | static const char *hmp_cmds[] = { | |
544f6ea3 | 23 | "announce_self", |
78f86a2b TH |
24 | "boot_set ndc", |
25 | "chardev-add null,id=testchardev1", | |
bbcee372 | 26 | "chardev-send-break testchardev1", |
75b60160 | 27 | "chardev-change testchardev1 ringbuf", |
78f86a2b TH |
28 | "chardev-remove testchardev1", |
29 | "commit all", | |
78f86a2b TH |
30 | "cpu 0", |
31 | "device_add ?", | |
32 | "device_add usb-mouse,id=mouse1", | |
ab638171 | 33 | "drive_add ignored format=help", |
78f86a2b TH |
34 | "mouse_button 7", |
35 | "mouse_move 10 10", | |
36 | "mouse_button 0", | |
37 | "device_del mouse1", | |
38 | "dump-guest-memory /dev/null 0 4096", | |
4e5c3a37 | 39 | "dump-guest-memory /dev/null", |
78f86a2b | 40 | "gdbserver", |
574d9693 | 41 | "gva2gpa 0", |
78f86a2b TH |
42 | "hostfwd_add tcp::43210-:43210", |
43 | "hostfwd_remove tcp::43210-:43210", | |
78f86a2b TH |
44 | "i /w 0", |
45 | "log all", | |
46 | "log none", | |
47 | "memsave 0 4096 \"/dev/null\"", | |
4d841dae | 48 | "migrate_set_parameter xbzrle-cache-size 64k", |
b21a6e31 MA |
49 | "migrate_set_parameter downtime-limit 1", |
50 | "migrate_set_parameter max-bandwidth 1", | |
78f86a2b TH |
51 | "netdev_add user,id=net1", |
52 | "set_link net1 off", | |
53 | "set_link net1 on", | |
54 | "netdev_del net1", | |
55 | "nmi", | |
56 | "o /w 0 0x1234", | |
57 | "object_add memory-backend-ram,id=mem1,size=256M", | |
58 | "object_del mem1", | |
e9ccfdd9 | 59 | "one-insn-per-tb on", |
78f86a2b TH |
60 | "pmemsave 0 4096 \"/dev/null\"", |
61 | "p $pc + 8", | |
62 | "qom-list /", | |
63 | "qom-set /machine initrd test", | |
89cf4fe3 | 64 | "qom-get /machine initrd", |
78f86a2b TH |
65 | "screendump /dev/null", |
66 | "sendkey x", | |
67 | "singlestep on", | |
68 | "wavcapture /dev/null", | |
69 | "stopcapture 0", | |
70 | "sum 0 512", | |
71 | "x /8i 0x100", | |
72 | "xp /16x 0", | |
73 | NULL | |
74 | }; | |
75 | ||
76 | /* Run through the list of pre-defined commands */ | |
8c7eb098 | 77 | static void test_commands(QTestState *qts) |
78f86a2b TH |
78 | { |
79 | char *response; | |
80 | int i; | |
81 | ||
82 | for (i = 0; hmp_cmds[i] != NULL; i++) { | |
8c7eb098 | 83 | response = qtest_hmp(qts, "%s", hmp_cmds[i]); |
78f86a2b | 84 | if (verbose) { |
0eaf3b82 VG |
85 | fprintf(stderr, |
86 | "\texecute HMP command: %s\n" | |
87 | "\tresult : %s\n", | |
88 | hmp_cmds[i], response); | |
78f86a2b | 89 | } |
78f86a2b TH |
90 | g_free(response); |
91 | } | |
92 | ||
93 | } | |
94 | ||
95 | /* Run through all info commands and call them blindly (without arguments) */ | |
8c7eb098 | 96 | static void test_info_commands(QTestState *qts) |
78f86a2b TH |
97 | { |
98 | char *resp, *info, *info_buf, *endp; | |
99 | ||
8c7eb098 | 100 | info_buf = info = qtest_hmp(qts, "help info"); |
78f86a2b TH |
101 | |
102 | while (*info) { | |
103 | /* Extract the info command, ignore parameters and description */ | |
104 | g_assert(strncmp(info, "info ", 5) == 0); | |
105 | endp = strchr(&info[5], ' '); | |
106 | g_assert(endp != NULL); | |
107 | *endp = '\0'; | |
108 | /* Now run the info command */ | |
109 | if (verbose) { | |
110 | fprintf(stderr, "\t%s\n", info); | |
111 | } | |
8c7eb098 | 112 | resp = qtest_hmp(qts, "%s", info); |
78f86a2b TH |
113 | g_free(resp); |
114 | /* And move forward to the next line */ | |
115 | info = strchr(endp + 1, '\n'); | |
116 | if (!info) { | |
117 | break; | |
118 | } | |
119 | info += 1; | |
120 | } | |
121 | ||
122 | g_free(info_buf); | |
123 | } | |
124 | ||
125 | static void test_machine(gconstpointer data) | |
126 | { | |
127 | const char *machine = data; | |
128 | char *args; | |
8c7eb098 | 129 | QTestState *qts; |
78f86a2b TH |
130 | |
131 | args = g_strdup_printf("-S -M %s", machine); | |
8c7eb098 | 132 | qts = qtest_init(args); |
78f86a2b | 133 | |
8c7eb098 TH |
134 | test_info_commands(qts); |
135 | test_commands(qts); | |
78f86a2b | 136 | |
8c7eb098 | 137 | qtest_quit(qts); |
78f86a2b TH |
138 | g_free(args); |
139 | g_free((void *)data); | |
140 | } | |
141 | ||
142 | static void add_machine_test_case(const char *mname) | |
143 | { | |
144 | char *path; | |
145 | ||
78f86a2b TH |
146 | path = g_strdup_printf("hmp/%s", mname); |
147 | qtest_add_data_func(path, g_strdup(mname), test_machine); | |
148 | g_free(path); | |
149 | } | |
150 | ||
151 | int main(int argc, char **argv) | |
152 | { | |
153 | char *v_env = getenv("V"); | |
154 | ||
6eb71c6a | 155 | if (v_env && atoi(v_env) >= 2) { |
78f86a2b TH |
156 | verbose = true; |
157 | } | |
158 | ||
159 | g_test_init(&argc, &argv, NULL); | |
160 | ||
1f4a0d81 | 161 | qtest_cb_for_every_machine(add_machine_test_case, g_test_quick()); |
78f86a2b | 162 | |
4e5c3a37 LV |
163 | /* as none machine has no memory by default, add a test case with memory */ |
164 | qtest_add_data_func("hmp/none+2MB", g_strdup("none -m 2"), test_machine); | |
165 | ||
78f86a2b TH |
166 | return g_test_run(); |
167 | } |