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