qemu/tests/pc-cpu-test.c
<<
>>
Prefs
   1/*
   2 * QTest testcase for PC CPUs
   3 *
   4 * Copyright (c) 2015 SUSE Linux GmbH
   5 *
   6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
   7 * See the COPYING file in the top-level directory.
   8 */
   9
  10#include "qemu/osdep.h"
  11
  12#include "qemu-common.h"
  13#include "libqtest.h"
  14#include "qapi/qmp/types.h"
  15
  16struct PCTestData {
  17    char *machine;
  18    const char *cpu_model;
  19    unsigned sockets;
  20    unsigned cores;
  21    unsigned threads;
  22    unsigned maxcpus;
  23};
  24typedef struct PCTestData PCTestData;
  25
  26static void test_pc_with_cpu_add(gconstpointer data)
  27{
  28    const PCTestData *s = data;
  29    char *args;
  30    QDict *response;
  31    unsigned int i;
  32
  33    args = g_strdup_printf("-machine %s -cpu %s "
  34                           "-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u",
  35                           s->machine, s->cpu_model,
  36                           s->sockets, s->cores, s->threads, s->maxcpus);
  37    qtest_start(args);
  38
  39    for (i = s->sockets * s->cores * s->threads; i < s->maxcpus; i++) {
  40        response = qmp("{ 'execute': 'cpu-add',"
  41                       "  'arguments': { 'id': %d } }", i);
  42        g_assert(response);
  43        g_assert(!qdict_haskey(response, "error"));
  44        QDECREF(response);
  45    }
  46
  47    qtest_end();
  48    g_free(args);
  49}
  50
  51static void test_pc_without_cpu_add(gconstpointer data)
  52{
  53    const PCTestData *s = data;
  54    char *args;
  55    QDict *response;
  56
  57    args = g_strdup_printf("-machine %s -cpu %s "
  58                           "-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u",
  59                           s->machine, s->cpu_model,
  60                           s->sockets, s->cores, s->threads, s->maxcpus);
  61    qtest_start(args);
  62
  63    response = qmp("{ 'execute': 'cpu-add',"
  64                   "  'arguments': { 'id': %d } }",
  65                   s->sockets * s->cores * s->threads);
  66    g_assert(response);
  67    g_assert(qdict_haskey(response, "error"));
  68    QDECREF(response);
  69
  70    qtest_end();
  71    g_free(args);
  72}
  73
  74static void test_data_free(gpointer data)
  75{
  76    PCTestData *pc = data;
  77
  78    g_free(pc->machine);
  79    g_free(pc);
  80}
  81
  82static void add_pc_test_case(const char *mname)
  83{
  84    char *path;
  85    PCTestData *data;
  86
  87    if (!g_str_has_prefix(mname, "pc-")) {
  88        return;
  89    }
  90    data = g_new(PCTestData, 1);
  91    data->machine = g_strdup(mname);
  92    data->cpu_model = "Haswell"; /* 1.3+ theoretically */
  93    data->sockets = 1;
  94    data->cores = 3;
  95    data->threads = 2;
  96    data->maxcpus = data->sockets * data->cores * data->threads * 2;
  97    if (g_str_has_suffix(mname, "-1.4") ||
  98        (strcmp(mname, "pc-1.3") == 0) ||
  99        (strcmp(mname, "pc-1.2") == 0) ||
 100        (strcmp(mname, "pc-1.1") == 0) ||
 101        (strcmp(mname, "pc-1.0") == 0) ||
 102        (strcmp(mname, "pc-0.15") == 0) ||
 103        (strcmp(mname, "pc-0.14") == 0) ||
 104        (strcmp(mname, "pc-0.13") == 0) ||
 105        (strcmp(mname, "pc-0.12") == 0) ||
 106        (strcmp(mname, "pc-0.11") == 0) ||
 107        (strcmp(mname, "pc-0.10") == 0)) {
 108        path = g_strdup_printf("cpu/%s/init/%ux%ux%u&maxcpus=%u",
 109                               mname, data->sockets, data->cores,
 110                               data->threads, data->maxcpus);
 111        qtest_add_data_func_full(path, data, test_pc_without_cpu_add,
 112                                 test_data_free);
 113        g_free(path);
 114    } else {
 115        path = g_strdup_printf("cpu/%s/add/%ux%ux%u&maxcpus=%u",
 116                               mname, data->sockets, data->cores,
 117                               data->threads, data->maxcpus);
 118        qtest_add_data_func_full(path, data, test_pc_with_cpu_add,
 119                                 test_data_free);
 120        g_free(path);
 121    }
 122}
 123
 124int main(int argc, char **argv)
 125{
 126    const char *arch = qtest_get_arch();
 127
 128    g_test_init(&argc, &argv, NULL);
 129
 130    if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
 131        qtest_cb_for_every_machine(add_pc_test_case);
 132    }
 133
 134    return g_test_run();
 135}
 136