diff --git a/src/flush.c b/src/flush.c index 1ea9b29fd9..15fd0c7c5c 100644 --- a/src/flush.c +++ b/src/flush.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * flush.c -- librpma flush-related implementations @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef TEST_MOCK_ALLOC #include "cmocka_alloc.h" @@ -40,6 +41,7 @@ struct rpma_flush_internal { struct flush_apm { void *raw; /* buffer for read-after-write memory region */ + size_t mmap_size; /* size of the mmap()'ed memory */ struct rpma_mr_local *raw_mr; /* read-after-write memory region */ }; @@ -51,6 +53,8 @@ struct flush_apm { static int rpma_flush_apm_new(struct rpma_peer *peer, struct rpma_flush *flush) { + int ret; + /* a memory registration has to be page-aligned */ long pagesize = sysconf(_SC_PAGESIZE); if (pagesize < 0) { @@ -59,29 +63,32 @@ rpma_flush_apm_new(struct rpma_peer *peer, struct rpma_flush *flush) return RPMA_E_PROVIDER; } + size_t mmap_size = (size_t)pagesize; + /* allocate memory for the read-after-write buffer (RAW) */ - void *raw = NULL; - int ret = posix_memalign(&raw, (size_t)pagesize, RAW_SIZE); - if (ret) + void *raw = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + if (raw == MAP_FAILED) return RPMA_E_NOMEM; /* register the RAW buffer */ struct rpma_mr_local *raw_mr = NULL; ret = rpma_mr_reg(peer, raw, RAW_SIZE, RPMA_MR_USAGE_READ_DST, &raw_mr); if (ret) { - free(raw); + (void) munmap(raw, mmap_size); return ret; } struct flush_apm *flush_apm = malloc(sizeof(struct flush_apm)); if (flush_apm == NULL) { (void) rpma_mr_dereg(&raw_mr); - free(raw); + (void) munmap(raw, mmap_size); return RPMA_E_NOMEM; } flush_apm->raw = raw; flush_apm->raw_mr = raw_mr; + flush_apm->mmap_size = mmap_size; struct rpma_flush_internal *flush_internal = (struct rpma_flush_internal *)flush; @@ -102,12 +109,18 @@ rpma_flush_apm_delete(struct rpma_flush *flush) (struct rpma_flush_internal *)flush; struct flush_apm *flush_apm = (struct flush_apm *)flush_internal->context; - int ret = rpma_mr_dereg(&flush_apm->raw_mr); - free(flush_apm->raw); + int ret_dereg = rpma_mr_dereg(&flush_apm->raw_mr); + int ret_unmap = munmap(flush_apm->raw, flush_apm->mmap_size); free(flush_apm); - return ret; + if (ret_dereg) + return ret_dereg; + + if (ret_unmap) + return RPMA_E_INVAL; + + return 0; } /* diff --git a/src/flush.h b/src/flush.h index 6053e9b733..b1e8715572 100644 --- a/src/flush.h +++ b/src/flush.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * flush.h -- librpma flush-related internal definitions @@ -24,7 +24,7 @@ struct rpma_flush { * ERRORS * rpma_flush_new() can fail with the following errors: * - * - RPMA_E_NOMEM - out of memory + * - RPMA_E_NOMEM - out of memory (mmap() failed) * - RPMA_E_PROVIDER - sysconf() or ibv_reg_mr() failed */ int rpma_flush_new(struct rpma_peer *peer, struct rpma_flush **flush_ptr); @@ -33,7 +33,8 @@ int rpma_flush_new(struct rpma_peer *peer, struct rpma_flush **flush_ptr); * ERRORS * rpma_flush_delete() can fail with the following error: * - * - RPMA_E_PROVIDER ibv_dereg_mr() failed + * - RPMA_E_PROVIDER - ibv_dereg_mr() failed + * - RPMA_E_INVAL - munmap() failed */ int rpma_flush_delete(struct rpma_flush **flush_ptr); diff --git a/src/include/librpma.h b/src/include/librpma.h index 50c52b9414..a3999cb0f1 100644 --- a/src/include/librpma.h +++ b/src/include/librpma.h @@ -1637,7 +1637,7 @@ int rpma_conn_disconnect(struct rpma_conn *conn); * * ERRORS * rpma_conn_delete() can fail with the following errors: - * - RPMA_E_INVAL - conn_ptr is NULL + * - RPMA_E_INVAL - conn_ptr is NULL or munmap() failed * - RPMA_E_PROVIDER - ibv_destroy_cq() or rdma_destroy_id() failed * * SEE ALSO diff --git a/tests/integration/common/mocks.c b/tests/integration/common/mocks.c index 7c4b9a68c2..89557ae8fd 100644 --- a/tests/integration/common/mocks.c +++ b/tests/integration/common/mocks.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * mocks.c -- common mocks for integration tests @@ -7,6 +7,8 @@ #include #include +#include +#include #include "cmocka_headers.h" #include "conn_cfg.h" @@ -758,3 +760,47 @@ create_descriptor(void *desc, return 0; } + +/* + * __wrap_mmap -- mmap() mock + */ +void * +__wrap_mmap(void *__addr, size_t __len, int __prot, + int __flags, int __fd, off_t __offset) +{ + void *ret = mock_type(void *); + if (ret != (void *)MOCK_OK) + return MAP_FAILED; + + struct mmap_args *args = mock_type(struct mmap_args *); + + void *memptr = __real__test_malloc(__len); + + /* + * Save the address and length of the allocated memory + * in order to verify it later. + */ + args->addr = memptr; + args->len = __len; + + return memptr; +} + +/* + * __wrap_munmap -- munmap() mock + */ +int +__wrap_munmap(void *__addr, size_t __len) +{ + struct mmap_args *args = mock_type(struct mmap_args *); + assert_ptr_equal(__addr, args->addr); + assert_int_equal(__len, args->len); + + test_free(__addr); + + errno = mock_type(int); + if (errno) + return -1; + + return 0; +} diff --git a/tests/integration/common/mocks.h b/tests/integration/common/mocks.h index 7d71ac52a0..7fac29ad85 100644 --- a/tests/integration/common/mocks.h +++ b/tests/integration/common/mocks.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * mocks.h -- common mocks for integration tests @@ -62,6 +62,11 @@ struct posix_memalign_args { void *ptr; }; +struct mmap_args { + void *addr; + size_t len; +}; + #ifdef ON_DEMAND_PAGING_SUPPORTED int ibv_query_device_ex_mock(struct ibv_context *context, const struct ibv_query_device_ex_input *input, diff --git a/tests/integration/example-01-connection/CMakeLists.txt b/tests/integration/example-01-connection/CMakeLists.txt index 6dc472f6dc..4748610604 100644 --- a/tests/integration/example-01-connection/CMakeLists.txt +++ b/tests/integration/example-01-connection/CMakeLists.txt @@ -1,6 +1,6 @@ # # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2020, Intel Corporation +# Copyright 2020-2021, Intel Corporation # include(../../cmake/ctest_helpers.cmake) @@ -34,7 +34,7 @@ target_include_directories(${TARGET} PRIVATE set_target_properties(${TARGET} PROPERTIES - LINK_FLAGS "-Wl,--wrap=_test_malloc,--wrap=posix_memalign,--wrap=fprintf") + LINK_FLAGS "-Wl,--wrap=_test_malloc,--wrap=mmap,--wrap=munmap,--wrap=fprintf") target_compile_definitions(${TARGET} PUBLIC TEST_MOCK_MAIN diff --git a/tests/integration/example-01-connection/example-01-connection.c b/tests/integration/example-01-connection/example-01-connection.c index ec1c663364..8de59f29d5 100644 --- a/tests/integration/example-01-connection/example-01-connection.c +++ b/tests/integration/example-01-connection/example-01-connection.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * example-01-connection.c -- connection integration tests @@ -92,13 +92,14 @@ test_client__success(void **unused) expect_value(rdma_migrate_id, channel, MOCK_EVCH); will_return(rdma_migrate_id, MOCK_OK); - struct posix_memalign_args allocated_raw = {0}; - will_return(__wrap_posix_memalign, &allocated_raw); + struct mmap_args allocated_raw = {0}; + will_return(__wrap_mmap, MOCK_OK); + will_return(__wrap_mmap, &allocated_raw); expect_value(ibv_reg_mr, pd, MOCK_IBV_PD); expect_value(ibv_reg_mr, length, MOCK_RAW_SIZE); expect_value(ibv_reg_mr, access, IBV_ACCESS_LOCAL_WRITE); - will_return(ibv_reg_mr, &allocated_raw.ptr); + will_return(ibv_reg_mr, &allocated_raw.addr); will_return(ibv_reg_mr, MOCK_MR); expect_value(rdma_connect, id, &id); @@ -133,6 +134,8 @@ test_client__success(void **unused) /* configure mocks for rpma_conn_delete() */ expect_value(ibv_dereg_mr, mr, MOCK_MR); will_return(ibv_dereg_mr, MOCK_OK); + will_return(__wrap_munmap, &allocated_raw); + will_return(__wrap_munmap, MOCK_OK); expect_value(rdma_destroy_qp, id, &id); @@ -244,13 +247,14 @@ test_server__success(void **unused) expect_value(rdma_migrate_id, channel, MOCK_EVCH); will_return(rdma_migrate_id, MOCK_OK); - struct posix_memalign_args allocated_raw = {0}; - will_return(__wrap_posix_memalign, &allocated_raw); + struct mmap_args allocated_raw = {0}; + will_return(__wrap_mmap, MOCK_OK); + will_return(__wrap_mmap, &allocated_raw); expect_value(ibv_reg_mr, pd, MOCK_IBV_PD); expect_value(ibv_reg_mr, length, MOCK_RAW_SIZE); expect_value(ibv_reg_mr, access, IBV_ACCESS_LOCAL_WRITE); - will_return(ibv_reg_mr, &allocated_raw.ptr); + will_return(ibv_reg_mr, &allocated_raw.addr); will_return(ibv_reg_mr, MOCK_MR); /* configure mocks for rpma_conn_next_event() */ @@ -283,6 +287,8 @@ test_server__success(void **unused) /* configure mocks for rpma_conn_delete() */ expect_value(ibv_dereg_mr, mr, MOCK_MR); will_return(ibv_dereg_mr, MOCK_OK); + will_return(__wrap_munmap, &allocated_raw); + will_return(__wrap_munmap, MOCK_OK); expect_value(rdma_destroy_qp, id, &id); diff --git a/tests/integration/example-02-read-to-volatile/CMakeLists.txt b/tests/integration/example-02-read-to-volatile/CMakeLists.txt index 412724aca8..54b4ffb909 100644 --- a/tests/integration/example-02-read-to-volatile/CMakeLists.txt +++ b/tests/integration/example-02-read-to-volatile/CMakeLists.txt @@ -1,6 +1,6 @@ # # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2020, Intel Corporation +# Copyright 2020-2021, Intel Corporation # include(../../cmake/ctest_helpers.cmake) @@ -35,7 +35,7 @@ target_include_directories(${TARGET} PRIVATE set_target_properties(${TARGET} PROPERTIES - LINK_FLAGS "-Wl,--wrap=_test_malloc,--wrap=posix_memalign,--wrap=fprintf") + LINK_FLAGS "-Wl,--wrap=_test_malloc,--wrap=posix_memalign,--wrap=fprintf,--wrap=mmap,--wrap=munmap") target_compile_definitions(${TARGET} PUBLIC TEST_MOCK_MAIN diff --git a/tests/integration/example-02-read-to-volatile/example-02-read-to-volatile.c b/tests/integration/example-02-read-to-volatile/example-02-read-to-volatile.c index aef113be35..5301250717 100644 --- a/tests/integration/example-02-read-to-volatile/example-02-read-to-volatile.c +++ b/tests/integration/example-02-read-to-volatile/example-02-read-to-volatile.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * example-02-read-to-volatile.c -- 'read to volatile' integration tests @@ -107,13 +107,14 @@ test_client__success(void **unused) expect_value(rdma_migrate_id, channel, MOCK_EVCH); will_return(rdma_migrate_id, MOCK_OK); - struct posix_memalign_args allocated_raw = {0}; - will_return(__wrap_posix_memalign, &allocated_raw); + struct mmap_args allocated_raw = {0}; + will_return(__wrap_mmap, MOCK_OK); + will_return(__wrap_mmap, &allocated_raw); expect_value(ibv_reg_mr, pd, MOCK_IBV_PD); expect_value(ibv_reg_mr, length, MOCK_RAW_SIZE); expect_value(ibv_reg_mr, access, IBV_ACCESS_LOCAL_WRITE); - will_return(ibv_reg_mr, &allocated_raw.ptr); + will_return(ibv_reg_mr, &allocated_raw.addr); will_return(ibv_reg_mr, MOCK_MR_RAW); expect_value(rdma_connect, id, &Cm_id); @@ -180,6 +181,8 @@ test_client__success(void **unused) /* configure mocks for rpma_conn_delete() */ expect_value(ibv_dereg_mr, mr, MOCK_MR_RAW); will_return(ibv_dereg_mr, MOCK_OK); + will_return(__wrap_munmap, &allocated_raw); + will_return(__wrap_munmap, MOCK_OK); expect_value(rdma_destroy_qp, id, &Cm_id); @@ -304,13 +307,14 @@ test_server__success(void **unused) expect_value(rdma_migrate_id, channel, MOCK_EVCH); will_return(rdma_migrate_id, MOCK_OK); - struct posix_memalign_args allocated_raw = {0}; - will_return(__wrap_posix_memalign, &allocated_raw); + struct mmap_args allocated_raw = {0}; + will_return(__wrap_mmap, MOCK_OK); + will_return(__wrap_mmap, &allocated_raw); expect_value(ibv_reg_mr, pd, MOCK_IBV_PD); expect_value(ibv_reg_mr, length, MOCK_RAW_SIZE); expect_value(ibv_reg_mr, access, IBV_ACCESS_LOCAL_WRITE); - will_return(ibv_reg_mr, &allocated_raw.ptr); + will_return(ibv_reg_mr, &allocated_raw.addr); will_return(ibv_reg_mr, MOCK_MR_RAW); /* configure mocks for rpma_conn_next_event() */ @@ -343,6 +347,8 @@ test_server__success(void **unused) /* configure mocks for rpma_conn_delete() */ expect_value(ibv_dereg_mr, mr, MOCK_MR_RAW); will_return(ibv_dereg_mr, MOCK_OK); + will_return(__wrap_munmap, &allocated_raw); + will_return(__wrap_munmap, MOCK_OK); expect_value(rdma_destroy_qp, id, &Cm_id); diff --git a/tests/integration/example-04-write-to-persistent/CMakeLists.txt b/tests/integration/example-04-write-to-persistent/CMakeLists.txt index 4865f48183..7c3ccf5b15 100644 --- a/tests/integration/example-04-write-to-persistent/CMakeLists.txt +++ b/tests/integration/example-04-write-to-persistent/CMakeLists.txt @@ -1,6 +1,6 @@ # # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2020, Intel Corporation +# Copyright 2020-2021, Intel Corporation # include(../../cmake/ctest_helpers.cmake) @@ -35,7 +35,7 @@ target_include_directories(${TARGET} PRIVATE set_target_properties(${TARGET} PROPERTIES - LINK_FLAGS "-Wl,--wrap=_test_malloc,--wrap=posix_memalign,--wrap=fprintf") + LINK_FLAGS "-Wl,--wrap=_test_malloc,--wrap=posix_memalign,--wrap=fprintf,--wrap=mmap,--wrap=munmap") target_compile_definitions(${TARGET} PUBLIC TEST_MOCK_MAIN diff --git a/tests/integration/example-04-write-to-persistent/example-04-write-to-persistent.c b/tests/integration/example-04-write-to-persistent/example-04-write-to-persistent.c index 7bbd9f9f7b..7aef9b48e0 100644 --- a/tests/integration/example-04-write-to-persistent/example-04-write-to-persistent.c +++ b/tests/integration/example-04-write-to-persistent/example-04-write-to-persistent.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * example-04-write-to-persistent.c -- 'write to persistent' integration tests @@ -111,13 +111,14 @@ test_client__success(void **unused) will_return(rdma_migrate_id, MOCK_OK); /* allocate memory for the rpma_flush_apm_new */ - struct posix_memalign_args flush = {0}; - will_return(__wrap_posix_memalign, &flush); + struct mmap_args flush = {0}; + will_return(__wrap_mmap, MOCK_OK); + will_return(__wrap_mmap, &flush); expect_value(ibv_reg_mr, pd, MOCK_IBV_PD); expect_value(ibv_reg_mr, length, MOCK_RAW_SIZE); expect_value(ibv_reg_mr, access, IBV_ACCESS_LOCAL_WRITE); - will_return(ibv_reg_mr, &flush.ptr); + will_return(ibv_reg_mr, &flush.addr); will_return(ibv_reg_mr, MOCK_MR_FLUSH); expect_value(rdma_connect, id, &Cm_id); @@ -219,6 +220,8 @@ test_client__success(void **unused) /* configure mocks for rpma_conn_delete() */ expect_value(ibv_dereg_mr, mr, MOCK_MR_FLUSH); will_return(ibv_dereg_mr, MOCK_OK); + will_return(__wrap_munmap, &flush); + will_return(__wrap_munmap, MOCK_OK); expect_value(rdma_destroy_qp, id, &Cm_id); @@ -341,13 +344,14 @@ test_server__success(void **unused) expect_value(rdma_migrate_id, channel, MOCK_EVCH); will_return(rdma_migrate_id, MOCK_OK); - struct posix_memalign_args allocated_raw = {0}; - will_return(__wrap_posix_memalign, &allocated_raw); + struct mmap_args allocated_raw = {0}; + will_return(__wrap_mmap, MOCK_OK); + will_return(__wrap_mmap, &allocated_raw); expect_value(ibv_reg_mr, pd, MOCK_IBV_PD); expect_value(ibv_reg_mr, length, MOCK_RAW_SIZE); expect_value(ibv_reg_mr, access, IBV_ACCESS_LOCAL_WRITE); - will_return(ibv_reg_mr, &allocated_raw.ptr); + will_return(ibv_reg_mr, &allocated_raw.addr); will_return(ibv_reg_mr, MOCK_MR_RAW); /* configure mocks for rpma_conn_next_event() */ @@ -380,6 +384,8 @@ test_server__success(void **unused) /* configure mocks for rpma_conn_delete() */ expect_value(ibv_dereg_mr, mr, MOCK_MR_RAW); will_return(ibv_dereg_mr, MOCK_OK); + will_return(__wrap_munmap, &allocated_raw); + will_return(__wrap_munmap, MOCK_OK); expect_value(rdma_destroy_qp, id, &Cm_id); diff --git a/tests/unit/common/mocks-rpma-mr.c b/tests/unit/common/mocks-rpma-mr.c index fcea4da061..f49406c6cb 100644 --- a/tests/unit/common/mocks-rpma-mr.c +++ b/tests/unit/common/mocks-rpma-mr.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * mocks-rpma-mr.c -- librpma mr.c module mocks @@ -99,8 +99,14 @@ rpma_mr_dereg(struct rpma_mr_local **mr_ptr) assert_non_null(mr_ptr); check_expected_ptr(*mr_ptr); + int ret = mock_type(int); + /* XXX validate the errno handling */ + if (ret == RPMA_E_PROVIDER) + errno = mock_type(int); + *mr_ptr = NULL; - return 0; + + return ret; } /* diff --git a/tests/unit/common/mocks-stdlib.c b/tests/unit/common/mocks-stdlib.c index 51944d711b..d397db0517 100644 --- a/tests/unit/common/mocks-stdlib.c +++ b/tests/unit/common/mocks-stdlib.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * mocks-stdlib.c -- stdlib mocks @@ -7,9 +7,12 @@ #include #include +#include +#include #include "cmocka_headers.h" #include "mocks-stdlib.h" +#include "test-common.h" void *__real__test_malloc(size_t size); @@ -28,22 +31,45 @@ __wrap__test_malloc(size_t size) } /* - * __wrap_posix_memalign -- posix_memalign() mock + * __wrap_mmap -- mmap() mock */ -int -__wrap_posix_memalign(void **memptr, size_t alignment, size_t size) +void * +__wrap_mmap(void *__addr, size_t __len, int __prot, + int __flags, int __fd, off_t __offset) { - int err = mock_type(int); - if (err) - return err; + void *ret = mock_type(void *); + if (ret != (void *)MOCK_OK) + return MAP_FAILED; - struct posix_memalign_args *args = - mock_type(struct posix_memalign_args *); + struct mmap_args *args = mock_type(struct mmap_args *); - *memptr = __real__test_malloc(size); + void *memptr = __real__test_malloc(__len); - /* save the address of the allocated memory to verify it later */ - args->ptr = *memptr; + /* + * Save the address and length of the allocated memory + * in order to verify it later. + */ + args->addr = memptr; + args->len = __len; + + return memptr; +} + +/* + * __wrap_munmap -- munmap() mock + */ +int +__wrap_munmap(void *__addr, size_t __len) +{ + struct mmap_args *args = mock_type(struct mmap_args *); + assert_ptr_equal(__addr, args->addr); + assert_int_equal(__len, args->len); + + test_free(__addr); + + errno = mock_type(int); + if (errno) + return -1; return 0; } diff --git a/tests/unit/common/mocks-stdlib.h b/tests/unit/common/mocks-stdlib.h index 5840969a4e..d6fcfe8be5 100644 --- a/tests/unit/common/mocks-stdlib.h +++ b/tests/unit/common/mocks-stdlib.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * mocks-stdlib.h -- the stdlib mocks' header @@ -8,8 +8,9 @@ #ifndef MOCKS_STDLIB_H #define MOCKS_STDLIB_H -struct posix_memalign_args { - void *ptr; +struct mmap_args { + void *addr; + size_t len; }; #endif /* MOCKS_STDLIB_H */ diff --git a/tests/unit/conn/conn-new.c b/tests/unit/conn/conn-new.c index 3ac1cc515a..a72b53a89c 100644 --- a/tests/unit/conn/conn-new.c +++ b/tests/unit/conn/conn-new.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * conn-new.c -- the connection new/delete unit tests @@ -255,6 +255,38 @@ delete__flush_delete_E_PROVIDER(void **unused) assert_null(cstate->conn); } +/* + * delete__flush_delete_E_INVAL - rpma_flush_delete() + * fails with RPMA_E_INVAL + */ +static void +delete__flush_delete_E_INVAL(void **unused) +{ + /* + * Cmocka does not allow freeing an object in a test if the object was + * created in the setup step whereas even failing rpma_conn_delete() + * will deallocate the rpma_conn object. + */ + struct conn_test_state *cstate; + int ret = setup__conn_new((void **)&cstate); + assert_int_equal(ret, 0); + assert_non_null(cstate->conn); + + /* configure mocks: */ + will_return(rpma_flush_delete, RPMA_E_INVAL); + will_return_maybe(ibv_destroy_cq, EAGAIN); + will_return_maybe(ibv_destroy_comp_channel, MOCK_OK); + expect_value(rdma_destroy_id, id, MOCK_CM_ID); + will_return_maybe(rdma_destroy_id, MOCK_OK); + + /* run test */ + ret = rpma_conn_delete(&cstate->conn); + + /* verify the results */ + assert_int_equal(ret, RPMA_E_INVAL); + assert_null(cstate->conn); +} + /* * delete__destroy_cq_EAGAIN - ibv_destroy_cq() fails with EAGAIN */ @@ -439,6 +471,7 @@ static const struct CMUnitTest tests_new[] = { cmocka_unit_test(delete__conn_ptr_NULL), cmocka_unit_test(delete__conn_NULL), cmocka_unit_test(delete__flush_delete_E_PROVIDER), + cmocka_unit_test(delete__flush_delete_E_INVAL), cmocka_unit_test(delete__destroy_cq_EAGAIN), cmocka_unit_test(delete__destroy_cq_EAGAIN_subsequent_EIO), cmocka_unit_test(delete__destroy_comp_channel_EAGAIN), diff --git a/tests/unit/flush/CMakeLists.txt b/tests/unit/flush/CMakeLists.txt index e2f668266e..283cd580ab 100644 --- a/tests/unit/flush/CMakeLists.txt +++ b/tests/unit/flush/CMakeLists.txt @@ -1,6 +1,6 @@ # # SPDX-License-Identifier: BSD-3-Clause -# Copyright 2020, Intel Corporation +# Copyright 2020-2021, Intel Corporation # include(../../cmake/ctest_helpers.cmake) @@ -22,7 +22,7 @@ function(add_test_flush name) set_target_properties(${name} PROPERTIES - LINK_FLAGS "-Wl,--wrap=_test_malloc,--wrap=posix_memalign,--wrap=sysconf") + LINK_FLAGS "-Wl,--wrap=_test_malloc,--wrap=mmap,--wrap=munmap,--wrap=sysconf") add_test_generic(NAME ${name} TRACERS none) endfunction() diff --git a/tests/unit/flush/flush-common.c b/tests/unit/flush/flush-common.c index 1820284e93..6d58c26e1c 100644 --- a/tests/unit/flush/flush-common.c +++ b/tests/unit/flush/flush-common.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * flush-common.c -- common part of unit tests of the flush module @@ -18,20 +18,20 @@ int setup__flush_new(void **fstate_ptr) { + static struct flush_test_state fstate = {0}; + /* configure mocks */ will_return_always(__wrap__test_malloc, MOCK_OK); will_return(__wrap_sysconf, MOCK_OK); - will_return(__wrap_posix_memalign, MOCK_OK); - struct posix_memalign_args allocated_raw = {0}; - will_return(__wrap_posix_memalign, &allocated_raw); + will_return(__wrap_mmap, MOCK_OK); + will_return(__wrap_mmap, &fstate.allocated_raw); expect_value(rpma_mr_reg, peer, MOCK_PEER); expect_value(rpma_mr_reg, size, 8); expect_value(rpma_mr_reg, usage, RPMA_MR_USAGE_READ_DST); - will_return(rpma_mr_reg, &allocated_raw.ptr); + will_return(rpma_mr_reg, &fstate.allocated_raw.addr); will_return(rpma_mr_reg, MOCK_RPMA_MR_LOCAL); /* run test */ - static struct flush_test_state fstate = {0}; int ret = rpma_flush_new(MOCK_PEER, &fstate.flush); /* verify the results */ @@ -48,11 +48,15 @@ setup__flush_new(void **fstate_ptr) int teardown__flush_delete(void **fstate_ptr) { + struct flush_test_state *fstate = *fstate_ptr; + /* configure mock */ expect_value(rpma_mr_dereg, *mr_ptr, MOCK_RPMA_MR_LOCAL); + will_return(rpma_mr_dereg, MOCK_OK); + will_return(__wrap_munmap, &fstate->allocated_raw); + will_return(__wrap_munmap, MOCK_OK); /* delete the object */ - struct flush_test_state *fstate = *fstate_ptr; int ret = rpma_flush_delete(&fstate->flush); /* verify the results */ diff --git a/tests/unit/flush/flush-common.h b/tests/unit/flush/flush-common.h index 4c1b9f0274..4007dc4649 100644 --- a/tests/unit/flush/flush-common.h +++ b/tests/unit/flush/flush-common.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * flush-common.h -- header of the common part of unit tests @@ -9,6 +9,8 @@ #ifndef FLUSH_COMMON_H #define FLUSH_COMMON_H 1 +#include "mocks-stdlib.h" + #define MOCK_RPMA_MR_REMOTE (struct rpma_mr_remote *)0xC412 #define MOCK_RPMA_MR_LOCAL (struct rpma_mr_local *)0xC411 #define MOCK_REMOTE_OFFSET (size_t)0xC414 @@ -22,6 +24,7 @@ */ struct flush_test_state { struct rpma_flush *flush; + struct mmap_args allocated_raw; }; int setup__flush_new(void **fstate_ptr); diff --git a/tests/unit/flush/flush-new.c b/tests/unit/flush/flush-new.c index 6ca6e60170..458b680a1b 100644 --- a/tests/unit/flush/flush-new.c +++ b/tests/unit/flush/flush-new.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD-3-Clause -/* Copyright 2020, Intel Corporation */ +/* Copyright 2020-2021, Intel Corporation */ /* * flush-new.c -- unit tests of the flush module @@ -14,6 +14,7 @@ #include "flush-common.h" #include "mocks-stdlib.h" #include "test-common.h" +#include /* * new__malloc_ENOMEM -- malloc() fail with ENOMEM @@ -53,15 +54,15 @@ new__apm_sysconf_EINVAL(void **unused) } /* - * new__apm_posix_memalign_ENOMEM -- malloc() fail with ENOMEM + * new__apm_mmap_ENOMEM -- mmap() fails with ENOMEM */ static void -new__apm_posix_memalign_ENOMEM(void **unused) +new__apm_mmap_ENOMEM(void **unused) { /* configure mocks */ will_return_always(__wrap__test_malloc, MOCK_OK); will_return(__wrap_sysconf, MOCK_OK); - will_return(__wrap_posix_memalign, ENOMEM); + will_return(__wrap_mmap, MAP_FAILED); /* run test */ struct rpma_flush *flush = NULL; @@ -82,15 +83,17 @@ new__apm_mr_reg_RPMA_E_NOMEM(void **unused) will_return_always(__wrap__test_malloc, MOCK_OK); will_return(__wrap_sysconf, MOCK_OK); - will_return(__wrap_posix_memalign, MOCK_OK); - struct posix_memalign_args allocated_raw = {0}; - will_return(__wrap_posix_memalign, &allocated_raw); + struct mmap_args allocated_raw = {0}; + will_return(__wrap_mmap, MOCK_OK); + will_return(__wrap_mmap, &allocated_raw); expect_value(rpma_mr_reg, peer, MOCK_PEER); expect_value(rpma_mr_reg, size, 8); expect_value(rpma_mr_reg, usage, RPMA_MR_USAGE_READ_DST); - will_return(rpma_mr_reg, &allocated_raw.ptr); + will_return(rpma_mr_reg, &allocated_raw.addr); will_return(rpma_mr_reg, NULL); will_return(rpma_mr_reg, RPMA_E_NOMEM); + will_return(__wrap_munmap, &allocated_raw); + will_return(__wrap_munmap, EINVAL); /* run test */ struct rpma_flush *flush = NULL; @@ -111,15 +114,18 @@ new__apm_malloc_ENOMEM(void **unused) will_return(__wrap__test_malloc, MOCK_OK); will_return(__wrap_sysconf, MOCK_OK); - will_return(__wrap_posix_memalign, MOCK_OK); - struct posix_memalign_args allocated_raw = {0}; - will_return(__wrap_posix_memalign, &allocated_raw); + struct mmap_args allocated_raw = {0}; + will_return(__wrap_mmap, MOCK_OK); + will_return(__wrap_mmap, &allocated_raw); expect_value(rpma_mr_reg, peer, MOCK_PEER); expect_value(rpma_mr_reg, size, 8); expect_value(rpma_mr_reg, usage, RPMA_MR_USAGE_READ_DST); - will_return(rpma_mr_reg, &allocated_raw.ptr); + will_return(rpma_mr_reg, &allocated_raw.addr); will_return(rpma_mr_reg, MOCK_RPMA_MR_LOCAL); will_return(__wrap__test_malloc, ENOMEM); + will_return(rpma_mr_dereg, MOCK_OK); + will_return(__wrap_munmap, &allocated_raw); + will_return(__wrap_munmap, MOCK_OK); expect_value(rpma_mr_dereg, *mr_ptr, MOCK_RPMA_MR_LOCAL); /* run test */ @@ -143,18 +149,71 @@ new__apm_success(void **unused) */ } +/* + * delete__apm_dereg_E_PROVIDER -- rpma_mr_dereg() failed with RPMA_E_PROVIDER + */ +static void +delete__apm_dereg_E_PROVIDER(void **unused) +{ + struct flush_test_state *fstate; + + setup__flush_new((void **)&fstate); + + /* configure mocks */ + expect_value(rpma_mr_dereg, *mr_ptr, MOCK_RPMA_MR_LOCAL); + will_return(__wrap_munmap, &fstate->allocated_raw); + will_return_maybe(__wrap_munmap, MOCK_OK); + will_return(rpma_mr_dereg, RPMA_E_PROVIDER); + will_return(rpma_mr_dereg, MOCK_ERRNO); + + /* delete the object */ + int ret = rpma_flush_delete(&fstate->flush); + + /* verify the results */ + assert_int_equal(ret, RPMA_E_PROVIDER); + assert_null(fstate->flush); +} + +/* + * delete__apm_munmap_E_INVAL -- munmap() failed with EINVAL + */ +static void +delete__apm_munmap_E_INVAL(void **unused) +{ + struct flush_test_state *fstate; + + setup__flush_new((void **)&fstate); + + /* configure mocks */ + expect_value(rpma_mr_dereg, *mr_ptr, MOCK_RPMA_MR_LOCAL); + will_return_maybe(rpma_mr_dereg, MOCK_OK); + will_return(__wrap_munmap, &fstate->allocated_raw); + will_return(__wrap_munmap, EINVAL); + + /* delete the object */ + int ret = rpma_flush_delete(&fstate->flush); + + /* verify the results */ + assert_int_equal(ret, RPMA_E_INVAL); + assert_null(fstate->flush); +} + int main(int argc, char *argv[]) { const struct CMUnitTest tests[] = { - /* rpma__new() unit tests */ + /* rpma_flush_new() unit tests */ cmocka_unit_test(new__malloc_ENOMEM), cmocka_unit_test(new__apm_sysconf_EINVAL), - cmocka_unit_test(new__apm_posix_memalign_ENOMEM), + cmocka_unit_test(new__apm_mmap_ENOMEM), cmocka_unit_test(new__apm_mr_reg_RPMA_E_NOMEM), cmocka_unit_test(new__apm_malloc_ENOMEM), cmocka_unit_test_setup_teardown(new__apm_success, setup__flush_new, teardown__flush_delete), + + /* rpma_flush_delete() unit tests */ + cmocka_unit_test(delete__apm_dereg_E_PROVIDER), + cmocka_unit_test(delete__apm_munmap_E_INVAL), }; return cmocka_run_group_tests(tests, NULL, NULL);