| OLD | NEW |
| 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 10 matching lines...) Expand all Loading... |
| 21 #include "base/files/scoped_temp_dir.h" | 21 #include "base/files/scoped_temp_dir.h" |
| 22 #include "base/location.h" | 22 #include "base/location.h" |
| 23 #include "base/macros.h" | 23 #include "base/macros.h" |
| 24 #include "base/run_loop.h" | 24 #include "base/run_loop.h" |
| 25 #include "base/single_thread_task_runner.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/threading/thread.h" | |
| 32 #include "base/threading/thread_task_runner_handle.h" | 31 #include "base/threading/thread_task_runner_handle.h" |
| 33 #include "build/build_config.h" | 32 #include "build/build_config.h" |
| 34 #include "testing/gtest/include/gtest/gtest.h" | 33 #include "testing/gtest/include/gtest/gtest.h" |
| 35 | 34 |
| 36 #if defined(OS_ANDROID) | 35 #if defined(OS_ANDROID) |
| 37 #include "base/android/path_utils.h" | 36 #include "base/android/path_utils.h" |
| 38 #endif // defined(OS_ANDROID) | 37 #endif // defined(OS_ANDROID) |
| 39 | 38 |
| 39 #if defined(OS_POSIX) |
| 40 #include "base/files/file_descriptor_watcher_posix.h" |
| 41 #endif // defined(OS_POSIX) |
| 42 |
| 40 namespace base { | 43 namespace base { |
| 41 | 44 |
| 42 namespace { | 45 namespace { |
| 43 | 46 |
| 44 class TestDelegate; | 47 class TestDelegate; |
| 45 | 48 |
| 46 // Aggregates notifications from the test delegates and breaks the message loop | 49 // Aggregates notifications from the test delegates and breaks the message loop |
| 47 // the test thread is waiting on once they all came in. | 50 // the test thread is waiting on once they all came in. |
| 48 class NotificationCollector | 51 class NotificationCollector |
| 49 : public base::RefCountedThreadSafe<NotificationCollector> { | 52 : public base::RefCountedThreadSafe<NotificationCollector> { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 else | 127 else |
| 125 collector_->OnChange(this); | 128 collector_->OnChange(this); |
| 126 } | 129 } |
| 127 | 130 |
| 128 private: | 131 private: |
| 129 scoped_refptr<NotificationCollector> collector_; | 132 scoped_refptr<NotificationCollector> collector_; |
| 130 | 133 |
| 131 DISALLOW_COPY_AND_ASSIGN(TestDelegate); | 134 DISALLOW_COPY_AND_ASSIGN(TestDelegate); |
| 132 }; | 135 }; |
| 133 | 136 |
| 134 void SetupWatchCallback(const FilePath& target, | |
| 135 FilePathWatcher* watcher, | |
| 136 TestDelegateBase* delegate, | |
| 137 bool recursive_watch, | |
| 138 bool* result, | |
| 139 base::WaitableEvent* completion) { | |
| 140 *result = watcher->Watch(target, recursive_watch, | |
| 141 base::Bind(&TestDelegateBase::OnFileChanged, | |
| 142 delegate->AsWeakPtr())); | |
| 143 completion->Signal(); | |
| 144 } | |
| 145 | |
| 146 class FilePathWatcherTest : public testing::Test { | 137 class FilePathWatcherTest : public testing::Test { |
| 147 public: | 138 public: |
| 148 FilePathWatcherTest() | 139 FilePathWatcherTest() |
| 149 : file_thread_("FilePathWatcherTest") {} | 140 #if defined(OS_POSIX) |
| 141 : file_descriptor_watcher_(&loop_) |
| 142 #endif |
| 143 { |
| 144 } |
| 150 | 145 |
| 151 ~FilePathWatcherTest() override {} | 146 ~FilePathWatcherTest() override {} |
| 152 | 147 |
| 153 protected: | 148 protected: |
| 154 void SetUp() override { | 149 void SetUp() override { |
| 155 // Create a separate file thread in order to test proper thread usage. | |
| 156 base::Thread::Options options(MessageLoop::TYPE_IO, 0); | |
| 157 ASSERT_TRUE(file_thread_.StartWithOptions(options)); | |
| 158 #if defined(OS_ANDROID) | 150 #if defined(OS_ANDROID) |
| 159 // Watching files is only permitted when all parent directories are | 151 // Watching files is only permitted when all parent directories are |
| 160 // accessible, which is not the case for the default temp directory | 152 // accessible, which is not the case for the default temp directory |
| 161 // on Android which is under /data/data. Use /sdcard instead. | 153 // on Android which is under /data/data. Use /sdcard instead. |
| 162 // TODO(pauljensen): Remove this when crbug.com/475568 is fixed. | 154 // TODO(pauljensen): Remove this when crbug.com/475568 is fixed. |
| 163 FilePath parent_dir; | 155 FilePath parent_dir; |
| 164 ASSERT_TRUE(android::GetExternalStorageDirectory(&parent_dir)); | 156 ASSERT_TRUE(android::GetExternalStorageDirectory(&parent_dir)); |
| 165 ASSERT_TRUE(temp_dir_.CreateUniqueTempDirUnderPath(parent_dir)); | 157 ASSERT_TRUE(temp_dir_.CreateUniqueTempDirUnderPath(parent_dir)); |
| 166 #else // defined(OS_ANDROID) | 158 #else // defined(OS_ANDROID) |
| 167 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 159 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 168 #endif // defined(OS_ANDROID) | 160 #endif // defined(OS_ANDROID) |
| 169 collector_ = new NotificationCollector(); | 161 collector_ = new NotificationCollector(); |
| 170 } | 162 } |
| 171 | 163 |
| 172 void TearDown() override { RunLoop().RunUntilIdle(); } | 164 void TearDown() override { RunLoop().RunUntilIdle(); } |
| 173 | 165 |
| 174 void DeleteDelegateOnFileThread(TestDelegate* delegate) { | |
| 175 file_thread_.task_runner()->DeleteSoon(FROM_HERE, delegate); | |
| 176 } | |
| 177 | |
| 178 FilePath test_file() { | 166 FilePath test_file() { |
| 179 return temp_dir_.GetPath().AppendASCII("FilePathWatcherTest"); | 167 return temp_dir_.GetPath().AppendASCII("FilePathWatcherTest"); |
| 180 } | 168 } |
| 181 | 169 |
| 182 FilePath test_link() { | 170 FilePath test_link() { |
| 183 return temp_dir_.GetPath().AppendASCII("FilePathWatcherTest.lnk"); | 171 return temp_dir_.GetPath().AppendASCII("FilePathWatcherTest.lnk"); |
| 184 } | 172 } |
| 185 | 173 |
| 186 // Write |content| to |file|. Returns true on success. | 174 // Write |content| to |file|. Returns true on success. |
| 187 bool WriteFile(const FilePath& file, const std::string& content) { | 175 bool WriteFile(const FilePath& file, const std::string& content) { |
| 188 int write_size = ::base::WriteFile(file, content.c_str(), content.length()); | 176 int write_size = ::base::WriteFile(file, content.c_str(), content.length()); |
| 189 return write_size == static_cast<int>(content.length()); | 177 return write_size == static_cast<int>(content.length()); |
| 190 } | 178 } |
| 191 | 179 |
| 192 bool SetupWatch(const FilePath& target, | 180 bool SetupWatch(const FilePath& target, |
| 193 FilePathWatcher* watcher, | 181 FilePathWatcher* watcher, |
| 194 TestDelegateBase* delegate, | 182 TestDelegateBase* delegate, |
| 195 bool recursive_watch) WARN_UNUSED_RESULT; | 183 bool recursive_watch) WARN_UNUSED_RESULT; |
| 196 | 184 |
| 197 bool WaitForEvents() WARN_UNUSED_RESULT { | 185 bool WaitForEvents() WARN_UNUSED_RESULT { |
| 198 collector_->Reset(); | 186 collector_->Reset(); |
| 187 |
| 188 RunLoop run_loop; |
| 199 // Make sure we timeout if we don't get notified. | 189 // Make sure we timeout if we don't get notified. |
| 200 loop_.task_runner()->PostDelayedTask(FROM_HERE, | 190 ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 201 MessageLoop::QuitWhenIdleClosure(), | 191 FROM_HERE, run_loop.QuitWhenIdleClosure(), |
| 202 TestTimeouts::action_timeout()); | 192 TestTimeouts::action_timeout()); |
| 203 RunLoop().Run(); | 193 run_loop.Run(); |
| 204 return collector_->Success(); | 194 return collector_->Success(); |
| 205 } | 195 } |
| 206 | 196 |
| 207 NotificationCollector* collector() { return collector_.get(); } | 197 NotificationCollector* collector() { return collector_.get(); } |
| 208 | 198 |
| 209 MessageLoop loop_; | 199 MessageLoopForIO loop_; |
| 210 base::Thread file_thread_; | 200 #if defined(OS_POSIX) |
| 201 FileDescriptorWatcher file_descriptor_watcher_; |
| 202 #endif |
| 203 |
| 211 ScopedTempDir temp_dir_; | 204 ScopedTempDir temp_dir_; |
| 212 scoped_refptr<NotificationCollector> collector_; | 205 scoped_refptr<NotificationCollector> collector_; |
| 213 | 206 |
| 214 private: | 207 private: |
| 215 DISALLOW_COPY_AND_ASSIGN(FilePathWatcherTest); | 208 DISALLOW_COPY_AND_ASSIGN(FilePathWatcherTest); |
| 216 }; | 209 }; |
| 217 | 210 |
| 218 bool FilePathWatcherTest::SetupWatch(const FilePath& target, | 211 bool FilePathWatcherTest::SetupWatch(const FilePath& target, |
| 219 FilePathWatcher* watcher, | 212 FilePathWatcher* watcher, |
| 220 TestDelegateBase* delegate, | 213 TestDelegateBase* delegate, |
| 221 bool recursive_watch) { | 214 bool recursive_watch) { |
| 222 base::WaitableEvent completion(WaitableEvent::ResetPolicy::AUTOMATIC, | 215 return watcher->Watch( |
| 223 WaitableEvent::InitialState::NOT_SIGNALED); | 216 target, recursive_watch, |
| 224 bool result; | 217 base::Bind(&TestDelegateBase::OnFileChanged, delegate->AsWeakPtr())); |
| 225 file_thread_.task_runner()->PostTask( | |
| 226 FROM_HERE, base::Bind(SetupWatchCallback, target, watcher, delegate, | |
| 227 recursive_watch, &result, &completion)); | |
| 228 completion.Wait(); | |
| 229 return result; | |
| 230 } | 218 } |
| 231 | 219 |
| 232 // Basic test: Create the file and verify that we notice. | 220 // Basic test: Create the file and verify that we notice. |
| 233 TEST_F(FilePathWatcherTest, NewFile) { | 221 TEST_F(FilePathWatcherTest, NewFile) { |
| 234 FilePathWatcher watcher; | 222 FilePathWatcher watcher; |
| 235 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 223 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 236 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); | 224 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); |
| 237 | 225 |
| 238 ASSERT_TRUE(WriteFile(test_file(), "content")); | 226 ASSERT_TRUE(WriteFile(test_file(), "content")); |
| 239 ASSERT_TRUE(WaitForEvents()); | 227 ASSERT_TRUE(WaitForEvents()); |
| 240 DeleteDelegateOnFileThread(delegate.release()); | |
| 241 } | 228 } |
| 242 | 229 |
| 243 // Verify that modifying the file is caught. | 230 // Verify that modifying the file is caught. |
| 244 TEST_F(FilePathWatcherTest, ModifiedFile) { | 231 TEST_F(FilePathWatcherTest, ModifiedFile) { |
| 245 ASSERT_TRUE(WriteFile(test_file(), "content")); | 232 ASSERT_TRUE(WriteFile(test_file(), "content")); |
| 246 | 233 |
| 247 FilePathWatcher watcher; | 234 FilePathWatcher watcher; |
| 248 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 235 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 249 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); | 236 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); |
| 250 | 237 |
| 251 // Now make sure we get notified if the file is modified. | 238 // Now make sure we get notified if the file is modified. |
| 252 ASSERT_TRUE(WriteFile(test_file(), "new content")); | 239 ASSERT_TRUE(WriteFile(test_file(), "new content")); |
| 253 ASSERT_TRUE(WaitForEvents()); | 240 ASSERT_TRUE(WaitForEvents()); |
| 254 DeleteDelegateOnFileThread(delegate.release()); | |
| 255 } | 241 } |
| 256 | 242 |
| 257 // Verify that moving the file into place is caught. | 243 // Verify that moving the file into place is caught. |
| 258 TEST_F(FilePathWatcherTest, MovedFile) { | 244 TEST_F(FilePathWatcherTest, MovedFile) { |
| 259 FilePath source_file(temp_dir_.GetPath().AppendASCII("source")); | 245 FilePath source_file(temp_dir_.GetPath().AppendASCII("source")); |
| 260 ASSERT_TRUE(WriteFile(source_file, "content")); | 246 ASSERT_TRUE(WriteFile(source_file, "content")); |
| 261 | 247 |
| 262 FilePathWatcher watcher; | 248 FilePathWatcher watcher; |
| 263 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 249 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 264 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); | 250 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); |
| 265 | 251 |
| 266 // Now make sure we get notified if the file is modified. | 252 // Now make sure we get notified if the file is modified. |
| 267 ASSERT_TRUE(base::Move(source_file, test_file())); | 253 ASSERT_TRUE(base::Move(source_file, test_file())); |
| 268 ASSERT_TRUE(WaitForEvents()); | 254 ASSERT_TRUE(WaitForEvents()); |
| 269 DeleteDelegateOnFileThread(delegate.release()); | |
| 270 } | 255 } |
| 271 | 256 |
| 272 TEST_F(FilePathWatcherTest, DeletedFile) { | 257 TEST_F(FilePathWatcherTest, DeletedFile) { |
| 273 ASSERT_TRUE(WriteFile(test_file(), "content")); | 258 ASSERT_TRUE(WriteFile(test_file(), "content")); |
| 274 | 259 |
| 275 FilePathWatcher watcher; | 260 FilePathWatcher watcher; |
| 276 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 261 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 277 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); | 262 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); |
| 278 | 263 |
| 279 // Now make sure we get notified if the file is deleted. | 264 // Now make sure we get notified if the file is deleted. |
| 280 base::DeleteFile(test_file(), false); | 265 base::DeleteFile(test_file(), false); |
| 281 ASSERT_TRUE(WaitForEvents()); | 266 ASSERT_TRUE(WaitForEvents()); |
| 282 DeleteDelegateOnFileThread(delegate.release()); | |
| 283 } | 267 } |
| 284 | 268 |
| 285 // Used by the DeleteDuringNotify test below. | 269 // Used by the DeleteDuringNotify test below. |
| 286 // Deletes the FilePathWatcher when it's notified. | 270 // Deletes the FilePathWatcher when it's notified. |
| 287 class Deleter : public TestDelegateBase { | 271 class Deleter : public TestDelegateBase { |
| 288 public: | 272 public: |
| 289 Deleter(FilePathWatcher* watcher, MessageLoop* loop) | 273 Deleter(FilePathWatcher* watcher, MessageLoop* loop) |
| 290 : watcher_(watcher), | 274 : watcher_(watcher), |
| 291 loop_(loop) { | 275 loop_(loop) { |
| 292 } | 276 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 320 // We win if we haven't crashed yet. | 304 // We win if we haven't crashed yet. |
| 321 // Might as well double-check it got deleted, too. | 305 // Might as well double-check it got deleted, too. |
| 322 ASSERT_TRUE(deleter->watcher() == NULL); | 306 ASSERT_TRUE(deleter->watcher() == NULL); |
| 323 } | 307 } |
| 324 | 308 |
| 325 // Verify that deleting the watcher works even if there is a pending | 309 // Verify that deleting the watcher works even if there is a pending |
| 326 // notification. | 310 // notification. |
| 327 // Flaky on MacOS (and ARM linux): http://crbug.com/85930 | 311 // Flaky on MacOS (and ARM linux): http://crbug.com/85930 |
| 328 TEST_F(FilePathWatcherTest, DISABLED_DestroyWithPendingNotification) { | 312 TEST_F(FilePathWatcherTest, DISABLED_DestroyWithPendingNotification) { |
| 329 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 313 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 330 FilePathWatcher* watcher = new FilePathWatcher; | 314 FilePathWatcher watcher; |
| 331 ASSERT_TRUE(SetupWatch(test_file(), watcher, delegate.get(), false)); | 315 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); |
| 332 ASSERT_TRUE(WriteFile(test_file(), "content")); | 316 ASSERT_TRUE(WriteFile(test_file(), "content")); |
| 333 file_thread_.task_runner()->DeleteSoon(FROM_HERE, watcher); | |
| 334 DeleteDelegateOnFileThread(delegate.release()); | |
| 335 } | 317 } |
| 336 | 318 |
| 337 TEST_F(FilePathWatcherTest, MultipleWatchersSingleFile) { | 319 TEST_F(FilePathWatcherTest, MultipleWatchersSingleFile) { |
| 338 FilePathWatcher watcher1, watcher2; | 320 FilePathWatcher watcher1, watcher2; |
| 339 std::unique_ptr<TestDelegate> delegate1(new TestDelegate(collector())); | 321 std::unique_ptr<TestDelegate> delegate1(new TestDelegate(collector())); |
| 340 std::unique_ptr<TestDelegate> delegate2(new TestDelegate(collector())); | 322 std::unique_ptr<TestDelegate> delegate2(new TestDelegate(collector())); |
| 341 ASSERT_TRUE(SetupWatch(test_file(), &watcher1, delegate1.get(), false)); | 323 ASSERT_TRUE(SetupWatch(test_file(), &watcher1, delegate1.get(), false)); |
| 342 ASSERT_TRUE(SetupWatch(test_file(), &watcher2, delegate2.get(), false)); | 324 ASSERT_TRUE(SetupWatch(test_file(), &watcher2, delegate2.get(), false)); |
| 343 | 325 |
| 344 ASSERT_TRUE(WriteFile(test_file(), "content")); | 326 ASSERT_TRUE(WriteFile(test_file(), "content")); |
| 345 ASSERT_TRUE(WaitForEvents()); | 327 ASSERT_TRUE(WaitForEvents()); |
| 346 DeleteDelegateOnFileThread(delegate1.release()); | |
| 347 DeleteDelegateOnFileThread(delegate2.release()); | |
| 348 } | 328 } |
| 349 | 329 |
| 350 // Verify that watching a file whose parent directory doesn't exist yet works if | 330 // Verify that watching a file whose parent directory doesn't exist yet works if |
| 351 // the directory and file are created eventually. | 331 // the directory and file are created eventually. |
| 352 TEST_F(FilePathWatcherTest, NonExistentDirectory) { | 332 TEST_F(FilePathWatcherTest, NonExistentDirectory) { |
| 353 FilePathWatcher watcher; | 333 FilePathWatcher watcher; |
| 354 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); | 334 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); |
| 355 FilePath file(dir.AppendASCII("file")); | 335 FilePath file(dir.AppendASCII("file")); |
| 356 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 336 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 357 ASSERT_TRUE(SetupWatch(file, &watcher, delegate.get(), false)); | 337 ASSERT_TRUE(SetupWatch(file, &watcher, delegate.get(), false)); |
| 358 | 338 |
| 359 ASSERT_TRUE(base::CreateDirectory(dir)); | 339 ASSERT_TRUE(base::CreateDirectory(dir)); |
| 360 | 340 |
| 361 ASSERT_TRUE(WriteFile(file, "content")); | 341 ASSERT_TRUE(WriteFile(file, "content")); |
| 362 | 342 |
| 363 VLOG(1) << "Waiting for file creation"; | 343 VLOG(1) << "Waiting for file creation"; |
| 364 ASSERT_TRUE(WaitForEvents()); | 344 ASSERT_TRUE(WaitForEvents()); |
| 365 | 345 |
| 366 ASSERT_TRUE(WriteFile(file, "content v2")); | 346 ASSERT_TRUE(WriteFile(file, "content v2")); |
| 367 VLOG(1) << "Waiting for file change"; | 347 VLOG(1) << "Waiting for file change"; |
| 368 ASSERT_TRUE(WaitForEvents()); | 348 ASSERT_TRUE(WaitForEvents()); |
| 369 | 349 |
| 370 ASSERT_TRUE(base::DeleteFile(file, false)); | 350 ASSERT_TRUE(base::DeleteFile(file, false)); |
| 371 VLOG(1) << "Waiting for file deletion"; | 351 VLOG(1) << "Waiting for file deletion"; |
| 372 ASSERT_TRUE(WaitForEvents()); | 352 ASSERT_TRUE(WaitForEvents()); |
| 373 DeleteDelegateOnFileThread(delegate.release()); | |
| 374 } | 353 } |
| 375 | 354 |
| 376 // Exercises watch reconfiguration for the case that directories on the path | 355 // Exercises watch reconfiguration for the case that directories on the path |
| 377 // are rapidly created. | 356 // are rapidly created. |
| 378 TEST_F(FilePathWatcherTest, DirectoryChain) { | 357 TEST_F(FilePathWatcherTest, DirectoryChain) { |
| 379 FilePath path(temp_dir_.GetPath()); | 358 FilePath path(temp_dir_.GetPath()); |
| 380 std::vector<std::string> dir_names; | 359 std::vector<std::string> dir_names; |
| 381 for (int i = 0; i < 20; i++) { | 360 for (int i = 0; i < 20; i++) { |
| 382 std::string dir(base::StringPrintf("d%d", i)); | 361 std::string dir(base::StringPrintf("d%d", i)); |
| 383 dir_names.push_back(dir); | 362 dir_names.push_back(dir); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 396 ASSERT_TRUE(base::CreateDirectory(sub_path)); | 375 ASSERT_TRUE(base::CreateDirectory(sub_path)); |
| 397 } | 376 } |
| 398 VLOG(1) << "Create File"; | 377 VLOG(1) << "Create File"; |
| 399 ASSERT_TRUE(WriteFile(file, "content")); | 378 ASSERT_TRUE(WriteFile(file, "content")); |
| 400 VLOG(1) << "Waiting for file creation"; | 379 VLOG(1) << "Waiting for file creation"; |
| 401 ASSERT_TRUE(WaitForEvents()); | 380 ASSERT_TRUE(WaitForEvents()); |
| 402 | 381 |
| 403 ASSERT_TRUE(WriteFile(file, "content v2")); | 382 ASSERT_TRUE(WriteFile(file, "content v2")); |
| 404 VLOG(1) << "Waiting for file modification"; | 383 VLOG(1) << "Waiting for file modification"; |
| 405 ASSERT_TRUE(WaitForEvents()); | 384 ASSERT_TRUE(WaitForEvents()); |
| 406 DeleteDelegateOnFileThread(delegate.release()); | |
| 407 } | 385 } |
| 408 | 386 |
| 409 #if defined(OS_MACOSX) | 387 #if defined(OS_MACOSX) |
| 410 // http://crbug.com/85930 | 388 // http://crbug.com/85930 |
| 411 #define DisappearingDirectory DISABLED_DisappearingDirectory | 389 #define DisappearingDirectory DISABLED_DisappearingDirectory |
| 412 #endif | 390 #endif |
| 413 TEST_F(FilePathWatcherTest, DisappearingDirectory) { | 391 TEST_F(FilePathWatcherTest, DisappearingDirectory) { |
| 414 FilePathWatcher watcher; | 392 FilePathWatcher watcher; |
| 415 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); | 393 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); |
| 416 FilePath file(dir.AppendASCII("file")); | 394 FilePath file(dir.AppendASCII("file")); |
| 417 ASSERT_TRUE(base::CreateDirectory(dir)); | 395 ASSERT_TRUE(base::CreateDirectory(dir)); |
| 418 ASSERT_TRUE(WriteFile(file, "content")); | 396 ASSERT_TRUE(WriteFile(file, "content")); |
| 419 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 397 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 420 ASSERT_TRUE(SetupWatch(file, &watcher, delegate.get(), false)); | 398 ASSERT_TRUE(SetupWatch(file, &watcher, delegate.get(), false)); |
| 421 | 399 |
| 422 ASSERT_TRUE(base::DeleteFile(dir, true)); | 400 ASSERT_TRUE(base::DeleteFile(dir, true)); |
| 423 ASSERT_TRUE(WaitForEvents()); | 401 ASSERT_TRUE(WaitForEvents()); |
| 424 DeleteDelegateOnFileThread(delegate.release()); | |
| 425 } | 402 } |
| 426 | 403 |
| 427 // Tests that a file that is deleted and reappears is tracked correctly. | 404 // Tests that a file that is deleted and reappears is tracked correctly. |
| 428 TEST_F(FilePathWatcherTest, DeleteAndRecreate) { | 405 TEST_F(FilePathWatcherTest, DeleteAndRecreate) { |
| 429 ASSERT_TRUE(WriteFile(test_file(), "content")); | 406 ASSERT_TRUE(WriteFile(test_file(), "content")); |
| 430 FilePathWatcher watcher; | 407 FilePathWatcher watcher; |
| 431 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 408 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 432 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); | 409 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); |
| 433 | 410 |
| 434 ASSERT_TRUE(base::DeleteFile(test_file(), false)); | 411 ASSERT_TRUE(base::DeleteFile(test_file(), false)); |
| 435 VLOG(1) << "Waiting for file deletion"; | 412 VLOG(1) << "Waiting for file deletion"; |
| 436 ASSERT_TRUE(WaitForEvents()); | 413 ASSERT_TRUE(WaitForEvents()); |
| 437 | 414 |
| 438 ASSERT_TRUE(WriteFile(test_file(), "content")); | 415 ASSERT_TRUE(WriteFile(test_file(), "content")); |
| 439 VLOG(1) << "Waiting for file creation"; | 416 VLOG(1) << "Waiting for file creation"; |
| 440 ASSERT_TRUE(WaitForEvents()); | 417 ASSERT_TRUE(WaitForEvents()); |
| 441 DeleteDelegateOnFileThread(delegate.release()); | |
| 442 } | 418 } |
| 443 | 419 |
| 444 TEST_F(FilePathWatcherTest, WatchDirectory) { | 420 TEST_F(FilePathWatcherTest, WatchDirectory) { |
| 445 FilePathWatcher watcher; | 421 FilePathWatcher watcher; |
| 446 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); | 422 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); |
| 447 FilePath file1(dir.AppendASCII("file1")); | 423 FilePath file1(dir.AppendASCII("file1")); |
| 448 FilePath file2(dir.AppendASCII("file2")); | 424 FilePath file2(dir.AppendASCII("file2")); |
| 449 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 425 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 450 ASSERT_TRUE(SetupWatch(dir, &watcher, delegate.get(), false)); | 426 ASSERT_TRUE(SetupWatch(dir, &watcher, delegate.get(), false)); |
| 451 | 427 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 464 ASSERT_TRUE(WaitForEvents()); | 440 ASSERT_TRUE(WaitForEvents()); |
| 465 #endif // !OS_MACOSX | 441 #endif // !OS_MACOSX |
| 466 | 442 |
| 467 ASSERT_TRUE(base::DeleteFile(file1, false)); | 443 ASSERT_TRUE(base::DeleteFile(file1, false)); |
| 468 VLOG(1) << "Waiting for file1 deletion"; | 444 VLOG(1) << "Waiting for file1 deletion"; |
| 469 ASSERT_TRUE(WaitForEvents()); | 445 ASSERT_TRUE(WaitForEvents()); |
| 470 | 446 |
| 471 ASSERT_TRUE(WriteFile(file2, "content")); | 447 ASSERT_TRUE(WriteFile(file2, "content")); |
| 472 VLOG(1) << "Waiting for file2 creation"; | 448 VLOG(1) << "Waiting for file2 creation"; |
| 473 ASSERT_TRUE(WaitForEvents()); | 449 ASSERT_TRUE(WaitForEvents()); |
| 474 DeleteDelegateOnFileThread(delegate.release()); | |
| 475 } | 450 } |
| 476 | 451 |
| 477 TEST_F(FilePathWatcherTest, MoveParent) { | 452 TEST_F(FilePathWatcherTest, MoveParent) { |
| 478 FilePathWatcher file_watcher; | 453 FilePathWatcher file_watcher; |
| 479 FilePathWatcher subdir_watcher; | 454 FilePathWatcher subdir_watcher; |
| 480 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); | 455 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); |
| 481 FilePath dest(temp_dir_.GetPath().AppendASCII("dest")); | 456 FilePath dest(temp_dir_.GetPath().AppendASCII("dest")); |
| 482 FilePath subdir(dir.AppendASCII("subdir")); | 457 FilePath subdir(dir.AppendASCII("subdir")); |
| 483 FilePath file(subdir.AppendASCII("file")); | 458 FilePath file(subdir.AppendASCII("file")); |
| 484 std::unique_ptr<TestDelegate> file_delegate(new TestDelegate(collector())); | 459 std::unique_ptr<TestDelegate> file_delegate(new TestDelegate(collector())); |
| 485 ASSERT_TRUE(SetupWatch(file, &file_watcher, file_delegate.get(), false)); | 460 ASSERT_TRUE(SetupWatch(file, &file_watcher, file_delegate.get(), false)); |
| 486 std::unique_ptr<TestDelegate> subdir_delegate(new TestDelegate(collector())); | 461 std::unique_ptr<TestDelegate> subdir_delegate(new TestDelegate(collector())); |
| 487 ASSERT_TRUE(SetupWatch(subdir, &subdir_watcher, subdir_delegate.get(), | 462 ASSERT_TRUE(SetupWatch(subdir, &subdir_watcher, subdir_delegate.get(), |
| 488 false)); | 463 false)); |
| 489 | 464 |
| 490 // Setup a directory hierarchy. | 465 // Setup a directory hierarchy. |
| 491 ASSERT_TRUE(base::CreateDirectory(subdir)); | 466 ASSERT_TRUE(base::CreateDirectory(subdir)); |
| 492 ASSERT_TRUE(WriteFile(file, "content")); | 467 ASSERT_TRUE(WriteFile(file, "content")); |
| 493 VLOG(1) << "Waiting for file creation"; | 468 VLOG(1) << "Waiting for file creation"; |
| 494 ASSERT_TRUE(WaitForEvents()); | 469 ASSERT_TRUE(WaitForEvents()); |
| 495 | 470 |
| 496 // Move the parent directory. | 471 // Move the parent directory. |
| 497 base::Move(dir, dest); | 472 base::Move(dir, dest); |
| 498 VLOG(1) << "Waiting for directory move"; | 473 VLOG(1) << "Waiting for directory move"; |
| 499 ASSERT_TRUE(WaitForEvents()); | 474 ASSERT_TRUE(WaitForEvents()); |
| 500 DeleteDelegateOnFileThread(file_delegate.release()); | |
| 501 DeleteDelegateOnFileThread(subdir_delegate.release()); | |
| 502 } | 475 } |
| 503 | 476 |
| 504 TEST_F(FilePathWatcherTest, RecursiveWatch) { | 477 TEST_F(FilePathWatcherTest, RecursiveWatch) { |
| 505 FilePathWatcher watcher; | 478 FilePathWatcher watcher; |
| 506 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); | 479 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); |
| 507 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 480 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 508 bool setup_result = SetupWatch(dir, &watcher, delegate.get(), true); | 481 bool setup_result = SetupWatch(dir, &watcher, delegate.get(), true); |
| 509 if (!FilePathWatcher::RecursiveWatchAvailable()) { | 482 if (!FilePathWatcher::RecursiveWatchAvailable()) { |
| 510 ASSERT_FALSE(setup_result); | 483 ASSERT_FALSE(setup_result); |
| 511 DeleteDelegateOnFileThread(delegate.release()); | |
| 512 return; | 484 return; |
| 513 } | 485 } |
| 514 ASSERT_TRUE(setup_result); | 486 ASSERT_TRUE(setup_result); |
| 515 | 487 |
| 516 // Main directory("dir") creation. | 488 // Main directory("dir") creation. |
| 517 ASSERT_TRUE(base::CreateDirectory(dir)); | 489 ASSERT_TRUE(base::CreateDirectory(dir)); |
| 518 ASSERT_TRUE(WaitForEvents()); | 490 ASSERT_TRUE(WaitForEvents()); |
| 519 | 491 |
| 520 // Create "$dir/file1". | 492 // Create "$dir/file1". |
| 521 FilePath file1(dir.AppendASCII("file1")); | 493 FilePath file1(dir.AppendASCII("file1")); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 ASSERT_TRUE(WaitForEvents()); | 529 ASSERT_TRUE(WaitForEvents()); |
| 558 #endif | 530 #endif |
| 559 | 531 |
| 560 // Delete "$dir/subdir/subdir_file1". | 532 // Delete "$dir/subdir/subdir_file1". |
| 561 ASSERT_TRUE(base::DeleteFile(subdir_file1, false)); | 533 ASSERT_TRUE(base::DeleteFile(subdir_file1, false)); |
| 562 ASSERT_TRUE(WaitForEvents()); | 534 ASSERT_TRUE(WaitForEvents()); |
| 563 | 535 |
| 564 // Delete "$dir/subdir/subdir_child_dir/child_dir_file1". | 536 // Delete "$dir/subdir/subdir_child_dir/child_dir_file1". |
| 565 ASSERT_TRUE(base::DeleteFile(child_dir_file1, false)); | 537 ASSERT_TRUE(base::DeleteFile(child_dir_file1, false)); |
| 566 ASSERT_TRUE(WaitForEvents()); | 538 ASSERT_TRUE(WaitForEvents()); |
| 567 DeleteDelegateOnFileThread(delegate.release()); | |
| 568 } | 539 } |
| 569 | 540 |
| 570 #if defined(OS_POSIX) | 541 #if defined(OS_POSIX) |
| 571 #if defined(OS_ANDROID) | 542 #if defined(OS_ANDROID) |
| 572 // Apps cannot create symlinks on Android in /sdcard as /sdcard uses the | 543 // Apps cannot create symlinks on Android in /sdcard as /sdcard uses the |
| 573 // "fuse" file system, while /data uses "ext4". Running these tests in /data | 544 // "fuse" file system, while /data uses "ext4". Running these tests in /data |
| 574 // would be preferable and allow testing file attributes and symlinks. | 545 // would be preferable and allow testing file attributes and symlinks. |
| 575 // TODO(pauljensen): Re-enable when crbug.com/475568 is fixed and SetUp() places | 546 // TODO(pauljensen): Re-enable when crbug.com/475568 is fixed and SetUp() places |
| 576 // the |temp_dir_| in /data. | 547 // the |temp_dir_| in /data. |
| 577 #define RecursiveWithSymLink DISABLED_RecursiveWithSymLink | 548 #define RecursiveWithSymLink DISABLED_RecursiveWithSymLink |
| (...skipping 27 matching lines...) Expand all Loading... |
| 605 FilePath target2(temp_dir_.GetPath().AppendASCII("target2")); | 576 FilePath target2(temp_dir_.GetPath().AppendASCII("target2")); |
| 606 ASSERT_TRUE(base::CreateDirectory(target2)); | 577 ASSERT_TRUE(base::CreateDirectory(target2)); |
| 607 ASSERT_TRUE(base::DeleteFile(symlink, false)); | 578 ASSERT_TRUE(base::DeleteFile(symlink, false)); |
| 608 ASSERT_TRUE(base::CreateSymbolicLink(target2, symlink)); | 579 ASSERT_TRUE(base::CreateSymbolicLink(target2, symlink)); |
| 609 ASSERT_TRUE(WaitForEvents()); | 580 ASSERT_TRUE(WaitForEvents()); |
| 610 | 581 |
| 611 // Create a file in target2. | 582 // Create a file in target2. |
| 612 FilePath target2_file(target2.AppendASCII("file")); | 583 FilePath target2_file(target2.AppendASCII("file")); |
| 613 ASSERT_TRUE(WriteFile(target2_file, "content")); | 584 ASSERT_TRUE(WriteFile(target2_file, "content")); |
| 614 ASSERT_TRUE(WaitForEvents()); | 585 ASSERT_TRUE(WaitForEvents()); |
| 615 | |
| 616 DeleteDelegateOnFileThread(delegate.release()); | |
| 617 } | 586 } |
| 618 #endif // OS_POSIX | 587 #endif // OS_POSIX |
| 619 | 588 |
| 620 TEST_F(FilePathWatcherTest, MoveChild) { | 589 TEST_F(FilePathWatcherTest, MoveChild) { |
| 621 FilePathWatcher file_watcher; | 590 FilePathWatcher file_watcher; |
| 622 FilePathWatcher subdir_watcher; | 591 FilePathWatcher subdir_watcher; |
| 623 FilePath source_dir(temp_dir_.GetPath().AppendASCII("source")); | 592 FilePath source_dir(temp_dir_.GetPath().AppendASCII("source")); |
| 624 FilePath source_subdir(source_dir.AppendASCII("subdir")); | 593 FilePath source_subdir(source_dir.AppendASCII("subdir")); |
| 625 FilePath source_file(source_subdir.AppendASCII("file")); | 594 FilePath source_file(source_subdir.AppendASCII("file")); |
| 626 FilePath dest_dir(temp_dir_.GetPath().AppendASCII("dest")); | 595 FilePath dest_dir(temp_dir_.GetPath().AppendASCII("dest")); |
| 627 FilePath dest_subdir(dest_dir.AppendASCII("subdir")); | 596 FilePath dest_subdir(dest_dir.AppendASCII("subdir")); |
| 628 FilePath dest_file(dest_subdir.AppendASCII("file")); | 597 FilePath dest_file(dest_subdir.AppendASCII("file")); |
| 629 | 598 |
| 630 // Setup a directory hierarchy. | 599 // Setup a directory hierarchy. |
| 631 ASSERT_TRUE(base::CreateDirectory(source_subdir)); | 600 ASSERT_TRUE(base::CreateDirectory(source_subdir)); |
| 632 ASSERT_TRUE(WriteFile(source_file, "content")); | 601 ASSERT_TRUE(WriteFile(source_file, "content")); |
| 633 | 602 |
| 634 std::unique_ptr<TestDelegate> file_delegate(new TestDelegate(collector())); | 603 std::unique_ptr<TestDelegate> file_delegate(new TestDelegate(collector())); |
| 635 ASSERT_TRUE(SetupWatch(dest_file, &file_watcher, file_delegate.get(), false)); | 604 ASSERT_TRUE(SetupWatch(dest_file, &file_watcher, file_delegate.get(), false)); |
| 636 std::unique_ptr<TestDelegate> subdir_delegate(new TestDelegate(collector())); | 605 std::unique_ptr<TestDelegate> subdir_delegate(new TestDelegate(collector())); |
| 637 ASSERT_TRUE(SetupWatch(dest_subdir, &subdir_watcher, subdir_delegate.get(), | 606 ASSERT_TRUE(SetupWatch(dest_subdir, &subdir_watcher, subdir_delegate.get(), |
| 638 false)); | 607 false)); |
| 639 | 608 |
| 640 // Move the directory into place, s.t. the watched file appears. | 609 // Move the directory into place, s.t. the watched file appears. |
| 641 ASSERT_TRUE(base::Move(source_dir, dest_dir)); | 610 ASSERT_TRUE(base::Move(source_dir, dest_dir)); |
| 642 ASSERT_TRUE(WaitForEvents()); | 611 ASSERT_TRUE(WaitForEvents()); |
| 643 DeleteDelegateOnFileThread(file_delegate.release()); | |
| 644 DeleteDelegateOnFileThread(subdir_delegate.release()); | |
| 645 } | 612 } |
| 646 | 613 |
| 647 // Verify that changing attributes on a file is caught | 614 // Verify that changing attributes on a file is caught |
| 648 #if defined(OS_ANDROID) | 615 #if defined(OS_ANDROID) |
| 649 // Apps cannot change file attributes on Android in /sdcard as /sdcard uses the | 616 // Apps cannot change file attributes on Android in /sdcard as /sdcard uses the |
| 650 // "fuse" file system, while /data uses "ext4". Running these tests in /data | 617 // "fuse" file system, while /data uses "ext4". Running these tests in /data |
| 651 // would be preferable and allow testing file attributes and symlinks. | 618 // would be preferable and allow testing file attributes and symlinks. |
| 652 // TODO(pauljensen): Re-enable when crbug.com/475568 is fixed and SetUp() places | 619 // TODO(pauljensen): Re-enable when crbug.com/475568 is fixed and SetUp() places |
| 653 // the |temp_dir_| in /data. | 620 // the |temp_dir_| in /data. |
| 654 #define FileAttributesChanged DISABLED_FileAttributesChanged | 621 #define FileAttributesChanged DISABLED_FileAttributesChanged |
| 655 #endif // defined(OS_ANDROID | 622 #endif // defined(OS_ANDROID |
| 656 TEST_F(FilePathWatcherTest, FileAttributesChanged) { | 623 TEST_F(FilePathWatcherTest, FileAttributesChanged) { |
| 657 ASSERT_TRUE(WriteFile(test_file(), "content")); | 624 ASSERT_TRUE(WriteFile(test_file(), "content")); |
| 658 FilePathWatcher watcher; | 625 FilePathWatcher watcher; |
| 659 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 626 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 660 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); | 627 ASSERT_TRUE(SetupWatch(test_file(), &watcher, delegate.get(), false)); |
| 661 | 628 |
| 662 // Now make sure we get notified if the file is modified. | 629 // Now make sure we get notified if the file is modified. |
| 663 ASSERT_TRUE(base::MakeFileUnreadable(test_file())); | 630 ASSERT_TRUE(base::MakeFileUnreadable(test_file())); |
| 664 ASSERT_TRUE(WaitForEvents()); | 631 ASSERT_TRUE(WaitForEvents()); |
| 665 DeleteDelegateOnFileThread(delegate.release()); | |
| 666 } | 632 } |
| 667 | 633 |
| 668 #if defined(OS_LINUX) | 634 #if defined(OS_LINUX) |
| 669 | 635 |
| 670 // Verify that creating a symlink is caught. | 636 // Verify that creating a symlink is caught. |
| 671 TEST_F(FilePathWatcherTest, CreateLink) { | 637 TEST_F(FilePathWatcherTest, CreateLink) { |
| 672 FilePathWatcher watcher; | 638 FilePathWatcher watcher; |
| 673 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 639 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 674 // Note that we are watching the symlink | 640 // Note that we are watching the symlink |
| 675 ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get(), false)); | 641 ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get(), false)); |
| 676 | 642 |
| 677 // Now make sure we get notified if the link is created. | 643 // Now make sure we get notified if the link is created. |
| 678 // Note that test_file() doesn't have to exist. | 644 // Note that test_file() doesn't have to exist. |
| 679 ASSERT_TRUE(CreateSymbolicLink(test_file(), test_link())); | 645 ASSERT_TRUE(CreateSymbolicLink(test_file(), test_link())); |
| 680 ASSERT_TRUE(WaitForEvents()); | 646 ASSERT_TRUE(WaitForEvents()); |
| 681 DeleteDelegateOnFileThread(delegate.release()); | |
| 682 } | 647 } |
| 683 | 648 |
| 684 // Verify that deleting a symlink is caught. | 649 // Verify that deleting a symlink is caught. |
| 685 TEST_F(FilePathWatcherTest, DeleteLink) { | 650 TEST_F(FilePathWatcherTest, DeleteLink) { |
| 686 // Unfortunately this test case only works if the link target exists. | 651 // Unfortunately this test case only works if the link target exists. |
| 687 // TODO(craig) fix this as part of crbug.com/91561. | 652 // TODO(craig) fix this as part of crbug.com/91561. |
| 688 ASSERT_TRUE(WriteFile(test_file(), "content")); | 653 ASSERT_TRUE(WriteFile(test_file(), "content")); |
| 689 ASSERT_TRUE(CreateSymbolicLink(test_file(), test_link())); | 654 ASSERT_TRUE(CreateSymbolicLink(test_file(), test_link())); |
| 690 FilePathWatcher watcher; | 655 FilePathWatcher watcher; |
| 691 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 656 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 692 ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get(), false)); | 657 ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get(), false)); |
| 693 | 658 |
| 694 // Now make sure we get notified if the link is deleted. | 659 // Now make sure we get notified if the link is deleted. |
| 695 ASSERT_TRUE(base::DeleteFile(test_link(), false)); | 660 ASSERT_TRUE(base::DeleteFile(test_link(), false)); |
| 696 ASSERT_TRUE(WaitForEvents()); | 661 ASSERT_TRUE(WaitForEvents()); |
| 697 DeleteDelegateOnFileThread(delegate.release()); | |
| 698 } | 662 } |
| 699 | 663 |
| 700 // Verify that modifying a target file that a link is pointing to | 664 // Verify that modifying a target file that a link is pointing to |
| 701 // when we are watching the link is caught. | 665 // when we are watching the link is caught. |
| 702 TEST_F(FilePathWatcherTest, ModifiedLinkedFile) { | 666 TEST_F(FilePathWatcherTest, ModifiedLinkedFile) { |
| 703 ASSERT_TRUE(WriteFile(test_file(), "content")); | 667 ASSERT_TRUE(WriteFile(test_file(), "content")); |
| 704 ASSERT_TRUE(CreateSymbolicLink(test_file(), test_link())); | 668 ASSERT_TRUE(CreateSymbolicLink(test_file(), test_link())); |
| 705 FilePathWatcher watcher; | 669 FilePathWatcher watcher; |
| 706 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 670 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 707 // Note that we are watching the symlink. | 671 // Note that we are watching the symlink. |
| 708 ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get(), false)); | 672 ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get(), false)); |
| 709 | 673 |
| 710 // Now make sure we get notified if the file is modified. | 674 // Now make sure we get notified if the file is modified. |
| 711 ASSERT_TRUE(WriteFile(test_file(), "new content")); | 675 ASSERT_TRUE(WriteFile(test_file(), "new content")); |
| 712 ASSERT_TRUE(WaitForEvents()); | 676 ASSERT_TRUE(WaitForEvents()); |
| 713 DeleteDelegateOnFileThread(delegate.release()); | |
| 714 } | 677 } |
| 715 | 678 |
| 716 // Verify that creating a target file that a link is pointing to | 679 // Verify that creating a target file that a link is pointing to |
| 717 // when we are watching the link is caught. | 680 // when we are watching the link is caught. |
| 718 TEST_F(FilePathWatcherTest, CreateTargetLinkedFile) { | 681 TEST_F(FilePathWatcherTest, CreateTargetLinkedFile) { |
| 719 ASSERT_TRUE(CreateSymbolicLink(test_file(), test_link())); | 682 ASSERT_TRUE(CreateSymbolicLink(test_file(), test_link())); |
| 720 FilePathWatcher watcher; | 683 FilePathWatcher watcher; |
| 721 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 684 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 722 // Note that we are watching the symlink. | 685 // Note that we are watching the symlink. |
| 723 ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get(), false)); | 686 ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get(), false)); |
| 724 | 687 |
| 725 // Now make sure we get notified if the target file is created. | 688 // Now make sure we get notified if the target file is created. |
| 726 ASSERT_TRUE(WriteFile(test_file(), "content")); | 689 ASSERT_TRUE(WriteFile(test_file(), "content")); |
| 727 ASSERT_TRUE(WaitForEvents()); | 690 ASSERT_TRUE(WaitForEvents()); |
| 728 DeleteDelegateOnFileThread(delegate.release()); | |
| 729 } | 691 } |
| 730 | 692 |
| 731 // Verify that deleting a target file that a link is pointing to | 693 // Verify that deleting a target file that a link is pointing to |
| 732 // when we are watching the link is caught. | 694 // when we are watching the link is caught. |
| 733 TEST_F(FilePathWatcherTest, DeleteTargetLinkedFile) { | 695 TEST_F(FilePathWatcherTest, DeleteTargetLinkedFile) { |
| 734 ASSERT_TRUE(WriteFile(test_file(), "content")); | 696 ASSERT_TRUE(WriteFile(test_file(), "content")); |
| 735 ASSERT_TRUE(CreateSymbolicLink(test_file(), test_link())); | 697 ASSERT_TRUE(CreateSymbolicLink(test_file(), test_link())); |
| 736 FilePathWatcher watcher; | 698 FilePathWatcher watcher; |
| 737 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 699 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 738 // Note that we are watching the symlink. | 700 // Note that we are watching the symlink. |
| 739 ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get(), false)); | 701 ASSERT_TRUE(SetupWatch(test_link(), &watcher, delegate.get(), false)); |
| 740 | 702 |
| 741 // Now make sure we get notified if the target file is deleted. | 703 // Now make sure we get notified if the target file is deleted. |
| 742 ASSERT_TRUE(base::DeleteFile(test_file(), false)); | 704 ASSERT_TRUE(base::DeleteFile(test_file(), false)); |
| 743 ASSERT_TRUE(WaitForEvents()); | 705 ASSERT_TRUE(WaitForEvents()); |
| 744 DeleteDelegateOnFileThread(delegate.release()); | |
| 745 } | 706 } |
| 746 | 707 |
| 747 // Verify that watching a file whose parent directory is a link that | 708 // Verify that watching a file whose parent directory is a link that |
| 748 // doesn't exist yet works if the symlink is created eventually. | 709 // doesn't exist yet works if the symlink is created eventually. |
| 749 TEST_F(FilePathWatcherTest, LinkedDirectoryPart1) { | 710 TEST_F(FilePathWatcherTest, LinkedDirectoryPart1) { |
| 750 FilePathWatcher watcher; | 711 FilePathWatcher watcher; |
| 751 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); | 712 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); |
| 752 FilePath link_dir(temp_dir_.GetPath().AppendASCII("dir.lnk")); | 713 FilePath link_dir(temp_dir_.GetPath().AppendASCII("dir.lnk")); |
| 753 FilePath file(dir.AppendASCII("file")); | 714 FilePath file(dir.AppendASCII("file")); |
| 754 FilePath linkfile(link_dir.AppendASCII("file")); | 715 FilePath linkfile(link_dir.AppendASCII("file")); |
| 755 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 716 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 756 // dir/file should exist. | 717 // dir/file should exist. |
| 757 ASSERT_TRUE(base::CreateDirectory(dir)); | 718 ASSERT_TRUE(base::CreateDirectory(dir)); |
| 758 ASSERT_TRUE(WriteFile(file, "content")); | 719 ASSERT_TRUE(WriteFile(file, "content")); |
| 759 // Note that we are watching dir.lnk/file which doesn't exist yet. | 720 // Note that we are watching dir.lnk/file which doesn't exist yet. |
| 760 ASSERT_TRUE(SetupWatch(linkfile, &watcher, delegate.get(), false)); | 721 ASSERT_TRUE(SetupWatch(linkfile, &watcher, delegate.get(), false)); |
| 761 | 722 |
| 762 ASSERT_TRUE(CreateSymbolicLink(dir, link_dir)); | 723 ASSERT_TRUE(CreateSymbolicLink(dir, link_dir)); |
| 763 VLOG(1) << "Waiting for link creation"; | 724 VLOG(1) << "Waiting for link creation"; |
| 764 ASSERT_TRUE(WaitForEvents()); | 725 ASSERT_TRUE(WaitForEvents()); |
| 765 | 726 |
| 766 ASSERT_TRUE(WriteFile(file, "content v2")); | 727 ASSERT_TRUE(WriteFile(file, "content v2")); |
| 767 VLOG(1) << "Waiting for file change"; | 728 VLOG(1) << "Waiting for file change"; |
| 768 ASSERT_TRUE(WaitForEvents()); | 729 ASSERT_TRUE(WaitForEvents()); |
| 769 | 730 |
| 770 ASSERT_TRUE(base::DeleteFile(file, false)); | 731 ASSERT_TRUE(base::DeleteFile(file, false)); |
| 771 VLOG(1) << "Waiting for file deletion"; | 732 VLOG(1) << "Waiting for file deletion"; |
| 772 ASSERT_TRUE(WaitForEvents()); | 733 ASSERT_TRUE(WaitForEvents()); |
| 773 DeleteDelegateOnFileThread(delegate.release()); | |
| 774 } | 734 } |
| 775 | 735 |
| 776 // Verify that watching a file whose parent directory is a | 736 // Verify that watching a file whose parent directory is a |
| 777 // dangling symlink works if the directory is created eventually. | 737 // dangling symlink works if the directory is created eventually. |
| 778 TEST_F(FilePathWatcherTest, LinkedDirectoryPart2) { | 738 TEST_F(FilePathWatcherTest, LinkedDirectoryPart2) { |
| 779 FilePathWatcher watcher; | 739 FilePathWatcher watcher; |
| 780 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); | 740 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); |
| 781 FilePath link_dir(temp_dir_.GetPath().AppendASCII("dir.lnk")); | 741 FilePath link_dir(temp_dir_.GetPath().AppendASCII("dir.lnk")); |
| 782 FilePath file(dir.AppendASCII("file")); | 742 FilePath file(dir.AppendASCII("file")); |
| 783 FilePath linkfile(link_dir.AppendASCII("file")); | 743 FilePath linkfile(link_dir.AppendASCII("file")); |
| 784 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 744 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 785 // Now create the link from dir.lnk pointing to dir but | 745 // Now create the link from dir.lnk pointing to dir but |
| 786 // neither dir nor dir/file exist yet. | 746 // neither dir nor dir/file exist yet. |
| 787 ASSERT_TRUE(CreateSymbolicLink(dir, link_dir)); | 747 ASSERT_TRUE(CreateSymbolicLink(dir, link_dir)); |
| 788 // Note that we are watching dir.lnk/file. | 748 // Note that we are watching dir.lnk/file. |
| 789 ASSERT_TRUE(SetupWatch(linkfile, &watcher, delegate.get(), false)); | 749 ASSERT_TRUE(SetupWatch(linkfile, &watcher, delegate.get(), false)); |
| 790 | 750 |
| 791 ASSERT_TRUE(base::CreateDirectory(dir)); | 751 ASSERT_TRUE(base::CreateDirectory(dir)); |
| 792 ASSERT_TRUE(WriteFile(file, "content")); | 752 ASSERT_TRUE(WriteFile(file, "content")); |
| 793 VLOG(1) << "Waiting for dir/file creation"; | 753 VLOG(1) << "Waiting for dir/file creation"; |
| 794 ASSERT_TRUE(WaitForEvents()); | 754 ASSERT_TRUE(WaitForEvents()); |
| 795 | 755 |
| 796 ASSERT_TRUE(WriteFile(file, "content v2")); | 756 ASSERT_TRUE(WriteFile(file, "content v2")); |
| 797 VLOG(1) << "Waiting for file change"; | 757 VLOG(1) << "Waiting for file change"; |
| 798 ASSERT_TRUE(WaitForEvents()); | 758 ASSERT_TRUE(WaitForEvents()); |
| 799 | 759 |
| 800 ASSERT_TRUE(base::DeleteFile(file, false)); | 760 ASSERT_TRUE(base::DeleteFile(file, false)); |
| 801 VLOG(1) << "Waiting for file deletion"; | 761 VLOG(1) << "Waiting for file deletion"; |
| 802 ASSERT_TRUE(WaitForEvents()); | 762 ASSERT_TRUE(WaitForEvents()); |
| 803 DeleteDelegateOnFileThread(delegate.release()); | |
| 804 } | 763 } |
| 805 | 764 |
| 806 // Verify that watching a file with a symlink on the path | 765 // Verify that watching a file with a symlink on the path |
| 807 // to the file works. | 766 // to the file works. |
| 808 TEST_F(FilePathWatcherTest, LinkedDirectoryPart3) { | 767 TEST_F(FilePathWatcherTest, LinkedDirectoryPart3) { |
| 809 FilePathWatcher watcher; | 768 FilePathWatcher watcher; |
| 810 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); | 769 FilePath dir(temp_dir_.GetPath().AppendASCII("dir")); |
| 811 FilePath link_dir(temp_dir_.GetPath().AppendASCII("dir.lnk")); | 770 FilePath link_dir(temp_dir_.GetPath().AppendASCII("dir.lnk")); |
| 812 FilePath file(dir.AppendASCII("file")); | 771 FilePath file(dir.AppendASCII("file")); |
| 813 FilePath linkfile(link_dir.AppendASCII("file")); | 772 FilePath linkfile(link_dir.AppendASCII("file")); |
| 814 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); | 773 std::unique_ptr<TestDelegate> delegate(new TestDelegate(collector())); |
| 815 ASSERT_TRUE(base::CreateDirectory(dir)); | 774 ASSERT_TRUE(base::CreateDirectory(dir)); |
| 816 ASSERT_TRUE(CreateSymbolicLink(dir, link_dir)); | 775 ASSERT_TRUE(CreateSymbolicLink(dir, link_dir)); |
| 817 // Note that we are watching dir.lnk/file but the file doesn't exist yet. | 776 // Note that we are watching dir.lnk/file but the file doesn't exist yet. |
| 818 ASSERT_TRUE(SetupWatch(linkfile, &watcher, delegate.get(), false)); | 777 ASSERT_TRUE(SetupWatch(linkfile, &watcher, delegate.get(), false)); |
| 819 | 778 |
| 820 ASSERT_TRUE(WriteFile(file, "content")); | 779 ASSERT_TRUE(WriteFile(file, "content")); |
| 821 VLOG(1) << "Waiting for file creation"; | 780 VLOG(1) << "Waiting for file creation"; |
| 822 ASSERT_TRUE(WaitForEvents()); | 781 ASSERT_TRUE(WaitForEvents()); |
| 823 | 782 |
| 824 ASSERT_TRUE(WriteFile(file, "content v2")); | 783 ASSERT_TRUE(WriteFile(file, "content v2")); |
| 825 VLOG(1) << "Waiting for file change"; | 784 VLOG(1) << "Waiting for file change"; |
| 826 ASSERT_TRUE(WaitForEvents()); | 785 ASSERT_TRUE(WaitForEvents()); |
| 827 | 786 |
| 828 ASSERT_TRUE(base::DeleteFile(file, false)); | 787 ASSERT_TRUE(base::DeleteFile(file, false)); |
| 829 VLOG(1) << "Waiting for file deletion"; | 788 VLOG(1) << "Waiting for file deletion"; |
| 830 ASSERT_TRUE(WaitForEvents()); | 789 ASSERT_TRUE(WaitForEvents()); |
| 831 DeleteDelegateOnFileThread(delegate.release()); | |
| 832 } | 790 } |
| 833 | 791 |
| 834 #endif // OS_LINUX | 792 #endif // OS_LINUX |
| 835 | 793 |
| 836 enum Permission { | 794 enum Permission { |
| 837 Read, | 795 Read, |
| 838 Write, | 796 Write, |
| 839 Execute | 797 Execute |
| 840 }; | 798 }; |
| 841 | 799 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 MessageLoop::QuitWhenIdleClosure(), | 857 MessageLoop::QuitWhenIdleClosure(), |
| 900 TestTimeouts::tiny_timeout()); | 858 TestTimeouts::tiny_timeout()); |
| 901 ASSERT_FALSE(WaitForEvents()); | 859 ASSERT_FALSE(WaitForEvents()); |
| 902 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Read, true)); | 860 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Read, true)); |
| 903 | 861 |
| 904 // We should get notified in this case because filepathwatcher can no | 862 // We should get notified in this case because filepathwatcher can no |
| 905 // longer access the file | 863 // longer access the file |
| 906 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, false)); | 864 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, false)); |
| 907 ASSERT_TRUE(WaitForEvents()); | 865 ASSERT_TRUE(WaitForEvents()); |
| 908 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, true)); | 866 ASSERT_TRUE(ChangeFilePermissions(test_dir1, Execute, true)); |
| 909 DeleteDelegateOnFileThread(delegate.release()); | |
| 910 } | 867 } |
| 911 | 868 |
| 912 #endif // OS_MACOSX | 869 #endif // OS_MACOSX |
| 913 } // namespace | 870 } // namespace |
| 914 | 871 |
| 915 } // namespace base | 872 } // namespace base |
| OLD | NEW |