blob: bf010142f7d6faf8f6b3936865218a04e1145889 [file] [log] [blame]
/*
* Copyright The Transfer List Library Contributors
*
* SPDX-License-Identifier: MIT OR GPL-2.0-or-later
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "test.h"
#include "transfer_list.h"
#include "unity.h"
void *buffer = NULL;
char *test_page_data = NULL;
uint8_t byte_sum(const char *ptr, size_t len)
{
uint8_t sum = 0;
for (size_t i = 0; i < len; i++) {
sum += ptr[i];
}
return sum;
}
static void setup_test_entries(struct transfer_list_header *tl,
unsigned int tag_base, unsigned int num_entries,
struct transfer_list_entry **entries)
{
unsigned int i;
unsigned int te_data_size;
struct transfer_list_entry *te;
te_data_size = tl->max_size / (num_entries * 2);
for (i = 0; i < num_entries; i++) {
TEST_ASSERT(transfer_list_add(tl, tag_base + i, te_data_size,
test_page_data));
TEST_ASSERT(te = transfer_list_find(tl, tag_base + i));
TEST_ASSERT(byte_sum((void *)tl, tl->size) == 0);
entries[i] = te;
}
}
void test_add()
{
struct transfer_list_header *tl;
struct transfer_list_entry *te;
TEST_ASSERT(tl = transfer_list_init((void *)buffer, TL_SIZE));
TEST_ASSERT(te = transfer_list_add(tl, test_tag, sizeof(test_data),
&test_data));
TEST_ASSERT_EQUAL(0, byte_sum((char *)tl, tl->max_size));
TEST_ASSERT(*(int *)transfer_list_entry_data(te) == test_data);
/* Try to add a TE larger greater than allocated TL space */
TEST_ASSERT_NULL(te = transfer_list_add(tl, 2, TL_SIZE, &test_data));
TEST_ASSERT_EQUAL(0, byte_sum((char *)tl, tl->max_size));
TEST_ASSERT_NULL(transfer_list_find(tl, 0x2));
unsigned int tags[4] = { TAG_GENERIC_START, TAG_GENERIC_END,
TAG_NON_STANDARD_START, TAG_NON_STANDARD_END };
for (size_t i = 0; i < 4; i++) {
TEST_ASSERT(te = transfer_list_add(tl, tags[i],
sizeof(test_data),
&test_data));
TEST_ASSERT_EQUAL(0, byte_sum((char *)tl, tl->max_size));
TEST_ASSERT(te = transfer_list_find(tl, tags[i]));
TEST_ASSERT(*(int *)transfer_list_entry_data(te) == test_data);
}
transfer_list_dump(tl);
/* Add some out of bound tags. */
TEST_ASSERT_NULL(
transfer_list_add(tl, 1 << 24, sizeof(test_data), &test_data));
TEST_ASSERT_NULL(
transfer_list_add(tl, -1, sizeof(test_data), &test_data));
}
void test_add_with_align()
{
struct transfer_list_header *tl =
transfer_list_init(buffer, TL_MAX_SIZE);
struct transfer_list_entry *te;
unsigned int test_id = 1;
const unsigned int entry_size = 0xff;
int *data;
TEST_ASSERT(tl->size == tl->hdr_size);
/*
* When a new TE with a larger alignment requirement than already exists
* appears, the TE should be added and TL alignement updated.
*/
for (char align = 0; align < (1 << 4); align++, test_id++) {
TEST_ASSERT(
te = transfer_list_add_with_align(
tl, test_id, entry_size, &test_data, align));
TEST_ASSERT(tl->alignment >= align);
TEST_ASSERT(te = transfer_list_find(tl, test_id));
TEST_ASSERT(data = transfer_list_entry_data(te));
TEST_ASSERT_FALSE((uintptr_t)data % (1 << align));
TEST_ASSERT_EQUAL(*(int *)data, test_data);
}
}
void test_rem()
{
struct transfer_list_header *tl = transfer_list_init(buffer, TL_SIZE);
struct transfer_list_entry *te[3];
unsigned int tag_base = test_tag;
TEST_ASSERT_EQUAL(tl->size, tl->hdr_size);
setup_test_entries(tl, tag_base, 3, te);
/* Remove the TE and make sure it does not present in the TL. */
TEST_ASSERT_TRUE(transfer_list_rem(tl, te[0]));
TEST_ASSERT(byte_sum((void *)tl, tl->size) == 0);
TEST_ASSERT_NULL(transfer_list_find(tl, tag_base));
/* Remove the TE3 and make sure it does not present in the TL. */
TEST_ASSERT_TRUE(transfer_list_rem(tl, te[2]));
TEST_ASSERT(byte_sum((void *)tl, tl->size) == 0);
TEST_ASSERT_NULL(transfer_list_find(tl, tag_base + 2));
/* Remove the TE2 and make sure it does not present in the TL. */
TEST_ASSERT_TRUE(transfer_list_rem(tl, te[1]));
TEST_ASSERT(byte_sum((void *)tl, tl->size) == 0);
TEST_ASSERT_NULL(transfer_list_find(tl, tag_base + 1));
/*
* Should have only one TL_TAG_EMPTY entry.
*/
TEST_ASSERT(te[0] = transfer_list_find(tl, TL_TAG_EMPTY));
TEST_ASSERT(transfer_list_next(tl, te[0]) == NULL);
}
void test_set_data_size()
{
struct transfer_list_header *tl = transfer_list_init(buffer, TL_SIZE);
struct transfer_list_entry *te[3];
unsigned int tag_base = test_tag;
unsigned int tl_size;
TEST_ASSERT_EQUAL(tl->size, tl->hdr_size);
setup_test_entries(tl, tag_base, 3, te);
/* Remove the TE2 and make sure it does not present in the TL. */
TEST_ASSERT_TRUE(transfer_list_rem(tl, te[1]));
TEST_ASSERT(byte_sum((void *)tl, tl->size) == 0);
TEST_ASSERT_NULL(transfer_list_find(tl, tag_base + 1));
/*
* Increase te size to tl->max_size / 4, this shouldn't increase the
* current transfer list's size since it will be increased with
* adjacent TL_TAG_EMPTY entry.
*/
tl_size = tl->size;
TEST_ASSERT(transfer_list_set_data_size(tl, te[0], tl->max_size / 4));
TEST_ASSERT(byte_sum((void *)tl, tl->size) == 0);
TEST_ASSERT(te[0]->data_size == tl->max_size / 4);
TEST_ASSERT(tl_size == tl->size);
/*
* Increase te size to tl->max_size / 2, this increases
* the transfer list size.
*/
tl_size = tl->size;
TEST_ASSERT(transfer_list_set_data_size(tl, te[0], tl->max_size / 2));
TEST_ASSERT(byte_sum((void *)tl, tl->size) == 0);
TEST_ASSERT(te[0]->data_size == tl->max_size / 2);
TEST_ASSERT(tl_size < tl->size);
}
void setUp(void)
{
buffer = malloc(TL_MAX_SIZE);
test_page_data = malloc(TL_SIZE);
memset(test_page_data, 0xff, TL_SIZE);
}
void tearDown(void)
{
free(test_page_data);
free(buffer);
buffer = NULL;
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_add);
RUN_TEST(test_add_with_align);
RUN_TEST(test_rem);
RUN_TEST(test_set_data_size);
return UNITY_END();
}