[2/5] wininet/tests: Add tests for asynchronous InternetReadFileEx. (v4)

Sebastian Lackner sebastian at fds-team.de
Wed Apr 27 22:10:07 CDT 2016


Signed-off-by: Sebastian Lackner <sebastian at fds-team.de>
---
Changes in v4:
* Replace SET_OPTIONAL with SET_EXPECT, to simplify the following patch.

 dlls/wininet/tests/http.c |  117 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 116 insertions(+), 1 deletion(-)

diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c
index 66ba526..22f8fbe 100644
--- a/dlls/wininet/tests/http.c
+++ b/dlls/wininet/tests/http.c
@@ -109,7 +109,7 @@ static int expect[MAX_INTERNET_STATUS], optional[MAX_INTERNET_STATUS],
     wine_allow[MAX_INTERNET_STATUS], notified[MAX_INTERNET_STATUS];
 static const char *status_string[MAX_INTERNET_STATUS];
 
-static HANDLE hCompleteEvent, conn_close_event;
+static HANDLE hCompleteEvent, conn_close_event, conn_wait_event;
 static DWORD req_error;
 
 #define TESTF_REDIRECT      0x01
@@ -2358,6 +2358,15 @@ static DWORD CALLBACK server_thread(LPVOID param)
             else
                 send(c, notokmsg, sizeof notokmsg-1, 0);
         }
+        if (strstr(buffer, "/async_read"))
+        {
+            const char *page1_mid = page1 + (sizeof page1 - 1)/2;
+            const char *page1_end = page1 + sizeof page1 - 1;
+            send(c, okmsg, sizeof okmsg-1, 0);
+            send(c, page1, page1_mid - page1, 0);
+            WaitForSingleObject(conn_wait_event, INFINITE);
+            send(c, page1_mid, page1_end - page1_mid, 0);
+        }
         shutdown(c, 2);
         closesocket(c);
         c = -1;
@@ -4420,6 +4429,111 @@ static void test_basic_auth_credentials_reuse(int port)
     InternetCloseHandle( ses );
 }
 
