[libvirt] [PATCH v2 0/5] qemumonitorjsontest: Introduce some tests

v2 to some patches that weren't ACKed yet. Michal Privoznik (5): qemuMonitorTestFree: Join worker thread qemumonitorjsontest: Extend the test for yet another monitor commands qemumonitorjsontest: Test qemuMonitorJSONGetCPUInfo qemumonitorjsontest: Test qemuMonitorJSONGetVirtType qemumonitorjsontest: Test qemuMonitorJSONSendKey tests/qemumonitorjsontest.c | 253 +++++++++++++++++++++++++++++++++++++++++++ tests/qemumonitortestutils.c | 5 +- 2 files changed, 256 insertions(+), 2 deletions(-) -- 1.8.1.5

Join the worker thread no matter if it is running or zombie already. With current implementation the thread is joined iff @running is true. However, when worker executes the last line, @running is set to false. Hence qemuMonitorTestFree() won't join it (and free resources) even though we can clearly see worker has run (nobody else sets @running = false). Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemumonitortestutils.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index cd43c7b..2aefabc 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -51,6 +51,7 @@ struct _qemuMonitorTest { bool json; bool quit; bool running; + bool started; char *incoming; size_t incomingLength; @@ -354,7 +355,7 @@ qemuMonitorTestFree(qemuMonitorTestPtr test) virObjectUnref(test->vm); - if (test->running) + if (test->started) virThreadJoin(&test->thread); if (timer != -1) @@ -846,7 +847,7 @@ qemuMonitorCommonTestInit(qemuMonitorTestPtr test) virMutexUnlock(&test->lock); goto error; } - test->running = true; + test->started = test->running = true; virMutexUnlock(&test->lock); return 0; -- 1.8.1.5

On Thu, Oct 03, 2013 at 12:49:33PM +0200, Michal Privoznik wrote:
Join the worker thread no matter if it is running or zombie already. With current implementation the thread is joined iff @running is true. However, when worker executes the last line, @running is set to false. Hence qemuMonitorTestFree() won't join it (and free resources) even though we can clearly see worker has run (nobody else sets @running = false).
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemumonitortestutils.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tests/qemumonitortestutils.c b/tests/qemumonitortestutils.c index cd43c7b..2aefabc 100644 --- a/tests/qemumonitortestutils.c +++ b/tests/qemumonitortestutils.c @@ -51,6 +51,7 @@ struct _qemuMonitorTest { bool json; bool quit; bool running; + bool started;
char *incoming; size_t incomingLength; @@ -354,7 +355,7 @@ qemuMonitorTestFree(qemuMonitorTestPtr test)
virObjectUnref(test->vm);
- if (test->running) + if (test->started) virThreadJoin(&test->thread);
if (timer != -1) @@ -846,7 +847,7 @@ qemuMonitorCommonTestInit(qemuMonitorTestPtr test) virMutexUnlock(&test->lock); goto error; } - test->running = true; + test->started = test->running = true; virMutexUnlock(&test->lock);
return 0;
ACK Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

