Index: base/files/file_path_watcher_browsertest.cc |
=================================================================== |
--- base/files/file_path_watcher_browsertest.cc (revision 170236) |
+++ base/files/file_path_watcher_browsertest.cc (working copy) |
@@ -4,8 +4,6 @@ |
#include "base/files/file_path_watcher.h" |
-#include <set> |
- |
#if defined(OS_WIN) |
#include <windows.h> |
#include <aclapi.h> |
@@ -13,6 +11,8 @@ |
#include <sys/stat.h> |
#endif |
+#include <set> |
+ |
#include "base/basictypes.h" |
#include "base/bind.h" |
#include "base/bind_helpers.h" |
@@ -22,7 +22,6 @@ |
#include "base/files/scoped_temp_dir.h" |
#include "base/message_loop.h" |
#include "base/message_loop_proxy.h" |
-#include "base/path_service.h" |
#include "base/stl_util.h" |
#include "base/stringprintf.h" |
#include "base/synchronization/waitable_event.h" |
@@ -50,7 +49,7 @@ |
void OnChange(TestDelegate* delegate) { |
loop_->PostTask(FROM_HERE, |
base::Bind(&NotificationCollector::RecordChange, this, |
- make_scoped_refptr(delegate))); |
+ base::Unretained(delegate))); |
} |
void Register(TestDelegate* delegate) { |
@@ -70,6 +69,7 @@ |
~NotificationCollector() {} |
void RecordChange(TestDelegate* delegate) { |
+ // Warning: |delegate| is Unretained. Do not dereference. |
ASSERT_TRUE(loop_->BelongsToCurrentThread()); |
ASSERT_TRUE(delegates_.count(delegate)); |
signaled_.insert(delegate); |
@@ -89,52 +89,54 @@ |
scoped_refptr<base::MessageLoopProxy> loop_; |
}; |
-// A mock FilePathWatcher::Delegate for testing. I'd rather use gmock, but it's |
-// not thread safe for setting expectations, so the test code couldn't safely |
-// reset expectations while the file watcher is running. In order to allow this, |
-// we keep simple thread safe status flags in TestDelegate. |
-class TestDelegate : public FilePathWatcher::Delegate { |
+class TestDelegateBase : public SupportsWeakPtr<TestDelegateBase> { |
public: |
- // The message loop specified by |loop| will be quit if a notification is |
- // received while the delegate is |armed_|. Note that the testing code must |
- // guarantee |loop| outlives the file thread on which OnFilePathChanged runs. |
+ TestDelegateBase() {} |
+ virtual ~TestDelegateBase() {} |
+ |
+ virtual void OnFileChanged(const FilePath& path, bool error) = 0; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(TestDelegateBase); |
+}; |
+ |
+// A mock class for testing. Gmock is not appropriate because it is not |
+// thread-safe for setting expectations. Thus the test code cannot safely |
+// reset expectations while the file watcher is running. |
+// Instead, TestDelegate gets the notifications from FilePathWatcher and uses |
+// NotificationCollector to aggregate the results. |
+class TestDelegate : public TestDelegateBase { |
+ public: |
explicit TestDelegate(NotificationCollector* collector) |
: collector_(collector) { |
collector_->Register(this); |
} |
+ ~TestDelegate() {} |
- virtual void OnFilePathChanged(const FilePath&) { |
- collector_->OnChange(this); |
+ virtual void OnFileChanged(const FilePath& path, bool error) OVERRIDE { |
+ if (error) |
+ ADD_FAILURE() << "Error " << path.value(); |
+ else |
+ collector_->OnChange(this); |
} |
- virtual void OnFilePathError(const FilePath& path) { |
- ADD_FAILURE() << "Error " << path.value(); |
- } |
- |
- protected: |
- virtual ~TestDelegate() {} |
- |
private: |
scoped_refptr<NotificationCollector> collector_; |
DISALLOW_COPY_AND_ASSIGN(TestDelegate); |
}; |
-void SetupWatchDelegate(const FilePath& target, |
+void SetupWatchCallback(const FilePath& target, |
FilePathWatcher* watcher, |
- FilePathWatcher::Delegate* delegate, |
+ TestDelegateBase* delegate, |
bool* result, |
base::WaitableEvent* completion) { |
- *result = watcher->Watch(target, delegate); |
+ *result = watcher->Watch(target, |
+ base::Bind(&TestDelegateBase::OnFileChanged, |
+ delegate->AsWeakPtr())); |
completion->Signal(); |
} |
-void SetupWatchCallback(const FilePath& target, |
- FilePathWatcher* watcher, |
- const FilePathWatcher::Callback& callback) { |
- ASSERT_TRUE(watcher->Watch(target, callback)); |
-} |
- |
void QuitLoopWatchCallback(MessageLoop* loop, |
const FilePath& expected_path, |
bool expected_error, |
@@ -168,6 +170,10 @@ |
loop_.RunUntilIdle(); |
} |
+ void DeleteDelegateOnFileThread(TestDelegate* delegate) { |
+ file_thread_.message_loop_proxy()->DeleteSoon(FROM_HERE, delegate); |
+ } |
+ |
FilePath test_file() { |
return temp_dir_.path().AppendASCII("FilePathWatcherTest"); |
} |
@@ -185,16 +191,7 @@ |
bool SetupWatch(const FilePath& target, |
FilePathWatcher* watcher, |
- FilePathWatcher::Delegate* delegate) WARN_UNUSED_RESULT { |
- base::WaitableEvent completion(false, false); |
- bool result; |
- file_thread_.message_loop_proxy()->PostTask( |
- FROM_HERE, |
- base::Bind(SetupWatchDelegate, target, watcher, |
- make_scoped_refptr(delegate), &result, &completion)); |
- completion.Wait(); |
- return result; |
- } |
+ TestDelegateBase* delegate) WARN_UNUSED_RESULT; |
bool WaitForEvents() WARN_UNUSED_RESULT { |
collector_->Reset(); |
@@ -208,16 +205,32 @@ |
base::Thread file_thread_; |
ScopedTempDir temp_dir_; |
scoped_refptr<NotificationCollector> collector_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FilePathWatcherTest); |
}; |
+bool FilePathWatcherTest::SetupWatch(const FilePath& target, |
+ FilePathWatcher* watcher, |
+ TestDelegateBase* delegate) { |
+ base::WaitableEvent completion(false, false); |
+ bool result; |
+ file_thread_.message_loop_proxy()->PostTask( |
+ FROM_HERE, |
+ base::Bind(SetupWatchCallback, |
+ target, watcher, delegate, &result, &completion)); |
+ completion.Wait(); |
+ return result; |
+} |
+ |
// Basic test: Create the file and verify that we notice. |
TEST_F(FilePathWatcherTest, NewFile) { |
FilePathWatcher watcher; |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get())); |
ASSERT_TRUE(WriteFile(test_file(), "content")); |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
// Verify that modifying the file is caught. |
@@ -225,12 +238,13 @@ |
ASSERT_TRUE(WriteFile(test_file(), "content")); |
FilePathWatcher watcher; |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get())); |
// Now make sure we get notified if the file is modified. |
ASSERT_TRUE(WriteFile(test_file(), "new content")); |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
// Verify that moving the file into place is caught. |
@@ -239,92 +253,57 @@ |
ASSERT_TRUE(WriteFile(source_file, "content")); |
FilePathWatcher watcher; |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get())); |
// Now make sure we get notified if the file is modified. |
ASSERT_TRUE(file_util::Move(source_file, test_file())); |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
TEST_F(FilePathWatcherTest, DeletedFile) { |
ASSERT_TRUE(WriteFile(test_file(), "content")); |
FilePathWatcher watcher; |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get())); |
// Now make sure we get notified if the file is deleted. |
file_util::Delete(test_file(), false); |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
-TEST_F(FilePathWatcherTest, Callback) { |
- FilePathWatcher* watcher = new FilePathWatcher(); |
- bool called_back = false; |
- |
- MessageLoop* file_loop = file_thread_.message_loop(); |
- ASSERT_TRUE(file_loop); |
- // The callback makes |loop_| quit on file events, and flips |called_back| |
- // to true. |
- FilePathWatcher::Callback callback = base::Bind( |
- QuitLoopWatchCallback, &loop_, test_file(), false, &called_back); |
- |
- // Start watching on the file thread, and unblock the loop once the callback |
- // has been installed. |
- file_thread_.message_loop_proxy()->PostTaskAndReply( |
- FROM_HERE, |
- base::Bind(SetupWatchCallback, test_file(), watcher, callback), |
- base::Bind(&MessageLoop::Quit, base::Unretained(&loop_))); |
- loop_.Run(); |
- |
- // The watch has been installed. Trigger a file event now, which will unblock |
- // the loop again. |
- ASSERT_TRUE(WriteFile(test_file(), "content")); |
- loop_.Run(); |
- EXPECT_TRUE(called_back); |
- |
- // Multiple events might have triggered, meaning that multiple |
- // QuitLoopWatchCallback have been posted. The FilePathWatcher can only cancel |
- // on the FILE thread, and thus that callback might still trigger after this |
- // function returns. Make sure the |watcher| is deleted before returning and |
- // destroying |called_back|. |
- // A better fix requires significant changes to the FilePathWatcher. |
- // TODO(joaodasilva): fix the FPW interface. http://crbug.com/145653 |
- file_thread_.message_loop_proxy()->DeleteSoon(FROM_HERE, watcher); |
- file_thread_.message_loop_proxy()->PostTaskAndReply( |
- FROM_HERE, |
- base::Bind(base::DoNothing), |
- base::Bind(&MessageLoop::Quit, base::Unretained(&loop_))); |
- loop_.Run(); |
-} |
- |
// Used by the DeleteDuringNotify test below. |
// Deletes the FilePathWatcher when it's notified. |
-class Deleter : public FilePathWatcher::Delegate { |
+class Deleter : public TestDelegateBase { |
public: |
Deleter(FilePathWatcher* watcher, MessageLoop* loop) |
: watcher_(watcher), |
loop_(loop) { |
} |
+ ~Deleter() {} |
- virtual void OnFilePathChanged(const FilePath& path) { |
+ virtual void OnFileChanged(const FilePath&, bool) OVERRIDE { |
watcher_.reset(); |
loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
} |
+ FilePathWatcher* watcher() const { return watcher_.get(); } |
+ |
+ private: |
scoped_ptr<FilePathWatcher> watcher_; |
MessageLoop* loop_; |
- private: |
- virtual ~Deleter() {} |
+ DISALLOW_COPY_AND_ASSIGN(Deleter); |
}; |
// Verify that deleting a watcher during the callback doesn't crash. |
TEST_F(FilePathWatcherTest, DeleteDuringNotify) { |
FilePathWatcher* watcher = new FilePathWatcher; |
// Takes ownership of watcher. |
- scoped_refptr<Deleter> deleter(new Deleter(watcher, &loop_)); |
+ scoped_ptr<Deleter> deleter(new Deleter(watcher, &loop_)); |
ASSERT_TRUE(SetupWatch(test_file(), watcher, deleter.get())); |
ASSERT_TRUE(WriteFile(test_file(), "content")); |
@@ -332,34 +311,38 @@ |
// We win if we haven't crashed yet. |
// Might as well double-check it got deleted, too. |
- ASSERT_TRUE(deleter->watcher_.get() == NULL); |
+ ASSERT_TRUE(deleter->watcher() == NULL); |
} |
// Verify that deleting the watcher works even if there is a pending |
// notification. |
// Flaky on MacOS. http://crbug.com/85930 |
#if defined(OS_MACOSX) |
-#define MAYBE_DestroyWithPendingNotification DISABLED_DestroyWithPendingNotification |
+#define MAYBE_DestroyWithPendingNotification \ |
+ DISABLED_DestroyWithPendingNotification |
#else |
#define MAYBE_DestroyWithPendingNotification DestroyWithPendingNotification |
#endif |
TEST_F(FilePathWatcherTest, MAYBE_DestroyWithPendingNotification) { |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
FilePathWatcher* watcher = new FilePathWatcher; |
ASSERT_TRUE(SetupWatch(test_file(), watcher, delegate.get())); |
ASSERT_TRUE(WriteFile(test_file(), "content")); |
file_thread_.message_loop_proxy()->DeleteSoon(FROM_HERE, watcher); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
TEST_F(FilePathWatcherTest, MultipleWatchersSingleFile) { |
FilePathWatcher watcher1, watcher2; |
- scoped_refptr<TestDelegate> delegate1(new TestDelegate(collector())); |
- scoped_refptr<TestDelegate> delegate2(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate1(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate2(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(test_file(), &watcher1, delegate1.get())); |
ASSERT_TRUE(SetupWatch(test_file(), &watcher2, delegate2.get())); |
ASSERT_TRUE(WriteFile(test_file(), "content")); |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate1.release()); |
+ DeleteDelegateOnFileThread(delegate2.release()); |
} |
// Verify that watching a file whose parent directory doesn't exist yet works if |
@@ -368,7 +351,7 @@ |
FilePathWatcher watcher; |
FilePath dir(temp_dir_.path().AppendASCII("dir")); |
FilePath file(dir.AppendASCII("file")); |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(file, &watcher, delegate.get())); |
ASSERT_TRUE(file_util::CreateDirectory(dir)); |
@@ -385,6 +368,7 @@ |
ASSERT_TRUE(file_util::Delete(file, false)); |
VLOG(1) << "Waiting for file deletion"; |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
// Exercises watch reconfiguration for the case that directories on the path |
@@ -400,7 +384,7 @@ |
FilePathWatcher watcher; |
FilePath file(path.AppendASCII("file")); |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(file, &watcher, delegate.get())); |
FilePath sub_path(temp_dir_.path()); |
@@ -417,6 +401,7 @@ |
ASSERT_TRUE(WriteFile(file, "content v2")); |
VLOG(1) << "Waiting for file modification"; |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
#if defined(OS_MACOSX) |
@@ -429,18 +414,19 @@ |
FilePath file(dir.AppendASCII("file")); |
ASSERT_TRUE(file_util::CreateDirectory(dir)); |
ASSERT_TRUE(WriteFile(file, "content")); |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(file, &watcher, delegate.get())); |
ASSERT_TRUE(file_util::Delete(dir, true)); |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
// Tests that a file that is deleted and reappears is tracked correctly. |
TEST_F(FilePathWatcherTest, DeleteAndRecreate) { |
ASSERT_TRUE(WriteFile(test_file(), "content")); |
FilePathWatcher watcher; |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get())); |
ASSERT_TRUE(file_util::Delete(test_file(), false)); |
@@ -450,6 +436,7 @@ |
ASSERT_TRUE(WriteFile(test_file(), "content")); |
VLOG(1) << "Waiting for file creation"; |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
TEST_F(FilePathWatcherTest, WatchDirectory) { |
@@ -457,7 +444,7 @@ |
FilePath dir(temp_dir_.path().AppendASCII("dir")); |
FilePath file1(dir.AppendASCII("file1")); |
FilePath file2(dir.AppendASCII("file2")); |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(dir, &watcher, delegate.get())); |
ASSERT_TRUE(file_util::CreateDirectory(dir)); |
@@ -482,6 +469,7 @@ |
ASSERT_TRUE(WriteFile(file2, "content")); |
VLOG(1) << "Waiting for file2 creation"; |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
TEST_F(FilePathWatcherTest, MoveParent) { |
@@ -491,9 +479,9 @@ |
FilePath dest(temp_dir_.path().AppendASCII("dest")); |
FilePath subdir(dir.AppendASCII("subdir")); |
FilePath file(subdir.AppendASCII("file")); |
- scoped_refptr<TestDelegate> file_delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> file_delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(file, &file_watcher, file_delegate.get())); |
- scoped_refptr<TestDelegate> subdir_delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> subdir_delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(subdir, &subdir_watcher, subdir_delegate.get())); |
// Setup a directory hierarchy. |
@@ -506,6 +494,8 @@ |
file_util::Move(dir, dest); |
VLOG(1) << "Waiting for directory move"; |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(file_delegate.release()); |
+ DeleteDelegateOnFileThread(subdir_delegate.release()); |
} |
TEST_F(FilePathWatcherTest, MoveChild) { |
@@ -522,14 +512,16 @@ |
ASSERT_TRUE(file_util::CreateDirectory(source_subdir)); |
ASSERT_TRUE(WriteFile(source_file, "content")); |
- scoped_refptr<TestDelegate> file_delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> file_delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(dest_file, &file_watcher, file_delegate.get())); |
- scoped_refptr<TestDelegate> subdir_delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> subdir_delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(dest_subdir, &subdir_watcher, subdir_delegate.get())); |
// Move the directory into place, s.t. the watched file appears. |
ASSERT_TRUE(file_util::Move(source_dir, dest_dir)); |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(file_delegate.release()); |
+ DeleteDelegateOnFileThread(subdir_delegate.release()); |
} |
#if !defined(OS_LINUX) |
@@ -540,12 +532,13 @@ |
TEST_F(FilePathWatcherTest, FileAttributesChanged) { |
ASSERT_TRUE(WriteFile(test_file(), "content")); |
FilePathWatcher watcher; |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get())); |
// Now make sure we get notified if the file is modified. |
ASSERT_TRUE(file_util::MakeFileUnreadable(test_file())); |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
#endif // !OS_LINUX |
@@ -555,7 +548,7 @@ |
// Verify that creating a symlink is caught. |
TEST_F(FilePathWatcherTest, CreateLink) { |
FilePathWatcher watcher; |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
// Note that we are watching the symlink |
ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get())); |
@@ -563,6 +556,7 @@ |
// Note that test_file() doesn't have to exist. |
ASSERT_TRUE(file_util::CreateSymbolicLink(test_file(), test_link())); |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
// Verify that deleting a symlink is caught. |
@@ -572,12 +566,13 @@ |
ASSERT_TRUE(WriteFile(test_file(), "content")); |
ASSERT_TRUE(file_util::CreateSymbolicLink(test_file(), test_link())); |
FilePathWatcher watcher; |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get())); |
// Now make sure we get notified if the link is deleted. |
ASSERT_TRUE(file_util::Delete(test_link(), false)); |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
// Verify that modifying a target file that a link is pointing to |
@@ -586,13 +581,14 @@ |
ASSERT_TRUE(WriteFile(test_file(), "content")); |
ASSERT_TRUE(file_util::CreateSymbolicLink(test_file(), test_link())); |
FilePathWatcher watcher; |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
// Note that we are watching the symlink. |
ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get())); |
// Now make sure we get notified if the file is modified. |
ASSERT_TRUE(WriteFile(test_file(), "new content")); |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
// Verify that creating a target file that a link is pointing to |
@@ -600,13 +596,14 @@ |
TEST_F(FilePathWatcherTest, CreateTargetLinkedFile) { |
ASSERT_TRUE(file_util::CreateSymbolicLink(test_file(), test_link())); |
FilePathWatcher watcher; |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
// Note that we are watching the symlink. |
ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get())); |
// Now make sure we get notified if the target file is created. |
ASSERT_TRUE(WriteFile(test_file(), "content")); |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
// Verify that deleting a target file that a link is pointing to |
@@ -615,13 +612,14 @@ |
ASSERT_TRUE(WriteFile(test_file(), "content")); |
ASSERT_TRUE(file_util::CreateSymbolicLink(test_file(), test_link())); |
FilePathWatcher watcher; |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
// Note that we are watching the symlink. |
ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get())); |
// Now make sure we get notified if the target file is deleted. |
ASSERT_TRUE(file_util::Delete(test_file(), false)); |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
// Verify that watching a file whose parent directory is a link that |
@@ -632,7 +630,7 @@ |
FilePath link_dir(temp_dir_.path().AppendASCII("dir.lnk")); |
FilePath file(dir.AppendASCII("file")); |
FilePath linkfile(link_dir.AppendASCII("file")); |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
// dir/file should exist. |
ASSERT_TRUE(file_util::CreateDirectory(dir)); |
ASSERT_TRUE(WriteFile(file, "content")); |
@@ -650,6 +648,7 @@ |
ASSERT_TRUE(file_util::Delete(file, false)); |
VLOG(1) << "Waiting for file deletion"; |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
// Verify that watching a file whose parent directory is a |
@@ -660,7 +659,7 @@ |
FilePath link_dir(temp_dir_.path().AppendASCII("dir.lnk")); |
FilePath file(dir.AppendASCII("file")); |
FilePath linkfile(link_dir.AppendASCII("file")); |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
// Now create the link from dir.lnk pointing to dir but |
// neither dir nor dir/file exist yet. |
ASSERT_TRUE(file_util::CreateSymbolicLink(dir, link_dir)); |
@@ -679,6 +678,7 @@ |
ASSERT_TRUE(file_util::Delete(file, false)); |
VLOG(1) << "Waiting for file deletion"; |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
// Verify that watching a file with a symlink on the path |
@@ -689,7 +689,7 @@ |
FilePath link_dir(temp_dir_.path().AppendASCII("dir.lnk")); |
FilePath file(dir.AppendASCII("file")); |
FilePath linkfile(link_dir.AppendASCII("file")); |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
ASSERT_TRUE(file_util::CreateDirectory(dir)); |
ASSERT_TRUE(file_util::CreateSymbolicLink(dir, link_dir)); |
// Note that we are watching dir.lnk/file but the file doesn't exist yet. |
@@ -706,6 +706,7 @@ |
ASSERT_TRUE(file_util::Delete(file, false)); |
VLOG(1) << "Waiting for file deletion"; |
ASSERT_TRUE(WaitForEvents()); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
#endif // OS_LINUX |
@@ -818,7 +819,7 @@ |
ASSERT_TRUE(WriteFile(test_file, "content")); |
FilePathWatcher watcher; |
- scoped_refptr<TestDelegate> delegate(new TestDelegate(collector())); |
+ scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
ASSERT_TRUE(SetupWatch(test_file, &watcher, delegate.get())); |
// We should not get notified in this case as it hasn't affected our ability |
@@ -835,6 +836,7 @@ |
ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, false)); |
ASSERT_TRUE(WaitForEvents()); |
ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, true)); |
+ DeleteDelegateOnFileThread(delegate.release()); |
} |
#endif // OS_MACOSX |