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

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

Issue 1113953002: Revert of base: Remove use of MessageLoopProxy (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 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
« no previous file with comments | « base/files/file_path_watcher_linux.cc ('k') | base/files/file_path_watcher_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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)
11 #include <sys/stat.h> 11 #include <sys/stat.h>
12 #endif 12 #endif
13 13
14 #include <set> 14 #include <set>
15 15
16 #include "base/basictypes.h" 16 #include "base/basictypes.h"
17 #include "base/bind.h" 17 #include "base/bind.h"
18 #include "base/bind_helpers.h" 18 #include "base/bind_helpers.h"
19 #include "base/compiler_specific.h" 19 #include "base/compiler_specific.h"
20 #include "base/files/file_path.h" 20 #include "base/files/file_path.h"
21 #include "base/files/file_util.h" 21 #include "base/files/file_util.h"
22 #include "base/files/scoped_temp_dir.h" 22 #include "base/files/scoped_temp_dir.h"
23 #include "base/location.h" 23 #include "base/message_loop/message_loop.h"
24 #include "base/message_loop/message_loop_proxy.h"
24 #include "base/run_loop.h" 25 #include "base/run_loop.h"
25 #include "base/single_thread_task_runner.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/thread_task_runner_handle.h"
32 #include "base/threading/thread.h" 31 #include "base/threading/thread.h"
33 #include "testing/gtest/include/gtest/gtest.h" 32 #include "testing/gtest/include/gtest/gtest.h"
34 33
35 #if defined(OS_ANDROID) 34 #if defined(OS_ANDROID)
36 #include "base/android/path_utils.h" 35 #include "base/android/path_utils.h"
37 #endif // defined(OS_ANDROID) 36 #endif // defined(OS_ANDROID)
38 37
39 namespace base { 38 namespace base {
40 39
41 namespace { 40 namespace {
42 41
43 class TestDelegate; 42 class TestDelegate;
44 43
45 // Aggregates notifications from the test delegates and breaks the message loop 44 // Aggregates notifications from the test delegates and breaks the message loop
46 // the test thread is waiting on once they all came in. 45 // the test thread is waiting on once they all came in.
47 class NotificationCollector 46 class NotificationCollector
48 : public base::RefCountedThreadSafe<NotificationCollector> { 47 : public base::RefCountedThreadSafe<NotificationCollector> {
49 public: 48 public:
50 NotificationCollector() : task_runner_(base::ThreadTaskRunnerHandle::Get()) {} 49 NotificationCollector()
50 : loop_(base::MessageLoopProxy::current()) {}
51 51
52 // Called from the file thread by the delegates. 52 // Called from the file thread by the delegates.
53 void OnChange(TestDelegate* delegate) { 53 void OnChange(TestDelegate* delegate) {
54 task_runner_->PostTask( 54 loop_->PostTask(FROM_HERE,
55 FROM_HERE, base::Bind(&NotificationCollector::RecordChange, this, 55 base::Bind(&NotificationCollector::RecordChange, this,
56 base::Unretained(delegate))); 56 base::Unretained(delegate)));
57 } 57 }
58 58
59 void Register(TestDelegate* delegate) { 59 void Register(TestDelegate* delegate) {
60 delegates_.insert(delegate); 60 delegates_.insert(delegate);
61 } 61 }
62 62
63 void Reset() { 63 void Reset() {
64 signaled_.clear(); 64 signaled_.clear();
65 } 65 }
66 66
67 bool Success() { 67 bool Success() {
68 return signaled_ == delegates_; 68 return signaled_ == delegates_;
69 } 69 }
70 70
71 private: 71 private:
72 friend class base::RefCountedThreadSafe<NotificationCollector>; 72 friend class base::RefCountedThreadSafe<NotificationCollector>;
73 ~NotificationCollector() {} 73 ~NotificationCollector() {}
74 74
75 void RecordChange(TestDelegate* delegate) { 75 void RecordChange(TestDelegate* delegate) {
76 // Warning: |delegate| is Unretained. Do not dereference. 76 // Warning: |delegate| is Unretained. Do not dereference.
77 ASSERT_TRUE(task_runner_->BelongsToCurrentThread()); 77 ASSERT_TRUE(loop_->BelongsToCurrentThread());
78 ASSERT_TRUE(delegates_.count(delegate)); 78 ASSERT_TRUE(delegates_.count(delegate));
79 signaled_.insert(delegate); 79 signaled_.insert(delegate);
80 80
81 // Check whether all delegates have been signaled. 81 // Check whether all delegates have been signaled.
82 if (signaled_ == delegates_) 82 if (signaled_ == delegates_)
83 task_runner_->PostTask(FROM_HERE, MessageLoop::QuitWhenIdleClosure()); 83 loop_->PostTask(FROM_HERE, MessageLoop::QuitWhenIdleClosure());
84 } 84 }
85 85
86 // Set of registered delegates. 86 // Set of registered delegates.
87 std::set<TestDelegate*> delegates_; 87 std::set<TestDelegate*> delegates_;
88 88
89 // Set of signaled delegates. 89 // Set of signaled delegates.
90 std::set<TestDelegate*> signaled_; 90 std::set<TestDelegate*> signaled_;
91 91
92 // The loop we should break after all delegates signaled. 92 // The loop we should break after all delegates signaled.
93 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; 93 scoped_refptr<base::MessageLoopProxy> loop_;
94 }; 94 };
95 95
96 class TestDelegateBase : public SupportsWeakPtr<TestDelegateBase> { 96 class TestDelegateBase : public SupportsWeakPtr<TestDelegateBase> {
97 public: 97 public:
98 TestDelegateBase() {} 98 TestDelegateBase() {}
99 virtual ~TestDelegateBase() {} 99 virtual ~TestDelegateBase() {}
100 100
101 virtual void OnFileChanged(const FilePath& path, bool error) = 0; 101 virtual void OnFileChanged(const FilePath& path, bool error) = 0;
102 102
103 private: 103 private:
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 ASSERT_TRUE(temp_dir_.CreateUniqueTempDirUnderPath(parent_dir)); 164 ASSERT_TRUE(temp_dir_.CreateUniqueTempDirUnderPath(parent_dir));
165 #else // defined(OS_ANDROID) 165 #else // defined(OS_ANDROID)
166 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 166 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
167 #endif // defined(OS_ANDROID) 167 #endif // defined(OS_ANDROID)
168 collector_ = new NotificationCollector(); 168 collector_ = new NotificationCollector();
169 } 169 }
170 170
171 void TearDown() override { RunLoop().RunUntilIdle(); } 171 void TearDown() override { RunLoop().RunUntilIdle(); }
172 172
173 void DeleteDelegateOnFileThread(TestDelegate* delegate) { 173 void DeleteDelegateOnFileThread(TestDelegate* delegate) {
174 file_thread_.task_runner()->DeleteSoon(FROM_HERE, delegate); 174 file_thread_.message_loop_proxy()->DeleteSoon(FROM_HERE, delegate);
175 } 175 }
176 176
177 FilePath test_file() { 177 FilePath test_file() {
178 return temp_dir_.path().AppendASCII("FilePathWatcherTest"); 178 return temp_dir_.path().AppendASCII("FilePathWatcherTest");
179 } 179 }
180 180
181 FilePath test_link() { 181 FilePath test_link() {
182 return temp_dir_.path().AppendASCII("FilePathWatcherTest.lnk"); 182 return temp_dir_.path().AppendASCII("FilePathWatcherTest.lnk");
183 } 183 }
184 184
(...skipping 24 matching lines...) Expand all
209 private: 209 private:
210 DISALLOW_COPY_AND_ASSIGN(FilePathWatcherTest); 210 DISALLOW_COPY_AND_ASSIGN(FilePathWatcherTest);
211 }; 211 };
212 212
213 bool FilePathWatcherTest::SetupWatch(const FilePath& target, 213 bool FilePathWatcherTest::SetupWatch(const FilePath& target,
214 FilePathWatcher* watcher, 214 FilePathWatcher* watcher,
215 TestDelegateBase* delegate, 215 TestDelegateBase* delegate,
216 bool recursive_watch) { 216 bool recursive_watch) {
217 base::WaitableEvent completion(false, false); 217 base::WaitableEvent completion(false, false);
218 bool result; 218 bool result;
219 file_thread_.task_runner()->PostTask( 219 file_thread_.message_loop_proxy()->PostTask(
220 FROM_HERE, base::Bind(SetupWatchCallback, target, watcher, delegate, 220 FROM_HERE,
221 recursive_watch, &result, &completion)); 221 base::Bind(SetupWatchCallback, target, watcher, delegate, recursive_watch,
222 &result, &completion));
222 completion.Wait(); 223 completion.Wait();
223 return result; 224 return result;
224 } 225 }
225 226
226 // Basic test: Create the file and verify that we notice. 227 // Basic test: Create the file and verify that we notice.
227 TEST_F(FilePathWatcherTest, NewFile) { 228 TEST_F(FilePathWatcherTest, NewFile) {
228 FilePathWatcher watcher; 229 FilePathWatcher watcher;
229 scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); 230 scoped_ptr<TestDelegate> delegate(new TestDelegate(collector()));
230 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); 231 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false));
231 232
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 class Deleter : public TestDelegateBase { 282 class Deleter : public TestDelegateBase {
282 public: 283 public:
283 Deleter(FilePathWatcher* watcher, MessageLoop* loop) 284 Deleter(FilePathWatcher* watcher, MessageLoop* loop)
284 : watcher_(watcher), 285 : watcher_(watcher),
285 loop_(loop) { 286 loop_(loop) {
286 } 287 }
287 ~Deleter() override {} 288 ~Deleter() override {}
288 289
289 void OnFileChanged(const FilePath&, bool) override { 290 void OnFileChanged(const FilePath&, bool) override {
290 watcher_.reset(); 291 watcher_.reset();
291 loop_->task_runner()->PostTask(FROM_HERE, 292 loop_->PostTask(FROM_HERE, MessageLoop::QuitWhenIdleClosure());
292 MessageLoop::QuitWhenIdleClosure());
293 } 293 }
294 294
295 FilePathWatcher* watcher() const { return watcher_.get(); } 295 FilePathWatcher* watcher() const { return watcher_.get(); }
296 296
297 private: 297 private:
298 scoped_ptr<FilePathWatcher> watcher_; 298 scoped_ptr<FilePathWatcher> watcher_;
299 MessageLoop* loop_; 299 MessageLoop* loop_;
300 300
301 DISALLOW_COPY_AND_ASSIGN(Deleter); 301 DISALLOW_COPY_AND_ASSIGN(Deleter);
302 }; 302 };
(...skipping 14 matching lines...) Expand all
317 } 317 }
318 318
319 // Verify that deleting the watcher works even if there is a pending 319 // Verify that deleting the watcher works even if there is a pending
320 // notification. 320 // notification.
321 // Flaky on MacOS (and ARM linux): http://crbug.com/85930 321 // Flaky on MacOS (and ARM linux): http://crbug.com/85930
322 TEST_F(FilePathWatcherTest, DISABLED_DestroyWithPendingNotification) { 322 TEST_F(FilePathWatcherTest, DISABLED_DestroyWithPendingNotification) {
323 scoped_ptr<TestDelegate> delegate(new TestDelegate(collector())); 323 scoped_ptr<TestDelegate> delegate(new TestDelegate(collector()));
324 FilePathWatcher* watcher = new FilePathWatcher; 324 FilePathWatcher* watcher = new FilePathWatcher;
325 ASSERT_TRUE(SetupWatch(test_file(), watcher, delegate.get(), false)); 325 ASSERT_TRUE(SetupWatch(test_file(), watcher, delegate.get(), false));
326 ASSERT_TRUE(WriteFile(test_file(), "content")); 326 ASSERT_TRUE(WriteFile(test_file(), "content"));
327 file_thread_.task_runner()->DeleteSoon(FROM_HERE, watcher); 327 file_thread_.message_loop_proxy()->DeleteSoon(FROM_HERE, watcher);
328 DeleteDelegateOnFileThread(delegate.release()); 328 DeleteDelegateOnFileThread(delegate.release());
329 } 329 }
330 330
331 TEST_F(FilePathWatcherTest, MultipleWatchersSingleFile) { 331 TEST_F(FilePathWatcherTest, MultipleWatchersSingleFile) {
332 FilePathWatcher watcher1, watcher2; 332 FilePathWatcher watcher1, watcher2;
333 scoped_ptr<TestDelegate> delegate1(new TestDelegate(collector())); 333 scoped_ptr<TestDelegate> delegate1(new TestDelegate(collector()));
334 scoped_ptr<TestDelegate> delegate2(new TestDelegate(collector())); 334 scoped_ptr<TestDelegate> delegate2(new TestDelegate(collector()));
335 ASSERT_TRUE(SetupWatch(test_file(), &watcher1, delegate1.get(), false)); 335 ASSERT_TRUE(SetupWatch(test_file(), &watcher1, delegate1.get(), false));
336 ASSERT_TRUE(SetupWatch(test_file(), &watcher2, delegate2.get(), false)); 336 ASSERT_TRUE(SetupWatch(test_file(), &watcher2, delegate2.get(), false));
337 337
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, false)); 899 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, false));
900 ASSERT_TRUE(WaitForEvents()); 900 ASSERT_TRUE(WaitForEvents());
901 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, true)); 901 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, true));
902 DeleteDelegateOnFileThread(delegate.release()); 902 DeleteDelegateOnFileThread(delegate.release());
903 } 903 }
904 904
905 #endif // OS_MACOSX 905 #endif // OS_MACOSX
906 } // namespace 906 } // namespace
907 907
908 } // namespace base 908 } // namespace base
OLDNEW
« no previous file with comments | « base/files/file_path_watcher_linux.cc ('k') | base/files/file_path_watcher_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698