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

Side by Side Diff: base/directory_watcher_unittest.cc

Issue 42388: Enable non-recursive watches for Windows DirectoryWatcher.... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: fix the typo Created 11 years, 9 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')
OLDNEW
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 <fstream> 7 #include <limits>
8 8
9 #include "build/build_config.h" 9 #include "base/basictypes.h"
10
11 #include "base/file_path.h" 10 #include "base/file_path.h"
12 #include "base/file_util.h" 11 #include "base/file_util.h"
13 #include "base/message_loop.h" 12 #include "base/message_loop.h"
14 #include "base/path_service.h" 13 #include "base/path_service.h"
15 #include "base/platform_thread.h" 14 #include "base/platform_thread.h"
16 #include "base/string_util.h" 15 #include "base/string_util.h"
17 #if defined(OS_WIN)
18 #include "base/win_util.h"
19 #endif
20 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
21 17
22 // TODO(phajdan.jr): Clean up ifdefs in this file when Linux/Windows differences
23 // get sorted out.
24
25 namespace { 18 namespace {
26 19
27 // For tests where we wait a bit to verify nothing happened 20 // For tests where we wait a bit to verify nothing happened
28 const int kWaitForEventTime = 500; 21 const int kWaitForEventTime = 500;
29 22
30 // Unfortunately Windows supports only recursive watches and Linux
31 // only non-recursive ones.
32 #if defined(OS_WIN)
33 const bool kDefaultRecursiveValue = true;
34 #elif defined(OS_LINUX)
35 const bool kDefaultRecursiveValue = false;
36 #endif
37
38 } // namespace 23 } // namespace
39 24
40 class DirectoryWatcherTest : public testing::Test, 25 class DirectoryWatcherTest : public testing::Test,
41 public DirectoryWatcher::Delegate { 26 public DirectoryWatcher::Delegate {
42 protected: 27 protected:
43 virtual void SetUp() { 28 virtual void SetUp() {
44 // Name a subdirectory of the temp directory. 29 // Name a subdirectory of the temp directory.
45 FilePath path; 30 FilePath path;
46 ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &path)); 31 ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &path));
47 test_dir_ = path.Append(FILE_PATH_LITERAL("DirectoryWatcherTest")); 32 test_dir_ = path.Append(FILE_PATH_LITERAL("DirectoryWatcherTest"));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 int quit_mod_count_; 104 int quit_mod_count_;
120 105
121 // Keep track of original thread id to verify that callbacks are called 106 // Keep track of original thread id to verify that callbacks are called
122 // on the same thread. 107 // on the same thread.
123 PlatformThreadId original_thread_id_; 108 PlatformThreadId original_thread_id_;
124 }; 109 };
125 110
126 // Basic test: add a file and verify we notice it. 111 // Basic test: add a file and verify we notice it.
127 TEST_F(DirectoryWatcherTest, NewFile) { 112 TEST_F(DirectoryWatcherTest, NewFile) {
128 DirectoryWatcher watcher; 113 DirectoryWatcher watcher;
129 ASSERT_TRUE(watcher.Watch(test_dir_, this, kDefaultRecursiveValue)); 114 ASSERT_TRUE(watcher.Watch(test_dir_, this, false));
130 115
131 SetExpectedNumberOfModifications(2); 116 SetExpectedNumberOfModifications(2);
132 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content"); 117 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content");
133 VerifyExpectedNumberOfModifications(); 118 VerifyExpectedNumberOfModifications();
134 } 119 }
135 120
136 // Verify that modifying a file is caught. 121 // Verify that modifying a file is caught.
137 TEST_F(DirectoryWatcherTest, ModifiedFile) { 122 TEST_F(DirectoryWatcherTest, ModifiedFile) {
138 DirectoryWatcher watcher; 123 DirectoryWatcher watcher;
139 ASSERT_TRUE(watcher.Watch(test_dir_, this, kDefaultRecursiveValue)); 124 ASSERT_TRUE(watcher.Watch(test_dir_, this, false));
140 125
141 // Write a file to the test dir. 126 // Write a file to the test dir.
142 SetExpectedNumberOfModifications(2); 127 SetExpectedNumberOfModifications(2);
143 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content"); 128 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content");
144 VerifyExpectedNumberOfModifications(); 129 VerifyExpectedNumberOfModifications();
145 130
146 // Now make sure we get notified if the file is modified. 131 // Now make sure we get notified if the file is modified.
147 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some new content"); 132 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some new content");
148 // Use a more forgiving function to check because on Linux you will get 133 // Use a more forgiving function to check because on Linux you will get
149 // 1 notification, and on Windows 2 (and nothing seems to convince it to 134 // 1 notification, and on Windows 2 (and nothing seems to convince it to
150 // send less notifications). 135 // send less notifications).
151 WaitForFirstNotification(); 136 WaitForFirstNotification();
152 } 137 }
153 138
154 // Verify that letting the watcher go out of scope stops notifications. 139 // Verify that letting the watcher go out of scope stops notifications.
155 TEST_F(DirectoryWatcherTest, Unregister) { 140 TEST_F(DirectoryWatcherTest, Unregister) {
156 { 141 {
157 DirectoryWatcher watcher; 142 DirectoryWatcher watcher;
158 ASSERT_TRUE(watcher.Watch(test_dir_, this, kDefaultRecursiveValue)); 143 ASSERT_TRUE(watcher.Watch(test_dir_, this, false));
159 144
160 // And then let it fall out of scope, clearing its watch. 145 // And then let it fall out of scope, clearing its watch.
161 } 146 }
162 147
163 // Write a file to the test dir. 148 // Write a file to the test dir.
164 SetExpectedNumberOfModifications(0); 149 SetExpectedNumberOfModifications(0);
165 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content"); 150 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content");
166 VerifyExpectedNumberOfModifications(); 151 VerifyExpectedNumberOfModifications();
167 } 152 }
168 153
169 TEST_F(DirectoryWatcherTest, SubDir) { 154 TEST_F(DirectoryWatcherTest, SubDirRecursive) {
170 FilePath subdir(FILE_PATH_LITERAL("SubDir")); 155 FilePath subdir(FILE_PATH_LITERAL("SubDir"));
171 ASSERT_TRUE(file_util::CreateDirectory(test_dir_.Append(subdir))); 156 ASSERT_TRUE(file_util::CreateDirectory(test_dir_.Append(subdir)));
172 157
173 #if defined(OS_WIN) 158 #if !defined(OS_WIN)
174 // TODO(port): Recursive watches are not implemented on Linux. 159 // TODO(port): Recursive watches are not implemented on Linux.
160 return;
161 #endif // !defined(OS_WIN)
175 162
176 // Verify that modifications to a subdirectory are noticed by recursive watch. 163 // Verify that modifications to a subdirectory are noticed by recursive watch.
177 { 164 DirectoryWatcher watcher;
178 DirectoryWatcher watcher; 165 ASSERT_TRUE(watcher.Watch(test_dir_, this, true));
179 ASSERT_TRUE(watcher.Watch(test_dir_, this, true)); 166 // Write a file to the subdir.
180 // Write a file to the subdir. 167 SetExpectedNumberOfModifications(2);
181 SetExpectedNumberOfModifications(2); 168 FilePath test_path = subdir.AppendASCII("test_file");
182 FilePath test_path = subdir.AppendASCII("test_file"); 169 WriteTestDirFile(test_path.value(), "some content");
183 WriteTestDirFile(test_path.value(), "some content"); 170 VerifyExpectedNumberOfModifications();
184 VerifyExpectedNumberOfModifications(); 171 }
185 }
186 #endif // defined(OS_WIN)
187 172
188 #if !defined(OS_WIN) 173 TEST_F(DirectoryWatcherTest, SubDirNonRecursive) {
189 // TODO: Enable when the root cause of http://crbug.com/5072 is fixed. 174 FilePath subdir(FILE_PATH_LITERAL("SubDir"));
175 ASSERT_TRUE(file_util::CreateDirectory(test_dir_.Append(subdir)));
176
177 // Create a test file before the test. On Windows we get a notification
178 // when creating a file in a subdir even with a non-recursive watch.
179 FilePath test_path = subdir.AppendASCII("test_file");
180 WriteTestDirFile(test_path.value(), "some content");
190 181
191 // Verify that modifications to a subdirectory are not noticed 182 // Verify that modifications to a subdirectory are not noticed
192 // by a not-recursive watch. 183 // by a not-recursive watch.
193 { 184 DirectoryWatcher watcher;
194 DirectoryWatcher watcher; 185 ASSERT_TRUE(watcher.Watch(test_dir_, this, false));
195 ASSERT_TRUE(watcher.Watch(test_dir_, this, false)); 186
196 // Write a file to the subdir. 187 // Modify the test file. There should be no notifications.
197 SetExpectedNumberOfModifications(0); 188 SetExpectedNumberOfModifications(0);
198 FilePath test_path = subdir.AppendASCII("test_file"); 189 WriteTestDirFile(test_path.value(), "some other content");
199 WriteTestDirFile(test_path.value(), "some content"); 190 VerifyExpectedNumberOfModifications();
200 VerifyExpectedNumberOfModifications();
201 }
202 #endif // !defined(OS_WIN)
203 } 191 }
204 192
205 namespace { 193 namespace {
206 // Used by the DeleteDuringNotify test below. 194 // Used by the DeleteDuringNotify test below.
207 // Deletes the DirectoryWatcher when it's notified. 195 // Deletes the DirectoryWatcher when it's notified.
208 class Deleter : public DirectoryWatcher::Delegate { 196 class Deleter : public DirectoryWatcher::Delegate {
209 public: 197 public:
210 Deleter(DirectoryWatcher* watcher, MessageLoop* loop) 198 Deleter(DirectoryWatcher* watcher, MessageLoop* loop)
211 : watcher_(watcher), 199 : watcher_(watcher),
212 loop_(loop) { 200 loop_(loop) {
213 } 201 }
214 202
215 virtual void OnDirectoryChanged(const FilePath& path) { 203 virtual void OnDirectoryChanged(const FilePath& path) {
216 watcher_.reset(NULL); 204 watcher_.reset(NULL);
217 loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); 205 loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
218 } 206 }
219 207
220 scoped_ptr<DirectoryWatcher> watcher_; 208 scoped_ptr<DirectoryWatcher> watcher_;
221 MessageLoop* loop_; 209 MessageLoop* loop_;
222 }; 210 };
223 } // anonymous namespace 211 } // anonymous namespace
224 212
225 // Verify that deleting a watcher during the callback 213 // Verify that deleting a watcher during the callback
226 TEST_F(DirectoryWatcherTest, DeleteDuringNotify) { 214 TEST_F(DirectoryWatcherTest, DeleteDuringNotify) {
227 DirectoryWatcher* watcher = new DirectoryWatcher; 215 DirectoryWatcher* watcher = new DirectoryWatcher;
228 Deleter deleter(watcher, &loop_); // Takes ownership of watcher. 216 Deleter deleter(watcher, &loop_); // Takes ownership of watcher.
229 ASSERT_TRUE(watcher->Watch(test_dir_, &deleter, kDefaultRecursiveValue)); 217 ASSERT_TRUE(watcher->Watch(test_dir_, &deleter, false));
230 218
231 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content"); 219 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content");
232 loop_.Run(); 220 loop_.Run();
233 221
234 // We win if we haven't crashed yet. 222 // We win if we haven't crashed yet.
235 // Might as well double-check it got deleted, too. 223 // Might as well double-check it got deleted, too.
236 ASSERT_TRUE(deleter.watcher_.get() == NULL); 224 ASSERT_TRUE(deleter.watcher_.get() == NULL);
237 } 225 }
238 226
239 TEST_F(DirectoryWatcherTest, MultipleWatchersSingleFile) { 227 TEST_F(DirectoryWatcherTest, MultipleWatchersSingleFile) {
240 DirectoryWatcher watcher1, watcher2; 228 DirectoryWatcher watcher1, watcher2;
241 ASSERT_TRUE(watcher1.Watch(test_dir_, this, kDefaultRecursiveValue)); 229 ASSERT_TRUE(watcher1.Watch(test_dir_, this, false));
242 ASSERT_TRUE(watcher2.Watch(test_dir_, this, kDefaultRecursiveValue)); 230 ASSERT_TRUE(watcher2.Watch(test_dir_, this, false));
243 231
244 SetExpectedNumberOfModifications(4); // Each watcher should fire twice. 232 SetExpectedNumberOfModifications(4); // Each watcher should fire twice.
245 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content"); 233 WriteTestDirFile(FILE_PATH_LITERAL("test_file"), "some content");
246 VerifyExpectedNumberOfModifications(); 234 VerifyExpectedNumberOfModifications();
247 } 235 }
248 236
249 TEST_F(DirectoryWatcherTest, MultipleWatchersDifferentFiles) { 237 TEST_F(DirectoryWatcherTest, MultipleWatchersDifferentFiles) {
250 const int kNumberOfWatchers = 5; 238 const int kNumberOfWatchers = 5;
251 DirectoryWatcher watchers[kNumberOfWatchers]; 239 DirectoryWatcher watchers[kNumberOfWatchers];
252 FilePath subdirs[kNumberOfWatchers]; 240 FilePath subdirs[kNumberOfWatchers];
253 for (int i = 0; i < kNumberOfWatchers; i++) { 241 for (int i = 0; i < kNumberOfWatchers; i++) {
254 subdirs[i] = FilePath(FILE_PATH_LITERAL("Dir")).AppendASCII(IntToString(i)); 242 subdirs[i] = FilePath(FILE_PATH_LITERAL("Dir")).AppendASCII(IntToString(i));
255 ASSERT_TRUE(file_util::CreateDirectory(test_dir_.Append(subdirs[i]))); 243 ASSERT_TRUE(file_util::CreateDirectory(test_dir_.Append(subdirs[i])));
256 244
257 ASSERT_TRUE(watchers[i].Watch(test_dir_.Append(subdirs[i]), this, 245 ASSERT_TRUE(watchers[i].Watch(test_dir_.Append(subdirs[i]), this, false));
258 kDefaultRecursiveValue));
259 } 246 }
260 for (int i = 0; i < kNumberOfWatchers; i++) { 247 for (int i = 0; i < kNumberOfWatchers; i++) {
261 // Verify that we only get modifications from one watcher (each watcher has 248 // Verify that we only get modifications from one watcher (each watcher has
262 // different directory). 249 // different directory).
263 250
264 ASSERT_EQ(0, directory_mods_); 251 ASSERT_EQ(0, directory_mods_);
265 252
266 // Write a file to the subdir. 253 // Write a file to the subdir.
267 FilePath test_path = subdirs[i].AppendASCII("test_file"); 254 FilePath test_path = subdirs[i].AppendASCII("test_file");
268 SetExpectedNumberOfModifications(2); 255 SetExpectedNumberOfModifications(2);
269 WriteTestDirFile(test_path.value(), "some content"); 256 WriteTestDirFile(test_path.value(), "some content");
270 VerifyExpectedNumberOfModifications(); 257 VerifyExpectedNumberOfModifications();
271 258
272 directory_mods_ = 0; 259 directory_mods_ = 0;
273 } 260 }
274 } 261 }
275 262
276 // Verify that watching a directory that doesn't exist fails, but doesn't 263 // Verify that watching a directory that doesn't exist fails, but doesn't
277 // asssert. 264 // asssert.
278 // Basic test: add a file and verify we notice it. 265 // Basic test: add a file and verify we notice it.
279 TEST_F(DirectoryWatcherTest, NonExistentDirectory) { 266 TEST_F(DirectoryWatcherTest, NonExistentDirectory) {
280 DirectoryWatcher watcher; 267 DirectoryWatcher watcher;
281 ASSERT_FALSE(watcher.Watch(test_dir_.AppendASCII("does-not-exist"), this, 268 ASSERT_FALSE(watcher.Watch(test_dir_.AppendASCII("does-not-exist"), this,
282 kDefaultRecursiveValue)); 269 false));
283 } 270 }
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