Module: wine Branch: master Commit: cae3d28a9bd9221ff8acf1aaa5eb41c27744d9cc URL: https://source.winehq.org/git/wine.git/?a=commit;h=cae3d28a9bd9221ff8acf1aaa...
Author: Jacek Caban jacek@codeweavers.com Date: Wed Oct 17 15:58:07 2018 +0200
rpcrt4/tests: Add a test of client reconnecting on send failure.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/rpcrt4/tests/server.c | 163 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 148 insertions(+), 15 deletions(-)
diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index 1494904..587dc45 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -1973,6 +1973,118 @@ static void test_server_listening(void) ok(status == RPC_S_OK, "RpcStringFree\n"); }
+HANDLE create_server_process(void) +{ + SECURITY_ATTRIBUTES sec_attr = { sizeof(sec_attr), NULL, TRUE }; + HANDLE ready_event; + char cmdline[MAX_PATH]; + PROCESS_INFORMATION info; + STARTUPINFOA startup; + DWORD ret; + + memset(&startup, 0, sizeof startup); + startup.cb = sizeof startup; + + ready_event = CreateEventW(&sec_attr, TRUE, FALSE, NULL); + ok(ready_event != NULL, "CreateEvent failed: %u\n", GetLastError()); + + sprintf(cmdline, "%s server run %lx", progname, (UINT_PTR)ready_event); + trace("running server process...\n"); + ok(CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0L, NULL, NULL, &startup, &info), "CreateProcess\n"); + ret = WaitForSingleObject(ready_event, 10000); + ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n"); + + ok(CloseHandle(info.hThread), "CloseHandle\n"); + ok(CloseHandle(ready_event), "CloseHandle\n"); + return info.hProcess; +} + +static void run_server(HANDLE ready_event) +{ + static unsigned char np[] = "ncacn_np"; + static unsigned char pipe[] = PIPE "term_test"; + RPC_STATUS status; + BOOL ret; + + status = RpcServerUseProtseqEpA(np, 0, pipe, NULL); + ok(status == RPC_S_OK, "RpcServerUseProtseqEp(ncacn_np) failed with status %d\n", status); + + status = RpcServerRegisterIf(s_IServer_v0_0_s_ifspec, NULL, NULL); + ok(status == RPC_S_OK, "RpcServerRegisterIf failed with status %d\n", status); + + test_is_server_listening(NULL, RPC_S_NOT_LISTENING); + status = RpcServerListen(1, 20, TRUE); + ok(status == RPC_S_OK, "RpcServerListen failed with status %d\n", status); + + stop_event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(stop_event != NULL, "CreateEvent failed with error %d\n", GetLastError()); + + ret = SetEvent(ready_event); + ok(ret, "SetEvent failed: %u\n", GetLastError()); + + ret = WaitForSingleObject(stop_event, 1000); + ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n"); + + status = RpcMgmtWaitServerListen(); + ok(status == RPC_S_OK, "RpcMgmtWaitServerListening failed with status %d\n", status); + + CloseHandle(stop_event); + stop_event = NULL; +} + +static DWORD WINAPI basic_tests_thread(void *arg) +{ + basic_tests(); + return 0; +} + +static void test_reconnect(void) +{ + static unsigned char np[] = "ncacn_np"; + static unsigned char address_np[] = "\\."; + static unsigned char pipe[] = PIPE "term_test"; + unsigned char *binding; + HANDLE threads[32]; + HANDLE server_process; + unsigned i; + DWORD ret; + + server_process = create_server_process(); + + ok(RPC_S_OK == RpcStringBindingComposeA(NULL, np, address_np, pipe, NULL, &binding), "RpcStringBindingCompose\n"); + ok(RPC_S_OK == RpcBindingFromStringBindingA(binding, &IServer_IfHandle), "RpcBindingFromStringBinding\n"); + + for (i = 0; i < ARRAY_SIZE(threads); i++) + { + threads[i] = CreateThread(NULL, 0, basic_tests_thread, 0, 0, NULL); + ok(threads[i] != NULL, "CreateThread failed: %u\n", GetLastError()); + } + + for (i = 0; i < ARRAY_SIZE(threads); i++) + { + ret = WaitForSingleObject(threads[i], 10000); + ok(WAIT_OBJECT_0 == ret, "WaitForSingleObject\n"); + CloseHandle(threads[i]); + } + + stop(); + + winetest_wait_child_process(server_process); + ok(CloseHandle(server_process), "CloseHandle\n"); + + /* create new server, rpcrt4 will connect to it once sending to existing connection fails + * that current connection is broken. */ + server_process = create_server_process(); + basic_tests(); + stop(); + + winetest_wait_child_process(server_process); + ok(CloseHandle(server_process), "CloseHandle\n"); + + ok(RPC_S_OK == RpcStringFreeA(&binding), "RpcStringFree\n"); + ok(RPC_S_OK == RpcBindingFree(&IServer_IfHandle), "RpcBindingFree\n"); +} + static BOOL is_process_elevated(void) { HANDLE token; @@ -2099,16 +2211,10 @@ START_TEST(server) ULONG size = 0; int argc; char **argv; - BOOL firewall_enabled = is_firewall_enabled(); + BOOL firewall_enabled = is_firewall_enabled(), firewall_disabled = FALSE;
InitFunctionPointers();
- if (firewall_enabled && !is_process_elevated()) - { - trace("no privileges, skipping tests to avoid firewall dialog\n"); - return; - } - ok(!GetUserNameExA(NameSamCompatible, NULL, &size), "GetUserNameExA\n"); domain_and_user = HeapAlloc(GetProcessHeap(), 0, size); ok(GetUserNameExA(NameSamCompatible, domain_and_user, &size), "GetUserNameExA\n"); @@ -2130,23 +2236,50 @@ START_TEST(server) } else if (argc == 4) { - test_server_listening(); + if (!strcmp(argv[3], "listen")) + { + test_server_listening(); + } + else if(!strcmp(argv[2], "run")) + { + UINT_PTR event; + sscanf(argv[3], "%lx", &event); + run_server((HANDLE)event); + } } else { if (firewall_enabled) { - HRESULT hr = set_firewall(APP_ADD); - if (hr != S_OK) + if (is_process_elevated()) { - skip("can't authorize app in firewall %08x\n", hr); - HeapFree(GetProcessHeap(), 0, domain_and_user); - return; + HRESULT hr = set_firewall(APP_ADD); + if (hr == S_OK) + { + firewall_enabled = FALSE; + firewall_disabled = TRUE; + } + else + { + skip("can't authorize app in firewall %08x\n", hr); + } + } + else + { + trace("no privileges, skipping tests to avoid firewall dialog\n"); } } - server(); + + if (!firewall_enabled) server(); + + /* Those tests cause occasional crashes on winxp and win2k3 */ + if (GetProcAddress(GetModuleHandleA("rpcrt4.dll"), "RpcExceptionFilter")) + test_reconnect(); + else + win_skip("Skipping reconnect tests on too old Windows version\n"); + run_client("test listen"); - if (firewall_enabled) set_firewall(APP_REMOVE); + if (firewall_disabled) set_firewall(APP_REMOVE); }
HeapFree(GetProcessHeap(), 0, domain_and_user);