[winpr,utils] improve TestQueue

properly test queue fill, drain and resize
This commit is contained in:
Armin Novak
2026-02-18 11:29:06 +01:00
parent d48452faf3
commit b08892fb9c

View File

@@ -3,56 +3,229 @@
#include <winpr/tchar.h>
#include <winpr/collections.h>
int TestQueue(int argc, char* argv[])
static bool wrap_test(bool (*fkt)(wQueue* queue))
{
size_t item = 0;
size_t count = 0;
wQueue* queue = NULL;
WINPR_UNUSED(argc);
WINPR_UNUSED(argv);
queue = Queue_New(TRUE, -1, -1);
wQueue* queue = Queue_New(TRUE, -1, -1);
if (!queue)
return -1;
return false;
WINPR_ASSERT(fkt);
const bool rc = fkt(queue);
Queue_Free(queue);
return rc;
}
static bool check(const void* ptr, size_t pos)
{
if (!ptr)
return false;
if (ptr != (void*)(pos + 23))
return false;
return true;
}
static bool append(wQueue* queue, size_t pos)
{
void* ptr = (void*)(pos + 23);
return Queue_Enqueue(queue, ptr);
}
static bool fill_capcity(wQueue* queue, size_t* pos)
{
WINPR_ASSERT(pos);
size_t cpos = *pos;
const size_t capacity = Queue_Capacity(queue);
while (Queue_Count(queue) < capacity)
{
if (!append(queue, cpos++))
return false;
}
*pos = cpos;
return true;
}
static bool drain(wQueue* queue, size_t expect)
{
void* ptr = Queue_Dequeue(queue);
return check(ptr, expect);
}
static bool drain_capcity(wQueue* queue, size_t remain, size_t* pos)
{
WINPR_ASSERT(pos);
size_t cpos = *pos;
while (Queue_Count(queue) > remain)
{
if (!drain(queue, cpos++))
return false;
}
*pos = cpos;
return true;
}
static bool test_growth_move(wQueue* queue, bool big)
{
WINPR_ASSERT(queue);
const size_t cap = Queue_Capacity(queue);
if (cap < 4)
return false;
size_t wpos = 0;
size_t rpos = 0;
if (!fill_capcity(queue, &wpos))
return false;
/* Ensure the (base) capacity is larger than the allocation step
* so a full copy of tail will not be possible */
if (big)
{
if (!append(queue, wpos++))
return false;
}
if (!drain_capcity(queue, 3, &rpos))
return false;
if (!fill_capcity(queue, &wpos))
return false;
if (!append(queue, wpos++))
return false;
return drain_capcity(queue, 0, &rpos);
}
static bool test_growth_big_move(wQueue* queue)
{
return test_growth_move(queue, true);
}
static bool test_growth_small_move(wQueue* queue)
{
return test_growth_move(queue, false);
}
static bool check_size(wQueue* queue, size_t expected)
{
WINPR_ASSERT(queue);
const size_t count = Queue_Count(queue);
printf("queue count: %" PRIuz "\n", count);
if (count != expected)
return false;
return true;
}
static bool enqueue(wQueue* queue, size_t val)
{
WINPR_ASSERT(queue);
void* ptr = (void*)(23 + val);
return Queue_Enqueue(queue, ptr);
}
static bool dequeue(wQueue* queue, size_t expected)
{
WINPR_ASSERT(queue);
const void* pexpect = (void*)(23 + expected);
void* ptr = Queue_Dequeue(queue);
if (pexpect != ptr)
return false;
return true;
}
static bool legacy_test(wQueue* queue)
{
WINPR_ASSERT(queue);
for (size_t index = 1; index <= 10; index++)
{
Queue_Enqueue(queue, (void*)index);
if (!enqueue(queue, index))
return false;
}
count = Queue_Count(queue);
printf("queue count: %" PRIuz "\n", count);
if (!check_size(queue, 10))
return false;
for (size_t index = 1; index <= 10; index++)
{
item = (size_t)Queue_Dequeue(queue);
if (item != index)
return -1;
if (!dequeue(queue, index))
return false;
}
count = Queue_Count(queue);
printf("queue count: %" PRIuz "\n", count);
if (!check_size(queue, 0))
return false;
Queue_Enqueue(queue, (void*)(size_t)1);
Queue_Enqueue(queue, (void*)(size_t)2);
Queue_Enqueue(queue, (void*)(size_t)3);
if (!enqueue(queue, 1))
return false;
if (!enqueue(queue, 2))
return false;
if (!enqueue(queue, 3))
return false;
Queue_Dequeue(queue);
Queue_Dequeue(queue);
if (!check_size(queue, 3))
return false;
Queue_Enqueue(queue, (void*)(size_t)4);
Queue_Enqueue(queue, (void*)(size_t)5);
Queue_Enqueue(queue, (void*)(size_t)6);
if (!dequeue(queue, 1))
return false;
if (!dequeue(queue, 2))
return false;
Queue_Dequeue(queue);
Queue_Dequeue(queue);
Queue_Dequeue(queue);
Queue_Dequeue(queue);
if (!check_size(queue, 1))
return false;
if (!enqueue(queue, 4))
return false;
if (!enqueue(queue, 5))
return false;
if (!enqueue(queue, 6))
return false;
if (!check_size(queue, 4))
return false;
if (!dequeue(queue, 3))
return false;
if (!dequeue(queue, 4))
return false;
if (!dequeue(queue, 5))
return false;
if (!dequeue(queue, 6))
return false;
if (!check_size(queue, 0))
return false;
Queue_Clear(queue);
Queue_Free(queue);
if (!check_size(queue, 0))
return false;
for (size_t x = 0; x < 32; x++)
{
void* ptr = (void*)(23 + x);
if (!Queue_Enqueue(queue, ptr))
return false;
}
if (!check_size(queue, 32))
return false;
Queue_Clear(queue);
if (!check_size(queue, 0))
return false;
return true;
}
int TestQueue(WINPR_ATTR_UNUSED int argc, WINPR_ATTR_UNUSED char* argv[])
{
if (!wrap_test(test_growth_big_move))
return -1;
if (!wrap_test(test_growth_small_move))
return -2;
if (!wrap_test(legacy_test))
return -3;
return 0;
}