Jacek Caban : rpcrt4/tests: Add a test of client reconnecting on send failure.
Alexandre Julliard
julliard at winehq.org
Wed Oct 17 18:15:43 CDT 2018
Module: wine
Branch: master
Commit: cae3d28a9bd9221ff8acf1aaa5eb41c27744d9cc
URL: https://source.winehq.org/git/wine.git/?a=commit;h=cae3d28a9bd9221ff8acf1aaa5eb41c27744d9cc
Author: Jacek Caban <jacek at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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);
More information about the wine-cvs
mailing list