net: buf: Add fragmentation API tests

Add tests for checking that the net_buf fragmentation works ok.

Change-Id: I778f79bae971314b6f19c1bf00ed42e1c2128e99
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2016-04-25 16:39:04 +03:00 committed by Johan Hedberg
parent 8a80ce5c6f
commit 7d6197cf94

View file

@ -43,8 +43,11 @@ struct bt_data {
};
static int destroy_called;
static int frag_destroy_called;
static struct nano_fifo bufs_fifo;
static struct nano_fifo no_data_buf_fifo;
static struct nano_fifo frags_fifo;
static void buf_destroy(struct net_buf *buf)
{
@ -59,9 +62,25 @@ static void buf_destroy(struct net_buf *buf)
nano_fifo_put(buf->free, buf);
}
static void frag_destroy(struct net_buf *buf)
{
frag_destroy_called++;
if (buf->free != &frags_fifo) {
printk("Invalid free frag pointer in buffer!\n");
} else {
nano_fifo_put(buf->free, buf);
}
}
static NET_BUF_POOL(bufs_pool, 22, 74, &bufs_fifo, buf_destroy,
sizeof(struct bt_data));
static NET_BUF_POOL(no_data_buf_pool, 1, 0, &no_data_buf_fifo, NULL,
sizeof(struct bt_data));
static NET_BUF_POOL(frags_pool, 13, 128, &frags_fifo, frag_destroy, 0);
static bool net_buf_test_1(void)
{
struct net_buf *bufs[ARRAY_SIZE(bufs_pool)];
@ -154,8 +173,9 @@ static void test_3_fiber(int arg1, int arg2)
net_buf_unref(buf);
if (destroy_called != ARRAY_SIZE(bufs_pool)) {
printk("Incorrect fragment destroy callback count: %d\n",
destroy_called);
printk("Incorrect fragment destroy callback count: %d "
"should be %d\n", destroy_called,
ARRAY_SIZE(bufs_pool));
return;
}
@ -214,6 +234,160 @@ static bool net_buf_test_3(void)
return true;
}
static bool net_buf_test_4(void)
{
struct net_buf *frags[ARRAY_SIZE(frags_pool)];
struct net_buf *buf, *frag;
int i, removed;
DBG("sizeof(struct net_buf) = %u\n", sizeof(struct net_buf));
DBG("sizeof(frags_pool) = %u\n", sizeof(frags_pool));
net_buf_pool_init(no_data_buf_pool);
net_buf_pool_init(frags_pool);
/* Create a buf that does not have any data to store, it just
* contains link to fragments.
*/
buf = net_buf_get(&no_data_buf_fifo, 0);
if (buf->size != 0) {
DBG("Invalid buf size %d\n", buf->size);
return false;
}
/* Test the fragments by appending after last fragment */
for (i = 0; i < ARRAY_SIZE(frags_pool) - 1; i++) {
frag = net_buf_get(&frags_fifo, 0);
net_buf_frag_add(buf, frag);
frags[i] = frag;
}
/* And one as a first fragment */
frag = net_buf_get(&frags_fifo, 0);
net_buf_frag_insert(buf, frag);
frags[i] = frag;
frag = buf->frags;
if (frag->user_data_size != 0) {
DBG("Invalid user data size %d\n", frag->user_data_size);
return false;
}
i = 0;
while (frag) {
frag = frag->frags;
i++;
}
if (i != ARRAY_SIZE(frags_pool)) {
DBG("Incorrect fragment count: %d vs %d\n",
i, ARRAY_SIZE(frags_pool));
return false;
}
/* Remove about half of the fragments and verify count */
i = removed = 0;
frag = buf->frags;
while (frag) {
struct net_buf *next = frag->frags;
if ((i % 2) && next) {
net_buf_frag_del(frag, next);
net_buf_unref(next);
removed++;
} else {
frag = next;
}
i++;
}
i = 0;
frag = buf->frags;
while (frag) {
frag = frag->frags;
i++;
}
if ((i + removed) != ARRAY_SIZE(frags_pool)) {
DBG("Incorrect removed fragment count: %d vs %d\n",
i + removed, ARRAY_SIZE(frags_pool));
return false;
}
removed = 0;
while (buf->frags) {
struct net_buf *frag = buf->frags;
net_buf_frag_del(buf, frag);
net_buf_unref(frag);
removed++;
}
if (removed != i) {
DBG("Not all fragments were removed: %d vs %d\n",
i, removed);
return false;
}
if (frag_destroy_called != ARRAY_SIZE(frags_pool)) {
DBG("Incorrect frag destroy callback count: %d vs %d\n",
frag_destroy_called, ARRAY_SIZE(frags_pool));
return false;
}
/* Add the fragments back and verify that they are properly unref
* by freeing the top buf.
*/
for (i = 0; i < ARRAY_SIZE(frags_pool) - 3; i++) {
net_buf_frag_add(buf, net_buf_get(&frags_fifo, 0));
}
/* Create a fragment list and add it to frags list after first
* element
*/
frag = net_buf_get(&frags_fifo, 0);
net_buf_frag_add(frag, net_buf_get(&frags_fifo, 0));
net_buf_frag_insert(frag, net_buf_get(&frags_fifo, 0));
net_buf_frag_insert(buf->frags->frags, frag);
i = 0;
frag = buf->frags;
while (frag) {
frag = frag->frags;
i++;
}
if (i != ARRAY_SIZE(frags_pool)) {
DBG("Incorrect fragment count: %d vs %d\n",
i, ARRAY_SIZE(frags_pool));
return false;
}
frag_destroy_called = 0;
net_buf_unref(buf);
if (frag_destroy_called != 0) {
DBG("Wrong frag destroy callback count\n");
return false;
}
for (i = 0; i < ARRAY_SIZE(frags_pool); i++) {
net_buf_unref(frags[i]);
}
if (frag_destroy_called != ARRAY_SIZE(frags_pool)) {
DBG("Incorrect frag destroy count: %d vs %d\n",
frag_destroy_called, ARRAY_SIZE(frags_pool));
return false;
}
return true;
}
static const struct {
const char *name;
bool (*func)(void);
@ -221,6 +395,7 @@ static const struct {
{ "Test 1", net_buf_test_1, },
{ "Test 2", net_buf_test_2, },
{ "Test 3", net_buf_test_3, },
{ "Test 4", net_buf_test_4, },
};
void main(void)