Michael Moss : kernel32/tests: Test notifications for overlapping directory watches.

Alexandre Julliard julliard at winehq.org
Fri Mar 21 07:46:49 CDT 2008


Module: wine
Branch: master
Commit: ded68372a29eecc057718137a35f668f9d26d497
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ded68372a29eecc057718137a35f668f9d26d497

Author: Michael Moss <mmoss at google.com>
Date:   Thu Mar 20 11:29:58 2008 -0700

kernel32/tests: Test notifications for overlapping directory watches.

---

 dlls/kernel32/tests/change.c |   87 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 87 insertions(+), 0 deletions(-)

diff --git a/dlls/kernel32/tests/change.c b/dlls/kernel32/tests/change.c
index b698eaa..7c90ccd 100644
--- a/dlls/kernel32/tests/change.c
+++ b/dlls/kernel32/tests/change.c
@@ -776,6 +776,92 @@ static void test_readdirectorychanges_filedir(void)
     ok( r == TRUE, "failed to remove directory\n");
 }
 
+static void test_ffcn_directory_overlap(void)
+{
+    HANDLE parent_watch, child_watch, parent_thread, child_thread;
+    char workdir[MAX_PATH], parentdir[MAX_PATH], childdir[MAX_PATH];
+    char tempfile[MAX_PATH];
+    DWORD threadId;
+    BOOL ret;
+
+    /* Setup directory hierarchy */
+    ret = GetTempPathA(MAX_PATH, workdir);
+    ok((ret > 0) && (ret <= MAX_PATH),
+       "GetTempPathA error: %d\n", GetLastError());
+
+    ret = GetTempFileNameA(workdir, "fcn", 0, tempfile);
+    ok(ret, "GetTempFileNameA error: %d\n", GetLastError());
+    ret = DeleteFileA(tempfile);
+    ok(ret, "DeleteFileA error: %d\n", GetLastError());
+
+    lstrcpyA(parentdir, tempfile);
+    ret = CreateDirectoryA(parentdir, NULL);
+    ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
+
+    lstrcpyA(childdir, parentdir);
+    lstrcatA(childdir, "\\c");
+    ret = CreateDirectoryA(childdir, NULL);
+    ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
+
+
+    /* When recursively watching overlapping directories, changes in child
+     * should trigger notifications for both child and parent */
+    parent_thread = StartNotificationThread(parentdir, TRUE,
+                                            FILE_NOTIFY_CHANGE_FILE_NAME);
+    child_thread = StartNotificationThread(childdir, TRUE,
+                                            FILE_NOTIFY_CHANGE_FILE_NAME);
+
+    /* Create a file in child */
+    ret = GetTempFileNameA(childdir, "fcn", 0, tempfile);
+    ok(ret, "GetTempFileNameA error: %d\n", GetLastError());
+
+    /* Both watches should trigger */
+    ret = FinishNotificationThread(parent_thread);
+    ok(ret, "Missed parent notification\n");
+    ret = FinishNotificationThread(child_thread);
+    ok(ret, "Missed child notification\n");
+
+    ret = DeleteFileA(tempfile);
+    ok(ret, "DeleteFileA error: %d\n", GetLastError());
+
+
+    /* Removing a recursive parent watch should not affect child watches. Doing
+     * so used to crash wineserver. */
+    parent_watch = FindFirstChangeNotificationA(parentdir, TRUE,
+                                                FILE_NOTIFY_CHANGE_FILE_NAME);
+    ok(parent_watch != INVALID_HANDLE_VALUE,
+       "FindFirstChangeNotification error: %d\n", GetLastError());
+    child_watch = FindFirstChangeNotificationA(childdir, TRUE,
+                                               FILE_NOTIFY_CHANGE_FILE_NAME);
+    ok(child_watch != INVALID_HANDLE_VALUE,
+       "FindFirstChangeNotification error: %d\n", GetLastError());
+
+    ret = FindCloseChangeNotification(parent_watch);
+    ok(ret, "FindCloseChangeNotification error: %d\n", GetLastError());
+
+    child_thread = CreateThread(NULL, 0, NotificationThread,
+                                (LPVOID)child_watch, 0, &threadId);
+    ok(child_thread != NULL, "CreateThread error: %d\n", GetLastError());
+
+    /* Create a file in child */
+    ret = GetTempFileNameA(childdir, "fcn", 0, tempfile);
+    ok(ret, "GetTempFileNameA error: %d\n", GetLastError());
+
+    /* Child watch should trigger */
+    ret = FinishNotificationThread(child_thread);
+    ok(ret, "Missed child notification\n");
+
+    /* clean up */
+    ret = DeleteFileA(tempfile);
+    ok(ret, "DeleteFileA error: %d\n", GetLastError());
+
+    ret = RemoveDirectoryA(childdir);
+    ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
+
+    ret = RemoveDirectoryA(parentdir);
+    ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
+}
+
 START_TEST(change)
 {
     HMODULE hkernel32 = GetModuleHandle("kernel32");
@@ -791,4 +877,5 @@ START_TEST(change)
     test_readdirectorychanges();
     test_readdirectorychanges_null();
     test_readdirectorychanges_filedir();
+    test_ffcn_directory_overlap();
 }




More information about the wine-cvs mailing list