/*
 * QTest testcase for CPU plugging
 *
 * Copyright (c) 2015 SUSE Linux GmbH
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"

#include "qemu-common.h"
#include "libqtest-single.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qlist.h"

struct PlugTestData {
    char *machine;
    const char *cpu_model;
    char *device_model;
    unsigned sockets;
    unsigned cores;
    unsigned threads;
    unsigned maxcpus;
};
typedef struct PlugTestData PlugTestData;

static void test_plug_with_device_add(gconstpointer data)
{
    const PlugTestData *td = data;
    char *args;
    QTestState *qts;
    QDict *resp;
    QList *cpus;
    QObject *e;
    int hotplugged = 0;

    args = g_strdup_printf("-machine %s -cpu %s "
                           "-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u",
                           td->machine, td->cpu_model,
                           td->sockets, td->cores, td->threads, td->maxcpus);
    qts = qtest_init(args);

    resp = qtest_qmp(qts, "{ 'execute': 'query-hotpluggable-cpus'}");
    g_assert(qdict_haskey(resp, "return"));
    cpus = qdict_get_qlist(resp, "return");
    g_assert(cpus);

    while ((e = qlist_pop(cpus))) {
        const QDict *cpu, *props;

        cpu = qobject_to(QDict, e);
        if (qdict_haskey(cpu, "qom-path")) {
            qobject_unref(e);
            continue;
        }

        g_assert(qdict_haskey(cpu, "props"));
        props = qdict_get_qdict(cpu, "props");

        qtest_qmp_device_add_qdict(qts, td->device_model, props);
        hotplugged++;
        qobject_unref(e);
    }

    /* make sure that there were hotplugged CPUs */
    g_assert(hotplugged);
    qobject_unref(resp);
    qtest_quit(qts);
    g_free(args);
}

static void test_data_free(gpointer data)
{
    PlugTestData *pc = data;

    g_free(pc->machine);
    g_free(pc->device_model);
    g_free(pc);
}

static void add_pc_test_case(const char *mname)
{
    char *path;
    PlugTestData *data;

    if (!g_str_has_prefix(mname, "pc-")) {
        return;
    }
    data = g_new(PlugTestData, 1);
    data->machine = g_strdup(mname);
    data->cpu_model = "Haswell"; /* 1.3+ theoretically */
    data->device_model = g_strdup_printf("%s-%s-cpu", data->cpu_model,
                                         qtest_get_arch());
    data->sockets = 1;
    data->cores = 3;
    data->threads = 2;
    data->maxcpus = data->sockets * data->cores * data->threads;

    path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u",
                           mname, data->sockets, data->cores,
                           data->threads, data->maxcpus);
    qtest_add_data_func_full(path, data, test_plug_with_device_add,
                             test_data_free);
    g_free(path);
}

static void add_pseries_test_case(const char *mname)
{
    char *path;
    PlugTestData *data;

    if (!g_str_has_prefix(mname, "pseries-") ||
        (g_str_has_prefix(mname, "pseries-2.") && atoi(&mname[10]) < 7)) {
        return;
    }
    data = g_new(PlugTestData, 1);
    data->machine = g_strdup(mname);
    data->cpu_model = "power8_v2.0";
    data->device_model = g_strdup("power8_v2.0-spapr-cpu-core");
    data->sockets = 2;
    data->cores = 3;
    data->threads = 1;
    data->maxcpus = data->sockets * data->cores * data->threads;

    path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u",
                           mname, data->sockets, data->cores,
                           data->threads, data->maxcpus);
    qtest_add_data_func_full(path, data, test_plug_with_device_add,
                             test_data_free);
    g_free(path);
}

static void add_s390x_test_case(const char *mname)
{
    char *path;
    PlugTestData *data;

    if (!g_str_has_prefix(mname, "s390-ccw-virtio-")) {
        return;
    }

    data = g_new(PlugTestData, 1);
    data->machine = g_strdup(mname);
    data->cpu_model = "qemu";
    data->device_model = g_strdup("qemu-s390x-cpu");
    data->sockets = 1;
    data->cores = 3;
    data->threads = 1;
    data->maxcpus = data->sockets * data->cores * data->threads;

    path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u",
                           mname, data->sockets, data->cores,
                           data->threads, data->maxcpus);
    qtest_add_data_func_full(path, data, test_plug_with_device_add,
                             test_data_free);
    g_free(path);
}

int main(int argc, char **argv)
{
    const char *arch = qtest_get_arch();

    g_test_init(&argc, &argv, NULL);

    if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
        qtest_cb_for_every_machine(add_pc_test_case, g_test_quick());
    } else if (g_str_equal(arch, "ppc64")) {
        qtest_cb_for_every_machine(add_pseries_test_case, g_test_quick());
    } else if (g_str_equal(arch, "s390x")) {
        qtest_cb_for_every_machine(add_s390x_test_case, g_test_quick());
    }

    return g_test_run();
}
