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