[PATCH] Strengthen current tests and add new tests for asynchronous I/O.

Zac Brown zac at zacbrown.org
Thu May 29 15:34:50 CDT 2008


---
 dlls/ntdll/tests/file.c |  103 ++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 79 insertions(+), 24 deletions(-)

diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index d824530..e3cbf77 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -2,6 +2,7 @@
  *
  * Copyright 2007 Jeff Latimer
  * Copyright 2007 Andrey Turkin
+ * Copyright 2008 Google (Zac Brown)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -65,6 +66,7 @@ static inline BOOL is_signaled( HANDLE obj )
 }
 
 #define PIPENAME "\\\\.\\pipe\\ntdll_tests_file.c"
+#define TEST_BUF_LEN 10
 
 static BOOL create_pipe( HANDLE *read, HANDLE *write, ULONG flags, ULONG size )
 {
@@ -114,7 +116,10 @@ static BOOL get_msg(HANDLE h)
 {
     LARGE_INTEGER timeout = {{-10000000*3}};
     DWORD res = pNtRemoveIoCompletion( h, &completionKey, &completionValue, &ioSb, &timeout);
-    ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %x\n", res );
+    if (res == STATUS_TIMEOUT)
+        ok( res == STATUS_TIMEOUT, "NtRemoveIoCompletion should have timed out, got: %x\n", res );
+    else
+        ok( res == STATUS_SUCCESS, "NtRemoveIoCompletion failed: %x\n", res );
     if (res != STATUS_SUCCESS)
     {
         completionKey = completionValue = 0;
@@ -507,6 +512,7 @@ static void test_iocp_fileio(HANDLE h)
     FILE_COMPLETION_INFORMATION fci = {h, CKEY_SECOND};
     HANDLE hPipeSrv, hPipeClt;
     NTSTATUS res;
+    BOOL rw_res;
 
     hPipeSrv = CreateNamedPipeA( pipe_name, PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 4, 1024, 1024, 1000, NULL );
     ok( hPipeSrv != INVALID_HANDLE_VALUE, "Cannot create named pipe\n" );
@@ -533,49 +539,97 @@ static void test_iocp_fileio(HANDLE h)
     if (hPipeClt != INVALID_HANDLE_VALUE)
     {
         OVERLAPPED o = {0,};
-        BYTE buf[3];
+        BYTE buf_send[TEST_BUF_LEN];
+        BYTE buf_rcv[TEST_BUF_LEN];
         DWORD read;
         long count;
+        unsigned int i;
 
         NTSTATUS res = pNtSetInformationFile( hPipeSrv, &iosb, &fci, sizeof(fci), FileCompletionInformation );
         ok( res == STATUS_SUCCESS, "NtSetInformationFile failed: %x\n", res );
         ok( U(iosb).Status == STATUS_SUCCESS, "iosb.Status invalid: %x\n", U(iosb).Status );
 
-        count = get_pending_msgs(h);
-        ok( !count, "Unexpected msg count: %ld\n", count );
-        ReadFile( hPipeSrv, buf, 3, &read, &o);
-        count = get_pending_msgs(h);
-        ok( !count, "Unexpected msg count: %ld\n", count );
-        WriteFile( hPipeClt, buf, 3, &read, NULL );
-
-        if (get_msg(h))
+        /* Try messages of differing lengths and values, checking that they match. */
+        for( i = 1; i < 10; i++ )
         {
-            ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey );
-            ok( ioSb.Information == 3, "Invalid ioSb.Information: %ld\n", ioSb.Information );
-            ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status);
-            ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue );
+            memset( buf_send, 0, TEST_BUF_LEN );
+            memset( buf_rcv, 0, TEST_BUF_LEN );
+            memset( buf_send, i, i );
+
+            /* Try reading before writing */
+            count = get_pending_msgs(h);
+            ok( !count, "Unexpected msg count: %ld\n", count );
+            rw_res = ReadFile( hPipeSrv, buf_rcv, i, &read, &o );
+            ok( rw_res == FALSE, "Unexpected success of ReadFile\n" );
+            ok( GetLastError() == ERROR_IO_PENDING, "Expected error of ERROR_IO_PENDING, got %d\n", GetLastError() );
+            count = get_pending_msgs(h);
+            ok( !count, "Unexpected msg count: %ld\n", count );
+            rw_res = WriteFile( hPipeClt, buf_send, i, &read, NULL );
+            ok( rw_res == TRUE, "Unexpected fail of WriteFile\n" );
+            if (get_msg(h))
+            {
+                ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey );
+                ok( ioSb.Information == i, "Invalid ioSb.Information: %ld\n", ioSb.Information );
+                ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status);
+                ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue );
+                ok( !memcmp( buf_send, buf_rcv, TEST_BUF_LEN ), "Receive buffer (%x %x %x) did not match send buffer (%x %x %x)\n",
+                    buf_rcv[0], buf_rcv[1], buf_rcv[2], buf_send[0], buf_send[1], buf_send[2] );
+            }
+            count = get_pending_msgs(h);
+            ok( !count, "Unexpected msg count: %ld\n", count );
+
+            /* Try writing before reading */
+            rw_res = WriteFile( hPipeClt, buf_send, i, &read, NULL );
+            ok( rw_res == TRUE, "Unexpected fail of WriteFile\n" );
+            count = get_pending_msgs(h);
+            ok( !count, "Unexpected msg count: %ld\n", count );
+            rw_res = ReadFile( hPipeSrv, buf_rcv, i, &read, &o );
+            ok( rw_res == TRUE, "Unexpected fail of ReadFile\n" );
+            if (get_msg(h))
+            {
+                ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey );
+                ok( ioSb.Information == i, "Invalid ioSb.Information: %ld\n", ioSb.Information );
+                ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status);
+                ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue );
+                ok( !memcmp( buf_send, buf_rcv, TEST_BUF_LEN ), "Receive buffer (%x %x %x) did not match send buffer (%x %x %x)\n",
+                    buf_rcv[0], buf_rcv[1], buf_rcv[2], buf_send[0], buf_send[1], buf_send[2] );
+            }
+            count = get_pending_msgs(h);
+            ok( !count, "Unexpected msg count: %ld\n", count );
         }
