diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/.gitignore | 1 | ||||
| -rw-r--r-- | tests/Makefile.include | 5 | ||||
| -rwxr-xr-x | tests/qemu-iotests/033 | 1 | ||||
| -rwxr-xr-x | tests/qemu-iotests/208 | 55 | ||||
| -rw-r--r-- | tests/qemu-iotests/208.out | 9 | ||||
| -rwxr-xr-x | tests/qemu-iotests/209 | 34 | ||||
| -rw-r--r-- | tests/qemu-iotests/209.out | 2 | ||||
| -rw-r--r-- | tests/qemu-iotests/group | 2 | ||||
| -rw-r--r-- | tests/qemu-iotests/iotests.py | 37 | ||||
| -rw-r--r-- | tests/qmp-test.c | 5 | ||||
| -rw-r--r-- | tests/rcutorture.c | 4 | ||||
| -rw-r--r-- | tests/socket-helpers.c | 149 | ||||
| -rw-r--r-- | tests/socket-helpers.h | 42 | ||||
| -rw-r--r-- | tests/test-char.c | 48 | ||||
| -rw-r--r-- | tests/test-cutils.c | 657 | ||||
| -rw-r--r-- | tests/test-io-channel-socket.c | 72 | ||||
| -rw-r--r-- | tests/test-util-sockets.c | 266 | ||||
| -rw-r--r-- | tests/virtio-scsi-test.c | 6 |
18 files changed, 1314 insertions, 81 deletions
diff --git a/tests/.gitignore b/tests/.gitignore index 18e58b2183..fb62d2299b 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -86,6 +86,7 @@ test-thread-pool test-throttle test-timed-average test-uuid +test-util-sockets test-visitor-serialization test-vmstate test-write-threshold diff --git a/tests/Makefile.include b/tests/Makefile.include index ef9b88c369..42fd426cd0 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -146,6 +146,7 @@ ifneq (,$(findstring qemu-ga,$(TOOLS))) check-unit-$(CONFIG_LINUX) += tests/test-qga$(EXESUF) endif check-unit-y += tests/test-timed-average$(EXESUF) +check-unit-y += tests/test-util-sockets$(EXESUF) check-unit-y += tests/test-io-task$(EXESUF) check-unit-y += tests/test-io-channel-socket$(EXESUF) check-unit-y += tests/test-io-channel-file$(EXESUF) @@ -713,9 +714,11 @@ tests/test-crypto-tlscredsx509$(EXESUF): tests/test-crypto-tlscredsx509.o \ tests/test-crypto-tlssession.o-cflags := $(TASN1_CFLAGS) tests/test-crypto-tlssession$(EXESUF): tests/test-crypto-tlssession.o \ tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y) +tests/test-util-sockets$(EXESUF): tests/test-util-sockets.o \ + tests/socket-helpers.o $(test-util-obj-y) tests/test-io-task$(EXESUF): tests/test-io-task.o $(test-io-obj-y) tests/test-io-channel-socket$(EXESUF): tests/test-io-channel-socket.o \ - tests/io-channel-helpers.o $(test-io-obj-y) + tests/io-channel-helpers.o tests/socket-helpers.o $(test-io-obj-y) tests/tpm-crb-test$(EXESUF): tests/tpm-crb-test.o tests/tpm-emu.o $(test-io-obj-y) tests/tpm-tis-test$(EXESUF): tests/tpm-tis-test.o tests/tpm-emu.o $(test-io-obj-y) tests/test-io-channel-file$(EXESUF): tests/test-io-channel-file.o \ diff --git a/tests/qemu-iotests/033 b/tests/qemu-iotests/033 index a1d8357331..ee8a1338bb 100755 --- a/tests/qemu-iotests/033 +++ b/tests/qemu-iotests/033 @@ -105,6 +105,7 @@ for align in 512 4k; do done done +_cleanup_test_img # Trigger truncate that would shrink qcow2 L1 table, which is done by # clearing one entry (8 bytes) with bdrv_co_pwrite_zeroes() diff --git a/tests/qemu-iotests/208 b/tests/qemu-iotests/208 new file mode 100755 index 0000000000..4e82b96c82 --- /dev/null +++ b/tests/qemu-iotests/208 @@ -0,0 +1,55 @@ +#!/usr/bin/env python +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Creator/Owner: Stefan Hajnoczi <stefanha@redhat.com> +# +# Check that the runtime NBD server does not crash when stopped after +# blockdev-snapshot-sync. + +import iotests + +with iotests.FilePath('disk.img') as disk_img_path, \ + iotests.FilePath('disk-snapshot.img') as disk_snapshot_img_path, \ + iotests.FilePath('nbd.sock') as nbd_sock_path, \ + iotests.VM() as vm: + + img_size = '10M' + iotests.qemu_img_pipe('create', '-f', iotests.imgfmt, disk_img_path, img_size) + + iotests.log('Launching VM...') + (vm.add_drive(disk_img_path, 'node-name=drive0-node', interface='none') + .launch()) + + iotests.log('Starting NBD server...') + iotests.log(vm.qmp('nbd-server-start', addr={ + "type": "unix", + "data": { + "path": nbd_sock_path, + } + })) + + iotests.log('Adding NBD export...') + iotests.log(vm.qmp('nbd-server-add', device='drive0-node', writable=True)) + + iotests.log('Creating external snapshot...') + iotests.log(vm.qmp('blockdev-snapshot-sync', + node_name='drive0-node', + snapshot_node_name='drive0-snapshot-node', + snapshot_file=disk_snapshot_img_path)) + + iotests.log('Stopping NBD server...') + iotests.log(vm.qmp('nbd-server-stop')) diff --git a/tests/qemu-iotests/208.out b/tests/qemu-iotests/208.out new file mode 100644 index 0000000000..3687e9d0dd --- /dev/null +++ b/tests/qemu-iotests/208.out @@ -0,0 +1,9 @@ +Launching VM... +Starting NBD server... +{u'return': {}} +Adding NBD export... +{u'return': {}} +Creating external snapshot... +{u'return': {}} +Stopping NBD server... +{u'return': {}} diff --git a/tests/qemu-iotests/209 b/tests/qemu-iotests/209 new file mode 100755 index 0000000000..259e991ec6 --- /dev/null +++ b/tests/qemu-iotests/209 @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# +# Tests for NBD BLOCK_STATUS extension +# +# Copyright (c) 2018 Virtuozzo International GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import iotests +from iotests import qemu_img_create, qemu_io, qemu_img_verbose, qemu_nbd, \ + file_path + +iotests.verify_image_format(supported_fmts=['qcow2']) + +disk, nbd_sock = file_path('disk', 'nbd-sock') +nbd_uri = 'nbd+unix:///exp?socket=' + nbd_sock + +qemu_img_create('-f', iotests.imgfmt, disk, '1M') +qemu_io('-f', iotests.imgfmt, '-c', 'write 0 512K', disk) + +qemu_nbd('-k', nbd_sock, '-x', 'exp', '-f', iotests.imgfmt, disk) +qemu_img_verbose('map', '-f', 'raw', '--output=json', nbd_uri) diff --git a/tests/qemu-iotests/209.out b/tests/qemu-iotests/209.out new file mode 100644 index 0000000000..0d29724e84 --- /dev/null +++ b/tests/qemu-iotests/209.out @@ -0,0 +1,2 @@ +[{ "start": 0, "length": 524288, "depth": 0, "zero": false, "data": true}, +{ "start": 524288, "length": 524288, "depth": 0, "zero": true, "data": false}] diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index e7747fea3d..0f912e17b0 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -206,3 +206,5 @@ 205 rw auto quick 206 rw auto 207 rw auto +208 rw auto quick +209 rw auto quick diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index 68b06c7d97..845be3ad01 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -23,12 +23,14 @@ import subprocess import string import unittest import sys -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts')) -import qtest import struct import json import signal import logging +import atexit + +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts')) +import qtest # This will not work if arguments contain spaces but is necessary if we @@ -249,6 +251,37 @@ class FilePath(object): return False +def file_path_remover(): + for path in reversed(file_path_remover.paths): + try: + os.remove(path) + except OSError: + pass + + +def file_path(*names): + ''' Another way to get auto-generated filename that cleans itself up. + + Use is as simple as: + + img_a, img_b = file_path('a.img', 'b.img') + sock = file_path('socket') + ''' + + if not hasattr(file_path_remover, 'paths'): + file_path_remover.paths = [] + atexit.register(file_path_remover) + + paths = [] + for name in names: + filename = '{0}-{1}'.format(os.getpid(), name) + path = os.path.join(test_dir, filename) + file_path_remover.paths.append(path) + paths.append(path) + + return paths[0] if len(paths) == 1 else paths + + class VM(qtest.QEMUQtestMachine): '''A QEMU VM''' diff --git a/tests/qmp-test.c b/tests/qmp-test.c index 22445d9ec2..7470c6b754 100644 --- a/tests/qmp-test.c +++ b/tests/qmp-test.c @@ -204,6 +204,11 @@ static bool query_is_blacklisted(const char *cmd) "query-gic-capabilities", /* arm */ /* Success depends on target-specific build configuration: */ "query-pci", /* CONFIG_PCI */ + /* Success depends on launching SEV guest */ + "query-sev-launch-measure", + /* Success depends on Host or Hypervisor SEV support */ + "query-sev", + "query-sev-capabilities", NULL }; int i; diff --git a/tests/rcutorture.c b/tests/rcutorture.c index 4002ecf123..49311c82ea 100644 --- a/tests/rcutorture.c +++ b/tests/rcutorture.c @@ -238,7 +238,6 @@ long long rcu_stress_count[RCU_STRESS_PIPE_LEN + 1]; static void *rcu_read_stress_test(void *arg) { int i; - int itercnt = 0; struct rcu_stress *p; int pc; long long n_reads_local = 0; @@ -269,9 +268,6 @@ static void *rcu_read_stress_test(void *arg) } rcu_stress_local[pc]++; n_reads_local++; - if ((++itercnt % 0x1000) == 0) { - synchronize_rcu(); - } } qemu_mutex_lock(&counts_mutex); n_reads += n_reads_local; diff --git a/tests/socket-helpers.c b/tests/socket-helpers.c new file mode 100644 index 0000000000..8112763f5b --- /dev/null +++ b/tests/socket-helpers.c @@ -0,0 +1,149 @@ +/* + * Helper functions for tests using sockets + * + * Copyright 2015-2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qemu/sockets.h" +#include "socket-helpers.h" + +#ifndef AI_ADDRCONFIG +# define AI_ADDRCONFIG 0 +#endif +#ifndef EAI_ADDRFAMILY +# define EAI_ADDRFAMILY 0 +#endif + +int socket_can_bind_connect(const char *hostname) +{ + int lfd = -1, cfd = -1, afd = -1; + struct addrinfo ai, *res = NULL; + struct sockaddr_storage ss; + socklen_t sslen = sizeof(ss); + int soerr; + socklen_t soerrlen = sizeof(soerr); + bool check_soerr = false; + int rc; + int ret = -1; + + memset(&ai, 0, sizeof(ai)); + ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; + ai.ai_family = AF_UNSPEC; + ai.ai_socktype = SOCK_STREAM; + + /* lookup */ + rc = getaddrinfo(hostname, NULL, &ai, &res); + if (rc != 0) { + if (rc == EAI_ADDRFAMILY || + rc == EAI_FAMILY) { + errno = EADDRNOTAVAIL; + } else { + errno = EINVAL; + } + goto cleanup; + } + + lfd = qemu_socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (lfd < 0) { + goto cleanup; + } + + cfd = qemu_socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (cfd < 0) { + goto cleanup; + } + + if (bind(lfd, res->ai_addr, res->ai_addrlen) < 0) { + goto cleanup; + } + + if (listen(lfd, 1) < 0) { + goto cleanup; + } + + if (getsockname(lfd, (struct sockaddr *)&ss, &sslen) < 0) { + goto cleanup; + } + + qemu_set_nonblock(cfd); + if (connect(cfd, (struct sockaddr *)&ss, sslen) < 0) { + if (errno == EINPROGRESS) { + check_soerr = true; + } else { + goto cleanup; + } + } + + sslen = sizeof(ss); + afd = accept(lfd, (struct sockaddr *)&ss, &sslen); + if (afd < 0) { + goto cleanup; + } + + if (check_soerr) { + if (qemu_getsockopt(cfd, SOL_SOCKET, SO_ERROR, &soerr, &soerrlen) < 0) { + goto cleanup; + } + if (soerr) { + errno = soerr; + goto cleanup; + } + } + + ret = 0; + + cleanup: + if (afd != -1) { + close(afd); + } + if (cfd != -1) { + close(cfd); + } + if (lfd != -1) { + close(lfd); + } + if (res) { + freeaddrinfo(res); + } + return ret; +} + + +int socket_check_protocol_support(bool *has_ipv4, bool *has_ipv6) +{ + *has_ipv4 = *has_ipv6 = false; + + if (socket_can_bind_connect("127.0.0.1") < 0) { + if (errno != EADDRNOTAVAIL) { + return -1; + } + } else { + *has_ipv4 = true; + } + + if (socket_can_bind_connect("::1") < 0) { + if (errno != EADDRNOTAVAIL) { + return -1; + } + } else { + *has_ipv6 = true; + } + + return 0; +} diff --git a/tests/socket-helpers.h b/tests/socket-helpers.h new file mode 100644 index 0000000000..1c07d6d656 --- /dev/null +++ b/tests/socket-helpers.h @@ -0,0 +1,42 @@ +/* + * Helper functions for tests using sockets + * + * Copyright 2015-2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + * + */ + +/* + * @hostname: a DNS name or numeric IP address + * + * Check whether it is possible to bind & connect to ports + * on the DNS name or IP address @hostname. If an IP address + * is used, it must not be a wildcard address. + * + * Returns 0 on success, -1 on error with errno set + */ +int socket_can_bind_connect(const char *hostname); + +/* + * @has_ipv4: set to true on return if IPv4 is available + * @has_ipv6: set to true on return if IPv6 is available + * + * Check whether IPv4 and/or IPv6 are available for use. + * On success, @has_ipv4 and @has_ipv6 will be set to + * indicate whether the respective protocols are available. + * + * Returns 0 on success, -1 on fatal error + */ +int socket_check_protocol_support(bool *has_ipv4, bool *has_ipv6); diff --git a/tests/test-char.c b/tests/test-char.c index b3a77af085..df939cc5c4 100644 --- a/tests/test-char.c +++ b/tests/test-char.c @@ -166,7 +166,6 @@ static void char_mux_test(void) FeHandler h1 = { 0, }, h2 = { 0, }; CharBackend chr_be1, chr_be2; - muxes_realized = true; /* done after machine init */ opts = qemu_opts_create(qemu_find_opts("chardev"), "mux-label", 1, &error_abort); qemu_opt_set(opts, "backend", "ringbuf", &error_abort); @@ -302,9 +301,8 @@ static int socket_can_read_hello(void *opaque) return 10; } -static void char_socket_test(void) +static void char_socket_test_common(Chardev *chr) { - Chardev *chr = qemu_chr_new("server", "tcp:127.0.0.1:0,server,nowait"); Chardev *chr_client; QObject *addr; QDict *qdict; @@ -359,6 +357,47 @@ static void char_socket_test(void) object_unparent(OBJECT(chr)); } + +static void char_socket_basic_test(void) +{ + Chardev *chr = qemu_chr_new("server", "tcp:127.0.0.1:0,server,nowait"); + + char_socket_test_common(chr); +} + + +static void char_socket_fdpass_test(void) +{ + Chardev *chr; + char *optstr; + QemuOpts *opts; + int fd; + SocketAddress *addr = g_new0(SocketAddress, 1); + + addr->type = SOCKET_ADDRESS_TYPE_INET; + addr->u.inet.host = g_strdup("127.0.0.1"); + addr->u.inet.port = g_strdup("0"); + + fd = socket_listen(addr, &error_abort); + g_assert(fd >= 0); + + qapi_free_SocketAddress(addr); + + optstr = g_strdup_printf("socket,id=cdev,fd=%d,server,nowait", fd); + + opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"), + optstr, true); + g_free(optstr); + g_assert_nonnull(opts); + + chr = qemu_chr_new_from_opts(opts, &error_abort); + + qemu_opts_del(opts); + + char_socket_test_common(chr); +} + + #ifndef _WIN32 static void char_pipe_test(void) { @@ -775,7 +814,8 @@ int main(int argc, char **argv) #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/socket/basic", char_socket_basic_test); + g_test_add_func("/char/socket/fdpass", char_socket_fdpass_test); g_test_add_func("/char/udp", char_udp_test); #ifdef HAVE_CHARDEV_SERIAL g_test_add_func("/char/serial", char_serial_test); diff --git a/tests/test-cutils.c b/tests/test-cutils.c index f64a49b7fb..64a489c2e9 100644 --- a/tests/test-cutils.c +++ b/tests/test-cutils.c @@ -223,6 +223,583 @@ static void test_parse_uint_full_correct(void) g_assert_cmpint(i, ==, 123); } +static void test_qemu_strtoi_correct(void) +{ + const char *str = "12345 foo"; + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 12345); + g_assert(endptr == str + 5); +} + +static void test_qemu_strtoi_null(void) +{ + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(NULL, &endptr, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); + g_assert(endptr == NULL); +} + +static void test_qemu_strtoi_empty(void) +{ + const char *str = ""; + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); + g_assert(endptr == str); +} + +static void test_qemu_strtoi_whitespace(void) +{ + const char *str = " \t "; + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); + g_assert(endptr == str); +} + +static void test_qemu_strtoi_invalid(void) +{ + const char *str = " xxxx \t abc"; + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); + g_assert(endptr == str); +} + +static void test_qemu_strtoi_trailing(void) +{ + const char *str = "123xxx"; + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 123); + g_assert(endptr == str + 3); +} + +static void test_qemu_strtoi_octal(void) +{ + const char *str = "0123"; + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(str, &endptr, 8, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 0123); + g_assert(endptr == str + strlen(str)); + + res = 999; + endptr = &f; + err = qemu_strtoi(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 0123); + g_assert(endptr == str + strlen(str)); +} + +static void test_qemu_strtoi_decimal(void) +{ + const char *str = "0123"; + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(str, &endptr, 10, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 123); + g_assert(endptr == str + strlen(str)); + + str = "123"; + res = 999; + endptr = &f; + err = qemu_strtoi(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 123); + g_assert(endptr == str + strlen(str)); +} + +static void test_qemu_strtoi_hex(void) +{ + const char *str = "0123"; + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(str, &endptr, 16, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 0x123); + g_assert(endptr == str + strlen(str)); + + str = "0x123"; + res = 999; + endptr = &f; + err = qemu_strtoi(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 0x123); + g_assert(endptr == str + strlen(str)); +} + +static void test_qemu_strtoi_max(void) +{ + char *str = g_strdup_printf("%d", INT_MAX); + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, INT_MAX); + g_assert(endptr == str + strlen(str)); + g_free(str); +} + +static void test_qemu_strtoi_overflow(void) +{ + char *str = g_strdup_printf("%lld", (long long)INT_MAX + 1ll); + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, -ERANGE); + g_assert_cmpint(res, ==, INT_MAX); + g_assert(endptr == str + strlen(str)); + g_free(str); +} + +static void test_qemu_strtoi_underflow(void) +{ + char *str = g_strdup_printf("%lld", (long long)INT_MIN - 1ll); + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, -ERANGE); + g_assert_cmpint(res, ==, INT_MIN); + g_assert(endptr == str + strlen(str)); + g_free(str); +} + +static void test_qemu_strtoi_negative(void) +{ + const char *str = " \t -321"; + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, -321); + g_assert(endptr == str + strlen(str)); +} + +static void test_qemu_strtoi_full_correct(void) +{ + const char *str = "123"; + int res = 999; + int err; + + err = qemu_strtoi(str, NULL, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, 123); +} + +static void test_qemu_strtoi_full_null(void) +{ + char f = 'X'; + const char *endptr = &f; + int res = 999; + int err; + + err = qemu_strtoi(NULL, &endptr, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); + g_assert(endptr == NULL); +} + +static void test_qemu_strtoi_full_empty(void) +{ + const char *str = ""; + int res = 999L; + int err; + + err = qemu_strtoi(str, NULL, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); +} + +static void test_qemu_strtoi_full_negative(void) +{ + const char *str = " \t -321"; + int res = 999; + int err; + + err = qemu_strtoi(str, NULL, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, -321); +} + +static void test_qemu_strtoi_full_trailing(void) +{ + const char *str = "123xxx"; + int res; + int err; + + err = qemu_strtoi(str, NULL, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); +} + +static void test_qemu_strtoi_full_max(void) +{ + char *str = g_strdup_printf("%d", INT_MAX); + int res; + int err; + + err = qemu_strtoi(str, NULL, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpint(res, ==, INT_MAX); + g_free(str); +} + +static void test_qemu_strtoui_correct(void) +{ + const char *str = "12345 foo"; + char f = 'X'; + const char *endptr = &f; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 12345); + g_assert(endptr == str + 5); +} + +static void test_qemu_strtoui_null(void) +{ + char f = 'X'; + const char *endptr = &f; + unsigned int res = 999; + int err; + + err = qemu_strtoui(NULL, &endptr, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); + g_assert(endptr == NULL); +} + +static void test_qemu_strtoui_empty(void) +{ + const char *str = ""; + char f = 'X'; + const char *endptr = &f; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); + g_assert(endptr == str); +} + +static void test_qemu_strtoui_whitespace(void) +{ + const char *str = " \t "; + char f = 'X'; + const char *endptr = &f; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); + g_assert(endptr == str); +} + +static void test_qemu_strtoui_invalid(void) +{ + const char *str = " xxxx \t abc"; + char f = 'X'; + const char *endptr = &f; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); + g_assert(endptr == str); +} + +static void test_qemu_strtoui_trailing(void) +{ + const char *str = "123xxx"; + char f = 'X'; + const char *endptr = &f; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 123); + g_assert(endptr == str + 3); +} + +static void test_qemu_strtoui_octal(void) +{ + const char *str = "0123"; + char f = 'X'; + const char *endptr = &f; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, &endptr, 8, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 0123); + g_assert(endptr == str + strlen(str)); + + res = 999; + endptr = &f; + err = qemu_strtoui(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 0123); + g_assert(endptr == str + strlen(str)); +} + +static void test_qemu_strtoui_decimal(void) +{ + const char *str = "0123"; + char f = 'X'; + const char *endptr = &f; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, &endptr, 10, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 123); + g_assert(endptr == str + strlen(str)); + + str = "123"; + res = 999; + endptr = &f; + err = qemu_strtoui(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 123); + g_assert(endptr == str + strlen(str)); +} + +static void test_qemu_strtoui_hex(void) +{ + const char *str = "0123"; + char f = 'X'; + const char *endptr = &f; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, &endptr, 16, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmphex(res, ==, 0x123); + g_assert(endptr == str + strlen(str)); + + str = "0x123"; + res = 999; + endptr = &f; + err = qemu_strtoui(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmphex(res, ==, 0x123); + g_assert(endptr == str + strlen(str)); +} + +static void test_qemu_strtoui_max(void) +{ + char *str = g_strdup_printf("%u", UINT_MAX); + char f = 'X'; + const char *endptr = &f; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmphex(res, ==, UINT_MAX); + g_assert(endptr == str + strlen(str)); + g_free(str); +} + +static void test_qemu_strtoui_overflow(void) +{ + char *str = g_strdup_printf("%lld", (long long)UINT_MAX + 1ll); + char f = 'X'; + const char *endptr = &f; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, -ERANGE); + g_assert_cmphex(res, ==, UINT_MAX); + g_assert(endptr == str + strlen(str)); + g_free(str); +} + +static void test_qemu_strtoui_underflow(void) +{ + char *str = g_strdup_printf("%lld", (long long)INT_MIN - 1ll); + char f = 'X'; + const char *endptr = &f; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, -ERANGE); + g_assert_cmpuint(res, ==, (unsigned int)-1); + g_assert(endptr == str + strlen(str)); + g_free(str); +} + +static void test_qemu_strtoui_negative(void) +{ + const char *str = " \t -321"; + char f = 'X'; + const char *endptr = &f; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, &endptr, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, (unsigned int)-321); + g_assert(endptr == str + strlen(str)); +} + +static void test_qemu_strtoui_full_correct(void) +{ + const char *str = "123"; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, NULL, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, 123); +} + +static void test_qemu_strtoui_full_null(void) +{ + unsigned int res = 999; + int err; + + err = qemu_strtoui(NULL, NULL, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); +} + +static void test_qemu_strtoui_full_empty(void) +{ + const char *str = ""; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, NULL, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); +} +static void test_qemu_strtoui_full_negative(void) +{ + const char *str = " \t -321"; + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, NULL, 0, &res); + g_assert_cmpint(err, ==, 0); + g_assert_cmpuint(res, ==, (unsigned int)-321); +} + +static void test_qemu_strtoui_full_trailing(void) +{ + const char *str = "123xxx"; + unsigned int res; + int err; + + err = qemu_strtoui(str, NULL, 0, &res); + + g_assert_cmpint(err, ==, -EINVAL); +} + +static void test_qemu_strtoui_full_max(void) +{ + char *str = g_strdup_printf("%u", UINT_MAX); + unsigned int res = 999; + int err; + + err = qemu_strtoui(str, NULL, 0, &res); + + g_assert_cmpint(err, ==, 0); + g_assert_cmphex(res, ==, UINT_MAX); + g_free(str); +} + static void test_qemu_strtol_correct(void) { const char *str = "12345 foo"; @@ -1612,6 +2189,86 @@ int main(int argc, char **argv) g_test_add_func("/cutils/parse_uint_full/correct", test_parse_uint_full_correct); + /* qemu_strtoi() tests */ + g_test_add_func("/cutils/qemu_strtoi/correct", + test_qemu_strtoi_correct); + g_test_add_func("/cutils/qemu_strtoi/null", + test_qemu_strtoi_null); + g_test_add_func("/cutils/qemu_strtoi/empty", + test_qemu_strtoi_empty); + g_test_add_func("/cutils/qemu_strtoi/whitespace", + test_qemu_strtoi_whitespace); + g_test_add_func("/cutils/qemu_strtoi/invalid", + test_qemu_strtoi_invalid); + g_test_add_func("/cutils/qemu_strtoi/trailing", + test_qemu_strtoi_trailing); + g_test_add_func("/cutils/qemu_strtoi/octal", + test_qemu_strtoi_octal); + g_test_add_func("/cutils/qemu_strtoi/decimal", + test_qemu_strtoi_decimal); + g_test_add_func("/cutils/qemu_strtoi/hex", + test_qemu_strtoi_hex); + g_test_add_func("/cutils/qemu_strtoi/max", + test_qemu_strtoi_max); + g_test_add_func("/cutils/qemu_strtoi/overflow", + test_qemu_strtoi_overflow); + g_test_add_func("/cutils/qemu_strtoi/underflow", + test_qemu_strtoi_underflow); + g_test_add_func("/cutils/qemu_strtoi/negative", + test_qemu_strtoi_negative); + g_test_add_func("/cutils/qemu_strtoi_full/correct", + test_qemu_strtoi_full_correct); + g_test_add_func("/cutils/qemu_strtoi_full/null", + test_qemu_strtoi_full_null); + g_test_add_func("/cutils/qemu_strtoi_full/empty", + test_qemu_strtoi_full_empty); + g_test_add_func("/cutils/qemu_strtoi_full/negative", + test_qemu_strtoi_full_negative); + g_test_add_func("/cutils/qemu_strtoi_full/trailing", + test_qemu_strtoi_full_trailing); + g_test_add_func("/cutils/qemu_strtoi_full/max", + test_qemu_strtoi_full_max); + + /* qemu_strtoui() tests */ + g_test_add_func("/cutils/qemu_strtoui/correct", + test_qemu_strtoui_correct); + g_test_add_func("/cutils/qemu_strtoui/null", + test_qemu_strtoui_null); + g_test_add_func("/cutils/qemu_strtoui/empty", + test_qemu_strtoui_empty); + g_test_add_func("/cutils/qemu_strtoui/whitespace", + test_qemu_strtoui_whitespace); + g_test_add_func("/cutils/qemu_strtoui/invalid", + test_qemu_strtoui_invalid); + g_test_add_func("/cutils/qemu_strtoui/trailing", + test_qemu_strtoui_trailing); + g_test_add_func("/cutils/qemu_strtoui/octal", + test_qemu_strtoui_octal); + g_test_add_func("/cutils/qemu_strtoui/decimal", + test_qemu_strtoui_decimal); + g_test_add_func("/cutils/qemu_strtoui/hex", + test_qemu_strtoui_hex); + g_test_add_func("/cutils/qemu_strtoui/max", + test_qemu_strtoui_max); + g_test_add_func("/cutils/qemu_strtoui/overflow", + test_qemu_strtoui_overflow); + g_test_add_func("/cutils/qemu_strtoui/underflow", + test_qemu_strtoui_underflow); + g_test_add_func("/cutils/qemu_strtoui/negative", + test_qemu_strtoui_negative); + g_test_add_func("/cutils/qemu_strtoui_full/correct", + test_qemu_strtoui_full_correct); + g_test_add_func("/cutils/qemu_strtoui_full/null", + test_qemu_strtoui_full_null); + g_test_add_func("/cutils/qemu_strtoui_full/empty", + test_qemu_strtoui_full_empty); + g_test_add_func("/cutils/qemu_strtoui_full/negative", + test_qemu_strtoui_full_negative); + g_test_add_func("/cutils/qemu_strtoui_full/trailing", + test_qemu_strtoui_full_trailing); + g_test_add_func("/cutils/qemu_strtoui_full/max", + test_qemu_strtoui_full_max); + /* qemu_strtol() tests */ g_test_add_func("/cutils/qemu_strtol/correct", test_qemu_strtol_correct); diff --git a/tests/test-io-channel-socket.c b/tests/test-io-channel-socket.c index b273fd3ba2..0597213f93 100644 --- a/tests/test-io-channel-socket.c +++ b/tests/test-io-channel-socket.c @@ -22,77 +22,9 @@ #include "io/channel-socket.h" #include "io/channel-util.h" #include "io-channel-helpers.h" +#include "socket-helpers.h" #include "qapi/error.h" -#ifndef AI_ADDRCONFIG -# define AI_ADDRCONFIG 0 -#endif -#ifndef EAI_ADDRFAMILY -# define EAI_ADDRFAMILY 0 -#endif - -static int check_bind(const char *hostname, bool *has_proto) -{ - int fd = -1; - struct addrinfo ai, *res = NULL; - int rc; - int ret = -1; - - memset(&ai, 0, sizeof(ai)); - ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; - ai.ai_family = AF_UNSPEC; - ai.ai_socktype = SOCK_STREAM; - - /* lookup */ - rc = getaddrinfo(hostname, NULL, &ai, &res); - if (rc != 0) { - if (rc == EAI_ADDRFAMILY || - rc == EAI_FAMILY) { - *has_proto = false; - goto done; - } - goto cleanup; - } - - fd = qemu_socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (fd < 0) { - goto cleanup; - } - - if (bind(fd, res->ai_addr, res->ai_addrlen) < 0) { - if (errno == EADDRNOTAVAIL) { - *has_proto = false; - goto done; - } - goto cleanup; - } - - *has_proto = true; - done: - ret = 0; - - cleanup: - if (fd != -1) { - close(fd); - } - if (res) { - freeaddrinfo(res); - } - return ret; -} - -static int check_protocol_support(bool *has_ipv4, bool *has_ipv6) -{ - if (check_bind("127.0.0.1", has_ipv4) < 0) { - return -1; - } - if (check_bind("::1", has_ipv6) < 0) { - return -1; - } - - return 0; -} - static void test_io_channel_set_socket_bufs(QIOChannel *src, QIOChannel *dst) @@ -566,7 +498,7 @@ int main(int argc, char **argv) * each protocol to avoid breaking tests on machines * with either IPv4 or IPv6 disabled. */ - if (check_protocol_support(&has_ipv4, &has_ipv6) < 0) { + if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) { return 1; } diff --git a/tests/test-util-sockets.c b/tests/test-util-sockets.c new file mode 100644 index 0000000000..acadd85e8f --- /dev/null +++ b/tests/test-util-sockets.c @@ -0,0 +1,266 @@ +/* + * Tests for util/qemu-sockets.c + * + * Copyright 2018 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this library; if not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qemu/sockets.h" +#include "qapi/error.h" +#include "socket-helpers.h" +#include "monitor/monitor.h" + +static void test_fd_is_socket_bad(void) +{ + char *tmp = g_strdup("qemu-test-util-sockets-XXXXXX"); + int fd = mkstemp(tmp); + if (fd != 0) { + unlink(tmp); + } + g_free(tmp); + + g_assert(fd >= 0); + + g_assert(!fd_is_socket(fd)); + close(fd); +} + +static void test_fd_is_socket_good(void) +{ + int fd = qemu_socket(PF_INET, SOCK_STREAM, 0); + + g_assert(fd >= 0); + + g_assert(fd_is_socket(fd)); + close(fd); +} + +static int mon_fd = -1; +static const char *mon_fdname; + +int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp) +{ + g_assert(cur_mon); + g_assert(mon == cur_mon); + if (mon_fd == -1 || !g_str_equal(mon_fdname, fdname)) { + error_setg(errp, "No fd named %s", fdname); + return -1; + } + return dup(mon_fd); +} + +/* Syms in libqemustub.a are discarded at .o file granularity. + * To replace monitor_get_fd() we must ensure everything in + * stubs/monitor.c is defined, to make sure monitor.o is discarded + * otherwise we get duplicate syms at link time. + */ +Monitor *cur_mon; +void monitor_init(Chardev *chr, int flags) {} + + +static void test_socket_fd_pass_name_good(void) +{ + SocketAddress addr; + int fd; + + cur_mon = g_malloc(1); /* Fake a monitor */ + mon_fdname = "myfd"; + mon_fd = qemu_socket(AF_INET, SOCK_STREAM, 0); + g_assert_cmpint(mon_fd, >, STDERR_FILENO); + + addr.type = SOCKET_ADDRESS_TYPE_FD; + addr.u.fd.str = g_strdup(mon_fdname); + + fd = socket_connect(&addr, &error_abort); + g_assert_cmpint(fd, !=, -1); + g_assert_cmpint(fd, !=, mon_fd); + close(fd); + + fd = socket_listen(&addr, &error_abort); + g_assert_cmpint(fd, !=, -1); + g_assert_cmpint(fd, !=, mon_fd); + close(fd); + + g_free(addr.u.fd.str); + mon_fdname = NULL; + close(mon_fd); + mon_fd = -1; + g_free(cur_mon); + cur_mon = NULL; +} + +static void test_socket_fd_pass_name_bad(void) +{ + SocketAddress addr; + Error *err = NULL; + int fd; + + cur_mon = g_malloc(1); /* Fake a monitor */ + mon_fdname = "myfd"; + mon_fd = dup(STDOUT_FILENO); + g_assert_cmpint(mon_fd, >, STDERR_FILENO); + + addr.type = SOCKET_ADDRESS_TYPE_FD; + addr.u.fd.str = g_strdup(mon_fdname); + + fd = socket_connect(&addr, &err); + g_assert_cmpint(fd, ==, -1); + error_free_or_abort(&err); + + fd = socket_listen(&addr, &err); + g_assert_cmpint(fd, ==, -1); + error_free_or_abort(&err); + + g_free(addr.u.fd.str); + mon_fdname = NULL; + close(mon_fd); + mon_fd = -1; + g_free(cur_mon); + cur_mon = NULL; +} + +static void test_socket_fd_pass_name_nomon(void) +{ + SocketAddress addr; + Error *err = NULL; + int fd; + + g_assert(cur_mon == NULL); + + addr.type = SOCKET_ADDRESS_TYPE_FD; + addr.u.fd.str = g_strdup("myfd"); + + fd = socket_connect(&addr, &err); + g_assert_cmpint(fd, ==, -1); + error_free_or_abort(&err); + + fd = socket_listen(&addr, &err); + g_assert_cmpint(fd, ==, -1); + error_free_or_abort(&err); + + g_free(addr.u.fd.str); +} + + +static void test_socket_fd_pass_num_good(void) +{ + SocketAddress addr; + int fd, sfd; + + g_assert(cur_mon == NULL); + sfd = qemu_socket(AF_INET, SOCK_STREAM, 0); + g_assert_cmpint(sfd, >, STDERR_FILENO); + + addr.type = SOCKET_ADDRESS_TYPE_FD; + addr.u.fd.str = g_strdup_printf("%d", sfd); + + fd = socket_connect(&addr, &error_abort); + g_assert_cmpint(fd, ==, sfd); + + fd = socket_listen(&addr, &error_abort); + g_assert_cmpint(fd, ==, sfd); + + g_free(addr.u.fd.str); + close(sfd); +} + +static void test_socket_fd_pass_num_bad(void) +{ + SocketAddress addr; + Error *err = NULL; + int fd, sfd; + + g_assert(cur_mon == NULL); + sfd = dup(STDOUT_FILENO); + + addr.type = SOCKET_ADDRESS_TYPE_FD; + addr.u.fd.str = g_strdup_printf("%d", sfd); + + fd = socket_connect(&addr, &err); + g_assert_cmpint(fd, ==, -1); + error_free_or_abort(&err); + + fd = socket_listen(&addr, &err); + g_assert_cmpint(fd, ==, -1); + error_free_or_abort(&err); + + g_free(addr.u.fd.str); + close(sfd); +} + +static void test_socket_fd_pass_num_nocli(void) +{ + SocketAddress addr; + Error *err = NULL; + int fd; + + cur_mon = g_malloc(1); /* Fake a monitor */ + + addr.type = SOCKET_ADDRESS_TYPE_FD; + addr.u.fd.str = g_strdup_printf("%d", STDOUT_FILENO); + + fd = socket_connect(&addr, &err); + g_assert_cmpint(fd, ==, -1); + error_free_or_abort(&err); + + fd = socket_listen(&addr, &err); + g_assert_cmpint(fd, ==, -1); + error_free_or_abort(&err); + + g_free(addr.u.fd.str); +} + + +int main(int argc, char **argv) +{ + bool has_ipv4, has_ipv6; + + socket_init(); + + g_test_init(&argc, &argv, NULL); + + /* We're creating actual IPv4/6 sockets, so we should + * check if the host running tests actually supports + * each protocol to avoid breaking tests on machines + * with either IPv4 or IPv6 disabled. + */ + if (socket_check_protocol_support(&has_ipv4, &has_ipv6) < 0) { + return 1; + } + + if (has_ipv4) { + g_test_add_func("/util/socket/is-socket/bad", + test_fd_is_socket_bad); + g_test_add_func("/util/socket/is-socket/good", + test_fd_is_socket_good); + g_test_add_func("/socket/fd-pass/name/good", + test_socket_fd_pass_name_good); + g_test_add_func("/socket/fd-pass/name/bad", + test_socket_fd_pass_name_bad); + g_test_add_func("/socket/fd-pass/name/nomon", + test_socket_fd_pass_name_nomon); + g_test_add_func("/socket/fd-pass/num/good", + test_socket_fd_pass_num_good); + g_test_add_func("/socket/fd-pass/num/bad", + test_socket_fd_pass_num_bad); + g_test_add_func("/socket/fd-pass/num/nocli", + test_socket_fd_pass_num_nocli); + } + + return g_test_run(); +} diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c index 7393d69bb2..037872bb98 100644 --- a/tests/virtio-scsi-test.c +++ b/tests/virtio-scsi-test.c @@ -216,6 +216,9 @@ static void test_unaligned_write_same(void) const uint8_t write_same_cdb_2[VIRTIO_SCSI_CDB_SIZE] = { 0x41, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x33, 0x00, 0x00 }; + const uint8_t write_same_cdb_ndob[VIRTIO_SCSI_CDB_SIZE] = { + 0x41, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x33, 0x00, 0x00 + }; vs = qvirtio_scsi_pci_init(PCI_SLOT); @@ -225,6 +228,9 @@ static void test_unaligned_write_same(void) g_assert_cmphex(0, ==, virtio_scsi_do_command(vs, write_same_cdb_2, NULL, 0, buf2, 512, NULL)); + g_assert_cmphex(0, ==, + virtio_scsi_do_command(vs, write_same_cdb_ndob, NULL, 0, NULL, 0, NULL)); + qvirtio_scsi_pci_free(vs); } |