[3/3] kernel32/tests: test CopyFile2 callback and cancellation

Daniel Jeliński djelinski1 at gmail.com
Sun Sep 29 15:54:38 CDT 2013


still working on tests for COPYFILE2_CALLBACK_ERROR.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20130929/1dda8f97/attachment-0001.html>
-------------- next part --------------
From 4ad647cdcea39db06f86492daf139f6822fdb6a8 Mon Sep 17 00:00:00 2001
From: Daniel Jelinski <djelinski1 at gmail.com>
Date: Sun, 15 Sep 2013 22:13:50 +0200
Subject: [PATCH 3/3] kernel32/tests: test CopyFile2 callback and cancellation

---
 dlls/kernel32/tests/file.c | 253 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 253 insertions(+)

diff --git a/dlls/kernel32/tests/file.c b/dlls/kernel32/tests/file.c
index d22959a..c26738b 100644
--- a/dlls/kernel32/tests/file.c
+++ b/dlls/kernel32/tests/file.c
@@ -79,6 +79,24 @@ struct progress_list {
     const DWORD lastError;             /* expected CopyFileEx error code */
 } ;
 
+/* structures for testing CopyFile2 */
+struct progress_list2 {
+    const COPYFILE2_MESSAGE_TYPE Type;              /* expected callback type */
+    const COPYFILE2_MESSAGE_ACTION progress_retval; /* value to return from progress routine */
+    const BOOL cancel;                              /* value to set Cancel flag to */
+};
+struct CopyFile2_test_list {
+    const struct progress_list2 callback[4]; /* expected callbacks */
+    const int test_id;                       /* identifier of test */
+    const int progress_count;                /* number of expected callbacks */
+    const DWORD result;                      /* expected CopyFile2 return value */
+    const BOOL expect_empty;                 /* expect zero bytes transferred in finish notification */
+};
+struct CopyFile2_data {
+    const struct CopyFile2_test_list* test_list;
+    int test_idx;
+};
+
 static void InitFunctionPointers(void)
 {
     HMODULE hkernel32 = GetModuleHandleA("kernel32");
@@ -897,8 +915,191 @@ static void test_CopyFileEx(void)
     ret = DeleteFileA(dest);
     ok(ret, "DeleteFileA: error %d\n", GetLastError());
 }
