OLD | NEW |
---|---|
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 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/directory_watcher.h" | 5 #include "base/directory_watcher.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/path_service.h" | 13 #include "base/path_service.h" |
14 #include "base/platform_thread.h" | 14 #include "base/platform_thread.h" |
15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
16 #include "base/thread.h" | 16 #include "base/thread.h" |
17 #if defined(OS_WIN) | 17 #if defined(OS_WIN) |
18 #include "base/win_util.h" | 18 #include "base/win_util.h" |
19 #endif // defined(OS_WIN) | 19 #endif // defined(OS_WIN) |
20 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 // For tests where we wait a bit to verify nothing happened | 24 // For tests where we wait a bit to verify nothing happened |
25 const int kWaitForEventTime = 1000; | 25 const int kWaitForEventTime = 500; |
M-A Ruel
2009/11/09 18:33:19
I'm just afraid it'll fail on slow VMs. That's the
| |
26 | 26 |
27 class DirectoryWatcherTest : public testing::Test { | 27 class DirectoryWatcherTest : public testing::Test { |
28 public: | 28 public: |
29 // Implementation of DirectoryWatcher on Mac requires UI loop. | 29 // Implementation of DirectoryWatcher on Mac requires UI loop. |
30 DirectoryWatcherTest() | 30 DirectoryWatcherTest() |
31 : loop_(MessageLoop::TYPE_UI), | 31 : loop_(MessageLoop::TYPE_UI), |
32 notified_delegates_(0), | 32 notified_delegates_(0), |
33 expected_notified_delegates_(0) { | 33 expected_notified_delegates_(0) { |
34 } | 34 } |
35 | 35 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
79 | 79 |
80 void SetExpectedNumberOfNotifiedDelegates(int n) { | 80 void SetExpectedNumberOfNotifiedDelegates(int n) { |
81 notified_delegates_ = 0; | 81 notified_delegates_ = 0; |
82 expected_notified_delegates_ = n; | 82 expected_notified_delegates_ = n; |
83 } | 83 } |
84 | 84 |
85 void VerifyExpectedNumberOfNotifiedDelegates() { | 85 void VerifyExpectedNumberOfNotifiedDelegates() { |
86 // Check that we get at least the expected number of notified delegates. | 86 // Check that we get at least the expected number of notified delegates. |
87 if (expected_notified_delegates_ - notified_delegates_ > 0) | 87 if (expected_notified_delegates_ - notified_delegates_ > 0) |
88 loop_.Run(); | 88 loop_.Run(); |
89 EXPECT_EQ(expected_notified_delegates_, notified_delegates_); | |
90 } | |
89 | 91 |
92 void VerifyNoExtraNotifications() { | |
90 // Check that we get no more than the expected number of notified delegates. | 93 // Check that we get no more than the expected number of notified delegates. |
91 loop_.PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask, | 94 loop_.PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask, |
92 kWaitForEventTime); | 95 kWaitForEventTime); |
93 loop_.Run(); | 96 loop_.Run(); |
94 EXPECT_EQ(expected_notified_delegates_, notified_delegates_); | 97 EXPECT_EQ(expected_notified_delegates_, notified_delegates_); |
95 } | 98 } |
96 | 99 |
97 // We need this function for reliable tests on Mac OS X. FSEvents API | 100 // We need this function for reliable tests on Mac OS X. FSEvents API |
98 // has a latency interval and can merge multiple events into one, | 101 // has a latency interval and can merge multiple events into one, |
99 // and we need a clear distinction between events triggered by test setup code | 102 // and we need a clear distinction between events triggered by test setup code |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 DirectoryWatcher watcher; | 204 DirectoryWatcher watcher; |
202 ASSERT_TRUE(watcher.Watch(test_dir_, &delegate, NULL, false)); | 205 ASSERT_TRUE(watcher.Watch(test_dir_, &delegate, NULL, false)); |
203 | 206 |
204 // And then let it fall out of scope, clearing its watch. | 207 // And then let it fall out of scope, clearing its watch. |
205 } | 208 } |
206 | 209 |
207 // Write a file to the test dir. | 210 // Write a file to the test dir. |
208 SetExpectedNumberOfNotifiedDelegates(0); | 211 SetExpectedNumberOfNotifiedDelegates(0); |
209 ASSERT_TRUE(WriteTestFile(test_dir_.AppendASCII("test_file"), "content")); | 212 ASSERT_TRUE(WriteTestFile(test_dir_.AppendASCII("test_file"), "content")); |
210 VerifyExpectedNumberOfNotifiedDelegates(); | 213 VerifyExpectedNumberOfNotifiedDelegates(); |
214 VerifyNoExtraNotifications(); | |
211 } | 215 } |
212 | 216 |
213 TEST_F(DirectoryWatcherTest, SubDirRecursive) { | 217 TEST_F(DirectoryWatcherTest, SubDirRecursive) { |
214 FilePath subdir(CreateTestDirDirectoryASCII("SubDir", true)); | 218 FilePath subdir(CreateTestDirDirectoryASCII("SubDir", true)); |
215 | 219 |
216 // Verify that modifications to a subdirectory are noticed by recursive watch. | 220 // Verify that modifications to a subdirectory are noticed by recursive watch. |
217 TestDelegate delegate(this); | 221 TestDelegate delegate(this); |
218 DirectoryWatcher watcher; | 222 DirectoryWatcher watcher; |
219 ASSERT_TRUE(watcher.Watch(test_dir_, &delegate, NULL, true)); | 223 ASSERT_TRUE(watcher.Watch(test_dir_, &delegate, NULL, true)); |
220 // Write a file to the subdir. | 224 // Write a file to the subdir. |
(...skipping 21 matching lines...) Expand all Loading... | |
242 // Verify that modifications to a subdirectory are not noticed | 246 // Verify that modifications to a subdirectory are not noticed |
243 // by a not-recursive watch. | 247 // by a not-recursive watch. |
244 DirectoryWatcher watcher; | 248 DirectoryWatcher watcher; |
245 TestDelegate delegate(this); | 249 TestDelegate delegate(this); |
246 ASSERT_TRUE(watcher.Watch(test_dir_, &delegate, NULL, false)); | 250 ASSERT_TRUE(watcher.Watch(test_dir_, &delegate, NULL, false)); |
247 | 251 |
248 // Modify the test file. There should be no notifications. | 252 // Modify the test file. There should be no notifications. |
249 SetExpectedNumberOfNotifiedDelegates(0); | 253 SetExpectedNumberOfNotifiedDelegates(0); |
250 ASSERT_TRUE(WriteTestFile(subdir.AppendASCII("test_file"), "other content")); | 254 ASSERT_TRUE(WriteTestFile(subdir.AppendASCII("test_file"), "other content")); |
251 VerifyExpectedNumberOfNotifiedDelegates(); | 255 VerifyExpectedNumberOfNotifiedDelegates(); |
256 VerifyNoExtraNotifications(); | |
252 } | 257 } |
253 | 258 |
254 namespace { | 259 namespace { |
255 // Used by the DeleteDuringNotify test below. | 260 // Used by the DeleteDuringNotify test below. |
256 // Deletes the DirectoryWatcher when it's notified. | 261 // Deletes the DirectoryWatcher when it's notified. |
257 class Deleter : public DirectoryWatcher::Delegate { | 262 class Deleter : public DirectoryWatcher::Delegate { |
258 public: | 263 public: |
259 Deleter(DirectoryWatcher* watcher, MessageLoop* loop) | 264 Deleter(DirectoryWatcher* watcher, MessageLoop* loop) |
260 : watcher_(watcher), | 265 : watcher_(watcher), |
261 loop_(loop) { | 266 loop_(loop) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
300 TestDelegate delegate1(this), delegate2(this); | 305 TestDelegate delegate1(this), delegate2(this); |
301 ASSERT_TRUE(watcher1.Watch(test_dir_, &delegate1, NULL, false)); | 306 ASSERT_TRUE(watcher1.Watch(test_dir_, &delegate1, NULL, false)); |
302 ASSERT_TRUE(watcher2.Watch(test_dir_, &delegate2, NULL, false)); | 307 ASSERT_TRUE(watcher2.Watch(test_dir_, &delegate2, NULL, false)); |
303 | 308 |
304 SetExpectedNumberOfNotifiedDelegates(2); | 309 SetExpectedNumberOfNotifiedDelegates(2); |
305 ASSERT_TRUE(WriteTestFile(test_dir_.AppendASCII("test_file"), "content")); | 310 ASSERT_TRUE(WriteTestFile(test_dir_.AppendASCII("test_file"), "content")); |
306 VerifyExpectedNumberOfNotifiedDelegates(); | 311 VerifyExpectedNumberOfNotifiedDelegates(); |
307 } | 312 } |
308 | 313 |
309 TEST_F(DirectoryWatcherTest, MultipleWatchersDifferentFiles) { | 314 TEST_F(DirectoryWatcherTest, MultipleWatchersDifferentFiles) { |
310 const int kNumberOfWatchers = 5; | 315 const int kNumberOfWatchers = 3; |
311 DirectoryWatcher watchers[kNumberOfWatchers]; | 316 DirectoryWatcher watchers[kNumberOfWatchers]; |
312 TestDelegate delegates[kNumberOfWatchers] = { | 317 TestDelegate delegates[kNumberOfWatchers] = { |
313 TestDelegate(this), | 318 TestDelegate(this), |
314 TestDelegate(this), | 319 TestDelegate(this), |
315 TestDelegate(this), | 320 TestDelegate(this), |
316 TestDelegate(this), | |
317 TestDelegate(this) | |
318 }; | 321 }; |
319 FilePath subdirs[kNumberOfWatchers]; | 322 FilePath subdirs[kNumberOfWatchers]; |
320 for (int i = 0; i < kNumberOfWatchers; i++) { | 323 for (int i = 0; i < kNumberOfWatchers; i++) { |
321 subdirs[i] = CreateTestDirDirectoryASCII("Dir" + IntToString(i), false); | 324 subdirs[i] = CreateTestDirDirectoryASCII("Dir" + IntToString(i), false); |
322 ASSERT_TRUE(watchers[i].Watch(subdirs[i], &delegates[i], | 325 ASSERT_TRUE(watchers[i].Watch(subdirs[i], &delegates[i], |
323 NULL, ((i % 2) == 0))); | 326 NULL, ((i % 2) == 0))); |
324 } | 327 } |
325 for (int i = 0; i < kNumberOfWatchers; i++) { | 328 for (int i = 0; i < kNumberOfWatchers; i++) { |
326 // Verify that we only get modifications from one watcher (each watcher has | 329 // Verify that we only get modifications from one watcher (each watcher has |
327 // different directory). | 330 // different directory). |
328 | 331 |
329 for (int j = 0; j < kNumberOfWatchers; j++) | 332 for (int j = 0; j < kNumberOfWatchers; j++) |
330 delegates[j].reset(); | 333 delegates[j].reset(); |
331 | 334 |
332 // Write a file to the subdir. | 335 // Write a file to the subdir. |
333 SetExpectedNumberOfNotifiedDelegates(1); | 336 SetExpectedNumberOfNotifiedDelegates(1); |
334 ASSERT_TRUE(WriteTestFile(subdirs[i].AppendASCII("test_file"), "content")); | 337 ASSERT_TRUE(WriteTestFile(subdirs[i].AppendASCII("test_file"), "content")); |
335 VerifyExpectedNumberOfNotifiedDelegates(); | 338 VerifyExpectedNumberOfNotifiedDelegates(); |
339 VerifyNoExtraNotifications(); | |
336 | 340 |
337 loop_.RunAllPending(); | 341 loop_.RunAllPending(); |
338 } | 342 } |
339 } | 343 } |
340 | 344 |
341 #if defined(OS_WIN) || defined(OS_MACOSX) | 345 #if defined(OS_WIN) || defined(OS_MACOSX) |
342 // TODO(phajdan.jr): Enable when support for Linux recursive watches is added. | 346 // TODO(phajdan.jr): Enable when support for Linux recursive watches is added. |
343 | 347 |
344 TEST_F(DirectoryWatcherTest, WatchCreatedDirectory) { | 348 TEST_F(DirectoryWatcherTest, WatchCreatedDirectory) { |
345 TestDelegate delegate(this); | 349 TestDelegate delegate(this); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
383 | 387 |
384 TestDelegate delegate1(this), delegate2(this); | 388 TestDelegate delegate1(this), delegate2(this); |
385 DirectoryWatcher watcher1, watcher2; | 389 DirectoryWatcher watcher1, watcher2; |
386 ASSERT_TRUE(watcher1.Watch(subdir1, &delegate1, NULL, true)); | 390 ASSERT_TRUE(watcher1.Watch(subdir1, &delegate1, NULL, true)); |
387 ASSERT_TRUE(watcher2.Watch(subdir2, &delegate2, NULL, true)); | 391 ASSERT_TRUE(watcher2.Watch(subdir2, &delegate2, NULL, true)); |
388 | 392 |
389 SetExpectedNumberOfNotifiedDelegates(1); | 393 SetExpectedNumberOfNotifiedDelegates(1); |
390 ASSERT_TRUE(WriteTestFile(subdir1.AppendASCII("file"), "some content")); | 394 ASSERT_TRUE(WriteTestFile(subdir1.AppendASCII("file"), "some content")); |
391 SyncIfPOSIX(); | 395 SyncIfPOSIX(); |
392 VerifyExpectedNumberOfNotifiedDelegates(); | 396 VerifyExpectedNumberOfNotifiedDelegates(); |
397 VerifyNoExtraNotifications(); | |
393 | 398 |
394 delegate1.reset(); | 399 delegate1.reset(); |
395 delegate2.reset(); | 400 delegate2.reset(); |
396 | 401 |
397 SetExpectedNumberOfNotifiedDelegates(2); | 402 SetExpectedNumberOfNotifiedDelegates(2); |
398 ASSERT_TRUE(file_util::Move(subdir1.AppendASCII("file"), | 403 ASSERT_TRUE(file_util::Move(subdir1.AppendASCII("file"), |
399 subdir2.AppendASCII("file"))); | 404 subdir2.AppendASCII("file"))); |
400 VerifyExpectedNumberOfNotifiedDelegates(); | 405 VerifyExpectedNumberOfNotifiedDelegates(); |
401 | 406 |
402 delegate1.reset(); | 407 delegate1.reset(); |
403 delegate2.reset(); | 408 delegate2.reset(); |
404 | 409 |
405 SetExpectedNumberOfNotifiedDelegates(1); | 410 SetExpectedNumberOfNotifiedDelegates(1); |
406 ASSERT_TRUE(WriteTestFile(subdir2.AppendASCII("file"), "other content")); | 411 ASSERT_TRUE(WriteTestFile(subdir2.AppendASCII("file"), "other content")); |
407 VerifyExpectedNumberOfNotifiedDelegates(); | 412 VerifyExpectedNumberOfNotifiedDelegates(); |
413 VerifyNoExtraNotifications(); | |
408 } | 414 } |
409 #endif // defined(OS_WIN) || defined(OS_MACOSX) | 415 #endif // defined(OS_WIN) || defined(OS_MACOSX) |
410 | 416 |
411 // Verify that watching a directory that doesn't exist fails, but doesn't | 417 // Verify that watching a directory that doesn't exist fails, but doesn't |
412 // asssert. | 418 // asssert. |
413 // Basic test: add a file and verify we notice it. | 419 // Basic test: add a file and verify we notice it. |
414 TEST_F(DirectoryWatcherTest, NonExistentDirectory) { | 420 TEST_F(DirectoryWatcherTest, NonExistentDirectory) { |
415 DirectoryWatcher watcher; | 421 DirectoryWatcher watcher; |
416 ASSERT_FALSE(watcher.Watch(test_dir_.AppendASCII("does-not-exist"), | 422 ASSERT_FALSE(watcher.Watch(test_dir_.AppendASCII("does-not-exist"), |
417 NULL, NULL, false)); | 423 NULL, NULL, false)); |
418 } | 424 } |
419 | 425 |
420 } // namespace | 426 } // namespace |
OLD | NEW |