qemu/tests/qtest/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 0",
  31    "device_add ?",
  32    "device_add usb-mouse,id=mouse1",
  33    "drive_add ignored format=help",
  34    "mouse_button 7",
  35    "mouse_move 10 10",
  36    "mouse_button 0",
  37    "device_del mouse1",
  38    "dump-guest-memory /dev/null 0 4096",
  39    "dump-guest-memory /dev/null",
  40    "gdbserver",
  41    "gva2gpa 0",
  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_parameter xbzrle_cache_size 1",
  49    "migrate_set_parameter downtime_limit 1",
  50    "migrate_set_parameter max_bandwidth 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    "qom-get /machine initrd",
  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    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, g_test_quick());
 161
 162    /* as none machine has no memory by default, add a test case with memory */
 163    qtest_add_data_func("hmp/none+2MB", g_strdup("none -m 2"), test_machine);
 164
 165    return g_test_run();
 166}
 167