+
+static COPYFILE2_MESSAGE_ACTION CALLBACK progress2(
+        const COPYFILE2_MESSAGE *pMessage,
+        PVOID lpData)
+{
+    int fileSize;
+    struct CopyFile2_data* data = (struct CopyFile2_data*)lpData;
+    const struct CopyFile2_test_list test = data->test_list[data->test_idx];
+    int test_id = test.test_id;
+    ok(pMessage->Type == test.callback[progressInvoked].Type,
+            "unexpected type %d during test %d in callback %d\n",
+             pMessage->Type, test_id, progressInvoked);
+    switch (pMessage->Type)
+    {
+        case COPYFILE2_CALLBACK_STREAM_STARTED:
+            fileSize = GetFileSize(pMessage->Info.StreamStarted.hSourceFile, NULL);
+            ok(pMessage->Info.StreamStarted.uliTotalFileSize.LowPart == fileSize,
+                "Unexpected uliTotalFileSize: %d in test %d\n", pMessage->Info.StreamStarted.uliTotalFileSize.LowPart, test_id);
+            ok(pMessage->Info.StreamStarted.uliStreamSize.LowPart == fileSize,
+                "Unexpected uliStreamSize: %d in test %d\n", pMessage->Info.StreamStarted.uliStreamSize.LowPart, test_id);
+            ok(pMessage->Info.StreamStarted.dwStreamNumber == 1,
+                "Unexpected dwStreamNumber: %d in test %d\n", pMessage->Info.StreamStarted.dwStreamNumber, test_id);
+            break;
+        case COPYFILE2_CALLBACK_CHUNK_STARTED:
+            fileSize = GetFileSize(pMessage->Info.ChunkStarted.hSourceFile, NULL);
+            ok(pMessage->Info.ChunkStarted.uliTotalFileSize.LowPart == fileSize,
+                "Unexpected uliTotalFileSize: %d in test %d\n", pMessage->Info.ChunkStarted.uliTotalFileSize.LowPart, test_id);
+            ok(pMessage->Info.ChunkStarted.uliStreamSize.LowPart == fileSize,
+                "Unexpected uliStreamSize: %d in test %d\n", pMessage->Info.ChunkStarted.uliStreamSize.LowPart, test_id);
+            ok(pMessage->Info.ChunkStarted.uliChunkNumber.LowPart == 0,
+                "Unexpected uliChunkNumber: %d in test %d\n", pMessage->Info.ChunkStarted.uliChunkNumber.LowPart, test_id);
+            ok(pMessage->Info.ChunkStarted.uliChunkSize.LowPart == fileSize,
+                "Unexpected uliChunkSize: %d in test %d\n", pMessage->Info.ChunkStarted.uliChunkSize.LowPart, test_id);
+            ok(pMessage->Info.ChunkStarted.dwStreamNumber == 1,
+                "Unexpected dwStreamNumber: %d in test %d\n", pMessage->Info.ChunkStarted.dwStreamNumber, test_id);
+            break;
+        case COPYFILE2_CALLBACK_CHUNK_FINISHED:
+            fileSize = GetFileSize(pMessage->Info.ChunkFinished.hSourceFile, NULL);
+            ok(pMessage->Info.ChunkFinished.uliTotalFileSize.LowPart == fileSize,
+                "Unexpected uliTotalFileSize: %d in test %d\n", pMessage->Info.ChunkFinished.uliTotalFileSize.LowPart, test_id);
+            ok(pMessage->Info.ChunkFinished.uliStreamSize.LowPart == fileSize,
+                "Unexpected uliStreamSize: %d in test %d\n", pMessage->Info.ChunkFinished.uliStreamSize.LowPart, test_id);
+            ok(pMessage->Info.ChunkFinished.uliTotalBytesTransferred.LowPart == fileSize,
+                "Unexpected uliTotalBytesTransferred: %d in test %d\n", pMessage->Info.ChunkFinished.uliTotalBytesTransferred.LowPart, test_id);
+            ok(pMessage->Info.ChunkFinished.uliStreamBytesTransferred.LowPart == fileSize,
+                "Unexpected uliStreamBytesTransferred: %d in test %d\n", pMessage->Info.ChunkFinished.uliStreamBytesTransferred.LowPart, test_id);
+            ok(pMessage->Info.ChunkFinished.uliChunkNumber.LowPart == 0,
+                "Unexpected uliChunkNumber: %d in test %d\n", pMessage->Info.ChunkFinished.uliChunkNumber.LowPart, test_id);
+            ok(pMessage->Info.ChunkFinished.uliChunkSize.LowPart == fileSize,
+                "Unexpected uliChunkSize: %d in test %d\n", pMessage->Info.ChunkFinished.uliChunkSize.LowPart, test_id);
+            ok(pMessage->Info.ChunkFinished.dwStreamNumber == 1,
+                "Unexpected dwStreamNumber: %d in test %d\n", pMessage->Info.ChunkFinished.dwStreamNumber, test_id);
+            break;
+        case COPYFILE2_CALLBACK_STREAM_FINISHED:
+            fileSize = GetFileSize(pMessage->Info.StreamFinished.hSourceFile, NULL);
+            ok(pMessage->Info.StreamFinished.uliTotalFileSize.LowPart == fileSize,
+                "Unexpected uliTotalFileSize: %d in test %d\n", pMessage->Info.StreamFinished.uliTotalFileSize.LowPart, test_id);
+            ok(pMessage->Info.StreamFinished.uliStreamSize.LowPart == fileSize,
+                "Unexpected uliStreamSize: %d in test %d\n", pMessage->Info.StreamFinished.uliStreamSize.LowPart, test_id);
+            if (test.expect_empty)
+            {
+                ok(pMessage->Info.StreamFinished.uliTotalBytesTransferred.LowPart == 0,
+                    "Unexpected uliTotalBytesTransferred: %d in test %d\n", pMessage->Info.StreamFinished.uliTotalBytesTransferred.LowPart, test_id);
+                ok(pMessage->Info.StreamFinished.uliStreamBytesTransferred.LowPart == 0,
+                    "Unexpected uliStreamBytesTransferred: %d in test %d\n", pMessage->Info.StreamFinished.uliStreamBytesTransferred.LowPart, test_id);
+            }
+            else
+            {
+                ok(pMessage->Info.StreamFinished.uliTotalBytesTransferred.LowPart == fileSize,
+                    "Unexpected uliTotalBytesTransferred: %d in test %d\n", pMessage->Info.StreamFinished.uliTotalBytesTransferred.LowPart, test_id);
+                ok(pMessage->Info.StreamFinished.uliStreamBytesTransferred.LowPart == fileSize,
+                    "Unexpected uliStreamBytesTransferred: %d in test %d\n", pMessage->Info.StreamFinished.uliStreamBytesTransferred.LowPart, test_id);
+            }
+            ok(pMessage->Info.StreamFinished.dwStreamNumber == 1,
+                "Unexpected dwStreamNumber: %d in test %d\n", pMessage->Info.StreamFinished.dwStreamNumber, test_id);
+            break;
+        default:
+            break;
+    }
+    cancel = test.callback[progressInvoked].cancel;
+    return test.callback[progressInvoked++].progress_retval;
+}
+
 static void test_CopyFile2(void)
 {
+    static const struct CopyFile2_test_list progress_tests2_empty[] = {
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE }
+          }, 1, 2, S_OK, TRUE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CONTINUE, TRUE }
+          }, 2, 2, ERROR_REQUEST_ABORTED, TRUE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_STOP, FALSE }
+          }, 3, 2, ERROR_REQUEST_ABORTED, TRUE },
+
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CANCEL, FALSE }
+          }, 4, 2, ERROR_REQUEST_ABORTED, TRUE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CANCEL, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE }
+          }, 5, 2, ERROR_REQUEST_ABORTED, TRUE },
+
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_PAUSE, FALSE }
+          }, 6, 2, S_OK, TRUE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_PAUSE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE }
+          }, 7, 2, S_OK, TRUE },
+
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_QUIET, FALSE }
+          }, 8, 2, S_OK, TRUE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_QUIET, FALSE }
+          }, 9, 1, S_OK, TRUE }
+        };
+
+    static const struct CopyFile2_test_list progress_tests2_nonempty[] = {
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE }
+          }, 101, 4, S_OK, FALSE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CONTINUE, TRUE }
+          }, 102, 4, ERROR_REQUEST_ABORTED, FALSE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_STOP, FALSE }
+          }, 103, 4, ERROR_REQUEST_ABORTED, FALSE },
+
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CANCEL, FALSE }
+          }, 104, 4, ERROR_REQUEST_ABORTED, FALSE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_FINISHED, COPYFILE2_PROGRESS_CANCEL, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE }
+          }, 105, 4, ERROR_REQUEST_ABORTED, FALSE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_STARTED, COPYFILE2_PROGRESS_CANCEL, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE }
+          }, 106, 3, ERROR_REQUEST_ABORTED, TRUE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CANCEL, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE }
+          }, 107, 2, ERROR_REQUEST_ABORTED, TRUE },
+
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_PAUSE, FALSE }
+          }, 108, 4, S_OK, FALSE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_FINISHED, COPYFILE2_PROGRESS_PAUSE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE }
+          }, 109, 4, S_OK, FALSE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_STARTED, COPYFILE2_PROGRESS_PAUSE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE }
+          }, 110, 3, ERROR_REQUEST_PAUSED, TRUE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_PAUSE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE }
+          }, 111, 2, ERROR_REQUEST_PAUSED, TRUE },
+
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_FINISHED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_STREAM_FINISHED, COPYFILE2_PROGRESS_QUIET, FALSE }
+          }, 112, 4, S_OK, FALSE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_FINISHED, COPYFILE2_PROGRESS_QUIET, FALSE }
+          }, 113, 3, S_OK, FALSE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_CONTINUE, FALSE },
+            { COPYFILE2_CALLBACK_CHUNK_STARTED, COPYFILE2_PROGRESS_QUIET, FALSE }
+          }, 114, 2, S_OK, FALSE },
+        { { { COPYFILE2_CALLBACK_STREAM_STARTED, COPYFILE2_PROGRESS_QUIET, FALSE }
+          }, 115, 1, S_OK, FALSE }
+        };
     static const WCHAR doesntexistW[] = {'d','o','e','s','n','t','e','x','i','s','t',0};
     static const WCHAR prefix[] = {'p','f','x',0};
     WCHAR source[MAX_PATH], dest[MAX_PATH], temp_path[MAX_PATH];
