Commit a56f3cdb authored by Markus Armbruster's avatar Markus Armbruster
Browse files

fuzz: Simplify how we compute available machines and types



apply_to_qlist(), apply_to_node() work with QObjects.  This is
designed for use by tests/qtest/qos-test.c, which gets the data in
that form via QMP.  Goes back to commit fc281c80 "tests: qgraph API
for the qtest driver framework".

Commit 275ab39d "fuzz: add support for qos-assisted fuzz targets"
added another user: qtest/fuzz/qos_fuzz.c.  To get the data as
QObjects, it uses qmp_marshal_query_machines() and
qmp_marshal_qom_list_types().

All this code is rather cumbersome.  Switch to working with generated
QAPI types instead:

* Replace apply_to_qlist() & friends by machines_apply_to_node() and
  types_apply_to_node().

* Have qos_fuzz.c use qmp_query_machines() and qmp_qom_list_types()
  instead.

* Have qos_test.c convert from QObject to the QAPI types.

Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
Message-Id: <20200424071142.3525-3-armbru@redhat.com>
Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: default avatarAlexander Bulekov <alxndr@bu.edu>
parent 14b6ce68
Loading
Loading
Loading
Loading
+9 −25
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@

#include "qapi/qapi-commands-machine.h"
#include "qapi/qapi-commands-qom.h"
#include "qapi/qmp/qlist.h"


void *fuzz_qos_obj;
@@ -45,34 +44,19 @@ QGuestAllocator *fuzz_qos_alloc;
static const char *fuzz_target_name;
static char **fuzz_path_vec;

/*
 * Replaced the qmp commands with direct qmp_marshal calls.
 * Probably there is a better way to do this
 */
static void qos_set_machines_devices_available(void)
{
    QDict *req = qdict_new();
    QObject *response;
    QDict *args = qdict_new();
    QList *lst;

    qmp_marshal_query_machines(NULL, &response, &error_abort);
    lst = qobject_to(QList, response);
    apply_to_qlist(lst, true);

    qobject_unref(response);

    MachineInfoList *mach_info;
    ObjectTypeInfoList *type_info;

    qdict_put_str(req, "execute", "qom-list-types");
    qdict_put_str(args, "implements", "device");
    qdict_put_bool(args, "abstract", true);
    qdict_put_obj(req, "arguments", (QObject *) args);
    mach_info = qmp_query_machines(&error_abort);
    machines_apply_to_node(mach_info);
    qapi_free_MachineInfoList(mach_info);

    qmp_marshal_qom_list_types(args, &response, &error_abort);
    lst = qobject_to(QList, response);
    apply_to_qlist(lst, false);
    qobject_unref(response);
    qobject_unref(req);
    type_info = qmp_qom_list_types(true, "device", true, true,
                                   &error_abort);
    types_apply_to_node(type_info);
    qapi_free_ObjectTypeInfoList(type_info);
}

static char **current_path;
+22 −44
Original line number Diff line number Diff line
@@ -29,62 +29,40 @@
#include "libqos/qgraph_internal.h"
#include "libqos/qos_external.h"

static void machine_apply_to_node(const char *name)
{
    char *machine_name = g_strconcat(qtest_get_arch(), "/", name, NULL);

    qos_graph_node_set_availability(machine_name, true);
    g_free(machine_name);
}

