tests: kernel: added memory pool api test

TestPurpose: verify memory pool APIs.
All TESTPOINTs extracted from kernel-doc comments in <kernel.h>

ZEP-1210

Change-Id: I7dcc0638e7b9c4d6b5ffe282e4fe41ca520d003f
Signed-off-by: Sharron LIU <sharron.liu@intel.com>
This commit is contained in:
Sharron LIU 2016-12-28 11:36:47 +08:00 committed by Anas Nashif
commit 415e71e04c
8 changed files with 304 additions and 0 deletions

View file

@ -0,0 +1,4 @@
BOARD ?= qemu_x86
CONF_FILE = prj.conf
include ${ZEPHYR_BASE}/Makefile.test

View file

@ -0,0 +1,2 @@
CONFIG_ZTEST=y
CONFIG_IRQ_OFFLOAD=y

View file

@ -0,0 +1,3 @@
include $(ZEPHYR_BASE)/tests/Makefile.test
obj-y = main.o test_mpool_api.o test_mpool_extern.o

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <ztest.h>
extern void test_mpool_alloc_free_thread(void);
extern void test_mpool_alloc_free_isr(void);
extern void test_mpool_kdefine_extern(void);
extern void test_mpool_alloc_size(void);
extern void test_mpool_alloc_timeout(void);
extern void test_mpool_defrag(void);
/*test case main entry*/
void test_main(void *p1, void *p2, void *p3)
{
ztest_test_suite(test_mpool_api,
ztest_unit_test(test_mpool_alloc_free_thread),
ztest_unit_test(test_mpool_alloc_free_isr),
ztest_unit_test(test_mpool_kdefine_extern),
ztest_unit_test(test_mpool_alloc_size),
ztest_unit_test(test_mpool_alloc_timeout),
ztest_unit_test(test_mpool_defrag));
ztest_run_test_suite(test_mpool_api);
}

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __TEST_MPOOL_H__
#define __TEST_MPOOL_H__
#define TIMEOUT 100
#define BLK_SIZE_MIN 4
#define BLK_SIZE_MAX 64
#define BLK_NUM_MIN 32
#define BLK_NUM_MAX 2
#define BLK_ALIGN BLK_SIZE_MIN
extern void tmpool_alloc_free(void *data);
#endif /*__TEST_MPOOL_H__*/

View file

