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