+static void test_async_read(int port)
+{
+    HINTERNET ses, con, req;
+    INTERNET_BUFFERSA ib;
+    char buffer[0x100];
+    DWORD pending_reads;
+    DWORD res, count;
+    BOOL ret;
+
+    hCompleteEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+    conn_wait_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+
+    /* test asynchronous InternetReadFileEx */
+    ses = InternetOpenA( "winetest", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, INTERNET_FLAG_ASYNC );
+    ok( ses != NULL, "InternetOpenA failed\n" );
+    pInternetSetStatusCallbackA( ses, &callback );
+
+    SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
+    con = InternetConnectA( ses, "localhost", port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0xdeadbeef );
+    ok( con != NULL, "InternetConnectA failed %u\n", GetLastError() );
+    CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
+
+    SET_EXPECT( INTERNET_STATUS_HANDLE_CREATED );
+    req = HttpOpenRequestA( con, "GET", "/async_read", NULL, NULL, NULL, INTERNET_FLAG_RELOAD, 0xdeadbeef );
+    ok( req != NULL, "HttpOpenRequestA failed %u\n", GetLastError() );
+    CHECK_NOTIFIED( INTERNET_STATUS_HANDLE_CREATED );
+
+    SET_OPTIONAL( INTERNET_STATUS_COOKIE_SENT );
+    SET_OPTIONAL( INTERNET_STATUS_DETECTING_PROXY );
+    SET_EXPECT( INTERNET_STATUS_CONNECTING_TO_SERVER );
+    SET_EXPECT( INTERNET_STATUS_CONNECTED_TO_SERVER );
+    SET_EXPECT( INTERNET_STATUS_SENDING_REQUEST );
+    SET_EXPECT( INTERNET_STATUS_REQUEST_SENT );
+    SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE );
+    SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED );
+    SET_OPTIONAL( INTERNET_STATUS_CLOSING_CONNECTION );
+    SET_OPTIONAL( INTERNET_STATUS_CONNECTION_CLOSED );
+    SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
+
+    SetLastError( 0xdeadbeef );
+    ret = HttpSendRequestA( req, NULL, 0, NULL, 0 );
+    ok( !ret, "HttpSendRequestA unexpectedly succeeded\n" );
+    ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
+    WaitForSingleObject( hCompleteEvent, INFINITE );
+    ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error );
+
+    CLEAR_NOTIFIED( INTERNET_STATUS_COOKIE_SENT );
+    CLEAR_NOTIFIED( INTERNET_STATUS_DETECTING_PROXY );
+    CHECK_NOTIFIED( INTERNET_STATUS_CONNECTING_TO_SERVER );
+    CHECK_NOTIFIED( INTERNET_STATUS_CONNECTED_TO_SERVER );
+    CHECK_NOTIFIED( INTERNET_STATUS_SENDING_REQUEST );
+    CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_SENT );
+    CHECK_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
+    CHECK_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
+    CLEAR_NOTIFIED( INTERNET_STATUS_CLOSING_CONNECTION );
+    CLEAR_NOTIFIED( INTERNET_STATUS_CONNECTION_CLOSED );
+    CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
+
+    pending_reads = 0;
+    memset( &ib, 0, sizeof(ib) );
+    memset( buffer, 0, sizeof(buffer) );
+    ib.dwStructSize = sizeof(ib);
+    for (count = 0; count < sizeof(buffer); count += ib.dwBufferLength)
+    {
+        ib.lpvBuffer = buffer + count;
+        ib.dwBufferLength = min(16, sizeof(buffer) - count);
+
+        SET_EXPECT( INTERNET_STATUS_RECEIVING_RESPONSE );
+        SET_EXPECT( INTERNET_STATUS_RESPONSE_RECEIVED );
+
+        ret = InternetReadFileExA( req, &ib, 0, 0xdeadbeef );
+        if (!count) /* the first part should arrive immediately */
+            ok( ret, "InternetReadFileExA failed %u\n", GetLastError() );
+        if (!ret)
+        {
+            ok( GetLastError() == ERROR_IO_PENDING, "expected ERROR_IO_PENDING, got %u\n", GetLastError() );
+            SET_EXPECT( INTERNET_STATUS_REQUEST_COMPLETE );
+            if (!pending_reads++)
+            {
+                res = WaitForSingleObject( hCompleteEvent, 0 );
+                ok( res == WAIT_TIMEOUT, "expected WAIT_TIMEOUT, got %u\n", res );
+                SetEvent( conn_wait_event );
+            }
+            res = WaitForSingleObject( hCompleteEvent, INFINITE );
+            ok( res == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", res );
+            ok( req_error == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", req_error );
+            todo_wine_if( pending_reads > 1 )
+            ok( ib.dwBufferLength != 0, "expected ib.dwBufferLength != 0\n" );
+            CHECK_NOTIFIED( INTERNET_STATUS_REQUEST_COMPLETE );
+        }
+
+        CLEAR_NOTIFIED( INTERNET_STATUS_RECEIVING_RESPONSE );
+        CLEAR_NOTIFIED( INTERNET_STATUS_RESPONSE_RECEIVED );
+        if (!ib.dwBufferLength) break;
+    }
+
+    todo_wine
+    ok( pending_reads == 1, "expected 1 pending read, got %u\n", pending_reads );
+    ok( !strcmp(buffer, page1), "unexpected buffer content\n" );
+    close_async_handle( ses, hCompleteEvent, 2 );
+
+    CloseHandle( hCompleteEvent );
+    CloseHandle( conn_wait_event );
+}
+
 static void test_http_connection(void)
 {
     struct server_info si;
@@ -4469,6 +4583,7 @@ static void test_http_connection(void)
     test_request_content_length(si.port);
     test_accept_encoding(si.port);
     test_basic_auth_credentials_reuse(si.port);
+    test_async_read(si.port);
 
     /* send the basic request again to shutdown the server thread */
     test_basic_request(si.port, "GET", "/quit");
-- 
2.8.0



More information about the wine-patches mailing list