@ -0,0 +1,196 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @addtogroup t_mpool
* @{
* @defgroup t_mpool_api test_mpool_api
* @brief TestPurpose: verify memory pool APIs.
* @details All TESTPOINTs extracted from kernel-doc comments in <kernel.h>
* - API coverage
* -# K_MEM_POOL_DEFINE
* -# k_mem_pool_alloc
* -# k_mem_pool_free
* -# k_mem_pool_defrag
* @}
*/
#include <ztest.h>
#include <irq_offload.h>
#include "test_mpool.h"
/** TESTPOINT: Statically define and initialize a memory pool*/
K_MEM_POOL_DEFINE(kmpool, BLK_SIZE_MIN, BLK_SIZE_MAX, BLK_NUM_MAX, BLK_ALIGN);
void tmpool_alloc_free(void *data)
{
ARG_UNUSED(data);
struct k_mem_block block[BLK_NUM_MIN];
for (int i = 0; i < BLK_NUM_MIN; i++) {
/**
* TESTPOINT: This routine allocates a memory block from a
* memory pool.
*/
/**
* TESTPOINT: @retval 0 Memory allocated. The @a data field of
* the block descriptor is set to the starting address of the
* memory block.
*/
assert_true(k_mem_pool_alloc(&kmpool, &block[i], BLK_SIZE_MIN,
K_NO_WAIT) == 0, NULL);
assert_not_null(block[i].data, NULL);
}
for (int i = 0; i < BLK_NUM_MIN; i++) {
/**
* TESTPOINT: This routine releases a previously allocated
* memory block back to its memory pool.
*/
k_mem_pool_free(&block[i]);
block[i].data = NULL;
}
/**
* TESTPOINT: The memory pool's buffer contains @a n_max blocks that are
* @a max_size bytes long.
*/
for (int i = 0; i < BLK_NUM_MAX; i++) {
assert_true(k_mem_pool_alloc(&kmpool, &block[i], BLK_SIZE_MAX,
K_NO_WAIT) == 0, NULL);
assert_not_null(block[i].data, NULL);
}
for (int i = 0; i < BLK_NUM_MAX; i++) {
k_mem_pool_free(&block[i]);
block[i].data = NULL;
}
}
/*test cases*/
void test_mpool_alloc_free_thread(void)
{
tmpool_alloc_free(NULL);
}
void test_mpool_alloc_free_isr(void)
{
irq_offload(tmpool_alloc_free, NULL);
}
void test_mpool_alloc_size(void)
{
struct k_mem_block block[BLK_NUM_MIN];
size_t size = BLK_SIZE_MAX;
int i = 0;
/**TESTPOINT: The memory pool allows blocks to be repeatedly partitioned
* into quarters, down to blocks of @a min_size bytes long.
*/
while (size >= BLK_SIZE_MIN) {
assert_true(k_mem_pool_alloc(&kmpool, &block[i], size,
K_NO_WAIT) == 0, NULL);
assert_not_null(block[i].data, NULL);
assert_true((uint32_t)(block[i++].data) % BLK_ALIGN == 0, NULL);
size = size >> 2;
}
while (i--) {
k_mem_pool_free(&block[i]);
block[i].data = NULL;
}
i = 0;
size = BLK_SIZE_MIN;
/**TESTPOINT: To ensure that all blocks in the buffer are similarly
* aligned to this boundary, min_size must also be a multiple of align.
*/
while (size <= BLK_SIZE_MAX) {
assert_true(k_mem_pool_alloc(&kmpool, &block[i], size,
K_NO_WAIT) == 0, NULL);
assert_not_null(block[i].data, NULL);
assert_true((uint32_t)(block[i++].data) % BLK_ALIGN == 0, NULL);
size = size << 2;
}
while (i--) {
k_mem_pool_free(&block[i]);
block[i].data = NULL;
}
}
void test_mpool_alloc_timeout(void)
{
struct k_mem_block block[BLK_NUM_MIN], fblock;
uint64_t tms;
for (int i = 0; i < BLK_NUM_MIN; i++) {
assert_equal(k_mem_pool_alloc(&kmpool, &block[i], BLK_SIZE_MIN,
K_NO_WAIT), 0, NULL);
}
/** TESTPOINT: Use K_NO_WAIT to return without waiting*/
/** TESTPOINT: @retval -ENOMEM Returned without waiting*/
assert_equal(k_mem_pool_alloc(&kmpool, &fblock, BLK_SIZE_MIN,
K_NO_WAIT), -ENOMEM, NULL);
/** TESTPOINT: @retval -EAGAIN Waiting period timed out*/
tms = k_uptime_get();
assert_equal(k_mem_pool_alloc(&kmpool, &fblock, BLK_SIZE_MIN, TIMEOUT),
-EAGAIN, NULL);
/**
* TESTPOINT: Maximum time to wait for operation to complete (in
* milliseconds)
*/
assert_true(k_uptime_delta(&tms) >= TIMEOUT, NULL);
for (int i = 0; i < BLK_NUM_MIN; i++) {
k_mem_pool_free(&block[i]);
block[i].data = NULL;
}
}
void test_mpool_defrag(void)
{
struct k_mem_block block[BLK_NUM_MIN];
/*fragment the memory pool into small blocks*/
for (int i = 0; i < BLK_NUM_MIN; i++) {
assert_true(k_mem_pool_alloc(&kmpool, &block[i], BLK_SIZE_MIN,
K_NO_WAIT) == 0, NULL);
}
/*free the small blocks in the 1st half of the pool*/
for (int i = 0; i < (BLK_NUM_MIN >> 1); i++) {
k_mem_pool_free(&block[i]);
}
/*request a big block, the pool has "adjacent free blocks" to merge*/
assert_true(k_mem_pool_alloc(&kmpool, &block[0], BLK_SIZE_MAX,
K_FOREVER) == 0, NULL);
/*free the small blocks in the 2nd half of the pool*/
for (int i = (BLK_NUM_MIN >> 1); i < BLK_NUM_MIN; i++) {
k_mem_pool_free(&block[i]);
}
/**
* TESTPOINT: This routine instructs a memory pool to concatenate unused
* memory blocks into larger blocks wherever possible.
*/
/*do manual de-fragment*/
k_mem_pool_defrag(&kmpool);
/*request a big block, the pool is de-fragmented*/
assert_true(k_mem_pool_alloc(&kmpool, &block[1], BLK_SIZE_MAX,
K_NO_WAIT) == 0, NULL);
/*free the big blocks*/
for (int i = 0; i < BLK_NUM_MAX; i++) {
k_mem_pool_free(&block[i]);
}
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <ztest.h>
#include "test_mpool.h"
/**
* TESTPOINT: If the pool is to be accessed outside the module where it is
* defined, it can be declared via @code extern struct k_mem_pool <name>
* @endcode
*/
extern struct k_mem_pool kmpool;
/*test cases*/
void test_mpool_kdefine_extern(void)
{
tmpool_alloc_free(NULL);
}

View file

@ -0,0 +1,2 @@
[test]
tags = kernel