-        count = get_pending_msgs(h);
-        ok( !count, "Unexpected msg count: %ld\n", count );
 
-        WriteFile( hPipeClt, buf, 2, &read, NULL );
+        /* Try sending a message of length zero. */
         count = get_pending_msgs(h);
         ok( !count, "Unexpected msg count: %ld\n", count );
-        ReadFile( hPipeSrv, buf, 2, &read, &o);
+        rw_res = WriteFile( hPipeClt, buf_send, 0, &read, NULL );
+        ok( rw_res == TRUE, "Unexpected fail of WriteFile\n" );
         count = get_pending_msgs(h);
-        ok( count == 1, "Unexpected msg count: %ld\n", count );
+        ok( !count, "Unexpected msg count: %ld\n", count );
+        rw_res = ReadFile( hPipeSrv, buf_rcv, TEST_BUF_LEN, &read, &o );
+        /* This passes on XP but not in wine. */
+        todo_wine ok( rw_res == TRUE, "Unexpected fail of ReadFile\n" );
         if (get_msg(h))
         {
             ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey );
-            ok( ioSb.Information == 2, "Invalid ioSb.Information: %ld\n", ioSb.Information );
+            ok( ioSb.Information == 0, "Invalid ioSb.Information: %ld\n", ioSb.Information );
             ok( U(ioSb).Status == STATUS_SUCCESS, "Invalid ioSb.Status: %x\n", U(ioSb).Status);
             ok( completionValue == (ULONG_PTR)&o, "Invalid completion value: %lx\n", completionValue );
         }
+        count = get_pending_msgs(h);
+        ok( !count, "Unexpected msg count: %ld\n", count );
 
-        ReadFile( hPipeSrv, buf, sizeof(buf), &read, &o);
-        CloseHandle( hPipeSrv );
+        rw_res = ReadFile( hPipeSrv, buf_rcv, TEST_BUF_LEN, &read, &o);
+        ok( rw_res == FALSE, "Unexpected success of ReadFile\n" );
+        ok( GetLastError() == ERROR_IO_PENDING, "Expected error of ERROR_IO_PENDING, got %d\n", GetLastError() );
+        rw_res = CloseHandle( hPipeSrv );
+        ok( rw_res == TRUE, "Unexpected fail of CloseHandle\n" );
         count = get_pending_msgs(h);
-        ok( count == 1, "Unexpected msg count: %ld\n", count );
+        /*
+         * Wine reports 1 extra message. This is probably due to the server
+         * reporting that a message is in the queue from sending an empty message above.
+         * The offending code is suspected to be in ntdll/file.c in the NtReadFile function.
+         */
+        todo_wine ok( count == 1, "Unexpected msg count: %ld\n", count );
         if (get_msg(h))
         {
             ok( completionKey == CKEY_SECOND, "Invalid completion key: %lx\n", completionKey );
@@ -586,7 +640,8 @@ static void test_iocp_fileio(HANDLE h)
         }
     }
 
-    CloseHandle( hPipeClt );
+    rw_res = CloseHandle( hPipeClt );
+    ok( rw_res == TRUE, "Unexpected fail of CloseHandle\n" );
 }
 
 static void test_iocompletion(void)
-- 
1.5.3.6


--------------070900030002070603050302--



More information about the wine-patches mailing list