@@ -906,8 +1107,11 @@ static void test_CopyFile2(void)
     HANDLE hfile, hmapfile;
     FILETIME ft1, ft2;
     DWORD ret, len;
+    int i;
+    BOOL retok;
     char buf[10];
     HRESULT hr;
+    struct CopyFile2_data progress_param;
 
     if (!pCopyFile2)
     {
@@ -942,6 +1146,55 @@ static void test_CopyFile2(void)
     hr = pCopyFile2(source, dest, &params);
     ok(hr == S_OK, "CopyFile2: error 0x%08x\n", hr);
 
+    /* test progress routine - empty file */
+    params.pfCancel = &cancel;
+    params.pProgressRoutine = progress2;
+    params.pvCallbackContext = &progress_param;
+
+    progress_param.test_list = progress_tests2_empty;
+    for (i = 0; i < sizeof(progress_tests2_empty) / sizeof(progress_tests2_empty[0]); i++)
+    {
+        progress_param.test_idx = i;
+        progressInvoked = 0;
+        SetLastError(0xdeadbeef);
+        hr = pCopyFile2(source, dest, &params);
+        ok(hr == HRESULT_FROM_WIN32(progress_tests2_empty[i].result),
+                "CopyFile2: error 0x%08x in test %d\n", hr, progress_tests2_empty[i].test_id);
+        if (FAILED(hr))
+            ok(GetLastError() == progress_tests2_empty[i].result,
+                    "CopyFile2: GetLastError returned 0x%08x in test %d\n", GetLastError(), progress_tests2_empty[i].test_id);
+        ok(progressInvoked == progress_tests2_empty[i].progress_count,
+                "Unexpected number of progress reports %d in test %d\n", progressInvoked, progress_tests2_empty[i].test_id);
+    }
+    /* test progress routine - nonempty file */
+    hfile = CreateFileW(source, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0 );
+    ok(hfile != INVALID_HANDLE_VALUE, "failed to open source file\n");
+    retok = WriteFile(hfile, prefix, sizeof(prefix), &ret, NULL );
+    ok( retok && ret == sizeof(prefix), "WriteFile error %d\n", GetLastError());
+    ok(GetFileSize(hfile, NULL) == sizeof(prefix), "source file has wrong size\n");
+    CloseHandle(hfile);
+
+    params.pfCancel = &cancel;
+    params.pProgressRoutine = progress2;
+    params.pvCallbackContext = &progress_param;
+
+    progress_param.test_list = progress_tests2_nonempty;
+    for (i = 0; i < sizeof(progress_tests2_nonempty) / sizeof(progress_tests2_nonempty[0]); i++)
+    {
+        progress_param.test_idx = i;
+        progressInvoked = 0;
+        SetLastError(0xdeadbeef);
+        hr = pCopyFile2(source, dest, &params);
+        ok(hr == HRESULT_FROM_WIN32(progress_tests2_nonempty[i].result),
+                "CopyFile2: error 0x%08x in test %d\n", hr, progress_tests2_nonempty[i].test_id);
+        if (FAILED(hr))
+            ok(GetLastError() == progress_tests2_nonempty[i].result,
+                    "CopyFile2: GetLastError returned 0x%08x in test %d\n", GetLastError(), progress_tests2_nonempty[i].test_id);
+        ok(progressInvoked == progress_tests2_nonempty[i].progress_count,
+                "Unexpected number of progress reports %d in test %d\n", progressInvoked, progress_tests2_nonempty[i].test_id);
+    }
+
+    memset(&params, 0, sizeof(params));
     /* copying a file to itself must fail */
     params.dwSize = sizeof(params);
     params.dwCopyFlags = 0;
-- 
1.8.1.2


More information about the wine-patches mailing list