mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:10 +00:00
qtest: add "qom-tests" command
Add a new "qom-tests" to exercise basic object lifecycle. Instantiate all non-abstract objects, get and set properties and unref. This should quickly find leaks and other related issues that are eventually triggerable at run-time with QMP qom commands. Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
@@ -31,6 +31,8 @@
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/target-info.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
#include "qom/qom-qobject.h"
|
||||
#include "qobject/qobject.h"
|
||||
|
||||
#define MAX_IRQ 256
|
||||
|
||||
@@ -754,6 +756,50 @@ static void qtest_process_command(CharFrontend *chr, gchar **words)
|
||||
new_ns = qemu_clock_advance_virtual_time(ns);
|
||||
qtest_sendf(chr, "%s %"PRIi64"\n",
|
||||
new_ns == ns ? "OK" : "FAIL", new_ns);
|
||||
} else if (strcmp(words[0], "qom-tests") == 0) {
|
||||
GSList *list, *l;
|
||||
|
||||
list = object_class_get_list(NULL, false);
|
||||
for (l = list; l; l = l->next) {
|
||||
ObjectClass *klass = l->data;
|
||||
const char *type_name = object_class_get_name(klass);
|
||||
Object *obj;
|
||||
ObjectPropertyIterator iter;
|
||||
ObjectProperty *prop;
|
||||
|
||||
obj = object_new_with_class(klass);
|
||||
object_property_iter_init(&iter, obj);
|
||||
while ((prop = object_property_iter_next(&iter))) {
|
||||
QObject *value;
|
||||
Error *local_err = NULL;
|
||||
|
||||
value = object_property_get_qobject(obj, prop->name,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
error_report("qom-tests: %s.%s: get failed: %s",
|
||||
type_name, prop->name,
|
||||
error_get_pretty(local_err));
|
||||
error_free(local_err);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prop->set) {
|
||||
if (!object_property_set_qobject(obj, prop->name, value,
|
||||
&local_err)) {
|
||||
error_report("qom-tests: %s.%s: set failed: %s",
|
||||
type_name, prop->name,
|
||||
error_get_pretty(local_err));
|
||||
error_free(local_err);
|
||||
}
|
||||
}
|
||||
|
||||
qobject_unref(value);
|
||||
}
|
||||
|
||||
object_unref(obj);
|
||||
}
|
||||
g_slist_free(list);
|
||||
qtest_send(chr, "OK\n");
|
||||
} else if (process_command_cb && process_command_cb(chr, words)) {
|
||||
/* Command got consumed by the callback handler */
|
||||
} else {
|
||||
|
||||
@@ -1137,6 +1137,12 @@ void qtest_module_load(QTestState *s, const char *prefix, const char *libname)
|
||||
qtest_rsp(s);
|
||||
}
|
||||
|
||||
void qtest_qom_tests(QTestState *s)
|
||||
{
|
||||
qtest_sendf(s, "qom-tests\n");
|
||||
qtest_rsp(s);
|
||||
}
|
||||
|
||||
static int64_t qtest_clock_rsp(QTestState *s)
|
||||
{
|
||||
gchar **words;
|
||||
|
||||
@@ -426,6 +426,14 @@ char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap)
|
||||
|
||||
void qtest_module_load(QTestState *s, const char *prefix, const char *libname);
|
||||
|
||||
/**
|
||||
* qtest_qom_tests:
|
||||
* @s: #QTestState instance to operate on.
|
||||
*
|
||||
* Run QOM property get/set round-trip tests on all non-abstract types.
|
||||
*/
|
||||
void qtest_qom_tests(QTestState *s);
|
||||
|
||||
/**
|
||||
* qtest_get_irq:
|
||||
* @s: #QTestState instance to operate on.
|
||||
|
||||
@@ -227,6 +227,17 @@ static void add_machine_test_case(const char *mname)
|
||||
g_free(path);
|
||||
}
|
||||
|
||||
static void test_qom_qtests(void)
|
||||
{
|
||||
QTestState *qts;
|
||||
|
||||
qts = qtest_initf("-machine none");
|
||||
|
||||
qtest_qom_tests(qts);
|
||||
|
||||
qtest_quit(qts);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *v_env = getenv("V");
|
||||
@@ -238,6 +249,7 @@ int main(int argc, char **argv)
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
qtest_cb_for_every_machine(add_machine_test_case, g_test_quick());
|
||||
qtest_add_func("qom/qom-qtests", test_qom_qtests);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user