Patchwork [RFC,v1,2/4] qtest: basic test infrastructure and vl.c hooks

login
register
mail settings
Submitter Michael Roth
Date Feb. 4, 2011, 1:49 p.m.
Message ID <1296827392-1291-3-git-send-email-mdroth@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/81890/
State New
Headers show

Comments

Michael Roth - Feb. 4, 2011, 1:49 p.m.
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 qtest/qtest.c |   65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qtest/qtest.h |   37 ++++++++++++++++++++++++++++++++
 vl.c          |   24 +++++++++++++++++++++
 3 files changed, 126 insertions(+), 0 deletions(-)
 create mode 100644 qtest/qtest.c
 create mode 100644 qtest/qtest.h

Patch

diff --git a/qtest/qtest.c b/qtest/qtest.c
new file mode 100644
index 0000000..fa30bdc
--- /dev/null
+++ b/qtest/qtest.c
@@ -0,0 +1,65 @@ 
+#include "qtest.h"
+#include "qemu-thread.h"
+
+static QTAILQ_HEAD(, QTestModule) qtest_module_list =
+QTAILQ_HEAD_INITIALIZER(qtest_module_list);
+
+static const QTestModule *qtest_module_by_name(const char *test_name)
+{
+    const QTestModule *module;
+    QTAILQ_FOREACH(module, &qtest_module_list, next) {
+        if (strcmp(module->name, test_name) == 0) {
+            return module;
+        }
+    }
+
+    return NULL;
+}
+
+void qtest_list_modules(void)
+{
+    const QTestModule *module;
+    printf("Available test modules:\n");
+    QTAILQ_FOREACH(module, &qtest_module_list, next) {
+        printf("%s\n", module->name);
+    }
+}
+
+void qtest_register(QTestModule *module)
+{
+    QTAILQ_INSERT_TAIL(&qtest_module_list, module, next);
+}
+
+void qtest_init(const char *test_name)
+{
+    const QTestModule *module = qtest_module_by_name(test_name);
+
+    if (!module) {
+        fprintf(stderr, "unknown qtest module: %s\n", test_name);
+        exit(1);
+    }
+    module->init();
+}
+
+void qtest_cleanup(const char *test_name)
+{
+    const QTestModule *module = qtest_module_by_name(test_name);
+
+    if (!module) {
+        fprintf(stderr, "unknown qtest module: %s\n", test_name);
+        exit(1);
+    }
+    module->cleanup();
+}
+
+void qtest_start(const char *test_name, void *thread_args)
+{
+    const QTestModule *module = qtest_module_by_name(test_name);
+    QemuThread thread;
+
+    if (!module) {
+        fprintf(stderr, "unknown qtest module: %s\n", test_name);
+        exit(1);
+    }
+    qemu_thread_create(&thread, module->start, thread_args);
+}
diff --git a/qtest/qtest.h b/qtest/qtest.h
new file mode 100644
index 0000000..7e3daed
--- /dev/null
+++ b/qtest/qtest.h
@@ -0,0 +1,37 @@ 
+/*
+ * qtest - general interface definitions
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ *  Michael Roth      <mdroth@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+#ifndef QTEST_H
+#define QTEST_H
+
+#include "qemu-common.h"
+#include "qemu-queue.h"
+
+typedef void *(QTestStartFunc)(void *thread_args);
+typedef void (QTestCleanupFunc)(void);
+typedef void (QTestInitFunc)(void);
+
+typedef struct QTestModule {
+    const char *name;
+    QTestInitFunc *init;
+    QTestCleanupFunc *cleanup;
+    QTestStartFunc *start;
+    QTAILQ_ENTRY(QTestModule) next;
+} QTestModule;
+
+void qtest_register(QTestModule *module);
+void qtest_init(const char *test_name);
+void qtest_cleanup(const char *test_name);
+void qtest_start(const char *test_name, void *thread_args);
+void qtest_list_modules(void);
+
+#endif
diff --git a/vl.c b/vl.c
index 655617f..0b5b613 100644
--- a/vl.c
+++ b/vl.c
@@ -164,6 +164,9 @@  int main(int argc, char **argv)
 #include "arch_init.h"
 
 #include "ui/qemu-spice.h"
+#ifdef CONFIG_QTEST
+#include "qtest/qtest.h"
+#endif
 
 //#define DEBUG_NET
 //#define DEBUG_SLIRP
@@ -1930,6 +1933,9 @@  int main(int argc, char **argv, char **envp)
     int show_vnc_port = 0;
     int defconfig = 1;
 
+#ifdef CONFIG_QTEST
+    const char *qtest_module = NULL;
+#endif
 #ifdef CONFIG_SIMPLE_TRACE
     const char *trace_file = NULL;
 #endif
@@ -1943,6 +1949,9 @@  int main(int argc, char **argv, char **envp)
     QLIST_INIT (&vm_change_state_head);
     os_setup_early_signal_handling();
 
+#ifdef CONFIG_QTEST
+    module_call_init(MODULE_INIT_QTEST_REGISTRY);
+#endif
     module_call_init(MODULE_INIT_MACHINE);
     machine = find_default_machine();
     cpu_model = NULL;
@@ -2859,7 +2868,11 @@  int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
+#ifdef CONFIG_QTEST
+    if (!qtest_module && kvm_allowed) {
+#else
     if (kvm_allowed) {
+#endif
         int ret = kvm_init();
         if (ret < 0) {
             if (!kvm_available()) {
@@ -2986,6 +2999,14 @@  int main(int argc, char **argv, char **envp)
         exit(1);
 
     module_call_init(MODULE_INIT_DEVICE);
+#ifdef CONFIG_QTEST
+    if (qtest_module) {
+        module_call_init(MODULE_INIT_QTEST_REGISTRY);
+        qtest_init(qtest_module);
+        qtest_start(qtest_module, NULL);
+        goto out_machine_creation;
+    }
+#endif
 
     if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0) != 0)
         exit(0);
@@ -3101,6 +3122,9 @@  int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
+#ifdef CONFIG_QTEST
+out_machine_creation:
+#endif
     qdev_machine_creation_done();
 
     if (rom_load_all() != 0) {