mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
[winpr,utils] improve TestMessageQueue
properly test queue fill, drain and resize
This commit is contained in:
@@ -22,35 +22,174 @@ static DWORD WINAPI message_queue_consumer_thread(LPVOID arg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TestMessageQueue(int argc, char* argv[])
|
static bool wrap_test(bool (*fkt)(wMessageQueue* queue))
|
||||||
{
|
{
|
||||||
HANDLE thread = NULL;
|
wMessageQueue* queue = MessageQueue_New(NULL);
|
||||||
wMessageQueue* queue = NULL;
|
if (!queue)
|
||||||
|
return false;
|
||||||
|
|
||||||
WINPR_UNUSED(argc);
|
WINPR_ASSERT(fkt);
|
||||||
WINPR_UNUSED(argv);
|
const bool rc = fkt(queue);
|
||||||
|
MessageQueue_Free(queue);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(queue = MessageQueue_New(NULL)))
|
static bool check(const wMessage* message, size_t pos)
|
||||||
|
{
|
||||||
|
if (!message)
|
||||||
|
return false;
|
||||||
|
if (message->context != (void*)13)
|
||||||
|
return false;
|
||||||
|
if (message->id != pos)
|
||||||
|
return false;
|
||||||
|
if (message->wParam != (void*)23)
|
||||||
|
return false;
|
||||||
|
if (message->lParam != (void*)42)
|
||||||
|
return false;
|
||||||
|
if (message->Free != NULL)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool append(wMessageQueue* queue, size_t pos)
|
||||||
|
{
|
||||||
|
const wMessage message = { .context = (void*)13,
|
||||||
|
.id = WINPR_ASSERTING_INT_CAST(DWORD, pos),
|
||||||
|
.wParam = (void*)23,
|
||||||
|
.lParam = (void*)42,
|
||||||
|
.Free = NULL };
|
||||||
|
|
||||||
|
return MessageQueue_Dispatch(queue, &message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool fill_capcity(wMessageQueue* queue, size_t* pos)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(pos);
|
||||||
|
|
||||||
|
size_t cpos = *pos;
|
||||||
|
const size_t capacity = MessageQueue_Capacity(queue);
|
||||||
|
while (MessageQueue_Size(queue) < capacity)
|
||||||
{
|
{
|
||||||
printf("failed to create message queue\n");
|
if (!append(queue, cpos++))
|
||||||
return 1;
|
return false;
|
||||||
|
}
|
||||||
|
*pos = cpos;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool drain(wMessageQueue* queue, size_t expect)
|
||||||
|
{
|
||||||
|
wMessage message = { 0 };
|
||||||
|
if (MessageQueue_Get(queue, &message) < 0)
|
||||||
|
return false;
|
||||||
|
if (!check(&message, expect))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool drain_capcity(wMessageQueue* queue, size_t remain, size_t* pos)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(pos);
|
||||||
|
|
||||||
|
size_t cpos = *pos;
|
||||||
|
while (MessageQueue_Size(queue) > remain)
|
||||||
|
{
|
||||||
|
if (!drain(queue, cpos++))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*pos = cpos;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool test_growth_move(wMessageQueue* queue, bool big)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(queue);
|
||||||
|
|
||||||
|
const size_t cap = MessageQueue_Capacity(queue);
|
||||||
|
if (cap < 4)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
size_t wpos = 0;
|
||||||
|
size_t rpos = 0;
|
||||||
|
if (!fill_capcity(queue, &wpos))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (big)
|
||||||
|
{
|
||||||
|
if (!append(queue, wpos++))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(thread = CreateThread(NULL, 0, message_queue_consumer_thread, (void*)queue, 0, NULL)))
|
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(wMessageQueue* queue)
|
||||||
|
{
|
||||||
|
return test_growth_move(queue, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool test_growth_small_move(wMessageQueue* queue)
|
||||||
|
{
|
||||||
|
return test_growth_move(queue, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool test_operation_run(wMessageQueue* queue, HANDLE thread)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(queue);
|
||||||
|
WINPR_ASSERT(thread);
|
||||||
|
|
||||||
|
if (!MessageQueue_Post(queue, NULL, 123, NULL, NULL))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!MessageQueue_Post(queue, NULL, 456, NULL, NULL))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!MessageQueue_Post(queue, NULL, 789, NULL, NULL))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!MessageQueue_PostQuit(queue, 0))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const DWORD status = WaitForSingleObject(thread, INFINITE);
|
||||||
|
if (status != WAIT_OBJECT_0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool test_operation(wMessageQueue* queue)
|
||||||
|
{
|
||||||
|
WINPR_ASSERT(queue);
|
||||||
|
|
||||||
|
HANDLE thread = CreateThread(NULL, 0, message_queue_consumer_thread, queue, 0, NULL);
|
||||||
|
if (!thread)
|
||||||
{
|
{
|
||||||
printf("failed to create thread\n");
|
printf("failed to create thread\n");
|
||||||
MessageQueue_Free(queue);
|
return false;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
const bool rc = test_operation_run(queue, thread);
|
||||||
|
if (!CloseHandle(thread))
|
||||||
|
return false;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
if (!MessageQueue_Post(queue, NULL, 123, NULL, NULL) ||
|
int TestMessageQueue(WINPR_ATTR_UNUSED int argc, WINPR_ATTR_UNUSED char* argv[])
|
||||||
!MessageQueue_Post(queue, NULL, 456, NULL, NULL) ||
|
{
|
||||||
!MessageQueue_Post(queue, NULL, 789, NULL, NULL) || !MessageQueue_PostQuit(queue, 0) ||
|
if (!wrap_test(test_growth_big_move))
|
||||||
WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
if (!wrap_test(test_growth_small_move))
|
||||||
MessageQueue_Free(queue);
|
return -2;
|
||||||
(void)CloseHandle(thread);
|
if (!wrap_test(test_operation))
|
||||||
|
return -3;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user