So far, we're unit testing some basic functions and some (so called) simple functions (e.g. "qmp_capabilities", "system_powerdown"). However, there are more functions which expect simple "{'return': {}}" reply, but takes more args to construct the command (for instance "set_link"). This patch aims on such functions. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemumonitorjsontest.c | 97 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 026beee..52b1a5b 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1108,6 +1108,69 @@ cleanup: return ret; } +#define GEN_TEST_FUNC(funcName, ...) \ +static int \ +testQemuMonitorJSON ## funcName(const void *opaque) \ +{ \ + const testQemuMonitorJSONSimpleFuncDataPtr data = \ + (const testQemuMonitorJSONSimpleFuncDataPtr) opaque; \ + virDomainXMLOptionPtr xmlopt = data->xmlopt; \ + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); \ + const char *reply = data->reply; \ + int ret = -1; \ + \ + if (!test) \ + return -1; \ + \ + if (!reply) \ + reply = "{\"return\":{}}"; \ + \ + if (qemuMonitorTestAddItem(test, data->cmd, reply) < 0) \ + goto cleanup; \ + \ + if (funcName(qemuMonitorTestGetMonitor(test), __VA_ARGS__) < 0) \ + goto cleanup; \ + \ + ret = 0; \ +cleanup: \ + qemuMonitorTestFree(test); \ + return ret; \ +} + +GEN_TEST_FUNC(qemuMonitorJSONSetLink, "vnet0", VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) +GEN_TEST_FUNC(qemuMonitorJSONBlockResize, "vda", 123456) +GEN_TEST_FUNC(qemuMonitorJSONSetVNCPassword, "secret_password") +GEN_TEST_FUNC(qemuMonitorJSONSetPassword, "spice", "secret_password", "disconnect") +GEN_TEST_FUNC(qemuMonitorJSONExpirePassword, "spice", "123456") +GEN_TEST_FUNC(qemuMonitorJSONSetBalloon, 1024) +GEN_TEST_FUNC(qemuMonitorJSONSetCPU, 1, true) +GEN_TEST_FUNC(qemuMonitorJSONEjectMedia, "hdc", true) +GEN_TEST_FUNC(qemuMonitorJSONChangeMedia, "hdc", "/foo/bar", NULL) +GEN_TEST_FUNC(qemuMonitorJSONSaveVirtualMemory, 0, 1024, "/foo/bar") +GEN_TEST_FUNC(qemuMonitorJSONSavePhysicalMemory, 0, 1024, "/foo/bar") +GEN_TEST_FUNC(qemuMonitorJSONSetMigrationSpeed, 1024) +GEN_TEST_FUNC(qemuMonitorJSONSetMigrationDowntime, 1) +GEN_TEST_FUNC(qemuMonitorJSONMigrate, QEMU_MONITOR_MIGRATE_BACKGROUND | + QEMU_MONITOR_MIGRATE_NON_SHARED_DISK | + QEMU_MONITOR_MIGRATE_NON_SHARED_INC, "tcp:localhost:12345") +GEN_TEST_FUNC(qemuMonitorJSONDump, "dummy_protocol") +GEN_TEST_FUNC(qemuMonitorJSONGraphicsRelocate, VIR_DOMAIN_GRAPHICS_TYPE_SPICE, + "localhost", 12345, 12346, NULL) +GEN_TEST_FUNC(qemuMonitorJSONAddNetdev, "some_dummy_netdevstr") +GEN_TEST_FUNC(qemuMonitorJSONRemoveNetdev, "net0") +GEN_TEST_FUNC(qemuMonitorJSONDelDevice, "ide0") +GEN_TEST_FUNC(qemuMonitorJSONAddDevice, "some_dummy_devicestr") +GEN_TEST_FUNC(qemuMonitorJSONSetDrivePassphrase, "vda", "secret_passhprase") +GEN_TEST_FUNC(qemuMonitorJSONDriveMirror, "vdb", "/foo/bar", NULL, 1024, + VIR_DOMAIN_BLOCK_REBASE_SHALLOW | VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT) +GEN_TEST_FUNC(qemuMonitorJSONBlockCommit, "vdb", "/foo/bar1", "/foo/bar2", 1024) +GEN_TEST_FUNC(qemuMonitorJSONDrivePivot, "vdb", NULL, NULL) +GEN_TEST_FUNC(qemuMonitorJSONScreendump, "/foo/bar") +GEN_TEST_FUNC(qemuMonitorJSONOpenGraphics, "spice", "spicefd", false) +GEN_TEST_FUNC(qemuMonitorJSONNBDServerStart, "localhost", 12345) +GEN_TEST_FUNC(qemuMonitorJSONNBDServerAdd, "vda", true) +GEN_TEST_FUNC(qemuMonitorJSONDetachCharDev, "serial1") + static int testQemuMonitorJSONqemuMonitorJSONGetBalloonInfo(const void *data) { @@ -1770,6 +1833,11 @@ mymain(void) if (virtTestRun(# FNC, 1, testQemuMonitorJSONSimpleFunc, &simpleFunc) < 0) \ ret = -1 +#define DO_TEST_GEN(name, ...) \ + simpleFunc = (testQemuMonitorJSONSimpleFuncData) {.xmlopt = xmlopt, __VA_ARGS__ }; \ + if (virtTestRun(# name, 1, testQemuMonitorJSON ## name, &simpleFunc) < 0) \ + ret = -1 + DO_TEST(GetStatus); DO_TEST(GetVersion); DO_TEST(GetMachines); @@ -1791,6 +1859,35 @@ mymain(void) DO_TEST_SIMPLE("inject-nmi", qemuMonitorJSONInjectNMI); DO_TEST_SIMPLE("system_wakeup", qemuMonitorJSONSystemWakeup); DO_TEST_SIMPLE("nbd-server-stop", qemuMonitorJSONNBDServerStop); + DO_TEST_GEN(qemuMonitorJSONSetLink); + DO_TEST_GEN(qemuMonitorJSONBlockResize); + DO_TEST_GEN(qemuMonitorJSONSetVNCPassword); + DO_TEST_GEN(qemuMonitorJSONSetPassword); + DO_TEST_GEN(qemuMonitorJSONExpirePassword); + DO_TEST_GEN(qemuMonitorJSONSetBalloon); + DO_TEST_GEN(qemuMonitorJSONSetCPU); + DO_TEST_GEN(qemuMonitorJSONEjectMedia); + DO_TEST_GEN(qemuMonitorJSONChangeMedia); + DO_TEST_GEN(qemuMonitorJSONSaveVirtualMemory); + DO_TEST_GEN(qemuMonitorJSONSavePhysicalMemory); + DO_TEST_GEN(qemuMonitorJSONSetMigrationSpeed); + DO_TEST_GEN(qemuMonitorJSONSetMigrationDowntime); + DO_TEST_GEN(qemuMonitorJSONMigrate); + DO_TEST_GEN(qemuMonitorJSONDump); + DO_TEST_GEN(qemuMonitorJSONGraphicsRelocate); + DO_TEST_GEN(qemuMonitorJSONAddNetdev); + DO_TEST_GEN(qemuMonitorJSONRemoveNetdev); + DO_TEST_GEN(qemuMonitorJSONDelDevice); + DO_TEST_GEN(qemuMonitorJSONAddDevice); + DO_TEST_GEN(qemuMonitorJSONSetDrivePassphrase); + DO_TEST_GEN(qemuMonitorJSONDriveMirror); + DO_TEST_GEN(qemuMonitorJSONBlockCommit); + DO_TEST_GEN(qemuMonitorJSONDrivePivot); + DO_TEST_GEN(qemuMonitorJSONScreendump); + DO_TEST_GEN(qemuMonitorJSONOpenGraphics); + DO_TEST_GEN(qemuMonitorJSONNBDServerStart); + DO_TEST_GEN(qemuMonitorJSONNBDServerAdd); + DO_TEST_GEN(qemuMonitorJSONDetachCharDev); DO_TEST(qemuMonitorJSONGetBalloonInfo); DO_TEST(qemuMonitorJSONGetBlockInfo); DO_TEST(qemuMonitorJSONGetBlockStatsInfo); -- 1.8.1.5

Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemumonitorjsontest.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 52b1a5b..15541dd 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1171,6 +1171,82 @@ GEN_TEST_FUNC(qemuMonitorJSONNBDServerStart, "localhost", 12345) GEN_TEST_FUNC(qemuMonitorJSONNBDServerAdd, "vda", true) GEN_TEST_FUNC(qemuMonitorJSONDetachCharDev, "serial1") + +static int +testQemuMonitorJSONqemuMonitorJSONGetCPUInfo(const void *data) +{ + virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); + int ret = -1; + pid_t *cpupids = NULL; + pid_t expected_cpupids[] = {17622, 17624, 17626, 17628}; + int ncpupids; + size_t i; + + if (!test) + return -1; + + if (qemuMonitorTestAddItem(test, "query-cpus", + "{" + " \"return\": [" + " {" + " \"current\": true," + " \"CPU\": 0," + " \"pc\": -2130530478," + " \"halted\": true," + " \"thread_id\": 17622" + " }," + " {" + " \"current\": false," + " \"CPU\": 1," + " \"pc\": -2130530478," + " \"halted\": true," + " \"thread_id\": 17624" + " }," + " {" + " \"current\": false," + " \"CPU\": 2," + " \"pc\": -2130530478," + " \"halted\": true," + " \"thread_id\": 17626" + " }," + " {" + " \"current\": false," + " \"CPU\": 3," + " \"pc\": -2130530478," + " \"halted\": true," + " \"thread_id\": 17628" + " }" + " ]," + " \"id\": \"libvirt-7\"" + "}") < 0) + goto cleanup; + + ncpupids = qemuMonitorJSONGetCPUInfo(qemuMonitorTestGetMonitor(test), &cpupids); + + if (ncpupids != 4) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Expecting ncpupids = 4 but got %d", ncpupids); + goto cleanup; + } + + for (i = 0; i < ncpupids; i++) { + if (cpupids[i] != expected_cpupids[i]) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Expecting cpupids[%zu] = %d but got %d", + i, expected_cpupids[i], cpupids[i]); + goto cleanup; + } + } + + ret = 0; + +cleanup: + VIR_FREE(cpupids); + qemuMonitorTestFree(test); + return ret; +} + static int testQemuMonitorJSONqemuMonitorJSONGetBalloonInfo(const void *data) { @@ -1898,6 +1974,7 @@ mymain(void) DO_TEST(qemuMonitorJSONSetBlockIoThrottle); DO_TEST(qemuMonitorJSONGetTargetArch); DO_TEST(qemuMonitorJSONGetMigrationCapability); + DO_TEST(qemuMonitorJSONGetCPUInfo); virObjectUnref(xmlopt); -- 1.8.1.5

Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemumonitorjsontest.c | 53 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 15541dd..67a58f5 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1284,6 +1284,58 @@ cleanup: } static int +testQemuMonitorJSONqemuMonitorJSONGetVirtType(const void *data) +{ + virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); + int ret = -1; + int virtType; + + if (!test) + return -1; + + if (qemuMonitorTestAddItem(test, "query-kvm", + "{" + " \"return\": {" + " \"enabled\": true," + " \"present\": true" + " }," + " \"id\": \"libvirt-8\"" + "}") < 0 || + qemuMonitorTestAddItem(test, "query-kvm", + "{" + " \"return\": {" + " \"enabled\": false," + " \"present\": true" + " }," + " \"id\": \"libvirt-7\"" + "}") < 0) + goto cleanup; + + if (qemuMonitorJSONGetVirtType(qemuMonitorTestGetMonitor(test), &virtType) < 0) + goto cleanup; + + if (virtType != VIR_DOMAIN_VIRT_KVM) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Unexpected virt type: %d, expecting %d", virtType, VIR_DOMAIN_VIRT_KVM); + goto cleanup; + } + + if (qemuMonitorJSONGetVirtType(qemuMonitorTestGetMonitor(test), &virtType) < 0) + goto cleanup; + + if (virtType != VIR_DOMAIN_VIRT_QEMU) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "Unexpected virt type: %d, expecting %d", virtType, VIR_DOMAIN_VIRT_QEMU); + } + + ret = 0; +cleanup: + qemuMonitorTestFree(test); + return ret; +} + +static int testHashEqualQemuDomainDiskInfo(const void *value1, const void *value2) { const struct qemuDomainDiskInfo *info1 = value1, *info2 = value2; @@ -1975,6 +2027,7 @@ mymain(void) DO_TEST(qemuMonitorJSONGetTargetArch); DO_TEST(qemuMonitorJSONGetMigrationCapability); DO_TEST(qemuMonitorJSONGetCPUInfo); + DO_TEST(qemuMonitorJSONGetVirtType); virObjectUnref(xmlopt); -- 1.8.1.5

Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- tests/qemumonitorjsontest.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 67a58f5..0b6807d 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -1934,6 +1934,31 @@ cleanup: } static int +testQemuMonitorJSONqemuMonitorJSONSendKey(const void *data) +{ + virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; + qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt); + int ret = -1; + unsigned int keycodes[] = {43, 26, 46, 32}; + + if (!test) + return -1; + + if (qemuMonitorTestAddItem(test, "send-key", + "{\"return\": {}, \"id\": \"libvirt-16\"}") < 0) + goto cleanup; + + if (qemuMonitorJSONSendKey(qemuMonitorTestGetMonitor(test), + 0, keycodes, ARRAY_CARDINALITY(keycodes)) < 0) + goto cleanup; + + ret = 0; +cleanup: + qemuMonitorTestFree(test); + return ret; +} + +static int mymain(void) { int ret = 0; @@ -2028,6 +2053,7 @@ mymain(void) DO_TEST(qemuMonitorJSONGetMigrationCapability); DO_TEST(qemuMonitorJSONGetCPUInfo); DO_TEST(qemuMonitorJSONGetVirtType); + DO_TEST(qemuMonitorJSONSendKey); virObjectUnref(xmlopt); -- 1.8.1.5

On 03.10.2013 12:49, Michal Privoznik wrote:
v2 to some patches that weren't ACKed yet.
Michal Privoznik (5): qemuMonitorTestFree: Join worker thread qemumonitorjsontest: Extend the test for yet another monitor commands qemumonitorjsontest: Test qemuMonitorJSONGetCPUInfo qemumonitorjsontest: Test qemuMonitorJSONGetVirtType qemumonitorjsontest: Test qemuMonitorJSONSendKey
tests/qemumonitorjsontest.c | 253 +++++++++++++++++++++++++++++++++++++++++++ tests/qemumonitortestutils.c | 5 +- 2 files changed, 256 insertions(+), 2 deletions(-)
Ping? 1/5 is ACked and pushed, but what about the others? Michal

On 10/10/2013 01:43 PM, Michal Privoznik wrote:
On 03.10.2013 12:49, Michal Privoznik wrote:
v2 to some patches that weren't ACKed yet.
Michal Privoznik (5): qemuMonitorTestFree: Join worker thread qemumonitorjsontest: Extend the test for yet another monitor commands qemumonitorjsontest: Test qemuMonitorJSONGetCPUInfo qemumonitorjsontest: Test qemuMonitorJSONGetVirtType qemumonitorjsontest: Test qemuMonitorJSONSendKey
tests/qemumonitorjsontest.c | 253 +++++++++++++++++++++++++++++++++++++++++++ tests/qemumonitortestutils.c | 5 +- 2 files changed, 256 insertions(+), 2 deletions(-)
Ping? 1/5 is ACked and pushed, but what about the others?
ACK series
participants (3)
-
Daniel P. Berrange
-
Ján Tomko
-
Michal Privoznik