aboutsummaryrefslogtreecommitdiff
path: root/tests/qtest/libqos
diff options
context:
space:
mode:
Diffstat (limited to 'tests/qtest/libqos')
-rw-r--r--tests/qtest/libqos/i2c.c10
-rw-r--r--tests/qtest/libqos/i2c.h4
-rw-r--r--tests/qtest/libqos/qos_external.c168
-rw-r--r--tests/qtest/libqos/qos_external.h28
4 files changed, 203 insertions, 7 deletions
diff --git a/tests/qtest/libqos/i2c.c b/tests/qtest/libqos/i2c.c
index 156114e..38f800d 100644
--- a/tests/qtest/libqos/i2c.c
+++ b/tests/qtest/libqos/i2c.c
@@ -10,12 +10,12 @@
#include "libqos/i2c.h"
#include "libqtest.h"
-void i2c_send(QI2CDevice *i2cdev, const uint8_t *buf, uint16_t len)
+void qi2c_send(QI2CDevice *i2cdev, const uint8_t *buf, uint16_t len)
{
i2cdev->bus->send(i2cdev->bus, i2cdev->addr, buf, len);
}
-void i2c_recv(QI2CDevice *i2cdev, uint8_t *buf, uint16_t len)
+void qi2c_recv(QI2CDevice *i2cdev, uint8_t *buf, uint16_t len)
{
i2cdev->bus->recv(i2cdev->bus, i2cdev->addr, buf, len);
}
@@ -23,8 +23,8 @@ void i2c_recv(QI2CDevice *i2cdev, uint8_t *buf, uint16_t len)
void i2c_read_block(QI2CDevice *i2cdev, uint8_t reg,
uint8_t *buf, uint16_t len)
{
- i2c_send(i2cdev, &reg, 1);
- i2c_recv(i2cdev, buf, len);
+ qi2c_send(i2cdev, &reg, 1);
+ qi2c_recv(i2cdev, buf, len);
}
void i2c_write_block(QI2CDevice *i2cdev, uint8_t reg,
@@ -33,7 +33,7 @@ void i2c_write_block(QI2CDevice *i2cdev, uint8_t reg,
uint8_t *cmd = g_malloc(len + 1);
cmd[0] = reg;
memcpy(&cmd[1], buf, len);
- i2c_send(i2cdev, cmd, len + 1);
+ qi2c_send(i2cdev, cmd, len + 1);
g_free(cmd);
}
diff --git a/tests/qtest/libqos/i2c.h b/tests/qtest/libqos/i2c.h
index 945b65b..c65f087 100644
--- a/tests/qtest/libqos/i2c.h
+++ b/tests/qtest/libqos/i2c.h
@@ -47,8 +47,8 @@ struct QI2CDevice {
void *i2c_device_create(void *i2c_bus, QGuestAllocator *alloc, void *addr);
void add_qi2c_address(QOSGraphEdgeOptions *opts, QI2CAddress *addr);
-void i2c_send(QI2CDevice *dev, const uint8_t *buf, uint16_t len);
-void i2c_recv(QI2CDevice *dev, uint8_t *buf, uint16_t len);
+void qi2c_send(QI2CDevice *dev, const uint8_t *buf, uint16_t len);
+void qi2c_recv(QI2CDevice *dev, uint8_t *buf, uint16_t len);
void i2c_read_block(QI2CDevice *dev, uint8_t reg,
uint8_t *buf, uint16_t len);
diff --git a/tests/qtest/libqos/qos_external.c b/tests/qtest/libqos/qos_external.c
new file mode 100644
index 0000000..398556d
--- /dev/null
+++ b/tests/qtest/libqos/qos_external.c
@@ -0,0 +1,168 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>
+ */
+
+#include "qemu/osdep.h"
+#include <getopt.h>
+#include "libqtest.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 "libqos/malloc.h"
+#include "libqos/qgraph.h"
+#include "libqos/qgraph_internal.h"
+#include "libqos/qos_external.h"
+
+
+
+void apply_to_node(const char *name, bool is_machine, bool is_abstract)
+{
+ char *machine_name = NULL;
+ if (is_machine) {
+ const char *arch = qtest_get_arch();
+ machine_name = g_strconcat(arch, "/", name, NULL);
+ name = machine_name;
+ }
+ 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)
+{
+ 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;
+ }
+
+ 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);
+ }
+ }
+}
+
+QGuestAllocator *get_machine_allocator(QOSGraphObject *obj)
+{
+ return obj->get_driver(obj, "memory");
+}
+
+/**
+ * allocate_objects(): given an array of nodes @arg,
+ * walks the path invoking all constructors and
+ * passing the corresponding parameter in order to
+ * continue the objects allocation.
+ * Once the test is reached, return the object it consumes.
+ *
+ * Since the machine and QEDGE_CONSUMED_BY nodes allocate
+ * memory in the constructor, g_test_queue_destroy is used so
+ * that after execution they can be safely free'd. (The test's
+ * ->before callback is also welcome to use g_test_queue_destroy).
+ *
+ * Note: as specified in walk_path() too, @arg is an array of
+ * char *, where arg[0] is a pointer to the command line
+ * string that will be used to properly start QEMU when executing
+ * the test, and the remaining elements represent the actual objects
+ * that will be allocated.
+ */
+void *allocate_objects(QTestState *qts, char **path, QGuestAllocator **p_alloc)
+{
+ int current = 0;
+ QGuestAllocator *alloc;
+ QOSGraphObject *parent = NULL;
+ QOSGraphEdge *edge;
+ QOSGraphNode *node;
+ void *edge_arg;
+ void *obj;
+
+ node = qos_graph_get_node(path[current]);
+ g_assert(node->type == QNODE_MACHINE);
+
+ obj = qos_machine_new(node, qts);
+ qos_object_queue_destroy(obj);
+
+ alloc = get_machine_allocator(obj);
+ if (p_alloc) {
+ *p_alloc = alloc;
+ }
+
+ for (;;) {
+ if (node->type != QNODE_INTERFACE) {
+ qos_object_start_hw(obj);
+ parent = obj;
+ }
+
+ /* follow edge and get object for next node constructor */
+ current++;
+ edge = qos_graph_get_edge(path[current - 1], path[current]);
+ node = qos_graph_get_node(path[current]);
+
+ if (node->type == QNODE_TEST) {
+ g_assert(qos_graph_edge_get_type(edge) == QEDGE_CONSUMED_BY);
+ return obj;
+ }
+
+ switch (qos_graph_edge_get_type(edge)) {
+ case QEDGE_PRODUCES:
+ obj = parent->get_driver(parent, path[current]);
+ break;
+
+ case QEDGE_CONSUMED_BY:
+ edge_arg = qos_graph_edge_get_arg(edge);
+ obj = qos_driver_new(node, obj, alloc, edge_arg);
+ qos_object_queue_destroy(obj);
+ break;
+
+ case QEDGE_CONTAINS:
+ obj = parent->get_device(parent, path[current]);
+ break;
+ }
+ }
+}
+
diff --git a/tests/qtest/libqos/qos_external.h b/tests/qtest/libqos/qos_external.h
new file mode 100644
index 0000000..7b44930
--- /dev/null
+++ b/tests/qtest/libqos/qos_external.h
@@ -0,0 +1,28 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>
+ */
+
+#ifndef QOS_EXTERNAL_H
+#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);
+QGuestAllocator *get_machine_allocator(QOSGraphObject *obj);
+void *allocate_objects(QTestState *qts, char **path, QGuestAllocator **p_alloc);
+
+#endif