xref: /qemu/tests/qtest/cpu-plug-test.c (revision 0f9668e0)
11e8a1faeSThomas Huth /*
21e8a1faeSThomas Huth  * QTest testcase for CPU plugging
31e8a1faeSThomas Huth  *
41e8a1faeSThomas Huth  * Copyright (c) 2015 SUSE Linux GmbH
51e8a1faeSThomas Huth  *
61e8a1faeSThomas Huth  * This work is licensed under the terms of the GNU GPL, version 2 or later.
71e8a1faeSThomas Huth  * See the COPYING file in the top-level directory.
81e8a1faeSThomas Huth  */
91e8a1faeSThomas Huth 
101e8a1faeSThomas Huth #include "qemu/osdep.h"
111e8a1faeSThomas Huth 
121e8a1faeSThomas Huth #include "libqtest-single.h"
131e8a1faeSThomas Huth #include "qapi/qmp/qdict.h"
141e8a1faeSThomas Huth #include "qapi/qmp/qlist.h"
151e8a1faeSThomas Huth 
161e8a1faeSThomas Huth struct PlugTestData {
171e8a1faeSThomas Huth     char *machine;
181e8a1faeSThomas Huth     const char *cpu_model;
191e8a1faeSThomas Huth     char *device_model;
201e8a1faeSThomas Huth     unsigned sockets;
211e8a1faeSThomas Huth     unsigned cores;
221e8a1faeSThomas Huth     unsigned threads;
231e8a1faeSThomas Huth     unsigned maxcpus;
241e8a1faeSThomas Huth };
251e8a1faeSThomas Huth typedef struct PlugTestData PlugTestData;
261e8a1faeSThomas Huth 
test_plug_with_device_add(gconstpointer data)271e8a1faeSThomas Huth static void test_plug_with_device_add(gconstpointer data)
281e8a1faeSThomas Huth {
291e8a1faeSThomas Huth     const PlugTestData *td = data;
301e8a1faeSThomas Huth     char *args;
311e8a1faeSThomas Huth     QTestState *qts;
321e8a1faeSThomas Huth     QDict *resp;
331e8a1faeSThomas Huth     QList *cpus;
341e8a1faeSThomas Huth     QObject *e;
351e8a1faeSThomas Huth     int hotplugged = 0;
361e8a1faeSThomas Huth 
371e8a1faeSThomas Huth     args = g_strdup_printf("-machine %s -cpu %s "
381e8a1faeSThomas Huth                            "-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u",
391e8a1faeSThomas Huth                            td->machine, td->cpu_model,
401e8a1faeSThomas Huth                            td->sockets, td->cores, td->threads, td->maxcpus);
411e8a1faeSThomas Huth     qts = qtest_init(args);
421e8a1faeSThomas Huth 
431e8a1faeSThomas Huth     resp = qtest_qmp(qts, "{ 'execute': 'query-hotpluggable-cpus'}");
441e8a1faeSThomas Huth     g_assert(qdict_haskey(resp, "return"));
451e8a1faeSThomas Huth     cpus = qdict_get_qlist(resp, "return");
461e8a1faeSThomas Huth     g_assert(cpus);
471e8a1faeSThomas Huth 
481e8a1faeSThomas Huth     while ((e = qlist_pop(cpus))) {
491e8a1faeSThomas Huth         const QDict *cpu, *props;
501e8a1faeSThomas Huth 
511e8a1faeSThomas Huth         cpu = qobject_to(QDict, e);
521e8a1faeSThomas Huth         if (qdict_haskey(cpu, "qom-path")) {
531e8a1faeSThomas Huth             qobject_unref(e);
541e8a1faeSThomas Huth             continue;
551e8a1faeSThomas Huth         }
561e8a1faeSThomas Huth 
571e8a1faeSThomas Huth         g_assert(qdict_haskey(cpu, "props"));
581e8a1faeSThomas Huth         props = qdict_get_qdict(cpu, "props");
591e8a1faeSThomas Huth 
601e8a1faeSThomas Huth         qtest_qmp_device_add_qdict(qts, td->device_model, props);
611e8a1faeSThomas Huth         hotplugged++;
621e8a1faeSThomas Huth         qobject_unref(e);
631e8a1faeSThomas Huth     }
641e8a1faeSThomas Huth 
651e8a1faeSThomas Huth     /* make sure that there were hotplugged CPUs */
661e8a1faeSThomas Huth     g_assert(hotplugged);
671e8a1faeSThomas Huth     qobject_unref(resp);
681e8a1faeSThomas Huth     qtest_quit(qts);
691e8a1faeSThomas Huth     g_free(args);
701e8a1faeSThomas Huth }
711e8a1faeSThomas Huth 
test_data_free(gpointer data)721e8a1faeSThomas Huth static void test_data_free(gpointer data)
731e8a1faeSThomas Huth {
741e8a1faeSThomas Huth     PlugTestData *pc = data;
751e8a1faeSThomas Huth 
761e8a1faeSThomas Huth     g_free(pc->machine);
771e8a1faeSThomas Huth     g_free(pc->device_model);
781e8a1faeSThomas Huth     g_free(pc);
791e8a1faeSThomas Huth }
801e8a1faeSThomas Huth 
add_pc_test_case(const char * mname)811e8a1faeSThomas Huth static void add_pc_test_case(const char *mname)
821e8a1faeSThomas Huth {
831e8a1faeSThomas Huth     char *path;
841e8a1faeSThomas Huth     PlugTestData *data;
851e8a1faeSThomas Huth 
861e8a1faeSThomas Huth     if (!g_str_has_prefix(mname, "pc-")) {
871e8a1faeSThomas Huth         return;
881e8a1faeSThomas Huth     }
891e8a1faeSThomas Huth     data = g_new(PlugTestData, 1);
901e8a1faeSThomas Huth     data->machine = g_strdup(mname);
911e8a1faeSThomas Huth     data->cpu_model = "Haswell"; /* 1.3+ theoretically */
921e8a1faeSThomas Huth     data->device_model = g_strdup_printf("%s-%s-cpu", data->cpu_model,
931e8a1faeSThomas Huth                                          qtest_get_arch());
941e8a1faeSThomas Huth     data->sockets = 1;
951e8a1faeSThomas Huth     data->cores = 3;
961e8a1faeSThomas Huth     data->threads = 2;
971e8a1faeSThomas Huth     data->maxcpus = data->sockets * data->cores * data->threads;
981e8a1faeSThomas Huth 
991e8a1faeSThomas Huth     path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u",
100*63e79833SIgor Mammedov                            mname, data->sockets, data->cores,
101*63e79833SIgor Mammedov                            data->threads, data->maxcpus);
102*63e79833SIgor Mammedov     qtest_add_data_func_full(path, data, test_plug_with_device_add,
1031e8a1faeSThomas Huth                              test_data_free);
1041e8a1faeSThomas Huth     g_free(path);
1051e8a1faeSThomas Huth }
1061e8a1faeSThomas Huth 
add_pseries_test_case(const char * mname)1071e8a1faeSThomas Huth static void add_pseries_test_case(const char *mname)
1081e8a1faeSThomas Huth {
1091e8a1faeSThomas Huth     char *path;
1101e8a1faeSThomas Huth     PlugTestData *data;
1111e8a1faeSThomas Huth 
1121e8a1faeSThomas Huth     if (!g_str_has_prefix(mname, "pseries-") ||
1131e8a1faeSThomas Huth         (g_str_has_prefix(mname, "pseries-2.") && atoi(&mname[10]) < 7)) {
1141e8a1faeSThomas Huth         return;
1151e8a1faeSThomas Huth     }
1161e8a1faeSThomas Huth     data = g_new(PlugTestData, 1);
1171e8a1faeSThomas Huth     data->machine = g_strdup(mname);
1181e8a1faeSThomas Huth     data->cpu_model = "power8_v2.0";
1191e8a1faeSThomas Huth     data->device_model = g_strdup("power8_v2.0-spapr-cpu-core");
1201e8a1faeSThomas Huth     data->sockets = 2;
1211e8a1faeSThomas Huth     data->cores = 3;
1221e8a1faeSThomas Huth     data->threads = 1;
1231e8a1faeSThomas Huth     data->maxcpus = data->sockets * data->cores * data->threads;
1241e8a1faeSThomas Huth 
1251e8a1faeSThomas Huth     path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u",
1261e8a1faeSThomas Huth                            mname, data->sockets, data->cores,
1271e8a1faeSThomas Huth                            data->threads, data->maxcpus);
1281e8a1faeSThomas Huth     qtest_add_data_func_full(path, data, test_plug_with_device_add,
1291e8a1faeSThomas Huth                              test_data_free);
1301e8a1faeSThomas Huth     g_free(path);
1311e8a1faeSThomas Huth }
1321e8a1faeSThomas Huth 
add_s390x_test_case(const char * mname)1331e8a1faeSThomas Huth static void add_s390x_test_case(const char *mname)
1341e8a1faeSThomas Huth {
1351e8a1faeSThomas Huth     char *path;
136*63e79833SIgor Mammedov     PlugTestData *data;
1371e8a1faeSThomas Huth 
1381e8a1faeSThomas Huth     if (!g_str_has_prefix(mname, "s390-ccw-virtio-")) {
1391e8a1faeSThomas Huth         return;
1401e8a1faeSThomas Huth     }
1411e8a1faeSThomas Huth 
1421e8a1faeSThomas Huth     data = g_new(PlugTestData, 1);
1431e8a1faeSThomas Huth     data->machine = g_strdup(mname);
1441e8a1faeSThomas Huth     data->cpu_model = "qemu";
1451e8a1faeSThomas Huth     data->device_model = g_strdup("qemu-s390x-cpu");
1461e8a1faeSThomas Huth     data->sockets = 1;
1471e8a1faeSThomas Huth     data->cores = 3;
1481e8a1faeSThomas Huth     data->threads = 1;
1491e8a1faeSThomas Huth     data->maxcpus = data->sockets * data->cores * data->threads;
1501e8a1faeSThomas Huth 
151*63e79833SIgor Mammedov     path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u",
1521e8a1faeSThomas Huth                            mname, data->sockets, data->cores,
1531e8a1faeSThomas Huth                            data->threads, data->maxcpus);
154*63e79833SIgor Mammedov     qtest_add_data_func_full(path, data, test_plug_with_device_add,
1551e8a1faeSThomas Huth                              test_data_free);
1561e8a1faeSThomas Huth     g_free(path);
1571e8a1faeSThomas Huth }
1581e8a1faeSThomas Huth 
main(int argc,char ** argv)1591e8a1faeSThomas Huth int main(int argc, char **argv)
1601e8a1faeSThomas Huth {
1611e8a1faeSThomas Huth     const char *arch = qtest_get_arch();
1621e8a1faeSThomas Huth 
1631e8a1faeSThomas Huth     g_test_init(&argc, &argv, NULL);
1641e8a1faeSThomas Huth 
1651e8a1faeSThomas Huth     if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
1661e8a1faeSThomas Huth         qtest_cb_for_every_machine(add_pc_test_case, g_test_quick());
1671e8a1faeSThomas Huth     } else if (g_str_equal(arch, "ppc64")) {
1681e8a1faeSThomas Huth         qtest_cb_for_every_machine(add_pseries_test_case, g_test_quick());
1691e8a1faeSThomas Huth     } else if (g_str_equal(arch, "s390x")) {
1701e8a1faeSThomas Huth         qtest_cb_for_every_machine(add_s390x_test_case, g_test_quick());
1711e8a1faeSThomas Huth     }
1721e8a1faeSThomas Huth 
1731e8a1faeSThomas Huth     return g_test_run();
1741e8a1faeSThomas Huth }
175