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