提交 c542a9f9 编写于 作者: P Peter Maydell

Merge remote-tracking branch 'remotes/armbru/tags/pull-tests-2018-08-16' into staging

Testing patches for 2018-08-16

# gpg: Signature made Thu 16 Aug 2018 09:34:43 BST
# gpg:                using RSA key 3870B400EB918653
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>"
# gpg:                 aka "Markus Armbruster <armbru@pond.sub.org>"
# Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867  4E5F 3870 B400 EB91 8653

* remotes/armbru/tags/pull-tests-2018-08-16: (25 commits)
  libqtest: Improve error reporting for bad read from QEMU
  tests/libqtest: Improve kill_qemu()
  libqtest: Rename qtest_FOOv() to qtest_vFOO() for consistency
  libqtest: Replace qtest_startf() by qtest_initf()
  libqtest: Enable compile-time format string checking
  migration-test: Clean up string interpolation into QMP, part 3
  migration-test: Clean up string interpolation into QMP, part 2
  migration-test: Clean up string interpolation into QMP, part 1
  migration-test: Make wait_command() cope with '%'
  tests: New helper qtest_qmp_receive_success()
  migration-test: Make wait_command() return the "return" member
  tests: Clean up string interpolation around qtest_qmp_device_add()
  cpu-plug-test: Don't pass integers as strings to device_add
  tests: Clean up string interpolation into QMP input (simple cases)
  tests: Pass literal format strings directly to qmp_FOO()
  qobject: qobject_from_jsonv() is dangerous, hide it away
  test-qobject-input-visitor: Avoid format string ambiguity
  libqtest: Simplify qmp_fd_vsend() a bit
  qobject: New qobject_from_vjsonf_nofail(), qdict_from_vjsonf_nofail()
  qobject: Replace qobject_from_jsonf() by qobject_from_jsonf_nofail()
  ...
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
...@@ -15,11 +15,15 @@ ...@@ -15,11 +15,15 @@
#define QJSON_H #define QJSON_H
QObject *qobject_from_json(const char *string, Error **errp); QObject *qobject_from_json(const char *string, Error **errp);
QObject *qobject_from_jsonf(const char *string, ...) GCC_FMT_ATTR(1, 2);
QObject *qobject_from_jsonv(const char *string, va_list *ap, Error **errp)
GCC_FMT_ATTR(1, 0);
QDict *qdict_from_jsonf_nofail(const char *string, ...) GCC_FMT_ATTR(1, 2); QObject *qobject_from_vjsonf_nofail(const char *string, va_list ap)
GCC_FMT_ATTR(1, 0);
QObject *qobject_from_jsonf_nofail(const char *string, ...)
GCC_FMT_ATTR(1, 2);
QDict *qdict_from_vjsonf_nofail(const char *string, va_list ap)
GCC_FMT_ATTR(1, 0);
QDict *qdict_from_jsonf_nofail(const char *string, ...)
GCC_FMT_ATTR(1, 2);
QString *qobject_to_json(const QObject *obj); QString *qobject_to_json(const QObject *obj);
QString *qobject_to_json_pretty(const QObject *obj); QString *qobject_to_json_pretty(const QObject *obj);
......
...@@ -39,7 +39,18 @@ static void parse_json(JSONMessageParser *parser, GQueue *tokens) ...@@ -39,7 +39,18 @@ static void parse_json(JSONMessageParser *parser, GQueue *tokens)
s->result = json_parser_parse_err(tokens, s->ap, &s->err); s->result = json_parser_parse_err(tokens, s->ap, &s->err);
} }
QObject *qobject_from_jsonv(const char *string, va_list *ap, Error **errp) /*
* Parse @string as JSON value.
* If @ap is non-null, interpolate %-escapes.
* Takes ownership of %p arguments.
* On success, return the JSON value.
* On failure, store an error through @errp and return NULL.
* Ownership of %p arguments becomes indeterminate then. To avoid
* leaks, callers passing %p must terminate on error, e.g. by passing
* &error_abort.
*/
static QObject *qobject_from_jsonv(const char *string, va_list *ap,
Error **errp)
{ {
JSONParsingState state = {}; JSONParsingState state = {};
...@@ -59,18 +70,56 @@ QObject *qobject_from_json(const char *string, Error **errp) ...@@ -59,18 +70,56 @@ QObject *qobject_from_json(const char *string, Error **errp)
return qobject_from_jsonv(string, NULL, errp); return qobject_from_jsonv(string, NULL, errp);
} }
QObject *qobject_from_jsonf(const char *string, ...) /*
* Parse @string as JSON value with %-escapes interpolated.
* Abort on error. Do not use with untrusted @string.
* Return the resulting QObject. It is never null.
*/
QObject *qobject_from_vjsonf_nofail(const char *string, va_list ap)
{
va_list ap_copy;
QObject *obj;
/* va_copy() is needed when va_list is an array type */
va_copy(ap_copy, ap);
obj = qobject_from_jsonv(string, &ap_copy, &error_abort);
va_end(ap_copy);
assert(obj);
return obj;
}
/*
* Parse @string as JSON value with %-escapes interpolated.
* Abort on error. Do not use with untrusted @string.
* Return the resulting QObject. It is never null.
*/
QObject *qobject_from_jsonf_nofail(const char *string, ...)
{ {
QObject *obj; QObject *obj;
va_list ap; va_list ap;
va_start(ap, string); va_start(ap, string);
obj = qobject_from_jsonv(string, &ap, &error_abort); obj = qobject_from_vjsonf_nofail(string, ap);
va_end(ap); va_end(ap);
return obj; return obj;
} }
/*
* Parse @string as JSON object with %-escapes interpolated.
* Abort on error. Do not use with untrusted @string.
* Return the resulting QDict. It is never null.
*/
QDict *qdict_from_vjsonf_nofail(const char *string, va_list ap)
{
QDict *qdict;
qdict = qobject_to(QDict, qobject_from_vjsonf_nofail(string, ap));
assert(qdict);
return qdict;
}
/* /*
* Parse @string as JSON object with %-escapes interpolated. * Parse @string as JSON object with %-escapes interpolated.
* Abort on error. Do not use with untrusted @string. * Abort on error. Do not use with untrusted @string.
...@@ -78,15 +127,13 @@ QObject *qobject_from_jsonf(const char *string, ...) ...@@ -78,15 +127,13 @@ QObject *qobject_from_jsonf(const char *string, ...)
*/ */
QDict *qdict_from_jsonf_nofail(const char *string, ...) QDict *qdict_from_jsonf_nofail(const char *string, ...)
{ {
QDict *obj; QDict *qdict;
va_list ap; va_list ap;
va_start(ap, string); va_start(ap, string);
obj = qobject_to(QDict, qobject_from_jsonv(string, &ap, &error_abort)); qdict = qdict_from_vjsonf_nofail(string, ap);
va_end(ap); va_end(ap);
return qdict;
assert(obj);
return obj;
} }
typedef struct ToJsonIterState typedef struct ToJsonIterState
......
...@@ -37,6 +37,9 @@ ...@@ -37,6 +37,9 @@
#include "hw/pci/pci_ids.h" #include "hw/pci/pci_ids.h"
#include "hw/pci/pci_regs.h" #include "hw/pci/pci_regs.h"
/* TODO actually test the results and get rid of this */
#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__))
/* Test images sizes in MB */ /* Test images sizes in MB */
#define TEST_IMAGE_SIZE_MB_LARGE (200 * 1024) #define TEST_IMAGE_SIZE_MB_LARGE (200 * 1024)
#define TEST_IMAGE_SIZE_MB_SMALL 64 #define TEST_IMAGE_SIZE_MB_SMALL 64
...@@ -1352,7 +1355,6 @@ static void test_flush_migrate(void) ...@@ -1352,7 +1355,6 @@ static void test_flush_migrate(void)
AHCIQState *src, *dst; AHCIQState *src, *dst;
AHCICommand *cmd; AHCICommand *cmd;
uint8_t px; uint8_t px;
const char *s;
char *uri = g_strdup_printf("unix:%s", mig_socket); char *uri = g_strdup_printf("unix:%s", mig_socket);
prepare_blkdebug_script(debug_path, "flush_to_disk"); prepare_blkdebug_script(debug_path, "flush_to_disk");
...@@ -1388,8 +1390,7 @@ static void test_flush_migrate(void) ...@@ -1388,8 +1390,7 @@ static void test_flush_migrate(void)
ahci_migrate(src, dst, uri); ahci_migrate(src, dst, uri);
/* Complete the command */ /* Complete the command */
s = "{'execute':'cont' }"; qmp_send("{'execute':'cont' }");
qmp_async(s);
qmp_eventwait("RESUME"); qmp_eventwait("RESUME");
ahci_command_wait(dst, cmd); ahci_command_wait(dst, cmd);
ahci_command_verify(dst, cmd); ahci_command_verify(dst, cmd);
...@@ -1592,8 +1593,8 @@ static void test_atapi_tray(void) ...@@ -1592,8 +1593,8 @@ static void test_atapi_tray(void)
atapi_wait_tray(false); atapi_wait_tray(false);
/* Remove media */ /* Remove media */
qmp_async("{'execute': 'blockdev-open-tray', " qmp_send("{'execute': 'blockdev-open-tray',"
"'arguments': {'id': 'cd0'}}"); " 'arguments': {'id': 'cd0'}}");
atapi_wait_tray(true); atapi_wait_tray(true);
rsp = qmp_receive(); rsp = qmp_receive();
qobject_unref(rsp); qobject_unref(rsp);
...@@ -1619,8 +1620,8 @@ static void test_atapi_tray(void) ...@@ -1619,8 +1620,8 @@ static void test_atapi_tray(void)
"'node-name': 'node0' }}"); "'node-name': 'node0' }}");
/* Again, the event shows up first */ /* Again, the event shows up first */
qmp_async("{'execute': 'blockdev-close-tray', " qmp_send("{'execute': 'blockdev-close-tray',"
"'arguments': {'id': 'cd0'}}"); " 'arguments': {'id': 'cd0'}}");
atapi_wait_tray(false); atapi_wait_tray(false);
rsp = qmp_receive(); rsp = qmp_receive();
qobject_unref(rsp); qobject_unref(rsp);
......
...@@ -13,9 +13,12 @@ ...@@ -13,9 +13,12 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "libqos/fw_cfg.h" #include "libqos/fw_cfg.h"
#include "libqtest.h" #include "libqtest.h"
#include "qapi/qmp/qdict.h"
#include "hw/nvram/fw_cfg_keys.h" #include "hw/nvram/fw_cfg_keys.h"
/* TODO actually test the results and get rid of this */
#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__))
typedef struct { typedef struct {
const char *args; const char *args;
uint64_t expected_boot; uint64_t expected_boot;
...@@ -30,10 +33,10 @@ static void test_a_boot_order(const char *machine, ...@@ -30,10 +33,10 @@ static void test_a_boot_order(const char *machine,
{ {
uint64_t actual; uint64_t actual;
global_qtest = qtest_startf("-nodefaults%s%s %s", global_qtest = qtest_initf("-nodefaults%s%s %s",
machine ? " -M " : "", machine ? " -M " : "",
machine ?: "", machine ?: "",
test_args); test_args);
actual = read_boot_order(); actual = read_boot_order();
g_assert_cmphex(actual, ==, expected_boot); g_assert_cmphex(actual, ==, expected_boot);
qmp_discard_response("{ 'execute': 'system_reset' }"); qmp_discard_response("{ 'execute': 'system_reset' }");
......
...@@ -172,11 +172,11 @@ static void test_machine(const void *data) ...@@ -172,11 +172,11 @@ static void test_machine(const void *data)
* Make sure that this test uses tcg if available: It is used as a * Make sure that this test uses tcg if available: It is used as a
* fast-enough smoketest for that. * fast-enough smoketest for that.
*/ */
global_qtest = qtest_startf("%s %s -M %s,accel=tcg:kvm " global_qtest = qtest_initf("%s %s -M %s,accel=tcg:kvm "
"-chardev file,id=serial0,path=%s " "-chardev file,id=serial0,path=%s "
"-no-shutdown -serial chardev:serial0 %s", "-no-shutdown -serial chardev:serial0 %s",
codeparam, code ? codetmp : "", codeparam, code ? codetmp : "",
test->machine, serialtmp, test->extra); test->machine, serialtmp, test->extra);
if (code) { if (code) {
unlink(codetmp); unlink(codetmp);
} }
......
...@@ -99,7 +99,7 @@ static void test_cdrom_param(gconstpointer data) ...@@ -99,7 +99,7 @@ static void test_cdrom_param(gconstpointer data)
QTestState *qts; QTestState *qts;
char *resp; char *resp;
qts = qtest_startf("-M %s -cdrom %s", (const char *)data, isoimage); qts = qtest_initf("-M %s -cdrom %s", (const char *)data, isoimage);
resp = qtest_hmp(qts, "info block"); resp = qtest_hmp(qts, "info block");
g_assert(strstr(resp, isoimage) != 0); g_assert(strstr(resp, isoimage) != 0);
g_free(resp); g_free(resp);
...@@ -120,8 +120,8 @@ static void test_cdboot(gconstpointer data) ...@@ -120,8 +120,8 @@ static void test_cdboot(gconstpointer data)
{ {
QTestState *qts; QTestState *qts;
qts = qtest_startf("-accel kvm:tcg -no-shutdown %s%s", (const char *)data, qts = qtest_initf("-accel kvm:tcg -no-shutdown %s%s", (const char *)data,
isoimage); isoimage);
boot_sector_test(qts); boot_sector_test(qts);
qtest_quit(qts); qtest_quit(qts);
} }
......
...@@ -865,7 +865,8 @@ static void vararg_string(void) ...@@ -865,7 +865,8 @@ static void vararg_string(void)
QString *str; QString *str;
str = qobject_to(QString, str = qobject_to(QString,
qobject_from_jsonf("%s", test_cases[i].decoded)); qobject_from_jsonf_nofail("%s",
test_cases[i].decoded));
g_assert(str); g_assert(str);
g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0); g_assert(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
...@@ -998,17 +999,17 @@ static void vararg_number(void) ...@@ -998,17 +999,17 @@ static void vararg_number(void)
double valuef = 2.323423423; double valuef = 2.323423423;
int64_t val; int64_t val;
qnum = qobject_to(QNum, qobject_from_jsonf("%d", value)); qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%d", value));
g_assert(qnum_get_try_int(qnum, &val)); g_assert(qnum_get_try_int(qnum, &val));
g_assert_cmpint(val, ==, value); g_assert_cmpint(val, ==, value);
qobject_unref(qnum); qobject_unref(qnum);
qnum = qobject_to(QNum, qobject_from_jsonf("%lld", value_ll)); qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%lld", value_ll));
g_assert(qnum_get_try_int(qnum, &val)); g_assert(qnum_get_try_int(qnum, &val));
g_assert_cmpint(val, ==, value_ll); g_assert_cmpint(val, ==, value_ll);
qobject_unref(qnum); qobject_unref(qnum);
qnum = qobject_to(QNum, qobject_from_jsonf("%f", valuef)); qnum = qobject_to(QNum, qobject_from_jsonf_nofail("%f", valuef));
g_assert(qnum_get_double(qnum) == valuef); g_assert(qnum_get_double(qnum) == valuef);
qobject_unref(qnum); qobject_unref(qnum);
} }
...@@ -1042,13 +1043,13 @@ static void keyword_literal(void) ...@@ -1042,13 +1043,13 @@ static void keyword_literal(void)
qobject_unref(qbool); qobject_unref(qbool);
qbool = qobject_to(QBool, qobject_from_jsonf("%i", false)); qbool = qobject_to(QBool, qobject_from_jsonf_nofail("%i", false));
g_assert(qbool); g_assert(qbool);
g_assert(qbool_get_bool(qbool) == false); g_assert(qbool_get_bool(qbool) == false);
qobject_unref(qbool); qobject_unref(qbool);
/* Test that non-zero values other than 1 get collapsed to true */ /* Test that non-zero values other than 1 get collapsed to true */
qbool = qobject_to(QBool, qobject_from_jsonf("%i", 2)); qbool = qobject_to(QBool, qobject_from_jsonf_nofail("%i", 2));
g_assert(qbool); g_assert(qbool);
g_assert(qbool_get_bool(qbool) == true); g_assert(qbool_get_bool(qbool) == true);
qobject_unref(qbool); qobject_unref(qbool);
...@@ -1298,7 +1299,7 @@ static void simple_varargs(void) ...@@ -1298,7 +1299,7 @@ static void simple_varargs(void)
embedded_obj = qobject_from_json("[32, 42]", &error_abort); embedded_obj = qobject_from_json("[32, 42]", &error_abort);
g_assert(embedded_obj != NULL); g_assert(embedded_obj != NULL);
obj = qobject_from_jsonf("[%d, 2, %p]", 1, embedded_obj); obj = qobject_from_jsonf_nofail("[%d, 2, %p]", 1, embedded_obj);
g_assert(qlit_equal_qobject(&decoded, obj)); g_assert(qlit_equal_qobject(&decoded, obj));
qobject_unref(obj); qobject_unref(obj);
......
...@@ -88,8 +88,9 @@ static void test_plug_with_device_add_x86(gconstpointer data) ...@@ -88,8 +88,9 @@ static void test_plug_with_device_add_x86(gconstpointer data)
for (c = 0; c < td->cores; c++) { for (c = 0; c < td->cores; c++) {
for (t = 0; t < td->threads; t++) { for (t = 0; t < td->threads; t++) {
char *id = g_strdup_printf("id-%i-%i-%i", s, c, t); char *id = g_strdup_printf("id-%i-%i-%i", s, c, t);
qtest_qmp_device_add(td->device_model, id, "'socket-id':'%i', " qtest_qmp_device_add(td->device_model, id,
"'core-id':'%i', 'thread-id':'%i'", "{'socket-id':%u, 'core-id':%u,"
" 'thread-id':%u}",
s, c, t); s, c, t);
g_free(id); g_free(id);
} }
...@@ -114,7 +115,7 @@ static void test_plug_with_device_add_coreid(gconstpointer data) ...@@ -114,7 +115,7 @@ static void test_plug_with_device_add_coreid(gconstpointer data)
for (c = td->cores; c < td->maxcpus / td->sockets / td->threads; c++) { for (c = td->cores; c < td->maxcpus / td->sockets / td->threads; c++) {
char *id = g_strdup_printf("id-%i", c); char *id = g_strdup_printf("id-%i", c);
qtest_qmp_device_add(td->device_model, id, "'core-id':'%i'", c); qtest_qmp_device_add(td->device_model, id, "{'core-id':%u}", c);
g_free(id); g_free(id);
} }
......
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
#include "libqos/virtio.h" #include "libqos/virtio.h"
#include "qapi/qmp/qdict.h" #include "qapi/qmp/qdict.h"
/* TODO actually test the results and get rid of this */
#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__))
static void drive_add(void) static void drive_add(void)
{ {
char *resp = hmp("drive_add 0 if=none,id=drive0"); char *resp = hmp("drive_add 0 if=none,id=drive0");
......
...@@ -456,12 +456,10 @@ static void test_e1000e_multiple_transfers(gconstpointer data) ...@@ -456,12 +456,10 @@ static void test_e1000e_multiple_transfers(gconstpointer data)
static void test_e1000e_hotplug(gconstpointer data) static void test_e1000e_hotplug(gconstpointer data)
{ {
static const uint8_t slot = 0x06;
qtest_start("-device e1000e"); qtest_start("-device e1000e");
qpci_plug_device_test("e1000e", "e1000e_net", slot, NULL); qtest_qmp_device_add("e1000e", "e1000e_net", "{'addr': '0x06'}");
qpci_unplug_acpi_device_test("e1000e_net", slot); qpci_unplug_acpi_device_test("e1000e_net", 0x06);
qtest_end(); qtest_end();
} }
......
...@@ -115,10 +115,10 @@ static void test_endianness(gconstpointer data) ...@@ -115,10 +115,10 @@ static void test_endianness(gconstpointer data)
{ {
const TestCase *test = data; const TestCase *test = data;
global_qtest = qtest_startf("-M %s%s%s -device pc-testdev", global_qtest = qtest_initf("-M %s%s%s -device pc-testdev",
test->machine, test->machine,
test->superio ? " -device " : "", test->superio ? " -device " : "",
test->superio ?: ""); test->superio ?: "");
isa_outl(test, 0xe0, 0x87654321); isa_outl(test, 0xe0, 0x87654321);
g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321); g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
...@@ -187,10 +187,10 @@ static void test_endianness_split(gconstpointer data) ...@@ -187,10 +187,10 @@ static void test_endianness_split(gconstpointer data)
{ {
const TestCase *test = data; const TestCase *test = data;
global_qtest = qtest_startf("-M %s%s%s -device pc-testdev", global_qtest = qtest_initf("-M %s%s%s -device pc-testdev",
test->machine, test->machine,
test->superio ? " -device " : "", test->superio ? " -device " : "",
test->superio ?: ""); test->superio ?: "");
isa_outl(test, 0xe8, 0x87654321); isa_outl(test, 0xe8, 0x87654321);
g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321); g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765); g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
...@@ -231,10 +231,10 @@ static void test_endianness_combine(gconstpointer data) ...@@ -231,10 +231,10 @@ static void test_endianness_combine(gconstpointer data)
{ {
const TestCase *test = data; const TestCase *test = data;
global_qtest = qtest_startf("-M %s%s%s -device pc-testdev", global_qtest = qtest_initf("-M %s%s%s -device pc-testdev",
test->machine, test->machine,
test->superio ? " -device " : "", test->superio ? " -device " : "",
test->superio ?: ""); test->superio ?: "");
isa_outl(test, 0xe0, 0x87654321); isa_outl(test, 0xe0, 0x87654321);
g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654321); g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654321);
g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765); g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
......
...@@ -26,8 +26,12 @@ ...@@ -26,8 +26,12 @@
#include "libqtest.h" #include "libqtest.h"
#include "qapi/qmp/qdict.h"
#include "qemu-common.h" #include "qemu-common.h"
/* TODO actually test the results and get rid of this */
#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__))
#define TEST_IMAGE_SIZE 1440 * 1024 #define TEST_IMAGE_SIZE 1440 * 1024
#define FLOPPY_BASE 0x3f0 #define FLOPPY_BASE 0x3f0
......
...@@ -29,12 +29,15 @@ ...@@ -29,12 +29,15 @@
#include "libqos/libqos.h" #include "libqos/libqos.h"
#include "libqos/pci-pc.h" #include "libqos/pci-pc.h"
#include "libqos/malloc-pc.h" #include "libqos/malloc-pc.h"
#include "qapi/qmp/qdict.h"
#include "qemu-common.h" #include "qemu-common.h"
#include "qemu/bswap.h" #include "qemu/bswap.h"
#include "hw/pci/pci_ids.h" #include "hw/pci/pci_ids.h"
#include "hw/pci/pci_regs.h" #include "hw/pci/pci_regs.h"
/* TODO actually test the results and get rid of this */
#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__))
#define TEST_IMAGE_SIZE 64 * 1024 * 1024 #define TEST_IMAGE_SIZE 64 * 1024 * 1024
#define IDE_PCI_DEV 1 #define IDE_PCI_DEV 1
...@@ -694,7 +697,6 @@ static void test_retry_flush(const char *machine) ...@@ -694,7 +697,6 @@ static void test_retry_flush(const char *machine)
QPCIDevice *dev; QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar; QPCIBar bmdma_bar, ide_bar;
uint8_t data; uint8_t data;
const char *s;
prepare_blkdebug_script(debug_path, "flush_to_disk"); prepare_blkdebug_script(debug_path, "flush_to_disk");
...@@ -722,8 +724,7 @@ static void test_retry_flush(const char *machine) ...@@ -722,8 +724,7 @@ static void test_retry_flush(const char *machine)
qmp_eventwait("STOP"); qmp_eventwait("STOP");
/* Complete the command */ /* Complete the command */
s = "{'execute':'cont' }"; qmp_discard_response("{'execute':'cont' }");
qmp_discard_response(s);
/* Check registers */ /* Check registers */
data = qpci_io_readb(dev, ide_bar, reg_device); data = qpci_io_readb(dev, ide_bar, reg_device);
......
...@@ -414,7 +414,7 @@ int main(int argc, char **argv) ...@@ -414,7 +414,7 @@ int main(int argc, char **argv)
/* Run the tests */ /* Run the tests */
g_test_init(&argc, &argv, NULL); g_test_init(&argc, &argv, NULL);
global_qtest = qtest_startf( global_qtest = qtest_initf(
" -chardev socket,id=ipmi0,host=localhost,port=%d,reconnect=10" " -chardev socket,id=ipmi0,host=localhost,port=%d,reconnect=10"
" -device ipmi-bmc-extern,chardev=ipmi0,id=bmc0" " -device ipmi-bmc-extern,chardev=ipmi0,id=bmc0"
" -device isa-ipmi-bt,bmc=bmc0", emu_port); " -device isa-ipmi-bt,bmc=bmc0", emu_port);
......
...@@ -420,19 +420,17 @@ static void test_ivshmem_server_irq(void) ...@@ -420,19 +420,17 @@ static void test_ivshmem_server_irq(void)
static void test_ivshmem_hotplug(void) static void test_ivshmem_hotplug(void)
{ {
const char *arch = qtest_get_arch(); const char *arch = qtest_get_arch();
gchar *opts;
qtest_start(""); qtest_start("");
opts = g_strdup_printf("'shm': '%s', 'size': '1M'", tmpshm); qtest_qmp_device_add("ivshmem",
"iv1", "{'addr': %s, 'shm': %s, 'size': '1M'}",
qpci_plug_device_test("ivshmem", "iv1", PCI_SLOT_HP, opts); stringify(PCI_SLOT_HP), tmpshm);
if (strcmp(arch, "ppc64") != 0) { if (strcmp(arch, "ppc64") != 0) {
qpci_unplug_acpi_device_test("iv1", PCI_SLOT_HP); qpci_unplug_acpi_device_test("iv1", PCI_SLOT_HP);
} }
qtest_end(); qtest_end();
g_free(opts);
} }
static void test_ivshmem_memdev(void) static void test_ivshmem_memdev(void)
......
...@@ -674,7 +674,7 @@ void ahci_exec(AHCIQState *ahci, uint8_t port, ...@@ -674,7 +674,7 @@ void ahci_exec(AHCIQState *ahci, uint8_t port,
g_assert_cmpint(rc, ==, 0); g_assert_cmpint(rc, ==, 0);
} }
if (opts->error) { if (opts->error) {
qtest_async_qmp(ahci->parent->qts, "{'execute':'cont' }"); qtest_qmp_send(ahci->parent->qts, "{'execute':'cont' }");
qtest_qmp_eventwait(ahci->parent->qts, "RESUME"); qtest_qmp_eventwait(ahci->parent->qts, "RESUME");
} }
...@@ -712,7 +712,7 @@ AHCICommand *ahci_guest_io_halt(AHCIQState *ahci, uint8_t port, ...@@ -712,7 +712,7 @@ AHCICommand *ahci_guest_io_halt(AHCIQState *ahci, uint8_t port,
void ahci_guest_io_resume(AHCIQState *ahci, AHCICommand *cmd) void ahci_guest_io_resume(AHCIQState *ahci, AHCICommand *cmd)
{ {
/* Complete the command */ /* Complete the command */
qtest_async_qmp(ahci->parent->qts, "{'execute':'cont' }"); qtest_qmp_send(ahci->parent->qts, "{'execute':'cont' }");
qtest_qmp_eventwait(ahci->parent->qts, "RESUME"); qtest_qmp_eventwait(ahci->parent->qts, "RESUME");
ahci_command_wait(ahci, cmd); ahci_command_wait(ahci, cmd);
ahci_command_verify(ahci, cmd); ahci_command_verify(ahci, cmd);
......
...@@ -160,14 +160,9 @@ void qpci_free_pc(QPCIBus *bus) ...@@ -160,14 +160,9 @@ void qpci_free_pc(QPCIBus *bus)
void qpci_unplug_acpi_device_test(const char *id, uint8_t slot) void qpci_unplug_acpi_device_test(const char *id, uint8_t slot)
{ {
QDict *response; QDict *response;
char *cmd;
response = qmp("{'execute': 'device_del', 'arguments': {'id': %s}}",
cmd = g_strdup_printf("{'execute': 'device_del'," id);
" 'arguments': {"
" 'id': '%s'"
"}}", id);
response = qmp(cmd);
g_free(cmd);
g_assert(response); g_assert(response);
g_assert(!qdict_haskey(response, "error")); g_assert(!qdict_haskey(response, "error"));
qobject_unref(response); qobject_unref(response);
......
...@@ -395,10 +395,3 @@ QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr) ...@@ -395,10 +395,3 @@ QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr)
QPCIBar bar = { .addr = addr }; QPCIBar bar = { .addr = addr };
return bar; return bar;
} }
void qpci_plug_device_test(const char *driver, const char *id,
uint8_t slot, const char *opts)
{
qtest_qmp_device_add(driver, id, "'addr': '%d'%s%s", slot,
opts ? ", " : "", opts ? opts : "");
}
...@@ -109,7 +109,5 @@ QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr); ...@@ -109,7 +109,5 @@ QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr);
void qpci_iounmap(QPCIDevice *dev, QPCIBar addr); void qpci_iounmap(QPCIDevice *dev, QPCIBar addr);
QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr); QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr);
void qpci_plug_device_test(const char *driver, const char *id,
uint8_t slot, const char *opts);
void qpci_unplug_acpi_device_test(const char *id, uint8_t slot); void qpci_unplug_acpi_device_test(const char *id, uint8_t slot);
#endif #endif
...@@ -37,13 +37,14 @@ void uhci_port_test(struct qhc *hc, int port, uint16_t expect) ...@@ -37,13 +37,14 @@ void uhci_port_test(struct qhc *hc, int port, uint16_t expect)
g_assert((value & mask) == (expect & mask)); g_assert((value & mask) == (expect & mask));
} }
void usb_test_hotplug(const char *hcd_id, const int port, void usb_test_hotplug(const char *hcd_id, const char *port,
void (*port_check)(void)) void (*port_check)(void))
{ {
char *id = g_strdup_printf("usbdev%d", port); char *id = g_strdup_printf("usbdev%s", port);
char *bus = g_strdup_printf("%s.0", hcd_id);
qtest_qmp_device_add("usb-tablet", id, "'port': '%d', 'bus': '%s.0'", qtest_qmp_device_add("usb-tablet", id, "{'port': %s, 'bus': %s}",
port, hcd_id); port, bus);
if (port_check) { if (port_check) {
port_check(); port_check();
...@@ -51,5 +52,6 @@ void usb_test_hotplug(const char *hcd_id, const int port, ...@@ -51,5 +52,6 @@ void usb_test_hotplug(const char *hcd_id, const int port,
qtest_qmp_device_del(id); qtest_qmp_device_del(id);
g_free(bus);
g_free(id); g_free(id);
} }
...@@ -13,6 +13,6 @@ void qusb_pci_init_one(QPCIBus *pcibus, struct qhc *hc, ...@@ -13,6 +13,6 @@ void qusb_pci_init_one(QPCIBus *pcibus, struct qhc *hc,
void uhci_port_test(struct qhc *hc, int port, uint16_t expect); void uhci_port_test(struct qhc *hc, int port, uint16_t expect);
void uhci_deinit(struct qhc *hc); void uhci_deinit(struct qhc *hc);
void usb_test_hotplug(const char *bus_name, const int port, void usb_test_hotplug(const char *bus_name, const char *port,
void (*port_check)(void)); void (*port_check)(void));
#endif #endif
...@@ -107,10 +107,28 @@ static void kill_qemu(QTestState *s) ...@@ -107,10 +107,28 @@ static void kill_qemu(QTestState *s)
pid_t pid; pid_t pid;
kill(s->qemu_pid, SIGTERM); kill(s->qemu_pid, SIGTERM);
pid = waitpid(s->qemu_pid, &wstatus, 0); TFR(pid = waitpid(s->qemu_pid, &wstatus, 0));
if (pid == s->qemu_pid && WIFSIGNALED(wstatus)) { assert(pid == s->qemu_pid);
assert(!WCOREDUMP(wstatus)); /*
* We expect qemu to exit with status 0; anything else is
* fishy and should be logged with as much detail as possible.
*/
if (wstatus) {
if (WIFEXITED(wstatus)) {
fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU "
"process but encountered exit status %d\n",
__FILE__, __LINE__, WEXITSTATUS(wstatus));
} else if (WIFSIGNALED(wstatus)) {
int sig = WTERMSIG(wstatus);
const char *signame = strsignal(sig) ?: "unknown ???";
const char *dump = WCOREDUMP(wstatus) ? " (core dumped)" : "";
fprintf(stderr, "%s:%d: kill_qemu() detected QEMU death "
"from signal %d (%s)%s\n",
__FILE__, __LINE__, sig, signame, dump);
}
abort();
} }
} }
} }
...@@ -249,32 +267,33 @@ QTestState *qtest_init_without_qmp_handshake(bool use_oob, ...@@ -249,32 +267,33 @@ QTestState *qtest_init_without_qmp_handshake(bool use_oob,
QTestState *qtest_init(const char *extra_args) QTestState *qtest_init(const char *extra_args)
{ {
QTestState *s = qtest_init_without_qmp_handshake(false, extra_args); QTestState *s = qtest_init_without_qmp_handshake(false, extra_args);
QDict *greeting;
/* Read the QMP greeting and then do the handshake */ /* Read the QMP greeting and then do the handshake */
qtest_qmp_discard_response(s, ""); greeting = qtest_qmp_receive(s);
qtest_qmp_discard_response(s, "{ 'execute': 'qmp_capabilities' }"); qobject_unref(greeting);
qobject_unref(qtest_qmp(s, "{ 'execute': 'qmp_capabilities' }"));
return s; return s;
} }
QTestState *qtest_vstartf(const char *fmt, va_list ap) QTestState *qtest_vinitf(const char *fmt, va_list ap)
{ {
char *args = g_strdup_vprintf(fmt, ap); char *args = g_strdup_vprintf(fmt, ap);
QTestState *s; QTestState *s;
s = qtest_start(args); s = qtest_init(args);
g_free(args); g_free(args);
global_qtest = NULL;
return s; return s;
} }
QTestState *qtest_startf(const char *fmt, ...) QTestState *qtest_initf(const char *fmt, ...)
{ {
va_list ap; va_list ap;
QTestState *s; QTestState *s;
va_start(ap, fmt); va_start(ap, fmt);
s = qtest_vstartf(fmt, ap); s = qtest_vinitf(fmt, ap);
va_end(ap); va_end(ap);
return s; return s;
} }
...@@ -348,7 +367,7 @@ static GString *qtest_recv_line(QTestState *s) ...@@ -348,7 +367,7 @@ static GString *qtest_recv_line(QTestState *s)
if (len == -1 || len == 0) { if (len == -1 || len == 0) {
fprintf(stderr, "Broken pipe\n"); fprintf(stderr, "Broken pipe\n");
exit(1); abort();
} }
g_string_append_len(s->rx, buffer, len); g_string_append_len(s->rx, buffer, len);
...@@ -435,7 +454,7 @@ static void qmp_response(JSONMessageParser *parser, GQueue *tokens) ...@@ -435,7 +454,7 @@ static void qmp_response(JSONMessageParser *parser, GQueue *tokens)
obj = json_parser_parse(tokens, NULL); obj = json_parser_parse(tokens, NULL);
if (!obj) { if (!obj) {
fprintf(stderr, "QMP JSON response parsing failed\n"); fprintf(stderr, "QMP JSON response parsing failed\n");
exit(1); abort();
} }
g_assert(!qmp->response); g_assert(!qmp->response);
...@@ -461,7 +480,7 @@ QDict *qmp_fd_receive(int fd) ...@@ -461,7 +480,7 @@ QDict *qmp_fd_receive(int fd)
if (len == -1 || len == 0) { if (len == -1 || len == 0) {
fprintf(stderr, "Broken pipe\n"); fprintf(stderr, "Broken pipe\n");
exit(1); abort();
} }
if (log) { if (log) {
...@@ -484,26 +503,22 @@ QDict *qtest_qmp_receive(QTestState *s) ...@@ -484,26 +503,22 @@ QDict *qtest_qmp_receive(QTestState *s)
* in the case that they choose to discard all replies up until * in the case that they choose to discard all replies up until
* a particular EVENT is received. * a particular EVENT is received.
*/ */
void qmp_fd_sendv(int fd, const char *fmt, va_list ap) void qmp_fd_vsend(int fd, const char *fmt, va_list ap)
{ {
va_list ap_copy;
QObject *qobj; QObject *qobj;
/* qobject_from_jsonv() silently eats leading 0xff as invalid /*
* JSON, but we want to test sending them over the wire to force * qobject_from_vjsonf_nofail() chokes on leading 0xff as invalid
* resyncs */ * JSON, but tests/test-qga.c needs to send that to test QGA
* synchronization
*/
if (*fmt == '\377') { if (*fmt == '\377') {
socket_send(fd, fmt, 1); socket_send(fd, fmt, 1);
fmt++; fmt++;
} }
/* Going through qobject ensures we escape strings properly. /* Going through qobject ensures we escape strings properly */
* This seemingly unnecessary copy is required in case va_list qobj = qobject_from_vjsonf_nofail(fmt, ap);
* is an array type.
*/
va_copy(ap_copy, ap);
qobj = qobject_from_jsonv(fmt, &ap_copy, &error_abort);
va_end(ap_copy);
/* No need to send anything for an empty QObject. */ /* No need to send anything for an empty QObject. */
if (qobj) { if (qobj) {
...@@ -529,21 +544,21 @@ void qmp_fd_sendv(int fd, const char *fmt, va_list ap) ...@@ -529,21 +544,21 @@ void qmp_fd_sendv(int fd, const char *fmt, va_list ap)
} }
} }
void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap) void qtest_qmp_vsend(QTestState *s, const char *fmt, va_list ap)
{ {
qmp_fd_sendv(s->qmp_fd, fmt, ap); qmp_fd_vsend(s->qmp_fd, fmt, ap);
} }
QDict *qmp_fdv(int fd, const char *fmt, va_list ap) QDict *qmp_fdv(int fd, const char *fmt, va_list ap)
{ {
qmp_fd_sendv(fd, fmt, ap); qmp_fd_vsend(fd, fmt, ap);
return qmp_fd_receive(fd); return qmp_fd_receive(fd);
} }
QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap) QDict *qtest_vqmp(QTestState *s, const char *fmt, va_list ap)
{ {
qtest_async_qmpv(s, fmt, ap); qtest_qmp_vsend(s, fmt, ap);
/* Receive reply */ /* Receive reply */
return qtest_qmp_receive(s); return qtest_qmp_receive(s);
...@@ -565,7 +580,7 @@ void qmp_fd_send(int fd, const char *fmt, ...) ...@@ -565,7 +580,7 @@ void qmp_fd_send(int fd, const char *fmt, ...)
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
qmp_fd_sendv(fd, fmt, ap); qmp_fd_vsend(fd, fmt, ap);
va_end(ap); va_end(ap);
} }
...@@ -575,37 +590,20 @@ QDict *qtest_qmp(QTestState *s, const char *fmt, ...) ...@@ -575,37 +590,20 @@ QDict *qtest_qmp(QTestState *s, const char *fmt, ...)
QDict *response; QDict *response;
va_start(ap, fmt); va_start(ap, fmt);
response = qtest_qmpv(s, fmt, ap); response = qtest_vqmp(s, fmt, ap);
va_end(ap); va_end(ap);
return response; return response;
} }
void qtest_async_qmp(QTestState *s, const char *fmt, ...) void qtest_qmp_send(QTestState *s, const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
qtest_async_qmpv(s, fmt, ap); qtest_qmp_vsend(s, fmt, ap);
va_end(ap); va_end(ap);
} }
void qtest_qmpv_discard_response(QTestState *s, const char *fmt, va_list ap)
{
QDict *response = qtest_qmpv(s, fmt, ap);
qobject_unref(response);
}
void qtest_qmp_discard_response(QTestState *s, const char *fmt, ...)
{
va_list ap;
QDict *response;
va_start(ap, fmt);
response = qtest_qmpv(s, fmt, ap);
va_end(ap);
qobject_unref(response);
}
QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event) QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event)
{ {
QDict *response; QDict *response;
...@@ -628,7 +626,7 @@ void qtest_qmp_eventwait(QTestState *s, const char *event) ...@@ -628,7 +626,7 @@ void qtest_qmp_eventwait(QTestState *s, const char *event)
qobject_unref(response); qobject_unref(response);
} }
char *qtest_hmpv(QTestState *s, const char *fmt, va_list ap) char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap)
{ {
char *cmd; char *cmd;
QDict *resp; QDict *resp;
...@@ -657,7 +655,7 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) ...@@ -657,7 +655,7 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...)
char *ret; char *ret;
va_start(ap, fmt); va_start(ap, fmt);
ret = qtest_hmpv(s, fmt, ap); ret = qtest_vhmp(s, fmt, ap);
va_end(ap); va_end(ap);
return ret; return ret;
} }
...@@ -963,35 +961,27 @@ QDict *qmp(const char *fmt, ...) ...@@ -963,35 +961,27 @@ QDict *qmp(const char *fmt, ...)
QDict *response; QDict *response;
va_start(ap, fmt); va_start(ap, fmt);
response = qtest_qmpv(global_qtest, fmt, ap); response = qtest_vqmp(global_qtest, fmt, ap);
va_end(ap); va_end(ap);
return response; return response;
} }
void qmp_async(const char *fmt, ...) void qmp_send(const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
qtest_async_qmpv(global_qtest, fmt, ap); qtest_qmp_vsend(global_qtest, fmt, ap);
va_end(ap); va_end(ap);
} }
void qmp_discard_response(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
qtest_qmpv_discard_response(global_qtest, fmt, ap);
va_end(ap);
}
char *hmp(const char *fmt, ...) char *hmp(const char *fmt, ...)
{ {
va_list ap; va_list ap;
char *ret; char *ret;
va_start(ap, fmt); va_start(ap, fmt);
ret = qtest_hmpv(global_qtest, fmt, ap); ret = qtest_vhmp(global_qtest, fmt, ap);
va_end(ap); va_end(ap);
return ret; return ret;
} }
...@@ -1031,35 +1021,67 @@ void qtest_cb_for_every_machine(void (*cb)(const char *machine)) ...@@ -1031,35 +1021,67 @@ void qtest_cb_for_every_machine(void (*cb)(const char *machine))
qobject_unref(response); qobject_unref(response);
} }
QDict *qtest_qmp_receive_success(QTestState *s,
void (*event_cb)(void *opaque,
const char *event,
QDict *data),
void *opaque)
{
QDict *response, *ret, *data;
const char *event;
for (;;) {
response = qtest_qmp_receive(s);
g_assert(!qdict_haskey(response, "error"));
ret = qdict_get_qdict(response, "return");
if (ret) {
break;
}
event = qdict_get_str(response, "event");
data = qdict_get_qdict(response, "data");
if (event_cb) {
event_cb(opaque, event, data);
}
qobject_unref(response);
}
qobject_ref(ret);
qobject_unref(response);
return ret;
}
/* /*
* Generic hot-plugging test via the device_add QMP command. * Generic hot-plugging test via the device_add QMP command.
*/ */
void qtest_qmp_device_add(const char *driver, const char *id, const char *fmt, void qtest_qmp_device_add(const char *driver, const char *id,
...) const char *fmt, ...)
{ {
QDict *response; QDict *args, *response;
char *cmd, *opts = NULL; va_list ap;
va_list va;
if (fmt) { va_start(ap, fmt);
va_start(va, fmt); args = qdict_from_vjsonf_nofail(fmt, ap);
opts = g_strdup_vprintf(fmt, va); va_end(ap);
va_end(va);
}
cmd = g_strdup_printf("{'execute': 'device_add'," g_assert(!qdict_haskey(args, "driver") && !qdict_haskey(args, "id"));
" 'arguments': { 'driver': '%s', 'id': '%s'%s%s }}", qdict_put_str(args, "driver", driver);
driver, id, opts ? ", " : "", opts ? opts : ""); qdict_put_str(args, "id", id);
g_free(opts);
response = qmp(cmd); response = qmp("{'execute': 'device_add', 'arguments': %p}", args);
g_free(cmd);
g_assert(response); g_assert(response);
g_assert(!qdict_haskey(response, "event")); /* We don't expect any events */ g_assert(!qdict_haskey(response, "event")); /* We don't expect any events */
g_assert(!qdict_haskey(response, "error")); g_assert(!qdict_haskey(response, "error"));
qobject_unref(response); qobject_unref(response);
} }
static void device_deleted_cb(void *opaque, const char *name, QDict *data)
{
bool *got_event = opaque;
g_assert_cmpstr(name, ==, "DEVICE_DELETED");
*got_event = true;
}
/* /*
* Generic hot-unplugging test via the device_del QMP command. * Generic hot-unplugging test via the device_del QMP command.
* Device deletion will get one response and one event. For example: * Device deletion will get one response and one event. For example:
...@@ -1080,30 +1102,21 @@ void qtest_qmp_device_add(const char *driver, const char *id, const char *fmt, ...@@ -1080,30 +1102,21 @@ void qtest_qmp_device_add(const char *driver, const char *id, const char *fmt,
*/ */
void qtest_qmp_device_del(const char *id) void qtest_qmp_device_del(const char *id)
{ {
QDict *response1, *response2, *event = NULL; bool got_event = false;
char *cmd; QDict *rsp;
cmd = g_strdup_printf("{'execute': 'device_del',"
" 'arguments': { 'id': '%s' }}", id);
response1 = qmp(cmd);
g_free(cmd);
g_assert(response1);
g_assert(!qdict_haskey(response1, "error"));
response2 = qmp(""); qtest_qmp_send(global_qtest,
g_assert(response2); "{'execute': 'device_del', 'arguments': {'id': %s}}",
g_assert(!qdict_haskey(response2, "error")); id);
rsp = qtest_qmp_receive_success(global_qtest, device_deleted_cb,
if (qdict_haskey(response1, "event")) { &got_event);
event = response1; qobject_unref(rsp);
} else if (qdict_haskey(response2, "event")) { if (!got_event) {
event = response2; rsp = qmp_receive();
g_assert_cmpstr(qdict_get_try_str(rsp, "event"),
==, "DEVICE_DELETED");
qobject_unref(rsp);
} }
g_assert(event);
g_assert_cmpstr(qdict_get_str(event, "event"), ==, "DEVICE_DELETED");
qobject_unref(response1);
qobject_unref(response2);
} }
bool qmp_rsp_is_err(QDict *rsp) bool qmp_rsp_is_err(QDict *rsp)
......
...@@ -22,33 +22,32 @@ typedef struct QTestState QTestState; ...@@ -22,33 +22,32 @@ typedef struct QTestState QTestState;
extern QTestState *global_qtest; extern QTestState *global_qtest;
/** /**
* qtest_startf: * qtest_initf:
* @fmt...: Format for creating other arguments to pass to QEMU, formatted * @fmt...: Format for creating other arguments to pass to QEMU, formatted
* like sprintf(). * like sprintf().
* *
* Start QEMU and return the resulting #QTestState (but unlike qtest_start(), * Convenience wrapper around qtest_start().
* #global_qtest is left at NULL).
* *
* Returns: #QTestState instance. * Returns: #QTestState instance.
*/ */
QTestState *qtest_startf(const char *fmt, ...) GCC_FMT_ATTR(1, 2); QTestState *qtest_initf(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
/** /**
* qtest_vstartf: * qtest_vinitf:
* @fmt: Format for creating other arguments to pass to QEMU, formatted * @fmt: Format for creating other arguments to pass to QEMU, formatted
* like vsprintf(). * like vsprintf().
* @ap: Format arguments. * @ap: Format arguments.
* *
* Start QEMU and return the resulting #QTestState (but unlike qtest_start(), * Convenience wrapper around qtest_start().
* #global_qtest is left at NULL).
* *
* Returns: #QTestState instance. * Returns: #QTestState instance.
*/ */
QTestState *qtest_vstartf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); QTestState *qtest_vinitf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0);
/** /**
* qtest_init: * qtest_init:
* @extra_args: other arguments to pass to QEMU. * @extra_args: other arguments to pass to QEMU. CAUTION: these
* arguments are subject to word splitting and shell evaluation.
* *
* Returns: #QTestState instance. * Returns: #QTestState instance.
*/ */
...@@ -73,62 +72,55 @@ QTestState *qtest_init_without_qmp_handshake(bool use_oob, ...@@ -73,62 +72,55 @@ QTestState *qtest_init_without_qmp_handshake(bool use_oob,
*/ */
void qtest_quit(QTestState *s); void qtest_quit(QTestState *s);
/**
* qtest_qmp_discard_response:
* @s: #QTestState instance to operate on.
* @fmt...: QMP message to send to qemu
*
* Sends a QMP message to QEMU and consumes the response.
*/
void qtest_qmp_discard_response(QTestState *s, const char *fmt, ...);
/** /**
* qtest_qmp: * qtest_qmp:
* @s: #QTestState instance to operate on. * @s: #QTestState instance to operate on.
* @fmt...: QMP message to send to qemu * @fmt...: QMP message to send to qemu, formatted like
* qobject_from_jsonf_nofail(). See parse_escape() for what's
* supported after '%'.
* *
* Sends a QMP message to QEMU and returns the response. * Sends a QMP message to QEMU and returns the response.
*/ */
QDict *qtest_qmp(QTestState *s, const char *fmt, ...); QDict *qtest_qmp(QTestState *s, const char *fmt, ...)
GCC_FMT_ATTR(2, 3);
/** /**
* qtest_async_qmp: * qtest_qmp_send:
* @s: #QTestState instance to operate on. * @s: #QTestState instance to operate on.
* @fmt...: QMP message to send to qemu * @fmt...: QMP message to send to qemu, formatted like
* qobject_from_jsonf_nofail(). See parse_escape() for what's
* supported after '%'.
* *
* Sends a QMP message to QEMU and leaves the response in the stream. * Sends a QMP message to QEMU and leaves the response in the stream.
*/ */
void qtest_async_qmp(QTestState *s, const char *fmt, ...); void qtest_qmp_send(QTestState *s, const char *fmt, ...)
GCC_FMT_ATTR(2, 3);
/**
* qtest_qmpv_discard_response:
* @s: #QTestState instance to operate on.
* @fmt: QMP message to send to QEMU
* @ap: QMP message arguments
*
* Sends a QMP message to QEMU and consumes the response.
*/
void qtest_qmpv_discard_response(QTestState *s, const char *fmt, va_list ap);
/** /**
* qtest_qmpv: * qtest_qmpv:
* @s: #QTestState instance to operate on. * @s: #QTestState instance to operate on.
* @fmt: QMP message to send to QEMU * @fmt: QMP message to send to QEMU, formatted like
* qobject_from_jsonf_nofail(). See parse_escape() for what's
* supported after '%'.
* @ap: QMP message arguments * @ap: QMP message arguments
* *
* Sends a QMP message to QEMU and returns the response. * Sends a QMP message to QEMU and returns the response.
*/ */
QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap); QDict *qtest_vqmp(QTestState *s, const char *fmt, va_list ap)
GCC_FMT_ATTR(2, 0);
/** /**
* qtest_async_qmpv: * qtest_qmp_vsend:
* @s: #QTestState instance to operate on. * @s: #QTestState instance to operate on.
* @fmt: QMP message to send to QEMU * @fmt: QMP message to send to QEMU, formatted like
* qobject_from_jsonf_nofail(). See parse_escape() for what's
* supported after '%'.
* @ap: QMP message arguments * @ap: QMP message arguments
* *
* Sends a QMP message to QEMU and leaves the response in the stream. * Sends a QMP message to QEMU and leaves the response in the stream.
*/ */
void qtest_async_qmpv(QTestState *s, const char *fmt, va_list ap); void qtest_qmp_vsend(QTestState *s, const char *fmt, va_list ap)
GCC_FMT_ATTR(2, 0);
/** /**
* qtest_receive: * qtest_receive:
...@@ -157,6 +149,23 @@ void qtest_qmp_eventwait(QTestState *s, const char *event); ...@@ -157,6 +149,23 @@ void qtest_qmp_eventwait(QTestState *s, const char *event);
*/ */
QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event); QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event);
/**
* qtest_qmp_receive_success:
* @s: #QTestState instance to operate on
* @event_cb: Event callback
* @opaque: Argument for @event_cb
*
* Poll QMP messages until a command success response is received.
* If @event_cb, call it for each event received, passing @opaque,
* the event's name and data.
* Return the success response's "return" member.
*/
QDict *qtest_qmp_receive_success(QTestState *s,
void (*event_cb)(void *opaque,
const char *name,
QDict *data),
void *opaque);
/** /**
* qtest_hmp: * qtest_hmp:
* @s: #QTestState instance to operate on. * @s: #QTestState instance to operate on.
...@@ -172,7 +181,7 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3); ...@@ -172,7 +181,7 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
/** /**
* qtest_hmpv: * qtest_hmpv:
* @s: #QTestState instance to operate on. * @s: #QTestState instance to operate on.
* @fmt: HMP command to send to QEMU * @fmt: HMP command to send to QEMU, formats arguments like vsprintf().
* @ap: HMP command arguments * @ap: HMP command arguments
* *
* Send HMP command to QEMU via QMP's human-monitor-command. * Send HMP command to QEMU via QMP's human-monitor-command.
...@@ -180,7 +189,8 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3); ...@@ -180,7 +189,8 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
* *
* Returns: the command's output. The caller should g_free() it. * Returns: the command's output. The caller should g_free() it.
*/ */
char *qtest_hmpv(QTestState *s, const char *fmt, va_list ap); char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap)
GCC_FMT_ATTR(2, 0);
/** /**
* qtest_get_irq: * qtest_get_irq:
...@@ -561,27 +571,23 @@ static inline void qtest_end(void) ...@@ -561,27 +571,23 @@ static inline void qtest_end(void)
/** /**
* qmp: * qmp:
* @fmt...: QMP message to send to qemu * @fmt...: QMP message to send to qemu, formatted like
* qobject_from_jsonf_nofail(). See parse_escape() for what's
* supported after '%'.
* *
* Sends a QMP message to QEMU and returns the response. * Sends a QMP message to QEMU and returns the response.
*/ */
QDict *qmp(const char *fmt, ...); QDict *qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
/** /**
* qmp_async: * qmp_send:
* @fmt...: QMP message to send to qemu * @fmt...: QMP message to send to qemu, formatted like
* qobject_from_jsonf_nofail(). See parse_escape() for what's
* supported after '%'.
* *
* Sends a QMP message to QEMU and leaves the response in the stream. * Sends a QMP message to QEMU and leaves the response in the stream.
*/ */
void qmp_async(const char *fmt, ...); void qmp_send(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
/**
* qmp_discard_response:
* @fmt...: QMP message to send to qemu
*
* Sends a QMP message to QEMU and consumes the response.
*/
void qmp_discard_response(const char *fmt, ...);
/** /**
* qmp_receive: * qmp_receive:
...@@ -940,10 +946,10 @@ static inline int64_t clock_set(int64_t val) ...@@ -940,10 +946,10 @@ static inline int64_t clock_set(int64_t val)
} }
QDict *qmp_fd_receive(int fd); QDict *qmp_fd_receive(int fd);
void qmp_fd_sendv(int fd, const char *fmt, va_list ap); void qmp_fd_vsend(int fd, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0);
void qmp_fd_send(int fd, const char *fmt, ...); void qmp_fd_send(int fd, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
QDict *qmp_fdv(int fd, const char *fmt, va_list ap); QDict *qmp_fdv(int fd, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0);
QDict *qmp_fd(int fd, const char *fmt, ...); QDict *qmp_fd(int fd, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
/** /**
* qtest_cb_for_every_machine: * qtest_cb_for_every_machine:
...@@ -957,7 +963,9 @@ void qtest_cb_for_every_machine(void (*cb)(const char *machine)); ...@@ -957,7 +963,9 @@ void qtest_cb_for_every_machine(void (*cb)(const char *machine));
* qtest_qmp_device_add: * qtest_qmp_device_add:
* @driver: Name of the device that should be added * @driver: Name of the device that should be added
* @id: Identification string * @id: Identification string
* @fmt: printf-like format string for further options to device_add * @fmt...: QMP message to send to qemu, formatted like
* qobject_from_jsonf_nofail(). See parse_escape() for what's
* supported after '%'.
* *
* Generic hot-plugging test via the device_add QMP command. * Generic hot-plugging test via the device_add QMP command.
*/ */
......
...@@ -363,9 +363,9 @@ int main(int argc, char **argv) ...@@ -363,9 +363,9 @@ int main(int argc, char **argv)
g_assert(ret == 0); g_assert(ret == 0);
close(fd); close(fd);
global_qtest = qtest_startf("-m 256 -machine palmetto-bmc " global_qtest = qtest_initf("-m 256 -machine palmetto-bmc "
"-drive file=%s,format=raw,if=mtd", "-drive file=%s,format=raw,if=mtd",
tmp_path); tmp_path);
qtest_add_func("/m25p80/read_jedec", test_read_jedec); qtest_add_func("/m25p80/read_jedec", test_read_jedec);
qtest_add_func("/m25p80/erase_sector", test_erase_sector); qtest_add_func("/m25p80/erase_sector", test_erase_sector);
......
...@@ -146,7 +146,7 @@ static void cmos_get_date_time(QTestState *s, struct tm *date) ...@@ -146,7 +146,7 @@ static void cmos_get_date_time(QTestState *s, struct tm *date)
static QTestState *m48t59_qtest_start(void) static QTestState *m48t59_qtest_start(void)
{ {
return qtest_startf("-M %s -rtc clock=vm", base_machine); return qtest_initf("-M %s -rtc clock=vm", base_machine);
} }
static void bcd_check_time(void) static void bcd_check_time(void)
......
...@@ -84,7 +84,7 @@ static void test_machine_cpu_cli(void) ...@@ -84,7 +84,7 @@ static void test_machine_cpu_cli(void)
} }
return; /* TODO: die here to force all targets have a test */ return; /* TODO: die here to force all targets have a test */
} }
global_qtest = qtest_startf("-machine none -cpu '%s'", cpu_model); global_qtest = qtest_initf("-machine none -cpu '%s'", cpu_model);
response = qmp("{ 'execute': 'quit' }"); response = qmp("{ 'execute': 'quit' }");
g_assert(qdict_haskey(response, "return")); g_assert(qdict_haskey(response, "return"));
......
...@@ -14,12 +14,16 @@ ...@@ -14,12 +14,16 @@
#include "libqtest.h" #include "libqtest.h"
#include "qapi/qmp/qdict.h" #include "qapi/qmp/qdict.h"
#include "qapi/qmp/qjson.h"
#include "qemu/option.h" #include "qemu/option.h"
#include "qemu/range.h" #include "qemu/range.h"
#include "qemu/sockets.h" #include "qemu/sockets.h"
#include "chardev/char.h" #include "chardev/char.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
/* TODO actually test the results and get rid of this */
#define qtest_qmp_discard_response(...) qobject_unref(qtest_qmp(__VA_ARGS__))
const unsigned start_address = 1024 * 1024; const unsigned start_address = 1024 * 1024;
const unsigned end_address = 100 * 1024 * 1024; const unsigned end_address = 100 * 1024 * 1024;
bool got_stop; bool got_stop;
...@@ -146,26 +150,26 @@ static void wait_for_serial(const char *side) ...@@ -146,26 +150,26 @@ static void wait_for_serial(const char *side)
} while (true); } while (true);
} }
static void stop_cb(void *opaque, const char *name, QDict *data)
{
if (!strcmp(name, "STOP")) {
got_stop = true;
}
}
/* /*
* Events can get in the way of responses we are actually waiting for. * Events can get in the way of responses we are actually waiting for.
*/ */
static QDict *wait_command(QTestState *who, const char *command) GCC_FMT_ATTR(2, 3)
static QDict *wait_command(QTestState *who, const char *command, ...)
{ {
const char *event_string; va_list ap;
QDict *response;
response = qtest_qmp(who, command); va_start(ap, command);
qtest_qmp_vsend(who, command, ap);
va_end(ap);
while (qdict_haskey(response, "event")) { return qtest_qmp_receive_success(who, stop_cb, NULL);
/* OK, it was an event */
event_string = qdict_get_str(response, "event");
if (!strcmp(event_string, "STOP")) {
got_stop = true;
}
qobject_unref(response);
response = qtest_qmp_receive(who);
}
return response;
} }
/* /*
...@@ -174,15 +178,7 @@ static QDict *wait_command(QTestState *who, const char *command) ...@@ -174,15 +178,7 @@ static QDict *wait_command(QTestState *who, const char *command)
*/ */
static QDict *migrate_query(QTestState *who) static QDict *migrate_query(QTestState *who)
{ {
QDict *rsp, *rsp_return; return wait_command(who, "{ 'execute': 'query-migrate' }");
rsp = wait_command(who, "{ 'execute': 'query-migrate' }");
rsp_return = qdict_get_qdict(rsp, "return");
g_assert(rsp_return);
qobject_ref(rsp_return);
qobject_unref(rsp);
return rsp_return;
} }
/* /*
...@@ -322,31 +318,25 @@ static void cleanup(const char *filename) ...@@ -322,31 +318,25 @@ static void cleanup(const char *filename)
} }
static void migrate_check_parameter(QTestState *who, const char *parameter, static void migrate_check_parameter(QTestState *who, const char *parameter,
const char *value) long long value)
{ {
QDict *rsp, *rsp_return; QDict *rsp_return;
char *result;
rsp = wait_command(who, "{ 'execute': 'query-migrate-parameters' }"); rsp_return = wait_command(who,
rsp_return = qdict_get_qdict(rsp, "return"); "{ 'execute': 'query-migrate-parameters' }");
result = g_strdup_printf("%" PRId64, g_assert_cmpint(qdict_get_int(rsp_return, parameter), ==, value);
qdict_get_try_int(rsp_return, parameter, -1)); qobject_unref(rsp_return);
g_assert_cmpstr(result, ==, value);
g_free(result);
qobject_unref(rsp);
} }
static void migrate_set_parameter(QTestState *who, const char *parameter, static void migrate_set_parameter(QTestState *who, const char *parameter,
const char *value) long long value)
{ {
QDict *rsp; QDict *rsp;
gchar *cmd;
cmd = g_strdup_printf("{ 'execute': 'migrate-set-parameters'," rsp = qtest_qmp(who,
"'arguments': { '%s': %s } }", "{ 'execute': 'migrate-set-parameters',"
parameter, value); "'arguments': { %s: %lld } }",
rsp = qtest_qmp(who, cmd); parameter, value);
g_free(cmd);
g_assert(qdict_haskey(rsp, "return")); g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);
migrate_check_parameter(who, parameter, value); migrate_check_parameter(who, parameter, value);
...@@ -357,51 +347,55 @@ static void migrate_pause(QTestState *who) ...@@ -357,51 +347,55 @@ static void migrate_pause(QTestState *who)
QDict *rsp; QDict *rsp;
rsp = wait_command(who, "{ 'execute': 'migrate-pause' }"); rsp = wait_command(who, "{ 'execute': 'migrate-pause' }");
g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);
} }
static void migrate_recover(QTestState *who, const char *uri) static void migrate_recover(QTestState *who, const char *uri)
{ {
QDict *rsp; QDict *rsp;
gchar *cmd = g_strdup_printf(
"{ 'execute': 'migrate-recover', "
" 'id': 'recover-cmd', "
" 'arguments': { 'uri': '%s' } }", uri);
rsp = wait_command(who, cmd); rsp = wait_command(who,
g_assert(qdict_haskey(rsp, "return")); "{ 'execute': 'migrate-recover', "
g_free(cmd); " 'id': 'recover-cmd', "
" 'arguments': { 'uri': %s } }",
uri);
qobject_unref(rsp); qobject_unref(rsp);
} }
static void migrate_set_capability(QTestState *who, const char *capability, static void migrate_set_capability(QTestState *who, const char *capability,
const char *value) bool value)
{ {
QDict *rsp; QDict *rsp;
gchar *cmd;
rsp = qtest_qmp(who,
cmd = g_strdup_printf("{ 'execute': 'migrate-set-capabilities'," "{ 'execute': 'migrate-set-capabilities',"
"'arguments': { " "'arguments': { "
"'capabilities': [ { " "'capabilities': [ { "
"'capability': '%s', 'state': %s } ] } }", "'capability': %s, 'state': %i } ] } }",
capability, value); capability, value);
rsp = qtest_qmp(who, cmd);
g_free(cmd);
g_assert(qdict_haskey(rsp, "return")); g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);
} }
static void migrate(QTestState *who, const char *uri, const char *extra) /*
* Send QMP command "migrate".
* Arguments are built from @fmt... (formatted like
* qobject_from_jsonf_nofail()) with "uri": @uri spliced in.
*/
GCC_FMT_ATTR(3, 4)
static void migrate(QTestState *who, const char *uri, const char *fmt, ...)
{ {
QDict *rsp; va_list ap;
gchar *cmd; QDict *args, *rsp;
va_start(ap, fmt);
args = qdict_from_vjsonf_nofail(fmt, ap);
va_end(ap);
g_assert(!qdict_haskey(args, "uri"));
qdict_put_str(args, "uri", uri);
cmd = g_strdup_printf("{ 'execute': 'migrate'," rsp = qmp("{ 'execute': 'migrate', 'arguments': %p}", args);
" 'arguments': { 'uri': '%s' %s } }",
uri, extra ? extra : "");
rsp = qtest_qmp(who, cmd);
g_free(cmd);
g_assert(qdict_haskey(rsp, "return")); g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);
} }
...@@ -411,7 +405,6 @@ static void migrate_postcopy_start(QTestState *from, QTestState *to) ...@@ -411,7 +405,6 @@ static void migrate_postcopy_start(QTestState *from, QTestState *to)
QDict *rsp; QDict *rsp;
rsp = wait_command(from, "{ 'execute': 'migrate-start-postcopy' }"); rsp = wait_command(from, "{ 'execute': 'migrate-start-postcopy' }");
g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);
if (!got_stop) { if (!got_stop) {
...@@ -529,31 +522,21 @@ static void test_migrate_end(QTestState *from, QTestState *to, bool test_dest) ...@@ -529,31 +522,21 @@ static void test_migrate_end(QTestState *from, QTestState *to, bool test_dest)
static void deprecated_set_downtime(QTestState *who, const double value) static void deprecated_set_downtime(QTestState *who, const double value)
{ {
QDict *rsp; QDict *rsp;
gchar *cmd;
char *expected; rsp = qtest_qmp(who,
int64_t result_int; "{ 'execute': 'migrate_set_downtime',"
" 'arguments': { 'value': %f } }", value);
cmd = g_strdup_printf("{ 'execute': 'migrate_set_downtime',"
"'arguments': { 'value': %g } }", value);
rsp = qtest_qmp(who, cmd);
g_free(cmd);
g_assert(qdict_haskey(rsp, "return")); g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);
result_int = value * 1000L; migrate_check_parameter(who, "downtime-limit", value * 1000);
expected = g_strdup_printf("%" PRId64, result_int);
migrate_check_parameter(who, "downtime-limit", expected);
g_free(expected);
} }
static void deprecated_set_speed(QTestState *who, const char *value) static void deprecated_set_speed(QTestState *who, long long value)
{ {
QDict *rsp; QDict *rsp;
gchar *cmd;
cmd = g_strdup_printf("{ 'execute': 'migrate_set_speed'," rsp = qtest_qmp(who, "{ 'execute': 'migrate_set_speed',"
"'arguments': { 'value': %s } }", value); "'arguments': { 'value': %lld } }", value);
rsp = qtest_qmp(who, cmd);
g_free(cmd);
g_assert(qdict_haskey(rsp, "return")); g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);
migrate_check_parameter(who, "max-bandwidth", value); migrate_check_parameter(who, "max-bandwidth", value);
...@@ -566,7 +549,7 @@ static void test_deprecated(void) ...@@ -566,7 +549,7 @@ static void test_deprecated(void)
from = qtest_start(""); from = qtest_start("");
deprecated_set_downtime(from, 0.12345); deprecated_set_downtime(from, 0.12345);
deprecated_set_speed(from, "12345"); deprecated_set_speed(from, 12345);
qtest_quit(from); qtest_quit(from);
} }
...@@ -582,21 +565,21 @@ static int migrate_postcopy_prepare(QTestState **from_ptr, ...@@ -582,21 +565,21 @@ static int migrate_postcopy_prepare(QTestState **from_ptr,
return -1; return -1;
} }
migrate_set_capability(from, "postcopy-ram", "true"); migrate_set_capability(from, "postcopy-ram", true);
migrate_set_capability(to, "postcopy-ram", "true"); migrate_set_capability(to, "postcopy-ram", true);
migrate_set_capability(to, "postcopy-blocktime", "true"); migrate_set_capability(to, "postcopy-blocktime", true);
/* We want to pick a speed slow enough that the test completes /* We want to pick a speed slow enough that the test completes
* quickly, but that it doesn't complete precopy even on a slow * quickly, but that it doesn't complete precopy even on a slow
* machine, so also set the downtime. * machine, so also set the downtime.
*/ */
migrate_set_parameter(from, "max-bandwidth", "100000000"); migrate_set_parameter(from, "max-bandwidth", 100000000);
migrate_set_parameter(from, "downtime-limit", "1"); migrate_set_parameter(from, "downtime-limit", 1);
/* Wait for the first serial output from the source */ /* Wait for the first serial output from the source */
wait_for_serial("src_serial"); wait_for_serial("src_serial");
migrate(from, uri, NULL); migrate(from, uri, "{}");
g_free(uri); g_free(uri);
wait_for_migration_pass(from); wait_for_migration_pass(from);
...@@ -642,7 +625,7 @@ static void test_postcopy_recovery(void) ...@@ -642,7 +625,7 @@ static void test_postcopy_recovery(void)
} }
/* Turn postcopy speed down, 4K/s is slow enough on any machines */ /* Turn postcopy speed down, 4K/s is slow enough on any machines */
migrate_set_parameter(from, "max-postcopy-bandwidth", "4096"); migrate_set_parameter(from, "max-postcopy-bandwidth", 4096);
/* Now we start the postcopy */ /* Now we start the postcopy */
migrate_postcopy_start(from, to); migrate_postcopy_start(from, to);
...@@ -679,11 +662,11 @@ static void test_postcopy_recovery(void) ...@@ -679,11 +662,11 @@ static void test_postcopy_recovery(void)
* the newly created channel * the newly created channel
*/ */
wait_for_migration_status(from, "postcopy-paused"); wait_for_migration_status(from, "postcopy-paused");
migrate(from, uri, ", 'resume': true"); migrate(from, uri, "{'resume': true}");
g_free(uri); g_free(uri);
/* Restore the postcopy bandwidth to unlimited */ /* Restore the postcopy bandwidth to unlimited */
migrate_set_parameter(from, "max-postcopy-bandwidth", "0"); migrate_set_parameter(from, "max-postcopy-bandwidth", 0);
migrate_postcopy_complete(from, to); migrate_postcopy_complete(from, to);
} }
...@@ -691,14 +674,14 @@ static void test_postcopy_recovery(void) ...@@ -691,14 +674,14 @@ static void test_postcopy_recovery(void)
static void test_baddest(void) static void test_baddest(void)
{ {
QTestState *from, *to; QTestState *from, *to;
QDict *rsp, *rsp_return; QDict *rsp_return;
char *status; char *status;
bool failed; bool failed;
if (test_migrate_start(&from, &to, "tcp:0:0", true)) { if (test_migrate_start(&from, &to, "tcp:0:0", true)) {
return; return;
} }
migrate(from, "tcp:0:0", NULL); migrate(from, "tcp:0:0", "{}");
do { do {
status = migrate_query_status(from); status = migrate_query_status(from);
g_assert(!strcmp(status, "setup") || !(strcmp(status, "failed"))); g_assert(!strcmp(status, "setup") || !(strcmp(status, "failed")));
...@@ -707,12 +690,10 @@ static void test_baddest(void) ...@@ -707,12 +690,10 @@ static void test_baddest(void)
} while (!failed); } while (!failed);
/* Is the machine currently running? */ /* Is the machine currently running? */
rsp = wait_command(from, "{ 'execute': 'query-status' }"); rsp_return = wait_command(from, "{ 'execute': 'query-status' }");
g_assert(qdict_haskey(rsp, "return"));
rsp_return = qdict_get_qdict(rsp, "return");
g_assert(qdict_haskey(rsp_return, "running")); g_assert(qdict_haskey(rsp_return, "running"));
g_assert(qdict_get_bool(rsp_return, "running")); g_assert(qdict_get_bool(rsp_return, "running"));
qobject_unref(rsp); qobject_unref(rsp_return);
test_migrate_end(from, to, false); test_migrate_end(from, to, false);
} }
...@@ -731,19 +712,19 @@ static void test_precopy_unix(void) ...@@ -731,19 +712,19 @@ static void test_precopy_unix(void)
* machine, so also set the downtime. * machine, so also set the downtime.
*/ */
/* 1 ms should make it not converge*/ /* 1 ms should make it not converge*/
migrate_set_parameter(from, "downtime-limit", "1"); migrate_set_parameter(from, "downtime-limit", 1);
/* 1GB/s */ /* 1GB/s */
migrate_set_parameter(from, "max-bandwidth", "1000000000"); migrate_set_parameter(from, "max-bandwidth", 1000000000);
/* Wait for the first serial output from the source */ /* Wait for the first serial output from the source */
wait_for_serial("src_serial"); wait_for_serial("src_serial");
migrate(from, uri, NULL); migrate(from, uri, "{}");
wait_for_migration_pass(from); wait_for_migration_pass(from);
/* 300 ms should converge */ /* 300 ms should converge */
migrate_set_parameter(from, "downtime-limit", "300"); migrate_set_parameter(from, "downtime-limit", 300);
if (!got_stop) { if (!got_stop) {
qtest_qmp_eventwait(from, "STOP"); qtest_qmp_eventwait(from, "STOP");
......
...@@ -267,8 +267,8 @@ static void pc_dynamic_cpu_cfg(const void *data) ...@@ -267,8 +267,8 @@ static void pc_dynamic_cpu_cfg(const void *data)
QList *cpus; QList *cpus;
QTestState *qs; QTestState *qs;
qs = qtest_startf("%s %s", data ? (char *)data : "", qs = qtest_initf("%s -nodefaults --preconfig -smp 2",
"-nodefaults --preconfig -smp 2"); data ? (char *)data : "");
/* create 2 numa nodes */ /* create 2 numa nodes */
g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node'," g_assert(!qmp_rsp_is_err(qtest_qmp(qs, "{ 'execute': 'set-numa-node',"
......
...@@ -79,8 +79,8 @@ static void test_cfam_id(const void *data) ...@@ -79,8 +79,8 @@ static void test_cfam_id(const void *data)
{ {
const PnvChip *chip = data; const PnvChip *chip = data;
global_qtest = qtest_startf("-M powernv,accel=tcg -cpu %s", global_qtest = qtest_initf("-M powernv,accel=tcg -cpu %s",
chip->cpu_model); chip->cpu_model);
test_xscom_cfam_id(chip); test_xscom_cfam_id(chip);
qtest_quit(global_qtest); qtest_quit(global_qtest);
} }
...@@ -114,8 +114,8 @@ static void test_core(const void *data) ...@@ -114,8 +114,8 @@ static void test_core(const void *data)
{ {
const PnvChip *chip = data; const PnvChip *chip = data;
global_qtest = qtest_startf("-M powernv,accel=tcg -cpu %s", global_qtest = qtest_initf("-M powernv,accel=tcg -cpu %s",
chip->cpu_model); chip->cpu_model);
test_xscom_core(chip); test_xscom_core(chip);
qtest_quit(global_qtest); qtest_quit(global_qtest);
} }
......
...@@ -49,11 +49,11 @@ static void test_machine(const void *machine) ...@@ -49,11 +49,11 @@ static void test_machine(const void *machine)
/* The pseries firmware boots much faster without the default devices */ /* The pseries firmware boots much faster without the default devices */
extra_args = strcmp(machine, "pseries") == 0 ? "-nodefaults" : ""; extra_args = strcmp(machine, "pseries") == 0 ? "-nodefaults" : "";
global_qtest = qtest_startf("-M %s,accel=tcg %s " global_qtest = qtest_initf("-M %s,accel=tcg %s "
"-prom-env 'use-nvramrc?=true' " "-prom-env 'use-nvramrc?=true' "
"-prom-env 'nvramrc=%x %x l!' ", "-prom-env 'nvramrc=%x %x l!' ",
(const char *)machine, extra_args, (const char *)machine, extra_args,
MAGIC, ADDRESS); MAGIC, ADDRESS);
check_guest_memory(); check_guest_memory();
qtest_quit(global_qtest); qtest_quit(global_qtest);
} }
......
...@@ -159,12 +159,12 @@ static void cleanup_blocking_cmd(void) ...@@ -159,12 +159,12 @@ static void cleanup_blocking_cmd(void)
static void send_cmd_that_blocks(QTestState *s, const char *id) static void send_cmd_that_blocks(QTestState *s, const char *id)
{ {
qtest_async_qmp(s, "{ 'execute': 'blockdev-add', 'id': %s," qtest_qmp_send(s, "{ 'execute': 'blockdev-add', 'id': %s,"
" 'arguments': {" " 'arguments': {"
" 'driver': 'blkdebug', 'node-name': %s," " 'driver': 'blkdebug', 'node-name': %s,"
" 'config': %s," " 'config': %s,"
" 'image': { 'driver': 'null-co' } } }", " 'image': { 'driver': 'null-co' } } }",
id, id, fifo_name); id, id, fifo_name);
} }
static void unblock_blocked_cmd(void) static void unblock_blocked_cmd(void)
...@@ -176,7 +176,7 @@ static void unblock_blocked_cmd(void) ...@@ -176,7 +176,7 @@ static void unblock_blocked_cmd(void)
static void send_oob_cmd_that_fails(QTestState *s, const char *id) static void send_oob_cmd_that_fails(QTestState *s, const char *id)
{ {
qtest_async_qmp(s, "{ 'exec-oob': 'migrate-pause', 'id': %s }", id); qtest_qmp_send(s, "{ 'exec-oob': 'migrate-pause', 'id': %s }", id);
} }
static void recv_cmd_id(QTestState *s, const char *id) static void recv_cmd_id(QTestState *s, const char *id)
...@@ -235,7 +235,7 @@ static void test_qmp_oob(void) ...@@ -235,7 +235,7 @@ static void test_qmp_oob(void)
/* OOB command overtakes slow in-band command */ /* OOB command overtakes slow in-band command */
setup_blocking_cmd(); setup_blocking_cmd();
send_cmd_that_blocks(qts, "ib-blocks-1"); send_cmd_that_blocks(qts, "ib-blocks-1");
qtest_async_qmp(qts, "{ 'execute': 'query-name', 'id': 'ib-quick-1' }"); qtest_qmp_send(qts, "{ 'execute': 'query-name', 'id': 'ib-quick-1' }");
send_oob_cmd_that_fails(qts, "oob-1"); send_oob_cmd_that_fails(qts, "oob-1");
recv_cmd_id(qts, "oob-1"); recv_cmd_id(qts, "oob-1");
unblock_blocked_cmd(); unblock_blocked_cmd();
...@@ -244,7 +244,7 @@ static void test_qmp_oob(void) ...@@ -244,7 +244,7 @@ static void test_qmp_oob(void)
/* Even malformed in-band command fails in-band */ /* Even malformed in-band command fails in-band */
send_cmd_that_blocks(qts, "blocks-2"); send_cmd_that_blocks(qts, "blocks-2");
qtest_async_qmp(qts, "{ 'id': 'err-2' }"); qtest_qmp_send(qts, "{ 'id': 'err-2' }");
unblock_blocked_cmd(); unblock_blocked_cmd();
recv_cmd_id(qts, "blocks-2"); recv_cmd_id(qts, "blocks-2");
recv_cmd_id(qts, "err-2"); recv_cmd_id(qts, "err-2");
...@@ -436,7 +436,7 @@ static void add_query_tests(QmpSchema *schema) ...@@ -436,7 +436,7 @@ static void add_query_tests(QmpSchema *schema)
static void test_qmp_preconfig(void) static void test_qmp_preconfig(void)
{ {
QDict *rsp, *ret; QDict *rsp, *ret;
QTestState *qs = qtest_startf("%s --preconfig", common_args); QTestState *qs = qtest_initf("%s --preconfig", common_args);
/* preconfig state */ /* preconfig state */
/* enabled commands, no error expected */ /* enabled commands, no error expected */
......
...@@ -184,8 +184,8 @@ static QSDHCI *machine_start(const struct sdhci_t *test) ...@@ -184,8 +184,8 @@ static QSDHCI *machine_start(const struct sdhci_t *test)
uint16_t vendor_id, device_id; uint16_t vendor_id, device_id;
uint64_t barsize; uint64_t barsize;
global_qtest = qtest_startf("-machine %s -device sdhci-pci", global_qtest = qtest_initf("-machine %s -device sdhci-pci",
test->machine); test->machine);
s->pci.bus = qpci_init_pc(global_qtest, NULL); s->pci.bus = qpci_init_pc(global_qtest, NULL);
...@@ -200,7 +200,7 @@ static QSDHCI *machine_start(const struct sdhci_t *test) ...@@ -200,7 +200,7 @@ static QSDHCI *machine_start(const struct sdhci_t *test)
qpci_device_enable(s->pci.dev); qpci_device_enable(s->pci.dev);
} else { } else {
/* SysBus */ /* SysBus */
global_qtest = qtest_startf("-machine %s", test->machine); global_qtest = qtest_initf("-machine %s", test->machine);
s->addr = test->sdhci.addr; s->addr = test->sdhci.addr;
} }
......
...@@ -58,9 +58,9 @@ static void test_init(TestData *d) ...@@ -58,9 +58,9 @@ static void test_init(TestData *d)
{ {
QTestState *qs; QTestState *qs;
qs = qtest_startf("-machine q35 %s %s", qs = qtest_initf("-machine q35 %s %s",
d->noreboot ? "" : "-global ICH9-LPC.noreboot=false", d->noreboot ? "" : "-global ICH9-LPC.noreboot=false",
!d->args ? "" : d->args); !d->args ? "" : d->args);
global_qtest = qs; global_qtest = qs;
qtest_irq_intercept_in(qs, "ioapic"); qtest_irq_intercept_in(qs, "ioapic");
......
...@@ -10,11 +10,15 @@ ...@@ -10,11 +10,15 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "libqtest.h" #include "libqtest.h"
#include "qapi/qmp/qdict.h"
#include "qemu/iov.h" #include "qemu/iov.h"
#include "qemu/sockets.h" #include "qemu/sockets.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "qemu/main-loop.h" #include "qemu/main-loop.h"
/* TODO actually test the results and get rid of this */
#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__))
static void test_mirror(void) static void test_mirror(void)
{ {
int send_sock[2], recv_sock; int send_sock[2], recv_sock;
...@@ -36,7 +40,7 @@ static void test_mirror(void) ...@@ -36,7 +40,7 @@ static void test_mirror(void)
ret = mkstemp(sock_path); ret = mkstemp(sock_path);
g_assert_cmpint(ret, !=, -1); g_assert_cmpint(ret, !=, -1);
global_qtest = qtest_startf( global_qtest = qtest_initf(
"-netdev socket,id=qtest-bn0,fd=%d " "-netdev socket,id=qtest-bn0,fd=%d "
"-device %s,netdev=qtest-bn0,id=qtest-e0 " "-device %s,netdev=qtest-bn0,id=qtest-e0 "
"-chardev socket,id=mirror0,path=%s,server,nowait " "-chardev socket,id=mirror0,path=%s,server,nowait "
......
...@@ -52,11 +52,15 @@ ...@@ -52,11 +52,15 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "libqtest.h" #include "libqtest.h"
#include "qapi/qmp/qdict.h"
#include "qemu/iov.h" #include "qemu/iov.h"
#include "qemu/sockets.h" #include "qemu/sockets.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "qemu/main-loop.h" #include "qemu/main-loop.h"
/* TODO actually test the results and get rid of this */
#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__))
static const char *get_devstr(void) static const char *get_devstr(void)
{ {
if (g_str_equal(qtest_get_arch(), "s390x")) { if (g_str_equal(qtest_get_arch(), "s390x")) {
...@@ -86,7 +90,7 @@ static void test_redirector_tx(void) ...@@ -86,7 +90,7 @@ static void test_redirector_tx(void)
ret = mkstemp(sock_path1); ret = mkstemp(sock_path1);
g_assert_cmpint(ret, !=, -1); g_assert_cmpint(ret, !=, -1);
global_qtest = qtest_startf( global_qtest = qtest_initf(
"-netdev socket,id=qtest-bn0,fd=%d " "-netdev socket,id=qtest-bn0,fd=%d "
"-device %s,netdev=qtest-bn0,id=qtest-e0 " "-device %s,netdev=qtest-bn0,id=qtest-e0 "
"-chardev socket,id=redirector0,path=%s,server,nowait " "-chardev socket,id=redirector0,path=%s,server,nowait "
...@@ -155,7 +159,7 @@ static void test_redirector_rx(void) ...@@ -155,7 +159,7 @@ static void test_redirector_rx(void)
ret = mkstemp(sock_path1); ret = mkstemp(sock_path1);
g_assert_cmpint(ret, !=, -1); g_assert_cmpint(ret, !=, -1);
global_qtest = qtest_startf( global_qtest = qtest_initf(
"-netdev socket,id=qtest-bn0,fd=%d " "-netdev socket,id=qtest-bn0,fd=%d "
"-device %s,netdev=qtest-bn0,id=qtest-e0 " "-device %s,netdev=qtest-bn0,id=qtest-e0 "
"-chardev socket,id=redirector0,path=%s,server,nowait " "-chardev socket,id=redirector0,path=%s,server,nowait "
......
...@@ -146,12 +146,11 @@ static void test_qga_sync_delimited(gconstpointer fix) ...@@ -146,12 +146,11 @@ static void test_qga_sync_delimited(gconstpointer fix)
guint32 v, r = g_random_int(); guint32 v, r = g_random_int();
unsigned char c; unsigned char c;
QDict *ret; QDict *ret;
gchar *cmd;
cmd = g_strdup_printf("\xff{'execute': 'guest-sync-delimited'," qmp_fd_send(fixture->fd,
" 'arguments': {'id': %u } }", r); "\xff{'execute': 'guest-sync-delimited',"
qmp_fd_send(fixture->fd, cmd); " 'arguments': {'id': %u } }",
g_free(cmd); r);
/* /*
* Read and ignore garbage until resynchronized. * Read and ignore garbage until resynchronized.
...@@ -188,7 +187,6 @@ static void test_qga_sync(gconstpointer fix) ...@@ -188,7 +187,6 @@ static void test_qga_sync(gconstpointer fix)
const TestFixture *fixture = fix; const TestFixture *fixture = fix;
guint32 v, r = g_random_int(); guint32 v, r = g_random_int();
QDict *ret; QDict *ret;
gchar *cmd;
/* /*
* TODO guest-sync is inherently limited: we cannot distinguish * TODO guest-sync is inherently limited: we cannot distinguish
...@@ -201,10 +199,9 @@ static void test_qga_sync(gconstpointer fix) ...@@ -201,10 +199,9 @@ static void test_qga_sync(gconstpointer fix)
* invalid JSON. Testing of '\xff' handling is done in * invalid JSON. Testing of '\xff' handling is done in
* guest-sync-delimited instead. * guest-sync-delimited instead.
*/ */
cmd = g_strdup_printf("{'execute': 'guest-sync'," ret = qmp_fd(fixture->fd,
" 'arguments': {'id': %u } }", r); "{'execute': 'guest-sync', 'arguments': {'id': %u } }",
ret = qmp_fd(fixture->fd, cmd); r);
g_free(cmd);
g_assert_nonnull(ret); g_assert_nonnull(ret);
qmp_assert_no_error(ret); qmp_assert_no_error(ret);
...@@ -428,7 +425,7 @@ static void test_qga_file_ops(gconstpointer fix) ...@@ -428,7 +425,7 @@ static void test_qga_file_ops(gconstpointer fix)
const TestFixture *fixture = fix; const TestFixture *fixture = fix;
const unsigned char helloworld[] = "Hello World!\n"; const unsigned char helloworld[] = "Hello World!\n";
const char *b64; const char *b64;
gchar *cmd, *path, *enc; gchar *path, *enc;
unsigned char *dec; unsigned char *dec;
QDict *ret, *val; QDict *ret, *val;
int64_t id, eof; int64_t id, eof;
...@@ -446,10 +443,10 @@ static void test_qga_file_ops(gconstpointer fix) ...@@ -446,10 +443,10 @@ static void test_qga_file_ops(gconstpointer fix)
enc = g_base64_encode(helloworld, sizeof(helloworld)); enc = g_base64_encode(helloworld, sizeof(helloworld));
/* write */ /* write */
cmd = g_strdup_printf("{'execute': 'guest-file-write'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "," "{'execute': 'guest-file-write',"
" 'buf-b64': '%s' } }", id, enc); " 'arguments': { 'handle': %" PRId64 ", 'buf-b64': %s } }",
ret = qmp_fd(fixture->fd, cmd); id, enc);
g_assert_nonnull(ret); g_assert_nonnull(ret);
qmp_assert_no_error(ret); qmp_assert_no_error(ret);
...@@ -459,23 +456,20 @@ static void test_qga_file_ops(gconstpointer fix) ...@@ -459,23 +456,20 @@ static void test_qga_file_ops(gconstpointer fix)
g_assert_cmpint(count, ==, sizeof(helloworld)); g_assert_cmpint(count, ==, sizeof(helloworld));
g_assert_cmpint(eof, ==, 0); g_assert_cmpint(eof, ==, 0);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* flush */ /* flush */
cmd = g_strdup_printf("{'execute': 'guest-file-flush'," ret = qmp_fd(fixture->fd,
" 'arguments': {'handle': %" PRId64 "} }", "{'execute': 'guest-file-flush',"
id); " 'arguments': {'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* close */ /* close */
cmd = g_strdup_printf("{'execute': 'guest-file-close'," ret = qmp_fd(fixture->fd,
" 'arguments': {'handle': %" PRId64 "} }", "{'execute': 'guest-file-close',"
id); " 'arguments': {'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* check content */ /* check content */
path = g_build_filename(fixture->test_dir, "foo", NULL); path = g_build_filename(fixture->test_dir, "foo", NULL);
...@@ -497,10 +491,10 @@ static void test_qga_file_ops(gconstpointer fix) ...@@ -497,10 +491,10 @@ static void test_qga_file_ops(gconstpointer fix)
qobject_unref(ret); qobject_unref(ret);
/* read */ /* read */
cmd = g_strdup_printf("{'execute': 'guest-file-read'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "} }", "{'execute': 'guest-file-read',"
id); " 'arguments': { 'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "count"); count = qdict_get_int(val, "count");
eof = qdict_get_bool(val, "eof"); eof = qdict_get_bool(val, "eof");
...@@ -510,14 +504,13 @@ static void test_qga_file_ops(gconstpointer fix) ...@@ -510,14 +504,13 @@ static void test_qga_file_ops(gconstpointer fix)
g_assert_cmpstr(b64, ==, enc); g_assert_cmpstr(b64, ==, enc);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
g_free(enc); g_free(enc);
/* read eof */ /* read eof */
cmd = g_strdup_printf("{'execute': 'guest-file-read'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "} }", "{'execute': 'guest-file-read',"
id); " 'arguments': { 'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "count"); count = qdict_get_int(val, "count");
eof = qdict_get_bool(val, "eof"); eof = qdict_get_bool(val, "eof");
...@@ -526,14 +519,13 @@ static void test_qga_file_ops(gconstpointer fix) ...@@ -526,14 +519,13 @@ static void test_qga_file_ops(gconstpointer fix)
g_assert(eof); g_assert(eof);
g_assert_cmpstr(b64, ==, ""); g_assert_cmpstr(b64, ==, "");
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* seek */ /* seek */
cmd = g_strdup_printf("{'execute': 'guest-file-seek'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 ", " "{'execute': 'guest-file-seek',"
" 'offset': %d, 'whence': '%s' } }", " 'arguments': { 'handle': %" PRId64 ", "
id, 6, "set"); " 'offset': %d, 'whence': %s } }",
ret = qmp_fd(fixture->fd, cmd); id, 6, "set");
qmp_assert_no_error(ret); qmp_assert_no_error(ret);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "position"); count = qdict_get_int(val, "position");
...@@ -541,13 +533,12 @@ static void test_qga_file_ops(gconstpointer fix) ...@@ -541,13 +533,12 @@ static void test_qga_file_ops(gconstpointer fix)
g_assert_cmpint(count, ==, 6); g_assert_cmpint(count, ==, 6);
g_assert(!eof); g_assert(!eof);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* partial read */ /* partial read */
cmd = g_strdup_printf("{'execute': 'guest-file-read'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "} }", "{'execute': 'guest-file-read',"
id); " 'arguments': { 'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "count"); count = qdict_get_int(val, "count");
eof = qdict_get_bool(val, "eof"); eof = qdict_get_bool(val, "eof");
...@@ -560,15 +551,13 @@ static void test_qga_file_ops(gconstpointer fix) ...@@ -560,15 +551,13 @@ static void test_qga_file_ops(gconstpointer fix)
g_free(dec); g_free(dec);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* close */ /* close */
cmd = g_strdup_printf("{'execute': 'guest-file-close'," ret = qmp_fd(fixture->fd,
" 'arguments': {'handle': %" PRId64 "} }", "{'execute': 'guest-file-close',"
id); " 'arguments': {'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
} }
static void test_qga_file_write_read(gconstpointer fix) static void test_qga_file_write_read(gconstpointer fix)
...@@ -576,7 +565,7 @@ static void test_qga_file_write_read(gconstpointer fix) ...@@ -576,7 +565,7 @@ static void test_qga_file_write_read(gconstpointer fix)
const TestFixture *fixture = fix; const TestFixture *fixture = fix;
const unsigned char helloworld[] = "Hello World!\n"; const unsigned char helloworld[] = "Hello World!\n";
const char *b64; const char *b64;
gchar *cmd, *enc; gchar *enc;
QDict *ret, *val; QDict *ret, *val;
int64_t id, eof; int64_t id, eof;
gsize count; gsize count;
...@@ -591,10 +580,10 @@ static void test_qga_file_write_read(gconstpointer fix) ...@@ -591,10 +580,10 @@ static void test_qga_file_write_read(gconstpointer fix)
enc = g_base64_encode(helloworld, sizeof(helloworld)); enc = g_base64_encode(helloworld, sizeof(helloworld));
/* write */ /* write */
cmd = g_strdup_printf("{'execute': 'guest-file-write'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "," "{'execute': 'guest-file-write',"
" 'buf-b64': '%s' } }", id, enc); " 'arguments': { 'handle': %" PRId64 ","
ret = qmp_fd(fixture->fd, cmd); " 'buf-b64': %s } }", id, enc);
g_assert_nonnull(ret); g_assert_nonnull(ret);
qmp_assert_no_error(ret); qmp_assert_no_error(ret);
...@@ -604,13 +593,12 @@ static void test_qga_file_write_read(gconstpointer fix) ...@@ -604,13 +593,12 @@ static void test_qga_file_write_read(gconstpointer fix)
g_assert_cmpint(count, ==, sizeof(helloworld)); g_assert_cmpint(count, ==, sizeof(helloworld));
g_assert_cmpint(eof, ==, 0); g_assert_cmpint(eof, ==, 0);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* read (check implicit flush) */ /* read (check implicit flush) */
cmd = g_strdup_printf("{'execute': 'guest-file-read'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "} }", "{'execute': 'guest-file-read',"
id); " 'arguments': { 'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "count"); count = qdict_get_int(val, "count");
eof = qdict_get_bool(val, "eof"); eof = qdict_get_bool(val, "eof");
...@@ -619,14 +607,13 @@ static void test_qga_file_write_read(gconstpointer fix) ...@@ -619,14 +607,13 @@ static void test_qga_file_write_read(gconstpointer fix)
g_assert(eof); g_assert(eof);
g_assert_cmpstr(b64, ==, ""); g_assert_cmpstr(b64, ==, "");
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* seek to 0 */ /* seek to 0 */
cmd = g_strdup_printf("{'execute': 'guest-file-seek'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 ", " "{'execute': 'guest-file-seek',"
" 'offset': %d, 'whence': '%s' } }", " 'arguments': { 'handle': %" PRId64 ", "
id, 0, "set"); " 'offset': %d, 'whence': %s } }",
ret = qmp_fd(fixture->fd, cmd); id, 0, "set");
qmp_assert_no_error(ret); qmp_assert_no_error(ret);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "position"); count = qdict_get_int(val, "position");
...@@ -634,13 +621,12 @@ static void test_qga_file_write_read(gconstpointer fix) ...@@ -634,13 +621,12 @@ static void test_qga_file_write_read(gconstpointer fix)
g_assert_cmpint(count, ==, 0); g_assert_cmpint(count, ==, 0);
g_assert(!eof); g_assert(!eof);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
/* read */ /* read */
cmd = g_strdup_printf("{'execute': 'guest-file-read'," ret = qmp_fd(fixture->fd,
" 'arguments': { 'handle': %" PRId64 "} }", "{'execute': 'guest-file-read',"
id); " 'arguments': { 'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
count = qdict_get_int(val, "count"); count = qdict_get_int(val, "count");
eof = qdict_get_bool(val, "eof"); eof = qdict_get_bool(val, "eof");
...@@ -649,16 +635,14 @@ static void test_qga_file_write_read(gconstpointer fix) ...@@ -649,16 +635,14 @@ static void test_qga_file_write_read(gconstpointer fix)
g_assert(eof); g_assert(eof);
g_assert_cmpstr(b64, ==, enc); g_assert_cmpstr(b64, ==, enc);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
g_free(enc); g_free(enc);
/* close */ /* close */
cmd = g_strdup_printf("{'execute': 'guest-file-close'," ret = qmp_fd(fixture->fd,
" 'arguments': {'handle': %" PRId64 "} }", "{'execute': 'guest-file-close',"
id); " 'arguments': {'handle': %" PRId64 "} }",
ret = qmp_fd(fixture->fd, cmd); id);
qobject_unref(ret); qobject_unref(ret);
g_free(cmd);
} }
static void test_qga_get_time(gconstpointer fix) static void test_qga_get_time(gconstpointer fix)
...@@ -814,7 +798,6 @@ static void test_qga_guest_exec(gconstpointer fix) ...@@ -814,7 +798,6 @@ static void test_qga_guest_exec(gconstpointer fix)
int64_t pid, now, exitcode; int64_t pid, now, exitcode;
gsize len; gsize len;
bool exited; bool exited;
char *cmd;
/* exec 'echo foo bar' */ /* exec 'echo foo bar' */
ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {" ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
...@@ -829,10 +812,10 @@ static void test_qga_guest_exec(gconstpointer fix) ...@@ -829,10 +812,10 @@ static void test_qga_guest_exec(gconstpointer fix)
/* wait for completion */ /* wait for completion */
now = g_get_monotonic_time(); now = g_get_monotonic_time();
cmd = g_strdup_printf("{'execute': 'guest-exec-status',"
" 'arguments': { 'pid': %" PRId64 " } }", pid);
do { do {
ret = qmp_fd(fixture->fd, cmd); ret = qmp_fd(fixture->fd,
"{'execute': 'guest-exec-status',"
" 'arguments': { 'pid': %" PRId64 " } }", pid);
g_assert_nonnull(ret); g_assert_nonnull(ret);
val = qdict_get_qdict(ret, "return"); val = qdict_get_qdict(ret, "return");
exited = qdict_get_bool(val, "exited"); exited = qdict_get_bool(val, "exited");
...@@ -842,7 +825,6 @@ static void test_qga_guest_exec(gconstpointer fix) ...@@ -842,7 +825,6 @@ static void test_qga_guest_exec(gconstpointer fix)
} while (!exited && } while (!exited &&
g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND); g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND);
g_assert(exited); g_assert(exited);
g_free(cmd);
/* check stdout */ /* check stdout */
exitcode = qdict_get_int(val, "exitcode"); exitcode = qdict_get_int(val, "exitcode");
......
...@@ -47,15 +47,13 @@ static void visitor_input_teardown(TestInputVisitorData *data, ...@@ -47,15 +47,13 @@ static void visitor_input_teardown(TestInputVisitorData *data,
/* The various test_init functions are provided instead of a test setup /* The various test_init functions are provided instead of a test setup
function so that the JSON string used by the tests are kept in the test function so that the JSON string used by the tests are kept in the test
functions (and not in main()). */ functions (and not in main()). */
static Visitor *visitor_input_test_init_internal(TestInputVisitorData *data,
bool keyval, static Visitor *test_init_internal(TestInputVisitorData *data, bool keyval,
const char *json_string, QObject *obj)
va_list *ap)
{ {
visitor_input_teardown(data, NULL); visitor_input_teardown(data, NULL);
data->obj = qobject_from_jsonv(json_string, ap, &error_abort); data->obj = obj;
g_assert(data->obj);
if (keyval) { if (keyval) {
data->qiv = qobject_input_visitor_new_keyval(data->obj); data->qiv = qobject_input_visitor_new_keyval(data->obj);
...@@ -75,7 +73,8 @@ Visitor *visitor_input_test_init_full(TestInputVisitorData *data, ...@@ -75,7 +73,8 @@ Visitor *visitor_input_test_init_full(TestInputVisitorData *data,
va_list ap; va_list ap;
va_start(ap, json_string); va_start(ap, json_string);
v = visitor_input_test_init_internal(data, keyval, json_string, &ap); v = test_init_internal(data, keyval,
qobject_from_vjsonf_nofail(json_string, ap));
va_end(ap); va_end(ap);
return v; return v;
} }
...@@ -88,7 +87,8 @@ Visitor *visitor_input_test_init(TestInputVisitorData *data, ...@@ -88,7 +87,8 @@ Visitor *visitor_input_test_init(TestInputVisitorData *data,
va_list ap; va_list ap;
va_start(ap, json_string); va_start(ap, json_string);
v = visitor_input_test_init_internal(data, false, json_string, &ap); v = test_init_internal(data, false,
qobject_from_vjsonf_nofail(json_string, ap));
va_end(ap); va_end(ap);
return v; return v;
} }
...@@ -103,7 +103,8 @@ Visitor *visitor_input_test_init(TestInputVisitorData *data, ...@@ -103,7 +103,8 @@ Visitor *visitor_input_test_init(TestInputVisitorData *data,
static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data, static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
const char *json_string) const char *json_string)
{ {
return visitor_input_test_init_internal(data, false, json_string, NULL); return test_init_internal(data, false,
qobject_from_json(json_string, &error_abort));
} }
static void test_visitor_in_int(TestInputVisitorData *data, static void test_visitor_in_int(TestInputVisitorData *data,
......
...@@ -22,8 +22,6 @@ ...@@ -22,8 +22,6 @@
#define TIS_REG(LOCTY, REG) \ #define TIS_REG(LOCTY, REG) \
(TPM_TIS_ADDR_BASE + ((LOCTY) << 12) + REG) (TPM_TIS_ADDR_BASE + ((LOCTY) << 12) + REG)
static bool got_stop;
void tpm_util_crb_transfer(QTestState *s, void tpm_util_crb_transfer(QTestState *s,
const unsigned char *req, size_t req_size, const unsigned char *req, size_t req_size,
unsigned char *rsp, size_t rsp_size) unsigned char *rsp, size_t rsp_size)
...@@ -239,52 +237,27 @@ void tpm_util_swtpm_kill(GPid pid) ...@@ -239,52 +237,27 @@ void tpm_util_swtpm_kill(GPid pid)
void tpm_util_migrate(QTestState *who, const char *uri) void tpm_util_migrate(QTestState *who, const char *uri)
{ {
QDict *rsp; QDict *rsp;
gchar *cmd;
cmd = g_strdup_printf("{ 'execute': 'migrate'," rsp = qtest_qmp(who,
"'arguments': { 'uri': '%s' } }", "{ 'execute': 'migrate', 'arguments': { 'uri': %s } }",
uri); uri);
rsp = qtest_qmp(who, cmd);
g_free(cmd);
g_assert(qdict_haskey(rsp, "return")); g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);
} }
/*
* Events can get in the way of responses we are actually waiting for.
*/
static QDict *tpm_util_wait_command(QTestState *who, const char *command)
{
const char *event_string;
QDict *response;
response = qtest_qmp(who, command);
while (qdict_haskey(response, "event")) {
/* OK, it was an event */
event_string = qdict_get_str(response, "event");
if (!strcmp(event_string, "STOP")) {
got_stop = true;
}
qobject_unref(response);
response = qtest_qmp_receive(who);
}
return response;
}
void tpm_util_wait_for_migration_complete(QTestState *who) void tpm_util_wait_for_migration_complete(QTestState *who)
{ {
while (true) { while (true) {
QDict *rsp, *rsp_return; QDict *rsp_return;
bool completed; bool completed;
const char *status; const char *status;
rsp = tpm_util_wait_command(who, "{ 'execute': 'query-migrate' }"); qtest_qmp_send(who, "{ 'execute': 'query-migrate' }");
rsp_return = qdict_get_qdict(rsp, "return"); rsp_return = qtest_qmp_receive_success(who, NULL, NULL);
status = qdict_get_str(rsp_return, "status"); status = qdict_get_str(rsp_return, "status");
completed = strcmp(status, "completed") == 0; completed = strcmp(status, "completed") == 0;
g_assert_cmpstr(status, !=, "failed"); g_assert_cmpstr(status, !=, "failed");
qobject_unref(rsp); qobject_unref(rsp_return);
if (completed) { if (completed) {
return; return;
} }
......
...@@ -139,7 +139,7 @@ static void pci_ehci_port_3_hotplug(void) ...@@ -139,7 +139,7 @@ static void pci_ehci_port_3_hotplug(void)
static void pci_ehci_port_hotplug(void) static void pci_ehci_port_hotplug(void)
{ {
usb_test_hotplug("ich9-ehci-1", 3, pci_ehci_port_3_hotplug); usb_test_hotplug("ich9-ehci-1", "3", pci_ehci_port_3_hotplug);
} }
......
...@@ -19,7 +19,7 @@ static void test_ohci_init(void) ...@@ -19,7 +19,7 @@ static void test_ohci_init(void)
static void test_ohci_hotplug(void) static void test_ohci_hotplug(void)
{ {
usb_test_hotplug("ohci", 1, NULL); usb_test_hotplug("ohci", "1", NULL);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
......
...@@ -43,12 +43,12 @@ static void test_port_2(void) ...@@ -43,12 +43,12 @@ static void test_port_2(void)
static void test_uhci_hotplug(void) static void test_uhci_hotplug(void)
{ {
usb_test_hotplug("uhci", 2, test_port_2); usb_test_hotplug("uhci", "2", test_port_2);
} }
static void test_usb_storage_hotplug(void) static void test_usb_storage_hotplug(void)
{ {
qtest_qmp_device_add("usb-storage", "usbdev0", "'drive': 'drive0'"); qtest_qmp_device_add("usb-storage", "usbdev0", "{'drive': 'drive0'}");
qtest_qmp_device_del("usbdev0"); qtest_qmp_device_del("usbdev0");
} }
......
...@@ -18,13 +18,13 @@ static void test_xhci_init(void) ...@@ -18,13 +18,13 @@ static void test_xhci_init(void)
static void test_xhci_hotplug(void) static void test_xhci_hotplug(void)
{ {
usb_test_hotplug("xhci", 1, NULL); usb_test_hotplug("xhci", "1", NULL);
} }
static void test_usb_uas_hotplug(void) static void test_usb_uas_hotplug(void)
{ {
qtest_qmp_device_add("usb-uas", "uas", NULL); qtest_qmp_device_add("usb-uas", "uas", "{}");
qtest_qmp_device_add("scsi-hd", "scsihd", "'drive': 'drive0'"); qtest_qmp_device_add("scsi-hd", "scsihd", "{'drive': 'drive0'}");
/* TODO: /* TODO:
UAS HBA driver in libqos, to check that UAS HBA driver in libqos, to check that
...@@ -37,10 +37,10 @@ static void test_usb_uas_hotplug(void) ...@@ -37,10 +37,10 @@ static void test_usb_uas_hotplug(void)
static void test_usb_ccid_hotplug(void) static void test_usb_ccid_hotplug(void)
{ {
qtest_qmp_device_add("usb-ccid", "ccid", NULL); qtest_qmp_device_add("usb-ccid", "ccid", "{}");
qtest_qmp_device_del("ccid"); qtest_qmp_device_del("ccid");
/* check the device can be added again */ /* check the device can be added again */
qtest_qmp_device_add("usb-ccid", "ccid", NULL); qtest_qmp_device_add("usb-ccid", "ccid", "{}");
qtest_qmp_device_del("ccid"); qtest_qmp_device_del("ccid");
} }
......
...@@ -709,11 +709,7 @@ static void test_migrate(void) ...@@ -709,11 +709,7 @@ static void test_migrate(void)
g_assert(qdict_haskey(rsp, "return")); g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);
cmd = g_strdup_printf("{ 'execute': 'migrate'," rsp = qmp("{ 'execute': 'migrate', 'arguments': { 'uri': %s } }", uri);
"'arguments': { 'uri': '%s' } }",
uri);
rsp = qmp(cmd);
g_free(cmd);
g_assert(qdict_haskey(rsp, "return")); g_assert(qdict_haskey(rsp, "return"));
qobject_unref(rsp); qobject_unref(rsp);
......
...@@ -23,8 +23,8 @@ int main(int argc, char **argv) ...@@ -23,8 +23,8 @@ int main(int argc, char **argv)
g_test_init(&argc, &argv, NULL); g_test_init(&argc, &argv, NULL);
qtest_add_func("/virtio/balloon/nop", balloon_nop); qtest_add_func("/virtio/balloon/nop", balloon_nop);
global_qtest = qtest_startf("-device virtio-balloon-%s", global_qtest = qtest_initf("-device virtio-balloon-%s",
qvirtio_get_dev_type()); qvirtio_get_dev_type());
ret = g_test_run(); ret = g_test_run();
qtest_end(); qtest_end();
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "libqos/virtio-pci.h" #include "libqos/virtio-pci.h"
#include "libqos/virtio-mmio.h" #include "libqos/virtio-mmio.h"
#include "libqos/malloc-generic.h" #include "libqos/malloc-generic.h"
#include "qapi/qmp/qdict.h"
#include "qemu/bswap.h" #include "qemu/bswap.h"
#include "standard-headers/linux/virtio_ids.h" #include "standard-headers/linux/virtio_ids.h"
#include "standard-headers/linux/virtio_config.h" #include "standard-headers/linux/virtio_config.h"
...@@ -23,6 +24,9 @@ ...@@ -23,6 +24,9 @@
#include "standard-headers/linux/virtio_blk.h" #include "standard-headers/linux/virtio_blk.h"
#include "standard-headers/linux/virtio_pci.h" #include "standard-headers/linux/virtio_pci.h"
/* TODO actually test the results and get rid of this */
#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__))
#define TEST_IMAGE_SIZE (64 * 1024 * 1024) #define TEST_IMAGE_SIZE (64 * 1024 * 1024)
#define QVIRTIO_BLK_TIMEOUT_US (30 * 1000 * 1000) #define QVIRTIO_BLK_TIMEOUT_US (30 * 1000 * 1000)
#define PCI_SLOT_HP 0x06 #define PCI_SLOT_HP 0x06
...@@ -89,10 +93,10 @@ static void arm_test_start(void) ...@@ -89,10 +93,10 @@ static void arm_test_start(void)
tmp_path = drive_create(); tmp_path = drive_create();
global_qtest = qtest_startf("-machine virt " global_qtest = qtest_initf("-machine virt "
"-drive if=none,id=drive0,file=%s,format=raw " "-drive if=none,id=drive0,file=%s,format=raw "
"-device virtio-blk-device,drive=drive0", "-device virtio-blk-device,drive=drive0",
tmp_path); tmp_path);
unlink(tmp_path); unlink(tmp_path);
g_free(tmp_path); g_free(tmp_path);
} }
...@@ -662,8 +666,9 @@ static void pci_hotplug(void) ...@@ -662,8 +666,9 @@ static void pci_hotplug(void)
qs = pci_test_start(); qs = pci_test_start();
/* plug secondary disk */ /* plug secondary disk */
qpci_plug_device_test("virtio-blk-pci", "drv1", PCI_SLOT_HP, qtest_qmp_device_add("virtio-blk-pci", "drv1",
"'drive': 'drive1'"); "{'addr': %s, 'drive': 'drive1'}",
stringify(PCI_SLOT_HP));
dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT_HP); dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT_HP);
g_assert(dev); g_assert(dev);
......
...@@ -14,17 +14,17 @@ ...@@ -14,17 +14,17 @@
/* Tests only initialization so far. TODO: Replace with functional tests */ /* Tests only initialization so far. TODO: Replace with functional tests */
static void console_nop(void) static void console_nop(void)
{ {
global_qtest = qtest_startf("-device virtio-serial-%s,id=vser0 " global_qtest = qtest_initf("-device virtio-serial-%s,id=vser0 "
"-device virtconsole,bus=vser0.0", "-device virtconsole,bus=vser0.0",
qvirtio_get_dev_type()); qvirtio_get_dev_type());
qtest_end(); qtest_end();
} }
static void serialport_nop(void) static void serialport_nop(void)
{ {
global_qtest = qtest_startf("-device virtio-serial-%s,id=vser0 " global_qtest = qtest_initf("-device virtio-serial-%s,id=vser0 "
"-device virtserialport,bus=vser0.0", "-device virtserialport,bus=vser0.0",
qvirtio_get_dev_type()); qvirtio_get_dev_type());
qtest_end(); qtest_end();
} }
......
...@@ -249,7 +249,8 @@ static void hotplug(void) ...@@ -249,7 +249,8 @@ static void hotplug(void)
qtest_start("-device virtio-net-pci"); qtest_start("-device virtio-net-pci");
qpci_plug_device_test("virtio-net-pci", "net1", PCI_SLOT_HP, NULL); qtest_qmp_device_add("virtio-net-pci", "net1",
"{'addr': %s}", stringify(PCI_SLOT_HP));
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
qpci_unplug_acpi_device_test("net1", PCI_SLOT_HP); qpci_unplug_acpi_device_test("net1", PCI_SLOT_HP);
......
...@@ -22,7 +22,8 @@ static void hotplug(void) ...@@ -22,7 +22,8 @@ static void hotplug(void)
{ {
const char *arch = qtest_get_arch(); const char *arch = qtest_get_arch();
qpci_plug_device_test("virtio-rng-pci", "rng1", PCI_SLOT_HP, NULL); qtest_qmp_device_add("virtio-rng-pci", "rng1",
"{'addr': %s}", stringify(PCI_SLOT_HP));
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
qpci_unplug_acpi_device_test("rng1", PCI_SLOT_HP); qpci_unplug_acpi_device_test("rng1", PCI_SLOT_HP);
......
...@@ -199,7 +199,7 @@ static void hotplug(void) ...@@ -199,7 +199,7 @@ static void hotplug(void)
qs = qvirtio_scsi_start( qs = qvirtio_scsi_start(
"-drive id=drv1,if=none,file=null-co://,format=raw"); "-drive id=drv1,if=none,file=null-co://,format=raw");
qtest_qmp_device_add("scsi-hd", "scsihd", "'drive': 'drv1'"); qtest_qmp_device_add("scsi-hd", "scsihd", "{'drive': 'drv1'}");
qtest_qmp_device_del("scsihd"); qtest_qmp_device_del("scsihd");
qvirtio_scsi_stop(qs); qvirtio_scsi_stop(qs);
} }
......
...@@ -18,7 +18,7 @@ static void virtio_serial_nop(void) ...@@ -18,7 +18,7 @@ static void virtio_serial_nop(void)
static void hotplug(void) static void hotplug(void)
{ {
qtest_qmp_device_add("virtserialport", "hp-port", NULL); qtest_qmp_device_add("virtserialport", "hp-port", "{}");
qtest_qmp_device_del("hp-port"); qtest_qmp_device_del("hp-port");
} }
...@@ -31,8 +31,8 @@ int main(int argc, char **argv) ...@@ -31,8 +31,8 @@ int main(int argc, char **argv)
qtest_add_func("/virtio/serial/nop", virtio_serial_nop); qtest_add_func("/virtio/serial/nop", virtio_serial_nop);
qtest_add_func("/virtio/serial/hotplug", hotplug); qtest_add_func("/virtio/serial/hotplug", hotplug);
global_qtest = qtest_startf("-device virtio-serial-%s", global_qtest = qtest_initf("-device virtio-serial-%s",
qvirtio_get_dev_type()); qvirtio_get_dev_type());
ret = g_test_run(); ret = g_test_run();
qtest_end(); qtest_end();
......
...@@ -142,7 +142,7 @@ static void vmgenid_set_guid_test(void) ...@@ -142,7 +142,7 @@ static void vmgenid_set_guid_test(void)
g_assert(qemu_uuid_parse(VGID_GUID, &expected) == 0); g_assert(qemu_uuid_parse(VGID_GUID, &expected) == 0);
global_qtest = qtest_startf(GUID_CMD(VGID_GUID)); global_qtest = qtest_initf(GUID_CMD(VGID_GUID));
/* Read the GUID from accessing guest memory */ /* Read the GUID from accessing guest memory */
read_guid_from_memory(&measured); read_guid_from_memory(&measured);
...@@ -155,7 +155,7 @@ static void vmgenid_set_guid_auto_test(void) ...@@ -155,7 +155,7 @@ static void vmgenid_set_guid_auto_test(void)
{ {
QemuUUID measured; QemuUUID measured;
global_qtest = qtest_startf(GUID_CMD("auto")); global_qtest = qtest_initf(GUID_CMD("auto"));
read_guid_from_memory(&measured); read_guid_from_memory(&measured);
...@@ -171,7 +171,7 @@ static void vmgenid_query_monitor_test(void) ...@@ -171,7 +171,7 @@ static void vmgenid_query_monitor_test(void)
g_assert(qemu_uuid_parse(VGID_GUID, &expected) == 0); g_assert(qemu_uuid_parse(VGID_GUID, &expected) == 0);
global_qtest = qtest_startf(GUID_CMD(VGID_GUID)); global_qtest = qtest_initf(GUID_CMD(VGID_GUID));
/* Read the GUID via the monitor */ /* Read the GUID via the monitor */
read_guid_from_monitor(&measured); read_guid_from_monitor(&measured);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册