[PATCH 1/4] kernel32/tests: Add tests for named pipes in PIPE_NOWAIT mode.
Brendan Shanks
bshanks at codeweavers.com
Tue Oct 1 11:16:57 CDT 2019
Signed-off-by: Brendan Shanks <bshanks at codeweavers.com>
---
dlls/kernel32/tests/pipe.c | 108 +++++++++++++++++++++++++++++++++++++
1 file changed, 108 insertions(+)
diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c
index f61d441303..227575ece3 100644
--- a/dlls/kernel32/tests/pipe.c
+++ b/dlls/kernel32/tests/pipe.c
@@ -3887,6 +3887,113 @@ static void test_wait_pipe(void)
CloseHandle(ov.hEvent);
}
+static DWORD CALLBACK test_nowait_read_thread(LPVOID arg)
+{
+ HANDLE *pipewrite = arg;
+ static const char buf[] = "bits";
+ DWORD written;
+
+ Sleep(2000);
+ WriteFile(*pipewrite, buf, sizeof(buf), &written, NULL);
+ return 0;
+}
+static DWORD CALLBACK test_nowait_write_thread(LPVOID arg)
+{
+ HANDLE *piperead = arg;
+ char buf[32768];
+ DWORD read;
+
+ Sleep(2000);
+ ReadFile(*piperead, buf, sizeof(buf), &read, NULL);
+ return 0;
+}
+static DWORD CALLBACK test_nowait_connect_thread(LPVOID arg)
+{
+ HANDLE hFile;
+
+ Sleep(2000);
+ hFile = CreateFileA(PIPENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
+ ok(hFile != INVALID_HANDLE_VALUE, "CreateFileA failed\n");
+ ok(CloseHandle(hFile), "CloseHandle failed\n");
+ return 0;
+}
+static void test_nowait(void)
+{
+ SECURITY_ATTRIBUTES pipe_attr;
+ HANDLE piperead, pipewrite, hThread;
+ DWORD mode;
+ DWORD read, write;
+ char readbuf[32768];
+
+ pipe_attr.nLength = sizeof(SECURITY_ATTRIBUTES);
+ pipe_attr.bInheritHandle = TRUE;
+ pipe_attr.lpSecurityDescriptor = NULL;
+
+ /* CreatePipe, use SetNamedHandleState to enable PIPE_NOWAIT, and read from empty pipe */
+ ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 0) != 0, "CreatePipe failed\n");
+ mode = PIPE_NOWAIT;
+ ok(SetNamedPipeHandleState(piperead, &mode, NULL, NULL) != 0, "SetNamedPipeHandleState failed\n");
+ /* spawn a thread that writes to the pipe after 2 seconds so the test won't hang if ReadFile blocks */
+ hThread = CreateThread(NULL, 0, test_nowait_read_thread, &pipewrite, 0, NULL);
+ ok(hThread != NULL, "CreateThread failed. %d\n", GetLastError());
+ SetLastError(0xdeadbeef);
+ todo_wine ok(ReadFile(piperead,readbuf,sizeof(readbuf),&read, NULL) == FALSE, "ReadFile should fail\n");
+ todo_wine ok(GetLastError() == ERROR_NO_DATA, "got %d should be ERROR_NO_DATA\n", GetLastError());
+ ok(WaitForSingleObject(hThread,INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject\n");
+ ok(CloseHandle(hThread), "CloseHandle for the thread failed\n");
+ ok(CloseHandle(pipewrite), "CloseHandle for the write pipe failed\n");
+ ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n");
+
+ /* CreatePipe, use SetNamedHandleState to enable PIPE_NOWAIT, and write to full pipe */
+ ok(CreatePipe(&piperead, &pipewrite, &pipe_attr, 512) != 0, "CreatePipe failed\n");
+ mode = PIPE_NOWAIT;
+ ok(SetNamedPipeHandleState(pipewrite, &mode, NULL, NULL) != 0, "SetNamedPipeHandleState failed\n");
+ /* spawn a thread that reads from the pipe after 2 seconds so the test won't hang if WriteFile blocks */
+ hThread = CreateThread(NULL, 0, test_nowait_write_thread, &piperead, 0, NULL);
+ ok(hThread != NULL, "CreateThread failed. %d\n", GetLastError());
+ SetLastError(0xdeadbeef);
+ ok(WriteFile(pipewrite,readbuf,sizeof(readbuf),&write, NULL) == TRUE, "WriteFile should return true\n");
+ /* WriteFile only documents that 'write < sizeof(readbuf)' for this case, but Windows
+ * doesn't seem to do partial writes ('write == 0' always)
+ */
+ todo_wine ok(write < sizeof(readbuf), "WriteFile should fail to write the whole buffer\n");
+ todo_wine ok(write == 0, "WriteFile shouldn't do partial writes\n");
+ ok(CloseHandle(hThread), "CloseHandle for the thread failed\n");
+ ok(CloseHandle(pipewrite), "CloseHandle for the write pipe failed\n");
+ ok(CloseHandle(piperead), "CloseHandle for the read pipe failed\n");
+
+ /* CreateNamedPipe with PIPE_NOWAIT, test ConnectNamedPipe */
+ pipewrite = CreateNamedPipeA(PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_NOWAIT,
+ /* nMaxInstances */ 1,
+ /* nOutBufSize */ 512,
+ /* nInBufSize */ 512,
+ /* nDefaultWait */ NMPWAIT_USE_DEFAULT_WAIT,
+ /* lpSecurityAttrib */ NULL);
+ ok(pipewrite != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
+ /* spawn a thread that connects to the pipe after 2 seconds so the test won't hang if ConnectNamedPipe blocks */
+ hThread = CreateThread(NULL, 0, test_nowait_connect_thread, NULL, 0, NULL);
+ ok(hThread != NULL, "CreateThread failed. %d\n", GetLastError());
+ SetLastError(0xdeadbeef);
+ todo_wine ok(ConnectNamedPipe(pipewrite,NULL) == FALSE, "ConnectNamedPipe should fail\n");
+ todo_wine ok(GetLastError() == ERROR_PIPE_LISTENING, "got %d should be ERROR_PIPE_LISTENING\n", GetLastError());
+ /* wait for thread to finish (connects and disconnects), then test ConnectNamedPipe again */
+ ok(WaitForSingleObject(hThread,INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject\n");
+ ok(CloseHandle(hThread), "CloseHandle for the thread failed\n");
+ SetLastError(0xdeadbeef);
+ todo_wine ok(ConnectNamedPipe(pipewrite,NULL) == FALSE, "ConnectNamedPipe should fail\n");
+ todo_wine ok(GetLastError() == ERROR_NO_DATA, "got %d should be ERROR_NO_DATA\n", GetLastError());
+ /* call DisconnectNamedPipe and test ConnectNamedPipe again */
+ ok(DisconnectNamedPipe(pipewrite) == TRUE, "DisconnectNamedPipe should succeed\n");
+ hThread = CreateThread(NULL, 0, test_nowait_connect_thread, NULL, 0, NULL);
+ ok(hThread != NULL, "CreateThread failed. %d\n", GetLastError());
+ SetLastError(0xdeadbeef);
+ todo_wine ok(ConnectNamedPipe(pipewrite,NULL) == FALSE, "ConnectNamedPipe should fail\n");
+ todo_wine ok(GetLastError() == ERROR_PIPE_LISTENING, "got %d should be ERROR_PIPE_LISTENING\n", GetLastError());
+ ok(WaitForSingleObject(hThread,INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject\n");
+ ok(CloseHandle(hThread), "CloseHandle for the thread failed\n");
+ ok(CloseHandle(pipewrite), "CloseHandle for the write pipe failed\n");
+}
+
START_TEST(pipe)
{
char **argv;
@@ -3954,4 +4061,5 @@ START_TEST(pipe)
test_namedpipe_session_id();
test_multiple_instances();
test_wait_pipe();
+ test_nowait();
}
--
2.17.1
More information about the wine-devel
mailing list