Testing patches for 2018-08-16
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJbdTcjAAoJEDhwtADrkYZTZEYP/ivp0ozEfMeGgc6PFItv3zmx QVD+NYJ8bnv/iEoWl/pnQ0/HY3YLHz4G1DTK0dSlJAvAiChpPiR7YCeJRXeTyLHL 9KCFQV5SV9llstVi0f4ebEK21mUkYWoqtlzxxyqXh0q2N/QLtaVQ85ysE6ufwhNH jlunmJLGRRwPR95F4a05uVHNOym1ig9eo5CtQ1Fa8viV9BgWTbpSp1t4feB1OLnt Ml9cbFubb1cA7CuhdNHazNOnRZtEW5A9eOo6rX4d5JcH/zgFWdPpKCRn/X/NdvSE aRKqk7ll0gxYlacqVpkea23pVKVl7e1oUqkziaL8rq/BYE0SePkRv+SnmsifD8uT kWl+eHLyaW1g43omc0uttyAuTkFnvAa+l9TqIrdEYcPJJNaCsZVgJpDvj9+Oxril fk3OIHAnzSWwp/AmFLCSOYdaoVuZhppp6rqnu26B0w9Rxkbqe1790LbjDJrLUB+2 vN7+JmDhUfJk7/2pi+MGZrBtj3zcgbb3Qc5+NG8H1401bA/n8FNnPKgWdmAlmO7i pTafa1FXArJGWiBhzg2PUqmZq45MQiheQ1+SWgviIodQX5oHB3kEimcRPg4Wk18c fTKJDe7w8NFFNjuH6ou2LI4KzgQeewW+oCjxh2A7kwCqDmq5Eq8nBw/bYO1DgcDr bfCnicNJinjCHcgvvCVM =DuZ8 -----END PGP SIGNATURE----- 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: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
c542a9f979
@ -15,11 +15,15 @@
|
||||
#define QJSON_H
|
||||
|
||||
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_pretty(const QObject *obj);
|
||||
|
@ -39,7 +39,18 @@ static void parse_json(JSONMessageParser *parser, GQueue *tokens)
|
||||
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 = {};
|
||||
|
||||
@ -59,18 +70,56 @@ QObject *qobject_from_json(const char *string, Error **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;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, string);
|
||||
obj = qobject_from_jsonv(string, &ap, &error_abort);
|
||||
obj = qobject_from_vjsonf_nofail(string, ap);
|
||||
va_end(ap);
|
||||
|
||||
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.
|
||||
* Abort on error. Do not use with untrusted @string.
|
||||
@ -78,15 +127,13 @@ QObject *qobject_from_jsonf(const char *string, ...)
|
||||
*/
|
||||
QDict *qdict_from_jsonf_nofail(const char *string, ...)
|
||||
{
|
||||
QDict *obj;
|
||||
QDict *qdict;
|
||||
va_list ap;
|
||||
|
||||
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);
|
||||
|
||||
assert(obj);
|
||||
return obj;
|
||||
return qdict;
|
||||
}
|
||||
|
||||
typedef struct ToJsonIterState
|
||||
|
@ -37,6 +37,9 @@
|
||||
#include "hw/pci/pci_ids.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 */
|
||||
#define TEST_IMAGE_SIZE_MB_LARGE (200 * 1024)
|
||||
#define TEST_IMAGE_SIZE_MB_SMALL 64
|
||||
@ -1352,7 +1355,6 @@ static void test_flush_migrate(void)
|
||||
AHCIQState *src, *dst;
|
||||
AHCICommand *cmd;
|
||||
uint8_t px;
|
||||
const char *s;
|
||||
char *uri = g_strdup_printf("unix:%s", mig_socket);
|
||||
|
||||
prepare_blkdebug_script(debug_path, "flush_to_disk");
|
||||
@ -1388,8 +1390,7 @@ static void test_flush_migrate(void)
|
||||
ahci_migrate(src, dst, uri);
|
||||
|
||||
/* Complete the command */
|
||||
s = "{'execute':'cont' }";
|
||||
qmp_async(s);
|
||||
qmp_send("{'execute':'cont' }");
|
||||
qmp_eventwait("RESUME");
|
||||
ahci_command_wait(dst, cmd);
|
||||
ahci_command_verify(dst, cmd);
|
||||
@ -1592,8 +1593,8 @@ static void test_atapi_tray(void)
|
||||
atapi_wait_tray(false);
|
||||
|
||||
/* Remove media */
|
||||
qmp_async("{'execute': 'blockdev-open-tray', "
|
||||
"'arguments': {'id': 'cd0'}}");
|
||||
qmp_send("{'execute': 'blockdev-open-tray',"
|
||||
" 'arguments': {'id': 'cd0'}}");
|
||||
atapi_wait_tray(true);
|
||||
rsp = qmp_receive();
|
||||
qobject_unref(rsp);
|
||||
@ -1619,8 +1620,8 @@ static void test_atapi_tray(void)
|
||||
"'node-name': 'node0' }}");
|
||||
|
||||
/* Again, the event shows up first */
|
||||
qmp_async("{'execute': 'blockdev-close-tray', "
|
||||
"'arguments': {'id': 'cd0'}}");
|
||||
qmp_send("{'execute': 'blockdev-close-tray',"
|
||||
" 'arguments': {'id': 'cd0'}}");
|
||||
atapi_wait_tray(false);
|
||||
rsp = qmp_receive();
|
||||
qobject_unref(rsp);
|
||||
|
@ -13,9 +13,12 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "libqos/fw_cfg.h"
|
||||
#include "libqtest.h"
|
||||
|
||||
#include "qapi/qmp/qdict.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 {
|
||||
const char *args;
|
||||
uint64_t expected_boot;
|
||||
@ -30,10 +33,10 @@ static void test_a_boot_order(const char *machine,
|
||||
{
|
||||
uint64_t actual;
|
||||
|
||||
global_qtest = qtest_startf("-nodefaults%s%s %s",
|
||||
machine ? " -M " : "",
|
||||
machine ?: "",
|
||||
test_args);
|
||||
global_qtest = qtest_initf("-nodefaults%s%s %s",
|
||||
machine ? " -M " : "",
|
||||
machine ?: "",
|
||||
test_args);
|
||||
actual = read_boot_order();
|
||||
g_assert_cmphex(actual, ==, expected_boot);
|
||||
qmp_discard_response("{ 'execute': 'system_reset' }");
|
||||
|
@ -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
|
||||
* fast-enough smoketest for that.
|
||||
*/
|
||||
global_qtest = qtest_startf("%s %s -M %s,accel=tcg:kvm "
|
||||
"-chardev file,id=serial0,path=%s "
|
||||
"-no-shutdown -serial chardev:serial0 %s",
|
||||
codeparam, code ? codetmp : "",
|
||||
test->machine, serialtmp, test->extra);
|
||||
global_qtest = qtest_initf("%s %s -M %s,accel=tcg:kvm "
|
||||
"-chardev file,id=serial0,path=%s "
|
||||
"-no-shutdown -serial chardev:serial0 %s",
|
||||
codeparam, code ? codetmp : "",
|
||||
test->machine, serialtmp, test->extra);
|
||||
if (code) {
|
||||
unlink(codetmp);
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ static void test_cdrom_param(gconstpointer data)
|
||||
QTestState *qts;
|
||||
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");
|
||||
g_assert(strstr(resp, isoimage) != 0);
|
||||
g_free(resp);
|
||||
@ -120,8 +120,8 @@ static void test_cdboot(gconstpointer data)
|
||||
{
|
||||
QTestState *qts;
|
||||
|
||||
qts = qtest_startf("-accel kvm:tcg -no-shutdown %s%s", (const char *)data,
|
||||
isoimage);
|
||||
qts = qtest_initf("-accel kvm:tcg -no-shutdown %s%s", (const char *)data,
|
||||
isoimage);
|
||||
boot_sector_test(qts);
|
||||
qtest_quit(qts);
|
||||
}
|
||||
|
@ -865,7 +865,8 @@ static void vararg_string(void)
|
||||
QString *str;
|
||||
|
||||
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(strcmp(qstring_get_str(str), test_cases[i].decoded) == 0);
|
||||
|
||||
@ -998,17 +999,17 @@ static void vararg_number(void)
|
||||
double valuef = 2.323423423;
|
||||
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_cmpint(val, ==, value);
|
||||
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_cmpint(val, ==, value_ll);
|
||||
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);
|
||||
qobject_unref(qnum);
|
||||
}
|
||||
@ -1042,13 +1043,13 @@ static void keyword_literal(void)
|
||||
|
||||
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_get_bool(qbool) == false);
|
||||
qobject_unref(qbool);
|
||||
|
||||
/* 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_get_bool(qbool) == true);
|
||||
qobject_unref(qbool);
|
||||
@ -1298,7 +1299,7 @@ static void simple_varargs(void)
|
||||
embedded_obj = qobject_from_json("[32, 42]", &error_abort);
|
||||
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));
|
||||
|
||||
qobject_unref(obj);
|
||||
|
@ -88,8 +88,9 @@ static void test_plug_with_device_add_x86(gconstpointer data)
|
||||
for (c = 0; c < td->cores; c++) {
|
||||
for (t = 0; t < td->threads; t++) {
|
||||
char *id = g_strdup_printf("id-%i-%i-%i", s, c, t);
|
||||
qtest_qmp_device_add(td->device_model, id, "'socket-id':'%i', "
|
||||
"'core-id':'%i', 'thread-id':'%i'",
|
||||
qtest_qmp_device_add(td->device_model, id,
|
||||
"{'socket-id':%u, 'core-id':%u,"
|
||||
" 'thread-id':%u}",
|
||||
s, c, t);
|
||||
g_free(id);
|
||||
}
|
||||
@ -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++) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,9 @@
|
||||
#include "libqos/virtio.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)
|
||||
{
|
||||
char *resp = hmp("drive_add 0 if=none,id=drive0");
|
||||
|
@ -456,12 +456,10 @@ static void test_e1000e_multiple_transfers(gconstpointer data)
|
||||
|
||||
static void test_e1000e_hotplug(gconstpointer data)
|
||||
{
|
||||
static const uint8_t slot = 0x06;
|
||||
|
||||
qtest_start("-device e1000e");
|
||||
|
||||
qpci_plug_device_test("e1000e", "e1000e_net", slot, NULL);
|
||||
qpci_unplug_acpi_device_test("e1000e_net", slot);
|
||||
qtest_qmp_device_add("e1000e", "e1000e_net", "{'addr': '0x06'}");
|
||||
qpci_unplug_acpi_device_test("e1000e_net", 0x06);
|
||||
|
||||
qtest_end();
|
||||
}
|
||||
|
@ -115,10 +115,10 @@ static void test_endianness(gconstpointer data)
|
||||
{
|
||||
const TestCase *test = data;
|
||||
|
||||
global_qtest = qtest_startf("-M %s%s%s -device pc-testdev",
|
||||
test->machine,
|
||||
test->superio ? " -device " : "",
|
||||
test->superio ?: "");
|
||||
global_qtest = qtest_initf("-M %s%s%s -device pc-testdev",
|
||||
test->machine,
|
||||
test->superio ? " -device " : "",
|
||||
test->superio ?: "");
|
||||
isa_outl(test, 0xe0, 0x87654321);
|
||||
g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
|
||||
g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
|
||||
@ -187,10 +187,10 @@ static void test_endianness_split(gconstpointer data)
|
||||
{
|
||||
const TestCase *test = data;
|
||||
|
||||
global_qtest = qtest_startf("-M %s%s%s -device pc-testdev",
|
||||
test->machine,
|
||||
test->superio ? " -device " : "",
|
||||
test->superio ?: "");
|
||||
global_qtest = qtest_initf("-M %s%s%s -device pc-testdev",
|
||||
test->machine,
|
||||
test->superio ? " -device " : "",
|
||||
test->superio ?: "");
|
||||
isa_outl(test, 0xe8, 0x87654321);
|
||||
g_assert_cmphex(isa_inl(test, 0xe0), ==, 0x87654321);
|
||||
g_assert_cmphex(isa_inw(test, 0xe2), ==, 0x8765);
|
||||
@ -231,10 +231,10 @@ static void test_endianness_combine(gconstpointer data)
|
||||
{
|
||||
const TestCase *test = data;
|
||||
|
||||
global_qtest = qtest_startf("-M %s%s%s -device pc-testdev",
|
||||
test->machine,
|
||||
test->superio ? " -device " : "",
|
||||
test->superio ?: "");
|
||||
global_qtest = qtest_initf("-M %s%s%s -device pc-testdev",
|
||||
test->machine,
|
||||
test->superio ? " -device " : "",
|
||||
test->superio ?: "");
|
||||
isa_outl(test, 0xe0, 0x87654321);
|
||||
g_assert_cmphex(isa_inl(test, 0xe8), ==, 0x87654321);
|
||||
g_assert_cmphex(isa_inw(test, 0xea), ==, 0x8765);
|
||||
|
@ -26,8 +26,12 @@
|
||||
|
||||
|
||||
#include "libqtest.h"
|
||||
#include "qapi/qmp/qdict.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 FLOPPY_BASE 0x3f0
|
||||
|
@ -29,12 +29,15 @@
|
||||
#include "libqos/libqos.h"
|
||||
#include "libqos/pci-pc.h"
|
||||
#include "libqos/malloc-pc.h"
|
||||
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qemu-common.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "hw/pci/pci_ids.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 IDE_PCI_DEV 1
|
||||
@ -694,7 +697,6 @@ static void test_retry_flush(const char *machine)
|
||||
QPCIDevice *dev;
|
||||
QPCIBar bmdma_bar, ide_bar;
|
||||
uint8_t data;
|
||||
const char *s;
|
||||
|
||||
prepare_blkdebug_script(debug_path, "flush_to_disk");
|
||||
|
||||
@ -722,8 +724,7 @@ static void test_retry_flush(const char *machine)
|
||||
qmp_eventwait("STOP");
|
||||
|
||||
/* Complete the command */
|
||||
s = "{'execute':'cont' }";
|
||||
qmp_discard_response(s);
|
||||
qmp_discard_response("{'execute':'cont' }");
|
||||
|
||||
/* Check registers */
|
||||
data = qpci_io_readb(dev, ide_bar, reg_device);
|
||||
|
@ -414,7 +414,7 @@ int main(int argc, char **argv)
|
||||
/* Run the tests */
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
global_qtest = qtest_startf(
|
||||
global_qtest = qtest_initf(
|
||||
" -chardev socket,id=ipmi0,host=localhost,port=%d,reconnect=10"
|
||||
" -device ipmi-bmc-extern,chardev=ipmi0,id=bmc0"
|
||||
" -device isa-ipmi-bt,bmc=bmc0", emu_port);
|
||||
|
@ -420,19 +420,17 @@ static void test_ivshmem_server_irq(void)
|
||||
static void test_ivshmem_hotplug(void)
|
||||
{
|
||||
const char *arch = qtest_get_arch();
|
||||
gchar *opts;
|
||||
|
||||
qtest_start("");
|
||||
|
||||
opts = g_strdup_printf("'shm': '%s', 'size': '1M'", tmpshm);
|
||||
|
||||
qpci_plug_device_test("ivshmem", "iv1", PCI_SLOT_HP, opts);
|
||||
qtest_qmp_device_add("ivshmem",
|
||||
"iv1", "{'addr': %s, 'shm': %s, 'size': '1M'}",
|
||||
stringify(PCI_SLOT_HP), tmpshm);
|
||||
if (strcmp(arch, "ppc64") != 0) {
|
||||
qpci_unplug_acpi_device_test("iv1", PCI_SLOT_HP);
|
||||
}
|
||||
|
||||
qtest_end();
|
||||
g_free(opts);
|
||||
}
|
||||
|
||||
static void test_ivshmem_memdev(void)
|
||||
|
@ -674,7 +674,7 @@ void ahci_exec(AHCIQState *ahci, uint8_t port,
|
||||
g_assert_cmpint(rc, ==, 0);
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
@ -712,7 +712,7 @@ AHCICommand *ahci_guest_io_halt(AHCIQState *ahci, uint8_t port,
|
||||
void ahci_guest_io_resume(AHCIQState *ahci, AHCICommand *cmd)
|
||||
{
|
||||
/* 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");
|
||||
ahci_command_wait(ahci, cmd);
|
||||
ahci_command_verify(ahci, cmd);
|
||||
|
@ -160,14 +160,9 @@ void qpci_free_pc(QPCIBus *bus)
|
||||
void qpci_unplug_acpi_device_test(const char *id, uint8_t slot)
|
||||
{
|
||||
QDict *response;
|
||||
char *cmd;
|
||||
|
||||
cmd = g_strdup_printf("{'execute': 'device_del',"
|
||||
" 'arguments': {"
|
||||
" 'id': '%s'"
|
||||
"}}", id);
|
||||
response = qmp(cmd);
|
||||
g_free(cmd);
|
||||
response = qmp("{'execute': 'device_del', 'arguments': {'id': %s}}",
|
||||
id);
|
||||
g_assert(response);
|
||||
g_assert(!qdict_haskey(response, "error"));
|
||||
qobject_unref(response);
|
||||
|
@ -395,10 +395,3 @@ QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr)
|
||||
QPCIBar bar = { .addr = addr };
|
||||
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);
|
||||
void qpci_iounmap(QPCIDevice *dev, QPCIBar 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);
|
||||
#endif
|
||||
|
@ -37,13 +37,14 @@ void uhci_port_test(struct qhc *hc, int port, uint16_t expect)
|
||||
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))
|
||||
{
|
||||
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'",
|
||||
port, hcd_id);
|
||||
qtest_qmp_device_add("usb-tablet", id, "{'port': %s, 'bus': %s}",
|
||||
port, bus);
|
||||
|
||||
if (port_check) {
|
||||
port_check();
|
||||
@ -51,5 +52,6 @@ void usb_test_hotplug(const char *hcd_id, const int port,
|
||||
|
||||
qtest_qmp_device_del(id);
|
||||
|
||||
g_free(bus);
|
||||
g_free(id);
|
||||
}
|
||||
|
@ -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_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));
|
||||
#endif
|
||||
|
219
tests/libqtest.c
219
tests/libqtest.c
@ -107,10 +107,28 @@ static void kill_qemu(QTestState *s)
|
||||
pid_t pid;
|
||||
|
||||
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(!WCOREDUMP(wstatus));
|
||||
assert(pid == s->qemu_pid);
|
||||
/*
|
||||
* 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,
|
||||
QTestState *qtest_init(const char *extra_args)
|
||||
{
|
||||
QTestState *s = qtest_init_without_qmp_handshake(false, extra_args);
|
||||
QDict *greeting;
|
||||
|
||||
/* Read the QMP greeting and then do the handshake */
|
||||
qtest_qmp_discard_response(s, "");
|
||||
qtest_qmp_discard_response(s, "{ 'execute': 'qmp_capabilities' }");
|
||||
greeting = qtest_qmp_receive(s);
|
||||
qobject_unref(greeting);
|
||||
qobject_unref(qtest_qmp(s, "{ 'execute': 'qmp_capabilities' }"));
|
||||
|
||||
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);
|
||||
QTestState *s;
|
||||
|
||||
s = qtest_start(args);
|
||||
s = qtest_init(args);
|
||||
g_free(args);
|
||||
global_qtest = NULL;
|
||||
return s;
|
||||
}
|
||||
|
||||
QTestState *qtest_startf(const char *fmt, ...)
|
||||
QTestState *qtest_initf(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
QTestState *s;
|
||||
|
||||
va_start(ap, fmt);
|
||||
s = qtest_vstartf(fmt, ap);
|
||||
s = qtest_vinitf(fmt, ap);
|
||||
va_end(ap);
|
||||
return s;
|
||||
}
|
||||
@ -348,7 +367,7 @@ static GString *qtest_recv_line(QTestState *s)
|
||||
|
||||
if (len == -1 || len == 0) {
|
||||
fprintf(stderr, "Broken pipe\n");
|
||||
exit(1);
|
||||
abort();
|
||||
}
|
||||
|
||||
g_string_append_len(s->rx, buffer, len);
|
||||
@ -435,7 +454,7 @@ static void qmp_response(JSONMessageParser *parser, GQueue *tokens)
|
||||
obj = json_parser_parse(tokens, NULL);
|
||||
if (!obj) {
|
||||
fprintf(stderr, "QMP JSON response parsing failed\n");
|
||||
exit(1);
|
||||
abort();
|
||||
}
|
||||
|
||||
g_assert(!qmp->response);
|
||||
@ -461,7 +480,7 @@ QDict *qmp_fd_receive(int fd)
|
||||
|
||||
if (len == -1 || len == 0) {
|
||||
fprintf(stderr, "Broken pipe\n");
|
||||
exit(1);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (log) {
|
||||
@ -484,26 +503,22 @@ QDict *qtest_qmp_receive(QTestState *s)
|
||||
* in the case that they choose to discard all replies up until
|
||||
* 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_from_jsonv() silently eats leading 0xff as invalid
|
||||
* JSON, but we want to test sending them over the wire to force
|
||||
* resyncs */
|
||||
/*
|
||||
* qobject_from_vjsonf_nofail() chokes on leading 0xff as invalid
|
||||
* JSON, but tests/test-qga.c needs to send that to test QGA
|
||||
* synchronization
|
||||
*/
|
||||
if (*fmt == '\377') {
|
||||
socket_send(fd, fmt, 1);
|
||||
fmt++;
|
||||
}
|
||||
|
||||
/* Going through qobject ensures we escape strings properly.
|
||||
* This seemingly unnecessary copy is required in case va_list
|
||||
* is an array type.
|
||||
*/
|
||||
va_copy(ap_copy, ap);
|
||||
qobj = qobject_from_jsonv(fmt, &ap_copy, &error_abort);
|
||||
va_end(ap_copy);
|
||||
/* Going through qobject ensures we escape strings properly */
|
||||
qobj = qobject_from_vjsonf_nofail(fmt, ap);
|
||||
|
||||
/* No need to send anything for an empty QObject. */
|
||||
if (qobj) {
|
||||
@ -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)
|
||||
{
|
||||
qmp_fd_sendv(fd, fmt, ap);
|
||||
qmp_fd_vsend(fd, fmt, ap);
|
||||
|
||||
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 */
|
||||
return qtest_qmp_receive(s);
|
||||
@ -565,7 +580,7 @@ void qmp_fd_send(int fd, const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
qmp_fd_sendv(fd, fmt, ap);
|
||||
qmp_fd_vsend(fd, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
@ -575,37 +590,20 @@ QDict *qtest_qmp(QTestState *s, const char *fmt, ...)
|
||||
QDict *response;
|
||||
|
||||
va_start(ap, fmt);
|
||||
response = qtest_qmpv(s, fmt, ap);
|
||||
response = qtest_vqmp(s, fmt, ap);
|
||||
va_end(ap);
|
||||
return response;
|
||||
}
|
||||
|
||||
void qtest_async_qmp(QTestState *s, const char *fmt, ...)
|
||||
void qtest_qmp_send(QTestState *s, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
qtest_async_qmpv(s, fmt, ap);
|
||||
qtest_qmp_vsend(s, fmt, 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 *response;
|
||||
@ -628,7 +626,7 @@ void qtest_qmp_eventwait(QTestState *s, const char *event)
|
||||
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;
|
||||
QDict *resp;
|
||||
@ -657,7 +655,7 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...)
|
||||
char *ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = qtest_hmpv(s, fmt, ap);
|
||||
ret = qtest_vhmp(s, fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
@ -963,35 +961,27 @@ QDict *qmp(const char *fmt, ...)
|
||||
QDict *response;
|
||||
|
||||
va_start(ap, fmt);
|
||||
response = qtest_qmpv(global_qtest, fmt, ap);
|
||||
response = qtest_vqmp(global_qtest, fmt, ap);
|
||||
va_end(ap);
|
||||
return response;
|
||||
}
|
||||
|
||||
void qmp_async(const char *fmt, ...)
|
||||
void qmp_send(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
qtest_async_qmpv(global_qtest, fmt, ap);
|
||||
qtest_qmp_vsend(global_qtest, fmt, 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, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = qtest_hmpv(global_qtest, fmt, ap);
|
||||
ret = qtest_vhmp(global_qtest, fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
@ -1031,35 +1021,67 @@ void qtest_cb_for_every_machine(void (*cb)(const char *machine))
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
char *cmd, *opts = NULL;
|
||||
va_list va;
|
||||
QDict *args, *response;
|
||||
va_list ap;
|
||||
|
||||
if (fmt) {
|
||||
va_start(va, fmt);
|
||||
opts = g_strdup_vprintf(fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
args = qdict_from_vjsonf_nofail(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
cmd = g_strdup_printf("{'execute': 'device_add',"
|
||||
" 'arguments': { 'driver': '%s', 'id': '%s'%s%s }}",
|
||||
driver, id, opts ? ", " : "", opts ? opts : "");
|
||||
g_free(opts);
|
||||
g_assert(!qdict_haskey(args, "driver") && !qdict_haskey(args, "id"));
|
||||
qdict_put_str(args, "driver", driver);
|
||||
qdict_put_str(args, "id", id);
|
||||
|
||||
response = qmp(cmd);
|
||||
g_free(cmd);
|
||||
response = qmp("{'execute': 'device_add', 'arguments': %p}", args);
|
||||
g_assert(response);
|
||||
g_assert(!qdict_haskey(response, "event")); /* We don't expect any events */
|
||||
g_assert(!qdict_haskey(response, "error"));
|
||||
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.
|
||||
* 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,
|
||||
*/
|
||||
void qtest_qmp_device_del(const char *id)
|
||||
{
|
||||
QDict *response1, *response2, *event = NULL;
|
||||
char *cmd;
|
||||
bool got_event = false;
|
||||
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("");
|
||||
g_assert(response2);
|
||||
g_assert(!qdict_haskey(response2, "error"));
|
||||
|
||||
if (qdict_haskey(response1, "event")) {
|
||||
event = response1;
|
||||
} else if (qdict_haskey(response2, "event")) {
|
||||
event = response2;
|
||||
qtest_qmp_send(global_qtest,
|
||||
"{'execute': 'device_del', 'arguments': {'id': %s}}",
|
||||
id);
|
||||
rsp = qtest_qmp_receive_success(global_qtest, device_deleted_cb,
|
||||
&got_event);
|
||||
qobject_unref(rsp);
|
||||
if (!got_event) {
|
||||
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)
|
||||
|
124
tests/libqtest.h
124
tests/libqtest.h
@ -22,33 +22,32 @@ typedef struct QTestState QTestState;
|
||||
extern QTestState *global_qtest;
|
||||
|
||||
/**
|
||||
* qtest_startf:
|
||||
* qtest_initf:
|
||||
* @fmt...: Format for creating other arguments to pass to QEMU, formatted
|
||||
* like sprintf().
|
||||
*
|
||||
* Start QEMU and return the resulting #QTestState (but unlike qtest_start(),
|
||||
* #global_qtest is left at NULL).
|
||||
* Convenience wrapper around qtest_start().
|
||||
*
|
||||
* 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
|
||||
* like vsprintf().
|
||||
* @ap: Format arguments.
|
||||
*
|
||||
* Start QEMU and return the resulting #QTestState (but unlike qtest_start(),
|
||||
* #global_qtest is left at NULL).
|
||||
* Convenience wrapper around qtest_start().
|
||||
*
|
||||
* 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:
|
||||
* @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.
|
||||
*/
|
||||
@ -73,62 +72,55 @@ QTestState *qtest_init_without_qmp_handshake(bool use_oob,
|
||||
*/
|
||||
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:
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
* @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.
|
||||
*/
|
||||
void qtest_async_qmp(QTestState *s, const char *fmt, ...);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
void qtest_qmp_send(QTestState *s, const char *fmt, ...)
|
||||
GCC_FMT_ATTR(2, 3);
|
||||
|
||||
/**
|
||||
* qtest_qmpv:
|
||||
* @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
|
||||
*
|
||||
* 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.
|
||||
* @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
|
||||
*
|
||||
* 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:
|
||||
@ -157,6 +149,23 @@ void qtest_qmp_eventwait(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:
|
||||
* @s: #QTestState instance to operate on.
|
||||
@ -172,7 +181,7 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
|
||||
/**
|
||||
* qtest_hmpv:
|
||||
* @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
|
||||
*
|
||||
* 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);
|
||||
*
|
||||
* 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:
|
||||
@ -561,27 +571,23 @@ static inline void qtest_end(void)
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
QDict *qmp(const char *fmt, ...);
|
||||
QDict *qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
|
||||
|
||||
/**
|
||||
* qmp_async:
|
||||
* @fmt...: QMP message to send to qemu
|
||||
* qmp_send:
|
||||
* @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.
|
||||
*/
|
||||
void qmp_async(const char *fmt, ...);
|
||||
|
||||
/**
|
||||
* 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, ...);
|
||||
void qmp_send(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
|
||||
|
||||
/**
|
||||
* qmp_receive:
|
||||
@ -940,10 +946,10 @@ static inline int64_t clock_set(int64_t val)
|
||||
}
|
||||
|
||||
QDict *qmp_fd_receive(int fd);
|
||||
void qmp_fd_sendv(int fd, const char *fmt, va_list ap);
|
||||
void qmp_fd_send(int fd, const char *fmt, ...);
|
||||
QDict *qmp_fdv(int fd, const char *fmt, va_list ap);
|
||||
QDict *qmp_fd(int fd, const char *fmt, ...);
|
||||
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, ...) GCC_FMT_ATTR(2, 3);
|
||||
QDict *qmp_fdv(int fd, const char *fmt, va_list ap) GCC_FMT_ATTR(2, 0);
|
||||
QDict *qmp_fd(int fd, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
|
||||
|
||||
/**
|
||||
* qtest_cb_for_every_machine:
|
||||
@ -957,7 +963,9 @@ void qtest_cb_for_every_machine(void (*cb)(const char *machine));
|
||||
* qtest_qmp_device_add:
|
||||
* @driver: Name of the device that should be added
|
||||
* @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.
|
||||
*/
|
||||
|
@ -363,9 +363,9 @@ int main(int argc, char **argv)
|
||||
g_assert(ret == 0);
|
||||
close(fd);
|
||||
|
||||
global_qtest = qtest_startf("-m 256 -machine palmetto-bmc "
|
||||
"-drive file=%s,format=raw,if=mtd",
|
||||
tmp_path);
|
||||
global_qtest = qtest_initf("-m 256 -machine palmetto-bmc "
|
||||
"-drive file=%s,format=raw,if=mtd",
|
||||
tmp_path);
|
||||
|
||||
qtest_add_func("/m25p80/read_jedec", test_read_jedec);
|
||||
qtest_add_func("/m25p80/erase_sector", test_erase_sector);
|
||||
|
@ -146,7 +146,7 @@ static void cmos_get_date_time(QTestState *s, struct tm *date)
|
||||
|
||||
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)
|
||||
|
@ -84,7 +84,7 @@ static void test_machine_cpu_cli(void)
|
||||
}
|
||||
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' }");
|
||||
g_assert(qdict_haskey(response, "return"));
|
||||
|
@ -14,12 +14,16 @@
|
||||
|
||||
#include "libqtest.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/qmp/qjson.h"
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/range.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "chardev/char.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 end_address = 100 * 1024 * 1024;
|
||||
bool got_stop;
|
||||
@ -146,26 +150,26 @@ static void wait_for_serial(const char *side)
|
||||
} 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.
|
||||
*/
|
||||
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;
|
||||
QDict *response;
|
||||
va_list ap;
|
||||
|
||||
response = qtest_qmp(who, command);
|
||||
va_start(ap, command);
|
||||
qtest_qmp_vsend(who, command, ap);
|
||||
va_end(ap);
|
||||
|
||||
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;
|
||||
return qtest_qmp_receive_success(who, stop_cb, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -174,15 +178,7 @@ static QDict *wait_command(QTestState *who, const char *command)
|
||||
*/
|
||||
static QDict *migrate_query(QTestState *who)
|
||||
{
|
||||
QDict *rsp, *rsp_return;
|
||||
|
||||
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;
|
||||
return wait_command(who, "{ 'execute': 'query-migrate' }");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -322,31 +318,25 @@ static void cleanup(const char *filename)
|
||||
}
|
||||
|
||||
static void migrate_check_parameter(QTestState *who, const char *parameter,
|
||||
const char *value)
|
||||
long long value)
|
||||
{
|
||||
QDict *rsp, *rsp_return;
|
||||
char *result;
|
||||
QDict *rsp_return;
|
||||
|
||||
rsp = wait_command(who, "{ 'execute': 'query-migrate-parameters' }");
|
||||
rsp_return = qdict_get_qdict(rsp, "return");
|
||||
result = g_strdup_printf("%" PRId64,
|
||||
qdict_get_try_int(rsp_return, parameter, -1));
|
||||
g_assert_cmpstr(result, ==, value);
|
||||
g_free(result);
|
||||
qobject_unref(rsp);
|
||||
rsp_return = wait_command(who,
|
||||
"{ 'execute': 'query-migrate-parameters' }");
|
||||
g_assert_cmpint(qdict_get_int(rsp_return, parameter), ==, value);
|
||||
qobject_unref(rsp_return);
|
||||
}
|
||||
|
||||
static void migrate_set_parameter(QTestState *who, const char *parameter,
|
||||
const char *value)
|
||||
long long value)
|
||||
{
|
||||
QDict *rsp;
|
||||
gchar *cmd;
|
||||
|
||||
cmd = g_strdup_printf("{ 'execute': 'migrate-set-parameters',"
|
||||
"'arguments': { '%s': %s } }",
|
||||
parameter, value);
|
||||
rsp = qtest_qmp(who, cmd);
|
||||
g_free(cmd);
|
||||
rsp = qtest_qmp(who,
|
||||
"{ 'execute': 'migrate-set-parameters',"
|
||||
"'arguments': { %s: %lld } }",
|
||||
parameter, value);
|
||||
g_assert(qdict_haskey(rsp, "return"));
|
||||
qobject_unref(rsp);
|
||||
migrate_check_parameter(who, parameter, value);
|
||||
@ -357,51 +347,55 @@ static void migrate_pause(QTestState *who)
|
||||
QDict *rsp;
|
||||
|
||||
rsp = wait_command(who, "{ 'execute': 'migrate-pause' }");
|
||||
g_assert(qdict_haskey(rsp, "return"));
|
||||
qobject_unref(rsp);
|
||||
}
|
||||
|
||||
static void migrate_recover(QTestState *who, const char *uri)
|
||||
{
|
||||
QDict *rsp;
|
||||
gchar *cmd = g_strdup_printf(
|
||||
"{ 'execute': 'migrate-recover', "
|
||||
" 'id': 'recover-cmd', "
|
||||
" 'arguments': { 'uri': '%s' } }", uri);
|
||||
|
||||
rsp = wait_command(who, cmd);
|
||||
g_assert(qdict_haskey(rsp, "return"));
|
||||
g_free(cmd);
|
||||
rsp = wait_command(who,
|
||||
"{ 'execute': 'migrate-recover', "
|
||||
" 'id': 'recover-cmd', "
|
||||
" 'arguments': { 'uri': %s } }",
|
||||
uri);
|
||||
qobject_unref(rsp);
|
||||
}
|
||||
|
||||
static void migrate_set_capability(QTestState *who, const char *capability,
|
||||
const char *value)
|
||||
bool value)
|
||||
{
|
||||
QDict *rsp;
|
||||
gchar *cmd;
|
||||
|
||||
cmd = g_strdup_printf("{ 'execute': 'migrate-set-capabilities',"
|
||||
"'arguments': { "
|
||||
"'capabilities': [ { "
|
||||
"'capability': '%s', 'state': %s } ] } }",
|
||||
capability, value);
|
||||
rsp = qtest_qmp(who, cmd);
|
||||
g_free(cmd);
|
||||
rsp = qtest_qmp(who,
|
||||
"{ 'execute': 'migrate-set-capabilities',"
|
||||
"'arguments': { "
|
||||
"'capabilities': [ { "
|
||||
"'capability': %s, 'state': %i } ] } }",
|
||||
capability, value);
|
||||
g_assert(qdict_haskey(rsp, "return"));
|
||||
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;
|
||||
gchar *cmd;
|
||||
va_list ap;
|
||||
QDict *args, *rsp;
|
||||
|
||||
cmd = g_strdup_printf("{ 'execute': 'migrate',"
|
||||
" 'arguments': { 'uri': '%s' %s } }",
|
||||
uri, extra ? extra : "");
|
||||
rsp = qtest_qmp(who, cmd);
|
||||
g_free(cmd);
|
||||
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);
|
||||
|
||||
rsp = qmp("{ 'execute': 'migrate', 'arguments': %p}", args);
|
||||
g_assert(qdict_haskey(rsp, "return"));
|
||||
qobject_unref(rsp);
|
||||
}
|
||||
@ -411,7 +405,6 @@ static void migrate_postcopy_start(QTestState *from, QTestState *to)
|
||||
QDict *rsp;
|
||||
|
||||
rsp = wait_command(from, "{ 'execute': 'migrate-start-postcopy' }");
|
||||
g_assert(qdict_haskey(rsp, "return"));
|
||||
qobject_unref(rsp);
|
||||
|
||||
if (!got_stop) {
|
||||
@ -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)
|
||||
{
|
||||
QDict *rsp;
|
||||
gchar *cmd;
|
||||
char *expected;
|
||||
int64_t result_int;
|
||||
|
||||
cmd = g_strdup_printf("{ 'execute': 'migrate_set_downtime',"
|
||||
"'arguments': { 'value': %g } }", value);
|
||||
rsp = qtest_qmp(who, cmd);
|
||||
g_free(cmd);
|
||||
rsp = qtest_qmp(who,
|
||||
"{ 'execute': 'migrate_set_downtime',"
|
||||
" 'arguments': { 'value': %f } }", value);
|
||||
g_assert(qdict_haskey(rsp, "return"));
|
||||
qobject_unref(rsp);
|
||||
result_int = value * 1000L;
|
||||
expected = g_strdup_printf("%" PRId64, result_int);
|
||||
migrate_check_parameter(who, "downtime-limit", expected);
|
||||
g_free(expected);
|
||||
migrate_check_parameter(who, "downtime-limit", value * 1000);
|
||||
}
|
||||
|
||||
static void deprecated_set_speed(QTestState *who, const char *value)
|
||||
static void deprecated_set_speed(QTestState *who, long long value)
|
||||
{
|
||||
QDict *rsp;
|
||||
gchar *cmd;
|
||||
|
||||
cmd = g_strdup_printf("{ 'execute': 'migrate_set_speed',"
|
||||
"'arguments': { 'value': %s } }", value);
|
||||
rsp = qtest_qmp(who, cmd);
|
||||
g_free(cmd);
|
||||
rsp = qtest_qmp(who, "{ 'execute': 'migrate_set_speed',"
|
||||
"'arguments': { 'value': %lld } }", value);
|
||||
g_assert(qdict_haskey(rsp, "return"));
|
||||
qobject_unref(rsp);
|
||||
migrate_check_parameter(who, "max-bandwidth", value);
|
||||
@ -566,7 +549,7 @@ static void test_deprecated(void)
|
||||
from = qtest_start("");
|
||||
|
||||
deprecated_set_downtime(from, 0.12345);
|
||||
deprecated_set_speed(from, "12345");
|
||||
deprecated_set_speed(from, 12345);
|
||||
|
||||
qtest_quit(from);
|
||||
}
|
||||
@ -582,21 +565,21 @@ static int migrate_postcopy_prepare(QTestState **from_ptr,
|
||||
return -1;
|
||||
}
|
||||
|
||||
migrate_set_capability(from, "postcopy-ram", "true");
|
||||
migrate_set_capability(to, "postcopy-ram", "true");
|
||||
migrate_set_capability(to, "postcopy-blocktime", "true");
|
||||
migrate_set_capability(from, "postcopy-ram", true);
|
||||
migrate_set_capability(to, "postcopy-ram", true);
|
||||
migrate_set_capability(to, "postcopy-blocktime", true);
|
||||
|
||||
/* We want to pick a speed slow enough that the test completes
|
||||
* quickly, but that it doesn't complete precopy even on a slow
|
||||
* machine, so also set the downtime.
|
||||
*/
|
||||
migrate_set_parameter(from, "max-bandwidth", "100000000");
|
||||
migrate_set_parameter(from, "downtime-limit", "1");
|
||||
migrate_set_parameter(from, "max-bandwidth", 100000000);
|
||||
migrate_set_parameter(from, "downtime-limit", 1);
|
||||
|
||||
/* Wait for the first serial output from the source */
|
||||
wait_for_serial("src_serial");
|
||||
|
||||
migrate(from, uri, NULL);
|
||||
migrate(from, uri, "{}");
|
||||
g_free(uri);
|
||||
|
||||
wait_for_migration_pass(from);
|
||||
@ -642,7 +625,7 @@ static void test_postcopy_recovery(void)
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
migrate_postcopy_start(from, to);
|
||||
@ -679,11 +662,11 @@ static void test_postcopy_recovery(void)
|
||||
* the newly created channel
|
||||
*/
|
||||
wait_for_migration_status(from, "postcopy-paused");
|
||||
migrate(from, uri, ", 'resume': true");
|
||||
migrate(from, uri, "{'resume': true}");
|
||||
g_free(uri);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
@ -691,14 +674,14 @@ static void test_postcopy_recovery(void)
|
||||
static void test_baddest(void)
|
||||
{
|
||||
QTestState *from, *to;
|
||||
QDict *rsp, *rsp_return;
|
||||
QDict *rsp_return;
|
||||
char *status;
|
||||
bool failed;
|
||||
|
||||
if (test_migrate_start(&from, &to, "tcp:0:0", true)) {
|
||||
return;
|
||||
}
|
||||
migrate(from, "tcp:0:0", NULL);
|
||||
migrate(from, "tcp:0:0", "{}");
|
||||
do {
|
||||
status = migrate_query_status(from);
|
||||
g_assert(!strcmp(status, "setup") || !(strcmp(status, "failed")));
|
||||
@ -707,12 +690,10 @@ static void test_baddest(void)
|
||||
} while (!failed);
|
||||
|
||||
/* Is the machine currently running? */
|
||||
rsp = wait_command(from, "{ 'execute': 'query-status' }");
|
||||
g_assert(qdict_haskey(rsp, "return"));
|
||||
rsp_return = qdict_get_qdict(rsp, "return");
|
||||
rsp_return = wait_command(from, "{ 'execute': 'query-status' }");
|
||||
g_assert(qdict_haskey(rsp_return, "running"));
|
||||
g_assert(qdict_get_bool(rsp_return, "running"));
|
||||
qobject_unref(rsp);
|
||||
qobject_unref(rsp_return);
|
||||
|
||||
test_migrate_end(from, to, false);
|
||||
}
|
||||
@ -731,19 +712,19 @@ static void test_precopy_unix(void)
|
||||
* machine, so also set the downtime.
|
||||
*/
|
||||
/* 1 ms should make it not converge*/
|
||||
migrate_set_parameter(from, "downtime-limit", "1");
|
||||
migrate_set_parameter(from, "downtime-limit", 1);
|
||||
/* 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_serial("src_serial");
|
||||
|
||||
migrate(from, uri, NULL);
|
||||
migrate(from, uri, "{}");
|
||||
|
||||
wait_for_migration_pass(from);
|
||||
|
||||
/* 300 ms should converge */
|
||||
migrate_set_parameter(from, "downtime-limit", "300");
|
||||
migrate_set_parameter(from, "downtime-limit", 300);
|
||||
|
||||
if (!got_stop) {
|
||||
qtest_qmp_eventwait(from, "STOP");
|
||||
|
@ -267,8 +267,8 @@ static void pc_dynamic_cpu_cfg(const void *data)
|
||||
QList *cpus;
|
||||
QTestState *qs;
|
||||
|
||||
qs = qtest_startf("%s %s", data ? (char *)data : "",
|
||||
"-nodefaults --preconfig -smp 2");
|
||||
qs = qtest_initf("%s -nodefaults --preconfig -smp 2",
|
||||
data ? (char *)data : "");
|
||||
|
||||
/* create 2 numa nodes */
|
||||
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)
|
||||
{
|
||||
const PnvChip *chip = data;
|
||||
|
||||
global_qtest = qtest_startf("-M powernv,accel=tcg -cpu %s",
|
||||
chip->cpu_model);
|
||||
global_qtest = qtest_initf("-M powernv,accel=tcg -cpu %s",
|
||||
chip->cpu_model);
|
||||
test_xscom_cfam_id(chip);
|
||||
qtest_quit(global_qtest);
|
||||
}
|
||||
@ -114,8 +114,8 @@ static void test_core(const void *data)
|
||||
{
|
||||
const PnvChip *chip = data;
|
||||
|
||||
global_qtest = qtest_startf("-M powernv,accel=tcg -cpu %s",
|
||||
chip->cpu_model);
|
||||
global_qtest = qtest_initf("-M powernv,accel=tcg -cpu %s",
|
||||
chip->cpu_model);
|
||||
test_xscom_core(chip);
|
||||
qtest_quit(global_qtest);
|
||||
}
|
||||
|
@ -49,11 +49,11 @@ static void test_machine(const void *machine)
|
||||
/* The pseries firmware boots much faster without the default devices */
|
||||
extra_args = strcmp(machine, "pseries") == 0 ? "-nodefaults" : "";
|
||||
|
||||
global_qtest = qtest_startf("-M %s,accel=tcg %s "
|
||||
"-prom-env 'use-nvramrc?=true' "
|
||||
"-prom-env 'nvramrc=%x %x l!' ",
|
||||
(const char *)machine, extra_args,
|
||||
MAGIC, ADDRESS);
|
||||
global_qtest = qtest_initf("-M %s,accel=tcg %s "
|
||||
"-prom-env 'use-nvramrc?=true' "
|
||||
"-prom-env 'nvramrc=%x %x l!' ",
|
||||
(const char *)machine, extra_args,
|
||||
MAGIC, ADDRESS);
|
||||
check_guest_memory();
|
||||
qtest_quit(global_qtest);
|
||||
}
|
||||
|
@ -159,12 +159,12 @@ static void cleanup_blocking_cmd(void)
|
||||
|
||||
static void send_cmd_that_blocks(QTestState *s, const char *id)
|
||||
{
|
||||
qtest_async_qmp(s, "{ 'execute': 'blockdev-add', 'id': %s,"
|
||||
" 'arguments': {"
|
||||
" 'driver': 'blkdebug', 'node-name': %s,"
|
||||
" 'config': %s,"
|
||||
" 'image': { 'driver': 'null-co' } } }",
|
||||
id, id, fifo_name);
|
||||
qtest_qmp_send(s, "{ 'execute': 'blockdev-add', 'id': %s,"
|
||||
" 'arguments': {"
|
||||
" 'driver': 'blkdebug', 'node-name': %s,"
|
||||
" 'config': %s,"
|
||||
" 'image': { 'driver': 'null-co' } } }",
|
||||
id, id, fifo_name);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
@ -235,7 +235,7 @@ static void test_qmp_oob(void)
|
||||
/* OOB command overtakes slow in-band command */
|
||||
setup_blocking_cmd();
|
||||
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");
|
||||
recv_cmd_id(qts, "oob-1");
|
||||
unblock_blocked_cmd();
|
||||
@ -244,7 +244,7 @@ static void test_qmp_oob(void)
|
||||
|
||||
/* Even malformed in-band command fails in-band */
|
||||
send_cmd_that_blocks(qts, "blocks-2");
|
||||
qtest_async_qmp(qts, "{ 'id': 'err-2' }");
|
||||
qtest_qmp_send(qts, "{ 'id': 'err-2' }");
|
||||
unblock_blocked_cmd();
|
||||
recv_cmd_id(qts, "blocks-2");
|
||||
recv_cmd_id(qts, "err-2");
|
||||
@ -436,7 +436,7 @@ static void add_query_tests(QmpSchema *schema)
|
||||
static void test_qmp_preconfig(void)
|
||||
{
|
||||
QDict *rsp, *ret;
|
||||
QTestState *qs = qtest_startf("%s --preconfig", common_args);
|
||||
QTestState *qs = qtest_initf("%s --preconfig", common_args);
|
||||
|
||||
/* preconfig state */
|
||||
/* enabled commands, no error expected */
|
||||
|
@ -184,8 +184,8 @@ static QSDHCI *machine_start(const struct sdhci_t *test)
|
||||
uint16_t vendor_id, device_id;
|
||||
uint64_t barsize;
|
||||
|
||||
global_qtest = qtest_startf("-machine %s -device sdhci-pci",
|
||||
test->machine);
|
||||
global_qtest = qtest_initf("-machine %s -device sdhci-pci",
|
||||
test->machine);
|
||||
|
||||
s->pci.bus = qpci_init_pc(global_qtest, NULL);
|
||||
|
||||
@ -200,7 +200,7 @@ static QSDHCI *machine_start(const struct sdhci_t *test)
|
||||
qpci_device_enable(s->pci.dev);
|
||||
} else {
|
||||
/* SysBus */
|
||||
global_qtest = qtest_startf("-machine %s", test->machine);
|
||||
global_qtest = qtest_initf("-machine %s", test->machine);
|
||||
s->addr = test->sdhci.addr;
|
||||
}
|
||||
|
||||
|
@ -58,9 +58,9 @@ static void test_init(TestData *d)
|
||||
{
|
||||
QTestState *qs;
|
||||
|
||||
qs = qtest_startf("-machine q35 %s %s",
|
||||
d->noreboot ? "" : "-global ICH9-LPC.noreboot=false",
|
||||
!d->args ? "" : d->args);
|
||||
qs = qtest_initf("-machine q35 %s %s",
|
||||
d->noreboot ? "" : "-global ICH9-LPC.noreboot=false",
|
||||
!d->args ? "" : d->args);
|
||||
global_qtest = qs;
|
||||
qtest_irq_intercept_in(qs, "ioapic");
|
||||
|
||||
|
@ -10,11 +10,15 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "libqtest.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qemu/iov.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "qemu/error-report.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)
|
||||
{
|
||||
int send_sock[2], recv_sock;
|
||||
@ -36,7 +40,7 @@ static void test_mirror(void)
|
||||
ret = mkstemp(sock_path);
|
||||
g_assert_cmpint(ret, !=, -1);
|
||||
|
||||
global_qtest = qtest_startf(
|
||||
global_qtest = qtest_initf(
|
||||
"-netdev socket,id=qtest-bn0,fd=%d "
|
||||
"-device %s,netdev=qtest-bn0,id=qtest-e0 "
|
||||
"-chardev socket,id=mirror0,path=%s,server,nowait "
|
||||
|
@ -52,11 +52,15 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "libqtest.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qemu/iov.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "qemu/error-report.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)
|
||||
{
|
||||
if (g_str_equal(qtest_get_arch(), "s390x")) {
|
||||
@ -86,7 +90,7 @@ static void test_redirector_tx(void)
|
||||
ret = mkstemp(sock_path1);
|
||||
g_assert_cmpint(ret, !=, -1);
|
||||
|
||||
global_qtest = qtest_startf(
|
||||
global_qtest = qtest_initf(
|
||||
"-netdev socket,id=qtest-bn0,fd=%d "
|
||||
"-device %s,netdev=qtest-bn0,id=qtest-e0 "
|
||||
"-chardev socket,id=redirector0,path=%s,server,nowait "
|
||||
@ -155,7 +159,7 @@ static void test_redirector_rx(void)
|
||||
ret = mkstemp(sock_path1);
|
||||
g_assert_cmpint(ret, !=, -1);
|
||||
|
||||
global_qtest = qtest_startf(
|
||||
global_qtest = qtest_initf(
|
||||
"-netdev socket,id=qtest-bn0,fd=%d "
|
||||
"-device %s,netdev=qtest-bn0,id=qtest-e0 "
|
||||
"-chardev socket,id=redirector0,path=%s,server,nowait "
|
||||
|
150
tests/test-qga.c
150
tests/test-qga.c
@ -146,12 +146,11 @@ static void test_qga_sync_delimited(gconstpointer fix)
|
||||
guint32 v, r = g_random_int();
|
||||
unsigned char c;
|
||||
QDict *ret;
|
||||
gchar *cmd;
|
||||
|
||||
cmd = g_strdup_printf("\xff{'execute': 'guest-sync-delimited',"
|
||||
" 'arguments': {'id': %u } }", r);
|
||||
qmp_fd_send(fixture->fd, cmd);
|
||||
g_free(cmd);
|
||||
qmp_fd_send(fixture->fd,
|
||||
"\xff{'execute': 'guest-sync-delimited',"
|
||||
" 'arguments': {'id': %u } }",
|
||||
r);
|
||||
|
||||
/*
|
||||
* Read and ignore garbage until resynchronized.
|
||||
@ -188,7 +187,6 @@ static void test_qga_sync(gconstpointer fix)
|
||||
const TestFixture *fixture = fix;
|
||||
guint32 v, r = g_random_int();
|
||||
QDict *ret;
|
||||
gchar *cmd;
|
||||
|
||||
/*
|
||||
* TODO guest-sync is inherently limited: we cannot distinguish
|
||||
@ -201,10 +199,9 @@ static void test_qga_sync(gconstpointer fix)
|
||||
* invalid JSON. Testing of '\xff' handling is done in
|
||||
* guest-sync-delimited instead.
|
||||
*/
|
||||
cmd = g_strdup_printf("{'execute': 'guest-sync',"
|
||||
" 'arguments': {'id': %u } }", r);
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
g_free(cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-sync', 'arguments': {'id': %u } }",
|
||||
r);
|
||||
|
||||
g_assert_nonnull(ret);
|
||||
qmp_assert_no_error(ret);
|
||||
@ -428,7 +425,7 @@ static void test_qga_file_ops(gconstpointer fix)
|
||||
const TestFixture *fixture = fix;
|
||||
const unsigned char helloworld[] = "Hello World!\n";
|
||||
const char *b64;
|
||||
gchar *cmd, *path, *enc;
|
||||
gchar *path, *enc;
|
||||
unsigned char *dec;
|
||||
QDict *ret, *val;
|
||||
int64_t id, eof;
|
||||
@ -446,10 +443,10 @@ static void test_qga_file_ops(gconstpointer fix)
|
||||
|
||||
enc = g_base64_encode(helloworld, sizeof(helloworld));
|
||||
/* write */
|
||||
cmd = g_strdup_printf("{'execute': 'guest-file-write',"
|
||||
" 'arguments': { 'handle': %" PRId64 ","
|
||||
" 'buf-b64': '%s' } }", id, enc);
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-file-write',"
|
||||
" 'arguments': { 'handle': %" PRId64 ", 'buf-b64': %s } }",
|
||||
id, enc);
|
||||
g_assert_nonnull(ret);
|
||||
qmp_assert_no_error(ret);
|
||||
|
||||
@ -459,23 +456,20 @@ static void test_qga_file_ops(gconstpointer fix)
|
||||
g_assert_cmpint(count, ==, sizeof(helloworld));
|
||||
g_assert_cmpint(eof, ==, 0);
|
||||
qobject_unref(ret);
|
||||
g_free(cmd);
|
||||
|
||||
/* flush */
|
||||
cmd = g_strdup_printf("{'execute': 'guest-file-flush',"
|
||||
" 'arguments': {'handle': %" PRId64 "} }",
|
||||
id);
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-file-flush',"
|
||||
" 'arguments': {'handle': %" PRId64 "} }",
|
||||
id);
|
||||
qobject_unref(ret);
|
||||
g_free(cmd);
|
||||
|
||||
/* close */
|
||||
cmd = g_strdup_printf("{'execute': 'guest-file-close',"
|
||||
" 'arguments': {'handle': %" PRId64 "} }",
|
||||
id);
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-file-close',"
|
||||
" 'arguments': {'handle': %" PRId64 "} }",
|
||||
id);
|
||||
qobject_unref(ret);
|
||||
g_free(cmd);
|
||||
|
||||
/* check content */
|
||||
path = g_build_filename(fixture->test_dir, "foo", NULL);
|
||||
@ -497,10 +491,10 @@ static void test_qga_file_ops(gconstpointer fix)
|
||||
qobject_unref(ret);
|
||||
|
||||
/* read */
|
||||
cmd = g_strdup_printf("{'execute': 'guest-file-read',"
|
||||
" 'arguments': { 'handle': %" PRId64 "} }",
|
||||
id);
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-file-read',"
|
||||
" 'arguments': { 'handle': %" PRId64 "} }",
|
||||
id);
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
count = qdict_get_int(val, "count");
|
||||
eof = qdict_get_bool(val, "eof");
|
||||
@ -510,14 +504,13 @@ static void test_qga_file_ops(gconstpointer fix)
|
||||
g_assert_cmpstr(b64, ==, enc);
|
||||
|
||||
qobject_unref(ret);
|
||||
g_free(cmd);
|
||||
g_free(enc);
|
||||
|
||||
/* read eof */
|
||||
cmd = g_strdup_printf("{'execute': 'guest-file-read',"
|
||||
" 'arguments': { 'handle': %" PRId64 "} }",
|
||||
id);
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-file-read',"
|
||||
" 'arguments': { 'handle': %" PRId64 "} }",
|
||||
id);
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
count = qdict_get_int(val, "count");
|
||||
eof = qdict_get_bool(val, "eof");
|
||||
@ -526,14 +519,13 @@ static void test_qga_file_ops(gconstpointer fix)
|
||||
g_assert(eof);
|
||||
g_assert_cmpstr(b64, ==, "");
|
||||
qobject_unref(ret);
|
||||
g_free(cmd);
|
||||
|
||||
/* seek */
|
||||
cmd = g_strdup_printf("{'execute': 'guest-file-seek',"
|
||||
" 'arguments': { 'handle': %" PRId64 ", "
|
||||
" 'offset': %d, 'whence': '%s' } }",
|
||||
id, 6, "set");
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-file-seek',"
|
||||
" 'arguments': { 'handle': %" PRId64 ", "
|
||||
" 'offset': %d, 'whence': %s } }",
|
||||
id, 6, "set");
|
||||
qmp_assert_no_error(ret);
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
count = qdict_get_int(val, "position");
|
||||
@ -541,13 +533,12 @@ static void test_qga_file_ops(gconstpointer fix)
|
||||
g_assert_cmpint(count, ==, 6);
|
||||
g_assert(!eof);
|
||||
qobject_unref(ret);
|
||||
g_free(cmd);
|
||||
|
||||
/* partial read */
|
||||
cmd = g_strdup_printf("{'execute': 'guest-file-read',"
|
||||
" 'arguments': { 'handle': %" PRId64 "} }",
|
||||
id);
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-file-read',"
|
||||
" 'arguments': { 'handle': %" PRId64 "} }",
|
||||
id);
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
count = qdict_get_int(val, "count");
|
||||
eof = qdict_get_bool(val, "eof");
|
||||
@ -560,15 +551,13 @@ static void test_qga_file_ops(gconstpointer fix)
|
||||
g_free(dec);
|
||||
|
||||
qobject_unref(ret);
|
||||
g_free(cmd);
|
||||
|
||||
/* close */
|
||||
cmd = g_strdup_printf("{'execute': 'guest-file-close',"
|
||||
" 'arguments': {'handle': %" PRId64 "} }",
|
||||
id);
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-file-close',"
|
||||
" 'arguments': {'handle': %" PRId64 "} }",
|
||||
id);
|
||||
qobject_unref(ret);
|
||||
g_free(cmd);
|
||||
}
|
||||
|
||||
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 unsigned char helloworld[] = "Hello World!\n";
|
||||
const char *b64;
|
||||
gchar *cmd, *enc;
|
||||
gchar *enc;
|
||||
QDict *ret, *val;
|
||||
int64_t id, eof;
|
||||
gsize count;
|
||||
@ -591,10 +580,10 @@ static void test_qga_file_write_read(gconstpointer fix)
|
||||
|
||||
enc = g_base64_encode(helloworld, sizeof(helloworld));
|
||||
/* write */
|
||||
cmd = g_strdup_printf("{'execute': 'guest-file-write',"
|
||||
" 'arguments': { 'handle': %" PRId64 ","
|
||||
" 'buf-b64': '%s' } }", id, enc);
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-file-write',"
|
||||
" 'arguments': { 'handle': %" PRId64 ","
|
||||
" 'buf-b64': %s } }", id, enc);
|
||||
g_assert_nonnull(ret);
|
||||
qmp_assert_no_error(ret);
|
||||
|
||||
@ -604,13 +593,12 @@ static void test_qga_file_write_read(gconstpointer fix)
|
||||
g_assert_cmpint(count, ==, sizeof(helloworld));
|
||||
g_assert_cmpint(eof, ==, 0);
|
||||
qobject_unref(ret);
|
||||
g_free(cmd);
|
||||
|
||||
/* read (check implicit flush) */
|
||||
cmd = g_strdup_printf("{'execute': 'guest-file-read',"
|
||||
" 'arguments': { 'handle': %" PRId64 "} }",
|
||||
id);
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-file-read',"
|
||||
" 'arguments': { 'handle': %" PRId64 "} }",
|
||||
id);
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
count = qdict_get_int(val, "count");
|
||||
eof = qdict_get_bool(val, "eof");
|
||||
@ -619,14 +607,13 @@ static void test_qga_file_write_read(gconstpointer fix)
|
||||
g_assert(eof);
|
||||
g_assert_cmpstr(b64, ==, "");
|
||||
qobject_unref(ret);
|
||||
g_free(cmd);
|
||||
|
||||
/* seek to 0 */
|
||||
cmd = g_strdup_printf("{'execute': 'guest-file-seek',"
|
||||
" 'arguments': { 'handle': %" PRId64 ", "
|
||||
" 'offset': %d, 'whence': '%s' } }",
|
||||
id, 0, "set");
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-file-seek',"
|
||||
" 'arguments': { 'handle': %" PRId64 ", "
|
||||
" 'offset': %d, 'whence': %s } }",
|
||||
id, 0, "set");
|
||||
qmp_assert_no_error(ret);
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
count = qdict_get_int(val, "position");
|
||||
@ -634,13 +621,12 @@ static void test_qga_file_write_read(gconstpointer fix)
|
||||
g_assert_cmpint(count, ==, 0);
|
||||
g_assert(!eof);
|
||||
qobject_unref(ret);
|
||||
g_free(cmd);
|
||||
|
||||
/* read */
|
||||
cmd = g_strdup_printf("{'execute': 'guest-file-read',"
|
||||
" 'arguments': { 'handle': %" PRId64 "} }",
|
||||
id);
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-file-read',"
|
||||
" 'arguments': { 'handle': %" PRId64 "} }",
|
||||
id);
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
count = qdict_get_int(val, "count");
|
||||
eof = qdict_get_bool(val, "eof");
|
||||
@ -649,16 +635,14 @@ static void test_qga_file_write_read(gconstpointer fix)
|
||||
g_assert(eof);
|
||||
g_assert_cmpstr(b64, ==, enc);
|
||||
qobject_unref(ret);
|
||||
g_free(cmd);
|
||||
g_free(enc);
|
||||
|
||||
/* close */
|
||||
cmd = g_strdup_printf("{'execute': 'guest-file-close',"
|
||||
" 'arguments': {'handle': %" PRId64 "} }",
|
||||
id);
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-file-close',"
|
||||
" 'arguments': {'handle': %" PRId64 "} }",
|
||||
id);
|
||||
qobject_unref(ret);
|
||||
g_free(cmd);
|
||||
}
|
||||
|
||||
static void test_qga_get_time(gconstpointer fix)
|
||||
@ -814,7 +798,6 @@ static void test_qga_guest_exec(gconstpointer fix)
|
||||
int64_t pid, now, exitcode;
|
||||
gsize len;
|
||||
bool exited;
|
||||
char *cmd;
|
||||
|
||||
/* exec 'echo foo bar' */
|
||||
ret = qmp_fd(fixture->fd, "{'execute': 'guest-exec', 'arguments': {"
|
||||
@ -829,10 +812,10 @@ static void test_qga_guest_exec(gconstpointer fix)
|
||||
|
||||
/* wait for completion */
|
||||
now = g_get_monotonic_time();
|
||||
cmd = g_strdup_printf("{'execute': 'guest-exec-status',"
|
||||
" 'arguments': { 'pid': %" PRId64 " } }", pid);
|
||||
do {
|
||||
ret = qmp_fd(fixture->fd, cmd);
|
||||
ret = qmp_fd(fixture->fd,
|
||||
"{'execute': 'guest-exec-status',"
|
||||
" 'arguments': { 'pid': %" PRId64 " } }", pid);
|
||||
g_assert_nonnull(ret);
|
||||
val = qdict_get_qdict(ret, "return");
|
||||
exited = qdict_get_bool(val, "exited");
|
||||
@ -842,7 +825,6 @@ static void test_qga_guest_exec(gconstpointer fix)
|
||||
} while (!exited &&
|
||||
g_get_monotonic_time() < now + 5 * G_TIME_SPAN_SECOND);
|
||||
g_assert(exited);
|
||||
g_free(cmd);
|
||||
|
||||
/* check stdout */
|
||||
exitcode = qdict_get_int(val, "exitcode");
|
||||
|
@ -47,15 +47,13 @@ static void visitor_input_teardown(TestInputVisitorData *data,
|
||||
/* 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
|
||||
functions (and not in main()). */
|
||||
static Visitor *visitor_input_test_init_internal(TestInputVisitorData *data,
|
||||
bool keyval,
|
||||
const char *json_string,
|
||||
va_list *ap)
|
||||
|
||||
static Visitor *test_init_internal(TestInputVisitorData *data, bool keyval,
|
||||
QObject *obj)
|
||||
{
|
||||
visitor_input_teardown(data, NULL);
|
||||
|
||||
data->obj = qobject_from_jsonv(json_string, ap, &error_abort);
|
||||
g_assert(data->obj);
|
||||
data->obj = obj;
|
||||
|
||||
if (keyval) {
|
||||
data->qiv = qobject_input_visitor_new_keyval(data->obj);
|
||||
@ -75,7 +73,8 @@ Visitor *visitor_input_test_init_full(TestInputVisitorData *data,
|
||||
va_list ap;
|
||||
|
||||
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);
|
||||
return v;
|
||||
}
|
||||
@ -88,7 +87,8 @@ Visitor *visitor_input_test_init(TestInputVisitorData *data,
|
||||
va_list ap;
|
||||
|
||||
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);
|
||||
return v;
|
||||
}
|
||||
@ -103,7 +103,8 @@ Visitor *visitor_input_test_init(TestInputVisitorData *data,
|
||||
static Visitor *visitor_input_test_init_raw(TestInputVisitorData *data,
|
||||
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,
|
||||
|
@ -22,8 +22,6 @@
|
||||
#define TIS_REG(LOCTY, REG) \
|
||||
(TPM_TIS_ADDR_BASE + ((LOCTY) << 12) + REG)
|
||||
|
||||
static bool got_stop;
|
||||
|
||||
void tpm_util_crb_transfer(QTestState *s,
|
||||
const unsigned char *req, size_t req_size,
|
||||
unsigned char *rsp, size_t rsp_size)
|
||||
@ -239,52 +237,27 @@ void tpm_util_swtpm_kill(GPid pid)
|
||||
void tpm_util_migrate(QTestState *who, const char *uri)
|
||||
{
|
||||
QDict *rsp;
|
||||
gchar *cmd;
|
||||
|
||||
cmd = g_strdup_printf("{ 'execute': 'migrate',"
|
||||
"'arguments': { 'uri': '%s' } }",
|
||||
uri);
|
||||
rsp = qtest_qmp(who, cmd);
|
||||
g_free(cmd);
|
||||
rsp = qtest_qmp(who,
|
||||
"{ 'execute': 'migrate', 'arguments': { 'uri': %s } }",
|
||||
uri);
|
||||
g_assert(qdict_haskey(rsp, "return"));
|
||||
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)
|
||||
{
|
||||
while (true) {
|
||||
QDict *rsp, *rsp_return;
|
||||
QDict *rsp_return;
|
||||
bool completed;
|
||||
const char *status;
|
||||
|
||||
rsp = tpm_util_wait_command(who, "{ 'execute': 'query-migrate' }");
|
||||
rsp_return = qdict_get_qdict(rsp, "return");
|
||||
qtest_qmp_send(who, "{ 'execute': 'query-migrate' }");
|
||||
rsp_return = qtest_qmp_receive_success(who, NULL, NULL);
|
||||
status = qdict_get_str(rsp_return, "status");
|
||||
completed = strcmp(status, "completed") == 0;
|
||||
g_assert_cmpstr(status, !=, "failed");
|
||||
qobject_unref(rsp);
|
||||
qobject_unref(rsp_return);
|
||||
if (completed) {
|
||||
return;
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ static void pci_ehci_port_3_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)
|
||||
|
||||
static void test_ohci_hotplug(void)
|
||||
{
|
||||
usb_test_hotplug("ohci", 1, NULL);
|
||||
usb_test_hotplug("ohci", "1", NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -43,12 +43,12 @@ static void test_port_2(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)
|
||||
{
|
||||
qtest_qmp_device_add("usb-storage", "usbdev0", "'drive': 'drive0'");
|
||||
qtest_qmp_device_add("usb-storage", "usbdev0", "{'drive': 'drive0'}");
|
||||
|
||||
qtest_qmp_device_del("usbdev0");
|
||||
}
|
||||
|
@ -18,13 +18,13 @@ static void test_xhci_init(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)
|
||||
{
|
||||
qtest_qmp_device_add("usb-uas", "uas", NULL);
|
||||
qtest_qmp_device_add("scsi-hd", "scsihd", "'drive': 'drive0'");
|
||||
qtest_qmp_device_add("usb-uas", "uas", "{}");
|
||||
qtest_qmp_device_add("scsi-hd", "scsihd", "{'drive': 'drive0'}");
|
||||
|
||||
/* TODO:
|
||||
UAS HBA driver in libqos, to check that
|
||||
@ -37,10 +37,10 @@ static void test_usb_uas_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");
|
||||
/* 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");
|
||||
}
|
||||
|
||||
|
@ -709,11 +709,7 @@ static void test_migrate(void)
|
||||
g_assert(qdict_haskey(rsp, "return"));
|
||||
qobject_unref(rsp);
|
||||
|
||||
cmd = g_strdup_printf("{ 'execute': 'migrate',"
|
||||
"'arguments': { 'uri': '%s' } }",
|
||||
uri);
|
||||
rsp = qmp(cmd);
|
||||
g_free(cmd);
|
||||
rsp = qmp("{ 'execute': 'migrate', 'arguments': { 'uri': %s } }", uri);
|
||||
g_assert(qdict_haskey(rsp, "return"));
|
||||
qobject_unref(rsp);
|
||||
|
||||
|
@ -23,8 +23,8 @@ int main(int argc, char **argv)
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
qtest_add_func("/virtio/balloon/nop", balloon_nop);
|
||||
|
||||
global_qtest = qtest_startf("-device virtio-balloon-%s",
|
||||
qvirtio_get_dev_type());
|
||||
global_qtest = qtest_initf("-device virtio-balloon-%s",
|
||||
qvirtio_get_dev_type());
|
||||
ret = g_test_run();
|
||||
|
||||
qtest_end();
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "libqos/virtio-pci.h"
|
||||
#include "libqos/virtio-mmio.h"
|
||||
#include "libqos/malloc-generic.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qemu/bswap.h"
|
||||
#include "standard-headers/linux/virtio_ids.h"
|
||||
#include "standard-headers/linux/virtio_config.h"
|
||||
@ -23,6 +24,9 @@
|
||||
#include "standard-headers/linux/virtio_blk.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 QVIRTIO_BLK_TIMEOUT_US (30 * 1000 * 1000)
|
||||
#define PCI_SLOT_HP 0x06
|
||||
@ -89,10 +93,10 @@ static void arm_test_start(void)
|
||||
|
||||
tmp_path = drive_create();
|
||||
|
||||
global_qtest = qtest_startf("-machine virt "
|
||||
"-drive if=none,id=drive0,file=%s,format=raw "
|
||||
"-device virtio-blk-device,drive=drive0",
|
||||
tmp_path);
|
||||
global_qtest = qtest_initf("-machine virt "
|
||||
"-drive if=none,id=drive0,file=%s,format=raw "
|
||||
"-device virtio-blk-device,drive=drive0",
|
||||
tmp_path);
|
||||
unlink(tmp_path);
|
||||
g_free(tmp_path);
|
||||
}
|
||||
@ -662,8 +666,9 @@ static void pci_hotplug(void)
|
||||
qs = pci_test_start();
|
||||
|
||||
/* plug secondary disk */
|
||||
qpci_plug_device_test("virtio-blk-pci", "drv1", PCI_SLOT_HP,
|
||||
"'drive': 'drive1'");
|
||||
qtest_qmp_device_add("virtio-blk-pci", "drv1",
|
||||
"{'addr': %s, 'drive': 'drive1'}",
|
||||
stringify(PCI_SLOT_HP));
|
||||
|
||||
dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT_HP);
|
||||
g_assert(dev);
|
||||
|
@ -14,17 +14,17 @@
|
||||
/* Tests only initialization so far. TODO: Replace with functional tests */
|
||||
static void console_nop(void)
|
||||
{
|
||||
global_qtest = qtest_startf("-device virtio-serial-%s,id=vser0 "
|
||||
"-device virtconsole,bus=vser0.0",
|
||||
qvirtio_get_dev_type());
|
||||
global_qtest = qtest_initf("-device virtio-serial-%s,id=vser0 "
|
||||
"-device virtconsole,bus=vser0.0",
|
||||
qvirtio_get_dev_type());
|
||||
qtest_end();
|
||||
}
|
||||
|
||||
static void serialport_nop(void)
|
||||
{
|
||||
global_qtest = qtest_startf("-device virtio-serial-%s,id=vser0 "
|
||||
"-device virtserialport,bus=vser0.0",
|
||||
qvirtio_get_dev_type());
|
||||
global_qtest = qtest_initf("-device virtio-serial-%s,id=vser0 "
|
||||
"-device virtserialport,bus=vser0.0",
|
||||
qvirtio_get_dev_type());
|
||||
qtest_end();
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,8 @@ static void hotplug(void)
|
||||
|
||||
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) {
|
||||
qpci_unplug_acpi_device_test("net1", PCI_SLOT_HP);
|
||||
|
@ -22,7 +22,8 @@ static void hotplug(void)
|
||||
{
|
||||
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) {
|
||||
qpci_unplug_acpi_device_test("rng1", PCI_SLOT_HP);
|
||||
|
@ -199,7 +199,7 @@ static void hotplug(void)
|
||||
|
||||
qs = qvirtio_scsi_start(
|
||||
"-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");
|
||||
qvirtio_scsi_stop(qs);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ static void virtio_serial_nop(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");
|
||||
}
|
||||
@ -31,8 +31,8 @@ int main(int argc, char **argv)
|
||||
qtest_add_func("/virtio/serial/nop", virtio_serial_nop);
|
||||
qtest_add_func("/virtio/serial/hotplug", hotplug);
|
||||
|
||||
global_qtest = qtest_startf("-device virtio-serial-%s",
|
||||
qvirtio_get_dev_type());
|
||||
global_qtest = qtest_initf("-device virtio-serial-%s",
|
||||
qvirtio_get_dev_type());
|
||||
ret = g_test_run();
|
||||
|
||||
qtest_end();
|
||||
|
@ -142,7 +142,7 @@ static void vmgenid_set_guid_test(void)
|
||||
|
||||
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_guid_from_memory(&measured);
|
||||
@ -155,7 +155,7 @@ static void vmgenid_set_guid_auto_test(void)
|
||||
{
|
||||
QemuUUID measured;
|
||||
|
||||
global_qtest = qtest_startf(GUID_CMD("auto"));
|
||||
global_qtest = qtest_initf(GUID_CMD("auto"));
|
||||
|
||||
read_guid_from_memory(&measured);
|
||||
|
||||
@ -171,7 +171,7 @@ static void vmgenid_query_monitor_test(void)
|
||||
|
||||
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_guid_from_monitor(&measured);
|
||||
|
Loading…
Reference in New Issue
Block a user