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_cases(void)
  83{
  84    QDict *response, *minfo;
  85    QList *list;
  86    const QListEntry *p;
  87    QObject *qobj;
  88    QString *qstr;
  89    const char *mname;
  90    char *path;
  91    PCTestData *data;
  92
  93    qtest_start("-machine none");
  94    response = qmp("{ 'execute': 'query-machines' }");
  95    g_assert(response);
  96    list = qdict_get_qlist(response, "return");
  97    g_assert(list);
  98
  99    for (p = qlist_first(list); p; p = qlist_next(p)) {
 100        minfo = qobject_to_qdict(qlist_entry_obj(p));
 101        g_assert(minfo);
 102        qobj = qdict_get(minfo, "name");
 103        g_assert(qobj);
 104        qstr = qobject_to_qstring(qobj);
 105        g_assert(qstr);
 106        mname = qstring_get_str(qstr);
 107        if (!g_str_has_prefix(mname, "pc-")) {
 108            continue;
 109        }
 110        data = g_malloc(sizeof(PCTestData));
 111        data->machine = g_strdup(mname);
 112        data->cpu_model = "Haswell"; /* 1.3+ theoretically */
 113        data->sockets = 1;
 114        data->cores = 3;
 115        data->threads = 2;
 116        data->maxcpus = data->sockets * data->cores * data->threads * 2;
 117        if (g_str_has_suffix(mname, "-1.4") ||
 118            (strcmp(mname, "pc-1.3") == 0) ||
 119            (strcmp(mname, "pc-1.2") == 0) ||
 120            (strcmp(mname, "pc-1.1") == 0) ||
 121            (strcmp(mname, "pc-1.0") == 0) ||
 122            (strcmp(mname, "pc-0.15") == 0) ||
 123            (strcmp(mname, "pc-0.14") == 0) ||
 124            (strcmp(mname, "pc-0.13") == 0) ||
 125            (strcmp(mname, "pc-0.12") == 0) ||
 126            (strcmp(mname, "pc-0.11") == 0) ||
 127            (strcmp(mname, "pc-0.10") == 0)) {
 128            path = g_strdup_printf("cpu/%s/init/%ux%ux%u&maxcpus=%u",
 129                                   mname, data->sockets, data->cores,
 130                                   data->threads, data->maxcpus);
 131            qtest_add_data_func_full(path, data, test_pc_without_cpu_add,
 132                                     test_data_free);
 133            g_free(path);
 134        } else {
 135            path = g_strdup_printf("cpu/%s/add/%ux%ux%u&maxcpus=%u",
 136                                   mname, data->sockets, data->cores,
 137                                   data->threads, data->maxcpus);
 138            qtest_add_data_func_full(path, data, test_pc_with_cpu_add,
 139                                     test_data_free);
 140            g_free(path);
 141        }
 142    }
 143    QDECREF(response);
 144    qtest_end();
 145}
 146
 147int main(int argc, char **argv)
 148{
 149    const char *arch = qtest_get_arch();
 150
 151    g_test_init(&argc, &argv, NULL);
 152
 153    if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
 154        add_pc_test_cases();
 155    }
 156
 157    return g_test_run();
 158}
 159