Some fixes and improvements for various qtests by Eric and me.

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJZu4MxAAoJEC7Z13T+cC21D/AQAJUxgGbNwos+hzxrXnzQCj6K
 EqC0pqyUE/XkxZvy3/HjSt4VzecHDS59i8hNEo0+wyb/Wt/RV4lTkedZye8P3VO1
 OdhPw2cMB18MtHPG+tuGMjj6wySqn67cV4Y1swNl34N//9PebcsYVLVrNWgz3bSw
 +U7023ztWbHF7MebzOt6JaKZPTej4S1aQoSGVQs7S4hj1ydIOur3vRCpdTmsGbts
 VcDbsVANFNYszP9y/EVU+z30s03iJzDdw2GRCr9C1JOwQbbpNB3onqbr9j2XA9uI
 dI6KkO+T02azKAgsJ4F8mqD3wm8dFjxY/CZGN//G1eQEWW2by2wiQcTbR5rm457T
 mbt5evqLQG8SmZsvrepKeM99JFKRzkoBloAOul8wGzK+7yG0vJVGw0dCwkjLWxW1
 DgiHKn4dcilLi2ybXvB7vK62dE5z3qk391YpZI/0gh1XOaNlc8/CnX93z9oFgpdP
 ZhUxzO4cWRRGw7rx49Skt6zg6JSvbgmjbpG7BJ0jjZhJt42I8d3/GtVDWkZ7XJI7
 AlNukRy/norwXOiTcT6OMiQe1/ZBkNbqxhgdJ2bhRQQ/sqrEV6B0vPGgb36qKwPc
 9abVsycIVWc5NNqV4zH8hS72lBb8UKwpl2gZUqM8TFwG9uv6y+KO0Z4eTgW/z0HD
 EfaZknpeBQzlt6srXKaB
 =9guJ
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/huth/tags/check-20170915' into staging

Some fixes and improvements for various qtests by Eric and me.

# gpg: Signature made Fri 15 Sep 2017 08:37:21 BST
# gpg:                using RSA key 0x2ED9D774FE702DB5
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>"
# gpg:                 aka "Thomas Huth <thuth@redhat.com>"
# gpg:                 aka "Thomas Huth <huth@tuxfamily.org>"
# gpg:                 aka "Thomas Huth <th.huth@posteo.de>"
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3  EAB9 2ED9 D774 FE70 2DB5

* remotes/huth/tags/check-20170915:
  qtest: Avoid passing raw strings through hmp()
  libqtest: Remove dead qtest_instances variable
  numa-test: Use hmp()
  qtest: Don't perform side effects inside assertion
  test-qga: Kill broken and dead QGA_TEST_SIDE_EFFECTING code
  tests: Fix broken ivshmem-server-msi/-irq tests
  tests/libqtest: Use a proper error message if QTEST_QEMU_BINARY is missing
  tests/test-hmp: Remove puv3 and tricore_testboard from the blacklist
  tests: Introduce generic device hot-plug/hot-unplug functions

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2017-09-15 20:29:44 +01:00
commit 5faf2d376a
12 changed files with 201 additions and 309 deletions

80
qtest.c
View File