void apply_to_node(const char *name, bool is_machine, bool is_abstract)
void machines_apply_to_node(MachineInfoList *mach_info)
{
    char *machine_name = NULL;
    if (is_machine) {
        const char *arch = qtest_get_arch();
        machine_name = g_strconcat(arch, "/", name, NULL);
        name = machine_name;
    MachineInfoList *tail;

    for (tail = mach_info; tail; tail = tail->next) {
        machine_apply_to_node(tail->value->name);
        if (tail->value->alias) {
            machine_apply_to_node(tail->value->alias);
        }
    }
}

static void type_apply_to_node(const char *name, bool is_abstract)
{
    qos_graph_node_set_availability(name, true);
    if (is_abstract) {
        qos_delete_cmd_line(name);
    }
    g_free(machine_name);
}

/**
 * apply_to_qlist(): using QMP queries QEMU for a list of
 * machines and devices available, and sets the respective node
 * as true. If a node is found, also all its produced and contained
 * child are marked available.
 *
 * See qos_graph_node_set_availability() for more info
 */
void apply_to_qlist(QList *list, bool is_machine)
void types_apply_to_node(ObjectTypeInfoList *type_info)
{
    const QListEntry *p;
    const char *name;
    bool abstract;
    QDict *minfo;
    QObject *qobj;
    QString *qstr;
    QBool *qbool;

    for (p = qlist_first(list); p; p = qlist_next(p)) {
        minfo = qobject_to(QDict, qlist_entry_obj(p));
        qobj = qdict_get(minfo, "name");
        qstr = qobject_to(QString, qobj);
        name = qstring_get_str(qstr);

        qobj = qdict_get(minfo, "abstract");
        if (qobj) {
            qbool = qobject_to(QBool, qobj);
            abstract = qbool_get_bool(qbool);
        } else {
            abstract = false;
        }
    ObjectTypeInfoList *tail;

        apply_to_node(name, is_machine, abstract);
        qobj = qdict_get(minfo, "alias");
        if (qobj) {
            qstr = qobject_to(QString, qobj);
            name = qstring_get_str(qstr);
            apply_to_node(name, is_machine, abstract);
        }
    for (tail = type_info; tail; tail = tail->next) {
        type_apply_to_node(tail->value->name, tail->value->abstract);
    }
}

+6 −2
Original line number Diff line number Diff line
@@ -20,8 +20,12 @@
#define QOS_EXTERNAL_H
#include "libqos/qgraph.h"

void apply_to_node(const char *name, bool is_machine, bool is_abstract);
void apply_to_qlist(QList *list, bool is_machine);
#include "libqos/malloc.h"
#include "qapi/qapi-types-machine.h"
#include "qapi/qapi-types-qom.h"

void machines_apply_to_node(MachineInfoList *mach_info);
void types_apply_to_node(ObjectTypeInfoList *type_info);
QGuestAllocator *get_machine_allocator(QOSGraphObject *obj);
void *allocate_objects(QTestState *qts, char **path, QGuestAllocator **p_alloc);

+20 −9
Original line number Diff line number Diff line
@@ -19,11 +19,12 @@
#include "qemu/osdep.h"
#include <getopt.h>
#include "libqtest-single.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qbool.h"
#include "qapi/qmp/qstring.h"
#include "qemu/module.h"
#include "qapi/qmp/qlist.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/qapi-visit-machine.h"
#include "qapi/qapi-visit-qom.h"
#include "libqos/malloc.h"
#include "libqos/qgraph.h"
#include "libqos/qgraph_internal.h"
@@ -51,13 +52,20 @@ static void qos_set_machines_devices_available(void)
{
    QDict *response;
    QDict *args = qdict_new();
    QList *list;
    QObject *ret;
    Visitor *v;
    MachineInfoList *mach_info;
    ObjectTypeInfoList *type_info;

    qtest_start("-machine none");
    response = qmp("{ 'execute': 'query-machines' }");
    list = qdict_get_qlist(response, "return");
    ret = qdict_get(response, "return");

    apply_to_qlist(list, true);
    v = qobject_input_visitor_new(ret);
    visit_type_MachineInfoList(v, NULL, &mach_info, &error_abort);
    visit_free(v);
    machines_apply_to_node(mach_info);
    qapi_free_MachineInfoList(mach_info);

    qobject_unref(response);

@@ -66,10 +74,13 @@ static void qos_set_machines_devices_available(void)

    response = qmp("{'execute': 'qom-list-types',"
                   " 'arguments': %p }", args);
    g_assert(qdict_haskey(response, "return"));
    list = qdict_get_qlist(response, "return");
    ret = qdict_get(response, "return");

    apply_to_qlist(list, false);
    v = qobject_input_visitor_new(ret);
    visit_type_ObjectTypeInfoList(v, NULL, &type_info, &error_abort);
    visit_free(v);
    types_apply_to_node(type_info);
    qapi_free_ObjectTypeInfoList(type_info);

    qtest_end();
    qobject_unref(response);