Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: base/files/file_path_watcher_browsertest.cc

Issue 313083007: Use FSEvents for recursive file watch on Mac (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: missing ; Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/files/file_path_watcher.h" 5 #include "base/files/file_path_watcher.h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 #include <windows.h> 8 #include <windows.h>
9 #include <aclapi.h> 9 #include <aclapi.h>
10 #elif defined(OS_POSIX) 10 #elif defined(OS_POSIX)
(...skipping 13 matching lines...) Expand all
24 #include "base/message_loop/message_loop_proxy.h" 24 #include "base/message_loop/message_loop_proxy.h"
25 #include "base/run_loop.h" 25 #include "base/run_loop.h"
26 #include "base/stl_util.h" 26 #include "base/stl_util.h"
27 #include "base/strings/stringprintf.h" 27 #include "base/strings/stringprintf.h"
28 #include "base/synchronization/waitable_event.h" 28 #include "base/synchronization/waitable_event.h"
29 #include "base/test/test_file_util.h" 29 #include "base/test/test_file_util.h"
30 #include "base/test/test_timeouts.h" 30 #include "base/test/test_timeouts.h"
31 #include "base/threading/thread.h" 31 #include "base/threading/thread.h"
32 #include "testing/gtest/include/gtest/gtest.h" 32 #include "testing/gtest/include/gtest/gtest.h"
33 33
34 #if defined(OS_MACOSX)
35 #include "base/mac/mac_util.h"
36 #endif
37
34 namespace base { 38 namespace base {
35 39
36 namespace { 40 namespace {
37 41
38 class TestDelegate; 42 class TestDelegate;
39 43
44
45 bool RecursiveWatchAvaiable() {
46 #if defined(OS_MACOSX) && !defined(OS_IOS)
47 // FSEvents isn't available on iOS and is broken on OSX 10.6 and earlier.
48 // See http://crbug.com/54822#c31
49 return mac::IsOSLionOrLater();
50 #elif defined(OS_WIN) || defined(OS_LINUX)
51 return true;
52 #else
53 return false;
54 #endif
55 }
56
40 // Aggregates notifications from the test delegates and breaks the message loop 57 // Aggregates notifications from the test delegates and breaks the message loop
41 // the test thread is waiting on once they all came in. 58 // the test thread is waiting on once they all came in.
42 class NotificationCollector 59 class NotificationCollector
43 : public base::RefCountedThreadSafe<NotificationCollector> { 60 : public base::RefCountedThreadSafe<NotificationCollector> {
44 public: 61 public:
45 NotificationCollector() 62 NotificationCollector()
46 : loop_(base::MessageLoopProxy::current()) {} 63 : loop_(base::MessageLoopProxy::current()) {}
47 64
48 // Called from the file thread by the delegates. 65 // Called from the file thread by the delegates.
49 void OnChange(TestDelegate* delegate) { 66 void OnChange(TestDelegate* delegate) {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 }; 215 };
199 216
200 bool FilePathWatcherTest::SetupWatch(const FilePath& target, 217 bool FilePathWatcherTest::SetupWatch(const FilePath& target,
201 FilePathWatcher* watcher, 218 FilePathWatcher* watcher,
202 TestDelegateBase* delegate, 219 TestDelegateBase* delegate,
203 bool recursive_watch) { 220 bool recursive_watch) {
204 base::WaitableEvent completion(false, false); 221 base::WaitableEvent completion(false, false);
205 bool result; 222 bool result;
206 file_thread_.message_loop_proxy()->PostTask( 223 file_thread_.message_loop_proxy()->PostTask(
207 FROM_HERE, 224 FROM_HERE,
208 base::Bind(SetupWatchCallback, 225 base::Bind(SetupWatchCallback, target, watcher, delegate, recursive_watch,
209 target, watcher, delegate, recursive_watch, &result, 226 &result, &completion));
210 &completion));
211 completion.Wait(); 227 completion.Wait();
212 return result; 228 return result;
213 } 229 }
214 230
215 // Basic test: Create the file and verify that we notice. 231 // Basic test: Create the file and verify that we notice.
216 TEST_F(FilePathWatcherTest, NewFile) { 232 TEST_F(FilePathWatcherTest, NewFile) {
217 FilePathWatcher watcher; 233 FilePathWatcher watcher;
218 scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); 234 scoped_ptr<TestDelegate> delegate(new TestDelegate(collector()));
219 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); 235 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false));
220 236
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 ASSERT_TRUE(WaitForEvents()); 492 ASSERT_TRUE(WaitForEvents());
477 493
478 // Move the parent directory. 494 // Move the parent directory.
479 base::Move(dir, dest); 495 base::Move(dir, dest);
480 VLOG(1) << "Waiting for directory move"; 496 VLOG(1) << "Waiting for directory move";
481 ASSERT_TRUE(WaitForEvents()); 497 ASSERT_TRUE(WaitForEvents());
482 DeleteDelegateOnFileThread(file_delegate.release()); 498 DeleteDelegateOnFileThread(file_delegate.release());
483 DeleteDelegateOnFileThread(subdir_delegate.release()); 499 DeleteDelegateOnFileThread(subdir_delegate.release());
484 } 500 }
485 501
486 #if defined(OS_WIN) || defined(OS_LINUX)
487 TEST_F(FilePathWatcherTest, RecursiveWatch) { 502 TEST_F(FilePathWatcherTest, RecursiveWatch) {
488 FilePathWatcher watcher; 503 FilePathWatcher watcher;
489 FilePath dir(temp_dir_.path().AppendASCII("dir")); 504 FilePath dir(temp_dir_.path().AppendASCII("dir"));
490 scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); 505 scoped_ptr<TestDelegate> delegate(new TestDelegate(collector()));
491 ASSERT_TRUE(SetupWatch(dir, &watcher, delegate.get(), true)); 506 bool setup_result = SetupWatch(dir, &watcher, delegate.get(), true);
507 if (!RecursiveWatchAvaiable()) {
508 ASSERT_FALSE(setup_result);
509 DeleteDelegateOnFileThread(delegate.release());
510 return;
511 }
512 ASSERT_TRUE(setup_result);
492 513
493 // Main directory("dir") creation. 514 // Main directory("dir") creation.
494 ASSERT_TRUE(base::CreateDirectory(dir)); 515 ASSERT_TRUE(base::CreateDirectory(dir));
495 ASSERT_TRUE(WaitForEvents()); 516 ASSERT_TRUE(WaitForEvents());
496 517
497 // Create "$dir/file1". 518 // Create "$dir/file1".
498 FilePath file1(dir.AppendASCII("file1")); 519 FilePath file1(dir.AppendASCII("file1"));
499 ASSERT_TRUE(WriteFile(file1, "content")); 520 ASSERT_TRUE(WriteFile(file1, "content"));
500 ASSERT_TRUE(WaitForEvents()); 521 ASSERT_TRUE(WaitForEvents());
501 522
(...skipping 27 matching lines...) Expand all
529 550
530 // Delete "$dir/subdir/subdir_file1". 551 // Delete "$dir/subdir/subdir_file1".
531 ASSERT_TRUE(base::DeleteFile(subdir_file1, false)); 552 ASSERT_TRUE(base::DeleteFile(subdir_file1, false));
532 ASSERT_TRUE(WaitForEvents()); 553 ASSERT_TRUE(WaitForEvents());
533 554
534 // Delete "$dir/subdir/subdir_child_dir/child_dir_file1". 555 // Delete "$dir/subdir/subdir_child_dir/child_dir_file1".
535 ASSERT_TRUE(base::DeleteFile(child_dir_file1, false)); 556 ASSERT_TRUE(base::DeleteFile(child_dir_file1, false));
536 ASSERT_TRUE(WaitForEvents()); 557 ASSERT_TRUE(WaitForEvents());
537 DeleteDelegateOnFileThread(delegate.release()); 558 DeleteDelegateOnFileThread(delegate.release());
538 } 559 }
539 #else 560
540 TEST_F(FilePathWatcherTest, RecursiveWatch) { 561 #if defined(OS_POSIX)
562 TEST_F(FilePathWatcherTest, RecursiveWithSymLink) {
563 if (!RecursiveWatchAvaiable())
564 return;
565
541 FilePathWatcher watcher; 566 FilePathWatcher watcher;
542 FilePath dir(temp_dir_.path().AppendASCII("dir")); 567 FilePath test_dir(temp_dir_.path().AppendASCII("test_dir"));
568 ASSERT_TRUE(base::CreateDirectory(test_dir));
569 FilePath symlink(test_dir.AppendASCII("symlink"));
543 scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); 570 scoped_ptr<TestDelegate> delegate(new TestDelegate(collector()));
544 // Only Windows/Linux support recursive watching. Other implementations 571 ASSERT_TRUE(SetupWatch(symlink, &watcher, delegate.get(), true));
545 // should simply fail. 572
546 ASSERT_FALSE(SetupWatch(dir, &watcher, delegate.get(), true)); 573 // Link creation.
574 FilePath target1(temp_dir_.path().AppendASCII("target1"));
575 ASSERT_TRUE(base::CreateSymbolicLink(target1, symlink));
576 ASSERT_TRUE(WaitForEvents());
577
578 // Target1 creation.
579 ASSERT_TRUE(base::CreateDirectory(target1));
580 ASSERT_TRUE(WaitForEvents());
581
582 // Create a file in target1.
583 FilePath target1_file(target1.AppendASCII("file"));
584 ASSERT_TRUE(WriteFile(target1_file, "content"));
585 ASSERT_TRUE(WaitForEvents());
586
587 // Link change.
588 FilePath target2(temp_dir_.path().AppendASCII("target2"));
589 ASSERT_TRUE(base::CreateDirectory(target2));
590 ASSERT_TRUE(base::DeleteFile(symlink, false));
591 ASSERT_TRUE(base::CreateSymbolicLink(target2, symlink));
592 ASSERT_TRUE(WaitForEvents());
593
594 // Create a file in target2.
595 FilePath target2_file(target2.AppendASCII("file"));
596 ASSERT_TRUE(WriteFile(target2_file, "content"));
597 ASSERT_TRUE(WaitForEvents());
598
547 DeleteDelegateOnFileThread(delegate.release()); 599 DeleteDelegateOnFileThread(delegate.release());
548 } 600 }
549 #endif 601 #endif // OS_POSIX
550 602
551 TEST_F(FilePathWatcherTest, MoveChild) { 603 TEST_F(FilePathWatcherTest, MoveChild) {
552 FilePathWatcher file_watcher; 604 FilePathWatcher file_watcher;
553 FilePathWatcher subdir_watcher; 605 FilePathWatcher subdir_watcher;
554 FilePath source_dir(temp_dir_.path().AppendASCII("source")); 606 FilePath source_dir(temp_dir_.path().AppendASCII("source"));
555 FilePath source_subdir(source_dir.AppendASCII("subdir")); 607 FilePath source_subdir(source_dir.AppendASCII("subdir"));
556 FilePath source_file(source_subdir.AppendASCII("file")); 608 FilePath source_file(source_subdir.AppendASCII("file"));
557 FilePath dest_dir(temp_dir_.path().AppendASCII("dest")); 609 FilePath dest_dir(temp_dir_.path().AppendASCII("dest"));
558 FilePath dest_subdir(dest_dir.AppendASCII("subdir")); 610 FilePath dest_subdir(dest_dir.AppendASCII("subdir"));
559 FilePath dest_file(dest_subdir.AppendASCII("file")); 611 FilePath dest_file(dest_subdir.AppendASCII("file"));
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, false)); 880 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, false));
829 ASSERT_TRUE(WaitForEvents()); 881 ASSERT_TRUE(WaitForEvents());
830 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, true)); 882 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, true));
831 DeleteDelegateOnFileThread(delegate.release()); 883 DeleteDelegateOnFileThread(delegate.release());
832 } 884 }
833 885
834 #endif // OS_MACOSX 886 #endif // OS_MACOSX
835 } // namespace 887 } // namespace
836 888
837 } // namespace base 889 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698