ntdll: Strengthen current tests and add new tests for asynchronous I/O.

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


Woops, ignore this patch. Its got a couple things wrong with it. I'll send a fix 
later on.

-Zac

Zac Brown wrote:
> Strengthen current tests and add new tests for asynchronous I/O. Missing 
> test for empty messages as well as thoroughly testing input and output 
> of read/write commands.
> 
> -Zac Brown
> 
> 
> ------------------------------------------------------------------------
> 
> From d2a3cbaf6d71c3b0bcfa39afcf854de7e5daa5bb Mon Sep 17 00:00:00 2001
> From: Zac Brown <zac at zacbrown.org>
> Date: Thu, 29 May 2008 13:34:50 -0700
> Subject: [PATCH] Strengthen current tests and add new tests for asynchronous I/O.
> 
> ---
>  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)
> 
> 
> ------------------------------------------------------------------------
> 
> 




More information about the wine-devel mailing list