Added patch with additional tests for job object accounting.

This commit is contained in:
Sebastian Lackner 2017-10-01 04:53:37 +02:00
parent cc7f8f108a
commit 37bc3c21bf
2 changed files with 239 additions and 0 deletions

View File

@ -0,0 +1,223 @@
From 6addfba7928c62ea5a1a7e9717c564f745523957 Mon Sep 17 00:00:00 2001
From: Mark Jansen <mark.jansen@reactos.org>
Date: Sun, 24 Sep 2017 22:45:22 +0200
Subject: kernel32/tests: Add tests for job object accounting
Signed-off-by: Mark Jansen <mark.jansen@reactos.org>
---
dlls/kernel32/tests/process.c | 95 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 95 insertions(+)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 07daea82aec..5379684e28d 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -2364,6 +2364,69 @@ static void _create_process(int line, const char *command, LPPROCESS_INFORMATION
ok_(__FILE__, line)(ret, "CreateProcess error %u\n", GetLastError());
}
+#define test_assigned_proc(job, ...) _test_assigned_proc(__LINE__, job, __VA_ARGS__)
+static void _test_assigned_proc(int line, HANDLE job, int expected_count, ...)
+{
+ char buf[sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) + sizeof(ULONG_PTR) * 20];
+ PJOBOBJECT_BASIC_PROCESS_ID_LIST pid_list = (JOBOBJECT_BASIC_PROCESS_ID_LIST *)buf;
+ DWORD ret_len, pid;
+ va_list valist;
+ int n;
+ BOOL ret;
+
+ memset(buf, 0, sizeof(buf));
+ ret = pQueryInformationJobObject(job, JobObjectBasicProcessIdList, pid_list, sizeof(buf), &ret_len);
+ ok_(__FILE__, line)(ret, "QueryInformationJobObject error %u\n", GetLastError());
+ if (ret)
+ {
+ todo_wine_if(expected_count)
+ ok_(__FILE__, line)(expected_count == pid_list->NumberOfAssignedProcesses,
+ "Expected NumberOfAssignedProcesses to be %d (expected_count) is %d\n",
+ expected_count, pid_list->NumberOfAssignedProcesses);
+ todo_wine_if(expected_count)
+ ok_(__FILE__, line)(expected_count == pid_list->NumberOfProcessIdsInList,
+ "Expected NumberOfProcessIdsInList to be %d (expected_count) is %d\n",
+ expected_count, pid_list->NumberOfProcessIdsInList);
+
+ va_start(valist, expected_count);
+ for (n = 0; n < min(expected_count, pid_list->NumberOfProcessIdsInList); ++n)
+ {
+ pid = va_arg(valist, DWORD);
+ ok_(__FILE__, line)(pid == pid_list->ProcessIdList[n],
+ "Expected pid_list->ProcessIdList[%d] to be %x is %lx\n",
+ n, pid, pid_list->ProcessIdList[n]);
+ }
+ va_end(valist);
+ }
+}
+
+#define test_accounting(job, total_proc, active_proc, terminated_proc) _test_accounting(__LINE__, job, total_proc, active_proc, terminated_proc)
+static void _test_accounting(int line, HANDLE job, int total_proc, int active_proc, int terminated_proc)
+{
+ JOBOBJECT_BASIC_ACCOUNTING_INFORMATION basic_accounting;
+ DWORD ret_len;
+ BOOL ret;
+
+ memset(&basic_accounting, 0, sizeof(basic_accounting));
+ ret = pQueryInformationJobObject(job, JobObjectBasicAccountingInformation, &basic_accounting, sizeof(basic_accounting), &ret_len);
+ ok_(__FILE__, line)(ret, "QueryInformationJobObject error %u\n", GetLastError());
+ if (ret)
+ {
+ /* Not going to check process times or page faults */
+
+ todo_wine_if(total_proc)
+ ok_(__FILE__, line)(total_proc == basic_accounting.TotalProcesses,
+ "Expected basic_accounting.TotalProcesses to be %d (total_proc) is %d\n",
+ total_proc, basic_accounting.TotalProcesses);
+ todo_wine_if(active_proc)
+ ok_(__FILE__, line)(active_proc == basic_accounting.ActiveProcesses,
+ "Expected basic_accounting.ActiveProcesses to be %d (active_proc) is %d\n",
+ active_proc, basic_accounting.ActiveProcesses);
+ ok_(__FILE__, line)(terminated_proc == basic_accounting.TotalTerminatedProcesses,
+ "Expected basic_accounting.TotalTerminatedProcesses to be %d (terminated_proc) is %d\n",
+ terminated_proc, basic_accounting.TotalTerminatedProcesses);
+ }
+}
static void test_IsProcessInJob(void)
{
@@ -2390,11 +2453,15 @@ static void test_IsProcessInJob(void)
ret = pIsProcessInJob(pi.hProcess, job, &out);
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(!out, "IsProcessInJob returned out=%u\n", out);
+ test_assigned_proc(job, 0);
+ test_accounting(job, 0, 0, 0);
out = TRUE;
ret = pIsProcessInJob(pi.hProcess, job2, &out);
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(!out, "IsProcessInJob returned out=%u\n", out);
+ test_assigned_proc(job2, 0);
+ test_accounting(job2, 0, 0, 0);
out = TRUE;
ret = pIsProcessInJob(pi.hProcess, NULL, &out);
@@ -2408,11 +2475,15 @@ static void test_IsProcessInJob(void)
ret = pIsProcessInJob(pi.hProcess, job, &out);
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(out, "IsProcessInJob returned out=%u\n", out);
+ test_assigned_proc(job, 1, pi.dwProcessId);
+ test_accounting(job, 1, 1, 0);
out = TRUE;
ret = pIsProcessInJob(pi.hProcess, job2, &out);
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(!out, "IsProcessInJob returned out=%u\n", out);
+ test_assigned_proc(job2, 0);
+ test_accounting(job2, 0, 0, 0);
out = FALSE;
ret = pIsProcessInJob(pi.hProcess, NULL, &out);
@@ -2428,6 +2499,8 @@ static void test_IsProcessInJob(void)
ret = pIsProcessInJob(pi.hProcess, job, &out);
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(out, "IsProcessInJob returned out=%u\n", out);
+ test_assigned_proc(job, 0);
+ test_accounting(job, 1, 0, 0);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
@@ -2444,11 +2517,15 @@ static void test_TerminateJobObject(void)
job = pCreateJobObjectW(NULL, NULL);
ok(job != NULL, "CreateJobObject error %u\n", GetLastError());
+ test_assigned_proc(job, 0);
+ test_accounting(job, 0, 0, 0);
create_process("wait", &pi);
ret = pAssignProcessToJobObject(job, pi.hProcess);
ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
+ test_assigned_proc(job, 1, pi.dwProcessId);
+ test_accounting(job, 1, 1, 0);
ret = pTerminateJobObject(job, 123);
ok(ret, "TerminateJobObject error %u\n", GetLastError());
@@ -2456,6 +2533,8 @@ static void test_TerminateJobObject(void)
dwret = WaitForSingleObject(pi.hProcess, 1000);
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0);
+ test_assigned_proc(job, 0);
+ test_accounting(job, 1, 0, 0);
ret = GetExitCodeProcess(pi.hProcess, &dwret);
ok(ret, "GetExitCodeProcess error %u\n", GetLastError());
@@ -2475,6 +2554,8 @@ static void test_TerminateJobObject(void)
ret = pAssignProcessToJobObject(job, pi.hProcess);
ok(!ret, "AssignProcessToJobObject unexpectedly succeeded\n");
expect_eq_d(ERROR_ACCESS_DENIED, GetLastError());
+ test_assigned_proc(job, 0);
+ test_accounting(job, 1, 0, 0);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
@@ -2661,11 +2742,15 @@ static void test_KillOnJobClose(void)
return;
}
ok(ret, "SetInformationJobObject error %u\n", GetLastError());
+ test_assigned_proc(job, 0);
+ test_accounting(job, 0, 0, 0);
create_process("wait", &pi);
ret = pAssignProcessToJobObject(job, pi.hProcess);
ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
+ test_assigned_proc(job, 1, pi.dwProcessId);
+ test_accounting(job, 1, 1, 0);
CloseHandle(job);
@@ -2769,6 +2854,8 @@ static HANDLE test_AddSelfToJob(void)
ret = pAssignProcessToJobObject(job, GetCurrentProcess());
ok(ret, "AssignProcessToJobObject error %u\n", GetLastError());
+ test_assigned_proc(job, 1, GetCurrentProcessId());
+ test_accounting(job, 1, 1, 0);
return job;
}
@@ -2796,6 +2883,8 @@ static void test_jobInheritance(HANDLE job)
ret = pIsProcessInJob(pi.hProcess, job, &out);
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(out, "IsProcessInJob returned out=%u\n", out);
+ test_assigned_proc(job, 2, GetCurrentProcessId(), pi.dwProcessId);
+ test_accounting(job, 2, 2, 0);
dwret = WaitForSingleObject(pi.hProcess, 1000);
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
@@ -2824,6 +2913,8 @@ static void test_BreakawayOk(HANDLE job)
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi);
ok(!ret, "CreateProcessA expected failure\n");
expect_eq_d(ERROR_ACCESS_DENIED, GetLastError());
+ test_assigned_proc(job, 1, GetCurrentProcessId());
+ test_accounting(job, 2, 1, 0);
if (ret)
{
@@ -2846,6 +2937,8 @@ static void test_BreakawayOk(HANDLE job)
ret = pIsProcessInJob(pi.hProcess, job, &out);
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(!out, "IsProcessInJob returned out=%u\n", out);
+ test_assigned_proc(job, 1, GetCurrentProcessId());
+ test_accounting(job, 2, 1, 0);
dwret = WaitForSingleObject(pi.hProcess, 1000);
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
@@ -2863,6 +2956,8 @@ static void test_BreakawayOk(HANDLE job)
ret = pIsProcessInJob(pi.hProcess, job, &out);
ok(ret, "IsProcessInJob error %u\n", GetLastError());
ok(!out, "IsProcessInJob returned out=%u\n", out);
+ test_assigned_proc(job, 1, GetCurrentProcessId());
+ test_accounting(job, 2, 1, 0);
dwret = WaitForSingleObject(pi.hProcess, 1000);
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
--
2.14.1

View File

@ -194,6 +194,7 @@ patch_enable_all ()
enable_kernel32_Debugger="$1"
enable_kernel32_FindFirstFile="$1"
enable_kernel32_GetShortPathName="$1"
enable_kernel32_Job_Tests="$1"
enable_kernel32_K32GetPerformanceInfo="$1"
enable_kernel32_LocaleNameToLCID="$1"
enable_kernel32_MODULE_get_binary_info="$1"
@ -864,6 +865,9 @@ patch_enable ()
kernel32-GetShortPathName)
enable_kernel32_GetShortPathName="$2"
;;
kernel32-Job_Tests)
enable_kernel32_Job_Tests="$2"
;;
kernel32-K32GetPerformanceInfo)
enable_kernel32_K32GetPerformanceInfo="$2"
;;
@ -5313,6 +5317,18 @@ if test "$enable_kernel32_GetShortPathName" -eq 1; then
) >> "$patchlist"
fi
# Patchset kernel32-Job_Tests
# |
# | Modified files:
# | * dlls/kernel32/tests/process.c
# |
if test "$enable_kernel32_Job_Tests" -eq 1; then
patch_apply kernel32-Job_Tests/0001-kernel32-tests-Add-tests-for-job-object-accounting.patch
(
printf '%s\n' '+ { "Mark Jansen", "kernel32/tests: Add tests for job object accounting.", 1 },';
) >> "$patchlist"
fi
# Patchset kernel32-K32GetPerformanceInfo
# |
# | Modified files: