Milestone 5: deliver embedded RDP sessions and lifecycle hardening
This commit is contained in:
225
third_party/FreeRDP/winpr/libwinpr/utils/test/TestQueue.c
vendored
Normal file
225
third_party/FreeRDP/winpr/libwinpr/utils/test/TestQueue.c
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
static bool wrap_test(bool (*fkt)(wQueue* queue))
|
||||
{
|
||||
wQueue* queue = Queue_New(TRUE, -1, -1);
|
||||
if (!queue)
|
||||
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);
|
||||
return (count == expected);
|
||||
}
|
||||
|
||||
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);
|
||||
return (pexpect == ptr);
|
||||
}
|
||||
|
||||
static bool legacy_test(wQueue* queue)
|
||||
{
|
||||
WINPR_ASSERT(queue);
|
||||
|
||||
for (size_t index = 1; index <= 10; index++)
|
||||
{
|
||||
if (!enqueue(queue, index))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!check_size(queue, 10))
|
||||
return false;
|
||||
|
||||
for (size_t index = 1; index <= 10; index++)
|
||||
{
|
||||
if (!dequeue(queue, index))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!check_size(queue, 0))
|
||||
return false;
|
||||
|
||||
if (!enqueue(queue, 1))
|
||||
return false;
|
||||
if (!enqueue(queue, 2))
|
||||
return false;
|
||||
if (!enqueue(queue, 3))
|
||||
return false;
|
||||
|
||||
if (!check_size(queue, 3))
|
||||
return false;
|
||||
|
||||
if (!dequeue(queue, 1))
|
||||
return false;
|
||||
if (!dequeue(queue, 2))
|
||||
return false;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
return check_size(queue, 0);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user