https://git.reactos.org/?p=reactos.git;a=commitdiff;h=938adaad22f3ff35db56125bc722fb7ef324958b

commit 938adaad22f3ff35db56125bc722fb7ef324958b
Author:     Tomáš Veselý <turic...@gmail.com>
AuthorDate: Mon Aug 26 21:34:30 2024 +0200
Commit:     GitHub <nore...@github.com>
CommitDate: Mon Aug 26 22:34:30 2024 +0300

    [WIN32KNT_APITEST] Add NtUserSetTimer API tests (#7100)
    
    Test 1 - test of creating/canceling 20 timers and comparing the raw number 
of returned messages - without parent window
    Test 2 - test of creating/cancelling 20 timers and comparing the raw number 
of returned messages - with parent window
    Test 3 - test creation/cancellation of 40000 timers - without parent window
    Test 4 - test of creation/cancellation of 40000 timers - with parent window
    Test 5 - test creation/cancellation of 2 timers and compare their index to 
see if they differ - without parent window
    
    Covers the case in CORE-9141 (see #7087).
---
 .../apitests/win32nt/ntuser/NtUserSetTimer.c       | 252 ++++++++++++++++++++-
 1 file changed, 245 insertions(+), 7 deletions(-)

diff --git a/modules/rostests/apitests/win32nt/ntuser/NtUserSetTimer.c 
b/modules/rostests/apitests/win32nt/ntuser/NtUserSetTimer.c
index aad40f49698..ccdc6da4602 100644
--- a/modules/rostests/apitests/win32nt/ntuser/NtUserSetTimer.c
+++ b/modules/rostests/apitests/win32nt/ntuser/NtUserSetTimer.c
@@ -1,18 +1,256 @@
 /*
- * PROJECT:         ReactOS api tests
- * LICENSE:         GPL - See COPYING in the top level directory
- * PURPOSE:         Test for NtUserSetTimer
- * PROGRAMMERS:
+ * PROJECT:     ReactOS API tests
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Tests for NtUserSetTimer
+ * COPYRIGHT:   Copyright 2008 Timo Kreuzer <timo.kreu...@reactos.org>
+ *              Copyright 2024 Tomáš Veselý <turic...@gmail.com>
  */
 
 #include "../win32nt.h"
 
+#define SLEEP_TIME 500
+#define TIME_TOLERANCE 0.5
+
+#define TEST1_COUNT 20
+#define TEST1_INTERVAL 10
+
+#define TEST2_COUNT 40000
+#define TEST2_INTERVAL 10
+
+#define TESTW1_COUNT 20
+#define TESTW1_INTERVAL 10
+
+#define TESTW2_COUNT 40000
+#define TESTW2_INTERVAL 10
+
+typedef struct TIMER_MESSAGE_STATE1
+{
+    UINT_PTR index;
+    UINT counter;
+} TIMER_MESSAGE_STATE1;
+
+TIMER_MESSAGE_STATE1 timerId1[TEST1_COUNT];
+
+typedef struct TIMER_MESSAGE_STATEW1
+{
+    UINT counter;
+} TIMER_MESSAGE_STATEW1;
+
+TIMER_MESSAGE_STATEW1 timerIdW1[TESTW1_COUNT];
+
+/* TIMERPROC for the test1,2,3() with messages without window */
+static void CALLBACK
+TimerProc(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+    UINT i;
+    for (i = 0; i < TEST1_COUNT; i++)
+    {
+        if (timerId1[i].index == idEvent)
+            timerId1[i].counter++;
+    }
+}
+
+/* TIMERPROC for the testW1,2() with messages with window */
+static LRESULT CALLBACK
+WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    switch (uMsg)
+    {
+    case WM_TIMER:
+        timerIdW1[wParam].counter++;
+        return 0;
+    }
+
+    return DefWindowProcW(hwnd, uMsg, wParam, lParam);
+}
+
+// TEST WITH MESSAGES WITHOUT WINDOW - test count of sent messages
+static BOOL test1(void)
+{
+    UINT i, countErrors = 0;
+    ULONGLONG startTime;
+    MSG msg = { NULL };
+
+    int minMessages = ((float)SLEEP_TIME / (float)TEST1_INTERVAL) * (1 - 
TIME_TOLERANCE);
+    int maxMessages = ((float)SLEEP_TIME / (float)TEST1_INTERVAL) * (1 + 
TIME_TOLERANCE);
+
+    ZeroMemory(timerId1, sizeof(timerId1));
+
+    for (i = 0; i < TEST1_COUNT; i++)
+    {
+        timerId1[i].index = SetTimer(NULL, 0, TEST1_INTERVAL, TimerProc);
+        if (timerId1[i].index == 0)
+            countErrors++;
+    }
+
+    startTime = GetTickCount();
+
+    while (GetMessageW(&msg, NULL, 0, 0))
+    {
+        TranslateMessage(&msg);
+        DispatchMessageW(&msg);
+
+        if (GetTickCount() - startTime >= SLEEP_TIME)
+            PostQuitMessage(0);
+    }
+
+    for (i = 0; i < TEST1_COUNT; i++)
+    {
+        if ((timerId1[i].counter < minMessages) || (timerId1[i].counter > 
maxMessages))
+            countErrors++;
+    }
+
+    for (i = 0; i < TEST1_COUNT; i++)
+    {
+        if (KillTimer(NULL, timerId1[i].index) == 0)
+            countErrors++;
+    }
+
+    return (countErrors == 0);
+}
+
+// TEST WITH MESSAGES WITHOUT WINDOW - create many timers
+static BOOL test2(void)
+{
+    UINT i, countErrors = 0;
+    UINT_PTR locIndex;
+
+    for (i = 0; i < TEST2_COUNT; i++)
+    {
+        locIndex = SetTimer(NULL, 0, TEST2_INTERVAL, TimerProc);
+
+        if (locIndex == 0)
+            countErrors++;
+        if (KillTimer(NULL, locIndex) == 0)
+            countErrors++;
+    }
+
+    return (countErrors == 0);
+}
+
+// TEST WITH MESSAGES WITHOUT WINDOW - test different ids
+static BOOL test3(void)
+{
+    UINT countErrors = 0;
+    UINT_PTR locIndex1;
+    UINT_PTR locIndex2;
+
+    locIndex1 = SetTimer(NULL, 0, TEST1_INTERVAL, TimerProc);
+    if (locIndex1 == 0)
+        countErrors++;
+    if (KillTimer(NULL, locIndex1) == 0)
+        countErrors++;
+    locIndex2 = SetTimer(NULL, 0, TEST1_INTERVAL, TimerProc);
+    if (locIndex2 == 0)
+        countErrors++;
+    if (KillTimer(NULL, locIndex2) == 0)
+        countErrors++;
+    if (locIndex1 == locIndex2)
+        countErrors++;
+
+    return (countErrors == 0);
+}
+
+// TEST WITH MESSAGES WITH WINDOW - test count of sent messages
+static BOOL testW1(HWND hwnd)
+{
+    UINT i, countErrors = 0;
+    UINT_PTR locIndex;
+    ULONGLONG startTime;
+    MSG msg = { NULL };
+
+    if (hwnd == NULL)
+        return FALSE;
+
+    int minMessages = ((float)SLEEP_TIME / (float)TESTW1_INTERVAL) * (1 - 
TIME_TOLERANCE);
+    int maxMessages = ((float)SLEEP_TIME / (float)TESTW1_INTERVAL) * (1 + 
TIME_TOLERANCE);
+
+    ZeroMemory(timerIdW1, sizeof(timerIdW1));
+
+    for (i = 0; i < TESTW1_COUNT; i++)
+    {
+        locIndex = SetTimer(hwnd, i, TESTW1_INTERVAL, NULL);
+        if (locIndex == 0)
+            countErrors++;
+    }
+
+    startTime = GetTickCount();
+
+    while (GetMessageW(&msg, NULL, 0, 0))
+    {
+        TranslateMessage(&msg);
+        DispatchMessageW(&msg);
+
+        if (GetTickCount() - startTime >= SLEEP_TIME)
+            PostQuitMessage(0);
+    }
+
+    for (i = 0; i < TESTW1_COUNT; i++)
+    {
+        if ((timerIdW1[i].counter < minMessages) || (timerIdW1[i].counter > 
maxMessages))
+            countErrors++;
+    }
+
+    for (i = 0; i < TESTW1_COUNT; i++)
+    {
+        if (KillTimer(hwnd, i) == 0)
+            countErrors++;
+    }
+
+    return (countErrors == 0);
+}
+
+// TEST WITH MESSAGES WITH WINDOW - create many timers
+static BOOL testW2(HWND hwnd)
+{
+    UINT i, countErrors = 0;
+    UINT_PTR result;
+
+    if (hwnd == NULL)
+        return FALSE;
+
+    for (i = 0; i < TESTW2_COUNT; i++)
+    {
+        result = SetTimer(hwnd, 1, TESTW2_INTERVAL, NULL);
+        if (result == 0)
+            countErrors++;
+        if (KillTimer(hwnd, 1) == 0)
+            countErrors++;
+    }
+
+    return (countErrors == 0);
+}
+
 START_TEST(NtUserSetTimer)
 {
+    WNDCLASSW wc = { 0 };
+    HWND hwnd;
+
+    // TEST WITH MESSAGES WITHOUT WINDOW - test count of sent messages
+    TEST(test1());
+
+    // TEST WITH MESSAGES WITHOUT WINDOW - create many timers
+    TEST(test2());
+
+    // TEST WITH MESSAGES WITHOUT WINDOW - test different ids
+    TEST(test3());
+
+    wc.lpfnWndProc = WindowProc;
+    wc.hInstance = GetModuleHandleW(NULL);
+    wc.lpszClassName = L"TimerWindowClass";
+    RegisterClassW(&wc);
+
+    hwnd = CreateWindowExW(0, L"TimerWindowClass", L"Timer Window", 0,
+        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+        HWND_MESSAGE, NULL, GetModuleHandleW(NULL), NULL);
 
+    // TEST WITH MESSAGES WITH WINDOW - test count of sent messages
+    TEST(testW1(hwnd));
 
-    // check valid argument
-    // check for replacement / new timers
-    // check when expiries are handled (msgs and calls)
+    // TEST WITH MESSAGES WITH WINDOW - create many timers
+    TEST(testW2(hwnd));
 
+    if (hwnd != NULL)
+        DestroyWindow(hwnd);
+    UnregisterClassW(L"TimerWindowClass", NULL);
 }

Reply via email to