diff options
-rw-r--r-- | lib/common.h | 15 | ||||
-rw-r--r-- | lib/dma.c | 30 | ||||
-rw-r--r-- | lib/dma.h | 19 | ||||
-rw-r--r-- | lib/libvfio-user.c | 37 | ||||
-rw-r--r-- | lib/migration.c | 4 | ||||
-rw-r--r-- | lib/migration.h | 4 | ||||
-rw-r--r-- | lib/private.h | 24 | ||||
-rw-r--r-- | lib/tran_sock.c | 10 | ||||
-rw-r--r-- | lib/tran_sock.h | 6 | ||||
-rw-r--r-- | test/CMakeLists.txt | 24 | ||||
-rw-r--r-- | test/mocks.c | 242 | ||||
-rw-r--r-- | test/mocks.h | 14 | ||||
-rw-r--r-- | test/unit-tests.c | 308 | ||||
-rw-r--r-- | test/valgrind.supp | 9 |
14 files changed, 353 insertions, 393 deletions
diff --git a/lib/common.h b/lib/common.h index 7ac865e..d15017a 100644 --- a/lib/common.h +++ b/lib/common.h @@ -55,21 +55,22 @@ #define ROUND_DOWN(x, a) ((x) & ~((a)-1)) #define ROUND_UP(x,a) ROUND_DOWN((x)+(a)-1, a) -#define UNIT_TEST_SYMBOL(x) \ - typeof(x) __wrap_##x __attribute__((weak, alias(#x))) - #ifdef UNIT_TEST -#define MOCKED(r, f, ...) \ +#define MOCK_DEFINE(f) \ + (__real_ ## f) + +#define MOCK_DECLARE(r, f, ...) \ r f(__VA_ARGS__); \ r __real_ ## f(__VA_ARGS__); \ r __wrap_ ## f(__VA_ARGS__); #else /* UNIT_TEST */ -#define MOCKED(r, f, ...) \ - r f(__VA_ARGS__); \ - r __wrap_ ## f(__VA_ARGS__) +#define MOCK_DEFINE(f) (f) + +#define MOCK_DECLARE(r, f, ...) \ + r f(__VA_ARGS__); #endif /* UNIT_TEST */ @@ -92,8 +92,8 @@ dma_controller_create(vfu_ctx_t *vfu_ctx, int max_regions) } void -_dma_controller_do_remove_region(dma_controller_t *dma, - dma_memory_region_t *region) +MOCK_DEFINE(_dma_controller_do_remove_region)(dma_controller_t *dma, + dma_memory_region_t *region) { int err; @@ -113,13 +113,6 @@ _dma_controller_do_remove_region(dma_controller_t *dma, } } } -UNIT_TEST_SYMBOL(_dma_controller_do_remove_region); -/* - * FIXME super ugly, but without this functions within the same compilation - * unit don't call the wrapped version, making unit testing impossible. - * Ideally we'd like the UNIT_TEST_SYMBOL macro to solve this. - */ -#define _dma_controller_do_remove_region __wrap__dma_controller_do_remove_region /* * FIXME no longer used. Also, it doesn't work for addresses that span two @@ -144,9 +137,10 @@ dma_controller_region_valid(dma_controller_t *dma, dma_addr_t dma_addr, /* FIXME not thread safe */ int -dma_controller_remove_region(dma_controller_t *dma, - dma_addr_t dma_addr, size_t size, - vfu_unmap_dma_cb_t *unmap_dma, void *data) +MOCK_DEFINE(dma_controller_remove_region)(dma_controller_t *dma, + dma_addr_t dma_addr, size_t size, + vfu_unmap_dma_cb_t *unmap_dma, + void *data) { int idx; dma_memory_region_t *region; @@ -183,7 +177,6 @@ dma_controller_remove_region(dma_controller_t *dma, } return -ENOENT; } -UNIT_TEST_SYMBOL(dma_controller_remove_region); static inline void dma_controller_remove_regions(dma_controller_t *dma) @@ -214,9 +207,9 @@ dma_controller_destroy(dma_controller_t *dma) } int -dma_controller_add_region(dma_controller_t *dma, - dma_addr_t dma_addr, size_t size, - int fd, off_t offset, uint32_t prot) +MOCK_DEFINE(dma_controller_add_region)(dma_controller_t *dma, + dma_addr_t dma_addr, size_t size, + int fd, off_t offset, uint32_t prot) { int idx; dma_memory_region_t *region; @@ -320,7 +313,6 @@ dma_controller_add_region(dma_controller_t *dma, err: return -idx - 1; } -UNIT_TEST_SYMBOL(dma_controller_add_region); static inline void mmap_round(size_t *offset, size_t *size, size_t page_size) @@ -331,7 +323,8 @@ mmap_round(size_t *offset, size_t *size, size_t page_size) } void * -dma_map_region(dma_memory_region_t *region, int prot, size_t offset, size_t len) +MOCK_DEFINE(dma_map_region)(dma_memory_region_t *region, int prot, + size_t offset, size_t len) { size_t mmap_offset, mmap_size = len; char *mmap_base; @@ -357,7 +350,6 @@ dma_map_region(dma_memory_region_t *region, int prot, size_t offset, size_t len) return mmap_base + (offset - mmap_offset); } -UNIT_TEST_SYMBOL(dma_map_region); int dma_unmap_region(dma_memory_region_t *region, void *virt_addr, size_t len) @@ -116,15 +116,16 @@ dma_controller_destroy(dma_controller_t *dma); * where this region would have been mapped to if the call could succeed * (e.g. due to conflict with existing region). */ -MOCKED(int, dma_controller_add_region, dma_controller_t *dma, - dma_addr_t dma_addr, size_t size, int fd, off_t offset, uint32_t prot); +MOCK_DECLARE(int, dma_controller_add_region, dma_controller_t *dma, + dma_addr_t dma_addr, size_t size, int fd, off_t offset, + uint32_t prot); -MOCKED(void, _dma_controller_do_remove_region, dma_controller_t *dma, - dma_memory_region_t *region); +MOCK_DECLARE(void, _dma_controller_do_remove_region, dma_controller_t *dma, + dma_memory_region_t *region); -MOCKED(int, dma_controller_remove_region, dma_controller_t *dma, - dma_addr_t dma_addr, size_t size, vfu_unmap_dma_cb_t *unmap_dma, - void *data); +MOCK_DECLARE(int, dma_controller_remove_region, dma_controller_t *dma, + dma_addr_t dma_addr, size_t size, vfu_unmap_dma_cb_t *unmap_dma, + void *data); // Helper for dma_addr_to_sg() slow path. int @@ -250,8 +251,8 @@ dma_addr_to_sg(const dma_controller_t *dma, return cnt; } -MOCKED(void *, dma_map_region, dma_memory_region_t *region, int prot, - size_t offset, size_t len); +MOCK_DECLARE(void *, dma_map_region, dma_memory_region_t *region, int prot, + size_t offset, size_t len); int dma_unmap_region(dma_memory_region_t *region, void *virt_addr, size_t len); diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c index 3140a75..40a23b8 100644 --- a/lib/libvfio-user.c +++ b/lib/libvfio-user.c @@ -618,9 +618,9 @@ out: } int -handle_dirty_pages(vfu_ctx_t *vfu_ctx, uint32_t size, - struct iovec **iovecs, size_t *nr_iovecs, - struct vfio_iommu_type1_dirty_bitmap *dirty_bitmap) +MOCK_DEFINE(handle_dirty_pages)(vfu_ctx_t *vfu_ctx, uint32_t size, + struct iovec **iovecs, size_t *nr_iovecs, + struct vfio_iommu_type1_dirty_bitmap *dirty_bitmap) { int ret; @@ -650,8 +650,6 @@ handle_dirty_pages(vfu_ctx_t *vfu_ctx, uint32_t size, return ret; } -UNIT_TEST_SYMBOL(handle_dirty_pages); -#define handle_dirty_pages __wrap_handle_dirty_pages /* * FIXME return value is messed up, sometimes we return -1 and set errno while @@ -693,8 +691,8 @@ validate_header(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, size_t size) * the number of bytes read. */ int -get_next_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, int *fds, - size_t *nr_fds) +MOCK_DEFINE(get_next_command)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, + int *fds, size_t *nr_fds) { int ret; @@ -723,21 +721,17 @@ get_next_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, int *fds, } return ret; } -UNIT_TEST_SYMBOL(get_next_command); -#define get_next_command __wrap_get_next_command bool -cmd_allowed_when_stopped_and_copying(uint16_t cmd) +MOCK_DEFINE(cmd_allowed_when_stopped_and_copying)(uint16_t cmd) { return cmd == VFIO_USER_REGION_READ || cmd == VFIO_USER_REGION_WRITE || cmd == VFIO_USER_DIRTY_PAGES; } -UNIT_TEST_SYMBOL(cmd_allowed_when_stopped_and_copying); -#define cmd_allowed_when_stopped_and_copying __wrap_cmd_allowed_when_stopped_and_copying bool -should_exec_command(vfu_ctx_t *vfu_ctx, uint16_t cmd) +MOCK_DEFINE(should_exec_command)(vfu_ctx_t *vfu_ctx, uint16_t cmd) { assert(vfu_ctx != NULL); @@ -755,14 +749,13 @@ should_exec_command(vfu_ctx_t *vfu_ctx, uint16_t cmd) } return true; } -UNIT_TEST_SYMBOL(should_exec_command); -#define should_exec_command __wrap_should_exec_command int -exec_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, size_t size, - int *fds, size_t nr_fds, int **fds_out, size_t *nr_fds_out, - struct iovec *_iovecs, struct iovec **iovecs, size_t *nr_iovecs, - bool *free_iovec_data) +MOCK_DEFINE(exec_command)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, + size_t size, int *fds, size_t nr_fds, int **fds_out, + size_t *nr_fds_out, struct iovec *_iovecs, + struct iovec **iovecs, size_t *nr_iovecs, + bool *free_iovec_data) { int ret; struct vfio_irq_info *irq_info; @@ -898,11 +891,9 @@ exec_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, size_t size, free(cmd_data); return ret; } -UNIT_TEST_SYMBOL(exec_command); -#define exec_command __wrap_exec_command int -process_request(vfu_ctx_t *vfu_ctx) +MOCK_DEFINE(process_request)(vfu_ctx_t *vfu_ctx) { struct vfio_user_header hdr = { 0, }; int ret; @@ -984,8 +975,6 @@ process_request(vfu_ctx_t *vfu_ctx) free(fds_out); return ret; } -UNIT_TEST_SYMBOL(process_request); -#define process_request __wrap_process_request int vfu_realize_ctx(vfu_ctx_t *vfu_ctx) diff --git a/lib/migration.c b/lib/migration.c index cc7abcf..93703a0 100644 --- a/lib/migration.c +++ b/lib/migration.c @@ -477,13 +477,13 @@ migration_region_access(vfu_ctx_t *vfu_ctx, char *buf, size_t count, } bool -device_is_stopped_and_copying(struct migration *migr) +MOCK_DEFINE(device_is_stopped_and_copying)(struct migration *migr) { return migr != NULL && migr->info.device_state == VFIO_DEVICE_STATE_SAVING; } bool -device_is_stopped(struct migration *migr) +MOCK_DEFINE(device_is_stopped)(struct migration *migr) { return migr != NULL && migr->info.device_state == VFIO_DEVICE_STATE_STOP; } diff --git a/lib/migration.h b/lib/migration.h index b0ea652..498cae0 100644 --- a/lib/migration.h +++ b/lib/migration.h @@ -55,9 +55,9 @@ migration_region_access(vfu_ctx_t *vfu_ctx, char *buf, size_t count, bool migration_available(vfu_ctx_t *vfu_ctx); -MOCKED(bool, device_is_stopped, struct migration *migr); +MOCK_DECLARE(bool, device_is_stopped, struct migration *migr); -MOCKED(bool, device_is_stopped_and_copying, struct migration *migration); +MOCK_DECLARE(bool, device_is_stopped_and_copying, struct migration *migration); size_t migration_get_pgsize(struct migration *migr); diff --git a/lib/private.h b/lib/private.h index 9f06304..c463fea 100644 --- a/lib/private.h +++ b/lib/private.h @@ -163,23 +163,23 @@ int handle_device_set_irqs(vfu_ctx_t *vfu_ctx, uint32_t size, int *fds, size_t nr_fds, struct vfio_irq_set *irq_set); -MOCKED(bool, should_exec_command, vfu_ctx_t *vfu_ctx, uint16_t cmd); +MOCK_DECLARE(bool, should_exec_command, vfu_ctx_t *vfu_ctx, uint16_t cmd); -MOCKED(bool, cmd_allowed_when_stopped_and_copying, uint16_t cmd); +MOCK_DECLARE(bool, cmd_allowed_when_stopped_and_copying, uint16_t cmd); -MOCKED(int, get_next_command, vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, - int *fds, size_t *nr_fds); +MOCK_DECLARE(int, get_next_command, vfu_ctx_t *vfu_ctx, + struct vfio_user_header *hdr, int *fds, size_t *nr_fds); -MOCKED(int, exec_command, vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, - size_t size, int *fds, size_t nr_fds, int **fds_out, size_t *nr_fds_out, - struct iovec *_iovecs, struct iovec **iovecs, size_t *nr_iovecs, - bool *free_iovec_data); +MOCK_DECLARE(int, exec_command, vfu_ctx_t *vfu_ctx, + struct vfio_user_header *hdr, size_t size, int *fds, size_t nr_fds, + int **fds_out, size_t *nr_fds_out, struct iovec *_iovecs, + struct iovec **iovecs, size_t *nr_iovecs, bool *free_iovec_data); -MOCKED(int, process_request, vfu_ctx_t *vfu_ctx); +MOCK_DECLARE(int, process_request, vfu_ctx_t *vfu_ctx); -MOCKED(int, handle_dirty_pages, vfu_ctx_t *vfu_ctx, uint32_t size, - struct iovec **iovecs, size_t *nr_iovecs, - struct vfio_iommu_type1_dirty_bitmap *dirty_bitmap); +MOCK_DECLARE(int, handle_dirty_pages, vfu_ctx_t *vfu_ctx, uint32_t size, + struct iovec **iovecs, size_t *nr_iovecs, + struct vfio_iommu_type1_dirty_bitmap *dirty_bitmap); #endif /* LIB_VFIO_USER_PRIVATE_H */ diff --git a/lib/tran_sock.c b/lib/tran_sock.c index 8919c3f..268b2b4 100644 --- a/lib/tran_sock.c +++ b/lib/tran_sock.c @@ -58,10 +58,10 @@ typedef struct { } tran_sock_t; int -tran_sock_send_iovec(int sock, uint16_t msg_id, bool is_reply, - enum vfio_user_command cmd, - struct iovec *iovecs, size_t nr_iovecs, - int *fds, int count, int err) +MOCK_DEFINE(tran_sock_send_iovec)(int sock, uint16_t msg_id, bool is_reply, + enum vfio_user_command cmd, + struct iovec *iovecs, size_t nr_iovecs, + int *fds, int count, int err) { int ret; struct vfio_user_header hdr = {.msg_id = msg_id}; @@ -123,8 +123,6 @@ tran_sock_send_iovec(int sock, uint16_t msg_id, bool is_reply, return 0; } -UNIT_TEST_SYMBOL(tran_sock_send_iovec); -#define tran_sock_send_iovec __wrap_tran_sock_send_iovec int tran_sock_send(int sock, uint16_t msg_id, bool is_reply, diff --git a/lib/tran_sock.h b/lib/tran_sock.h index 754798f..eb7658b 100644 --- a/lib/tran_sock.h +++ b/lib/tran_sock.h @@ -60,9 +60,9 @@ tran_parse_version_json(const char *json_str, int *client_max_fdsp, * Send a message to the other end. The iovecs array should leave the first * entry empty, as it will be used for the header. */ -MOCKED(int, tran_sock_send_iovec, int sock, uint16_t msg_id, bool is_reply, - enum vfio_user_command cmd, struct iovec *iovecs, size_t nr_iovecs, - int *fds, int count, int err); +MOCK_DECLARE(int, tran_sock_send_iovec, int sock, uint16_t msg_id, + bool is_reply, enum vfio_user_command cmd, struct iovec *iovecs, + size_t nr_iovecs, int *fds, int count, int err); /* * Send a message to the other end with the given data. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d243adc..2fd2e84 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -32,6 +32,7 @@ else() set(valgrind_path "/usr/bin/valgrind") set(valgrind_args "--error-exitcode=1 --leak-check=full --quiet") set(valgrind_args "${valgrind_args} --show-leak-kinds=all --track-origins=yes") + set(valgrind_args "${valgrind_args} --suppressions=${CMAKE_CURRENT_SOURCE_DIR}/valgrind.supp") separate_arguments(valgrind_args) set(valgrind ${valgrind_path} ${valgrind_args}) endif() @@ -45,31 +46,10 @@ add_executable(unit-tests unit-tests.c mocks.c ../lib/pci_caps.c ../lib/tran_sock.c) -target_link_libraries(unit-tests PUBLIC cmocka json-c) +target_link_libraries(unit-tests PUBLIC cmocka dl json-c) target_compile_definitions(unit-tests PUBLIC UNIT_TEST) -# No "target_link_options" in cmake2 -target_link_libraries(unit-tests PUBLIC - "-Wl,--wrap=_dma_controller_do_remove_region") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=dma_controller_add_region") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=dma_controller_remove_region") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=dma_map_region") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=device_is_stopped") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=get_next_command") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=exec_command") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=close") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=tran_sock_send_iovec") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=free") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=process_request") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=bind") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=listen") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=device_is_stopped_and_copying") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=cmd_allowed_when_stopped_and_copying") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=device_is_stopped") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=should_exec_command") -target_link_libraries(unit-tests PUBLIC "-Wl,--wrap=handle_dirty_pages") - enable_testing() add_test(NAME unit-tests COMMAND ${valgrind} ${CMAKE_CURRENT_BINARY_DIR}/unit-tests) add_test(NAME lspci COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/test-lspci.sh) diff --git a/test/mocks.c b/test/mocks.c index daeeb81..3a83ed5 100644 --- a/test/mocks.c +++ b/test/mocks.c @@ -28,14 +28,17 @@ * */ +#include <dlfcn.h> +#include <setjmp.h> #include <stdarg.h> #include <stddef.h> -#include <setjmp.h> -#include <cmocka.h> +#include <string.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> +#include <cmocka.h> + #include "mocks.h" #include "dma.h" #include "migration.h" @@ -44,16 +47,74 @@ struct function { - void *addr; + const char *name; bool patched; }; +; +static int (*__real_close)(int); + +static struct function funcs[] = { + /* mocked internal funcs */ + { .name = "_dma_controller_do_remove_region" }, + { .name = "cmd_allowed_when_stopped_and_copying" }, + { .name = "device_is_stopped_and_copying" }, + { .name = "device_is_stopped" }, + { .name = "dma_controller_add_region" }, + { .name = "dma_controller_remove_region" }, + { .name = "dma_map_region" }, + { .name = "exec_command" }, + { .name = "get_next_command" }, + { .name = "handle_dirty_pages" }, + { .name = "process_request" }, + { .name = "should_exec_command" }, + { .name = "tran_sock_send_iovec" }, + /* system libs */ + { .name = "bind" }, + { .name = "close" }, + { .name = "listen" }, +}; + +static struct function * +find(const char *name) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(funcs); i++) { + if (strcmp(name, funcs[i].name) == 0) { + return &funcs[i]; + } + } + assert(false); +} + +void +patch(const char *name) +{ + struct function *func = find(name); + func->patched = true; +} + +static bool +is_patched(const char *name) +{ + return find(name)->patched; +} + +void +unpatch_all(void) +{ + size_t i; + for (i = 0; i < ARRAY_SIZE(funcs); i++) { + funcs[i].patched = false; + } +} int -__wrap_dma_controller_add_region(dma_controller_t *dma, dma_addr_t dma_addr, - size_t size, int fd, off_t offset, - uint32_t prot) +dma_controller_add_region(dma_controller_t *dma, dma_addr_t dma_addr, + size_t size, int fd, off_t offset, + uint32_t prot) { - if (!is_patched(dma_controller_add_region)) { + if (!is_patched("dma_controller_add_region")) { return __real_dma_controller_add_region(dma, dma_addr, size, fd, offset, prot); } @@ -68,11 +129,11 @@ __wrap_dma_controller_add_region(dma_controller_t *dma, dma_addr_t dma_addr, } int -__wrap_dma_controller_remove_region(dma_controller_t *dma, - dma_addr_t dma_addr, size_t size, - vfu_unmap_dma_cb_t *unmap_dma, void *data) +dma_controller_remove_region(dma_controller_t *dma, + dma_addr_t dma_addr, size_t size, + vfu_unmap_dma_cb_t *unmap_dma, void *data) { - if (!is_patched(dma_controller_remove_region)) { + if (!is_patched("dma_controller_remove_region")) { return __real_dma_controller_remove_region(dma, dma_addr, size, unmap_dma, data); } @@ -86,8 +147,8 @@ __wrap_dma_controller_remove_region(dma_controller_t *dma, } void * -__wrap_dma_map_region(dma_memory_region_t *region, int prot, size_t offset, - size_t len) +dma_map_region(dma_memory_region_t *region, int prot, size_t offset, + size_t len) { check_expected_ptr(region); check_expected(prot); @@ -97,17 +158,17 @@ __wrap_dma_map_region(dma_memory_region_t *region, int prot, size_t offset, } void -__wrap__dma_controller_do_remove_region(dma_controller_t *dma, - dma_memory_region_t *region) +_dma_controller_do_remove_region(dma_controller_t *dma, + dma_memory_region_t *region) { check_expected(dma); check_expected(region); } bool -__wrap_device_is_stopped(struct migration *migration) +device_is_stopped(struct migration *migration) { - if (!is_patched(device_is_stopped)) { + if (!is_patched("device_is_stopped")) { return __real_device_is_stopped(migration); } check_expected(migration); @@ -115,8 +176,8 @@ __wrap_device_is_stopped(struct migration *migration) } int -__wrap_get_next_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, - int *fds, size_t *nr_fds) +get_next_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, + int *fds, size_t *nr_fds) { check_expected(vfu_ctx); check_expected(hdr); @@ -126,13 +187,13 @@ __wrap_get_next_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, } int -__wrap_exec_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, - size_t size, int *fds, size_t nr_fds, int **fds_out, - size_t *nr_fds_out, struct iovec *_iovecs, - struct iovec **iovecs, size_t *nr_iovecs, - bool *free_iovec_data) +exec_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, + size_t size, int *fds, size_t nr_fds, int **fds_out, + size_t *nr_fds_out, struct iovec *_iovecs, + struct iovec **iovecs, size_t *nr_iovecs, + bool *free_iovec_data) { - if (!is_patched(exec_command)) { + if (!is_patched("exec_command")) { return __real_exec_command(vfu_ctx, hdr, size, fds, nr_fds, fds_out, nr_fds_out, _iovecs, iovecs, nr_iovecs, free_iovec_data); @@ -152,21 +213,10 @@ __wrap_exec_command(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, } int -__wrap_close(int fd) -{ - if (!is_patched(close)) { - return __real_close(fd); - } - - check_expected(fd); - return mock(); -} - -int -__wrap_tran_sock_send_iovec(int sock, uint16_t msg_id, bool is_reply, - enum vfio_user_command cmd, - struct iovec *iovecs, size_t nr_iovecs, - int *fds, int count, int err) +tran_sock_send_iovec(int sock, uint16_t msg_id, bool is_reply, + enum vfio_user_command cmd, + struct iovec *iovecs, size_t nr_iovecs, + int *fds, int count, int err) { check_expected(sock); check_expected(msg_id); @@ -180,21 +230,11 @@ __wrap_tran_sock_send_iovec(int sock, uint16_t msg_id, bool is_reply, return mock(); } -void -__wrap_free(void *ptr) -{ - if (!is_patched(free)) { - __real_free(ptr); - return; - } - check_expected(ptr); -} - int -__wrap_process_request(vfu_ctx_t *vfu_ctx) +process_request(vfu_ctx_t *vfu_ctx) { - if (!is_patched(process_request)) { + if (!is_patched("process_request")) { return __real_process_request(vfu_ctx); } check_expected(vfu_ctx); @@ -202,23 +242,10 @@ __wrap_process_request(vfu_ctx_t *vfu_ctx) return mock(); } -int -__wrap_bind(int sockfd UNUSED, const struct sockaddr *addr UNUSED, - socklen_t addrlen UNUSED) -{ - return 0; -} - -int -__wrap_listen(int sockfd UNUSED, int backlog UNUSED) -{ - return 0; -} - bool -__wrap_device_is_stopped_and_copying(struct migration *migration) +device_is_stopped_and_copying(struct migration *migration) { - if (!is_patched(device_is_stopped_and_copying)) { + if (!is_patched("device_is_stopped_and_copying")) { return __real_device_is_stopped_and_copying(migration); } check_expected(migration); @@ -226,9 +253,9 @@ __wrap_device_is_stopped_and_copying(struct migration *migration) } bool -__wrap_cmd_allowed_when_stopped_and_copying(uint16_t cmd) +cmd_allowed_when_stopped_and_copying(uint16_t cmd) { - if (!is_patched(cmd_allowed_when_stopped_and_copying)) { + if (!is_patched("cmd_allowed_when_stopped_and_copying")) { return __real_cmd_allowed_when_stopped_and_copying(cmd); } check_expected(cmd); @@ -236,9 +263,9 @@ __wrap_cmd_allowed_when_stopped_and_copying(uint16_t cmd) } bool -__wrap_should_exec_command(vfu_ctx_t *vfu_ctx, uint16_t cmd) +should_exec_command(vfu_ctx_t *vfu_ctx, uint16_t cmd) { - if (!is_patched(should_exec_command)) { + if (!is_patched("should_exec_command")) { return __real_should_exec_command(vfu_ctx, cmd); } check_expected(vfu_ctx); @@ -247,11 +274,11 @@ __wrap_should_exec_command(vfu_ctx_t *vfu_ctx, uint16_t cmd) } int -__wrap_handle_dirty_pages(vfu_ctx_t *vfu_ctx, uint32_t size, - struct iovec **iovecs, size_t *nr_iovecs, - struct vfio_iommu_type1_dirty_bitmap *dirty_bitmap) +handle_dirty_pages(vfu_ctx_t *vfu_ctx, uint32_t size, + struct iovec **iovecs, size_t *nr_iovecs, + struct vfio_iommu_type1_dirty_bitmap *dirty_bitmap) { - if (!is_patched(handle_dirty_pages)) { + if (!is_patched("handle_dirty_pages")) { return __real_handle_dirty_pages(vfu_ctx, size, iovecs, nr_iovecs, dirty_bitmap); } @@ -273,61 +300,34 @@ mock_unmap_dma(vfu_ctx_t *vfu_ctx, uint64_t iova, uint64_t len) return mock(); } -/* FIXME should be something faster than unsorted array, look at tsearch(3). */ -static struct function funcs[] = { - {.addr = &__wrap_dma_controller_add_region}, - {.addr = &__wrap_dma_controller_remove_region}, - {.addr = &__wrap_dma_map_region}, - {.addr = &__wrap__dma_controller_do_remove_region}, - {.addr = &__wrap_device_is_stopped}, - {.addr = &__wrap_get_next_command}, - {.addr = &__wrap_exec_command}, - {.addr = &__wrap_close}, - {.addr = &__wrap_tran_sock_send_iovec}, - {.addr = &__wrap_free}, - {.addr = &__wrap_process_request}, - {.addr = &__wrap_bind}, - {.addr = &__wrap_listen}, - {.addr = &__wrap_device_is_stopped_and_copying}, - {.addr = &__wrap_cmd_allowed_when_stopped_and_copying}, - {.addr = &__wrap_device_is_stopped}, - {.addr = &__wrap_should_exec_command}, - {.addr = &__wrap_handle_dirty_pages}, -}; +/* System-provided funcs. */ -static struct function* -find(void *addr) +int +bind(int sockfd UNUSED, const struct sockaddr *addr UNUSED, + socklen_t addrlen UNUSED) { - size_t i; - - for (i = 0; i < ARRAY_SIZE(funcs); i++) { - if (addr == funcs[i].addr) { - return &funcs[i]; - } - } - assert(false); + return 0; } -void -patch(void *addr) +int +close(int fd) { - struct function *func = find(addr); - func->patched = true; -} + if (!is_patched("close")) { + if (__real_close == NULL) { + __real_close = dlsym(RTLD_NEXT, "close"); + } -bool -is_patched(void *addr) -{ - return find(addr)->patched; + return __real_close(fd); + } + + check_expected(fd); + return mock(); } -void -unpatch_all(void) +int +listen(int sockfd UNUSED, int backlog UNUSED) { - size_t i; - for (i = 0; i < ARRAY_SIZE(funcs); i++) { - funcs[i].patched = false; - } + return 0; } /* ex: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/test/mocks.h b/test/mocks.h index b005af6..4ffe047 100644 --- a/test/mocks.h +++ b/test/mocks.h @@ -33,19 +33,9 @@ #include "private.h" -void unpatch_all(void); - -void patch(void *fn); - -bool is_patched(void *fn); - -MOCKED(int, close, int fd); +void patch(const char *func); -MOCKED(void, free, void *); - -MOCKED(int, bind, int sockfd, const struct sockaddr *addr, socklen_t addrlen); - -MOCKED(int, listen, int sockfd, int backlog); +void unpatch_all(void); int mock_unmap_dma(vfu_ctx_t *vfu_ctx, uint64_t iova, uint64_t len); diff --git a/test/unit-tests.c b/test/unit-tests.c index e773ead..c593b09 100644 --- a/test/unit-tests.c +++ b/test/unit-tests.c @@ -93,14 +93,14 @@ test_dma_map_without_fd(void **state UNUSED) }; int fd; - patch(dma_controller_add_region); - will_return(__wrap_dma_controller_add_region, 0); - expect_value(__wrap_dma_controller_add_region, dma, vfu_ctx.dma); - expect_value(__wrap_dma_controller_add_region, dma_addr, r.addr); - expect_value(__wrap_dma_controller_add_region, size, r.size); - expect_value(__wrap_dma_controller_add_region, fd, -1); - expect_value(__wrap_dma_controller_add_region, offset, r.offset); - expect_value(__wrap_dma_controller_add_region, prot, r.prot); + patch("dma_controller_add_region"); + will_return(dma_controller_add_region, 0); + expect_value(dma_controller_add_region, dma, vfu_ctx.dma); + expect_value(dma_controller_add_region, dma_addr, r.addr); + expect_value(dma_controller_add_region, size, r.size); + expect_value(dma_controller_add_region, fd, -1); + expect_value(dma_controller_add_region, offset, r.offset); + expect_value(dma_controller_add_region, prot, r.prot); assert_int_equal(0, handle_dma_map_or_unmap(&vfu_ctx, size, true, &fd, 0, &r)); } @@ -152,23 +152,23 @@ test_dma_add_regions_mixed(void **state UNUSED) }; int fd = 0x0badf00d; - patch(dma_controller_add_region); + patch("dma_controller_add_region"); /* 1st region */ - will_return(__wrap_dma_controller_add_region, 0); - expect_value(__wrap_dma_controller_add_region, dma, vfu_ctx.dma); - expect_value(__wrap_dma_controller_add_region, dma_addr, r[0].addr); - expect_value(__wrap_dma_controller_add_region, size, r[0].size); - expect_value(__wrap_dma_controller_add_region, fd, -1); - expect_value(__wrap_dma_controller_add_region, offset, r[0].offset); - expect_value(__wrap_dma_controller_add_region, prot, r[0].prot); + will_return(dma_controller_add_region, 0); + expect_value(dma_controller_add_region, dma, vfu_ctx.dma); + expect_value(dma_controller_add_region, dma_addr, r[0].addr); + expect_value(dma_controller_add_region, size, r[0].size); + expect_value(dma_controller_add_region, fd, -1); + expect_value(dma_controller_add_region, offset, r[0].offset); + expect_value(dma_controller_add_region, prot, r[0].prot); /* 2nd region */ - will_return(__wrap_dma_controller_add_region, 0); - expect_value(__wrap_dma_controller_add_region, dma, vfu_ctx.dma); - expect_value(__wrap_dma_controller_add_region, dma_addr, r[1].addr); - expect_value(__wrap_dma_controller_add_region, size, r[1].size); - expect_value(__wrap_dma_controller_add_region, fd, fd); - expect_value(__wrap_dma_controller_add_region, offset, r[1].offset); - expect_value(__wrap_dma_controller_add_region, prot, r[1].prot); + will_return(dma_controller_add_region, 0); + expect_value(dma_controller_add_region, dma, vfu_ctx.dma); + expect_value(dma_controller_add_region, dma_addr, r[1].addr); + expect_value(dma_controller_add_region, size, r[1].size); + expect_value(dma_controller_add_region, fd, fd); + expect_value(dma_controller_add_region, offset, r[1].offset); + expect_value(dma_controller_add_region, prot, r[1].prot); assert_int_equal(0, handle_dma_map_or_unmap(&vfu_ctx, sizeof(r), true, &fd, 1, r)); assert_int_equal(2, count); @@ -207,38 +207,38 @@ test_dma_add_regions_mixed_partial_failure(void **state UNUSED) }; int fds[] = {0xa, 0xb}; - patch(dma_controller_add_region); + patch("dma_controller_add_region"); /* 1st region */ - expect_value(__wrap_dma_controller_add_region, dma, vfu_ctx.dma); - expect_value(__wrap_dma_controller_add_region, dma_addr, r[0].addr); - expect_value(__wrap_dma_controller_add_region, size, r[0].size); - expect_value(__wrap_dma_controller_add_region, fd, -1); - expect_value(__wrap_dma_controller_add_region, offset, r[0].offset); - expect_value(__wrap_dma_controller_add_region, prot, r[0].prot); - will_return(__wrap_dma_controller_add_region, 0); + expect_value(dma_controller_add_region, dma, vfu_ctx.dma); + expect_value(dma_controller_add_region, dma_addr, r[0].addr); + expect_value(dma_controller_add_region, size, r[0].size); + expect_value(dma_controller_add_region, fd, -1); + expect_value(dma_controller_add_region, offset, r[0].offset); + expect_value(dma_controller_add_region, prot, r[0].prot); + will_return(dma_controller_add_region, 0); /* 2nd region */ - expect_value(__wrap_dma_controller_add_region, dma, vfu_ctx.dma); - expect_value(__wrap_dma_controller_add_region, dma_addr, r[1].addr); - expect_value(__wrap_dma_controller_add_region, size, r[1].size); - expect_value(__wrap_dma_controller_add_region, fd, fds[0]); - expect_value(__wrap_dma_controller_add_region, offset, r[1].offset); - expect_value(__wrap_dma_controller_add_region, prot, r[1].prot); - will_return(__wrap_dma_controller_add_region, 0); + expect_value(dma_controller_add_region, dma, vfu_ctx.dma); + expect_value(dma_controller_add_region, dma_addr, r[1].addr); + expect_value(dma_controller_add_region, size, r[1].size); + expect_value(dma_controller_add_region, fd, fds[0]); + expect_value(dma_controller_add_region, offset, r[1].offset); + expect_value(dma_controller_add_region, prot, r[1].prot); + will_return(dma_controller_add_region, 0); /* 3rd region */ - expect_value(__wrap_dma_controller_add_region, dma, vfu_ctx.dma); - expect_value(__wrap_dma_controller_add_region, dma_addr, r[2].addr); - expect_value(__wrap_dma_controller_add_region, size, r[2].size); - expect_value(__wrap_dma_controller_add_region, fd, fds[1]); - expect_value(__wrap_dma_controller_add_region, offset, r[2].offset); - expect_value(__wrap_dma_controller_add_region, prot, r[2].prot); - will_return(__wrap_dma_controller_add_region, -0x1234); - - patch(close); - expect_value(__wrap_close, fd, 0xb); - will_return(__wrap_close, 0); + expect_value(dma_controller_add_region, dma, vfu_ctx.dma); + expect_value(dma_controller_add_region, dma_addr, r[2].addr); + expect_value(dma_controller_add_region, size, r[2].size); + expect_value(dma_controller_add_region, fd, fds[1]); + expect_value(dma_controller_add_region, offset, r[2].offset); + expect_value(dma_controller_add_region, prot, r[2].prot); + will_return(dma_controller_add_region, -0x1234); + + patch("close"); + expect_value(close, fd, 0xb); + will_return(close, 0); assert_int_equal(-0x1234, handle_dma_map_or_unmap(&vfu_ctx, @@ -259,14 +259,14 @@ test_dma_map_return_value(void **state UNUSED) struct vfio_user_dma_region r = { 0 }; int fd = 0; - patch(dma_controller_add_region); - expect_value(__wrap_dma_controller_add_region, dma, vfu_ctx.dma); - expect_value(__wrap_dma_controller_add_region, dma_addr, r.addr); - expect_value(__wrap_dma_controller_add_region, size, r.size); - expect_value(__wrap_dma_controller_add_region, fd, -1); - expect_value(__wrap_dma_controller_add_region, offset, r.offset); - expect_value(__wrap_dma_controller_add_region, prot, r.prot); - will_return(__wrap_dma_controller_add_region, 2); + patch("dma_controller_add_region"); + expect_value(dma_controller_add_region, dma, vfu_ctx.dma); + expect_value(dma_controller_add_region, dma_addr, r.addr); + expect_value(dma_controller_add_region, size, r.size); + expect_value(dma_controller_add_region, fd, -1); + expect_value(dma_controller_add_region, offset, r.offset); + expect_value(dma_controller_add_region, prot, r.prot); + will_return(dma_controller_add_region, 2); assert_int_equal(0, handle_dma_map_or_unmap(&vfu_ctx, sizeof(struct vfio_user_dma_region), @@ -290,20 +290,20 @@ test_handle_dma_unmap(void **state UNUSED) { .addr = 0xbcda, .size = 0x4321 } }; - patch(dma_controller_add_region); - patch(dma_controller_remove_region); - expect_value(__wrap_dma_controller_remove_region, dma, &d); - expect_value(__wrap_dma_controller_remove_region, dma_addr, 0xabcd); - expect_value(__wrap_dma_controller_remove_region, size, 0x1234); - expect_value(__wrap_dma_controller_remove_region, unmap_dma, 0x8badf00d); - expect_value(__wrap_dma_controller_remove_region, data, &v); - will_return(__wrap_dma_controller_remove_region, 0); - expect_value(__wrap_dma_controller_remove_region, dma, &d); - expect_value(__wrap_dma_controller_remove_region, dma_addr, 0xbcda); - expect_value(__wrap_dma_controller_remove_region, size, 0x4321); - expect_value(__wrap_dma_controller_remove_region, unmap_dma, 0x8badf00d); - expect_value(__wrap_dma_controller_remove_region, data, &v); - will_return(__wrap_dma_controller_remove_region, 0); + patch("dma_controller_add_region"); + patch("dma_controller_remove_region"); + expect_value(dma_controller_remove_region, dma, &d); + expect_value(dma_controller_remove_region, dma_addr, 0xabcd); + expect_value(dma_controller_remove_region, size, 0x1234); + expect_value(dma_controller_remove_region, unmap_dma, 0x8badf00d); + expect_value(dma_controller_remove_region, data, &v); + will_return(dma_controller_remove_region, 0); + expect_value(dma_controller_remove_region, dma, &d); + expect_value(dma_controller_remove_region, dma_addr, 0xbcda); + expect_value(dma_controller_remove_region, size, 0x4321); + expect_value(dma_controller_remove_region, unmap_dma, 0x8badf00d); + expect_value(dma_controller_remove_region, data, &v); + will_return(dma_controller_remove_region, 0); assert_int_equal(0, handle_dma_map_or_unmap(&v, sizeof(r), false, (void *)0xdeadbeef, 0, r)); @@ -357,9 +357,9 @@ test_dma_controller_remove_region_mapped(void **state UNUSED) expect_value(mock_unmap_dma, len, 0x100); /* FIXME add uni test when unmap_dma fails */ will_return(mock_unmap_dma, 0); - patch(_dma_controller_do_remove_region); - expect_value(__wrap__dma_controller_do_remove_region, dma, d); - expect_value(__wrap__dma_controller_do_remove_region, region, &d->regions[0]); + patch("_dma_controller_do_remove_region"); + expect_value(_dma_controller_do_remove_region, dma, d); + expect_value(_dma_controller_do_remove_region, region, &d->regions[0]); assert_int_equal(0, dma_controller_remove_region(d, 0xdeadbeef, 0x100, mock_unmap_dma, &v)); } @@ -381,7 +381,7 @@ test_dma_controller_remove_region_unmapped(void **state UNUSED) expect_value(mock_unmap_dma, iova, 0xdeadbeef); expect_value(mock_unmap_dma, len, 0x100); will_return(mock_unmap_dma, 0); - patch(_dma_controller_do_remove_region); + patch("_dma_controller_do_remove_region"); assert_int_equal(0, dma_controller_remove_region(d, 0xdeadbeef, 0x100, mock_unmap_dma, &v)); } @@ -430,42 +430,42 @@ test_process_command_free_passed_fds(void **state UNUSED) .tran_data = &ts }; - patch(get_next_command); - expect_value(__wrap_get_next_command, vfu_ctx, &vfu_ctx); - expect_any(__wrap_get_next_command, hdr); - expect_check(__wrap_get_next_command, fds, &set_fds, &get_next_command); - expect_check(__wrap_get_next_command, nr_fds, &set_nr_fds, NULL); - will_return(__wrap_get_next_command, 0x0000beef); - - patch(exec_command); - expect_value(__wrap_exec_command, vfu_ctx, &vfu_ctx); - expect_any(__wrap_exec_command, hdr); - expect_value(__wrap_exec_command, size, 0x0000beef); - expect_check(__wrap_exec_command, fds, &set_fds, &exec_command); - expect_any(__wrap_exec_command, nr_fds); - expect_any(__wrap_exec_command, fds_out); - expect_any(__wrap_exec_command, nr_fds_out); - expect_any(__wrap_exec_command, _iovecs); - expect_any(__wrap_exec_command, iovecs); - expect_any(__wrap_exec_command, nr_iovecs); - expect_any(__wrap_exec_command, free_iovec_data); - will_return(__wrap_exec_command, -0x1234); - - patch(close); - expect_value(__wrap_close, fd, 0xcd); - will_return(__wrap_close, 0); - - patch(tran_sock_send_iovec); - expect_value(__wrap_tran_sock_send_iovec, sock, ts.conn_fd); - expect_any(__wrap_tran_sock_send_iovec, msg_id); - expect_value(__wrap_tran_sock_send_iovec, is_reply, true); - expect_any(__wrap_tran_sock_send_iovec, cmd); - expect_any(__wrap_tran_sock_send_iovec, iovecs); - expect_any(__wrap_tran_sock_send_iovec, nr_iovecs); - expect_any(__wrap_tran_sock_send_iovec, fds); - expect_any(__wrap_tran_sock_send_iovec, count); - expect_any(__wrap_tran_sock_send_iovec, err); - will_return(__wrap_tran_sock_send_iovec, 0); + patch("get_next_command"); + expect_value(get_next_command, vfu_ctx, &vfu_ctx); + expect_any(get_next_command, hdr); + expect_check(get_next_command, fds, &set_fds, &get_next_command); + expect_check(get_next_command, nr_fds, &set_nr_fds, NULL); + will_return(get_next_command, 0x0000beef); + + patch("exec_command"); + expect_value(exec_command, vfu_ctx, &vfu_ctx); + expect_any(exec_command, hdr); + expect_value(exec_command, size, 0x0000beef); + expect_check(exec_command, fds, &set_fds, &exec_command); + expect_any(exec_command, nr_fds); + expect_any(exec_command, fds_out); + expect_any(exec_command, nr_fds_out); + expect_any(exec_command, _iovecs); + expect_any(exec_command, iovecs); + expect_any(exec_command, nr_iovecs); + expect_any(exec_command, free_iovec_data); + will_return(exec_command, -0x1234); + + patch("close"); + expect_value(close, fd, 0xcd); + will_return(close, 0); + + patch("tran_sock_send_iovec"); + expect_value(tran_sock_send_iovec, sock, ts.conn_fd); + expect_any(tran_sock_send_iovec, msg_id); + expect_value(tran_sock_send_iovec, is_reply, true); + expect_any(tran_sock_send_iovec, cmd); + expect_any(tran_sock_send_iovec, iovecs); + expect_any(tran_sock_send_iovec, nr_iovecs); + expect_any(tran_sock_send_iovec, fds); + expect_any(tran_sock_send_iovec, count); + expect_any(tran_sock_send_iovec, err); + will_return(tran_sock_send_iovec, 0); assert_int_equal(0, process_request(&vfu_ctx)); } @@ -529,18 +529,18 @@ test_run_ctx(UNUSED void **state) vfu_ctx.realized = true; vfu_ctx.flags = LIBVFIO_USER_FLAG_ATTACH_NB; - patch(process_request); - expect_value(__wrap_process_request, vfu_ctx, &vfu_ctx); - will_return(__wrap_process_request, 0); + patch("process_request"); + expect_value(process_request, vfu_ctx, &vfu_ctx); + will_return(process_request, 0); assert_int_equal(0, vfu_run_ctx(&vfu_ctx)); // device realized, with blocking vfu_ctx vfu_ctx.flags = 0; - expect_value(__wrap_process_request, vfu_ctx, &vfu_ctx); - will_return(__wrap_process_request, 0); + expect_value(process_request, vfu_ctx, &vfu_ctx); + will_return(process_request, 0); - expect_value(__wrap_process_request, vfu_ctx, &vfu_ctx); - will_return(__wrap_process_request, -1); + expect_value(process_request, vfu_ctx, &vfu_ctx); + will_return(process_request, -1); assert_int_equal(-1, vfu_run_ctx(&vfu_ctx)); } @@ -681,9 +681,9 @@ test_vfu_ctx_create(void **state UNUSED) vfu_pci_add_capability(vfu_ctx, 0, 0, &pm)); assert_int_equal(0, vfu_realize_ctx(vfu_ctx)); - patch(close); - expect_value(__wrap_close, fd, ((tran_sock_t *)vfu_ctx->tran_data)->fd); - will_return(__wrap_close, 0); + patch("close"); + expect_value(close, fd, ((tran_sock_t *)vfu_ctx->tran_data)->fd); + will_return(close, 0); vfu_destroy_ctx(vfu_ctx); } @@ -1567,36 +1567,36 @@ test_should_exec_command(UNUSED void **state) struct migration migration = { { 0 } }; vfu_ctx_t vfu_ctx = { .migration = &migration }; - patch(device_is_stopped_and_copying); - patch(cmd_allowed_when_stopped_and_copying); - patch(device_is_stopped); + patch("device_is_stopped_and_copying"); + patch("cmd_allowed_when_stopped_and_copying"); + patch("device_is_stopped"); /* XXX stopped and copying, command allowed */ - will_return(__wrap_device_is_stopped_and_copying, true); - expect_value(__wrap_device_is_stopped_and_copying, migration, &migration); - will_return(__wrap_cmd_allowed_when_stopped_and_copying, true); - expect_value(__wrap_cmd_allowed_when_stopped_and_copying, cmd, 0xbeef); + will_return(device_is_stopped_and_copying, true); + expect_value(device_is_stopped_and_copying, migration, &migration); + will_return(cmd_allowed_when_stopped_and_copying, true); + expect_value(cmd_allowed_when_stopped_and_copying, cmd, 0xbeef); assert_true(should_exec_command(&vfu_ctx, 0xbeef)); /* XXX stopped and copying, command not allowed */ - will_return(__wrap_device_is_stopped_and_copying, true); - expect_any(__wrap_device_is_stopped_and_copying, migration); - will_return(__wrap_cmd_allowed_when_stopped_and_copying, false); - expect_any(__wrap_cmd_allowed_when_stopped_and_copying, cmd); + will_return(device_is_stopped_and_copying, true); + expect_any(device_is_stopped_and_copying, migration); + will_return(cmd_allowed_when_stopped_and_copying, false); + expect_any(cmd_allowed_when_stopped_and_copying, cmd); assert_false(should_exec_command(&vfu_ctx, 0xbeef)); /* XXX stopped */ - will_return(__wrap_device_is_stopped_and_copying, false); - expect_any(__wrap_device_is_stopped_and_copying, migration); - will_return(__wrap_device_is_stopped, true); - expect_value(__wrap_device_is_stopped, migration, &migration); + will_return(device_is_stopped_and_copying, false); + expect_any(device_is_stopped_and_copying, migration); + will_return(device_is_stopped, true); + expect_value(device_is_stopped, migration, &migration); assert_false(should_exec_command(&vfu_ctx, 0xbeef)); /* XXX none of the above */ - will_return(__wrap_device_is_stopped_and_copying, false); - expect_any(__wrap_device_is_stopped_and_copying, migration); - will_return(__wrap_device_is_stopped, false); - expect_any(__wrap_device_is_stopped, migration); + will_return(device_is_stopped_and_copying, false); + expect_any(device_is_stopped_and_copying, migration); + will_return(device_is_stopped, false); + expect_any(device_is_stopped, migration); assert_true(should_exec_command(&vfu_ctx, 0xbeef)); } @@ -1626,10 +1626,10 @@ test_exec_command(UNUSED void **state) int r; /* XXX should NOT execute command */ - patch(should_exec_command); - will_return(__wrap_should_exec_command, false); - expect_value(__wrap_should_exec_command, vfu_ctx, &vfu_ctx); - expect_value(__wrap_should_exec_command, cmd, 0xbeef); + patch("should_exec_command"); + will_return(should_exec_command, false); + expect_value(should_exec_command, vfu_ctx, &vfu_ctx); + expect_value(should_exec_command, cmd, 0xbeef); r = exec_command(&vfu_ctx, &hdr, size, &fds, 0, NULL, NULL, &_iovecs, &iovecs, &nr_iovecs, &free_iovec_data); assert_int_equal(-EINVAL, r); @@ -1637,9 +1637,9 @@ test_exec_command(UNUSED void **state) /* XXX should execute command */ struct transport_ops tran = { .recv_body = recv_body }; vfu_ctx.tran = &tran; - will_return(__wrap_should_exec_command, true); - expect_value(__wrap_should_exec_command, vfu_ctx, &vfu_ctx); - expect_value(__wrap_should_exec_command, cmd, 0xbeef); + will_return(should_exec_command, true); + expect_value(should_exec_command, vfu_ctx, &vfu_ctx); + expect_value(should_exec_command, cmd, 0xbeef); r = exec_command(&vfu_ctx, &hdr, size, &fds, 0, NULL, NULL, &_iovecs, &iovecs, &nr_iovecs, &free_iovec_data); assert_int_equal(-1, r); @@ -1665,7 +1665,7 @@ test_dirty_pages_without_dma(UNUSED void **state) int r; - patch(handle_dirty_pages); + patch("handle_dirty_pages"); /* XXX w/o DMA controller */ r = exec_command(&vfu_ctx, &hdr, size, &fds, 0, NULL, NULL, @@ -1674,12 +1674,12 @@ test_dirty_pages_without_dma(UNUSED void **state) /* XXX w/ DMA controller */ vfu_ctx.dma = (void*)0xdeadbeef; - expect_value(__wrap_handle_dirty_pages, vfu_ctx, &vfu_ctx); - expect_value(__wrap_handle_dirty_pages, size, 0); - expect_value(__wrap_handle_dirty_pages, iovecs, &iovecs); - expect_value(__wrap_handle_dirty_pages, nr_iovecs, &nr_iovecs); - expect_value(__wrap_handle_dirty_pages, dirty_bitmap, NULL); - will_return(__wrap_handle_dirty_pages, 0xabcd); + expect_value(handle_dirty_pages, vfu_ctx, &vfu_ctx); + expect_value(handle_dirty_pages, size, 0); + expect_value(handle_dirty_pages, iovecs, &iovecs); + expect_value(handle_dirty_pages, nr_iovecs, &nr_iovecs); + expect_value(handle_dirty_pages, dirty_bitmap, NULL); + will_return(handle_dirty_pages, 0xabcd); r = exec_command(&vfu_ctx, &hdr, size, &fds, 0, NULL, NULL, &_iovecs, &iovecs, &nr_iovecs, &free_iovec_data); assert_int_equal(0xabcd, r); diff --git a/test/valgrind.supp b/test/valgrind.supp new file mode 100644 index 0000000..3e1c5df --- /dev/null +++ b/test/valgrind.supp @@ -0,0 +1,9 @@ +{ + libdl-non-leak + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + fun:_dlerror_run + fun:dlsym + fun:close +} |