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>
This commit is contained in:
parent
8a48621fc9
commit
cae3d28a9b
|
@ -1973,6 +1973,118 @@ static void test_server_listening(void)
|
||||||
ok(status == RPC_S_OK, "RpcStringFree\n");
|
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)
|
static BOOL is_process_elevated(void)
|
||||||
{
|
{
|
||||||
HANDLE token;
|
HANDLE token;
|
||||||
|
@ -2099,16 +2211,10 @@ START_TEST(server)
|
||||||
ULONG size = 0;
|
ULONG size = 0;
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
BOOL firewall_enabled = is_firewall_enabled();
|
BOOL firewall_enabled = is_firewall_enabled(), firewall_disabled = FALSE;
|
||||||
|
|
||||||
InitFunctionPointers();
|
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");
|
ok(!GetUserNameExA(NameSamCompatible, NULL, &size), "GetUserNameExA\n");
|
||||||
domain_and_user = HeapAlloc(GetProcessHeap(), 0, size);
|
domain_and_user = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
ok(GetUserNameExA(NameSamCompatible, domain_and_user, &size), "GetUserNameExA\n");
|
ok(GetUserNameExA(NameSamCompatible, domain_and_user, &size), "GetUserNameExA\n");
|
||||||
|
@ -2130,23 +2236,50 @@ START_TEST(server)
|
||||||
}
|
}
|
||||||
else if (argc == 4)
|
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
|
else
|
||||||
{
|
{
|
||||||
if (firewall_enabled)
|
if (firewall_enabled)
|
||||||
{
|
{
|
||||||
HRESULT hr = set_firewall(APP_ADD);
|
if (is_process_elevated())
|
||||||
if (hr != S_OK)
|
|
||||||
{
|
{
|
||||||
skip("can't authorize app in firewall %08x\n", hr);
|
HRESULT hr = set_firewall(APP_ADD);
|
||||||
HeapFree(GetProcessHeap(), 0, domain_and_user);
|
if (hr == S_OK)
|
||||||
return;
|
{
|
||||||
|
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");
|
run_client("test listen");
|
||||||
if (firewall_enabled) set_firewall(APP_REMOVE);
|
if (firewall_disabled) set_firewall(APP_REMOVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, domain_and_user);
|
HeapFree(GetProcessHeap(), 0, domain_and_user);
|
||||||
|
|
Loading…
Reference in New Issue