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

Side by Side Diff: base/directory_watcher_unittest.cc

Issue 6377: Add a DirectoryWatcher class, allowing objects to be notified whenever... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « base/directory_watcher.h ('k') | base/directory_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')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "base/directory_watcher.h"
6
7 #include <fstream>
8
9 #include "base/file_path.h"
10 #include "base/file_util.h"
11 #include "base/logging.h"
12 #include "base/message_loop.h"
13 #include "base/path_service.h"
14 #include "base/string_util.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 // For tests where we wait a bit to verify nothing happened
18 namespace {
19 const int kWaitForEventTime = 500;
20 }
21
22 class DirectoryWatcherTest : public testing::Test,
23 public DirectoryWatcher::Delegate {
24 protected:
25 virtual void SetUp() {
26 // Name a subdirectory of the temp directory.
27 std::wstring path_str;
28 ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &path_str));
29 test_dir_ = FilePath(path_str).Append(
30 FILE_PATH_LITERAL("DirectoryWatcherTest"));
31
32 // Create a fresh, empty copy of this directory.
33 file_util::Delete(test_dir_.value(), true);
34 file_util::CreateDirectory(test_dir_.value());
35
36 directory_mods_ = 0;
37 quit_mod_count_ = 0;
38 }
39
40 virtual void OnDirectoryChanged(const FilePath& path) {
41 ++directory_mods_;
42 if (directory_mods_ == quit_mod_count_)
43 MessageLoop::current()->Quit();
44 }
45
46 virtual void TearDown() {
47 // Clean up test directory.
48 ASSERT_TRUE(file_util::Delete(test_dir_.value(), true));
49 ASSERT_FALSE(file_util::PathExists(test_dir_.value()));
50 }
51
52 // Write |content| to a file under the test directory.
53 void WriteTestDirFile(const FilePath::StringType& filename,
54 const std::string& content) {
55 FilePath path = test_dir_.Append(filename);
56
57 std::ofstream file;
58 file.open(WideToUTF8(path.value()).c_str());
59 file << content;
60 file.close();
61 }
62
63 // Run the message loop until we've seen |n| directory modifications.
64 void LoopUntilModsEqual(int n) {
65 quit_mod_count_ = n;
66 loop_.Run();
67 }
68
69 MessageLoopForIO loop_;
darin (slow to review) 2008/10/17 02:43:51 I don't think DirectoryWatcher is limited to only
70
71 // The path to a temporary directory used for testing.
72 FilePath test_dir_;
73
74 // The number of times a directory modification has been observed.
75 int directory_mods_;
76
77 // The number of directory mods which, when reached, cause us to quit
78 // our message loop.
79 int quit_mod_count_;
80 };
81
82 // Basic test: add a file and verify we notice it.
83 TEST_F(DirectoryWatcherTest, NewFile) {
84 DirectoryWatcher watcher;
85 ASSERT_TRUE(watcher.Watch(test_dir_, this));
86
87 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content");
88 LoopUntilModsEqual(2);
89 }
90
91 // Verify that modifying a file is caught.
92 TEST_F(DirectoryWatcherTest, ModifiedFile) {
93 DirectoryWatcher watcher;
94 ASSERT_TRUE(watcher.Watch(test_dir_, this));
95
96 // Write a file to the test dir.
97 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content");
98 LoopUntilModsEqual(2);
99
100 // Now make sure we get notified if the file is modified.
101 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some new content");
102 LoopUntilModsEqual(3);
103 }
104
105 // Verify that letting the watcher go out of scope stops notifications.
106 TEST_F(DirectoryWatcherTest, Unregister) {
107 {
108 DirectoryWatcher watcher;
109 ASSERT_TRUE(watcher.Watch(test_dir_, this));
110
111 // And then let it fall out of scope, clearing its watch.
112 }
113
114 // Write a file to the test dir.
115 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content");
116
117 // We won't get a notification, so we just wait around a bit to verify
118 // that notification doesn't come.
119 loop_.PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask,
120 kWaitForEventTime);
121 loop_.Run();
122
123 ASSERT_EQ(directory_mods_, 0);
124 }
125
126 // Verify that modifications to a subdirectory isn't noticed.
127 TEST_F(DirectoryWatcherTest, SubDir) {
128 FilePath subdir = test_dir_.Append(FILE_PATH_LITERAL("SubDir"));
129 ASSERT_TRUE(file_util::CreateDirectory(subdir.value()));
130
131 DirectoryWatcher watcher;
132 ASSERT_TRUE(watcher.Watch(test_dir_, this));
133 // Write a file to the subdir.
134 FilePath test_path = subdir.Append(FILE_PATH_LITERAL("test_file"));
135 WriteTestDirFile(test_path.value(), "some content");
136
137 // We won't get a notification, so we just wait around a bit to verify
138 // that notification doesn't come.
139 loop_.PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask,
140 kWaitForEventTime);
141 loop_.Run();
142
143 // We shouldn't have been notified and shouldn't have crashed.
144 ASSERT_EQ(directory_mods_, 0);
145 }
146
147 namespace {
148 // Used by the DeleteDuringNotify test below.
149 // Deletes the DirectoryWatcher when it's notified.
150 class Deleter : public DirectoryWatcher::Delegate {
151 public:
152 Deleter(DirectoryWatcher* watcher) : watcher_(watcher) {}
153 virtual void OnDirectoryChanged(const FilePath& path) {
154 watcher_.reset(NULL);
155 MessageLoop::current()->Quit();
156 }
157
158 scoped_ptr<DirectoryWatcher> watcher_;
159 };
160 } // anonymous namespace
161
162 // Verify that deleting a watcher during the callback
163 TEST_F(DirectoryWatcherTest, DeleteDuringNotify) {
164 DirectoryWatcher* watcher = new DirectoryWatcher;
165 Deleter deleter(watcher); // Takes ownership of watcher.
166 ASSERT_TRUE(watcher->Watch(test_dir_, &deleter));
167
168 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content");
169 LoopUntilModsEqual(2);
170
171 // We win if we haven't crashed yet.
172 // Might as well double-check it got deleted, too.
173 ASSERT_TRUE(deleter.watcher_.get() == NULL);
174 }
OLDNEW
« no previous file with comments | « base/directory_watcher.h ('k') | base/directory_watcher_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698