Chromium Code Reviews| 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 |