qemu/tests/test-hmp.c
<<
>>
Prefs
   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"
  18#include "libqtest.h"
  19
  20static int verbose;
  21
  22static const char *hmp_cmds[] = {
  23    "announce_self",
  24    "boot_set ndc",
  25    "chardev-add null,id=testchardev1",
  26    "chardev-send-break testchardev1",
  27    "chardev-change testchardev1 ringbuf",
  28    "chardev-remove testchardev1",
  29    "commit all",
  30    "cpu-add 1",
  31    "cpu 0",
  32    "device_add ?",
  33    "device_add usb-mouse,id=mouse1",
  34    "drive_add ignored format=help",
  35    "mouse_button 7",
  36    "mouse_move 10 10",
  37    "mouse_button 0",
  38    "device_del mouse1",
  39    "dump-guest-memory /dev/null 0 4096",
  40    "dump-guest-memory /dev/null",
  41    "gdbserver",
  42    "hostfwd_add tcp::43210-:43210",
  43    "hostfwd_remove tcp::43210-:43210",
  44    "i /w 0",
  45    "log all",
  46    "log none",
  47    "memsave 0 4096 \"/dev/null\"",
  48    "migrate_set_cache_size 1",
  49    "migrate_set_downtime 1",
  50    "migrate_set_speed 1",
  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",
  59    "pmemsave 0 4096 \"/dev/null\"",
  60    "p $pc + 8",
  61    "qom-list /",
  62    "qom-set /machine initrd test",
  63    "screendump /dev/null",
  64    "sendkey x",
  65    "singlestep on",
  66    "wavcapture /dev/null",
  67    "stopcapture 0",
  68    "sum 0 512",
  69    "x /8i 0x100",
  70    "xp /16x 0",
  71    NULL
  72};
  73
  74/* Run through the list of pre-defined commands */
  75static void test_commands(void)
  76{
  77    char *response;
  78    int i;
  79
  80    for (i = 0; hmp_cmds[i] != NULL; i++) {
  81        response = hmp("%s", hmp_cmds[i]);
  82        if (verbose) {
  83            fprintf(stderr,
  84                    "\texecute HMP command: %s\n"
  85                    "\tresult             : %s\n",
  86                    hmp_cmds[i], response);
  87        }
  88        g_free(response);
  89    }
  90
  91}
  92
  93/* Run through all info commands and call them blindly (without arguments) */
  94static void test_info_commands(void)
  95{
  96    char *resp, *info, *info_buf, *endp;
  97
  98    info_buf = info = hmp("help info");
  99
 100    while (*info) {
 101        /* Extract the info command, ignore parameters and description */
 102        g_assert(strncmp(info, "info ", 5) == 0);
 103        endp = strchr(&info[5], ' ');
 104        g_assert(endp != NULL);
 105        *endp = '\0';
 106        /* Now run the info command */
 107        if (verbose) {
 108            fprintf(stderr, "\t%s\n", info);
 109        }
 110        resp = hmp("%s", info);
 111        g_free(resp);
 112        /* And move forward to the next line */
 113        info = strchr(endp + 1, '\n');
 114        if (!info) {
 115            break;
 116        }
 117        info += 1;
 118    }
 119
 120    g_free(info_buf);
 121}
 122
 123static void test_machine(gconstpointer data)
 124{
 125    const char *machine = data;
 126    char *args;
 127
 128    args = g_strdup_printf("-S -M %s", machine);
 129    qtest_start(args);
 130
 131    test_info_commands();
 132    test_commands();
 133
 134    qtest_end();
 135    g_free(args);
 136    g_free((void *)data);
 137}
 138
 139static void add_machine_test_case(const char *mname)
 140{
 141    char *path;
 142
 143    /* Ignore blacklisted machines that have known problems */
 144    if (!strcmp("xenfv", mname) || !strcmp("xenpv", mname)) {
 145        return;
 146    }
 147
 148    path = g_strdup_printf("hmp/%s", mname);
 149    qtest_add_data_func(path, g_strdup(mname), test_machine);
 150    g_free(path);
 151}
 152
 153int main(int argc, char **argv)
 154{
 155    char *v_env = getenv("V");
 156
 157    if (v_env && *v_env >= '2') {
 158        verbose = true;
 159    }
 160
 161    g_test_init(&argc, &argv, NULL);
 162
 163    qtest_cb_for_every_machine(add_machine_test_case, g_test_quick());
 164
 165    /* as none machine has no memory by default, add a test case with memory */
 166    qtest_add_data_func("hmp/none+2MB", g_strdup("none -m 2"), test_machine);
 167
 168    return g_test_run();
 169}
 170