@ -332,10 +332,13 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
strcmp(words[0], "outl") == 0) {
unsigned long addr;
unsigned long value;
int ret;
g_assert(words[1] && words[2]);
g_assert(qemu_strtoul(words[1], NULL, 0, &addr) == 0);
g_assert(qemu_strtoul(words[2], NULL, 0, &value) == 0);
ret = qemu_strtoul(words[1], NULL, 0, &addr);
g_assert(ret == 0);
ret = qemu_strtoul(words[2], NULL, 0, &value);
g_assert(ret == 0);
g_assert(addr <= 0xffff);
if (words[0][3] == 'b') {
@ -352,9 +355,11 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
strcmp(words[0], "inl") == 0) {
unsigned long addr;
uint32_t value = -1U;
int ret;
g_assert(words[1]);
g_assert(qemu_strtoul(words[1], NULL, 0, &addr) == 0);
ret = qemu_strtoul(words[1], NULL, 0, &addr);
g_assert(ret == 0);
g_assert(addr <= 0xffff);
if (words[0][2] == 'b') {
@ -372,10 +377,13 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
strcmp(words[0], "writeq") == 0) {
uint64_t addr;
uint64_t value;
int ret;
g_assert(words[1] && words[2]);
g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
g_assert(qemu_strtou64(words[2], NULL, 0, &value) == 0);
ret = qemu_strtou64(words[1], NULL, 0, &addr);
g_assert(ret == 0);
ret = qemu_strtou64(words[2], NULL, 0, &value);
g_assert(ret == 0);
if (words[0][5] == 'b') {
uint8_t data = value;
@ -401,9 +409,11 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
strcmp(words[0], "readq") == 0) {
uint64_t addr;
uint64_t value = UINT64_C(-1);
int ret;
g_assert(words[1]);
g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
ret = qemu_strtou64(words[1], NULL, 0, &addr);
g_assert(ret == 0);
if (words[0][4] == 'b') {
uint8_t data;
@ -427,10 +437,13 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
uint64_t addr, len, i;
uint8_t *data;
char *enc;
int ret;
g_assert(words[1] && words[2]);
g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
g_assert(qemu_strtou64(words[2], NULL, 0, &len) == 0);
ret = qemu_strtou64(words[1], NULL, 0, &addr);
g_assert(ret == 0);
ret = qemu_strtou64(words[2], NULL, 0, &len);
g_assert(ret == 0);
/* We'd send garbage to libqtest if len is 0 */
g_assert(len);
@ -451,10 +464,13 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
uint64_t addr, len;
uint8_t *data;
gchar *b64_data;
int ret;
g_assert(words[1] && words[2]);
g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
g_assert(qemu_strtou64(words[2], NULL, 0, &len) == 0);
ret = qemu_strtou64(words[1], NULL, 0, &addr);
g_assert(ret == 0);
ret = qemu_strtou64(words[2], NULL, 0, &len);
g_assert(ret == 0);
data = g_malloc(len);
cpu_physical_memory_read(addr, data, len);
@ -468,10 +484,13 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
uint64_t addr, len, i;
uint8_t *data;
size_t data_len;
int ret;
g_assert(words[1] && words[2] && words[3]);
g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
g_assert(qemu_strtou64(words[2], NULL, 0, &len) == 0);
ret = qemu_strtou64(words[1], NULL, 0, &addr);
g_assert(ret == 0);
ret = qemu_strtou64(words[2], NULL, 0, &len);
g_assert(ret == 0);
data_len = strlen(words[3]);
if (data_len < 3) {
@ -497,11 +516,15 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
uint64_t addr, len;
uint8_t *data;
unsigned long pattern;
int ret;
g_assert(words[1] && words[2] && words[3]);
g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
g_assert(qemu_strtou64(words[2], NULL, 0, &len) == 0);
g_assert(qemu_strtoul(words[3], NULL, 0, &pattern) == 0);
ret = qemu_strtou64(words[1], NULL, 0, &addr);
g_assert(ret == 0);
ret = qemu_strtou64(words[2], NULL, 0, &len);
g_assert(ret == 0);
ret = qemu_strtoul(words[3], NULL, 0, &pattern);
g_assert(ret == 0);
if (len) {
data = g_malloc(len);
@ -517,10 +540,13 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
uint8_t *data;
size_t data_len;
gsize out_len;
int ret;
g_assert(words[1] && words[2] && words[3]);
g_assert(qemu_strtou64(words[1], NULL, 0, &addr) == 0);
g_assert(qemu_strtou64(words[2], NULL, 0, &len) == 0);
ret = qemu_strtou64(words[1], NULL, 0, &addr);
g_assert(ret == 0);
ret = qemu_strtou64(words[2], NULL, 0, &len);
g_assert(ret == 0);
data_len = strlen(words[3]);
if (data_len < 3) {
@ -551,11 +577,16 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
} else if (strcmp(words[0], "rtas") == 0) {
uint64_t res, args, ret;
unsigned long nargs, nret;
int rc;
g_assert(qemu_strtoul(words[2], NULL, 0, &nargs) == 0);
g_assert(qemu_strtou64(words[3], NULL, 0, &args) == 0);
g_assert(qemu_strtoul(words[4], NULL, 0, &nret) == 0);
g_assert(qemu_strtou64(words[5], NULL, 0, &ret) == 0);
rc = qemu_strtoul(words[2], NULL, 0, &nargs);
g_assert(rc == 0);
rc = qemu_strtou64(words[3], NULL, 0, &args);
g_assert(rc == 0);
rc = qemu_strtoul(words[4], NULL, 0, &nret);
g_assert(rc == 0);
rc = qemu_strtou64(words[5], NULL, 0, &ret);
g_assert(rc == 0);
res = qtest_rtas_call(words[1], nargs, args, nret, ret);
qtest_send_prefix(chr);
@ -565,7 +596,8 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
int64_t ns;
if (words[1]) {
g_assert(qemu_strtoi64(words[1], NULL, 0, &ns) == 0);
int ret = qemu_strtoi64(words[1], NULL, 0, &ns);
g_assert(ret == 0);
} else {
ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
}
@ -575,9 +607,11 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
(int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
} else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) {
int64_t ns;
int ret;
g_assert(words[1]);
g_assert(qemu_strtoi64(words[1], NULL, 0, &ns) == 0);
ret = qemu_strtoi64(words[1], NULL, 0, &ns);
g_assert(ret == 0);
qtest_clock_warp(ns);
qtest_send_prefix(chr);
qtest_sendf(chr, "OK %"PRIi64"\n",

View File

@ -120,6 +120,8 @@ void qpci_msix_enable(QPCIDevice *dev)
bir_pba = table & PCI_MSIX_FLAGS_BIRMASK;
if (bir_pba != bir_table) {
dev->msix_pba_bar = qpci_iomap(dev, bir_pba, NULL);
} else {
dev->msix_pba_bar = dev->msix_table_bar;
}
dev->msix_pba_off = table & ~PCI_MSIX_FLAGS_BIRMASK;
@ -138,8 +140,11 @@ void qpci_msix_disable(QPCIDevice *dev)
qpci_config_writew(dev, addr + PCI_MSIX_FLAGS,
val & ~PCI_MSIX_FLAGS_ENABLE);
if (dev->msix_pba_bar.addr != dev->msix_table_bar.addr) {
qpci_iounmap(dev, dev->msix_pba_bar);
}
qpci_iounmap(dev, dev->msix_table_bar);
qpci_iounmap(dev, dev->msix_pba_bar);
dev->msix_enabled = 0;
dev->msix_table_off = 0;
dev->msix_pba_off = 0;
@ -394,21 +399,6 @@ 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)
{
QDict *response;
char *cmd;
cmd = g_strdup_printf("{'execute': 'device_add',"
" 'arguments': {"
" 'driver': '%s',"
" 'addr': '%d',"
" %s%s"
" 'id': '%s'"
"}}", driver, slot,
opts ? opts : "", opts ? "," : "",
id);
response = qmp(cmd);
g_free(cmd);
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
QDECREF(response);
qtest_qmp_device_add(driver, id, "'addr': '%d'%s%s", slot,
opts ? ", " : "", opts ? opts : "");
}

View File

@ -40,34 +40,16 @@ void uhci_port_test(struct qhc *hc, int port, uint16_t expect)
void usb_test_hotplug(const char *hcd_id, const int port,
void (*port_check)(void))
{
QDict *response;
char *cmd;
char *id = g_strdup_printf("usbdev%d", port);
cmd = g_strdup_printf("{'execute': 'device_add',"
" 'arguments': {"
" 'driver': 'usb-tablet',"
" 'port': '%d',"
" 'bus': '%s.0',"
" 'id': 'usbdev%d'"
"}}", port, hcd_id, port);
response = qmp(cmd);
g_free(cmd);
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
QDECREF(response);
qtest_qmp_device_add("usb-tablet", id, "'port': '%d', 'bus': '%s.0'",
port, hcd_id);
if (port_check) {
port_check();
}
cmd = g_strdup_printf("{'execute': 'device_del',"
" 'arguments': {"
" 'id': 'usbdev%d'"
"}}", port);
response = qmp(cmd);
g_free(cmd);
g_assert(response);
g_assert(qdict_haskey(response, "event"));
g_assert(!strcmp(qdict_get_str(response, "event"), "DEVICE_DELETED"));
QDECREF(response);
qtest_qmp_device_del(id);
g_free(id);
}

View File

@ -42,7 +42,6 @@ struct QTestState
};
static GHookList abrt_hooks;
static GList *qtest_instances;
static struct sigaction sigact_old;
#define g_assert_no_errno(ret) do { \
@ -150,6 +149,19 @@ void qtest_add_abrt_handler(GHookFunc fn, const void *data)
g_hook_prepend(&abrt_hooks, hook);
}
static const char *qtest_qemu_binary(void)
{
const char *qemu_bin;
qemu_bin = getenv("QTEST_QEMU_BINARY");
if (!qemu_bin) {
fprintf(stderr, "Environment variable QTEST_QEMU_BINARY required\n");
exit(1);
}
return qemu_bin;
}
QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
{
QTestState *s;
@ -157,13 +169,7 @@ QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
gchar *socket_path;
gchar *qmp_socket_path;
gchar *command;
const char *qemu_binary;
qemu_binary = getenv("QTEST_QEMU_BINARY");
if (!qemu_binary) {
fprintf(stderr, "Environment variable QTEST_QEMU_BINARY required\n");
exit(1);
}
const char *qemu_binary = qtest_qemu_binary();
s = g_malloc(sizeof(*s));
@ -240,13 +246,10 @@ QTestState *qtest_init(const char *extra_args)
void qtest_quit(QTestState *s)
{
qtest_instances = g_list_remove(qtest_instances, s);
g_hook_destroy_link(&abrt_hooks, g_hook_find_data(&abrt_hooks, TRUE, s));
/* Uninstall SIGABRT handler on last instance */
if (!qtest_instances) {
cleanup_sigabrt_handler();
}
cleanup_sigabrt_handler();
kill_qemu(s);
close(s->fd);
@ -624,8 +627,7 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...)
const char *qtest_get_arch(void)
{
const char *qemu = getenv("QTEST_QEMU_BINARY");
g_assert(qemu != NULL);
const char *qemu = qtest_qemu_binary();
const char *end = strrchr(qemu, '/');
return end + strlen("/qemu-system-");
@ -987,3 +989,78 @@ void qtest_cb_for_every_machine(void (*cb)(const char *machine))
qtest_end();
QDECREF(response);
}
/*
* Generic hot-plugging test via the device_add QMP command.
*/
void qtest_qmp_device_add(const char *driver, const char *id, const char *fmt,
...)
{
QDict *response;
char *cmd, *opts = NULL;
va_list va;
if (fmt) {
va_start(va, fmt);
opts = g_strdup_vprintf(fmt, va);
va_end(va);
}
cmd = g_strdup_printf("{'execute': 'device_add',"
" 'arguments': { 'driver': '%s', 'id': '%s'%s%s }}",
driver, id, opts ? ", " : "", opts ? opts : "");
g_free(opts);
response = qmp(cmd);
g_free(cmd);
g_assert(response);
g_assert(!qdict_haskey(response, "event")); /* We don't expect any events */
g_assert(!qdict_haskey(response, "error"));
QDECREF(response);
}
/*
* Generic hot-unplugging test via the device_del QMP command.
* Device deletion will get one response and one event. For example:
*
* {'execute': 'device_del','arguments': { 'id': 'scsi-hd'}}
*
* will get this one:
*
* {"timestamp": {"seconds": 1505289667, "microseconds": 569862},
* "event": "DEVICE_DELETED", "data": {"device": "scsi-hd",
* "path": "/machine/peripheral/scsi-hd"}}
*
* and this one:
*
* {"return": {}}
*
* But the order of arrival may vary - so we've got to detect both.
*/
void qtest_qmp_device_del(const char *id)
{
QDict *response1, *response2, *event = NULL;
char *cmd;
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;
}
g_assert(event);
g_assert_cmpstr(qdict_get_str(event, "event"), ==, "DEVICE_DELETED");
QDECREF(response1);
QDECREF(response2);
}

View File

@ -134,14 +134,14 @@ QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event);
/**
* qtest_hmp:
* @s: #QTestState instance to operate on.
* @fmt...: HMP command to send to QEMU
* @fmt...: HMP command to send to QEMU, formats arguments like sprintf().
*
* Send HMP command to QEMU via QMP's human-monitor-command.
* QMP events are discarded.
*
* Returns: the command's output. The caller should g_free() it.
*/
char *qtest_hmp(QTestState *s, const char *fmt, ...);
char *qtest_hmp(QTestState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
/**
* qtest_hmpv:
@ -592,13 +592,13 @@ static inline QDict *qmp_eventwait_ref(const char *event)
/**
* hmp:
* @fmt...: HMP command to send to QEMU
* @fmt...: HMP command to send to QEMU, formats arguments like sprintf().
*
* Send HMP command to QEMU via QMP's human-monitor-command.
*
* Returns: the command's output. The caller should g_free() it.
*/
char *hmp(const char *fmt, ...);
char *hmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
/**
* get_irq:
@ -927,4 +927,23 @@ QDict *qmp_fd(int fd, const char *fmt, ...);
*/
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
*
* Generic hot-plugging test via the device_add QMP command.
*/
void qtest_qmp_device_add(const char *driver, const char *id, const char *fmt,
...) GCC_FMT_ATTR(3, 4);
/**
* qtest_qmp_device_del:
* @id: Identification string
*
* Generic hot-unplugging test via the device_del QMP command.
*/
void qtest_qmp_device_del(const char *id);
#endif

View File

@ -17,21 +17,6 @@ static char *make_cli(const char *generic_cli, const char *test_cli)
return g_strdup_printf("%s %s", generic_cli ? generic_cli : "", test_cli);
}
static char *hmp_info_numa(void)
{
QDict *resp;
char *s;
resp = qmp("{ 'execute': 'human-monitor-command', 'arguments': "
"{ 'command-line': 'info numa '} }");
g_assert(resp);
g_assert(qdict_haskey(resp, "return"));
s = g_strdup(qdict_get_str(resp, "return"));
g_assert(s);
QDECREF(resp);
return s;
}
static void test_mon_explicit(const void *data)
{
char *s;
@ -42,7 +27,7 @@ static void test_mon_explicit(const void *data)
"-numa node,nodeid=1,cpus=4-7 ");
qtest_start(cli);
s = hmp_info_numa();
s = hmp("info numa");
g_assert(strstr(s, "node 0 cpus: 0 1 2 3"));
g_assert(strstr(s, "node 1 cpus: 4 5 6 7"));
g_free(s);
@ -59,7 +44,7 @@ static void test_mon_default(const void *data)
cli = make_cli(data, "-smp 8 -numa node -numa node");
qtest_start(cli);
s = hmp_info_numa();
s = hmp("info numa");
g_assert(strstr(s, "node 0 cpus: 0 2 4 6"));
g_assert(strstr(s, "node 1 cpus: 1 3 5 7"));
g_free(s);
@ -78,7 +63,7 @@ static void test_mon_partial(const void *data)
"-numa node,nodeid=1,cpus=4-5 ");
qtest_start(cli);
s = hmp_info_numa();
s = hmp("info numa");
g_assert(strstr(s, "node 0 cpus: 0 1 2 3 6 7"));
g_assert(strstr(s, "node 1 cpus: 4 5"));
g_free(s);

View File

@ -81,7 +81,7 @@ static void test_commands(void)
if (verbose) {
fprintf(stderr, "\t%s\n", hmp_cmds[i]);
}
response = hmp(hmp_cmds[i]);
response = hmp("%s", hmp_cmds[i]);
g_free(response);
}
@ -104,7 +104,7 @@ static void test_info_commands(void)
if (verbose) {
fprintf(stderr, "\t%s\n", info);
}
resp = hmp(info);
resp = hmp("%s", info);
g_free(resp);
/* And move forward to the next line */
info = strchr(endp + 1, '\n');
@ -138,8 +138,7 @@ static void add_machine_test_case(const char *mname)
char *path;
/* Ignore blacklisted machines that have known problems */
if (!strcmp("puv3", mname) || !strcmp("tricore_testboard", mname) ||
!strcmp("xenfv", mname) || !strcmp("xenpv", mname)) {
if (!strcmp("xenfv", mname) || !strcmp("xenpv", mname)) {
return;
}

View File

@ -642,65 +642,6 @@ static void test_qga_get_time(gconstpointer fix)
QDECREF(ret);
}
static void test_qga_set_time(gconstpointer fix)
{
const TestFixture *fixture = fix;
QDict *ret;
int64_t current, time;
gchar *cmd;
/* get current time */
ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-time'}");
g_assert_nonnull(ret);
qmp_assert_no_error(ret);
current = qdict_get_int(ret, "return");
g_assert_cmpint(current, >, 0);
QDECREF(ret);
/* set some old time */
ret = qmp_fd(fixture->fd, "{'execute': 'guest-set-time',"
" 'arguments': { 'time': 1000 } }");
g_assert_nonnull(ret);
qmp_assert_no_error(ret);
QDECREF(ret);
/* check old time */
ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-time'}");
g_assert_nonnull(ret);
qmp_assert_no_error(ret);
time = qdict_get_int(ret, "return");
g_assert_cmpint(time / 1000, <, G_USEC_PER_SEC * 10);
QDECREF(ret);
/* set back current time */
cmd = g_strdup_printf("{'execute': 'guest-set-time',"
" 'arguments': { 'time': %" PRId64 " } }",
current + time * 1000);
ret = qmp_fd(fixture->fd, cmd);
g_free(cmd);
g_assert_nonnull(ret);
qmp_assert_no_error(ret);
QDECREF(ret);
}
static void test_qga_fstrim(gconstpointer fix)
{
const TestFixture *fixture = fix;
QDict *ret;
QList *list;
const QListEntry *entry;
ret = qmp_fd(fixture->fd, "{'execute': 'guest-fstrim',"
" arguments: { minimum: 4194304 } }");
g_assert_nonnull(ret);
qmp_assert_no_error(ret);
list = qdict_get_qlist(ret, "return");
entry = qlist_first(list);
g_assert(qdict_haskey(qobject_to_qdict(entry->value), "paths"));
QDECREF(ret);
}
static void test_qga_blacklist(gconstpointer data)
{
TestFixture fix;
@ -831,30 +772,6 @@ static void test_qga_fsfreeze_status(gconstpointer fix)
QDECREF(ret);
}
static void test_qga_fsfreeze_and_thaw(gconstpointer fix)
{
const TestFixture *fixture = fix;
QDict *ret;
const gchar *status;
ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-freeze'}");
g_assert_nonnull(ret);
qmp_assert_no_error(ret);
QDECREF(ret);
ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-status'}");
g_assert_nonnull(ret);
qmp_assert_no_error(ret);
status = qdict_get_try_str(ret, "return");
g_assert_cmpstr(status, ==, "frozen");
QDECREF(ret);
ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-thaw'}");
g_assert_nonnull(ret);
qmp_assert_no_error(ret);
QDECREF(ret);
}
static void test_qga_guest_exec(gconstpointer fix)
{
const TestFixture *fixture = fix;
@ -1029,13 +946,6 @@ int main(int argc, char **argv)
g_test_add_data_func("/qga/guest-get-osinfo", &fix,
test_qga_guest_get_osinfo);
if (g_getenv("QGA_TEST_SIDE_EFFECTING")) {
g_test_add_data_func("/qga/fsfreeze-and-thaw", &fix,
test_qga_fsfreeze_and_thaw);
g_test_add_data_func("/qga/set-time", &fix, test_qga_set_time);
g_test_add_data_func("/qga/fstrim", &fix, test_qga_fstrim);
}
ret = g_test_run();
fixture_tear_down(&fix, NULL);

View File

@ -48,31 +48,9 @@ static void test_uhci_hotplug(void)
static void test_usb_storage_hotplug(void)
{
QDict *response;
qtest_qmp_device_add("usb-storage", "usbdev0", "'drive': 'drive0'");
response = qmp("{'execute': 'device_add',"
" 'arguments': {"
" 'driver': 'usb-storage',"
" 'drive': 'drive0',"
" 'id': 'usbdev0'"
"}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
QDECREF(response);
response = qmp("{'execute': 'device_del',"
" 'arguments': {"
" 'id': 'usbdev0'"
"}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
QDECREF(response);
response = qmp("");
g_assert(response);
g_assert(qdict_haskey(response, "event"));
g_assert(!strcmp(qdict_get_str(response, "event"), "DEVICE_DELETED"));
QDECREF(response);
qtest_qmp_device_del("usbdev0");
}
int main(int argc, char **argv)

View File

@ -23,59 +23,16 @@ static void test_xhci_hotplug(void)
static void test_usb_uas_hotplug(void)
{
QDict *response;
response = qmp("{'execute': 'device_add',"
" 'arguments': {"
" 'driver': 'usb-uas',"
" 'id': 'uas'"
"}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
QDECREF(response);
response = qmp("{'execute': 'device_add',"
" 'arguments': {"
" 'driver': 'scsi-hd',"
" 'drive': 'drive0',"
" 'id': 'scsi-hd'"
"}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
QDECREF(response);
qtest_qmp_device_add("usb-uas", "uas", NULL);
qtest_qmp_device_add("scsi-hd", "scsihd", "'drive': 'drive0'");
/* TODO:
UAS HBA driver in libqos, to check that
added disk is visible after BUS rescan
*/
response = qmp("{'execute': 'device_del',"
" 'arguments': {"
" 'id': 'scsi-hd'"
"}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
QDECREF(response);
response = qmp("");
g_assert(qdict_haskey(response, "event"));
g_assert(!strcmp(qdict_get_str(response, "event"), "DEVICE_DELETED"));
QDECREF(response);
response = qmp("{'execute': 'device_del',"
" 'arguments': {"
" 'id': 'uas'"
"}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
QDECREF(response);
response = qmp("");
g_assert(response);
g_assert(qdict_haskey(response, "event"));
g_assert(!strcmp(qdict_get_str(response, "event"), "DEVICE_DELETED"));
QDECREF(response);
qtest_qmp_device_del("scsihd");
qtest_qmp_device_del("uas");
}
int main(int argc, char **argv)

View File

@ -192,32 +192,12 @@ static void pci_nop(void)
static void hotplug(void)
{
QDict *response;
QOSState *qs;
qs = qvirtio_scsi_start(
"-drive id=drv1,if=none,file=null-co://,format=raw");
response = qmp("{\"execute\": \"device_add\","
" \"arguments\": {"
" \"driver\": \"scsi-hd\","
" \"id\": \"scsi-hd\","
" \"drive\": \"drv1\""
"}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
QDECREF(response);
response = qmp("{\"execute\": \"device_del\","
" \"arguments\": {"
" \"id\": \"scsi-hd\""
"}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
g_assert(qdict_haskey(response, "event"));
g_assert(!strcmp(qdict_get_str(response, "event"), "DEVICE_DELETED"));
QDECREF(response);
qtest_qmp_device_add("scsi-hd", "scsihd", "'drive': 'drv1'");
qtest_qmp_device_del("scsihd");
qvirtio_scsi_stop(qs);
}

View File

@ -17,28 +17,9 @@ static void pci_nop(void)
static void hotplug(void)
{
QDict *response;
qtest_qmp_device_add("virtserialport", "hp-port", NULL);
response = qmp("{\"execute\": \"device_add\","
" \"arguments\": {"
" \"driver\": \"virtserialport\","
" \"id\": \"hp-port\""
"}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
QDECREF(response);
response = qmp("{\"execute\": \"device_del\","
" \"arguments\": {"
" \"id\": \"hp-port\""
"}}");
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
g_assert(qdict_haskey(response, "event"));
g_assert(!strcmp(qdict_get_str(response, "event"), "DEVICE_DELETED"));
QDECREF(response);
qtest_qmp_device_del("hp-port");
}
int main(int argc, char **argv)