mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-03-12 05:25:23 -07:00
186 lines
6.4 KiB
C
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 }
|
|
};
|