Related to https://source.winehq.org/patches/data/150818
--- dlls/ntdll/tests/Makefile.in | 1 + dlls/ntdll/tests/thread.c | 83 ++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 dlls/ntdll/tests/thread.c
diff --git a/dlls/ntdll/tests/Makefile.in b/dlls/ntdll/tests/Makefile.in index 5c70f3f01a..26b7f8cd09 100644 --- a/dlls/ntdll/tests/Makefile.in +++ b/dlls/ntdll/tests/Makefile.in @@ -22,4 +22,5 @@ C_SRCS = \ rtlstr.c \ string.c \ threadpool.c \ + thread.c \ time.c diff --git a/dlls/ntdll/tests/thread.c b/dlls/ntdll/tests/thread.c new file mode 100644 index 0000000000..740d64fff5 --- /dev/null +++ b/dlls/ntdll/tests/thread.c @@ -0,0 +1,83 @@ +/* + * Unit test suite for ntdll thread functions + * + * Copyright 2018 Roger Zoellner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "ntdll_test.h" + +static NTSTATUS (WINAPI *pNtSetInformationThread)(HANDLE handle, THREADINFOCLASS class, LPCVOID data, ULONG length); + +static DWORD WINAPI thread_main(LPVOID lpParam) +{ + /* Thread is created with CREATE_SUSPENDED flag set and isn't doing anything */ +} + +static void test_NtSetInformationThread(HANDLE thread) +{ + /* class ThreadAffinityMask */ + THREADINFOCLASS class = ThreadAffinityMask; + DWORD_PTR req_aff; + ULONG req_aff_length = sizeof(req_aff); + NTSTATUS status; + + HANDLE process = GetCurrentProcess(); + DWORD_PTR system_aff; + DWORD_PTR process_aff; + BOOL success = GetProcessAffinityMask(process, &process_aff, &system_aff); + ok(success == TRUE, "GetProcessAffinityMask failed. Expected TRUE, got FALSE\n"); + + if (success == FALSE) return; + + /* Test required affinity mask, no bits set */ + req_aff = 0; + status = pNtSetInformationThread(thread, class, &req_aff, req_aff_length); + ok(status == STATUS_INVALID_PARAMETER, "NtSetInformationThread failed. Expected STATUS_INVALID_PARAMETER, got %08x (class=ThreadAffinityMask, case 1, req_aff=%08x, process_aff=%08x)\n", status, req_aff, process_aff); + + /* Test required affinity mask, all bits set */ + req_aff = ~0u; + status = pNtSetInformationThread(thread, class, &req_aff, req_aff_length); + ok(status == STATUS_SUCCESS, "NtSetInformationThread failed. Expected STATUS_SUCCESS, got %08x (class=ThreadAffinityMask, case 2, req_aff=%08x, process_aff=%08x)\n", status, req_aff, process_aff); + + /* Test required affinity mask = process affinity mask */ + req_aff = process_aff; + status = pNtSetInformationThread(thread, class, &req_aff, req_aff_length); + ok(status == STATUS_SUCCESS, "NtSetInformationThread failed. Expected STATUS_SUCCESS, got %08x (class=ThreadAffinityMask, case 3, req_aff=%08x, process_aff=%08x)\n", status, req_aff, process_aff); + + /* Test required affinity mask = process affinity mask with a prepended bit set */ + req_aff = (process_aff << 1) | process_aff; + status = pNtSetInformationThread(thread, class, &req_aff, req_aff_length); + ok(status == STATUS_SUCCESS, "NtSetInformationThread failed. Expected STATUS_SUCCESS, got %08x (class=ThreadAffinityMask, case 4, req_aff=%08x, process_aff=%08x)\n", status, req_aff, process_aff); +} + +START_TEST(thread) +{ + HMODULE mod = GetModuleHandleA("ntdll.dll"); + pNtSetInformationThread = (void *) GetProcAddress(mod ,"NtSetInformationThread"); + HANDLE thread; + + thread = CreateThread(NULL, 0, thread_main, NULL, CREATE_SUSPENDED, NULL); + ok(thread != NULL, "dlls/ntdll/tests/: Could not create new thread\n"); + + if (thread != NULL) + { + test_NtSetInformationThread(thread); + TerminateThread(thread, 0); + CloseHandle(thread); + } +} +
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=41748
Your paranoid android.
=== wxppro (32 bit Windows report) ===
ntdll: thread.c:54: Test failed: NtSetInformationThread failed. Expected STATUS_SUCCESS, got c000000d (class=ThreadAffinityMask, case 2, req_aff=ffffffff, process_aff=00000003) thread.c:64: Test failed: NtSetInformationThread failed. Expected STATUS_SUCCESS, got c000000d (class=ThreadAffinityMask, case 4, req_aff=00000007, process_aff=00000003)
=== w2003std (32 bit Windows report) ===
ntdll: thread.c:54: Test failed: NtSetInformationThread failed. Expected STATUS_SUCCESS, got c000000d (class=ThreadAffinityMask, case 2, req_aff=ffffffff, process_aff=00000003) thread.c:64: Test failed: NtSetInformationThread failed. Expected STATUS_SUCCESS, got c000000d (class=ThreadAffinityMask, case 4, req_aff=00000007, process_aff=00000003)
On 09/09/2018 11:16 AM, Roger Zoellner wrote:
+static DWORD WINAPI thread_main(LPVOID lpParam) +{
- /* Thread is created with CREATE_SUSPENDED flag set and isn't doing anything */
+}
You should still probably do
(void)lpParam; return 0;
to avoid compiler warnings about unused parameters and lacking a return value.
- /* Test required affinity mask, all bits set */
- req_aff = ~0u;
This isn't all bits set for 64-bit targets. Try
req_aff = ~(ULONG_PTR)0;
for that.
- status = pNtSetInformationThread(thread, class, &req_aff, req_aff_length);
- ok(status == STATUS_SUCCESS, "NtSetInformationThread failed. Expected STATUS_SUCCESS, got %08x (class=ThreadAffinityMask, case 2, req_aff=%08x, process_aff=%08x)\n", status, req_aff, process_aff);
...
- /* Test required affinity mask = process affinity mask with a prepended bit set */
- req_aff = (process_aff << 1) | process_aff;
- status = pNtSetInformationThread(thread, class, &req_aff, req_aff_length);
- ok(status == STATUS_SUCCESS, "NtSetInformationThread failed. Expected STATUS_SUCCESS, got %08x (class=ThreadAffinityMask, case 4, req_aff=%08x, process_aff=%08x)\n", status, req_aff, process_aff);
Might it be worth checking to see what's returned from NtQueryInformationThread after trying to set extraneous mask bits?
Also, the tests that currently fail under Wine should be marked with todo_wine until a proper fix is made, and such a fix would remove the rodo_wines (unless the tests are part of a series that come after the fix).
Thank you for the suggestions. I will look into it. However, I'm wondering why the test fails on that two 32bit systems...
Am So., 9. Sep. 2018 um 21:10 Uhr schrieb Chris Robinson < chris.kcat@gmail.com>:
On 09/09/2018 11:16 AM, Roger Zoellner wrote:
+static DWORD WINAPI thread_main(LPVOID lpParam) +{
- /* Thread is created with CREATE_SUSPENDED flag set and isn't doing
anything */
+}
You should still probably do
(void)lpParam; return 0;
to avoid compiler warnings about unused parameters and lacking a return value.
- /* Test required affinity mask, all bits set */
- req_aff = ~0u;
This isn't all bits set for 64-bit targets. Try
req_aff = ~(ULONG_PTR)0;
for that.
- status = pNtSetInformationThread(thread, class, &req_aff,
req_aff_length);
- ok(status == STATUS_SUCCESS, "NtSetInformationThread failed.
Expected STATUS_SUCCESS, got %08x (class=ThreadAffinityMask, case 2, req_aff=%08x, process_aff=%08x)\n", status, req_aff, process_aff);
...
- /* Test required affinity mask = process affinity mask with a
prepended bit set */
- req_aff = (process_aff << 1) | process_aff;
- status = pNtSetInformationThread(thread, class, &req_aff,
req_aff_length);
- ok(status == STATUS_SUCCESS, "NtSetInformationThread failed.
Expected STATUS_SUCCESS, got %08x (class=ThreadAffinityMask, case 4, req_aff=%08x, process_aff=%08x)\n", status, req_aff, process_aff);
Might it be worth checking to see what's returned from NtQueryInformationThread after trying to set extraneous mask bits?
Also, the tests that currently fail under Wine should be marked with todo_wine until a proper fix is made, and such a fix would remove the rodo_wines (unless the tests are part of a series that come after the fix).
Hello Roger, thanks for your contribution.
On 09/09/18 13:16, Roger Zoellner wrote:
Ideally these should be sent together as a series, or possibly in the same patch.
Also, we already have tests for ThreadAffinityMask; see test_affinity() in dlls/ntdll/tests/info.c. You should probably append your tests there instead of adding new ones here.
Ah, great. Didn't know there already were some tests. I expected to find tests for thread.c in tests/thread.c. Thanks very much. This patch is obsolete then. Forgot to sign it off anyway :)