OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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/file_path_component_watcher.h" | |
6 | |
7 #include <gtest/gtest.h> | |
8 | |
9 #include "base/basictypes.h" | |
10 #include "base/file_util.h" | |
11 #include "base/message_loop.h" | |
12 #include "base/scoped_ptr.h" | |
13 #include "base/scoped_temp_dir.h" | |
14 #include "base/test/test_timeouts.h" | |
15 | |
16 #if defined(OS_MACOSX) | |
17 | |
18 namespace { | |
19 | |
20 class TestDelegate : public base::FilePathComponentWatcher::Delegate { | |
21 public: | |
22 TestDelegate() : components_changed_(false) { } | |
23 virtual ~TestDelegate() { } | |
24 virtual void OnFilePathComponentsChanged(const FilePath& old_path, | |
25 const FilePath& new_path) { | |
26 components_changed_ = true; | |
27 old_path_ = old_path; | |
28 new_path_ = new_path; | |
29 MessageLoop::current()->Quit(); | |
30 } | |
31 | |
32 bool components_changed_; | |
33 FilePath old_path_; | |
34 FilePath new_path_; | |
35 }; | |
36 | |
37 class FilePathComponentWatcherTest : public testing::Test { | |
38 public: | |
39 // Implementation of FilePathWatcher on Mac requires UI loop. | |
40 FilePathComponentWatcherTest() | |
41 : loop_(MessageLoop::TYPE_UI), delegate_(new TestDelegate) { | |
42 } | |
43 | |
44 protected: | |
45 virtual void SetUp() { | |
46 temp_dir_.reset(new ScopedTempDir); | |
47 ASSERT_TRUE(temp_dir_->CreateUniqueTempDir()); | |
48 } | |
49 | |
50 virtual void TearDown() { | |
51 loop_.RunAllPending(); | |
52 } | |
53 | |
54 FilePath test_file() { | |
55 return temp_dir_->path().AppendASCII("FilePathWatcherTest"); | |
56 } | |
57 | |
58 // Write |content| to |file|. Returns true on success. | |
59 bool WriteFile(const FilePath& file, const std::string& content) { | |
60 int write_size = file_util::WriteFile(file, content.c_str(), | |
61 content.length()); | |
62 return write_size == static_cast<int>(content.length()); | |
63 } | |
64 | |
65 void WaitForEvents() { | |
66 loop_.Run(); | |
67 } | |
68 | |
69 MessageLoop loop_; | |
70 scoped_ptr<ScopedTempDir> temp_dir_; | |
Paweł Hajdan Jr.
2011/03/10 16:02:04
nit: No need for scoped_ptr, really. The entire te
| |
71 base::FilePathComponentWatcher file_watcher_; | |
72 scoped_refptr<TestDelegate> delegate_; | |
73 }; | |
74 | |
75 class TestTask : public Task { | |
76 public: | |
77 void set_success() { *success_ = true; } | |
78 | |
79 protected: | |
80 bool* success_; | |
81 TestTask(bool *success) : success_(success) { *success_ = false; } | |
82 virtual ~TestTask() { } | |
83 }; | |
84 | |
85 class ChangeAttr : public TestTask { | |
Paweł Hajdan Jr.
2011/03/10 16:02:04
nit: It's going to be simpler to use NewRunnableFu
| |
86 public: | |
87 ChangeAttr(bool *success, const FilePath& path) | |
88 : TestTask(success), path_(path) { } | |
89 virtual ~ChangeAttr() { } | |
90 virtual void Run() { | |
91 if (chmod(path_.value().c_str(), S_IRWXU | S_IRWXG | S_IRWXO) == 0) { | |
92 set_success(); | |
93 } | |
94 } | |
95 | |
96 private: | |
97 FilePath path_; | |
98 | |
99 DISALLOW_COPY_AND_ASSIGN(ChangeAttr); | |
100 }; | |
101 | |
102 class Move : public TestTask { | |
103 public: | |
104 Move(bool *success, const FilePath& old_path, const FilePath& new_path) | |
105 : TestTask(success), old_path_(old_path), new_path_(new_path) { } | |
106 virtual ~Move() { } | |
107 virtual void Run() { | |
108 if (file_util::Move(old_path_, new_path_)) { | |
109 set_success(); | |
110 } | |
111 } | |
112 | |
113 private: | |
114 FilePath old_path_, new_path_; | |
115 | |
116 DISALLOW_COPY_AND_ASSIGN(Move); | |
117 }; | |
118 | |
119 class Delete : public TestTask { | |
120 public: | |
121 Delete(bool *success, const FilePath& path) | |
122 : TestTask(success), path_(path) { } | |
123 virtual ~Delete() { } | |
124 virtual void Run() { | |
125 if (file_util::Delete(path_, true)) { | |
126 set_success(); | |
127 } | |
128 } | |
129 | |
130 private: | |
131 FilePath path_; | |
132 | |
133 DISALLOW_COPY_AND_ASSIGN(Delete); | |
134 }; | |
135 | |
136 TEST_F(FilePathComponentWatcherTest, AttrChange) { | |
137 FilePath source_dir(temp_dir_->path().AppendASCII("source")); | |
138 FilePath source_file(source_dir.AppendASCII("file")); | |
139 | |
140 // Setup a directory hierarchy. | |
141 ASSERT_TRUE(file_util::CreateDirectory(source_dir)); | |
142 ASSERT_TRUE(WriteFile(source_file, "content")); | |
143 | |
144 ASSERT_TRUE(file_watcher_.Watch(source_file, delegate_)); | |
145 bool success; | |
146 loop_.PostTask(FROM_HERE, new ChangeAttr(&success, source_file)); | |
147 loop_.PostDelayedTask(FROM_HERE, | |
148 new MessageLoop::QuitTask, | |
149 TestTimeouts::action_timeout_ms()); | |
150 WaitForEvents(); | |
151 | |
152 ASSERT_TRUE(success); | |
153 ASSERT_TRUE(delegate_->components_changed_); | |
154 ASSERT_TRUE(file_util::AreReferringToSameObject(delegate_->old_path_, | |
155 source_file)); | |
156 ASSERT_TRUE(file_util::AreReferringToSameObject(delegate_->new_path_, | |
157 source_file)); | |
158 } | |
159 | |
160 TEST_F(FilePathComponentWatcherTest, InheritedAttrChange) { | |
161 FilePath source_dir1(temp_dir_->path().AppendASCII("source1")); | |
162 FilePath source_dir2(source_dir1.AppendASCII("source2")); | |
163 FilePath source_file(source_dir2.AppendASCII("file")); | |
164 | |
165 // Setup a directory hierarchy. | |
166 ASSERT_TRUE(file_util::CreateDirectory(source_dir2)); | |
167 ASSERT_TRUE(WriteFile(source_file, "content")); | |
168 | |
169 ASSERT_TRUE(file_watcher_.Watch(source_file, delegate_)); | |
170 | |
171 bool success; | |
172 loop_.PostTask(FROM_HERE, new ChangeAttr(&success, source_dir1)); | |
173 loop_.PostDelayedTask(FROM_HERE, | |
174 new MessageLoop::QuitTask, | |
175 TestTimeouts::action_timeout_ms()); | |
176 WaitForEvents(); | |
177 | |
178 ASSERT_TRUE(success); | |
179 ASSERT_TRUE(delegate_->components_changed_); | |
180 ASSERT_TRUE(file_util::AreReferringToSameObject(delegate_->old_path_, | |
181 source_file)); | |
182 ASSERT_TRUE(file_util::AreReferringToSameObject(delegate_->new_path_, | |
183 source_file)); | |
184 } | |
185 | |
186 TEST_F(FilePathComponentWatcherTest, InheritedMove) { | |
187 FilePath source_dir1(temp_dir_->path().AppendASCII("source1")); | |
188 FilePath source_dir2(source_dir1.AppendASCII("source2")); | |
189 FilePath source_file(source_dir2.AppendASCII("file")); | |
190 FilePath new_sourcedir1(temp_dir_->path().AppendASCII("new_source1")); | |
191 FilePath new_sourcedir2(new_sourcedir1.AppendASCII("source2")); | |
192 FilePath new_source_file(new_sourcedir2.AppendASCII("file")); | |
193 | |
194 // Setup a directory hierarchy. | |
195 ASSERT_TRUE(file_util::CreateDirectory(source_dir2)); | |
196 ASSERT_TRUE(WriteFile(source_file, "content")); | |
197 | |
198 ASSERT_TRUE(file_watcher_.Watch(source_file, delegate_)); | |
199 | |
200 bool success; | |
201 loop_.PostTask(FROM_HERE, new Move(&success, source_dir1, new_sourcedir1)); | |
202 loop_.PostDelayedTask(FROM_HERE, | |
203 new MessageLoop::QuitTask, | |
204 TestTimeouts::action_timeout_ms()); | |
205 WaitForEvents(); | |
206 | |
207 ASSERT_TRUE(success); | |
208 ASSERT_TRUE(delegate_->components_changed_); | |
209 | |
210 ASSERT_TRUE(file_util::AreReferringToSameObject(delegate_->new_path_, | |
211 new_source_file)); | |
212 | |
213 // File has been moved, so these paths will no longer exist | |
214 ASSERT_FALSE(file_util::PathExists(delegate_->old_path_)); | |
215 ASSERT_FALSE(file_util::PathExists(source_file)); | |
216 } | |
217 | |
218 TEST_F(FilePathComponentWatcherTest, Delete) { | |
219 FilePath source_dir1(temp_dir_->path().AppendASCII("source1")); | |
220 FilePath source_dir2(source_dir1.AppendASCII("source2")); | |
221 FilePath source_file(source_dir2.AppendASCII("file")); | |
222 | |
223 // Setup a directory hierarchy. | |
224 ASSERT_TRUE(file_util::CreateDirectory(source_dir2)); | |
225 ASSERT_TRUE(WriteFile(source_file, "content")); | |
226 | |
227 ASSERT_TRUE(file_watcher_.Watch(source_file, delegate_)); | |
228 | |
229 bool success; | |
230 loop_.PostTask(FROM_HERE, new Delete(&success, source_file)); | |
231 loop_.PostDelayedTask(FROM_HERE, | |
232 new MessageLoop::QuitTask, | |
233 TestTimeouts::action_timeout_ms()); | |
234 WaitForEvents(); | |
235 | |
236 ASSERT_TRUE(success); | |
237 ASSERT_TRUE(delegate_->components_changed_); | |
238 | |
239 // File has been deleted, so these paths will no longer exist | |
240 ASSERT_FALSE(file_util::PathExists(delegate_->old_path_)); | |
241 ASSERT_FALSE(file_util::PathExists(source_file)); | |
242 } | |
243 | |
244 } | |
245 | |
246 #else // OS_MACOSX | |
247 | |
248 // Test that our stub is there for now | |
249 TEST(FilePathComponentWatcherTest, StubTest) { | |
250 base::FilePathComponentWatcher file_watcher_; | |
251 ScopedTempDir temp_dir; | |
252 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | |
253 ASSERT_FALSE(file_watcher_.Watch(temp_dir.path(), NULL)); | |
254 } | |
255 | |
256 #endif // OS_MACOSX | |
OLD | NEW |