diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-07-14 12:16:09 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-07-14 12:16:09 +0100 |
commit | 6c6076662d98c068059983d411cb2a8987ba5670 (patch) | |
tree | b3a180eb5eab8474c5557b8a77c2589faa980f8e /tests | |
parent | 7d367e7002c3ca78531653105bd4fccd55e426a8 (diff) | |
parent | 68c761e19c2ea453f880dbbd04e867d34d1468b8 (diff) |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* gdbstub fixes (Alex)
* IOMMU MemoryRegion subclass (Alexey)
* Chardev hotswap (Anton)
* NBD_OPT_GO support (Eric)
* Misc bugfixes
* DEFINE_PROP_LINK (minus the ARM patches - Fam)
* MAINTAINERS updates (Philippe)
# gpg: Signature made Fri 14 Jul 2017 11:06:27 BST
# gpg: using RSA key 0xBFFBD25F78C7AE83
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>"
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>"
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1
# Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83
* remotes/bonzini/tags/for-upstream: (55 commits)
spapr_rng: Convert to DEFINE_PROP_LINK
cpu: Convert to DEFINE_PROP_LINK
mips_cmgcr: Convert to DEFINE_PROP_LINK
ivshmem: Convert to DEFINE_PROP_LINK
dimm: Convert to DEFINE_PROP_LINK
virtio-crypto: Convert to DEFINE_PROP_LINK
virtio-rng: Convert to DEFINE_PROP_LINK
virtio-scsi: Convert to DEFINE_PROP_LINK
virtio-blk: Convert to DEFINE_PROP_LINK
qdev: Add const qualifier to PropertyInfo definitions
qmp: Use ObjectProperty.type if present
qdev: Introduce DEFINE_PROP_LINK
qdev: Introduce PropertyInfo.create
qom: enforce readonly nature of link's check callback
translate-all: remove redundant !tcg_enabled check in dump_exec_info
vl: fix breakage of -tb-size
nbd: Implement NBD_INFO_BLOCK_SIZE on client
nbd: Implement NBD_INFO_BLOCK_SIZE on server
nbd: Implement NBD_OPT_GO on client
nbd: Implement NBD_OPT_GO on server
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/test-char.c | 275 | ||||
-rw-r--r-- | tests/test-hmp.c | 1 | ||||
-rw-r--r-- | tests/vhost-user-test.c | 2 |
3 files changed, 206 insertions, 72 deletions
diff --git a/tests/test-char.c b/tests/test-char.c index b962063e56..7ac25ff73f 100644 --- a/tests/test-char.c +++ b/tests/test-char.c @@ -178,6 +178,7 @@ static void char_mux_test(void) fe_can_read, fe_read, fe_event, + NULL, &h1, NULL, true); @@ -186,6 +187,7 @@ static void char_mux_test(void) fe_can_read, fe_read, fe_event, + NULL, &h2, NULL, true); qemu_chr_fe_take_focus(&chr_be2); @@ -209,7 +211,8 @@ static void char_mux_test(void) h1.read_count = 0; /* remove first handler */ - qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL, NULL, true); + qemu_chr_fe_set_handlers(&chr_be1, NULL, NULL, NULL, NULL, + NULL, NULL, true); qemu_chr_be_write(base, (void *)"hello", 6); g_assert_cmpint(h1.read_count, ==, 0); g_assert_cmpint(h2.read_count, ==, 0); @@ -307,13 +310,13 @@ static void char_socket_test(void) qemu_chr_fe_init(&be, chr, &error_abort); qemu_chr_fe_set_handlers(&be, socket_can_read, socket_read, - NULL, &d, NULL, true); + NULL, NULL, &d, NULL, true); chr_client = qemu_chr_new("client", tmp); qemu_chr_fe_init(&client_be, chr_client, &error_abort); qemu_chr_fe_set_handlers(&client_be, socket_can_read_hello, socket_read_hello, - NULL, &d, NULL, true); + NULL, NULL, &d, NULL, true); g_free(tmp); d.conn_expected = true; @@ -383,6 +386,7 @@ static void char_pipe_test(void) fe_can_read, fe_read, fe_event, + NULL, &fe, NULL, true); @@ -403,16 +407,11 @@ static void char_pipe_test(void) } #endif -static void char_udp_test(void) +static int make_udp_socket(int *port) { - struct sockaddr_in addr = { 0, }, other; - SocketIdleData d = { 0, }; - Chardev *chr; - CharBackend be; + struct sockaddr_in addr = { 0, }; socklen_t alen = sizeof(addr); int ret, sock = qemu_socket(PF_INET, SOCK_DGRAM, 0); - char buf[10]; - char *tmp; g_assert_cmpint(sock, >, 0); addr.sin_family = AF_INET ; @@ -423,19 +422,41 @@ static void char_udp_test(void) ret = getsockname(sock, (struct sockaddr *)&addr, &alen); g_assert_cmpint(ret, ==, 0); - tmp = g_strdup_printf("udp:127.0.0.1:%d", - ntohs(addr.sin_port)); - chr = qemu_chr_new("client", tmp); - g_assert_nonnull(chr); + *port = ntohs(addr.sin_port); + return sock; +} + +static void char_udp_test_internal(Chardev *reuse_chr, int sock) +{ + struct sockaddr_in other; + SocketIdleData d = { 0, }; + Chardev *chr; + CharBackend *be; + socklen_t alen = sizeof(other); + int ret; + char buf[10]; + char *tmp = NULL; + + if (reuse_chr) { + chr = reuse_chr; + be = chr->be; + } else { + int port; + sock = make_udp_socket(&port); + tmp = g_strdup_printf("udp:127.0.0.1:%d", port); + chr = qemu_chr_new("client", tmp); + g_assert_nonnull(chr); + + be = g_alloca(sizeof(CharBackend)); + qemu_chr_fe_init(be, chr, &error_abort); + } d.chr = chr; - qemu_chr_fe_init(&be, chr, &error_abort); - qemu_chr_fe_set_handlers(&be, socket_can_read_hello, socket_read_hello, - NULL, &d, NULL, true); + qemu_chr_fe_set_handlers(be, socket_can_read_hello, socket_read_hello, + NULL, NULL, &d, NULL, true); ret = qemu_chr_write_all(chr, (uint8_t *)"hello", 5); g_assert_cmpint(ret, ==, 5); - alen = sizeof(addr); ret = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&other, &alen); g_assert_cmpint(ret, ==, 5); @@ -444,10 +465,18 @@ static void char_udp_test(void) main_loop(); - close(sock); + if (!reuse_chr) { + close(sock); + qemu_chr_fe_deinit(be, true); + } g_free(tmp); } +static void char_udp_test(void) +{ + char_udp_test_internal(NULL, 0); +} + #ifdef HAVE_CHARDEV_SERIAL static void char_serial_test(void) { @@ -474,81 +503,110 @@ static void char_serial_test(void) } #endif -static void char_file_test(void) +#ifndef _WIN32 +static void char_file_fifo_test(void) { + Chardev *chr; + CharBackend be; char *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL); + char *fifo = g_build_filename(tmp_path, "fifo", NULL); char *out = g_build_filename(tmp_path, "out", NULL); - char *contents = NULL; - ChardevFile file = { .out = out }; + ChardevFile file = { .in = fifo, + .has_in = true, + .out = out }; ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE, .u.file.data = &file }; + FeHandler fe = { 0, }; + int fd, ret; + + if (mkfifo(fifo, 0600) < 0) { + abort(); + } + + fd = open(fifo, O_RDWR); + ret = write(fd, "fifo-in", 8); + g_assert_cmpint(ret, ==, 8); + + chr = qemu_chardev_new("label-file", TYPE_CHARDEV_FILE, &backend, + &error_abort); + + qemu_chr_fe_init(&be, chr, &error_abort); + qemu_chr_fe_set_handlers(&be, + fe_can_read, + fe_read, + fe_event, + NULL, + &fe, NULL, true); + + g_assert_cmpint(fe.last_event, !=, CHR_EVENT_BREAK); + qmp_chardev_send_break("label-foo", NULL); + g_assert_cmpint(fe.last_event, !=, CHR_EVENT_BREAK); + qmp_chardev_send_break("label-file", NULL); + g_assert_cmpint(fe.last_event, ==, CHR_EVENT_BREAK); + + main_loop(); + + close(fd); + + g_assert_cmpint(fe.read_count, ==, 8); + g_assert_cmpstr(fe.read_buf, ==, "fifo-in"); + + qemu_chr_fe_deinit(&be, true); + + g_unlink(fifo); + g_free(fifo); + g_unlink(out); + g_free(out); + g_rmdir(tmp_path); + g_free(tmp_path); +} +#endif + +static void char_file_test_internal(Chardev *ext_chr, const char *filepath) +{ + char *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL); + char *out; Chardev *chr; + char *contents = NULL; + ChardevFile file = {}; + ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE, + .u.file.data = &file }; gsize length; int ret; - chr = qemu_chardev_new(NULL, TYPE_CHARDEV_FILE, &backend, - &error_abort); + if (ext_chr) { + chr = ext_chr; + out = g_strdup(filepath); + file.out = out; + } else { + out = g_build_filename(tmp_path, "out", NULL); + file.out = out; + chr = qemu_chardev_new(NULL, TYPE_CHARDEV_FILE, &backend, + &error_abort); + } ret = qemu_chr_write_all(chr, (uint8_t *)"hello!", 6); g_assert_cmpint(ret, ==, 6); - object_unref(OBJECT(chr)); ret = g_file_get_contents(out, &contents, &length, NULL); g_assert(ret == TRUE); g_assert_cmpint(length, ==, 6); g_assert(strncmp(contents, "hello!", 6) == 0); - g_free(contents); - -#ifndef _WIN32 - { - CharBackend be; - FeHandler fe = { 0, }; - char *fifo = g_build_filename(tmp_path, "fifo", NULL); - int fd; - - if (mkfifo(fifo, 0600) < 0) { - abort(); - } - - fd = open(fifo, O_RDWR); - ret = write(fd, "fifo-in", 8); - g_assert_cmpint(ret, ==, 8); - - file.in = fifo; - file.has_in = true; - chr = qemu_chardev_new("label-file", TYPE_CHARDEV_FILE, &backend, - &error_abort); - - qemu_chr_fe_init(&be, chr, &error_abort); - qemu_chr_fe_set_handlers(&be, - fe_can_read, - fe_read, - fe_event, - &fe, NULL, true); - - g_assert_cmpint(fe.last_event, !=, CHR_EVENT_BREAK); - qmp_chardev_send_break("label-foo", NULL); - g_assert_cmpint(fe.last_event, !=, CHR_EVENT_BREAK); - qmp_chardev_send_break("label-file", NULL); - g_assert_cmpint(fe.last_event, ==, CHR_EVENT_BREAK); - - main_loop(); - close(fd); - - g_assert_cmpint(fe.read_count, ==, 8); - g_assert_cmpstr(fe.read_buf, ==, "fifo-in"); - qemu_chr_fe_deinit(&be, true); - g_unlink(fifo); - g_free(fifo); + if (!ext_chr) { + object_unref(OBJECT(chr)); + g_unlink(out); } -#endif - - g_unlink(out); + g_free(contents); g_rmdir(tmp_path); g_free(tmp_path); g_free(out); } +static void char_file_test(void) +{ + char_file_test_internal(NULL, NULL); +} + static void char_null_test(void) { Error *err = NULL; @@ -583,6 +641,7 @@ static void char_null_test(void) fe_can_read, fe_read, fe_event, + NULL, NULL, NULL, true); ret = qemu_chr_fe_write(&be, (void *)"buf", 4); @@ -599,6 +658,76 @@ static void char_invalid_test(void) g_assert_null(chr); } +static int chardev_change(void *opaque) +{ + return 0; +} + +static int chardev_change_denied(void *opaque) +{ + return -1; +} + +static void char_hotswap_test(void) +{ + char *chr_args; + Chardev *chr; + CharBackend be; + + gchar *tmp_path = g_dir_make_tmp("qemu-test-char.XXXXXX", NULL); + char *filename = g_build_filename(tmp_path, "file", NULL); + ChardevFile file = { .out = filename }; + ChardevBackend backend = { .type = CHARDEV_BACKEND_KIND_FILE, + .u.file.data = &file }; + ChardevReturn *ret; + + int port; + int sock = make_udp_socket(&port); + g_assert_cmpint(sock, >, 0); + + chr_args = g_strdup_printf("udp:127.0.0.1:%d", port); + + chr = qemu_chr_new("chardev", chr_args); + qemu_chr_fe_init(&be, chr, &error_abort); + + /* check that chardev operates correctly */ + char_udp_test_internal(chr, sock); + + /* set the handler that denies the hotswap */ + qemu_chr_fe_set_handlers(&be, NULL, NULL, + NULL, chardev_change_denied, NULL, NULL, true); + + /* now, change is denied and has to keep the old backend operating */ + ret = qmp_chardev_change("chardev", &backend, NULL); + g_assert(!ret); + g_assert(be.chr == chr); + + char_udp_test_internal(chr, sock); + + /* now allow the change */ + qemu_chr_fe_set_handlers(&be, NULL, NULL, + NULL, chardev_change, NULL, NULL, true); + + /* has to succeed now */ + ret = qmp_chardev_change("chardev", &backend, &error_abort); + g_assert(be.chr != chr); + + close(sock); + chr = be.chr; + + /* run the file chardev test */ + char_file_test_internal(chr, filename); + + object_unparent(OBJECT(chr)); + + qapi_free_ChardevReturn(ret); + g_unlink(filename); + g_free(filename); + g_rmdir(tmp_path); + g_free(tmp_path); + g_free(chr_args); +} + int main(int argc, char **argv) { qemu_init_main_loop(&error_abort); @@ -625,11 +754,15 @@ int main(int argc, char **argv) g_test_add_func("/char/pipe", char_pipe_test); #endif g_test_add_func("/char/file", char_file_test); +#ifndef _WIN32 + g_test_add_func("/char/file-fifo", char_file_fifo_test); +#endif g_test_add_func("/char/socket", char_socket_test); g_test_add_func("/char/udp", char_udp_test); #ifdef HAVE_CHARDEV_SERIAL g_test_add_func("/char/serial", char_serial_test); #endif + g_test_add_func("/char/hotswap", char_hotswap_test); return g_test_run(); } diff --git a/tests/test-hmp.c b/tests/test-hmp.c index 6dfa0c36e2..d77b3c8710 100644 --- a/tests/test-hmp.c +++ b/tests/test-hmp.c @@ -23,6 +23,7 @@ static const char *hmp_cmds[] = { "boot_set ndc", "chardev-add null,id=testchardev1", "chardev-send-break testchardev2", + "chardev-change testchardev1 ringbuf", "chardev-remove testchardev1", "commit all", "cpu-add 1", diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c index b3cc045765..d4da09f147 100644 --- a/tests/vhost-user-test.c +++ b/tests/vhost-user-test.c @@ -464,7 +464,7 @@ static void test_server_create_chr(TestServer *server, const gchar *opt) qemu_chr_fe_init(&server->chr, chr, &error_abort); qemu_chr_fe_set_handlers(&server->chr, chr_can_read, chr_read, - chr_event, server, NULL, true); + chr_event, NULL, server, NULL, true); } static void test_server_listen(TestServer *server) |