From 21046f799b2c70c39d285d7d70fd9059fcf6be21 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 29 Nov 2022 15:15:01 -0500 Subject: [PATCH] Fix #176, implement mpool test cases Implement test cases to cover all mpool implementation. There are a few branches which are justifiably unreachable. --- mpool/inc/v7_mpool.h | 31 + mpool/src/v7_mpool.c | 8 +- mpool/src/v7_mpool_bblocks.c | 25 +- mpool/src/v7_mpool_internal.h | 3 + mpool/ut-coverage/test_bplib_mpool.h | 19 + mpool/ut-coverage/test_bplib_mpool_setup.c | 87 ++ mpool/ut-coverage/test_bplib_v7_mpool.c | 948 +++++++++++++++++- .../ut-coverage/test_bplib_v7_mpool_bblocks.c | 281 +++++- mpool/ut-coverage/test_bplib_v7_mpool_flows.c | 286 +++++- mpool/ut-coverage/test_bplib_v7_mpool_job.c | 159 ++- mpool/ut-coverage/test_bplib_v7_mpool_ref.c | 115 ++- mpool/ut-coverage/test_bplib_v7_mpstream.c | 153 ++- 12 files changed, 2066 insertions(+), 49 deletions(-) diff --git a/mpool/inc/v7_mpool.h b/mpool/inc/v7_mpool.h index 0b30fe5c..107218a3 100644 --- a/mpool/inc/v7_mpool.h +++ b/mpool/inc/v7_mpool.h @@ -359,6 +359,18 @@ void bplib_mpool_init_secondary_link(bplib_mpool_block_t *base_block, bplib_mpoo */ bplib_mpool_block_t *bplib_mpool_get_block_from_link(bplib_mpool_block_t *lblk); +/** + * @brief Gets the offset of the block user content section + * + * Some block types have an area that may be used for general purpose data storage. + * The size and offset of this area depends on the block type. This gets the offset + * of the start of the area for the given a block type. + * + * @param bt Block type + * @return size_t + */ +size_t bplib_mpool_get_user_data_offset_by_blocktype(bplib_mpool_blocktype_t bt); + /** * @brief Gets the capacity (maximum size) of the generic data block * @@ -567,6 +579,18 @@ int bplib_mpool_foreach_item_in_list(bplib_mpool_block_t *list, bool always_remo bplib_mpool_block_t *bplib_mpool_search_list(const bplib_mpool_block_t *list, bplib_mpool_callback_func_t match_fn, void *match_arg); +/** + * @brief Garbage collection routine + * + * Processes the list of recycled blocks and performing any additional cleanup work + * + * @param pool The mpool object + * @param limit The maximum number of entries to process + * + * @returns The number of blocks collected + */ +uint32_t bplib_mpool_collect_blocks(bplib_mpool_t *pool, uint32_t limit); + /** * @brief Run basic maintenance on the memory pool * @@ -625,6 +649,13 @@ size_t bplib_mpool_query_mem_current_use(bplib_mpool_t *pool); */ size_t bplib_mpool_query_mem_max_use(bplib_mpool_t *pool); +/** + * @brief Initializes the global lock table + * + * Must be called once per process using bplib (not per instance). + */ +void bplib_mpool_lock_init(void); + /* DEBUG/TEST verification routines */ void bplib_mpool_debug_scan(bplib_mpool_t *pool); diff --git a/mpool/src/v7_mpool.c b/mpool/src/v7_mpool.c index 51b47fd9..2acf057d 100644 --- a/mpool/src/v7_mpool.c +++ b/mpool/src/v7_mpool.c @@ -745,7 +745,7 @@ int bplib_mpool_list_iter_goto_last(const bplib_mpool_block_t *list, bplib_mpool *-----------------------------------------------------------------*/ int bplib_mpool_list_iter_forward(bplib_mpool_list_iter_t *iter) { - if (bplib_mpool_is_list_head(iter->pending_entry)) + if (iter->pending_entry == NULL || bplib_mpool_is_list_head(iter->pending_entry)) { iter->position = NULL; return BP_ERROR; @@ -763,7 +763,7 @@ int bplib_mpool_list_iter_forward(bplib_mpool_list_iter_t *iter) *-----------------------------------------------------------------*/ int bplib_mpool_list_iter_reverse(bplib_mpool_list_iter_t *iter) { - if (bplib_mpool_is_list_head(iter->pending_entry)) + if (iter->pending_entry == NULL || bplib_mpool_is_list_head(iter->pending_entry)) { iter->position = NULL; return BP_ERROR; @@ -1136,7 +1136,9 @@ void bplib_mpool_debug_scan(bplib_mpool_t *pool) memset(count_by_type, 0, sizeof(count_by_type)); count_invalid = 0; pchunk = &pool->admin_block; - for (i = 0; i < admin->num_bufs_total; ++i) + + /* Note that num_bufs_total does not include the admin block (0) */ + for (i = 0; i <= admin->num_bufs_total; ++i) { if (i == 0) { diff --git a/mpool/src/v7_mpool_bblocks.c b/mpool/src/v7_mpool_bblocks.c index 18c77320..2461c1f4 100644 --- a/mpool/src/v7_mpool_bblocks.c +++ b/mpool/src/v7_mpool_bblocks.c @@ -122,17 +122,19 @@ void bplib_mpool_bblock_canonical_init(bplib_mpool_block_t *base_block, bplib_mp * Function: bplib_mpool_bblock_primary_alloc * *-----------------------------------------------------------------*/ -bplib_mpool_block_t *bplib_mpool_bblock_primary_alloc(bplib_mpool_t *pool, uint32_t magic_number, void *init_arg, uint8_t priority, uint64_t timeout) +bplib_mpool_block_t *bplib_mpool_bblock_primary_alloc(bplib_mpool_t *pool, uint32_t magic_number, void *init_arg, + uint8_t priority, uint64_t timeout) { bplib_mpool_block_content_t *result; bplib_mpool_lock_t *lock; - bool within_timeout; + bool within_timeout; - lock = bplib_mpool_lock_resource(pool); + lock = bplib_mpool_lock_resource(pool); within_timeout = true; while (true) { - result = bplib_mpool_alloc_block_internal(pool, bplib_mpool_blocktype_primary, magic_number, init_arg, priority); + result = + bplib_mpool_alloc_block_internal(pool, bplib_mpool_blocktype_primary, magic_number, init_arg, priority); if (result != NULL || !within_timeout) { break; @@ -156,7 +158,8 @@ bplib_mpool_block_t *bplib_mpool_bblock_canonical_alloc(bplib_mpool_t *pool, uin bplib_mpool_lock_t *lock; lock = bplib_mpool_lock_resource(pool); - result = bplib_mpool_alloc_block_internal(pool, bplib_mpool_blocktype_canonical, magic_number, init_arg, BPLIB_MPOOL_ALLOC_PRI_MED); + result = bplib_mpool_alloc_block_internal(pool, bplib_mpool_blocktype_canonical, magic_number, init_arg, + BPLIB_MPOOL_ALLOC_PRI_MED); bplib_mpool_lock_release(lock); return (bplib_mpool_block_t *)result; @@ -172,9 +175,9 @@ bplib_mpool_block_t *bplib_mpool_bblock_cbor_alloc(bplib_mpool_t *pool) bplib_mpool_block_content_t *result; bplib_mpool_lock_t *lock; - lock = bplib_mpool_lock_resource(pool); - result = - bplib_mpool_alloc_block_internal(pool, bplib_mpool_blocktype_generic, MPOOL_CACHE_CBOR_DATA_SIGNATURE, NULL, BPLIB_MPOOL_ALLOC_PRI_MED); + lock = bplib_mpool_lock_resource(pool); + result = bplib_mpool_alloc_block_internal(pool, bplib_mpool_blocktype_generic, MPOOL_CACHE_CBOR_DATA_SIGNATURE, + NULL, BPLIB_MPOOL_ALLOC_PRI_MED); bplib_mpool_lock_release(lock); return (bplib_mpool_block_t *)result; @@ -258,7 +261,11 @@ size_t bplib_mpool_bblock_cbor_export(bplib_mpool_block_t *list, void *out_ptr, blk = list; while (data_left > 0) { - blk = bplib_mpool_get_next_block(blk); + blk = bplib_mpool_get_next_block(blk); + if (blk == list) + { + break; + } src_ptr = bplib_mpool_bblock_cbor_cast(blk); if (src_ptr == NULL) { diff --git a/mpool/src/v7_mpool_internal.h b/mpool/src/v7_mpool_internal.h index b5ee53e1..f185c389 100644 --- a/mpool/src/v7_mpool_internal.h +++ b/mpool/src/v7_mpool_internal.h @@ -344,6 +344,9 @@ const bplib_mpool_block_content_t *bplib_mpool_get_block_content_const(const bpl /* similar to bplib_mpool_get_block_content() but also dereferences any ref blocks */ bplib_mpool_block_content_t *bplib_mpool_block_dereference_content(bplib_mpool_block_t *cb); +void bplib_mpool_init_base_object(bplib_mpool_block_header_t *block_hdr, uint16_t user_content_length, + uint32_t content_type_signature); + bplib_mpool_block_content_t *bplib_mpool_alloc_block_internal(bplib_mpool_t *pool, bplib_mpool_blocktype_t blocktype, uint32_t content_type_signature, void *init_arg, uint8_t priority); diff --git a/mpool/ut-coverage/test_bplib_mpool.h b/mpool/ut-coverage/test_bplib_mpool.h index 23c479f8..798b4554 100644 --- a/mpool/ut-coverage/test_bplib_mpool.h +++ b/mpool/ut-coverage/test_bplib_mpool.h @@ -23,6 +23,25 @@ #include "utstubs.h" #include "uttest.h" +#include "v7_mpool_internal.h" + +typedef struct +{ + bplib_mpool_t pool; + bplib_mpool_block_content_t blk[3]; +} UT_bplib_mpool_buf_t; + +/* helper functions used in multiple tests */ +void UT_AltHandler_PointerReturn(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context); +int test_bplib_mpool_callback_stub(void *arg, bplib_mpool_block_t *blk); +void test_make_singleton_link(bplib_mpool_t *parent_pool, bplib_mpool_block_t *b); +void test_setup_mpblock(bplib_mpool_t *pool, bplib_mpool_block_content_t *b, bplib_mpool_blocktype_t blktype, + uint32 sig); +void test_setup_allocation(bplib_mpool_t *pool, bplib_mpool_block_content_t *db, bplib_mpool_block_content_t *apib); + +void TestBplibMpool_ResetTestEnvironment(void); + +/* Registration functions */ void TestBplibMpoolBBlocks_Register(void); void TestBplibMpoolFlows_Register(void); void TestBplibMpoolJob_Register(void); diff --git a/mpool/ut-coverage/test_bplib_mpool_setup.c b/mpool/ut-coverage/test_bplib_mpool_setup.c index ac3a75f0..4bc7af90 100644 --- a/mpool/ut-coverage/test_bplib_mpool_setup.c +++ b/mpool/ut-coverage/test_bplib_mpool_setup.c @@ -21,6 +21,93 @@ */ #include "test_bplib_mpool.h" +void TestBplibMpool_ResetTestEnvironment(void) +{ + UT_ResetState(0); +} + +void UT_AltHandler_PointerReturn(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context) +{ + UT_Stub_SetReturnValue(FuncKey, UserObj); +} + +int test_bplib_mpool_callback_stub(void *arg, bplib_mpool_block_t *blk) +{ + return UT_DEFAULT_IMPL(test_bplib_mpool_callback_stub); +} + +void test_make_singleton_link(bplib_mpool_t *parent_pool, bplib_mpool_block_t *b) +{ + if (parent_pool != NULL) + { + b->parent_offset = ((uintptr_t)b - (uintptr_t)parent_pool) / sizeof(bplib_mpool_block_content_t); + } + else + { + b->parent_offset = 0; + } + + b->next = b; + b->prev = b; +} + +void test_setup_mpblock(bplib_mpool_t *pool, bplib_mpool_block_content_t *b, bplib_mpool_blocktype_t blktype, + uint32 sig) +{ + b->header.base_link.type = blktype; + b->header.content_type_signature = sig; + test_make_singleton_link(pool, &b->header.base_link); + + /* + * Need to also initialize the fields within the content part, this calls the real internal function to do so. + * It is done here because it is needed to be valid more often than not; test cases may unset/corrupt fields + * if there is a specific path to target + */ + memset(&b->u, 0, sizeof(b->u)); + switch (blktype) + { + case bplib_mpool_blocktype_primary: + bplib_mpool_bblock_primary_init(&b->header.base_link, &b->u.primary.pblock); + break; + case bplib_mpool_blocktype_canonical: + bplib_mpool_bblock_canonical_init(&b->header.base_link, &b->u.canonical.cblock); + break; + case bplib_mpool_blocktype_admin: + bplib_mpool_subq_init(&b->header.base_link, &b->u.admin.free_blocks); + bplib_mpool_subq_init(&b->header.base_link, &b->u.admin.recycle_blocks); + bplib_mpool_init_list_head(&b->header.base_link, &b->u.admin.active_list); + break; + case bplib_mpool_blocktype_flow: + bplib_mpool_flow_init(&b->header.base_link, &b->u.flow.fblock); + break; + + default: + break; + } +} + +void test_setup_allocation(bplib_mpool_t *pool, bplib_mpool_block_content_t *db, bplib_mpool_block_content_t *apib) +{ + bplib_mpool_block_admin_content_t *admin; + void *api_content; + + test_setup_mpblock(pool, &pool->admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(pool, db, bplib_mpool_blocktype_undefined, 0); + if (apib != NULL) + { + test_setup_mpblock(pool, apib, bplib_mpool_blocktype_api, 0); + api_content = &apib->u; + } + else + { + api_content = NULL; + } + + admin = bplib_mpool_get_admin(pool); + bplib_mpool_subq_push_single(&admin->free_blocks, &db->header.base_link); + UT_SetHandlerFunction(UT_KEY(bplib_rbt_search_generic), UT_AltHandler_PointerReturn, api_content); +} + void UtTest_Setup(void) { TestBplibMpoolBase_Register(); diff --git a/mpool/ut-coverage/test_bplib_v7_mpool.c b/mpool/ut-coverage/test_bplib_v7_mpool.c index 1f8e4dba..908e2f32 100644 --- a/mpool/ut-coverage/test_bplib_v7_mpool.c +++ b/mpool/ut-coverage/test_bplib_v7_mpool.c @@ -23,6 +23,952 @@ #include "utstubs.h" #include "uttest.h" +#include "test_bplib_mpool.h" #include "v7_mpool.h" -void TestBplibMpoolBase_Register(void) {} +const uint32 UT_TESTBLOCKTYPE_SIG = 0x5f33c01a; + +void UT_AltHandler_PointerReturnForSignature(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context) +{ + bp_val_t RefSig = UT_Hook_GetArgValueByName(Context, "search_key_value", bp_val_t); + + if (RefSig == UT_TESTBLOCKTYPE_SIG) + { + UserObj = NULL; + } + + UT_Stub_SetReturnValue(FuncKey, UserObj); +} + +void test_bplib_mpool_lock_init(void) +{ + /* Test function for: + * void bplib_mpool_lock_init(void) + */ + + UT_SetDefaultReturnValue(UT_KEY(bplib_os_createlock), 1); + + /* Call it twice, first time should init, second time should skip init */ + UtAssert_VOIDCALL(bplib_mpool_lock_init()); + UtAssert_VOIDCALL(bplib_mpool_lock_init()); +} + +void test_bplib_mpool_lock_prepare(void) +{ + /* Test function for: + * bplib_mpool_lock_t *bplib_mpool_lock_prepare(void *resource_addr) + */ + + UtAssert_NOT_NULL(bplib_mpool_lock_prepare(NULL)); +} + +void test_bplib_mpool_lock_resource(void) +{ + /* Test function for: + * bplib_mpool_lock_t *bplib_mpool_lock_resource(void *resource_addr) + */ + + UtAssert_NOT_NULL(bplib_mpool_lock_resource(NULL)); +} + +void test_bplib_mpool_lock_wait(void) +{ + /* Test function for: + * bool bplib_mpool_lock_wait(bplib_mpool_lock_t *lock, uint64_t until_dtntime) + */ + + bplib_mpool_lock_t *lock = bplib_mpool_lock_prepare(NULL); + + UT_SetDefaultReturnValue(UT_KEY(bplib_os_get_dtntime_ms), 1000); + UtAssert_BOOL_FALSE(bplib_mpool_lock_wait(lock, 0)); + UtAssert_BOOL_TRUE(bplib_mpool_lock_wait(lock, 5000)); + UT_SetDefaultReturnValue(UT_KEY(bplib_os_wait_until_ms), BP_TIMEOUT); + UtAssert_BOOL_FALSE(bplib_mpool_lock_wait(lock, 5000)); +} + +void test_bplib_mpool_block_from_external_id(void) +{ + /* Test function for: + * bplib_mpool_block_t *bplib_mpool_block_from_external_id(bplib_mpool_t *pool, bp_handle_t handle) + */ + UT_bplib_mpool_buf_t buf; + bp_handle_t id1; + bp_handle_t id2; + + memset(&buf, 0, sizeof(buf)); + + UtAssert_NULL(bplib_mpool_block_from_external_id(&buf.pool, BP_INVALID_HANDLE)); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_primary, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_primary, 0); + + UtAssert_BOOL_TRUE(bp_handle_is_valid(id1 = bplib_mpool_get_external_id(&buf.blk[0].header.base_link))); + UtAssert_BOOL_TRUE(bp_handle_is_valid(id2 = bplib_mpool_get_external_id(&buf.blk[1].header.base_link))); + UtAssert_NULL(bplib_mpool_block_from_external_id(&buf.pool, id1)); + UtAssert_NULL(bplib_mpool_block_from_external_id(&buf.pool, id2)); + + buf.pool.admin_block.u.admin.num_bufs_total = 3; + UtAssert_ADDRESS_EQ(bplib_mpool_block_from_external_id(&buf.pool, id1), &buf.blk[0].header.base_link); + UtAssert_ADDRESS_EQ(bplib_mpool_block_from_external_id(&buf.pool, id2), &buf.blk[1].header.base_link); +} + +void test_bplib_mpool_get_block_from_link(void) +{ + /* Test function for: + * bplib_mpool_block_t *bplib_mpool_get_block_from_link(bplib_mpool_block_t *lblk) + */ + struct + { + bplib_mpool_block_t base_blk; + uint8_t unused1[3]; + bplib_mpool_block_t sublink_blk1; + uint8_t unused2[7]; + bplib_mpool_block_t sublink_blk2; + } test_block; + + memset(&test_block, 0, sizeof(test_block)); + + UtAssert_NULL(bplib_mpool_get_block_from_link(NULL)); + UtAssert_ADDRESS_EQ(bplib_mpool_get_block_from_link(&test_block.base_blk), &test_block.base_blk); + + test_block.base_blk.type = bplib_mpool_blocktype_undefined; + bplib_mpool_init_list_head(&test_block.base_blk, &test_block.sublink_blk1); + bplib_mpool_init_list_head(&test_block.base_blk, &test_block.sublink_blk2); + + UtAssert_ADDRESS_EQ(bplib_mpool_get_block_from_link(&test_block.sublink_blk1), &test_block.base_blk); + UtAssert_ADDRESS_EQ(bplib_mpool_get_block_from_link(&test_block.sublink_blk2), &test_block.base_blk); + + test_block.sublink_blk2.parent_offset = 0; /* Invalid, but forces check path */ + UtAssert_ADDRESS_EQ(bplib_mpool_get_block_from_link(&test_block.sublink_blk2), &test_block.sublink_blk2); + + test_block.base_blk.type = bplib_mpool_blocktype_admin; + UtAssert_ADDRESS_EQ(bplib_mpool_get_block_from_link(&test_block.base_blk), &test_block.base_blk); +} + +void test_bplib_mpool_get_block_content(void) +{ + /* Test function for: + * bplib_mpool_block_content_t *bplib_mpool_get_block_content(bplib_mpool_block_t *cb) + * const bplib_mpool_block_content_t *bplib_mpool_get_block_content_const(const bplib_mpool_block_t *cb) + * + * NOTE: these two functions are identical except for the const-ness of input and output pointers. + */ + bplib_mpool_block_content_t my_block; + + memset(&my_block, 0, sizeof(my_block)); + + UtAssert_NULL(bplib_mpool_get_block_content(NULL)); + UtAssert_NULL(bplib_mpool_get_block_content_const(NULL)); + UtAssert_NULL(bplib_mpool_get_block_content(&my_block.header.base_link)); + UtAssert_NULL(bplib_mpool_get_block_content_const(&my_block.header.base_link)); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_primary, 0); + UtAssert_ADDRESS_EQ(bplib_mpool_get_block_content(&my_block.header.base_link), &my_block); + UtAssert_ADDRESS_EQ(bplib_mpool_get_block_content_const(&my_block.header.base_link), &my_block); +} + +void test_bplib_mpool_block_dereference_content(void) +{ + /* Test function for: + * bplib_mpool_block_content_t *bplib_mpool_block_dereference_content(bplib_mpool_block_t *cb) + */ + + bplib_mpool_block_content_t my_block; + bplib_mpool_block_content_t my_ref; + + UtAssert_NULL(bplib_mpool_block_dereference_content(NULL)); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_primary, 0); + UtAssert_ADDRESS_EQ(bplib_mpool_block_dereference_content(&my_block.header.base_link), &my_block); + + test_setup_mpblock(NULL, &my_ref, bplib_mpool_blocktype_ref, 0); + my_ref.u.ref.pref_target = &my_block; + UtAssert_ADDRESS_EQ(bplib_mpool_block_dereference_content(&my_ref.header.base_link), &my_block); +} + +void test_bplib_mpool_get_user_data_offset_by_blocktype(void) +{ + /* Test function for: + * size_t bplib_mpool_get_user_data_offset_by_blocktype(bplib_mpool_blocktype_t bt) + */ + + UtAssert_UINT32_EQ(bplib_mpool_get_user_data_offset_by_blocktype(bplib_mpool_blocktype_undefined), SIZE_MAX); + UtAssert_UINT32_EQ(bplib_mpool_get_user_data_offset_by_blocktype(bplib_mpool_blocktype_max), SIZE_MAX); + UtAssert_UINT32_EQ(bplib_mpool_get_user_data_offset_by_blocktype(bplib_mpool_blocktype_generic), 0); +} + +void test_bplib_mpool_get_generic_data_capacity(void) +{ + /* Test function for: + * size_t bplib_mpool_get_generic_data_capacity(const bplib_mpool_block_t *cb) + */ + bplib_mpool_block_content_t my_block; + + memset(&my_block, 0, sizeof(my_block)); + + UtAssert_ZERO(bplib_mpool_get_generic_data_capacity(&my_block.header.base_link)); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_generic, 0); + UtAssert_UINT32_EQ(bplib_mpool_get_generic_data_capacity(&my_block.header.base_link), + sizeof(bplib_mpool_block_buffer_t)); +} + +void test_bplib_mpool_init_secondary_link(void) +{ + /* Test function for: + * void bplib_mpool_init_secondary_link(bplib_mpool_block_t *base_block, bplib_mpool_block_t *secondary_link, + * bplib_mpool_blocktype_t block_type) + */ + bplib_mpool_block_content_t my_block; + + memset(&my_block, 0, sizeof(my_block)); + + UtAssert_VOIDCALL( + bplib_mpool_init_secondary_link(NULL, &my_block.header.base_link, bplib_mpool_blocktype_secondary_generic)); + UtAssert_VOIDCALL(bplib_mpool_init_secondary_link( + &my_block.header.base_link, &my_block.u.primary.pblock.cblock_list, bplib_mpool_blocktype_list_head)); +} + +void test_bplib_mpool_init_list_head(void) +{ + /* Test function for: + * void bplib_mpool_init_list_head(bplib_mpool_block_t *base_block, bplib_mpool_block_t *list_head) + */ + bplib_mpool_block_content_t my_block; + + memset(&my_block, 0, sizeof(my_block)); + + UtAssert_VOIDCALL(bplib_mpool_init_list_head(&my_block.header.base_link, &my_block.u.primary.pblock.cblock_list)); +} + +void test_bplib_mpool_insert_after(void) +{ + /* Test function for: + * void bplib_mpool_insert_after(bplib_mpool_block_t *list, bplib_mpool_block_t *node) + */ + struct + { + bplib_mpool_block_t base_blk; + bplib_mpool_block_t head_blk; + } list; + bplib_mpool_block_t content[2]; + + memset(&list, 0, sizeof(list)); + memset(&content, 0, sizeof(content)); + test_make_singleton_link(NULL, &content[0]); + test_make_singleton_link(NULL, &content[1]); + + UtAssert_VOIDCALL(bplib_mpool_init_list_head(&list.base_blk, &list.head_blk)); + + UtAssert_VOIDCALL(bplib_mpool_insert_after(&list.head_blk, &content[0])); + UtAssert_VOIDCALL(bplib_mpool_insert_after(&list.head_blk, &content[1])); + + UtAssert_ADDRESS_EQ(list.head_blk.prev, &content[0]); + UtAssert_ADDRESS_EQ(list.head_blk.next, &content[1]); + UtAssert_ADDRESS_EQ(content[1].prev, &list.head_blk); + UtAssert_ADDRESS_EQ(content[1].next, &content[0]); + UtAssert_ADDRESS_EQ(content[0].prev, &content[1]); + UtAssert_ADDRESS_EQ(content[0].next, &list.head_blk); +} + +void test_bplib_mpool_insert_before(void) +{ + /* Test function for: + * void bplib_mpool_insert_before(bplib_mpool_block_t *list, bplib_mpool_block_t *node) + */ + + struct + { + bplib_mpool_block_t base_blk; + bplib_mpool_block_t head_blk; + } list; + bplib_mpool_block_t content[2]; + + memset(&list, 0, sizeof(list)); + memset(&content, 0, sizeof(content)); + test_make_singleton_link(NULL, &content[0]); + test_make_singleton_link(NULL, &content[1]); + + UtAssert_VOIDCALL(bplib_mpool_init_list_head(&list.base_blk, &list.head_blk)); + + UtAssert_VOIDCALL(bplib_mpool_insert_before(&list.head_blk, &content[0])); + UtAssert_VOIDCALL(bplib_mpool_insert_before(&list.head_blk, &content[1])); + + UtAssert_ADDRESS_EQ(list.head_blk.prev, &content[1]); + UtAssert_ADDRESS_EQ(list.head_blk.next, &content[0]); + UtAssert_ADDRESS_EQ(content[0].prev, &list.head_blk); + UtAssert_ADDRESS_EQ(content[0].next, &content[1]); + UtAssert_ADDRESS_EQ(content[1].prev, &content[0]); + UtAssert_ADDRESS_EQ(content[1].next, &list.head_blk); +} + +void test_bplib_mpool_extract_node(void) +{ + /* Test function for: + * void bplib_mpool_extract_node(bplib_mpool_block_t *node) + */ + + struct + { + bplib_mpool_block_t base_blk; + bplib_mpool_block_t head_blk; + } list; + bplib_mpool_block_t content[2]; + + memset(&list, 0, sizeof(list)); + memset(&content, 0, sizeof(content)); + test_make_singleton_link(NULL, &content[0]); + test_make_singleton_link(NULL, &content[1]); + + UtAssert_VOIDCALL(bplib_mpool_init_list_head(&list.base_blk, &list.head_blk)); + + UtAssert_VOIDCALL(bplib_mpool_insert_before(&list.head_blk, &content[0])); + UtAssert_VOIDCALL(bplib_mpool_insert_before(&list.head_blk, &content[1])); + UtAssert_VOIDCALL(bplib_mpool_extract_node(&content[0])); + + UtAssert_BOOL_TRUE(bplib_mpool_is_link_attached(&content[1])); + UtAssert_BOOL_TRUE(bplib_mpool_is_link_unattached(&content[0])); + + UtAssert_VOIDCALL(bplib_mpool_extract_node(&content[1])); + UtAssert_BOOL_TRUE(bplib_mpool_is_empty_list_head(&list.head_blk)); + UtAssert_BOOL_TRUE(bplib_mpool_is_link_unattached(&content[1])); + UtAssert_BOOL_TRUE(bplib_mpool_is_link_unattached(&content[0])); +} + +void test_bplib_mpool_merge_list(void) +{ + /* Test function for: + * void bplib_mpool_merge_list(bplib_mpool_block_t *dest, bplib_mpool_block_t *src) + */ + struct + { + bplib_mpool_block_t base_blk; + bplib_mpool_block_t head_blk; + } list[2]; + bplib_mpool_block_t content[2]; + bplib_mpool_block_t *blk; + + memset(&list, 0, sizeof(list)); + memset(&content, 0, sizeof(content)); + test_make_singleton_link(NULL, &content[0]); + test_make_singleton_link(NULL, &content[1]); + + UtAssert_VOIDCALL(bplib_mpool_init_list_head(&list[0].base_blk, &list[0].head_blk)); + UtAssert_VOIDCALL(bplib_mpool_init_list_head(&list[1].base_blk, &list[1].head_blk)); + UtAssert_VOIDCALL(bplib_mpool_insert_before(&list[0].head_blk, &content[0])); + UtAssert_VOIDCALL(bplib_mpool_insert_before(&list[1].head_blk, &content[1])); + + UtAssert_VOIDCALL(bplib_mpool_merge_list(&list[1].head_blk, &list[0].head_blk)); + + /* Note "merge" puts everything into one list, including both heads */ + /* follow the links forward and backward */ + blk = &list[1].head_blk; + + UtAssert_ADDRESS_EQ(blk = bplib_mpool_get_next_block(blk), &content[1]); + UtAssert_ADDRESS_EQ(blk = bplib_mpool_get_next_block(blk), &list[0].head_blk); + UtAssert_ADDRESS_EQ(blk = bplib_mpool_get_next_block(blk), &content[0]); + UtAssert_ADDRESS_EQ(blk = bplib_mpool_get_next_block(blk), &list[1].head_blk); + + UtAssert_ADDRESS_EQ(blk = bplib_mpool_get_prev_block(blk), &content[0]); + UtAssert_ADDRESS_EQ(blk = bplib_mpool_get_prev_block(blk), &list[0].head_blk); + UtAssert_ADDRESS_EQ(blk = bplib_mpool_get_prev_block(blk), &content[1]); + UtAssert_ADDRESS_EQ(blk = bplib_mpool_get_prev_block(blk), &list[1].head_blk); +} + +void test_bplib_mpool_get_user_content_size(void) +{ + /* Test function for: + * size_t bplib_mpool_get_user_content_size(const bplib_mpool_block_t *cb) + */ + bplib_mpool_block_content_t my_block; + + UtAssert_ZERO(bplib_mpool_get_user_content_size(NULL)); + + memset(&my_block, 0, sizeof(my_block)); + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_generic, 0); + my_block.header.user_content_length = 14; + + UtAssert_UINT32_EQ(bplib_mpool_get_user_content_size(&my_block.header.base_link), 14); +} + +void test_bplib_mpool_read_refcount(void) +{ + /* Test function for: + * size_t bplib_mpool_read_refcount(const bplib_mpool_block_t *cb) + */ + bplib_mpool_block_content_t my_block; + + UtAssert_ZERO(bplib_mpool_read_refcount(NULL)); + + memset(&my_block, 0, sizeof(my_block)); + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_generic, 0); + my_block.header.refcount = 6; + + UtAssert_UINT32_EQ(bplib_mpool_read_refcount(&my_block.header.base_link), 6); +} + +void test_bplib_mpool_get_parent_pool_from_link(void) +{ + /* Test function for: + * bplib_mpool_t *bplib_mpool_get_parent_pool_from_link(bplib_mpool_block_t *cb) + */ + + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + + UtAssert_NULL(bplib_mpool_get_parent_pool_from_link(NULL)); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_primary, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_primary, 0); + + UtAssert_ADDRESS_EQ(bplib_mpool_get_parent_pool_from_link(&buf.blk[0].header.base_link), &buf.pool); + UtAssert_ADDRESS_EQ(bplib_mpool_get_parent_pool_from_link(&buf.blk[0].u.primary.pblock.cblock_list), &buf.pool); +} + +void test_bplib_mpool_generic_data_cast(void) +{ + /* Test function for: + * void *bplib_mpool_generic_data_cast(bplib_mpool_block_t *cb, uint32_t required_magic) + * bplib_mpool_block_t *bplib_mpool_generic_data_uncast(void *blk, bplib_mpool_blocktype_t parent_bt, uint32_t + * required_magic) + * + * These two functions are inverse ops so they are paired together + */ + static const uint32 UT_SIG = 0x4953ab26; + bplib_mpool_block_content_t my_block; + bplib_mpool_block_content_t my_ref; + + UtAssert_NULL(bplib_mpool_generic_data_cast(NULL, 0)); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_admin, 0); + UtAssert_NULL(bplib_mpool_generic_data_cast(&my_block.header.base_link, 0)); + UtAssert_NULL(bplib_mpool_generic_data_uncast(&my_block.u, bplib_mpool_blocktype_admin, 0)); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_generic, UT_SIG); + + UtAssert_ADDRESS_EQ(bplib_mpool_generic_data_cast(&my_block.header.base_link, UT_SIG), &my_block.u); + UtAssert_NULL(bplib_mpool_generic_data_cast(&my_block.header.base_link, ~UT_SIG)); + + UtAssert_ADDRESS_EQ(bplib_mpool_generic_data_uncast(&my_block.u, bplib_mpool_blocktype_generic, UT_SIG), &my_block); + UtAssert_NULL(bplib_mpool_generic_data_uncast(&my_block.u, bplib_mpool_blocktype_generic, ~UT_SIG)); + UtAssert_NULL(bplib_mpool_generic_data_uncast(&my_block.u, bplib_mpool_blocktype_generic, ~UT_SIG)); + UtAssert_NULL(bplib_mpool_generic_data_uncast(&my_block.u, bplib_mpool_blocktype_flow, UT_SIG)); + + test_setup_mpblock(NULL, &my_ref, bplib_mpool_blocktype_ref, 0); + my_ref.u.ref.pref_target = &my_block; + UtAssert_ADDRESS_EQ(bplib_mpool_generic_data_cast(&my_ref.header.base_link, UT_SIG), &my_block.u); +} + +void test_bplib_mpool_init_base_object(void) +{ + /* Test function for: + * void bplib_mpool_init_base_object(bplib_mpool_block_header_t *block_hdr, uint16_t user_content_length, uint32_t + * content_type_signature) + */ + + static const uint32 UT_SIG = 0x2c9f27d0; + static const uint16 UT_LEN = sizeof(bplib_mpool_generic_data_content_t); + bplib_mpool_block_content_t my_block; + + memset(&my_block, 0, sizeof(my_block)); + + UtAssert_VOIDCALL(bplib_mpool_init_base_object(&my_block.header, UT_LEN, UT_SIG)); + + UtAssert_UINT32_EQ(my_block.header.content_type_signature, UT_SIG); + UtAssert_UINT16_EQ(my_block.header.user_content_length, UT_LEN); +} + +void test_bplib_mpool_alloc_block_internal(void) +{ + /* Test function for: + * bplib_mpool_block_content_t *bplib_mpool_alloc_block_internal(bplib_mpool_t *pool, bplib_mpool_blocktype_t + * blocktype, uint32_t content_type_signature, void *init_arg, uint8_t priority) + */ + + UT_bplib_mpool_buf_t buf; + bplib_mpool_block_admin_content_t *admin; + + memset(&buf, 0, sizeof(buf)); + + UtAssert_NULL(bplib_mpool_alloc_block_internal(&buf.pool, bplib_mpool_blocktype_undefined, 0, NULL, 0)); + UtAssert_NULL(bplib_mpool_alloc_block_internal(&buf.pool, bplib_mpool_blocktype_max, 0, NULL, 0)); + UtAssert_NULL(bplib_mpool_alloc_block_internal(&buf.pool, bplib_mpool_blocktype_generic, 0, NULL, 0)); + + /* Nominal (need to do each blocktype that has a different init) */ + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + admin = bplib_mpool_get_admin(&buf.pool); + admin->num_bufs_total = 3; + UtAssert_ADDRESS_EQ(bplib_mpool_alloc_block_internal(&buf.pool, bplib_mpool_blocktype_generic, 0, NULL, 0), + &buf.blk[0]); + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + UtAssert_ADDRESS_EQ(bplib_mpool_alloc_block_internal(&buf.pool, bplib_mpool_blocktype_primary, 0, NULL, 0), + &buf.blk[0]); + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + UtAssert_ADDRESS_EQ(bplib_mpool_alloc_block_internal(&buf.pool, bplib_mpool_blocktype_canonical, 0, NULL, 0), + &buf.blk[0]); + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + UtAssert_ADDRESS_EQ(bplib_mpool_alloc_block_internal(&buf.pool, bplib_mpool_blocktype_flow, 0, NULL, 0), + &buf.blk[0]); + + /* free_blocks list empty (just repeat w/o resetting the state) */ + UtAssert_NULL(bplib_mpool_alloc_block_internal(&buf.pool, bplib_mpool_blocktype_generic, 0, NULL, 0)); + + /* Too Big */ + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + buf.blk[1].u.api.user_content_size = 16 + sizeof(bplib_mpool_block_buffer_t); + UtAssert_NULL(bplib_mpool_alloc_block_internal(&buf.pool, bplib_mpool_blocktype_generic, 0, NULL, 0)); + + /* No API */ + test_setup_allocation(&buf.pool, &buf.blk[0], NULL); + UtAssert_NULL(bplib_mpool_alloc_block_internal(&buf.pool, bplib_mpool_blocktype_generic, 0, NULL, 0)); +} + +void test_bplib_mpool_generic_data_alloc(void) +{ + /* Test function for: + * bplib_mpool_block_t *bplib_mpool_generic_data_alloc(bplib_mpool_t *pool, uint32_t magic_number, void *init_arg) + */ + + UT_bplib_mpool_buf_t buf; + uint8_t my_constructor_val; + + memset(&buf, 0, sizeof(buf)); + + /* Nominal (this is just a wrapper around bplib_mpool_alloc_block_internal) */ + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + buf.blk[1].u.api.api.construct = test_bplib_mpool_callback_stub; + UtAssert_ADDRESS_EQ(bplib_mpool_generic_data_alloc(&buf.pool, 0, &my_constructor_val), &buf.blk[0]); + + /* Failure of constructor still returns the block */ + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + UT_SetDefaultReturnValue(UT_KEY(test_bplib_mpool_callback_stub), BP_ERROR); + buf.blk[1].u.api.api.construct = test_bplib_mpool_callback_stub; + UtAssert_ADDRESS_EQ(bplib_mpool_generic_data_alloc(&buf.pool, 0, &my_constructor_val), &buf.blk[0]); +} + +void test_bplib_mpool_recycle_all_blocks_in_list(void) +{ + /* Test function for: + * void bplib_mpool_recycle_all_blocks_in_list(bplib_mpool_t *pool, bplib_mpool_block_t *list) + */ + UT_bplib_mpool_buf_t buf; + bplib_mpool_block_admin_content_t *admin; + + memset(&buf, 0, sizeof(buf)); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + admin = bplib_mpool_get_admin(&buf.pool); + + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_primary, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_primary, 0); + bplib_mpool_insert_after(&admin->active_list, &buf.blk[0].header.base_link); + bplib_mpool_insert_after(&admin->active_list, &buf.blk[1].header.base_link); + + UtAssert_VOIDCALL(bplib_mpool_recycle_all_blocks_in_list(&buf.pool, &admin->active_list)); + + UtAssert_BOOL_TRUE(bplib_mpool_is_empty_list_head(&admin->active_list)); + UtAssert_ADDRESS_EQ(bplib_mpool_get_next_block(&admin->recycle_blocks.block_list), &buf.blk[1].header.base_link); + UtAssert_ADDRESS_EQ(bplib_mpool_get_prev_block(&admin->recycle_blocks.block_list), &buf.blk[0].header.base_link); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_primary, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_canonical, 0); + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_canonical, 0); + bplib_mpool_insert_after(&buf.blk[0].u.primary.pblock.cblock_list, &buf.blk[1].header.base_link); + bplib_mpool_insert_after(&buf.blk[0].u.primary.pblock.cblock_list, &buf.blk[2].header.base_link); + UtAssert_VOIDCALL(bplib_mpool_recycle_all_blocks_in_list(NULL, &buf.blk[0].u.primary.pblock.cblock_list)); + UtAssert_ADDRESS_EQ(bplib_mpool_get_next_block(&admin->recycle_blocks.block_list), &buf.blk[2].header.base_link); + UtAssert_ADDRESS_EQ(bplib_mpool_get_prev_block(&admin->recycle_blocks.block_list), &buf.blk[1].header.base_link); +} + +void test_bplib_mpool_recycle_block(void) +{ + /* Test function for: + * void bplib_mpool_recycle_block(bplib_mpool_block_t *blk) + */ + UT_bplib_mpool_buf_t buf; + bplib_mpool_block_admin_content_t *admin; + + memset(&buf, 0, sizeof(buf)); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + admin = bplib_mpool_get_admin(&buf.pool); + + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_primary, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_primary, 0); + + bplib_mpool_insert_after(&admin->active_list, &buf.blk[0].header.base_link); + bplib_mpool_insert_after(&admin->active_list, &buf.blk[1].header.base_link); + + UtAssert_VOIDCALL(bplib_mpool_recycle_block(&buf.blk[1].header.base_link)); + UtAssert_ADDRESS_EQ(bplib_mpool_get_next_block(&admin->recycle_blocks.block_list), &buf.blk[1].header.base_link); + UtAssert_ADDRESS_EQ(bplib_mpool_get_next_block(&admin->active_list), &buf.blk[0].header.base_link); +} + +void test_bplib_mpool_list_iter_goto_first(void) +{ + /* Test function for: + * int bplib_mpool_list_iter_goto_first(const bplib_mpool_block_t *list, bplib_mpool_list_iter_t *iter) + */ + bplib_mpool_block_t list; + bplib_mpool_list_iter_t it; + + memset(&list, 0, sizeof(list)); + UtAssert_INT32_EQ(bplib_mpool_list_iter_goto_first(&list, &it), BP_ERROR); + + bplib_mpool_init_list_head(NULL, &list); + UtAssert_INT32_EQ(bplib_mpool_list_iter_goto_first(&list, &it), BP_ERROR); +} + +void test_bplib_mpool_list_iter_goto_last(void) +{ + /* Test function for: + * int bplib_mpool_list_iter_goto_last(const bplib_mpool_block_t *list, bplib_mpool_list_iter_t *iter) + */ + + bplib_mpool_block_t list; + bplib_mpool_list_iter_t it; + + memset(&list, 0, sizeof(list)); + UtAssert_INT32_EQ(bplib_mpool_list_iter_goto_last(&list, &it), BP_ERROR); + + bplib_mpool_init_list_head(NULL, &list); + UtAssert_INT32_EQ(bplib_mpool_list_iter_goto_last(&list, &it), BP_ERROR); +} + +void test_bplib_mpool_list_iter_forward(void) +{ + /* Test function for: + * int bplib_mpool_list_iter_forward(bplib_mpool_list_iter_t *iter) + */ + bplib_mpool_list_iter_t it; + bplib_mpool_block_t list; + bplib_mpool_block_content_t my_block; + + memset(&it, 0, sizeof(it)); + UtAssert_INT32_EQ(bplib_mpool_list_iter_forward(&it), BP_ERROR); + + memset(&list, 0, sizeof(list)); + bplib_mpool_init_list_head(NULL, &list); + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_generic, 0); + bplib_mpool_insert_after(&list, &my_block.header.base_link); + + it.pending_entry = &my_block.header.base_link; + UtAssert_INT32_EQ(bplib_mpool_list_iter_forward(&it), BP_SUCCESS); + + UtAssert_ADDRESS_EQ(it.position, &my_block); + UtAssert_ADDRESS_EQ(it.pending_entry, &list); + + UtAssert_INT32_EQ(bplib_mpool_list_iter_forward(&it), BP_ERROR); +} + +void test_bplib_mpool_list_iter_reverse(void) +{ + /* Test function for: + * int bplib_mpool_list_iter_reverse(bplib_mpool_list_iter_t *iter) + */ + bplib_mpool_list_iter_t it; + bplib_mpool_block_t list; + bplib_mpool_block_content_t my_block; + + memset(&it, 0, sizeof(it)); + + UtAssert_INT32_EQ(bplib_mpool_list_iter_reverse(&it), BP_ERROR); + + memset(&list, 0, sizeof(list)); + bplib_mpool_init_list_head(NULL, &list); + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_generic, 0); + bplib_mpool_insert_after(&list, &my_block.header.base_link); + + it.pending_entry = &my_block.header.base_link; + UtAssert_INT32_EQ(bplib_mpool_list_iter_reverse(&it), BP_SUCCESS); + + UtAssert_ADDRESS_EQ(it.position, &my_block); + UtAssert_ADDRESS_EQ(it.pending_entry, &list); + + UtAssert_INT32_EQ(bplib_mpool_list_iter_reverse(&it), BP_ERROR); +} + +void test_bplib_mpool_foreach_item_in_list(void) +{ + /* Test function for: + * int bplib_mpool_foreach_item_in_list(bplib_mpool_block_t *list, bool always_remove, bplib_mpool_callback_func_t + * callback_fn, void *callback_arg) + */ + + bplib_mpool_block_t list; + bplib_mpool_block_content_t my_block; + + memset(&list, 0, sizeof(list)); + bplib_mpool_init_list_head(NULL, &list); + + UtAssert_ZERO(bplib_mpool_foreach_item_in_list(&list, false, test_bplib_mpool_callback_stub, NULL)); + UtAssert_STUB_COUNT(test_bplib_mpool_callback_stub, 0); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_generic, 0); + bplib_mpool_insert_after(&list, &my_block.header.base_link); + + UtAssert_INT32_EQ(bplib_mpool_foreach_item_in_list(&list, false, test_bplib_mpool_callback_stub, NULL), 1); + UtAssert_STUB_COUNT(test_bplib_mpool_callback_stub, 1); + + UtAssert_INT32_EQ(bplib_mpool_foreach_item_in_list(&list, true, test_bplib_mpool_callback_stub, NULL), 1); + UtAssert_STUB_COUNT(test_bplib_mpool_callback_stub, 2); + UtAssert_BOOL_TRUE(bplib_mpool_is_link_unattached(&my_block.header.base_link)); +} + +void test_bplib_mpool_search_list(void) +{ + /* Test function for: + * bplib_mpool_block_t *bplib_mpool_search_list(const bplib_mpool_block_t *list, bplib_mpool_callback_func_t + * match_fn, void *match_arg) + */ + bplib_mpool_block_t list; + bplib_mpool_block_content_t my_block; + + memset(&list, 0, sizeof(list)); + bplib_mpool_init_list_head(NULL, &list); + + UtAssert_NULL(bplib_mpool_search_list(&list, test_bplib_mpool_callback_stub, NULL)); + UtAssert_STUB_COUNT(test_bplib_mpool_callback_stub, 0); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_generic, 0); + bplib_mpool_insert_after(&list, &my_block.header.base_link); + + UtAssert_ADDRESS_EQ(bplib_mpool_search_list(&list, test_bplib_mpool_callback_stub, NULL), + &my_block.header.base_link); + UtAssert_STUB_COUNT(test_bplib_mpool_callback_stub, 1); + + UT_SetDefaultReturnValue(UT_KEY(test_bplib_mpool_callback_stub), 1); + UtAssert_NULL(bplib_mpool_search_list(&list, test_bplib_mpool_callback_stub, NULL)); + UtAssert_STUB_COUNT(test_bplib_mpool_callback_stub, 2); +} + +void test_bplib_mpool_register_blocktype(void) +{ + /* Test function for: + * int bplib_mpool_register_blocktype(bplib_mpool_t *pool, uint32_t magic_number, const bplib_mpool_blocktype_api_t + * *api, size_t user_content_size) + */ + UT_bplib_mpool_buf_t buf; + + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_api, 0); + UT_SetHandlerFunction(UT_KEY(bplib_rbt_search_generic), UT_AltHandler_PointerReturnForSignature, &buf.blk[1].u); + + UtAssert_INT32_EQ( + bplib_mpool_register_blocktype(&buf.pool, UT_TESTBLOCKTYPE_SIG, &buf.blk[2].u.api.api, sizeof(uint32)), + BP_SUCCESS); + UtAssert_INT32_EQ(bplib_mpool_register_blocktype(&buf.pool, UT_TESTBLOCKTYPE_SIG, &buf.blk[2].u.api.api, 0), + BP_ERROR); + + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_api, 0); + UT_SetHandlerFunction(UT_KEY(bplib_rbt_search_generic), UT_AltHandler_PointerReturnForSignature, &buf.blk[1].u); + UT_SetDefaultReturnValue(UT_KEY(bplib_rbt_insert_value_generic), BP_DUPLICATE); + UtAssert_INT32_EQ(bplib_mpool_register_blocktype(&buf.pool, UT_TESTBLOCKTYPE_SIG, NULL, 0), BP_DUPLICATE); + + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_api, 0); + UtAssert_INT32_EQ( + bplib_mpool_register_blocktype(&buf.pool, UT_TESTBLOCKTYPE_SIG, &buf.blk[2].u.api.api, sizeof(uint32)), + BP_DUPLICATE); +} + +void test_bplib_mpool_collect_blocks(void) +{ + /* Test function for: + * uint32_t bplib_mpool_collect_blocks(bplib_mpool_t *pool, uint32_t limit) + */ + UT_bplib_mpool_buf_t buf; + bplib_mpool_block_admin_content_t *admin; + + memset(&buf, 0, sizeof(buf)); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_api, 0); + UT_SetHandlerFunction(UT_KEY(bplib_rbt_search_generic), UT_AltHandler_PointerReturn, &buf.blk[0].u); + buf.blk[0].u.api.api.destruct = test_bplib_mpool_callback_stub; + + admin = bplib_mpool_get_admin(&buf.pool); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_primary, 0); + bplib_mpool_subq_push_single(&admin->recycle_blocks, &buf.blk[1].header.base_link); + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_canonical, 0); + bplib_mpool_subq_push_single(&admin->recycle_blocks, &buf.blk[2].header.base_link); + + UtAssert_UINT32_EQ(bplib_mpool_collect_blocks(&buf.pool, 1), 1); + UtAssert_STUB_COUNT(test_bplib_mpool_callback_stub, 1); + UtAssert_UINT32_EQ(bplib_mpool_collect_blocks(&buf.pool, 1), 1); + UtAssert_STUB_COUNT(test_bplib_mpool_callback_stub, 2); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + UT_SetHandlerFunction(UT_KEY(bplib_rbt_search_generic), UT_AltHandler_PointerReturn, NULL); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_generic, 0); + bplib_mpool_subq_push_single(&admin->recycle_blocks, &buf.blk[0].header.base_link); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_flow, 0); + bplib_mpool_subq_push_single(&admin->recycle_blocks, &buf.blk[1].header.base_link); + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_ref, 0); + bplib_mpool_subq_push_single(&admin->recycle_blocks, &buf.blk[2].header.base_link); + + UtAssert_UINT32_EQ(bplib_mpool_collect_blocks(&buf.pool, 10), 3); +} + +void test_bplib_mpool_maintain(void) +{ + /* Test function for: + * void bplib_mpool_maintain(bplib_mpool_t *pool) + */ + UT_bplib_mpool_buf_t buf; + bplib_mpool_block_admin_content_t *admin; + + memset(&buf, 0, sizeof(buf)); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + UtAssert_VOIDCALL(bplib_mpool_maintain(&buf.pool)); + + admin = bplib_mpool_get_admin(&buf.pool); + + UT_SetHandlerFunction(UT_KEY(bplib_rbt_search_generic), UT_AltHandler_PointerReturn, NULL); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_generic, 0); + bplib_mpool_subq_push_single(&admin->recycle_blocks, &buf.blk[0].header.base_link); + + UtAssert_VOIDCALL(bplib_mpool_maintain(&buf.pool)); +} + +void test_bplib_mpool_query_mem_current_use(void) +{ + /* Test function for: + * size_t bplib_mpool_query_mem_current_use(bplib_mpool_t *pool) + */ + + bplib_mpool_t pool; + + memset(&pool, 0, sizeof(pool)); + + test_setup_mpblock(&pool, &pool.admin_block, bplib_mpool_blocktype_admin, 0); + + UtAssert_UINT32_EQ(bplib_mpool_query_mem_current_use(&pool), 0); +} + +void test_bplib_mpool_query_mem_max_use(void) +{ + /* Test function for: + * size_t bplib_mpool_query_mem_max_use(bplib_mpool_t *pool) + */ + bplib_mpool_t pool; + + memset(&pool, 0, sizeof(pool)); + + test_setup_mpblock(&pool, &pool.admin_block, bplib_mpool_blocktype_admin, 0); + + UtAssert_UINT32_EQ(bplib_mpool_query_mem_max_use(&pool), 0); +} + +void test_bplib_mpool_create(void) +{ + /* Test function for: + * bplib_mpool_t *bplib_mpool_create(void *pool_mem, size_t pool_size) + */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + + UtAssert_NULL(bplib_mpool_create(NULL, sizeof(buf))); + UtAssert_NULL(bplib_mpool_create(&buf, 1)); + UtAssert_ADDRESS_EQ(bplib_mpool_create(&buf, sizeof(buf)), &buf); +} + +void test_bplib_mpool_debug_scan(void) +{ + /* Test function for: + * void bplib_mpool_debug_scan(bplib_mpool_t *pool) + * + * Note this is not really part of the real code, it is for debugging only, + * and thus may not need a coverage test. But for now, call it for completeness. + */ + UT_bplib_mpool_buf_t buf; + bplib_mpool_t *pool; + + memset(&buf, 0, sizeof(buf)); + UtAssert_NOT_NULL(pool = bplib_mpool_create(&buf, sizeof(buf))); + + buf.blk[0].header.base_link.type = bplib_mpool_blocktype_primary; + buf.blk[1].header.base_link.type = bplib_mpool_blocktype_canonical; + buf.blk[2].header.base_link.type = bplib_mpool_blocktype_generic; + + UtAssert_VOIDCALL(bplib_mpool_debug_scan(pool)); + + buf.blk[0].header.base_link.type = bplib_mpool_blocktype_ref; + buf.blk[1].header.base_link.type = bplib_mpool_blocktype_flow; + buf.blk[2].header.base_link.type = bplib_mpool_blocktype_max; + + UtAssert_VOIDCALL(bplib_mpool_debug_scan(pool)); +} + +void TestBplibMpoolBase_Register(void) +{ + UtTest_Add(test_bplib_mpool_lock_init, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_lock_init"); + UtTest_Add(test_bplib_mpool_lock_prepare, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_lock_prepare"); + UtTest_Add(test_bplib_mpool_lock_resource, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_lock_resource"); + UtTest_Add(test_bplib_mpool_lock_wait, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_lock_wait"); + UtTest_Add(test_bplib_mpool_block_from_external_id, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_block_from_external_id"); + UtTest_Add(test_bplib_mpool_get_block_from_link, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_get_block_from_link"); + UtTest_Add(test_bplib_mpool_get_block_content, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_get_block_content"); + UtTest_Add(test_bplib_mpool_block_dereference_content, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_block_dereference_content"); + UtTest_Add(test_bplib_mpool_get_user_data_offset_by_blocktype, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_get_user_data_offset_by_blocktype"); + UtTest_Add(test_bplib_mpool_get_generic_data_capacity, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_get_generic_data_capacity"); + UtTest_Add(test_bplib_mpool_init_secondary_link, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_init_secondary_link"); + UtTest_Add(test_bplib_mpool_init_list_head, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_init_list_head"); + UtTest_Add(test_bplib_mpool_insert_after, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_insert_after"); + UtTest_Add(test_bplib_mpool_insert_before, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_insert_before"); + UtTest_Add(test_bplib_mpool_extract_node, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_extract_node"); + UtTest_Add(test_bplib_mpool_merge_list, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_merge_list"); + UtTest_Add(test_bplib_mpool_get_user_content_size, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_get_user_content_size"); + UtTest_Add(test_bplib_mpool_read_refcount, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_read_refcount"); + UtTest_Add(test_bplib_mpool_get_parent_pool_from_link, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_get_parent_pool_from_link"); + UtTest_Add(test_bplib_mpool_generic_data_cast, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_generic_data_[un]cast"); + UtTest_Add(test_bplib_mpool_init_base_object, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_init_base_object"); + UtTest_Add(test_bplib_mpool_alloc_block_internal, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_alloc_block_internal"); + UtTest_Add(test_bplib_mpool_generic_data_alloc, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_generic_data_alloc"); + UtTest_Add(test_bplib_mpool_recycle_all_blocks_in_list, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_recycle_all_blocks_in_list"); + UtTest_Add(test_bplib_mpool_recycle_block, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_recycle_block"); + UtTest_Add(test_bplib_mpool_list_iter_goto_first, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_list_iter_goto_first"); + UtTest_Add(test_bplib_mpool_list_iter_goto_last, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_list_iter_goto_last"); + UtTest_Add(test_bplib_mpool_list_iter_forward, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_list_iter_forward"); + UtTest_Add(test_bplib_mpool_list_iter_reverse, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_list_iter_reverse"); + UtTest_Add(test_bplib_mpool_foreach_item_in_list, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_foreach_item_in_list"); + UtTest_Add(test_bplib_mpool_search_list, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_search_list"); + UtTest_Add(test_bplib_mpool_register_blocktype, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_register_blocktype"); + UtTest_Add(test_bplib_mpool_collect_blocks, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_collect_blocks"); + UtTest_Add(test_bplib_mpool_maintain, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_maintain"); + UtTest_Add(test_bplib_mpool_query_mem_current_use, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_query_mem_current_use"); + UtTest_Add(test_bplib_mpool_query_mem_max_use, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_query_mem_max_use"); + UtTest_Add(test_bplib_mpool_create, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_create"); + UtTest_Add(test_bplib_mpool_debug_scan, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_debug_scan"); +} diff --git a/mpool/ut-coverage/test_bplib_v7_mpool_bblocks.c b/mpool/ut-coverage/test_bplib_v7_mpool_bblocks.c index 48a2669d..19602db3 100644 --- a/mpool/ut-coverage/test_bplib_v7_mpool_bblocks.c +++ b/mpool/ut-coverage/test_bplib_v7_mpool_bblocks.c @@ -23,24 +23,31 @@ #include "utstubs.h" #include "uttest.h" +#include "test_bplib_mpool.h" #include "v7_mpool_bblocks.h" -#include "v7_mpool_internal.h" void test_bplib_mpool_bblock_primary_cast(void) { /* Test function for: * bplib_mpool_bblock_primary_t *bplib_mpool_bblock_primary_cast(bplib_mpool_block_t *cb); */ - bplib_mpool_block_content_t my_block; - bplib_mpool_block_t *cb = &my_block.header.base_link; + bplib_mpool_block_content_t my_block; + bplib_mpool_bblock_primary_t *pri; + bplib_mpool_block_t *cb = &my_block.header.base_link; UtAssert_NULL(bplib_mpool_bblock_primary_cast(NULL)); memset(&my_block, 0, sizeof(my_block)); UtAssert_NULL(bplib_mpool_bblock_primary_cast(cb)); - cb->type = bplib_mpool_blocktype_primary; - UtAssert_ADDRESS_EQ(bplib_mpool_bblock_primary_cast(cb), &my_block.u); + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_primary, 0); + UtAssert_ADDRESS_EQ(pri = bplib_mpool_bblock_primary_cast(cb), &my_block.u); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_canonical, 0); + UtAssert_NULL(bplib_mpool_bblock_primary_cast(cb)); + + /* Ensure that the logical accessors work (inline) */ + UtAssert_NOT_NULL(bplib_mpool_bblock_primary_get_logical(pri)); } void test_bplib_mpool_bblock_canonical_cast(void) @@ -48,16 +55,26 @@ void test_bplib_mpool_bblock_canonical_cast(void) /* Test function for: * bplib_mpool_bblock_canonical_t *bplib_mpool_bblock_canonical_cast(bplib_mpool_block_t *cb); */ - bplib_mpool_block_content_t my_block; - bplib_mpool_block_t *cb = &my_block.header.base_link; + bplib_mpool_block_content_t my_block; + bplib_mpool_bblock_canonical_t *canonical; + bplib_mpool_block_t *cb = &my_block.header.base_link; UtAssert_NULL(bplib_mpool_bblock_canonical_cast(NULL)); memset(&my_block, 0, sizeof(my_block)); UtAssert_NULL(bplib_mpool_bblock_canonical_cast(cb)); - cb->type = bplib_mpool_blocktype_canonical; - UtAssert_ADDRESS_EQ(bplib_mpool_bblock_canonical_cast(cb), &my_block.u); + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_canonical, 0); + UtAssert_ADDRESS_EQ(canonical = bplib_mpool_bblock_canonical_cast(cb), &my_block.u); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_primary, 0); + UtAssert_NULL(bplib_mpool_bblock_canonical_cast(cb)); + + /* Ensure that the logical accessors work (inline) */ + UtAssert_NOT_NULL(bplib_mpool_bblock_canonical_get_logical(canonical)); + UtAssert_VOIDCALL(bplib_mpool_bblock_canonical_set_content_position(canonical, 1, 2)); + UtAssert_UINT32_EQ(bplib_mpool_bblock_canonical_get_content_length(canonical), 2); + UtAssert_UINT32_EQ(bplib_mpool_bblock_canonical_get_content_offset(canonical), 1); } void test_bplib_mpool_bblock_cbor_cast(void) @@ -73,8 +90,7 @@ void test_bplib_mpool_bblock_cbor_cast(void) memset(&my_block, 0, sizeof(my_block)); UtAssert_NULL(bplib_mpool_bblock_cbor_cast(cb)); - cb->type = bplib_mpool_blocktype_generic; - my_block.header.content_type_signature = MPOOL_CACHE_CBOR_DATA_SIGNATURE; + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_generic, MPOOL_CACHE_CBOR_DATA_SIGNATURE); UtAssert_ADDRESS_EQ(bplib_mpool_bblock_cbor_cast(cb), &my_block.u); } @@ -83,80 +99,297 @@ void test_bplib_mpool_bblock_cbor_set_size(void) /* Test function for: * void bplib_mpool_bblock_cbor_set_size(bplib_mpool_block_t *cb, size_t user_content_size); */ + bplib_mpool_block_content_t my_block; + + UtAssert_VOIDCALL(bplib_mpool_bblock_cbor_set_size(NULL, 0)); + + memset(&my_block, 0, sizeof(my_block)); + UtAssert_VOIDCALL(bplib_mpool_bblock_cbor_set_size(&my_block.header.base_link, 0)); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_generic, ~MPOOL_CACHE_CBOR_DATA_SIGNATURE); + UtAssert_VOIDCALL(bplib_mpool_bblock_cbor_set_size(&my_block.header.base_link, 0)); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_canonical, MPOOL_CACHE_CBOR_DATA_SIGNATURE); + UtAssert_VOIDCALL(bplib_mpool_bblock_cbor_set_size(&my_block.header.base_link, 0)); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_generic, MPOOL_CACHE_CBOR_DATA_SIGNATURE); + UtAssert_VOIDCALL(bplib_mpool_bblock_cbor_set_size(&my_block.header.base_link, 123)); + + UtAssert_UINT32_EQ(my_block.header.user_content_length, 123); } + void test_bplib_mpool_bblock_primary_alloc(void) { /* Test function for: * bplib_mpool_block_t *bplib_mpool_bblock_primary_alloc(bplib_mpool_t *pool, uint32_t magic_number, void *init_arg, * uint8_t priority, uint64_t timeout); */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + + UtAssert_NULL(bplib_mpool_bblock_primary_alloc(&buf.pool, 1234, NULL, 0, 0)); + + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + UtAssert_ADDRESS_EQ(bplib_mpool_bblock_primary_alloc(&buf.pool, 1234, NULL, 0, 0), &buf.blk[0]); } + void test_bplib_mpool_bblock_canonical_alloc(void) { /* Test function for: * bplib_mpool_block_t *bplib_mpool_bblock_canonical_alloc(bplib_mpool_t *pool, uint32_t magic_number, void * *init_arg); */ + + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + + UtAssert_NULL(bplib_mpool_bblock_canonical_alloc(&buf.pool, 1234, NULL)); + + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + UtAssert_ADDRESS_EQ(bplib_mpool_bblock_canonical_alloc(&buf.pool, 1234, NULL), &buf.blk[0]); } + void test_bplib_mpool_bblock_cbor_alloc(void) { /* Test function for: * bplib_mpool_block_t *bplib_mpool_bblock_cbor_alloc(bplib_mpool_t *pool); */ + + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + + UtAssert_NULL(bplib_mpool_bblock_cbor_alloc(&buf.pool)); + + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + UtAssert_ADDRESS_EQ(bplib_mpool_bblock_cbor_alloc(&buf.pool), &buf.blk[0]); } + void test_bplib_mpool_bblock_cbor_append(void) { /* Test function for: * void bplib_mpool_bblock_cbor_append(bplib_mpool_block_t *head, bplib_mpool_block_t *blk); */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_generic, MPOOL_CACHE_CBOR_DATA_SIGNATURE); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_generic, MPOOL_CACHE_CBOR_DATA_SIGNATURE); + + UtAssert_VOIDCALL(bplib_mpool_bblock_cbor_append(&buf.blk[0].header.base_link, &buf.blk[1].header.base_link)); } + void test_bplib_mpool_bblock_primary_append(void) { /* Test function for: * void bplib_mpool_bblock_primary_append(bplib_mpool_bblock_primary_t *cpb, bplib_mpool_block_t *ccb); */ + + UT_bplib_mpool_buf_t buf; + bp_canonical_block_buffer_t *b; + + memset(&buf, 0, sizeof(buf)); + + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_primary, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_canonical, 0); + + UtAssert_VOIDCALL(bplib_mpool_bblock_primary_append(&buf.blk[0].u.primary.pblock, &buf.blk[1].header.base_link)); + + /* Test the special case if inserting blocknum 1, it should go last */ + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_canonical, 0); + b = bplib_mpool_bblock_canonical_get_logical(&buf.blk[2].u.canonical.cblock); + b->canonical_block.blockNum = 1; + UtAssert_VOIDCALL(bplib_mpool_bblock_primary_append(&buf.blk[0].u.primary.pblock, &buf.blk[2].header.base_link)); } + void test_bplib_mpool_bblock_primary_locate_canonical(void) { /* Test function for: * bplib_mpool_block_t *bplib_mpool_bblock_primary_locate_canonical(bplib_mpool_bblock_primary_t *cpb, * bp_blocktype_t block_type); */ + + UT_bplib_mpool_buf_t buf; + bp_canonical_block_buffer_t *b; + + memset(&buf, 0, sizeof(buf)); + + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_primary, 0); + UtAssert_NULL(bplib_mpool_bblock_primary_locate_canonical(&buf.blk[0].u.primary.pblock, bp_blocktype_undefined)); + + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_canonical, 0); + bplib_mpool_insert_after(&buf.blk[0].u.primary.pblock.cblock_list, &buf.blk[1].header.base_link); + b = bplib_mpool_bblock_canonical_get_logical(&buf.blk[1].u.canonical.cblock); + b->canonical_block.blockType = bp_blocktype_bundleAge; + + /* canonical block of a different type should not be found */ + UtAssert_NULL(bplib_mpool_bblock_primary_locate_canonical(&buf.blk[0].u.primary.pblock, bp_blocktype_hopCount)); + + /* canonical block of the correct type should be found */ + UtAssert_ADDRESS_EQ( + bplib_mpool_bblock_primary_locate_canonical(&buf.blk[0].u.primary.pblock, bp_blocktype_bundleAge), &buf.blk[1]); + + /* include a block that is NOT a canonical block */ + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_generic, 0); + bplib_mpool_insert_before(&buf.blk[0].u.primary.pblock.cblock_list, &buf.blk[2].header.base_link); + UtAssert_NULL(bplib_mpool_bblock_primary_locate_canonical(&buf.blk[0].u.primary.pblock, bp_blocktype_hopCount)); } + void test_bplib_mpool_bblock_primary_drop_encode(void) { /* Test function for: * void bplib_mpool_bblock_primary_drop_encode(bplib_mpool_bblock_primary_t *cpb); */ + UT_bplib_mpool_buf_t buf; + bplib_mpool_block_admin_content_t *admin; + + memset(&buf, 0, sizeof(buf)); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + admin = bplib_mpool_get_admin(&buf.pool); + + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_primary, 0); + UtAssert_VOIDCALL(bplib_mpool_bblock_primary_drop_encode(&buf.blk[0].u.primary.pblock)); + + /* confirms nothing got recycled (empty cbor block list) */ + UtAssert_BOOL_TRUE(bplib_mpool_is_empty_list_head(&admin->recycle_blocks.block_list)); + + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_generic, MPOOL_CACHE_CBOR_DATA_SIGNATURE); + bplib_mpool_insert_after(&buf.blk[0].u.primary.pblock.chunk_list, &buf.blk[1].header.base_link); + UtAssert_VOIDCALL(bplib_mpool_bblock_primary_drop_encode(&buf.blk[0].u.primary.pblock)); + + /* confirms that cbor block got recycled */ + UtAssert_BOOL_FALSE(bplib_mpool_is_empty_list_head(&admin->recycle_blocks.block_list)); } + void test_bplib_mpool_bblock_canonical_drop_encode(void) { /* Test function for: * void bplib_mpool_bblock_canonical_drop_encode(bplib_mpool_bblock_canonical_t *ccb); */ + UT_bplib_mpool_buf_t buf; + bplib_mpool_block_admin_content_t *admin; + + memset(&buf, 0, sizeof(buf)); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + admin = bplib_mpool_get_admin(&buf.pool); + + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_canonical, 0); + buf.blk[0].u.canonical.cblock.block_encode_size_cache = 32; + UtAssert_VOIDCALL(bplib_mpool_bblock_canonical_drop_encode(&buf.blk[0].u.canonical.cblock)); + UtAssert_ZERO(buf.blk[0].u.canonical.cblock.block_encode_size_cache); + + /* confirms nothing got recycled (empty cbor block list) */ + UtAssert_BOOL_TRUE(bplib_mpool_is_empty_list_head(&admin->recycle_blocks.block_list)); + + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_generic, MPOOL_CACHE_CBOR_DATA_SIGNATURE); + buf.blk[0].u.canonical.cblock.block_encode_size_cache = 32; + bplib_mpool_insert_after(&buf.blk[0].u.canonical.cblock.chunk_list, &buf.blk[1].header.base_link); + UtAssert_VOIDCALL(bplib_mpool_bblock_canonical_drop_encode(&buf.blk[0].u.canonical.cblock)); + UtAssert_ZERO(buf.blk[0].u.canonical.cblock.block_encode_size_cache); + + /* confirms that cbor block got recycled */ + UtAssert_BOOL_FALSE(bplib_mpool_is_empty_list_head(&admin->recycle_blocks.block_list)); + + /* confirm that a primary block associated with this canonical block is also invalidated */ + memset(&buf, 0, sizeof(buf)); + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_primary, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_canonical, 0); + bplib_mpool_insert_after(&buf.blk[0].u.primary.pblock.cblock_list, &buf.blk[1].header.base_link); + buf.blk[0].u.primary.pblock.bundle_encode_size_cache = 16; + buf.blk[1].u.canonical.cblock.block_encode_size_cache = 32; + buf.blk[1].u.canonical.cblock.bundle_ref = &buf.blk[0].u.primary.pblock; + UtAssert_VOIDCALL(bplib_mpool_bblock_canonical_drop_encode(&buf.blk[1].u.canonical.cblock)); + UtAssert_ZERO(buf.blk[0].u.primary.pblock.bundle_encode_size_cache); + UtAssert_ZERO(buf.blk[1].u.canonical.cblock.block_encode_size_cache); } + void test_bplib_mpool_bblock_cbor_export(void) { /* Test function for: * size_t bplib_mpool_bblock_cbor_export(bplib_mpool_block_t *list, void *out_ptr, size_t max_out_size, size_t * seek_start, size_t max_count); */ + UT_bplib_mpool_buf_t buf; + uint8_t output[128]; + + memset(&buf, 0, sizeof(buf)); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_primary, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_generic, MPOOL_CACHE_CBOR_DATA_SIGNATURE); + + /* call with a direct ref to a cbor block (invalid, should be a list) */ + UtAssert_ZERO( + bplib_mpool_bblock_cbor_export(&buf.blk[1].header.base_link, output, sizeof(output), 0, sizeof(output))); + + /* nominal call, one zero-size block in the chunk_list */ + bplib_mpool_insert_after(&buf.blk[0].u.primary.pblock.chunk_list, &buf.blk[1].header.base_link); + UtAssert_ZERO(bplib_mpool_bblock_cbor_export(&buf.blk[0].u.primary.pblock.chunk_list, output, sizeof(output), 0, + sizeof(output))); + + /* nominal call, one nonzero-size block in the chunk_list */ + bplib_mpool_bblock_cbor_set_size(&buf.blk[1].header.base_link, 32); + UtAssert_UINT32_EQ(bplib_mpool_bblock_cbor_export(&buf.blk[0].u.primary.pblock.chunk_list, output, sizeof(output), + 0, sizeof(output)), + 32); + + /* call with a seek_start (skips initial bytes, greater than cbor block) */ + UtAssert_UINT32_EQ(bplib_mpool_bblock_cbor_export(&buf.blk[0].u.primary.pblock.chunk_list, output, sizeof(output), + 48, sizeof(output)), + 0); + + /* call with a seek_start (skips initial bytes, less than cbor block) */ + UtAssert_UINT32_EQ(bplib_mpool_bblock_cbor_export(&buf.blk[0].u.primary.pblock.chunk_list, output, sizeof(output), + 16, sizeof(output)), + 16); + + /* cbor data will not fit into output (variant 1, this copies the portion that will fit) */ + UtAssert_UINT32_EQ( + bplib_mpool_bblock_cbor_export(&buf.blk[0].u.primary.pblock.chunk_list, output, sizeof(output), 0, 16), 16); + + /* cbor data will not fit into output (variant 2, this copies none of the block) */ + UtAssert_ZERO( + bplib_mpool_bblock_cbor_export(&buf.blk[0].u.primary.pblock.chunk_list, output, 16, 0, sizeof(output))); + + /* include a block that is NOT cbor, should stop at that point */ + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_generic, ~MPOOL_CACHE_CBOR_DATA_SIGNATURE); + bplib_mpool_insert_after(&buf.blk[0].u.primary.pblock.chunk_list, &buf.blk[2].header.base_link); + UtAssert_ZERO(bplib_mpool_bblock_cbor_export(&buf.blk[0].u.primary.pblock.chunk_list, output, sizeof(output), 0, + sizeof(output))); } void TestBplibMpoolBBlocks_Register(void) { - UtTest_Add(test_bplib_mpool_bblock_primary_cast, NULL, NULL, "bplib_mpool_bblock_primary_cast"); - UtTest_Add(test_bplib_mpool_bblock_canonical_cast, NULL, NULL, "bplib_mpool_bblock_canonical_cast"); - UtTest_Add(test_bplib_mpool_bblock_cbor_cast, NULL, NULL, "bplib_mpool_bblock_cbor_cast"); - UtTest_Add(test_bplib_mpool_bblock_cbor_set_size, NULL, NULL, "bplib_mpool_bblock_cbor_set_size"); - UtTest_Add(test_bplib_mpool_bblock_primary_alloc, NULL, NULL, "bplib_mpool_bblock_primary_alloc"); - UtTest_Add(test_bplib_mpool_bblock_canonical_alloc, NULL, NULL, "bplib_mpool_bblock_canonical_alloc"); - UtTest_Add(test_bplib_mpool_bblock_cbor_alloc, NULL, NULL, "bplib_mpool_bblock_cbor_alloc"); - UtTest_Add(test_bplib_mpool_bblock_cbor_append, NULL, NULL, "bplib_mpool_bblock_cbor_append"); - UtTest_Add(test_bplib_mpool_bblock_primary_append, NULL, NULL, "bplib_mpool_bblock_primary_append"); - UtTest_Add(test_bplib_mpool_bblock_primary_locate_canonical, NULL, NULL, + UtTest_Add(test_bplib_mpool_bblock_primary_cast, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_bblock_primary_cast"); + UtTest_Add(test_bplib_mpool_bblock_canonical_cast, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_bblock_canonical_cast"); + UtTest_Add(test_bplib_mpool_bblock_cbor_cast, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_bblock_cbor_cast"); + UtTest_Add(test_bplib_mpool_bblock_cbor_set_size, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_bblock_cbor_set_size"); + UtTest_Add(test_bplib_mpool_bblock_primary_alloc, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_bblock_primary_alloc"); + UtTest_Add(test_bplib_mpool_bblock_canonical_alloc, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_bblock_canonical_alloc"); + UtTest_Add(test_bplib_mpool_bblock_cbor_alloc, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_bblock_cbor_alloc"); + UtTest_Add(test_bplib_mpool_bblock_cbor_append, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_bblock_cbor_append"); + UtTest_Add(test_bplib_mpool_bblock_primary_append, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_bblock_primary_append"); + UtTest_Add(test_bplib_mpool_bblock_primary_locate_canonical, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_bblock_primary_locate_canonical"); - UtTest_Add(test_bplib_mpool_bblock_primary_drop_encode, NULL, NULL, "bplib_mpool_bblock_primary_drop_encode"); - UtTest_Add(test_bplib_mpool_bblock_canonical_drop_encode, NULL, NULL, "bplib_mpool_bblock_canonical_drop_encode"); - UtTest_Add(test_bplib_mpool_bblock_cbor_export, NULL, NULL, "bplib_mpool_bblock_cbor_export"); + UtTest_Add(test_bplib_mpool_bblock_primary_drop_encode, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_bblock_primary_drop_encode"); + UtTest_Add(test_bplib_mpool_bblock_canonical_drop_encode, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_bblock_canonical_drop_encode"); + UtTest_Add(test_bplib_mpool_bblock_cbor_export, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_bblock_cbor_export"); } diff --git a/mpool/ut-coverage/test_bplib_v7_mpool_flows.c b/mpool/ut-coverage/test_bplib_v7_mpool_flows.c index 5f0e814b..94da8261 100644 --- a/mpool/ut-coverage/test_bplib_v7_mpool_flows.c +++ b/mpool/ut-coverage/test_bplib_v7_mpool_flows.c @@ -23,13 +23,128 @@ #include "utstubs.h" #include "uttest.h" +#include "test_bplib_mpool.h" #include "v7_mpool_flows.h" +void UT_AltHandler_MoveQueue(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context) +{ + bplib_mpool_flow_t *flow = UserObj; + bplib_mpool_block_t *blk; + + blk = bplib_mpool_subq_pull_single(&flow->ingress.base_subq); + if (blk) + { + bplib_mpool_subq_push_single(&flow->egress.base_subq, blk); + } +} + +void test_bplib_mpool_subq_merge_list(void) +{ + /* Test function for: + * uint32_t bplib_mpool_subq_merge_list(bplib_mpool_subq_base_t *subq_dst, bplib_mpool_block_t *list) + */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_flow, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_flow, 0); + UtAssert_UINT32_EQ(bplib_mpool_subq_merge_list(&buf.blk[0].u.flow.fblock.ingress.base_subq, + &buf.blk[1].u.flow.fblock.ingress.base_subq.block_list), + 0); + + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_primary, 0); + bplib_mpool_subq_push_single(&buf.blk[1].u.flow.fblock.ingress.base_subq, &buf.blk[2].header.base_link); + + UtAssert_UINT32_EQ(bplib_mpool_subq_merge_list(&buf.blk[0].u.flow.fblock.ingress.base_subq, + &buf.blk[1].u.flow.fblock.ingress.base_subq.block_list), + 1); + UtAssert_UINT32_EQ(buf.blk[0].u.flow.fblock.ingress.base_subq.push_count, 1); + UtAssert_UINT32_EQ(buf.blk[0].u.flow.fblock.ingress.base_subq.pull_count, 0); +} + +void test_bplib_mpool_subq_move_all(void) +{ + /* Test function for: + * uint32_t bplib_mpool_subq_move_all(bplib_mpool_subq_base_t *subq_dst, bplib_mpool_subq_base_t *subq_src) + */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_flow, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_flow, 0); + UtAssert_UINT32_EQ(bplib_mpool_subq_move_all(&buf.blk[0].u.flow.fblock.ingress.base_subq, + &buf.blk[1].u.flow.fblock.ingress.base_subq), + 0); + + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_primary, 0); + bplib_mpool_subq_push_single(&buf.blk[1].u.flow.fblock.ingress.base_subq, &buf.blk[2].header.base_link); + + UtAssert_UINT32_EQ(bplib_mpool_subq_move_all(&buf.blk[0].u.flow.fblock.ingress.base_subq, + &buf.blk[1].u.flow.fblock.ingress.base_subq), + 1); + UtAssert_UINT32_EQ(buf.blk[0].u.flow.fblock.ingress.base_subq.push_count, 1); + UtAssert_UINT32_EQ(buf.blk[0].u.flow.fblock.ingress.base_subq.pull_count, 0); + UtAssert_UINT32_EQ(buf.blk[1].u.flow.fblock.ingress.base_subq.push_count, 1); + UtAssert_UINT32_EQ(buf.blk[1].u.flow.fblock.ingress.base_subq.pull_count, 1); +} + +void test_bplib_mpool_subq_drop_all(void) +{ + /* Test function for: + * uint32_t bplib_mpool_subq_drop_all(bplib_mpool_t *pool, bplib_mpool_subq_base_t *subq) + */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_flow, 0); + UtAssert_UINT32_EQ(bplib_mpool_subq_drop_all(&buf.pool, &buf.blk[0].u.flow.fblock.ingress.base_subq), 0); + + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_primary, 0); + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_primary, 0); + bplib_mpool_subq_push_single(&buf.blk[0].u.flow.fblock.ingress.base_subq, &buf.blk[1].header.base_link); + bplib_mpool_subq_push_single(&buf.blk[0].u.flow.fblock.ingress.base_subq, &buf.blk[2].header.base_link); + + UtAssert_UINT32_EQ(bplib_mpool_subq_drop_all(&buf.pool, &buf.blk[0].u.flow.fblock.ingress.base_subq), 2); + UtAssert_UINT32_EQ(buf.blk[0].u.flow.fblock.ingress.base_subq.push_count, 2); + UtAssert_UINT32_EQ(buf.blk[0].u.flow.fblock.ingress.base_subq.pull_count, 2); +} + +void test_bplib_mpool_subq_pull_single(void) +{ + /* Test function for: + * bplib_mpool_block_t *bplib_mpool_subq_pull_single(bplib_mpool_subq_base_t *subq) + */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_flow, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_flow, 0); + + UtAssert_NULL(bplib_mpool_subq_pull_single(&buf.blk[0].u.flow.fblock.ingress.base_subq)); +} + void test_bplib_mpool_flow_cast(void) { /* Test function for: * bplib_mpool_flow_t *bplib_mpool_flow_cast(bplib_mpool_block_t *cb) */ + bplib_mpool_block_content_t my_block; + bplib_mpool_block_t *cb = &my_block.header.base_link; + + UtAssert_NULL(bplib_mpool_flow_cast(NULL)); + + memset(&my_block, 0, sizeof(my_block)); + UtAssert_NULL(bplib_mpool_flow_cast(cb)); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_flow, 0); + UtAssert_ADDRESS_EQ(bplib_mpool_flow_cast(cb), &my_block.u); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_generic, 0); + UtAssert_NULL(bplib_mpool_flow_cast(cb)); } void test_bplib_mpool_flow_alloc(void) @@ -37,6 +152,14 @@ void test_bplib_mpool_flow_alloc(void) /* Test function for: * bplib_mpool_block_t *bplib_mpool_flow_alloc(bplib_mpool_t *pool, uint32_t magic_number, void *init_arg) */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + + UtAssert_NULL(bplib_mpool_flow_alloc(&buf.pool, 1234, NULL)); + + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + UtAssert_ADDRESS_EQ(bplib_mpool_flow_alloc(&buf.pool, 1234, NULL), &buf.blk[0]); } void test_bplib_mpool_flow_disable(void) @@ -44,13 +167,27 @@ void test_bplib_mpool_flow_disable(void) /* Test function for: * uint32_t bplib_mpool_flow_disable(bplib_mpool_subq_workitem_t *subq) */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_flow, 0); + + UtAssert_ZERO(bplib_mpool_flow_disable(&buf.blk[0].u.flow.fblock.ingress)); } void test_bplib_mpool_flow_enable(void) { /* Test function for: - * void bplib_mpool_flow_enable(bplib_mpool_subq_workitem_t *subq, uint32_t depth_limit) + * void bplib_mpool_flow_enable(bplib_mpool_subq_workitem_t *subq, uint32_t depth_limit) */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_flow, 0); + + UtAssert_VOIDCALL(bplib_mpool_flow_enable(&buf.blk[0].u.flow.fblock.ingress, 1)); } void test_bplib_mpool_flow_try_push(void) @@ -59,6 +196,31 @@ void test_bplib_mpool_flow_try_push(void) * bool bplib_mpool_flow_try_push(bplib_mpool_subq_workitem_t *subq_dst, bplib_mpool_block_t *qblk, uint64_t * abs_timeout) */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_flow, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_primary, 0); + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_primary, 0); + + UtAssert_BOOL_FALSE(bplib_mpool_flow_try_push(&buf.blk[0].u.flow.fblock.ingress, &buf.blk[1].header.base_link, 0)); + UtAssert_STUB_COUNT(bplib_os_broadcast_signal, 0); + + UtAssert_BOOL_TRUE(bplib_mpool_is_link_unattached(&buf.blk[1].header.base_link)); + UtAssert_VOIDCALL(bplib_mpool_flow_enable(&buf.blk[0].u.flow.fblock.ingress, 1)); + UtAssert_BOOL_TRUE(bplib_mpool_flow_try_push(&buf.blk[0].u.flow.fblock.ingress, &buf.blk[1].header.base_link, 0)); + UtAssert_STUB_COUNT(bplib_os_broadcast_signal, 1); + UtAssert_BOOL_TRUE(bplib_mpool_is_link_attached(&buf.blk[1].header.base_link)); + + UtAssert_BOOL_FALSE(bplib_mpool_flow_try_push(&buf.blk[0].u.flow.fblock.ingress, &buf.blk[2].header.base_link, 0)); + UtAssert_STUB_COUNT(bplib_os_broadcast_signal, 1); + UtAssert_BOOL_TRUE(bplib_mpool_is_link_unattached(&buf.blk[2].header.base_link)); + + /* This time use a nonzero timeout */ + UT_SetHandlerFunction(UT_KEY(bplib_os_wait_until_ms), UT_AltHandler_MoveQueue, &buf.blk[0].u.flow.fblock); + UtAssert_BOOL_TRUE(bplib_mpool_flow_try_push(&buf.blk[0].u.flow.fblock.ingress, &buf.blk[2].header.base_link, 100)); + UtAssert_STUB_COUNT(bplib_os_broadcast_signal, 2); } void test_bplib_mpool_flow_try_move_all(void) @@ -67,6 +229,34 @@ void test_bplib_mpool_flow_try_move_all(void) * uint32_t bplib_mpool_flow_try_move_all(bplib_mpool_subq_workitem_t *subq_dst, bplib_mpool_subq_workitem_t * *subq_src, uint64_t abs_timeout) */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_flow, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_primary, 0); + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_primary, 0); + + UtAssert_ZERO( + bplib_mpool_flow_try_move_all(&buf.blk[0].u.flow.fblock.egress, &buf.blk[0].u.flow.fblock.ingress, 0)); + /* Even though the above did nothing it still signals on the lock */ + UtAssert_STUB_COUNT(bplib_os_broadcast_signal, 1); + + UtAssert_VOIDCALL(bplib_mpool_flow_enable(&buf.blk[0].u.flow.fblock.ingress, 1)); + UtAssert_VOIDCALL(bplib_mpool_flow_enable(&buf.blk[0].u.flow.fblock.egress, 1)); + UtAssert_VOIDCALL( + bplib_mpool_subq_push_single(&buf.blk[0].u.flow.fblock.ingress.base_subq, &buf.blk[1].header.base_link)); + UtAssert_UINT32_EQ( + bplib_mpool_flow_try_move_all(&buf.blk[0].u.flow.fblock.egress, &buf.blk[0].u.flow.fblock.ingress, 0), 1); + UtAssert_STUB_COUNT(bplib_os_broadcast_signal, 2); + + UT_SetHandlerFunction(UT_KEY(bplib_os_wait_until_ms), UT_AltHandler_MoveQueue, &buf.blk[0].u.flow.fblock); + UT_SetDeferredRetcode(UT_KEY(bplib_os_wait_until_ms), 2, BP_TIMEOUT); + UtAssert_VOIDCALL( + bplib_mpool_subq_push_single(&buf.blk[0].u.flow.fblock.ingress.base_subq, &buf.blk[2].header.base_link)); + UtAssert_ZERO( + bplib_mpool_flow_try_move_all(&buf.blk[0].u.flow.fblock.ingress, &buf.blk[0].u.flow.fblock.egress, 100)); + UtAssert_STUB_COUNT(bplib_os_broadcast_signal, 2); } void test_bplib_mpool_flow_try_pull(void) @@ -74,6 +264,32 @@ void test_bplib_mpool_flow_try_pull(void) /* Test function for: * bplib_mpool_block_t *bplib_mpool_flow_try_pull(bplib_mpool_subq_workitem_t *subq_src, uint64_t abs_timeout) */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_flow, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_primary, 0); + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_primary, 0); + + UtAssert_NULL(bplib_mpool_flow_try_pull(&buf.blk[0].u.flow.fblock.ingress, 0)); + UtAssert_STUB_COUNT(bplib_os_broadcast_signal, 0); + + UtAssert_VOIDCALL(bplib_mpool_flow_enable(&buf.blk[0].u.flow.fblock.ingress, 1)); + UtAssert_VOIDCALL(bplib_mpool_flow_enable(&buf.blk[0].u.flow.fblock.egress, 1)); + UtAssert_VOIDCALL( + bplib_mpool_subq_push_single(&buf.blk[0].u.flow.fblock.egress.base_subq, &buf.blk[1].header.base_link)); + + UtAssert_ADDRESS_EQ(bplib_mpool_flow_try_pull(&buf.blk[0].u.flow.fblock.egress, 0), &buf.blk[1]); + UtAssert_STUB_COUNT(bplib_os_broadcast_signal, 1); + UtAssert_BOOL_TRUE(bplib_mpool_is_link_unattached(&buf.blk[1].header.base_link)); + + /* This time use a nonzero timeout */ + UtAssert_VOIDCALL( + bplib_mpool_subq_push_single(&buf.blk[0].u.flow.fblock.ingress.base_subq, &buf.blk[1].header.base_link)); + UT_SetHandlerFunction(UT_KEY(bplib_os_wait_until_ms), UT_AltHandler_MoveQueue, &buf.blk[0].u.flow.fblock); + UtAssert_ADDRESS_EQ(bplib_mpool_flow_try_pull(&buf.blk[0].u.flow.fblock.egress, 100), &buf.blk[1]); + UtAssert_STUB_COUNT(bplib_os_broadcast_signal, 2); } void test_bplib_mpool_flow_modify_flags(void) @@ -81,16 +297,68 @@ void test_bplib_mpool_flow_modify_flags(void) /* Test function for: * bool bplib_mpool_flow_modify_flags(bplib_mpool_block_t *cb, uint32_t set_bits, uint32_t clear_bits) */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_flow, 0); + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_primary, 0); + + UtAssert_BOOL_FALSE(bplib_mpool_flow_modify_flags(&buf.blk[1].header.base_link, 1, 2)); + UtAssert_BOOL_FALSE(bplib_mpool_flow_modify_flags(&buf.blk[0].header.base_link, 0, 0)); + UtAssert_BOOL_TRUE(bplib_mpool_flow_modify_flags(&buf.blk[0].header.base_link, 1, 2)); +} + +static int ut_flow_statechange_check(void *arg, bplib_mpool_block_t *jblk) +{ + return 0; +} + +void test_bplib_mpool_flow_event_handler(void) +{ + /* Test function for: + * static int bplib_mpool_flow_event_handler(void *arg, bplib_mpool_block_t *jblk) + */ + + bplib_mpool_block_content_t my_block; + bplib_mpool_flow_t *flow; + bplib_mpool_callback_func_t evhandler; + + memset(&my_block, 0, sizeof(my_block)); + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_flow, 0); + + flow = &my_block.u.flow.fblock; + evhandler = flow->statechange_job.base_job.handler; + flow->statechange_job.event_handler = ut_flow_statechange_check; + + UtAssert_INT32_EQ(evhandler(NULL, NULL), -1); + UtAssert_INT32_EQ(evhandler(NULL, &my_block.header.base_link), 0); + flow->pending_state_flags = BPLIB_MPOOL_FLOW_FLAGS_ADMIN_UP | BPLIB_MPOOL_FLOW_FLAGS_OPER_UP; + UtAssert_INT32_EQ(evhandler(NULL, &my_block.header.base_link), 0); + flow->pending_state_flags |= BPLIB_MPOOL_FLOW_FLAGS_POLL; + UtAssert_INT32_EQ(evhandler(NULL, &my_block.header.base_link), 0); + flow->pending_state_flags &= ~BPLIB_MPOOL_FLOW_FLAGS_OPER_UP; + UtAssert_INT32_EQ(evhandler(NULL, &my_block.header.base_link), 0); } void TestBplibMpoolFlows_Register(void) { - UtTest_Add(test_bplib_mpool_flow_cast, NULL, NULL, "bplib_mpool_flow_cast"); - UtTest_Add(test_bplib_mpool_flow_alloc, NULL, NULL, "bplib_mpool_flow_alloc"); - UtTest_Add(test_bplib_mpool_flow_disable, NULL, NULL, "bplib_mpool_flow_disable"); - UtTest_Add(test_bplib_mpool_flow_enable, NULL, NULL, "bplib_mpool_flow_enable"); - UtTest_Add(test_bplib_mpool_flow_try_push, NULL, NULL, "bplib_mpool_flow_try_push"); - UtTest_Add(test_bplib_mpool_flow_try_move_all, NULL, NULL, "bplib_mpool_flow_try_move_all"); - UtTest_Add(test_bplib_mpool_flow_try_pull, NULL, NULL, "bplib_mpool_flow_try_pull"); - UtTest_Add(test_bplib_mpool_flow_modify_flags, NULL, NULL, "bplib_mpool_flow_modify_flags"); + UtTest_Add(test_bplib_mpool_subq_merge_list, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_subq_merge_list"); + UtTest_Add(test_bplib_mpool_subq_move_all, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_subq_move_all"); + UtTest_Add(test_bplib_mpool_subq_drop_all, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_subq_drop_all"); + UtTest_Add(test_bplib_mpool_subq_pull_single, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_subq_pull_single"); + UtTest_Add(test_bplib_mpool_flow_cast, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_flow_cast"); + UtTest_Add(test_bplib_mpool_flow_alloc, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_flow_alloc"); + UtTest_Add(test_bplib_mpool_flow_disable, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_flow_disable"); + UtTest_Add(test_bplib_mpool_flow_enable, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_flow_enable"); + UtTest_Add(test_bplib_mpool_flow_try_push, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_flow_try_push"); + UtTest_Add(test_bplib_mpool_flow_try_move_all, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_flow_try_move_all"); + UtTest_Add(test_bplib_mpool_flow_try_pull, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_flow_try_pull"); + UtTest_Add(test_bplib_mpool_flow_modify_flags, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_flow_modify_flags"); + UtTest_Add(test_bplib_mpool_flow_event_handler, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_flow_event_handler"); } diff --git a/mpool/ut-coverage/test_bplib_v7_mpool_job.c b/mpool/ut-coverage/test_bplib_v7_mpool_job.c index 28131f53..bccec0f6 100644 --- a/mpool/ut-coverage/test_bplib_v7_mpool_job.c +++ b/mpool/ut-coverage/test_bplib_v7_mpool_job.c @@ -23,6 +23,163 @@ #include "utstubs.h" #include "uttest.h" +#include "test_bplib_mpool.h" #include "v7_mpool_job.h" -void TestBplibMpoolJob_Register(void) {} +struct UT_job_block +{ + bplib_mpool_block_header_t blkh; + bplib_mpool_job_t job; +}; + +union UT_job_block_content +{ + bplib_mpool_block_content_t reserved_space; + bplib_mpool_block_t block; + struct UT_job_block content; +}; + +struct UT_job_poolbuf +{ + bplib_mpool_t pool; + union UT_job_block_content u; +}; + +void test_bplib_mpool_job_init(void) +{ + /* Test function for: + * void bplib_mpool_job_init(bplib_mpool_block_t *base_block, bplib_mpool_job_t *jblk) + */ + struct UT_job_block buf; + + memset(&buf, 0, sizeof(buf)); + + UtAssert_VOIDCALL(bplib_mpool_job_init(&buf.blkh.base_link, &buf.job)); +} + +void test_bplib_mpool_job_cast(void) +{ + /* Test function for: + * bplib_mpool_job_t *bplib_mpool_job_cast(bplib_mpool_block_t *cb) + */ + bplib_mpool_block_t blk; + + UtAssert_NULL(bplib_mpool_job_cast(NULL)); + + memset(&blk, 0, sizeof(blk)); + UtAssert_NULL(bplib_mpool_job_cast(&blk)); + + blk.type = bplib_mpool_blocktype_job; + UtAssert_ADDRESS_EQ(bplib_mpool_job_cast(&blk), &blk); +} + +void test_bplib_mpool_job_mark_active(void) +{ + /* Test function for: + * void bplib_mpool_job_mark_active(bplib_mpool_job_t *job) + */ + struct UT_job_poolbuf buf; + bplib_mpool_block_admin_content_t *admin; + bplib_mpool_job_t *job; + + memset(&buf, 0, sizeof(buf)); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.u.reserved_space, bplib_mpool_blocktype_generic, 0); + + job = &buf.u.content.job; + admin = bplib_mpool_get_admin(&buf.pool); + + bplib_mpool_job_init(&buf.u.block, job); + + job->handler = test_bplib_mpool_callback_stub; + UtAssert_VOIDCALL(bplib_mpool_job_mark_active(job)); + UtAssert_ADDRESS_EQ(bplib_mpool_get_next_block(&admin->active_list), job); + + job->handler = NULL; + UtAssert_VOIDCALL(bplib_mpool_job_mark_active(job)); + UtAssert_BOOL_TRUE(bplib_mpool_is_empty_list_head(&admin->active_list)); + UtAssert_BOOL_TRUE(bplib_mpool_is_link_unattached(&job->link)); +} + +void test_bplib_mpool_job_get_next_active(void) +{ + /* Test function for: + * bplib_mpool_job_t *bplib_mpool_job_get_next_active(bplib_mpool_t *pool) + */ + + struct UT_job_poolbuf buf; + bplib_mpool_block_admin_content_t *admin; + bplib_mpool_job_t *job; + + memset(&buf, 0, sizeof(buf)); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.u.reserved_space, bplib_mpool_blocktype_generic, 0); + + job = &buf.u.content.job; + admin = bplib_mpool_get_admin(&buf.pool); + + bplib_mpool_job_init(&buf.u.block, job); + job->handler = test_bplib_mpool_callback_stub; + bplib_mpool_insert_after(&admin->active_list, &job->link); + + UtAssert_ADDRESS_EQ(bplib_mpool_job_get_next_active(&buf.pool), job); + UtAssert_BOOL_TRUE(bplib_mpool_is_empty_list_head(&admin->active_list)); + UtAssert_BOOL_TRUE(bplib_mpool_is_link_unattached(&job->link)); + + /* insert something into active_list that is NOT a job */ + bplib_mpool_insert_after(&admin->active_list, &buf.u.block); + UtAssert_NULL(bplib_mpool_job_get_next_active(&buf.pool)); +} + +void test_bplib_mpool_job_run_all(void) +{ + /* Test function for: + * void bplib_mpool_job_run_all(bplib_mpool_t *pool, void *arg) + */ + + struct UT_job_poolbuf buf; + bplib_mpool_block_admin_content_t *admin; + bplib_mpool_job_t *job; + + memset(&buf, 0, sizeof(buf)); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.u.reserved_space, bplib_mpool_blocktype_generic, 0); + + job = &buf.u.content.job; + admin = bplib_mpool_get_admin(&buf.pool); + + bplib_mpool_job_init(&buf.u.block, job); + job->handler = test_bplib_mpool_callback_stub; + bplib_mpool_insert_after(&admin->active_list, &job->link); + + UtAssert_VOIDCALL(bplib_mpool_job_run_all(&buf.pool, NULL)); + UtAssert_BOOL_TRUE(bplib_mpool_is_empty_list_head(&admin->active_list)); + UtAssert_BOOL_TRUE(bplib_mpool_is_link_unattached(&job->link)); + + job->handler = NULL; + bplib_mpool_insert_after(&admin->active_list, &job->link); + + UtAssert_VOIDCALL(bplib_mpool_job_run_all(&buf.pool, NULL)); + UtAssert_BOOL_TRUE(bplib_mpool_is_empty_list_head(&admin->active_list)); + UtAssert_BOOL_TRUE(bplib_mpool_is_link_unattached(&job->link)); +} + +void TestBplibMpoolJob_Register(void) +{ + UtTest_Add(test_bplib_mpool_job_init, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_job_init"); + UtTest_Add(test_bplib_mpool_job_cast, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_job_cast"); +#ifdef jphfix + UtTest_Add(test_bplib_mpool_job_cancel_internal, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_job_cancel_internal"); + UtTest_Add(test_bplib_mpool_job_mark_active_internal, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_job_mark_active_internal"); +#endif + UtTest_Add(test_bplib_mpool_job_mark_active, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_job_mark_active"); + UtTest_Add(test_bplib_mpool_job_get_next_active, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_job_get_next_active"); + UtTest_Add(test_bplib_mpool_job_run_all, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_job_run_all"); +} diff --git a/mpool/ut-coverage/test_bplib_v7_mpool_ref.c b/mpool/ut-coverage/test_bplib_v7_mpool_ref.c index 18b595f3..4ca19304 100644 --- a/mpool/ut-coverage/test_bplib_v7_mpool_ref.c +++ b/mpool/ut-coverage/test_bplib_v7_mpool_ref.c @@ -23,6 +23,119 @@ #include "utstubs.h" #include "uttest.h" +#include "test_bplib_mpool.h" #include "v7_mpool_ref.h" -void TestBplibMpoolRef_Register(void) {} +void test_bplib_mpool_ref_create(void) +{ + /* Test function for: + * bplib_mpool_ref_t bplib_mpool_ref_create(bplib_mpool_block_t *blk) + */ + bplib_mpool_block_content_t my_block; + + UtAssert_NULL(bplib_mpool_ref_create(NULL)); + + memset(&my_block, 0, sizeof(my_block)); + UtAssert_NULL(bplib_mpool_ref_create(&my_block.header.base_link)); + + test_setup_mpblock(NULL, &my_block, bplib_mpool_blocktype_generic, 0); + UtAssert_ADDRESS_EQ(bplib_mpool_ref_create(&my_block.header.base_link), &my_block); + UtAssert_UINT16_EQ(my_block.header.refcount, 1); +} + +void test_bplib_mpool_ref_duplicate(void) +{ + /* Test function for: + * bplib_mpool_ref_t bplib_mpool_ref_duplicate(bplib_mpool_ref_t refptr) + */ + bplib_mpool_block_content_t my_block; + + memset(&my_block, 0, sizeof(my_block)); + my_block.header.refcount = 1; + + UtAssert_ADDRESS_EQ(bplib_mpool_ref_duplicate(&my_block), &my_block); + UtAssert_UINT16_EQ(my_block.header.refcount, 2); +} + +void test_bplib_mpool_ref_from_block(void) +{ + /* Test function for: + * bplib_mpool_ref_t bplib_mpool_ref_from_block(bplib_mpool_block_t *rblk) + */ + bplib_mpool_block_content_t my_block; + bplib_mpool_block_content_t my_ref; + + memset(&my_block, 0, sizeof(my_block)); + memset(&my_ref, 0, sizeof(my_ref)); + + UtAssert_NULL(bplib_mpool_ref_from_block(NULL)); + UtAssert_NULL(bplib_mpool_ref_from_block(&my_block.header.base_link)); + + test_setup_mpblock(NULL, &my_ref, bplib_mpool_blocktype_ref, 0); + my_ref.u.ref.pref_target = &my_block; + my_block.header.refcount = 1; + UtAssert_ADDRESS_EQ(bplib_mpool_ref_from_block(&my_ref.header.base_link), &my_block); +} + +void test_bplib_mpool_ref_release(void) +{ + /* Test function for: + * void bplib_mpool_ref_release(bplib_mpool_ref_t refptr) + */ + UT_bplib_mpool_buf_t buf; + bplib_mpool_block_admin_content_t *admin; + + UtAssert_VOIDCALL(bplib_mpool_ref_release(NULL)); + + memset(&buf, 0, sizeof(buf)); + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + test_setup_mpblock(&buf.pool, &buf.blk[0], bplib_mpool_blocktype_generic, 0); + buf.blk[0].header.refcount = 2; + + admin = bplib_mpool_get_admin(&buf.pool); + + UtAssert_VOIDCALL(bplib_mpool_ref_release(&buf.blk[0])); + UtAssert_UINT16_EQ(buf.blk[0].header.refcount, 1); + UtAssert_BOOL_TRUE(bplib_mpool_is_empty_list_head(&admin->recycle_blocks.block_list)); + UtAssert_BOOL_TRUE(bplib_mpool_is_link_unattached(&buf.blk[0].header.base_link)); + + UtAssert_VOIDCALL(bplib_mpool_ref_release(&buf.blk[0])); + UtAssert_ZERO(buf.blk[0].header.refcount); + UtAssert_ADDRESS_EQ(bplib_mpool_get_prev_block(&admin->recycle_blocks.block_list), &buf.blk[0]); + + test_setup_mpblock(&buf.pool, &buf.blk[1], bplib_mpool_blocktype_generic, 0); + UtAssert_VOIDCALL(bplib_mpool_ref_release(&buf.blk[1])); + UtAssert_ADDRESS_EQ(bplib_mpool_get_prev_block(&admin->recycle_blocks.block_list), &buf.blk[1]); +} + +void test_bplib_mpool_ref_make_block(void) +{ + /* Test function for: + * bplib_mpool_block_t *bplib_mpool_ref_make_block(bplib_mpool_ref_t refptr, uint32_t magic_number, void *init_arg) + */ + UT_bplib_mpool_buf_t buf; + + memset(&buf, 0, sizeof(buf)); + + /* Nominal (need to do each blocktype that has a different init) */ + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + test_setup_mpblock(&buf.pool, &buf.blk[2], bplib_mpool_blocktype_generic, 0); + buf.blk[2].header.refcount = 1; + + UtAssert_ADDRESS_EQ(bplib_mpool_ref_make_block(&buf.blk[2], 0, NULL), &buf.blk[0]); + UtAssert_ADDRESS_EQ(buf.blk[0].u.ref.pref_target, &buf.blk[2]); + + /* Trying again should fail because the free list is now empty */ + UtAssert_NULL(bplib_mpool_ref_make_block(&buf.blk[2], 0, NULL)); +} + +void TestBplibMpoolRef_Register(void) +{ + UtTest_Add(test_bplib_mpool_ref_create, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_ref_create"); + UtTest_Add(test_bplib_mpool_ref_duplicate, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_ref_duplicate"); + UtTest_Add(test_bplib_mpool_ref_from_block, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_ref_from_block"); + UtTest_Add(test_bplib_mpool_ref_release, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_ref_release"); + UtTest_Add(test_bplib_mpool_ref_make_block, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_ref_make_block"); +} diff --git a/mpool/ut-coverage/test_bplib_v7_mpstream.c b/mpool/ut-coverage/test_bplib_v7_mpstream.c index 3df641c9..80a1ee59 100644 --- a/mpool/ut-coverage/test_bplib_v7_mpstream.c +++ b/mpool/ut-coverage/test_bplib_v7_mpstream.c @@ -23,6 +23,157 @@ #include "utstubs.h" #include "uttest.h" +#include "test_bplib_mpool.h" #include "v7_mpstream.h" -void TestBplibMpoolMPStream_Register(void) {} +static void test_setup_append_mps_block(bplib_mpool_t *pool, bplib_mpool_stream_t *mps, bplib_mpool_block_content_t *b, + uint8_t byte_val, size_t amount) +{ + test_setup_mpblock(pool, b, bplib_mpool_blocktype_generic, MPOOL_CACHE_CBOR_DATA_SIGNATURE); + b->header.user_content_length = amount; + memset(&b->u, byte_val, amount); + bplib_mpool_insert_before(&mps->head, &b->header.base_link); +} + +void test_bplib_mpool_start_stream_init(void) +{ + /* Test function for: + * void bplib_mpool_start_stream_init(bplib_mpool_stream_t *mps, bplib_mpool_t *pool, bplib_mpool_stream_dir_t + * dir); + */ + bplib_mpool_stream_t mps; + + UtAssert_VOIDCALL(bplib_mpool_start_stream_init(&mps, NULL, bplib_mpool_stream_dir_undefined)); +} + +void test_bplib_mpool_stream_write(void) +{ + /* Test function for: + * size_t bplib_mpool_stream_write(bplib_mpool_stream_t *mps, const void *data, size_t size); + */ + UT_bplib_mpool_buf_t buf; + bplib_mpool_stream_t mps; + uint8_t data[BP_MPOOL_MIN_USER_BLOCK_SIZE]; + + memset(&buf, 0, sizeof(buf)); + memset(&data, 0xEE, sizeof(data)); + + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + + UtAssert_VOIDCALL(bplib_mpool_start_stream_init(&mps, NULL, bplib_mpool_stream_dir_undefined)); + UtAssert_ZERO(bplib_mpool_stream_write(&mps, data, sizeof(data))); + + UtAssert_VOIDCALL(bplib_mpool_start_stream_init(&mps, &buf.pool, bplib_mpool_stream_dir_write)); + UtAssert_ZERO(bplib_mpool_stream_write(&mps, data, 0)); + UtAssert_UINT32_EQ(bplib_mpool_stream_write(&mps, data, sizeof(data) / 2), sizeof(data) / 2); + UtAssert_UINT32_EQ(bplib_mpool_stream_write(&mps, data, sizeof(data)), sizeof(data) / 2); + UtAssert_ZERO(bplib_mpool_stream_write(&mps, data, sizeof(data))); +} + +void test_bplib_mpool_stream_read(void) +{ + /* Test function for: + * size_t bplib_mpool_stream_read(bplib_mpool_stream_t *mps, void *data, size_t size); + */ + UT_bplib_mpool_buf_t buf; + bplib_mpool_stream_t mps; + uint8_t data[BP_MPOOL_MIN_USER_BLOCK_SIZE]; + + memset(&buf, 0, sizeof(buf)); + memset(&data, 0, sizeof(data)); + + UtAssert_VOIDCALL(bplib_mpool_start_stream_init(&mps, NULL, bplib_mpool_stream_dir_undefined)); + UtAssert_ZERO(bplib_mpool_stream_read(&mps, data, sizeof(data))); + + test_setup_mpblock(&buf.pool, &buf.pool.admin_block, bplib_mpool_blocktype_admin, 0); + + UtAssert_VOIDCALL(bplib_mpool_start_stream_init(&mps, &buf.pool, bplib_mpool_stream_dir_read)); + UtAssert_ZERO(bplib_mpool_stream_read(&mps, data, 0)); + UtAssert_ZERO(bplib_mpool_stream_read(&mps, data, sizeof(data))); + + test_setup_append_mps_block(&buf.pool, &mps, &buf.blk[0], 0xAA, sizeof(data) / 2); + test_setup_append_mps_block(&buf.pool, &mps, &buf.blk[1], 0xBB, sizeof(data) / 2); + UtAssert_UINT32_EQ(bplib_mpool_stream_read(&mps, data, sizeof(data) / 4), sizeof(data) / 4); + UtAssert_UINT32_EQ(bplib_mpool_stream_read(&mps, data, sizeof(data)), (3 * sizeof(data)) / 4); + UtAssert_ZERO(bplib_mpool_stream_read(&mps, data, sizeof(data))); +} + +void test_bplib_mpool_stream_seek(void) +{ + /* Test function for: + * size_t bplib_mpool_stream_seek(bplib_mpool_stream_t *mps, size_t target_position); + */ + UT_bplib_mpool_buf_t buf; + bplib_mpool_stream_t mps; + uint8_t data[BP_MPOOL_MIN_USER_BLOCK_SIZE]; + + memset(&buf, 0, sizeof(buf)); + memset(&data, 0xEE, sizeof(data)); + + UtAssert_VOIDCALL(bplib_mpool_start_stream_init(&mps, NULL, bplib_mpool_stream_dir_undefined)); + UtAssert_ZERO(bplib_mpool_stream_seek(&mps, 0)); + UtAssert_ZERO(bplib_mpool_stream_seek(&mps, sizeof(data))); + UtAssert_ZERO(bplib_mpool_stream_tell(&mps)); + + test_setup_allocation(&buf.pool, &buf.blk[0], &buf.blk[1]); + + /* Write streams are seekable beyond the end, which should extend the data */ + UtAssert_VOIDCALL(bplib_mpool_start_stream_init(&mps, &buf.pool, bplib_mpool_stream_dir_write)); + test_setup_append_mps_block(&buf.pool, &mps, &buf.blk[2], 0xCC, BP_MPOOL_MIN_USER_BLOCK_SIZE); + mps.last_eblk = &buf.blk[2].header.base_link; + mps.stream_position = BP_MPOOL_MIN_USER_BLOCK_SIZE; + mps.curr_pos = BP_MPOOL_MIN_USER_BLOCK_SIZE; + mps.curr_limit = BP_MPOOL_MIN_USER_BLOCK_SIZE; + UtAssert_UINT32_EQ(bplib_mpool_stream_seek(&mps, BP_MPOOL_MIN_USER_BLOCK_SIZE + sizeof(data)), + BP_MPOOL_MIN_USER_BLOCK_SIZE + sizeof(data)); + UtAssert_UINT32_EQ(bplib_mpool_stream_seek(&mps, 1), 1); + UtAssert_UINT32_EQ(bplib_mpool_stream_seek(&mps, sizeof(data) / 2), sizeof(data) / 2); + UtAssert_UINT32_EQ(bplib_mpool_stream_tell(&mps), sizeof(data) / 2); + + /* Read streams are NOT seekable beyond the end */ + UtAssert_VOIDCALL(bplib_mpool_start_stream_init(&mps, &buf.pool, bplib_mpool_stream_dir_read)); + test_setup_append_mps_block(&buf.pool, &mps, &buf.blk[0], 0xAA, sizeof(data) / 2); + test_setup_append_mps_block(&buf.pool, &mps, &buf.blk[1], 0xBB, sizeof(data) / 2); + UtAssert_UINT32_EQ(bplib_mpool_stream_seek(&mps, 2 * sizeof(data)), sizeof(data)); + UtAssert_UINT32_EQ(bplib_mpool_stream_seek(&mps, sizeof(data) / 4), sizeof(data) / 4); + UtAssert_UINT32_EQ(bplib_mpool_stream_tell(&mps), sizeof(data) / 4); +} + +void test_bplib_mpool_stream_attach(void) +{ + /* Test function for: + * void bplib_mpool_stream_attach(bplib_mpool_stream_t *mps, bplib_mpool_block_t *head); + */ + bplib_mpool_stream_t mps; + bplib_mpool_block_t list; + + UtAssert_VOIDCALL(bplib_mpool_start_stream_init(&mps, NULL, bplib_mpool_stream_dir_undefined)); + + bplib_mpool_init_list_head(NULL, &list); + UtAssert_VOIDCALL(bplib_mpool_stream_attach(&mps, &list)); +} + +void test_bplib_mpool_stream_close(void) +{ + /* Test function for: + * void bplib_mpool_stream_close(bplib_mpool_stream_t *mps); + */ + bplib_mpool_t pool; + bplib_mpool_stream_t mps; + + test_setup_mpblock(&pool, &pool.admin_block, bplib_mpool_blocktype_admin, 0); + + UtAssert_VOIDCALL(bplib_mpool_start_stream_init(&mps, &pool, bplib_mpool_stream_dir_undefined)); + UtAssert_VOIDCALL(bplib_mpool_stream_close(&mps)); +} + +void TestBplibMpoolMPStream_Register(void) +{ + UtTest_Add(test_bplib_mpool_start_stream_init, TestBplibMpool_ResetTestEnvironment, NULL, + "bplib_mpool_start_stream_init"); + UtTest_Add(test_bplib_mpool_stream_write, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_stream_write"); + UtTest_Add(test_bplib_mpool_stream_read, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_stream_read"); + UtTest_Add(test_bplib_mpool_stream_seek, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_stream_seek"); + UtTest_Add(test_bplib_mpool_stream_attach, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_stream_attach"); + UtTest_Add(test_bplib_mpool_stream_close, TestBplibMpool_ResetTestEnvironment, NULL, "bplib_mpool_stream_close"); +}