chiaki/test/reorderqueue.c
2021-01-01 11:09:13 +01:00

186 lines
6.4 KiB
C

// SPDX-License-Identifier: LicenseRef-AGPL-3.0-only-OpenSSL
#include <munit.h>
#include <chiaki/reorderqueue.h>
#define DROP_RECORD_MAX 16
typedef struct drop_record_t
{
uint64_t count[DROP_RECORD_MAX];
uint64_t seq_num[DROP_RECORD_MAX];
bool failed;
} DropRecord;
static void drop(uint64_t seq_num, void *elem_user, void *cb_user)
{
DropRecord *record = cb_user;
uint64_t v = (uint64_t)(size_t)elem_user;
if(v > DROP_RECORD_MAX)
{
record->failed = true;
return;
}
record->count[v]++;
record->seq_num[v] = seq_num;
}
static MunitResult test_reorder_queue_16(const MunitParameter params[], void *test_user)
{
ChiakiReorderQueue queue;
ChiakiErrorCode err = chiaki_reorder_queue_init_16(&queue, 2, 42);
munit_assert_int(err, ==, CHIAKI_ERR_SUCCESS);
munit_assert_size(chiaki_reorder_queue_size(&queue), ==, 4);
munit_assert_uint64(chiaki_reorder_queue_count(&queue), ==, 0);
chiaki_reorder_queue_set_drop_strategy(&queue, CHIAKI_REORDER_QUEUE_DROP_STRATEGY_END);
DropRecord drop_record = { 0 };
chiaki_reorder_queue_set_drop_cb(&queue, drop, &drop_record);
uint64_t seq_num = 0;
void *user = NULL;
// pull from empty
bool pulled = chiaki_reorder_queue_pull(&queue, &seq_num, &user);
munit_assert(!pulled);
munit_assert_uint64(chiaki_reorder_queue_count(&queue), ==, 0);
munit_assert(!drop_record.failed);
// push one
chiaki_reorder_queue_push(&queue, 42, (void *)0);
munit_assert_uint64(chiaki_reorder_queue_count(&queue), ==, 1);
// pull one
pulled = chiaki_reorder_queue_pull(&queue, &seq_num, &user);
munit_assert(pulled);
munit_assert_uint64(chiaki_reorder_queue_count(&queue), ==, 0);
munit_assert(!drop_record.failed);
munit_assert_uint64(drop_record.count[0], ==, 0);
munit_assert_uint64((uint64_t)(size_t)user, ==, 0);
munit_assert_uint64(seq_num, ==, 42);
// push outdated
chiaki_reorder_queue_push(&queue, 42, (void *)0);
munit_assert_uint64(chiaki_reorder_queue_count(&queue), ==, 0);
munit_assert(!drop_record.failed);
munit_assert_uint64(drop_record.count[0], ==, 1);
munit_assert_uint64(drop_record.seq_num[0], ==, 42);
memset(&drop_record, 0, sizeof(drop_record));
// push until full out of order and try to pull in between
chiaki_reorder_queue_push(&queue, 46, (void *)1);
pulled = chiaki_reorder_queue_pull(&queue, &seq_num, &user);
munit_assert(!pulled);
chiaki_reorder_queue_push(&queue, 45, (void *)2);
pulled = chiaki_reorder_queue_pull(&queue, &seq_num, &user);
munit_assert(!pulled);
chiaki_reorder_queue_push(&queue, 44, (void *)3);
pulled = chiaki_reorder_queue_pull(&queue, &seq_num, &user);
munit_assert(!pulled);
chiaki_reorder_queue_push(&queue, 43, (void *)4);
munit_assert(!drop_record.failed);
for(size_t i=0; i<DROP_RECORD_MAX; i++)
munit_assert_uint64(drop_record.count[i], ==, 0);
// push more, because of CHIAKI_REORDER_QUEUE_DROP_STRATEGY_END this should be dropped
chiaki_reorder_queue_push(&queue, 47, (void *)5);
munit_assert(!drop_record.failed);
for(size_t i=0; i<DROP_RECORD_MAX; i++)
munit_assert_uint64(drop_record.count[i], ==, i == 5 ? 1 : 0);
munit_assert_uint64(drop_record.seq_num[5], ==, 47);
memset(&drop_record, 0, sizeof(drop_record));
// push more with CHIAKI_REORDER_QUEUE_DROP_STRATEGY_BEGIN, so older elements should be dropped
chiaki_reorder_queue_set_drop_strategy(&queue, CHIAKI_REORDER_QUEUE_DROP_STRATEGY_BEGIN);
chiaki_reorder_queue_push(&queue, 47, (void *)5);
munit_assert(!drop_record.failed);
for(size_t i=0; i<DROP_RECORD_MAX; i++)
munit_assert_uint64(drop_record.count[i], ==, i == 4 ? 1 : 0);
munit_assert_uint64(drop_record.seq_num[4], ==, 43);
memset(&drop_record, 0, sizeof(drop_record));
// pull all, elements should arrive in order
pulled = chiaki_reorder_queue_pull(&queue, &seq_num, &user);
munit_assert(pulled);
munit_assert_uint64(seq_num, ==, 44);
munit_assert_uint64((uint64_t)(size_t)user, ==, 3);
pulled = chiaki_reorder_queue_pull(&queue, &seq_num, &user);
munit_assert(pulled);
munit_assert_uint64(seq_num, ==, 45);
munit_assert_uint64((uint64_t)(size_t)user, ==, 2);
pulled = chiaki_reorder_queue_pull(&queue, &seq_num, &user);
munit_assert(pulled);
munit_assert_uint64(seq_num, ==, 46);
munit_assert_uint64((uint64_t)(size_t)user, ==, 1);
pulled = chiaki_reorder_queue_pull(&queue, &seq_num, &user);
munit_assert(pulled);
munit_assert_uint64(seq_num, ==, 47);
munit_assert_uint64((uint64_t)(size_t)user, ==, 5);
// should be empty now again
pulled = chiaki_reorder_queue_pull(&queue, &seq_num, &user);
munit_assert(!pulled);
munit_assert_uint64(chiaki_reorder_queue_count(&queue), ==, 0);
munit_assert(!drop_record.failed);
for(size_t i=0; i<DROP_RECORD_MAX; i++)
munit_assert_uint64(drop_record.count[i], ==, 0);
// now push something much higher, because of CHIAKI_REORDER_QUEUE_DROP_STRATEGY_BEGIN, the queue should be relocated
chiaki_reorder_queue_push(&queue, 1337, (void *)6);
munit_assert_uint64(chiaki_reorder_queue_count(&queue), ==, 1);
munit_assert(!drop_record.failed);
for(size_t i=0; i<DROP_RECORD_MAX; i++)
munit_assert_uint64(drop_record.count[i], ==, 0);
// and pull again
pulled = chiaki_reorder_queue_pull(&queue, &seq_num, &user);
munit_assert(pulled);
munit_assert_uint64(seq_num, ==, 1337);
munit_assert_uint64((uint64_t)(size_t)user, ==, 6);
munit_assert_uint64(chiaki_reorder_queue_count(&queue), ==, 0);
// same as before, but with an element in the queue that will be dropped
chiaki_reorder_queue_push(&queue, 1338, (void *)7);
munit_assert_uint64(chiaki_reorder_queue_count(&queue), ==, 1);
munit_assert(!drop_record.failed);
for(size_t i=0; i<DROP_RECORD_MAX; i++)
munit_assert_uint64(drop_record.count[i], ==, 0);
chiaki_reorder_queue_push(&queue, 2000, (void *)8);
munit_assert_uint64(chiaki_reorder_queue_count(&queue), ==, 1);
munit_assert(!drop_record.failed);
for(size_t i=0; i<DROP_RECORD_MAX; i++)
munit_assert_uint64(drop_record.count[i], ==, i == 7 ? 1 : 0);
munit_assert_uint64(drop_record.seq_num[7], ==, 1338);
// pull again
pulled = chiaki_reorder_queue_pull(&queue, &seq_num, &user);
munit_assert(pulled);
munit_assert_uint64(seq_num, ==, 2000);
munit_assert_uint64((uint64_t)(size_t)user, ==, 8);
munit_assert_uint64(chiaki_reorder_queue_count(&queue), ==, 0);
chiaki_reorder_queue_fini(&queue);
return MUNIT_OK;
}
MunitTest tests_reorder_queue[] = {
{
"/reorder_queue_16",
test_reorder_queue_16,
NULL,
NULL,
MUNIT_TEST_OPTION_NONE,
NULL
},
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
};